@subwallet/extension-base 1.2.4-0 → 1.2.5-0
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/cjs/koni/api/staking/bonding/utils.js +38 -6
- package/cjs/koni/background/handlers/Tabs.js +3 -2
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/index.js +4 -2
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +104 -113
- package/cjs/services/earning-service/service.js +1 -1
- package/cjs/services/earning-service/utils/index.js +6 -1
- package/cjs/services/request-service/constants.js +5 -3
- package/cjs/services/request-service/handler/AuthRequestHandler.js +32 -12
- package/koni/api/staking/bonding/utils.d.ts +6 -2
- package/koni/api/staking/bonding/utils.js +33 -4
- package/koni/background/handlers/Tabs.js +3 -2
- package/package.json +5 -5
- package/packageInfo.js +1 -1
- package/page/index.d.ts +2 -2
- package/page/index.js +4 -2
- package/services/earning-service/handlers/native-staking/relay-chain.d.ts +5 -2
- package/services/earning-service/handlers/native-staking/relay-chain.js +106 -115
- package/services/earning-service/service.js +1 -1
- package/services/earning-service/utils/index.d.ts +2 -0
- package/services/earning-service/utils/index.js +6 -2
- package/services/request-service/constants.d.ts +1 -0
- package/services/request-service/constants.js +4 -2
- package/services/request-service/handler/AuthRequestHandler.d.ts +1 -0
- package/services/request-service/handler/AuthRequestHandler.js +22 -3
|
@@ -21,12 +21,15 @@ exports.getExistUnstakeErrorMessage = void 0;
|
|
|
21
21
|
exports.getInflationParams = getInflationParams;
|
|
22
22
|
exports.getMinStakeErrorMessage = exports.getMaxValidatorErrorMessage = void 0;
|
|
23
23
|
exports.getParaCurrentInflation = getParaCurrentInflation;
|
|
24
|
+
exports.getRelayBlockedValidatorList = getRelayBlockedValidatorList;
|
|
25
|
+
exports.getRelayEraRewardMap = getRelayEraRewardMap;
|
|
26
|
+
exports.getRelayMaxNominations = getRelayMaxNominations;
|
|
27
|
+
exports.getRelayTopValidatorByPoints = getRelayTopValidatorByPoints;
|
|
28
|
+
exports.getRelayValidatorPointsMap = getRelayValidatorPointsMap;
|
|
24
29
|
exports.getStakingAvailableActionsByChain = getStakingAvailableActionsByChain;
|
|
25
30
|
exports.getStakingAvailableActionsByNominator = getStakingAvailableActionsByNominator;
|
|
26
31
|
exports.getSupportedDaysByHistoryDepth = getSupportedDaysByHistoryDepth;
|
|
27
|
-
exports.getTopValidatorByPoints = getTopValidatorByPoints;
|
|
28
32
|
exports.getValidatorLabel = getValidatorLabel;
|
|
29
|
-
exports.getValidatorPointsMap = getValidatorPointsMap;
|
|
30
33
|
exports.getWithdrawalInfo = getWithdrawalInfo;
|
|
31
34
|
exports.getYieldAvailableActionsByPosition = getYieldAvailableActionsByPosition;
|
|
32
35
|
exports.getYieldAvailableActionsByType = getYieldAvailableActionsByType;
|
|
@@ -393,14 +396,13 @@ function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liveDay) {
|
|
|
393
396
|
return maxSupportDay;
|
|
394
397
|
}
|
|
395
398
|
}
|
|
396
|
-
function
|
|
399
|
+
function getRelayValidatorPointsMap(eraRewardMap) {
|
|
397
400
|
// mapping store validator and totalPoints
|
|
398
401
|
const validatorTotalPointsMap = {};
|
|
399
402
|
Object.values(eraRewardMap).forEach(info => {
|
|
400
403
|
const individual = info.individual;
|
|
401
404
|
Object.entries(individual).forEach(_ref => {
|
|
402
|
-
let [validator,
|
|
403
|
-
const points = rawPoints.replaceAll(',', '');
|
|
405
|
+
let [validator, points] = _ref;
|
|
404
406
|
if (!validatorTotalPointsMap[validator]) {
|
|
405
407
|
validatorTotalPointsMap[validator] = new _bignumber.default(points);
|
|
406
408
|
} else {
|
|
@@ -410,7 +412,7 @@ function getValidatorPointsMap(eraRewardMap) {
|
|
|
410
412
|
});
|
|
411
413
|
return validatorTotalPointsMap;
|
|
412
414
|
}
|
|
413
|
-
function
|
|
415
|
+
function getRelayTopValidatorByPoints(validatorPointsList) {
|
|
414
416
|
const sortValidatorPointsList = Object.fromEntries(Object.entries(validatorPointsList).sort((a, b) => a[1].minus(b[1]).toNumber()).reverse());
|
|
415
417
|
|
|
416
418
|
// keep 50% first validator
|
|
@@ -420,6 +422,36 @@ function getTopValidatorByPoints(validatorPointsList) {
|
|
|
420
422
|
const top50PercentRecord = Object.fromEntries(top50PercentEntries);
|
|
421
423
|
return Object.keys(top50PercentRecord);
|
|
422
424
|
}
|
|
425
|
+
function getRelayBlockedValidatorList(validators) {
|
|
426
|
+
const blockValidatorList = [];
|
|
427
|
+
for (const validator of validators) {
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
429
|
+
const validatorAddress = validator[0].toHuman()[0];
|
|
430
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
431
|
+
const validatorPrefs = validator[1].toHuman();
|
|
432
|
+
const isBlocked = validatorPrefs.blocked;
|
|
433
|
+
if (isBlocked) {
|
|
434
|
+
blockValidatorList.push(validatorAddress);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return blockValidatorList;
|
|
438
|
+
}
|
|
439
|
+
function getRelayEraRewardMap(eraRewardPointArray, startEraForPoints) {
|
|
440
|
+
const eraRewardMap = {};
|
|
441
|
+
for (const item of eraRewardPointArray) {
|
|
442
|
+
eraRewardMap[startEraForPoints] = item.toPrimitive();
|
|
443
|
+
startEraForPoints++;
|
|
444
|
+
}
|
|
445
|
+
return eraRewardMap;
|
|
446
|
+
}
|
|
447
|
+
async function getRelayMaxNominations(substrateApi) {
|
|
448
|
+
var _substrateApi$api$con, _substrateApi$api$con2, _substrateApi$api$cal;
|
|
449
|
+
await substrateApi.isReady;
|
|
450
|
+
const maxNominations = ((_substrateApi$api$con = substrateApi.api.consts.staking) === null || _substrateApi$api$con === void 0 ? void 0 : (_substrateApi$api$con2 = _substrateApi$api$con.maxNominations) === null || _substrateApi$api$con2 === void 0 ? void 0 : _substrateApi$api$con2.toString()) || '16';
|
|
451
|
+
const _maxNominationsByNominationQuota = await ((_substrateApi$api$cal = substrateApi.api.call.stakingApi) === null || _substrateApi$api$cal === void 0 ? void 0 : _substrateApi$api$cal.nominationsQuota(0)); // todo: review param. Currently return constant for all param.
|
|
452
|
+
const maxNominationsByNominationQuota = _maxNominationsByNominationQuota === null || _maxNominationsByNominationQuota === void 0 ? void 0 : _maxNominationsByNominationQuota.toString();
|
|
453
|
+
return maxNominationsByNominationQuota || maxNominations;
|
|
454
|
+
}
|
|
423
455
|
const getMinStakeErrorMessage = (chainInfo, bnMinStake) => {
|
|
424
456
|
const tokenInfo = (0, _utils._getChainNativeTokenBasicInfo)(chainInfo);
|
|
425
457
|
const number = (0, _number.formatNumber)(bnMinStake.toString(), tokenInfo.decimals || 0, _number.balanceFormatter);
|
|
@@ -276,7 +276,7 @@ class KoniTabs {
|
|
|
276
276
|
anyType
|
|
277
277
|
} = _ref10;
|
|
278
278
|
const authInfo = await this.getAuthInfo(url);
|
|
279
|
-
return transformAccountsV2(this.#koniState.keyringService.accounts, anyType, authInfo, accountAuthType);
|
|
279
|
+
return transformAccountsV2(this.#koniState.keyringService.accounts, anyType, authInfo, (authInfo === null || authInfo === void 0 ? void 0 : authInfo.accountAuthType) || accountAuthType);
|
|
280
280
|
}
|
|
281
281
|
accountsSubscribeV2(url, _ref11, id, port) {
|
|
282
282
|
let {
|
|
@@ -289,8 +289,9 @@ class KoniTabs {
|
|
|
289
289
|
this.#accountSubs[id] = {
|
|
290
290
|
subscription: authInfoSubject.subscribe(infos => {
|
|
291
291
|
this.getAuthInfo(url, infos).then(authInfo => {
|
|
292
|
+
const accountAuthType_ = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.accountAuthType) || accountAuthType;
|
|
292
293
|
const accounts = this.#koniState.keyringService.accounts;
|
|
293
|
-
return cb(transformAccountsV2(accounts, false, authInfo,
|
|
294
|
+
return cb(transformAccountsV2(accounts, false, authInfo, accountAuthType_));
|
|
294
295
|
}).catch(console.error);
|
|
295
296
|
}),
|
|
296
297
|
url
|
package/cjs/packageInfo.js
CHANGED
package/cjs/page/index.js
CHANGED
|
@@ -41,9 +41,11 @@ function sendMessage(message, request, subscriber) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// the enable function, called by the dapp to allow access
|
|
44
|
-
|
|
44
|
+
|
|
45
|
+
async function enable(origin, opt) {
|
|
45
46
|
await sendMessage('pub(authorize.tabV2)', {
|
|
46
|
-
origin
|
|
47
|
+
origin,
|
|
48
|
+
accountAuthType: (opt === null || opt === void 0 ? void 0 : opt.accountAuthType) || 'substrate'
|
|
47
49
|
});
|
|
48
50
|
return new _Injected.default(sendMessage);
|
|
49
51
|
}
|
|
@@ -51,17 +51,14 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
51
51
|
await defaultCallback();
|
|
52
52
|
await substrateApi.isReady;
|
|
53
53
|
const unsub = await ((_substrateApi$api$que = substrateApi.api.query.staking) === null || _substrateApi$api$que === void 0 ? void 0 : _substrateApi$api$que.currentEra(async _currentEra => {
|
|
54
|
-
var _substrateApi$api$con, _substrateApi$api$
|
|
54
|
+
var _substrateApi$api$con, _substrateApi$api$que2, _substrateApi$api$que3, _substrateApi$api$que4, _substrateApi$api$que5, _substrateApi$api$que6;
|
|
55
55
|
if (cancel) {
|
|
56
56
|
unsub();
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
|
-
let maxNominations = ((_substrateApi$api$con = substrateApi.api.consts.staking) === null || _substrateApi$api$con === void 0 ? void 0 : (_substrateApi$api$con2 = _substrateApi$api$con.maxNominations) === null || _substrateApi$api$con2 === void 0 ? void 0 : _substrateApi$api$con2.toString()) || '16';
|
|
60
59
|
const unlimitedNominatorRewarded = substrateApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
61
|
-
const maxNominatorRewarded = (_substrateApi$api$
|
|
62
|
-
const
|
|
63
|
-
const maxNominationsByNominationQuota = _maxNominationsByNominationQuota === null || _maxNominationsByNominationQuota === void 0 ? void 0 : _maxNominationsByNominationQuota.toString();
|
|
64
|
-
maxNominations = maxNominationsByNominationQuota !== null && maxNominationsByNominationQuota !== void 0 ? maxNominationsByNominationQuota : maxNominations;
|
|
60
|
+
const maxNominatorRewarded = (_substrateApi$api$con = substrateApi.api.consts.staking.maxNominatorRewardedPerValidator) === null || _substrateApi$api$con === void 0 ? void 0 : _substrateApi$api$con.toString();
|
|
61
|
+
const maxNominations = await (0, _utils.getRelayMaxNominations)(substrateApi);
|
|
65
62
|
const currentEra = _currentEra.toString();
|
|
66
63
|
const maxUnlockingChunks = substrateApi.api.consts.staking.maxUnlockingChunks.toString();
|
|
67
64
|
const unlockingEras = substrateApi.api.consts.staking.bondingDuration.toString();
|
|
@@ -140,54 +137,15 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
140
137
|
const [_nominations, _bonded, _activeEra] = await Promise.all([(_substrateApi$api$que7 = substrateApi.api.query) === null || _substrateApi$api$que7 === void 0 ? void 0 : (_substrateApi$api$que8 = _substrateApi$api$que7.staking) === null || _substrateApi$api$que8 === void 0 ? void 0 : _substrateApi$api$que8.nominators(address), (_substrateApi$api$que9 = substrateApi.api.query) === null || _substrateApi$api$que9 === void 0 ? void 0 : (_substrateApi$api$que10 = _substrateApi$api$que9.staking) === null || _substrateApi$api$que10 === void 0 ? void 0 : _substrateApi$api$que10.bonded(address), (_substrateApi$api$que11 = substrateApi.api.query) === null || _substrateApi$api$que11 === void 0 ? void 0 : (_substrateApi$api$que12 = _substrateApi$api$que11.staking) === null || _substrateApi$api$que12 === void 0 ? void 0 : _substrateApi$api$que12.activeEra()]);
|
|
141
138
|
const unlimitedNominatorRewarded = substrateApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
142
139
|
const _maxNominatorRewardedPerValidator = (substrateApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
|
|
143
|
-
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
|
|
140
|
+
const maxNominatorRewardedPerValidator = unlimitedNominatorRewarded ? undefined : parseInt(_maxNominatorRewardedPerValidator);
|
|
144
141
|
const nominations = _nominations.toPrimitive();
|
|
145
142
|
const bonded = _bonded.toHuman();
|
|
143
|
+
const addressFormatted = (0, _utils4.reformatAddress)(address, (0, _utils2._getChainSubstrateAddressPrefix)(chainInfo));
|
|
146
144
|
const activeStake = ledger.active.toString();
|
|
147
145
|
const totalStake = ledger.total.toString();
|
|
148
146
|
const unstakingBalance = (ledger.total - ledger.active).toString();
|
|
149
|
-
const nominationList = [];
|
|
150
147
|
const unstakingList = [];
|
|
151
|
-
|
|
152
|
-
const validatorList = nominations.targets;
|
|
153
|
-
await Promise.all(validatorList.map(async validatorAddress => {
|
|
154
|
-
let nominationStatus = _types.EarningStatus.NOT_EARNING;
|
|
155
|
-
let eraStakerOtherList = [];
|
|
156
|
-
let identity;
|
|
157
|
-
if (_constants2._UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
158
|
-
// todo: review all relaychains later
|
|
159
|
-
const [[_identity], _eraStaker] = await Promise.all([(0, _utils3.parseIdentity)(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
|
|
160
|
-
identity = _identity;
|
|
161
|
-
eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
|
|
162
|
-
} else {
|
|
163
|
-
const [[_identity], _eraStaker] = await Promise.all([(0, _utils3.parseIdentity)(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
164
|
-
identity = _identity;
|
|
165
|
-
const eraStaker = _eraStaker.toPrimitive();
|
|
166
|
-
eraStakerOtherList = eraStaker.others;
|
|
167
|
-
}
|
|
168
|
-
const sortedNominators = eraStakerOtherList.sort((a, b) => {
|
|
169
|
-
return new _bignumber.default(b.value).minus(a.value).toNumber();
|
|
170
|
-
});
|
|
171
|
-
const topNominators = sortedNominators.map(nominator => {
|
|
172
|
-
return nominator.who;
|
|
173
|
-
});
|
|
174
|
-
if (!topNominators.includes((0, _utils4.reformatAddress)(address, (0, _utils2._getChainSubstrateAddressPrefix)(chainInfo)))) {
|
|
175
|
-
// if nominator has target but not in nominator list
|
|
176
|
-
nominationStatus = _types.EarningStatus.WAITING;
|
|
177
|
-
} else if (topNominators.slice(0, unlimitedNominatorRewarded ? undefined : maxNominatorRewardedPerValidator).includes((0, _utils4.reformatAddress)(address, (0, _utils2._getChainSubstrateAddressPrefix)(chainInfo)))) {
|
|
178
|
-
// if address in top nominators
|
|
179
|
-
nominationStatus = _types.EarningStatus.EARNING_REWARD;
|
|
180
|
-
}
|
|
181
|
-
nominationList.push({
|
|
182
|
-
chain,
|
|
183
|
-
validatorAddress,
|
|
184
|
-
status: nominationStatus,
|
|
185
|
-
validatorIdentity: identity,
|
|
186
|
-
activeStake: '0' // relaychain allocates stake accordingly
|
|
187
|
-
});
|
|
188
|
-
}));
|
|
189
|
-
}
|
|
190
|
-
|
|
148
|
+
const nominationList = (await this.handleNominationsList(substrateApi, chain, nominations, currentEra, addressFormatted, maxNominatorRewardedPerValidator)) || [];
|
|
191
149
|
let stakingStatus = _types.EarningStatus.NOT_EARNING;
|
|
192
150
|
const bnActiveStake = new _util.BN(activeStake);
|
|
193
151
|
let waitingNominationCount = 0;
|
|
@@ -231,6 +189,51 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
231
189
|
unstakings: unstakingList
|
|
232
190
|
};
|
|
233
191
|
}
|
|
192
|
+
async handleNominationsList(substrateApi, chain, nominations, currentEra, address, maxNominatorRewardedPerValidator) {
|
|
193
|
+
const nominationList = [];
|
|
194
|
+
if (!nominations) {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
const validatorList = nominations.targets;
|
|
198
|
+
await Promise.all(validatorList.map(async validatorAddress => {
|
|
199
|
+
let nominationStatus = _types.EarningStatus.NOT_EARNING;
|
|
200
|
+
let eraStakerOtherList = [];
|
|
201
|
+
let identity;
|
|
202
|
+
if (_constants2._UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
203
|
+
// todo: review all relaychains later
|
|
204
|
+
const [[_identity], _eraStaker] = await Promise.all([(0, _utils3.parseIdentity)(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
|
|
205
|
+
identity = _identity;
|
|
206
|
+
eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
|
|
207
|
+
} else {
|
|
208
|
+
const [[_identity], _eraStaker] = await Promise.all([(0, _utils3.parseIdentity)(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
209
|
+
identity = _identity;
|
|
210
|
+
const eraStaker = _eraStaker.toPrimitive();
|
|
211
|
+
eraStakerOtherList = eraStaker.others;
|
|
212
|
+
}
|
|
213
|
+
const sortedNominators = eraStakerOtherList.sort((a, b) => {
|
|
214
|
+
return new _bignumber.default(b.value).minus(a.value).toNumber();
|
|
215
|
+
});
|
|
216
|
+
const topNominators = sortedNominators.map(nominator => {
|
|
217
|
+
return nominator.who;
|
|
218
|
+
});
|
|
219
|
+
if (!topNominators.includes(address)) {
|
|
220
|
+
// if nominator has target but not in nominator list
|
|
221
|
+
nominationStatus = _types.EarningStatus.WAITING;
|
|
222
|
+
} else if (topNominators.slice(0, maxNominatorRewardedPerValidator).includes(address)) {
|
|
223
|
+
// if address in top nominators
|
|
224
|
+
nominationStatus = _types.EarningStatus.EARNING_REWARD;
|
|
225
|
+
}
|
|
226
|
+
nominationList.push({
|
|
227
|
+
chain,
|
|
228
|
+
validatorAddress,
|
|
229
|
+
status: nominationStatus,
|
|
230
|
+
validatorIdentity: identity,
|
|
231
|
+
activeStake: '0' // relaychain allocates stake accordingly
|
|
232
|
+
});
|
|
233
|
+
}));
|
|
234
|
+
|
|
235
|
+
return nominationList;
|
|
236
|
+
}
|
|
234
237
|
async subscribePoolPosition(useAddresses, resultCallback) {
|
|
235
238
|
var _substrateApi$api$que13;
|
|
236
239
|
let cancel = false;
|
|
@@ -292,7 +295,6 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
292
295
|
|
|
293
296
|
async getPoolTargets() {
|
|
294
297
|
var _chainApi$api$query$s;
|
|
295
|
-
const decimals = this.nativeToken.decimals || 0;
|
|
296
298
|
const chainApi = await this.substrateApi.isReady;
|
|
297
299
|
const poolInfo = await this.getPoolInfo();
|
|
298
300
|
if (!poolInfo || !poolInfo.statistic) {
|
|
@@ -302,11 +304,9 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
302
304
|
const currentEra = _era.toString();
|
|
303
305
|
const activeEraInfo = _activeEraInfo.toPrimitive();
|
|
304
306
|
const activeEra = activeEraInfo.index;
|
|
305
|
-
const allValidators = [];
|
|
306
|
-
const validatorInfoList = [];
|
|
307
307
|
const maxEraRewardPointsEras = _constants2.MaxEraRewardPointsEras;
|
|
308
308
|
const endEraForPoints = parseInt(activeEra) - 1;
|
|
309
|
-
|
|
309
|
+
const startEraForPoints = Math.max(endEraForPoints - maxEraRewardPointsEras + 1, 0);
|
|
310
310
|
let _eraStakersPromise;
|
|
311
311
|
if (_constants2._UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
312
312
|
// todo: review all relaychains later
|
|
@@ -315,43 +315,65 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
315
315
|
_eraStakersPromise = chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra));
|
|
316
316
|
}
|
|
317
317
|
const [_totalEraStake, _eraStakers, _minBond, _stakingRewards, _validators, ..._eraRewardPoints] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), _eraStakersPromise, chainApi.api.query.staking.minNominatorBond(), ((_chainApi$api$query$s = chainApi.api.query.stakingRewards) === null || _chainApi$api$query$s === void 0 ? void 0 : _chainApi$api$query$s.data) && chainApi.api.query.stakingRewards.data(), chainApi.api.query.staking.validators.entries(), chainApi.api.query.staking.erasRewardPoints.multi([...Array(maxEraRewardPointsEras).keys()].map(i => i + startEraForPoints))]);
|
|
318
|
-
const eraRewardMap =
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
startEraForPoints++;
|
|
322
|
-
}
|
|
323
|
-
const validatorPointsMap = (0, _utils.getValidatorPointsMap)(eraRewardMap);
|
|
324
|
-
const topValidatorList = (0, _utils.getTopValidatorByPoints)(validatorPointsMap);
|
|
325
|
-
|
|
326
|
-
// filter blocked validators
|
|
318
|
+
const eraRewardMap = (0, _utils.getRelayEraRewardMap)(_eraRewardPoints[0], startEraForPoints);
|
|
319
|
+
const validatorPointsMap = (0, _utils.getRelayValidatorPointsMap)(eraRewardMap);
|
|
320
|
+
const topValidatorList = (0, _utils.getRelayTopValidatorByPoints)(validatorPointsMap);
|
|
327
321
|
const validators = _validators;
|
|
328
|
-
const
|
|
329
|
-
for (const validator of validators) {
|
|
330
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
331
|
-
const validatorAddress = validator[0].toHuman()[0];
|
|
332
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
333
|
-
const validatorPrefs = validator[1].toHuman();
|
|
334
|
-
const isBlocked = validatorPrefs.blocked;
|
|
335
|
-
if (isBlocked) {
|
|
336
|
-
blockValidatorList.push(validatorAddress);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
const stakingRewards = _stakingRewards === null || _stakingRewards === void 0 ? void 0 : _stakingRewards.toPrimitive();
|
|
322
|
+
const blockedValidatorList = (0, _utils.getRelayBlockedValidatorList)(validators);
|
|
340
323
|
const unlimitedNominatorRewarded = chainApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
341
324
|
const maxNominatorRewarded = (chainApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
|
|
342
325
|
const bnTotalEraStake = new _util.BN(_totalEraStake.toString());
|
|
343
|
-
const
|
|
344
|
-
const
|
|
326
|
+
const minBond = _minBond.toPrimitive();
|
|
327
|
+
const [totalStakeMap, allValidatorAddresses, validatorInfoList] = this.parseEraStakerData(_eraStakers, blockedValidatorList, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded);
|
|
328
|
+
const extraInfoMap = {};
|
|
329
|
+
await Promise.all(allValidatorAddresses.map(async address => {
|
|
330
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
331
|
+
const [_commissionInfo, [identity, isVerified]] = await Promise.all([chainApi.api.query.staking.validators(address), (0, _utils3.parseIdentity)(chainApi, address)]);
|
|
332
|
+
const commissionInfo = _commissionInfo.toHuman();
|
|
333
|
+
extraInfoMap[address] = {
|
|
334
|
+
commission: commissionInfo.commission,
|
|
335
|
+
blocked: commissionInfo.blocked,
|
|
336
|
+
identity,
|
|
337
|
+
isVerified: isVerified
|
|
338
|
+
};
|
|
339
|
+
}));
|
|
340
|
+
const decimals = this.nativeToken.decimals || 0;
|
|
341
|
+
const bnAvgStake = (0, _utils3.applyDecimal)(bnTotalEraStake.divn(validatorInfoList.length), decimals);
|
|
342
|
+
for (const validator of validatorInfoList) {
|
|
343
|
+
const commissionString = extraInfoMap[validator.address].commission;
|
|
344
|
+
const commission = (0, _utils.getCommission)(commissionString);
|
|
345
|
+
validator.expectedReturn = this.getValidatorExpectedReturn(this.chain, validator, poolInfo.statistic.totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake);
|
|
346
|
+
validator.commission = commission;
|
|
347
|
+
validator.blocked = extraInfoMap[validator.address].blocked;
|
|
348
|
+
validator.identity = extraInfoMap[validator.address].identity;
|
|
349
|
+
validator.isVerified = extraInfoMap[validator.address].isVerified;
|
|
350
|
+
}
|
|
351
|
+
return validatorInfoList;
|
|
352
|
+
}
|
|
353
|
+
getValidatorExpectedReturn(chain, validator, totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake) {
|
|
354
|
+
if (_constants2._STAKING_CHAIN_GROUP.aleph.includes(chain)) {
|
|
355
|
+
return (0, _utils.calculateAlephZeroValidatorReturn)(totalApy, commission);
|
|
356
|
+
} else if (_constants2._STAKING_CHAIN_GROUP.ternoa.includes(chain)) {
|
|
357
|
+
const stakingRewards = _stakingRewards === null || _stakingRewards === void 0 ? void 0 : _stakingRewards.toPrimitive();
|
|
358
|
+
const rewardPerValidator = (0, _utils3.applyDecimal)(new _util.BN(stakingRewards.sessionExtraRewardPayout).divn(allValidatorAddresses.length), decimals);
|
|
359
|
+
const validatorStake = (0, _utils3.applyDecimal)(totalStakeMap[validator.address], decimals).toNumber();
|
|
360
|
+
return (0, _utils.calculateTernoaValidatorReturn)(rewardPerValidator.toNumber(), validatorStake, commission);
|
|
361
|
+
} else {
|
|
362
|
+
const bnValidatorStake = (0, _utils3.applyDecimal)(totalStakeMap[validator.address], decimals);
|
|
363
|
+
return (0, _utils.calculateValidatorStakedReturn)(totalApy, bnValidatorStake, bnAvgStake, commission);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
parseEraStakerData(_eraStakers, blockedValidatorList, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded) {
|
|
345
367
|
const totalStakeMap = {};
|
|
346
|
-
const
|
|
347
|
-
const
|
|
348
|
-
for (const item of
|
|
368
|
+
const allValidatorAddresses = [];
|
|
369
|
+
const validatorInfoList = [];
|
|
370
|
+
for (const item of _eraStakers) {
|
|
349
371
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
350
372
|
const rawValidatorInfo = item[0].toHuman();
|
|
351
373
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
352
374
|
const rawValidatorStat = item[1].toPrimitive();
|
|
353
375
|
const validatorAddress = rawValidatorInfo[1];
|
|
354
|
-
if (!
|
|
376
|
+
if (!blockedValidatorList.includes(validatorAddress)) {
|
|
355
377
|
var _validatorPointsMap$v;
|
|
356
378
|
let isTopQuartile = false;
|
|
357
379
|
if (topValidatorList.includes(validatorAddress)) {
|
|
@@ -372,7 +394,7 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
372
394
|
nominatorCount = others.length;
|
|
373
395
|
}
|
|
374
396
|
}
|
|
375
|
-
|
|
397
|
+
allValidatorAddresses.push(validatorAddress);
|
|
376
398
|
validatorInfoList.push({
|
|
377
399
|
address: validatorAddress,
|
|
378
400
|
totalStake: bnTotalStake.toString(),
|
|
@@ -384,46 +406,15 @@ class RelayNativeStakingPoolHandler extends _base.default {
|
|
|
384
406
|
expectedReturn: 0,
|
|
385
407
|
blocked: false,
|
|
386
408
|
isVerified: false,
|
|
387
|
-
minBond,
|
|
409
|
+
minBond: minBond.toString(),
|
|
388
410
|
isCrowded: unlimitedNominatorRewarded ? false : nominatorCount > parseInt(maxNominatorRewarded),
|
|
389
411
|
eraRewardPoint: ((_validatorPointsMap$v = validatorPointsMap[validatorAddress]) !== null && _validatorPointsMap$v !== void 0 ? _validatorPointsMap$v : _util.BN_ZERO).toString(),
|
|
390
412
|
topQuartile: isTopQuartile
|
|
391
413
|
});
|
|
392
414
|
}
|
|
393
415
|
}
|
|
394
|
-
|
|
395
|
-
await Promise.all(allValidators.map(async address => {
|
|
396
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
397
|
-
const [_commissionInfo, [identity, isVerified]] = await Promise.all([chainApi.api.query.staking.validators(address), (0, _utils3.parseIdentity)(chainApi, address)]);
|
|
398
|
-
const commissionInfo = _commissionInfo.toHuman();
|
|
399
|
-
extraInfoMap[address] = {
|
|
400
|
-
commission: commissionInfo.commission,
|
|
401
|
-
blocked: commissionInfo.blocked,
|
|
402
|
-
identity,
|
|
403
|
-
isVerified: isVerified
|
|
404
|
-
};
|
|
405
|
-
}));
|
|
406
|
-
const bnAvgStake = bnTotalEraStake.divn(validatorInfoList.length).div(bnDecimals);
|
|
407
|
-
for (const validator of validatorInfoList) {
|
|
408
|
-
const commission = extraInfoMap[validator.address].commission;
|
|
409
|
-
const bnValidatorStake = totalStakeMap[validator.address].div(bnDecimals);
|
|
410
|
-
if (_constants2._STAKING_CHAIN_GROUP.aleph.includes(this.chain)) {
|
|
411
|
-
validator.expectedReturn = (0, _utils.calculateAlephZeroValidatorReturn)(poolInfo.statistic.totalApy, (0, _utils.getCommission)(commission));
|
|
412
|
-
} else if (_constants2._STAKING_CHAIN_GROUP.ternoa.includes(this.chain)) {
|
|
413
|
-
const rewardPerValidator = new _util.BN(stakingRewards.sessionExtraRewardPayout).divn(allValidators.length).div(bnDecimals);
|
|
414
|
-
const validatorStake = totalStakeMap[validator.address].div(bnDecimals).toNumber();
|
|
415
|
-
validator.expectedReturn = (0, _utils.calculateTernoaValidatorReturn)(rewardPerValidator.toNumber(), validatorStake, (0, _utils.getCommission)(commission));
|
|
416
|
-
} else {
|
|
417
|
-
validator.expectedReturn = (0, _utils.calculateValidatorStakedReturn)(poolInfo.statistic.totalApy, bnValidatorStake, bnAvgStake, (0, _utils.getCommission)(commission));
|
|
418
|
-
}
|
|
419
|
-
validator.commission = parseFloat(commission.split('%')[0]);
|
|
420
|
-
validator.blocked = extraInfoMap[validator.address].blocked;
|
|
421
|
-
validator.identity = extraInfoMap[validator.address].identity;
|
|
422
|
-
validator.isVerified = extraInfoMap[validator.address].isVerified;
|
|
423
|
-
}
|
|
424
|
-
return validatorInfoList;
|
|
416
|
+
return [totalStakeMap, allValidatorAddresses, validatorInfoList];
|
|
425
417
|
}
|
|
426
|
-
|
|
427
418
|
/* Get pool targets */
|
|
428
419
|
|
|
429
420
|
/* Join pool action */
|
|
@@ -40,7 +40,7 @@ class EarningService {
|
|
|
40
40
|
yieldPositionSubject = new _rxjs.BehaviorSubject({});
|
|
41
41
|
yieldPositionListSubject = new _rxjs.BehaviorSubject([]); // virtual list of yieldPositionSubject with filter values
|
|
42
42
|
|
|
43
|
-
useOnlineCacheOnly =
|
|
43
|
+
useOnlineCacheOnly = true;
|
|
44
44
|
constructor(state) {
|
|
45
45
|
this.state = state;
|
|
46
46
|
this.dbService = state.dbService;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.applyDecimal = applyDecimal;
|
|
6
7
|
exports.calculateReward = calculateReward;
|
|
7
8
|
exports.isActionFromValidator = isActionFromValidator;
|
|
8
9
|
exports.isNominationPool = exports.isNativeStakingPool = exports.isLiquidPool = exports.isLendingPool = void 0;
|
|
@@ -133,4 +134,8 @@ exports.isLiquidPool = isLiquidPool;
|
|
|
133
134
|
const isLendingPool = pool => {
|
|
134
135
|
return pool.type === _types.YieldPoolType.LENDING;
|
|
135
136
|
};
|
|
136
|
-
exports.isLendingPool = isLendingPool;
|
|
137
|
+
exports.isLendingPool = isLendingPool;
|
|
138
|
+
function applyDecimal(bnNumber, decimals) {
|
|
139
|
+
const bnDecimals = new _util.BN((10 ** decimals).toString());
|
|
140
|
+
return bnNumber.div(bnDecimals);
|
|
141
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.WEB_APP_URL = exports.PREDEFINED_CHAIN_DAPP_CHAIN_MAP = exports.EXTENSION_REQUEST_URL = void 0;
|
|
6
|
+
exports.WEB_APP_URL = exports.PREDEFINED_CHAIN_DAPP_CHAIN_MAP = exports.EXTENSION_REQUEST_URL = exports.DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL = void 0;
|
|
7
7
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
8
8
|
// SPDX-License-Identifier: Apache-2.0
|
|
9
9
|
|
|
@@ -21,6 +21,8 @@ const WEB_APP_URL = [
|
|
|
21
21
|
// Local
|
|
22
22
|
'subwallet-webapp.pages.dev',
|
|
23
23
|
// Pull request build
|
|
24
|
-
'web.subwallet.app' // Production
|
|
24
|
+
'web.subwallet.app' // Production,
|
|
25
25
|
];
|
|
26
|
-
exports.WEB_APP_URL = WEB_APP_URL;
|
|
26
|
+
exports.WEB_APP_URL = WEB_APP_URL;
|
|
27
|
+
const DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL = ['https://polkadot.js.org/apps/', 'https://ipfs.io/ipns/dotapps.io'];
|
|
28
|
+
exports.DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL = DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL;
|
|
@@ -29,6 +29,25 @@ class AuthRequestHandler {
|
|
|
29
29
|
this.keyringService = keyringService;
|
|
30
30
|
this.#requestService = requestService;
|
|
31
31
|
this.#chainService = chainService;
|
|
32
|
+
this.init().catch(console.error);
|
|
33
|
+
}
|
|
34
|
+
async init() {
|
|
35
|
+
const authList = await this.getAuthList();
|
|
36
|
+
let needUpdateAuthList = false;
|
|
37
|
+
Object.entries(authList).forEach(_ref => {
|
|
38
|
+
let [key, value] = _ref;
|
|
39
|
+
const existKeyAllBothConnect = _constants.DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL.find(url_ => url_.includes(key));
|
|
40
|
+
if (existKeyAllBothConnect && value.accountAuthType !== 'both') {
|
|
41
|
+
needUpdateAuthList = true;
|
|
42
|
+
authList[key] = {
|
|
43
|
+
...value,
|
|
44
|
+
accountAuthType: 'both'
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
if (needUpdateAuthList) {
|
|
49
|
+
this.setAuthorize(authList);
|
|
50
|
+
}
|
|
32
51
|
}
|
|
33
52
|
getAddressList() {
|
|
34
53
|
let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
@@ -42,12 +61,12 @@ class AuthRequestHandler {
|
|
|
42
61
|
return Object.keys(this.#authRequestsV2).length;
|
|
43
62
|
}
|
|
44
63
|
get allAuthRequestsV2() {
|
|
45
|
-
return Object.values(this.#authRequestsV2).map(
|
|
64
|
+
return Object.values(this.#authRequestsV2).map(_ref2 => {
|
|
46
65
|
let {
|
|
47
66
|
id,
|
|
48
67
|
request,
|
|
49
68
|
url
|
|
50
|
-
} =
|
|
69
|
+
} = _ref2;
|
|
51
70
|
return {
|
|
52
71
|
id,
|
|
53
72
|
request,
|
|
@@ -200,11 +219,11 @@ class AuthRequestHandler {
|
|
|
200
219
|
reject(error);
|
|
201
220
|
});
|
|
202
221
|
},
|
|
203
|
-
resolve:
|
|
222
|
+
resolve: _ref3 => {
|
|
204
223
|
let {
|
|
205
224
|
accounts,
|
|
206
225
|
result
|
|
207
|
-
} =
|
|
226
|
+
} = _ref3;
|
|
208
227
|
complete(result, () => {
|
|
209
228
|
resolve(result);
|
|
210
229
|
}, accounts);
|
|
@@ -214,7 +233,9 @@ class AuthRequestHandler {
|
|
|
214
233
|
authorizePromiseMap = {};
|
|
215
234
|
async authorizeUrlV2(url, request) {
|
|
216
235
|
let authList = await this.getAuthList();
|
|
217
|
-
|
|
236
|
+
const idStr = (0, _utils2.stripUrl)(url);
|
|
237
|
+
const isAllowedDappConnectAllType = !!_constants.DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL.find(url_ => url.includes(url_));
|
|
238
|
+
let accountAuthType = isAllowedDappConnectAllType ? 'both' : request.accountAuthType || 'substrate';
|
|
218
239
|
request.accountAuthType = accountAuthType;
|
|
219
240
|
if (!authList) {
|
|
220
241
|
authList = {};
|
|
@@ -226,9 +247,8 @@ class AuthRequestHandler {
|
|
|
226
247
|
reject,
|
|
227
248
|
resolve
|
|
228
249
|
} = promiseHandler;
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
let [key, data] = _ref3;
|
|
250
|
+
const isExistedAuthBothBefore = Object.entries(this.authorizeUrlSubject.value).find(_ref4 => {
|
|
251
|
+
let [key, data] = _ref4;
|
|
232
252
|
return key === idStr && data.accountAuthType === 'both';
|
|
233
253
|
});
|
|
234
254
|
if (isExistedAuthBothBefore) {
|
|
@@ -244,8 +264,8 @@ class AuthRequestHandler {
|
|
|
244
264
|
|
|
245
265
|
// Do not enqueue duplicate authorization requests.
|
|
246
266
|
const mergeKeys = [];
|
|
247
|
-
Object.entries(this.#authRequestsV2).forEach(
|
|
248
|
-
let [key, _request] =
|
|
267
|
+
Object.entries(this.#authRequestsV2).forEach(_ref5 => {
|
|
268
|
+
let [key, _request] = _ref5;
|
|
249
269
|
if (_request.idStr === idStr) {
|
|
250
270
|
if (_request.accountAuthType !== request.accountAuthType) {
|
|
251
271
|
request.accountAuthType = 'both';
|
|
@@ -276,8 +296,8 @@ class AuthRequestHandler {
|
|
|
276
296
|
if (inBlackList) {
|
|
277
297
|
throw new Error('The source {{url}} is not allowed to interact with this extension'.replace('{{url}}', url));
|
|
278
298
|
}
|
|
279
|
-
request.allowedAccounts = Object.entries(existedAuth.isAllowedMap).map(
|
|
280
|
-
let [address, allowed] =
|
|
299
|
+
request.allowedAccounts = Object.entries(existedAuth.isAllowedMap).map(_ref6 => {
|
|
300
|
+
let [address, allowed] = _ref6;
|
|
281
301
|
return allowed ? address : '';
|
|
282
302
|
}).filter(item => item !== '');
|
|
283
303
|
let allowedListByRequestType = [...request.allowedAccounts];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { NominationInfo, NominatorMetadata, StakingType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
3
|
import { _SubstrateInflationParams } from '@subwallet/extension-base/services/chain-service/constants';
|
|
4
|
+
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
4
5
|
import { EarningStatus, PalletStakingEraRewardPoints, YieldPoolInfo, YieldPositionInfo } from '@subwallet/extension-base/types';
|
|
5
6
|
import BigNumber from 'bignumber.js';
|
|
6
7
|
import { ApiPromise } from '@polkadot/api';
|
|
@@ -158,8 +159,11 @@ export declare function getEarningStatusByNominations(bnTotalActiveStake: BN, no
|
|
|
158
159
|
export declare function getValidatorLabel(chain: string): "dApp" | "Validator" | "Collator";
|
|
159
160
|
export declare function getAvgValidatorEraReward(supportedDays: number, eraRewardHistory: Codec[]): BigNumber;
|
|
160
161
|
export declare function getSupportedDaysByHistoryDepth(erasPerDay: number, maxSupportedEras: number, liveDay?: number): number;
|
|
161
|
-
export declare function
|
|
162
|
-
export declare function
|
|
162
|
+
export declare function getRelayValidatorPointsMap(eraRewardMap: Record<string, PalletStakingEraRewardPoints>): Record<string, BigNumber>;
|
|
163
|
+
export declare function getRelayTopValidatorByPoints(validatorPointsList: Record<string, BigNumber>): string[];
|
|
164
|
+
export declare function getRelayBlockedValidatorList(validators: any[]): string[];
|
|
165
|
+
export declare function getRelayEraRewardMap(eraRewardPointArray: Codec[], startEraForPoints: number): Record<string, PalletStakingEraRewardPoints>;
|
|
166
|
+
export declare function getRelayMaxNominations(substrateApi: _SubstrateApi): Promise<string>;
|
|
163
167
|
export declare const getMinStakeErrorMessage: (chainInfo: _ChainInfo, bnMinStake: BN) => string;
|
|
164
168
|
export declare const getMaxValidatorErrorMessage: (chainInfo: _ChainInfo, max: number) => string;
|
|
165
169
|
export declare const getExistUnstakeErrorMessage: (chain: string, type?: StakingType, isStakeMore?: boolean) => string;
|
|
@@ -354,13 +354,12 @@ export function getSupportedDaysByHistoryDepth(erasPerDay, maxSupportedEras, liv
|
|
|
354
354
|
return maxSupportDay;
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
|
-
export function
|
|
357
|
+
export function getRelayValidatorPointsMap(eraRewardMap) {
|
|
358
358
|
// mapping store validator and totalPoints
|
|
359
359
|
const validatorTotalPointsMap = {};
|
|
360
360
|
Object.values(eraRewardMap).forEach(info => {
|
|
361
361
|
const individual = info.individual;
|
|
362
|
-
Object.entries(individual).forEach(([validator,
|
|
363
|
-
const points = rawPoints.replaceAll(',', '');
|
|
362
|
+
Object.entries(individual).forEach(([validator, points]) => {
|
|
364
363
|
if (!validatorTotalPointsMap[validator]) {
|
|
365
364
|
validatorTotalPointsMap[validator] = new BigNumber(points);
|
|
366
365
|
} else {
|
|
@@ -370,7 +369,7 @@ export function getValidatorPointsMap(eraRewardMap) {
|
|
|
370
369
|
});
|
|
371
370
|
return validatorTotalPointsMap;
|
|
372
371
|
}
|
|
373
|
-
export function
|
|
372
|
+
export function getRelayTopValidatorByPoints(validatorPointsList) {
|
|
374
373
|
const sortValidatorPointsList = Object.fromEntries(Object.entries(validatorPointsList).sort((a, b) => a[1].minus(b[1]).toNumber()).reverse());
|
|
375
374
|
|
|
376
375
|
// keep 50% first validator
|
|
@@ -380,6 +379,36 @@ export function getTopValidatorByPoints(validatorPointsList) {
|
|
|
380
379
|
const top50PercentRecord = Object.fromEntries(top50PercentEntries);
|
|
381
380
|
return Object.keys(top50PercentRecord);
|
|
382
381
|
}
|
|
382
|
+
export function getRelayBlockedValidatorList(validators) {
|
|
383
|
+
const blockValidatorList = [];
|
|
384
|
+
for (const validator of validators) {
|
|
385
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
386
|
+
const validatorAddress = validator[0].toHuman()[0];
|
|
387
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
388
|
+
const validatorPrefs = validator[1].toHuman();
|
|
389
|
+
const isBlocked = validatorPrefs.blocked;
|
|
390
|
+
if (isBlocked) {
|
|
391
|
+
blockValidatorList.push(validatorAddress);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return blockValidatorList;
|
|
395
|
+
}
|
|
396
|
+
export function getRelayEraRewardMap(eraRewardPointArray, startEraForPoints) {
|
|
397
|
+
const eraRewardMap = {};
|
|
398
|
+
for (const item of eraRewardPointArray) {
|
|
399
|
+
eraRewardMap[startEraForPoints] = item.toPrimitive();
|
|
400
|
+
startEraForPoints++;
|
|
401
|
+
}
|
|
402
|
+
return eraRewardMap;
|
|
403
|
+
}
|
|
404
|
+
export async function getRelayMaxNominations(substrateApi) {
|
|
405
|
+
var _substrateApi$api$con, _substrateApi$api$con2, _substrateApi$api$cal;
|
|
406
|
+
await substrateApi.isReady;
|
|
407
|
+
const maxNominations = ((_substrateApi$api$con = substrateApi.api.consts.staking) === null || _substrateApi$api$con === void 0 ? void 0 : (_substrateApi$api$con2 = _substrateApi$api$con.maxNominations) === null || _substrateApi$api$con2 === void 0 ? void 0 : _substrateApi$api$con2.toString()) || '16';
|
|
408
|
+
const _maxNominationsByNominationQuota = await ((_substrateApi$api$cal = substrateApi.api.call.stakingApi) === null || _substrateApi$api$cal === void 0 ? void 0 : _substrateApi$api$cal.nominationsQuota(0)); // todo: review param. Currently return constant for all param.
|
|
409
|
+
const maxNominationsByNominationQuota = _maxNominationsByNominationQuota === null || _maxNominationsByNominationQuota === void 0 ? void 0 : _maxNominationsByNominationQuota.toString();
|
|
410
|
+
return maxNominationsByNominationQuota || maxNominations;
|
|
411
|
+
}
|
|
383
412
|
export const getMinStakeErrorMessage = (chainInfo, bnMinStake) => {
|
|
384
413
|
const tokenInfo = _getChainNativeTokenBasicInfo(chainInfo);
|
|
385
414
|
const number = formatNumber(bnMinStake.toString(), tokenInfo.decimals || 0, balanceFormatter);
|
|
@@ -237,7 +237,7 @@ export default class KoniTabs {
|
|
|
237
237
|
anyType
|
|
238
238
|
}) {
|
|
239
239
|
const authInfo = await this.getAuthInfo(url);
|
|
240
|
-
return transformAccountsV2(this.#koniState.keyringService.accounts, anyType, authInfo, accountAuthType);
|
|
240
|
+
return transformAccountsV2(this.#koniState.keyringService.accounts, anyType, authInfo, (authInfo === null || authInfo === void 0 ? void 0 : authInfo.accountAuthType) || accountAuthType);
|
|
241
241
|
}
|
|
242
242
|
accountsSubscribeV2(url, {
|
|
243
243
|
accountAuthType
|
|
@@ -249,8 +249,9 @@ export default class KoniTabs {
|
|
|
249
249
|
this.#accountSubs[id] = {
|
|
250
250
|
subscription: authInfoSubject.subscribe(infos => {
|
|
251
251
|
this.getAuthInfo(url, infos).then(authInfo => {
|
|
252
|
+
const accountAuthType_ = (authInfo === null || authInfo === void 0 ? void 0 : authInfo.accountAuthType) || accountAuthType;
|
|
252
253
|
const accounts = this.#koniState.keyringService.accounts;
|
|
253
|
-
return cb(transformAccountsV2(accounts, false, authInfo,
|
|
254
|
+
return cb(transformAccountsV2(accounts, false, authInfo, accountAuthType_));
|
|
254
255
|
}).catch(console.error);
|
|
255
256
|
}),
|
|
256
257
|
url
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.2.
|
|
20
|
+
"version": "1.2.5-0",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -1922,10 +1922,10 @@
|
|
|
1922
1922
|
"@sora-substrate/type-definitions": "^1.17.7",
|
|
1923
1923
|
"@substrate/connect": "^0.8.9",
|
|
1924
1924
|
"@subwallet/chain-list": "0.2.67",
|
|
1925
|
-
"@subwallet/extension-base": "^1.2.
|
|
1926
|
-
"@subwallet/extension-chains": "^1.2.
|
|
1927
|
-
"@subwallet/extension-dapp": "^1.2.
|
|
1928
|
-
"@subwallet/extension-inject": "^1.2.
|
|
1925
|
+
"@subwallet/extension-base": "^1.2.5-0",
|
|
1926
|
+
"@subwallet/extension-chains": "^1.2.5-0",
|
|
1927
|
+
"@subwallet/extension-dapp": "^1.2.5-0",
|
|
1928
|
+
"@subwallet/extension-inject": "^1.2.5-0",
|
|
1929
1929
|
"@subwallet/keyring": "^0.1.5",
|
|
1930
1930
|
"@subwallet/ui-keyring": "^0.1.5",
|
|
1931
1931
|
"@walletconnect/keyvaluestorage": "^1.1.1",
|
package/packageInfo.js
CHANGED
|
@@ -7,5 +7,5 @@ export const packageInfo = {
|
|
|
7
7
|
name: '@subwallet/extension-base',
|
|
8
8
|
path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
|
|
9
9
|
type: 'esm',
|
|
10
|
-
version: '1.2.
|
|
10
|
+
version: '1.2.5-0'
|
|
11
11
|
};
|
package/page/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MessageTypes, MessageTypesWithNoSubscriptions, MessageTypesWithNullRequest, MessageTypesWithSubscriptions, RequestTypes, ResponseTypes, SubscriptionMessageTypes, TransportResponseMessage } from '../background/types';
|
|
2
|
-
import { EvmProvider } from '@subwallet/extension-inject/types';
|
|
2
|
+
import { AuthRequestOption, EvmProvider } from '@subwallet/extension-inject/types';
|
|
3
3
|
import Injected from './Injected';
|
|
4
4
|
export interface Handler {
|
|
5
5
|
resolve: (data?: any) => void;
|
|
@@ -10,7 +10,7 @@ export declare type Handlers = Record<string, Handler>;
|
|
|
10
10
|
export declare function sendMessage<TMessageType extends MessageTypesWithNullRequest>(message: TMessageType): Promise<ResponseTypes[TMessageType]>;
|
|
11
11
|
export declare function sendMessage<TMessageType extends MessageTypesWithNoSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType]): Promise<ResponseTypes[TMessageType]>;
|
|
12
12
|
export declare function sendMessage<TMessageType extends MessageTypesWithSubscriptions>(message: TMessageType, request: RequestTypes[TMessageType], subscriber: (data: SubscriptionMessageTypes[TMessageType]) => void): Promise<ResponseTypes[TMessageType]>;
|
|
13
|
-
export declare function enable(origin: string): Promise<Injected>;
|
|
13
|
+
export declare function enable(origin: string, opt?: AuthRequestOption): Promise<Injected>;
|
|
14
14
|
export declare function handleResponse<TMessageType extends MessageTypes>(data: TransportResponseMessage<TMessageType> & {
|
|
15
15
|
subscription?: string;
|
|
16
16
|
}): void;
|
package/page/index.js
CHANGED
|
@@ -38,9 +38,11 @@ export function sendMessage(message, request, subscriber) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// the enable function, called by the dapp to allow access
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
export async function enable(origin, opt) {
|
|
42
43
|
await sendMessage('pub(authorize.tabV2)', {
|
|
43
|
-
origin
|
|
44
|
+
origin,
|
|
45
|
+
accountAuthType: (opt === null || opt === void 0 ? void 0 : opt.accountAuthType) || 'substrate'
|
|
44
46
|
});
|
|
45
47
|
return new Injected(sendMessage);
|
|
46
48
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
3
|
-
import { ExtrinsicType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
+
import { ExtrinsicType, NominationInfo, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
4
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
5
|
-
import { BaseYieldPositionInfo, OptimalYieldPath, PalletStakingStakingLedger, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
5
|
+
import { BaseYieldPositionInfo, OptimalYieldPath, PalletStakingNominations, PalletStakingStakingLedger, StakeCancelWithdrawalParams, SubmitJoinNativeStaking, SubmitYieldJoinData, TransactionData, ValidatorInfo, YieldPoolInfo, YieldPositionInfo, YieldTokenBaseInfo } from '@subwallet/extension-base/types';
|
|
6
6
|
import { DeriveSessionProgress } from '@polkadot/api-derive/types';
|
|
7
7
|
import { BN } from '@polkadot/util';
|
|
8
8
|
import BaseNativeStakingPoolHandler from './base';
|
|
9
9
|
export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPoolHandler {
|
|
10
10
|
subscribePoolInfo(callback: (data: YieldPoolInfo) => void): Promise<VoidFunction>;
|
|
11
11
|
parseNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi, ledger: PalletStakingStakingLedger, currentEra: string, minStake: BN, _deriveSessionProgress: DeriveSessionProgress): Promise<Omit<YieldPositionInfo, keyof BaseYieldPositionInfo>>;
|
|
12
|
+
handleNominationsList(substrateApi: _SubstrateApi, chain: string, nominations: PalletStakingNominations, currentEra: string, address: string, maxNominatorRewardedPerValidator: number | undefined): Promise<NominationInfo[]>;
|
|
12
13
|
subscribePoolPosition(useAddresses: string[], resultCallback: (rs: YieldPositionInfo) => void): Promise<VoidFunction>;
|
|
13
14
|
getPoolTargets(): Promise<ValidatorInfo[]>;
|
|
15
|
+
private getValidatorExpectedReturn;
|
|
16
|
+
private parseEraStakerData;
|
|
14
17
|
validateYieldJoin(data: SubmitYieldJoinData, path: OptimalYieldPath): Promise<TransactionError[]>;
|
|
15
18
|
createJoinExtrinsic(data: SubmitJoinNativeStaking, positionInfo?: YieldPositionInfo, bondDest?: string): Promise<[TransactionData, YieldTokenBaseInfo]>;
|
|
16
19
|
validateYieldLeave(amount: string, address: string, fastLeave: boolean, selectedTarget?: string): Promise<TransactionError[]>;
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
5
|
import { BasicTxErrorType, ExtrinsicType, StakingTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
-
import { calculateAlephZeroValidatorReturn, calculateChainStakedReturnV2, calculateInflation, calculateTernoaValidatorReturn, calculateValidatorStakedReturn, getAvgValidatorEraReward, getCommission, getMaxValidatorErrorMessage, getMinStakeErrorMessage,
|
|
6
|
+
import { calculateAlephZeroValidatorReturn, calculateChainStakedReturnV2, calculateInflation, calculateTernoaValidatorReturn, calculateValidatorStakedReturn, getAvgValidatorEraReward, getCommission, getMaxValidatorErrorMessage, getMinStakeErrorMessage, getRelayBlockedValidatorList, getRelayEraRewardMap, getRelayMaxNominations, getRelayTopValidatorByPoints, getRelayValidatorPointsMap, getSupportedDaysByHistoryDepth } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
7
7
|
import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
8
|
import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
9
|
import { _STAKING_CHAIN_GROUP, _UPDATED_RUNTIME_STAKING_GROUP, MaxEraRewardPointsEras } from '@subwallet/extension-base/services/earning-service/constants';
|
|
10
|
-
import { parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
|
|
10
|
+
import { applyDecimal, parseIdentity } from '@subwallet/extension-base/services/earning-service/utils';
|
|
11
11
|
import { EarningStatus, UnstakingStatus } from '@subwallet/extension-base/types';
|
|
12
12
|
import { balanceFormatter, formatNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
13
13
|
import BigN from 'bignumber.js';
|
|
@@ -44,17 +44,14 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
44
44
|
await defaultCallback();
|
|
45
45
|
await substrateApi.isReady;
|
|
46
46
|
const unsub = await ((_substrateApi$api$que = substrateApi.api.query.staking) === null || _substrateApi$api$que === void 0 ? void 0 : _substrateApi$api$que.currentEra(async _currentEra => {
|
|
47
|
-
var _substrateApi$api$con, _substrateApi$api$
|
|
47
|
+
var _substrateApi$api$con, _substrateApi$api$que2, _substrateApi$api$que3, _substrateApi$api$que4, _substrateApi$api$que5, _substrateApi$api$que6;
|
|
48
48
|
if (cancel) {
|
|
49
49
|
unsub();
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
|
-
let maxNominations = ((_substrateApi$api$con = substrateApi.api.consts.staking) === null || _substrateApi$api$con === void 0 ? void 0 : (_substrateApi$api$con2 = _substrateApi$api$con.maxNominations) === null || _substrateApi$api$con2 === void 0 ? void 0 : _substrateApi$api$con2.toString()) || '16';
|
|
53
52
|
const unlimitedNominatorRewarded = substrateApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
54
|
-
const maxNominatorRewarded = (_substrateApi$api$
|
|
55
|
-
const
|
|
56
|
-
const maxNominationsByNominationQuota = _maxNominationsByNominationQuota === null || _maxNominationsByNominationQuota === void 0 ? void 0 : _maxNominationsByNominationQuota.toString();
|
|
57
|
-
maxNominations = maxNominationsByNominationQuota !== null && maxNominationsByNominationQuota !== void 0 ? maxNominationsByNominationQuota : maxNominations;
|
|
53
|
+
const maxNominatorRewarded = (_substrateApi$api$con = substrateApi.api.consts.staking.maxNominatorRewardedPerValidator) === null || _substrateApi$api$con === void 0 ? void 0 : _substrateApi$api$con.toString();
|
|
54
|
+
const maxNominations = await getRelayMaxNominations(substrateApi);
|
|
58
55
|
const currentEra = _currentEra.toString();
|
|
59
56
|
const maxUnlockingChunks = substrateApi.api.consts.staking.maxUnlockingChunks.toString();
|
|
60
57
|
const unlockingEras = substrateApi.api.consts.staking.bondingDuration.toString();
|
|
@@ -133,54 +130,15 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
133
130
|
const [_nominations, _bonded, _activeEra] = await Promise.all([(_substrateApi$api$que7 = substrateApi.api.query) === null || _substrateApi$api$que7 === void 0 ? void 0 : (_substrateApi$api$que8 = _substrateApi$api$que7.staking) === null || _substrateApi$api$que8 === void 0 ? void 0 : _substrateApi$api$que8.nominators(address), (_substrateApi$api$que9 = substrateApi.api.query) === null || _substrateApi$api$que9 === void 0 ? void 0 : (_substrateApi$api$que10 = _substrateApi$api$que9.staking) === null || _substrateApi$api$que10 === void 0 ? void 0 : _substrateApi$api$que10.bonded(address), (_substrateApi$api$que11 = substrateApi.api.query) === null || _substrateApi$api$que11 === void 0 ? void 0 : (_substrateApi$api$que12 = _substrateApi$api$que11.staking) === null || _substrateApi$api$que12 === void 0 ? void 0 : _substrateApi$api$que12.activeEra()]);
|
|
134
131
|
const unlimitedNominatorRewarded = substrateApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
135
132
|
const _maxNominatorRewardedPerValidator = (substrateApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
|
|
136
|
-
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
|
|
133
|
+
const maxNominatorRewardedPerValidator = unlimitedNominatorRewarded ? undefined : parseInt(_maxNominatorRewardedPerValidator);
|
|
137
134
|
const nominations = _nominations.toPrimitive();
|
|
138
135
|
const bonded = _bonded.toHuman();
|
|
136
|
+
const addressFormatted = reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo));
|
|
139
137
|
const activeStake = ledger.active.toString();
|
|
140
138
|
const totalStake = ledger.total.toString();
|
|
141
139
|
const unstakingBalance = (ledger.total - ledger.active).toString();
|
|
142
|
-
const nominationList = [];
|
|
143
140
|
const unstakingList = [];
|
|
144
|
-
|
|
145
|
-
const validatorList = nominations.targets;
|
|
146
|
-
await Promise.all(validatorList.map(async validatorAddress => {
|
|
147
|
-
let nominationStatus = EarningStatus.NOT_EARNING;
|
|
148
|
-
let eraStakerOtherList = [];
|
|
149
|
-
let identity;
|
|
150
|
-
if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
151
|
-
// todo: review all relaychains later
|
|
152
|
-
const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
|
|
153
|
-
identity = _identity;
|
|
154
|
-
eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
|
|
155
|
-
} else {
|
|
156
|
-
const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
157
|
-
identity = _identity;
|
|
158
|
-
const eraStaker = _eraStaker.toPrimitive();
|
|
159
|
-
eraStakerOtherList = eraStaker.others;
|
|
160
|
-
}
|
|
161
|
-
const sortedNominators = eraStakerOtherList.sort((a, b) => {
|
|
162
|
-
return new BigN(b.value).minus(a.value).toNumber();
|
|
163
|
-
});
|
|
164
|
-
const topNominators = sortedNominators.map(nominator => {
|
|
165
|
-
return nominator.who;
|
|
166
|
-
});
|
|
167
|
-
if (!topNominators.includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
168
|
-
// if nominator has target but not in nominator list
|
|
169
|
-
nominationStatus = EarningStatus.WAITING;
|
|
170
|
-
} else if (topNominators.slice(0, unlimitedNominatorRewarded ? undefined : maxNominatorRewardedPerValidator).includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
171
|
-
// if address in top nominators
|
|
172
|
-
nominationStatus = EarningStatus.EARNING_REWARD;
|
|
173
|
-
}
|
|
174
|
-
nominationList.push({
|
|
175
|
-
chain,
|
|
176
|
-
validatorAddress,
|
|
177
|
-
status: nominationStatus,
|
|
178
|
-
validatorIdentity: identity,
|
|
179
|
-
activeStake: '0' // relaychain allocates stake accordingly
|
|
180
|
-
});
|
|
181
|
-
}));
|
|
182
|
-
}
|
|
183
|
-
|
|
141
|
+
const nominationList = (await this.handleNominationsList(substrateApi, chain, nominations, currentEra, addressFormatted, maxNominatorRewardedPerValidator)) || [];
|
|
184
142
|
let stakingStatus = EarningStatus.NOT_EARNING;
|
|
185
143
|
const bnActiveStake = new BN(activeStake);
|
|
186
144
|
let waitingNominationCount = 0;
|
|
@@ -224,6 +182,51 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
224
182
|
unstakings: unstakingList
|
|
225
183
|
};
|
|
226
184
|
}
|
|
185
|
+
async handleNominationsList(substrateApi, chain, nominations, currentEra, address, maxNominatorRewardedPerValidator) {
|
|
186
|
+
const nominationList = [];
|
|
187
|
+
if (!nominations) {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
const validatorList = nominations.targets;
|
|
191
|
+
await Promise.all(validatorList.map(async validatorAddress => {
|
|
192
|
+
let nominationStatus = EarningStatus.NOT_EARNING;
|
|
193
|
+
let eraStakerOtherList = [];
|
|
194
|
+
let identity;
|
|
195
|
+
if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
196
|
+
// todo: review all relaychains later
|
|
197
|
+
const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakersPaged.entries(currentEra, validatorAddress)]);
|
|
198
|
+
identity = _identity;
|
|
199
|
+
eraStakerOtherList = _eraStaker.flatMap(paged => paged[1].toPrimitive().others);
|
|
200
|
+
} else {
|
|
201
|
+
const [[_identity], _eraStaker] = await Promise.all([parseIdentity(substrateApi, validatorAddress), substrateApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
202
|
+
identity = _identity;
|
|
203
|
+
const eraStaker = _eraStaker.toPrimitive();
|
|
204
|
+
eraStakerOtherList = eraStaker.others;
|
|
205
|
+
}
|
|
206
|
+
const sortedNominators = eraStakerOtherList.sort((a, b) => {
|
|
207
|
+
return new BigN(b.value).minus(a.value).toNumber();
|
|
208
|
+
});
|
|
209
|
+
const topNominators = sortedNominators.map(nominator => {
|
|
210
|
+
return nominator.who;
|
|
211
|
+
});
|
|
212
|
+
if (!topNominators.includes(address)) {
|
|
213
|
+
// if nominator has target but not in nominator list
|
|
214
|
+
nominationStatus = EarningStatus.WAITING;
|
|
215
|
+
} else if (topNominators.slice(0, maxNominatorRewardedPerValidator).includes(address)) {
|
|
216
|
+
// if address in top nominators
|
|
217
|
+
nominationStatus = EarningStatus.EARNING_REWARD;
|
|
218
|
+
}
|
|
219
|
+
nominationList.push({
|
|
220
|
+
chain,
|
|
221
|
+
validatorAddress,
|
|
222
|
+
status: nominationStatus,
|
|
223
|
+
validatorIdentity: identity,
|
|
224
|
+
activeStake: '0' // relaychain allocates stake accordingly
|
|
225
|
+
});
|
|
226
|
+
}));
|
|
227
|
+
|
|
228
|
+
return nominationList;
|
|
229
|
+
}
|
|
227
230
|
async subscribePoolPosition(useAddresses, resultCallback) {
|
|
228
231
|
var _substrateApi$api$que13;
|
|
229
232
|
let cancel = false;
|
|
@@ -285,7 +288,6 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
285
288
|
|
|
286
289
|
async getPoolTargets() {
|
|
287
290
|
var _chainApi$api$query$s;
|
|
288
|
-
const decimals = this.nativeToken.decimals || 0;
|
|
289
291
|
const chainApi = await this.substrateApi.isReady;
|
|
290
292
|
const poolInfo = await this.getPoolInfo();
|
|
291
293
|
if (!poolInfo || !poolInfo.statistic) {
|
|
@@ -295,11 +297,9 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
295
297
|
const currentEra = _era.toString();
|
|
296
298
|
const activeEraInfo = _activeEraInfo.toPrimitive();
|
|
297
299
|
const activeEra = activeEraInfo.index;
|
|
298
|
-
const allValidators = [];
|
|
299
|
-
const validatorInfoList = [];
|
|
300
300
|
const maxEraRewardPointsEras = MaxEraRewardPointsEras;
|
|
301
301
|
const endEraForPoints = parseInt(activeEra) - 1;
|
|
302
|
-
|
|
302
|
+
const startEraForPoints = Math.max(endEraForPoints - maxEraRewardPointsEras + 1, 0);
|
|
303
303
|
let _eraStakersPromise;
|
|
304
304
|
if (_UPDATED_RUNTIME_STAKING_GROUP.includes(this.chain)) {
|
|
305
305
|
// todo: review all relaychains later
|
|
@@ -308,43 +308,65 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
308
308
|
_eraStakersPromise = chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra));
|
|
309
309
|
}
|
|
310
310
|
const [_totalEraStake, _eraStakers, _minBond, _stakingRewards, _validators, ..._eraRewardPoints] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), _eraStakersPromise, chainApi.api.query.staking.minNominatorBond(), ((_chainApi$api$query$s = chainApi.api.query.stakingRewards) === null || _chainApi$api$query$s === void 0 ? void 0 : _chainApi$api$query$s.data) && chainApi.api.query.stakingRewards.data(), chainApi.api.query.staking.validators.entries(), chainApi.api.query.staking.erasRewardPoints.multi([...Array(maxEraRewardPointsEras).keys()].map(i => i + startEraForPoints))]);
|
|
311
|
-
const eraRewardMap =
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
startEraForPoints++;
|
|
315
|
-
}
|
|
316
|
-
const validatorPointsMap = getValidatorPointsMap(eraRewardMap);
|
|
317
|
-
const topValidatorList = getTopValidatorByPoints(validatorPointsMap);
|
|
318
|
-
|
|
319
|
-
// filter blocked validators
|
|
311
|
+
const eraRewardMap = getRelayEraRewardMap(_eraRewardPoints[0], startEraForPoints);
|
|
312
|
+
const validatorPointsMap = getRelayValidatorPointsMap(eraRewardMap);
|
|
313
|
+
const topValidatorList = getRelayTopValidatorByPoints(validatorPointsMap);
|
|
320
314
|
const validators = _validators;
|
|
321
|
-
const
|
|
322
|
-
for (const validator of validators) {
|
|
323
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
324
|
-
const validatorAddress = validator[0].toHuman()[0];
|
|
325
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
326
|
-
const validatorPrefs = validator[1].toHuman();
|
|
327
|
-
const isBlocked = validatorPrefs.blocked;
|
|
328
|
-
if (isBlocked) {
|
|
329
|
-
blockValidatorList.push(validatorAddress);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
const stakingRewards = _stakingRewards === null || _stakingRewards === void 0 ? void 0 : _stakingRewards.toPrimitive();
|
|
315
|
+
const blockedValidatorList = getRelayBlockedValidatorList(validators);
|
|
333
316
|
const unlimitedNominatorRewarded = chainApi.api.consts.staking.maxExposurePageSize !== undefined;
|
|
334
317
|
const maxNominatorRewarded = (chainApi.api.consts.staking.maxNominatorRewardedPerValidator || 0).toString();
|
|
335
318
|
const bnTotalEraStake = new BN(_totalEraStake.toString());
|
|
336
|
-
const
|
|
337
|
-
const
|
|
319
|
+
const minBond = _minBond.toPrimitive();
|
|
320
|
+
const [totalStakeMap, allValidatorAddresses, validatorInfoList] = this.parseEraStakerData(_eraStakers, blockedValidatorList, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded);
|
|
321
|
+
const extraInfoMap = {};
|
|
322
|
+
await Promise.all(allValidatorAddresses.map(async address => {
|
|
323
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
324
|
+
const [_commissionInfo, [identity, isVerified]] = await Promise.all([chainApi.api.query.staking.validators(address), parseIdentity(chainApi, address)]);
|
|
325
|
+
const commissionInfo = _commissionInfo.toHuman();
|
|
326
|
+
extraInfoMap[address] = {
|
|
327
|
+
commission: commissionInfo.commission,
|
|
328
|
+
blocked: commissionInfo.blocked,
|
|
329
|
+
identity,
|
|
330
|
+
isVerified: isVerified
|
|
331
|
+
};
|
|
332
|
+
}));
|
|
333
|
+
const decimals = this.nativeToken.decimals || 0;
|
|
334
|
+
const bnAvgStake = applyDecimal(bnTotalEraStake.divn(validatorInfoList.length), decimals);
|
|
335
|
+
for (const validator of validatorInfoList) {
|
|
336
|
+
const commissionString = extraInfoMap[validator.address].commission;
|
|
337
|
+
const commission = getCommission(commissionString);
|
|
338
|
+
validator.expectedReturn = this.getValidatorExpectedReturn(this.chain, validator, poolInfo.statistic.totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake);
|
|
339
|
+
validator.commission = commission;
|
|
340
|
+
validator.blocked = extraInfoMap[validator.address].blocked;
|
|
341
|
+
validator.identity = extraInfoMap[validator.address].identity;
|
|
342
|
+
validator.isVerified = extraInfoMap[validator.address].isVerified;
|
|
343
|
+
}
|
|
344
|
+
return validatorInfoList;
|
|
345
|
+
}
|
|
346
|
+
getValidatorExpectedReturn(chain, validator, totalApy, commission, _stakingRewards, allValidatorAddresses, decimals, totalStakeMap, bnAvgStake) {
|
|
347
|
+
if (_STAKING_CHAIN_GROUP.aleph.includes(chain)) {
|
|
348
|
+
return calculateAlephZeroValidatorReturn(totalApy, commission);
|
|
349
|
+
} else if (_STAKING_CHAIN_GROUP.ternoa.includes(chain)) {
|
|
350
|
+
const stakingRewards = _stakingRewards === null || _stakingRewards === void 0 ? void 0 : _stakingRewards.toPrimitive();
|
|
351
|
+
const rewardPerValidator = applyDecimal(new BN(stakingRewards.sessionExtraRewardPayout).divn(allValidatorAddresses.length), decimals);
|
|
352
|
+
const validatorStake = applyDecimal(totalStakeMap[validator.address], decimals).toNumber();
|
|
353
|
+
return calculateTernoaValidatorReturn(rewardPerValidator.toNumber(), validatorStake, commission);
|
|
354
|
+
} else {
|
|
355
|
+
const bnValidatorStake = applyDecimal(totalStakeMap[validator.address], decimals);
|
|
356
|
+
return calculateValidatorStakedReturn(totalApy, bnValidatorStake, bnAvgStake, commission);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
parseEraStakerData(_eraStakers, blockedValidatorList, topValidatorList, validatorPointsMap, minBond, maxNominatorRewarded, unlimitedNominatorRewarded) {
|
|
338
360
|
const totalStakeMap = {};
|
|
339
|
-
const
|
|
340
|
-
const
|
|
341
|
-
for (const item of
|
|
361
|
+
const allValidatorAddresses = [];
|
|
362
|
+
const validatorInfoList = [];
|
|
363
|
+
for (const item of _eraStakers) {
|
|
342
364
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
343
365
|
const rawValidatorInfo = item[0].toHuman();
|
|
344
366
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
345
367
|
const rawValidatorStat = item[1].toPrimitive();
|
|
346
368
|
const validatorAddress = rawValidatorInfo[1];
|
|
347
|
-
if (!
|
|
369
|
+
if (!blockedValidatorList.includes(validatorAddress)) {
|
|
348
370
|
var _validatorPointsMap$v;
|
|
349
371
|
let isTopQuartile = false;
|
|
350
372
|
if (topValidatorList.includes(validatorAddress)) {
|
|
@@ -365,7 +387,7 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
365
387
|
nominatorCount = others.length;
|
|
366
388
|
}
|
|
367
389
|
}
|
|
368
|
-
|
|
390
|
+
allValidatorAddresses.push(validatorAddress);
|
|
369
391
|
validatorInfoList.push({
|
|
370
392
|
address: validatorAddress,
|
|
371
393
|
totalStake: bnTotalStake.toString(),
|
|
@@ -377,46 +399,15 @@ export default class RelayNativeStakingPoolHandler extends BaseNativeStakingPool
|
|
|
377
399
|
expectedReturn: 0,
|
|
378
400
|
blocked: false,
|
|
379
401
|
isVerified: false,
|
|
380
|
-
minBond,
|
|
402
|
+
minBond: minBond.toString(),
|
|
381
403
|
isCrowded: unlimitedNominatorRewarded ? false : nominatorCount > parseInt(maxNominatorRewarded),
|
|
382
404
|
eraRewardPoint: ((_validatorPointsMap$v = validatorPointsMap[validatorAddress]) !== null && _validatorPointsMap$v !== void 0 ? _validatorPointsMap$v : BN_ZERO).toString(),
|
|
383
405
|
topQuartile: isTopQuartile
|
|
384
406
|
});
|
|
385
407
|
}
|
|
386
408
|
}
|
|
387
|
-
|
|
388
|
-
await Promise.all(allValidators.map(async address => {
|
|
389
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
390
|
-
const [_commissionInfo, [identity, isVerified]] = await Promise.all([chainApi.api.query.staking.validators(address), parseIdentity(chainApi, address)]);
|
|
391
|
-
const commissionInfo = _commissionInfo.toHuman();
|
|
392
|
-
extraInfoMap[address] = {
|
|
393
|
-
commission: commissionInfo.commission,
|
|
394
|
-
blocked: commissionInfo.blocked,
|
|
395
|
-
identity,
|
|
396
|
-
isVerified: isVerified
|
|
397
|
-
};
|
|
398
|
-
}));
|
|
399
|
-
const bnAvgStake = bnTotalEraStake.divn(validatorInfoList.length).div(bnDecimals);
|
|
400
|
-
for (const validator of validatorInfoList) {
|
|
401
|
-
const commission = extraInfoMap[validator.address].commission;
|
|
402
|
-
const bnValidatorStake = totalStakeMap[validator.address].div(bnDecimals);
|
|
403
|
-
if (_STAKING_CHAIN_GROUP.aleph.includes(this.chain)) {
|
|
404
|
-
validator.expectedReturn = calculateAlephZeroValidatorReturn(poolInfo.statistic.totalApy, getCommission(commission));
|
|
405
|
-
} else if (_STAKING_CHAIN_GROUP.ternoa.includes(this.chain)) {
|
|
406
|
-
const rewardPerValidator = new BN(stakingRewards.sessionExtraRewardPayout).divn(allValidators.length).div(bnDecimals);
|
|
407
|
-
const validatorStake = totalStakeMap[validator.address].div(bnDecimals).toNumber();
|
|
408
|
-
validator.expectedReturn = calculateTernoaValidatorReturn(rewardPerValidator.toNumber(), validatorStake, getCommission(commission));
|
|
409
|
-
} else {
|
|
410
|
-
validator.expectedReturn = calculateValidatorStakedReturn(poolInfo.statistic.totalApy, bnValidatorStake, bnAvgStake, getCommission(commission));
|
|
411
|
-
}
|
|
412
|
-
validator.commission = parseFloat(commission.split('%')[0]);
|
|
413
|
-
validator.blocked = extraInfoMap[validator.address].blocked;
|
|
414
|
-
validator.identity = extraInfoMap[validator.address].identity;
|
|
415
|
-
validator.isVerified = extraInfoMap[validator.address].isVerified;
|
|
416
|
-
}
|
|
417
|
-
return validatorInfoList;
|
|
409
|
+
return [totalStakeMap, allValidatorAddresses, validatorInfoList];
|
|
418
410
|
}
|
|
419
|
-
|
|
420
411
|
/* Get pool targets */
|
|
421
412
|
|
|
422
413
|
/* Join pool action */
|
|
@@ -33,7 +33,7 @@ export default class EarningService {
|
|
|
33
33
|
yieldPositionSubject = new BehaviorSubject({});
|
|
34
34
|
yieldPositionListSubject = new BehaviorSubject([]); // virtual list of yieldPositionSubject with filter values
|
|
35
35
|
|
|
36
|
-
useOnlineCacheOnly =
|
|
36
|
+
useOnlineCacheOnly = true;
|
|
37
37
|
constructor(state) {
|
|
38
38
|
this.state = state;
|
|
39
39
|
this.dbService = state.dbService;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
2
2
|
import { LendingYieldPoolInfo, LiquidYieldPoolInfo, NativeYieldPoolInfo, NominationYieldPoolInfo, YieldAssetExpectedEarning, YieldCompoundingPeriod, YieldPoolInfo, YieldPoolType } from '@subwallet/extension-base/types';
|
|
3
|
+
import { BN } from '@polkadot/util';
|
|
3
4
|
export declare function calculateReward(apr: number, amount?: number, compoundingPeriod?: YieldCompoundingPeriod, isApy?: boolean): YieldAssetExpectedEarning;
|
|
4
5
|
/**
|
|
5
6
|
* @returns
|
|
@@ -16,3 +17,4 @@ export declare const isNominationPool: (pool: YieldPoolInfo) => pool is Nominati
|
|
|
16
17
|
export declare const isNativeStakingPool: (pool: YieldPoolInfo) => pool is NativeYieldPoolInfo;
|
|
17
18
|
export declare const isLiquidPool: (pool: YieldPoolInfo) => pool is LiquidYieldPoolInfo;
|
|
18
19
|
export declare const isLendingPool: (pool: YieldPoolInfo) => pool is LendingYieldPoolInfo;
|
|
20
|
+
export declare function applyDecimal(bnNumber: BN, decimals: number): BN;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
|
|
5
5
|
import { YieldCompoundingPeriod, YieldPoolType } from '@subwallet/extension-base/types';
|
|
6
|
-
import { hexToString, isHex } from '@polkadot/util';
|
|
6
|
+
import { BN, hexToString, isHex } from '@polkadot/util';
|
|
7
7
|
export function calculateReward(apr, amount = 0, compoundingPeriod = YieldCompoundingPeriod.YEARLY, isApy = false) {
|
|
8
8
|
if (!apr) {
|
|
9
9
|
return {};
|
|
@@ -117,4 +117,8 @@ export const isLiquidPool = pool => {
|
|
|
117
117
|
};
|
|
118
118
|
export const isLendingPool = pool => {
|
|
119
119
|
return pool.type === YieldPoolType.LENDING;
|
|
120
|
-
};
|
|
120
|
+
};
|
|
121
|
+
export function applyDecimal(bnNumber, decimals) {
|
|
122
|
+
const bnDecimals = new BN((10 ** decimals).toString());
|
|
123
|
+
return bnNumber.div(bnDecimals);
|
|
124
|
+
}
|
|
@@ -13,5 +13,7 @@ export const WEB_APP_URL = [
|
|
|
13
13
|
// Local
|
|
14
14
|
'subwallet-webapp.pages.dev',
|
|
15
15
|
// Pull request build
|
|
16
|
-
'web.subwallet.app' // Production
|
|
17
|
-
];
|
|
16
|
+
'web.subwallet.app' // Production,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export const DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL = ['https://polkadot.js.org/apps/', 'https://ipfs.io/ipns/dotapps.io'];
|
|
@@ -15,6 +15,7 @@ export default class AuthRequestHandler {
|
|
|
15
15
|
private readonly evmChainSubject;
|
|
16
16
|
readonly authSubjectV2: BehaviorSubject<AuthorizeRequest[]>;
|
|
17
17
|
constructor(requestService: RequestService, chainService: ChainService, keyringService: KeyringService);
|
|
18
|
+
private init;
|
|
18
19
|
private getAddressList;
|
|
19
20
|
get numAuthRequestsV2(): number;
|
|
20
21
|
private get allAuthRequestsV2();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
5
|
-
import { PREDEFINED_CHAIN_DAPP_CHAIN_MAP, WEB_APP_URL } from '@subwallet/extension-base/services/request-service/constants';
|
|
5
|
+
import { DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL, PREDEFINED_CHAIN_DAPP_CHAIN_MAP, WEB_APP_URL } from '@subwallet/extension-base/services/request-service/constants';
|
|
6
6
|
import AuthorizeStore from '@subwallet/extension-base/stores/Authorize';
|
|
7
7
|
import { createPromiseHandler, getDomainFromUrl, stripUrl } from '@subwallet/extension-base/utils';
|
|
8
8
|
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
@@ -22,6 +22,24 @@ export default class AuthRequestHandler {
|
|
|
22
22
|
this.keyringService = keyringService;
|
|
23
23
|
this.#requestService = requestService;
|
|
24
24
|
this.#chainService = chainService;
|
|
25
|
+
this.init().catch(console.error);
|
|
26
|
+
}
|
|
27
|
+
async init() {
|
|
28
|
+
const authList = await this.getAuthList();
|
|
29
|
+
let needUpdateAuthList = false;
|
|
30
|
+
Object.entries(authList).forEach(([key, value]) => {
|
|
31
|
+
const existKeyAllBothConnect = DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL.find(url_ => url_.includes(key));
|
|
32
|
+
if (existKeyAllBothConnect && value.accountAuthType !== 'both') {
|
|
33
|
+
needUpdateAuthList = true;
|
|
34
|
+
authList[key] = {
|
|
35
|
+
...value,
|
|
36
|
+
accountAuthType: 'both'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
if (needUpdateAuthList) {
|
|
41
|
+
this.setAuthorize(authList);
|
|
42
|
+
}
|
|
25
43
|
}
|
|
26
44
|
getAddressList(value = false) {
|
|
27
45
|
const addressList = Object.keys(this.keyringService.accounts);
|
|
@@ -202,7 +220,9 @@ export default class AuthRequestHandler {
|
|
|
202
220
|
authorizePromiseMap = {};
|
|
203
221
|
async authorizeUrlV2(url, request) {
|
|
204
222
|
let authList = await this.getAuthList();
|
|
205
|
-
|
|
223
|
+
const idStr = stripUrl(url);
|
|
224
|
+
const isAllowedDappConnectAllType = !!DAPP_CONNECT_ALL_TYPE_ACCOUNT_URL.find(url_ => url.includes(url_));
|
|
225
|
+
let accountAuthType = isAllowedDappConnectAllType ? 'both' : request.accountAuthType || 'substrate';
|
|
206
226
|
request.accountAuthType = accountAuthType;
|
|
207
227
|
if (!authList) {
|
|
208
228
|
authList = {};
|
|
@@ -214,7 +234,6 @@ export default class AuthRequestHandler {
|
|
|
214
234
|
reject,
|
|
215
235
|
resolve
|
|
216
236
|
} = promiseHandler;
|
|
217
|
-
const idStr = stripUrl(url);
|
|
218
237
|
const isExistedAuthBothBefore = Object.entries(this.authorizeUrlSubject.value).find(([key, data]) => key === idStr && data.accountAuthType === 'both');
|
|
219
238
|
if (isExistedAuthBothBefore) {
|
|
220
239
|
return true;
|