Skip to content

feat: add support for pool migration #1702

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

Merged
merged 5 commits into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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,26 +1,27 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

/* eslint-disable react/jsx-max-props-per-line */
// @ts-nocheck

import type { DeriveBalancesAll } from '@polkadot/api-derive/types';
import type { BalancesInfo } from '@polkadot/extension-polkagate/util/types';
import type { BN } from '@polkadot/util';
import type { Lock } from '../../../../hooks/useAccountLocks';

import { Grid, Skeleton, Typography } from '@mui/material';
import { Grid, Typography } from '@mui/material';
import React from 'react';

import { BN, BN_MAX_INTEGER } from '@polkadot/util';
import { BN_MAX_INTEGER } from '@polkadot/util';

import { useCurrentBlockNumber, useDecimal, useToken, useTranslation } from '../../../../hooks';
import { Lock } from '../../../../hooks/useAccountLocks';
import { amountToHuman, remainingTime } from '../../../../util/utils';

interface Props {
address: string | undefined;
accountLocks: Lock[] | undefined
}

export function getAlreadyLockedValue(allBalances: DeriveBalancesAll | undefined): BN | undefined {
export function getAlreadyLockedValue (allBalances: BalancesInfo | undefined): BN | undefined {
const LOCKS_ORDERED = ['pyconvot', 'democrac', 'phrelect'];
const sortedLocks = allBalances?.lockedBreakdown
// first sort by amount, so greatest value first
Expand All @@ -30,6 +31,7 @@ export function getAlreadyLockedValue(allBalances: DeriveBalancesAll | undefined
// then sort by the type of lock (we try to find relevant)
.sort((a, b): number => {
if (!a.id.eq(b.id)) {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < LOCKS_ORDERED.length; i++) {
const lockName = LOCKS_ORDERED[i];

Expand All @@ -48,7 +50,7 @@ export function getAlreadyLockedValue(allBalances: DeriveBalancesAll | undefined
return sortedLocks?.[0] || allBalances?.lockedBalance;
}

function AlreadyLockedTooltipText({ accountLocks, address }: Props): React.ReactElement {
function AlreadyLockedTooltipText ({ accountLocks, address }: Props): React.ReactElement {
const { t } = useTranslation();
const currentBlock = useCurrentBlockNumber(address);
const token = useToken(address);
Expand Down Expand Up @@ -80,7 +82,7 @@ function AlreadyLockedTooltipText({ accountLocks, address }: Props): React.React
{currentBlock && accountLocks?.map((lock, index) => (
<React.Fragment key={index}>
<Grid item xs={2.5}>
{lock.refId.toNumber()}
{lock.refId?.toNumber()}
</Grid>
<Grid item xs={3.6}>
{amountToHuman(lock.total, decimal)} {token}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

/* eslint-disable react/jsx-max-props-per-line */
Expand Down Expand Up @@ -76,7 +76,7 @@ export default function Review ({ address, api, chain, depositToPay, depositValu

useEffect(() => {
formatted && api?.derive.balances?.all(formatted).then((b) => {
setBalances(b as BalancesInfo);
setBalances(b as unknown as BalancesInfo);
});
}, [api, formatted]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type React from 'react';
import type { Balance } from '@polkadot/types/interfaces';
//@ts-ignore
import type { FrameSystemAccountInfo } from '@polkadot/types/lookup';
import type { HexString } from '@polkadot/util/types';
Expand Down Expand Up @@ -42,6 +43,8 @@ export default function useNativeAssetBalances (address: string | undefined, ref
// some chains such as PARALLEL does not support this call hence BN_ZERO is set for them
const frozenBalance = systemBalance?.frozen || BN_ZERO;

const votingBalance = api.createType('Balance', allBalances.freeBalance.add(allBalances.reservedBalance)) as unknown as Balance;

setNewBalances({
ED,
assetId: isFetchingNativeTokenOfAssetHub ? NATIVE_TOKEN_ASSET_ID_ON_ASSETHUB : NATIVE_TOKEN_ASSET_ID,
Expand All @@ -53,7 +56,8 @@ export default function useNativeAssetBalances (address: string | undefined, ref
genesisHash: api.genesisHash.toString(),
pooledBalance: balances?.pooledBalance, // fill from saved balance it exists, it will be updated
soloTotal: stakingAccount?.stakingLedger?.total as unknown as BN,
token
token,
votingBalance // since api derive does not updated after pools migration
});
setRefresh?.(false);
isFetching.fetching[String(formatted)]['balances'] = false;
Expand Down
29 changes: 23 additions & 6 deletions packages/extension-polkagate/src/hooks/useReservedDetails.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

// @ts-nocheck
Expand All @@ -13,18 +13,24 @@ import { useCallback, useEffect, useMemo, useState } from 'react';

import { BN_ZERO } from '@polkadot/util';

import { PROXY_CHAINS } from '../util/constants';
import { MIGRATED_NOMINATION_POOLS_CHAINS, PROXY_CHAINS } from '../util/constants';
import useActiveRecoveries from './useActiveRecoveries';
import { useInfo } from '.';
import { useAccountAssets, useInfo } from '.';

type Item = 'identity' | 'proxy' | 'bounty' | 'recovery' | 'referenda' | 'index' | 'society' | 'multisig' | 'preimage';
type Item = 'identity' | 'proxy' | 'bounty' | 'recovery' | 'referenda' | 'index' | 'society' | 'multisig' | 'preimage' | 'pooledBalance';
export type Reserved = { [key in Item]?: Balance };

export default function useReservedDetails (address: string | undefined): Reserved {
const { api, formatted, genesisHash } = useInfo(address);
const activeRecoveries = useActiveRecoveries(api);
const accountAssets = useAccountAssets(address);

const [reserved, setReserved] = useState<Reserved>({});

const maybePooledBalance = useMemo(() =>
accountAssets?.find((balance) => balance.genesisHash === genesisHash)?.pooledBalance
, [accountAssets, genesisHash]);

const activeLost = useMemo(() =>
activeRecoveries && formatted
? activeRecoveries.filter((active) => active.lost === String(formatted)).at(-1) ?? null
Expand Down Expand Up @@ -274,10 +280,21 @@ export default function useReservedDetails (address: string | undefined): Reserv
}
}).catch(console.error);
}

/** handle pooleBalance as reserved */
if (maybePooledBalance && MIGRATED_NOMINATION_POOLS_CHAINS.includes(genesisHash)) {
if (!maybePooledBalance.isZero()) {
setReserved((prev) => {
prev.pooledBalance = toBalance(maybePooledBalance);

return prev;
});
}
}
} catch (e) {
console.error('Fatal error while fetching reserved details:', e)
console.error('Fatal error while fetching reserved details:', e);
}
}, [activeLost?.deposit, api, formatted, genesisHash, toBalance]);
}, [activeLost?.deposit, api, formatted, genesisHash, maybePooledBalance, toBalance]);

useEffect(() => {
setReserved({});
Expand Down
9 changes: 7 additions & 2 deletions packages/extension-polkagate/src/popup/account/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

/**
Expand All @@ -10,6 +10,8 @@ import type { BalancesInfo } from '../../util/types';

import { BN, BN_ZERO, bnMax } from '@polkadot/util';

import { MIGRATED_NOMINATION_POOLS_CHAINS } from '../../util/constants';

function isEmptyObject (obj: object): boolean {
return Object.keys(obj).length === 0;
}
Expand All @@ -22,8 +24,11 @@ export const getValue = (type: string, balances: BalancesInfo | null | undefined
switch (type.toLocaleLowerCase()) {
case ('total'):
case ('total balance'):
// eslint-disable-next-line no-case-declarations
const isPoolsMigrated = MIGRATED_NOMINATION_POOLS_CHAINS.includes(balances.genesisHash);

return balances?.freeBalance && balances.reservedBalance
? new BN(balances.freeBalance).add(new BN(balances.reservedBalance)).add(balances?.pooledBalance ? new BN(balances.pooledBalance) : BN_ZERO)
? new BN(balances.freeBalance).add(new BN(balances.reservedBalance)).add((balances?.pooledBalance && !isPoolsMigrated) ? new BN(balances.pooledBalance) : BN_ZERO)
: new BN(balances?.totalBalance || 0);
case ('pooled balance'):
case ('pool stake'):
Expand Down
9 changes: 8 additions & 1 deletion packages/extension-polkagate/src/popup/home/news.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

/* eslint-disable sort-keys */
Expand All @@ -9,6 +9,13 @@ export interface News {
}

export const news: News[] = [
{
version: '0.34.1',
notes: [
'Added support for pool migration, allowing users to vote on governance using their staked funds in pools on Kusama.',
'PolkaGate is getting a complete new look, so stay tuned for the upcoming update!'
]
},
{
version: '0.34.0',
notes: [
Expand Down
5 changes: 3 additions & 2 deletions packages/extension-polkagate/src/util/constants.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { ProxyTypes } from './types';
Expand Down Expand Up @@ -53,7 +53,6 @@ export const POLKADOT_PEOPLE_GENESIS_HASH = '0x67fa177a097bfa18f77ea95ab56e9bcdf
export const KUSAMA_PEOPLE_GENESIS_HASH = '0xc1af4cb4eb3918e5db15086c0cc5ec17fb334f728b7c65dd44bfe1e174ff8b3f';
export const WESTEND_PEOPLE_GENESIS_HASH = '0x1eb6fb0ba5187434de017a70cb84d4f47142df1d571d0ef9e7e1407f2b80b93c';


/** relay chains info */
export const RELAY_CHAINS_NAMES = ['Polkadot', 'Kusama', 'Westend', 'Paseo'];

Expand All @@ -62,6 +61,8 @@ export const KUSAMA_GENESIS_HASH = '0xb0a8d493285c2df73290dfb7e61f870f17b4180119
export const WESTEND_GENESIS_HASH = '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e';
export const PASEO_GENESIS_HASH = '0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f';

export const MIGRATED_NOMINATION_POOLS_CHAINS = [WESTEND_GENESIS_HASH, KUSAMA_GENESIS_HASH];

export const RELAY_CHAINS_GENESISHASH = [
POLKADOT_GENESIS_HASH,
KUSAMA_GENESIS_HASH,
Expand Down
5 changes: 4 additions & 1 deletion packages/extension-polkagate/src/util/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

/* eslint-disable @typescript-eslint/consistent-indexed-object-style */

import type { LinkOption } from '@polkagate/apps-config/endpoints/types';
import type React from 'react';
import type { ApiPromise } from '@polkadot/api';
Expand Down Expand Up @@ -683,6 +685,7 @@ export interface BalancesInfo extends DeriveBalancesAll {
decimal: number;
genesisHash: string;
pooledBalance?: BN;
votingBalance: Balance;
frozenBalance: BN;
soloTotal?: BN;
token: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { NATIVE_TOKEN_ASSET_ID, TEST_NETS } from '../../constants';
import { BN_ZERO } from '@polkadot/util';

import { MIGRATED_NOMINATION_POOLS_CHAINS, NATIVE_TOKEN_ASSET_ID, TEST_NETS } from '../../constants';
import { getPriceIdByChainName } from '../../utils';
import { balancify, closeWebsockets } from '../utils';
import { getBalances } from './getBalances.js';
Expand All @@ -23,8 +25,9 @@ export async function getAssetOnRelayChain (addresses, chainName, userAddedEndpo
}

balanceInfo.forEach(({ address, balances, pooledBalance, soloTotal }) => {
const totalBalance = balances.freeBalance.add(balances.reservedBalance).add(pooledBalance);
const genesisHash = api.genesisHash.toString();
const isMigrated = MIGRATED_NOMINATION_POOLS_CHAINS.includes(genesisHash);
const totalBalance = balances.freeBalance.add(balances.reservedBalance).add(isMigrated ? BN_ZERO : pooledBalance);

const priceId = TEST_NETS.includes(genesisHash)
? undefined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// Copyright 2019-2025 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

// @ts-nocheck
import { BN_ZERO } from '@polkadot/util';


export function balancify (balances) {
const base = {
Expand All @@ -14,7 +16,8 @@ export function balancify (balances) {
vestedClaimable: String(balances.vestedClaimable),
vestingLocked: String(balances.vestingLocked),
vestingTotal: String(balances.vestingTotal),
votingBalance: String(balances.votingBalance)
// votingBalance: String(balances.votingBalance)
votingBalance: String(balances.free.add(balances?.reserved || BN_ZERO)) // after pool migration the voting balance returned fro api is not correct
};

if (balances.soloTotal) {
Expand Down
Loading