@subwallet/extension-base 1.3.23-0 → 1.3.24-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +2 -2
- package/cjs/constants/environment.js +1 -1
- package/cjs/constants/index.js +21 -4
- package/cjs/core/logic-validation/transfer.js +23 -8
- package/cjs/koni/background/handlers/Extension.js +109 -89
- package/cjs/koni/background/handlers/State.js +2 -2
- package/cjs/koni/background/handlers/Tabs.js +1 -1
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/transfer/smart-contract.js +24 -3
- package/cjs/services/chain-service/index.js +11 -0
- package/cjs/services/fee-service/utils/tokenPayFee.js +151 -0
- package/cjs/services/request-service/handler/MetadataRequestHandler.js +5 -13
- package/cjs/services/request-service/index.js +2 -2
- package/cjs/services/transaction-service/index.js +8 -5
- package/cjs/utils/fee/transfer.js +47 -14
- package/constants/environment.js +1 -1
- package/constants/index.d.ts +6 -1
- package/constants/index.js +14 -1
- package/core/logic-validation/transfer.d.ts +1 -1
- package/core/logic-validation/transfer.js +25 -10
- package/koni/background/handlers/Extension.js +82 -62
- package/koni/background/handlers/State.d.ts +1 -1
- package/koni/background/handlers/State.js +2 -2
- package/koni/background/handlers/Tabs.js +1 -1
- package/package.json +11 -6
- package/packageInfo.js +1 -1
- package/services/balance-service/transfer/smart-contract.d.ts +4 -2
- package/services/balance-service/transfer/smart-contract.js +24 -3
- package/services/chain-service/index.d.ts +1 -0
- package/services/chain-service/index.js +12 -1
- package/services/fee-service/interfaces.d.ts +25 -0
- package/services/fee-service/utils/tokenPayFee.d.ts +8 -0
- package/services/fee-service/utils/tokenPayFee.js +141 -0
- package/services/request-service/handler/MetadataRequestHandler.d.ts +1 -1
- package/services/request-service/handler/MetadataRequestHandler.js +5 -13
- package/services/request-service/index.d.ts +1 -1
- package/services/request-service/index.js +2 -2
- package/services/transaction-service/index.js +10 -7
- package/types/fee/option.d.ts +1 -1
- package/utils/fee/transfer.d.ts +1 -1
- package/utils/fee/transfer.js +46 -13
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.batchExtrinsicSetFeeHydration = batchExtrinsicSetFeeHydration;
|
|
8
|
+
exports.getAssetHubTokensCanPayFee = getAssetHubTokensCanPayFee;
|
|
9
|
+
exports.getHydrationRate = getHydrationRate;
|
|
10
|
+
exports.getHydrationTokensCanPayFee = getHydrationTokensCanPayFee;
|
|
11
|
+
var _types = require("@subwallet/chain-list/types");
|
|
12
|
+
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
13
|
+
var _utils2 = require("@subwallet/extension-base/services/swap-service/handler/asset-hub/utils");
|
|
14
|
+
var _subwalletApiSdk = _interopRequireDefault(require("@subwallet/subwallet-api-sdk"));
|
|
15
|
+
var _bignumber = _interopRequireDefault(require("bignumber.js"));
|
|
16
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
17
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
18
|
+
|
|
19
|
+
async function getAssetHubTokensCanPayFee(request) {
|
|
20
|
+
const {
|
|
21
|
+
chainService,
|
|
22
|
+
feeAmount,
|
|
23
|
+
nativeBalanceInfo,
|
|
24
|
+
nativeTokenInfo,
|
|
25
|
+
substrateApi,
|
|
26
|
+
tokensHasBalanceInfoMap
|
|
27
|
+
} = request;
|
|
28
|
+
const tokensList = [nativeBalanceInfo];
|
|
29
|
+
if (!(nativeTokenInfo.metadata && nativeTokenInfo.metadata.multilocation)) {
|
|
30
|
+
return tokensList;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ensure nativeTokenInfo and localTokenInfo have multi-location metadata beforehand to improve performance.
|
|
34
|
+
const tokensHasBalanceSlug = Object.keys(tokensHasBalanceInfoMap);
|
|
35
|
+
const tokenInfos = tokensHasBalanceSlug.map(tokenSlug => chainService.getAssetBySlug(tokenSlug)).filter(token => token.originChain === substrateApi.chainSlug && token.assetType !== _types._AssetType.NATIVE && token.metadata && token.metadata.multilocation);
|
|
36
|
+
await Promise.all(tokenInfos.map(async tokenInfo => {
|
|
37
|
+
try {
|
|
38
|
+
const tokenSlug = tokenInfo.slug;
|
|
39
|
+
const reserve = await (0, _utils2.getReserveForPool)(substrateApi.api, nativeTokenInfo, tokenInfo);
|
|
40
|
+
if (!reserve || !reserve[0] || !reserve[1] || reserve[0] === '0' || reserve[1] === '0') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const rate = new _bignumber.default(reserve[1]).div(reserve[0]).toFixed();
|
|
44
|
+
const tokenCanPayFee = {
|
|
45
|
+
slug: tokenSlug,
|
|
46
|
+
free: tokensHasBalanceInfoMap[tokenSlug].free,
|
|
47
|
+
rate
|
|
48
|
+
};
|
|
49
|
+
if (feeAmount === undefined) {
|
|
50
|
+
tokensList.push(tokenCanPayFee);
|
|
51
|
+
} else {
|
|
52
|
+
const amount = (0, _utils2.estimateTokensForPool)(feeAmount, reserve);
|
|
53
|
+
const liquidityError = (0, _utils2.checkLiquidityForPool)(amount, reserve[0], reserve[1]);
|
|
54
|
+
if (!liquidityError) {
|
|
55
|
+
tokensList.push(tokenCanPayFee);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error('error when fetching pool with token', tokenInfo.slug, e);
|
|
60
|
+
}
|
|
61
|
+
}));
|
|
62
|
+
return tokensList;
|
|
63
|
+
}
|
|
64
|
+
async function getHydrationTokensCanPayFee(request) {
|
|
65
|
+
const {
|
|
66
|
+
address,
|
|
67
|
+
chainService,
|
|
68
|
+
nativeBalanceInfo,
|
|
69
|
+
nativeTokenInfo,
|
|
70
|
+
substrateApi,
|
|
71
|
+
tokensHasBalanceInfoMap
|
|
72
|
+
} = request;
|
|
73
|
+
const tokensList = [nativeBalanceInfo];
|
|
74
|
+
const _acceptedCurrencies = await substrateApi.api.query.multiTransactionPayment.acceptedCurrencies.entries();
|
|
75
|
+
const supportedAssetIds = _acceptedCurrencies.map(_assetId => {
|
|
76
|
+
const assetId = _assetId[0].toHuman();
|
|
77
|
+
return assetId[0].replaceAll(',', '');
|
|
78
|
+
});
|
|
79
|
+
const nativePriceId = (0, _utils._getAssetPriceId)(nativeTokenInfo);
|
|
80
|
+
if (!nativePriceId) {
|
|
81
|
+
return tokensList;
|
|
82
|
+
}
|
|
83
|
+
const tokenInfos = Object.keys(tokensHasBalanceInfoMap).map(tokenSlug => chainService.getAssetBySlug(tokenSlug)).filter(token => token.originChain === substrateApi.chainSlug && token.assetType !== _types._AssetType.NATIVE && !!token.metadata && !!token.metadata.assetId);
|
|
84
|
+
await Promise.all(tokenInfos.map(async tokenInfo => {
|
|
85
|
+
const priceId = (0, _utils._getAssetPriceId)(tokenInfo);
|
|
86
|
+
const rate = await getHydrationRate(address, nativeTokenInfo, tokenInfo);
|
|
87
|
+
if (priceId && rate) {
|
|
88
|
+
if (supportedAssetIds.includes((0, _utils._getTokenOnChainAssetId)(tokenInfo))) {
|
|
89
|
+
tokensList.push({
|
|
90
|
+
slug: tokenInfo.slug,
|
|
91
|
+
free: tokensHasBalanceInfoMap[tokenInfo.slug].free,
|
|
92
|
+
rate: rate.toString()
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}));
|
|
97
|
+
return tokensList;
|
|
98
|
+
}
|
|
99
|
+
function batchExtrinsicSetFeeHydration(substrateApi, tx, feeSetting, assetId) {
|
|
100
|
+
const api = substrateApi.api;
|
|
101
|
+
const isSettingLocalFee = feeSetting && feeSetting !== 0;
|
|
102
|
+
const isAttendToSetLocalFee = assetId && assetId !== '0';
|
|
103
|
+
if (!tx) {
|
|
104
|
+
return tx;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// current native - set native
|
|
108
|
+
if (!isSettingLocalFee && !isAttendToSetLocalFee) {
|
|
109
|
+
return tx;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// current native - set local
|
|
113
|
+
if (!isSettingLocalFee && isAttendToSetLocalFee) {
|
|
114
|
+
return api.tx.utility.batchAll([api.tx.multiTransactionPayment.setCurrency(assetId), tx, api.tx.multiTransactionPayment.setCurrency('0')]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// current local - set native
|
|
118
|
+
if (isSettingLocalFee && !isAttendToSetLocalFee) {
|
|
119
|
+
return api.tx.utility.batchAll([api.tx.multiTransactionPayment.setCurrency('0'), tx]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// current local - set local
|
|
123
|
+
if (isSettingLocalFee && isAttendToSetLocalFee) {
|
|
124
|
+
if (assetId === feeSetting.toString()) {
|
|
125
|
+
// current local = set local
|
|
126
|
+
return api.tx.utility.batchAll([tx, api.tx.multiTransactionPayment.setCurrency('0')]);
|
|
127
|
+
} else {
|
|
128
|
+
// current local != set local
|
|
129
|
+
return api.tx.utility.batchAll([api.tx.multiTransactionPayment.setCurrency(assetId), tx, api.tx.multiTransactionPayment.setCurrency('0')]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return tx;
|
|
133
|
+
}
|
|
134
|
+
async function getHydrationRate(address, hdx, desToken) {
|
|
135
|
+
var _subwalletApiSdk$swap;
|
|
136
|
+
const quoteRate = await ((_subwalletApiSdk$swap = _subwalletApiSdk.default.swapApi) === null || _subwalletApiSdk$swap === void 0 ? void 0 : _subwalletApiSdk$swap.getHydrationRate({
|
|
137
|
+
address,
|
|
138
|
+
pair: {
|
|
139
|
+
slug: `${hdx.slug}___${desToken.slug}`,
|
|
140
|
+
from: hdx.slug,
|
|
141
|
+
to: desToken.slug
|
|
142
|
+
}
|
|
143
|
+
}));
|
|
144
|
+
if (!quoteRate) {
|
|
145
|
+
return undefined;
|
|
146
|
+
} else {
|
|
147
|
+
const hdxDecimal = (0, _utils._getAssetDecimals)(hdx);
|
|
148
|
+
const desTokenDecimal = (0, _utils._getAssetDecimals)(desToken);
|
|
149
|
+
return new _bignumber.default(quoteRate).multipliedBy(10 ** (desTokenDecimal - hdxDecimal)).toFixed();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _helper = require("@subwallet/extension-base/services/request-service/helper");
|
|
8
8
|
var _stores = require("@subwallet/extension-base/stores");
|
|
9
|
-
var _getId = require("@subwallet/extension-base/utils/getId");
|
|
10
9
|
var _extensionChains = require("@subwallet/extension-chains");
|
|
11
10
|
var _rxjs = require("rxjs");
|
|
12
11
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
@@ -52,6 +51,8 @@ class MetadataRequestHandler {
|
|
|
52
51
|
this.metaSubject.next(this.allMetaRequests);
|
|
53
52
|
this.#requestService.updateIconV2(shouldClose);
|
|
54
53
|
}
|
|
54
|
+
|
|
55
|
+
// @ts-ignore
|
|
55
56
|
metaComplete = (id, resolve, reject) => {
|
|
56
57
|
const complete = () => {
|
|
57
58
|
delete this.#metaRequests[id];
|
|
@@ -68,18 +69,9 @@ class MetadataRequestHandler {
|
|
|
68
69
|
}
|
|
69
70
|
};
|
|
70
71
|
};
|
|
71
|
-
injectMetadata(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.#metaRequests[id] = {
|
|
75
|
-
...this.metaComplete(id, resolve, reject),
|
|
76
|
-
id,
|
|
77
|
-
request,
|
|
78
|
-
url
|
|
79
|
-
};
|
|
80
|
-
this.updateIconMeta();
|
|
81
|
-
this.#requestService.popupOpen();
|
|
82
|
-
});
|
|
72
|
+
injectMetadata(request) {
|
|
73
|
+
this.saveMetadata(request);
|
|
74
|
+
return true;
|
|
83
75
|
}
|
|
84
76
|
resetWallet() {
|
|
85
77
|
for (const request of Object.values(this.#metaRequests)) {
|
|
@@ -87,8 +87,8 @@ class RequestService {
|
|
|
87
87
|
get numMetaRequests() {
|
|
88
88
|
return this.#metadataRequestHandler.numMetaRequests;
|
|
89
89
|
}
|
|
90
|
-
injectMetadata(
|
|
91
|
-
return this.#metadataRequestHandler.injectMetadata(
|
|
90
|
+
injectMetadata(request) {
|
|
91
|
+
return this.#metadataRequestHandler.injectMetadata(request);
|
|
92
92
|
}
|
|
93
93
|
getMetaRequest(id) {
|
|
94
94
|
return this.#metadataRequestHandler.getMetaRequest(id);
|
|
@@ -97,8 +97,6 @@ class TransactionService {
|
|
|
97
97
|
(0, _transfer.checkSupportForAction)(validationResponse, blockedActionsMap);
|
|
98
98
|
}
|
|
99
99
|
const transaction = transactionInput.transaction;
|
|
100
|
-
const nativeTokenInfo = this.state.chainService.getNativeTokenInfo(chain);
|
|
101
|
-
const tokenPayFeeInfo = transactionInput.nonNativeTokenPayFeeSlug ? this.chainService.getAssetBySlug(transactionInput.nonNativeTokenPayFeeSlug) : undefined;
|
|
102
100
|
|
|
103
101
|
// Check duplicated transaction
|
|
104
102
|
validationResponse.errors.push(...this.checkDuplicate(transactionInput));
|
|
@@ -124,7 +122,12 @@ class TransactionService {
|
|
|
124
122
|
// Estimate fee for transaction
|
|
125
123
|
const id = (0, _getId.getId)();
|
|
126
124
|
const feeInfo = await this.state.feeService.subscribeChainFee(id, chain, 'evm');
|
|
127
|
-
|
|
125
|
+
const nativeTokenInfo = this.state.chainService.getNativeTokenInfo(chain);
|
|
126
|
+
const tokenPayFeeSlug = transactionInput.tokenPayFeeSlug;
|
|
127
|
+
const isNonNativeTokenPayFee = tokenPayFeeSlug && !(0, _utils2._isNativeTokenBySlug)(tokenPayFeeSlug);
|
|
128
|
+
const nonNativeTokenPayFeeInfo = isNonNativeTokenPayFee ? this.chainService.getAssetBySlug(tokenPayFeeSlug) : undefined;
|
|
129
|
+
const priceMap = (await this.state.priceService.getPrice()).priceMap;
|
|
130
|
+
validationResponse.estimateFee = await (0, _transfer.estimateFeeForTransaction)(validationResponse, transaction, chainInfo, evmApi, substrateApi, priceMap, feeInfo, nativeTokenInfo, nonNativeTokenPayFeeInfo, transactionInput.isTransferLocalTokenAndPayThatTokenAsFee);
|
|
128
131
|
const chainInfoMap = this.state.chainService.getChainInfoMap();
|
|
129
132
|
|
|
130
133
|
// Check account signing transaction
|
|
@@ -1367,14 +1370,14 @@ class TransactionService {
|
|
|
1367
1370
|
chain,
|
|
1368
1371
|
feeCustom,
|
|
1369
1372
|
id,
|
|
1370
|
-
nonNativeTokenPayFeeSlug,
|
|
1371
1373
|
signAfterCreate,
|
|
1372
1374
|
step,
|
|
1375
|
+
tokenPayFeeSlug,
|
|
1373
1376
|
transaction,
|
|
1374
1377
|
url
|
|
1375
1378
|
} = _ref12;
|
|
1376
1379
|
const tip = (feeCustom === null || feeCustom === void 0 ? void 0 : feeCustom.tip) || '0';
|
|
1377
|
-
const feeAssetId =
|
|
1380
|
+
const feeAssetId = tokenPayFeeSlug && !(0, _utils2._isNativeTokenBySlug)(tokenPayFeeSlug) && _constants._SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(chain) ? (_this$state$chainServ = this.state.chainService.getAssetBySlug(tokenPayFeeSlug).metadata) === null || _this$state$chainServ === void 0 ? void 0 : _this$state$chainServ.multilocation : undefined;
|
|
1378
1381
|
const emitter = new _eventemitter.default();
|
|
1379
1382
|
const eventData = {
|
|
1380
1383
|
id,
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.detectTransferTxType = exports.
|
|
7
|
+
exports.detectTransferTxType = exports.calculateXcmMaxTransferable = exports.calculateTransferMaxTransferable = exports.calculateMaxTransferable = void 0;
|
|
8
8
|
var _constants = require("@subwallet/extension-base/constants");
|
|
9
9
|
var _xcmParser = require("@subwallet/extension-base/core/substrate/xcm-parser");
|
|
10
10
|
var _consts = require("@subwallet/extension-base/services/balance-service/helpers/subscribe/cardano/consts");
|
|
@@ -18,6 +18,7 @@ var _polygonBridge = require("@subwallet/extension-base/services/balance-service
|
|
|
18
18
|
var _posBridge = require("@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge");
|
|
19
19
|
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
20
20
|
var _utils2 = require("@subwallet/extension-base/services/fee-service/utils");
|
|
21
|
+
var _tokenPayFee = require("@subwallet/extension-base/services/fee-service/utils/tokenPayFee");
|
|
21
22
|
var _helpers = require("@subwallet/extension-base/services/transaction-service/helpers");
|
|
22
23
|
var _utils3 = require("@subwallet/extension-base/utils");
|
|
23
24
|
var _keyring = require("@subwallet/keyring");
|
|
@@ -57,7 +58,13 @@ const calculateMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
|
57
58
|
const isXcmTransfer = srcChain.slug !== destChain.slug;
|
|
58
59
|
let maxTransferableAmount;
|
|
59
60
|
if (isXcmTransfer) {
|
|
60
|
-
|
|
61
|
+
const _request = {
|
|
62
|
+
// todo: temp not support pay local fee with xcm
|
|
63
|
+
...request,
|
|
64
|
+
isTransferLocalTokenAndPayThatTokenAsFee: false,
|
|
65
|
+
isTransferNativeTokenAndPayLocalTokenAsFee: false
|
|
66
|
+
};
|
|
67
|
+
maxTransferableAmount = await calculateXcmMaxTransferable(id, _request, freeBalance, fee);
|
|
61
68
|
} else {
|
|
62
69
|
maxTransferableAmount = await calculateTransferMaxTransferable(id, request, freeBalance, fee);
|
|
63
70
|
}
|
|
@@ -97,7 +104,7 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
97
104
|
// todo: refactor: merge getERC20TransactionObject & getEVMTransactionObject
|
|
98
105
|
// Estimate with EVM API
|
|
99
106
|
if ((0, _utils._isTokenEvmSmartContract)(srcToken) || (0, _utils._isLocalToken)(srcToken)) {
|
|
100
|
-
[transaction] = await (0, _smartContract.getERC20TransactionObject)({
|
|
107
|
+
[transaction,, error] = await (0, _smartContract.getERC20TransactionObject)({
|
|
101
108
|
assetAddress: (0, _utils._getContractAddressOfToken)(srcToken),
|
|
102
109
|
chain: srcChain.slug,
|
|
103
110
|
evmApi,
|
|
@@ -107,10 +114,11 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
107
114
|
from: address,
|
|
108
115
|
to: recipient,
|
|
109
116
|
transferAll: false,
|
|
110
|
-
value: '0'
|
|
117
|
+
value: '0',
|
|
118
|
+
fallbackFee: true
|
|
111
119
|
});
|
|
112
120
|
} else {
|
|
113
|
-
[transaction] = await (0, _smartContract.getEVMTransactionObject)({
|
|
121
|
+
[transaction,, error] = await (0, _smartContract.getEVMTransactionObject)({
|
|
114
122
|
chain: srcChain.slug,
|
|
115
123
|
evmApi,
|
|
116
124
|
feeCustom,
|
|
@@ -119,7 +127,8 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
119
127
|
from: address,
|
|
120
128
|
to: recipient,
|
|
121
129
|
transferAll: false,
|
|
122
|
-
value: '0'
|
|
130
|
+
value: '0',
|
|
131
|
+
fallbackFee: true
|
|
123
132
|
});
|
|
124
133
|
}
|
|
125
134
|
} else if ((0, _keyring.isTonAddress)(address) && (0, _utils._isTokenTransferredByTon)(srcToken)) {
|
|
@@ -240,9 +249,21 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
240
249
|
console.warn('Unable to estimate fee', e);
|
|
241
250
|
}
|
|
242
251
|
if (isTransferLocalTokenAndPayThatTokenAsFee && feeChainType === 'substrate') {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
252
|
+
if (_constants._SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(srcChain.slug)) {
|
|
253
|
+
const estimatedFeeNative = (BigInt(estimatedFee) * BigInt(_utils2.FEE_COVERAGE_PERCENTAGE_SPECIAL_CASE) / BigInt(100)).toString();
|
|
254
|
+
const estimatedFeeLocal = await (0, _utils2.calculateToAmountByReservePool)(substrateApi.api, nativeToken, srcToken, estimatedFeeNative);
|
|
255
|
+
maxTransferable = (0, _bignumber.default)(freeBalance.value).minus(estimatedFeeLocal);
|
|
256
|
+
} else if (_constants._SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(srcChain.slug)) {
|
|
257
|
+
const rate = await (0, _tokenPayFee.getHydrationRate)(address, nativeToken, srcToken);
|
|
258
|
+
if (rate) {
|
|
259
|
+
const estimatedFeeLocal = new _bignumber.default(estimatedFee).multipliedBy(rate).integerValue(_bignumber.default.ROUND_UP).toString();
|
|
260
|
+
maxTransferable = (0, _bignumber.default)(freeBalance.value).minus(estimatedFeeLocal);
|
|
261
|
+
} else {
|
|
262
|
+
throw new Error(`Unable to estimate fee for ${srcChain.slug}.`);
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
throw new Error(`Unable to estimate fee for ${srcChain.slug}.`);
|
|
266
|
+
}
|
|
246
267
|
} else if (isTransferNativeTokenAndPayLocalTokenAsFee) {
|
|
247
268
|
maxTransferable = (0, _bignumber.default)(freeBalance.value);
|
|
248
269
|
} else {
|
|
@@ -261,7 +282,7 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
261
282
|
};
|
|
262
283
|
};
|
|
263
284
|
exports.calculateTransferMaxTransferable = calculateTransferMaxTransferable;
|
|
264
|
-
const
|
|
285
|
+
const calculateXcmMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
265
286
|
const {
|
|
266
287
|
address,
|
|
267
288
|
destChain,
|
|
@@ -384,9 +405,21 @@ const calculateXCMMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
|
384
405
|
if (!destToken) {
|
|
385
406
|
maxTransferable = _utils3.BN_ZERO;
|
|
386
407
|
} else if (isTransferLocalTokenAndPayThatTokenAsFee && feeChainType === 'substrate') {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
408
|
+
if (_constants._SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(srcChain.slug)) {
|
|
409
|
+
const estimatedFeeNative = (BigInt(estimatedFee) * BigInt(_utils2.FEE_COVERAGE_PERCENTAGE_SPECIAL_CASE) / BigInt(100)).toString();
|
|
410
|
+
const estimatedFeeLocal = await (0, _utils2.calculateToAmountByReservePool)(substrateApi.api, nativeToken, srcToken, estimatedFeeNative);
|
|
411
|
+
maxTransferable = (0, _bignumber.default)(freeBalance.value).minus(estimatedFeeLocal);
|
|
412
|
+
} else if (_constants._SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(srcChain.slug)) {
|
|
413
|
+
const rate = await (0, _tokenPayFee.getHydrationRate)(address, nativeToken, srcToken);
|
|
414
|
+
if (rate) {
|
|
415
|
+
const estimatedFeeLocal = new _bignumber.default(estimatedFee).multipliedBy(rate).integerValue(_bignumber.default.ROUND_UP).toString();
|
|
416
|
+
maxTransferable = (0, _bignumber.default)(freeBalance.value).minus(estimatedFeeLocal);
|
|
417
|
+
} else {
|
|
418
|
+
throw new Error(`Unable to estimate fee for ${srcChain.slug}.`);
|
|
419
|
+
}
|
|
420
|
+
} else {
|
|
421
|
+
throw new Error(`Unable to estimate fee for ${srcChain.slug}.`);
|
|
422
|
+
}
|
|
390
423
|
} else if (isTransferNativeTokenAndPayLocalTokenAsFee) {
|
|
391
424
|
maxTransferable = (0, _bignumber.default)(freeBalance.value);
|
|
392
425
|
} else {
|
|
@@ -404,4 +437,4 @@ const calculateXCMMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
|
404
437
|
error
|
|
405
438
|
};
|
|
406
439
|
};
|
|
407
|
-
exports.
|
|
440
|
+
exports.calculateXcmMaxTransferable = calculateXcmMaxTransferable;
|
package/constants/environment.js
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
|
|
5
5
|
const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
|
|
6
6
|
export const isProductionMode = PRODUCTION_BRANCHES.indexOf(branchName) > -1;
|
|
7
|
-
export const BACKEND_API_URL = process.env.SUBWALLET_API || (isProductionMode ? 'https://sw-services.subwallet.app/api' : 'https://
|
|
7
|
+
export const BACKEND_API_URL = process.env.SUBWALLET_API || (isProductionMode ? 'https://sw-services.subwallet.app/api' : 'https://be-dev.subwallet.app/api');
|
package/constants/index.d.ts
CHANGED
|
@@ -35,7 +35,12 @@ export declare const NETWORK_MULTI_GAS_FEE: string[];
|
|
|
35
35
|
export declare const ORDINAL_COLLECTION = "__Ordinal__";
|
|
36
36
|
export declare const ORDINAL_METHODS: string[];
|
|
37
37
|
export declare const PERMISSIONS_TO_REVOKE: string[];
|
|
38
|
-
export declare const
|
|
38
|
+
export declare const _SUPPORT_TOKEN_PAY_FEE_GROUP: {
|
|
39
|
+
assetHub: string[];
|
|
40
|
+
hydration: string[];
|
|
41
|
+
};
|
|
42
|
+
export declare const getSupportTokenPayFeeChain: () => string[];
|
|
43
|
+
export declare const isChainSupportTokenPayFee: (chainSlug: string) => boolean;
|
|
39
44
|
export * from './blocked-actions';
|
|
40
45
|
export * from './environment';
|
|
41
46
|
export * from './signing';
|
package/constants/index.js
CHANGED
|
@@ -37,7 +37,20 @@ export const NETWORK_MULTI_GAS_FEE = ['*'];
|
|
|
37
37
|
export const ORDINAL_COLLECTION = '__Ordinal__';
|
|
38
38
|
export const ORDINAL_METHODS = ['drc-20', 'pol-20'];
|
|
39
39
|
export const PERMISSIONS_TO_REVOKE = ['eth_accounts'];
|
|
40
|
-
export const
|
|
40
|
+
export const _SUPPORT_TOKEN_PAY_FEE_GROUP = {
|
|
41
|
+
assetHub: ['paseo_assethub', 'westend_assethub', 'rococo_assethub', 'statemine', 'statemint'],
|
|
42
|
+
hydration: ['hydradx_main', 'hydradx_rococo']
|
|
43
|
+
};
|
|
44
|
+
export const getSupportTokenPayFeeChain = () => {
|
|
45
|
+
return Object.values(_SUPPORT_TOKEN_PAY_FEE_GROUP).flat();
|
|
46
|
+
};
|
|
47
|
+
export const isChainSupportTokenPayFee = chainSlug => {
|
|
48
|
+
if (!chainSlug) {
|
|
49
|
+
console.error('You must provide chain slug!');
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return getSupportTokenPayFeeChain().includes(chainSlug);
|
|
53
|
+
};
|
|
41
54
|
export * from "./blocked-actions.js";
|
|
42
55
|
export * from "./environment.js";
|
|
43
56
|
export * from "./signing.js";
|
|
@@ -14,7 +14,7 @@ export declare function additionalValidateXcmTransfer(originTokenInfo: _ChainAss
|
|
|
14
14
|
export declare function checkSupportForFeature(validationResponse: SWTransactionResponse, blockedFeaturesList: string[], chainInfo: _ChainInfo): void;
|
|
15
15
|
export declare function checkSupportForAction(validationResponse: SWTransactionResponse, blockedActionsMap: Record<ExtrinsicType, string[]>): void;
|
|
16
16
|
export declare function checkSupportForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction): void;
|
|
17
|
-
export declare function estimateFeeForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi, substrateApi: _SubstrateApi, feeInfo: EvmFeeInfo, nativeTokenInfo: _ChainAsset,
|
|
17
|
+
export declare function estimateFeeForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi, substrateApi: _SubstrateApi, priceMap: Record<string, number>, feeInfo: EvmFeeInfo, nativeTokenInfo: _ChainAsset, nonNativeTokenPayFeeInfo: _ChainAsset | undefined, isTransferLocalTokenAndPayThatTokenAsFee: boolean | undefined): Promise<FeeData>;
|
|
18
18
|
export declare function checkSigningAccountForTransaction(validationResponse: SWTransactionResponse, chainInfoMap: Record<string, _ChainInfo>): void;
|
|
19
19
|
export declare function checkBalanceWithTransactionFee(validationResponse: SWTransactionResponse, transactionInput: SWTransactionInput, nativeTokenInfo: _ChainAsset, nativeTokenAvailable: AmountData): void;
|
|
20
20
|
export declare function checkTonAddressBounceableAndAccountNotActive(tonApi: _TonApi, validationResponse: SWTransactionResponse): Promise<void>;
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
5
|
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { TransactionWarning } from '@subwallet/extension-base/background/warnings/TransactionWarning';
|
|
7
|
-
import { LEDGER_SIGNING_COMPATIBLE_MAP, SIGNING_COMPATIBLE_MAP, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
|
|
7
|
+
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, LEDGER_SIGNING_COMPATIBLE_MAP, SIGNING_COMPATIBLE_MAP, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
|
|
8
8
|
import { _canAccountBeReaped, _isAccountActive } from '@subwallet/extension-base/core/substrate/system-pallet';
|
|
9
9
|
import { getCardanoAssetId } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/cardano/utils';
|
|
10
10
|
import { isBounceableAddress } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/ton/utils';
|
|
11
11
|
import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
12
|
-
import { _getAssetDecimals, _getChainExistentialDeposit, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getTokenMinAmount, _isCIP26Token, _isNativeToken, _isTokenEvmSmartContract, _isTokenTonSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
12
|
+
import { _getAssetDecimals, _getAssetPriceId, _getAssetSymbol, _getChainExistentialDeposit, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getTokenMinAmount, _isCIP26Token, _isNativeToken, _isNativeTokenBySlug, _isTokenEvmSmartContract, _isTokenTonSmartContract } from '@subwallet/extension-base/services/chain-service/utils';
|
|
13
13
|
import { calculateToAmountByReservePool, FEE_COVERAGE_PERCENTAGE_SPECIAL_CASE } from '@subwallet/extension-base/services/fee-service/utils';
|
|
14
14
|
import { isCardanoTransaction, isSubstrateTransaction, isTonTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
|
|
15
15
|
import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, TransferTxErrorType } from '@subwallet/extension-base/types';
|
|
@@ -331,7 +331,7 @@ export function checkSupportForTransaction(validationResponse, transaction) {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
|
-
export async function estimateFeeForTransaction(validationResponse, transaction, chainInfo, evmApi, substrateApi, feeInfo, nativeTokenInfo,
|
|
334
|
+
export async function estimateFeeForTransaction(validationResponse, transaction, chainInfo, evmApi, substrateApi, priceMap, feeInfo, nativeTokenInfo, nonNativeTokenPayFeeInfo, isTransferLocalTokenAndPayThatTokenAsFee) {
|
|
335
335
|
const estimateFee = {
|
|
336
336
|
symbol: '',
|
|
337
337
|
decimals: 0,
|
|
@@ -377,11 +377,25 @@ export async function estimateFeeForTransaction(validationResponse, transaction,
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
|
-
|
|
380
|
+
const isCustomTokenPayFeeAssetHub = !!nonNativeTokenPayFeeInfo && _SUPPORT_TOKEN_PAY_FEE_GROUP.assetHub.includes(nonNativeTokenPayFeeInfo.originChain);
|
|
381
|
+
const isCustomTokenPayFeeHydration = !!nonNativeTokenPayFeeInfo && _SUPPORT_TOKEN_PAY_FEE_GROUP.hydration.includes(nonNativeTokenPayFeeInfo.originChain);
|
|
382
|
+
if (isCustomTokenPayFeeAssetHub) {
|
|
381
383
|
const estimatedFeeAmount = isTransferLocalTokenAndPayThatTokenAsFee ? (BigInt(estimateFee.value) * BigInt(FEE_COVERAGE_PERCENTAGE_SPECIAL_CASE) / BigInt(100)).toString() : estimateFee.value;
|
|
382
|
-
estimateFee.decimals =
|
|
383
|
-
estimateFee.symbol =
|
|
384
|
-
estimateFee.value = await calculateToAmountByReservePool(substrateApi.api, nativeTokenInfo,
|
|
384
|
+
estimateFee.decimals = _getAssetDecimals(nonNativeTokenPayFeeInfo);
|
|
385
|
+
estimateFee.symbol = _getAssetSymbol(nonNativeTokenPayFeeInfo);
|
|
386
|
+
estimateFee.value = await calculateToAmountByReservePool(substrateApi.api, nativeTokenInfo, nonNativeTokenPayFeeInfo, estimatedFeeAmount);
|
|
387
|
+
}
|
|
388
|
+
if (isCustomTokenPayFeeHydration) {
|
|
389
|
+
const nativePriceId = _getAssetPriceId(nativeTokenInfo);
|
|
390
|
+
const nativeDecimals = _getAssetDecimals(nativeTokenInfo);
|
|
391
|
+
const nativePrice = priceMap[nativePriceId];
|
|
392
|
+
const tokenPriceId = _getAssetPriceId(nonNativeTokenPayFeeInfo);
|
|
393
|
+
const tokenDecimals = _getAssetDecimals(nonNativeTokenPayFeeInfo);
|
|
394
|
+
const tokenPrice = priceMap[tokenPriceId];
|
|
395
|
+
const rate = new BigN(nativePrice).div(tokenPrice).multipliedBy(10 ** (tokenDecimals - nativeDecimals)).toFixed();
|
|
396
|
+
estimateFee.decimals = _getAssetDecimals(nonNativeTokenPayFeeInfo);
|
|
397
|
+
estimateFee.symbol = _getAssetSymbol(nonNativeTokenPayFeeInfo);
|
|
398
|
+
estimateFee.value = new BigN(estimateFee.value).multipliedBy(rate).toFixed(0);
|
|
385
399
|
}
|
|
386
400
|
return estimateFee;
|
|
387
401
|
}
|
|
@@ -421,10 +435,11 @@ export function checkBalanceWithTransactionFee(validationResponse, transactionIn
|
|
|
421
435
|
edAsWarning,
|
|
422
436
|
extrinsicType,
|
|
423
437
|
isTransferAll,
|
|
424
|
-
|
|
425
|
-
|
|
438
|
+
skipFeeValidation,
|
|
439
|
+
tokenPayFeeSlug
|
|
426
440
|
} = transactionInput;
|
|
427
|
-
if (skipFeeValidation ||
|
|
441
|
+
if (skipFeeValidation || tokenPayFeeSlug && !_isNativeTokenBySlug(tokenPayFeeSlug)) {
|
|
442
|
+
// todo: need improve: input should be balance of fee token and check this again
|
|
428
443
|
return;
|
|
429
444
|
}
|
|
430
445
|
const bnFee = new BigN(validationResponse.estimateFee.value);
|