Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support Aleph Zero #1576

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<Theme>;
setAddress: React.Dispatch<React.SetStateAction<string | AccountId | undefined | null>> | null;
setAddress?: React.Dispatch<React.SetStateAction<string | undefined | null>>;
ignoreAddress?: string
name?: string;
helperText?: string;
disabled?: boolean;
}

export default function AccountInputWithIdentity({ address, chain, disabled, helperText, ignoreAddress, label, name, setAddress, style }: Props): React.ReactElement<Props> {
export default function AccountInputWithIdentity ({ address, chain, disabled, helperText, ignoreAddress, label, name, setAddress, style }: Props): React.ReactElement<Props> {
const theme = useTheme();
const { t } = useTranslation();
const { hierarchy } = useContext(AccountContext);
Expand All @@ -39,9 +36,9 @@ export default function AccountInputWithIdentity({ address, chain, disabled, hel
return (
<Grid alignItems='flex-end' container justifyContent='space-between' sx={{ ...style }}>
<AddressInput
address={address as string}
address={address}
allAddresses={allAddresses}
chain={chain as any}
chain={chain}
disabled={disabled}
helperText={helperText}
label={label}
Expand All @@ -53,11 +50,11 @@ export default function AccountInputWithIdentity({ address, chain, disabled, hel
<Grid alignItems='center' container item sx={{ bgcolor: 'background.paper', border: 1, borderBottomLeftRadius: '5px', borderBottomRightRadius: '5px', borderColor: theme.palette.secondary.light, borderTop: 0, fontSize: '28px', fontWeight: 400, letterSpacing: '-0.015em', maxWidth: '100%', mt: '-4px', pl: '7px', pt: '8px' }} xs={12}>
<Identity
api={api}
chain={chain as any}
chain={chain}
formatted={address}
identiconSize={31}
name={name}
style={{ maxWidth: '100%', width: 'fit-content', height: '51px' }}
style={{ height: '51px', maxWidth: '100%', width: 'fit-content' }}
/>
</Grid>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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<boolean>(false);
Expand Down Expand Up @@ -96,7 +96,7 @@ export default function DisplayBalance ({ actions, address, amount, icons, isUns
<Typography fontSize='18px' fontWeight={400} width='28%'>
{title}
</Typography>
<Grid alignItems='center' container item width='34%'>
<Grid alignItems='center' container item width='36%'>
<Grid item sx={{ fontSize: '22px', fontWeight: 600 }}>
<ShowBalance
balance={amount}
Expand All @@ -116,7 +116,7 @@ export default function DisplayBalance ({ actions, address, amount, icons, isUns
skeletonHeight={20}
/>
</Grid>
<Grid container item justifyContent='flex-end' width='38%'>
<Grid container item justifyContent='flex-end' width='36%'>
{isUnstaking &&
<Grid alignItems='center' container direction='column' item justifyContent='center' minWidth='96px' sx={{ ml: '10px', width: 'fit-content' }}>
<ArrowForwardIosRoundedIcon
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// 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 { AccountStakingInfo, BalancesInfo } from '@polkadot/extension-polkagate/src/util/types';
import type { BN } from '@polkadot/util';

import { faArrowRotateLeft, faBolt, faCircleDown, faClockFour, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';
import { Boy as BoyIcon } from '@mui/icons-material';
import { Grid } from '@mui/material';
import React, { useCallback, useMemo } from 'react';
import { useParams } from 'react-router';

import type { AccountStakingInfo, BalancesInfo } from '@polkadot/extension-polkagate/src/util/types';
import { BN } from '@polkadot/util';

import { useAvailableToSoloStake, useStakingRewardDestinationAddress, useStakingRewards, useTranslation, useUnstakingAmount, useUnSupportedNetwork } from '../../../hooks';
import { STAKING_CHAINS } from '../../../util/constants';
import Bread from '../../partials/Bread';
Expand All @@ -33,7 +32,7 @@ interface Props {
balances: BalancesInfo | undefined
}

export default function StakedSolo({ balances, refresh, setRefresh, setShow, stakingAccount }: Props): React.ReactElement {
export default function StakedSolo ({ balances, refresh, setRefresh, setShow, stakingAccount }: Props): React.ReactElement {
const { t } = useTranslation();
const { address } = useParams<{ address: string }>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid casting 'stashId' using 'as unknown as string'; use '.toString()' method instead

Casting parsedStakingAccount.stashId with as unknown as string may conceal underlying type issues and reduce type safety. It's clearer and more type-safe to convert stashId to a string using the .toString() method.

Apply this diff to fix the issue:

-        return ({ payee, stashId: parsedStakingAccount.stashId as unknown as string });
+        return ({ payee, stashId: parsedStakingAccount.stashId.toString() });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return ({ payee, stashId: parsedStakingAccount.stashId as unknown as string });
return ({ payee, stashId: parsedStakingAccount.stashId.toString() });

}, [stakingAccount]);

const getOptionLabel = useCallback((s: SoloSettings): 'Staked' | 'Others' => s?.payee === 'Staked' ? 'Staked' : 'Others', []);
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -19,27 +20,27 @@ interface Props {
set: React.Dispatch<React.SetStateAction<Payee | undefined>>
}

export default function SetPayee({ address, set, title }: Props): React.ReactElement<Props> {
export default function SetPayee ({ address, set, title }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const theme = useTheme();
const { chain, decimal, formatted, token } = useInfo(address);

const stakingConsts = useStakingConsts(address);

const [rewardDestinationValue, setRewardDestinationValue] = useState<'Staked' | 'Others'>('Staked');
const [rewardDestinationAccount, setRewardDestinationAccount] = useState<string>();
const [rewardDestinationAccount, setRewardDestinationAccount] = useState<string | null>();

const ED = useMemo(() => stakingConsts?.existentialDeposit && decimal && amountToHuman(stakingConsts.existentialDeposit, decimal), [decimal, stakingConsts?.existentialDeposit]);

const onSelectionMethodChange = useCallback((event: React.ChangeEvent<HTMLInputElement>, value: 'Staked' | 'Others'): void => {
setRewardDestinationValue(value);
const onSelectionMethodChange = useCallback((_event: React.ChangeEvent<HTMLInputElement>, 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';
}
Expand All @@ -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 }) => (
<Grid container justifyContent='center' sx={style}>
<Warning
fontWeight={400}
Expand All @@ -91,7 +92,7 @@ export default function SetPayee({ address, set, title }: Props): React.ReactEle
: <Skeleton
animation='wave'
height={20}
sx={{ display: 'inline-block', fontWeight: 'bold', transform: 'none', width: '200px', mt: '10px' }}
sx={{ display: 'inline-block', fontWeight: 'bold', mt: '10px', transform: 'none', width: '200px' }}
/>
}
</FormControl>
Expand All @@ -100,7 +101,7 @@ export default function SetPayee({ address, set, title }: Props): React.ReactEle
<>
<AccountInputWithIdentity
address={rewardDestinationAccount}
chain={chain as any}
chain={chain}
label={t('Specific account')}
setAddress={setRewardDestinationAccount}
style={{ pt: '25px', px: '15px' }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function ShowValidator ({ accountInfo, allInOneRow = true, api, chain, check, de
{t('Staked')}:
</Grid>
<Grid fontSize='14px' fontWeight={400} item pl='3px'>
{isHexToBn(v.exposure.total.toString()).gt(BN_ZERO)
{!!v.exposure && isHexToBn(v.exposure.total.toString()).gt(BN_ZERO)
? <ShowBalance
api={api}
balance={v.exposure.total}
Expand All @@ -89,7 +89,17 @@ function ShowValidator ({ accountInfo, allInOneRow = true, api, chain, check, de
skeletonWidth={50}
token={token}
/>
: t('waiting')
: !v.exposure && v.stakingLedger.total && isHexToBn(v.stakingLedger.total.toString()).gt(BN_ZERO)
? <ShowBalance
api={api}
balance={isHexToBn(v.stakingLedger.total.toString())}
decimal={decimal}
decimalPoint={1}
height={15}
skeletonWidth={50}
token={token}
/>
: t('waiting')
}
</Grid>
</Grid>
Expand All @@ -108,7 +118,7 @@ function ShowValidator ({ accountInfo, allInOneRow = true, api, chain, check, de
{t('Nominators')}:
</Grid>
<Grid fontSize='14px' fontWeight={400} item lineHeight='22px' pl='3px'>
{v.exposure.others?.length || t('N/A')}
{v.exposure?.others?.length || t('N/A')}
</Grid>
</Grid>
<Grid alignItems='center' container item justifyContent='flex-end' sx={{ lineHeight: '23px', pl: '2px' }} width='fit-content'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]);

Expand Down
1 change: 0 additions & 1 deletion packages/extension-polkagate/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
14 changes: 12 additions & 2 deletions packages/extension-polkagate/src/hooks/useApiWithChain2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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()
);
Comment on lines +24 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential issue with converting undefined to string

Using String(e.text) and String(e.info) may result in the string "undefined" when e.text or e.info are undefined, leading to incorrect comparisons. This could cause valid endpoints to be missed in the filter.

Consider updating the filter logic to handle undefined values safely:

const endpoints = allEndpoints?.filter((e) =>
  e.text?.toLowerCase() === chainName?.toLowerCase() ||
  e.info?.toLowerCase() === chainName?.toLowerCase() ||
  e.text?.replace(/\s/g, '').toLowerCase() === chainName?.toLowerCase()
);


if (!endpoints?.length && userAddedEndpoint) {
return userAddedEndpoint[0].value as string;
}
Comment on lines +30 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure 'userAddedEndpoint' is not empty before accessing

When userAddedEndpoint is defined but empty, accessing userAddedEndpoint[0] may lead to an undefined value or runtime error. To prevent this, check that the array has at least one element:

if (!endpoints?.length && userAddedEndpoint?.length > 0) {
  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);

Expand Down
4 changes: 3 additions & 1 deletion packages/extension-polkagate/src/hooks/useEndpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion packages/extension-polkagate/src/hooks/useIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix potential type casting issue by adding parentheses

The type assertion may not apply as intended due to operator precedence. To ensure that the type casting applies to the entire expression (i.unwrap()[0] || i.unwrap()), please add parentheses around it.

Apply this diff to fix the issue:

-    const id = i.isSome ? i.unwrap()[0] || i.unwrap() as PalletIdentityRegistration : null;
+    const id = i.isSome ? (i.unwrap()[0] || i.unwrap()) as PalletIdentityRegistration : null;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const id = i.isSome ? i.unwrap()[0] || i.unwrap() as PalletIdentityRegistration : null;
const id = i.isSome ? (i.unwrap()[0] || i.unwrap()) as PalletIdentityRegistration : null;


return id?.info
? {
Expand Down
23 changes: 0 additions & 23 deletions packages/extension-polkagate/src/hooks/useNativeTokenPrice.ts

This file was deleted.

Loading
Loading