@subwallet/extension-base 1.3.40-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 (232) 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/environment.js +4 -2
  9. package/cjs/constants/index.js +16 -1
  10. package/cjs/core/logic-validation/recipientAddress.js +9 -0
  11. package/cjs/core/logic-validation/transfer.js +25 -5
  12. package/cjs/core/types.js +1 -0
  13. package/cjs/core/utils.js +15 -1
  14. package/cjs/koni/background/handlers/Extension.js +96 -41
  15. package/cjs/koni/background/handlers/State.js +52 -11
  16. package/cjs/packageInfo.js +1 -1
  17. package/cjs/services/balance-service/helpers/subscribe/bitcoin.js +94 -0
  18. package/cjs/services/balance-service/helpers/subscribe/evm.js +6 -1
  19. package/cjs/services/balance-service/helpers/subscribe/index.js +19 -7
  20. package/cjs/services/balance-service/index.js +32 -4
  21. package/cjs/services/balance-service/transfer/bitcoin-transfer.js +119 -0
  22. package/cjs/services/balance-service/transfer/token.js +2 -0
  23. package/cjs/services/balance-service/transfer/xcm/index.js +15 -9
  24. package/cjs/services/balance-service/transfer/xcm/utils.js +12 -14
  25. package/cjs/services/base/types.js +2 -0
  26. package/cjs/services/chain-service/constants.js +18 -6
  27. package/cjs/services/chain-service/handler/CardanoApi.js +25 -35
  28. package/cjs/services/chain-service/handler/bitcoin/BitcoinApi.js +105 -0
  29. package/cjs/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +78 -0
  30. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +371 -0
  31. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +19 -0
  32. package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +368 -0
  33. package/cjs/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +302 -0
  34. package/cjs/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  35. package/cjs/services/chain-service/index.js +27 -3
  36. package/cjs/services/chain-service/utils/index.js +57 -4
  37. package/cjs/services/chain-service/utils/patch.js +1 -1
  38. package/cjs/services/earning-service/handlers/native-staking/tao.js +4 -38
  39. package/cjs/services/event-service/index.js +4 -0
  40. package/cjs/services/fee-service/service.js +8 -3
  41. package/cjs/services/hiro-service/index.js +96 -0
  42. package/cjs/services/hiro-service/utils/index.js +85 -0
  43. package/cjs/services/history-service/bitcoin-history.js +58 -0
  44. package/cjs/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  45. package/cjs/services/history-service/index.js +41 -3
  46. package/cjs/services/keyring-service/context/handlers/Derive.js +1 -1
  47. package/cjs/services/keyring-service/context/handlers/Migration.js +2 -2
  48. package/cjs/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  49. package/cjs/services/migration-service/scripts/MigrateNewUnifiedAccount.js +29 -0
  50. package/cjs/services/migration-service/scripts/index.js +3 -1
  51. package/cjs/services/request-service/handler/BitcoinRequestHandler.js +440 -0
  52. package/cjs/services/request-service/index.js +29 -3
  53. package/cjs/services/rune-service/index.js +105 -0
  54. package/cjs/services/swap-service/handler/chainflip-handler.js +29 -18
  55. package/cjs/services/swap-service/handler/kyber-handler.js +5 -9
  56. package/cjs/services/swap-service/handler/simpleswap-handler.js +4 -7
  57. package/cjs/services/swap-service/handler/uniswap-handler.js +5 -12
  58. package/cjs/services/swap-service/utils.js +46 -37
  59. package/cjs/services/transaction-service/helpers/index.js +7 -1
  60. package/cjs/services/transaction-service/index.js +136 -15
  61. package/cjs/services/transaction-service/utils.js +6 -3
  62. package/cjs/strategy/api-request-strategy/context/base.js +31 -0
  63. package/cjs/strategy/api-request-strategy/index.js +90 -0
  64. package/cjs/strategy/api-request-strategy/types.js +1 -0
  65. package/cjs/strategy/api-request-strategy/utils/index.js +33 -0
  66. package/cjs/types/account/info/keyring.js +1 -1
  67. package/cjs/types/bitcoin.js +24 -0
  68. package/cjs/types/environment.js +19 -0
  69. package/cjs/types/fee/bitcoin.js +1 -0
  70. package/cjs/types/fee/index.js +11 -0
  71. package/cjs/types/index.js +11 -0
  72. package/cjs/utils/account/analyze.js +3 -3
  73. package/cjs/utils/account/common.js +16 -6
  74. package/cjs/utils/account/derive/info/solo.js +68 -19
  75. package/cjs/utils/account/derive/info/unified.js +2 -0
  76. package/cjs/utils/account/derive/validate.js +70 -2
  77. package/cjs/utils/account/transform.js +11 -5
  78. package/cjs/utils/bitcoin/common.js +98 -0
  79. package/cjs/utils/bitcoin/fee.js +21 -0
  80. package/cjs/utils/bitcoin/index.js +38 -0
  81. package/cjs/utils/bitcoin/utxo-management.js +281 -0
  82. package/cjs/utils/environment.js +30 -2
  83. package/cjs/utils/fee/transfer.js +48 -0
  84. package/cjs/utils/index.js +15 -1
  85. package/constants/bitcoin.d.ts +3 -0
  86. package/constants/bitcoin.js +13 -0
  87. package/constants/environment.d.ts +1 -0
  88. package/constants/environment.js +2 -1
  89. package/constants/index.d.ts +2 -0
  90. package/constants/index.js +3 -1
  91. package/core/logic-validation/recipientAddress.js +10 -1
  92. package/core/logic-validation/transfer.d.ts +2 -2
  93. package/core/logic-validation/transfer.js +27 -7
  94. package/core/types.d.ts +1 -0
  95. package/core/types.js +1 -0
  96. package/core/utils.d.ts +1 -0
  97. package/core/utils.js +15 -2
  98. package/koni/background/handlers/Extension.d.ts +2 -0
  99. package/koni/background/handlers/Extension.js +95 -42
  100. package/koni/background/handlers/State.d.ts +7 -3
  101. package/koni/background/handlers/State.js +52 -12
  102. package/package.json +149 -8
  103. package/packageInfo.js +1 -1
  104. package/services/balance-service/helpers/subscribe/bitcoin.d.ts +2 -0
  105. package/services/balance-service/helpers/subscribe/bitcoin.js +87 -0
  106. package/services/balance-service/helpers/subscribe/evm.js +6 -1
  107. package/services/balance-service/helpers/subscribe/index.d.ts +2 -2
  108. package/services/balance-service/helpers/subscribe/index.js +20 -8
  109. package/services/balance-service/index.d.ts +2 -0
  110. package/services/balance-service/index.js +32 -4
  111. package/services/balance-service/transfer/bitcoin-transfer.d.ts +14 -0
  112. package/services/balance-service/transfer/bitcoin-transfer.js +112 -0
  113. package/services/balance-service/transfer/token.js +2 -0
  114. package/services/balance-service/transfer/xcm/index.js +15 -9
  115. package/services/balance-service/transfer/xcm/utils.d.ts +2 -0
  116. package/services/balance-service/transfer/xcm/utils.js +12 -14
  117. package/services/base/types.d.ts +2 -0
  118. package/services/base/types.js +2 -0
  119. package/services/chain-service/constants.d.ts +7 -0
  120. package/services/chain-service/constants.js +12 -5
  121. package/services/chain-service/handler/CardanoApi.d.ts +1 -5
  122. package/services/chain-service/handler/CardanoApi.js +26 -34
  123. package/services/chain-service/handler/bitcoin/BitcoinApi.d.ts +31 -0
  124. package/services/chain-service/handler/bitcoin/BitcoinApi.js +98 -0
  125. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.d.ts +16 -0
  126. package/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +70 -0
  127. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.d.ts +28 -0
  128. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +362 -0
  129. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.d.ts +2 -0
  130. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +5 -0
  131. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.d.ts +28 -0
  132. package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +359 -0
  133. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.d.ts +28 -0
  134. package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +293 -0
  135. package/services/chain-service/handler/bitcoin/strategy/types.d.ts +291 -0
  136. package/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
  137. package/services/chain-service/index.d.ts +3 -0
  138. package/services/chain-service/index.js +31 -5
  139. package/services/chain-service/types.d.ts +20 -0
  140. package/services/chain-service/utils/index.d.ts +4 -0
  141. package/services/chain-service/utils/index.js +50 -4
  142. package/services/chain-service/utils/patch.js +1 -1
  143. package/services/earning-service/handlers/native-staking/tao.d.ts +0 -11
  144. package/services/earning-service/handlers/native-staking/tao.js +4 -24
  145. package/services/event-service/index.d.ts +3 -0
  146. package/services/event-service/index.js +4 -0
  147. package/services/event-service/types.d.ts +3 -0
  148. package/services/fee-service/service.js +8 -3
  149. package/services/hiro-service/index.d.ts +17 -0
  150. package/services/hiro-service/index.js +88 -0
  151. package/services/hiro-service/utils/index.d.ts +6 -0
  152. package/services/hiro-service/utils/index.js +72 -0
  153. package/services/history-service/bitcoin-history.d.ts +4 -0
  154. package/services/history-service/bitcoin-history.js +52 -0
  155. package/services/history-service/helpers/recoverHistoryStatus.d.ts +3 -1
  156. package/services/history-service/helpers/recoverHistoryStatus.js +96 -4
  157. package/services/history-service/index.d.ts +1 -0
  158. package/services/history-service/index.js +42 -4
  159. package/services/keyring-service/context/handlers/Derive.js +2 -2
  160. package/services/keyring-service/context/handlers/Migration.js +2 -2
  161. package/services/keyring-service/context/handlers/Mnemonic.js +4 -3
  162. package/services/migration-service/scripts/MigrateNewUnifiedAccount.d.ts +4 -0
  163. package/services/migration-service/scripts/MigrateNewUnifiedAccount.js +21 -0
  164. package/services/migration-service/scripts/index.js +3 -1
  165. package/services/request-service/handler/BitcoinRequestHandler.d.ts +23 -0
  166. package/services/request-service/handler/BitcoinRequestHandler.js +427 -0
  167. package/services/request-service/index.d.ts +9 -2
  168. package/services/request-service/index.js +25 -3
  169. package/services/rune-service/index.d.ts +17 -0
  170. package/services/rune-service/index.js +97 -0
  171. package/services/swap-service/handler/chainflip-handler.d.ts +0 -2
  172. package/services/swap-service/handler/chainflip-handler.js +25 -13
  173. package/services/swap-service/handler/kyber-handler.d.ts +0 -1
  174. package/services/swap-service/handler/kyber-handler.js +5 -8
  175. package/services/swap-service/handler/simpleswap-handler.d.ts +0 -1
  176. package/services/swap-service/handler/simpleswap-handler.js +4 -6
  177. package/services/swap-service/handler/uniswap-handler.js +6 -13
  178. package/services/swap-service/utils.d.ts +0 -13
  179. package/services/swap-service/utils.js +46 -34
  180. package/services/transaction-service/helpers/index.d.ts +3 -1
  181. package/services/transaction-service/helpers/index.js +5 -0
  182. package/services/transaction-service/index.d.ts +3 -5
  183. package/services/transaction-service/index.js +135 -16
  184. package/services/transaction-service/types.d.ts +12 -2
  185. package/services/transaction-service/utils.js +7 -4
  186. package/strategy/api-request-strategy/context/base.d.ts +15 -0
  187. package/strategy/api-request-strategy/context/base.js +24 -0
  188. package/strategy/api-request-strategy/index.d.ts +15 -0
  189. package/strategy/api-request-strategy/index.js +83 -0
  190. package/strategy/api-request-strategy/types.d.ts +22 -0
  191. package/strategy/api-request-strategy/types.js +1 -0
  192. package/strategy/api-request-strategy/utils/index.d.ts +2 -0
  193. package/strategy/api-request-strategy/utils/index.js +23 -0
  194. package/types/account/info/keyring.d.ts +1 -1
  195. package/types/account/info/keyring.js +1 -1
  196. package/types/balance/index.d.ts +4 -1
  197. package/types/balance/transfer.d.ts +17 -0
  198. package/types/bitcoin.d.ts +93 -0
  199. package/types/bitcoin.js +17 -0
  200. package/types/environment.d.ts +9 -0
  201. package/types/environment.js +13 -0
  202. package/types/fee/base.d.ts +4 -1
  203. package/types/fee/bitcoin.d.ts +18 -0
  204. package/types/fee/bitcoin.js +1 -0
  205. package/types/fee/index.d.ts +1 -0
  206. package/types/fee/index.js +2 -1
  207. package/types/fee/subscription.d.ts +4 -3
  208. package/types/index.d.ts +1 -0
  209. package/types/index.js +1 -0
  210. package/utils/account/analyze.js +4 -4
  211. package/utils/account/common.d.ts +7 -8
  212. package/utils/account/common.js +16 -6
  213. package/utils/account/derive/info/solo.js +70 -21
  214. package/utils/account/derive/info/unified.js +2 -0
  215. package/utils/account/derive/validate.d.ts +1 -0
  216. package/utils/account/derive/validate.js +68 -1
  217. package/utils/account/transform.d.ts +1 -1
  218. package/utils/account/transform.js +11 -5
  219. package/utils/bitcoin/common.d.ts +22 -0
  220. package/utils/bitcoin/common.js +88 -0
  221. package/utils/bitcoin/fee.d.ts +2 -0
  222. package/utils/bitcoin/fee.js +14 -0
  223. package/utils/bitcoin/index.d.ts +3 -0
  224. package/utils/bitcoin/index.js +6 -0
  225. package/utils/bitcoin/utxo-management.d.ts +33 -0
  226. package/utils/bitcoin/utxo-management.js +266 -0
  227. package/utils/environment.d.ts +2 -0
  228. package/utils/environment.js +27 -1
  229. package/utils/fee/transfer.d.ts +3 -1
  230. package/utils/fee/transfer.js +47 -1
  231. package/utils/index.d.ts +1 -0
  232. package/utils/index.js +6 -3
