@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,112 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
|
+
import { _BITCOIN_CHAIN_SLUG, _BITCOIN_NAME, _BITCOIN_TESTNET_NAME } from '@subwallet/extension-base/services/chain-service/constants';
|
|
6
|
+
import { combineBitcoinFee, determineUtxosForSpend, determineUtxosForSpendAll, getTransferableBitcoinUtxos } from '@subwallet/extension-base/utils';
|
|
7
|
+
import { BitcoinAddressType } from '@subwallet/keyring/types';
|
|
8
|
+
import { getBitcoinAddressInfo } from '@subwallet/keyring/utils';
|
|
9
|
+
import { keyring } from '@subwallet/ui-keyring';
|
|
10
|
+
import BigN from 'bignumber.js';
|
|
11
|
+
import { Psbt } from 'bitcoinjs-lib';
|
|
12
|
+
export async function createBitcoinTransaction(params) {
|
|
13
|
+
const {
|
|
14
|
+
bitcoinApi,
|
|
15
|
+
chain,
|
|
16
|
+
feeCustom: _feeCustom,
|
|
17
|
+
feeInfo: _feeInfo,
|
|
18
|
+
feeOption,
|
|
19
|
+
from,
|
|
20
|
+
network,
|
|
21
|
+
to,
|
|
22
|
+
transferAll,
|
|
23
|
+
value
|
|
24
|
+
} = params;
|
|
25
|
+
const feeCustom = _feeCustom;
|
|
26
|
+
const feeInfo = _feeInfo;
|
|
27
|
+
const bitcoinFee = combineBitcoinFee(feeInfo, feeOption, feeCustom);
|
|
28
|
+
const utxos = await getTransferableBitcoinUtxos(bitcoinApi, from);
|
|
29
|
+
try {
|
|
30
|
+
const amountValue = parseFloat(value);
|
|
31
|
+
const determineUtxosArgs = {
|
|
32
|
+
amount: amountValue,
|
|
33
|
+
feeRate: bitcoinFee.feeRate,
|
|
34
|
+
recipient: to,
|
|
35
|
+
sender: from,
|
|
36
|
+
utxos
|
|
37
|
+
};
|
|
38
|
+
const {
|
|
39
|
+
fee,
|
|
40
|
+
inputs,
|
|
41
|
+
isCustomFeeRate,
|
|
42
|
+
outputs,
|
|
43
|
+
size
|
|
44
|
+
} = transferAll ? determineUtxosForSpendAll(determineUtxosArgs) : determineUtxosForSpend(determineUtxosArgs);
|
|
45
|
+
const pair = keyring.getPair(from);
|
|
46
|
+
const tx = new Psbt({
|
|
47
|
+
network
|
|
48
|
+
});
|
|
49
|
+
let transferAmount = new BigN(0);
|
|
50
|
+
for (const input of inputs) {
|
|
51
|
+
const addressInfo = getBitcoinAddressInfo(pair.address);
|
|
52
|
+
if (addressInfo.type === BitcoinAddressType.p2pkh || addressInfo.type === BitcoinAddressType.p2sh) {
|
|
53
|
+
// BIP-44 (Legacy)
|
|
54
|
+
const hex = await bitcoinApi.api.getTxHex(input.txid);
|
|
55
|
+
tx.addInput({
|
|
56
|
+
hash: input.txid,
|
|
57
|
+
index: input.vout,
|
|
58
|
+
nonWitnessUtxo: Buffer.from(hex, 'hex')
|
|
59
|
+
});
|
|
60
|
+
} else if (addressInfo.type === BitcoinAddressType.p2wpkh) {
|
|
61
|
+
// BIP-84 (Native SegWit)
|
|
62
|
+
tx.addInput({
|
|
63
|
+
hash: input.txid,
|
|
64
|
+
index: input.vout,
|
|
65
|
+
witnessUtxo: {
|
|
66
|
+
script: pair.bitcoin.output,
|
|
67
|
+
value: input.value
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
} else if (addressInfo.type === BitcoinAddressType.p2tr) {
|
|
71
|
+
// BIP-86 (Taproot)
|
|
72
|
+
tx.addInput({
|
|
73
|
+
hash: input.txid,
|
|
74
|
+
index: input.vout,
|
|
75
|
+
witnessUtxo: {
|
|
76
|
+
script: pair.bitcoin.output,
|
|
77
|
+
value: input.value // UTXO value in satoshis
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
tapInternalKey: pair.bitcoin.internalPubkey // X-only public key (32 bytes)
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
throw new Error(`Unsupported address type: ${addressInfo.type}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const output of outputs) {
|
|
87
|
+
tx.addOutput({
|
|
88
|
+
address: output.address || from,
|
|
89
|
+
value: output.value
|
|
90
|
+
});
|
|
91
|
+
if (output.address === to) {
|
|
92
|
+
transferAmount = transferAmount.plus(output.value);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const customFeeRate = fee / size;
|
|
96
|
+
const customFeeRateResult = isCustomFeeRate ? customFeeRate.toString() : undefined;
|
|
97
|
+
return [tx, transferAmount.toString(), customFeeRateResult];
|
|
98
|
+
} catch (e) {
|
|
99
|
+
if (e instanceof TransactionError) {
|
|
100
|
+
throw e;
|
|
101
|
+
}
|
|
102
|
+
console.warn('Failed to create Bitcoin transaction:', e);
|
|
103
|
+
throw new Error(`You don’t have enough BTC (${convertChainToSymbol(chain)}) for the transaction. Lower your BTC amount and try again`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function convertChainToSymbol(chain) {
|
|
107
|
+
if (chain === _BITCOIN_CHAIN_SLUG) {
|
|
108
|
+
return _BITCOIN_NAME;
|
|
109
|
+
} else {
|
|
110
|
+
return _BITCOIN_TESTNET_NAME;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -108,6 +108,8 @@ export const createSubstrateExtrinsic = async ({
|
|
|
108
108
|
transfer = api.tx.balances.transfer(to, new BN(value));
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
} else if (_TRANSFER_CHAIN_GROUP.truth.includes(networkKey)) {
|
|
112
|
+
transfer = api.tx.assetManager.transfer(to, _getTokenOnChainInfo(tokenInfo), value);
|
|
111
113
|
}
|
|
112
114
|
return [transfer, transferAmount || value];
|
|
113
115
|
};
|
package/services/base/types.d.ts
CHANGED
package/services/base/types.js
CHANGED
|
@@ -10,6 +10,8 @@ export let ServiceStatus;
|
|
|
10
10
|
ServiceStatus["INITIALIZED"] = "initialized";
|
|
11
11
|
ServiceStatus["STARTED"] = "started";
|
|
12
12
|
ServiceStatus["STARTING"] = "starting";
|
|
13
|
+
ServiceStatus["STARTED_FULL"] = "started_full";
|
|
14
|
+
ServiceStatus["STARTING_FULL"] = "starting_full";
|
|
13
15
|
ServiceStatus["STOPPED"] = "stopped";
|
|
14
16
|
ServiceStatus["STOPPING"] = "stopping";
|
|
15
17
|
})(ServiceStatus || (ServiceStatus = {}));
|
|
@@ -72,6 +72,7 @@ export declare const _TRANSFER_CHAIN_GROUP: {
|
|
|
72
72
|
pendulum: string[];
|
|
73
73
|
centrifuge: string[];
|
|
74
74
|
disable_transfer: string[];
|
|
75
|
+
truth: string[];
|
|
75
76
|
};
|
|
76
77
|
export declare const _BALANCE_PARSING_CHAIN_GROUP: {
|
|
77
78
|
bobabeam: string[];
|
|
@@ -95,9 +96,14 @@ export declare const EVM_REFORMAT_DECIMALS: {
|
|
|
95
96
|
acala: string[];
|
|
96
97
|
};
|
|
97
98
|
export declare const LATEST_CHAIN_DATA_FETCHING_INTERVAL = 120000;
|
|
99
|
+
export declare const _BITCOIN_CHAIN_SLUG = "bitcoin";
|
|
100
|
+
export declare const _BITCOIN_TESTNET_CHAIN_SLUG = "bitcoinTestnet";
|
|
101
|
+
export declare const _BITCOIN_NAME = "Bitcoin";
|
|
102
|
+
export declare const _BITCOIN_TESTNET_NAME = "Bitcoin Testnet";
|
|
98
103
|
export declare const _CHAIN_INFO_SRC: string;
|
|
99
104
|
export declare const _CHAIN_ASSET_SRC: string;
|
|
100
105
|
export declare const _ASSET_REF_SRC: string;
|
|
101
106
|
export declare const _MULTI_CHAIN_ASSET_SRC: string;
|
|
102
107
|
export declare const _CHAIN_LOGO_MAP_SRC: string;
|
|
103
108
|
export declare const _ASSET_LOGO_MAP_SRC: string;
|
|
109
|
+
export declare const _BTC_SERVICE_TOKEN: string;
|
|
@@ -261,7 +261,8 @@ export const _TRANSFER_CHAIN_GROUP = {
|
|
|
261
261
|
avail: ['kate', 'goldberg_testnet'],
|
|
262
262
|
pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot', 'jamton'],
|
|
263
263
|
centrifuge: ['centrifuge'],
|
|
264
|
-
disable_transfer: ['crab', 'pangolin']
|
|
264
|
+
disable_transfer: ['crab', 'pangolin'],
|
|
265
|
+
truth: ['truth_network']
|
|
265
266
|
};
|
|
266
267
|
export const _BALANCE_PARSING_CHAIN_GROUP = {
|
|
267
268
|
bobabeam: ['bobabeam', 'bobabase']
|
|
@@ -302,9 +303,14 @@ export const LATEST_CHAIN_DATA_FETCHING_INTERVAL = 120000;
|
|
|
302
303
|
|
|
303
304
|
// TODO: review
|
|
304
305
|
const TARGET_BRANCH = process.env.NODE_ENV !== 'production' ? 'koni-dev' : 'master';
|
|
306
|
+
export const _BITCOIN_CHAIN_SLUG = 'bitcoin';
|
|
307
|
+
export const _BITCOIN_TESTNET_CHAIN_SLUG = 'bitcoinTestnet';
|
|
308
|
+
export const _BITCOIN_NAME = 'Bitcoin';
|
|
309
|
+
export const _BITCOIN_TESTNET_NAME = 'Bitcoin Testnet';
|
|
305
310
|
export const _CHAIN_INFO_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainInfo.json`;
|
|
306
311
|
export const _CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainAsset.json`;
|
|
307
312
|
export const _ASSET_REF_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetRef.json`;
|
|
308
313
|
export const _MULTI_CHAIN_ASSET_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/MultiChainAsset.json`;
|
|
309
314
|
export const _CHAIN_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/ChainLogoMap.json`;
|
|
310
|
-
export const _ASSET_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetLogoMap.json`;
|
|
315
|
+
export const _ASSET_LOGO_MAP_SRC = `https://raw.githubusercontent.com/Koniverse/SubWallet-Chain/${TARGET_BRANCH}/packages/chain-list/src/data/AssetLogoMap.json`;
|
|
316
|
+
export const _BTC_SERVICE_TOKEN = process.env.BTC_SERVICE_TOKEN || '';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BitcoinApiStrategy } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/types';
|
|
2
|
+
import { PromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
3
|
+
import { BehaviorSubject } from 'rxjs';
|
|
4
|
+
import { _ApiOptions } from '../../handler/types';
|
|
5
|
+
import { _BitcoinApi, _ChainConnectionStatus } from '../../types';
|
|
6
|
+
export declare class BitcoinApi implements _BitcoinApi {
|
|
7
|
+
chainSlug: string;
|
|
8
|
+
apiUrl: string;
|
|
9
|
+
apiError?: string;
|
|
10
|
+
apiRetry: number;
|
|
11
|
+
readonly isApiConnectedSubject: BehaviorSubject<boolean>;
|
|
12
|
+
readonly connectionStatusSubject: BehaviorSubject<_ChainConnectionStatus>;
|
|
13
|
+
isApiReady: boolean;
|
|
14
|
+
isApiReadyOnce: boolean;
|
|
15
|
+
isReadyHandler: PromiseHandler<_BitcoinApi>;
|
|
16
|
+
providerName: string;
|
|
17
|
+
api: BitcoinApiStrategy;
|
|
18
|
+
constructor(chainSlug: string, apiUrl: string, { providerName }?: _ApiOptions);
|
|
19
|
+
get isApiConnected(): boolean;
|
|
20
|
+
private createApiStrategy;
|
|
21
|
+
get connectionStatus(): _ChainConnectionStatus;
|
|
22
|
+
private updateConnectionStatus;
|
|
23
|
+
get isReady(): Promise<_BitcoinApi>;
|
|
24
|
+
updateApiUrl(apiUrl: string): Promise<void>;
|
|
25
|
+
recoverConnect(): Promise<void>;
|
|
26
|
+
connect(): void;
|
|
27
|
+
disconnect(): Promise<void>;
|
|
28
|
+
destroy(): Promise<void>;
|
|
29
|
+
onConnect(): void;
|
|
30
|
+
onDisconnect(): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { BlockStreamTestnetRequestStrategy, MempoolTestnetRequestStrategy } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet';
|
|
5
|
+
import { SubWalletMainnetRequestStrategy } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet';
|
|
6
|
+
import { createPromiseHandler } from '@subwallet/extension-base/utils/promise';
|
|
7
|
+
import { BehaviorSubject } from 'rxjs';
|
|
8
|
+
import { _ChainConnectionStatus } from "../../types.js";
|
|
9
|
+
|
|
10
|
+
// const isBlockStreamProvider = (apiUrl: string): boolean => apiUrl === 'https://blockstream-testnet.openbit.app' || apiUrl === 'https://electrs.openbit.app';
|
|
11
|
+
// const BLOCKSTREAM_TESTNET_API_URL = 'https://blockstream.info/testnet/api/';
|
|
12
|
+
// const MEMPOOL_TESTNET_V4_API_URL = 'https://mempool.space/testnet4/api/';
|
|
13
|
+
|
|
14
|
+
export class BitcoinApi {
|
|
15
|
+
apiRetry = 0;
|
|
16
|
+
isApiConnectedSubject = new BehaviorSubject(false);
|
|
17
|
+
connectionStatusSubject = new BehaviorSubject(_ChainConnectionStatus.DISCONNECTED);
|
|
18
|
+
isApiReady = false;
|
|
19
|
+
isApiReadyOnce = false;
|
|
20
|
+
constructor(chainSlug, apiUrl, {
|
|
21
|
+
providerName
|
|
22
|
+
} = {}) {
|
|
23
|
+
this.chainSlug = chainSlug;
|
|
24
|
+
this.apiUrl = apiUrl;
|
|
25
|
+
this.providerName = providerName || 'unknown';
|
|
26
|
+
this.isReadyHandler = createPromiseHandler();
|
|
27
|
+
this.api = this.createApiStrategy(apiUrl);
|
|
28
|
+
this.connect();
|
|
29
|
+
}
|
|
30
|
+
get isApiConnected() {
|
|
31
|
+
return this.isApiConnectedSubject.getValue();
|
|
32
|
+
}
|
|
33
|
+
createApiStrategy(apiUrl) {
|
|
34
|
+
const isTestnet = apiUrl.includes('testnet');
|
|
35
|
+
const isBlockstreamUrl = apiUrl.includes('blockstream');
|
|
36
|
+
if (isTestnet) {
|
|
37
|
+
return isBlockstreamUrl ? new BlockStreamTestnetRequestStrategy(apiUrl) : new MempoolTestnetRequestStrategy(apiUrl);
|
|
38
|
+
}
|
|
39
|
+
return new SubWalletMainnetRequestStrategy(apiUrl);
|
|
40
|
+
}
|
|
41
|
+
get connectionStatus() {
|
|
42
|
+
return this.connectionStatusSubject.getValue();
|
|
43
|
+
}
|
|
44
|
+
updateConnectionStatus(status) {
|
|
45
|
+
const isConnected = status === _ChainConnectionStatus.CONNECTED;
|
|
46
|
+
if (isConnected !== this.isApiConnectedSubject.value) {
|
|
47
|
+
this.isApiConnectedSubject.next(isConnected);
|
|
48
|
+
}
|
|
49
|
+
if (status !== this.connectionStatusSubject.value) {
|
|
50
|
+
this.connectionStatusSubject.next(status);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
get isReady() {
|
|
54
|
+
return this.isReadyHandler.promise;
|
|
55
|
+
}
|
|
56
|
+
async updateApiUrl(apiUrl) {
|
|
57
|
+
if (this.apiUrl === apiUrl) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
await this.disconnect();
|
|
61
|
+
this.apiUrl = apiUrl;
|
|
62
|
+
this.api = this.createApiStrategy(apiUrl);
|
|
63
|
+
this.connect();
|
|
64
|
+
}
|
|
65
|
+
async recoverConnect() {
|
|
66
|
+
await this.isReadyHandler.promise;
|
|
67
|
+
}
|
|
68
|
+
connect() {
|
|
69
|
+
this.updateConnectionStatus(_ChainConnectionStatus.CONNECTING);
|
|
70
|
+
this.onConnect();
|
|
71
|
+
}
|
|
72
|
+
async disconnect() {
|
|
73
|
+
this.onDisconnect();
|
|
74
|
+
this.updateConnectionStatus(_ChainConnectionStatus.DISCONNECTED);
|
|
75
|
+
return Promise.resolve();
|
|
76
|
+
}
|
|
77
|
+
destroy() {
|
|
78
|
+
return this.disconnect();
|
|
79
|
+
}
|
|
80
|
+
onConnect() {
|
|
81
|
+
if (!this.isApiConnected) {
|
|
82
|
+
console.log(`Connected to ${this.chainSlug} at ${this.apiUrl}`);
|
|
83
|
+
this.isApiReady = true;
|
|
84
|
+
if (this.isApiReadyOnce) {
|
|
85
|
+
this.isReadyHandler.resolve(this);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.updateConnectionStatus(_ChainConnectionStatus.CONNECTED);
|
|
89
|
+
}
|
|
90
|
+
onDisconnect() {
|
|
91
|
+
this.updateConnectionStatus(_ChainConnectionStatus.DISCONNECTED);
|
|
92
|
+
if (this.isApiConnected) {
|
|
93
|
+
console.warn(`Disconnected from ${this.chainSlug} of ${this.apiUrl}`);
|
|
94
|
+
this.isApiReady = false;
|
|
95
|
+
this.isReadyHandler = createPromiseHandler();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
2
|
+
import { AbstractChainHandler } from '../AbstractChainHandler';
|
|
3
|
+
import { _ApiOptions } from '../types';
|
|
4
|
+
import { BitcoinApi } from './BitcoinApi';
|
|
5
|
+
export declare class BitcoinChainHandler extends AbstractChainHandler {
|
|
6
|
+
private apiMap;
|
|
7
|
+
constructor(parent?: ChainService);
|
|
8
|
+
getApiMap(): Record<string, BitcoinApi>;
|
|
9
|
+
getApiByChain(chain: string): BitcoinApi;
|
|
10
|
+
setApi(chainSlug: string, api: BitcoinApi): void;
|
|
11
|
+
initApi(chainSlug: string, apiUrl: string, { onUpdateStatus, providerName }?: Omit<_ApiOptions, 'metadata'>): Promise<BitcoinApi>;
|
|
12
|
+
recoverApi(chainSlug: string): Promise<void>;
|
|
13
|
+
destroyApi(chain: string): void;
|
|
14
|
+
sleep(): Promise<void>;
|
|
15
|
+
wakeUp(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { AbstractChainHandler } from "../AbstractChainHandler.js";
|
|
5
|
+
import { BitcoinApi } from "./BitcoinApi.js";
|
|
6
|
+
export class BitcoinChainHandler extends AbstractChainHandler {
|
|
7
|
+
apiMap = {};
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line no-useless-constructor
|
|
10
|
+
constructor(parent) {
|
|
11
|
+
super(parent);
|
|
12
|
+
}
|
|
13
|
+
getApiMap() {
|
|
14
|
+
return this.apiMap;
|
|
15
|
+
}
|
|
16
|
+
getApiByChain(chain) {
|
|
17
|
+
return this.apiMap[chain];
|
|
18
|
+
}
|
|
19
|
+
setApi(chainSlug, api) {
|
|
20
|
+
this.apiMap[chainSlug] = api;
|
|
21
|
+
}
|
|
22
|
+
async initApi(chainSlug, apiUrl, {
|
|
23
|
+
onUpdateStatus,
|
|
24
|
+
providerName
|
|
25
|
+
} = {}) {
|
|
26
|
+
const existed = this.getApiByChain(chainSlug);
|
|
27
|
+
if (existed) {
|
|
28
|
+
existed.connect();
|
|
29
|
+
if (apiUrl !== existed.apiUrl) {
|
|
30
|
+
existed.updateApiUrl(apiUrl).catch(console.error);
|
|
31
|
+
}
|
|
32
|
+
return existed;
|
|
33
|
+
}
|
|
34
|
+
const apiObject = new BitcoinApi(chainSlug, apiUrl, {
|
|
35
|
+
providerName
|
|
36
|
+
});
|
|
37
|
+
apiObject.connectionStatusSubject.subscribe(this.handleConnection.bind(this, chainSlug));
|
|
38
|
+
apiObject.connectionStatusSubject.subscribe(onUpdateStatus);
|
|
39
|
+
return Promise.resolve(apiObject);
|
|
40
|
+
}
|
|
41
|
+
async recoverApi(chainSlug) {
|
|
42
|
+
const existed = this.getApiByChain(chainSlug);
|
|
43
|
+
if (existed && !existed.isApiReadyOnce) {
|
|
44
|
+
console.log(`Reconnect ${existed.providerName || existed.chainSlug} at ${existed.apiUrl}`);
|
|
45
|
+
return existed.recoverConnect();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
destroyApi(chain) {
|
|
49
|
+
const api = this.getApiByChain(chain);
|
|
50
|
+
api === null || api === void 0 ? void 0 : api.destroy().catch(console.error);
|
|
51
|
+
}
|
|
52
|
+
async sleep() {
|
|
53
|
+
this.isSleeping = true;
|
|
54
|
+
this.cancelAllRecover();
|
|
55
|
+
await Promise.all(Object.values(this.getApiMap()).map(evmApi => {
|
|
56
|
+
return evmApi.disconnect().catch(console.error);
|
|
57
|
+
}));
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
wakeUp() {
|
|
61
|
+
var _this$parent;
|
|
62
|
+
this.isSleeping = false;
|
|
63
|
+
const activeChains = ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.getActiveChains()) || [];
|
|
64
|
+
for (const chain of activeChains) {
|
|
65
|
+
const api = this.getApiByChain(chain);
|
|
66
|
+
api === null || api === void 0 ? void 0 : api.connect();
|
|
67
|
+
}
|
|
68
|
+
return Promise.resolve();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BitcoinAddressSummaryInfo, BitcoinApiStrategy, BitcoinTransactionEventMap, BlockStreamTransactionDetail, BlockStreamTransactionStatus, Inscription, RunesInfoByAddress } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/types';
|
|
2
|
+
import { BaseApiRequestStrategy } from '@subwallet/extension-base/strategy/api-request-strategy';
|
|
3
|
+
import { BitcoinFeeInfo, BitcoinTx, UtxoResponseItem } from '@subwallet/extension-base/types';
|
|
4
|
+
import EventEmitter from 'eventemitter3';
|
|
5
|
+
export declare class BlockStreamTestnetRequestStrategy extends BaseApiRequestStrategy implements BitcoinApiStrategy {
|
|
6
|
+
private readonly baseUrl;
|
|
7
|
+
private readonly isTestnet;
|
|
8
|
+
private timePerBlock;
|
|
9
|
+
constructor(url: string);
|
|
10
|
+
private headers;
|
|
11
|
+
isRateLimited(): boolean;
|
|
12
|
+
getUrl(path: string): string;
|
|
13
|
+
getBlockTime(): Promise<number>;
|
|
14
|
+
computeBlockTime(): Promise<number>;
|
|
15
|
+
getAddressSummaryInfo(address: string): Promise<BitcoinAddressSummaryInfo>;
|
|
16
|
+
getAddressTransaction(address: string, limit?: number): Promise<BitcoinTx[]>;
|
|
17
|
+
getTransactionStatus(txHash: string): Promise<BlockStreamTransactionStatus>;
|
|
18
|
+
getTransactionDetail(txHash: string): Promise<BlockStreamTransactionDetail>;
|
|
19
|
+
getFeeRate(): Promise<BitcoinFeeInfo>;
|
|
20
|
+
getRecommendedFeeRate(): Promise<BitcoinFeeInfo>;
|
|
21
|
+
getUtxos(address: string): Promise<UtxoResponseItem[]>;
|
|
22
|
+
sendRawTransaction(rawTransaction: string): EventEmitter<BitcoinTransactionEventMap, any>;
|
|
23
|
+
simpleSendRawTransaction(rawTransaction: string): Promise<string>;
|
|
24
|
+
getRunes(address: string): Promise<RunesInfoByAddress[]>;
|
|
25
|
+
getRuneUtxos(address: string): Promise<import("@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/types").RuneUtxo[]>;
|
|
26
|
+
getAddressInscriptions(address: string): Promise<Inscription[]>;
|
|
27
|
+
getTxHex(txHash: string): Promise<string>;
|
|
28
|
+
}
|