@pezkuwi/api-derive 16.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/build/accounts/accountId.d.ts +17 -0
- package/build/accounts/flags.d.ts +29 -0
- package/build/accounts/idAndIndex.d.ts +15 -0
- package/build/accounts/idToIndex.d.ts +16 -0
- package/build/accounts/identity.d.ts +48 -0
- package/build/accounts/index.d.ts +8 -0
- package/build/accounts/indexToId.d.ts +15 -0
- package/build/accounts/indexes.d.ts +16 -0
- package/build/accounts/info.d.ts +18 -0
- package/build/accounts/types.d.ts +39 -0
- package/build/alliance/index.d.ts +70 -0
- package/build/augment.d.ts +1 -0
- package/build/bagsList/get.d.ts +12 -0
- package/build/bagsList/getExpanded.d.ts +16 -0
- package/build/bagsList/index.d.ts +3 -0
- package/build/bagsList/listNodes.d.ts +9 -0
- package/build/bagsList/types.d.ts +13 -0
- package/build/bagsList/util.d.ts +2 -0
- package/build/balances/account.d.ts +17 -0
- package/build/balances/all.d.ts +20 -0
- package/build/balances/index.d.ts +20 -0
- package/build/balances/types.d.ts +69 -0
- package/build/balances/votingBalances.d.ts +15 -0
- package/build/bounties/bounties.d.ts +12 -0
- package/build/bounties/helpers/filterBountyProposals.d.ts +2 -0
- package/build/bounties/index.d.ts +1 -0
- package/build/bundle.d.ts +9 -0
- package/build/chain/bestNumber.d.ts +11 -0
- package/build/chain/bestNumberFinalized.d.ts +12 -0
- package/build/chain/bestNumberLag.d.ts +15 -0
- package/build/chain/getBlock.d.ts +15 -0
- package/build/chain/getBlockByNumber.d.ts +16 -0
- package/build/chain/getHeader.d.ts +16 -0
- package/build/chain/index.d.ts +10 -0
- package/build/chain/subscribeFinalizedBlocks.d.ts +14 -0
- package/build/chain/subscribeFinalizedHeads.d.ts +22 -0
- package/build/chain/subscribeNewBlocks.d.ts +14 -0
- package/build/chain/subscribeNewHeads.d.ts +15 -0
- package/build/chain/util.d.ts +9 -0
- package/build/collective/helpers.d.ts +6 -0
- package/build/collective/index.d.ts +3 -0
- package/build/collective/members.d.ts +2 -0
- package/build/collective/prime.d.ts +2 -0
- package/build/collective/proposals.d.ts +6 -0
- package/build/collective/types.d.ts +19 -0
- package/build/contracts/fees.d.ts +14 -0
- package/build/contracts/index.d.ts +1 -0
- package/build/council/index.d.ts +72 -0
- package/build/council/types.d.ts +6 -0
- package/build/council/votes.d.ts +11 -0
- package/build/council/votesOf.d.ts +16 -0
- package/build/crowdloan/childKey.d.ts +15 -0
- package/build/crowdloan/contributions.d.ts +14 -0
- package/build/crowdloan/index.d.ts +3 -0
- package/build/crowdloan/ownContributions.d.ts +15 -0
- package/build/crowdloan/types.d.ts +6 -0
- package/build/crowdloan/util.d.ts +10 -0
- package/build/democracy/dispatchQueue.d.ts +12 -0
- package/build/democracy/index.d.ts +11 -0
- package/build/democracy/locks.d.ts +14 -0
- package/build/democracy/nextExternal.d.ts +12 -0
- package/build/democracy/preimages.d.ts +24 -0
- package/build/democracy/proposals.d.ts +12 -0
- package/build/democracy/referendumIds.d.ts +12 -0
- package/build/democracy/referendums.d.ts +11 -0
- package/build/democracy/referendumsActive.d.ts +12 -0
- package/build/democracy/referendumsFinished.d.ts +15 -0
- package/build/democracy/referendumsInfo.d.ts +23 -0
- package/build/democracy/sqrtElectorate.d.ts +13 -0
- package/build/democracy/types.d.ts +70 -0
- package/build/democracy/util.d.ts +18 -0
- package/build/derive.d.ts +52 -0
- package/build/elections/index.d.ts +1 -0
- package/build/elections/info.d.ts +14 -0
- package/build/elections/types.d.ts +18 -0
- package/build/imOnline/index.d.ts +1 -0
- package/build/imOnline/receivedHeartbeats.d.ts +13 -0
- package/build/index.d.ts +2 -0
- package/build/membership/index.d.ts +70 -0
- package/build/packageDetect.d.ts +1 -0
- package/build/packageInfo.d.ts +6 -0
- package/build/parachains/index.d.ts +2 -0
- package/build/parachains/info.d.ts +19 -0
- package/build/parachains/overview.d.ts +15 -0
- package/build/parachains/types.d.ts +38 -0
- package/build/parachains/util.d.ts +3 -0
- package/build/session/index.d.ts +3 -0
- package/build/session/indexes.d.ts +15 -0
- package/build/session/info.d.ts +13 -0
- package/build/session/progress.d.ts +47 -0
- package/build/session/types.d.ts +19 -0
- package/build/society/candidates.d.ts +12 -0
- package/build/society/index.d.ts +4 -0
- package/build/society/info.d.ts +12 -0
- package/build/society/member.d.ts +14 -0
- package/build/society/members.d.ts +14 -0
- package/build/society/types.d.ts +27 -0
- package/build/staking/account.d.ts +31 -0
- package/build/staking/cache.d.ts +12 -0
- package/build/staking/currentPoints.d.ts +13 -0
- package/build/staking/electedInfo.d.ts +23 -0
- package/build/staking/erasExposure.d.ts +30 -0
- package/build/staking/erasHistoric.d.ts +8 -0
- package/build/staking/erasPoints.d.ts +18 -0
- package/build/staking/erasPrefs.d.ts +27 -0
- package/build/staking/erasRewards.d.ts +14 -0
- package/build/staking/erasSlashes.d.ts +26 -0
- package/build/staking/index.d.ts +22 -0
- package/build/staking/keys.d.ts +35 -0
- package/build/staking/overview.d.ts +19 -0
- package/build/staking/ownExposure.d.ts +37 -0
- package/build/staking/ownSlashes.d.ts +35 -0
- package/build/staking/query.d.ts +31 -0
- package/build/staking/stakerExposure.d.ts +33 -0
- package/build/staking/stakerPoints.d.ts +22 -0
- package/build/staking/stakerPrefs.d.ts +24 -0
- package/build/staking/stakerRewards.d.ts +49 -0
- package/build/staking/stakerSlashes.d.ts +22 -0
- package/build/staking/stashes.d.ts +16 -0
- package/build/staking/types.d.ts +139 -0
- package/build/staking/util.d.ts +14 -0
- package/build/staking/validators.d.ts +33 -0
- package/build/staking/waitingInfo.d.ts +16 -0
- package/build/technicalCommittee/index.d.ts +70 -0
- package/build/treasury/index.d.ts +1 -0
- package/build/treasury/proposals.d.ts +12 -0
- package/build/tx/constants.d.ts +5 -0
- package/build/tx/events.d.ts +22 -0
- package/build/tx/extrinsicInfo.d.ts +61 -0
- package/build/tx/index.d.ts +3 -0
- package/build/tx/signingInfo.d.ts +25 -0
- package/build/type/HeaderExtended.d.ts +4 -0
- package/build/type/SignedBlockExtended.d.ts +4 -0
- package/build/type/index.d.ts +2 -0
- package/build/type/types.d.ts +15 -0
- package/build/type/util.d.ts +2 -0
- package/build/types.d.ts +79 -0
- package/build/util/approvalFlagsToBools.d.ts +4 -0
- package/build/util/blockNumber.d.ts +7 -0
- package/build/util/cache.d.ts +4 -0
- package/build/util/cacheImpl.d.ts +3 -0
- package/build/util/first.d.ts +4 -0
- package/build/util/index.d.ts +7 -0
- package/build/util/lazy.d.ts +4 -0
- package/build/util/types.d.ts +6 -0
- package/package.json +42 -0
- package/src/accounts/accountId.ts +44 -0
- package/src/accounts/flags.ts +90 -0
- package/src/accounts/idAndIndex.ts +51 -0
- package/src/accounts/idToIndex.ts +31 -0
- package/src/accounts/identity.ts +235 -0
- package/src/accounts/index.ts +11 -0
- package/src/accounts/indexToId.ts +33 -0
- package/src/accounts/indexes.ts +56 -0
- package/src/accounts/info.ts +58 -0
- package/src/accounts/types.ts +48 -0
- package/src/alliance/index.ts +76 -0
- package/src/augment.ts +4 -0
- package/src/bagsList/get.ts +79 -0
- package/src/bagsList/getExpanded.ts +41 -0
- package/src/bagsList/index.ts +6 -0
- package/src/bagsList/listNodes.ts +50 -0
- package/src/bagsList/types.ts +18 -0
- package/src/bagsList/util.ts +14 -0
- package/src/balances/account.ts +210 -0
- package/src/balances/all.ts +246 -0
- package/src/balances/index.ts +26 -0
- package/src/balances/types.ts +79 -0
- package/src/balances/votingBalances.ts +33 -0
- package/src/bounties/bounties.spec.ts +162 -0
- package/src/bounties/bounties.ts +76 -0
- package/src/bounties/helpers/filterBountyProposals.ts +13 -0
- package/src/bounties/index.ts +4 -0
- package/src/bundle.ts +140 -0
- package/src/chain/bestNumber.ts +21 -0
- package/src/chain/bestNumberFinalized.ts +22 -0
- package/src/chain/bestNumberLag.ts +33 -0
- package/src/chain/getBlock.ts +43 -0
- package/src/chain/getBlockByNumber.ts +30 -0
- package/src/chain/getHeader.ts +37 -0
- package/src/chain/index.ts +13 -0
- package/src/chain/subscribeFinalizedBlocks.ts +30 -0
- package/src/chain/subscribeFinalizedHeads.ts +62 -0
- package/src/chain/subscribeNewBlocks.ts +30 -0
- package/src/chain/subscribeNewHeads.ts +38 -0
- package/src/chain/util.ts +112 -0
- package/src/checkTypes.manual.ts +8 -0
- package/src/collective/helpers.ts +36 -0
- package/src/collective/index.ts +6 -0
- package/src/collective/members.ts +8 -0
- package/src/collective/prime.ts +25 -0
- package/src/collective/proposals.ts +73 -0
- package/src/collective/types.ts +30 -0
- package/src/contracts/fees.ts +61 -0
- package/src/contracts/index.ts +4 -0
- package/src/council/index.ts +79 -0
- package/src/council/types.ts +11 -0
- package/src/council/votes.ts +97 -0
- package/src/council/votesOf.ts +35 -0
- package/src/crowdloan/childKey.ts +57 -0
- package/src/crowdloan/contributions.ts +142 -0
- package/src/crowdloan/index.ts +6 -0
- package/src/crowdloan/ownContributions.ts +81 -0
- package/src/crowdloan/types.ts +11 -0
- package/src/crowdloan/util.ts +33 -0
- package/src/democracy/dispatchQueue.ts +158 -0
- package/src/democracy/index.ts +14 -0
- package/src/democracy/locks.ts +114 -0
- package/src/democracy/nextExternal.ts +49 -0
- package/src/democracy/preimages.ts +171 -0
- package/src/democracy/proposals.ts +81 -0
- package/src/democracy/referendumIds.ts +37 -0
- package/src/democracy/referendums.ts +39 -0
- package/src/democracy/referendumsActive.ts +30 -0
- package/src/democracy/referendumsFinished.ts +37 -0
- package/src/democracy/referendumsInfo.ts +181 -0
- package/src/democracy/sqrtElectorate.ts +29 -0
- package/src/democracy/types.ts +84 -0
- package/src/democracy/util.ts +166 -0
- package/src/derive.ts +41 -0
- package/src/elections/index.ts +4 -0
- package/src/elections/info.ts +126 -0
- package/src/elections/types.ts +22 -0
- package/src/imOnline/index.ts +4 -0
- package/src/imOnline/receivedHeartbeats.ts +65 -0
- package/src/index.spec.ts +103 -0
- package/src/index.ts +6 -0
- package/src/membership/index.ts +76 -0
- package/src/mod.ts +4 -0
- package/src/packageDetect.ts +11 -0
- package/src/packageInfo.ts +6 -0
- package/src/parachains/index.ts +5 -0
- package/src/parachains/info.ts +111 -0
- package/src/parachains/overview.ts +63 -0
- package/src/parachains/types.ts +46 -0
- package/src/parachains/util.ts +11 -0
- package/src/session/index.ts +6 -0
- package/src/session/indexes.ts +90 -0
- package/src/session/info.ts +39 -0
- package/src/session/progress.ts +130 -0
- package/src/session/types.ts +25 -0
- package/src/society/candidates.ts +71 -0
- package/src/society/index.ts +7 -0
- package/src/society/info.ts +50 -0
- package/src/society/member.ts +28 -0
- package/src/society/members.ts +107 -0
- package/src/society/types.ts +33 -0
- package/src/staking/account.ts +112 -0
- package/src/staking/cache.ts +48 -0
- package/src/staking/currentPoints.ts +28 -0
- package/src/staking/electedInfo.ts +54 -0
- package/src/staking/erasExposure.ts +105 -0
- package/src/staking/erasHistoric.ts +47 -0
- package/src/staking/erasPoints.ts +67 -0
- package/src/staking/erasPrefs.ts +63 -0
- package/src/staking/erasRewards.ts +52 -0
- package/src/staking/erasSlashes.ts +69 -0
- package/src/staking/index.ts +25 -0
- package/src/staking/keys.ts +86 -0
- package/src/staking/overview.ts +42 -0
- package/src/staking/ownExposure.ts +83 -0
- package/src/staking/ownSlashes.ts +68 -0
- package/src/staking/query.ts +230 -0
- package/src/staking/stakerExposure.ts +78 -0
- package/src/staking/stakerPoints.ts +46 -0
- package/src/staking/stakerPrefs.ts +45 -0
- package/src/staking/stakerRewards.ts +298 -0
- package/src/staking/stakerSlashes.ts +45 -0
- package/src/staking/stashes.ts +55 -0
- package/src/staking/types.ts +174 -0
- package/src/staking/util.ts +94 -0
- package/src/staking/validators.ts +82 -0
- package/src/staking/waitingInfo.ts +45 -0
- package/src/technicalCommittee/index.ts +76 -0
- package/src/test/bountyFactory.ts +39 -0
- package/src/test/bytesFactory.ts +15 -0
- package/src/test/helpers.ts +23 -0
- package/src/test/proposalFactory.ts +25 -0
- package/src/treasury/index.ts +4 -0
- package/src/treasury/proposals.ts +109 -0
- package/src/tx/constants.ts +13 -0
- package/src/tx/events.ts +43 -0
- package/src/tx/extrinsicInfo.ts +123 -0
- package/src/tx/index.ts +6 -0
- package/src/tx/signingInfo.ts +129 -0
- package/src/type/HeaderExtended.ts +33 -0
- package/src/type/SignedBlockExtended.ts +75 -0
- package/src/type/index.ts +5 -0
- package/src/type/types.ts +21 -0
- package/src/type/util.ts +45 -0
- package/src/types.ts +97 -0
- package/src/util/approvalFlagToBools.spec.ts +37 -0
- package/src/util/approvalFlagsToBools.ts +26 -0
- package/src/util/blockNumber.ts +15 -0
- package/src/util/cache.ts +65 -0
- package/src/util/cacheImpl.ts +30 -0
- package/src/util/first.ts +20 -0
- package/src/util/index.ts +13 -0
- package/src/util/lazy.ts +16 -0
- package/src/util/types.ts +9 -0
- package/tsconfig.build.json +21 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.spec.json +27 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Observable } from 'rxjs';
|
|
5
|
+
import type { Option } from '@pezkuwi/types';
|
|
6
|
+
import type { AccountId32 } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { PalletBagsListListBag, PalletBagsListListNode } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { DeriveApi } from '../types.js';
|
|
9
|
+
|
|
10
|
+
import { BehaviorSubject, map, of, switchMap, tap, toArray } from 'rxjs';
|
|
11
|
+
|
|
12
|
+
import { nextTick } from '@pezkuwi/util';
|
|
13
|
+
|
|
14
|
+
import { memo } from '../util/index.js';
|
|
15
|
+
import { getQueryInterface } from './util.js';
|
|
16
|
+
|
|
17
|
+
function traverseLinks (api: DeriveApi, head: AccountId32 | string): Observable<PalletBagsListListNode[]> {
|
|
18
|
+
const subject = new BehaviorSubject<AccountId32 | string>(head);
|
|
19
|
+
const query = getQueryInterface(api);
|
|
20
|
+
|
|
21
|
+
return subject.pipe(
|
|
22
|
+
switchMap((account) =>
|
|
23
|
+
query.listNodes<Option<PalletBagsListListNode>>(account)
|
|
24
|
+
),
|
|
25
|
+
tap((node: Option<PalletBagsListListNode>): void => {
|
|
26
|
+
nextTick((): void => {
|
|
27
|
+
node.isSome && node.value.next.isSome
|
|
28
|
+
? subject.next(node.unwrap().next.unwrap())
|
|
29
|
+
: subject.complete();
|
|
30
|
+
});
|
|
31
|
+
}),
|
|
32
|
+
toArray(), // toArray since we want to startSubject to be completed
|
|
33
|
+
map((all: Option<PalletBagsListListNode>[]) =>
|
|
34
|
+
all.map((o) => o.unwrap())
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @name listNodes
|
|
41
|
+
* @param {(PalletBagsListListBag | null)} bag A reference to a specific bag in the BagsList pallet.
|
|
42
|
+
* @description Retrieves the list of nodes (accounts) contained in a specific bag within the BagsList pallet.
|
|
43
|
+
*/
|
|
44
|
+
export function listNodes (instanceId: string, api: DeriveApi): (bag: PalletBagsListListBag | null) => Observable<PalletBagsListListNode[]> {
|
|
45
|
+
return memo(instanceId, (bag: PalletBagsListListBag | null): Observable<PalletBagsListListNode[]> =>
|
|
46
|
+
bag && bag.head.isSome
|
|
47
|
+
? traverseLinks(api, bag.head.unwrap())
|
|
48
|
+
: of([])
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { PalletBagsListListBag, PalletBagsListListNode } from '@pezkuwi/types/lookup';
|
|
5
|
+
import type { BN } from '@pezkuwi/util';
|
|
6
|
+
|
|
7
|
+
export interface Bag {
|
|
8
|
+
bag: PalletBagsListListBag | null;
|
|
9
|
+
bagUpper: BN;
|
|
10
|
+
bagLower: BN;
|
|
11
|
+
id: BN;
|
|
12
|
+
index: number;
|
|
13
|
+
key: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface BagExpanded extends Bag {
|
|
17
|
+
nodes: PalletBagsListListNode[];
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { DeriveApi } from '../types.js';
|
|
5
|
+
|
|
6
|
+
export function getQueryInterface (api: DeriveApi): DeriveApi['query']['voterList'] {
|
|
7
|
+
return (
|
|
8
|
+
// latest substrate & polkadot
|
|
9
|
+
api.query.voterList ||
|
|
10
|
+
// previous substrate
|
|
11
|
+
api.query['voterBagsList'] ||
|
|
12
|
+
api.query['bagsList']
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Observable } from 'rxjs';
|
|
5
|
+
import type { QueryableStorageEntry } from '@pezkuwi/api-base/types';
|
|
6
|
+
import type { AccountData, AccountId, AccountIndex, AccountInfo, Address, Balance, Index } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { FrameSystemAccountInfo, PalletBalancesAccountData } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { ITuple } from '@pezkuwi/types/types';
|
|
9
|
+
import type { DeriveApi, DeriveBalancesAccount, DeriveBalancesAccountData } from '../types.js';
|
|
10
|
+
|
|
11
|
+
import { combineLatest, map, of, switchMap } from 'rxjs';
|
|
12
|
+
|
|
13
|
+
import { isFunction, objectSpread } from '@pezkuwi/util';
|
|
14
|
+
|
|
15
|
+
import { memo } from '../util/index.js';
|
|
16
|
+
|
|
17
|
+
type BalanceResult = [Balance, Balance, Balance, Balance];
|
|
18
|
+
|
|
19
|
+
type Result = [Index, BalanceResult[], AccountType];
|
|
20
|
+
|
|
21
|
+
interface AccountType { isFrameAccountData: boolean }
|
|
22
|
+
|
|
23
|
+
type DeriveCustomAccount = DeriveApi['derive'] & Record<string, {
|
|
24
|
+
customAccount?: DeriveApi['query']['balances']['account']
|
|
25
|
+
}>
|
|
26
|
+
|
|
27
|
+
function zeroBalance (api: DeriveApi) {
|
|
28
|
+
return api.registry.createType('Balance');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getBalance (api: DeriveApi, [freeBalance, reservedBalance, frozenFeeOrFrozen, frozenMiscOrFlags]: BalanceResult, accType: AccountType): DeriveBalancesAccountData {
|
|
32
|
+
const votingBalance = api.registry.createType('Balance', freeBalance.toBn());
|
|
33
|
+
|
|
34
|
+
if (accType.isFrameAccountData) {
|
|
35
|
+
return {
|
|
36
|
+
frameSystemAccountInfo: {
|
|
37
|
+
flags: frozenMiscOrFlags,
|
|
38
|
+
frozen: frozenFeeOrFrozen
|
|
39
|
+
},
|
|
40
|
+
freeBalance,
|
|
41
|
+
frozenFee: api.registry.createType('Balance', 0),
|
|
42
|
+
frozenMisc: api.registry.createType('Balance', 0),
|
|
43
|
+
reservedBalance,
|
|
44
|
+
votingBalance
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
freeBalance,
|
|
50
|
+
frozenFee: frozenFeeOrFrozen,
|
|
51
|
+
frozenMisc: frozenMiscOrFlags,
|
|
52
|
+
reservedBalance,
|
|
53
|
+
votingBalance
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function calcBalances (api: DeriveApi, [accountId, [accountNonce, [primary, ...additional], accType]]: [AccountId, Result]): DeriveBalancesAccount {
|
|
58
|
+
return objectSpread({
|
|
59
|
+
accountId,
|
|
60
|
+
accountNonce,
|
|
61
|
+
additional: additional.map((b) => getBalance(api, b, accType))
|
|
62
|
+
}, getBalance(api, primary, accType));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// old
|
|
66
|
+
function queryBalancesFree (api: DeriveApi, accountId: AccountId): Observable<Result> {
|
|
67
|
+
return combineLatest([
|
|
68
|
+
api.query.balances['freeBalance']<Balance>(accountId),
|
|
69
|
+
api.query.balances['reservedBalance']<Balance>(accountId),
|
|
70
|
+
api.query.system['accountNonce']<Index>(accountId)
|
|
71
|
+
]).pipe(
|
|
72
|
+
map(([freeBalance, reservedBalance, accountNonce]): Result => [
|
|
73
|
+
accountNonce,
|
|
74
|
+
[[freeBalance, reservedBalance, zeroBalance(api), zeroBalance(api)]],
|
|
75
|
+
{ isFrameAccountData: false }
|
|
76
|
+
])
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function queryNonceOnly (api: DeriveApi, accountId: AccountId): Observable<Result> {
|
|
81
|
+
const fill = (nonce: Index): Result => [
|
|
82
|
+
nonce,
|
|
83
|
+
[[zeroBalance(api), zeroBalance(api), zeroBalance(api), zeroBalance(api)]],
|
|
84
|
+
{ isFrameAccountData: false }
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
return isFunction(api.query.system.account)
|
|
88
|
+
? api.query.system.account(accountId).pipe(
|
|
89
|
+
map(({ nonce }) => fill(nonce))
|
|
90
|
+
)
|
|
91
|
+
: isFunction(api.query.system['accountNonce'])
|
|
92
|
+
? api.query.system['accountNonce']<Index>(accountId).pipe(
|
|
93
|
+
map((nonce) => fill(nonce))
|
|
94
|
+
)
|
|
95
|
+
: of(fill(api.registry.createType('Index')));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function queryBalancesAccount (api: DeriveApi, accountId: AccountId, modules: string[] = ['balances']): Observable<Result> {
|
|
99
|
+
const balances = modules
|
|
100
|
+
.map((m): QueryableStorageEntry<'rxjs'> => (api.derive as DeriveCustomAccount)[m]?.customAccount || api.query[m as 'balances']?.account)
|
|
101
|
+
.filter((q) => isFunction(q));
|
|
102
|
+
|
|
103
|
+
const extract = (nonce: Index, data: AccountData[]): Result => [
|
|
104
|
+
nonce,
|
|
105
|
+
data.map(({ feeFrozen, free, miscFrozen, reserved }): BalanceResult => [free, reserved, feeFrozen, miscFrozen]),
|
|
106
|
+
{ isFrameAccountData: false }
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// NOTE this is for the first case where we do have instances specified
|
|
110
|
+
return balances.length
|
|
111
|
+
? isFunction(api.query.system.account)
|
|
112
|
+
? combineLatest([
|
|
113
|
+
api.query.system.account(accountId),
|
|
114
|
+
...balances.map((c) => c(accountId))
|
|
115
|
+
]).pipe(
|
|
116
|
+
map(([{ nonce }, ...balances]) => extract(nonce, balances as unknown as AccountData[]))
|
|
117
|
+
)
|
|
118
|
+
: combineLatest([
|
|
119
|
+
api.query.system['accountNonce']<Index>(accountId),
|
|
120
|
+
...balances.map((c) => c(accountId))
|
|
121
|
+
]).pipe(
|
|
122
|
+
map(([nonce, ...balances]) => extract(nonce, balances as unknown as AccountData[]))
|
|
123
|
+
)
|
|
124
|
+
: queryNonceOnly(api, accountId);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function querySystemAccount (api: DeriveApi, accountId: AccountId): Observable<Result> {
|
|
128
|
+
// AccountInfo is current, support old, eg. Edgeware
|
|
129
|
+
return api.query.system.account<AccountInfo | FrameSystemAccountInfo | ITuple<[Index, AccountData]>>(accountId).pipe(
|
|
130
|
+
map((infoOrTuple): Result => {
|
|
131
|
+
const data = (infoOrTuple as AccountInfo).nonce
|
|
132
|
+
? (infoOrTuple as AccountInfo).data
|
|
133
|
+
: (infoOrTuple as [Index, AccountData])[1];
|
|
134
|
+
|
|
135
|
+
const nonce = (infoOrTuple as AccountInfo).nonce || (infoOrTuple as [Index, AccountData])[0];
|
|
136
|
+
|
|
137
|
+
if (!data || data.isEmpty) {
|
|
138
|
+
return [
|
|
139
|
+
nonce,
|
|
140
|
+
[[zeroBalance(api), zeroBalance(api), zeroBalance(api), zeroBalance(api)]],
|
|
141
|
+
{ isFrameAccountData: false }
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const isFrameType = !!(infoOrTuple as FrameSystemAccountInfo).data.frozen;
|
|
146
|
+
|
|
147
|
+
if (isFrameType) {
|
|
148
|
+
const { flags, free, frozen, reserved } = (data as unknown as PalletBalancesAccountData);
|
|
149
|
+
|
|
150
|
+
return [
|
|
151
|
+
nonce,
|
|
152
|
+
[[free, reserved, frozen, flags]],
|
|
153
|
+
{ isFrameAccountData: true }
|
|
154
|
+
];
|
|
155
|
+
} else {
|
|
156
|
+
const { feeFrozen, free, miscFrozen, reserved } = data;
|
|
157
|
+
|
|
158
|
+
return [
|
|
159
|
+
nonce,
|
|
160
|
+
[[free, reserved, feeFrozen, miscFrozen]],
|
|
161
|
+
{ isFrameAccountData: false }
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @name account
|
|
170
|
+
* @description Retrieves the essential balance details for an account, such as free balance and account nonce.
|
|
171
|
+
* @param {( AccountIndex | AccountId | Address | string )} address An accountsId in different formats.
|
|
172
|
+
* @example
|
|
173
|
+
* ```javascript
|
|
174
|
+
* const ALICE = 'F7Hs';
|
|
175
|
+
*
|
|
176
|
+
* api.derive.balances.all(ALICE, ({ accountId, lockedBalance }) => {
|
|
177
|
+
* console.log(`The account ${accountId} has a locked balance ${lockedBalance} units.`);
|
|
178
|
+
* });
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export function account (instanceId: string, api: DeriveApi): (address: AccountIndex | AccountId | Address | string) => Observable<DeriveBalancesAccount> {
|
|
182
|
+
const balanceInstances = api.registry.getModuleInstances(api.runtimeVersion.specName, 'balances');
|
|
183
|
+
const nonDefaultBalances = balanceInstances && balanceInstances[0] !== 'balances';
|
|
184
|
+
|
|
185
|
+
return memo(instanceId, (address: AccountIndex | AccountId | Address | string): Observable<DeriveBalancesAccount> =>
|
|
186
|
+
api.derive.accounts.accountId(address).pipe(
|
|
187
|
+
switchMap((accountId): Observable<[AccountId, Result]> =>
|
|
188
|
+
(accountId
|
|
189
|
+
? combineLatest([
|
|
190
|
+
of(accountId),
|
|
191
|
+
nonDefaultBalances
|
|
192
|
+
? queryBalancesAccount(api, accountId, balanceInstances)
|
|
193
|
+
: isFunction(api.query.system?.account)
|
|
194
|
+
? querySystemAccount(api, accountId)
|
|
195
|
+
: isFunction(api.query.balances?.account)
|
|
196
|
+
? queryBalancesAccount(api, accountId)
|
|
197
|
+
: isFunction(api.query.balances?.['freeBalance'])
|
|
198
|
+
? queryBalancesFree(api, accountId)
|
|
199
|
+
: queryNonceOnly(api, accountId)
|
|
200
|
+
])
|
|
201
|
+
: of([api.registry.createType('AccountId'), [
|
|
202
|
+
api.registry.createType('Index'),
|
|
203
|
+
[[zeroBalance(api), zeroBalance(api), zeroBalance(api), zeroBalance(api)]],
|
|
204
|
+
{ isFrameAccountData: false }
|
|
205
|
+
]])
|
|
206
|
+
)
|
|
207
|
+
),
|
|
208
|
+
map((result): DeriveBalancesAccount => calcBalances(api, result))
|
|
209
|
+
));
|
|
210
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Observable } from 'rxjs';
|
|
5
|
+
import type { Option, Vec } from '@pezkuwi/types';
|
|
6
|
+
import type { AccountId, Balance, BalanceLockTo212, BlockNumber, VestingSchedule } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { PalletBalancesBalanceLock, PalletBalancesReserveData, PalletVestingVestingInfo } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { DeriveApi, DeriveBalancesAccount, DeriveBalancesAccountData, DeriveBalancesAll, DeriveBalancesAllAccountData, DeriveBalancesAllVesting } from '../types.js';
|
|
9
|
+
|
|
10
|
+
import { combineLatest, map, of, switchMap } from 'rxjs';
|
|
11
|
+
|
|
12
|
+
import { BN, BN_ZERO, bnMax, bnMin, isFunction, objectSpread } from '@pezkuwi/util';
|
|
13
|
+
|
|
14
|
+
import { memo } from '../util/index.js';
|
|
15
|
+
|
|
16
|
+
type ResultBalance = [PalletVestingVestingInfo[] | null, ((PalletBalancesBalanceLock | BalanceLockTo212)[])[], PalletBalancesReserveData[][]];
|
|
17
|
+
type Result = [DeriveBalancesAccount, ResultBalance, BlockNumber];
|
|
18
|
+
|
|
19
|
+
interface AllLocked {
|
|
20
|
+
allLocked: boolean,
|
|
21
|
+
lockedBalance: Balance,
|
|
22
|
+
lockedBreakdown: (PalletBalancesBalanceLock | BalanceLockTo212)[],
|
|
23
|
+
vestingLocked: Balance
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type DeriveCustomLocks = DeriveApi['derive'] & Record<string, {
|
|
27
|
+
customLocks?: DeriveApi['query']['balances']['locks']
|
|
28
|
+
}>
|
|
29
|
+
|
|
30
|
+
const VESTING_ID = '0x76657374696e6720';
|
|
31
|
+
|
|
32
|
+
function calcLocked (api: DeriveApi, bestNumber: BlockNumber, locks: (PalletBalancesBalanceLock | BalanceLockTo212)[]): AllLocked {
|
|
33
|
+
let lockedBalance = api.registry.createType('Balance');
|
|
34
|
+
let lockedBreakdown: (PalletBalancesBalanceLock | BalanceLockTo212)[] = [];
|
|
35
|
+
let vestingLocked = api.registry.createType('Balance');
|
|
36
|
+
let allLocked = false;
|
|
37
|
+
|
|
38
|
+
if (Array.isArray(locks)) {
|
|
39
|
+
// only get the locks that are valid until passed the current block
|
|
40
|
+
lockedBreakdown = (locks as BalanceLockTo212[]).filter(({ until }): boolean => !until || (bestNumber && until.gt(bestNumber)));
|
|
41
|
+
allLocked = lockedBreakdown.some(({ amount }) => amount && amount.isMax());
|
|
42
|
+
vestingLocked = api.registry.createType('Balance', lockedBreakdown.filter(({ id }) => id.eq(VESTING_ID)).reduce((result: BN, { amount }) => result.iadd(amount), new BN(0)));
|
|
43
|
+
|
|
44
|
+
// get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699
|
|
45
|
+
const notAll = lockedBreakdown.filter(({ amount }) => amount && !amount.isMax());
|
|
46
|
+
|
|
47
|
+
if (notAll.length) {
|
|
48
|
+
lockedBalance = api.registry.createType('Balance', bnMax(...notAll.map(({ amount }): Balance => amount)));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { allLocked, lockedBalance, lockedBreakdown, vestingLocked };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function calcShared (api: DeriveApi, bestNumber: BlockNumber, data: DeriveBalancesAccountData, locks: (PalletBalancesBalanceLock | BalanceLockTo212)[]): DeriveBalancesAllAccountData {
|
|
56
|
+
const { allLocked, lockedBalance, lockedBreakdown, vestingLocked } = calcLocked(api, bestNumber, locks);
|
|
57
|
+
let transferable = null;
|
|
58
|
+
|
|
59
|
+
if (data?.frameSystemAccountInfo?.frozen) {
|
|
60
|
+
const { frameSystemAccountInfo, freeBalance, reservedBalance } = data;
|
|
61
|
+
const noFrozenReserved = frameSystemAccountInfo.frozen.isZero() && reservedBalance.isZero();
|
|
62
|
+
const ED = api.consts.balances.existentialDeposit;
|
|
63
|
+
const maybeED = noFrozenReserved ? new BN(0) : ED;
|
|
64
|
+
const frozenReserveDif = frameSystemAccountInfo.frozen.sub(reservedBalance);
|
|
65
|
+
|
|
66
|
+
transferable = api.registry.createType(
|
|
67
|
+
'Balance',
|
|
68
|
+
allLocked
|
|
69
|
+
? 0
|
|
70
|
+
: bnMax(new BN(0), freeBalance.sub(bnMax(maybeED, frozenReserveDif)))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return objectSpread({}, data, {
|
|
75
|
+
availableBalance: api.registry.createType('Balance', allLocked ? 0 : bnMax(new BN(0), data?.freeBalance ? data.freeBalance.sub(lockedBalance) : new BN(0))),
|
|
76
|
+
lockedBalance,
|
|
77
|
+
lockedBreakdown,
|
|
78
|
+
transferable,
|
|
79
|
+
vestingLocked
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function calcVesting (bestNumber: BlockNumber, shared: DeriveBalancesAllAccountData, _vesting: PalletVestingVestingInfo[] | null): DeriveBalancesAllVesting {
|
|
84
|
+
// Calculate the vesting balances,
|
|
85
|
+
// - offset = balance locked at startingBlock
|
|
86
|
+
// - perBlock is the unlock amount
|
|
87
|
+
const vesting = _vesting || [];
|
|
88
|
+
const isVesting = !shared.vestingLocked.isZero();
|
|
89
|
+
const vestedBalances = vesting.map(({ locked, perBlock, startingBlock }) =>
|
|
90
|
+
bestNumber.gt(startingBlock)
|
|
91
|
+
? bnMin(locked, perBlock.mul(bestNumber.sub(startingBlock)))
|
|
92
|
+
: BN_ZERO
|
|
93
|
+
);
|
|
94
|
+
const vestedBalance = vestedBalances.reduce<BN>((all, value) => all.iadd(value), new BN(0));
|
|
95
|
+
const vestingTotal = vesting.reduce<BN>((all, { locked }) => all.iadd(locked), new BN(0));
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
isVesting,
|
|
99
|
+
vestedBalance,
|
|
100
|
+
vestedClaimable: isVesting
|
|
101
|
+
? shared.vestingLocked.sub(vestingTotal.sub(vestedBalance))
|
|
102
|
+
: BN_ZERO,
|
|
103
|
+
vesting: vesting
|
|
104
|
+
.map(({ locked, perBlock, startingBlock }, index) => ({
|
|
105
|
+
endBlock: locked.div(perBlock).iadd(startingBlock),
|
|
106
|
+
locked,
|
|
107
|
+
perBlock,
|
|
108
|
+
startingBlock,
|
|
109
|
+
vested: vestedBalances[index]
|
|
110
|
+
}))
|
|
111
|
+
.filter(({ locked }) => !locked.isZero()),
|
|
112
|
+
vestingTotal
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function calcBalances (api: DeriveApi, result: Result): DeriveBalancesAll {
|
|
117
|
+
const [data, [vesting, allLocks, namedReserves], bestNumber] = result;
|
|
118
|
+
const shared = calcShared(api, bestNumber, data, allLocks[0]);
|
|
119
|
+
|
|
120
|
+
return objectSpread(shared, calcVesting(bestNumber, shared, vesting), {
|
|
121
|
+
accountId: data.accountId,
|
|
122
|
+
accountNonce: data.accountNonce,
|
|
123
|
+
additional: allLocks
|
|
124
|
+
.slice(1)
|
|
125
|
+
.map((l, index) => calcShared(api, bestNumber, data.additional[index], l)),
|
|
126
|
+
namedReserves
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// old
|
|
131
|
+
function queryOld (api: DeriveApi, accountId: AccountId | string): Observable<ResultBalance> {
|
|
132
|
+
return combineLatest([
|
|
133
|
+
api.query.balances.locks(accountId),
|
|
134
|
+
api.query.balances['vesting']<Option<VestingSchedule>>(accountId)
|
|
135
|
+
]).pipe(
|
|
136
|
+
map(([locks, optVesting]): ResultBalance => {
|
|
137
|
+
let vestingNew = null;
|
|
138
|
+
|
|
139
|
+
if (optVesting.isSome) {
|
|
140
|
+
const { offset: locked, perBlock, startingBlock } = optVesting.unwrap();
|
|
141
|
+
|
|
142
|
+
vestingNew = api.registry.createType<PalletVestingVestingInfo>('VestingInfo', { locked, perBlock, startingBlock });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return [
|
|
146
|
+
vestingNew
|
|
147
|
+
? [vestingNew]
|
|
148
|
+
: null,
|
|
149
|
+
[locks],
|
|
150
|
+
[]
|
|
151
|
+
];
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const isNonNullable = <T>(nullable: T): nullable is NonNullable<T> => !!nullable;
|
|
157
|
+
|
|
158
|
+
function createCalls <T> (calls: (((a: unknown) => Observable<T>) | null | undefined)[]): [boolean[], ((a: unknown) => Observable<T>)[]] {
|
|
159
|
+
return [
|
|
160
|
+
calls.map((c) => !c),
|
|
161
|
+
calls.filter(isNonNullable)
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// current (balances, vesting)
|
|
166
|
+
function queryCurrent (api: DeriveApi, accountId: AccountId | string, balanceInstances: string[] = ['balances']): Observable<ResultBalance> {
|
|
167
|
+
const [lockEmpty, lockQueries] = createCalls<Vec<PalletBalancesBalanceLock>>(
|
|
168
|
+
balanceInstances.map((m) =>
|
|
169
|
+
(api.derive as DeriveCustomLocks)[m]?.customLocks || api.query[m as 'balances']?.locks
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
const [reserveEmpty, reserveQueries] = createCalls<Vec<PalletBalancesReserveData>>(
|
|
173
|
+
balanceInstances.map((m) =>
|
|
174
|
+
api.query[m as 'balances']?.reserves
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
return combineLatest([
|
|
179
|
+
api.query.vesting?.vesting
|
|
180
|
+
? api.query.vesting.vesting(accountId)
|
|
181
|
+
: of(api.registry.createType('Option<VestingInfo>')),
|
|
182
|
+
lockQueries.length
|
|
183
|
+
? combineLatest(lockQueries.map((c) => c(accountId)))
|
|
184
|
+
: of([] as Vec<PalletBalancesBalanceLock>[]),
|
|
185
|
+
reserveQueries.length
|
|
186
|
+
? combineLatest(reserveQueries.map((c) => c(accountId)))
|
|
187
|
+
: of([] as Vec<PalletBalancesReserveData>[])
|
|
188
|
+
]).pipe(
|
|
189
|
+
map(([opt, locks, reserves]): ResultBalance => {
|
|
190
|
+
let offsetLock = -1;
|
|
191
|
+
let offsetReserve = -1;
|
|
192
|
+
const vesting = opt.unwrapOr(null);
|
|
193
|
+
|
|
194
|
+
return [
|
|
195
|
+
vesting
|
|
196
|
+
? Array.isArray(vesting)
|
|
197
|
+
? vesting
|
|
198
|
+
: [vesting as PalletVestingVestingInfo]
|
|
199
|
+
: null,
|
|
200
|
+
lockEmpty.map((e) =>
|
|
201
|
+
e ? api.registry.createType<Vec<PalletBalancesBalanceLock>>('Vec<BalanceLock>') : locks[++offsetLock]
|
|
202
|
+
),
|
|
203
|
+
reserveEmpty.map((e) =>
|
|
204
|
+
e ? api.registry.createType<Vec<PalletBalancesReserveData>>('Vec<PalletBalancesReserveData>') : reserves[++offsetReserve]
|
|
205
|
+
)
|
|
206
|
+
];
|
|
207
|
+
})
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @name all
|
|
213
|
+
* @description Retrieves the complete balance information for an account, including free balance, locked balance, reserved balance, and more.
|
|
214
|
+
* @param {( AccountId | string )} address An accountsId in different formats.
|
|
215
|
+
* @example
|
|
216
|
+
* ```javascript
|
|
217
|
+
* const ALICE = 'F7Hs';
|
|
218
|
+
*
|
|
219
|
+
* api.derive.balances.account(ALICE, (accountInfo) => {
|
|
220
|
+
* console.log(
|
|
221
|
+
* `${accountInfo.accountId} info:`,
|
|
222
|
+
* Object.keys(accountInfo).map((key) => `${key}: ${accountInfo[key]}`)
|
|
223
|
+
* );
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
export function all (instanceId: string, api: DeriveApi): (address: AccountId | string) => Observable<DeriveBalancesAll> {
|
|
228
|
+
const balanceInstances = api.registry.getModuleInstances(api.runtimeVersion.specName, 'balances');
|
|
229
|
+
|
|
230
|
+
return memo(instanceId, (address: AccountId | string): Observable<DeriveBalancesAll> =>
|
|
231
|
+
combineLatest([
|
|
232
|
+
api.derive.balances.account(address),
|
|
233
|
+
isFunction(api.query.system?.account) || isFunction(api.query.balances?.account)
|
|
234
|
+
? queryCurrent(api, address, balanceInstances)
|
|
235
|
+
: queryOld(api, address)
|
|
236
|
+
]).pipe(
|
|
237
|
+
switchMap(([account, locks]) =>
|
|
238
|
+
combineLatest([
|
|
239
|
+
of(account),
|
|
240
|
+
of(locks),
|
|
241
|
+
api.derive.chain.bestNumber()
|
|
242
|
+
])
|
|
243
|
+
),
|
|
244
|
+
map((result) => calcBalances(api, result))
|
|
245
|
+
));
|
|
246
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { all } from './all.js';
|
|
5
|
+
|
|
6
|
+
export * from './account.js';
|
|
7
|
+
export * from './votingBalances.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @name votingBalance
|
|
11
|
+
* @param {( AccountId | string )} address An accounts Id in different formats.
|
|
12
|
+
* @returns An object containing the results of various balance queries
|
|
13
|
+
* @example
|
|
14
|
+
* <BR>
|
|
15
|
+
*
|
|
16
|
+
* ```javascript
|
|
17
|
+
* const ALICE = 'F7Hs';
|
|
18
|
+
*
|
|
19
|
+
* api.derive.balances.votingBalance(ALICE, ({ accountId, lockedBalance }) => {
|
|
20
|
+
* console.log(`The account ${accountId} has a locked balance ${lockedBalance} units.`);
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
const votingBalance = all;
|
|
25
|
+
|
|
26
|
+
export { all, votingBalance };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AccountId, Balance, BalanceLockTo212, Index } from '@pezkuwi/types/interfaces';
|
|
5
|
+
import type { PalletBalancesBalanceLock, PalletBalancesReserveData } from '@pezkuwi/types/lookup';
|
|
6
|
+
import type { BN } from '@pezkuwi/util';
|
|
7
|
+
|
|
8
|
+
export interface DeriveBalancesAccountData {
|
|
9
|
+
frameSystemAccountInfo?: {
|
|
10
|
+
frozen: Balance;
|
|
11
|
+
flags: Balance;
|
|
12
|
+
}
|
|
13
|
+
freeBalance: Balance;
|
|
14
|
+
frozenFee: Balance;
|
|
15
|
+
frozenMisc: Balance;
|
|
16
|
+
reservedBalance: Balance;
|
|
17
|
+
votingBalance: Balance;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DeriveBalancesAccount extends DeriveBalancesAccountData {
|
|
21
|
+
accountId: AccountId;
|
|
22
|
+
accountNonce: Index;
|
|
23
|
+
additional: DeriveBalancesAccountData[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DeriveBalancesAllAccountData extends DeriveBalancesAccountData {
|
|
27
|
+
/**
|
|
28
|
+
* Calculated available balance. This uses the formula: max(0, free - locked)
|
|
29
|
+
* This is only correct when the return type of `api.query.system.account` is `AccountInfo` which was replaced by `FrameSystemAccountInfo`.
|
|
30
|
+
* See `transferable` for the correct balance calculation.
|
|
31
|
+
*
|
|
32
|
+
* ref: https://github.com/paritytech/substrate/pull/12951
|
|
33
|
+
*/
|
|
34
|
+
availableBalance: Balance;
|
|
35
|
+
/**
|
|
36
|
+
* The amount of balance locked away.
|
|
37
|
+
*/
|
|
38
|
+
lockedBalance: Balance;
|
|
39
|
+
/**
|
|
40
|
+
* The breakdown of locked balances.
|
|
41
|
+
*/
|
|
42
|
+
lockedBreakdown: (PalletBalancesBalanceLock | BalanceLockTo212)[];
|
|
43
|
+
/**
|
|
44
|
+
* Calculated transferable balance. This uses the formula: free - max(maybeEd, frozen - reserve)
|
|
45
|
+
* Where `maybeEd` means if there is no frozen and reserves it will be zero, else it will be the existential deposit.
|
|
46
|
+
* This is only correct when the return type of `api.query.system.account` is `FrameSystemAccountInfo`.
|
|
47
|
+
* Which is the most up to date calulcation for transferrable balances.
|
|
48
|
+
*
|
|
49
|
+
* ref: https://github.com/paritytech/polkadot-sdk/issues/1833
|
|
50
|
+
*/
|
|
51
|
+
transferable: Balance | null;
|
|
52
|
+
/**
|
|
53
|
+
* Amount locked in vesting.
|
|
54
|
+
*/
|
|
55
|
+
vestingLocked: Balance;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DeriveBalancesVesting {
|
|
59
|
+
startingBlock: BN;
|
|
60
|
+
endBlock: BN;
|
|
61
|
+
perBlock: BN;
|
|
62
|
+
locked: BN;
|
|
63
|
+
vested: BN;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface DeriveBalancesAllVesting {
|
|
67
|
+
isVesting: boolean;
|
|
68
|
+
vestedBalance: BN;
|
|
69
|
+
vestedClaimable: BN;
|
|
70
|
+
vesting: DeriveBalancesVesting[];
|
|
71
|
+
vestingTotal: BN;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface DeriveBalancesAll extends DeriveBalancesAccount, DeriveBalancesAllAccountData, DeriveBalancesAllVesting {
|
|
75
|
+
additional: DeriveBalancesAllAccountData[];
|
|
76
|
+
namedReserves: PalletBalancesReserveData[][];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type DeriveBalancesMap = Record<string, DeriveBalancesAll>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Observable } from 'rxjs';
|
|
5
|
+
import type { AccountId, AccountIndex, Address } from '@pezkuwi/types/interfaces';
|
|
6
|
+
import type { DeriveApi, DeriveBalancesAccount } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { combineLatest, of } from 'rxjs';
|
|
9
|
+
|
|
10
|
+
import { memo } from '../util/index.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @name votingBalances
|
|
14
|
+
* @description Retrieves the balance information for multiple accounts, typically used in governance-related contexts to check voting power.
|
|
15
|
+
* @param {(AccountId | AccountIndex | Address | string)[]} addresses An array of account identifiers.
|
|
16
|
+
* @example
|
|
17
|
+
* ```javascript
|
|
18
|
+
* const addresses = ["5D4b...Zf1", "5HGj...yrV"];
|
|
19
|
+
* const balances = await api.derive.balances.votingBalances(addresses);
|
|
20
|
+
* console.log("Voting Balances:", balances);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function votingBalances (instanceId: string, api: DeriveApi): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DeriveBalancesAccount[]> {
|
|
24
|
+
return memo(instanceId, (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DeriveBalancesAccount[]> =>
|
|
25
|
+
!addresses?.length
|
|
26
|
+
? of([] as DeriveBalancesAccount[])
|
|
27
|
+
: combineLatest(
|
|
28
|
+
addresses.map((accountId): Observable<DeriveBalancesAccount> =>
|
|
29
|
+
api.derive.balances.account(accountId)
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
);
|
|
33
|
+
}
|