diff --git a/apps/portal/package.json b/apps/portal/package.json
index a702f8b77..ee9a0cf43 100644
--- a/apps/portal/package.json
+++ b/apps/portal/package.json
@@ -49,6 +49,7 @@
"@talismn/web-icons": "workspace:^",
"@tanstack/react-query": "^5.32.0",
"@visx/visx": "^3.1.2",
+ "avail-js-sdk": "^0.2.13",
"bignumber.js": "^9.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
diff --git a/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStakeSideSheet.tsx b/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStakeSideSheet.tsx
index e8cbec3bd..8c2d56307 100644
--- a/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStakeSideSheet.tsx
+++ b/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStakeSideSheet.tsx
@@ -1,4 +1,4 @@
-import { ChainProvider } from '../../../../domains/chains'
+import { ChainProvider, useChainState } from '../../../../domains/chains'
import { nominationPoolsEnabledChainsState, type ChainInfo } from '../../../../domains/chains/recoils'
import { useEraEtaFormatter } from '../../../../domains/common/hooks'
import { useApr } from '../../../../domains/staking/substrate/nominationPools'
@@ -7,13 +7,18 @@ import StakeForm from '../../../recipes/StakeForm/StakeForm'
import ErrorBoundary from '../../ErrorBoundary'
import { AssetSelect, ControlledStakeForm } from './StakeForm'
import { CircularProgressIndicator } from '@talismn/ui'
+import { Text } from '@talismn/ui'
import BN from 'bn.js'
import { Suspense, useState, useTransition } from 'react'
import { useSearchParams } from 'react-router-dom'
import { useRecoilValue } from 'recoil'
const Rewards = () => {
- return <>{useApr().toLocaleString(undefined, { style: 'percent', maximumFractionDigits: 2 })}>
+ const chain = useRecoilValue(useChainState())
+ const apr = useApr()
+
+ if (chain.id === 'avail') return Coming Soon
+ return <>{apr.toLocaleString(undefined, { style: 'percent', maximumFractionDigits: 2 })}>
}
const EraEta = () => {
diff --git a/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStatisticsSideSheet.tsx b/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStatisticsSideSheet.tsx
index bc81f5c9a..ec0857a0b 100644
--- a/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStatisticsSideSheet.tsx
+++ b/apps/portal/src/components/widgets/staking/substrate/NominationPoolsStatisticsSideSheet.tsx
@@ -305,7 +305,13 @@ const ExistingPool = (props: NominationPoolsStatisticsSideSheetProps & { pool: D
poolStatus={props.pool.status}
balance={{balance.decimalAmount.toLocaleString()}}
rewards={{last15DaysTotalPayouts.toLocaleString()}}
- apr={stakedReturn.toLocaleString(undefined, { style: 'percent' })}
+ apr={
+ chain.id === 'avail' ? (
+ Coming Soon
+ ) : (
+ stakedReturn.toLocaleString(undefined, { style: 'percent' })
+ )
+ }
nextEraEta={useEraEtaFormatter()(1)}
unbondings={useMemo(
() =>
diff --git a/apps/portal/src/components/widgets/staking/substrate/StakeCalculatorDialog.tsx b/apps/portal/src/components/widgets/staking/substrate/StakeCalculatorDialog.tsx
index 20b7f8f52..9a5bbc21d 100644
--- a/apps/portal/src/components/widgets/staking/substrate/StakeCalculatorDialog.tsx
+++ b/apps/portal/src/components/widgets/staking/substrate/StakeCalculatorDialog.tsx
@@ -4,6 +4,7 @@ import { useApr } from '../../../../domains/staking/substrate/nominationPools'
import StakeCalculatorDialogComponent from '../../../recipes/StakeCalculatorDialog'
import ErrorBoundary from '../../ErrorBoundary'
import { AssetSelect } from './StakeForm'
+import { Text } from '@talismn/ui'
import BN from 'bn.js'
import { Suspense, useDeferredValue, useMemo, useState, useTransition } from 'react'
import { useRecoilValue } from 'recoil'
@@ -11,6 +12,7 @@ import { useRecoilValue } from 'recoil'
type StakeCalculatorDialogProps = { open?: boolean; onRequestDismiss: () => unknown }
const EstimatedYield = (props: { amount: string }) => {
+ const chain = useRecoilValue(useChainState())
const stakedReturn = useApr()
const amount = useTokenAmount(props.amount)
@@ -28,6 +30,16 @@ const EstimatedYield = (props: { amount: string }) => {
const dailyYield = useTokenAmountFromPlanck(useMemo(() => bnPlanck?.divn(365), [bnPlanck]))
+ if (chain.id === 'avail')
+ return (
+ Coming Soon}
+ monthlyYield={monthlyYield.decimalAmount?.toLocaleString()}
+ weeklyYield={weeklyYield.decimalAmount?.toLocaleString()}
+ dailyYield={dailyYield.decimalAmount?.toLocaleString()}
+ />
+ )
+
return (
(props: {
const EstimatedYield = memo(
(props: { amount: Decimal }) => {
+ const chain = useRecoilValue(Chains_useChainState())
const stakedReturn = useApr()
const annualReturn = useMemo(
() => new BN(props.amount.planck.toString()).muln(stakedReturn),
@@ -255,6 +255,9 @@ const EstimatedYield = memo(
)
const parsedAnnualReturn = useTokenAmountFromPlanck(annualReturn)
+ if (chain.id === 'avail')
+ return Coming Soon} fiatAmount={null} />
+
return (
{
- return <>{useApr().toLocaleString(undefined, { style: 'percent', maximumFractionDigits: 2 })}>
+ const chain = useRecoilValue(useChainState())
+ const apr = useApr()
+
+ if (chain.id === 'avail') return Coming Soon
+ return <>{apr.toLocaleString(undefined, { style: 'percent', maximumFractionDigits: 2 })}>
}
const useAvailableBalance = () => {
diff --git a/apps/portal/src/domains/chains/config.ts b/apps/portal/src/domains/chains/config.ts
index afdf12cd0..f290cac69 100644
--- a/apps/portal/src/domains/chains/config.ts
+++ b/apps/portal/src/domains/chains/config.ts
@@ -57,6 +57,13 @@ export const chainConfigs: ChainConfig[] = [
talismanPools: [8],
novaIndexerUrl: 'https://api.subquery.network/sq/nova-wallet/nova-wallet---vara',
},
+ // Avail
+ {
+ genesisHash: '0xb91746b45e0346cc2f815a520b9c6cb4d5c0902af848db0a80f85932d2e8276a',
+ hasNominationPools: true,
+ priorityPool: 2,
+ talismanPools: [2],
+ },
// Westend
{
genesisHash: '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e',
diff --git a/apps/portal/src/domains/common/recoils/api.ts b/apps/portal/src/domains/common/recoils/api.ts
index a8800dd3e..2c926b537 100644
--- a/apps/portal/src/domains/common/recoils/api.ts
+++ b/apps/portal/src/domains/common/recoils/api.ts
@@ -1,10 +1,26 @@
import { useSubstrateApiEndpoint } from '..'
+import { chainsState } from '@/domains/chains'
import { ApiPromise, WsProvider } from '@polkadot/api'
+import * as AvailJsSdk from 'avail-js-sdk'
import { selectorFamily } from 'recoil'
export const substrateApiState = selectorFamily({
key: 'SubstrateApiState',
- get: endpoint => async () => await ApiPromise.create({ provider: new WsProvider(endpoint) }),
+ get:
+ endpoint =>
+ async ({ get }) => {
+ const availEndpoints = (get(chainsState).find(chain => chain.id === 'avail')?.rpcs ?? []).map(({ url }) => url)
+ const isAvail = endpoint && availEndpoints.includes(endpoint)
+ if (isAvail)
+ return await ApiPromise.create({
+ provider: new WsProvider(endpoint),
+ types: AvailJsSdk.spec.types,
+ rpc: AvailJsSdk.spec.rpc,
+ signedExtensions: AvailJsSdk.spec.signedExtensions,
+ })
+
+ return await ApiPromise.create({ provider: new WsProvider(endpoint) })
+ },
dangerouslyAllowMutability: true,
cachePolicy_UNSTABLE: { eviction: 'most-recent' },
})
diff --git a/apps/portal/src/routes/portfolio/assets/main.tsx b/apps/portal/src/routes/portfolio/assets/main.tsx
index 2a3c6a75f..c575b8cec 100644
--- a/apps/portal/src/routes/portfolio/assets/main.tsx
+++ b/apps/portal/src/routes/portfolio/assets/main.tsx
@@ -39,7 +39,7 @@ const Assets = () => {
onChangeText={setSearch}
placeholder="Search for an Asset"
containerClassName={css({ flex: 1, maxWidth: '37rem' })}
- css={{ width: 0 }}
+ css={{ width: '100%' }}
/>
)}
diff --git a/apps/portal/src/routes/portfolio/overview.tsx b/apps/portal/src/routes/portfolio/overview.tsx
index bd7c81de3..5c16105a0 100644
--- a/apps/portal/src/routes/portfolio/overview.tsx
+++ b/apps/portal/src/routes/portfolio/overview.tsx
@@ -85,7 +85,7 @@ const SuspendableAssetsOverview = () => {
onChangeText={setSearch}
css={{
'@media (min-width: 1024px)': {
- width: 0,
+ width: 'auto',
},
}}
/>
diff --git a/packages/ui/src/theme.tsx b/packages/ui/src/theme.tsx
index 864879db0..c3fecd578 100644
--- a/packages/ui/src/theme.tsx
+++ b/packages/ui/src/theme.tsx
@@ -143,7 +143,7 @@ export const ThemeProvider = ({ theme: propsTheme = greenDark, merge = false, ch
styles={css`
:root {
color: ${theme.color.onBackground};
- font-family: ${theme.typography.body.fontFamily};
+ font-family: ${theme.typography.body.fontFamily}, sans-serif;
font-size: 10px;
font-weight: ${theme.typography.body.fontWeight ?? 'revert'};
background-color: ${theme.color.background};
diff --git a/yarn.lock b/yarn.lock
index aa007aa1d..fd702ec82 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5328,7 +5328,7 @@ __metadata:
languageName: node
linkType: hard
-"@polkadot/api@npm:^10.11.1, @polkadot/api@npm:^10.7.3, @polkadot/api@npm:^10.9.1":
+"@polkadot/api@npm:^10.11.1, @polkadot/api@npm:^10.11.3, @polkadot/api@npm:^10.7.3, @polkadot/api@npm:^10.9.1":
version: 10.13.1
resolution: "@polkadot/api@npm:10.13.1"
dependencies:
@@ -9861,6 +9861,7 @@ __metadata:
"@types/react-router-dom": "npm:^5.3.3"
"@visx/visx": "npm:^3.1.2"
"@vitejs/plugin-react": "npm:^4.2.1"
+ avail-js-sdk: "npm:^0.2.13"
bignumber.js: "npm:^9.1.1"
class-variance-authority: "npm:^0.7.0"
clsx: "npm:^2.1.1"
@@ -12962,6 +12963,15 @@ __metadata:
languageName: node
linkType: hard
+"avail-js-sdk@npm:^0.2.13":
+ version: 0.2.13
+ resolution: "avail-js-sdk@npm:0.2.13"
+ dependencies:
+ "@polkadot/api": "npm:^10.11.3"
+ checksum: 10c0/0f85b816f4858e0e132aab786280ce9500d5d69382f939203088c39e815f0aab27f6f6863535221119d9a2f19fb837b1aa304f80adf63925650f8d10788282fe
+ languageName: node
+ linkType: hard
+
"available-typed-arrays@npm:^1.0.7":
version: 1.0.7
resolution: "available-typed-arrays@npm:1.0.7"