@subwallet/extension-base 1.0.1 → 1.0.2-1b
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 +25 -36
- package/background/KoniTypes.js +12 -7
- package/background/errors/TransactionError.js +21 -1
- package/cjs/background/KoniTypes.js +14 -8
- package/cjs/background/errors/TransactionError.js +20 -0
- package/cjs/constants/index.js +13 -28
- package/cjs/koni/api/dotsama/balance.js +60 -224
- package/cjs/koni/api/dotsama/transfer.js +30 -29
- package/cjs/koni/api/nft/acala_nft/index.js +4 -1
- package/cjs/koni/api/nft/bit.country/index.js +4 -1
- package/cjs/koni/api/nft/evm_nft/index.js +7 -3
- package/cjs/koni/api/nft/index.js +3 -6
- package/cjs/koni/api/nft/karura_nft/index.js +4 -1
- package/cjs/koni/api/nft/rmrk_nft/index.js +8 -1
- package/cjs/koni/api/nft/statemine_nft/index.js +4 -1
- package/cjs/koni/api/nft/unique_nft/index.js +6 -1
- package/cjs/koni/api/nft/wasm_nft/index.js +169 -111
- package/cjs/koni/api/nft/wasm_nft/utils.js +11 -7
- package/cjs/koni/api/staking/bonding/amplitude.js +18 -10
- package/cjs/koni/api/staking/bonding/astar.js +37 -238
- package/cjs/koni/api/staking/bonding/index.js +26 -14
- package/cjs/koni/api/staking/bonding/paraChain.js +100 -11
- package/cjs/koni/api/staking/bonding/relayChain.js +174 -16
- package/cjs/koni/api/staking/bonding/utils.js +55 -10
- package/cjs/koni/api/tokens/wasm/index.js +5 -4
- package/cjs/koni/api/tokens/wasm/utils.js +63 -0
- package/cjs/koni/api/xcm/index.js +0 -111
- package/cjs/koni/api/xcm/polkadotXcm.js +2 -2
- package/cjs/koni/api/xcm/utils.js +18 -13
- package/cjs/koni/api/xcm/xTokens.js +3 -5
- package/cjs/koni/api/xcm/xcmPallet.js +9 -6
- package/cjs/koni/background/cron.js +179 -77
- package/cjs/koni/background/handlers/Extension.js +231 -195
- package/cjs/koni/background/handlers/State.js +147 -111
- package/cjs/koni/background/handlers/Tabs.js +48 -39
- package/cjs/koni/background/subscription.js +64 -56
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/index.js +5 -0
- package/cjs/services/chain-service/constants.js +1 -11
- package/cjs/services/chain-service/handler/SubstrateChainHandler.js +13 -8
- package/cjs/services/chain-service/handler/light-client/index.js +2 -0
- package/cjs/services/chain-service/index.js +39 -6
- package/cjs/services/chain-service/utils.js +4 -0
- package/cjs/services/event-service/index.js +75 -0
- package/cjs/services/event-service/types.js +11 -0
- package/cjs/services/history-service/index.js +46 -21
- package/cjs/services/history-service/subsquid-multi-chain-history.js +19 -11
- package/cjs/services/keyring-service/index.js +101 -0
- package/cjs/services/migration-service/index.js +13 -10
- package/cjs/{koni/migration/scripts/RemoveWrongCrowdloan.js → services/migration-service/scripts/AutoEnableChainsTokens.js} +11 -6
- package/cjs/services/migration-service/scripts/MigrateNetworkSettings.js +39 -19
- package/cjs/services/migration-service/scripts/MigrateSettings.js +31 -0
- package/cjs/services/migration-service/scripts/MigrateTransactionHistory.js +72 -0
- package/cjs/services/migration-service/scripts/index.js +13 -4
- package/cjs/services/price-service/coingecko.js +15 -3
- package/cjs/services/price-service/index.js +15 -18
- package/cjs/services/request-service/constants.js +8 -2
- package/cjs/services/request-service/handler/AuthRequestHandler.js +43 -12
- package/cjs/services/request-service/index.js +3 -0
- package/cjs/services/storage-service/DatabaseService.js +53 -34
- package/cjs/services/storage-service/databases/index.js +1 -1
- package/cjs/services/storage-service/db-stores/BaseStoreWithAddressAndChain.js +2 -8
- package/cjs/services/storage-service/db-stores/Nft.js +8 -18
- package/cjs/services/storage-service/db-stores/Transaction.js +10 -7
- package/cjs/services/subscan-service/index.js +107 -0
- package/cjs/services/subscan-service/subscan-chain-map.js +74 -0
- package/cjs/services/subscan-service/types.js +1 -0
- package/cjs/services/transaction-service/event-parser/index.js +20 -48
- package/cjs/services/transaction-service/index.js +66 -22
- package/cjs/services/transaction-service/utils.js +4 -6
- package/cjs/utils/address.js +9 -1
- package/cjs/utils/index.js +30 -26
- package/constants/index.d.ts +8 -13
- package/constants/index.js +8 -13
- package/koni/api/dotsama/balance.d.ts +0 -1
- package/koni/api/dotsama/balance.js +33 -197
- package/koni/api/dotsama/transfer.js +5 -4
- package/koni/api/nft/acala_nft/index.js +3 -1
- package/koni/api/nft/bit.country/index.js +3 -1
- package/koni/api/nft/evm_nft/index.js +6 -3
- package/koni/api/nft/index.d.ts +1 -2
- package/koni/api/nft/index.js +3 -6
- package/koni/api/nft/karura_nft/index.js +3 -1
- package/koni/api/nft/nft.d.ts +1 -0
- package/koni/api/nft/rmrk_nft/index.js +8 -1
- package/koni/api/nft/statemine_nft/index.js +3 -1
- package/koni/api/nft/unique_nft/index.js +5 -1
- package/koni/api/nft/wasm_nft/index.d.ts +0 -2
- package/koni/api/nft/wasm_nft/index.js +167 -109
- package/koni/api/nft/wasm_nft/utils.d.ts +7 -5
- package/koni/api/nft/wasm_nft/utils.js +7 -5
- package/koni/api/staking/bonding/amplitude.d.ts +1 -2
- package/koni/api/staking/bonding/amplitude.js +22 -13
- package/koni/api/staking/bonding/astar.d.ts +2 -11
- package/koni/api/staking/bonding/astar.js +39 -231
- package/koni/api/staking/bonding/index.d.ts +5 -2
- package/koni/api/staking/bonding/index.js +27 -17
- package/koni/api/staking/bonding/paraChain.d.ts +4 -1
- package/koni/api/staking/bonding/paraChain.js +101 -14
- package/koni/api/staking/bonding/relayChain.d.ts +6 -2
- package/koni/api/staking/bonding/relayChain.js +172 -17
- package/koni/api/staking/bonding/utils.d.ts +15 -2
- package/koni/api/staking/bonding/utils.js +53 -11
- package/koni/api/tokens/wasm/index.js +5 -4
- package/koni/api/tokens/wasm/utils.d.ts +6 -0
- package/koni/api/tokens/wasm/utils.js +54 -0
- package/koni/api/xcm/index.js +1 -112
- package/koni/api/xcm/polkadotXcm.js +3 -3
- package/koni/api/xcm/utils.d.ts +5 -6
- package/koni/api/xcm/utils.js +15 -10
- package/koni/api/xcm/xTokens.js +5 -7
- package/koni/api/xcm/xcmPallet.js +10 -9
- package/koni/background/cron.d.ts +6 -1
- package/koni/background/cron.js +179 -76
- package/koni/background/handlers/Extension.d.ts +2 -2
- package/koni/background/handlers/Extension.js +161 -125
- package/koni/background/handlers/State.d.ts +21 -20
- package/koni/background/handlers/State.js +144 -111
- package/koni/background/handlers/Tabs.js +30 -20
- package/koni/background/subscription.d.ts +1 -1
- package/koni/background/subscription.js +64 -58
- package/package.json +63 -18
- package/packageInfo.js +1 -1
- package/page/index.d.ts +2 -0
- package/page/index.js +4 -0
- package/services/chain-service/constants.d.ts +0 -1
- package/services/chain-service/constants.js +0 -9
- package/services/chain-service/handler/SubstrateChainHandler.js +14 -9
- package/services/chain-service/handler/light-client/index.d.ts +17 -1
- package/services/chain-service/handler/light-client/index.js +1 -1
- package/services/chain-service/helper/psp22_abi.json +1041 -881
- package/services/chain-service/helper/psp34_abi.json +2963 -1807
- package/services/chain-service/index.d.ts +6 -4
- package/services/chain-service/index.js +40 -9
- package/services/chain-service/utils.d.ts +1 -0
- package/services/chain-service/utils.js +3 -0
- package/services/event-service/index.d.ts +22 -0
- package/services/event-service/index.js +63 -0
- package/services/event-service/types.d.ts +28 -0
- package/services/event-service/types.js +4 -0
- package/services/history-service/index.d.ts +5 -3
- package/services/history-service/index.js +46 -21
- package/services/history-service/subsquid-multi-chain-history.js +22 -13
- package/services/keyring-service/index.d.ts +19 -0
- package/services/keyring-service/index.js +93 -0
- package/services/migration-service/index.js +11 -9
- package/services/migration-service/scripts/AutoEnableChainsTokens.d.ts +4 -0
- package/services/migration-service/scripts/AutoEnableChainsTokens.js +13 -0
- package/services/migration-service/scripts/MigrateNetworkSettings.js +37 -18
- package/services/migration-service/scripts/MigrateSettings.d.ts +4 -0
- package/services/migration-service/scripts/MigrateSettings.js +23 -0
- package/services/migration-service/scripts/MigrateTransactionHistory.d.ts +4 -0
- package/services/migration-service/scripts/MigrateTransactionHistory.js +64 -0
- package/services/migration-service/scripts/index.d.ts +1 -0
- package/services/migration-service/scripts/index.js +10 -3
- package/services/price-service/coingecko.js +15 -3
- package/services/price-service/index.d.ts +5 -3
- package/services/price-service/index.js +15 -18
- package/services/request-service/constants.d.ts +1 -0
- package/services/request-service/constants.js +6 -1
- package/services/request-service/handler/AuthRequestHandler.d.ts +8 -1
- package/services/request-service/handler/AuthRequestHandler.js +44 -13
- package/services/request-service/index.d.ts +7 -1
- package/services/request-service/index.js +3 -0
- package/services/storage-service/DatabaseService.d.ts +1 -0
- package/services/storage-service/DatabaseService.js +53 -34
- package/services/storage-service/databases/index.js +1 -1
- package/services/storage-service/db-stores/BaseStoreWithAddressAndChain.d.ts +1 -1
- package/services/storage-service/db-stores/BaseStoreWithAddressAndChain.js +2 -8
- package/services/storage-service/db-stores/Nft.d.ts +3 -3
- package/services/storage-service/db-stores/Nft.js +8 -17
- package/services/storage-service/db-stores/Transaction.js +10 -7
- package/services/subscan-service/index.d.ts +20 -0
- package/services/subscan-service/index.js +99 -0
- package/services/subscan-service/subscan-chain-map.d.ts +5 -0
- package/services/subscan-service/subscan-chain-map.js +63 -0
- package/services/subscan-service/types.d.ts +27 -0
- package/services/subscan-service/types.js +1 -0
- package/services/transaction-service/event-parser/index.d.ts +2 -2
- package/services/transaction-service/event-parser/index.js +21 -49
- package/services/transaction-service/index.d.ts +4 -2
- package/services/transaction-service/index.js +66 -22
- package/services/transaction-service/utils.js +5 -6
- package/utils/address.d.ts +1 -0
- package/utils/address.js +9 -2
- package/utils/index.d.ts +2 -1
- package/utils/index.js +26 -23
- package/cjs/background/errors/EvmRpcError.js +0 -21
- package/cjs/background/errors/SubWalletProviderError.js +0 -17
- package/cjs/constants/ethereum.js +0 -19
- package/cjs/errors/SubWalletProviderError.js +0 -17
- package/cjs/koni/api/xcm/astar.js +0 -160
- package/cjs/koni/api/xcm/moonbeamXcm.js +0 -80
- package/cjs/koni/api/xcm/statemintXcm.js +0 -197
- package/cjs/koni/api/xcm/substrateXcm.js +0 -213
- package/cjs/koni/migration/Base.js +0 -20
- package/cjs/koni/migration/index.js +0 -45
- package/cjs/koni/migration/scripts/ChangeRouteToHome.js +0 -22
- package/cjs/koni/migration/scripts/ClearOldStorage.js +0 -24
- package/cjs/koni/migration/scripts/RemoveWrongTransactionHistoriesFromStore.js +0 -36
- package/cjs/koni/migration/scripts/ResetTransactionHistoryEventIdx.js +0 -21
- package/cjs/koni/migration/scripts/index.js +0 -22
- package/cjs/koni/page/index.js +0 -16
- package/cjs/services/asset-service/index.js +0 -91
- package/cjs/services/storage-service/db-stores/ExtraDelegationInfo.js +0 -17
- package/cjs/stores/Balance.js +0 -18
- package/cjs/stores/Crowdloan.js +0 -18
- package/cjs/stores/CustomEvmToken.js +0 -18
- package/cjs/stores/NetworkMap.js +0 -18
- package/cjs/stores/Nft.js +0 -18
- package/cjs/stores/NftCollection.js +0 -18
- package/cjs/stores/Price.js +0 -18
- package/cjs/stores/Staking.js +0 -18
- package/cjs/stores/StakingReward.js +0 -18
- package/cjs/utils/eth/parseTransactionData.js +0 -284
- package/koni/page/index.d.ts +0 -2
- package/koni/page/index.js +0 -9
- /package/cjs/{koni/page → page}/SubWalleEvmProvider.js +0 -0
- /package/{koni/page → page}/SubWalleEvmProvider.d.ts +0 -0
- /package/{koni/page → page}/SubWalleEvmProvider.js +0 -0
|
@@ -1,13 +1,86 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { BasicTxErrorType, StakingStatus, StakingTxErrorType, StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { getBondedValidators, getParaCurrentInflation, getStakingStatusByNominations, isUnstakeAll, parseIdentity } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
6
7
|
import { _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
7
8
|
import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
-
import { parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
9
|
+
import { isSameAddress, parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
9
10
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
10
11
|
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
12
|
+
export function validateParaChainUnbondingCondition(amount, nominatorMetadata, chainStakingMetadata, selectedCollator) {
|
|
13
|
+
const errors = [];
|
|
14
|
+
let targetNomination;
|
|
15
|
+
for (const nomination of nominatorMetadata.nominations) {
|
|
16
|
+
if (isSameAddress(nomination.validatorAddress, selectedCollator)) {
|
|
17
|
+
targetNomination = nomination;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!targetNomination) {
|
|
22
|
+
errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
|
|
23
|
+
return errors;
|
|
24
|
+
}
|
|
25
|
+
const bnActiveStake = new BN(targetNomination.activeStake);
|
|
26
|
+
const bnRemainingStake = bnActiveStake.sub(new BN(amount));
|
|
27
|
+
const bnChainMinStake = new BN(chainStakingMetadata.minStake || '0');
|
|
28
|
+
const bnCollatorMinStake = new BN(targetNomination.validatorMinStake || '0');
|
|
29
|
+
const bnMinStake = bnCollatorMinStake > bnChainMinStake ? bnCollatorMinStake : bnChainMinStake;
|
|
30
|
+
if (targetNomination.hasUnstaking) {
|
|
31
|
+
errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST));
|
|
32
|
+
}
|
|
33
|
+
if (!(bnRemainingStake.isZero() || bnRemainingStake.gte(bnMinStake))) {
|
|
34
|
+
errors.push(new TransactionError(StakingTxErrorType.INVALID_ACTIVE_STAKE));
|
|
35
|
+
}
|
|
36
|
+
return errors;
|
|
37
|
+
}
|
|
38
|
+
export function validateParaChainBondingCondition(chainInfo, amount, selectedCollators, address, chainStakingMetadata, nominatorMetadata) {
|
|
39
|
+
const errors = [];
|
|
40
|
+
const selectedCollator = selectedCollators[0];
|
|
41
|
+
let bnTotalStake = new BN(amount);
|
|
42
|
+
const bnChainMinStake = new BN(chainStakingMetadata.minStake || '0');
|
|
43
|
+
const bnCollatorMinStake = new BN(selectedCollator.minBond || '0');
|
|
44
|
+
const bnMinStake = bnCollatorMinStake > bnChainMinStake ? bnCollatorMinStake : bnChainMinStake;
|
|
45
|
+
if (!nominatorMetadata) {
|
|
46
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
47
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
48
|
+
}
|
|
49
|
+
return errors;
|
|
50
|
+
}
|
|
51
|
+
const {
|
|
52
|
+
bondedValidators
|
|
53
|
+
} = getBondedValidators(nominatorMetadata.nominations);
|
|
54
|
+
const parsedSelectedCollatorAddress = reformatAddress(selectedCollator.address, 0);
|
|
55
|
+
if (!bondedValidators.includes(parsedSelectedCollatorAddress)) {
|
|
56
|
+
// new delegation
|
|
57
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
58
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
59
|
+
}
|
|
60
|
+
const delegationCount = nominatorMetadata.nominations.length + 1;
|
|
61
|
+
if (delegationCount > chainStakingMetadata.maxValidatorPerNominator) {
|
|
62
|
+
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_NOMINATIONS));
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
let currentDelegationAmount = '0';
|
|
66
|
+
let hasUnstaking = false;
|
|
67
|
+
for (const delegation of nominatorMetadata.nominations) {
|
|
68
|
+
if (reformatAddress(delegation.validatorAddress, 0) === parsedSelectedCollatorAddress) {
|
|
69
|
+
currentDelegationAmount = delegation.activeStake;
|
|
70
|
+
hasUnstaking = !!delegation.hasUnstaking && delegation.hasUnstaking;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
bnTotalStake = bnTotalStake.add(new BN(currentDelegationAmount));
|
|
75
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
76
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
77
|
+
}
|
|
78
|
+
if (hasUnstaking) {
|
|
79
|
+
errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return errors;
|
|
83
|
+
}
|
|
11
84
|
export async function getParaChainStakingMetadata(chain, substrateApi) {
|
|
12
85
|
const chainApi = await substrateApi.isReady;
|
|
13
86
|
const _round = (await chainApi.api.query.parachainStaking.round()).toHuman();
|
|
@@ -61,13 +134,16 @@ export async function getParaChainNominatorMetadata(chainInfo, address, substrat
|
|
|
61
134
|
}
|
|
62
135
|
let bnTotalActiveStake = BN_ZERO;
|
|
63
136
|
await Promise.all(delegatorState.delegations.map(async delegation => {
|
|
64
|
-
const [_delegationScheduledRequests, _identity, _roundInfo] = await Promise.all([chainApi.api.query.parachainStaking.delegationScheduledRequests(delegation.owner), chainApi.api.query.identity.identityOf(delegation.owner), chainApi.api.query.parachainStaking.round()]);
|
|
137
|
+
const [_delegationScheduledRequests, _identity, _roundInfo, _collatorInfo] = await Promise.all([chainApi.api.query.parachainStaking.delegationScheduledRequests(delegation.owner), chainApi.api.query.identity.identityOf(delegation.owner), chainApi.api.query.parachainStaking.round(), chainApi.api.query.parachainStaking.candidateInfo(delegation.owner)]);
|
|
138
|
+
const rawCollatorInfo = _collatorInfo.toHuman();
|
|
139
|
+
const minDelegation = (rawCollatorInfo === null || rawCollatorInfo === void 0 ? void 0 : rawCollatorInfo.lowestTopDelegationAmount).replaceAll(',', '');
|
|
65
140
|
const identityInfo = _identity.toHuman();
|
|
66
141
|
const roundInfo = _roundInfo.toPrimitive();
|
|
67
142
|
const delegationScheduledRequests = _delegationScheduledRequests.toPrimitive();
|
|
68
143
|
const currentRound = roundInfo.current;
|
|
69
144
|
const identity = parseIdentity(identityInfo);
|
|
70
145
|
let hasUnstaking = false;
|
|
146
|
+
let delegationStatus = StakingStatus.NOT_EARNING;
|
|
71
147
|
|
|
72
148
|
// parse unstaking info
|
|
73
149
|
if (delegationScheduledRequests) {
|
|
@@ -94,9 +170,13 @@ export async function getParaChainNominatorMetadata(chainInfo, address, substrat
|
|
|
94
170
|
const bnStake = new BN(delegation.amount);
|
|
95
171
|
const bnUnstakeBalance = unstakingMap[delegation.owner] ? new BN(unstakingMap[delegation.owner].claimable) : BN_ZERO;
|
|
96
172
|
const bnActiveStake = bnStake.sub(bnUnstakeBalance);
|
|
173
|
+
if (bnActiveStake.gt(BN_ZERO) && bnActiveStake.gte(new BN(minDelegation))) {
|
|
174
|
+
delegationStatus = StakingStatus.EARNING_REWARD;
|
|
175
|
+
}
|
|
97
176
|
bnTotalActiveStake = bnTotalActiveStake.add(bnActiveStake);
|
|
98
177
|
nominationList.push({
|
|
99
178
|
chain,
|
|
179
|
+
status: delegationStatus,
|
|
100
180
|
validatorAddress: delegation.owner,
|
|
101
181
|
validatorIdentity: identity,
|
|
102
182
|
activeStake: bnActiveStake.toString(),
|
|
@@ -108,9 +188,11 @@ export async function getParaChainNominatorMetadata(chainInfo, address, substrat
|
|
|
108
188
|
const collatorInfo = _collatorInfo.toPrimitive();
|
|
109
189
|
nomination.validatorMinStake = collatorInfo.lowestTopDelegationAmount.toString();
|
|
110
190
|
}));
|
|
191
|
+
const stakingStatus = getStakingStatusByNominations(bnTotalActiveStake, nominationList);
|
|
111
192
|
return {
|
|
112
193
|
chain,
|
|
113
194
|
type: StakingType.NOMINATED,
|
|
195
|
+
status: stakingStatus,
|
|
114
196
|
address: address,
|
|
115
197
|
activeStake: bnTotalActiveStake.toString(),
|
|
116
198
|
nominations: nominationList,
|
|
@@ -119,15 +201,16 @@ export async function getParaChainNominatorMetadata(chainInfo, address, substrat
|
|
|
119
201
|
}
|
|
120
202
|
export async function getParachainCollatorsInfo(chain, substrateApi) {
|
|
121
203
|
const apiProps = await substrateApi.isReady;
|
|
122
|
-
const
|
|
204
|
+
const allCollators = [];
|
|
123
205
|
const [_allCollators, _collatorCommission] = await Promise.all([apiProps.api.query.parachainStaking.candidateInfo.entries(), apiProps.api.query.parachainStaking.collatorCommission()]);
|
|
124
206
|
const maxDelegationPerCollator = apiProps.api.consts.parachainStaking.maxTopDelegationsPerCandidate.toString();
|
|
125
207
|
const rawCollatorCommission = _collatorCommission.toHuman();
|
|
126
208
|
const collatorCommission = parseFloat(rawCollatorCommission.split('%')[0]);
|
|
127
209
|
for (const collator of _allCollators) {
|
|
128
|
-
const
|
|
210
|
+
const _collatorAddress = collator[0].toHuman();
|
|
211
|
+
const collatorAddress = _collatorAddress[0];
|
|
129
212
|
const collatorInfo = collator[1].toPrimitive();
|
|
130
|
-
|
|
213
|
+
allCollators.push({
|
|
131
214
|
commission: 0,
|
|
132
215
|
expectedReturn: 0,
|
|
133
216
|
address: collatorAddress,
|
|
@@ -143,9 +226,9 @@ export async function getParachainCollatorsInfo(chain, substrateApi) {
|
|
|
143
226
|
});
|
|
144
227
|
}
|
|
145
228
|
const extraInfoMap = {};
|
|
146
|
-
await Promise.all(
|
|
229
|
+
await Promise.all(allCollators.map(async collator => {
|
|
147
230
|
var _apiProps$api$query, _apiProps$api$query$i;
|
|
148
|
-
const [_info, _identity] = await Promise.all([apiProps.api.query.parachainStaking.candidateInfo(
|
|
231
|
+
const [_info, _identity] = await Promise.all([apiProps.api.query.parachainStaking.candidateInfo(collator.address), (_apiProps$api$query = apiProps.api.query) === null || _apiProps$api$query === void 0 ? void 0 : (_apiProps$api$query$i = _apiProps$api$query.identity) === null || _apiProps$api$query$i === void 0 ? void 0 : _apiProps$api$query$i.identityOf(collator.address) // some chains might not have identity pallet
|
|
149
232
|
]);
|
|
150
233
|
const rawInfo = _info.toHuman();
|
|
151
234
|
const rawIdentity = _identity ? _identity.toHuman() : null;
|
|
@@ -161,7 +244,7 @@ export async function getParachainCollatorsInfo(chain, substrateApi) {
|
|
|
161
244
|
isReasonable = rawIdentity.judgements.length > 0;
|
|
162
245
|
identity = parseIdentity(rawIdentity);
|
|
163
246
|
}
|
|
164
|
-
extraInfoMap[
|
|
247
|
+
extraInfoMap[collator.address] = {
|
|
165
248
|
identity,
|
|
166
249
|
isVerified: isReasonable,
|
|
167
250
|
bond: bond.toString(),
|
|
@@ -170,7 +253,7 @@ export async function getParachainCollatorsInfo(chain, substrateApi) {
|
|
|
170
253
|
active
|
|
171
254
|
};
|
|
172
255
|
}));
|
|
173
|
-
for (const validator of
|
|
256
|
+
for (const validator of allCollators) {
|
|
174
257
|
validator.minBond = extraInfoMap[validator.address].minDelegation.toString();
|
|
175
258
|
validator.ownStake = extraInfoMap[validator.address].bond.toString();
|
|
176
259
|
validator.blocked = !extraInfoMap[validator.address].active;
|
|
@@ -181,16 +264,20 @@ export async function getParachainCollatorsInfo(chain, substrateApi) {
|
|
|
181
264
|
validator.nominatorCount = extraInfoMap[validator.address].delegationCount;
|
|
182
265
|
validator.commission = collatorCommission;
|
|
183
266
|
}
|
|
184
|
-
return
|
|
267
|
+
return allCollators;
|
|
185
268
|
}
|
|
186
|
-
export async function getParaBondingExtrinsic(
|
|
269
|
+
export async function getParaBondingExtrinsic(chainInfo, substrateApi, amount, selectedCollatorInfo, nominatorMetadata) {
|
|
187
270
|
const apiPromise = await substrateApi.isReady;
|
|
188
271
|
const binaryAmount = new BN(amount);
|
|
272
|
+
if (!nominatorMetadata) {
|
|
273
|
+
return apiPromise.api.tx.parachainStaking.delegate(selectedCollatorInfo.address, binaryAmount, new BN(selectedCollatorInfo.nominatorCount), 0);
|
|
274
|
+
}
|
|
189
275
|
const {
|
|
190
276
|
bondedValidators,
|
|
191
277
|
nominationCount
|
|
192
278
|
} = getBondedValidators(nominatorMetadata.nominations);
|
|
193
|
-
|
|
279
|
+
const parsedSelectedCollatorAddress = reformatAddress(selectedCollatorInfo.address, 0);
|
|
280
|
+
if (!bondedValidators.includes(parsedSelectedCollatorAddress)) {
|
|
194
281
|
return apiPromise.api.tx.parachainStaking.delegate(selectedCollatorInfo.address, binaryAmount, new BN(selectedCollatorInfo.nominatorCount), nominationCount);
|
|
195
282
|
} else {
|
|
196
283
|
return apiPromise.api.tx.parachainStaking.delegatorBondMore(selectedCollatorInfo.address, binaryAmount);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
2
3
|
import { ChainStakingMetadata, NominationPoolInfo, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
4
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
4
5
|
export interface PalletStakingNominations {
|
|
@@ -17,12 +18,15 @@ export interface PalletStakingStakingLedger {
|
|
|
17
18
|
unlocking: UnlockingChunk[];
|
|
18
19
|
claimedRewards: number[];
|
|
19
20
|
}
|
|
20
|
-
export declare function
|
|
21
|
+
export declare function validateRelayUnbondingCondition(amount: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata: NominatorMetadata): TransactionError[];
|
|
22
|
+
export declare function validatePoolBondingCondition(chainInfo: _ChainInfo, amount: string, selectedPool: NominationPoolInfo, address: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata?: NominatorMetadata): TransactionError[];
|
|
23
|
+
export declare function validateRelayBondingCondition(chainInfo: _ChainInfo, amount: string, selectedValidators: ValidatorInfo[], address: string, chainStakingMetadata: ChainStakingMetadata, nominatorMetadata?: NominatorMetadata): TransactionError[];
|
|
24
|
+
export declare function getRelayChainStakingMetadata(chainInfo: _ChainInfo, substrateApi: _SubstrateApi): Promise<ChainStakingMetadata>;
|
|
21
25
|
export declare function getRelayChainNominatorMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
|
|
22
26
|
export declare function getRelayChainPoolMemberMetadata(chainInfo: _ChainInfo, address: string, substrateApi: _SubstrateApi): Promise<NominatorMetadata | undefined>;
|
|
23
27
|
export declare function getRelayValidatorsInfo(chain: string, substrateApi: _SubstrateApi, decimals: number, chainStakingMetadata: ChainStakingMetadata): Promise<ValidatorInfo[]>;
|
|
24
28
|
export declare function getRelayPoolsInfo(chain: string, substrateApi: _SubstrateApi): Promise<NominationPoolInfo[]>;
|
|
25
|
-
export declare function getRelayBondingExtrinsic(substrateApi: _SubstrateApi, amount: string, targetValidators: ValidatorInfo[],
|
|
29
|
+
export declare function getRelayBondingExtrinsic(substrateApi: _SubstrateApi, amount: string, targetValidators: ValidatorInfo[], chainInfo: _ChainInfo, address: string, nominatorMetadata?: NominatorMetadata, bondDest?: string): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
26
30
|
export declare function getRelayUnbondingExtrinsic(substrateApi: _SubstrateApi, amount: string, nominatorMetadata: NominatorMetadata): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
27
31
|
export declare function getRelayWithdrawalExtrinsic(substrateApi: _SubstrateApi, address: string): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
28
32
|
export declare function getRelayCancelWithdrawalExtrinsic(substrateApi: _SubstrateApi, selectedUnstaking: UnstakingInfo): Promise<import("@polkadot/api-base/types").SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
|
|
@@ -1,21 +1,99 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { StakingStatus, StakingTxErrorType, StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { calculateAlephZeroValidatorReturn, calculateChainStakedReturn, calculateInflation, calculateValidatorStakedReturn, getCommission, parseIdentity, parsePoolStashAddress, transformPoolName } from '@subwallet/extension-base/koni/api/staking/bonding/utils';
|
|
6
7
|
import { _STAKING_CHAIN_GROUP, _STAKING_ERA_LENGTH_MAP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
|
+
import { _getChainNativeTokenBasicInfo, _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
|
+
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
7
10
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
8
11
|
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
9
|
-
export
|
|
10
|
-
|
|
12
|
+
export function validateRelayUnbondingCondition(amount, chainStakingMetadata, nominatorMetadata) {
|
|
13
|
+
const errors = [];
|
|
14
|
+
const bnActiveStake = new BN(nominatorMetadata.activeStake);
|
|
15
|
+
const bnRemainingStake = bnActiveStake.sub(new BN(amount));
|
|
16
|
+
const minStake = new BN(chainStakingMetadata.minPoolBonding || '0');
|
|
17
|
+
if (!(bnRemainingStake.isZero() || bnRemainingStake.gte(minStake))) {
|
|
18
|
+
errors.push(new TransactionError(StakingTxErrorType.INVALID_ACTIVE_STAKE));
|
|
19
|
+
}
|
|
20
|
+
if (nominatorMetadata.unstakings.length > chainStakingMetadata.maxWithdrawalRequestPerValidator) {
|
|
21
|
+
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_UNSTAKING));
|
|
22
|
+
}
|
|
23
|
+
return errors;
|
|
24
|
+
}
|
|
25
|
+
export function validatePoolBondingCondition(chainInfo, amount, selectedPool, address, chainStakingMetadata, nominatorMetadata) {
|
|
26
|
+
// cannot stake when unstake all
|
|
27
|
+
// amount >= min stake
|
|
28
|
+
const errors = [];
|
|
29
|
+
let bnTotalStake = new BN(amount);
|
|
30
|
+
const bnMinStake = new BN(chainStakingMetadata.minPoolBonding || '0');
|
|
31
|
+
if (nominatorMetadata) {
|
|
32
|
+
const bnCurrentActiveStake = new BN(nominatorMetadata.activeStake);
|
|
33
|
+
bnTotalStake = bnTotalStake.add(bnCurrentActiveStake);
|
|
34
|
+
if (!bnCurrentActiveStake.gt(BN_ZERO)) {
|
|
35
|
+
errors.push(new TransactionError(StakingTxErrorType.EXIST_UNSTAKING_REQUEST));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
39
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
40
|
+
}
|
|
41
|
+
return errors;
|
|
42
|
+
}
|
|
43
|
+
export function validateRelayBondingCondition(chainInfo, amount, selectedValidators, address, chainStakingMetadata, nominatorMetadata) {
|
|
44
|
+
const errors = [];
|
|
45
|
+
let bnTotalStake = new BN(amount);
|
|
46
|
+
const bnMinStake = new BN(chainStakingMetadata.minStake);
|
|
47
|
+
if (!nominatorMetadata) {
|
|
48
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
49
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
50
|
+
}
|
|
51
|
+
if (selectedValidators.length > chainStakingMetadata.maxValidatorPerNominator) {
|
|
52
|
+
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_NOMINATIONS));
|
|
53
|
+
}
|
|
54
|
+
return errors;
|
|
55
|
+
}
|
|
56
|
+
const bnCurrentActiveStake = new BN(nominatorMetadata.activeStake);
|
|
57
|
+
bnTotalStake = bnTotalStake.add(bnCurrentActiveStake);
|
|
58
|
+
if (!bnTotalStake.gte(bnMinStake)) {
|
|
59
|
+
errors.push(new TransactionError(StakingTxErrorType.NOT_ENOUGH_MIN_STAKE));
|
|
60
|
+
}
|
|
61
|
+
if (selectedValidators.length > chainStakingMetadata.maxValidatorPerNominator) {
|
|
62
|
+
errors.push(new TransactionError(StakingTxErrorType.EXCEED_MAX_NOMINATIONS));
|
|
63
|
+
}
|
|
64
|
+
return errors;
|
|
65
|
+
}
|
|
66
|
+
export async function getRelayChainStakingMetadata(chainInfo, substrateApi) {
|
|
67
|
+
var _chainApi$api$query$a, _chainApi$api$query, _chainApi$api$query$s, _chainApi$api$query2, _chainApi$api$query2$, _chainApi$api$query3, _chainApi$api$query3$;
|
|
68
|
+
const chain = chainInfo.slug;
|
|
69
|
+
const {
|
|
70
|
+
decimals
|
|
71
|
+
} = _getChainNativeTokenBasicInfo(chainInfo);
|
|
11
72
|
const chainApi = await substrateApi.isReady;
|
|
12
73
|
const _era = await chainApi.api.query.staking.currentEra();
|
|
13
74
|
const currentEra = _era.toString();
|
|
14
75
|
const maxNominations = chainApi.api.consts.staking.maxNominations.toString();
|
|
15
76
|
const maxUnlockingChunks = chainApi.api.consts.staking.maxUnlockingChunks.toString();
|
|
16
77
|
const unlockingEras = chainApi.api.consts.staking.bondingDuration.toString();
|
|
17
|
-
const [_totalEraStake, _totalIssuance, _auctionCounter, _minimumActiveStake, _minPoolJoin] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), chainApi.api.query.balances.totalIssuance(), (_chainApi$api$query$a = chainApi.api.query.auctions) === null || _chainApi$api$query$a === void 0 ? void 0 : _chainApi$api$query$a.auctionCounter(), chainApi.api.query.staking.minimumActiveStake()
|
|
18
|
-
const
|
|
78
|
+
const [_totalEraStake, _totalIssuance, _auctionCounter, _minimumActiveStake, _minNominatorBond, _minPoolJoin, _eraStakers] = await Promise.all([chainApi.api.query.staking.erasTotalStake(parseInt(currentEra)), chainApi.api.query.balances.totalIssuance(), (_chainApi$api$query$a = chainApi.api.query.auctions) === null || _chainApi$api$query$a === void 0 ? void 0 : _chainApi$api$query$a.auctionCounter(), ((_chainApi$api$query = chainApi.api.query) === null || _chainApi$api$query === void 0 ? void 0 : (_chainApi$api$query$s = _chainApi$api$query.staking) === null || _chainApi$api$query$s === void 0 ? void 0 : _chainApi$api$query$s.minimumActiveStake) && ((_chainApi$api$query2 = chainApi.api.query) === null || _chainApi$api$query2 === void 0 ? void 0 : (_chainApi$api$query2$ = _chainApi$api$query2.staking) === null || _chainApi$api$query2$ === void 0 ? void 0 : _chainApi$api$query2$.minimumActiveStake()), chainApi.api.query.staking.minNominatorBond(), (_chainApi$api$query3 = chainApi.api.query) === null || _chainApi$api$query3 === void 0 ? void 0 : (_chainApi$api$query3$ = _chainApi$api$query3.nominationPools) === null || _chainApi$api$query3$ === void 0 ? void 0 : _chainApi$api$query3$.minJoinBond(), chainApi.api.query.staking.erasStakers.entries(parseInt(currentEra))]);
|
|
79
|
+
const eraStakers = _eraStakers;
|
|
80
|
+
const nominatorList = [];
|
|
81
|
+
for (const item of eraStakers) {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
83
|
+
const rawValidatorStat = item[1].toHuman();
|
|
84
|
+
const eraNominators = rawValidatorStat.others;
|
|
85
|
+
for (const nominator of eraNominators) {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
|
|
87
|
+
if (!nominatorList.includes(nominator.who)) {
|
|
88
|
+
nominatorList.push(nominator.who);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
|
|
93
|
+
const minNominatorBond = _minNominatorBond.toString();
|
|
94
|
+
const bnMinActiveStake = new BN(minActiveStake);
|
|
95
|
+
const bnMinNominatorBond = new BN(minNominatorBond);
|
|
96
|
+
const minStake = bnMinActiveStake.gt(bnMinNominatorBond) ? bnMinActiveStake : bnMinNominatorBond;
|
|
19
97
|
const minPoolJoin = (_minPoolJoin === null || _minPoolJoin === void 0 ? void 0 : _minPoolJoin.toString()) || undefined;
|
|
20
98
|
const rawTotalEraStake = _totalEraStake.toString();
|
|
21
99
|
const rawTotalIssuance = _totalIssuance.toString();
|
|
@@ -33,23 +111,34 @@ export async function getRelayChainStakingMetadata(chain, substrateApi) {
|
|
|
33
111
|
expectedReturn,
|
|
34
112
|
// in %, annually
|
|
35
113
|
inflation,
|
|
36
|
-
minStake,
|
|
114
|
+
minStake: minStake.toString(),
|
|
115
|
+
minPoolBonding: (10 ** decimals).toString(),
|
|
116
|
+
// default is 1
|
|
37
117
|
maxValidatorPerNominator: parseInt(maxNominations),
|
|
38
118
|
maxWithdrawalRequestPerValidator: parseInt(maxUnlockingChunks),
|
|
39
119
|
allowCancelUnstaking: true,
|
|
40
120
|
unstakingPeriod: unlockingPeriod,
|
|
41
|
-
minJoinNominationPool: minPoolJoin
|
|
121
|
+
minJoinNominationPool: minPoolJoin,
|
|
122
|
+
nominatorCount: nominatorList.length
|
|
42
123
|
};
|
|
43
124
|
}
|
|
44
125
|
export async function getRelayChainNominatorMetadata(chainInfo, address, substrateApi) {
|
|
126
|
+
var _chainApi$api$query4, _chainApi$api$query4$, _chainApi$api$query5, _chainApi$api$query5$, _chainApi$api$query6, _chainApi$api$query6$, _chainApi$api$query7, _chainApi$api$query7$, _chainApi$api$query8, _chainApi$api$query8$, _chainApi$api$query9, _chainApi$api$query9$, _chainApi$api$query10, _chainApi$api$query11;
|
|
45
127
|
if (isEthereumAddress(address)) {
|
|
46
128
|
return;
|
|
47
129
|
}
|
|
48
130
|
const chain = chainInfo.slug;
|
|
49
131
|
const chainApi = await substrateApi.isReady;
|
|
50
|
-
const [_ledger, _nominations, _currentEra, _bonded] = await Promise.all([chainApi.api.query.staking
|
|
51
|
-
const
|
|
52
|
-
const
|
|
132
|
+
const [_ledger, _nominations, _currentEra, _bonded, _minimumActiveStake, _minNominatorBond] = await Promise.all([(_chainApi$api$query4 = chainApi.api.query) === null || _chainApi$api$query4 === void 0 ? void 0 : (_chainApi$api$query4$ = _chainApi$api$query4.staking) === null || _chainApi$api$query4$ === void 0 ? void 0 : _chainApi$api$query4$.ledger(address), (_chainApi$api$query5 = chainApi.api.query) === null || _chainApi$api$query5 === void 0 ? void 0 : (_chainApi$api$query5$ = _chainApi$api$query5.staking) === null || _chainApi$api$query5$ === void 0 ? void 0 : _chainApi$api$query5$.nominators(address), (_chainApi$api$query6 = chainApi.api.query) === null || _chainApi$api$query6 === void 0 ? void 0 : (_chainApi$api$query6$ = _chainApi$api$query6.staking) === null || _chainApi$api$query6$ === void 0 ? void 0 : _chainApi$api$query6$.currentEra(), (_chainApi$api$query7 = chainApi.api.query) === null || _chainApi$api$query7 === void 0 ? void 0 : (_chainApi$api$query7$ = _chainApi$api$query7.staking) === null || _chainApi$api$query7$ === void 0 ? void 0 : _chainApi$api$query7$.bonded(address), ((_chainApi$api$query8 = chainApi.api.query) === null || _chainApi$api$query8 === void 0 ? void 0 : (_chainApi$api$query8$ = _chainApi$api$query8.staking) === null || _chainApi$api$query8$ === void 0 ? void 0 : _chainApi$api$query8$.minimumActiveStake) && ((_chainApi$api$query9 = chainApi.api.query) === null || _chainApi$api$query9 === void 0 ? void 0 : (_chainApi$api$query9$ = _chainApi$api$query9.staking) === null || _chainApi$api$query9$ === void 0 ? void 0 : _chainApi$api$query9$.minimumActiveStake()), (_chainApi$api$query10 = chainApi.api.query) === null || _chainApi$api$query10 === void 0 ? void 0 : (_chainApi$api$query11 = _chainApi$api$query10.staking) === null || _chainApi$api$query11 === void 0 ? void 0 : _chainApi$api$query11.minNominatorBond()]);
|
|
133
|
+
const minActiveStake = (_minimumActiveStake === null || _minimumActiveStake === void 0 ? void 0 : _minimumActiveStake.toString()) || '0';
|
|
134
|
+
const minNominatorBond = _minNominatorBond.toString();
|
|
135
|
+
const bnMinActiveStake = new BN(minActiveStake);
|
|
136
|
+
const bnMinNominatorBond = new BN(minNominatorBond);
|
|
137
|
+
const minStake = bnMinActiveStake.gt(bnMinNominatorBond) ? bnMinActiveStake : bnMinNominatorBond;
|
|
138
|
+
const _maxNominatorRewardedPerValidator = chainApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
|
|
139
|
+
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
|
|
140
|
+
const ledger = _ledger.toPrimitive();
|
|
141
|
+
const nominations = _nominations.toPrimitive();
|
|
53
142
|
const currentEra = _currentEra.toString();
|
|
54
143
|
const bonded = _bonded.toHuman();
|
|
55
144
|
if (!ledger) {
|
|
@@ -61,17 +150,47 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
61
150
|
if (nominations) {
|
|
62
151
|
const validatorList = nominations.targets;
|
|
63
152
|
await Promise.all(validatorList.map(async validatorAddress => {
|
|
64
|
-
|
|
153
|
+
let nominationStatus = StakingStatus.NOT_EARNING;
|
|
154
|
+
const [_identityInfo, _eraStaker] = await Promise.all([chainApi.api.query.identity.identityOf(validatorAddress), chainApi.api.query.staking.erasStakers(currentEra, validatorAddress)]);
|
|
155
|
+
const eraStaker = _eraStaker.toPrimitive();
|
|
156
|
+
const identityInfo = _identityInfo.toHuman();
|
|
65
157
|
const identity = parseIdentity(identityInfo);
|
|
158
|
+
const topNominators = eraStaker.others.map(nominator => {
|
|
159
|
+
return nominator.who;
|
|
160
|
+
});
|
|
161
|
+
if (!topNominators.includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
162
|
+
// if nominator has target but not in nominator list
|
|
163
|
+
nominationStatus = StakingStatus.WAITING;
|
|
164
|
+
} else if (topNominators.slice(0, maxNominatorRewardedPerValidator).includes(reformatAddress(address, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
165
|
+
// if address in top nominators
|
|
166
|
+
nominationStatus = StakingStatus.EARNING_REWARD;
|
|
167
|
+
}
|
|
66
168
|
nominationList.push({
|
|
67
169
|
chain,
|
|
68
170
|
validatorAddress,
|
|
171
|
+
status: nominationStatus,
|
|
69
172
|
validatorIdentity: identity,
|
|
70
173
|
activeStake: '0' // relaychain allocates stake accordingly
|
|
71
174
|
});
|
|
72
175
|
}));
|
|
73
176
|
}
|
|
74
177
|
|
|
178
|
+
let stakingStatus = StakingStatus.NOT_EARNING;
|
|
179
|
+
const bnActiveStake = new BN(activeStake);
|
|
180
|
+
let waitingNominationCount = 0;
|
|
181
|
+
if (bnActiveStake.gte(minStake)) {
|
|
182
|
+
for (const nomination of nominationList) {
|
|
183
|
+
if (nomination.status === StakingStatus.EARNING_REWARD) {
|
|
184
|
+
// only need 1 earning nomination to count
|
|
185
|
+
stakingStatus = StakingStatus.EARNING_REWARD;
|
|
186
|
+
} else if (nomination.status === StakingStatus.WAITING) {
|
|
187
|
+
waitingNominationCount += 1;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (waitingNominationCount === nominationList.length) {
|
|
191
|
+
stakingStatus = StakingStatus.WAITING;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
75
194
|
ledger.unlocking.forEach(unlockingChunk => {
|
|
76
195
|
const isClaimable = unlockingChunk.era - parseInt(currentEra) <= 0;
|
|
77
196
|
const remainingEra = unlockingChunk.era - (parseInt(currentEra) + 1);
|
|
@@ -86,6 +205,7 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
86
205
|
return {
|
|
87
206
|
chain,
|
|
88
207
|
type: StakingType.NOMINATED,
|
|
208
|
+
status: stakingStatus,
|
|
89
209
|
address: address,
|
|
90
210
|
activeStake,
|
|
91
211
|
nominations: nominationList,
|
|
@@ -96,17 +216,39 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
96
216
|
export async function getRelayChainPoolMemberMetadata(chainInfo, address, substrateApi) {
|
|
97
217
|
const chainApi = await substrateApi.isReady;
|
|
98
218
|
const [_poolMemberInfo, _currentEra] = await Promise.all([chainApi.api.query.nominationPools.poolMembers(address), chainApi.api.query.staking.currentEra()]);
|
|
219
|
+
const _maxNominatorRewardedPerValidator = chainApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
|
|
220
|
+
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
|
|
221
|
+
const poolsPalletId = chainApi.api.consts.nominationPools.palletId.toString();
|
|
99
222
|
const poolMemberInfo = _poolMemberInfo.toPrimitive();
|
|
100
223
|
const currentEra = _currentEra.toString();
|
|
101
224
|
if (!poolMemberInfo) {
|
|
102
225
|
return;
|
|
103
226
|
}
|
|
227
|
+
let stakingStatus = StakingStatus.NOT_EARNING;
|
|
104
228
|
const _poolMetadata = await chainApi.api.query.nominationPools.metadata(poolMemberInfo.poolId);
|
|
105
229
|
const poolMetadata = _poolMetadata.toPrimitive();
|
|
106
230
|
const poolName = transformPoolName(poolMetadata.isUtf8 ? poolMetadata.toUtf8() : poolMetadata.toString());
|
|
231
|
+
const poolStashAccount = parsePoolStashAddress(chainApi.api, 0, poolMemberInfo.poolId, poolsPalletId);
|
|
232
|
+
const _nominations = await chainApi.api.query.staking.nominators(poolStashAccount);
|
|
233
|
+
const nominations = _nominations.toJSON();
|
|
234
|
+
if (nominations) {
|
|
235
|
+
const validatorList = nominations.targets;
|
|
236
|
+
await Promise.all(validatorList.map(async validatorAddress => {
|
|
237
|
+
const _eraStaker = await chainApi.api.query.staking.erasStakers(currentEra, validatorAddress);
|
|
238
|
+
const eraStaker = _eraStaker.toPrimitive();
|
|
239
|
+
const topNominators = eraStaker.others.map(nominator => {
|
|
240
|
+
return nominator.who;
|
|
241
|
+
}).slice(0, maxNominatorRewardedPerValidator);
|
|
242
|
+
if (topNominators.includes(reformatAddress(poolStashAccount, _getChainSubstrateAddressPrefix(chainInfo)))) {
|
|
243
|
+
// if address in top nominators
|
|
244
|
+
stakingStatus = StakingStatus.EARNING_REWARD;
|
|
245
|
+
}
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
107
248
|
const joinedPoolInfo = {
|
|
108
249
|
activeStake: poolMemberInfo.points.toString(),
|
|
109
250
|
chain: chainInfo.slug,
|
|
251
|
+
status: stakingStatus,
|
|
110
252
|
validatorIdentity: poolName,
|
|
111
253
|
validatorAddress: poolMemberInfo.poolId.toString(),
|
|
112
254
|
// use poolId
|
|
@@ -124,10 +266,15 @@ export async function getRelayChainPoolMemberMetadata(chainInfo, address, substr
|
|
|
124
266
|
waitingTime: waitingTime > 0 ? waitingTime : 0
|
|
125
267
|
});
|
|
126
268
|
});
|
|
269
|
+
const bnActiveStake = new BN(poolMemberInfo.points.toString());
|
|
270
|
+
if (!bnActiveStake.gt(BN_ZERO)) {
|
|
271
|
+
stakingStatus = StakingStatus.NOT_EARNING;
|
|
272
|
+
}
|
|
127
273
|
return {
|
|
128
274
|
chain: chainInfo.slug,
|
|
129
275
|
type: StakingType.POOLED,
|
|
130
276
|
address,
|
|
277
|
+
status: stakingStatus,
|
|
131
278
|
activeStake: poolMemberInfo.points.toString(),
|
|
132
279
|
nominations: [joinedPoolInfo],
|
|
133
280
|
// can only join 1 pool at a time
|
|
@@ -183,9 +330,9 @@ export async function getRelayValidatorsInfo(chain, substrateApi, decimals, chai
|
|
|
183
330
|
}
|
|
184
331
|
const extraInfoMap = {};
|
|
185
332
|
await Promise.all(allValidators.map(async address => {
|
|
186
|
-
var _chainApi$api$
|
|
333
|
+
var _chainApi$api$query12, _chainApi$api$query13, _identityInfo$judgeme;
|
|
187
334
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
188
|
-
const [_commissionInfo, _identityInfo] = await Promise.all([chainApi.api.query.staking.validators(address), (_chainApi$api$
|
|
335
|
+
const [_commissionInfo, _identityInfo] = await Promise.all([chainApi.api.query.staking.validators(address), (_chainApi$api$query12 = chainApi.api.query) === null || _chainApi$api$query12 === void 0 ? void 0 : (_chainApi$api$query13 = _chainApi$api$query12.identity) === null || _chainApi$api$query13 === void 0 ? void 0 : _chainApi$api$query13.identityOf(address)]);
|
|
189
336
|
const commissionInfo = _commissionInfo.toHuman();
|
|
190
337
|
const identityInfo = _identityInfo ? _identityInfo.toHuman() : null;
|
|
191
338
|
let identity;
|
|
@@ -236,22 +383,30 @@ export async function getRelayPoolsInfo(chain, substrateApi) {
|
|
|
236
383
|
}));
|
|
237
384
|
return nominationPools;
|
|
238
385
|
}
|
|
239
|
-
export async function getRelayBondingExtrinsic(substrateApi, amount, targetValidators,
|
|
386
|
+
export async function getRelayBondingExtrinsic(substrateApi, amount, targetValidators, chainInfo, address, nominatorMetadata, bondDest = 'Staked') {
|
|
240
387
|
const chainApi = await substrateApi.isReady;
|
|
241
388
|
const binaryAmount = new BN(amount);
|
|
242
389
|
let bondTx;
|
|
243
390
|
let nominateTx;
|
|
391
|
+
const validatorParamList = targetValidators.map(validator => {
|
|
392
|
+
return validator.address;
|
|
393
|
+
});
|
|
394
|
+
if (!nominatorMetadata) {
|
|
395
|
+
bondTx = chainApi.api.tx.staking.bond(address, binaryAmount, bondDest);
|
|
396
|
+
nominateTx = chainApi.api.tx.staking.nominate(validatorParamList);
|
|
397
|
+
return chainApi.api.tx.utility.batchAll([bondTx, nominateTx]);
|
|
398
|
+
}
|
|
244
399
|
if (!nominatorMetadata.isBondedBefore) {
|
|
245
400
|
// first time
|
|
246
401
|
bondTx = chainApi.api.tx.staking.bond(nominatorMetadata.address, binaryAmount, bondDest);
|
|
247
|
-
nominateTx = chainApi.api.tx.staking.nominate(
|
|
402
|
+
nominateTx = chainApi.api.tx.staking.nominate(validatorParamList);
|
|
248
403
|
return chainApi.api.tx.utility.batchAll([bondTx, nominateTx]);
|
|
249
404
|
} else {
|
|
250
405
|
if (binaryAmount.gt(BN_ZERO)) {
|
|
251
406
|
bondTx = chainApi.api.tx.staking.bondExtra(binaryAmount);
|
|
252
407
|
}
|
|
253
408
|
if (nominatorMetadata.isBondedBefore && targetValidators.length > 0) {
|
|
254
|
-
nominateTx = chainApi.api.tx.staking.nominate(
|
|
409
|
+
nominateTx = chainApi.api.tx.staking.nominate(validatorParamList);
|
|
255
410
|
}
|
|
256
411
|
}
|
|
257
412
|
if (bondTx && !nominateTx) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { NominationInfo, NominatorMetadata, StakingType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
import { NominationInfo, NominatorMetadata, StakingStatus, StakingType, UnstakingInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
3
|
import { _SubstrateInflationParams } from '@subwallet/extension-base/services/chain-service/constants';
|
|
4
|
+
import { ApiPromise } from '@polkadot/api';
|
|
4
5
|
import { BN } from '@polkadot/util';
|
|
5
6
|
export interface PalletNominationPoolsPoolMember {
|
|
6
7
|
poolId: number;
|
|
@@ -64,6 +65,15 @@ export interface PalletParachainStakingDelegator {
|
|
|
64
65
|
lessTotal: number;
|
|
65
66
|
status: number;
|
|
66
67
|
}
|
|
68
|
+
export interface PalletStakingExposureItem {
|
|
69
|
+
who: string;
|
|
70
|
+
value: number;
|
|
71
|
+
}
|
|
72
|
+
export interface PalletStakingExposure {
|
|
73
|
+
total: number;
|
|
74
|
+
own: number;
|
|
75
|
+
others: PalletStakingExposureItem[];
|
|
76
|
+
}
|
|
67
77
|
export interface PalletIdentityRegistration {
|
|
68
78
|
judgements: any[];
|
|
69
79
|
deposit: number;
|
|
@@ -92,6 +102,7 @@ export interface Unlocking {
|
|
|
92
102
|
remainingEras: BN;
|
|
93
103
|
value: BN;
|
|
94
104
|
}
|
|
105
|
+
export declare function parsePoolStashAddress(api: ApiPromise, index: number, poolId: number, poolsPalletId: string): string;
|
|
95
106
|
export declare function transformPoolName(input: string): string;
|
|
96
107
|
export declare function parseIdentity(identityInfo: PalletIdentityRegistration | null): string | undefined;
|
|
97
108
|
export declare function getInflationParams(networkKey: string): _SubstrateInflationParams;
|
|
@@ -137,6 +148,8 @@ export declare enum StakingAction {
|
|
|
137
148
|
CLAIM_REWARD = "CLAIM_REWARD",
|
|
138
149
|
CANCEL_UNSTAKE = "CANCEL_UNSTAKE"
|
|
139
150
|
}
|
|
140
|
-
export declare function
|
|
151
|
+
export declare function getStakingAvailableActionsByChain(chain: string, type: StakingType): StakingAction[];
|
|
152
|
+
export declare function getStakingAvailableActionsByNominator(nominatorMetadata: NominatorMetadata, unclaimedReward?: string): StakingAction[];
|
|
141
153
|
export declare function isActionFromValidator(stakingType: StakingType, chain: string): boolean;
|
|
142
154
|
export declare function getWithdrawalInfo(nominatorMetadata: NominatorMetadata): UnstakingInfo | undefined;
|
|
155
|
+
export declare function getStakingStatusByNominations(bnTotalActiveStake: BN, nominationList: NominationInfo[]): StakingStatus;
|