// Copyright 2017-2024 @polkadot/test-supports authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { DeriveBalancesAll, DeriveStakingAccount } from '@polkadot/api-derive/types'; import type { Accounts } from '@polkadot/react-hooks/ctx/types'; import type { UseAccountInfo } from '@polkadot/react-hooks/types'; import type { KeyringJson$Meta } from '@polkadot/ui-keyring/types'; import { BN } from '@polkadot/util'; import { balanceOf } from '../creation/balance.js'; import { makeStakingLedger } from '../creation/staking.js'; export interface Account { balance: DeriveBalancesAll, info: UseAccountInfo, staking: DeriveStakingAccount } export type AccountsMap = Record; export type Override = { [P in keyof T]?: T[P]; } /** * Test inputs structure */ export interface AccountOverrides { meta?: Override; balance?: Override; staking?: Override; info?: Override; } export const emptyAccounts: Accounts = { allAccounts: [], allAccountsHex: [], areAccountsLoaded: true, hasAccounts: false, isAccount: () => true }; // here it's extremely hard to reconstruct the entire DeriveBalancesAll upfront, so we incrementally add properties // instead along the way; thus the need to tell the tsc we know what we are doing here export const defaultBalanceAccount = { accountNonce: new BN(1), additional: [], availableBalance: balanceOf(0), freeBalance: balanceOf(0), lockedBalance: balanceOf(0), lockedBreakdown: [], namedReserves: [], reservedBalance: balanceOf(0) } as unknown as DeriveBalancesAll; // here it's extremely hard to reconstruct the entire DeriveStakingAccount upfront, // so we set just the properties that we use in page-accounts export const defaultStakingAccount = { nextSessionIds: [], nominators: [], redeemable: balanceOf(0), sessionIds: [], stakingLedger: makeStakingLedger(0), unlocking: [ { remainingEras: new BN('1000000000'), value: balanceOf(0) }, { remainingEras: new BN('2000000000'), value: balanceOf(0) }, { remainingEras: new BN('3000000000'), value: balanceOf(0) } ] } as unknown as DeriveStakingAccount; export const defaultMeta: KeyringJson$Meta = {}; export const defaultAccountInfo = { flags: {}, identity: { email: 'user@email.com', isExistent: true, judgements: [] }, tags: [] } as unknown as UseAccountInfo; class MockAccountHooks { public useAccounts: Accounts = emptyAccounts; public accountsMap: AccountsMap = {}; public nonce: BN = new BN(1); public setAccounts (accounts: [string, AccountOverrides][]): void { this.useAccounts = { allAccounts: accounts.map(([address]) => address), allAccountsHex: [], areAccountsLoaded: true, hasAccounts: accounts && accounts.length !== 0, isAccount: () => true }; for (const [address, props] of accounts) { const staking = { ...defaultStakingAccount }; const meta = { ...defaultMeta }; const balance = { ...defaultBalanceAccount }; const info = { ...defaultAccountInfo }; Object .entries(props.meta || meta) .forEach(([key, value]) => { (meta as Record)[key] = value; }); Object .entries(props.balance || balance) .forEach(([key, value]) => { (balance as Record)[key] = value; }); Object .entries(props.staking || staking) .forEach(([key, value]) => { (staking as Record)[key] = value; }); Object .entries(props.info || info) .forEach(([key, value]) => { (info as Record)[key] = value; }); this.accountsMap[address] = { balance, info, staking }; } } } export const mockAccountHooks = new MockAccountHooks();