@@ -0,0 +1,23 @@
1
+ import { ConfirmationDefinitionsBitcoin, ConfirmationsQueueBitcoin, ConfirmationsQueueItemOptions, ConfirmationTypeBitcoin, RequestConfirmationCompleteBitcoin, SignMessageBitcoinResult } from '@subwallet/extension-base/background/KoniTypes';
2
+ import { ChainService } from '@subwallet/extension-base/services/chain-service';
3
+ import FeeService from '@subwallet/extension-base/services/fee-service/service';
4
+ import RequestService from '@subwallet/extension-base/services/request-service';
5
+ import TransactionService from '@subwallet/extension-base/services/transaction-service';
6
+ import { BehaviorSubject } from 'rxjs';
7
+ export default class BitcoinRequestHandler {
8
+ #private;
9
+ private readonly confirmationsQueueSubjectBitcoin;
10
+ private readonly confirmationsPromiseMap;
11
+ constructor(requestService: RequestService, chainService: ChainService, feeService: FeeService, transactionService: TransactionService);
12
+ get numBitcoinRequests(): number;
13
+ getConfirmationsQueueSubjectBitcoin(): BehaviorSubject<ConfirmationsQueueBitcoin>;
14
+ addConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, url: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): Promise<ConfirmationDefinitionsBitcoin[CT][1]>;
15
+ updateConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): void;
16
+ signMessageBitcoin(confirmation: ConfirmationDefinitionsBitcoin['bitcoinSignatureRequest'][0]): SignMessageBitcoinResult;
17
+ private signTransactionBitcoin;
18
+ private signTransactionBitcoinWithPayload;
19
+ private signPsbt;
20
+ private decorateResultBitcoin;
21
+ completeConfirmationBitcoin(request: RequestConfirmationCompleteBitcoin): Promise<boolean>;
22
+ resetWallet(): void;
23
+ }
@@ -0,0 +1,427 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { BitcoinProviderError } from '@subwallet/extension-base/background/errors/BitcoinProviderError';
5
+ import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
+ import { BitcoinProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
7
+ import { createBitcoinTransaction } from '@subwallet/extension-base/services/balance-service/transfer/bitcoin-transfer';
8
+ import { BasicTxErrorType } from '@subwallet/extension-base/types';
9
+ import { createPromiseHandler } from '@subwallet/extension-base/utils';
10
+ import { getId } from '@subwallet/extension-base/utils/getId';
11
+ import { isInternalRequest } from '@subwallet/extension-base/utils/request';
12
+ import keyring from '@subwallet/ui-keyring';
13
+ import { Psbt } from 'bitcoinjs-lib';
14
+ import * as bitcoin from 'bitcoinjs-lib';
15
+ import { t } from 'i18next';
16
+ import { BehaviorSubject } from 'rxjs';
17
+ import { isArray, logger as createLogger } from '@polkadot/util';
18
+ export default class BitcoinRequestHandler {
19
+ #requestService;
20
+ #chainService;
21
+ #transactionService;
22
+ #feeService;
23
+ #logger;
24
+ confirmationsQueueSubjectBitcoin = new BehaviorSubject({
25
+ bitcoinSignatureRequest: {},
26
+ bitcoinSendTransactionRequest: {},
27
+ bitcoinWatchTransactionRequest: {},
28
+ bitcoinSendTransactionRequestAfterConfirmation: {},
29
+ bitcoinSignPsbtRequest: {}
30
+ });
31
+ confirmationsPromiseMap = {};
32
+ constructor(requestService, chainService, feeService, transactionService) {
33
+ this.#requestService = requestService;
34
+ this.#chainService = chainService;
35
+ this.#feeService = feeService;
36
+ this.#transactionService = transactionService;
37
+ this.#logger = createLogger('BitcoinRequestHandler');
38
+ }
39
+ get numBitcoinRequests() {
40
+ let count = 0;
41
+ Object.values(this.confirmationsQueueSubjectBitcoin.getValue()).forEach(x => {
42
+ count += Object.keys(x).length;
43
+ });
44
+ return count;
45
+ }
46
+ getConfirmationsQueueSubjectBitcoin() {
47
+ return this.confirmationsQueueSubjectBitcoin;
48
+ }
49
+ async addConfirmationBitcoin(id, url, type, payload, options = {}, validator) {
50
+ const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
51
+ const confirmationType = confirmations[type];
52
+ const payloadJson = JSON.stringify(payload);
53
+ const isInternal = isInternalRequest(url);
54
+ if (['bitcoinSignatureRequest', 'bitcoinSendTransactionRequest', 'bitcoinSendTransactionRequestAfterConfirmation'].includes(type)) {
55
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
56
+ if (isAlwaysRequired) {
57
+ this.#requestService.keyringService.lock();
58
+ }
59
+ }
60
+
61
+ // Check duplicate request
62
+ const duplicated = Object.values(confirmationType).find(c => c.url === url && c.payloadJson === payloadJson);
63
+ if (duplicated) {
64
+ throw new Error('Duplicate request');
65
+ }
66
+ confirmationType[id] = {
67
+ id,
68
+ url,
69
+ isInternal,
70
+ payload,
71
+ payloadJson,
72
+ ...options
73
+ };
74
+ const promise = new Promise((resolve, reject) => {
75
+ this.confirmationsPromiseMap[id] = {
76
+ validator: validator,
77
+ resolver: {
78
+ resolve: resolve,
79
+ reject: reject
80
+ }
81
+ };
82
+ });
83
+ this.confirmationsQueueSubjectBitcoin.next(confirmations);
84
+ if (!isInternal) {
85
+ this.#requestService.popupOpen();
86
+ }
87
+ this.#requestService.updateIconV2();
88
+ return promise;
89
+ }
90
+ updateConfirmationBitcoin(id, type, payload, options = {}, validator) {
91
+ const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
92
+ const confirmationType = confirmations[type];
93
+
94
+ // Check duplicate request
95
+ const exists = confirmationType[id];
96
+ if (!exists) {
97
+ throw new Error('Request does not exist');
98
+ }
99
+ const payloadJson = JSON.stringify(payload);
100
+ confirmationType[id] = {
101
+ ...exists,
102
+ payload,
103
+ payloadJson,
104
+ ...options
105
+ };
106
+ if (validator) {
107
+ this.confirmationsPromiseMap[id].validator = validator;
108
+ }
109
+ this.confirmationsQueueSubjectBitcoin.next(confirmations);
110
+ }
111
+ signMessageBitcoin(confirmation) {
112
+ const {
113
+ account,
114
+ payload
115
+ } = confirmation.payload;
116
+ const address = account.address;
117
+ const pair = keyring.getPair(address);
118
+ if (pair.isLocked) {
119
+ keyring.unlockPair(pair.address);
120
+ }
121
+
122
+ // Check if payload is a string
123
+ if (typeof payload === 'string') {
124
+ // Assume BitcoinSigner is an instance that implements the BitcoinSigner interface
125
+ return {
126
+ signature: pair.bitcoin.signMessage(payload),
127
+ message: payload,
128
+ address
129
+ }; // Assuming compressed = false
130
+ } else if (payload instanceof Uint8Array) {
131
+ // Check if payload is a byte array (Uint8Array)
132
+ // Convert Uint8Array to string
133
+ const payloadString = Buffer.from(payload).toString('hex');
134
+
135
+ // Assume BitcoinSigner is an instance that implements the BitcoinSigner interface
136
+ return {
137
+ signature: pair.bitcoin.signMessage(payloadString),
138
+ message: payload.toString(),
139
+ address
140
+ }; // Assuming compressed = false
141
+ } else {
142
+ // Handle the case where payload is invalid
143
+ throw new Error('Invalid payload type');
144
+ }
145
+ }
146
+ signTransactionBitcoin(request) {
147
+ // Extract necessary information from the BitcoinSendTransactionRequest
148
+ const {
149
+ account,
150
+ hashPayload
151
+ } = request.payload;
152
+ const address = account.address;
153
+ const pair = keyring.getPair(address);
154
+
155
+ // Unlock the pair if it is locked
156
+ if (pair.isLocked) {
157
+ keyring.unlockPair(pair.address);
158
+ }
159
+ const psbt = Psbt.fromHex(hashPayload);
160
+
161
+ // Finalize all inputs in the Psbt
162
+ // Sign the Psbt using the pair's bitcoin object
163
+ const signedTransaction = pair.bitcoin.signTransaction(psbt, psbt.txInputs.map((v, i) => i));
164
+ signedTransaction.finalizeAllInputs();
165
+ return signedTransaction.extractTransaction().toHex();
166
+ }
167
+ async signTransactionBitcoinWithPayload(request) {
168
+ const transaction = this.#transactionService.getTransaction(request.id);
169
+ const {
170
+ chain,
171
+ emitterTransaction,
172
+ feeCustom,
173
+ feeOption,
174
+ id
175
+ } = transaction;
176
+ const {
177
+ from,
178
+ to,
179
+ value
180
+ } = transaction.data;
181
+ if (!emitterTransaction) {
182
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
183
+ }
184
+ const chainInfo = this.#chainService.getChainInfoByKey(chain);
185
+ const bitcoinApi = this.#chainService.getBitcoinApi(chain);
186
+ const eventData = {
187
+ id,
188
+ errors: [],
189
+ warnings: [],
190
+ extrinsicHash: id
191
+ };
192
+ const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
193
+ const feeInfo = await this.#feeService.subscribeChainFee(getId(), chain, 'bitcoin');
194
+ const [psbt] = await createBitcoinTransaction({
195
+ bitcoinApi,
196
+ chain,
197
+ from,
198
+ feeCustom,
199
+ feeOption,
200
+ feeInfo,
201
+ to,
202
+ transferAll: false,
203
+ value: value || '0',
204
+ network
205
+ });
206
+ const pair = keyring.getPair(from);
207
+
208
+ // Unlock the pair if it is locked
209
+ if (pair.isLocked) {
210
+ keyring.unlockPair(pair.address);
211
+ }
212
+
213
+ // Finalize all inputs in the Psbt
214
+
215
+ // Sign the Psbt using the pair's bitcoin object
216
+ const signedTransaction = pair.bitcoin.signTransaction(psbt, psbt.txInputs.map((v, i) => i));
217
+ signedTransaction.finalizeAllInputs();
218
+ const signature = signedTransaction.extractTransaction().toHex();
219
+ this.#transactionService.emitterEventTransaction(emitterTransaction, eventData, chainInfo.slug, signature);
220
+ const {
221
+ promise,
222
+ reject,
223
+ resolve
224
+ } = createPromiseHandler();
225
+ emitterTransaction.on('extrinsicHash', data => {
226
+ if (!data.extrinsicHash) {
227
+ reject(BitcoinProviderErrorType.INTERNAL_ERROR);
228
+ } else {
229
+ resolve(data.extrinsicHash);
230
+ }
231
+ });
232
+ emitterTransaction.on('error', error => {
233
+ reject(error);
234
+ });
235
+ return promise;
236
+ }
237
+ async signPsbt(request) {
238
+ // Extract necessary information from the BitcoinSendTransactionRequest
239
+ const {
240
+ account,
241
+ payload
242
+ } = request.payload;
243
+ const {
244
+ allowedSighash,
245
+ broadcast,
246
+ psbt,
247
+ signAtIndex
248
+ } = payload;
249
+ const transaction = this.#transactionService.getTransaction(request.id);
250
+ let eventData = {
251
+ id: request.id,
252
+ errors: [],
253
+ warnings: [],
254
+ extrinsicHash: request.id
255
+ };
256
+
257
+ // todo: validate type of the account
258
+
259
+ if (Object.keys(account).length === 0) {
260
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, 'Please connect to Wallet to try this request');
261
+ }
262
+ const pair = keyring.getPair(account.address);
263
+
264
+ // Unlock the pair if it is locked
265
+ if (pair.isLocked) {
266
+ keyring.unlockPair(pair.address);
267
+ }
268
+ const signAtIndexGenerate = signAtIndex ? isArray(signAtIndex) ? signAtIndex : [signAtIndex] : [...Array(psbt.inputCount)].map((_, i) => i);
269
+ let psptSignedTransaction = null;
270
+
271
+ // Sign the Psbt using the pair's bitcoin object
272
+ try {
273
+ psptSignedTransaction = pair.bitcoin.signTransaction(psbt, signAtIndexGenerate, allowedSighash);
274
+ } catch (e) {
275
+ if (transaction) {
276
+ var _transaction$emitterT;
277
+ (_transaction$emitterT = transaction.emitterTransaction) === null || _transaction$emitterT === void 0 ? void 0 : _transaction$emitterT.emit('error', {
278
+ ...eventData,
279
+ errors: [new TransactionError(BasicTxErrorType.INVALID_PARAMS, e.message)],
280
+ id: transaction.id,
281
+ extrinsicHash: transaction.id
282
+ });
283
+ }
284
+ throw new Error(e.message);
285
+ }
286
+ if (!psptSignedTransaction) {
287
+ throw new Error('Unable to sign');
288
+ }
289
+ if (!broadcast) {
290
+ for (const index of signAtIndexGenerate) {
291
+ psptSignedTransaction.finalizeInput(index);
292
+ }
293
+ return {
294
+ psbt: psptSignedTransaction.toHex()
295
+ };
296
+ }
297
+ if (!transaction) {
298
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
299
+ }
300
+ const {
301
+ chain,
302
+ emitterTransaction,
303
+ id
304
+ } = transaction;
305
+ eventData = {
306
+ id,
307
+ errors: [],
308
+ warnings: [],
309
+ extrinsicHash: id
310
+ };
311
+ if (!emitterTransaction) {
312
+ throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
313
+ }
314
+ const chainInfo = this.#chainService.getChainInfoByKey(chain);
315
+ try {
316
+ psptSignedTransaction.finalizeAllInputs();
317
+ } catch (e) {
318
+ emitterTransaction.emit('error', {
319
+ ...eventData,
320
+ errors: [new TransactionError(BasicTxErrorType.INVALID_PARAMS, e.message)]
321
+ });
322
+ throw new Error(e.message);
323
+ }
324
+ const hexTransaction = psptSignedTransaction.extractTransaction().toHex();
325
+ this.#transactionService.emitterEventTransaction(emitterTransaction, eventData, chainInfo.slug, hexTransaction);
326
+ const {
327
+ promise,
328
+ reject,
329
+ resolve
330
+ } = createPromiseHandler();
331
+ emitterTransaction.on('extrinsicHash', data => {
332
+ if (!data.extrinsicHash || !psptSignedTransaction) {
333
+ reject(BitcoinProviderErrorType.INTERNAL_ERROR);
334
+ } else {
335
+ var _psptSignedTransactio;
336
+ resolve({
337
+ psbt: (_psptSignedTransactio = psptSignedTransaction) === null || _psptSignedTransactio === void 0 ? void 0 : _psptSignedTransactio.toHex(),
338
+ txid: data.extrinsicHash
339
+ });
340
+ }
341
+ });
342
+ emitterTransaction.on('error', error => {
343
+ reject(error);
344
+ });
345
+ return promise;
346
+ }
347
+ async decorateResultBitcoin(t, request, result) {
348
+ if (t === 'bitcoinSignatureRequest') {
349
+ result.payload = this.signMessageBitcoin(request);
350
+ } else if (t === 'bitcoinSendTransactionRequest') {
351
+ result.payload = this.signTransactionBitcoin(request);
352
+ } else if (t === 'bitcoinSignPsbtRequest') {
353
+ result.payload = await this.signPsbt(request);
354
+ } else if (t === 'bitcoinSendTransactionRequestAfterConfirmation') {
355
+ result.payload = await this.signTransactionBitcoinWithPayload(request);
356
+ }
357
+ if (t === 'bitcoinSignatureRequest' || t === 'bitcoinSendTransactionRequest' || t === 'bitcoinSignPsbtRequest' || t === 'bitcoinSendTransactionRequestAfterConfirmation') {
358
+ const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
359
+ if (isAlwaysRequired) {
360
+ this.#requestService.keyringService.lock();
361
+ }
362
+ }
363
+ }
364
+ async completeConfirmationBitcoin(request) {
365
+ const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
366
+ for (const ct in request) {
367
+ const type = ct;
368
+ const result = request[type];
369
+ const {
370
+ id,
371
+ isApproved
372
+ } = result;
373
+ const {
374
+ resolver,
375
+ validator
376
+ } = this.confirmationsPromiseMap[id];
377
+ const confirmation = confirmations[type][id];
378
+ if (!resolver || !confirmation) {
379
+ this.#logger.error(t('Unable to proceed. Please try again'), type, id);
380
+ throw new Error('Unable to proceed. Please try again');
381
+ }
382
+ if (isApproved) {
383
+ try {
384
+ // Fill signature for some special type
385
+ await this.decorateResultBitcoin(type, confirmation, result);
386
+ const error = validator && validator(result);
387
+ if (error) {
388
+ resolver.reject(error);
389
+ }
390
+ } catch (e) {
391
+ resolver.reject(e);
392
+ }
393
+ }
394
+
395
+ // Delete confirmations from queue
396
+ delete this.confirmationsPromiseMap[id];
397
+ delete confirmations[type][id];
398
+ this.confirmationsQueueSubjectBitcoin.next(confirmations);
399
+
400
+ // Update icon, and close queue
401
+ this.#requestService.updateIconV2(this.#requestService.numAllRequests === 0);
402
+ resolver.resolve(result);
403
+ }
404
+ return true;
405
+ }
406
+ resetWallet() {
407
+ const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
408
+ for (const [type, requests] of Object.entries(confirmations)) {
409
+ for (const confirmation of Object.values(requests)) {
410
+ const {
411
+ id
412
+ } = confirmation;
413
+ const {
414
+ resolver
415
+ } = this.confirmationsPromiseMap[id];
416
+ if (!resolver || !confirmation) {
417
+ console.error('Not found confirmation', type, id);
418
+ } else {
419
+ resolver.reject(new Error('Reset wallet'));
420
+ }
421
+ delete this.confirmationsPromiseMap[id];
422
+ delete confirmations[type][id];
423
+ }
424
+ }
425
+ this.confirmationsQueueSubjectBitcoin.next(confirmations);
426
+ }
427
+ }
@@ -1,8 +1,10 @@
1
- import { AuthRequestV2, ConfirmationDefinitions, ConfirmationDefinitionsCardano, ConfirmationDefinitionsTon, ConfirmationsQueue, ConfirmationsQueueCardano, ConfirmationsQueueItemOptions, ConfirmationsQueueTon, ConfirmationType, ConfirmationTypeCardano, ConfirmationTypeTon, RequestConfirmationComplete, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon } from '@subwallet/extension-base/background/KoniTypes';
1
+ import { AuthRequestV2, ConfirmationDefinitions, ConfirmationDefinitionsBitcoin, ConfirmationDefinitionsCardano, ConfirmationDefinitionsTon, ConfirmationsQueue, ConfirmationsQueueBitcoin, ConfirmationsQueueCardano, ConfirmationsQueueItemOptions, ConfirmationsQueueTon, ConfirmationType, ConfirmationTypeBitcoin, ConfirmationTypeCardano, ConfirmationTypeTon, RequestConfirmationComplete, RequestConfirmationCompleteBitcoin, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon } from '@subwallet/extension-base/background/KoniTypes';
2
2
  import { AccountAuthType, AuthorizeRequest, MetadataRequest, RequestAuthorizeTab, RequestSign, ResponseSigning, SigningRequest } from '@subwallet/extension-base/background/types';
