From 10bc136b85dc022d9ce07c098a3a3427774279e0 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 1 Oct 2024 19:37:33 +0330 Subject: [PATCH 1/3] feat: support Aleph Zero plus its staking --- .../components/AccountInputWithIdentity.tsx | 19 ++++---- .../stake/partials/DisplayBalance.tsx | 8 ++-- .../src/fullscreen/stake/solo/StakedSolo.tsx | 9 ++-- .../solo/commonTasks/configurePayee/index.tsx | 2 +- .../stake/solo/partials/SetPayee.tsx | 23 +++++----- .../stake/solo/partials/ShowValidator.tsx | 16 +++++-- .../stake/solo/partials/ValidatorsTableFS.tsx | 6 +-- .../extension-polkagate/src/hooks/index.ts | 1 - .../src/hooks/useApiWithChain2.ts | 14 +++++- .../src/hooks/useEndpoints.ts | 4 +- .../src/hooks/useIdentity.ts | 2 +- .../src/hooks/useNativeTokenPrice.ts | 23 ---------- .../src/hooks/usePeopleChain.ts | 17 ++++--- .../src/hooks/useValidatorSuggestion.ts | 2 +- .../src/partials/FullScreenChainSwitch.tsx | 2 +- .../src/popup/send/index.tsx | 6 +-- .../src/popup/staking/solo/stake/Settings.tsx | 4 +- .../solo/stake/partials/RewardDestination.tsx | 6 +-- .../stake/partials/SetPayeeController.tsx | 25 +++++------ .../staking/solo/stake/partials/util.tsx | 4 +- .../src/util/api/getPrices.ts | 5 ++- .../src/util/constants.tsx | 16 +++---- .../extension-polkagate/src/util/getLogo2.ts | 2 +- .../extension-polkagate/src/util/types.ts | 4 +- .../src/util/workers/getStakingConsts.js | 27 +++++++----- .../src/util/workers/getValidatorsInfo.js | 4 +- .../util/workers/utils/getChainEndpoints.js | 9 +++- replacements/interfaces.js | 44 ++++++++++--------- 28 files changed, 161 insertions(+), 143 deletions(-) delete mode 100644 packages/extension-polkagate/src/hooks/useNativeTokenPrice.ts diff --git a/packages/extension-polkagate/src/components/AccountInputWithIdentity.tsx b/packages/extension-polkagate/src/components/AccountInputWithIdentity.tsx index 85605feb9..0fafd00cb 100644 --- a/packages/extension-polkagate/src/components/AccountInputWithIdentity.tsx +++ b/packages/extension-polkagate/src/components/AccountInputWithIdentity.tsx @@ -1,34 +1,31 @@ // Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors // SPDX-License-Identifier: Apache-2.0 -// @ts-nocheck /* eslint-disable react/jsx-max-props-per-line */ +import type { Chain } from '@polkadot/extension-chains/types'; + import { Grid, type SxProps, type Theme, useTheme } from '@mui/material'; import React, { useContext } from 'react'; import { useParams } from 'react-router'; -import type { Chain } from '@polkadot/extension-chains/types'; - - import { useApi, useTranslation } from '../hooks'; import getAllAddresses from '../util/getAllAddresses'; import { AccountContext, AddressInput, Identity } from '.'; -import type { AccountId } from '@polkadot/types/interfaces'; interface Props { address: string | null | undefined; chain: Chain | null | undefined; label: string; style?: SxProps; - setAddress: React.Dispatch> | null; + setAddress?: React.Dispatch>; ignoreAddress?: string name?: string; helperText?: string; disabled?: boolean; } -export default function AccountInputWithIdentity({ address, chain, disabled, helperText, ignoreAddress, label, name, setAddress, style }: Props): React.ReactElement { +export default function AccountInputWithIdentity ({ address, chain, disabled, helperText, ignoreAddress, label, name, setAddress, style }: Props): React.ReactElement { const theme = useTheme(); const { t } = useTranslation(); const { hierarchy } = useContext(AccountContext); @@ -39,9 +36,9 @@ export default function AccountInputWithIdentity({ address, chain, disabled, hel return ( } diff --git a/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx b/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx index 0b9b4fd07..59c4af4de 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx @@ -13,7 +13,7 @@ import { Box, Collapse, Divider, Grid, Typography, useTheme } from '@mui/materia import React, { useCallback, useMemo, useState } from 'react'; import { useTranslation } from '@polkadot/extension-polkagate/src/components/translate'; -import { useInfo, useNativeTokenPrice } from '@polkadot/extension-polkagate/src/hooks'; +import { useInfo, useTokenPrice } from '@polkadot/extension-polkagate/src/hooks'; import { DATE_OPTIONS } from '@polkadot/extension-polkagate/src/util/constants'; import { noop } from '@polkadot/extension-polkagate/src/util/utils'; @@ -66,7 +66,7 @@ const ToBeReleased = ({ decimal, showUnstaking, text, toBeReleased, token }: ToB export default function DisplayBalance ({ actions, address, amount, icons, isUnstaking, marginTop = '10px', onClicks, title, toBeReleased }: DisplayBalanceProps): React.ReactElement { const theme = useTheme(); const { t } = useTranslation(); - const price = useNativeTokenPrice(address); + const { price } = useTokenPrice(address, 0); const { decimal, token } = useInfo(address); const [showUnstaking, setShowUnstaking] = useState(false); @@ -96,7 +96,7 @@ export default function DisplayBalance ({ actions, address, amount, icons, isUns {title} - + - + {isUnstaking && (); diff --git a/packages/extension-polkagate/src/fullscreen/stake/solo/commonTasks/configurePayee/index.tsx b/packages/extension-polkagate/src/fullscreen/stake/solo/commonTasks/configurePayee/index.tsx index a033f0103..bcb1d6574 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/solo/commonTasks/configurePayee/index.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/solo/commonTasks/configurePayee/index.tsx @@ -128,7 +128,7 @@ export default function ConfigurePayee ({ address, setRefresh, setShow, show }: setRewardDestinationValue(payee === 'Staked' ? 'Staked' : 'Others'); - return ({ payee, stashId: parsedStakingAccount.stashId }); + return ({ payee, stashId: parsedStakingAccount.stashId as unknown as string }); }, [stakingAccount]); const getOptionLabel = useCallback((s: SoloSettings): 'Staked' | 'Others' => s?.payee === 'Staked' ? 'Staked' : 'Others', []); diff --git a/packages/extension-polkagate/src/fullscreen/stake/solo/partials/SetPayee.tsx b/packages/extension-polkagate/src/fullscreen/stake/solo/partials/SetPayee.tsx index 149cae3d0..70b02b462 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/solo/partials/SetPayee.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/solo/partials/SetPayee.tsx @@ -1,13 +1,14 @@ // Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors // SPDX-License-Identifier: Apache-2.0 -// @ts-nocheck /* eslint-disable react/jsx-max-props-per-line */ -import { FormControl, FormControlLabel, FormLabel, Grid, Radio, RadioGroup, Skeleton, SxProps, Typography, useTheme } from '@mui/material'; +import type { SxProps } from '@mui/material'; +import type { Payee } from '@polkadot/extension-polkagate/src/util/types'; + +import { FormControl, FormControlLabel, FormLabel, Grid, Radio, RadioGroup, Skeleton, Typography, useTheme } from '@mui/material'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { Payee } from '@polkadot/extension-polkagate/src/util/types'; import { amountToHuman } from '@polkadot/extension-polkagate/src/util/utils'; import { AccountInputWithIdentity, Warning } from '../../../../components'; @@ -19,7 +20,7 @@ interface Props { set: React.Dispatch> } -export default function SetPayee({ address, set, title }: Props): React.ReactElement { +export default function SetPayee ({ address, set, title }: Props): React.ReactElement { const { t } = useTranslation(); const theme = useTheme(); const { chain, decimal, formatted, token } = useInfo(address); @@ -27,19 +28,19 @@ export default function SetPayee({ address, set, title }: Props): React.ReactEle const stakingConsts = useStakingConsts(address); const [rewardDestinationValue, setRewardDestinationValue] = useState<'Staked' | 'Others'>('Staked'); - const [rewardDestinationAccount, setRewardDestinationAccount] = useState(); + const [rewardDestinationAccount, setRewardDestinationAccount] = useState(); const ED = useMemo(() => stakingConsts?.existentialDeposit && decimal && amountToHuman(stakingConsts.existentialDeposit, decimal), [decimal, stakingConsts?.existentialDeposit]); - const onSelectionMethodChange = useCallback((event: React.ChangeEvent, value: 'Staked' | 'Others'): void => { - setRewardDestinationValue(value); + const onSelectionMethodChange = useCallback((_event: React.ChangeEvent, value: string): void => { + setRewardDestinationValue(value as 'Staked' | 'Others'); if (value === 'Staked') { setRewardDestinationAccount(undefined);// to reset } }, []); - const makePayee = useCallback((value: 'Staked' | 'Others', account?: string) => { + const makePayee = useCallback((value: 'Staked' | 'Others', account?: string | null) => { if (value === 'Staked') { return 'Staked'; } @@ -65,7 +66,7 @@ export default function SetPayee({ address, set, title }: Props): React.ReactEle set(newPayee); }, [makePayee, rewardDestinationAccount, rewardDestinationValue, set]); - const Warn = ({ text, style = {} }: { text: string, style?: SxProps }) => ( + const Warn = ({ style = {}, text }: { text: string, style?: SxProps }) => ( } @@ -100,7 +101,7 @@ export default function SetPayee({ address, set, title }: Props): React.ReactEle <> - {isHexToBn(v.exposure.total.toString()).gt(BN_ZERO) + {!!v.exposure && isHexToBn(v.exposure.total.toString()).gt(BN_ZERO) ? - : t('waiting') + : !v.exposure && v.stakingLedger.total && isHexToBn(v.stakingLedger.total.toString()).gt(BN_ZERO) + ? + : t('waiting') } @@ -108,7 +118,7 @@ function ShowValidator ({ accountInfo, allInOneRow = true, api, chain, check, de {t('Nominators')}: - {v.exposure.others?.length || t('N/A')} + {v.exposure?.others?.length || t('N/A')} diff --git a/packages/extension-polkagate/src/fullscreen/stake/solo/partials/ValidatorsTableFS.tsx b/packages/extension-polkagate/src/fullscreen/stake/solo/partials/ValidatorsTableFS.tsx index 4e63f9f10..d9364fc27 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/solo/partials/ValidatorsTableFS.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/solo/partials/ValidatorsTableFS.tsx @@ -55,12 +55,12 @@ export default function ValidatorsTableFS ({ activeValidators, address, allValid } const threshold = stakingConsts.maxNominatorRewardedPerValidator; - const sortedNominators = v.exposure.others?.sort((a: any, b: any) => b.value - a.value); + const sortedNominators = v.exposure?.others?.sort((a: any, b: any) => b.value - a.value); const maybeMyIndex = staked ? sortedNominators?.findIndex((n: any) => new BN(isHex(n.value) ? hexToBn(n.value) : String(n.value)).lt(staked)) : -1; return { - notSafe: v.exposure.others?.length > threshold && (maybeMyIndex > threshold || maybeMyIndex === -1), - safe: v.exposure.others?.length > threshold && (maybeMyIndex < threshold || maybeMyIndex === -1) + notSafe: v.exposure?.others?.length > threshold && (maybeMyIndex > threshold || maybeMyIndex === -1), + safe: v.exposure?.others?.length > threshold && (maybeMyIndex < threshold || maybeMyIndex === -1) }; }, [staked, stakingConsts]); diff --git a/packages/extension-polkagate/src/hooks/index.ts b/packages/extension-polkagate/src/hooks/index.ts index 9b0e8fc3f..acf73b982 100644 --- a/packages/extension-polkagate/src/hooks/index.ts +++ b/packages/extension-polkagate/src/hooks/index.ts @@ -66,7 +66,6 @@ export { default as useMinToReceiveRewardsInSolo2 } from './useMinToReceiveRewar export { default as useMyAccountIdentity } from './useMyAccountIdentity'; export { default as useMyPools } from './useMyPools'; export { default as useMyVote } from './useMyVote'; -export { default as useNativeTokenPrice } from './useNativeTokenPrice'; export { default as useNeedsPutInFrontOf } from './useNeedsPutInFrontOf'; export { default as useNeedsRebag } from './useNeedsRebag'; export { default as useNotifyOnChainChange } from './useNotifyOnChainChange'; diff --git a/packages/extension-polkagate/src/hooks/useApiWithChain2.ts b/packages/extension-polkagate/src/hooks/useApiWithChain2.ts index 4f5cfbbda..f9dfab47c 100644 --- a/packages/extension-polkagate/src/hooks/useApiWithChain2.ts +++ b/packages/extension-polkagate/src/hooks/useApiWithChain2.ts @@ -7,6 +7,7 @@ import type { Chain } from '@polkadot/extension-chains/types'; import { createWsEndpoints } from '@polkagate/apps-config'; import { useMemo } from 'react'; +import { useUserAddedEndpoint } from '../fullscreen/addNewChain/utils'; import getChainGenesisHash from '../util/getChainGenesisHash'; import { sanitizeChainName } from '../util/utils'; import useApi from './useApi'; @@ -15,14 +16,23 @@ const allEndpoints = createWsEndpoints(); export default function useApiWithChain2 (chain: Chain | null | undefined): ApiPromise | undefined { const genesisHash = useMemo(() => chain?.genesisHash || getChainGenesisHash(chain?.name), [chain]); + const userAddedEndpoint = useUserAddedEndpoint(genesisHash); const maybeEndpoint = useMemo(() => { const chainName = sanitizeChainName(chain?.name); - const endpoints = allEndpoints?.filter((e) => String(e.text)?.toLowerCase() === chainName?.toLowerCase() || String(e.info)?.toLowerCase() === chainName?.toLowerCase()); + const endpoints = allEndpoints?.filter((e) => + String(e.text)?.toLowerCase() === chainName?.toLowerCase() || + String(e.info)?.toLowerCase() === chainName?.toLowerCase() || + String(e.text)?.replace(/\s/g, '')?.toLowerCase() === chainName?.toLowerCase() + ); + + if (!endpoints?.length && userAddedEndpoint) { + return userAddedEndpoint[0].value as string; + } return endpoints?.length ? endpoints[0].value : undefined; - }, [chain?.name]); + }, [chain?.name, userAddedEndpoint]); const _api = useApi(undefined, undefined, maybeEndpoint, genesisHash); diff --git a/packages/extension-polkagate/src/hooks/useEndpoints.ts b/packages/extension-polkagate/src/hooks/useEndpoints.ts index 9b06318f1..d837d68c3 100644 --- a/packages/extension-polkagate/src/hooks/useEndpoints.ts +++ b/packages/extension-polkagate/src/hooks/useEndpoints.ts @@ -37,7 +37,9 @@ export function useEndpoints (genesisHash: string | null | undefined): DropdownO const endpoints = allEndpoints?.filter((e) => e.value && (String(e.info)?.toLowerCase() === chainName?.toLowerCase() || - String(e.text)?.toLowerCase()?.includes(chainName?.toLowerCase() ?? '')) + String(e.text)?.toLowerCase()?.includes(chainName?.toLowerCase() ?? '') || + String(e.text)?.replace(/\s/g, '')?.toLowerCase() === chainName?.toLowerCase() + ) ); if (!endpoints) { diff --git a/packages/extension-polkagate/src/hooks/useIdentity.ts b/packages/extension-polkagate/src/hooks/useIdentity.ts index b77943e2c..79d8257c1 100644 --- a/packages/extension-polkagate/src/hooks/useIdentity.ts +++ b/packages/extension-polkagate/src/hooks/useIdentity.ts @@ -28,7 +28,7 @@ export default function useIdentity (genesisHash: string | undefined, formatted: } const i = await api.query['identity']['identityOf'](accountId) as any; - const id = i.isSome ? i.unwrap()[0] as PalletIdentityRegistration : null; + const id = i.isSome ? i.unwrap()[0] || i.unwrap() as PalletIdentityRegistration : null; return id?.info ? { diff --git a/packages/extension-polkagate/src/hooks/useNativeTokenPrice.ts b/packages/extension-polkagate/src/hooks/useNativeTokenPrice.ts deleted file mode 100644 index a9070b893..000000000 --- a/packages/extension-polkagate/src/hooks/useNativeTokenPrice.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors -// SPDX-License-Identifier: Apache-2.0 -// @ts-nocheck - -/* eslint-disable @typescript-eslint/no-non-null-assertion */ - -import { useMemo } from 'react'; - -import { sanitizeChainName } from '../util/utils'; -import { useInfo, usePrices } from '.'; - -export default function useNativeTokenPrice(address: string): number | undefined | null { - const pricesInCurrency = usePrices(); - const { chainName } = useInfo(address); - - return useMemo((): number | undefined => { - const currentChainName = sanitizeChainName(chainName)?.toLocaleLowerCase(); - const currentAssetPrices = pricesInCurrency?.prices?.[currentChainName as string]; - const mayBeTestNetPrice = pricesInCurrency?.prices && !currentAssetPrices ? 0 : undefined; - - return currentAssetPrices?.value || mayBeTestNetPrice; - }, [chainName, pricesInCurrency?.prices]); -} diff --git a/packages/extension-polkagate/src/hooks/usePeopleChain.ts b/packages/extension-polkagate/src/hooks/usePeopleChain.ts index 7ae069340..aa8b222dc 100644 --- a/packages/extension-polkagate/src/hooks/usePeopleChain.ts +++ b/packages/extension-polkagate/src/hooks/usePeopleChain.ts @@ -6,6 +6,7 @@ import type { Chain } from '@polkadot/extension-chains/types'; import { createWsEndpoints } from '@polkagate/apps-config'; import { useMemo } from 'react'; +import { useUserAddedEndpoint } from '../fullscreen/addNewChain/utils'; import { KUSAMA_PEOPLE_GENESIS_HASH, PASEO_GENESIS_HASH, POLKADOT_PEOPLE_GENESIS_HASH, RELAY_CHAINS_NAMES, WESTEND_PEOPLE_GENESIS_HASH } from '../util/constants'; import getChain from '../util/getChain'; import { sanitizeChainName } from '../util/utils'; @@ -31,7 +32,7 @@ const getPeopleChainGenesisHash = (chainName: string | undefined) => { case 'Kusama': return KUSAMA_PEOPLE_GENESIS_HASH; case 'Polkadot': - return POLKADOT_PEOPLE_GENESIS_HASH; // should be changed to POLKADOT_PEOPLE_GENESIS_HASH in the future + return POLKADOT_PEOPLE_GENESIS_HASH; case 'Paseo': return PASEO_GENESIS_HASH; default: @@ -43,15 +44,17 @@ const allEndpoints = createWsEndpoints(); export default function usePeopleChain (address: string | undefined, genesisHash?: string): PeopleChainInfo { const { chain } = useInfo(address); + const userAddedEndpoint = useUserAddedEndpoint(genesisHash); + const _chain = chain || getChain(genesisHash); const _chainName = sanitizeChainName(_chain?.name); const peopleChainGenesisHash = getPeopleChainGenesisHash(_chainName); - const peopleChain = useMetadata(peopleChainGenesisHash, true); + const identityChain = useMetadata(peopleChainGenesisHash || genesisHash, true); const maybeEndpoint = useMemo(() => { - const peopleChainName = sanitizeChainName(peopleChain?.name as string); + const peopleChainName = sanitizeChainName(identityChain?.name); if (!peopleChainName) { return; @@ -59,11 +62,15 @@ export default function usePeopleChain (address: string | undefined, genesisHash const endpoints = allEndpoints?.filter((e) => String(e.text)?.toLowerCase() === peopleChainName?.toLowerCase() || String(e.info)?.toLowerCase() === peopleChainName?.toLowerCase()); + if (!endpoints?.length && userAddedEndpoint) { + return userAddedEndpoint[0].value as string; + } + return endpoints?.length ? endpoints[0].value : undefined; - }, [peopleChain]); + }, [identityChain?.name, userAddedEndpoint]); return { endpoint: maybeEndpoint, - peopleChain + peopleChain: identityChain }; } diff --git a/packages/extension-polkagate/src/hooks/useValidatorSuggestion.ts b/packages/extension-polkagate/src/hooks/useValidatorSuggestion.ts index ee0b143c2..77bb58505 100644 --- a/packages/extension-polkagate/src/hooks/useValidatorSuggestion.ts +++ b/packages/extension-polkagate/src/hooks/useValidatorSuggestion.ts @@ -64,7 +64,7 @@ export default function useValidatorSuggestion(address: string): ValidatorInfo[] // !v.validatorPrefs.blocked && // filter blocked validators Number(v.validatorPrefs.commission) !== 0 && // filter 0 commission validators, to exclude new and chilled validators (Number(v.validatorPrefs.commission) / (10 ** 7)) < DEFAULT_FILTERS.maxCommission.value && // filter high commission validators - v.exposure.others?.length && v.exposure.others.length < stakingConsts?.maxNominatorRewardedPerValidator// filter oversubscribed + v.exposure?.others?.length && v.exposure.others.length < stakingConsts?.maxNominatorRewardedPerValidator// filter oversubscribed // && v.exposure.others.length > stakingConsts?.maxNominatorRewardedPerValidator / 4 // filter validators with very low nominators ); const filtered2 = onLimitValidatorsPerOperator(filtered1, DEFAULT_FILTERS.limitOfValidatorsPerOperator.value); diff --git a/packages/extension-polkagate/src/partials/FullScreenChainSwitch.tsx b/packages/extension-polkagate/src/partials/FullScreenChainSwitch.tsx index fac6d067b..1cacfaf8d 100644 --- a/packages/extension-polkagate/src/partials/FullScreenChainSwitch.tsx +++ b/packages/extension-polkagate/src/partials/FullScreenChainSwitch.tsx @@ -122,7 +122,7 @@ function FullScreenChainSwitch ({ address, chains }: Props): React.ReactElement< const open = Boolean(anchorEl); const id = open ? 'simple-popover' : undefined; - + return ( diff --git a/packages/extension-polkagate/src/popup/send/index.tsx b/packages/extension-polkagate/src/popup/send/index.tsx index ede0f0fd3..3d12c8df4 100644 --- a/packages/extension-polkagate/src/popup/send/index.tsx +++ b/packages/extension-polkagate/src/popup/send/index.tsx @@ -40,7 +40,7 @@ export default function Send(): React.ReactElement { const [estimatedFee, setEstimatedFee] = useState(); const [maxFee, setMaxFee] = useState(); - const [recipientAddress, setRecipientAddress] = useState(); + const [recipientAddress, setRecipientAddress] = useState(); const recipientNameIfIsInExtension = useAccountName(recipientAddress as string); const recipientInfo = useIdentity(genesisHash, recipientAddress as string); const [amount, setAmount] = useState(); @@ -178,8 +178,8 @@ export default function Send(): React.ReactElement { title={t('From')} /> { +export default function SetPayeeController ({ address, buttonLabel, newSettings, set, setShow, setShowReview, settings, stakingConsts }: Props): React.ReactElement { const { t } = useTranslation(); const theme = useTheme(); const { api, chain, decimal, formatted, token } = useInfo(address); - const [controllerId, setControllerId] = useState(settings.controllerId); + const [controllerId, setControllerId] = useState< string | undefined | null>(settings.controllerId); const [rewardDestinationValue, setRewardDestinationValue] = useState<'Staked' | 'Others'>(settings.payee === 'Staked' ? 'Staked' : 'Others'); - const [rewardDestinationAccount, setRewardDestinationAccount] = useState(getPayee(settings)); + const [rewardDestinationAccount, setRewardDestinationAccount] = useState< string | null | undefined>(getPayee(settings)); const isSettingAtBonding = useMemo(() => !newSettings, [newSettings]); @@ -70,6 +68,7 @@ export default function SetPayeeController({ address, buttonLabel, newSettings, if (rewardDestinationAccount) { return { Account: rewardDestinationAccount }; } + return undefined; }, [controllerId, settings.controllerId, settings.stashId]); @@ -110,7 +109,7 @@ export default function SetPayeeController({ address, buttonLabel, newSettings, !setShowReview && setShow(false); // can be left open when settings accessed from home }, [controllerId, isSettingAtBonding, makePayee, rewardDestinationAccount, rewardDestinationValue, set, setShow, setShowReview, settings]); - const Warn = ({ text, style = {} }: { text: string, style?: SxProps }) => ( + const Warn = ({ style = {}, text }: { text: string, style?: SxProps }) => ( {needToSetControllerToStashID && @@ -161,8 +160,8 @@ export default function SetPayeeController({ address, buttonLabel, newSettings, {rewardDestinationValue === 'Others' && <> = { + alephzero: 'aleph-zero', nodle: 'nodle-network', parallel: 'parallel-finance', pendulum: 'pendulum-chain' }; export default async function getPrices (priceIds: string[], currencyCode = 'usd') { - console.log(' getting prices for:', priceIds.sort()); + console.log('getting prices for:', priceIds.sort()); - const revisedPriceIds = priceIds.map((item) => (EXTRA_PRICE_IDS[item] || item)); + const revisedPriceIds = priceIds.map((item) => (EXTRA_PRICE_IDS[item.toLocaleLowerCase()] || item)); const prices = await getReq(`https://api.coingecko.com/api/v3/simple/price?ids=${revisedPriceIds}&vs_currencies=${currencyCode}&include_24hr_change=true`, {}); diff --git a/packages/extension-polkagate/src/util/constants.tsx b/packages/extension-polkagate/src/util/constants.tsx index 4408be840..ece6bbed6 100644 --- a/packages/extension-polkagate/src/util/constants.tsx +++ b/packages/extension-polkagate/src/util/constants.tsx @@ -25,7 +25,6 @@ export const POLKAGATE_POOL_IDS: Record = { export const BALANCES_VALIDITY_PERIOD = 5 * 60 * 1000; // to show outdated balance in grey export const AUCTION_GRACE_PERIOD = 27000;// blocks -export const MAX_NOMINATIONS = 16; export const FLOATING_POINT_DIGIT = 4; export const BLOCK_RATE = 6; // sec export const DEFAULT_TOKEN_DECIMALS = 12; @@ -37,13 +36,12 @@ export const MAX_HISTORY_RECORD_TO_SHOW = 40; export const MAX_AMOUNT_LENGTH = 15; export const TIME_TO_SHAKE_ICON = 5000;// msec -export const CHAINS_WITH_BLACK_LOGO = ['statescan', 'Centrifuge', 'Centrifuge Chain', 'Kusama', 'Kusama Relay Chain', 'Pendulum', 'Pendulum chain', 'Zeitgeist', 'Westend Collectives']; +export const CHAINS_WITH_BLACK_LOGO = ['AlephZero', 'statescan', 'Centrifuge', 'Centrifuge Chain', 'Kusama', 'Kusama Relay Chain', 'Pendulum', 'Pendulum chain', 'Zeitgeist', 'Westend Collectives']; export const TOKENS_WITH_BLACK_LOGO = ['KSM', 'PEN', 'ZTG']; export const CHAINS_ON_POLKAHOLIC = ['Pendulum', 'Pendulum chain', 'Amplitude', 'Amplitude chain']; export const DISABLED_NETWORKS = ['3DP network', 'xx network', 'Polkadex Mainnet', 'Stafi', 'Peaq Network', 'Genshiro Network']; export const ACALA_GENESIS_HASH = '0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c'; - export const WESTMINT_GENESIS_HASH = '0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9'; export const STATEMINE_GENESIS_HASH = '0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a'; // KUSAMA ASSET HUB export const STATEMINT_GENESIS_HASH = '0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f'; @@ -53,6 +51,8 @@ export const POLKADOT_PEOPLE_GENESIS_HASH = '0x67fa177a097bfa18f77ea95ab56e9bcdf export const KUSAMA_PEOPLE_GENESIS_HASH = '0xc1af4cb4eb3918e5db15086c0cc5ec17fb334f728b7c65dd44bfe1e174ff8b3f'; export const WESTEND_PEOPLE_GENESIS_HASH = '0x1eb6fb0ba5187434de017a70cb84d4f47142df1d571d0ef9e7e1407f2b80b93c'; +export const ALEPH_ZERO_GENESIS_HASH = '0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e'; +export const ALEPH_ZERO_TESTNET_GENESIS_HASH = '0x05d5279c52c484cc80396535a316add7d47b1c5b9e0398dd1f584149341460c5'; /** relay chains info */ export const RELAY_CHAINS_NAMES = ['Polkadot', 'Kusama', 'Westend', 'Paseo']; @@ -81,7 +81,8 @@ export const TEST_NETS = [ WESTMINT_GENESIS_HASH, WESTEND_PEOPLE_GENESIS_HASH, PASEO_GENESIS_HASH, - PASEO_ASSET_HUB_GENESIS_HASH + PASEO_ASSET_HUB_GENESIS_HASH, + ALEPH_ZERO_TESTNET_GENESIS_HASH ]; export const PROXY_CHAINS = [ @@ -110,10 +111,9 @@ export const SOCIAL_RECOVERY_CHAINS = [ // used to enable/disable staking icon in account page export const STAKING_CHAINS = [ - POLKADOT_GENESIS_HASH, - KUSAMA_GENESIS_HASH, - WESTEND_GENESIS_HASH, - PASEO_GENESIS_HASH + ...RELAY_CHAINS_GENESISHASH, + ALEPH_ZERO_GENESIS_HASH, + ALEPH_ZERO_TESTNET_GENESIS_HASH ]; export const PEOPLE_CHAINS = ['Polkadot', 'Kusama', 'Westend', 'PolkadotPeople', 'KusamaPeople', 'WestendPeople']; diff --git a/packages/extension-polkagate/src/util/getLogo2.ts b/packages/extension-polkagate/src/util/getLogo2.ts index b0313815a..2a8afa05e 100644 --- a/packages/extension-polkagate/src/util/getLogo2.ts +++ b/packages/extension-polkagate/src/util/getLogo2.ts @@ -44,7 +44,7 @@ export default function getLogo2 (info: string | undefined | null | Chain, token let mayBeExternalLogo; const iconName = sanitizeChainName(chainNameFromGenesisHash || (info as Chain)?.name || (info as string))?.toLowerCase(); - const endpoint = endpoints.find((o) => o.info?.toLowerCase() === iconName); + const endpoint = endpoints.find(({ info, text }) => info?.toLowerCase() === iconName || text?.replace(/\s/g, '')?.toLowerCase() === iconName); if (!endpoint) { mayBeExternalLogo = Object diff --git a/packages/extension-polkagate/src/util/types.ts b/packages/extension-polkagate/src/util/types.ts index 5c3899911..ffb6cc7bf 100644 --- a/packages/extension-polkagate/src/util/types.ts +++ b/packages/extension-polkagate/src/util/types.ts @@ -796,9 +796,9 @@ export interface AlertContextType { export interface PayeeAccount { Account: string } export type Payee = 'Staked' | 'Controller' | 'Stash' | PayeeAccount; export interface SoloSettings { - controllerId?: AccountId | string | undefined, + controllerId?: string | undefined, payee: Payee, - stashId?: AccountId | string | undefined, + stashId?: string | undefined, } export interface DropdownOption { diff --git a/packages/extension-polkagate/src/util/workers/getStakingConsts.js b/packages/extension-polkagate/src/util/workers/getStakingConsts.js index f92645d17..6cf05e0b5 100644 --- a/packages/extension-polkagate/src/util/workers/getStakingConsts.js +++ b/packages/extension-polkagate/src/util/workers/getStakingConsts.js @@ -1,35 +1,40 @@ // Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors // SPDX-License-Identifier: Apache-2.0 - /* eslint-disable header/header */ - // @ts-nocheck - -import { MAX_NOMINATIONS } from '../constants'; import getApi from '../getApi.ts'; -async function getStakingConsts(endpoint) { +const MAX_NOMINATIONS = { + DOT: 16, + KSM: 24, + WND: 16, + TZER: 1, + AZERO: 1 +}; + +const DEFAULT_MAX_NOMINATIONS = 16; + +async function getStakingConsts (endpoint) { try { const api = await getApi(endpoint); const at = await api.rpc.chain.getFinalizedHead(); const apiAt = await api.at(at); - const maxNominations = apiAt.consts.staking.maxNominations?.toNumber() || MAX_NOMINATIONS; - // TODO: apiAt.consts.staking.maxNominatorRewardedPerValidator is deprecated + const token = api.registry.chainTokens[0]; + + const maxNominations = MAX_NOMINATIONS?.[token] || DEFAULT_MAX_NOMINATIONS; const maxNominatorRewardedPerValidator = (apiAt.consts.staking.maxNominatorRewardedPerValidator || apiAt.consts.staking.maxExposurePageSize).toNumber(); const existentialDeposit = apiAt.consts.balances.existentialDeposit.toString(); const bondingDuration = apiAt.consts.staking.bondingDuration.toNumber(); const sessionsPerEra = apiAt.consts.staking.sessionsPerEra.toNumber(); - const epochDuration = apiAt.consts.babe.epochDuration.toNumber(); - const expectedBlockTime = api.consts.babe.expectedBlockTime.toNumber(); + const epochDuration = apiAt.consts.babe ? apiAt.consts.babe.epochDuration.toNumber() : 0; + const expectedBlockTime = api.consts.babe ? api.consts.babe.expectedBlockTime.toNumber() : 0; const epochDurationInHours = epochDuration * expectedBlockTime / 3600000; // 1000 milSec * 60sec * 60min const [minNominatorBond, currentEraIndex] = await Promise.all([ apiAt.query.staking.minNominatorBond(), api.query.staking.currentEra() ]); - const token = api.registry.chainTokens[0]; - return { bondingDuration, eraIndex: Number(currentEraIndex?.toString(), '0'), diff --git a/packages/extension-polkagate/src/util/workers/getValidatorsInfo.js b/packages/extension-polkagate/src/util/workers/getValidatorsInfo.js index 4293b1ea7..f84743a25 100644 --- a/packages/extension-polkagate/src/util/workers/getValidatorsInfo.js +++ b/packages/extension-polkagate/src/util/workers/getValidatorsInfo.js @@ -1,13 +1,13 @@ // Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors // SPDX-License-Identifier: Apache-2.0 -// @ts-nocheck + /* eslint-disable header/header */ // @ts-nocheck import getApi from '../getApi.ts'; -async function getAllValidators(endpoint) { +async function getAllValidators (endpoint) { console.log('getting validators info from ', endpoint); try { diff --git a/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js b/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js index f35e31d5a..8a169dca7 100644 --- a/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js +++ b/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js @@ -13,7 +13,14 @@ export function getChainEndpoints (chainName, userAddedEndpoints) { const allEndpoints = createWsEndpoints(); let endpoints = allEndpoints - .filter((endpoint) => endpoint.info && endpoint.info.toLowerCase() === chainName.toLowerCase() && !endpoint.isDisabled && !endpoint?.isLightClient); + .filter((endpoint) => + endpoint.info && + ( + endpoint.info.toLowerCase() === chainName.toLowerCase() || + endpoint.text?.replace(/\s/g, '')?.toLowerCase() === chainName.toLowerCase() + ) && + !endpoint.isDisabled && !endpoint?.isLightClient + ); if (!endpoints.length && userAddedEndpoints) { const maybeEndpoint = Object.entries(userAddedEndpoints).find(([_, { chain }]) => chain?.replace(/\s/g, '')?.toLowerCase() === chainName.toLowerCase()); diff --git a/replacements/interfaces.js b/replacements/interfaces.js index 8033b9f1e..1bd14021a 100644 --- a/replacements/interfaces.js +++ b/replacements/interfaces.js @@ -10,7 +10,7 @@ function toExpanded(o) { n.slip44 = knownLedger[network]; n.hasLedgerSupport = !!n.slip44; // general items - n.genesisHash = knownGenesis[network] || []; + n.genesisHash = supportedGenesis[network] || []; n.icon = knownIcon[network] || 'substrate'; // filtering n.isTestnet = !!knownTestnet[network] || TESTNETS.includes(nameParts[nameParts.length - 1]); @@ -38,24 +38,17 @@ function sortNetworks(a, b) { : 1; } // added by PolkaGate -knownGenesis.westmint = [ - '0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9' -]; -knownGenesis.polkadotPeople = [ - '0x67fa177a097bfa18f77ea95ab56e9bcdfeb0e5b8a40e46298bb93e16b6fc5008' -]; -knownGenesis.westendPeople = [ - '0x1eb6fb0ba5187434de017a70cb84d4f47142df1d571d0ef9e7e1407f2b80b93c' -]; -knownGenesis.kusamaPeople = [ - '0xc1af4cb4eb3918e5db15086c0cc5ec17fb334f728b7c65dd44bfe1e174ff8b3f' -]; -knownGenesis.paseo = [ - '0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f' -]; -knownGenesis.paseoAssetHub = [ - '0x862ce2fa5abfdc3d29ead85a9472071efc69433b0128db1d6f009967fae87952' -]; +const supportedGenesis = { + ...knownGenesis, + westmint: ['0x67f9723393ef76214df0118c34bbbd3dbebc8ed46a10973a8c969d48fe7598c9'], + polkadotPeople: ['0x67fa177a097bfa18f77ea95ab56e9bcdfeb0e5b8a40e46298bb93e16b6fc5008'], + westendPeople: ['0x1eb6fb0ba5187434de017a70cb84d4f47142df1d571d0ef9e7e1407f2b80b93c'], + kusamaPeople: ['0xc1af4cb4eb3918e5db15086c0cc5ec17fb334f728b7c65dd44bfe1e174ff8b3f'], + paseo: ['0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f'], + paseoAssetHub: ['0x862ce2fa5abfdc3d29ead85a9472071efc69433b0128db1d6f009967fae87952'], + aleph: ['0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e'], + polkadexparachain: ['0x72f3bba34b1ecd532bccbed46701ad37c4ef329bfe86b7cf014ac06cb92ed47d'], +} const testnets = [{ "prefix": 42, @@ -143,8 +136,19 @@ const peopleChains = [ } ]; -knownSubstrate.push(...assetHubs, ...peopleChains, ...testnets); +const liveChains = [ + { + "prefix": 42, + "network": "aleph", + "displayName": "Aleph Zero", + "symbols": ["AZERO"], + "decimals": [12], + "standardAccount": "*25519", + "website": "https://alephZero.org" + } +]; +knownSubstrate.push(...assetHubs, ...peopleChains, ...testnets, ...liveChains); export const allNetworks = knownSubstrate.map(toExpanded); export const availableNetworks = allNetworks.filter(filterAvailable).sort(sortNetworks); export const selectableNetworks = availableNetworks.filter(filterSelectable); From d595eeedf9a2f3f385e8262bff884ddd85d360c9 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 1 Oct 2024 19:59:29 +0330 Subject: [PATCH 2/3] fix: check if fast unstake is available --- .../fullscreen/stake/partials/DisplayBalance.tsx | 13 +++++++++---- .../src/fullscreen/stake/solo/fastUnstake/index.tsx | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx b/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx index 59c4af4de..06299e029 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/partials/DisplayBalance.tsx @@ -68,9 +68,11 @@ export default function DisplayBalance ({ actions, address, amount, icons, isUns const { t } = useTranslation(); const { price } = useTokenPrice(address, 0); - const { decimal, token } = useInfo(address); + const { api, decimal, token } = useInfo(address); const [showUnstaking, setShowUnstaking] = useState(false); + const isFastUnstakeAvailable = api?.tx?.['fastUnstake']; + const triangleColor = useMemo(() => { switch (title) { case (t('Staked')): @@ -136,15 +138,18 @@ export default function DisplayBalance ({ actions, address, amount, icons, isUns } {icons?.map((_, index) => { const noValueToAct = (!amount || amount?.isZero()) && actions && actions[index] !== t('pending'); + const isFastUnstakeToBeDisabled = !isFastUnstakeAvailable && actions?.[index] === t('fast unstake'); + + const isDisabled = noValueToAct || isFastUnstakeToBeDisabled; return (actions && - + - + {actions[index]} diff --git a/packages/extension-polkagate/src/fullscreen/stake/solo/fastUnstake/index.tsx b/packages/extension-polkagate/src/fullscreen/stake/solo/fastUnstake/index.tsx index 60ecdb3a7..1ee54dbc2 100644 --- a/packages/extension-polkagate/src/fullscreen/stake/solo/fastUnstake/index.tsx +++ b/packages/extension-polkagate/src/fullscreen/stake/solo/fastUnstake/index.tsx @@ -16,7 +16,7 @@ import { DraggableModal } from '@polkadot/extension-polkagate/src/fullscreen/gov import WaitScreen from '@polkadot/extension-polkagate/src/fullscreen/governance/partials/WaitScreen'; import { getValue } from '@polkadot/extension-polkagate/src/popup/account/util'; import { amountToHuman } from '@polkadot/extension-polkagate/src/util/utils'; -import { BN, BN_MAX_INTEGER, BN_ONE } from '@polkadot/util'; +import { BN, BN_MAX_INTEGER, BN_ONE, BN_ZERO } from '@polkadot/util'; import { PButton, Progress, Warning } from '../../../../components'; import { useBalances, useInfo, useIsExposed, useStakingAccount, useStakingConsts, useTranslation } from '../../../../hooks'; @@ -48,7 +48,7 @@ export default function FastUnstake ({ address, setRefresh, setShow, show }: Pro const [inputs, setInputs] = useState(); const redeemable = useMemo(() => stakingAccount?.redeemable, [stakingAccount?.redeemable]); - const fastUnstakeDeposit = api && api.consts['fastUnstake']['deposit'] as unknown as BN; + const fastUnstakeDeposit = api && (api.consts['fastUnstake']?.['deposit'] as unknown as BN || BN_ZERO); const availableBalance = getValue('available', myBalances); const hasEnoughDeposit = fastUnstakeDeposit && stakingConsts && myBalances && estimatedFee && availableBalance ? new BN(fastUnstakeDeposit).add(estimatedFee).lt(availableBalance || BN_MAX_INTEGER) From ab04780eeb04b2888dfbff6b3149533769d6dcc7 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 1 Oct 2024 20:02:46 +0330 Subject: [PATCH 3/3] fix: type issues --- packages/extension-polkagate/src/util/getLogo2.ts | 2 +- .../src/util/workers/utils/getChainEndpoints.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/extension-polkagate/src/util/getLogo2.ts b/packages/extension-polkagate/src/util/getLogo2.ts index 2a8afa05e..103eb5e0b 100644 --- a/packages/extension-polkagate/src/util/getLogo2.ts +++ b/packages/extension-polkagate/src/util/getLogo2.ts @@ -44,7 +44,7 @@ export default function getLogo2 (info: string | undefined | null | Chain, token let mayBeExternalLogo; const iconName = sanitizeChainName(chainNameFromGenesisHash || (info as Chain)?.name || (info as string))?.toLowerCase(); - const endpoint = endpoints.find(({ info, text }) => info?.toLowerCase() === iconName || text?.replace(/\s/g, '')?.toLowerCase() === iconName); + const endpoint = endpoints.find(({ info, text }) => info?.toLowerCase() === iconName || (text as string)?.replace(/\s/g, '')?.toLowerCase() === iconName); if (!endpoint) { mayBeExternalLogo = Object diff --git a/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js b/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js index 8a169dca7..3b0cbb78f 100644 --- a/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js +++ b/packages/extension-polkagate/src/util/workers/utils/getChainEndpoints.js @@ -17,6 +17,7 @@ export function getChainEndpoints (chainName, userAddedEndpoints) { endpoint.info && ( endpoint.info.toLowerCase() === chainName.toLowerCase() || + //@ts-ignore endpoint.text?.replace(/\s/g, '')?.toLowerCase() === chainName.toLowerCase() ) && !endpoint.isDisabled && !endpoint?.isLightClient