@substrate/api-sidecar 17.5.0 → 17.5.2
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/build/package.json +11 -11
- package/build/src/controllers/accounts/AccountsStakingPayoutsController.js +51 -11
- package/build/src/controllers/accounts/AccountsStakingPayoutsController.js.map +1 -1
- package/build/src/services/accounts/AccountsStakingPayoutsService.d.ts +45 -17
- package/build/src/services/accounts/AccountsStakingPayoutsService.js +170 -40
- package/build/src/services/accounts/AccountsStakingPayoutsService.js.map +1 -1
- package/build/src/services/accounts/kusamaEarlyErasBlockInfo.json +2082 -0
- package/package.json +11 -11
package/build/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "17.5.
|
|
2
|
+
"version": "17.5.2",
|
|
3
3
|
"name": "@substrate/api-sidecar",
|
|
4
4
|
"description": "REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.",
|
|
5
5
|
"homepage": "https://github.com/paritytech/substrate-api-sidecar#readme",
|
|
@@ -50,29 +50,29 @@
|
|
|
50
50
|
"test:test-release": "yarn build:scripts && node scripts/build/runYarnPack.js"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@polkadot/api": "^10.11.
|
|
54
|
-
"@polkadot/api-contract": "^10.11.
|
|
53
|
+
"@polkadot/api": "^10.11.3",
|
|
54
|
+
"@polkadot/api-contract": "^10.11.3",
|
|
55
55
|
"@polkadot/util-crypto": "^12.6.2",
|
|
56
56
|
"@substrate/calc": "^0.3.1",
|
|
57
57
|
"argparse": "^2.0.1",
|
|
58
58
|
"confmgr": "^1.0.10",
|
|
59
|
-
"express": "^4.18.
|
|
59
|
+
"express": "^4.18.2",
|
|
60
60
|
"express-winston": "^4.2.0",
|
|
61
61
|
"http-errors": "^2.0.0",
|
|
62
62
|
"lru-cache": "^7.13.1",
|
|
63
63
|
"prom-client": "^14.2.0",
|
|
64
|
-
"rxjs": "^7.
|
|
65
|
-
"winston": "^3.
|
|
64
|
+
"rxjs": "^7.8.1",
|
|
65
|
+
"winston": "^3.11.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@substrate/dev": "^0.7.1",
|
|
69
|
-
"@types/argparse": "2.0.
|
|
70
|
-
"@types/express": "^4.17.
|
|
71
|
-
"@types/express-serve-static-core": "^4.17.
|
|
69
|
+
"@types/argparse": "2.0.14",
|
|
70
|
+
"@types/express": "^4.17.21",
|
|
71
|
+
"@types/express-serve-static-core": "^4.17.43",
|
|
72
72
|
"@types/http-errors": "1.8.2",
|
|
73
73
|
"@types/lru-cache": "^7.10.10",
|
|
74
|
-
"@types/morgan": "1.9.
|
|
75
|
-
"@types/triple-beam": "^1.3.
|
|
74
|
+
"@types/morgan": "1.9.9",
|
|
75
|
+
"@types/triple-beam": "^1.3.5",
|
|
76
76
|
"ts-node-dev": "^2.0.0"
|
|
77
77
|
},
|
|
78
78
|
"keywords": [
|
|
@@ -23,6 +23,7 @@ const bn_js_1 = __importDefault(require("bn.js"));
|
|
|
23
23
|
const http_errors_1 = require("http-errors");
|
|
24
24
|
const middleware_1 = require("../../middleware");
|
|
25
25
|
const services_1 = require("../../services");
|
|
26
|
+
const kusamaEarlyErasBlockInfo_json_1 = __importDefault(require("../../services/accounts/kusamaEarlyErasBlockInfo.json"));
|
|
26
27
|
const AbstractController_1 = __importDefault(require("../AbstractController"));
|
|
27
28
|
/**
|
|
28
29
|
* GET payout information for a stash account.
|
|
@@ -85,11 +86,27 @@ class AccountsStakingPayoutsController extends AbstractController_1.default {
|
|
|
85
86
|
* @param res Express Response
|
|
86
87
|
*/
|
|
87
88
|
this.getStakingPayoutsByAccountId = async ({ params: { address }, query: { depth, era, unclaimedOnly, at } }, res) => {
|
|
88
|
-
const
|
|
89
|
-
|
|
89
|
+
const earlyErasBlockInfo = kusamaEarlyErasBlockInfo_json_1.default;
|
|
90
|
+
let hash = await this.getHashFromAt(at);
|
|
91
|
+
let apiAt = await this.api.at(hash);
|
|
90
92
|
const { eraArg, currentEra } = await this.getEraAndHash(apiAt, this.verifyAndCastOr('era', era, undefined));
|
|
93
|
+
if (currentEra <= 519 && depth !== undefined) {
|
|
94
|
+
throw new http_errors_1.InternalServerError('The `depth` query parameter is disabled for eras less than 518.');
|
|
95
|
+
}
|
|
96
|
+
else if (currentEra <= 519 && era !== undefined) {
|
|
97
|
+
throw new http_errors_1.InternalServerError('The `era` query parameter is disabled for eras less than 518.');
|
|
98
|
+
}
|
|
99
|
+
let sanitizedDepth;
|
|
100
|
+
if (depth) {
|
|
101
|
+
sanitizedDepth = Math.min(Number(depth), currentEra - 518).toString();
|
|
102
|
+
}
|
|
103
|
+
if (currentEra < 518) {
|
|
104
|
+
const eraStartBlock = earlyErasBlockInfo[currentEra].start;
|
|
105
|
+
hash = await this.getHashFromAt(eraStartBlock.toString());
|
|
106
|
+
apiAt = await this.api.at(hash);
|
|
107
|
+
}
|
|
91
108
|
const unclaimedOnlyArg = unclaimedOnly === 'false' ? false : true;
|
|
92
|
-
AccountsStakingPayoutsController.sanitizedSend(res, await this.service.fetchAccountStakingPayout(hash, address, this.verifyAndCastOr('depth',
|
|
109
|
+
AccountsStakingPayoutsController.sanitizedSend(res, await this.service.fetchAccountStakingPayout(hash, address, this.verifyAndCastOr('depth', sanitizedDepth, 1), eraArg, unclaimedOnlyArg, currentEra, apiAt));
|
|
93
110
|
};
|
|
94
111
|
this.initRoutes();
|
|
95
112
|
}
|
|
@@ -98,15 +115,8 @@ class AccountsStakingPayoutsController extends AbstractController_1.default {
|
|
|
98
115
|
this.safeMountAsyncGetHandlers([['', this.getStakingPayoutsByAccountId]]);
|
|
99
116
|
}
|
|
100
117
|
async getEraAndHash(apiAt, era) {
|
|
101
|
-
const [activeEraOption, currentEraMaybeOption] = await Promise.all([
|
|
102
|
-
apiAt.query.staking.activeEra(),
|
|
103
|
-
apiAt.query.staking.currentEra(),
|
|
104
|
-
]);
|
|
105
|
-
if (activeEraOption.isNone) {
|
|
106
|
-
throw new http_errors_1.InternalServerError('ActiveEra is None when Some was expected');
|
|
107
|
-
}
|
|
108
|
-
const activeEra = activeEraOption.unwrap().index.toNumber();
|
|
109
118
|
let currentEra;
|
|
119
|
+
const currentEraMaybeOption = (await apiAt.query.staking.currentEra());
|
|
110
120
|
if (currentEraMaybeOption instanceof types_1.Option) {
|
|
111
121
|
if (currentEraMaybeOption.isNone) {
|
|
112
122
|
throw new http_errors_1.InternalServerError('CurrentEra is None when Some was expected');
|
|
@@ -120,6 +130,36 @@ class AccountsStakingPayoutsController extends AbstractController_1.default {
|
|
|
120
130
|
else {
|
|
121
131
|
throw new http_errors_1.InternalServerError('Query for current_era returned a non-processable result.');
|
|
122
132
|
}
|
|
133
|
+
let activeEra;
|
|
134
|
+
if (apiAt.query.staking.activeEra) {
|
|
135
|
+
const activeEraOption = await apiAt.query.staking.activeEra();
|
|
136
|
+
if (activeEraOption.isNone) {
|
|
137
|
+
const historicActiveEra = await apiAt.query.staking.currentEra();
|
|
138
|
+
if (historicActiveEra.isNone) {
|
|
139
|
+
throw new http_errors_1.InternalServerError('ActiveEra is None when Some was expected');
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
activeEra = historicActiveEra.unwrap().toNumber();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
activeEra = activeEraOption.unwrap().index.toNumber();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const sessionIndex = await apiAt.query.session.currentIndex();
|
|
151
|
+
const idx = sessionIndex.toNumber() % 6;
|
|
152
|
+
// https://substrate.stackexchange.com/a/2026/1786
|
|
153
|
+
if (currentEra < 518) {
|
|
154
|
+
activeEra = currentEra;
|
|
155
|
+
}
|
|
156
|
+
else if (idx > 0) {
|
|
157
|
+
activeEra = currentEra;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
activeEra = currentEra - 1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
123
163
|
if (era !== undefined && era > activeEra - 1) {
|
|
124
164
|
throw new http_errors_1.BadRequest(`The specified era (${era}) is too large. ` + `Largest era payout info is available for is ${activeEra - 1}`);
|
|
125
165
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsStakingPayoutsController.js","sourceRoot":"","sources":["../../../../src/controllers/accounts/AccountsStakingPayoutsController.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,8CAA8C;AAC9C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,oEAAoE;AACpE,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,iEAAiE;AACjE,gEAAgE;AAChE,+CAA+C;AAC/C,EAAE;AACF,oEAAoE;AACpE,wEAAwE;;;;;AAIxE,
|
|
1
|
+
{"version":3,"file":"AccountsStakingPayoutsController.js","sourceRoot":"","sources":["../../../../src/controllers/accounts/AccountsStakingPayoutsController.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,8CAA8C;AAC9C,EAAE;AACF,gFAAgF;AAChF,uEAAuE;AACvE,oEAAoE;AACpE,sCAAsC;AACtC,EAAE;AACF,kEAAkE;AAClE,iEAAiE;AACjE,gEAAgE;AAChE,+CAA+C;AAC/C,EAAE;AACF,oEAAoE;AACpE,wEAAwE;;;;;AAIxE,2CAA8C;AAC9C,kDAAuB;AAEvB,6CAA8D;AAE9D,iDAAoE;AACpE,6CAA+D;AAE/D,0HAA6F;AAE7F,+EAAuD;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAqB,gCAAiC,SAAQ,4BAAiD;IAC9G,YAAY,GAAe;QAC1B,KAAK,CAAC,GAAG,EAAE,oCAAoC,EAAE,IAAI,wCAA6B,CAAC,GAAG,CAAC,CAAC,CAAC;QAU1F;;;;;WAKG;QACK,iCAA4B,GAAkC,KAAK,EAC1E,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,EACjE,GAAG,EACa,EAAE;YAClB,MAAM,kBAAkB,GAAwB,uCAAwB,CAAC;YACzE,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YACxC,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;YAC5G,IAAI,UAAU,IAAI,GAAG,IAAI,KAAK,KAAK,SAAS,EAAE;gBAC7C,MAAM,IAAI,iCAAmB,CAAC,iEAAiE,CAAC,CAAC;aACjG;iBAAM,IAAI,UAAU,IAAI,GAAG,IAAI,GAAG,KAAK,SAAS,EAAE;gBAClD,MAAM,IAAI,iCAAmB,CAAC,+DAA+D,CAAC,CAAC;aAC/F;YACD,IAAI,cAAkC,CAAC;YACvC,IAAI,KAAK,EAAE;gBACV,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;aACtE;YACD,IAAI,UAAU,GAAG,GAAG,EAAE;gBACrB,MAAM,aAAa,GAAW,kBAAkB,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC;gBACnE,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1D,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;aAChC;YAED,MAAM,gBAAgB,GAAG,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;YAElE,gCAAgC,CAAC,aAAa,CAC7C,GAAG,EACH,MAAM,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAC3C,IAAI,EACJ,OAAO,EACP,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,CAAW,EAC1D,MAAM,EACN,gBAAgB,EAChB,UAAU,EACV,KAAK,CACL,CACD,CAAC;QACH,CAAC,CAAC;QApDD,IAAI,CAAC,UAAU,EAAE,CAAC;IACnB,CAAC;IAES,UAAU;QACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,4BAAe,EAAE,IAAA,4BAAe,EAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEhF,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IA+CO,KAAK,CAAC,aAAa,CAAC,KAA+B,EAAE,GAAY;QACxE,IAAI,UAAkB,CAAC;QACvB,MAAM,qBAAqB,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAsB,CAAC;QAC5F,IAAI,qBAAqB,YAAY,cAAM,EAAE;YAC5C,IAAI,qBAAqB,CAAC,MAAM,EAAE;gBACjC,MAAM,IAAI,iCAAmB,CAAC,2CAA2C,CAAC,CAAC;aAC3E;YAED,UAAU,GAAG,qBAAqB,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;SACvD;aAAM,IAAK,qBAAiC,YAAY,eAAE,EAAE;YAC5D,uEAAuE;YACvE,UAAU,GAAI,qBAA4B,CAAC,QAAQ,EAAE,CAAC;SACtD;aAAM;YACN,MAAM,IAAI,iCAAmB,CAAC,0DAA0D,CAAC,CAAC;SAC1F;QAED,IAAI,SAAS,CAAC;QACd,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE;YAClC,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC9D,IAAI,eAAe,CAAC,MAAM,EAAE;gBAC3B,MAAM,iBAAiB,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACjE,IAAI,iBAAiB,CAAC,MAAM,EAAE;oBAC7B,MAAM,IAAI,iCAAmB,CAAC,0CAA0C,CAAC,CAAC;iBAC1E;qBAAM;oBACN,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC;iBAClD;aACD;iBAAM;gBACN,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;aACtD;SACD;aAAM;YACN,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC9D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACxC,kDAAkD;YAClD,IAAI,UAAU,GAAG,GAAG,EAAE;gBACrB,SAAS,GAAG,UAAU,CAAC;aACvB;iBAAM,IAAI,GAAG,GAAG,CAAC,EAAE;gBACnB,SAAS,GAAG,UAAU,CAAC;aACvB;iBAAM;gBACN,SAAS,GAAG,UAAU,GAAG,CAAC,CAAC;aAC3B;SACD;QAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,SAAS,GAAG,CAAC,EAAE;YAC7C,MAAM,IAAI,wBAAU,CACnB,sBAAsB,GAAG,kBAAkB,GAAG,+CAA+C,SAAS,GAAG,CAAC,EAAE,CAC5G,CAAC;SACF;QAED,OAAO;YACN,MAAM,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;YAC/C,UAAU;SACV,CAAC;IACH,CAAC;CACD;AA9GD,mDA8GC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ApiDecoration } from '@polkadot/api/types';
|
|
2
2
|
import type { DeriveEraExposure, DeriveEraExposureNominating } from '@polkadot/api-derive/staking/types';
|
|
3
|
-
import
|
|
4
|
-
import type { BalanceOf, BlockHash, EraIndex, Perbill } from '@polkadot/types/interfaces';
|
|
3
|
+
import { Option } from '@polkadot/types';
|
|
4
|
+
import type { BalanceOf, BlockHash, EraIndex, EraPoints, Perbill } from '@polkadot/types/interfaces';
|
|
5
5
|
import type { PalletStakingEraRewardPoints, PalletStakingStakingLedger } from '@polkadot/types/lookup';
|
|
6
6
|
import type { IAccountStakingPayouts, IEraPayouts } from '../../types/responses';
|
|
7
7
|
import { AbstractService } from '../AbstractService';
|
|
@@ -9,7 +9,20 @@ import { AbstractService } from '../AbstractService';
|
|
|
9
9
|
* General information about an era, in tuple form because we initially get it
|
|
10
10
|
* by destructuring a Promise.all(...)
|
|
11
11
|
*/
|
|
12
|
-
type IErasGeneral = [
|
|
12
|
+
type IErasGeneral = [IAdjustedDeriveEraExposure, PalletStakingEraRewardPoints | EraPoints, Option<BalanceOf>];
|
|
13
|
+
/**
|
|
14
|
+
* Index of the validator for eras previous to 518
|
|
15
|
+
*/
|
|
16
|
+
interface ValidatorIndex {
|
|
17
|
+
[x: string]: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Adapted AdjustedDeriveEraExposure interface for compatibility with eras
|
|
21
|
+
* previous to 518
|
|
22
|
+
*/
|
|
23
|
+
interface IAdjustedDeriveEraExposure extends DeriveEraExposure {
|
|
24
|
+
validatorIndex?: ValidatorIndex;
|
|
25
|
+
}
|
|
13
26
|
/**
|
|
14
27
|
* Commission and staking ledger of a validator
|
|
15
28
|
*/
|
|
@@ -21,14 +34,28 @@ interface ICommissionAndLedger {
|
|
|
21
34
|
* All the data we need to calculate payouts for an address at a given era.
|
|
22
35
|
*/
|
|
23
36
|
interface IEraData {
|
|
24
|
-
deriveEraExposure:
|
|
25
|
-
eraRewardPoints: PalletStakingEraRewardPoints;
|
|
37
|
+
deriveEraExposure: IAdjustedDeriveEraExposure;
|
|
38
|
+
eraRewardPoints: PalletStakingEraRewardPoints | EraPoints;
|
|
26
39
|
erasValidatorRewardOption: Option<BalanceOf>;
|
|
27
40
|
exposuresWithCommission?: (ICommissionAndLedger & {
|
|
28
41
|
validatorId: string;
|
|
29
42
|
})[];
|
|
30
43
|
eraIndex: EraIndex;
|
|
31
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Block information relevant for compatibility with eras previous
|
|
47
|
+
* to 518
|
|
48
|
+
*/
|
|
49
|
+
interface IBlockInfo {
|
|
50
|
+
height: string;
|
|
51
|
+
hash: BlockHash;
|
|
52
|
+
}
|
|
53
|
+
export interface IEarlyErasBlockInfo {
|
|
54
|
+
[era: string]: {
|
|
55
|
+
start: number;
|
|
56
|
+
end: number;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
32
59
|
export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
33
60
|
/**
|
|
34
61
|
* Fetch and derive payouts for `address`.
|
|
@@ -45,22 +72,22 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
45
72
|
/**
|
|
46
73
|
* Fetch general info about eras in the inclusive range `startEra` .. `era`.
|
|
47
74
|
*
|
|
48
|
-
* @param api
|
|
49
|
-
* @param hash `BlockHash` to make call at
|
|
75
|
+
* @param historicApi Historic api for querying past blocks
|
|
50
76
|
* @param startEra first era to get data for
|
|
51
77
|
* @param era the last era to get data for
|
|
78
|
+
* @param blockNumber block information to ensure compatibility with older eras
|
|
52
79
|
*/
|
|
53
|
-
fetchAllErasGeneral(historicApi: ApiDecoration<'promise'>, startEra: number, era: number): Promise<IErasGeneral[]>;
|
|
80
|
+
fetchAllErasGeneral(historicApi: ApiDecoration<'promise'>, startEra: number, era: number, blockNumber: IBlockInfo): Promise<IErasGeneral[]>;
|
|
81
|
+
private fetchHistoricRewardPoints;
|
|
54
82
|
/**
|
|
55
83
|
* Fetch the commission & staking ledger for each `validatorId` in `deriveErasExposures`.
|
|
56
84
|
*
|
|
57
|
-
* @param api
|
|
58
|
-
* @param hash `BlockHash` to make call at
|
|
85
|
+
* @param historicApi Historic api for querying past blocks
|
|
59
86
|
* @param address address of the _Stash_ account to get the payouts of
|
|
60
87
|
* @param startEra first era to get data for
|
|
61
88
|
* @param deriveErasExposures exposures per era for `address`
|
|
62
89
|
*/
|
|
63
|
-
fetchAllErasCommissions(historicApi: ApiDecoration<'promise'>, address: string, startEra: number, deriveErasExposures:
|
|
90
|
+
fetchAllErasCommissions(historicApi: ApiDecoration<'promise'>, address: string, startEra: number, deriveErasExposures: IAdjustedDeriveEraExposure[]): Promise<ICommissionAndLedger[][]>;
|
|
64
91
|
/**
|
|
65
92
|
* Derive all the payouts for `address` at `era`.
|
|
66
93
|
*
|
|
@@ -74,10 +101,9 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
74
101
|
/**
|
|
75
102
|
* Fetch the `commission` and `StakingLedger` of `validatorId`.
|
|
76
103
|
*
|
|
77
|
-
* @param api
|
|
104
|
+
* @param historicApi Historic api for querying past blocks
|
|
78
105
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
79
106
|
* @param era the era to query
|
|
80
|
-
* @param hash `BlockHash` to make call at
|
|
81
107
|
* @param validatorLedgerCache object mapping validatorId => StakingLedger to limit redundant queries
|
|
82
108
|
*/
|
|
83
109
|
private fetchCommissionAndLedger;
|
|
@@ -88,8 +114,8 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
88
114
|
* The original version uses the base ApiDerive implementation which does not include the ApiDecoration implementation.
|
|
89
115
|
* It is required in this version to query older blocks for their historic data.
|
|
90
116
|
*
|
|
91
|
-
* @param historicApi
|
|
92
|
-
* @param eraIndex
|
|
117
|
+
* @param historicApi Historic api for querying past blocks
|
|
118
|
+
* @param eraIndex index of the era to query
|
|
93
119
|
*/
|
|
94
120
|
private deriveEraExposure;
|
|
95
121
|
/**
|
|
@@ -97,6 +123,8 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
97
123
|
*
|
|
98
124
|
* @param eraRewardPoints
|
|
99
125
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
126
|
+
* @param validatorIndex index of the validator in relation to the `EraPoints`
|
|
127
|
+
* array
|
|
100
128
|
* */
|
|
101
129
|
private extractTotalValidatorRewardPoints;
|
|
102
130
|
/**
|
|
@@ -105,7 +133,7 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
105
133
|
*
|
|
106
134
|
* @param address address of the _Stash_ account to get the exposure of behind `validatorId`
|
|
107
135
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
108
|
-
* @param deriveEraExposure
|
|
136
|
+
* @param deriveEraExposure result of deriveEraExposure
|
|
109
137
|
*/
|
|
110
138
|
private extractExposure;
|
|
111
139
|
/**
|
|
@@ -115,6 +143,6 @@ export declare class AccountsStakingPayoutsService extends AbstractService {
|
|
|
115
143
|
* @param address address of the _Stash_ account to get the payouts of
|
|
116
144
|
* @param deriveEraExposure result of deriveEraExposure
|
|
117
145
|
*/
|
|
118
|
-
deriveNominatedExposures(address: string, deriveEraExposure:
|
|
146
|
+
deriveNominatedExposures(address: string, deriveEraExposure: IAdjustedDeriveEraExposure): DeriveEraExposureNominating[] | undefined;
|
|
119
147
|
}
|
|
120
148
|
export {};
|
|
@@ -14,11 +14,15 @@
|
|
|
14
14
|
//
|
|
15
15
|
// You should have received a copy of the GNU General Public License
|
|
16
16
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
17
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
21
|
exports.AccountsStakingPayoutsService = void 0;
|
|
19
22
|
const calc_1 = require("@substrate/calc");
|
|
20
23
|
const http_errors_1 = require("http-errors");
|
|
21
24
|
const AbstractService_1 = require("../AbstractService");
|
|
25
|
+
const kusamaEarlyErasBlockInfo_json_1 = __importDefault(require("./kusamaEarlyErasBlockInfo.json"));
|
|
22
26
|
class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
23
27
|
/**
|
|
24
28
|
* Fetch and derive payouts for `address`.
|
|
@@ -34,24 +38,28 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
34
38
|
async fetchAccountStakingPayout(hash, address, depth, era, unclaimedOnly, currentEra, historicApi) {
|
|
35
39
|
const { api } = this;
|
|
36
40
|
const { number } = await api.rpc.chain.getHeader(hash);
|
|
41
|
+
const sanitizedEra = era < 0 ? 0 : era;
|
|
37
42
|
/**
|
|
38
43
|
* Given https://github.com/polkadot-js/api/issues/5232,
|
|
39
44
|
* polkadot-js, and substrate treats historyDepth as a consts. In order
|
|
40
45
|
* to maintain historical integrity we need to make a check to cover both the
|
|
41
46
|
* storage query and the consts.
|
|
42
47
|
*/
|
|
43
|
-
let historyDepth;
|
|
48
|
+
let historyDepth = api.registry.createType('u32', 84);
|
|
44
49
|
if (historicApi.consts.staking.historyDepth) {
|
|
45
50
|
historyDepth = historicApi.consts.staking.historyDepth;
|
|
46
51
|
}
|
|
47
|
-
else {
|
|
52
|
+
else if (historicApi.query.staking.historyDepth) {
|
|
48
53
|
historyDepth = await historicApi.query.staking.historyDepth();
|
|
49
54
|
}
|
|
55
|
+
else if (currentEra < 518) {
|
|
56
|
+
historyDepth = api.registry.createType('u32', 0);
|
|
57
|
+
}
|
|
50
58
|
// Information is kept for eras in `[current_era - history_depth; current_era]`
|
|
51
|
-
if (depth > historyDepth.toNumber()) {
|
|
59
|
+
if (historyDepth.toNumber() !== 0 && depth > historyDepth.toNumber()) {
|
|
52
60
|
throw new http_errors_1.BadRequest('Must specify a depth less than history_depth');
|
|
53
61
|
}
|
|
54
|
-
if (era - (depth - 1) < currentEra - historyDepth.toNumber()) {
|
|
62
|
+
if (era - (depth - 1) < currentEra - historyDepth.toNumber() && historyDepth.toNumber() !== 0) {
|
|
55
63
|
// In scenarios where depth is not > historyDepth, but the user specifies an era
|
|
56
64
|
// and historyDepth combo that would lead to querying eras older than history depth
|
|
57
65
|
throw new http_errors_1.BadRequest('Must specify era and depth such that era - (depth - 1) is less ' +
|
|
@@ -62,9 +70,9 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
62
70
|
hash,
|
|
63
71
|
};
|
|
64
72
|
// User friendly - we don't error if the user specified era & depth combo <= 0, instead just start at 0
|
|
65
|
-
const startEra = Math.max(0,
|
|
73
|
+
const startEra = Math.max(0, sanitizedEra - (depth - 1));
|
|
66
74
|
// Fetch general data about the era
|
|
67
|
-
const allErasGeneral = await this.fetchAllErasGeneral(historicApi, startEra,
|
|
75
|
+
const allErasGeneral = await this.fetchAllErasGeneral(historicApi, startEra, sanitizedEra, at);
|
|
68
76
|
// With the general data, we can now fetch the commission of each validator `address` nominates
|
|
69
77
|
const allErasCommissions = await this.fetchAllErasCommissions(historicApi, address, startEra,
|
|
70
78
|
// Create an array of `DeriveEraExposure`
|
|
@@ -99,29 +107,78 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
99
107
|
/**
|
|
100
108
|
* Fetch general info about eras in the inclusive range `startEra` .. `era`.
|
|
101
109
|
*
|
|
102
|
-
* @param api
|
|
103
|
-
* @param hash `BlockHash` to make call at
|
|
110
|
+
* @param historicApi Historic api for querying past blocks
|
|
104
111
|
* @param startEra first era to get data for
|
|
105
112
|
* @param era the last era to get data for
|
|
113
|
+
* @param blockNumber block information to ensure compatibility with older eras
|
|
106
114
|
*/
|
|
107
|
-
async fetchAllErasGeneral(historicApi, startEra, era) {
|
|
115
|
+
async fetchAllErasGeneral(historicApi, startEra, era, blockNumber) {
|
|
108
116
|
const allDeriveQuerys = [];
|
|
117
|
+
let nextEraStartBlock = Number(blockNumber.height);
|
|
118
|
+
let eraDurationInBlocks = 0;
|
|
119
|
+
const runtimeInfo = await this.api.rpc.state.getRuntimeVersion(blockNumber.hash);
|
|
120
|
+
const earlyErasBlockInfo = kusamaEarlyErasBlockInfo_json_1.default;
|
|
109
121
|
for (let e = startEra; e <= era; e += 1) {
|
|
110
122
|
const eraIndex = historicApi.registry.createType('EraIndex', e);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
123
|
+
if (historicApi.query.staking.erasRewardPoints) {
|
|
124
|
+
const eraGeneralTuple = Promise.all([
|
|
125
|
+
this.deriveEraExposure(historicApi, eraIndex),
|
|
126
|
+
historicApi.query.staking.erasRewardPoints(eraIndex),
|
|
127
|
+
historicApi.query.staking.erasValidatorReward(eraIndex),
|
|
128
|
+
]);
|
|
129
|
+
allDeriveQuerys.push(eraGeneralTuple);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// We check if we are in the Kusama chain since currently we have
|
|
133
|
+
// the block info for the early eras only for Kusama.
|
|
134
|
+
if (runtimeInfo.specName.toString() === 'kusama') {
|
|
135
|
+
// Retrieve the first block of the era following the given era in order
|
|
136
|
+
// to fetch the `Rewards` event at that block.
|
|
137
|
+
nextEraStartBlock = era === 0 ? earlyErasBlockInfo[era + 1].start : earlyErasBlockInfo[era].start;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const sessionDuration = historicApi.consts.staking.sessionsPerEra.toNumber();
|
|
141
|
+
const epochDuration = historicApi.consts.babe.epochDuration.toNumber();
|
|
142
|
+
eraDurationInBlocks = sessionDuration * epochDuration;
|
|
143
|
+
}
|
|
144
|
+
const nextEraStartBlockHash = await this.api.rpc.chain.getBlockHash(nextEraStartBlock);
|
|
145
|
+
const currentEraEndBlockHash = era === 0
|
|
146
|
+
? await this.api.rpc.chain.getBlockHash(earlyErasBlockInfo[0].end)
|
|
147
|
+
: await this.api.rpc.chain.getBlockHash(earlyErasBlockInfo[era - 1].end);
|
|
148
|
+
let reward = historicApi.registry.createType('Option<u128>');
|
|
149
|
+
const blockInfo = await this.api.rpc.chain.getBlock(nextEraStartBlockHash);
|
|
150
|
+
const allRecords = await historicApi.query.system.events();
|
|
151
|
+
blockInfo.block.extrinsics.forEach((index) => {
|
|
152
|
+
allRecords
|
|
153
|
+
.filter(({ phase }) => phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(index))
|
|
154
|
+
.forEach(({ event }) => {
|
|
155
|
+
if (event.method.toString() === 'Reward') {
|
|
156
|
+
const [dispatchInfo] = event.data;
|
|
157
|
+
reward = historicApi.registry.createType('Option<u128>', dispatchInfo.toString());
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
const points = this.fetchHistoricRewardPoints(currentEraEndBlockHash);
|
|
162
|
+
const rewardPromise = new Promise((resolve) => {
|
|
163
|
+
resolve(reward);
|
|
164
|
+
});
|
|
165
|
+
if (runtimeInfo.specName.toString() !== 'kusama') {
|
|
166
|
+
nextEraStartBlock = nextEraStartBlock - eraDurationInBlocks;
|
|
167
|
+
}
|
|
168
|
+
const eraGeneralTuple = Promise.all([this.deriveEraExposure(historicApi, eraIndex), points, rewardPromise]);
|
|
169
|
+
allDeriveQuerys.push(eraGeneralTuple);
|
|
170
|
+
}
|
|
117
171
|
}
|
|
118
172
|
return Promise.all(allDeriveQuerys);
|
|
119
173
|
}
|
|
174
|
+
async fetchHistoricRewardPoints(hash) {
|
|
175
|
+
const historicApi = await this.api.at(hash);
|
|
176
|
+
return historicApi.query.staking.currentEraPointsEarned();
|
|
177
|
+
}
|
|
120
178
|
/**
|
|
121
179
|
* Fetch the commission & staking ledger for each `validatorId` in `deriveErasExposures`.
|
|
122
180
|
*
|
|
123
|
-
* @param api
|
|
124
|
-
* @param hash `BlockHash` to make call at
|
|
181
|
+
* @param historicApi Historic api for querying past blocks
|
|
125
182
|
* @param address address of the _Stash_ account to get the payouts of
|
|
126
183
|
* @param startEra first era to get data for
|
|
127
184
|
* @param deriveErasExposures exposures per era for `address`
|
|
@@ -153,18 +210,21 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
153
210
|
message: `${address} has no nominations for the era ${eraIndex.toString()}`,
|
|
154
211
|
};
|
|
155
212
|
}
|
|
156
|
-
if (erasValidatorRewardOption.isNone) {
|
|
213
|
+
if (erasValidatorRewardOption.isNone && eraIndex.toNumber() !== 0) {
|
|
214
|
+
const event = eraIndex.toNumber() > 517 ? 'ErasValidatorReward' : 'Reward';
|
|
157
215
|
return {
|
|
158
|
-
message: `No
|
|
216
|
+
message: `No ${event} for the era ${eraIndex.toString()}`,
|
|
159
217
|
};
|
|
160
218
|
}
|
|
161
219
|
const totalEraRewardPoints = eraRewardPoints.total;
|
|
162
|
-
const totalEraPayout = erasValidatorRewardOption.unwrap();
|
|
220
|
+
const totalEraPayout = eraIndex.toNumber() !== 0 ? erasValidatorRewardOption.unwrap() : this.api.registry.createType('BalanceOf', 0);
|
|
163
221
|
const calcPayout = calc_1.CalcPayout.from_params(totalEraRewardPoints.toNumber(), totalEraPayout.toString(10));
|
|
164
222
|
// Iterate through validators that this nominator backs and calculate payouts for the era
|
|
165
223
|
const payouts = [];
|
|
166
224
|
for (const { validatorId, commission: validatorCommission, validatorLedger } of exposuresWithCommission) {
|
|
167
|
-
const totalValidatorRewardPoints =
|
|
225
|
+
const totalValidatorRewardPoints = deriveEraExposure.validatorIndex
|
|
226
|
+
? this.extractTotalValidatorRewardPoints(eraRewardPoints, validatorId, deriveEraExposure.validatorIndex)
|
|
227
|
+
: this.extractTotalValidatorRewardPoints(eraRewardPoints, validatorId);
|
|
168
228
|
if (!totalValidatorRewardPoints || (totalValidatorRewardPoints === null || totalValidatorRewardPoints === void 0 ? void 0 : totalValidatorRewardPoints.toNumber()) === 0) {
|
|
169
229
|
// Nothing to do if there are no reward points for the validator
|
|
170
230
|
continue;
|
|
@@ -177,14 +237,35 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
177
237
|
if (!validatorLedger) {
|
|
178
238
|
continue;
|
|
179
239
|
}
|
|
180
|
-
|
|
240
|
+
/**
|
|
241
|
+
* Check if the reward has already been claimed.
|
|
242
|
+
*
|
|
243
|
+
* It is important to note that the following examines types that are both current and historic.
|
|
244
|
+
* When going back far enough in certain chains types such as `StakingLedgerTo240` are necessary for grabbing
|
|
245
|
+
* any reward data.
|
|
246
|
+
*/
|
|
181
247
|
let indexOfEra;
|
|
182
248
|
if (validatorLedger.legacyClaimedRewards) {
|
|
183
249
|
indexOfEra = validatorLedger.legacyClaimedRewards.indexOf(eraIndex);
|
|
184
250
|
}
|
|
185
|
-
else {
|
|
251
|
+
else if (validatorLedger.claimedRewards) {
|
|
186
252
|
indexOfEra = validatorLedger.claimedRewards.indexOf(eraIndex);
|
|
187
253
|
}
|
|
254
|
+
else if (validatorLedger.lastReward) {
|
|
255
|
+
const lastReward = validatorLedger.lastReward;
|
|
256
|
+
if (lastReward.isSome) {
|
|
257
|
+
indexOfEra = validatorLedger.lastReward.unwrap().toNumber();
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (eraIndex.toNumber() < 518) {
|
|
264
|
+
indexOfEra = eraIndex.toNumber();
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
188
269
|
const claimed = Number.isInteger(indexOfEra) && indexOfEra !== -1;
|
|
189
270
|
if (unclaimedOnly && claimed) {
|
|
190
271
|
continue;
|
|
@@ -210,26 +291,39 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
210
291
|
/**
|
|
211
292
|
* Fetch the `commission` and `StakingLedger` of `validatorId`.
|
|
212
293
|
*
|
|
213
|
-
* @param api
|
|
294
|
+
* @param historicApi Historic api for querying past blocks
|
|
214
295
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
215
296
|
* @param era the era to query
|
|
216
|
-
* @param hash `BlockHash` to make call at
|
|
217
297
|
* @param validatorLedgerCache object mapping validatorId => StakingLedger to limit redundant queries
|
|
218
298
|
*/
|
|
219
299
|
async fetchCommissionAndLedger(historicApi, validatorId, era, validatorLedgerCache) {
|
|
220
300
|
let commission;
|
|
221
301
|
let validatorLedger;
|
|
302
|
+
let commissionPromise;
|
|
303
|
+
const ancient = era < 518;
|
|
222
304
|
if (validatorId in validatorLedgerCache) {
|
|
223
305
|
validatorLedger = validatorLedgerCache[validatorId];
|
|
224
|
-
|
|
225
|
-
|
|
306
|
+
let prefs;
|
|
307
|
+
if (!ancient) {
|
|
308
|
+
prefs = await historicApi.query.staking.erasValidatorPrefs(era, validatorId);
|
|
309
|
+
commission = prefs.commission.unwrap();
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
prefs = (await historicApi.query.staking.validators(validatorId));
|
|
313
|
+
commission = prefs[0].commission.unwrap();
|
|
314
|
+
}
|
|
226
315
|
}
|
|
227
316
|
else {
|
|
317
|
+
commissionPromise = ancient
|
|
318
|
+
? historicApi.query.staking.validators(validatorId)
|
|
319
|
+
: historicApi.query.staking.erasValidatorPrefs(era, validatorId);
|
|
228
320
|
const [prefs, validatorControllerOption] = await Promise.all([
|
|
229
|
-
|
|
321
|
+
commissionPromise,
|
|
230
322
|
historicApi.query.staking.bonded(validatorId),
|
|
231
323
|
]);
|
|
232
|
-
commission =
|
|
324
|
+
commission = ancient
|
|
325
|
+
? prefs[0].commission.unwrap()
|
|
326
|
+
: prefs.commission.unwrap();
|
|
233
327
|
if (validatorControllerOption.isNone) {
|
|
234
328
|
return {
|
|
235
329
|
commission,
|
|
@@ -253,11 +347,11 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
253
347
|
* The original version uses the base ApiDerive implementation which does not include the ApiDecoration implementation.
|
|
254
348
|
* It is required in this version to query older blocks for their historic data.
|
|
255
349
|
*
|
|
256
|
-
* @param historicApi
|
|
257
|
-
* @param eraIndex
|
|
350
|
+
* @param historicApi Historic api for querying past blocks
|
|
351
|
+
* @param eraIndex index of the era to query
|
|
258
352
|
*/
|
|
259
353
|
async deriveEraExposure(historicApi, eraIndex) {
|
|
260
|
-
function mapStakers(era, stakers) {
|
|
354
|
+
function mapStakers(era, stakers, validatorIndex) {
|
|
261
355
|
const nominators = {};
|
|
262
356
|
const validators = {};
|
|
263
357
|
stakers.forEach(([key, exposure]) => {
|
|
@@ -269,22 +363,58 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
269
363
|
nominators[nominatorId].push({ validatorId, validatorIndex });
|
|
270
364
|
});
|
|
271
365
|
});
|
|
272
|
-
|
|
366
|
+
if (Object.keys(validatorIndex).length > 0) {
|
|
367
|
+
return { era, nominators, validators, validatorIndex };
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
return { era, nominators, validators };
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
let storageKeys = [];
|
|
374
|
+
const validatorIndex = {};
|
|
375
|
+
if (historicApi.query.staking.erasStakersClipped) {
|
|
376
|
+
storageKeys = await historicApi.query.staking.erasStakersClipped.entries(eraIndex);
|
|
273
377
|
}
|
|
274
|
-
|
|
275
|
-
|
|
378
|
+
else {
|
|
379
|
+
const validators = (await historicApi.query.staking.currentElected());
|
|
380
|
+
const validatorId = [];
|
|
381
|
+
validators.map((validator, index) => {
|
|
382
|
+
validatorIndex[validator.toString()] = index;
|
|
383
|
+
validatorId.push(validator);
|
|
384
|
+
});
|
|
385
|
+
let eraExposure = {};
|
|
386
|
+
for (const validator of validatorId) {
|
|
387
|
+
const storageKey = {
|
|
388
|
+
args: [eraIndex, validator],
|
|
389
|
+
};
|
|
390
|
+
eraExposure = (await historicApi.query.staking.stakers(validator));
|
|
391
|
+
storageKeys.push([storageKey, eraExposure]);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return mapStakers(eraIndex, storageKeys, validatorIndex);
|
|
276
395
|
}
|
|
277
396
|
/**
|
|
278
397
|
* Extract the reward points of `validatorId` from `EraRewardPoints`.
|
|
279
398
|
*
|
|
280
399
|
* @param eraRewardPoints
|
|
281
400
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
401
|
+
* @param validatorIndex index of the validator in relation to the `EraPoints`
|
|
402
|
+
* array
|
|
282
403
|
* */
|
|
283
|
-
extractTotalValidatorRewardPoints(eraRewardPoints, validatorId) {
|
|
404
|
+
extractTotalValidatorRewardPoints(eraRewardPoints, validatorId, validatorIndex) {
|
|
284
405
|
// Ideally we would just use the map's `get`, but that does not seem to be working here
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
406
|
+
if (validatorIndex === undefined) {
|
|
407
|
+
for (const [id, points] of eraRewardPoints.individual.entries()) {
|
|
408
|
+
if (id.toString() === validatorId) {
|
|
409
|
+
return points;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
for (const [id, points] of eraRewardPoints.individual.entries()) {
|
|
415
|
+
if (id.toString() === validatorIndex[validatorId.toString()].toString()) {
|
|
416
|
+
return points;
|
|
417
|
+
}
|
|
288
418
|
}
|
|
289
419
|
}
|
|
290
420
|
return;
|
|
@@ -295,7 +425,7 @@ class AccountsStakingPayoutsService extends AbstractService_1.AbstractService {
|
|
|
295
425
|
*
|
|
296
426
|
* @param address address of the _Stash_ account to get the exposure of behind `validatorId`
|
|
297
427
|
* @param validatorId accountId of a validator's _Stash_ account
|
|
298
|
-
* @param deriveEraExposure
|
|
428
|
+
* @param deriveEraExposure result of deriveEraExposure
|
|
299
429
|
*/
|
|
300
430
|
extractExposure(address, validatorId, deriveEraExposure) {
|
|
301
431
|
var _a;
|