@airgap/polkadot 0.13.45-beta.2 → 0.13.45-beta.3
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/package.json +4 -4
- package/v0/index.js +6 -6
- package/v0/index.js.map +1 -1
- package/v0/protocol/kusama/KusamaProtocol.js +22 -41
- package/v0/protocol/kusama/KusamaProtocol.js.map +1 -1
- package/v0/protocol/kusama/KusamaProtocolOptions.js +33 -70
- package/v0/protocol/kusama/KusamaProtocolOptions.js.map +1 -1
- package/v0/protocol/polkadot/PolkadotProtocol.js +23 -42
- package/v0/protocol/polkadot/PolkadotProtocol.js.map +1 -1
- package/v0/protocol/polkadot/PolkadotProtocolOptions.js +33 -70
- package/v0/protocol/polkadot/PolkadotProtocolOptions.js.map +1 -1
- package/v1/controller/PolkadotAccountController.js +373 -648
- package/v1/controller/PolkadotAccountController.js.map +1 -1
- package/v1/controller/PolkadotTransactionController.js +3 -23
- package/v1/controller/PolkadotTransactionController.js.map +1 -1
- package/v1/data/staking/PolkadotActiveEraInfo.js +10 -11
- package/v1/data/staking/PolkadotActiveEraInfo.js.map +1 -1
- package/v1/data/staking/PolkadotEraRewardPoints.js +10 -13
- package/v1/data/staking/PolkadotEraRewardPoints.js.map +1 -1
- package/v1/data/staking/PolkadotExposure.js +11 -14
- package/v1/data/staking/PolkadotExposure.js.map +1 -1
- package/v1/data/staking/PolkadotNominationStatus.js +1 -1
- package/v1/data/staking/PolkadotNominationStatus.js.map +1 -1
- package/v1/data/staking/PolkadotNominations.js +11 -12
- package/v1/data/staking/PolkadotNominations.js.map +1 -1
- package/v1/data/staking/PolkadotNominatorDetails.d.ts +1 -1
- package/v1/data/staking/PolkadotPayee.js +1 -1
- package/v1/data/staking/PolkadotPayee.js.map +1 -1
- package/v1/data/staking/PolkadotSlashingSpans.js +12 -13
- package/v1/data/staking/PolkadotSlashingSpans.js.map +1 -1
- package/v1/data/staking/PolkadotStakingActionType.js +1 -1
- package/v1/data/staking/PolkadotStakingActionType.js.map +1 -1
- package/v1/data/staking/PolkadotStakingLedger.js +13 -16
- package/v1/data/staking/PolkadotStakingLedger.js.map +1 -1
- package/v1/data/staking/PolkadotValidatorDetails.d.ts +1 -1
- package/v1/data/staking/PolkadotValidatorPrefs.js +9 -10
- package/v1/data/staking/PolkadotValidatorPrefs.js.map +1 -1
- package/v1/data/transaction/method/args.js +146 -271
- package/v1/data/transaction/method/args.js.map +1 -1
- package/v1/data/transaction/transaction.js +11 -22
- package/v1/data/transaction/transaction.js.map +1 -1
- package/v1/index.js +6 -6
- package/v1/index.js.map +1 -1
- package/v1/module/PolkadotModule.d.ts +1 -1
- package/v1/module/PolkadotModule.js +40 -98
- package/v1/module/PolkadotModule.js.map +1 -1
- package/v1/module.js +2 -3
- package/v1/module.js.map +1 -1
- package/v1/node/PolkadotNodeClient.js +101 -284
- package/v1/node/PolkadotNodeClient.js.map +1 -1
- package/v1/protocol/KusamaProtocol.js +28 -54
- package/v1/protocol/KusamaProtocol.js.map +1 -1
- package/v1/protocol/PolkadotBaseProtocol.js +409 -701
- package/v1/protocol/PolkadotBaseProtocol.js.map +1 -1
- package/v1/protocol/PolkadotProtocol.js +20 -51
- package/v1/protocol/PolkadotProtocol.js.map +1 -1
- package/v1/serializer/v3/schemas/converter/transaction-converter.js +5 -6
- package/v1/serializer/v3/schemas/converter/transaction-converter.js.map +1 -1
- package/v1/serializer/v3/serializer-companion.js +75 -154
- package/v1/serializer/v3/serializer-companion.js.map +1 -1
- package/v1/serializer/v3/validators/transaction-validator.js +3 -23
- package/v1/serializer/v3/validators/transaction-validator.js.map +1 -1
- package/v1/serializer/v3/validators/validators.js +1 -1
- package/v1/serializer/v3/validators/validators.js.map +1 -1
- package/v1/types/configuration.d.ts +1 -1
- package/v1/types/crypto.d.ts +1 -1
- package/v1/types/protocol.d.ts +2 -2
|
@@ -1,675 +1,400 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
-
function step(op) {
|
|
31
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
-
while (_) try {
|
|
33
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
-
switch (op[0]) {
|
|
36
|
-
case 0: case 1: t = op; break;
|
|
37
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
-
default:
|
|
41
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
-
if (t[2]) _.ops.pop();
|
|
46
|
-
_.trys.pop(); continue;
|
|
47
|
-
}
|
|
48
|
-
op = body.call(thisArg, _);
|
|
49
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
54
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
55
4
|
};
|
|
56
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
6
|
exports.PolkadotAccountController = void 0;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
7
|
+
const bignumber_1 = __importDefault(require("@airgap/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber"));
|
|
8
|
+
const v1_1 = require("@airgap/substrate/v1");
|
|
9
|
+
const PolkadotNominationStatus_1 = require("../data/staking/PolkadotNominationStatus");
|
|
10
|
+
const PolkadotStakingActionType_1 = require("../data/staking/PolkadotStakingActionType");
|
|
11
|
+
class PolkadotAccountController extends v1_1.SubstrateCommonAccountController {
|
|
12
|
+
async getStakingBalance(accountId) {
|
|
13
|
+
const stakingDetails = await this.nodeClient.getStakingLedger(this.substrateAddressFrom(accountId));
|
|
14
|
+
if (stakingDetails === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const bonded = stakingDetails.active.value;
|
|
18
|
+
const unlocking = stakingDetails.unlocking.elements
|
|
19
|
+
.map((entry) => entry.first.value)
|
|
20
|
+
.reduce((sum, next) => sum.plus(next), new bignumber_1.default(0));
|
|
21
|
+
return { bonded, unlocking };
|
|
66
22
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
validators = ((_b = (_a = nominations === null || nominations === void 0 ? void 0 : nominations.targets) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.map(function (target) { return target.asAddress(); })) || [];
|
|
221
|
-
return [4 /*yield*/, this.getStakingDetails(accountId, stakingLedger, nominations, activeEra, expectedEraDuration)];
|
|
222
|
-
case 2:
|
|
223
|
-
stakingDetails = _c.sent();
|
|
224
|
-
return [4 /*yield*/, this.getAvailableStakingActions(stakingDetails, nominations, validatorIds !== null && validatorIds !== void 0 ? validatorIds : validators, balance.transferable)];
|
|
225
|
-
case 3:
|
|
226
|
-
availableActions = _c.sent();
|
|
227
|
-
return [2 /*return*/, {
|
|
228
|
-
address: address.asString(),
|
|
229
|
-
balance: balance.total.toString(),
|
|
230
|
-
delegatees: validators,
|
|
231
|
-
availableActions: availableActions,
|
|
232
|
-
stakingDetails: stakingDetails
|
|
233
|
-
}];
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
};
|
|
238
|
-
PolkadotAccountController.prototype.getNominationStatus = function (nominator, validator, era) {
|
|
239
|
-
var _a;
|
|
240
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
241
|
-
var eraIndex, _b, nominations, exposure, isActive, isOversubscribed, position;
|
|
242
|
-
return __generator(this, function (_c) {
|
|
243
|
-
switch (_c.label) {
|
|
244
|
-
case 0:
|
|
245
|
-
if (!(era !== undefined)) return [3 /*break*/, 1];
|
|
246
|
-
_b = era;
|
|
247
|
-
return [3 /*break*/, 3];
|
|
248
|
-
case 1: return [4 /*yield*/, this.nodeClient.getActiveEraInfo()];
|
|
249
|
-
case 2:
|
|
250
|
-
_b = (_a = (_c.sent())) === null || _a === void 0 ? void 0 : _a.index.toNumber();
|
|
251
|
-
_c.label = 3;
|
|
252
|
-
case 3:
|
|
253
|
-
eraIndex = _b;
|
|
254
|
-
if (eraIndex === undefined) {
|
|
255
|
-
return [2 /*return*/, Promise.reject('Could not fetch active era')];
|
|
256
|
-
}
|
|
257
|
-
return [4 /*yield*/, this.nodeClient.getNominations(this.substrateAddressFrom(nominator))];
|
|
258
|
-
case 4:
|
|
259
|
-
nominations = _c.sent();
|
|
260
|
-
if (nominations === undefined ||
|
|
261
|
-
!nominations.targets.elements.some(function (target) { return target.asAddress() === validator; })) {
|
|
262
|
-
return [2 /*return*/, undefined];
|
|
263
|
-
}
|
|
264
|
-
return [4 /*yield*/, this.nodeClient.getValidatorExposure(eraIndex, this.substrateAddressFrom(validator))];
|
|
265
|
-
case 5:
|
|
266
|
-
exposure = _c.sent();
|
|
267
|
-
if (!exposure) {
|
|
268
|
-
return [2 /*return*/, PolkadotNominationStatus_1.PolkadotNominationStatus.INACTIVE];
|
|
269
|
-
}
|
|
270
|
-
isActive = exposure.others.elements.some(function (element) { return element.first.asAddress() === nominator.toString(); });
|
|
271
|
-
if (!isActive) {
|
|
272
|
-
return [2 /*return*/, PolkadotNominationStatus_1.PolkadotNominationStatus.INACTIVE];
|
|
273
|
-
}
|
|
274
|
-
isOversubscribed = exposure.others.elements.length > 256;
|
|
275
|
-
if (isOversubscribed) {
|
|
276
|
-
position = exposure.others.elements
|
|
277
|
-
.sort(function (a, b) { return b.second.value.minus(a.second.value).toNumber(); })
|
|
278
|
-
.map(function (exposure) { return exposure.first.asAddress(); })
|
|
279
|
-
.indexOf(nominator.toString());
|
|
280
|
-
if (position > 256) {
|
|
281
|
-
return [2 /*return*/, PolkadotNominationStatus_1.PolkadotNominationStatus.OVERSUBSCRIBED];
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return [2 /*return*/, PolkadotNominationStatus_1.PolkadotNominationStatus.ACTIVE];
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
};
|
|
289
|
-
PolkadotAccountController.prototype.getSlashingSpansNumber = function (accountId) {
|
|
290
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
291
|
-
var slashingSpans;
|
|
292
|
-
return __generator(this, function (_a) {
|
|
293
|
-
switch (_a.label) {
|
|
294
|
-
case 0: return [4 /*yield*/, this.nodeClient.getSlashingSpan(this.substrateAddressFrom(accountId))];
|
|
295
|
-
case 1:
|
|
296
|
-
slashingSpans = _a.sent();
|
|
297
|
-
return [2 /*return*/, slashingSpans ? slashingSpans.prior.elements.length + 1 : 0];
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
};
|
|
302
|
-
PolkadotAccountController.prototype.getStakingDetails = function (accountId, stakingLedger, nominations, activeEra, expectedEraDuration) {
|
|
303
|
-
var _a, _b;
|
|
304
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
305
|
-
var unlockingDetails, results, stakingStatus, rewards;
|
|
306
|
-
return __generator(this, function (_c) {
|
|
307
|
-
switch (_c.label) {
|
|
308
|
-
case 0:
|
|
309
|
-
if (!stakingLedger) {
|
|
310
|
-
return [2 /*return*/, undefined];
|
|
311
|
-
}
|
|
312
|
-
unlockingDetails = this.getUnlockingDetails(stakingLedger.unlocking.elements.map(function (tuple) { return [tuple.first.value, tuple.second.value]; }), activeEra, expectedEraDuration);
|
|
313
|
-
return [4 /*yield*/, Promise.all([
|
|
314
|
-
this.getStakingStatus(accountId, nominations, activeEra.index.toNumber()),
|
|
315
|
-
nominations
|
|
316
|
-
? this.getNominatorRewards(accountId, nominations.targets.elements.map(function (id) { return id.address; }), activeEra, 5)
|
|
317
|
-
: []
|
|
318
|
-
])];
|
|
319
|
-
case 1:
|
|
320
|
-
results = _c.sent();
|
|
321
|
-
stakingStatus = results[0];
|
|
322
|
-
rewards = results[1];
|
|
323
|
-
return [2 /*return*/, {
|
|
324
|
-
total: stakingLedger.total.toString(),
|
|
325
|
-
active: stakingLedger.active.toString(),
|
|
326
|
-
locked: unlockingDetails.locked,
|
|
327
|
-
unlocked: unlockingDetails.unlocked,
|
|
328
|
-
status: stakingStatus,
|
|
329
|
-
nextEra: ((_b = (_a = activeEra.start.value) === null || _a === void 0 ? void 0 : _a.plus(expectedEraDuration)) === null || _b === void 0 ? void 0 : _b.toNumber()) || 0,
|
|
330
|
-
rewards: rewards
|
|
331
|
-
}];
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
|
-
PolkadotAccountController.prototype.getUnlockingDetails = function (unlocking, activeEra, expectedEraDuration) {
|
|
337
|
-
var _a = this.partitionArray(unlocking, function (_a) {
|
|
338
|
-
var _ = _a[0], era = _a[1];
|
|
339
|
-
return activeEra.index.lt(era);
|
|
340
|
-
}), locked = _a[0], unlocked = _a[1];
|
|
341
|
-
var lockedDetails = locked.map(function (_a) {
|
|
342
|
-
var _b;
|
|
343
|
-
var value = _a[0], era = _a[1];
|
|
344
|
-
var eraStart = ((_b = activeEra.start.value) === null || _b === void 0 ? void 0 : _b.value) || new bignumber_1.default(0);
|
|
345
|
-
var estimatedDuration = era.minus(activeEra.index.value).multipliedBy(expectedEraDuration);
|
|
346
|
-
var expectedUnlock = eraStart.plus(estimatedDuration);
|
|
23
|
+
async getUnlockingBalance(accountId) {
|
|
24
|
+
const stakingBalance = await this.getStakingBalance(accountId);
|
|
25
|
+
return stakingBalance?.unlocking ?? new bignumber_1.default(0);
|
|
26
|
+
}
|
|
27
|
+
async isBonded(accountId) {
|
|
28
|
+
const bonded = await this.nodeClient.getBonded(this.substrateAddressFrom(accountId));
|
|
29
|
+
return bonded != undefined;
|
|
30
|
+
}
|
|
31
|
+
async isDelegating(accountId) {
|
|
32
|
+
const nominations = await this.nodeClient.getNominations(this.substrateAddressFrom(accountId));
|
|
33
|
+
return nominations != undefined;
|
|
34
|
+
}
|
|
35
|
+
async getCurrentValidators(accountId) {
|
|
36
|
+
const nominations = await this.nodeClient.getNominations(this.substrateAddressFrom(accountId));
|
|
37
|
+
if (nominations) {
|
|
38
|
+
return nominations.targets.elements.map((target) => target.asAddress());
|
|
39
|
+
}
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
async getValidatorDetails(accountId) {
|
|
43
|
+
const address = this.substrateAddressFrom(accountId);
|
|
44
|
+
const activeEra = await this.nodeClient.getActiveEraInfo();
|
|
45
|
+
let identity;
|
|
46
|
+
let status;
|
|
47
|
+
let exposure;
|
|
48
|
+
let validatorPrefs;
|
|
49
|
+
let lastEraReward;
|
|
50
|
+
if (activeEra) {
|
|
51
|
+
const activeEraIndex = activeEra.index.toNumber();
|
|
52
|
+
const results = await Promise.all([
|
|
53
|
+
this.getAccountIdentityInfo(address),
|
|
54
|
+
this.nodeClient.getValidators(),
|
|
55
|
+
this.nodeClient.getValidatorPrefs(activeEraIndex, address),
|
|
56
|
+
this.nodeClient.getValidatorExposure(activeEraIndex, address)
|
|
57
|
+
]);
|
|
58
|
+
identity = results[0];
|
|
59
|
+
const currentValidators = results[1];
|
|
60
|
+
validatorPrefs = results[2];
|
|
61
|
+
exposure = results[3];
|
|
62
|
+
lastEraReward = await this.getEraValidatorReward(address, activeEraIndex - 1);
|
|
63
|
+
if (currentValidators && currentValidators.find((current) => current.compare(address) == 0)) {
|
|
64
|
+
status = 'Active';
|
|
65
|
+
}
|
|
66
|
+
else if (currentValidators) {
|
|
67
|
+
status = 'Inactive';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
address: address.asString(),
|
|
72
|
+
name: identity ? identity.display.toString() : undefined,
|
|
73
|
+
status,
|
|
74
|
+
ownStash: exposure ? exposure.own.toString() : undefined,
|
|
75
|
+
totalStakingBalance: exposure ? exposure.total.toString() : undefined,
|
|
76
|
+
commission: validatorPrefs
|
|
77
|
+
? validatorPrefs.commission.value.dividedBy(1_000_000_000).toString() // commission is Perbill (parts per billion)
|
|
78
|
+
: undefined,
|
|
79
|
+
lastEraReward,
|
|
80
|
+
nominators: exposure?.others.elements.length ?? 0
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async getNominatorDetails(accountId, validatorIds) {
|
|
84
|
+
const address = this.substrateAddressFrom(accountId);
|
|
85
|
+
const results = await Promise.all([
|
|
86
|
+
this.getBalance(address),
|
|
87
|
+
this.nodeClient.getStakingLedger(address),
|
|
88
|
+
this.nodeClient.getNominations(address),
|
|
89
|
+
this.nodeClient.getActiveEraInfo(),
|
|
90
|
+
this.nodeClient.getExpectedEraDuration(),
|
|
91
|
+
this.nodeClient.getExistentialDeposit()
|
|
92
|
+
]);
|
|
93
|
+
const balance = results[0];
|
|
94
|
+
const stakingLedger = results[1];
|
|
95
|
+
const nominations = results[2];
|
|
96
|
+
const activeEra = results[3];
|
|
97
|
+
const expectedEraDuration = results[4];
|
|
98
|
+
if (!balance || !activeEra || !expectedEraDuration) {
|
|
99
|
+
return Promise.reject('Could not fetch nominator details.');
|
|
100
|
+
}
|
|
101
|
+
const validators = nominations?.targets?.elements?.map((target) => target.asAddress()) || [];
|
|
102
|
+
const stakingDetails = await this.getStakingDetails(accountId, stakingLedger, nominations, activeEra, expectedEraDuration);
|
|
103
|
+
const availableActions = await this.getAvailableStakingActions(stakingDetails, nominations, validatorIds ?? validators, balance.transferable);
|
|
104
|
+
return {
|
|
105
|
+
address: address.asString(),
|
|
106
|
+
balance: balance.total.toString(),
|
|
107
|
+
delegatees: validators,
|
|
108
|
+
availableActions,
|
|
109
|
+
stakingDetails
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async getNominationStatus(nominator, validator, era) {
|
|
113
|
+
const eraIndex = era !== undefined ? era : (await this.nodeClient.getActiveEraInfo())?.index.toNumber();
|
|
114
|
+
if (eraIndex === undefined) {
|
|
115
|
+
return Promise.reject('Could not fetch active era');
|
|
116
|
+
}
|
|
117
|
+
const nominations = await this.nodeClient.getNominations(this.substrateAddressFrom(nominator));
|
|
118
|
+
if (nominations === undefined ||
|
|
119
|
+
!nominations.targets.elements.some((target) => target.asAddress() === validator)) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const exposure = await this.nodeClient.getValidatorExposure(eraIndex, this.substrateAddressFrom(validator));
|
|
123
|
+
if (!exposure) {
|
|
124
|
+
return PolkadotNominationStatus_1.PolkadotNominationStatus.INACTIVE;
|
|
125
|
+
}
|
|
126
|
+
const isActive = exposure.others.elements.some((element) => element.first.asAddress() === nominator.toString());
|
|
127
|
+
if (!isActive) {
|
|
128
|
+
return PolkadotNominationStatus_1.PolkadotNominationStatus.INACTIVE;
|
|
129
|
+
}
|
|
130
|
+
const isOversubscribed = exposure.others.elements.length > 256;
|
|
131
|
+
if (isOversubscribed) {
|
|
132
|
+
const position = exposure.others.elements
|
|
133
|
+
.sort((a, b) => b.second.value.minus(a.second.value).toNumber())
|
|
134
|
+
.map((exposure) => exposure.first.asAddress())
|
|
135
|
+
.indexOf(nominator.toString());
|
|
136
|
+
if (position > 256) {
|
|
137
|
+
return PolkadotNominationStatus_1.PolkadotNominationStatus.OVERSUBSCRIBED;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return PolkadotNominationStatus_1.PolkadotNominationStatus.ACTIVE;
|
|
141
|
+
}
|
|
142
|
+
async getSlashingSpansNumber(accountId) {
|
|
143
|
+
const slashingSpans = await this.nodeClient.getSlashingSpan(this.substrateAddressFrom(accountId));
|
|
144
|
+
return slashingSpans ? slashingSpans.prior.elements.length + 1 : 0;
|
|
145
|
+
}
|
|
146
|
+
async getStakingDetails(accountId, stakingLedger, nominations, activeEra, expectedEraDuration) {
|
|
147
|
+
if (!stakingLedger) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
const unlockingDetails = this.getUnlockingDetails(stakingLedger.unlocking.elements.map((tuple) => [tuple.first.value, tuple.second.value]), activeEra, expectedEraDuration);
|
|
151
|
+
const results = await Promise.all([
|
|
152
|
+
this.getStakingStatus(accountId, nominations, activeEra.index.toNumber()),
|
|
153
|
+
nominations
|
|
154
|
+
? this.getNominatorRewards(accountId, nominations.targets.elements.map((id) => id.address), activeEra, 5)
|
|
155
|
+
: []
|
|
156
|
+
]);
|
|
157
|
+
const stakingStatus = results[0];
|
|
158
|
+
const rewards = results[1];
|
|
159
|
+
return {
|
|
160
|
+
total: stakingLedger.total.toString(),
|
|
161
|
+
active: stakingLedger.active.toString(),
|
|
162
|
+
locked: unlockingDetails.locked,
|
|
163
|
+
unlocked: unlockingDetails.unlocked,
|
|
164
|
+
status: stakingStatus,
|
|
165
|
+
nextEra: activeEra.start.value?.plus(expectedEraDuration)?.toNumber() || 0,
|
|
166
|
+
rewards
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
getUnlockingDetails(unlocking, activeEra, expectedEraDuration) {
|
|
170
|
+
const [locked, unlocked] = this.partitionArray(unlocking, ([_, era]) => activeEra.index.lt(era));
|
|
171
|
+
const lockedDetails = locked.map(([value, era]) => {
|
|
172
|
+
const eraStart = activeEra.start.value?.value || new bignumber_1.default(0);
|
|
173
|
+
const estimatedDuration = era.minus(activeEra.index.value).multipliedBy(expectedEraDuration);
|
|
174
|
+
const expectedUnlock = eraStart.plus(estimatedDuration);
|
|
347
175
|
return {
|
|
348
176
|
value: value.toString(10),
|
|
349
177
|
expectedUnlock: expectedUnlock.toNumber()
|
|
350
178
|
};
|
|
351
179
|
});
|
|
352
|
-
|
|
353
|
-
var value = _a[0], _ = _a[1];
|
|
354
|
-
return total.plus(value);
|
|
355
|
-
}, new bignumber_1.default(0));
|
|
180
|
+
const totalUnlocked = unlocked.reduce((total, [value, _]) => total.plus(value), new bignumber_1.default(0));
|
|
356
181
|
return {
|
|
357
182
|
locked: lockedDetails,
|
|
358
183
|
unlocked: totalUnlocked.toString()
|
|
359
184
|
};
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
185
|
+
}
|
|
186
|
+
async getStakingStatus(nominator, nominations, eraIndex) {
|
|
187
|
+
const isWaitingForNomination = nominations?.submittedIn.gte(eraIndex) ?? false;
|
|
188
|
+
let hasActiveNominations = false;
|
|
189
|
+
if (!isWaitingForNomination && nominations) {
|
|
190
|
+
hasActiveNominations = (await Promise.all(nominations.targets.elements.map((target) => this.getNominationStatus(nominator, target.asAddress(), eraIndex)))).some((status) => status === PolkadotNominationStatus_1.PolkadotNominationStatus.ACTIVE);
|
|
191
|
+
}
|
|
192
|
+
if (nominations === undefined) {
|
|
193
|
+
return 'bonded';
|
|
194
|
+
}
|
|
195
|
+
else if (hasActiveNominations) {
|
|
196
|
+
return 'nominating';
|
|
197
|
+
}
|
|
198
|
+
else if (!isWaitingForNomination && !hasActiveNominations) {
|
|
199
|
+
return 'nominating_inactive';
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
return 'nominating_waiting';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async getEraValidatorReward(accountId, eraIndex) {
|
|
206
|
+
const address = this.substrateAddressFrom(accountId);
|
|
207
|
+
const results = await Promise.all([
|
|
208
|
+
this.nodeClient.getValidatorReward(eraIndex).then(async (result) => {
|
|
209
|
+
return result ? result : this.nodeClient.getValidatorReward(eraIndex - 1);
|
|
210
|
+
}),
|
|
211
|
+
this.nodeClient.getRewardPoints(eraIndex),
|
|
212
|
+
this.nodeClient.getStakersClipped(eraIndex, address),
|
|
213
|
+
this.nodeClient.getValidatorPrefs(eraIndex, address)
|
|
214
|
+
]);
|
|
215
|
+
if (results.some((result) => !result)) {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
const eraReward = results[0];
|
|
219
|
+
const eraPoints = results[1];
|
|
220
|
+
const exposureClipped = results[2];
|
|
221
|
+
const validatorPrefs = results[3];
|
|
222
|
+
const validatorPoints = eraPoints?.individual?.elements?.find((element) => element.first.address.compare(address))?.second?.value;
|
|
223
|
+
if (!eraReward || !eraPoints || !exposureClipped || !validatorPrefs || !validatorPoints) {
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
const validatorReward = this.calculateValidatorReward(eraReward, eraPoints.total.value, validatorPoints);
|
|
227
|
+
return {
|
|
228
|
+
amount: validatorReward.toFixed(),
|
|
229
|
+
totalStake: exposureClipped.total.toString(),
|
|
230
|
+
ownStake: exposureClipped.own.toString(),
|
|
231
|
+
commission: validatorPrefs.commission.toString()
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
async getNominatorRewards(accountId, validators, activeEra, eras) {
|
|
235
|
+
const address = this.substrateAddressFrom(accountId);
|
|
236
|
+
const expectedEraDuration = await this.nodeClient.getExpectedEraDuration();
|
|
237
|
+
if (!expectedEraDuration) {
|
|
238
|
+
return Promise.reject('Could not fetch all necessary data.');
|
|
239
|
+
}
|
|
240
|
+
const eraIndices = Array.isArray(eras) ? eras : Array.from(Array(eras).keys()).map((index) => activeEra.index.toNumber() - 1 - index);
|
|
241
|
+
const rewards = await Promise.all(eraIndices.map((era) => this.calculateEraNominatorReward(address, validators.map((validator) => this.substrateAddressFrom(validator)), era).then((partial) => {
|
|
242
|
+
if (partial) {
|
|
243
|
+
const rewardEra = partial.eraIndex || activeEra.index.toNumber();
|
|
244
|
+
const erasPassed = activeEra.index.minus(rewardEra).toNumber();
|
|
245
|
+
partial.timestamp = activeEra.start.value
|
|
246
|
+
? activeEra.start.value.minus(expectedEraDuration.multipliedBy(erasPassed - 1)).toNumber()
|
|
247
|
+
: 0;
|
|
248
|
+
}
|
|
249
|
+
return partial;
|
|
250
|
+
})));
|
|
251
|
+
return rewards.filter((reward) => reward);
|
|
252
|
+
}
|
|
253
|
+
async calculateEraNominatorReward(accountId, validators, eraIndex) {
|
|
254
|
+
const results = await Promise.all([
|
|
255
|
+
this.nodeClient.getValidatorReward(eraIndex),
|
|
256
|
+
this.nodeClient.getRewardPoints(eraIndex),
|
|
257
|
+
Promise.all(validators.map(async (validator) => [
|
|
258
|
+
this.substrateAddressFrom(validator),
|
|
259
|
+
await this.nodeClient
|
|
260
|
+
.getValidatorPrefs(eraIndex, this.substrateAddressFrom(validator))
|
|
261
|
+
.then((prefs) => prefs?.commission?.value),
|
|
262
|
+
await this.nodeClient.getStakersClipped(eraIndex, this.substrateAddressFrom(validator))
|
|
263
|
+
]))
|
|
264
|
+
]);
|
|
265
|
+
const reward = results[0];
|
|
266
|
+
const rewardPoints = results[1];
|
|
267
|
+
const exposuresWithValidators = results[2];
|
|
268
|
+
if (!reward || !rewardPoints || !exposuresWithValidators) {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
const partialRewards = exposuresWithValidators
|
|
272
|
+
.map(([validator, commission, exposure]) => {
|
|
273
|
+
const validatorPoints = rewardPoints.individual.elements.find((element) => element.first.compare(validator) === 0)?.second?.value;
|
|
274
|
+
const nominatorStake = exposure?.others.elements.find((element) => element.first.compare(accountId) === 0)?.second?.value;
|
|
275
|
+
if (commission && exposure && validatorPoints && nominatorStake) {
|
|
276
|
+
const validatorReward = this.calculateValidatorReward(reward, rewardPoints.total.value, validatorPoints);
|
|
277
|
+
return this.calculateNominatorReward(validatorReward, commission, exposure.total.value, nominatorStake);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
.filter((reward) => reward !== undefined);
|
|
284
|
+
if (partialRewards.every((reward) => !reward)) {
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
eraIndex,
|
|
289
|
+
amount: partialRewards.reduce((sum, next) => sum.plus(next), new bignumber_1.default(0)).toFixed(0),
|
|
290
|
+
exposures: exposuresWithValidators
|
|
291
|
+
?.map(([validator, _, exposure]) => [
|
|
292
|
+
validator.asString(),
|
|
293
|
+
exposure?.others.elements.findIndex((element) => element.first.compare(accountId) === 0)
|
|
294
|
+
])
|
|
295
|
+
.filter(([_, index]) => index !== undefined)
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
calculateValidatorReward(totalReward, totalPoints, validatorPoints) {
|
|
299
|
+
return validatorPoints.dividedBy(totalPoints).multipliedBy(totalReward);
|
|
300
|
+
}
|
|
301
|
+
calculateNominatorReward(validatorReward, validatorCommission, totalStake, nominatorStake) {
|
|
302
|
+
const nominatorShare = nominatorStake.dividedBy(totalStake);
|
|
303
|
+
return new bignumber_1.default(1).minus(validatorCommission.dividedBy(1_000_000_000)).multipliedBy(validatorReward).multipliedBy(nominatorShare);
|
|
304
|
+
}
|
|
305
|
+
// tslint:disable-next-line: cyclomatic-complexity
|
|
306
|
+
async getAvailableStakingActions(stakingDetails, nominations, validatorIds, maxDelegationValue) {
|
|
307
|
+
const availableActions = [];
|
|
308
|
+
const currentValidators = nominations?.targets?.elements?.map((target) => target.asAddress()) || [];
|
|
309
|
+
const validatorAddresses = validatorIds.map((id) => this.substrateAddressFrom(id).asString());
|
|
310
|
+
const bondedValue = new bignumber_1.default(stakingDetails?.active ?? 0);
|
|
311
|
+
const minDelegationValue = await this.nodeClient.getMinNominatorBond();
|
|
312
|
+
const isBonded = bondedValue.gt(0);
|
|
313
|
+
const hasEnoughBond = bondedValue.gte(minDelegationValue ?? 0);
|
|
314
|
+
const isDelegating = nominations !== undefined;
|
|
315
|
+
const isUnbonding = stakingDetails && stakingDetails.locked.length > 0;
|
|
316
|
+
const hasFundsToWithdraw = new bignumber_1.default(stakingDetails?.unlocked ?? 0).gt(0);
|
|
317
|
+
if (maxDelegationValue.gt(0) && !isBonded && !isUnbonding) {
|
|
318
|
+
availableActions.push({
|
|
319
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.BOND_NOMINATE,
|
|
320
|
+
args: ['targets', 'controller', 'value', 'payee']
|
|
393
321
|
});
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
var address, results, eraReward, eraPoints, exposureClipped, validatorPrefs, validatorPoints, validatorReward;
|
|
400
|
-
var _this = this;
|
|
401
|
-
return __generator(this, function (_e) {
|
|
402
|
-
switch (_e.label) {
|
|
403
|
-
case 0:
|
|
404
|
-
address = this.substrateAddressFrom(accountId);
|
|
405
|
-
return [4 /*yield*/, Promise.all([
|
|
406
|
-
this.nodeClient.getValidatorReward(eraIndex).then(function (result) { return __awaiter(_this, void 0, void 0, function () {
|
|
407
|
-
return __generator(this, function (_a) {
|
|
408
|
-
return [2 /*return*/, result ? result : this.nodeClient.getValidatorReward(eraIndex - 1)];
|
|
409
|
-
});
|
|
410
|
-
}); }),
|
|
411
|
-
this.nodeClient.getRewardPoints(eraIndex),
|
|
412
|
-
this.nodeClient.getStakersClipped(eraIndex, address),
|
|
413
|
-
this.nodeClient.getValidatorPrefs(eraIndex, address)
|
|
414
|
-
])];
|
|
415
|
-
case 1:
|
|
416
|
-
results = _e.sent();
|
|
417
|
-
if (results.some(function (result) { return !result; })) {
|
|
418
|
-
return [2 /*return*/, undefined];
|
|
419
|
-
}
|
|
420
|
-
eraReward = results[0];
|
|
421
|
-
eraPoints = results[1];
|
|
422
|
-
exposureClipped = results[2];
|
|
423
|
-
validatorPrefs = results[3];
|
|
424
|
-
validatorPoints = (_d = (_c = (_b = (_a = eraPoints === null || eraPoints === void 0 ? void 0 : eraPoints.individual) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.find(function (element) { return element.first.address.compare(address); })) === null || _c === void 0 ? void 0 : _c.second) === null || _d === void 0 ? void 0 : _d.value;
|
|
425
|
-
if (!eraReward || !eraPoints || !exposureClipped || !validatorPrefs || !validatorPoints) {
|
|
426
|
-
return [2 /*return*/, undefined];
|
|
427
|
-
}
|
|
428
|
-
validatorReward = this.calculateValidatorReward(eraReward, eraPoints.total.value, validatorPoints);
|
|
429
|
-
return [2 /*return*/, {
|
|
430
|
-
amount: validatorReward.toFixed(),
|
|
431
|
-
totalStake: exposureClipped.total.toString(),
|
|
432
|
-
ownStake: exposureClipped.own.toString(),
|
|
433
|
-
commission: validatorPrefs.commission.toString()
|
|
434
|
-
}];
|
|
435
|
-
}
|
|
322
|
+
}
|
|
323
|
+
if (isBonded && !isDelegating && hasEnoughBond && !isUnbonding) {
|
|
324
|
+
availableActions.push({
|
|
325
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.NOMINATE,
|
|
326
|
+
args: ['targets']
|
|
436
327
|
});
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
var _this = this;
|
|
443
|
-
return __generator(this, function (_a) {
|
|
444
|
-
switch (_a.label) {
|
|
445
|
-
case 0:
|
|
446
|
-
address = this.substrateAddressFrom(accountId);
|
|
447
|
-
return [4 /*yield*/, this.nodeClient.getExpectedEraDuration()];
|
|
448
|
-
case 1:
|
|
449
|
-
expectedEraDuration = _a.sent();
|
|
450
|
-
if (!expectedEraDuration) {
|
|
451
|
-
return [2 /*return*/, Promise.reject('Could not fetch all necessary data.')];
|
|
452
|
-
}
|
|
453
|
-
eraIndices = Array.isArray(eras) ? eras : Array.from(Array(eras).keys()).map(function (index) { return activeEra.index.toNumber() - 1 - index; });
|
|
454
|
-
return [4 /*yield*/, Promise.all(eraIndices.map(function (era) {
|
|
455
|
-
return _this.calculateEraNominatorReward(address, validators.map(function (validator) { return _this.substrateAddressFrom(validator); }), era).then(function (partial) {
|
|
456
|
-
if (partial) {
|
|
457
|
-
var rewardEra = partial.eraIndex || activeEra.index.toNumber();
|
|
458
|
-
var erasPassed = activeEra.index.minus(rewardEra).toNumber();
|
|
459
|
-
partial.timestamp = activeEra.start.value
|
|
460
|
-
? activeEra.start.value.minus(expectedEraDuration.multipliedBy(erasPassed - 1)).toNumber()
|
|
461
|
-
: 0;
|
|
462
|
-
}
|
|
463
|
-
return partial;
|
|
464
|
-
});
|
|
465
|
-
}))];
|
|
466
|
-
case 2:
|
|
467
|
-
rewards = _a.sent();
|
|
468
|
-
return [2 /*return*/, rewards.filter(function (reward) { return reward; })];
|
|
469
|
-
}
|
|
328
|
+
}
|
|
329
|
+
if (maxDelegationValue.gt(0) && isBonded && !isUnbonding) {
|
|
330
|
+
availableActions.push({
|
|
331
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.BOND_EXTRA,
|
|
332
|
+
args: ['value']
|
|
470
333
|
});
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
var _this = this;
|
|
477
|
-
return __generator(this, function (_a) {
|
|
478
|
-
switch (_a.label) {
|
|
479
|
-
case 0: return [4 /*yield*/, Promise.all([
|
|
480
|
-
this.nodeClient.getValidatorReward(eraIndex),
|
|
481
|
-
this.nodeClient.getRewardPoints(eraIndex),
|
|
482
|
-
Promise.all(validators.map(function (validator) { return __awaiter(_this, void 0, void 0, function () {
|
|
483
|
-
var _a;
|
|
484
|
-
return __generator(this, function (_b) {
|
|
485
|
-
switch (_b.label) {
|
|
486
|
-
case 0:
|
|
487
|
-
_a = [this.substrateAddressFrom(validator)];
|
|
488
|
-
return [4 /*yield*/, this.nodeClient
|
|
489
|
-
.getValidatorPrefs(eraIndex, this.substrateAddressFrom(validator))
|
|
490
|
-
.then(function (prefs) { var _a; return (_a = prefs === null || prefs === void 0 ? void 0 : prefs.commission) === null || _a === void 0 ? void 0 : _a.value; })];
|
|
491
|
-
case 1:
|
|
492
|
-
_a = _a.concat([
|
|
493
|
-
_b.sent()
|
|
494
|
-
]);
|
|
495
|
-
return [4 /*yield*/, this.nodeClient.getStakersClipped(eraIndex, this.substrateAddressFrom(validator))];
|
|
496
|
-
case 2: return [2 /*return*/, _a.concat([
|
|
497
|
-
_b.sent()
|
|
498
|
-
])];
|
|
499
|
-
}
|
|
500
|
-
});
|
|
501
|
-
}); }))
|
|
502
|
-
])];
|
|
503
|
-
case 1:
|
|
504
|
-
results = _a.sent();
|
|
505
|
-
reward = results[0];
|
|
506
|
-
rewardPoints = results[1];
|
|
507
|
-
exposuresWithValidators = results[2];
|
|
508
|
-
if (!reward || !rewardPoints || !exposuresWithValidators) {
|
|
509
|
-
return [2 /*return*/, undefined];
|
|
510
|
-
}
|
|
511
|
-
partialRewards = exposuresWithValidators
|
|
512
|
-
.map(function (_a) {
|
|
513
|
-
var _b, _c, _d, _e;
|
|
514
|
-
var validator = _a[0], commission = _a[1], exposure = _a[2];
|
|
515
|
-
var validatorPoints = (_c = (_b = rewardPoints.individual.elements.find(function (element) { return element.first.compare(validator) === 0; })) === null || _b === void 0 ? void 0 : _b.second) === null || _c === void 0 ? void 0 : _c.value;
|
|
516
|
-
var nominatorStake = (_e = (_d = exposure === null || exposure === void 0 ? void 0 : exposure.others.elements.find(function (element) { return element.first.compare(accountId) === 0; })) === null || _d === void 0 ? void 0 : _d.second) === null || _e === void 0 ? void 0 : _e.value;
|
|
517
|
-
if (commission && exposure && validatorPoints && nominatorStake) {
|
|
518
|
-
var validatorReward = _this.calculateValidatorReward(reward, rewardPoints.total.value, validatorPoints);
|
|
519
|
-
return _this.calculateNominatorReward(validatorReward, commission, exposure.total.value, nominatorStake);
|
|
520
|
-
}
|
|
521
|
-
else {
|
|
522
|
-
return undefined;
|
|
523
|
-
}
|
|
524
|
-
})
|
|
525
|
-
.filter(function (reward) { return reward !== undefined; });
|
|
526
|
-
if (partialRewards.every(function (reward) { return !reward; })) {
|
|
527
|
-
return [2 /*return*/, undefined];
|
|
528
|
-
}
|
|
529
|
-
return [2 /*return*/, {
|
|
530
|
-
eraIndex: eraIndex,
|
|
531
|
-
amount: partialRewards.reduce(function (sum, next) { return sum.plus(next); }, new bignumber_1.default(0)).toFixed(0),
|
|
532
|
-
exposures: exposuresWithValidators === null || exposuresWithValidators === void 0 ? void 0 : exposuresWithValidators.map(function (_a) {
|
|
533
|
-
var validator = _a[0], _ = _a[1], exposure = _a[2];
|
|
534
|
-
return [
|
|
535
|
-
validator.asString(),
|
|
536
|
-
exposure === null || exposure === void 0 ? void 0 : exposure.others.elements.findIndex(function (element) { return element.first.compare(accountId) === 0; })
|
|
537
|
-
];
|
|
538
|
-
}).filter(function (_a) {
|
|
539
|
-
var _ = _a[0], index = _a[1];
|
|
540
|
-
return index !== undefined;
|
|
541
|
-
})
|
|
542
|
-
}];
|
|
543
|
-
}
|
|
334
|
+
}
|
|
335
|
+
if (isBonded && !isDelegating && !isUnbonding) {
|
|
336
|
+
availableActions.push({
|
|
337
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.UNBOND,
|
|
338
|
+
args: ['value']
|
|
544
339
|
});
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
PolkadotAccountController.prototype.calculateNominatorReward = function (validatorReward, validatorCommission, totalStake, nominatorStake) {
|
|
551
|
-
var nominatorShare = nominatorStake.dividedBy(totalStake);
|
|
552
|
-
return new bignumber_1.default(1).minus(validatorCommission.dividedBy(1000000000)).multipliedBy(validatorReward).multipliedBy(nominatorShare);
|
|
553
|
-
};
|
|
554
|
-
// tslint:disable-next-line: cyclomatic-complexity
|
|
555
|
-
PolkadotAccountController.prototype.getAvailableStakingActions = function (stakingDetails, nominations, validatorIds, maxDelegationValue) {
|
|
556
|
-
var _a, _b, _c, _d;
|
|
557
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
558
|
-
var availableActions, currentValidators, validatorAddresses, bondedValue, minDelegationValue, isBonded, hasEnoughBond, isDelegating, isUnbonding, hasFundsToWithdraw;
|
|
559
|
-
var _this = this;
|
|
560
|
-
return __generator(this, function (_e) {
|
|
561
|
-
switch (_e.label) {
|
|
562
|
-
case 0:
|
|
563
|
-
availableActions = [];
|
|
564
|
-
currentValidators = ((_b = (_a = nominations === null || nominations === void 0 ? void 0 : nominations.targets) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.map(function (target) { return target.asAddress(); })) || [];
|
|
565
|
-
validatorAddresses = validatorIds.map(function (id) { return _this.substrateAddressFrom(id).asString(); });
|
|
566
|
-
bondedValue = new bignumber_1.default((_c = stakingDetails === null || stakingDetails === void 0 ? void 0 : stakingDetails.active) !== null && _c !== void 0 ? _c : 0);
|
|
567
|
-
return [4 /*yield*/, this.nodeClient.getMinNominatorBond()];
|
|
568
|
-
case 1:
|
|
569
|
-
minDelegationValue = _e.sent();
|
|
570
|
-
isBonded = bondedValue.gt(0);
|
|
571
|
-
hasEnoughBond = bondedValue.gte(minDelegationValue !== null && minDelegationValue !== void 0 ? minDelegationValue : 0);
|
|
572
|
-
isDelegating = nominations !== undefined;
|
|
573
|
-
isUnbonding = stakingDetails && stakingDetails.locked.length > 0;
|
|
574
|
-
hasFundsToWithdraw = new bignumber_1.default((_d = stakingDetails === null || stakingDetails === void 0 ? void 0 : stakingDetails.unlocked) !== null && _d !== void 0 ? _d : 0).gt(0);
|
|
575
|
-
if (maxDelegationValue.gt(0) && !isBonded && !isUnbonding) {
|
|
576
|
-
availableActions.push({
|
|
577
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.BOND_NOMINATE,
|
|
578
|
-
args: ['targets', 'controller', 'value', 'payee']
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
if (isBonded && !isDelegating && hasEnoughBond && !isUnbonding) {
|
|
582
|
-
availableActions.push({
|
|
583
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.NOMINATE,
|
|
584
|
-
args: ['targets']
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
|
-
if (maxDelegationValue.gt(0) && isBonded && !isUnbonding) {
|
|
588
|
-
availableActions.push({
|
|
589
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.BOND_EXTRA,
|
|
590
|
-
args: ['value']
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
if (isBonded && !isDelegating && !isUnbonding) {
|
|
594
|
-
availableActions.push({
|
|
595
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.UNBOND,
|
|
596
|
-
args: ['value']
|
|
597
|
-
});
|
|
598
|
-
}
|
|
599
|
-
if (isUnbonding && !isDelegating) {
|
|
600
|
-
availableActions.push({
|
|
601
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.REBOND_NOMINATE,
|
|
602
|
-
args: ['targets', 'value']
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
if (isUnbonding && isDelegating) {
|
|
606
|
-
availableActions.push({
|
|
607
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.REBOND_EXTRA,
|
|
608
|
-
args: ['value']
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
if (isDelegating) {
|
|
612
|
-
if (validatorAddresses.every(function (validator) { return currentValidators.includes(validator); }) &&
|
|
613
|
-
validatorAddresses.length === currentValidators.length) {
|
|
614
|
-
availableActions.push({
|
|
615
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.CANCEL_NOMINATION,
|
|
616
|
-
args: ['value']
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
else if (validatorAddresses.length > 0) {
|
|
620
|
-
availableActions.push({
|
|
621
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.CHANGE_NOMINATION,
|
|
622
|
-
args: ['targets']
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
if (hasFundsToWithdraw) {
|
|
627
|
-
availableActions.push({
|
|
628
|
-
type: PolkadotStakingActionType_1.PolkadotStakingActionType.WITHDRAW_UNBONDED,
|
|
629
|
-
args: []
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
availableActions.sort(function (a, b) { return a.type - b.type; });
|
|
633
|
-
return [2 /*return*/, availableActions];
|
|
634
|
-
}
|
|
340
|
+
}
|
|
341
|
+
if (isUnbonding && !isDelegating) {
|
|
342
|
+
availableActions.push({
|
|
343
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.REBOND_NOMINATE,
|
|
344
|
+
args: ['targets', 'value']
|
|
635
345
|
});
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
return __generator(this, function (_b) {
|
|
642
|
-
switch (_b.label) {
|
|
643
|
-
case 0:
|
|
644
|
-
_b.trys.push([0, 3, , 4]);
|
|
645
|
-
return [4 /*yield*/, this.nodeClient.getIdentityOf(address)];
|
|
646
|
-
case 1:
|
|
647
|
-
registration = _b.sent();
|
|
648
|
-
if (registration) {
|
|
649
|
-
return [2 /*return*/, registration.identityInfo];
|
|
650
|
-
}
|
|
651
|
-
return [4 /*yield*/, this.nodeClient.getSuperOf(address)];
|
|
652
|
-
case 2:
|
|
653
|
-
superOf = _b.sent();
|
|
654
|
-
return [2 /*return*/, superOf ? this.getAccountIdentityInfo(superOf.first.address) : undefined];
|
|
655
|
-
case 3:
|
|
656
|
-
_a = _b.sent();
|
|
657
|
-
return [2 /*return*/, undefined];
|
|
658
|
-
case 4: return [2 /*return*/];
|
|
659
|
-
}
|
|
346
|
+
}
|
|
347
|
+
if (isUnbonding && isDelegating) {
|
|
348
|
+
availableActions.push({
|
|
349
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.REBOND_EXTRA,
|
|
350
|
+
args: ['value']
|
|
660
351
|
});
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
352
|
+
}
|
|
353
|
+
if (isDelegating) {
|
|
354
|
+
if (validatorAddresses.every((validator) => currentValidators.includes(validator)) &&
|
|
355
|
+
validatorAddresses.length === currentValidators.length) {
|
|
356
|
+
availableActions.push({
|
|
357
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.CANCEL_NOMINATION,
|
|
358
|
+
args: ['value']
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
else if (validatorAddresses.length > 0) {
|
|
362
|
+
availableActions.push({
|
|
363
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.CHANGE_NOMINATION,
|
|
364
|
+
args: ['targets']
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (hasFundsToWithdraw) {
|
|
369
|
+
availableActions.push({
|
|
370
|
+
type: PolkadotStakingActionType_1.PolkadotStakingActionType.WITHDRAW_UNBONDED,
|
|
371
|
+
args: []
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
availableActions.sort((a, b) => a.type - b.type);
|
|
375
|
+
return availableActions;
|
|
376
|
+
}
|
|
377
|
+
async getAccountIdentityInfo(address) {
|
|
378
|
+
try {
|
|
379
|
+
const registration = await this.nodeClient.getIdentityOf(address);
|
|
380
|
+
if (registration) {
|
|
381
|
+
return registration.identityInfo;
|
|
382
|
+
}
|
|
383
|
+
const superOf = await this.nodeClient.getSuperOf(address);
|
|
384
|
+
return superOf ? this.getAccountIdentityInfo(superOf.first.address) : undefined;
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
return undefined;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
partitionArray(array, predicate) {
|
|
391
|
+
const partitioned = [[], []];
|
|
392
|
+
for (const item of array) {
|
|
393
|
+
const index = predicate(item) ? 0 : 1;
|
|
668
394
|
partitioned[index].push(item);
|
|
669
395
|
}
|
|
670
396
|
return partitioned;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
}(v1_1.SubstrateCommonAccountController));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
674
399
|
exports.PolkadotAccountController = PolkadotAccountController;
|
|
675
400
|
//# sourceMappingURL=PolkadotAccountController.js.map
|