@subwallet/extension-base 1.3.41-0 → 1.3.42-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 +121 -4
- package/background/KoniTypes.js +18 -0
- package/background/errors/BitcoinProviderError.d.ts +6 -0
- package/background/errors/BitcoinProviderError.js +47 -0
- package/cjs/background/KoniTypes.js +20 -1
- package/cjs/background/errors/BitcoinProviderError.js +54 -0
- package/cjs/constants/bitcoin.js +22 -0
- package/cjs/constants/index.js +16 -1
- package/cjs/core/logic-validation/recipientAddress.js +9 -0
- package/cjs/core/logic-validation/transfer.js +25 -5
- package/cjs/core/types.js +1 -0
- package/cjs/core/utils.js +15 -1
- package/cjs/koni/background/handlers/Extension.js +59 -3
- package/cjs/koni/background/handlers/State.js +52 -11
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/bitcoin.js +94 -0
- package/cjs/services/balance-service/helpers/subscribe/index.js +19 -7
- package/cjs/services/balance-service/index.js +32 -4
- package/cjs/services/balance-service/transfer/bitcoin-transfer.js +119 -0
- package/cjs/services/balance-service/transfer/token.js +2 -0
- package/cjs/services/base/types.js +2 -0
- package/cjs/services/chain-service/constants.js +14 -3
- package/cjs/services/chain-service/handler/bitcoin/BitcoinApi.js +105 -0
- package/cjs/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +78 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +371 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +19 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +368 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +302 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
- package/cjs/services/chain-service/index.js +27 -3
- package/cjs/services/chain-service/utils/index.js +57 -4
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/event-service/index.js +4 -0
- package/cjs/services/fee-service/service.js +8 -3
- package/cjs/services/hiro-service/index.js +96 -0
- package/cjs/services/hiro-service/utils/index.js +85 -0
- package/cjs/services/history-service/bitcoin-history.js +58 -0
- package/cjs/services/history-service/helpers/recoverHistoryStatus.js +96 -4
- package/cjs/services/history-service/index.js +41 -3
- package/cjs/services/keyring-service/context/handlers/Derive.js +1 -1
- package/cjs/services/keyring-service/context/handlers/Migration.js +2 -2
- package/cjs/services/keyring-service/context/handlers/Mnemonic.js +4 -3
- package/cjs/services/migration-service/scripts/MigrateNewUnifiedAccount.js +29 -0
- package/cjs/services/migration-service/scripts/index.js +3 -1
- package/cjs/services/request-service/handler/BitcoinRequestHandler.js +440 -0
- package/cjs/services/request-service/index.js +29 -3
- package/cjs/services/rune-service/index.js +105 -0
- package/cjs/services/transaction-service/helpers/index.js +7 -1
- package/cjs/services/transaction-service/index.js +136 -15
- package/cjs/services/transaction-service/utils.js +6 -3
- package/cjs/strategy/api-request-strategy/context/base.js +31 -0
- package/cjs/strategy/api-request-strategy/index.js +90 -0
- package/cjs/strategy/api-request-strategy/types.js +1 -0
- package/cjs/strategy/api-request-strategy/utils/index.js +33 -0
- package/cjs/types/account/info/keyring.js +1 -1
- package/cjs/types/bitcoin.js +24 -0
- package/cjs/types/fee/bitcoin.js +1 -0
- package/cjs/types/fee/index.js +11 -0
- package/cjs/types/index.js +11 -0
- package/cjs/utils/account/analyze.js +3 -3
- package/cjs/utils/account/common.js +16 -6
- package/cjs/utils/account/derive/info/solo.js +68 -19
- package/cjs/utils/account/derive/info/unified.js +2 -0
- package/cjs/utils/account/derive/validate.js +70 -2
- package/cjs/utils/account/transform.js +11 -5
- package/cjs/utils/bitcoin/common.js +98 -0
- package/cjs/utils/bitcoin/fee.js +21 -0
- package/cjs/utils/bitcoin/index.js +38 -0
- package/cjs/utils/bitcoin/utxo-management.js +281 -0
- package/cjs/utils/fee/transfer.js +48 -0
- package/cjs/utils/index.js +15 -1
- package/constants/bitcoin.d.ts +3 -0
- package/constants/bitcoin.js +13 -0
- package/constants/index.d.ts +2 -0
- package/constants/index.js +3 -1
- package/core/logic-validation/recipientAddress.js +10 -1
- package/core/logic-validation/transfer.d.ts +2 -2
- package/core/logic-validation/transfer.js +27 -7
- package/core/types.d.ts +1 -0
- package/core/types.js +1 -0
- package/core/utils.d.ts +1 -0
- package/core/utils.js +15 -2
- package/koni/background/handlers/Extension.d.ts +2 -0
- package/koni/background/handlers/Extension.js +58 -4
- package/koni/background/handlers/State.d.ts +7 -3
- package/koni/background/handlers/State.js +52 -12
- package/package.json +144 -8
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/bitcoin.d.ts +2 -0
- package/services/balance-service/helpers/subscribe/bitcoin.js +87 -0
- package/services/balance-service/helpers/subscribe/index.d.ts +2 -2
- package/services/balance-service/helpers/subscribe/index.js +20 -8
- package/services/balance-service/index.d.ts +2 -0
- package/services/balance-service/index.js +32 -4
- package/services/balance-service/transfer/bitcoin-transfer.d.ts +14 -0
- package/services/balance-service/transfer/bitcoin-transfer.js +112 -0
- package/services/balance-service/transfer/token.js +2 -0
- package/services/base/types.d.ts +2 -0
- package/services/base/types.js +2 -0
- package/services/chain-service/constants.d.ts +6 -0
- package/services/chain-service/constants.js +8 -2
- package/services/chain-service/handler/bitcoin/BitcoinApi.d.ts +31 -0
- package/services/chain-service/handler/bitcoin/BitcoinApi.js +98 -0
- package/services/chain-service/handler/bitcoin/BitcoinChainHandler.d.ts +16 -0
- package/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +70 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +362 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.d.ts +2 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +5 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +359 -0
- package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +293 -0
- package/services/chain-service/handler/bitcoin/strategy/types.d.ts +291 -0
- package/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
- package/services/chain-service/index.d.ts +3 -0
- package/services/chain-service/index.js +31 -5
- package/services/chain-service/types.d.ts +20 -0
- package/services/chain-service/utils/index.d.ts +4 -0
- package/services/chain-service/utils/index.js +50 -4
- package/services/chain-service/utils/patch.js +1 -1
- package/services/event-service/index.d.ts +3 -0
- package/services/event-service/index.js +4 -0
- package/services/event-service/types.d.ts +3 -0
- package/services/fee-service/service.js +8 -3
- package/services/hiro-service/index.d.ts +17 -0
- package/services/hiro-service/index.js +88 -0
- package/services/hiro-service/utils/index.d.ts +6 -0
- package/services/hiro-service/utils/index.js +72 -0
- package/services/history-service/bitcoin-history.d.ts +4 -0
- package/services/history-service/bitcoin-history.js +52 -0
- package/services/history-service/helpers/recoverHistoryStatus.d.ts +3 -1
- package/services/history-service/helpers/recoverHistoryStatus.js +96 -4
- package/services/history-service/index.d.ts +1 -0
- package/services/history-service/index.js +42 -4
- package/services/keyring-service/context/handlers/Derive.js +2 -2
- package/services/keyring-service/context/handlers/Migration.js +2 -2
- package/services/keyring-service/context/handlers/Mnemonic.js +4 -3
- package/services/migration-service/scripts/MigrateNewUnifiedAccount.d.ts +4 -0
- package/services/migration-service/scripts/MigrateNewUnifiedAccount.js +21 -0
- package/services/migration-service/scripts/index.js +3 -1
- package/services/request-service/handler/BitcoinRequestHandler.d.ts +23 -0
- package/services/request-service/handler/BitcoinRequestHandler.js +427 -0
- package/services/request-service/index.d.ts +9 -2
- package/services/request-service/index.js +25 -3
- package/services/rune-service/index.d.ts +17 -0
- package/services/rune-service/index.js +97 -0
- package/services/transaction-service/helpers/index.d.ts +3 -1
- package/services/transaction-service/helpers/index.js +5 -0
- package/services/transaction-service/index.d.ts +3 -5
- package/services/transaction-service/index.js +135 -16
- package/services/transaction-service/types.d.ts +12 -2
- package/services/transaction-service/utils.js +7 -4
- package/strategy/api-request-strategy/context/base.d.ts +15 -0
- package/strategy/api-request-strategy/context/base.js +24 -0
- package/strategy/api-request-strategy/index.d.ts +15 -0
- package/strategy/api-request-strategy/index.js +83 -0
- package/strategy/api-request-strategy/types.d.ts +22 -0
- package/strategy/api-request-strategy/types.js +1 -0
- package/strategy/api-request-strategy/utils/index.d.ts +2 -0
- package/strategy/api-request-strategy/utils/index.js +23 -0
- package/types/account/info/keyring.d.ts +1 -1
- package/types/account/info/keyring.js +1 -1
- package/types/balance/index.d.ts +4 -1
- package/types/balance/transfer.d.ts +17 -0
- package/types/bitcoin.d.ts +93 -0
- package/types/bitcoin.js +17 -0
- package/types/fee/base.d.ts +4 -1
- package/types/fee/bitcoin.d.ts +18 -0
- package/types/fee/bitcoin.js +1 -0
- package/types/fee/index.d.ts +1 -0
- package/types/fee/index.js +2 -1
- package/types/fee/subscription.d.ts +4 -3
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/utils/account/analyze.js +4 -4
- package/utils/account/common.d.ts +7 -8
- package/utils/account/common.js +16 -6
- package/utils/account/derive/info/solo.js +70 -21
- package/utils/account/derive/info/unified.js +2 -0
- package/utils/account/derive/validate.d.ts +1 -0
- package/utils/account/derive/validate.js +68 -1
- package/utils/account/transform.d.ts +1 -1
- package/utils/account/transform.js +11 -5
- package/utils/bitcoin/common.d.ts +22 -0
- package/utils/bitcoin/common.js +88 -0
- package/utils/bitcoin/fee.d.ts +2 -0
- package/utils/bitcoin/fee.js +14 -0
- package/utils/bitcoin/index.d.ts +3 -0
- package/utils/bitcoin/index.js +6 -0
- package/utils/bitcoin/utxo-management.d.ts +33 -0
- package/utils/bitcoin/utxo-management.js +266 -0
- package/utils/fee/transfer.d.ts +3 -1
- package/utils/fee/transfer.js +47 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +6 -3
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.determineUtxosForSpend = determineUtxosForSpend;
|
|
8
|
+
exports.determineUtxosForSpendAll = determineUtxosForSpendAll;
|
|
9
|
+
exports.filterOutPendingTxsUtxos = filterOutPendingTxsUtxos;
|
|
10
|
+
exports.filterUneconomicalUtxos = filterUneconomicalUtxos;
|
|
11
|
+
exports.filteredOutTxsUtxos = filteredOutTxsUtxos;
|
|
12
|
+
exports.getInscriptionUtxos = getInscriptionUtxos;
|
|
13
|
+
exports.getRuneUtxos = getRuneUtxos;
|
|
14
|
+
var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
|
|
15
|
+
var _constants = require("@subwallet/extension-base/constants");
|
|
16
|
+
var _types = require("@subwallet/extension-base/types");
|
|
17
|
+
var _utils = require("@subwallet/extension-base/utils");
|
|
18
|
+
var _types2 = require("@subwallet/keyring/types");
|
|
19
|
+
var _utils2 = require("@subwallet/keyring/utils");
|
|
20
|
+
var _bignumber = _interopRequireDefault(require("bignumber.js"));
|
|
21
|
+
var _common = require("./common");
|
|
22
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
23
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
24
|
+
|
|
25
|
+
// https://github.com/leather-wallet/extension/blob/dev/src/app/common/transactions/bitcoin/utils.ts
|
|
26
|
+
// Check if the spendable amount drops when adding a utxo. If it drops, don't use that utxo.
|
|
27
|
+
// Method might be not particularly efficient as it would
|
|
28
|
+
// go through the utxo array multiple times, but it's reliable.
|
|
29
|
+
function filterUneconomicalUtxos(_ref) {
|
|
30
|
+
let {
|
|
31
|
+
feeRate,
|
|
32
|
+
recipients,
|
|
33
|
+
sender,
|
|
34
|
+
utxos
|
|
35
|
+
} = _ref;
|
|
36
|
+
const addressInfo = (0, _utils2.validateBitcoinAddress)(sender) ? (0, _utils2.getBitcoinAddressInfo)(sender) : null;
|
|
37
|
+
const inputAddressTypeWithFallback = addressInfo ? addressInfo.type : _types2.BitcoinAddressType.p2wpkh;
|
|
38
|
+
const filteredAndSortUtxos = utxos.filter(utxo => utxo.value >= _constants.BTC_DUST_AMOUNT[inputAddressTypeWithFallback]).sort((a, b) => a.value - b.value); // ascending order
|
|
39
|
+
|
|
40
|
+
return filteredAndSortUtxos.reduce((utxos, utxo, currentIndex) => {
|
|
41
|
+
const utxosWithout = utxos.filter(u => u.txid !== utxo.txid);
|
|
42
|
+
const {
|
|
43
|
+
spendableAmount: spendableAmountWithout
|
|
44
|
+
} = (0, _common.getSpendableAmount)({
|
|
45
|
+
utxos: utxosWithout,
|
|
46
|
+
feeRate,
|
|
47
|
+
recipients,
|
|
48
|
+
sender
|
|
49
|
+
});
|
|
50
|
+
const {
|
|
51
|
+
spendableAmount
|
|
52
|
+
} = (0, _common.getSpendableAmount)({
|
|
53
|
+
utxos,
|
|
54
|
+
feeRate,
|
|
55
|
+
recipients,
|
|
56
|
+
sender
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// console.log(utxosWithout, feeWithout, spendableAmountWithout.toString());
|
|
60
|
+
// console.log(utxos, fee, spendableAmount.toString());
|
|
61
|
+
|
|
62
|
+
if (spendableAmount.lte(0)) {
|
|
63
|
+
return utxosWithout;
|
|
64
|
+
} else {
|
|
65
|
+
// if spendable amount becomes bigger, do not use that utxo
|
|
66
|
+
return spendableAmountWithout.gt(spendableAmount) ? utxosWithout : utxos;
|
|
67
|
+
}
|
|
68
|
+
}, [...filteredAndSortUtxos]).reverse();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// https://github.com/leather-wallet/extension/blob/dev/src/app/common/transactions/bitcoin/coinselect/local-coin-selection.ts
|
|
72
|
+
function determineUtxosForSpendAll(_ref2) {
|
|
73
|
+
let {
|
|
74
|
+
feeRate,
|
|
75
|
+
recipient,
|
|
76
|
+
sender,
|
|
77
|
+
utxos
|
|
78
|
+
} = _ref2;
|
|
79
|
+
if (!(0, _utils2.validateBitcoinAddress)(recipient)) {
|
|
80
|
+
throw new Error('Cannot calculate spend of invalid address type');
|
|
81
|
+
}
|
|
82
|
+
const recipientAddressInfo = (0, _utils2.getBitcoinAddressInfo)(recipient);
|
|
83
|
+
const recipientDustLimit = _constants.BTC_DUST_AMOUNT[recipientAddressInfo.type] || 546;
|
|
84
|
+
const recipients = [recipient];
|
|
85
|
+
const filteredUtxos = filterUneconomicalUtxos({
|
|
86
|
+
utxos,
|
|
87
|
+
feeRate,
|
|
88
|
+
recipients,
|
|
89
|
+
sender
|
|
90
|
+
});
|
|
91
|
+
const sizeInfo = (0, _common.getSizeInfo)({
|
|
92
|
+
sender,
|
|
93
|
+
inputLength: filteredUtxos.length,
|
|
94
|
+
recipients
|
|
95
|
+
});
|
|
96
|
+
const amount = filteredUtxos.reduce((acc, utxo) => acc + utxo.value, 0) - Math.ceil(sizeInfo.txVBytes * feeRate);
|
|
97
|
+
if (amount <= 0) {
|
|
98
|
+
throw new _types.InsufficientFundsError();
|
|
99
|
+
}
|
|
100
|
+
if (amount < recipientDustLimit) {
|
|
101
|
+
const atLeastStr = (0, _utils.formatNumber)(recipientDustLimit, 8, _utils.balanceFormatter, {
|
|
102
|
+
maxNumberFormat: 8,
|
|
103
|
+
minNumberFormat: 8
|
|
104
|
+
});
|
|
105
|
+
throw new _TransactionError.TransactionError(_types.TransferTxErrorType.NOT_ENOUGH_VALUE, `You must transfer at least ${atLeastStr} BTC`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Fee has already been deducted from the amount with send all
|
|
109
|
+
const outputs = [{
|
|
110
|
+
value: amount,
|
|
111
|
+
address: recipient
|
|
112
|
+
}];
|
|
113
|
+
const fee = Math.ceil(sizeInfo.txVBytes * feeRate);
|
|
114
|
+
return {
|
|
115
|
+
inputs: filteredUtxos,
|
|
116
|
+
outputs,
|
|
117
|
+
size: sizeInfo.txVBytes,
|
|
118
|
+
fee,
|
|
119
|
+
isCustomFeeRate: false
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// https://github.com/leather-wallet/extension/blob/dev/src/app/common/transactions/bitcoin/coinselect/local-coin-selection.ts
|
|
124
|
+
function determineUtxosForSpend(_ref3) {
|
|
125
|
+
let {
|
|
126
|
+
amount,
|
|
127
|
+
feeRate,
|
|
128
|
+
recipient,
|
|
129
|
+
sender,
|
|
130
|
+
utxos
|
|
131
|
+
} = _ref3;
|
|
132
|
+
if (!(0, _utils2.validateBitcoinAddress)(recipient)) {
|
|
133
|
+
throw new Error('Cannot calculate spend of invalid address type');
|
|
134
|
+
}
|
|
135
|
+
const recipientAddressInfo = (0, _utils2.getBitcoinAddressInfo)(recipient);
|
|
136
|
+
const recipientDustLimit = _constants.BTC_DUST_AMOUNT[recipientAddressInfo.type] || 546;
|
|
137
|
+
if (amount < recipientDustLimit) {
|
|
138
|
+
const atLeastStr = (0, _utils.formatNumber)(recipientDustLimit, 8, _utils.balanceFormatter, {
|
|
139
|
+
maxNumberFormat: 8,
|
|
140
|
+
minNumberFormat: 8
|
|
141
|
+
});
|
|
142
|
+
throw new _TransactionError.TransactionError(_types.TransferTxErrorType.NOT_ENOUGH_VALUE, `You must transfer at least ${atLeastStr} BTC`);
|
|
143
|
+
}
|
|
144
|
+
const orderedUtxos = utxos.sort((a, b) => b.value - a.value);
|
|
145
|
+
const recipients = [recipient, sender];
|
|
146
|
+
const filteredUtxos = filterUneconomicalUtxos({
|
|
147
|
+
utxos: orderedUtxos,
|
|
148
|
+
feeRate,
|
|
149
|
+
recipients,
|
|
150
|
+
sender
|
|
151
|
+
});
|
|
152
|
+
const neededUtxos = [];
|
|
153
|
+
let sum = new _bignumber.default(0);
|
|
154
|
+
let sizeInfo = null;
|
|
155
|
+
for (const utxo of filteredUtxos) {
|
|
156
|
+
sizeInfo = (0, _common.getSizeInfo)({
|
|
157
|
+
inputLength: neededUtxos.length,
|
|
158
|
+
sender,
|
|
159
|
+
recipients
|
|
160
|
+
});
|
|
161
|
+
const currentValue = new _bignumber.default(amount).plus(Math.ceil(sizeInfo.txVBytes * feeRate));
|
|
162
|
+
if (sum.gte(currentValue)) {
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
sum = sum.plus(utxo.value);
|
|
166
|
+
neededUtxos.push(utxo);
|
|
167
|
+
|
|
168
|
+
// re calculate size info, some case array end
|
|
169
|
+
sizeInfo = (0, _common.getSizeInfo)({
|
|
170
|
+
inputLength: neededUtxos.length,
|
|
171
|
+
sender,
|
|
172
|
+
recipients
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (!sizeInfo) {
|
|
176
|
+
throw new _types.InsufficientFundsError();
|
|
177
|
+
}
|
|
178
|
+
const fee = Math.ceil(sizeInfo.txVBytes * feeRate);
|
|
179
|
+
const amountLeft = sum.minus(amount).minus(fee);
|
|
180
|
+
if (amountLeft.lte(0)) {
|
|
181
|
+
throw new _types.InsufficientFundsError();
|
|
182
|
+
}
|
|
183
|
+
const senderAddressInfo = (0, _utils2.getBitcoinAddressInfo)(sender);
|
|
184
|
+
const dustLimit = _constants.BTC_DUST_AMOUNT[senderAddressInfo.type] || 546;
|
|
185
|
+
const outputs = [
|
|
186
|
+
// outputs[0] = the desired amount going to recipient
|
|
187
|
+
{
|
|
188
|
+
value: amount,
|
|
189
|
+
address: recipient
|
|
190
|
+
}];
|
|
191
|
+
if (amountLeft.gte(dustLimit)) {
|
|
192
|
+
// outputs[1] = the remainder to be returned to a change address
|
|
193
|
+
outputs.push({
|
|
194
|
+
value: amountLeft.toNumber(),
|
|
195
|
+
address: sender
|
|
196
|
+
});
|
|
197
|
+
} else {
|
|
198
|
+
// Todo: This solution for improve later, current throw error
|
|
199
|
+
// // Increase the fee to use the remaining balance
|
|
200
|
+
console.warn(`Change output of ${amountLeft.toString()} satoshis is below dust limit (${dustLimit} satoshis for ${senderAddressInfo.type}). Omitting change output.`);
|
|
201
|
+
//
|
|
202
|
+
sizeInfo = (0, _common.getSizeInfo)({
|
|
203
|
+
inputLength: neededUtxos.length,
|
|
204
|
+
sender,
|
|
205
|
+
recipients: recipients.slice(0, 1)
|
|
206
|
+
});
|
|
207
|
+
const newFee = sum.minus(amount).toNumber();
|
|
208
|
+
return {
|
|
209
|
+
filteredUtxos,
|
|
210
|
+
inputs: neededUtxos,
|
|
211
|
+
outputs,
|
|
212
|
+
size: sizeInfo.txVBytes,
|
|
213
|
+
fee: newFee,
|
|
214
|
+
isCustomFeeRate: true
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
filteredUtxos,
|
|
219
|
+
inputs: neededUtxos,
|
|
220
|
+
outputs,
|
|
221
|
+
size: sizeInfo.txVBytes,
|
|
222
|
+
fee,
|
|
223
|
+
isCustomFeeRate: false
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function filterOutPendingTxsUtxos(utxos) {
|
|
227
|
+
return utxos.filter(utxo => utxo.status.confirmed);
|
|
228
|
+
}
|
|
229
|
+
function filteredOutTxsUtxos(allTxsUtxos, filteredOutTxsUtxos) {
|
|
230
|
+
if (!filteredOutTxsUtxos.length) {
|
|
231
|
+
return allTxsUtxos;
|
|
232
|
+
}
|
|
233
|
+
const listFilterOut = filteredOutTxsUtxos.map(utxo => {
|
|
234
|
+
return `${utxo.txid}:${utxo.vout}`;
|
|
235
|
+
});
|
|
236
|
+
return allTxsUtxos.filter(element => !listFilterOut.includes(`${element.txid}:${element.vout}`));
|
|
237
|
+
}
|
|
238
|
+
async function getRuneUtxos(bitcoinApi, address) {
|
|
239
|
+
const responseRuneUtxos = await bitcoinApi.api.getRuneUtxos(address);
|
|
240
|
+
const runeUtxos = [];
|
|
241
|
+
responseRuneUtxos.forEach(responseRuneUtxo => {
|
|
242
|
+
const txid = responseRuneUtxo.txid;
|
|
243
|
+
const vout = responseRuneUtxo.vout;
|
|
244
|
+
const utxoValue = responseRuneUtxo.satoshi;
|
|
245
|
+
if (txid && vout && utxoValue) {
|
|
246
|
+
const item = {
|
|
247
|
+
txid,
|
|
248
|
+
vout,
|
|
249
|
+
status: {
|
|
250
|
+
confirmed: true // not use in filter out rune utxos
|
|
251
|
+
},
|
|
252
|
+
|
|
253
|
+
value: utxoValue
|
|
254
|
+
};
|
|
255
|
+
runeUtxos.push(item);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
return runeUtxos;
|
|
259
|
+
}
|
|
260
|
+
async function getInscriptionUtxos(bitcoinApi, address) {
|
|
261
|
+
try {
|
|
262
|
+
const inscriptions = await bitcoinApi.api.getAddressInscriptions(address);
|
|
263
|
+
return inscriptions.map(inscription => {
|
|
264
|
+
const [txid, vout] = inscription.output.split(':');
|
|
265
|
+
return {
|
|
266
|
+
txid,
|
|
267
|
+
vout: parseInt(vout),
|
|
268
|
+
status: {
|
|
269
|
+
confirmed: true,
|
|
270
|
+
// not use in filter out inscription utxos
|
|
271
|
+
block_height: inscription.genesis_block_height,
|
|
272
|
+
block_hash: inscription.genesis_block_hash,
|
|
273
|
+
block_time: inscription.genesis_timestamp
|
|
274
|
+
},
|
|
275
|
+
value: parseInt(inscription.value)
|
|
276
|
+
};
|
|
277
|
+
});
|
|
278
|
+
} catch (e) {
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -8,6 +8,7 @@ exports.detectTransferTxType = exports.calculateXcmMaxTransferable = exports.cal
|
|
|
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");
|
|
11
|
+
var _bitcoinTransfer = require("@subwallet/extension-base/services/balance-service/transfer/bitcoin-transfer");
|
|
11
12
|
var _cardanoTransfer = require("@subwallet/extension-base/services/balance-service/transfer/cardano-transfer");
|
|
12
13
|
var _smartContract = require("@subwallet/extension-base/services/balance-service/transfer/smart-contract");
|
|
13
14
|
var _token = require("@subwallet/extension-base/services/balance-service/transfer/token");
|
|
@@ -24,10 +25,14 @@ var _tokenPayFee = require("@subwallet/extension-base/services/fee-service/utils
|
|
|
24
25
|
var _helpers = require("@subwallet/extension-base/services/transaction-service/helpers");
|
|
25
26
|
var _utils4 = require("@subwallet/extension-base/utils");
|
|
26
27
|
var _keyring = require("@subwallet/keyring");
|
|
28
|
+
var _validate = require("@subwallet/keyring/utils/address/validate");
|
|
27
29
|
var _bignumber = _interopRequireDefault(require("bignumber.js"));
|
|
30
|
+
var bitcoin = _interopRequireWildcard(require("bitcoinjs-lib"));
|
|
28
31
|
var _util = require("@polkadot/util");
|
|
29
32
|
var _utilCrypto = require("@polkadot/util-crypto");
|
|
30
33
|
var _combine = require("./combine");
|
|
34
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
35
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
31
36
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
32
37
|
// SPDX-License-Identifier: Apache-2.0
|
|
33
38
|
|
|
@@ -47,6 +52,8 @@ const detectTransferTxType = (srcToken, srcChain, destChain) => {
|
|
|
47
52
|
return 'ton';
|
|
48
53
|
} else if ((0, _utils2._isChainCardanoCompatible)(srcChain) && (0, _utils2._isTokenTransferredByCardano)(srcToken)) {
|
|
49
54
|
return 'cardano';
|
|
55
|
+
} else if ((0, _utils2._isChainBitcoinCompatible)(srcChain) && (0, _utils2._isTokenTransferredByBitcoin)(srcToken)) {
|
|
56
|
+
return 'bitcoin';
|
|
50
57
|
} else {
|
|
51
58
|
return 'substrate';
|
|
52
59
|
}
|
|
@@ -78,6 +85,7 @@ exports.calculateMaxTransferable = calculateMaxTransferable;
|
|
|
78
85
|
const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
79
86
|
const {
|
|
80
87
|
address,
|
|
88
|
+
bitcoinApi,
|
|
81
89
|
cardanoApi,
|
|
82
90
|
destChain,
|
|
83
91
|
evmApi,
|
|
@@ -89,6 +97,7 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
89
97
|
srcChain,
|
|
90
98
|
srcToken,
|
|
91
99
|
substrateApi,
|
|
100
|
+
to,
|
|
92
101
|
tonApi,
|
|
93
102
|
value
|
|
94
103
|
} = request;
|
|
@@ -158,6 +167,18 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
158
167
|
cardanoApi,
|
|
159
168
|
nativeTokenInfo: nativeToken
|
|
160
169
|
});
|
|
170
|
+
} else if ((0, _validate.isBitcoinAddress)(address) && (0, _utils2._isTokenTransferredByBitcoin)(srcToken)) {
|
|
171
|
+
const network = srcChain.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
|
|
172
|
+
[transaction] = await (0, _bitcoinTransfer.createBitcoinTransaction)({
|
|
173
|
+
chain: srcChain.slug,
|
|
174
|
+
from: address,
|
|
175
|
+
to: to || address,
|
|
176
|
+
value,
|
|
177
|
+
feeInfo: fee,
|
|
178
|
+
transferAll: false,
|
|
179
|
+
bitcoinApi,
|
|
180
|
+
network: network
|
|
181
|
+
});
|
|
161
182
|
} else {
|
|
162
183
|
[transaction] = await (0, _token.createSubstrateExtrinsic)({
|
|
163
184
|
transferAll: false,
|
|
@@ -203,6 +224,15 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
203
224
|
...fee,
|
|
204
225
|
estimatedFee
|
|
205
226
|
};
|
|
227
|
+
} else if (feeChainType === 'bitcoin') {
|
|
228
|
+
// Calculate fee for bitcoin transaction
|
|
229
|
+
// TODO: Support maxTransferable for bitcoin
|
|
230
|
+
estimatedFee = '0';
|
|
231
|
+
feeOptions = {
|
|
232
|
+
...fee,
|
|
233
|
+
vSize: 0,
|
|
234
|
+
estimatedFee
|
|
235
|
+
};
|
|
206
236
|
} else {
|
|
207
237
|
if (transaction) {
|
|
208
238
|
if ((0, _helpers.isTonTransaction)(transaction)) {
|
|
@@ -242,6 +272,12 @@ const calculateTransferMaxTransferable = async (id, request, freeBalance, fee) =
|
|
|
242
272
|
estimatedFee,
|
|
243
273
|
gasLimit: '0'
|
|
244
274
|
};
|
|
275
|
+
} else if (fee.type === 'bitcoin') {
|
|
276
|
+
feeOptions = {
|
|
277
|
+
...fee,
|
|
278
|
+
estimatedFee,
|
|
279
|
+
vSize: 0
|
|
280
|
+
};
|
|
245
281
|
} else {
|
|
246
282
|
feeOptions = {
|
|
247
283
|
...fee,
|
|
@@ -405,6 +441,12 @@ const calculateXcmMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
|
405
441
|
...fee,
|
|
406
442
|
estimatedFee
|
|
407
443
|
};
|
|
444
|
+
} else if (feeChainType === 'bitcoin') {
|
|
445
|
+
feeOptions = {
|
|
446
|
+
...fee,
|
|
447
|
+
estimatedFee,
|
|
448
|
+
vSize: 0
|
|
449
|
+
};
|
|
408
450
|
} else {
|
|
409
451
|
// Not implemented yet
|
|
410
452
|
estimatedFee = '0';
|
|
@@ -421,6 +463,12 @@ const calculateXcmMaxTransferable = async (id, request, freeBalance, fee) => {
|
|
|
421
463
|
estimatedFee,
|
|
422
464
|
gasLimit: '0'
|
|
423
465
|
};
|
|
466
|
+
} else if (fee.type === 'bitcoin') {
|
|
467
|
+
feeOptions = {
|
|
468
|
+
...fee,
|
|
469
|
+
estimatedFee,
|
|
470
|
+
vSize: 0
|
|
471
|
+
};
|
|
424
472
|
} else {
|
|
425
473
|
feeOptions = {
|
|
426
474
|
...fee,
|
package/cjs/utils/index.js
CHANGED
|
@@ -74,6 +74,7 @@ var _config = require("@subwallet/extension-base/koni/api/nft/config");
|
|
|
74
74
|
var _utils = require("@subwallet/extension-base/services/chain-service/utils");
|
|
75
75
|
var _account = require("@subwallet/extension-base/utils/account");
|
|
76
76
|
var _keyring = require("@subwallet/keyring");
|
|
77
|
+
var _validate = require("@subwallet/keyring/utils/address/validate");
|
|
77
78
|
var _i18next = require("i18next");
|
|
78
79
|
var _util = require("@polkadot/util");
|
|
79
80
|
var _utilCrypto = require("@polkadot/util-crypto");
|
|
@@ -330,6 +331,18 @@ Object.keys(_translate).forEach(function (key) {
|
|
|
330
331
|
}
|
|
331
332
|
});
|
|
332
333
|
});
|
|
334
|
+
var _bitcoin = require("./bitcoin");
|
|
335
|
+
Object.keys(_bitcoin).forEach(function (key) {
|
|
336
|
+
if (key === "default" || key === "__esModule") return;
|
|
337
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
338
|
+
if (key in exports && exports[key] === _bitcoin[key]) return;
|
|
339
|
+
Object.defineProperty(exports, key, {
|
|
340
|
+
enumerable: true,
|
|
341
|
+
get: function () {
|
|
342
|
+
return _bitcoin[key];
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
});
|
|
333
346
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
334
347
|
// SPDX-License-Identifier: Apache-2.0
|
|
335
348
|
|
|
@@ -590,7 +603,8 @@ function isAddressAndChainCompatible(address, chain) {
|
|
|
590
603
|
const isTonCompatible = (0, _keyring.isTonAddress)(address) && (0, _utils._isChainTonCompatible)(chain);
|
|
591
604
|
const isSubstrateCompatible = !(0, _utilCrypto.isEthereumAddress)(address) && !(0, _keyring.isTonAddress)(address) && (0, _utils._isChainSubstrateCompatible)(chain); // todo: need isSubstrateAddress util function to check exactly
|
|
592
605
|
const isCardanoCompatible = (0, _keyring.isCardanoAddress)(address) && (0, _utils._isChainCardanoCompatible)(chain);
|
|
593
|
-
|
|
606
|
+
const isBitcoinCompatible = (0, _validate.isBitcoinAddress)(address) && (0, _utils._isChainBitcoinCompatible)(chain);
|
|
607
|
+
return isEvmCompatible || isSubstrateCompatible || isTonCompatible || isCardanoCompatible || isBitcoinCompatible;
|
|
594
608
|
}
|
|
595
609
|
function getDomainFromUrl(url) {
|
|
596
610
|
return url.replace(/^(https?:\/\/)?(www\.)?/, '').split('/')[0];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// https://bitcoin.stackexchange.com/a/41082/139277
|
|
5
|
+
import { BitcoinAddressType } from '@subwallet/keyring/types';
|
|
6
|
+
export const BTC_DUST_AMOUNT = {
|
|
7
|
+
[BitcoinAddressType.p2pkh]: 546,
|
|
8
|
+
[BitcoinAddressType.p2sh]: 540,
|
|
9
|
+
[BitcoinAddressType.p2tr]: 330,
|
|
10
|
+
[BitcoinAddressType.p2wpkh]: 294,
|
|
11
|
+
[BitcoinAddressType.p2wsh]: 330
|
|
12
|
+
};
|
|
13
|
+
export const BITCOIN_DECIMAL = 8;
|
package/constants/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const CRON_AUTO_RECOVER_DOTSAMA_INTERVAL = 60000;
|
|
|
6
6
|
export declare const CRON_AUTO_RECOVER_WEB3_INTERVAL = 90000;
|
|
7
7
|
export declare const ACALA_REFRESH_CROWDLOAN_INTERVAL = 300000;
|
|
8
8
|
export declare const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
|
|
9
|
+
export declare const BITCOIN_REFRESH_BALANCE_INTERVAL = 600000;
|
|
9
10
|
export declare const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
|
|
10
11
|
export declare const CRON_REFRESH_NFT_INTERVAL = 7200000;
|
|
11
12
|
export declare const CRON_REFRESH_MKT_CAMPAIGN_INTERVAL: number;
|
|
@@ -48,3 +49,4 @@ export * from './signing';
|
|
|
48
49
|
export * from './staking';
|
|
49
50
|
export * from './storage';
|
|
50
51
|
export * from './remind-notification-time';
|
|
52
|
+
export * from './bitcoin';
|
package/constants/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export const CRON_AUTO_RECOVER_DOTSAMA_INTERVAL = 60000;
|
|
|
8
8
|
export const CRON_AUTO_RECOVER_WEB3_INTERVAL = 90000;
|
|
9
9
|
export const ACALA_REFRESH_CROWDLOAN_INTERVAL = 300000;
|
|
10
10
|
export const ASTAR_REFRESH_BALANCE_INTERVAL = 60000;
|
|
11
|
+
export const BITCOIN_REFRESH_BALANCE_INTERVAL = 600000;
|
|
11
12
|
export const SUB_TOKEN_REFRESH_BALANCE_INTERVAL = 60000;
|
|
12
13
|
export const CRON_REFRESH_NFT_INTERVAL = 7200000;
|
|
13
14
|
export const CRON_REFRESH_MKT_CAMPAIGN_INTERVAL = 15 * BASE_MINUTE_INTERVAL;
|
|
@@ -57,4 +58,5 @@ export * from "./environment.js";
|
|
|
57
58
|
export * from "./signing.js";
|
|
58
59
|
export * from "./staking.js";
|
|
59
60
|
export * from "./storage.js";
|
|
60
|
-
export * from "./remind-notification-time.js";
|
|
61
|
+
export * from "./remind-notification-time.js";
|
|
62
|
+
export * from "./bitcoin.js";
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
4
|
import { ActionType, ValidationCondition } from '@subwallet/extension-base/core/types';
|
|
5
|
-
import { _isAddress, _isNotDuplicateAddress, _isNotNull, _isSupportLedgerAccount, _isValidAddressForEcosystem, _isValidCardanoAddressFormat, _isValidSubstrateAddressFormat, _isValidTonAddressFormat } from '@subwallet/extension-base/core/utils';
|
|
5
|
+
import { _isAddress, _isNotDuplicateAddress, _isNotNull, _isSupportLedgerAccount, _isValidAddressForEcosystem, _isValidBitcoinAddressFormat, _isValidCardanoAddressFormat, _isValidSubstrateAddressFormat, _isValidTonAddressFormat } from '@subwallet/extension-base/core/utils';
|
|
6
6
|
import { AccountSignMode } from '@subwallet/extension-base/types';
|
|
7
7
|
import { detectTranslate } from '@subwallet/extension-base/utils';
|
|
8
8
|
import { isCardanoAddress, isSubstrateAddress, isTonAddress } from '@subwallet/keyring';
|
|
9
|
+
import { isBitcoinAddress } from '@subwallet/keyring/utils/address/validate';
|
|
9
10
|
function getConditions(validateRecipientParams) {
|
|
10
11
|
const {
|
|
11
12
|
account,
|
|
@@ -30,6 +31,9 @@ function getConditions(validateRecipientParams) {
|
|
|
30
31
|
if (isCardanoAddress(toAddress)) {
|
|
31
32
|
conditions.push(ValidationCondition.IS_VALID_CARDANO_ADDRESS_FORMAT);
|
|
32
33
|
}
|
|
34
|
+
if (isBitcoinAddress(toAddress)) {
|
|
35
|
+
conditions.push(ValidationCondition.IS_VALID_BITCOIN_ADDRESS_FORMAT);
|
|
36
|
+
}
|
|
33
37
|
if (srcChain === destChainInfo.slug && isSendAction && !destChainInfo.tonInfo && !destChainInfo.cardanoInfo) {
|
|
34
38
|
conditions.push(ValidationCondition.IS_NOT_DUPLICATE_ADDRESS);
|
|
35
39
|
}
|
|
@@ -75,6 +79,11 @@ function getValidationFunctions(conditions) {
|
|
|
75
79
|
validationFunctions.push(_isValidCardanoAddressFormat);
|
|
76
80
|
break;
|
|
77
81
|
}
|
|
82
|
+
case ValidationCondition.IS_VALID_BITCOIN_ADDRESS_FORMAT:
|
|
83
|
+
{
|
|
84
|
+
validationFunctions.push(_isValidBitcoinAddressFormat);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
78
87
|
case ValidationCondition.IS_NOT_DUPLICATE_ADDRESS:
|
|
79
88
|
{
|
|
80
89
|
validationFunctions.push(_isNotDuplicateAddress);
|
|
@@ -5,7 +5,7 @@ import { TransactionWarning } from '@subwallet/extension-base/background/warning
|
|
|
5
5
|
import { FrameSystemAccountInfo } from '@subwallet/extension-base/core/substrate/types';
|
|
6
6
|
import { _EvmApi, _SubstrateApi, _TonApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
7
7
|
import { OptionalSWTransaction, SWTransactionInput, SWTransactionResponse } from '@subwallet/extension-base/services/transaction-service/types';
|
|
8
|
-
import {
|
|
8
|
+
import { FeeInfo } from '@subwallet/extension-base/types';
|
|
9
9
|
import { KeyringPair } from '@subwallet/keyring/types';
|
|
10
10
|
export declare function validateTransferRequest(tokenInfo: _ChainAsset, from: _Address, to: _Address, value: string | undefined, transferAll: boolean | undefined): TransactionError[];
|
|
11
11
|
export declare function additionalValidateTransferForRecipient(sendingTokenInfo: _ChainAsset, nativeTokenInfo: _ChainAsset, extrinsicType: ExtrinsicType, receiverSendingTokenKeepAliveBalance: bigint, transferAmount: bigint, senderSendingTokenTransferable?: bigint, receiverSystemAccountInfo?: FrameSystemAccountInfo, isSendingTokenSufficient?: boolean): [TransactionWarning[], TransactionError[]];
|
|
@@ -13,7 +13,7 @@ export declare function validateXcmTransferRequest(destTokenInfo: _ChainAsset |
|
|
|
13
13
|
export declare function checkSupportForFeature(validationResponse: SWTransactionResponse, blockedFeaturesList: string[], chainInfo: _ChainInfo): void;
|
|
14
14
|
export declare function checkSupportForAction(validationResponse: SWTransactionResponse, blockedActionsMap: Record<ExtrinsicType, string[]>): void;
|
|
15
15
|
export declare function checkSupportForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction): void;
|
|
16
|
-
export declare function estimateFeeForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi, substrateApi: _SubstrateApi, priceMap: Record<string, number>, feeInfo:
|
|
16
|
+
export declare function estimateFeeForTransaction(validationResponse: SWTransactionResponse, transaction: OptionalSWTransaction, chainInfo: _ChainInfo, evmApi: _EvmApi, substrateApi: _SubstrateApi, priceMap: Record<string, number>, feeInfo: FeeInfo, nativeTokenInfo: _ChainAsset, nonNativeTokenPayFeeInfo: _ChainAsset | undefined, isTransferLocalTokenAndPayThatTokenAsFee: boolean | undefined): Promise<FeeData>;
|
|
17
17
|
export declare function checkSigningAccountForTransaction(validationResponse: SWTransactionResponse, chainInfoMap: Record<string, _ChainInfo>): void;
|
|
18
18
|
export declare function checkBalanceWithTransactionFee(validationResponse: SWTransactionResponse, transactionInput: SWTransactionInput, nativeTokenInfo: _ChainAsset, nativeTokenAvailable: AmountData): void;
|
|
19
19
|
export declare function checkTonAddressBounceableAndAccountNotActive(tonApi: _TonApi, validationResponse: SWTransactionResponse): Promise<void>;
|
|
@@ -11,9 +11,9 @@ import { isBounceableAddress } from '@subwallet/extension-base/services/balance-
|
|
|
11
11
|
import { _TRANSFER_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
|
|
12
12
|
import { _getAssetDecimals, _getAssetPriceId, _getAssetSymbol, _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
|
-
import { isCardanoTransaction, isSubstrateTransaction, isTonTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
|
|
14
|
+
import { isBitcoinTransaction, isCardanoTransaction, isSubstrateTransaction, isTonTransaction } from '@subwallet/extension-base/services/transaction-service/helpers';
|
|
15
15
|
import { AccountSignMode, BasicTxErrorType, BasicTxWarningCode, TransferTxErrorType } from '@subwallet/extension-base/types';
|
|
16
|
-
import { balanceFormatter, combineEthFee, formatNumber, pairToAccount } from '@subwallet/extension-base/utils';
|
|
16
|
+
import { balanceFormatter, combineBitcoinFee, combineEthFee, formatNumber, getSizeInfo, pairToAccount } from '@subwallet/extension-base/utils';
|
|
17
17
|
import { isCardanoAddress, isTonAddress } from '@subwallet/keyring';
|
|
18
18
|
import { keyring } from '@subwallet/ui-keyring';
|
|
19
19
|
import BigN from 'bignumber.js';
|
|
@@ -312,6 +312,11 @@ export async function estimateFeeForTransaction(validationResponse, transaction,
|
|
|
312
312
|
} = _getChainNativeTokenBasicInfo(chainInfo);
|
|
313
313
|
estimateFee.decimals = decimals;
|
|
314
314
|
estimateFee.symbol = symbol;
|
|
315
|
+
const {
|
|
316
|
+
address,
|
|
317
|
+
feeCustom,
|
|
318
|
+
feeOption
|
|
319
|
+
} = validationResponse;
|
|
315
320
|
if (transaction) {
|
|
316
321
|
try {
|
|
317
322
|
if (isSubstrateTransaction(transaction)) {
|
|
@@ -321,13 +326,28 @@ export async function estimateFeeForTransaction(validationResponse, transaction,
|
|
|
321
326
|
estimateFee.value = transaction.estimateFee; // todo: might need to update logic estimate fee inside for future actions excluding normal transfer Ton and Jetton
|
|
322
327
|
} else if (isCardanoTransaction(transaction)) {
|
|
323
328
|
estimateFee.value = transaction.estimateCardanoFee;
|
|
329
|
+
} else if (isBitcoinTransaction(transaction)) {
|
|
330
|
+
const feeCombine = combineBitcoinFee(feeInfo, feeOption, feeCustom);
|
|
331
|
+
const recipients = [];
|
|
332
|
+
for (const txOutput of transaction.txOutputs) {
|
|
333
|
+
txOutput.address && recipients.push(txOutput.address);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// TODO: Need review
|
|
337
|
+
const sizeInfo = getSizeInfo({
|
|
338
|
+
inputLength: transaction.inputCount,
|
|
339
|
+
recipients: recipients,
|
|
340
|
+
sender: address
|
|
341
|
+
});
|
|
342
|
+
estimateFee.value = Math.ceil(feeCombine.feeRate * sizeInfo.txVBytes).toString();
|
|
324
343
|
} else {
|
|
325
|
-
const
|
|
344
|
+
const _transaction = transaction;
|
|
345
|
+
const gasLimit = _transaction.gas || (await evmApi.api.eth.estimateGas(_transaction));
|
|
326
346
|
const feeCombine = combineEthFee(feeInfo, validationResponse.feeOption, validationResponse.feeCustom);
|
|
327
|
-
if (
|
|
328
|
-
estimateFee.value = new BigN(
|
|
329
|
-
} else if (
|
|
330
|
-
estimateFee.value = new BigN(
|
|
347
|
+
if (_transaction.maxFeePerGas) {
|
|
348
|
+
estimateFee.value = new BigN(_transaction.maxFeePerGas.toString()).multipliedBy(gasLimit).toFixed(0);
|
|
349
|
+
} else if (_transaction.gasPrice) {
|
|
350
|
+
estimateFee.value = new BigN(_transaction.gasPrice.toString()).multipliedBy(gasLimit).toFixed(0);
|
|
331
351
|
} else {
|
|
332
352
|
if (feeCombine.maxFeePerGas) {
|
|
333
353
|
const maxFee = new BigN(feeCombine.maxFeePerGas); // TODO: Need review
|
package/core/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare enum ValidationCondition {
|
|
|
8
8
|
IS_VALID_SUBSTRATE_ADDRESS_FORMAT = "IS_VALID_SUBSTRATE_ADDRESS_FORMAT",
|
|
9
9
|
IS_VALID_TON_ADDRESS_FORMAT = "IS_VALID_TON_ADDRESS_FORMAT",
|
|
10
10
|
IS_VALID_CARDANO_ADDRESS_FORMAT = "IS_VALID_CARDANO_ADDRESS_FORMAT",
|
|
11
|
+
IS_VALID_BITCOIN_ADDRESS_FORMAT = "IS_VALID_BITCOIN_ADDRESS_FORMAT",
|
|
11
12
|
IS_NOT_DUPLICATE_ADDRESS = "IS_NOT_DUPLICATE_ADDRESS",
|
|
12
13
|
IS_SUPPORT_LEDGER_ACCOUNT = "IS_SUPPORT_LEDGER_ACCOUNT"
|
|
13
14
|
}
|
package/core/types.js
CHANGED
|
@@ -9,6 +9,7 @@ export let ValidationCondition;
|
|
|
9
9
|
ValidationCondition["IS_VALID_SUBSTRATE_ADDRESS_FORMAT"] = "IS_VALID_SUBSTRATE_ADDRESS_FORMAT";
|
|
10
10
|
ValidationCondition["IS_VALID_TON_ADDRESS_FORMAT"] = "IS_VALID_TON_ADDRESS_FORMAT";
|
|
11
11
|
ValidationCondition["IS_VALID_CARDANO_ADDRESS_FORMAT"] = "IS_VALID_CARDANO_ADDRESS_FORMAT";
|
|
12
|
+
ValidationCondition["IS_VALID_BITCOIN_ADDRESS_FORMAT"] = "IS_VALID_BITCOIN_ADDRESS_FORMAT";
|
|
12
13
|
ValidationCondition["IS_NOT_DUPLICATE_ADDRESS"] = "IS_NOT_DUPLICATE_ADDRESS";
|
|
13
14
|
ValidationCondition["IS_SUPPORT_LEDGER_ACCOUNT"] = "IS_SUPPORT_LEDGER_ACCOUNT";
|
|
14
15
|
})(ValidationCondition || (ValidationCondition = {}));
|
package/core/utils.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare function _isValidAddressForEcosystem(validateRecipientParams: Val
|
|
|
13
13
|
export declare function _isValidSubstrateAddressFormat(validateRecipientParams: ValidateRecipientParams): string;
|
|
14
14
|
export declare function _isValidTonAddressFormat(validateRecipientParams: ValidateRecipientParams): string;
|
|
15
15
|
export declare function _isValidCardanoAddressFormat(validateRecipientParams: ValidateRecipientParams): string;
|
|
16
|
+
export declare function _isValidBitcoinAddressFormat(validateRecipientParams: ValidateRecipientParams): string;
|
|
16
17
|
export declare function _isNotDuplicateAddress(validateRecipientParams: ValidateRecipientParams): string;
|
|
17
18
|
export declare function _isSupportLedgerAccount(validateRecipientParams: ValidateRecipientParams): string;
|
|
18
19
|
export declare const _isSufficientToken: (tokenInfo: _ChainAsset, substrateApi: _SubstrateApi, sufficientChain: SufficientChainsDetails) => Promise<boolean>;
|