From 78c8300dd1046a261dfda888f9d5ac4d0c916e20 Mon Sep 17 00:00:00 2001 From: Ross Bulat Date: Sun, 11 Feb 2024 12:51:53 +0700 Subject: [PATCH] feat(refactor): nominatons to BalancesController --- src/contexts/Balances/defaults.ts | 1 + src/contexts/Balances/index.tsx | 2 + src/contexts/Balances/types.ts | 9 +++++ src/contexts/Bonded/defaults.ts | 7 +--- src/contexts/Bonded/index.tsx | 39 +------------------ src/contexts/Bonded/types.ts | 9 ----- src/contexts/Pools/ActivePool/types.ts | 2 +- src/contexts/Staking/index.tsx | 6 +-- src/hooks/useActiveBalances/index.tsx | 14 +++++++ src/hooks/useActivePools/types.ts | 2 +- src/hooks/useNominationStatus/index.tsx | 10 ++--- src/library/Graphs/PayoutBar.tsx | 2 +- src/library/Graphs/PayoutLine.tsx | 2 +- src/library/Nominations/index.tsx | 6 +-- src/modals/StopNominations/index.tsx | 8 ++-- src/modals/Unstake/index.tsx | 14 ++++--- .../Active/Status/NominationStatus.tsx | 7 +--- src/pages/Nominate/Active/index.tsx | 6 +-- src/static/ActivePoolsController/index.ts | 2 +- src/static/ActivePoolsController/types.ts | 2 +- src/static/BalancesController/defaults.ts | 7 +++- src/static/BalancesController/index.ts | 30 ++++++++++++++ src/static/SyncController/types.ts | 1 - 23 files changed, 100 insertions(+), 88 deletions(-) diff --git a/src/contexts/Balances/defaults.ts b/src/contexts/Balances/defaults.ts index 3628ebbf1b..792a24a3a9 100644 --- a/src/contexts/Balances/defaults.ts +++ b/src/contexts/Balances/defaults.ts @@ -18,4 +18,5 @@ export const defaultBalancesContext: BalancesContextInterface = { getLedger: (source) => defaultLedger, getPayee: (address) => defaultPayee, getPoolMembership: (address) => null, + getNominations: (address) => [], }; diff --git a/src/contexts/Balances/index.tsx b/src/contexts/Balances/index.tsx index 4c3b6c56bd..e5705435d1 100644 --- a/src/contexts/Balances/index.tsx +++ b/src/contexts/Balances/index.tsx @@ -35,6 +35,7 @@ export const BalancesProvider = ({ children }: { children: ReactNode }) => { getLedger, getPayee, getPoolMembership, + getNominations, } = useActiveBalances({ accounts: [activeAccount, activeProxy, controller], }); @@ -96,6 +97,7 @@ export const BalancesProvider = ({ children }: { children: ReactNode }) => { getLedger, getPayee, getPoolMembership, + getNominations, }} > {children} diff --git a/src/contexts/Balances/types.ts b/src/contexts/Balances/types.ts index 9f5c47d81e..793de5b90e 100644 --- a/src/contexts/Balances/types.ts +++ b/src/contexts/Balances/types.ts @@ -14,6 +14,7 @@ export interface BalancesContextInterface { getLedger: (source: ActiveLedgerSource) => Ledger; getPayee: (address: MaybeAddress) => PayeeConfig; getPoolMembership: (address: MaybeAddress) => PoolMembership | null; + getNominations: (address: MaybeAddress) => Targets; } export type ActiveBalancesState = Record; @@ -23,6 +24,7 @@ export interface ActiveBalance { balances: Balances; payee: PayeeConfig; poolMembership: PoolMembership; + nominations: Nominations; } export interface Balances { @@ -67,3 +69,10 @@ export interface Ledger { export type ActiveLedgerSource = { [key in 'stash' | 'key']?: MaybeAddress; }; + +export interface Nominations { + targets: Targets; + submittedIn: string | number; +} + +export type Targets = string[]; diff --git a/src/contexts/Bonded/defaults.ts b/src/contexts/Bonded/defaults.ts index 73aa456aa7..87f4069e9f 100644 --- a/src/contexts/Bonded/defaults.ts +++ b/src/contexts/Bonded/defaults.ts @@ -2,10 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* eslint-disable @typescript-eslint/no-unused-vars */ -import type { - BondedContextInterface, - Nominations, -} from 'contexts/Bonded/types'; +import type { Nominations } from 'contexts/Balances/types'; +import type { BondedContextInterface } from 'contexts/Bonded/types'; export const nominations: Nominations = { targets: [], @@ -14,6 +12,5 @@ export const nominations: Nominations = { export const defaultBondedContext: BondedContextInterface = { getBondedAccount: (address) => null, - getAccountNominations: (address) => [], bondedAccounts: [], }; diff --git a/src/contexts/Bonded/index.tsx b/src/contexts/Bonded/index.tsx index 4f613574a0..5bb9090d2f 100644 --- a/src/contexts/Bonded/index.tsx +++ b/src/contexts/Bonded/index.tsx @@ -19,8 +19,6 @@ import { useOtherAccounts } from 'contexts/Connect/OtherAccounts'; import { useExternalAccounts } from 'contexts/Connect/ExternalAccounts'; import * as defaults from './defaults'; import type { BondedAccount, BondedContextInterface } from './types'; -import { useActiveAccounts } from 'contexts/ActiveAccounts'; -import { SyncController } from 'static/SyncController'; export const BondedContext = createContext( defaults.defaultBondedContext @@ -32,7 +30,6 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { const { network } = useNetwork(); const { api, isReady } = useApi(); const { accounts } = useImportedAccounts(); - const { activeAccount } = useActiveAccounts(); const { addExternalAccount } = useExternalAccounts(); const { addOrReplaceOtherAccount } = useOtherAccounts(); @@ -66,15 +63,6 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { const added = addedTo(accounts, bondedAccountsRef.current, ['address']); if (added.length) { - // If the current active account is being subscribed to, dispatch the `nominator` syncing - // event. - const activeAccountInAdded = added.find( - ({ address }) => address === activeAccount - ); - if (activeAccountInAdded) { - SyncController.dispatch('nominator', 'syncing'); - } - // Subscribe to all newly added accounts bonded and nominator status. added.map(({ address }) => subscribeToBondedAccount(address)); } @@ -100,11 +88,8 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { } const unsub = await api.queryMulti( - [ - [api.query.staking.bonded, address], - [api.query.staking.nominators, address], - ], - async ([controller, nominations]) => { + [[api.query.staking.bonded, address]], + async ([controller]) => { const newAccount: BondedAccount = { address, }; @@ -127,27 +112,12 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { } } - // set account nominations. - const newNominations = nominations.unwrapOr(null); - newAccount.nominations = - newNominations === null - ? defaults.nominations - : { - targets: newNominations.targets.toHuman(), - submittedIn: newNominations.submittedIn.toHuman(), - }; - // remove stale account if it's already in list. const newBonded = Object.values(bondedAccountsRef.current) .filter((a) => a.address !== address) .concat(newAccount); setStateWithRef(newBonded, setBondedAccounts, bondedAccountsRef); - - // If this callback was syncing the active account, mark `nominator` syncing as complete. - if (address === activeAccount) { - SyncController.dispatch('nominator', 'complete'); - } } ); @@ -159,10 +129,6 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { bondedAccountsRef.current.find((a) => a.address === address)?.bonded || null; - const getAccountNominations = (address: MaybeAddress) => - bondedAccountsRef.current.find((a) => a.address === address)?.nominations - ?.targets || []; - // Handle accounts sync on connected accounts change. useEffectIgnoreInitial(() => { if (isReady) { @@ -182,7 +148,6 @@ export const BondedProvider = ({ children }: { children: ReactNode }) => { diff --git a/src/contexts/Bonded/types.ts b/src/contexts/Bonded/types.ts index 4b4fc417fe..a7fe6aef8b 100644 --- a/src/contexts/Bonded/types.ts +++ b/src/contexts/Bonded/types.ts @@ -6,18 +6,9 @@ import type { MaybeAddress } from 'types'; export interface BondedAccount { address?: string; bonded?: string; - nominations?: Nominations; } -export interface Nominations { - targets: Targets; - submittedIn: string | number; -} - -export type Targets = string[]; - export interface BondedContextInterface { getBondedAccount: (address: MaybeAddress) => string | null; - getAccountNominations: (address: MaybeAddress) => Targets; bondedAccounts: BondedAccount[]; } diff --git a/src/contexts/Pools/ActivePool/types.ts b/src/contexts/Pools/ActivePool/types.ts index 9090e7651c..5f9be92bc2 100644 --- a/src/contexts/Pools/ActivePool/types.ts +++ b/src/contexts/Pools/ActivePool/types.ts @@ -4,8 +4,8 @@ import type BigNumber from 'bignumber.js'; import type { PoolAddresses } from '../BondedPools/types'; import type { MaybeAddress } from '@polkadot-cloud/react/types'; -import type { Nominations } from 'contexts/Bonded/types'; import type { Identity, SuperIdentity } from 'contexts/Validators/types'; +import type { Nominations } from 'contexts/Balances/types'; export interface ActivePoolContextState { isBonding: () => boolean; diff --git a/src/contexts/Staking/index.tsx b/src/contexts/Staking/index.tsx index a73b8cbc5f..6844dc84e7 100644 --- a/src/contexts/Staking/index.tsx +++ b/src/contexts/Staking/index.tsx @@ -44,11 +44,11 @@ export const StakingContext = createContext( export const useStaking = () => useContext(StakingContext); export const StakingProvider = ({ children }: { children: ReactNode }) => { - const { getLedger } = useBalances(); + const { getBondedAccount } = useBonded(); const { networkData, network } = useNetwork(); + const { getLedger, getNominations } = useBalances(); const { accounts: connectAccounts } = useImportedAccounts(); const { activeAccount, getActiveAccount } = useActiveAccounts(); - const { getBondedAccount, getAccountNominations } = useBonded(); const { isReady, api, apiStatus, consts, activeEra, isPagedRewardsActive } = useApi(); const { maxExposurePageSize } = consts; @@ -224,7 +224,7 @@ export const StakingProvider = ({ children }: { children: ReactNode }) => { hasController() && getLedger({ stash: activeAccount }).unlocking.length; // Helper function to determine whether the active account is nominating, or is yet to start. - const isNominating = () => getAccountNominations(activeAccount).length > 0; + const isNominating = () => getNominations(activeAccount).length > 0; // Helper function to determine whether the active account is nominating, or is yet to start. const inSetup = () => diff --git a/src/hooks/useActiveBalances/index.tsx b/src/hooks/useActiveBalances/index.tsx index 219fc8bd77..2e187ef5b2 100644 --- a/src/hooks/useActiveBalances/index.tsx +++ b/src/hooks/useActiveBalances/index.tsx @@ -10,6 +10,7 @@ import type { BalanceLock, BalanceLocks, Ledger, + Targets, } from 'contexts/Balances/types'; import { useNetwork } from 'contexts/Network'; import { useEffect, useRef, useState } from 'react'; @@ -126,6 +127,18 @@ export const useActiveBalances = ({ return new BigNumber(0); }; + // Gets an active balance's nominations. + const getNominations = (address: MaybeAddress): Targets => { + if (address) { + const maybeNominations = + activeBalances[address]?.nominations?.targets || []; + if (maybeNominations) { + return maybeNominations; + } + } + return []; + }; + // Handle new account balance event being reported from `BalancesController`. const newAccountBalancesCallback = (e: Event) => { if ( @@ -191,5 +204,6 @@ export const useActiveBalances = ({ getPayee, getPoolMembership, getEdReserved, + getNominations, }; }; diff --git a/src/hooks/useActivePools/types.ts b/src/hooks/useActivePools/types.ts index a71b1b08b8..8a705426ce 100644 --- a/src/hooks/useActivePools/types.ts +++ b/src/hooks/useActivePools/types.ts @@ -1,7 +1,7 @@ // Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import type { Nominations } from 'contexts/Bonded/types'; +import type { Nominations } from 'contexts/Balances/types'; import type { ActivePool } from 'contexts/Pools/ActivePool/types'; import type { DetailActivePool } from 'static/ActivePoolsController/types'; diff --git a/src/hooks/useNominationStatus/index.tsx b/src/hooks/useNominationStatus/index.tsx index e30dce588b..12b0584871 100644 --- a/src/hooks/useNominationStatus/index.tsx +++ b/src/hooks/useNominationStatus/index.tsx @@ -4,13 +4,13 @@ import { planckToUnit } from '@polkadot-cloud/utils'; import BigNumber from 'bignumber.js'; import { useTranslation } from 'react-i18next'; -import { useBonded } from 'contexts/Bonded'; import { useActivePool } from 'contexts/Pools/ActivePool'; import { useStaking } from 'contexts/Staking'; import { useValidators } from 'contexts/Validators/ValidatorEntries'; import type { AnyJson, BondFor, MaybeAddress } from 'types'; import { useNetwork } from 'contexts/Network'; import { useSyncing } from 'hooks/useSyncing'; +import { useBalances } from 'contexts/Balances'; export const useNominationStatus = () => { const { t } = useTranslation(); @@ -20,19 +20,19 @@ export const useNominationStatus = () => { const { inSetup, eraStakers, - getNominationsStatusFromTargets, getLowestRewardFromStaker, + getNominationsStatusFromTargets, } = useStaking(); const { validators } = useValidators(); - const { getAccountNominations } = useBonded(); - const { activePoolNominations } = useActivePool(); + const { getNominations } = useBalances(); const { syncing } = useSyncing(['era-stakers']); + const { activePoolNominations } = useActivePool(); // Utility to get an account's nominees alongside their status. const getNominationSetStatus = (who: MaybeAddress, type: BondFor) => { const nominations = type === 'nominator' - ? getAccountNominations(who) + ? getNominations(who) : activePoolNominations?.targets ?? []; return getNominationsStatusFromTargets(who, nominations); diff --git a/src/library/Graphs/PayoutBar.tsx b/src/library/Graphs/PayoutBar.tsx index 89b0d77697..4e11a1aa53 100644 --- a/src/library/Graphs/PayoutBar.tsx +++ b/src/library/Graphs/PayoutBar.tsx @@ -48,7 +48,7 @@ export const PayoutBar = ({ const { mode } = useTheme(); const { inSetup } = useStaking(); const { getPoolMembership } = useBalances(); - const { syncing } = useSyncing(['nominator']); + const { syncing } = useSyncing(['balances']); const { activeAccount } = useActiveAccounts(); const membership = getPoolMembership(activeAccount); diff --git a/src/library/Graphs/PayoutLine.tsx b/src/library/Graphs/PayoutLine.tsx index 9676ea7deb..e3ac3b725f 100644 --- a/src/library/Graphs/PayoutLine.tsx +++ b/src/library/Graphs/PayoutLine.tsx @@ -49,7 +49,7 @@ export const PayoutLine = ({ const { t } = useTranslation('library'); const { mode } = useTheme(); const { inSetup } = useStaking(); - const { syncing } = useSyncing(['nominator']); + const { syncing } = useSyncing(['balances']); const { getPoolMembership } = useBalances(); const { activeAccount } = useActiveAccounts(); diff --git a/src/library/Nominations/index.tsx b/src/library/Nominations/index.tsx index e9ba205ca7..00a840558f 100644 --- a/src/library/Nominations/index.tsx +++ b/src/library/Nominations/index.tsx @@ -4,7 +4,6 @@ import { faCog, faStopCircle } from '@fortawesome/free-solid-svg-icons'; import { ButtonHelp, ButtonPrimary } from '@polkadot-cloud/react'; import { useTranslation } from 'react-i18next'; -import { useBonded } from 'contexts/Bonded'; import { useHelp } from 'contexts/Help'; import { useActivePool } from 'contexts/Pools/ActivePool'; import { useStaking } from 'contexts/Staking'; @@ -19,6 +18,7 @@ import { useImportedAccounts } from 'contexts/Connect/ImportedAccounts'; import { ListStatusHeader } from 'library/List'; import { Wrapper } from './Wrapper'; import { useSyncing } from 'hooks/useSyncing'; +import { useBalances } from 'contexts/Balances'; export const Nominations = ({ bondFor, @@ -41,10 +41,10 @@ export const Nominations = ({ canvas: { openCanvas }, } = useOverlay(); const { syncing } = useSyncing('*'); + const { getNominations } = useBalances(); const { isFastUnstaking } = useUnstaking(); const { formatWithPrefs } = useValidators(); const { activeAccount } = useActiveAccounts(); - const { getAccountNominations } = useBonded(); const { isReadOnlyAccount } = useImportedAccounts(); // Determine if pool or nominator. @@ -53,7 +53,7 @@ export const Nominations = ({ // Derive nominations from `bondFor` type. const nominated = bondFor === 'nominator' - ? formatWithPrefs(getAccountNominations(activeAccount)) + ? formatWithPrefs(getNominations(activeAccount)) : activePoolNominations ? formatWithPrefs(activePoolNominations.targets) : []; diff --git a/src/modals/StopNominations/index.tsx b/src/modals/StopNominations/index.tsx index 4596ed1fb1..a620e00e4b 100644 --- a/src/modals/StopNominations/index.tsx +++ b/src/modals/StopNominations/index.tsx @@ -19,14 +19,16 @@ import { SubmitTx } from 'library/SubmitTx'; import { useTxMeta } from 'contexts/TxMeta'; import { useOverlay } from '@polkadot-cloud/react/hooks'; import { useActiveAccounts } from 'contexts/ActiveAccounts'; +import { useBalances } from 'contexts/Balances'; export const StopNominations = () => { const { t } = useTranslation('modals'); const { api } = useApi(); - const { activeAccount } = useActiveAccounts(); const { notEnoughFunds } = useTxMeta(); + const { getBondedAccount } = useBonded(); + const { getNominations } = useBalances(); + const { activeAccount } = useActiveAccounts(); const { getSignerWarnings } = useSignerWarnings(); - const { getBondedAccount, getAccountNominations } = useBonded(); const { setModalStatus, config: { options }, @@ -44,7 +46,7 @@ export const StopNominations = () => { const nominations = isPool === true ? activePoolNominations?.targets || [] - : getAccountNominations(activeAccount); + : getNominations(activeAccount); // valid to submit transaction const [valid, setValid] = useState(false); diff --git a/src/modals/Unstake/index.tsx b/src/modals/Unstake/index.tsx index 167c59fb89..00ad3e78de 100644 --- a/src/modals/Unstake/index.tsx +++ b/src/modals/Unstake/index.tsx @@ -26,24 +26,26 @@ import { useTxMeta } from 'contexts/TxMeta'; import { useOverlay } from '@polkadot-cloud/react/hooks'; import { useNetwork } from 'contexts/Network'; import { useActiveAccounts } from 'contexts/ActiveAccounts'; +import { useBalances } from 'contexts/Balances'; export const Unstake = () => { const { t } = useTranslation('modals'); - const { newBatchCall } = useBatchCall(); - const { notEnoughFunds } = useTxMeta(); - const { activeAccount } = useActiveAccounts(); - const { api, consts } = useApi(); const { networkData: { units, unit }, } = useNetwork(); + const { api, consts } = useApi(); + const { notEnoughFunds } = useTxMeta(); + const { newBatchCall } = useBatchCall(); + const { getBondedAccount } = useBonded(); + const { getNominations } = useBalances(); + const { activeAccount } = useActiveAccounts(); const { erasToSeconds } = useErasToTimeLeft(); const { getSignerWarnings } = useSignerWarnings(); const { getTransferOptions } = useTransferOptions(); const { setModalStatus, setModalResize } = useOverlay().modal; - const { getBondedAccount, getAccountNominations } = useBonded(); const controller = getBondedAccount(activeAccount); - const nominations = getAccountNominations(activeAccount); + const nominations = getNominations(activeAccount); const { bondDuration } = consts; const allTransferOptions = getTransferOptions(activeAccount); const { active } = allTransferOptions.nominate; diff --git a/src/pages/Nominate/Active/Status/NominationStatus.tsx b/src/pages/Nominate/Active/Status/NominationStatus.tsx index 2bf626e221..3886f9c723 100644 --- a/src/pages/Nominate/Active/Status/NominationStatus.tsx +++ b/src/pages/Nominate/Active/Status/NominationStatus.tsx @@ -31,12 +31,7 @@ export const NominationStatus = ({ const { inSetup } = useStaking(); const { openModal } = useOverlay().modal; const { getBondedAccount } = useBonded(); - const { syncing } = useSyncing([ - 'initialization', - 'era-stakers', - 'balances', - 'nominator', - ]); + const { syncing } = useSyncing(['initialization', 'era-stakers', 'balances']); const { isReady, networkMetrics: { fastUnstakeErasToCheckPerBlock }, diff --git a/src/pages/Nominate/Active/index.tsx b/src/pages/Nominate/Active/index.tsx index 5dd1d67001..a22ea30758 100644 --- a/src/pages/Nominate/Active/index.tsx +++ b/src/pages/Nominate/Active/index.tsx @@ -28,20 +28,20 @@ import { MinimumNominatorBondStat } from './Stats/MinimumNominatorBond'; import { Status } from './Status'; import { UnstakePrompts } from './UnstakePrompts'; import { useSyncing } from 'hooks/useSyncing'; -import { useBonded } from 'contexts/Bonded'; +import { useBalances } from 'contexts/Balances'; export const Active = () => { const { t } = useTranslation(); const { openHelp } = useHelp(); const { inSetup } = useStaking(); const { syncing } = useSyncing('*'); + const { getNominations } = useBalances(); const { openCanvas } = useOverlay().canvas; const { isFastUnstaking } = useUnstaking(); const { formatWithPrefs } = useValidators(); - const { getAccountNominations } = useBonded(); const { activeAccount } = useActiveAccounts(); - const nominated = formatWithPrefs(getAccountNominations(activeAccount)); + const nominated = formatWithPrefs(getNominations(activeAccount)); const ROW_HEIGHT = 220; return ( diff --git a/src/static/ActivePoolsController/index.ts b/src/static/ActivePoolsController/index.ts index 32357f98bc..2e87ac693a 100644 --- a/src/static/ActivePoolsController/index.ts +++ b/src/static/ActivePoolsController/index.ts @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only import type { VoidFn } from '@polkadot/api/types'; -import type { Nominations } from 'contexts/Bonded/types'; import { defaultPoolNominations } from 'contexts/Pools/ActivePool/defaults'; import type { ActivePool, PoolRoles } from 'contexts/Pools/ActivePool/types'; import { APIController } from 'static/APIController'; @@ -10,6 +9,7 @@ import { IdentitiesController } from 'static/IdentitiesController'; import type { AnyApi } from 'types'; import type { ActivePoolItem, DetailActivePool } from './types'; import { SyncController } from 'static/SyncController'; +import type { Nominations } from 'contexts/Balances/types'; export class ActivePoolsController { // ------------------------------------------------------ diff --git a/src/static/ActivePoolsController/types.ts b/src/static/ActivePoolsController/types.ts index 100c85b98d..f3fe5c5df4 100644 --- a/src/static/ActivePoolsController/types.ts +++ b/src/static/ActivePoolsController/types.ts @@ -1,7 +1,7 @@ // Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors // SPDX-License-Identifier: GPL-3.0-only -import type { Nominations } from 'contexts/Bonded/types'; +import type { Nominations } from 'contexts/Balances/types'; import type { ActivePool } from 'contexts/Pools/ActivePool/types'; export interface DetailActivePool { diff --git a/src/static/BalancesController/defaults.ts b/src/static/BalancesController/defaults.ts index 8ac3783e05..dd5f2bdfd2 100644 --- a/src/static/BalancesController/defaults.ts +++ b/src/static/BalancesController/defaults.ts @@ -3,7 +3,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import BigNumber from 'bignumber.js'; -import type { Balance, Ledger } from 'contexts/Balances/types'; +import type { Balance, Ledger, Nominations } from 'contexts/Balances/types'; import type { PayeeConfig } from 'contexts/Setup/types'; export const defaultBalance: Balance = { @@ -23,3 +23,8 @@ export const defaultPayee: PayeeConfig = { destination: 'Staked', account: null, }; + +export const defaultNominations: Nominations = { + targets: [], + submittedIn: 0, +}; diff --git a/src/static/BalancesController/index.ts b/src/static/BalancesController/index.ts index 52800e1d59..46e173ba70 100644 --- a/src/static/BalancesController/index.ts +++ b/src/static/BalancesController/index.ts @@ -10,11 +10,13 @@ import type { ActiveBalance, Balances, Ledger, + Nominations, UnlockChunkRaw, } from 'contexts/Balances/types'; import type { PayeeConfig, PayeeOptions } from 'contexts/Setup/types'; import type { PoolMembership } from 'contexts/Pools/types'; import { SyncController } from 'static/SyncController'; +import { defaultNominations } from './defaults'; export class BalancesController { // ------------------------------------------------------ @@ -36,6 +38,9 @@ export class BalancesController { // Account pool membership and claim commissions, populated by api callbacks. static poolMemberships: Record = {}; + // Account nominations, populated by api callbacks. + static nominations: Record = {}; + // Unsubscribe objects. static _unsubs: Record = {}; @@ -74,6 +79,7 @@ export class BalancesController { [api.query.staking.payee, address], [api.query.nominationPools.poolMembers, address], [api.query.nominationPools.claimPermissions, address], + [api.query.staking.nominators, address], ], async ([ ledgerResult, @@ -82,6 +88,7 @@ export class BalancesController { payeeResult, poolMembersResult, claimPermissionsResult, + nominatorsResult, ]): Promise => { this.handleLedgerCallback(address, ledgerResult); this.handleAccountCallback(address, accountResult, locksResult); @@ -94,6 +101,8 @@ export class BalancesController { claimPermissionsResult ); + this.handleNominations(address, nominatorsResult); + // Send updated account state back to UI. document.dispatchEvent( new CustomEvent('new-account-balance', { @@ -103,6 +112,7 @@ export class BalancesController { balances: this.balances[address], payee: this.payees[address], poolMembership: this.poolMemberships[address], + nominations: this.nominations[address], }, }) ); @@ -126,6 +136,7 @@ export class BalancesController { delete this.balances[account]; delete this.payees[account]; delete this.poolMemberships[account]; + delete this.nominations[account]; }); // Remove removed accounts from class. this.accounts = this.accounts.filter( @@ -256,12 +267,29 @@ export class BalancesController { }; }; + // Handle nominations callback. + static handleNominations = ( + address: string, + nominatorsResult: AnyApi + ): void => { + const nominators = nominatorsResult.unwrapOr(null); + + this.nominations[address] = + nominators === null + ? defaultNominations + : { + targets: nominators.targets.toHuman(), + submittedIn: nominators.submittedIn.toHuman(), + }; + }; + // Gets an `ActiveBalance` from class members for the given address if it exists. static getAccountBalances = (address: string): ActiveBalance | undefined => { const ledger = this.ledgers[address]; const balances = this.balances[address]; const payee = this.payees[address]; const poolMembership = this.poolMemberships[address]; + const nominations = this.nominations[address]; // Account info has not synced yet. Note that `ledger` may not exist and therefore cannot be // tested. @@ -273,6 +301,7 @@ export class BalancesController { balances, payee, poolMembership, + nominations, }; }; @@ -290,6 +319,7 @@ export class BalancesController { this.balances = {}; this.payees = {}; this.poolMemberships = {}; + this.nominations = {}; this._unsubs = {}; }; diff --git a/src/static/SyncController/types.ts b/src/static/SyncController/types.ts index 4fc13b07e7..915aa8b624 100644 --- a/src/static/SyncController/types.ts +++ b/src/static/SyncController/types.ts @@ -5,7 +5,6 @@ export type SyncID = | 'initialization' | 'balances' | 'era-stakers' - | 'nominator' | 'active-pools'; export interface SyncEvent {