@subwallet/extension-base 1.2.2-0 → 1.2.3-1
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 +4 -0
- package/cjs/core/logic-validation/earning.js +47 -0
- package/cjs/core/logic-validation/swap.js +99 -0
- package/cjs/core/logic-validation/transfer.js +219 -0
- package/cjs/core/substrate/nominationpools-pallet.js +12 -0
- package/cjs/core/substrate/system-pallet.js +78 -0
- package/cjs/koni/api/dotsama/transfer.js +49 -4
- package/cjs/koni/api/staking/bonding/utils.js +1 -1
- package/cjs/koni/api/xcm/index.js +30 -2
- package/cjs/koni/background/handlers/Extension.js +135 -245
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/group.js +4 -27
- package/cjs/services/balance-service/helpers/subscribe/index.js +2 -30
- package/cjs/services/balance-service/helpers/subscribe/substrate/index.js +41 -80
- package/cjs/services/balance-service/index.js +11 -9
- package/cjs/services/chain-service/index.js +0 -1
- package/cjs/services/chain-service/utils/index.js +6 -0
- package/cjs/services/earning-service/handlers/base.js +1 -1
- package/cjs/services/earning-service/handlers/special.js +11 -12
- package/cjs/services/swap-service/handler/base-handler.js +28 -44
- package/cjs/services/swap-service/handler/chainflip-handler.js +23 -21
- package/cjs/services/swap-service/handler/hydradx-handler.js +40 -38
- package/cjs/services/swap-service/index.js +6 -0
- package/cjs/services/swap-service/utils.js +8 -49
- package/cjs/services/transaction-service/index.js +66 -155
- package/core/logic-validation/earning.d.ts +10 -0
- package/core/logic-validation/earning.js +37 -0
- package/core/logic-validation/swap.d.ts +8 -0
- package/core/logic-validation/swap.js +89 -0
- package/core/logic-validation/transfer.d.ts +16 -0
- package/core/logic-validation/transfer.js +206 -0
- package/core/substrate/nominationpools-pallet.d.ts +7 -0
- package/core/substrate/nominationpools-pallet.js +6 -0
- package/core/substrate/system-pallet.d.ts +27 -0
- package/core/substrate/system-pallet.js +71 -0
- package/koni/api/dotsama/transfer.d.ts +3 -1
- package/koni/api/dotsama/transfer.js +44 -1
- package/koni/api/staking/bonding/relayChain.d.ts +2 -1
- package/koni/api/staking/bonding/utils.js +1 -1
- package/koni/api/xcm/index.d.ts +2 -0
- package/koni/api/xcm/index.js +27 -1
- package/koni/background/handlers/Extension.d.ts +5 -5
- package/koni/background/handlers/Extension.js +111 -221
- package/package.json +34 -9
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/group.js +4 -27
- package/services/balance-service/helpers/subscribe/index.d.ts +2 -1
- package/services/balance-service/helpers/subscribe/index.js +2 -30
- package/services/balance-service/helpers/subscribe/substrate/index.d.ts +2 -1
- package/services/balance-service/helpers/subscribe/substrate/index.js +26 -64
- package/services/balance-service/index.d.ts +7 -6
- package/services/balance-service/index.js +12 -10
- package/services/chain-service/index.js +0 -1
- package/services/chain-service/utils/index.d.ts +1 -0
- package/services/chain-service/utils/index.js +4 -0
- package/services/earning-service/handlers/base.js +1 -1
- package/services/earning-service/handlers/nomination-pool/index.d.ts +2 -1
- package/services/earning-service/handlers/special.js +11 -12
- package/services/swap-service/handler/base-handler.d.ts +3 -2
- package/services/swap-service/handler/base-handler.js +26 -42
- package/services/swap-service/handler/chainflip-handler.d.ts +2 -1
- package/services/swap-service/handler/chainflip-handler.js +4 -2
- package/services/swap-service/handler/hydradx-handler.d.ts +2 -1
- package/services/swap-service/handler/hydradx-handler.js +7 -5
- package/services/swap-service/index.js +7 -1
- package/services/swap-service/utils.d.ts +2 -4
- package/services/swap-service/utils.js +7 -47
- package/services/transaction-service/index.d.ts +1 -1
- package/services/transaction-service/index.js +30 -119
- package/services/transaction-service/types.d.ts +1 -0
- package/types/balance/index.d.ts +6 -10
- package/types/yield/info/pallet.d.ts +0 -6
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
|
|
5
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
6
|
+
import { BasicTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
|
+
import { _getAssetDecimals, _isChainEvmCompatible } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { SwapErrorType } from '@subwallet/extension-base/types/swap';
|
|
9
|
+
import { formatNumber } from '@subwallet/extension-base/utils';
|
|
10
|
+
import BigN from 'bignumber.js';
|
|
11
|
+
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
12
|
+
export function _validateBalanceToSwap(fromToken, feeToken, feeTokenChainInfo, feeAmount, fromTokenBalance, feeTokenBalance, swapAmount, isXcmOk, minSwap) {
|
|
13
|
+
if (new BigN(feeTokenBalance).lte(feeAmount)) {
|
|
14
|
+
return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `You don't have enough ${feeToken.symbol} (${feeTokenChainInfo.name}) to pay transaction fee`);
|
|
15
|
+
}
|
|
16
|
+
if (fromToken.slug === feeToken.slug) {
|
|
17
|
+
if (new BigN(fromTokenBalance).lte(new BigN(feeAmount).plus(swapAmount))) {
|
|
18
|
+
return new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE, `Insufficient balance. Deposit ${fromToken.symbol} and try again.`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (isXcmOk) {
|
|
22
|
+
// assume that the swap is valid if XCM is in the process and it was successful
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
if (minSwap) {
|
|
26
|
+
if (new BigN(fromTokenBalance).lte(minSwap)) {
|
|
27
|
+
const parsedMinSwapValue = formatNumber(minSwap, _getAssetDecimals(fromToken));
|
|
28
|
+
return new TransactionError(SwapErrorType.SWAP_NOT_ENOUGH_BALANCE, `Insufficient balance. You need more than ${parsedMinSwapValue} ${fromToken.symbol} to start swapping. Deposit ${fromToken.symbol} and try again.`); // todo: min swap or amount?
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (new BigN(swapAmount).gte(fromTokenBalance)) {
|
|
33
|
+
const parsedMaxBalanceSwap = formatNumber(fromTokenBalance, _getAssetDecimals(fromToken));
|
|
34
|
+
return new TransactionError(SwapErrorType.SWAP_EXCEED_ALLOWANCE, `Amount too high. Lower your amount ${new BigN(fromTokenBalance).gt(0) ? `below ${parsedMaxBalanceSwap} ${fromToken.symbol}` : ''} and try again`);
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
export function _validateSwapRecipient(destChainInfo, recipient) {
|
|
39
|
+
const isEvmAddress = isEthereumAddress(recipient);
|
|
40
|
+
const isEvmDestChain = _isChainEvmCompatible(destChainInfo);
|
|
41
|
+
if (isEvmAddress && !isEvmDestChain || !isEvmAddress && isEvmDestChain) {
|
|
42
|
+
return new TransactionError(SwapErrorType.INVALID_RECIPIENT);
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
export function _getChainflipEarlyValidationError(error, metadata) {
|
|
47
|
+
// todo: support more providers
|
|
48
|
+
switch (error) {
|
|
49
|
+
case SwapErrorType.NOT_MEET_MIN_SWAP:
|
|
50
|
+
{
|
|
51
|
+
const parsedMinSwapValue = formatNumber(metadata.minSwap.value, metadata.minSwap.decimals);
|
|
52
|
+
const message = `Amount too low. Increase your amount above ${parsedMinSwapValue} ${metadata.minSwap.symbol} and try again`;
|
|
53
|
+
return new SwapError(error, message);
|
|
54
|
+
}
|
|
55
|
+
case SwapErrorType.SWAP_EXCEED_ALLOWANCE:
|
|
56
|
+
{
|
|
57
|
+
if (metadata.maxSwap) {
|
|
58
|
+
const parsedMaxSwapValue = formatNumber(metadata.maxSwap.value, metadata.maxSwap.decimals);
|
|
59
|
+
return new SwapError(error, `Amount too high. Lower your amount below ${parsedMaxSwapValue} ${metadata.maxSwap.symbol} and try again`);
|
|
60
|
+
} else {
|
|
61
|
+
return new SwapError(error, 'Amount too high. Lower your amount and try again');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
case SwapErrorType.ASSET_NOT_SUPPORTED:
|
|
65
|
+
return new SwapError(error, 'This swap pair is not supported');
|
|
66
|
+
case SwapErrorType.UNKNOWN:
|
|
67
|
+
return new SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
|
|
68
|
+
case SwapErrorType.ERROR_FETCHING_QUOTE:
|
|
69
|
+
return new SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
|
|
70
|
+
default:
|
|
71
|
+
return new SwapError(error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function _getEarlyHydradxValidationError(error, metadata) {
|
|
75
|
+
switch (error) {
|
|
76
|
+
case SwapErrorType.AMOUNT_CANNOT_BE_ZERO:
|
|
77
|
+
{
|
|
78
|
+
return new SwapError(error, 'Amount too low. Increase your amount above 0 and try again');
|
|
79
|
+
}
|
|
80
|
+
case SwapErrorType.ASSET_NOT_SUPPORTED:
|
|
81
|
+
return new SwapError(error, 'This swap pair is not supported');
|
|
82
|
+
case SwapErrorType.UNKNOWN:
|
|
83
|
+
return new SwapError(error, `Undefined error. Check your Internet and ${metadata.chain.slug} connection or contact support`);
|
|
84
|
+
case SwapErrorType.ERROR_FETCHING_QUOTE:
|
|
85
|
+
return new SwapError(error, 'No swap quote found. Adjust your amount or try again later.');
|
|
86
|
+
default:
|
|
87
|
+
return new SwapError(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
3
|
+
import { _Address, AmountData, ExtrinsicType, FeeData } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
|
+
import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
|
|
5
|
+
import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
6
|
+
import { OptionalSWTransaction, SWTransactionInput, SWTransactionResponse } from '@subwallet/extension-base/services/transaction-service/types';
|
|
7
|
+
import { KeyringPair } from '@subwallet/keyring/types';
|
|
8
|
+
import BigN from 'bignumber.js';
|
|
9
|
+
export declare function validateTransferRequest(tokenInfo: _ChainAsset, from: _Address, to: _Address, value: string | undefined, transferAll: boolean | undefined): [TransactionError[], KeyringPair | undefined, BigN | undefined];
|
|
10
|
+
export declare function additionalValidateTransfer(tokenInfo: _ChainAsset, extrinsicType: ExtrinsicType, receiverTransferTokenFreeBalance: string, transferAmount: string, senderTransferTokenTransferable?: string): [TransactionWarning | undefined, TransactionError | undefined];
|
|
11
|
+
export declare function validateXcmTransferRequest(destTokenInfo: _ChainAsset | undefined, sender: _Address, sendingValue: string): [TransactionError[], KeyringPair | undefined, BigN | undefined];
|
|
12
|
+
export declare function additionalValidateXcmTransfer(originTokenInfo: _ChainAsset, destinationTokenInfo: _ChainAsset, sendingAmount: string, senderTransferable: string): [TransactionWarning | undefined, TransactionError | undefined];
|
|
13
|
+
export declare function checkSupportForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction): void;
|
|
14
|
+
export declare function estimateFeeForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi): Promise<FeeData>;
|
|
15
|
+
export declare function checkSigningAccountForTransaction(validationResponse: SWTransactionResponse): void;
|
|
16
|
+
export declare function checkBalanceWithTransactionFee(validationResponse: SWTransactionResponse, transactionInput: SWTransactionInput, nativeTokenInfo: _ChainAsset, nativeTokenAvailable: AmountData): void;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { BasicTxErrorType, BasicTxWarningCode, ExtrinsicType, TransferTxErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
|
+
import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
|
|
7
|
+
import { XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
|
|
8
|
+
import { _canAccountBeReaped } from '@subwallet/extension-base/core/substrate/system-pallet';
|
|
9
|
+
import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
10
|
+
import { _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getTokenMinAmount, _isNativeToken, _isTokenEvmSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
11
|
+
import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
|
|
12
|
+
import { isSubstrateTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
|
|
13
|
+
import { balanceFormatter, formatNumber } from '@subwallet/extension-base/utils';
|
|
14
|
+
import { keyring } from '@subwallet/ui-keyring';
|
|
15
|
+
import BigN from 'bignumber.js';
|
|
16
|
+
import { t } from 'i18next';
|
|
17
|
+
import { isEthereumAddress } from '@polkadot/util-crypto';
|
|
18
|
+
|
|
19
|
+
// normal transfer
|
|
20
|
+
export function validateTransferRequest(tokenInfo, from, to, value, transferAll) {
|
|
21
|
+
const errors = [];
|
|
22
|
+
const keypair = keyring.getPair(from);
|
|
23
|
+
let transferValue;
|
|
24
|
+
if (!transferAll) {
|
|
25
|
+
if (value === undefined) {
|
|
26
|
+
errors.push(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Transfer amount is required')));
|
|
27
|
+
}
|
|
28
|
+
if (value) {
|
|
29
|
+
transferValue = new BigN(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!tokenInfo) {
|
|
33
|
+
errors.push(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Not found token from registry')));
|
|
34
|
+
}
|
|
35
|
+
if (isEthereumAddress(from) && isEthereumAddress(to) && _isTokenEvmSmartContract(tokenInfo) && _getContractAddressOfToken(tokenInfo).length === 0) {
|
|
36
|
+
errors.push(new TransactionError(BasicTxErrorType.INVALID_PARAMS, t('Not found ERC20 address for this token')));
|
|
37
|
+
}
|
|
38
|
+
return [errors, keypair, transferValue];
|
|
39
|
+
}
|
|
40
|
+
export function additionalValidateTransfer(tokenInfo, extrinsicType, receiverTransferTokenFreeBalance, transferAmount, senderTransferTokenTransferable) {
|
|
41
|
+
const minAmount = _getTokenMinAmount(tokenInfo);
|
|
42
|
+
let warning;
|
|
43
|
+
let error;
|
|
44
|
+
|
|
45
|
+
// Check ed of not native token for sender
|
|
46
|
+
if (extrinsicType === ExtrinsicType.TRANSFER_TOKEN && senderTransferTokenTransferable) {
|
|
47
|
+
if (new BigN(senderTransferTokenTransferable).minus(transferAmount).lt(minAmount)) {
|
|
48
|
+
warning = new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check ed for receiver
|
|
53
|
+
if (new BigN(receiverTransferTokenFreeBalance).plus(transferAmount).lt(minAmount)) {
|
|
54
|
+
const atLeast = new BigN(minAmount).minus(receiverTransferTokenFreeBalance).plus((tokenInfo.decimals || 0) === 0 ? 0 : 1);
|
|
55
|
+
const atLeastStr = formatNumber(atLeast, tokenInfo.decimals || 0, balanceFormatter, {
|
|
56
|
+
maxNumberFormat: tokenInfo.decimals || 6
|
|
57
|
+
});
|
|
58
|
+
error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('You must transfer at least {{amount}} {{symbol}} to keep the destination account alive', {
|
|
59
|
+
replace: {
|
|
60
|
+
amount: atLeastStr,
|
|
61
|
+
symbol: tokenInfo.symbol
|
|
62
|
+
}
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
return [warning, error];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// xcm transfer
|
|
69
|
+
export function validateXcmTransferRequest(destTokenInfo, sender, sendingValue) {
|
|
70
|
+
const errors = [];
|
|
71
|
+
const keypair = keyring.getPair(sender);
|
|
72
|
+
const transferValue = new BigN(sendingValue);
|
|
73
|
+
if (!destTokenInfo) {
|
|
74
|
+
errors.push(new TransactionError(TransferTxErrorType.INVALID_TOKEN, t('Not found token from registry')));
|
|
75
|
+
}
|
|
76
|
+
return [errors, keypair, transferValue];
|
|
77
|
+
}
|
|
78
|
+
export function additionalValidateXcmTransfer(originTokenInfo, destinationTokenInfo, sendingAmount, senderTransferable) {
|
|
79
|
+
const destMinAmount = _getTokenMinAmount(destinationTokenInfo);
|
|
80
|
+
const minSendingRequired = new BigN(destMinAmount).multipliedBy(XCM_MIN_AMOUNT_RATIO);
|
|
81
|
+
let error;
|
|
82
|
+
let warning;
|
|
83
|
+
|
|
84
|
+
// Check ed for receiver
|
|
85
|
+
if (new BigN(sendingAmount).lt(minSendingRequired)) {
|
|
86
|
+
const atLeastStr = formatNumber(minSendingRequired, destinationTokenInfo.decimals || 0, balanceFormatter, {
|
|
87
|
+
maxNumberFormat: destinationTokenInfo.decimals || 6
|
|
88
|
+
});
|
|
89
|
+
error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t('You must transfer at least {{amount}} {{symbol}} to keep the destination account alive', {
|
|
90
|
+
replace: {
|
|
91
|
+
amount: atLeastStr,
|
|
92
|
+
symbol: originTokenInfo.symbol
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check ed for sender
|
|
98
|
+
if (!_isNativeToken(originTokenInfo)) {
|
|
99
|
+
if (new BigN(senderTransferable).minus(sendingAmount).lt(_getTokenMinAmount(originTokenInfo))) {
|
|
100
|
+
warning = new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return [warning, error];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// general validations
|
|
107
|
+
export function checkSupportForTransaction(validationResponse, transaction) {
|
|
108
|
+
const {
|
|
109
|
+
extrinsicType
|
|
110
|
+
} = validationResponse;
|
|
111
|
+
if (!transaction) {
|
|
112
|
+
if (extrinsicType === ExtrinsicType.SEND_NFT) {
|
|
113
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.UNSUPPORTED, t('This feature is not yet available for this NFT')));
|
|
114
|
+
} else {
|
|
115
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export async function estimateFeeForTransaction(validationResponse, transaction, chainInfo, evmApi) {
|
|
120
|
+
const estimateFee = {
|
|
121
|
+
symbol: '',
|
|
122
|
+
decimals: 0,
|
|
123
|
+
value: '0',
|
|
124
|
+
tooHigh: false
|
|
125
|
+
};
|
|
126
|
+
const {
|
|
127
|
+
decimals,
|
|
128
|
+
symbol
|
|
129
|
+
} = _getChainNativeTokenBasicInfo(chainInfo);
|
|
130
|
+
estimateFee.decimals = decimals;
|
|
131
|
+
estimateFee.symbol = symbol;
|
|
132
|
+
if (transaction) {
|
|
133
|
+
try {
|
|
134
|
+
if (isSubstrateTransaction(transaction)) {
|
|
135
|
+
estimateFee.value = (await transaction.paymentInfo(validationResponse.address)).partialFee.toString();
|
|
136
|
+
} else {
|
|
137
|
+
const gasLimit = await evmApi.api.eth.estimateGas(transaction);
|
|
138
|
+
const priority = await calculateGasFeeParams(evmApi, chainInfo.slug);
|
|
139
|
+
if (priority.baseGasFee) {
|
|
140
|
+
const maxFee = priority.maxFeePerGas; // TODO: Need review
|
|
141
|
+
|
|
142
|
+
estimateFee.value = maxFee.multipliedBy(gasLimit).toFixed(0);
|
|
143
|
+
} else {
|
|
144
|
+
estimateFee.value = new BigN(priority.gasPrice).multipliedBy(gasLimit).toFixed(0);
|
|
145
|
+
}
|
|
146
|
+
estimateFee.tooHigh = priority.busyNetwork;
|
|
147
|
+
}
|
|
148
|
+
} catch (e) {
|
|
149
|
+
const error = e;
|
|
150
|
+
if (error.message.includes('gas required exceeds allowance') && error.message.includes('insufficient funds')) {
|
|
151
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return estimateFee;
|
|
156
|
+
}
|
|
157
|
+
export function checkSigningAccountForTransaction(validationResponse) {
|
|
158
|
+
const pair = keyring.getPair(validationResponse.address);
|
|
159
|
+
if (!pair) {
|
|
160
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('Unable to find account')));
|
|
161
|
+
} else {
|
|
162
|
+
var _pair$meta;
|
|
163
|
+
if ((_pair$meta = pair.meta) !== null && _pair$meta !== void 0 && _pair$meta.isReadOnly) {
|
|
164
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, t('This account is watch-only')));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export function checkBalanceWithTransactionFee(validationResponse, transactionInput, nativeTokenInfo, nativeTokenAvailable) {
|
|
169
|
+
if (!validationResponse.estimateFee) {
|
|
170
|
+
// todo: estimateFee should be must-have, need to refactor interface
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// if (!nativeTokenAvailable.metadata) {
|
|
175
|
+
// validationResponse.errors.push(new TransactionError(BasicTxErrorType.INTERNAL_ERROR));
|
|
176
|
+
//
|
|
177
|
+
// return;
|
|
178
|
+
// }
|
|
179
|
+
|
|
180
|
+
const {
|
|
181
|
+
edAsWarning,
|
|
182
|
+
extrinsicType,
|
|
183
|
+
isTransferAll,
|
|
184
|
+
skipFeeValidation
|
|
185
|
+
} = transactionInput;
|
|
186
|
+
if (skipFeeValidation) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const bnFee = new BigN(validationResponse.estimateFee.value);
|
|
190
|
+
const bnNativeTokenAvailable = new BigN(nativeTokenAvailable.value);
|
|
191
|
+
const bnNativeTokenTransferAmount = new BigN(validationResponse.transferNativeAmount || '0');
|
|
192
|
+
if (!bnNativeTokenAvailable.gt(0)) {
|
|
193
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE));
|
|
194
|
+
}
|
|
195
|
+
const isChainNotSupportTransferAll = [..._TRANSFER_CHAIN_GROUP.acala, ..._TRANSFER_CHAIN_GROUP.genshiro, ..._TRANSFER_CHAIN_GROUP.bitcountry, ..._TRANSFER_CHAIN_GROUP.statemine].includes(nativeTokenInfo.originChain);
|
|
196
|
+
if (bnNativeTokenTransferAmount.plus(bnFee).gt(bnNativeTokenAvailable) && (!isTransferAll || isChainNotSupportTransferAll)) {
|
|
197
|
+
validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_BALANCE)); // todo: should be generalized and reused in all features
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// todo: only system.pallet has metadata, we should add for other pallets and mechanisms as well
|
|
201
|
+
const isNeedCheckRemainingBalance = !isTransferAll && extrinsicType === ExtrinsicType.TRANSFER_BALANCE && nativeTokenAvailable.metadata && _canAccountBeReaped(nativeTokenAvailable.metadata);
|
|
202
|
+
const isRemainingBalanceValid = bnNativeTokenAvailable.minus(bnNativeTokenTransferAmount).minus(bnFee).lt(_getTokenMinAmount(nativeTokenInfo));
|
|
203
|
+
if (isNeedCheckRemainingBalance && isRemainingBalanceValid) {
|
|
204
|
+
edAsWarning ? validationResponse.warnings.push(new TransactionWarning(BasicTxWarningCode.NOT_ENOUGH_EXISTENTIAL_DEPOSIT)) : validationResponse.errors.push(new TransactionError(BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare type PalletNominationPoolsPoolMember = {
|
|
2
|
+
poolId: number;
|
|
3
|
+
points: number;
|
|
4
|
+
lastRecordedRewardCounter: number;
|
|
5
|
+
unbondingEras: Record<string, number>;
|
|
6
|
+
};
|
|
7
|
+
export declare function _getActiveStakeInNominationPool(memberInfo: PalletNominationPoolsPoolMember): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
|
+
export declare type FrameSystemAccountInfoV2 = Omit<FrameSystemAccountInfoV1, 'data'> & {
|
|
3
|
+
data: {
|
|
4
|
+
free: number;
|
|
5
|
+
reserved: number;
|
|
6
|
+
frozen: number;
|
|
7
|
+
flags: number;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export declare type FrameSystemAccountInfoV1 = {
|
|
11
|
+
nonce: number;
|
|
12
|
+
consumers: number;
|
|
13
|
+
providers: number;
|
|
14
|
+
sufficients: number;
|
|
15
|
+
data: {
|
|
16
|
+
free: number | string;
|
|
17
|
+
reserved: number;
|
|
18
|
+
miscFrozen: number;
|
|
19
|
+
feeFrozen: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare type FrameSystemAccountInfo = FrameSystemAccountInfoV1 | FrameSystemAccountInfoV2;
|
|
23
|
+
export declare function _getSystemPalletTransferable(accountInfo: FrameSystemAccountInfo, existentialDeposit: string, extrinsicType?: ExtrinsicType): string;
|
|
24
|
+
export declare function _canAccountBeReaped(accountInfo: FrameSystemAccountInfo): boolean;
|
|
25
|
+
export declare function _isAccountActive(accountInfo: FrameSystemAccountInfo): boolean;
|
|
26
|
+
export declare function _getSystemPalletTotalBalance(accountInfo: FrameSystemAccountInfo): string;
|
|
27
|
+
export declare function _getAppliedExistentialDepositWithExtrinsicType(accountInfo: FrameSystemAccountInfo, existentialDeposit: string, extrinsicType?: ExtrinsicType): string;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
5
|
+
import BigN from 'bignumber.js';
|
|
6
|
+
|
|
7
|
+
// https://crates.parity.io/frame_system/struct.AccountInfo.html
|
|
8
|
+
// https://wiki.polkadot.network/docs/learn-account-balances
|
|
9
|
+
|
|
10
|
+
function isV1(accountInfo) {
|
|
11
|
+
return accountInfo.data.miscFrozen !== undefined && accountInfo.data.feeFrozen !== undefined;
|
|
12
|
+
}
|
|
13
|
+
export function _getSystemPalletTransferable(accountInfo, existentialDeposit, extrinsicType) {
|
|
14
|
+
const strictMode = !extrinsicType || ![ExtrinsicType.TRANSFER_BALANCE].includes(extrinsicType); // always apply strict mode to keep account alive unless explicitly specified otherwise
|
|
15
|
+
|
|
16
|
+
if (isV1(accountInfo)) {
|
|
17
|
+
return _getSystemPalletTransferableV1(accountInfo, existentialDeposit, strictMode);
|
|
18
|
+
} else {
|
|
19
|
+
return _getSystemPalletTransferableV2(accountInfo, existentialDeposit, strictMode);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function _canAccountBeReaped(accountInfo) {
|
|
23
|
+
return accountInfo.consumers === 0; // might need to check refCount
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function _isAccountActive(accountInfo) {
|
|
27
|
+
return accountInfo.providers === 0 && accountInfo.consumers === 0;
|
|
28
|
+
}
|
|
29
|
+
export function _getSystemPalletTotalBalance(accountInfo) {
|
|
30
|
+
if (isV1(accountInfo)) {
|
|
31
|
+
return _getSystemPalletTotalBalanceV1(accountInfo);
|
|
32
|
+
} else {
|
|
33
|
+
return _getSystemPalletTotalBalanceV2(accountInfo);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function _getAppliedExistentialDepositWithExtrinsicType(accountInfo, existentialDeposit, extrinsicType) {
|
|
37
|
+
const strictMode = !extrinsicType || ![ExtrinsicType.TRANSFER_BALANCE].includes(extrinsicType); // always apply strict mode to keep account alive unless explicitly specified otherwise
|
|
38
|
+
|
|
39
|
+
return _getAppliedExistentialDeposit(accountInfo, existentialDeposit, strictMode);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ----------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
function _getAppliedExistentialDeposit(accountInfo, existentialDeposit, strictMode) {
|
|
45
|
+
// strict mode will always apply existential deposit to keep account alive
|
|
46
|
+
if (strictMode) {
|
|
47
|
+
return existentialDeposit;
|
|
48
|
+
}
|
|
49
|
+
return _canAccountBeReaped(accountInfo) ? '0' : existentialDeposit; // account for ED here will go better with max transfer logic
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function _getSystemPalletTransferableV2(accountInfo, existentialDeposit, strictMode) {
|
|
53
|
+
const bnFree = new BigN(accountInfo.data.free);
|
|
54
|
+
const bnLocked = new BigN(accountInfo.data.frozen).minus(accountInfo.data.reserved); // locked can go below 0 but this shouldn't matter
|
|
55
|
+
const bnAppliedExistentialDeposit = new BigN(_getAppliedExistentialDeposit(accountInfo, existentialDeposit, strictMode));
|
|
56
|
+
const bnTransferableBalance = bnFree.minus(BigN.max(bnLocked, bnAppliedExistentialDeposit));
|
|
57
|
+
return BigN.max(bnTransferableBalance, 0).toFixed();
|
|
58
|
+
}
|
|
59
|
+
function _getSystemPalletTotalBalanceV2(accountInfo) {
|
|
60
|
+
return new BigN(accountInfo.data.free).plus(accountInfo.data.reserved).toFixed();
|
|
61
|
+
}
|
|
62
|
+
function _getSystemPalletTransferableV1(accountInfo, existentialDeposit, strictMode) {
|
|
63
|
+
const bnAppliedExistentialDeposit = new BigN(_getAppliedExistentialDeposit(accountInfo, existentialDeposit, strictMode));
|
|
64
|
+
const bnAppliedFrozen = BigN.max(accountInfo.data.feeFrozen, accountInfo.data.miscFrozen);
|
|
65
|
+
const bnTotalBalance = new BigN(_getSystemPalletTotalBalanceV1(accountInfo));
|
|
66
|
+
const bnTransferableBalance = bnTotalBalance.minus(BigN.max(bnAppliedFrozen, accountInfo.data.reserved, bnAppliedExistentialDeposit));
|
|
67
|
+
return BigN.max(bnTransferableBalance, 0).toFixed();
|
|
68
|
+
}
|
|
69
|
+
function _getSystemPalletTotalBalanceV1(accountInfo) {
|
|
70
|
+
return new BigN(accountInfo.data.free).toFixed();
|
|
71
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { SupportTransferResponse } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
|
-
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
3
|
+
import { _EvmApi, _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
4
|
+
import BigN from 'bignumber.js';
|
|
4
5
|
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
|
5
6
|
export declare function checkReferenceCount(networkKey: string, address: string, substrateApiMap: Record<string, _SubstrateApi>, chainInfo: _ChainInfo): Promise<boolean>;
|
|
6
7
|
export declare function checkSupportTransfer(networkKey: string, tokenInfo: _ChainAsset, substrateApiMap: Record<string, _SubstrateApi>, chainInfo: _ChainInfo): Promise<SupportTransferResponse>;
|
|
@@ -14,4 +15,5 @@ interface CreateTransferExtrinsicProps {
|
|
|
14
15
|
tokenInfo: _ChainAsset;
|
|
15
16
|
}
|
|
16
17
|
export declare const createTransferExtrinsic: ({ from, networkKey, substrateApi, to, tokenInfo, transferAll, value }: CreateTransferExtrinsicProps) => Promise<[SubmittableExtrinsic | null, string]>;
|
|
18
|
+
export declare const getTransferMockTxFee: (address: string, chainInfo: _ChainInfo, tokenInfo: _ChainAsset, api: _SubstrateApi | _EvmApi) => Promise<BigN>;
|
|
17
19
|
export {};
|
|
@@ -5,8 +5,10 @@ import { GearApi } from '@gear-js/api';
|
|
|
5
5
|
import { getPSP22ContractPromise } from '@subwallet/extension-base/koni/api/tokens/wasm';
|
|
6
6
|
import { getWasmContractGasLimit } from '@subwallet/extension-base/koni/api/tokens/wasm/utils';
|
|
7
7
|
import { _BALANCE_TOKEN_GROUP, _MANTA_ZK_CHAIN_GROUP, _TRANSFER_CHAIN_GROUP, _TRANSFER_NOT_SUPPORTED_CHAINS, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
|
-
import { _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _isChainEvmCompatible, _isNativeToken, _isTokenGearSmartContract, _isTokenWasmSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { _getContractAddressOfToken, _getTokenOnChainAssetId, _getTokenOnChainInfo, _isChainEvmCompatible, _isNativeToken, _isTokenGearSmartContract, _isTokenTransferredByEvm, _isTokenWasmSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
|
+
import { calculateGasFeeParams } from '@subwallet/extension-base/services/fee-service/utils';
|
|
9
10
|
import { getGRC20ContractPromise } from '@subwallet/extension-base/utils';
|
|
11
|
+
import BigN from 'bignumber.js';
|
|
10
12
|
import { BN, u8aToHex } from '@polkadot/util';
|
|
11
13
|
import { decodeAddress } from '@polkadot/util-crypto';
|
|
12
14
|
function isRefCount(accountInfo) {
|
|
@@ -211,4 +213,45 @@ export const createTransferExtrinsic = async ({
|
|
|
211
213
|
}
|
|
212
214
|
}
|
|
213
215
|
return [transfer, transferAmount || value];
|
|
216
|
+
};
|
|
217
|
+
export const getTransferMockTxFee = async (address, chainInfo, tokenInfo, api) => {
|
|
218
|
+
try {
|
|
219
|
+
let estimatedFee;
|
|
220
|
+
if (_isChainEvmCompatible(chainInfo) && _isTokenTransferredByEvm(tokenInfo)) {
|
|
221
|
+
const web3 = api;
|
|
222
|
+
const transaction = {
|
|
223
|
+
value: 0,
|
|
224
|
+
to: '0x0000000000000000000000000000000000000000',
|
|
225
|
+
// null address
|
|
226
|
+
from: address
|
|
227
|
+
};
|
|
228
|
+
const gasLimit = await web3.api.eth.estimateGas(transaction);
|
|
229
|
+
const priority = await calculateGasFeeParams(web3, chainInfo.slug);
|
|
230
|
+
if (priority.baseGasFee) {
|
|
231
|
+
const maxFee = priority.maxFeePerGas;
|
|
232
|
+
estimatedFee = maxFee.multipliedBy(gasLimit);
|
|
233
|
+
} else {
|
|
234
|
+
estimatedFee = new BigN(priority.gasPrice).multipliedBy(gasLimit);
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
var _paymentInfo$partialF;
|
|
238
|
+
const substrateApi = api;
|
|
239
|
+
const [mockTx] = await createTransferExtrinsic({
|
|
240
|
+
from: address,
|
|
241
|
+
networkKey: chainInfo.slug,
|
|
242
|
+
substrateApi,
|
|
243
|
+
to: address,
|
|
244
|
+
tokenInfo,
|
|
245
|
+
transferAll: true,
|
|
246
|
+
value: '1000000000000000000'
|
|
247
|
+
});
|
|
248
|
+
const paymentInfo = await (mockTx === null || mockTx === void 0 ? void 0 : mockTx.paymentInfo(address));
|
|
249
|
+
estimatedFee = new BigN((paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0'); // todo: should handle error case instead of setting fee to 0
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return estimatedFee;
|
|
253
|
+
} catch (e) {
|
|
254
|
+
console.error('error mocking tx fee', e);
|
|
255
|
+
return new BigN(0);
|
|
256
|
+
}
|
|
214
257
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
3
3
|
import { ChainStakingMetadata, NominatorMetadata, UnstakingInfo, ValidatorInfo } from '@subwallet/extension-base/background/KoniTypes';
|
|
4
|
+
import { PalletNominationPoolsPoolMember } from '@subwallet/extension-base/core/substrate/nominationpools-pallet';
|
|
4
5
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
5
|
-
import { NominationPoolInfo
|
|
6
|
+
import { NominationPoolInfo } from '@subwallet/extension-base/types';
|
|
6
7
|
export interface PalletStakingNominations {
|
|
7
8
|
targets: string[];
|
|
8
9
|
submittedIn: number;
|
|
@@ -383,7 +383,7 @@ export function getTopValidatorByPoints(validatorPointsList) {
|
|
|
383
383
|
export const getMinStakeErrorMessage = (chainInfo, bnMinStake) => {
|
|
384
384
|
const tokenInfo = _getChainNativeTokenBasicInfo(chainInfo);
|
|
385
385
|
const number = formatNumber(bnMinStake.toString(), tokenInfo.decimals || 0, balanceFormatter);
|
|
386
|
-
return t('Insufficient stake.
|
|
386
|
+
return t('Insufficient stake. You need to stake at least {{number}} {{tokenSymbol}} to earn rewards', {
|
|
387
387
|
replace: {
|
|
388
388
|
tokenSymbol: tokenInfo.symbol,
|
|
389
389
|
number
|
package/koni/api/xcm/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { _SubstrateApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
3
|
+
import BigN from 'bignumber.js';
|
|
3
4
|
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
|
4
5
|
interface CreateXcmExtrinsicProps {
|
|
5
6
|
originTokenInfo: _ChainAsset;
|
|
@@ -10,4 +11,5 @@ interface CreateXcmExtrinsicProps {
|
|
|
10
11
|
chainInfoMap: Record<string, _ChainInfo>;
|
|
11
12
|
}
|
|
12
13
|
export declare const createXcmExtrinsic: ({ chainInfoMap, destinationTokenInfo, originTokenInfo, recipient, sendingValue, substrateApi }: CreateXcmExtrinsicProps) => Promise<SubmittableExtrinsic<'promise'>>;
|
|
14
|
+
export declare const getXcmMockTxFee: (substrateApi: _SubstrateApi, chainInfoMap: Record<string, _ChainInfo>, address: string, originTokenInfo: _ChainAsset, destinationTokenInfo: _ChainAsset) => Promise<BigN>;
|
|
13
15
|
export {};
|
package/koni/api/xcm/index.js
CHANGED
|
@@ -5,7 +5,10 @@ import { getExtrinsicByPolkadotXcmPallet } from '@subwallet/extension-base/koni/
|
|
|
5
5
|
import { getExtrinsicByXcmPalletPallet } from '@subwallet/extension-base/koni/api/xcm/xcmPallet';
|
|
6
6
|
import { getExtrinsicByXtokensPallet } from '@subwallet/extension-base/koni/api/xcm/xTokens';
|
|
7
7
|
import { _XCM_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
8
|
-
import { _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
9
|
+
import BigN from 'bignumber.js';
|
|
10
|
+
import { u8aToHex } from '@polkadot/util';
|
|
11
|
+
import { addressToEvm, isEthereumAddress } from '@polkadot/util-crypto';
|
|
9
12
|
export const createXcmExtrinsic = async ({
|
|
10
13
|
chainInfoMap,
|
|
11
14
|
destinationTokenInfo,
|
|
@@ -31,4 +34,27 @@ export const createXcmExtrinsic = async ({
|
|
|
31
34
|
extrinsic = getExtrinsicByXtokensPallet(originTokenInfo, originChainInfo, destinationChainInfo, recipient, sendingValue, api);
|
|
32
35
|
}
|
|
33
36
|
return extrinsic;
|
|
37
|
+
};
|
|
38
|
+
export const getXcmMockTxFee = async (substrateApi, chainInfoMap, address, originTokenInfo, destinationTokenInfo) => {
|
|
39
|
+
try {
|
|
40
|
+
var _paymentInfo$partialF;
|
|
41
|
+
const destChainInfo = chainInfoMap[destinationTokenInfo.originChain];
|
|
42
|
+
const originChainInfo = chainInfoMap[originTokenInfo.originChain];
|
|
43
|
+
|
|
44
|
+
// mock receiving account from sender
|
|
45
|
+
const recipient = !isEthereumAddress(address) && _isChainEvmCompatible(destChainInfo) && !_isChainEvmCompatible(originChainInfo) ? u8aToHex(addressToEvm(address)) : address;
|
|
46
|
+
const mockTx = await createXcmExtrinsic({
|
|
47
|
+
chainInfoMap,
|
|
48
|
+
destinationTokenInfo,
|
|
49
|
+
originTokenInfo,
|
|
50
|
+
recipient: recipient,
|
|
51
|
+
sendingValue: '1000000000000000000',
|
|
52
|
+
substrateApi
|
|
53
|
+
});
|
|
54
|
+
const paymentInfo = await mockTx.paymentInfo(address);
|
|
55
|
+
return new BigN((paymentInfo === null || paymentInfo === void 0 ? void 0 : (_paymentInfo$partialF = paymentInfo.partialFee) === null || _paymentInfo$partialF === void 0 ? void 0 : _paymentInfo$partialF.toString()) || '0');
|
|
56
|
+
} catch (e) {
|
|
57
|
+
console.error('error mocking xcm tx fee', e);
|
|
58
|
+
return new BigN(0);
|
|
59
|
+
}
|
|
34
60
|
};
|
|
@@ -124,9 +124,7 @@ export default class KoniExtension {
|
|
|
124
124
|
private subscribeStaking;
|
|
125
125
|
private subscribeHistory;
|
|
126
126
|
private subscribeHistoryByChainAndAddress;
|
|
127
|
-
private validateTransfer;
|
|
128
127
|
private makeTransfer;
|
|
129
|
-
private validateCrossChainTransfer;
|
|
130
128
|
private makeCrossChainTransfer;
|
|
131
129
|
private evmNftSubmitTransaction;
|
|
132
130
|
private upsertChain;
|
|
@@ -140,9 +138,11 @@ export default class KoniExtension {
|
|
|
140
138
|
private upsertCustomToken;
|
|
141
139
|
private deleteCustomAsset;
|
|
142
140
|
private validateCustomAsset;
|
|
143
|
-
private
|
|
144
|
-
private
|
|
145
|
-
private
|
|
141
|
+
private getAddressTransferableBalance;
|
|
142
|
+
private getMaxTransferable;
|
|
143
|
+
private getXcmMaxTransferable;
|
|
144
|
+
private getNativeTokenMaxTransferable;
|
|
145
|
+
private subscribeAddressTransferableBalance;
|
|
146
146
|
private transferCheckReferenceCount;
|
|
147
147
|
private transferCheckSupporting;
|
|
148
148
|
private transferGetExistentialDeposit;
|