3
3
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
4
+ import FeeService from '@subwallet/extension-base/services/fee-service/service';
4
5
  import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
5
6
  import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
7
+ import TransactionService from '@subwallet/extension-base/services/transaction-service';
6
8
  import { WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
7
9
  import { MetadataDef } from '@subwallet/extension-inject/types';
8
10
  import { BehaviorSubject } from 'rxjs';
@@ -12,7 +14,7 @@ export default class RequestService {
12
14
  #private;
13
15
  readonly settingService: SettingService;
14
16
  readonly keyringService: KeyringService;
15
- constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService);
17
+ constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService, feeService: FeeService, transactionService: TransactionService);
16
18
  get numAllRequests(): number;
17
19
  updateIconV2(shouldClose?: boolean): void;
18
20
  getAddressList(value?: boolean): Record<string, boolean>;
@@ -48,6 +50,7 @@ export default class RequestService {
48
50
  get numEvmRequests(): number;
49
51
  get numTonRequests(): number;
50
52
  get numCardanoRequests(): number;
53
+ get numBitcoinRequests(): number;
51
54
  get confirmationsQueueSubject(): BehaviorSubject<ConfirmationsQueue>;
52
55
  get confirmationsQueueSubjectTon(): BehaviorSubject<ConfirmationsQueueTon>;
53
56
  get confirmationsQueueSubjectCardano(): BehaviorSubject<ConfirmationsQueueCardano>;
@@ -60,6 +63,10 @@ export default class RequestService {
60
63
  completeConfirmationTon(request: RequestConfirmationCompleteTon): Promise<boolean>;
61
64
  completeConfirmationCardano(request: RequestConfirmationCompleteCardano): Promise<boolean>;
62
65
  updateConfirmation<CT extends ConfirmationType>(id: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): void;
66
+ get confirmationsQueueSubjectBitcoin(): BehaviorSubject<ConfirmationsQueueBitcoin>;
67
+ addConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, url: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): Promise<ConfirmationDefinitionsBitcoin[CT][1]>;
68
+ completeConfirmationBitcoin(request: RequestConfirmationCompleteBitcoin): Promise<boolean>;
69
+ updateConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): void;
63
70
  getConnectWCRequest(id: string): import("@subwallet/extension-base/services/wallet-connect-service/types").RequestWalletConnectSession;
