@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,298 @@
|
|
|
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 { AccountId, EraIndex } from '@pezkuwi/types/interfaces';
|
|
7
|
+
import type { PalletStakingStakingLedger, SpStakingExposure, SpStakingExposurePage } from '@pezkuwi/types/lookup';
|
|
8
|
+
import type { BN } from '@pezkuwi/util';
|
|
9
|
+
import type { DeriveApi, DeriveEraPoints, DeriveEraPrefs, DeriveEraRewards, DeriveEraValPoints, DeriveEraValPrefs, DeriveStakerExposure, DeriveStakerReward, DeriveStakerRewardValidator } from '../types.js';
|
|
10
|
+
import type { DeriveStakingQuery } from './types.js';
|
|
11
|
+
|
|
12
|
+
import { combineLatest, map, of, switchMap } from 'rxjs';
|
|
13
|
+
|
|
14
|
+
import { BN_BILLION, BN_ZERO, objectSpread } from '@pezkuwi/util';
|
|
15
|
+
|
|
16
|
+
import { firstMemo, memo } from '../util/index.js';
|
|
17
|
+
|
|
18
|
+
type ErasResult = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[]];
|
|
19
|
+
|
|
20
|
+
// handle compatibility between generations of structures
|
|
21
|
+
function extractCompatRewards (claimedRewardsEras: Vec<u32>, ledger?: PalletStakingStakingLedger): u32[] {
|
|
22
|
+
const l = ledger
|
|
23
|
+
? (
|
|
24
|
+
ledger.legacyClaimedRewards ||
|
|
25
|
+
(ledger as PalletStakingStakingLedger & { claimedRewards: Vec<u32> }).claimedRewards
|
|
26
|
+
)?.toArray()
|
|
27
|
+
: [] as unknown as Vec<u32>;
|
|
28
|
+
|
|
29
|
+
return (claimedRewardsEras.toArray() || []).concat(l);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseRewards (api: DeriveApi, stashId: AccountId, [erasPoints, erasPrefs, erasRewards]: ErasResult, exposures: DeriveStakerExposure[], claimedRewardsEras: Vec<u32>): DeriveStakerReward[] {
|
|
33
|
+
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
|
|
34
|
+
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: BN_ZERO, validators: {} as DeriveEraValPoints };
|
|
35
|
+
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: api.registry.createType('Balance') };
|
|
36
|
+
const { validators: allValPrefs } = erasPrefs.find((p) => p.era.eq(era)) || { validators: {} as DeriveEraValPrefs };
|
|
37
|
+
const validators: Record<string, DeriveStakerRewardValidator> = {};
|
|
38
|
+
const stakerId = stashId.toString();
|
|
39
|
+
|
|
40
|
+
Object.entries(eraValidators).forEach(([validatorId, exposure]): void => {
|
|
41
|
+
const valPoints = allValPoints[validatorId] || BN_ZERO;
|
|
42
|
+
const valComm = allValPrefs[validatorId]?.commission.unwrap() || BN_ZERO;
|
|
43
|
+
const expTotal = (exposure as SpStakingExposure).total
|
|
44
|
+
? (exposure as SpStakingExposure).total?.unwrap()
|
|
45
|
+
: (exposure as SpStakingExposurePage).pageTotal
|
|
46
|
+
? (exposure as SpStakingExposurePage).pageTotal?.unwrap()
|
|
47
|
+
: BN_ZERO;
|
|
48
|
+
let avail = BN_ZERO;
|
|
49
|
+
let value: BN | undefined;
|
|
50
|
+
|
|
51
|
+
if (!(expTotal.isZero() || valPoints.isZero() || eraPoints.isZero())) {
|
|
52
|
+
avail = eraReward.mul(valPoints).div(eraPoints);
|
|
53
|
+
|
|
54
|
+
const valCut = valComm.mul(avail).div(BN_BILLION);
|
|
55
|
+
let staked: BN;
|
|
56
|
+
|
|
57
|
+
if (validatorId === stakerId) {
|
|
58
|
+
if ((exposure as SpStakingExposure).own) {
|
|
59
|
+
staked = (exposure as SpStakingExposure).own.unwrap();
|
|
60
|
+
} else {
|
|
61
|
+
const expAccount = exposure.others.find(({ who }) => who.eq(validatorId));
|
|
62
|
+
|
|
63
|
+
staked = expAccount
|
|
64
|
+
? expAccount.value.unwrap()
|
|
65
|
+
: BN_ZERO;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
const stakerExp = exposure.others.find(({ who }) => who.eq(stakerId));
|
|
69
|
+
|
|
70
|
+
staked = stakerExp
|
|
71
|
+
? stakerExp.value.unwrap()
|
|
72
|
+
: BN_ZERO;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
value = avail.sub(valCut).imul(staked).div(expTotal).iadd(validatorId === stakerId ? valCut : BN_ZERO);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
validators[validatorId] = {
|
|
79
|
+
total: api.registry.createType('Balance', avail),
|
|
80
|
+
value: api.registry.createType('Balance', value)
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
era,
|
|
86
|
+
eraReward,
|
|
87
|
+
// This might not always be accurate as you need validator account information in order to see if the rewards have been claimed.
|
|
88
|
+
// This is possibly adjusted in `filterRewards` when need be.
|
|
89
|
+
isClaimed: claimedRewardsEras.some((c) => c.eq(era)),
|
|
90
|
+
isEmpty,
|
|
91
|
+
isValidator,
|
|
92
|
+
nominating,
|
|
93
|
+
validators
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function allUniqValidators (rewards: DeriveStakerReward[][]): [string[], string[][]] {
|
|
99
|
+
return rewards.reduce(([all, perStash]: [string[], string[][]], rewards) => {
|
|
100
|
+
const uniq: string[] = [];
|
|
101
|
+
|
|
102
|
+
perStash.push(uniq);
|
|
103
|
+
rewards.forEach(({ validators }) =>
|
|
104
|
+
Object.keys(validators).forEach((validatorId): void => {
|
|
105
|
+
if (!uniq.includes(validatorId)) {
|
|
106
|
+
uniq.push(validatorId);
|
|
107
|
+
|
|
108
|
+
if (!all.includes(validatorId)) {
|
|
109
|
+
all.push(validatorId);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
return [all, perStash];
|
|
116
|
+
}, [[], []]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function removeClaimed (validators: string[], queryValidators: DeriveStakingQuery[], reward: DeriveStakerReward, claimedRewardsEras: Vec<u32>): void {
|
|
120
|
+
const rm: string[] = [];
|
|
121
|
+
|
|
122
|
+
Object.keys(reward.validators).forEach((validatorId): void => {
|
|
123
|
+
const index = validators.indexOf(validatorId);
|
|
124
|
+
|
|
125
|
+
if (index !== -1) {
|
|
126
|
+
const valLedger = queryValidators[index].stakingLedger;
|
|
127
|
+
|
|
128
|
+
if (extractCompatRewards(claimedRewardsEras, valLedger).some((e) => reward.era?.eq(e))) {
|
|
129
|
+
rm.push(validatorId);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
rm.forEach((validatorId): void => {
|
|
135
|
+
delete reward.validators[validatorId];
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function filterRewards (eras: EraIndex[], valInfo: [string, DeriveStakingQuery][], { claimedRewardsEras, rewards, stakingLedger }: { rewards: DeriveStakerReward[]; stakingLedger: PalletStakingStakingLedger, claimedRewardsEras: Vec<u32> }): DeriveStakerReward[] {
|
|
140
|
+
const filter = eras.filter((e) => !extractCompatRewards(claimedRewardsEras, stakingLedger).some((s) => s?.eq(e)));
|
|
141
|
+
const validators = valInfo.map(([v]) => v);
|
|
142
|
+
const queryValidators = valInfo.map(([, q]) => q);
|
|
143
|
+
|
|
144
|
+
return rewards
|
|
145
|
+
.filter(({ isEmpty }) => !isEmpty)
|
|
146
|
+
.filter((reward): boolean => {
|
|
147
|
+
if (!filter.some((e) => reward.era.eq(e))) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
removeClaimed(validators, queryValidators, reward, claimedRewardsEras);
|
|
152
|
+
|
|
153
|
+
return true;
|
|
154
|
+
})
|
|
155
|
+
.filter(({ validators }) => Object.keys(validators).length !== 0)
|
|
156
|
+
.map((reward) => {
|
|
157
|
+
let isClaimed = reward.isClaimed;
|
|
158
|
+
const valKeys = Object.keys(reward.validators);
|
|
159
|
+
|
|
160
|
+
if (!reward.isClaimed && valKeys.length) {
|
|
161
|
+
for (const key of valKeys) {
|
|
162
|
+
const info = queryValidators.find((i) => i.accountId.toString() === key);
|
|
163
|
+
|
|
164
|
+
if (info) {
|
|
165
|
+
isClaimed = info.claimedRewardsEras?.toArray().some((era) => era.eq(reward.era));
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return objectSpread({}, reward, {
|
|
172
|
+
isClaimed,
|
|
173
|
+
nominators: reward.nominating.filter((n) => reward.validators[n.validatorId])
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function _stakerRewardsEras (instanceId: string, api: DeriveApi): (eras: EraIndex[], withActive?: boolean) => Observable<ErasResult> {
|
|
179
|
+
return memo(instanceId, (eras: EraIndex[], withActive = false): Observable<ErasResult> =>
|
|
180
|
+
combineLatest([
|
|
181
|
+
api.derive.staking._erasPoints(eras, withActive),
|
|
182
|
+
api.derive.staking._erasPrefs(eras, withActive),
|
|
183
|
+
api.derive.staking._erasRewards(eras, withActive)
|
|
184
|
+
])
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function _stakerRewards (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[][]> {
|
|
189
|
+
return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[], withActive = false): Observable<DeriveStakerReward[][]> => {
|
|
190
|
+
// Ensures that when number or string types are passed in they are sanitized
|
|
191
|
+
// Ref: https://github.com/polkadot-js/api/issues/5910
|
|
192
|
+
const sanitizedEras: EraIndex[] = eras.map((e) => typeof e === 'number' || typeof e === 'string' ? api.registry.createType('u32', e) : e);
|
|
193
|
+
|
|
194
|
+
return combineLatest([
|
|
195
|
+
api.derive.staking.queryMulti(accountIds, { withClaimedRewardsEras: true, withLedger: true }),
|
|
196
|
+
api.derive.staking._stakerExposures(accountIds, sanitizedEras, withActive),
|
|
197
|
+
api.derive.staking._stakerRewardsEras(sanitizedEras, withActive)
|
|
198
|
+
]).pipe(
|
|
199
|
+
switchMap(([queries, exposures, erasResult]): Observable<DeriveStakerReward[][]> => {
|
|
200
|
+
const allRewards = queries.map(({ claimedRewardsEras, stakingLedger, stashId }, index): DeriveStakerReward[] =>
|
|
201
|
+
(!stashId || (!stakingLedger && !claimedRewardsEras))
|
|
202
|
+
? []
|
|
203
|
+
: parseRewards(api, stashId, erasResult, exposures[index], claimedRewardsEras)
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
if (withActive) {
|
|
207
|
+
return of(allRewards);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const [allValidators, stashValidators] = allUniqValidators(allRewards);
|
|
211
|
+
|
|
212
|
+
return api.derive.staking.queryMulti(allValidators, { withClaimedRewardsEras: true, withLedger: true }).pipe(
|
|
213
|
+
map((queriedVals): DeriveStakerReward[][] =>
|
|
214
|
+
queries.map(({ claimedRewardsEras, stakingLedger }, index): DeriveStakerReward[] =>
|
|
215
|
+
filterRewards(
|
|
216
|
+
eras,
|
|
217
|
+
stashValidators[index]
|
|
218
|
+
.map((validatorId): [string, DeriveStakingQuery | undefined] => [
|
|
219
|
+
validatorId,
|
|
220
|
+
queriedVals.find((q) => q.accountId.eq(validatorId))
|
|
221
|
+
])
|
|
222
|
+
.filter((v): v is [string, DeriveStakingQuery] => !!v[1]),
|
|
223
|
+
{
|
|
224
|
+
claimedRewardsEras,
|
|
225
|
+
rewards: allRewards[index],
|
|
226
|
+
stakingLedger
|
|
227
|
+
}
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
);
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @name stakerRewards
|
|
240
|
+
* @description Staking rewards history for a given staker.
|
|
241
|
+
* @param { Uint8Array | string } accountId The stakers AccountId.
|
|
242
|
+
* @param { boolean } withActive Whether to include the active era.
|
|
243
|
+
* @example
|
|
244
|
+
* ```javascript
|
|
245
|
+
* const rewards = await api.derive.staking.stakerRewards(
|
|
246
|
+
* ALICE, //Alice accountId
|
|
247
|
+
* false
|
|
248
|
+
* );
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
export const stakerRewards = /*#__PURE__*/ firstMemo(
|
|
252
|
+
(api: DeriveApi, accountId: Uint8Array | string, withActive?: boolean) =>
|
|
253
|
+
api.derive.staking.erasHistoric(withActive).pipe(
|
|
254
|
+
switchMap((eras) => api.derive.staking._stakerRewards([accountId], eras, withActive))
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @name stakerRewardsMultiEras
|
|
260
|
+
* @description Staking rewards for multiple stakers over specific eras.
|
|
261
|
+
* @param { Uint8Array | string } accountIds List of stakers identified by their AccountId.
|
|
262
|
+
* @param { EraIndex[] } eras Eras for which to retrieve the data.
|
|
263
|
+
* @example
|
|
264
|
+
* ```javascript
|
|
265
|
+
* const rewards = await api.derive.staking.stakerRewardsMultiEras(
|
|
266
|
+
* [ALICE, BOB, CHARLIER], //accountIds
|
|
267
|
+
* [100,101] //eras
|
|
268
|
+
* );
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export function stakerRewardsMultiEras (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], eras: EraIndex[]) => Observable<DeriveStakerReward[][]> {
|
|
272
|
+
return memo(instanceId, (accountIds: (Uint8Array | string)[], eras: EraIndex[]): Observable<DeriveStakerReward[][]> =>
|
|
273
|
+
accountIds.length && eras.length
|
|
274
|
+
? api.derive.staking._stakerRewards(accountIds, eras, false)
|
|
275
|
+
: of([])
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @name stakerRewardsMulti
|
|
281
|
+
* @description Staking rewards for multiple stakers.
|
|
282
|
+
* @param { Uint8Array | string } accountIds List of stakers identified by their AccountId.
|
|
283
|
+
* @param { boolean } withActive Whether to include the active era.
|
|
284
|
+
* @example
|
|
285
|
+
* ```javascript
|
|
286
|
+
* const rewards = await api.derive.staking.stakerRewardsMulti(
|
|
287
|
+
* [ALICE, BOB, CHARLIER], //accountIds
|
|
288
|
+
* true
|
|
289
|
+
* );
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function stakerRewardsMulti (instanceId: string, api: DeriveApi): (accountIds: (Uint8Array | string)[], withActive?: boolean) => Observable<DeriveStakerReward[][]> {
|
|
293
|
+
return memo(instanceId, (accountIds: (Uint8Array | string)[], withActive = false): Observable<DeriveStakerReward[][]> =>
|
|
294
|
+
api.derive.staking.erasHistoric(withActive).pipe(
|
|
295
|
+
switchMap((eras) => api.derive.staking.stakerRewardsMultiEras(accountIds, eras))
|
|
296
|
+
)
|
|
297
|
+
);
|
|
298
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { EraIndex } from '@pezkuwi/types/interfaces';
|
|
6
|
+
import type { DeriveApi, DeriveStakerSlashes } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { map } from 'rxjs';
|
|
9
|
+
|
|
10
|
+
import { memo } from '../util/index.js';
|
|
11
|
+
import { erasHistoricApplyAccount } from './util.js';
|
|
12
|
+
|
|
13
|
+
export function _stakerSlashes (instanceId: string, api: DeriveApi): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable<DeriveStakerSlashes[]> {
|
|
14
|
+
return memo(instanceId, (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable<DeriveStakerSlashes[]> => {
|
|
15
|
+
const stakerId = api.registry.createType('AccountId', accountId).toString();
|
|
16
|
+
|
|
17
|
+
return api.derive.staking._erasSlashes(eras, withActive).pipe(
|
|
18
|
+
map((slashes): DeriveStakerSlashes[] =>
|
|
19
|
+
slashes.map(({ era, nominators, validators }): DeriveStakerSlashes => ({
|
|
20
|
+
era,
|
|
21
|
+
total: nominators[stakerId] || validators[stakerId] || api.registry.createType('Balance')
|
|
22
|
+
}))
|
|
23
|
+
)
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @name stakerSlashes
|
|
30
|
+
* @param { Uint8Array | string } accountId The stakers AccountId.
|
|
31
|
+
* @param { boolean } withActive Whether to include the active era.
|
|
32
|
+
* @description Retrieve the historical slashes (penalties) for a given staker.
|
|
33
|
+
* @example
|
|
34
|
+
* ```javascript
|
|
35
|
+
* const stakerSlashes = await api.derive.staking.stakerSlashes(
|
|
36
|
+
* ALICE, //Alice accountId
|
|
37
|
+
* true
|
|
38
|
+
* );
|
|
39
|
+
* console.log(
|
|
40
|
+
* 'Staker Slashes:',
|
|
41
|
+
* stakerSlashes.map(({ era, total }) => `Era ${era}: Slashed ${total.toString()}`)
|
|
42
|
+
* );
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const stakerSlashes = /*#__PURE__*/ erasHistoricApplyAccount('_stakerSlashes');
|
|
@@ -0,0 +1,55 @@
|
|
|
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 } from '@pezkuwi/types/interfaces';
|
|
6
|
+
import type { DeriveApi } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { map, startWith, switchMap } from 'rxjs';
|
|
9
|
+
|
|
10
|
+
import { drr, memo } from '../util/index.js';
|
|
11
|
+
|
|
12
|
+
function onBondedEvent (api: DeriveApi): Observable<number> {
|
|
13
|
+
let current = Date.now();
|
|
14
|
+
|
|
15
|
+
return api.query.system.events().pipe(
|
|
16
|
+
map((events): number => {
|
|
17
|
+
current = events.filter(({ event, phase }): boolean => {
|
|
18
|
+
try {
|
|
19
|
+
return phase.isApplyExtrinsic &&
|
|
20
|
+
event.section === 'staking' &&
|
|
21
|
+
event.method === 'Bonded';
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
? Date.now()
|
|
27
|
+
: current;
|
|
28
|
+
|
|
29
|
+
return current;
|
|
30
|
+
}),
|
|
31
|
+
startWith(current),
|
|
32
|
+
drr({ skipTimeout: true })
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @name stashes
|
|
38
|
+
* @description Retrieve the list of all validator stashes.
|
|
39
|
+
* @example
|
|
40
|
+
* ```javascript
|
|
41
|
+
* const stashes = await api.derive.staking.stashes();
|
|
42
|
+
* console.log(
|
|
43
|
+
* "Validator Stashes:",
|
|
44
|
+
* stashes.map((s) => s.toString())
|
|
45
|
+
* );
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function stashes (instanceId: string, api: DeriveApi): () => Observable<AccountId[]> {
|
|
49
|
+
return memo(instanceId, (): Observable<AccountId[]> =>
|
|
50
|
+
onBondedEvent(api).pipe(
|
|
51
|
+
switchMap(() => api.query.staking.validators.keys()),
|
|
52
|
+
map((keys) => keys.map(({ args: [v] }) => v).filter((a) => a))
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/api-derive authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Option, u32, Vec } from '@pezkuwi/types';
|
|
5
|
+
import type { AccountId, Balance, EraIndex, RewardPoint } from '@pezkuwi/types/interfaces';
|
|
6
|
+
import type { PalletStakingRewardDestination, PalletStakingStakingLedger, PalletStakingValidatorPrefs, SpStakingExposure, SpStakingExposurePage, SpStakingPagedExposureMetadata } from '@pezkuwi/types/lookup';
|
|
7
|
+
import type { BN } from '@pezkuwi/util';
|
|
8
|
+
import type { DeriveSessionIndexes } from '../session/types.js';
|
|
9
|
+
|
|
10
|
+
export type DeriveEraValPoints = Record<string, RewardPoint>;
|
|
11
|
+
|
|
12
|
+
export type DeriveEraValPrefs = Record<string, PalletStakingValidatorPrefs>;
|
|
13
|
+
|
|
14
|
+
export type DeriveEraValSlash = Record<string, Balance>;
|
|
15
|
+
|
|
16
|
+
export interface DeriveEraPoints {
|
|
17
|
+
era: EraIndex;
|
|
18
|
+
eraPoints: RewardPoint;
|
|
19
|
+
validators: DeriveEraValPoints;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface DeriveEraPrefs {
|
|
23
|
+
era: EraIndex;
|
|
24
|
+
validators: DeriveEraValPrefs;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface DeriveEraRewards {
|
|
28
|
+
era: EraIndex;
|
|
29
|
+
eraReward: Balance;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface DeriveEraSlashes {
|
|
33
|
+
era: EraIndex;
|
|
34
|
+
nominators: DeriveEraValSlash;
|
|
35
|
+
validators: DeriveEraValSlash;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DeriveStakerPoints {
|
|
39
|
+
era: EraIndex;
|
|
40
|
+
eraPoints: RewardPoint;
|
|
41
|
+
points: RewardPoint;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface DeriveOwnExposure {
|
|
45
|
+
clipped: SpStakingExposure;
|
|
46
|
+
exposurePaged: Option<SpStakingExposurePage>;
|
|
47
|
+
era: EraIndex;
|
|
48
|
+
exposure: SpStakingExposure;
|
|
49
|
+
exposureMeta: Option<SpStakingPagedExposureMetadata>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface DeriveEraExposureNominating {
|
|
53
|
+
validatorId: string;
|
|
54
|
+
validatorIndex: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type DeriveEraNominatorExposure = Record<string, DeriveEraExposureNominating[]>;
|
|
58
|
+
|
|
59
|
+
export type DeriveEraValidatorExposure = Record<string, SpStakingExposure>;
|
|
60
|
+
|
|
61
|
+
export type DeriveEraValidatorExposurePaged = Record<string, SpStakingExposurePage | SpStakingExposure>;
|
|
62
|
+
|
|
63
|
+
export interface DeriveEraExposure {
|
|
64
|
+
era: EraIndex;
|
|
65
|
+
nominators: DeriveEraNominatorExposure;
|
|
66
|
+
validators: DeriveEraValidatorExposure;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface DeriveEraExposurePaged {
|
|
70
|
+
era: EraIndex;
|
|
71
|
+
nominators: DeriveEraNominatorExposure;
|
|
72
|
+
validators: DeriveEraValidatorExposurePaged;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface DeriveStakerExposure {
|
|
76
|
+
era: EraIndex;
|
|
77
|
+
isEmpty: boolean;
|
|
78
|
+
isValidator: boolean;
|
|
79
|
+
nominating: DeriveEraExposureNominating[];
|
|
80
|
+
validators: DeriveEraValidatorExposurePaged;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface DeriveStakerPrefs {
|
|
84
|
+
era: EraIndex;
|
|
85
|
+
validatorPrefs: PalletStakingValidatorPrefs;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface DeriveStakerRewardValidator {
|
|
89
|
+
total: Balance;
|
|
90
|
+
value: Balance;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface DeriveStakerReward {
|
|
94
|
+
era: EraIndex;
|
|
95
|
+
eraReward: Balance;
|
|
96
|
+
isClaimed: boolean;
|
|
97
|
+
isEmpty: boolean;
|
|
98
|
+
isValidator: boolean;
|
|
99
|
+
nominating: DeriveEraExposureNominating[];
|
|
100
|
+
validators: Record<string, DeriveStakerRewardValidator>;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface DeriveStakerSlashes {
|
|
104
|
+
era: EraIndex;
|
|
105
|
+
total: Balance;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export type DeriveOwnSlashes = DeriveStakerSlashes;
|
|
109
|
+
|
|
110
|
+
export interface DeriveStakingKeys {
|
|
111
|
+
nextSessionIds: AccountId[];
|
|
112
|
+
sessionIds: AccountId[];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface DeriveStakingValidators {
|
|
116
|
+
nextElected: AccountId[];
|
|
117
|
+
validators: AccountId[];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface DeriveStakingStash {
|
|
121
|
+
controllerId: AccountId | null;
|
|
122
|
+
// Legacy Support for erasStakers
|
|
123
|
+
exposureEraStakers: SpStakingExposure;
|
|
124
|
+
exposurePaged: Option<SpStakingExposurePage>;
|
|
125
|
+
exposureMeta: Option<SpStakingPagedExposureMetadata>;
|
|
126
|
+
nominators: AccountId[];
|
|
127
|
+
rewardDestination: PalletStakingRewardDestination | null;
|
|
128
|
+
stashId: AccountId;
|
|
129
|
+
validatorPrefs: PalletStakingValidatorPrefs;
|
|
130
|
+
claimedRewardsEras: Vec<u32>
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface DeriveStakingQuery extends DeriveStakingStash {
|
|
134
|
+
accountId: AccountId;
|
|
135
|
+
stakingLedger: PalletStakingStakingLedger;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface DeriveStakingElected {
|
|
139
|
+
info: DeriveStakingQuery[];
|
|
140
|
+
nextElected: AccountId[];
|
|
141
|
+
validators: AccountId[];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface DeriveStakingWaiting {
|
|
145
|
+
info: DeriveStakingQuery[];
|
|
146
|
+
waiting: AccountId[];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface DeriveUnlocking {
|
|
150
|
+
remainingEras: BN;
|
|
151
|
+
value: Balance;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface DeriveStakingAccount extends DeriveStakingQuery, DeriveStakingKeys {
|
|
155
|
+
redeemable?: Balance;
|
|
156
|
+
unlocking?: DeriveUnlocking[];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface DeriveStakingOverview extends DeriveSessionIndexes {
|
|
160
|
+
nextElected: AccountId[];
|
|
161
|
+
validators: AccountId[];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface StakingQueryFlags {
|
|
165
|
+
withController?: boolean;
|
|
166
|
+
withDestination?: boolean;
|
|
167
|
+
withExposure?: boolean;
|
|
168
|
+
withExposureErasStakersLegacy?: boolean,
|
|
169
|
+
withLedger?: boolean;
|
|
170
|
+
withNominations?: boolean;
|
|
171
|
+
withPrefs?: boolean;
|
|
172
|
+
withExposureMeta?: boolean;
|
|
173
|
+
withClaimedRewardsEras?: boolean;
|
|
174
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
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 { ObsInnerType } from '@pezkuwi/api-base/types';
|
|
6
|
+
import type { u32 } from '@pezkuwi/types';
|
|
7
|
+
import type { EraIndex } from '@pezkuwi/types/interfaces';
|
|
8
|
+
import type { AnyNumber } from '@pezkuwi/types-codec/types';
|
|
9
|
+
import type { ExactDerive } from '../derive.js';
|
|
10
|
+
import type { DeriveApi } from '../types.js';
|
|
11
|
+
|
|
12
|
+
import { BehaviorSubject, combineLatest, map, of, switchMap, tap, toArray } from 'rxjs';
|
|
13
|
+
|
|
14
|
+
import { arrayChunk, arrayFlatten, nextTick } from '@pezkuwi/util';
|
|
15
|
+
|
|
16
|
+
import { memo } from '../util/index.js';
|
|
17
|
+
|
|
18
|
+
type ApplyReturn<T extends keyof ExactDerive['staking']> = ReturnType<ExactDerive['staking'][T]>;
|
|
19
|
+
|
|
20
|
+
// only retrieve a maximum of 14 eras (84 / 6) at a time
|
|
21
|
+
// (This is not empirically calculated. Rather smaller sizes take longer
|
|
22
|
+
// time due to the serial nature, large sizes may tie up the RPCs)
|
|
23
|
+
const ERA_CHUNK_SIZE = 14;
|
|
24
|
+
|
|
25
|
+
function chunkEras <T> (eras: EraIndex[], fn: (eras: EraIndex[]) => Observable<T[]>): Observable<T[]> {
|
|
26
|
+
const chunked = arrayChunk(eras, ERA_CHUNK_SIZE);
|
|
27
|
+
let index = 0;
|
|
28
|
+
const subject = new BehaviorSubject<EraIndex[]>(chunked[index]);
|
|
29
|
+
|
|
30
|
+
return subject.pipe(
|
|
31
|
+
switchMap(fn),
|
|
32
|
+
tap((): void => {
|
|
33
|
+
nextTick((): void => {
|
|
34
|
+
index++;
|
|
35
|
+
|
|
36
|
+
index === chunked.length
|
|
37
|
+
? subject.complete()
|
|
38
|
+
: subject.next(chunked[index]);
|
|
39
|
+
});
|
|
40
|
+
}),
|
|
41
|
+
toArray(),
|
|
42
|
+
map(arrayFlatten)
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function filterEras <T extends { era: EraIndex }> (eras: EraIndex[], list: T[]): EraIndex[] {
|
|
47
|
+
return eras.filter((e) => !list.some(({ era }) => e.eq(era)));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function erasHistoricApply <F extends '_erasExposure' | '_erasPoints' | '_erasPrefs' | '_erasRewards' | '_erasSlashes'> (fn: F): (instanceId: string, api: DeriveApi) => (withActive?: boolean) => ApplyReturn<F> {
|
|
51
|
+
return (instanceId: string, api: DeriveApi) =>
|
|
52
|
+
// Cannot quite get the typing right, but it is right in the code
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
54
|
+
memo(instanceId, (withActive = false) =>
|
|
55
|
+
api.derive.staking.erasHistoric(withActive).pipe(
|
|
56
|
+
switchMap((e) => api.derive.staking[fn](e, withActive))
|
|
57
|
+
)
|
|
58
|
+
) as any;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function erasHistoricApplyAccount <F extends '_ownExposures' | '_ownSlashes' | '_stakerPoints' | '_stakerPrefs' | '_stakerSlashes'> (fn: F): (instanceId: string, api: DeriveApi) => (accountId: string | Uint8Array, withActive?: boolean) => ApplyReturn<F> {
|
|
62
|
+
return (instanceId: string, api: DeriveApi) =>
|
|
63
|
+
// Cannot quite get the typing right, but it is right in the code
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
65
|
+
memo(instanceId, (accountId: string | Uint8Array, withActive = false, page?: u32 | AnyNumber) =>
|
|
66
|
+
api.derive.staking.erasHistoric(withActive).pipe(
|
|
67
|
+
switchMap((e) => api.derive.staking[fn](accountId, e, withActive, page || 0))
|
|
68
|
+
)
|
|
69
|
+
) as any;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function singleEra <F extends '_eraExposure' | '_eraPrefs' | '_eraSlashes'> (fn: F): (instanceId: string, api: DeriveApi) => (era: EraIndex) => ApplyReturn<F> {
|
|
73
|
+
return (instanceId: string, api: DeriveApi) =>
|
|
74
|
+
// Cannot quite get the typing right, but it is right in the code
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
76
|
+
memo(instanceId, (era: EraIndex) =>
|
|
77
|
+
api.derive.staking[fn](era, true)
|
|
78
|
+
) as any;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function combineEras <F extends '_eraExposure' | '_eraPrefs' | '_eraSlashes'> (fn: F): (instanceId: string, api: DeriveApi) => (eras: EraIndex[], withActive: boolean) => Observable<ObsInnerType<ApplyReturn<F>>[]> {
|
|
82
|
+
return (instanceId: string, api: DeriveApi) =>
|
|
83
|
+
// Cannot quite get the typing right, but it is right in the code
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
85
|
+
memo(instanceId, (eras: EraIndex[], withActive: boolean) =>
|
|
86
|
+
!eras.length
|
|
87
|
+
? of([])
|
|
88
|
+
: chunkEras(eras, (eras) =>
|
|
89
|
+
combineLatest(
|
|
90
|
+
eras.map((e) => api.derive.staking[fn](e, withActive))
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
) as any;
|
|
94
|
+
}
|