@subwallet/extension-base 1.2.3-1 → 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/background/KoniTypes.d.ts +0 -153
- package/background/KoniTypes.js +0 -21
- package/cjs/background/KoniTypes.js +1 -22
- package/cjs/core/logic-validation/earning.js +2 -2
- package/cjs/core/logic-validation/transfer.js +0 -7
- package/cjs/core/substrate/nominationpools-pallet.js +11 -1
- package/cjs/core/substrate/system-pallet.js +2 -3
- package/cjs/core/substrate/xcm-parser.js +190 -0
- package/cjs/koni/api/dotsama/transfer.js +10 -119
- package/cjs/koni/api/staking/bonding/utils.js +38 -6
- package/cjs/koni/api/xcm/polkadotXcm.js +12 -20
- package/cjs/koni/api/xcm/utils.js +8 -126
- package/cjs/koni/api/xcm/xTokens.js +10 -8
- package/cjs/koni/api/xcm/xcmPallet.js +6 -6
- package/cjs/koni/background/handlers/Extension.js +90 -113
- 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/balance-service/helpers/subscribe/substrate/index.js +6 -3
- package/cjs/services/chain-service/constants.js +2 -2
- package/cjs/services/chain-service/utils/index.js +7 -2
- package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +104 -113
- package/cjs/services/earning-service/handlers/special.js +3 -3
- package/cjs/services/earning-service/service.js +1 -1
- package/cjs/services/earning-service/utils/index.js +6 -1
- package/cjs/services/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +2 -1
- package/cjs/services/migration-service/scripts/databases/MigrateAssetSetting.js +2 -1
- package/cjs/services/migration-service/scripts/index.js +2 -2
- package/cjs/services/request-service/constants.js +5 -3
- package/cjs/services/request-service/handler/AuthRequestHandler.js +32 -12
- package/cjs/services/swap-service/handler/base-handler.js +5 -3
- package/cjs/services/swap-service/handler/hydradx-handler.js +1 -1
- package/core/logic-validation/earning.d.ts +1 -1
- package/core/logic-validation/earning.js +2 -2
- package/core/logic-validation/transfer.js +0 -7
- package/core/substrate/nominationpools-pallet.d.ts +4 -1
- package/core/substrate/nominationpools-pallet.js +8 -1
- package/core/substrate/system-pallet.js +2 -3
- package/core/substrate/xcm-parser.d.ts +49 -0
- package/core/substrate/xcm-parser.js +181 -0
- package/koni/api/dotsama/transfer.d.ts +0 -3
- package/koni/api/dotsama/transfer.js +12 -119
- package/koni/api/staking/bonding/utils.d.ts +6 -2
- package/koni/api/staking/bonding/utils.js +33 -4
- package/koni/api/xcm/polkadotXcm.js +14 -22
- package/koni/api/xcm/utils.d.ts +3 -48
- package/koni/api/xcm/utils.js +5 -114
- package/koni/api/xcm/xTokens.js +12 -10
- package/koni/api/xcm/xcmPallet.js +7 -7
- package/koni/background/handlers/Extension.d.ts +1 -3
- package/koni/background/handlers/Extension.js +8 -28
- package/koni/background/handlers/Tabs.js +3 -2
- package/package.json +11 -6
- package/packageInfo.js +1 -1
- package/page/index.d.ts +2 -2
- package/page/index.js +4 -2
- package/services/balance-service/helpers/subscribe/substrate/index.js +8 -5
- package/services/chain-service/constants.js +2 -2
- package/services/chain-service/utils/index.d.ts +3 -2
- package/services/chain-service/utils/index.js +5 -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/handlers/special.js +3 -3
- 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/migration-service/scripts/MigrateTransactionHistoryBySymbol.js +2 -1
- package/services/migration-service/scripts/databases/MigrateAssetSetting.js +2 -1
- package/services/migration-service/scripts/index.js +2 -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
- package/services/swap-service/handler/base-handler.js +5 -3
- package/services/swap-service/handler/hydradx-handler.js +1 -1
|
@@ -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 */
|
|
@@ -277,11 +277,11 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
277
277
|
const xcmFee = new BN(path.totalFee[1].amount || '0');
|
|
278
278
|
const xcmAmount = missingAmount.add(xcmFee);
|
|
279
279
|
const bnAltInputTokenBalance = new BN(altInputTokenBalance.value || '0');
|
|
280
|
-
if (!bnAltInputTokenBalance.sub(xcmAmount).gt(BN_ZERO)) {
|
|
280
|
+
if (!bnAltInputTokenBalance.sub(xcmAmount).sub(xcmFee).gt(BN_ZERO)) {
|
|
281
281
|
processValidation.failedStep = path.steps[1];
|
|
282
282
|
processValidation.ok = false;
|
|
283
283
|
processValidation.status = YieldValidationStatus.NOT_ENOUGH_BALANCE;
|
|
284
|
-
const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee);
|
|
284
|
+
const maxBn = bnInputTokenBalance.add(new BN(altInputTokenBalance.value)).sub(xcmFee).sub(xcmFee);
|
|
285
285
|
const maxValue = formatNumber(maxBn.toString(), inputTokenInfo.decimals || 0);
|
|
286
286
|
const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
|
|
287
287
|
const symbol = altInputTokenInfo.symbol;
|
|
@@ -289,7 +289,7 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
|
|
|
289
289
|
const inputNetworkName = this.chainInfo.name;
|
|
290
290
|
const altNetworkName = altNetwork.name;
|
|
291
291
|
const currentValue = formatNumber(bnInputTokenBalance.toString(), inputTokenInfo.decimals || 0);
|
|
292
|
-
const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee);
|
|
292
|
+
const bnMaxXCM = new BN(altInputTokenBalance.value).sub(xcmFee).sub(xcmFee);
|
|
293
293
|
const maxXCMValue = formatNumber(bnMaxXCM.toString(), inputTokenInfo.decimals || 0);
|
|
294
294
|
processValidation.message = t('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
|
|
295
295
|
replace: {
|
|
@@ -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
|
+
}
|
|
@@ -7,7 +7,8 @@ export default class MigrateTransactionHistoryBySymbol extends BaseMigrationJob
|
|
|
7
7
|
const state = this.state;
|
|
8
8
|
try {
|
|
9
9
|
const changeSlugsMap = {
|
|
10
|
-
'
|
|
10
|
+
'bobMainnet-LOCAL-wBTC-0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3': 'bobMainnet-LOCAL-WBTC-0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3',
|
|
11
|
+
'hydradx_main-LOCAL-LRNA': 'hydradx_main-LOCAL-H2O'
|
|
11
12
|
};
|
|
12
13
|
const allTxs = [];
|
|
13
14
|
await Promise.all(Object.entries(changeSlugsMap).map(async ([oldSlug, newSlug], i) => {
|
|
@@ -6,7 +6,8 @@ export default class MigrateAssetSetting extends BaseMigrationJob {
|
|
|
6
6
|
async run() {
|
|
7
7
|
try {
|
|
8
8
|
const changeSlugsMap = {
|
|
9
|
-
'
|
|
9
|
+
'bobMainnet-LOCAL-wBTC-0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3': 'bobMainnet-LOCAL-WBTC-0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3',
|
|
10
|
+
'hydradx_main-LOCAL-LRNA': 'hydradx_main-LOCAL-H2O'
|
|
10
11
|
};
|
|
11
12
|
const assetSetting = await this.state.chainService.getAssetSettings();
|
|
12
13
|
const migratedAssetSetting = {};
|
|
@@ -49,8 +49,8 @@ export default {
|
|
|
49
49
|
'1.1.28-01': MigrateEarningVersion,
|
|
50
50
|
'1.1.41-01': DeleteChainStaking,
|
|
51
51
|
'1.1.46-01': AutoEnableSomeTokens,
|
|
52
|
-
'1.1.
|
|
53
|
-
'1.1.
|
|
52
|
+
'1.1.69-03': MigrateAssetSetting,
|
|
53
|
+
'1.1.69-02': MigrateTransactionHistoryBySymbol,
|
|
54
54
|
'1.2.69-01': MigrateRemoveGenesisHash
|
|
55
55
|
// [`${EVERYTIME}-1.1.42-02`]: MigrateTransactionHistoryBySymbol
|
|
56
56
|
// [`${EVERYTIME}-1`]: AutoEnableChainsTokens
|
|
@@ -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;
|
|
@@ -60,11 +60,13 @@ export class SwapBaseHandler {
|
|
|
60
60
|
const xcmFeeComponent = params.process.totalFee[stepIndex].feeComponent[0]; // todo: can do better than indexing
|
|
61
61
|
const xcmFee = new BigNumber(xcmFeeComponent.amount || '0');
|
|
62
62
|
let xcmAmount = bnAmount.minus(bnFromAssetBalance);
|
|
63
|
+
let editedXcmFee = new BigNumber(0);
|
|
63
64
|
if (_isNativeToken(alternativeAsset)) {
|
|
64
65
|
xcmAmount = xcmAmount.plus(xcmFee);
|
|
66
|
+
editedXcmFee = xcmFee.times(2);
|
|
65
67
|
}
|
|
66
|
-
if (!bnAlternativeAssetBalance.minus(xcmAmount).gt(0)) {
|
|
67
|
-
const maxBn = bnFromAssetBalance.plus(new BigNumber(alternativeAssetBalance.value)).minus(xcmFee);
|
|
68
|
+
if (!bnAlternativeAssetBalance.minus(_isNativeToken(alternativeAsset) ? xcmAmount.plus(xcmFee) : xcmFee).gt(0)) {
|
|
69
|
+
const maxBn = bnFromAssetBalance.plus(new BigNumber(alternativeAssetBalance.value)).minus(_isNativeToken(alternativeAsset) ? editedXcmFee : xcmFee);
|
|
68
70
|
const maxValue = formatNumber(maxBn.toString(), fromAsset.decimals || 0);
|
|
69
71
|
const altInputTokenInfo = this.chainService.getAssetBySlug(alternativeAssetSlug);
|
|
70
72
|
const symbol = altInputTokenInfo.symbol;
|
|
@@ -73,7 +75,7 @@ export class SwapBaseHandler {
|
|
|
73
75
|
const inputNetworkName = chain.name;
|
|
74
76
|
const altNetworkName = alternativeChain.name;
|
|
75
77
|
const currentValue = formatNumber(bnFromAssetBalance.toString(), fromAsset.decimals || 0);
|
|
76
|
-
const bnMaxXCM = new BigNumber(alternativeAssetBalance.value).minus(xcmFee);
|
|
78
|
+
const bnMaxXCM = new BigNumber(alternativeAssetBalance.value).minus(_isNativeToken(alternativeAsset) ? editedXcmFee : xcmFee);
|
|
77
79
|
const maxXCMValue = formatNumber(bnMaxXCM.toString(), fromAsset.decimals || 0);
|
|
78
80
|
if (maxBn.lte(0) || bnFromAssetBalance.lte(0) || bnMaxXCM.lte(0)) {
|
|
79
81
|
return [new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, t(`Insufficient balance. Deposit ${fromAsset.symbol} and try again.`))];
|
|
@@ -26,7 +26,7 @@ export class HydradxHandler {
|
|
|
26
26
|
this.swapBaseHandler = new SwapBaseHandler({
|
|
27
27
|
balanceService,
|
|
28
28
|
chainService,
|
|
29
|
-
providerName: isTestnet ? '
|
|
29
|
+
providerName: isTestnet ? 'Hydration Testnet' : 'Hydration',
|
|
30
30
|
providerSlug: isTestnet ? SwapProviderId.HYDRADX_TESTNET : SwapProviderId.HYDRADX_MAINNET
|
|
31
31
|
});
|
|
32
32
|
this.providerSlug = isTestnet ? SwapProviderId.HYDRADX_TESTNET : SwapProviderId.HYDRADX_MAINNET;
|