64
71
  get connectWCSubject(): BehaviorSubject<WalletConnectSessionRequest[]>;
65
72
  get allConnectWCRequests(): WalletConnectSessionRequest[];
@@ -1,6 +1,7 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base authors & contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ import BitcoinRequestHandler from '@subwallet/extension-base/services/request-service/handler/BitcoinRequestHandler';
4
5
  import CardanoRequestHandler from '@subwallet/extension-base/services/request-service/handler/CardanoRequestHandler';
5
6
  import TonRequestHandler from "./handler/TonRequestHandler.js";
6
7
  import { AuthRequestHandler, ConnectWCRequestHandler, EvmRequestHandler, MetadataRequestHandler, NotSupportWCRequestHandler, PopupHandler, SubstrateRequestHandler } from "./handler/index.js";
@@ -12,13 +13,14 @@ export default class RequestService {
12
13
  #authRequestHandler;
13
14
  #substrateRequestHandler;
14
15
  #evmRequestHandler;
16
+ #bitcoinRequestHandler;
15
17
  #tonRequestHandler;
16
18
  #cardanoRequestHandler;
17
19
  #connectWCRequestHandler;
18
20
  #notSupportWCRequestHandler;
19
21
 
20
22
  // Common
21
- constructor(chainService, settingService, keyringService) {
23
+ constructor(chainService, settingService, keyringService, feeService, transactionService) {
22
24
  this.#chainService = chainService;
23
25
  this.settingService = settingService;
24
26
  this.keyringService = keyringService;
@@ -29,6 +31,7 @@ export default class RequestService {
29
31
  this.#evmRequestHandler = new EvmRequestHandler(this);
30
32
  this.#tonRequestHandler = new TonRequestHandler(this);
31
33
  this.#cardanoRequestHandler = new CardanoRequestHandler(this);
34
+ this.#bitcoinRequestHandler = new BitcoinRequestHandler(this, this.#chainService, feeService, transactionService);
32
35
  this.#connectWCRequestHandler = new ConnectWCRequestHandler(this);
33
36
  this.#notSupportWCRequestHandler = new NotSupportWCRequestHandler(this);
34
37
 
@@ -36,7 +39,7 @@ export default class RequestService {
36
39
  this.updateIconV2();
37
40
  }
38
41
  get numAllRequests() {
39
- return this.allSubstrateRequests.length + this.numEvmRequests + this.numTonRequests + this.numCardanoRequests;
42
+ return this.allSubstrateRequests.length + this.numEvmRequests + this.numTonRequests + this.numCardanoRequests + this.numBitcoinRequests;
40
43
  }
41
44
  updateIconV2(shouldClose) {
42
45
  this.#popupHandler.updateIconV2(shouldClose);
@@ -148,6 +151,9 @@ export default class RequestService {
148
151
  get numCardanoRequests() {
149
152
  return this.#cardanoRequestHandler.numCardanoRequests;
150
153
  }
154
+ get numBitcoinRequests() {
155
+ return this.#bitcoinRequestHandler.numBitcoinRequests;
156
+ }
151
157
  get confirmationsQueueSubject() {
152
158
  return this.#evmRequestHandler.getConfirmationsQueueSubject();
153
159
  }
@@ -185,6 +191,21 @@ export default class RequestService {
185
191
  return this.#evmRequestHandler.updateConfirmation(id, type, payload, options, validator);
186
192
  }
187
193
 
194
+ // Bitcoin requests
195
+
196
+ get confirmationsQueueSubjectBitcoin() {
197
+ return this.#bitcoinRequestHandler.getConfirmationsQueueSubjectBitcoin();
198
+ }
199
+ addConfirmationBitcoin(id, url, type, payload, options = {}, validator) {
200
+ return this.#bitcoinRequestHandler.addConfirmationBitcoin(id, url, type, payload, options, validator);
201
+ }
202
+ async completeConfirmationBitcoin(request) {
203
+ return await this.#bitcoinRequestHandler.completeConfirmationBitcoin(request);
204
+ }
205
+ updateConfirmationBitcoin(id, type, payload, options = {}, validator) {
206
+ return this.#bitcoinRequestHandler.updateConfirmationBitcoin(id, type, payload, options, validator);
207
+ }
208
+
188
209
  // WalletConnect Connect requests
189
210
  getConnectWCRequest(id) {
190
211
  return this.#connectWCRequestHandler.getConnectWCRequest(id);
@@ -221,7 +242,7 @@ export default class RequestService {
221
242
 
222
243
  // General methods
223
244
  get numRequests() {
224
- return this.numMetaRequests + this.numAuthRequests + this.numSubstrateRequests + this.numEvmRequests + this.numConnectWCRequests + this.numNotSupportWCRequests + this.numTonRequests + this.numCardanoRequests;
245
+ return this.numMetaRequests + this.numAuthRequests + this.numSubstrateRequests + this.numEvmRequests + this.numConnectWCRequests + this.numNotSupportWCRequests + this.numTonRequests + this.numCardanoRequests + this.numBitcoinRequests;
225
246
  }
226
247
  resetWallet() {
227
248
  this.#authRequestHandler.resetWallet();
@@ -229,6 +250,7 @@ export default class RequestService {
229
250
  this.#evmRequestHandler.resetWallet();
230
251
  this.#tonRequestHandler.resetWallet();
231
252
  this.#cardanoRequestHandler.resetWallet();
253
+ this.#bitcoinRequestHandler.resetWallet();
232
254
  this.#metadataRequestHandler.resetWallet();
233
255
  this.#connectWCRequestHandler.resetWallet();
234
256
  this.#notSupportWCRequestHandler.resetWallet();
@@ -0,0 +1,17 @@
1
+ import { RuneMetadata, RunesCollectionInfoResponse, RunesInfoByAddressFetchedData, RuneTxsResponse, RuneUtxoResponse } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/types';
2
+ import { BaseApiRequestStrategy } from '@subwallet/extension-base/strategy/api-request-strategy';
3
+ export declare class RunesService extends BaseApiRequestStrategy {
4
+ baseUrl: string;
5
+ private constructor();
6
+ private headers;
7
+ isRateLimited(): boolean;
8
+ getUrl(path: string): string;
9
+ getAddressRunesInfo(address: string, params: Record<string, string>): Promise<RunesInfoByAddressFetchedData>;
10
+ getRuneCollectionsByBatch(params: Record<string, string>): Promise<RunesCollectionInfoResponse>;
11
+ getAddressRuneTxs(address: string, params: Record<string, string>): Promise<RuneTxsResponse>;
12
+ getRuneMetadata(runeid: string): Promise<RuneMetadata>;
13
+ getAddressRuneUtxos(address: string): Promise<RuneUtxoResponse>;
14
+ private static mainnet;
15
+ private static testnet;
16
+ static getInstance(isTestnet?: boolean): RunesService;
17
+ }