@subwallet/extension-base 1.0.2-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 +16 -34
- package/background/KoniTypes.js +6 -7
- package/background/errors/TransactionError.js +21 -1
- package/cjs/background/KoniTypes.js +6 -7
- package/cjs/background/errors/TransactionError.js +20 -0
- package/cjs/constants/index.js +8 -26
- package/cjs/koni/api/dotsama/balance.js +49 -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 +13 -9
- package/cjs/koni/api/staking/bonding/astar.js +15 -13
- package/cjs/koni/api/staking/bonding/index.js +22 -10
- package/cjs/koni/api/staking/bonding/paraChain.js +85 -2
- package/cjs/koni/api/staking/bonding/relayChain.js +119 -16
- package/cjs/koni/api/staking/bonding/utils.js +27 -8
- 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/polkadotXcm.js +1 -1
- package/cjs/koni/api/xcm/utils.js +18 -13
- package/cjs/koni/api/xcm/xTokens.js +1 -1
- package/cjs/koni/api/xcm/xcmPallet.js +9 -6
- package/cjs/koni/background/cron.js +150 -47
- package/cjs/koni/background/handlers/Extension.js +106 -64
- package/cjs/koni/background/handlers/State.js +19 -21
- package/cjs/koni/background/handlers/Tabs.js +8 -1
- package/cjs/koni/background/subscription.js +32 -29
- 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 +6 -7
- package/cjs/services/event-service/index.js +5 -1
- package/cjs/services/event-service/types.js +11 -1
- package/cjs/services/history-service/index.js +16 -10
- package/cjs/services/history-service/subsquid-multi-chain-history.js +12 -9
- package/cjs/services/price-service/coingecko.js +0 -1
- package/cjs/services/price-service/index.js +2 -3
- package/cjs/services/request-service/handler/AuthRequestHandler.js +6 -2
- package/cjs/services/storage-service/DatabaseService.js +52 -33
- package/cjs/services/storage-service/db-stores/Nft.js +4 -17
- package/cjs/services/transaction-service/event-parser/index.js +20 -48
- package/cjs/services/transaction-service/index.js +23 -14
- package/cjs/utils/index.js +7 -14
- package/constants/index.d.ts +7 -13
- package/constants/index.js +7 -13
- package/koni/api/dotsama/balance.d.ts +0 -1
- package/koni/api/dotsama/balance.js +22 -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 +0 -1
- package/koni/api/staking/bonding/amplitude.js +15 -10
- package/koni/api/staking/bonding/astar.js +8 -6
- package/koni/api/staking/bonding/index.d.ts +4 -1
- package/koni/api/staking/bonding/index.js +23 -13
- package/koni/api/staking/bonding/paraChain.d.ts +3 -0
- package/koni/api/staking/bonding/paraChain.js +86 -5
- package/koni/api/staking/bonding/relayChain.d.ts +5 -1
- package/koni/api/staking/bonding/relayChain.js +118 -18
- package/koni/api/staking/bonding/utils.d.ts +3 -2
- package/koni/api/staking/bonding/utils.js +27 -9
- 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/polkadotXcm.js +2 -2
- package/koni/api/xcm/utils.d.ts +5 -6
- package/koni/api/xcm/utils.js +15 -10
- package/koni/api/xcm/xTokens.js +2 -2
- package/koni/api/xcm/xcmPallet.js +10 -9
- package/koni/background/cron.d.ts +6 -1
- package/koni/background/cron.js +151 -48
- package/koni/background/handlers/Extension.d.ts +2 -2
- package/koni/background/handlers/Extension.js +108 -67
- package/koni/background/handlers/State.d.ts +5 -6
- package/koni/background/handlers/State.js +19 -21
- package/koni/background/handlers/Tabs.js +8 -1
- package/koni/background/subscription.js +31 -30
- package/package.json +9 -4
- 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.js +6 -7
- package/services/event-service/index.js +5 -1
- package/services/event-service/types.d.ts +5 -9
- package/services/event-service/types.js +4 -1
- package/services/history-service/index.d.ts +1 -1
- package/services/history-service/index.js +16 -10
- package/services/history-service/subsquid-multi-chain-history.js +15 -11
- package/services/price-service/coingecko.js +0 -1
- package/services/price-service/index.js +2 -3
- package/services/request-service/handler/AuthRequestHandler.js +6 -2
- package/services/storage-service/DatabaseService.d.ts +1 -0
- package/services/storage-service/DatabaseService.js +52 -33
- package/services/storage-service/db-stores/Nft.d.ts +1 -2
- package/services/storage-service/db-stores/Nft.js +4 -16
- package/services/transaction-service/event-parser/index.js +21 -49
- package/services/transaction-service/index.js +23 -14
- package/utils/index.d.ts +1 -1
- package/utils/index.js +6 -12
|
@@ -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,10 +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,
|
|
100
|
-
status:
|
|
179
|
+
status: delegationStatus,
|
|
101
180
|
validatorAddress: delegation.owner,
|
|
102
181
|
validatorIdentity: identity,
|
|
103
182
|
activeStake: bnActiveStake.toString(),
|
|
@@ -109,9 +188,11 @@ export async function getParaChainNominatorMetadata(chainInfo, address, substrat
|
|
|
109
188
|
const collatorInfo = _collatorInfo.toPrimitive();
|
|
110
189
|
nomination.validatorMinStake = collatorInfo.lowestTopDelegationAmount.toString();
|
|
111
190
|
}));
|
|
191
|
+
const stakingStatus = getStakingStatusByNominations(bnTotalActiveStake, nominationList);
|
|
112
192
|
return {
|
|
113
193
|
chain,
|
|
114
194
|
type: StakingType.NOMINATED,
|
|
195
|
+
status: stakingStatus,
|
|
115
196
|
address: address,
|
|
116
197
|
activeStake: bnTotalActiveStake.toString(),
|
|
117
198
|
nominations: nominationList,
|
|
@@ -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,7 +18,10 @@ 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[]>;
|
|
@@ -1,23 +1,99 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { StakingStatus, StakingTxErrorType, StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
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';
|
|
7
|
-
import { _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { _getChainNativeTokenBasicInfo, _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
9
|
import { reformatAddress } from '@subwallet/extension-base/utils';
|
|
9
10
|
import { BN, BN_ZERO } from '@polkadot/util';
|
|
10
11
|
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
11
|
-
export
|
|
12
|
-
|
|
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);
|
|
13
72
|
const chainApi = await substrateApi.isReady;
|
|
14
73
|
const _era = await chainApi.api.query.staking.currentEra();
|
|
15
74
|
const currentEra = _era.toString();
|
|
16
75
|
const maxNominations = chainApi.api.consts.staking.maxNominations.toString();
|
|
17
76
|
const maxUnlockingChunks = chainApi.api.consts.staking.maxUnlockingChunks.toString();
|
|
18
77
|
const unlockingEras = chainApi.api.consts.staking.bondingDuration.toString();
|
|
19
|
-
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()
|
|
20
|
-
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;
|
|
21
97
|
const minPoolJoin = (_minPoolJoin === null || _minPoolJoin === void 0 ? void 0 : _minPoolJoin.toString()) || undefined;
|
|
22
98
|
const rawTotalEraStake = _totalEraStake.toString();
|
|
23
99
|
const rawTotalIssuance = _totalIssuance.toString();
|
|
@@ -35,21 +111,30 @@ export async function getRelayChainStakingMetadata(chain, substrateApi) {
|
|
|
35
111
|
expectedReturn,
|
|
36
112
|
// in %, annually
|
|
37
113
|
inflation,
|
|
38
|
-
minStake,
|
|
114
|
+
minStake: minStake.toString(),
|
|
115
|
+
minPoolBonding: (10 ** decimals).toString(),
|
|
116
|
+
// default is 1
|
|
39
117
|
maxValidatorPerNominator: parseInt(maxNominations),
|
|
40
118
|
maxWithdrawalRequestPerValidator: parseInt(maxUnlockingChunks),
|
|
41
119
|
allowCancelUnstaking: true,
|
|
42
120
|
unstakingPeriod: unlockingPeriod,
|
|
43
|
-
minJoinNominationPool: minPoolJoin
|
|
121
|
+
minJoinNominationPool: minPoolJoin,
|
|
122
|
+
nominatorCount: nominatorList.length
|
|
44
123
|
};
|
|
45
124
|
}
|
|
46
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;
|
|
47
127
|
if (isEthereumAddress(address)) {
|
|
48
128
|
return;
|
|
49
129
|
}
|
|
50
130
|
const chain = chainInfo.slug;
|
|
51
131
|
const chainApi = await substrateApi.isReady;
|
|
52
|
-
const [_ledger, _nominations, _currentEra, _bonded] = await Promise.all([chainApi.api.query.staking
|
|
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;
|
|
53
138
|
const _maxNominatorRewardedPerValidator = chainApi.api.consts.staking.maxNominatorRewardedPerValidator.toString();
|
|
54
139
|
const maxNominatorRewardedPerValidator = parseInt(_maxNominatorRewardedPerValidator);
|
|
55
140
|
const ledger = _ledger.toPrimitive();
|
|
@@ -59,7 +144,6 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
59
144
|
if (!ledger) {
|
|
60
145
|
return;
|
|
61
146
|
}
|
|
62
|
-
let stakingStatus = StakingStatus.NOT_EARNING;
|
|
63
147
|
const activeStake = ledger.active.toString();
|
|
64
148
|
const nominationList = [];
|
|
65
149
|
const unstakingList = [];
|
|
@@ -74,7 +158,10 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
74
158
|
const topNominators = eraStaker.others.map(nominator => {
|
|
75
159
|
return nominator.who;
|
|
76
160
|
});
|
|
77
|
-
if (topNominators.
|
|
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)))) {
|
|
78
165
|
// if address in top nominators
|
|
79
166
|
nominationStatus = StakingStatus.EARNING_REWARD;
|
|
80
167
|
}
|
|
@@ -88,11 +175,20 @@ export async function getRelayChainNominatorMetadata(chainInfo, address, substra
|
|
|
88
175
|
}));
|
|
89
176
|
}
|
|
90
177
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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;
|
|
96
192
|
}
|
|
97
193
|
}
|
|
98
194
|
ledger.unlocking.forEach(unlockingChunk => {
|
|
@@ -170,6 +266,10 @@ export async function getRelayChainPoolMemberMetadata(chainInfo, address, substr
|
|
|
170
266
|
waitingTime: waitingTime > 0 ? waitingTime : 0
|
|
171
267
|
});
|
|
172
268
|
});
|
|
269
|
+
const bnActiveStake = new BN(poolMemberInfo.points.toString());
|
|
270
|
+
if (!bnActiveStake.gt(BN_ZERO)) {
|
|
271
|
+
stakingStatus = StakingStatus.NOT_EARNING;
|
|
272
|
+
}
|
|
173
273
|
return {
|
|
174
274
|
chain: chainInfo.slug,
|
|
175
275
|
type: StakingType.POOLED,
|
|
@@ -230,9 +330,9 @@ export async function getRelayValidatorsInfo(chain, substrateApi, decimals, chai
|
|
|
230
330
|
}
|
|
231
331
|
const extraInfoMap = {};
|
|
232
332
|
await Promise.all(allValidators.map(async address => {
|
|
233
|
-
var _chainApi$api$
|
|
333
|
+
var _chainApi$api$query12, _chainApi$api$query13, _identityInfo$judgeme;
|
|
234
334
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
235
|
-
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)]);
|
|
236
336
|
const commissionInfo = _commissionInfo.toHuman();
|
|
237
337
|
const identityInfo = _identityInfo ? _identityInfo.toHuman() : null;
|
|
238
338
|
let identity;
|
|
@@ -1,5 +1,5 @@
|
|
|
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
4
|
import { ApiPromise } from '@polkadot/api';
|
|
5
5
|
import { BN } from '@polkadot/util';
|
|
@@ -149,6 +149,7 @@ export declare enum StakingAction {
|
|
|
149
149
|
CANCEL_UNSTAKE = "CANCEL_UNSTAKE"
|
|
150
150
|
}
|
|
151
151
|
export declare function getStakingAvailableActionsByChain(chain: string, type: StakingType): StakingAction[];
|
|
152
|
-
export declare function getStakingAvailableActionsByNominator(nominatorMetadata: NominatorMetadata): StakingAction[];
|
|
152
|
+
export declare function getStakingAvailableActionsByNominator(nominatorMetadata: NominatorMetadata, unclaimedReward?: string): StakingAction[];
|
|
153
153
|
export declare function isActionFromValidator(stakingType: StakingType, chain: string): boolean;
|
|
154
154
|
export declare function getWithdrawalInfo(nominatorMetadata: NominatorMetadata): UnstakingInfo | undefined;
|
|
155
|
+
export declare function getStakingStatusByNominations(bnTotalActiveStake: BN, nominationList: NominationInfo[]): StakingStatus;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-koni authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import { StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
|
+
import { StakingStatus, StakingType, UnstakingStatus } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
5
|
import { _KNOWN_CHAIN_INFLATION_PARAMS, _STAKING_CHAIN_GROUP, _SUBSTRATE_DEFAULT_INFLATION_PARAMS } from '@subwallet/extension-base/services/chain-service/constants';
|
|
6
6
|
import { parseRawNumber, reformatAddress } from '@subwallet/extension-base/utils';
|
|
7
7
|
import { BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_THOUSAND, BN_ZERO, bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
|
@@ -125,11 +125,8 @@ export function getBondedValidators(nominations) {
|
|
|
125
125
|
const bondedValidators = [];
|
|
126
126
|
let nominationCount = 0;
|
|
127
127
|
for (const nomination of nominations) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
nominationCount += 1;
|
|
131
|
-
bondedValidators.push(reformatAddress(nomination.validatorAddress, 0));
|
|
132
|
-
}
|
|
128
|
+
nominationCount += 1;
|
|
129
|
+
bondedValidators.push(reformatAddress(nomination.validatorAddress, 0));
|
|
133
130
|
}
|
|
134
131
|
return {
|
|
135
132
|
nominationCount,
|
|
@@ -171,13 +168,15 @@ export function getStakingAvailableActionsByChain(chain, type) {
|
|
|
171
168
|
}
|
|
172
169
|
return [StakingAction.STAKE, StakingAction.UNSTAKE, StakingAction.WITHDRAW, StakingAction.CANCEL_UNSTAKE];
|
|
173
170
|
}
|
|
174
|
-
export function getStakingAvailableActionsByNominator(nominatorMetadata) {
|
|
171
|
+
export function getStakingAvailableActionsByNominator(nominatorMetadata, unclaimedReward) {
|
|
175
172
|
const result = [StakingAction.STAKE];
|
|
176
173
|
const bnActiveStake = new BN(nominatorMetadata.activeStake);
|
|
177
174
|
if (nominatorMetadata.activeStake && bnActiveStake.gt(BN_ZERO)) {
|
|
178
175
|
result.push(StakingAction.UNSTAKE);
|
|
179
|
-
const
|
|
180
|
-
|
|
176
|
+
const isAstarNetwork = _STAKING_CHAIN_GROUP.astar.includes(nominatorMetadata.chain);
|
|
177
|
+
const isAmplitudeNetwork = _STAKING_CHAIN_GROUP.amplitude.includes(nominatorMetadata.chain);
|
|
178
|
+
const bnUnclaimedReward = new BN(unclaimedReward || '0');
|
|
179
|
+
if ((nominatorMetadata.type === StakingType.POOLED || isAmplitudeNetwork) && bnUnclaimedReward.gt(BN_ZERO) || isAstarNetwork) {
|
|
181
180
|
result.push(StakingAction.CLAIM_REWARD);
|
|
182
181
|
}
|
|
183
182
|
}
|
|
@@ -219,4 +218,23 @@ export function getWithdrawalInfo(nominatorMetadata) {
|
|
|
219
218
|
}
|
|
220
219
|
}
|
|
221
220
|
return result;
|
|
221
|
+
}
|
|
222
|
+
export function getStakingStatusByNominations(bnTotalActiveStake, nominationList) {
|
|
223
|
+
let stakingStatus = StakingStatus.EARNING_REWARD;
|
|
224
|
+
if (bnTotalActiveStake.isZero()) {
|
|
225
|
+
stakingStatus = StakingStatus.NOT_EARNING;
|
|
226
|
+
} else {
|
|
227
|
+
let invalidDelegationCount = 0;
|
|
228
|
+
for (const nomination of nominationList) {
|
|
229
|
+
if (nomination.status === StakingStatus.NOT_EARNING) {
|
|
230
|
+
invalidDelegationCount += 1;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (invalidDelegationCount > 0 && invalidDelegationCount < nominationList.length) {
|
|
234
|
+
stakingStatus = StakingStatus.PARTIALLY_EARNING;
|
|
235
|
+
} else if (invalidDelegationCount === nominationList.length) {
|
|
236
|
+
stakingStatus = StakingStatus.NOT_EARNING;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return stakingStatus;
|
|
222
240
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { getWasmContractGasLimit } from '@subwallet/extension-base/koni/api/tokens/wasm/utils';
|
|
4
5
|
import { _PSP22_ABI, _PSP34_ABI } from '@subwallet/extension-base/services/chain-service/helper';
|
|
5
6
|
import { ContractPromise } from '@polkadot/api-contract';
|
|
6
7
|
export function getPSP22ContractPromise(apiPromise, contractAddress) {
|
|
@@ -14,10 +15,10 @@ export async function getPSP34TransferExtrinsic(networkKey, substrateApi, sender
|
|
|
14
15
|
const onChainOption = params.onChainOption;
|
|
15
16
|
try {
|
|
16
17
|
const contractPromise = getPSP34ContractPromise(substrateApi.api, contractAddress);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
const gasLimit = await getWasmContractGasLimit(substrateApi.api, senderAddress, 'psp34::transfer', contractPromise, {}, [recipientAddress, onChainOption, {}]);
|
|
20
|
+
|
|
21
|
+
// @ts-ignore
|
|
21
22
|
return contractPromise.tx['psp34::transfer']({
|
|
22
23
|
gasLimit
|
|
23
24
|
}, recipientAddress, onChainOption, {});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ApiPromise } from '@polkadot/api';
|
|
2
|
+
import { ContractPromise } from '@polkadot/api-contract';
|
|
3
|
+
import { WeightV2 } from '@polkadot/types/interfaces';
|
|
4
|
+
import { Codec } from '@polkadot/types/types';
|
|
5
|
+
export declare function getWasmContractGasLimit(api: ApiPromise, callerAddress: string, message: string, contract: ContractPromise, options?: {}, args?: never[]): Promise<Codec>;
|
|
6
|
+
export declare function getDefaultWeightV2(apiPromise: ApiPromise, isFallback?: boolean): WeightV2;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { BN } from '@polkadot/util';
|
|
5
|
+
const MAX_CALL_WEIGHT = '5000000000000';
|
|
6
|
+
const DEFAULT_REF_TIME = '1000000000000';
|
|
7
|
+
const toContractAbiMessage = (contractPromise, message) => {
|
|
8
|
+
const value = contractPromise.abi.messages.find(m => m.method === message);
|
|
9
|
+
if (!value) {
|
|
10
|
+
const messages = contractPromise === null || contractPromise === void 0 ? void 0 : contractPromise.abi.messages.map(m => m.method).join(', ');
|
|
11
|
+
const error = `"${message}" not found in metadata.spec.messages: [${messages}]`;
|
|
12
|
+
console.error(error);
|
|
13
|
+
return {
|
|
14
|
+
ok: false,
|
|
15
|
+
error
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
ok: true,
|
|
20
|
+
value
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export async function getWasmContractGasLimit(api, callerAddress, message, contract, options = {}, args = []) {
|
|
24
|
+
try {
|
|
25
|
+
var _abiMessage$value;
|
|
26
|
+
const abiMessage = toContractAbiMessage(contract, message);
|
|
27
|
+
if (!abiMessage.ok) {
|
|
28
|
+
return getDefaultWeightV2(api, true);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
const {
|
|
33
|
+
gasLimit,
|
|
34
|
+
storageDepositLimit,
|
|
35
|
+
value
|
|
36
|
+
} = options;
|
|
37
|
+
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
const {
|
|
40
|
+
gasRequired
|
|
41
|
+
} = await api.call.contractsApi.call(callerAddress, contract.address, value !== null && value !== void 0 ? value : new BN(0), gasLimit !== null && gasLimit !== void 0 ? gasLimit : null, storageDepositLimit !== null && storageDepositLimit !== void 0 ? storageDepositLimit : null, abiMessage === null || abiMessage === void 0 ? void 0 : (_abiMessage$value = abiMessage.value) === null || _abiMessage$value === void 0 ? void 0 : _abiMessage$value.toU8a(args));
|
|
42
|
+
return gasRequired;
|
|
43
|
+
} catch {
|
|
44
|
+
return getDefaultWeightV2(api, true);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function getDefaultWeightV2(apiPromise, isFallback) {
|
|
48
|
+
const proofSize = isFallback ? 3407872 : MAX_CALL_WEIGHT; // TODO: handle error better
|
|
49
|
+
const refTime = isFallback ? 32490000000 : DEFAULT_REF_TIME;
|
|
50
|
+
return apiPromise.registry.createType('WeightV2', {
|
|
51
|
+
refTime,
|
|
52
|
+
proofSize
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { getBeneficiary, getDestWeight } from '@subwallet/extension-base/koni/api/xcm/utils';
|
|
5
5
|
import { _getSubstrateParaId, _getXcmAssetMultilocation, _isSubstrateParaChain, _isSubstrateRelayChain } from '@subwallet/extension-base/services/chain-service/utils';
|
|
6
6
|
function getDestinationChainLocation(destinationChainInfo) {
|
|
7
7
|
if (_isSubstrateParaChain(destinationChainInfo)) {
|
|
@@ -36,7 +36,7 @@ function getAssetLocation(tokenInfo, sendingValue) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
export function getExtrinsicByPolkadotXcmPallet(tokenInfo, originChainInfo, destinationChainInfo, recipientAddress, value, api) {
|
|
39
|
-
const weightParam =
|
|
39
|
+
const weightParam = getDestWeight();
|
|
40
40
|
const beneficiary = getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress);
|
|
41
41
|
const destination = getDestinationChainLocation(destinationChainInfo);
|
|
42
42
|
const assetLocation = getAssetLocation(tokenInfo, value);
|
package/koni/api/xcm/utils.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
-
export declare const FOUR_INSTRUCTIONS_WEIGHT
|
|
2
|
+
export declare const FOUR_INSTRUCTIONS_WEIGHT = 5000000000;
|
|
3
|
+
export declare const FOUR_INSTRUCTIONS_LIMITED_WEIGHT: {
|
|
3
4
|
Limited: number;
|
|
4
5
|
};
|
|
5
|
-
export declare const POLKADOT_LIMITED_WEIGHT = 1000000000;
|
|
6
|
-
export declare const POLKADOT_UNLIMITED_WEIGHT = "Unlimited";
|
|
7
6
|
export declare function getReceiverLocation(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, toAddress: string): Record<string, any>;
|
|
8
|
-
export declare function getBeneficiary(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, recipientAddress: string): {
|
|
9
|
-
|
|
7
|
+
export declare function getBeneficiary(originChainInfo: _ChainInfo, destinationChainInfo: _ChainInfo, recipientAddress: string, version?: string): {
|
|
8
|
+
[x: string]: {
|
|
10
9
|
parents: number;
|
|
11
10
|
interior: {
|
|
12
11
|
X1: Record<string, any>;
|
|
13
12
|
};
|
|
14
13
|
};
|
|
15
14
|
};
|
|
16
|
-
export declare
|
|
15
|
+
export declare function getDestWeight(): string;
|
package/koni/api/xcm/utils.js
CHANGED
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
|
|
5
|
-
import {
|
|
5
|
+
import { _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
6
6
|
import { decodeAddress, evmToAddress } from '@polkadot/util-crypto';
|
|
7
|
-
export const FOUR_INSTRUCTIONS_WEIGHT =
|
|
7
|
+
export const FOUR_INSTRUCTIONS_WEIGHT = 5000000000;
|
|
8
|
+
export const FOUR_INSTRUCTIONS_LIMITED_WEIGHT = {
|
|
8
9
|
Limited: 5000000000
|
|
9
10
|
};
|
|
10
|
-
export const POLKADOT_LIMITED_WEIGHT = 1000000000;
|
|
11
|
-
export const POLKADOT_UNLIMITED_WEIGHT = 'Unlimited';
|
|
12
11
|
|
|
13
12
|
// get multilocation for destination chain from a parachain
|
|
14
13
|
|
|
15
14
|
export function getReceiverLocation(originChainInfo, destinationChainInfo, toAddress) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if (destinationChainInfo.slug === COMMON_CHAIN_SLUGS.ASTAR_EVM) {
|
|
16
|
+
const ss58Address = evmToAddress(toAddress, 2006); // TODO: shouldn't pass addressPrefix directly
|
|
17
|
+
|
|
19
18
|
return {
|
|
20
19
|
AccountId32: {
|
|
21
20
|
network: 'Any',
|
|
@@ -38,10 +37,10 @@ export function getReceiverLocation(originChainInfo, destinationChainInfo, toAdd
|
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
39
|
}
|
|
41
|
-
export function getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress) {
|
|
40
|
+
export function getBeneficiary(originChainInfo, destinationChainInfo, recipientAddress, version = 'V1') {
|
|
42
41
|
const receiverLocation = getReceiverLocation(originChainInfo, destinationChainInfo, recipientAddress);
|
|
43
42
|
return {
|
|
44
|
-
|
|
43
|
+
[version]: {
|
|
45
44
|
parents: 0,
|
|
46
45
|
interior: {
|
|
47
46
|
X1: receiverLocation
|
|
@@ -49,4 +48,10 @@ export function getBeneficiary(originChainInfo, destinationChainInfo, recipientA
|
|
|
49
48
|
}
|
|
50
49
|
};
|
|
51
50
|
}
|
|
52
|
-
export
|
|
51
|
+
export function getDestWeight() {
|
|
52
|
+
return 'Unlimited';
|
|
53
|
+
// return api.tx.xTokens.transfer.meta.args[3].type.toString() ===
|
|
54
|
+
// 'XcmV2WeightLimit'
|
|
55
|
+
// ? 'Unlimited'
|
|
56
|
+
// : FOUR_INSTRUCTIONS_WEIGHT;
|
|
57
|
+
}
|