@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,181 @@
|
|
|
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, Hash, ReferendumInfoTo239, Vote } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyVoteVoting } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { BN } from '@pezkuwi/util';
|
|
9
|
+
import type { DeriveApi, DeriveBalancesAccount, DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes } 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
|
+
import { calcVotes, getImageHash, getStatus } from './util.js';
|
|
17
|
+
|
|
18
|
+
type VotingDelegating = PalletDemocracyVoteVoting['asDelegating'];
|
|
19
|
+
type VotingDirect = PalletDemocracyVoteVoting['asDirect'];
|
|
20
|
+
type VotingDirectVote = VotingDirect['votes'][0];
|
|
21
|
+
|
|
22
|
+
function votesPrev (api: DeriveApi, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
|
23
|
+
return api.query.democracy['votersFor']<Vec<AccountId>>(referendumId).pipe(
|
|
24
|
+
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DeriveBalancesAccount[]]> =>
|
|
25
|
+
combineLatest([
|
|
26
|
+
of(votersFor),
|
|
27
|
+
votersFor.length
|
|
28
|
+
? api.query.democracy['voteOf'].multi<Vote>(
|
|
29
|
+
votersFor.map((accountId): [BN | number, AccountId] =>
|
|
30
|
+
[referendumId, accountId]
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
: of([]),
|
|
34
|
+
api.derive.balances.votingBalances(votersFor)
|
|
35
|
+
])
|
|
36
|
+
),
|
|
37
|
+
map(([votersFor, votes, balances]): DeriveReferendumVote[] =>
|
|
38
|
+
votersFor.map((accountId, index): DeriveReferendumVote => ({
|
|
39
|
+
accountId,
|
|
40
|
+
balance: balances[index].votingBalance || api.registry.createType('Balance'),
|
|
41
|
+
isDelegating: false,
|
|
42
|
+
vote: votes[index] || api.registry.createType('Vote')
|
|
43
|
+
}))
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function extractVotes (mapped: [AccountId, PalletDemocracyVoteVoting][], referendumId: BN): DeriveReferendumVote[] {
|
|
49
|
+
return mapped
|
|
50
|
+
.filter(([, voting]) => voting.isDirect)
|
|
51
|
+
.map(([accountId, voting]): [AccountId, VotingDirectVote[]] => [
|
|
52
|
+
accountId,
|
|
53
|
+
voting.asDirect.votes.filter(([idx]) => idx.eq(referendumId))
|
|
54
|
+
])
|
|
55
|
+
.filter(([, directVotes]) => !!directVotes.length)
|
|
56
|
+
.reduce((result: DeriveReferendumVote[], [accountId, votes]) =>
|
|
57
|
+
// FIXME We are ignoring split votes
|
|
58
|
+
votes.reduce((result: DeriveReferendumVote[], [, vote]): DeriveReferendumVote[] => {
|
|
59
|
+
if (vote.isStandard) {
|
|
60
|
+
result.push(
|
|
61
|
+
objectSpread({
|
|
62
|
+
accountId,
|
|
63
|
+
isDelegating: false
|
|
64
|
+
}, vote.asStandard)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return result;
|
|
69
|
+
}, result), []
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function votesCurr (api: DeriveApi, referendumId: BN): Observable<DeriveReferendumVote[]> {
|
|
74
|
+
return api.query.democracy.votingOf.entries().pipe(
|
|
75
|
+
map((allVoting): DeriveReferendumVote[] => {
|
|
76
|
+
const mapped = allVoting.map(([{ args: [accountId] }, voting]): [AccountId, PalletDemocracyVoteVoting] => [accountId, voting]);
|
|
77
|
+
const votes = extractVotes(mapped, referendumId);
|
|
78
|
+
const delegations = mapped
|
|
79
|
+
.filter(([, voting]) => voting.isDelegating)
|
|
80
|
+
.map(([accountId, voting]): [AccountId, VotingDelegating] => [accountId, voting.asDelegating]);
|
|
81
|
+
|
|
82
|
+
// add delegations
|
|
83
|
+
delegations.forEach(([accountId, { balance, conviction, target }]): void => {
|
|
84
|
+
// Are we delegating to a delegator
|
|
85
|
+
const toDelegator = delegations.find(([accountId]) => accountId.eq(target));
|
|
86
|
+
const to = votes.find(({ accountId }) => accountId.eq(toDelegator ? toDelegator[0] : target));
|
|
87
|
+
|
|
88
|
+
// this delegation has a target
|
|
89
|
+
if (to) {
|
|
90
|
+
votes.push({
|
|
91
|
+
accountId,
|
|
92
|
+
balance,
|
|
93
|
+
isDelegating: true,
|
|
94
|
+
vote: api.registry.createType('Vote', { aye: to.vote.isAye, conviction })
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return votes;
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function _referendumVotes (instanceId: string, api: DeriveApi): (referendum: DeriveReferendum) => Observable<DeriveReferendumVotes> {
|
|
105
|
+
return memo(instanceId, (referendum: DeriveReferendum): Observable<DeriveReferendumVotes> =>
|
|
106
|
+
combineLatest([
|
|
107
|
+
api.derive.democracy.sqrtElectorate(),
|
|
108
|
+
isFunction(api.query.democracy.votingOf)
|
|
109
|
+
? votesCurr(api, referendum.index)
|
|
110
|
+
: votesPrev(api, referendum.index)
|
|
111
|
+
]).pipe(
|
|
112
|
+
map(([sqrtElectorate, votes]) =>
|
|
113
|
+
calcVotes(sqrtElectorate, referendum, votes)
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function _referendumsVotes (instanceId: string, api: DeriveApi): (referendums: DeriveReferendum[]) => Observable<DeriveReferendumVotes[]> {
|
|
120
|
+
return memo(instanceId, (referendums: DeriveReferendum[]): Observable<DeriveReferendumVotes[]> =>
|
|
121
|
+
referendums.length
|
|
122
|
+
? combineLatest(
|
|
123
|
+
referendums.map((referendum): Observable<DeriveReferendumVotes> =>
|
|
124
|
+
api.derive.democracy._referendumVotes(referendum)
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
: of([])
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function _referendumInfo (instanceId: string, api: DeriveApi): (index: BN, info: Option<PalletDemocracyReferendumInfo | ReferendumInfoTo239>) => Observable<DeriveReferendum | null> {
|
|
132
|
+
return memo(instanceId, (index: BN, info: Option<PalletDemocracyReferendumInfo | ReferendumInfoTo239>): Observable<DeriveReferendum | null> => {
|
|
133
|
+
const status = getStatus(info);
|
|
134
|
+
|
|
135
|
+
return status
|
|
136
|
+
? api.derive.democracy.preimage(
|
|
137
|
+
(status as PalletDemocracyReferendumStatus).proposal ||
|
|
138
|
+
(status as unknown as { proposalHash: Hash }).proposalHash
|
|
139
|
+
).pipe(
|
|
140
|
+
map((image): DeriveReferendum => ({
|
|
141
|
+
image,
|
|
142
|
+
imageHash: getImageHash(status),
|
|
143
|
+
index: api.registry.createType('ReferendumIndex', index),
|
|
144
|
+
status
|
|
145
|
+
}))
|
|
146
|
+
)
|
|
147
|
+
: of(null);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @name referendumsInfo
|
|
153
|
+
* @description Retrieves information about multiple referendums by their IDs.
|
|
154
|
+
* @param {BN[]} ids An array of referendum IDs to query.
|
|
155
|
+
* @example
|
|
156
|
+
* ```javascript
|
|
157
|
+
* import { BN } from "@pezkuwi/util";
|
|
158
|
+
*
|
|
159
|
+
* const referendumIds = [new BN(1)];
|
|
160
|
+
* const referendums = await api.derive.democracy.referendumsInfo(referendumIds);
|
|
161
|
+
* console.log("Referendums Info:", referendums);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function referendumsInfo (instanceId: string, api: DeriveApi): (ids: BN[]) => Observable<DeriveReferendum[]> {
|
|
165
|
+
return memo(instanceId, (ids: BN[]): Observable<DeriveReferendum[]> =>
|
|
166
|
+
ids.length
|
|
167
|
+
? api.query.democracy.referendumInfoOf.multi(ids).pipe(
|
|
168
|
+
switchMap((infos): Observable<(DeriveReferendum | null)[]> =>
|
|
169
|
+
combineLatest(
|
|
170
|
+
ids.map((id, index): Observable<DeriveReferendum | null> =>
|
|
171
|
+
api.derive.democracy._referendumInfo(id, infos[index])
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
),
|
|
175
|
+
map((infos) =>
|
|
176
|
+
infos.filter((r): r is DeriveReferendum => !!r)
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
: of([])
|
|
180
|
+
);
|
|
181
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
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 { BN } from '@pezkuwi/util';
|
|
6
|
+
import type { DeriveApi } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { map } from 'rxjs';
|
|
9
|
+
|
|
10
|
+
import { bnSqrt } from '@pezkuwi/util';
|
|
11
|
+
|
|
12
|
+
import { memo } from '../util/index.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @name sqrtElectorate
|
|
16
|
+
* @description Computes the square root of the total token issuance in the network.
|
|
17
|
+
* @example
|
|
18
|
+
* ```javascript
|
|
19
|
+
* let sqrtElectorate = await api.derive.democracy.sqrtElectorate();
|
|
20
|
+
* console.log("Square root of token issuance:", sqrtElectorate);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function sqrtElectorate (instanceId: string, api: DeriveApi): () => Observable<BN> {
|
|
24
|
+
return memo(instanceId, (): Observable<BN> =>
|
|
25
|
+
api.query.balances.totalIssuance().pipe(
|
|
26
|
+
map(bnSqrt)
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Vec } from '@pezkuwi/types';
|
|
5
|
+
import type { AccountId, Balance, Call, Hash, PropIndex, ReferendumIndex, ReferendumInfoTo239, Vote } from '@pezkuwi/types/interfaces';
|
|
6
|
+
import type { PalletDemocracyReferendumStatus, PalletDemocracyVoteThreshold } from '@pezkuwi/types/lookup';
|
|
7
|
+
import type { BN } from '@pezkuwi/util';
|
|
8
|
+
import type { HexString } from '@pezkuwi/util/types';
|
|
9
|
+
|
|
10
|
+
export interface AtBlock {
|
|
11
|
+
at: BN;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface DeriveDemocracyLock {
|
|
15
|
+
balance: Balance;
|
|
16
|
+
isDelegated: boolean;
|
|
17
|
+
isFinished: boolean;
|
|
18
|
+
referendumEnd: BN;
|
|
19
|
+
referendumId: ReferendumIndex;
|
|
20
|
+
unlockAt: BN;
|
|
21
|
+
vote: Vote;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DeriveProposalImage extends AtBlock {
|
|
25
|
+
balance: Balance;
|
|
26
|
+
proposal?: Call | undefined;
|
|
27
|
+
proposalHash?: HexString;
|
|
28
|
+
proposalLen?: number;
|
|
29
|
+
proposer: AccountId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface DeriveDispatch extends AtBlock {
|
|
33
|
+
index: ReferendumIndex;
|
|
34
|
+
imageHash: HexString;
|
|
35
|
+
image?: DeriveProposalImage | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DeriveProposal {
|
|
39
|
+
balance?: Balance;
|
|
40
|
+
index: PropIndex;
|
|
41
|
+
image?: DeriveProposalImage | undefined;
|
|
42
|
+
imageHash: Hash;
|
|
43
|
+
proposer: AccountId;
|
|
44
|
+
seconds: Vec<AccountId>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface DeriveProposalExternal {
|
|
48
|
+
image?: DeriveProposalImage | undefined;
|
|
49
|
+
imageHash: HexString;
|
|
50
|
+
threshold: PalletDemocracyVoteThreshold;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface DeriveReferendum {
|
|
54
|
+
index: ReferendumIndex;
|
|
55
|
+
image?: DeriveProposalImage | undefined;
|
|
56
|
+
imageHash: HexString;
|
|
57
|
+
status: PalletDemocracyReferendumStatus | ReferendumInfoTo239;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface DeriveReferendumVote {
|
|
61
|
+
accountId: AccountId;
|
|
62
|
+
balance: Balance;
|
|
63
|
+
isDelegating: boolean;
|
|
64
|
+
vote: Vote;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface DeriveReferendumVoteState {
|
|
68
|
+
allAye: DeriveReferendumVote[];
|
|
69
|
+
allNay: DeriveReferendumVote[];
|
|
70
|
+
voteCount: number;
|
|
71
|
+
voteCountAye: number;
|
|
72
|
+
voteCountNay: number;
|
|
73
|
+
votedAye: BN;
|
|
74
|
+
votedNay: BN;
|
|
75
|
+
votedTotal: BN;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface DeriveReferendumVotes extends DeriveReferendumVoteState {
|
|
79
|
+
isPassing: boolean;
|
|
80
|
+
votes: DeriveReferendumVote[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface DeriveReferendumExt extends DeriveReferendum, DeriveReferendumVotes {
|
|
84
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Hash, ReferendumInfoTo239, Tally } from '@pezkuwi/types/interfaces';
|
|
5
|
+
import type { FrameSupportPreimagesBounded, PalletDemocracyReferendumInfo, PalletDemocracyReferendumStatus, PalletDemocracyVoteThreshold } from '@pezkuwi/types/lookup';
|
|
6
|
+
import type { Option } from '@pezkuwi/types-codec';
|
|
7
|
+
import type { HexString } from '@pezkuwi/util/types';
|
|
8
|
+
import type { DeriveReferendum, DeriveReferendumVote, DeriveReferendumVotes, DeriveReferendumVoteState } from '../types.js';
|
|
9
|
+
|
|
10
|
+
import { BN, bnSqrt, isHex, isString, isU8a, objectSpread, stringToHex, u8aToHex } from '@pezkuwi/util';
|
|
11
|
+
|
|
12
|
+
interface ApproxState {
|
|
13
|
+
votedAye: BN;
|
|
14
|
+
votedNay: BN;
|
|
15
|
+
votedTotal: BN;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isOldInfo (info: PalletDemocracyReferendumInfo | ReferendumInfoTo239): info is ReferendumInfoTo239 {
|
|
19
|
+
return !!(info as ReferendumInfoTo239).proposalHash;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isCurrentStatus (status: PalletDemocracyReferendumStatus | ReferendumInfoTo239): status is PalletDemocracyReferendumStatus {
|
|
23
|
+
return !!(status as PalletDemocracyReferendumStatus).tally;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function compareRationals (n1: BN, d1: BN, n2: BN, d2: BN): boolean {
|
|
27
|
+
while (true) {
|
|
28
|
+
const q1 = n1.div(d1);
|
|
29
|
+
const q2 = n2.div(d2);
|
|
30
|
+
|
|
31
|
+
if (q1.lt(q2)) {
|
|
32
|
+
return true;
|
|
33
|
+
} else if (q2.lt(q1)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const r1 = n1.mod(d1);
|
|
38
|
+
const r2 = n2.mod(d2);
|
|
39
|
+
|
|
40
|
+
if (r2.isZero()) {
|
|
41
|
+
return false;
|
|
42
|
+
} else if (r1.isZero()) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
n1 = d2;
|
|
47
|
+
n2 = d1;
|
|
48
|
+
d1 = r2;
|
|
49
|
+
d2 = r1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function calcPassingOther (threshold: PalletDemocracyVoteThreshold, sqrtElectorate: BN, { votedAye, votedNay, votedTotal }: ApproxState): boolean {
|
|
54
|
+
const sqrtVoters = bnSqrt(votedTotal);
|
|
55
|
+
|
|
56
|
+
return sqrtVoters.isZero()
|
|
57
|
+
? false
|
|
58
|
+
: threshold.isSuperMajorityApprove
|
|
59
|
+
? compareRationals(votedNay, sqrtVoters, votedAye, sqrtElectorate)
|
|
60
|
+
: compareRationals(votedNay, sqrtElectorate, votedAye, sqrtVoters);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function calcPassing (threshold: PalletDemocracyVoteThreshold, sqrtElectorate: BN, state: ApproxState): boolean {
|
|
64
|
+
return threshold.isSimpleMajority
|
|
65
|
+
? state.votedAye.gt(state.votedNay)
|
|
66
|
+
: calcPassingOther(threshold, sqrtElectorate, state);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function calcVotesPrev (votesFor: DeriveReferendumVote[]): DeriveReferendumVoteState {
|
|
70
|
+
return votesFor.reduce((state: DeriveReferendumVoteState, derived): DeriveReferendumVoteState => {
|
|
71
|
+
const { balance, vote } = derived;
|
|
72
|
+
const isDefault = vote.conviction.index === 0;
|
|
73
|
+
const counted = balance
|
|
74
|
+
.muln(isDefault ? 1 : vote.conviction.index)
|
|
75
|
+
.divn(isDefault ? 10 : 1);
|
|
76
|
+
|
|
77
|
+
if (vote.isAye) {
|
|
78
|
+
state.allAye.push(derived);
|
|
79
|
+
state.voteCountAye++;
|
|
80
|
+
state.votedAye.iadd(counted);
|
|
81
|
+
} else {
|
|
82
|
+
state.allNay.push(derived);
|
|
83
|
+
state.voteCountNay++;
|
|
84
|
+
state.votedNay.iadd(counted);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
state.voteCount++;
|
|
88
|
+
state.votedTotal.iadd(counted);
|
|
89
|
+
|
|
90
|
+
return state;
|
|
91
|
+
}, { allAye: [], allNay: [], voteCount: 0, voteCountAye: 0, voteCountNay: 0, votedAye: new BN(0), votedNay: new BN(0), votedTotal: new BN(0) });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function calcVotesCurrent (tally: Tally, votes: DeriveReferendumVote[]): DeriveReferendumVoteState {
|
|
95
|
+
const allAye: DeriveReferendumVote[] = [];
|
|
96
|
+
const allNay: DeriveReferendumVote[] = [];
|
|
97
|
+
|
|
98
|
+
votes.forEach((derived): void => {
|
|
99
|
+
if (derived.vote.isAye) {
|
|
100
|
+
allAye.push(derived);
|
|
101
|
+
} else {
|
|
102
|
+
allNay.push(derived);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
allAye,
|
|
108
|
+
allNay,
|
|
109
|
+
voteCount: allAye.length + allNay.length,
|
|
110
|
+
voteCountAye: allAye.length,
|
|
111
|
+
voteCountNay: allNay.length,
|
|
112
|
+
votedAye: tally.ayes,
|
|
113
|
+
votedNay: tally.nays,
|
|
114
|
+
votedTotal: tally.turnout
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function calcVotes (sqrtElectorate: BN, referendum: DeriveReferendum, votes: DeriveReferendumVote[]): DeriveReferendumVotes {
|
|
119
|
+
const state = isCurrentStatus(referendum.status)
|
|
120
|
+
? calcVotesCurrent(referendum.status.tally, votes)
|
|
121
|
+
: calcVotesPrev(votes);
|
|
122
|
+
|
|
123
|
+
return objectSpread({}, state, {
|
|
124
|
+
isPassing: calcPassing(referendum.status.threshold, sqrtElectorate, state),
|
|
125
|
+
votes
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function getStatus (info: Option<PalletDemocracyReferendumInfo | ReferendumInfoTo239>): PalletDemocracyReferendumStatus | ReferendumInfoTo239 | null {
|
|
130
|
+
if (info.isNone) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const unwrapped = info.unwrap();
|
|
135
|
+
|
|
136
|
+
return isOldInfo(unwrapped)
|
|
137
|
+
? unwrapped
|
|
138
|
+
: unwrapped.isOngoing
|
|
139
|
+
? unwrapped.asOngoing
|
|
140
|
+
// done, we don't include it here... only currently active
|
|
141
|
+
: null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function getImageHashBounded (hash: Uint8Array | string | Hash | FrameSupportPreimagesBounded): HexString {
|
|
145
|
+
return (hash as FrameSupportPreimagesBounded).isLegacy
|
|
146
|
+
? (hash as FrameSupportPreimagesBounded).asLegacy.hash_.toHex()
|
|
147
|
+
: (hash as FrameSupportPreimagesBounded).isLookup
|
|
148
|
+
? (hash as FrameSupportPreimagesBounded).asLookup.hash_.toHex()
|
|
149
|
+
// for inline, use the actual Bytes hash
|
|
150
|
+
: (hash as FrameSupportPreimagesBounded).isInline
|
|
151
|
+
? (hash as FrameSupportPreimagesBounded).asInline.hash.toHex()
|
|
152
|
+
: isString(hash)
|
|
153
|
+
? isHex(hash)
|
|
154
|
+
? hash
|
|
155
|
+
: stringToHex(hash)
|
|
156
|
+
: isU8a(hash)
|
|
157
|
+
? u8aToHex(hash)
|
|
158
|
+
: hash.toHex();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function getImageHash (status: PalletDemocracyReferendumStatus | ReferendumInfoTo239): HexString {
|
|
162
|
+
return getImageHashBounded(
|
|
163
|
+
(status as PalletDemocracyReferendumStatus).proposal ||
|
|
164
|
+
(status as ReferendumInfoTo239).proposalHash
|
|
165
|
+
);
|
|
166
|
+
}
|
package/src/derive.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { AnyFunction } from '@pezkuwi/types/types';
|
|
5
|
+
|
|
6
|
+
import * as accounts from './accounts/index.js';
|
|
7
|
+
import * as alliance from './alliance/index.js';
|
|
8
|
+
import * as bagsList from './bagsList/index.js';
|
|
9
|
+
import * as balances from './balances/index.js';
|
|
10
|
+
import * as bounties from './bounties/index.js';
|
|
11
|
+
import * as chain from './chain/index.js';
|
|
12
|
+
import * as contracts from './contracts/index.js';
|
|
13
|
+
import * as council from './council/index.js';
|
|
14
|
+
import * as crowdloan from './crowdloan/index.js';
|
|
15
|
+
import * as democracy from './democracy/index.js';
|
|
16
|
+
import * as elections from './elections/index.js';
|
|
17
|
+
import * as imOnline from './imOnline/index.js';
|
|
18
|
+
import * as membership from './membership/index.js';
|
|
19
|
+
import * as parachains from './parachains/index.js';
|
|
20
|
+
import * as session from './session/index.js';
|
|
21
|
+
import * as society from './society/index.js';
|
|
22
|
+
import * as staking from './staking/index.js';
|
|
23
|
+
import * as technicalCommittee from './technicalCommittee/index.js';
|
|
24
|
+
import * as treasury from './treasury/index.js';
|
|
25
|
+
import * as tx from './tx/index.js';
|
|
26
|
+
|
|
27
|
+
export const derive = { accounts, alliance, bagsList, balances, bounties, chain, contracts, council, crowdloan, democracy, elections, imOnline, membership, parachains, session, society, staking, technicalCommittee, treasury, tx };
|
|
28
|
+
|
|
29
|
+
type DeriveSection<Section> = {
|
|
30
|
+
[M in keyof Section]: Section[M] extends AnyFunction
|
|
31
|
+
? ReturnType<Section[M]> // ReturnType<Section[Method]> will be the inner function, i.e. without (api) argument
|
|
32
|
+
: never;
|
|
33
|
+
};
|
|
34
|
+
type DeriveAllSections<AllSections> = {
|
|
35
|
+
[S in keyof AllSections]: DeriveSection<AllSections[S]>
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
39
|
+
export interface ExactDerive extends DeriveAllSections<typeof derive> {
|
|
40
|
+
// keep empty, allows for augmentation
|
|
41
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
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 { u32, Vec } from '@pezkuwi/types';
|
|
6
|
+
import type { AccountId32, Balance, BlockNumber } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { PalletElectionsPhragmenSeatHolder } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { ITuple } from '@pezkuwi/types/types';
|
|
9
|
+
import type { DeriveApi } from '../types.js';
|
|
10
|
+
import type { DeriveElectionsInfo } from './types.js';
|
|
11
|
+
|
|
12
|
+
import { combineLatest, map, of } from 'rxjs';
|
|
13
|
+
|
|
14
|
+
import { objectSpread } from '@pezkuwi/util';
|
|
15
|
+
|
|
16
|
+
import { memo } from '../util/index.js';
|
|
17
|
+
|
|
18
|
+
// SeatHolder is current tuple is 2.x-era Substrate
|
|
19
|
+
type Member = PalletElectionsPhragmenSeatHolder | ITuple<[AccountId32, Balance]>;
|
|
20
|
+
|
|
21
|
+
type Candidate = AccountId32 | ITuple<[AccountId32, Balance]>;
|
|
22
|
+
|
|
23
|
+
function isSeatHolder (value: Member): value is PalletElectionsPhragmenSeatHolder {
|
|
24
|
+
return !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function isCandidateTuple (value: Candidate): value is ITuple<[AccountId32, Balance]> {
|
|
28
|
+
return Array.isArray(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getAccountTuple (value: Member): [AccountId32, Balance] {
|
|
32
|
+
return isSeatHolder(value)
|
|
33
|
+
? [value.who, value.stake]
|
|
34
|
+
: value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getCandidate (value: Candidate): AccountId32 {
|
|
38
|
+
return isCandidateTuple(value)
|
|
39
|
+
? value[0]
|
|
40
|
+
: value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function sortAccounts ([, balanceA]: [AccountId32, Balance], [, balanceB]: [AccountId32, Balance]): number {
|
|
44
|
+
return balanceB.cmp(balanceA);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getConstants (api: DeriveApi, elections: string | null): Partial<DeriveElectionsInfo> {
|
|
48
|
+
return elections
|
|
49
|
+
? {
|
|
50
|
+
candidacyBond: api.consts[elections as 'elections'].candidacyBond as Balance,
|
|
51
|
+
desiredRunnersUp: api.consts[elections as 'elections'].desiredRunnersUp as u32,
|
|
52
|
+
desiredSeats: api.consts[elections as 'elections'].desiredMembers as u32,
|
|
53
|
+
termDuration: api.consts[elections as 'elections'].termDuration as BlockNumber,
|
|
54
|
+
votingBond: api.consts[elections as 'elections']['votingBond'] as Balance,
|
|
55
|
+
votingBondBase: api.consts[elections as 'elections'].votingBondBase as Balance,
|
|
56
|
+
votingBondFactor: api.consts[elections as 'elections'].votingBondFactor as Balance
|
|
57
|
+
}
|
|
58
|
+
: {};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getModules (api: DeriveApi): [string, string | null] {
|
|
62
|
+
const [council] = api.registry.getModuleInstances(api.runtimeVersion.specName, 'council') || ['council'];
|
|
63
|
+
const elections = api.query['phragmenElection']
|
|
64
|
+
? 'phragmenElection'
|
|
65
|
+
: api.query['electionsPhragmen']
|
|
66
|
+
? 'electionsPhragmen'
|
|
67
|
+
: api.query.elections
|
|
68
|
+
? 'elections'
|
|
69
|
+
: null;
|
|
70
|
+
// In some cases council here can refer to `generalCouncil` depending on what the chain specific override is.
|
|
71
|
+
// Therefore, we check to see if it exists in the query field. If it does not we default to `council`.
|
|
72
|
+
const resolvedCouncil = api.query[council] ? council : 'council';
|
|
73
|
+
|
|
74
|
+
return [resolvedCouncil, elections];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function queryAll (api: DeriveApi, council: string, elections: string): Observable<[AccountId32[], Candidate[], Member[], Member[]]> {
|
|
78
|
+
return api.queryMulti<[Vec<AccountId32>, Vec<Candidate>, Vec<Member>, Vec<Member>]>([
|
|
79
|
+
api.query[council as 'council'].members,
|
|
80
|
+
api.query[elections as 'elections'].candidates,
|
|
81
|
+
api.query[elections as 'elections'].members,
|
|
82
|
+
api.query[elections as 'elections'].runnersUp
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function queryCouncil (api: DeriveApi, council: string): Observable<[AccountId32[], Candidate[], Member[], Member[]]> {
|
|
87
|
+
return combineLatest([
|
|
88
|
+
api.query[council as 'council'].members(),
|
|
89
|
+
of<Candidate[]>([]),
|
|
90
|
+
of<Member[]>([]),
|
|
91
|
+
of<Member[]>([])
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @name info
|
|
97
|
+
* @description An object containing the combined results of the storage queries for all relevant election module properties.
|
|
98
|
+
* @example
|
|
99
|
+
* ```javascript
|
|
100
|
+
* api.derive.elections.info(({ members, candidates }) => {
|
|
101
|
+
* console.log(`There are currently ${members.length} council members and ${candidates.length} prospective council candidates.`);
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function info (instanceId: string, api: DeriveApi): () => Observable<DeriveElectionsInfo> {
|
|
106
|
+
return memo(instanceId, (): Observable<DeriveElectionsInfo> => {
|
|
107
|
+
const [council, elections] = getModules(api);
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
elections
|
|
111
|
+
? queryAll(api, council, elections)
|
|
112
|
+
: queryCouncil(api, council)
|
|
113
|
+
).pipe(
|
|
114
|
+
map(([councilMembers, candidates, members, runnersUp]): DeriveElectionsInfo =>
|
|
115
|
+
objectSpread({}, getConstants(api, elections), {
|
|
116
|
+
candidateCount: api.registry.createType('u32', candidates.length),
|
|
117
|
+
candidates: candidates.map(getCandidate),
|
|
118
|
+
members: members.length
|
|
119
|
+
? members.map(getAccountTuple).sort(sortAccounts)
|
|
120
|
+
: councilMembers.map((a): [AccountId32, Balance] => [a, api.registry.createType('Balance')]),
|
|
121
|
+
runnersUp: runnersUp.map(getAccountTuple).sort(sortAccounts)
|
|
122
|
+
})
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { u32 } from '@pezkuwi/types';
|
|
5
|
+
import type { AccountId, Balance, BlockNumber, SetIndex, VoteIndex } from '@pezkuwi/types/interfaces';
|
|
6
|
+
|
|
7
|
+
export interface DeriveElectionsInfo {
|
|
8
|
+
candidates: AccountId[];
|
|
9
|
+
candidateCount: u32;
|
|
10
|
+
candidacyBond?: Balance;
|
|
11
|
+
desiredRunnersUp?: u32;
|
|
12
|
+
desiredSeats?: u32;
|
|
13
|
+
members: [AccountId, Balance][];
|
|
14
|
+
nextVoterSet?: SetIndex;
|
|
15
|
+
runnersUp: [AccountId, Balance][];
|
|
16
|
+
termDuration?: BlockNumber;
|
|
17
|
+
voteCount?: VoteIndex;
|
|
18
|
+
voterCount?: SetIndex;
|
|
19
|
+
votingBond?: Balance;
|
|
20
|
+
votingBondBase?: Balance;
|
|
21
|
+
votingBondFactor?: Balance;
|
|
22
|
+
}
|