diff --git a/src/contexts/Connect/ImportedAccounts/index.tsx b/src/contexts/Connect/ImportedAccounts/index.tsx index 62c7d2a2c5..79d799e7d3 100644 --- a/src/contexts/Connect/ImportedAccounts/index.tsx +++ b/src/contexts/Connect/ImportedAccounts/index.tsx @@ -4,7 +4,10 @@ import type { ReactNode } from 'react'; import { createContext, useCallback, useContext } from 'react'; import type { MaybeAddress } from 'types'; -import type { ExternalAccount } from '@polkadot-cloud/react/types'; +import type { + ExternalAccount, + ImportedAccount, +} from '@polkadot-cloud/react/types'; import { ManualSigners } from 'consts'; import { useEffectIgnoreInitial, @@ -33,13 +36,31 @@ export const ImportedAccountsProvider = ({ const { extensionAccounts } = useExtensionAccounts(); const allAccounts = extensionAccounts.concat(otherAccounts); + // Stringify account addresses and account names to determine if they have changed. Ignore other properties including `signer` and `source`. + const shallowAccountStringify = (accounts: ImportedAccount[]) => { + const sorted = accounts.sort((a, b) => { + if (a.address < b.address) { + return -1; + } + if (a.address > b.address) { + return 1; + } + return 0; + }); + return JSON.stringify( + sorted.map((account) => [account.address, account.name]) + ); + }; + + const allAccountsStringified = shallowAccountStringify(allAccounts); + // Gets an account from `allAccounts`. // // Caches the function when imported accounts update. const getAccount = useCallback( (who: MaybeAddress) => allAccounts.find(({ address }) => address === who) || null, - [allAccounts] + [allAccountsStringified] ); // Checks if an address is a read-only account. @@ -54,7 +75,7 @@ export const ImportedAccountsProvider = ({ } return false; }, - [allAccounts] + [allAccountsStringified] ); // Checks whether an account can sign transactions. @@ -66,7 +87,7 @@ export const ImportedAccountsProvider = ({ (account) => account.address === address && account.source !== 'external' ) !== undefined, - [allAccounts] + [allAccountsStringified] ); // Checks whether an account needs manual signing. @@ -80,7 +101,7 @@ export const ImportedAccountsProvider = ({ allAccounts.find( (a) => a.address === address && ManualSigners.includes(a.source) ) !== undefined, - [allAccounts] + [allAccountsStringified] ); // Keep accounts in sync with `BalancesController`. @@ -88,7 +109,7 @@ export const ImportedAccountsProvider = ({ if (isReady) { BalancesController.syncAccounts(allAccounts.map((a) => a.address)); } - }, [isReady, allAccounts]); + }, [isReady, allAccountsStringified]); return ( { setStateWithRef('syncing', setSynced, syncedRef); handlePoolSubscriptions(); } - }, [network, isReady, syncedRef.current]); + }, [network, isReady, synced]); // re-calculate pending rewards when membership changes useEffectIgnoreInitial(() => { diff --git a/src/contexts/Pools/PoolMemberships/index.tsx b/src/contexts/Pools/PoolMemberships/index.tsx index 80cd9961de..90e1801ee6 100644 --- a/src/contexts/Pools/PoolMemberships/index.tsx +++ b/src/contexts/Pools/PoolMemberships/index.tsx @@ -34,8 +34,8 @@ export const PoolMembershipsProvider = ({ const { t } = useTranslation('base'); const { network } = useNetwork(); const { api, isReady } = useApi(); + const { accounts } = useImportedAccounts(); const { activeAccount } = useActiveAccounts(); - const { accounts: connectAccounts } = useImportedAccounts(); // Stores pool memberships for the imported accounts. const [poolMemberships, setPoolMemberships] = useState([]); @@ -44,31 +44,13 @@ export const PoolMembershipsProvider = ({ // Stores pool membership unsubs. const unsubs = useRef([]); - useEffectIgnoreInitial(() => { - if (isReady) { - (() => { - setStateWithRef([], setPoolMemberships, poolMembershipsRef); - unsubAll(); - getPoolMemberships(); - })(); - } - }, [network, isReady, connectAccounts]); - // subscribe to account pool memberships const getPoolMemberships = async () => { Promise.all( - connectAccounts.map(({ address }) => subscribeToPoolMembership(address)) + accounts.map(({ address }) => subscribeToPoolMembership(address)) ); }; - // unsubscribe from pool memberships on unmount - useEffect( - () => () => { - unsubAll(); - }, - [] - ); - // unsubscribe from all pool memberships const unsubAll = () => { Object.values(unsubs.current).forEach((v: Fn) => v()); @@ -183,6 +165,37 @@ export const PoolMembershipsProvider = ({ }, ]; + // Reset and re-sync pool memberships on network change. + // re-sync pool memberships when accounts update. + useEffectIgnoreInitial(() => { + if (isReady) { + (() => { + // NOTE: resetting memberships here. + setStateWithRef([], setPoolMemberships, poolMembershipsRef); + unsubAll(); + getPoolMemberships(); + })(); + } + }, [network, isReady]); + + // re-sync pool memberships when accounts update. + useEffectIgnoreInitial(() => { + if (isReady) { + (() => { + unsubAll(); + getPoolMemberships(); + })(); + } + }, [isReady, accounts]); + + // Unsubscribe from pool memberships on unmount. + useEffect( + () => () => { + unsubAll(); + }, + [] + ); + return (