@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.
Files changed (196) hide show
  1. package/background/KoniTypes.d.ts +121 -4
  2. package/background/KoniTypes.js +18 -0
  3. package/background/errors/BitcoinProviderError.d.ts +6 -0
  4. package/background/errors/BitcoinProviderError.js +47 -0
  5. package/cjs/background/KoniTypes.js +20 -1
  6. package/cjs/background/errors/BitcoinProviderError.js +54 -0
  7. package/cjs/constants/bitcoin.js +22 -0
  8. package/cjs/constants/index.js +16 -1
  9. package/cjs/core/logic-validation/recipientAddress.js +9 -0
  10. package/cjs/core/logic-validation/transfer.js +25 -5
  11. package/cjs/core/types.js +1 -0
  12. package/cjs/core/utils.js +15 -1
  13. package/cjs/koni/background/handlers/Extension.js +59 -3
  14. package/cjs/koni/background/handlers/State.js +52 -11
  15. package/cjs/packageInfo.js +1 -1
  16. package/cjs/services/balance-service/helpers/subscribe/bitcoin.js +94 -0
  17. package/cjs/services/balance-service/helpers/subscribe/index.js +19 -7
  18. package/cjs/services/balance-service/index.js +32 -4
  19. package/cjs/services/balance-service/transfer/bitcoin-transfer.js +119 -0
  20. package/cjs/services/balance-service/transfer/token.js +2 -0
  21. package/cjs/services/base/types.js +2 -0
  22. package/cjs/services/chain-service/constants.js +14 -3
  23. package/cjs/services/chain-service/handler/bitcoin/BitcoinApi.js +105 -0
  24. package/cjs/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +78 -0
  25. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +371 -0
  26. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +19 -0
  27. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +368 -0
  28. package/cjs/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +302 -0
  29. package/cjs/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  30. package/cjs/services/chain-service/index.js +27 -3
  31. package/cjs/services/chain-service/utils/index.js +57 -4
  32. package/cjs/services/chain-service/utils/patch.js +1 -1
  33. package/cjs/services/event-service/index.js +4 -0
  34. package/cjs/services/fee-service/service.js +8 -3
  35. package/cjs/services/hiro-service/index.js +96 -0
  36. package/cjs/services/hiro-service/utils/index.js +85 -0
  37. package/cjs/services/history-service/bitcoin-history.js +58 -0
  38. package/cjs/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  39. package/cjs/services/history-service/index.js +41 -3
  40. package/cjs/services/keyring-service/context/handlers/Derive.js +1 -1
  41. package/cjs/services/keyring-service/context/handlers/Migration.js +2 -2
  42. package/cjs/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  43. package/cjs/services/migration-service/scripts/MigrateNewUnifiedAccount.js +29 -0
  44. package/cjs/services/migration-service/scripts/index.js +3 -1
  45. package/cjs/services/request-service/handler/BitcoinRequestHandler.js +440 -0
  46. package/cjs/services/request-service/index.js +29 -3
  47. package/cjs/services/rune-service/index.js +105 -0
  48. package/cjs/services/transaction-service/helpers/index.js +7 -1
  49. package/cjs/services/transaction-service/index.js +136 -15
  50. package/cjs/services/transaction-service/utils.js +6 -3
  51. package/cjs/strategy/api-request-strategy/context/base.js +31 -0
  52. package/cjs/strategy/api-request-strategy/index.js +90 -0
  53. package/cjs/strategy/api-request-strategy/types.js +1 -0
  54. package/cjs/strategy/api-request-strategy/utils/index.js +33 -0
  55. package/cjs/types/account/info/keyring.js +1 -1
  56. package/cjs/types/bitcoin.js +24 -0
  57. package/cjs/types/fee/bitcoin.js +1 -0
  58. package/cjs/types/fee/index.js +11 -0
  59. package/cjs/types/index.js +11 -0
  60. package/cjs/utils/account/analyze.js +3 -3
  61. package/cjs/utils/account/common.js +16 -6
  62. package/cjs/utils/account/derive/info/solo.js +68 -19
  63. package/cjs/utils/account/derive/info/unified.js +2 -0
  64. package/cjs/utils/account/derive/validate.js +70 -2
  65. package/cjs/utils/account/transform.js +11 -5
  66. package/cjs/utils/bitcoin/common.js +98 -0
  67. package/cjs/utils/bitcoin/fee.js +21 -0
  68. package/cjs/utils/bitcoin/index.js +38 -0
  69. package/cjs/utils/bitcoin/utxo-management.js +281 -0
  70. package/cjs/utils/fee/transfer.js +48 -0
  71. package/cjs/utils/index.js +15 -1
  72. package/constants/bitcoin.d.ts +3 -0
  73. package/constants/bitcoin.js +13 -0
  74. package/constants/index.d.ts +2 -0
  75. package/constants/index.js +3 -1
  76. package/core/logic-validation/recipientAddress.js +10 -1
  77. package/core/logic-validation/transfer.d.ts +2 -2
  78. package/core/logic-validation/transfer.js +27 -7
  79. package/core/types.d.ts +1 -0
  80. package/core/types.js +1 -0
  81. package/core/utils.d.ts +1 -0
  82. package/core/utils.js +15 -2
  83. package/koni/background/handlers/Extension.d.ts +2 -0
  84. package/koni/background/handlers/Extension.js +58 -4
  85. package/koni/background/handlers/State.d.ts +7 -3
  86. package/koni/background/handlers/State.js +52 -12
  87. package/package.json +144 -8
  88. package/packageInfo.js +1 -1
  89. package/services/balance-service/helpers/subscribe/bitcoin.d.ts +2 -0
  90. package/services/balance-service/helpers/subscribe/bitcoin.js +87 -0
  91. package/services/balance-service/helpers/subscribe/index.d.ts +2 -2
  92. package/services/balance-service/helpers/subscribe/index.js +20 -8
  93. package/services/balance-service/index.d.ts +2 -0
  94. package/services/balance-service/index.js +32 -4
  95. package/services/balance-service/transfer/bitcoin-transfer.d.ts +14 -0
  96. package/services/balance-service/transfer/bitcoin-transfer.js +112 -0
  97. package/services/balance-service/transfer/token.js +2 -0
  98. package/services/base/types.d.ts +2 -0
  99. package/services/base/types.js +2 -0
  100. package/services/chain-service/constants.d.ts +6 -0
  101. package/services/chain-service/constants.js +8 -2
  102. package/services/chain-service/handler/bitcoin/BitcoinApi.d.ts +31 -0
  103. package/services/chain-service/handler/bitcoin/BitcoinApi.js +98 -0
  104. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.d.ts +16 -0
  105. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +70 -0
  106. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.d.ts +28 -0
  107. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +362 -0
  108. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.d.ts +2 -0
  109. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +5 -0
  110. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.d.ts +28 -0
  111. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +359 -0
  112. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.d.ts +28 -0
  113. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +293 -0
  114. package/services/chain-service/handler/bitcoin/strategy/types.d.ts +291 -0
  115. package/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  116. package/services/chain-service/index.d.ts +3 -0
  117. package/services/chain-service/index.js +31 -5
  118. package/services/chain-service/types.d.ts +20 -0
  119. package/services/chain-service/utils/index.d.ts +4 -0
  120. package/services/chain-service/utils/index.js +50 -4
  121. package/services/chain-service/utils/patch.js +1 -1
  122. package/services/event-service/index.d.ts +3 -0
  123. package/services/event-service/index.js +4 -0
  124. package/services/event-service/types.d.ts +3 -0
  125. package/services/fee-service/service.js +8 -3
  126. package/services/hiro-service/index.d.ts +17 -0
  127. package/services/hiro-service/index.js +88 -0
  128. package/services/hiro-service/utils/index.d.ts +6 -0
  129. package/services/hiro-service/utils/index.js +72 -0
  130. package/services/history-service/bitcoin-history.d.ts +4 -0
  131. package/services/history-service/bitcoin-history.js +52 -0
  132. package/services/history-service/helpers/recoverHistoryStatus.d.ts +3 -1
  133. package/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  134. package/services/history-service/index.d.ts +1 -0
  135. package/services/history-service/index.js +42 -4
  136. package/services/keyring-service/context/handlers/Derive.js +2 -2
  137. package/services/keyring-service/context/handlers/Migration.js +2 -2
  138. package/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  139. package/services/migration-service/scripts/MigrateNewUnifiedAccount.d.ts +4 -0
  140. package/services/migration-service/scripts/MigrateNewUnifiedAccount.js +21 -0
  141. package/services/migration-service/scripts/index.js +3 -1
  142. package/services/request-service/handler/BitcoinRequestHandler.d.ts +23 -0
  143. package/services/request-service/handler/BitcoinRequestHandler.js +427 -0
  144. package/services/request-service/index.d.ts +9 -2
  145. package/services/request-service/index.js +25 -3
  146. package/services/rune-service/index.d.ts +17 -0
  147. package/services/rune-service/index.js +97 -0
  148. package/services/transaction-service/helpers/index.d.ts +3 -1
  149. package/services/transaction-service/helpers/index.js +5 -0
  150. package/services/transaction-service/index.d.ts +3 -5
  151. package/services/transaction-service/index.js +135 -16
  152. package/services/transaction-service/types.d.ts +12 -2
  153. package/services/transaction-service/utils.js +7 -4
  154. package/strategy/api-request-strategy/context/base.d.ts +15 -0
  155. package/strategy/api-request-strategy/context/base.js +24 -0
  156. package/strategy/api-request-strategy/index.d.ts +15 -0
  157. package/strategy/api-request-strategy/index.js +83 -0
  158. package/strategy/api-request-strategy/types.d.ts +22 -0
  159. package/strategy/api-request-strategy/types.js +1 -0
  160. package/strategy/api-request-strategy/utils/index.d.ts +2 -0
  161. package/strategy/api-request-strategy/utils/index.js +23 -0
  162. package/types/account/info/keyring.d.ts +1 -1
  163. package/types/account/info/keyring.js +1 -1
  164. package/types/balance/index.d.ts +4 -1
  165. package/types/balance/transfer.d.ts +17 -0
  166. package/types/bitcoin.d.ts +93 -0
  167. package/types/bitcoin.js +17 -0
  168. package/types/fee/base.d.ts +4 -1
  169. package/types/fee/bitcoin.d.ts +18 -0
  170. package/types/fee/bitcoin.js +1 -0
  171. package/types/fee/index.d.ts +1 -0
  172. package/types/fee/index.js +2 -1
  173. package/types/fee/subscription.d.ts +4 -3
  174. package/types/index.d.ts +1 -0
  175. package/types/index.js +1 -0
  176. package/utils/account/analyze.js +4 -4
  177. package/utils/account/common.d.ts +7 -8
  178. package/utils/account/common.js +16 -6
  179. package/utils/account/derive/info/solo.js +70 -21
  180. package/utils/account/derive/info/unified.js +2 -0
  181. package/utils/account/derive/validate.d.ts +1 -0
  182. package/utils/account/derive/validate.js +68 -1
  183. package/utils/account/transform.d.ts +1 -1
  184. package/utils/account/transform.js +11 -5
  185. package/utils/bitcoin/common.d.ts +22 -0
  186. package/utils/bitcoin/common.js +88 -0
  187. package/utils/bitcoin/fee.d.ts +2 -0
  188. package/utils/bitcoin/fee.js +14 -0
  189. package/utils/bitcoin/index.d.ts +3 -0
  190. package/utils/bitcoin/index.js +6 -0
  191. package/utils/bitcoin/utxo-management.d.ts +33 -0
  192. package/utils/bitcoin/utxo-management.js +266 -0
  193. package/utils/fee/transfer.d.ts +3 -1
  194. package/utils/fee/transfer.js +47 -1
  195. package/utils/index.d.ts +1 -0
  196. 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
  };
@@ -5,6 +5,8 @@ export declare enum ServiceStatus {
5
5
  INITIALIZED = "initialized",
6
6
  STARTED = "started",
7
7
  STARTING = "starting",
8
+ STARTED_FULL = "started_full",
9
+ STARTING_FULL = "starting_full",
8
10
  STOPPED = "stopped",
9
11
  STOPPING = "stopping"
10
12
  }
@@ -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
+ }