otx-btc-wallet-connectors 0.1.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 (142) hide show
  1. package/README.md +554 -0
  2. package/dist/base-IAFq7sd8.d.mts +53 -0
  3. package/dist/base-IAFq7sd8.d.ts +53 -0
  4. package/dist/binance/index.d.mts +81 -0
  5. package/dist/binance/index.d.ts +81 -0
  6. package/dist/binance/index.js +13 -0
  7. package/dist/binance/index.js.map +1 -0
  8. package/dist/binance/index.mjs +4 -0
  9. package/dist/binance/index.mjs.map +1 -0
  10. package/dist/bitget/index.d.mts +84 -0
  11. package/dist/bitget/index.d.ts +84 -0
  12. package/dist/bitget/index.js +13 -0
  13. package/dist/bitget/index.js.map +1 -0
  14. package/dist/bitget/index.mjs +4 -0
  15. package/dist/bitget/index.mjs.map +1 -0
  16. package/dist/chunk-5Z5Q2Y75.mjs +91 -0
  17. package/dist/chunk-5Z5Q2Y75.mjs.map +1 -0
  18. package/dist/chunk-7KK2LZLZ.mjs +208 -0
  19. package/dist/chunk-7KK2LZLZ.mjs.map +1 -0
  20. package/dist/chunk-AW2JZIHR.mjs +753 -0
  21. package/dist/chunk-AW2JZIHR.mjs.map +1 -0
  22. package/dist/chunk-EIJOSZXZ.js +331 -0
  23. package/dist/chunk-EIJOSZXZ.js.map +1 -0
  24. package/dist/chunk-EQHR7P7G.js +541 -0
  25. package/dist/chunk-EQHR7P7G.js.map +1 -0
  26. package/dist/chunk-EWRXLZO4.mjs +539 -0
  27. package/dist/chunk-EWRXLZO4.mjs.map +1 -0
  28. package/dist/chunk-FISNQZZ7.js +802 -0
  29. package/dist/chunk-FISNQZZ7.js.map +1 -0
  30. package/dist/chunk-HL4WDMGS.js +200 -0
  31. package/dist/chunk-HL4WDMGS.js.map +1 -0
  32. package/dist/chunk-IPYWR76I.js +314 -0
  33. package/dist/chunk-IPYWR76I.js.map +1 -0
  34. package/dist/chunk-JYYNWR5G.js +142 -0
  35. package/dist/chunk-JYYNWR5G.js.map +1 -0
  36. package/dist/chunk-LNKTYZJM.js +701 -0
  37. package/dist/chunk-LNKTYZJM.js.map +1 -0
  38. package/dist/chunk-LVZMONQL.mjs +699 -0
  39. package/dist/chunk-LVZMONQL.mjs.map +1 -0
  40. package/dist/chunk-MFXLQWOE.js +93 -0
  41. package/dist/chunk-MFXLQWOE.js.map +1 -0
  42. package/dist/chunk-NBIA4TTE.mjs +204 -0
  43. package/dist/chunk-NBIA4TTE.mjs.map +1 -0
  44. package/dist/chunk-O4DD2XJ2.js +206 -0
  45. package/dist/chunk-O4DD2XJ2.js.map +1 -0
  46. package/dist/chunk-P7HVBU2B.mjs +140 -0
  47. package/dist/chunk-P7HVBU2B.mjs.map +1 -0
  48. package/dist/chunk-Q7QVQYEB.js +210 -0
  49. package/dist/chunk-Q7QVQYEB.js.map +1 -0
  50. package/dist/chunk-RLZEG6KL.mjs +329 -0
  51. package/dist/chunk-RLZEG6KL.mjs.map +1 -0
  52. package/dist/chunk-SYLDBJ75.mjs +246 -0
  53. package/dist/chunk-SYLDBJ75.mjs.map +1 -0
  54. package/dist/chunk-TTEUU3CI.mjs +198 -0
  55. package/dist/chunk-TTEUU3CI.mjs.map +1 -0
  56. package/dist/chunk-V66BXDTR.mjs +292 -0
  57. package/dist/chunk-V66BXDTR.mjs.map +1 -0
  58. package/dist/chunk-X77ZT4OI.js +268 -0
  59. package/dist/chunk-X77ZT4OI.js.map +1 -0
  60. package/dist/imtoken/index.d.mts +116 -0
  61. package/dist/imtoken/index.d.ts +116 -0
  62. package/dist/imtoken/index.js +14 -0
  63. package/dist/imtoken/index.js.map +1 -0
  64. package/dist/imtoken/index.mjs +5 -0
  65. package/dist/imtoken/index.mjs.map +1 -0
  66. package/dist/index.d.mts +14 -0
  67. package/dist/index.d.ts +14 -0
  68. package/dist/index.js +170 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/index.mjs +13 -0
  71. package/dist/index.mjs.map +1 -0
  72. package/dist/ledger/index.d.mts +290 -0
  73. package/dist/ledger/index.d.ts +290 -0
  74. package/dist/ledger/index.js +14 -0
  75. package/dist/ledger/index.js.map +1 -0
  76. package/dist/ledger/index.mjs +5 -0
  77. package/dist/ledger/index.mjs.map +1 -0
  78. package/dist/okx/index.d.mts +88 -0
  79. package/dist/okx/index.d.ts +88 -0
  80. package/dist/okx/index.js +13 -0
  81. package/dist/okx/index.js.map +1 -0
  82. package/dist/okx/index.mjs +4 -0
  83. package/dist/okx/index.mjs.map +1 -0
  84. package/dist/phantom/index.d.mts +96 -0
  85. package/dist/phantom/index.d.ts +96 -0
  86. package/dist/phantom/index.js +14 -0
  87. package/dist/phantom/index.js.map +1 -0
  88. package/dist/phantom/index.mjs +5 -0
  89. package/dist/phantom/index.mjs.map +1 -0
  90. package/dist/psbt-builder-CFOs69Z5.d.mts +131 -0
  91. package/dist/psbt-builder-CFOs69Z5.d.ts +131 -0
  92. package/dist/trezor/index.d.mts +155 -0
  93. package/dist/trezor/index.d.ts +155 -0
  94. package/dist/trezor/index.js +14 -0
  95. package/dist/trezor/index.js.map +1 -0
  96. package/dist/trezor/index.mjs +5 -0
  97. package/dist/trezor/index.mjs.map +1 -0
  98. package/dist/unisat/index.d.mts +75 -0
  99. package/dist/unisat/index.d.ts +75 -0
  100. package/dist/unisat/index.js +13 -0
  101. package/dist/unisat/index.js.map +1 -0
  102. package/dist/unisat/index.mjs +4 -0
  103. package/dist/unisat/index.mjs.map +1 -0
  104. package/dist/utils/index.d.mts +398 -0
  105. package/dist/utils/index.d.ts +398 -0
  106. package/dist/utils/index.js +120 -0
  107. package/dist/utils/index.js.map +1 -0
  108. package/dist/utils/index.mjs +3 -0
  109. package/dist/utils/index.mjs.map +1 -0
  110. package/dist/xverse/index.d.mts +79 -0
  111. package/dist/xverse/index.d.ts +79 -0
  112. package/dist/xverse/index.js +13 -0
  113. package/dist/xverse/index.js.map +1 -0
  114. package/dist/xverse/index.mjs +4 -0
  115. package/dist/xverse/index.mjs.map +1 -0
  116. package/package.json +108 -0
  117. package/src/base.ts +132 -0
  118. package/src/binance/BinanceConnector.ts +307 -0
  119. package/src/binance/index.ts +1 -0
  120. package/src/bitget/BitgetConnector.ts +301 -0
  121. package/src/bitget/index.ts +1 -0
  122. package/src/imtoken/ImTokenConnector.ts +420 -0
  123. package/src/imtoken/index.ts +2 -0
  124. package/src/index.ts +78 -0
  125. package/src/ledger/LedgerConnector.ts +1019 -0
  126. package/src/ledger/index.ts +8 -0
  127. package/src/okx/OKXConnector.ts +230 -0
  128. package/src/okx/index.ts +1 -0
  129. package/src/phantom/PhantomConnector.ts +381 -0
  130. package/src/phantom/index.ts +2 -0
  131. package/src/trezor/TrezorConnector.ts +824 -0
  132. package/src/trezor/index.ts +6 -0
  133. package/src/unisat/UnisatConnector.ts +312 -0
  134. package/src/unisat/index.ts +1 -0
  135. package/src/utils/blockstream.ts +230 -0
  136. package/src/utils/btc-service.ts +364 -0
  137. package/src/utils/index.ts +56 -0
  138. package/src/utils/mempool.ts +232 -0
  139. package/src/utils/psbt-builder.ts +492 -0
  140. package/src/utils/types.ts +183 -0
  141. package/src/xverse/XverseConnector.ts +479 -0
  142. package/src/xverse/index.ts +1 -0
@@ -0,0 +1,802 @@
1
+ 'use strict';
2
+
3
+ var bitcoin = require('bitcoinjs-lib');
4
+
5
+ function _interopNamespace(e) {
6
+ if (e && e.__esModule) return e;
7
+ var n = Object.create(null);
8
+ if (e) {
9
+ Object.keys(e).forEach(function (k) {
10
+ if (k !== 'default') {
11
+ var d = Object.getOwnPropertyDescriptor(e, k);
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: function () { return e[k]; }
15
+ });
16
+ }
17
+ });
18
+ }
19
+ n.default = e;
20
+ return Object.freeze(n);
21
+ }
22
+
23
+ var bitcoin__namespace = /*#__PURE__*/_interopNamespace(bitcoin);
24
+
25
+ // src/utils/mempool.ts
26
+ var DEFAULT_MEMPOOL_ENDPOINTS = {
27
+ mainnet: "https://mempool.space/api",
28
+ testnet: "https://mempool.space/testnet/api",
29
+ testnet4: "https://mempool.space/testnet4/api",
30
+ signet: "https://mempool.space/signet/api"
31
+ };
32
+ async function fetchWithTimeout(url, options, timeout = 1e4) {
33
+ const controller = new AbortController();
34
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
35
+ try {
36
+ const response = await fetch(url, {
37
+ ...options,
38
+ signal: controller.signal
39
+ });
40
+ clearTimeout(timeoutId);
41
+ return response;
42
+ } catch (error) {
43
+ clearTimeout(timeoutId);
44
+ throw error;
45
+ }
46
+ }
47
+ var MempoolService = class {
48
+ constructor(network = "mainnet", customEndpoints) {
49
+ this.name = "mempool";
50
+ this._network = network;
51
+ this._customEndpoints = customEndpoints ?? {};
52
+ }
53
+ get network() {
54
+ return this._network;
55
+ }
56
+ get baseUrl() {
57
+ return this._customEndpoints[this._network] ?? DEFAULT_MEMPOOL_ENDPOINTS[this._network];
58
+ }
59
+ setNetwork(network) {
60
+ this._network = network;
61
+ }
62
+ /**
63
+ * Set custom endpoints for this service
64
+ */
65
+ setCustomEndpoints(endpoints) {
66
+ this._customEndpoints = { ...this._customEndpoints, ...endpoints };
67
+ }
68
+ /**
69
+ * Get current endpoints configuration
70
+ */
71
+ getEndpoints() {
72
+ return {
73
+ mainnet: this._customEndpoints.mainnet ?? DEFAULT_MEMPOOL_ENDPOINTS.mainnet,
74
+ testnet: this._customEndpoints.testnet ?? DEFAULT_MEMPOOL_ENDPOINTS.testnet,
75
+ testnet4: this._customEndpoints.testnet4 ?? DEFAULT_MEMPOOL_ENDPOINTS.testnet4,
76
+ signet: this._customEndpoints.signet ?? DEFAULT_MEMPOOL_ENDPOINTS.signet
77
+ };
78
+ }
79
+ // ============ UTXO Methods ============
80
+ async getUtxos(address2) {
81
+ const response = await fetchWithTimeout(`${this.baseUrl}/address/${address2}/utxo`);
82
+ if (!response.ok) {
83
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
84
+ }
85
+ return response.json();
86
+ }
87
+ async getUtxosWithTxHex(address2) {
88
+ const utxos = await this.getUtxos(address2);
89
+ const utxosWithTx = await Promise.all(
90
+ utxos.map(async (utxo) => {
91
+ const txHex = await this.getTxHex(utxo.txid);
92
+ return { ...utxo, txHex };
93
+ })
94
+ );
95
+ return utxosWithTx;
96
+ }
97
+ // ============ Transaction Methods ============
98
+ async getTxHex(txid) {
99
+ const response = await fetchWithTimeout(`${this.baseUrl}/tx/${txid}/hex`);
100
+ if (!response.ok) {
101
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
102
+ }
103
+ return response.text();
104
+ }
105
+ async getTransaction(txid) {
106
+ const response = await fetchWithTimeout(`${this.baseUrl}/tx/${txid}`);
107
+ if (!response.ok) {
108
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
109
+ }
110
+ return response.json();
111
+ }
112
+ async getFullTransaction(txid) {
113
+ const response = await fetchWithTimeout(`${this.baseUrl}/tx/${txid}`);
114
+ if (!response.ok) {
115
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
116
+ }
117
+ return response.json();
118
+ }
119
+ async broadcastTransaction(txHex) {
120
+ const response = await fetchWithTimeout(
121
+ `${this.baseUrl}/tx`,
122
+ {
123
+ method: "POST",
124
+ body: txHex,
125
+ headers: { "Content-Type": "text/plain" }
126
+ },
127
+ 3e4
128
+ );
129
+ if (!response.ok) {
130
+ const error = await response.text();
131
+ throw new Error(`Mempool broadcast error: ${error}`);
132
+ }
133
+ return response.text();
134
+ }
135
+ // ============ Address Methods ============
136
+ async getAddressInfo(address2) {
137
+ const response = await fetchWithTimeout(`${this.baseUrl}/address/${address2}`);
138
+ if (!response.ok) {
139
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
140
+ }
141
+ return response.json();
142
+ }
143
+ async getBalance(address2) {
144
+ const info = await this.getAddressInfo(address2);
145
+ const confirmedBalance = info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum;
146
+ const unconfirmedBalance = info.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum;
147
+ return confirmedBalance + unconfirmedBalance;
148
+ }
149
+ async getConfirmedBalance(address2) {
150
+ const info = await this.getAddressInfo(address2);
151
+ return info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum;
152
+ }
153
+ // ============ Fee Methods ============
154
+ async getFeeRates() {
155
+ const response = await fetchWithTimeout(`${this.baseUrl}/v1/fees/recommended`);
156
+ if (!response.ok) {
157
+ throw new Error(`Mempool API error: ${response.status} ${response.statusText}`);
158
+ }
159
+ const fees = await response.json();
160
+ return {
161
+ fastest: fees.fastestFee,
162
+ halfHour: fees.halfHourFee,
163
+ hour: fees.hourFee,
164
+ economy: fees.economyFee,
165
+ minimum: fees.minimumFee
166
+ };
167
+ }
168
+ };
169
+
170
+ // src/utils/blockstream.ts
171
+ var DEFAULT_BLOCKSTREAM_ENDPOINTS = {
172
+ mainnet: "https://blockstream.info/api",
173
+ testnet: "https://blockstream.info/testnet/api",
174
+ testnet4: "https://mempool.space/testnet4/api",
175
+ // Fallback to mempool
176
+ signet: "https://mempool.space/signet/api"
177
+ // Fallback to mempool
178
+ };
179
+ async function fetchWithTimeout2(url, options, timeout = 1e4) {
180
+ const controller = new AbortController();
181
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
182
+ try {
183
+ const response = await fetch(url, {
184
+ ...options,
185
+ signal: controller.signal
186
+ });
187
+ clearTimeout(timeoutId);
188
+ return response;
189
+ } catch (error) {
190
+ clearTimeout(timeoutId);
191
+ throw error;
192
+ }
193
+ }
194
+ var BlockstreamService = class {
195
+ constructor(network = "mainnet", customEndpoints) {
196
+ this.name = "blockstream";
197
+ this._network = network;
198
+ this._customEndpoints = customEndpoints ?? {};
199
+ }
200
+ get network() {
201
+ return this._network;
202
+ }
203
+ get baseUrl() {
204
+ return this._customEndpoints[this._network] ?? DEFAULT_BLOCKSTREAM_ENDPOINTS[this._network];
205
+ }
206
+ setNetwork(network) {
207
+ this._network = network;
208
+ }
209
+ /**
210
+ * Set custom endpoints for this service
211
+ */
212
+ setCustomEndpoints(endpoints) {
213
+ this._customEndpoints = { ...this._customEndpoints, ...endpoints };
214
+ }
215
+ /**
216
+ * Get current endpoints configuration
217
+ */
218
+ getEndpoints() {
219
+ return {
220
+ mainnet: this._customEndpoints.mainnet ?? DEFAULT_BLOCKSTREAM_ENDPOINTS.mainnet,
221
+ testnet: this._customEndpoints.testnet ?? DEFAULT_BLOCKSTREAM_ENDPOINTS.testnet,
222
+ testnet4: this._customEndpoints.testnet4 ?? DEFAULT_BLOCKSTREAM_ENDPOINTS.testnet4,
223
+ signet: this._customEndpoints.signet ?? DEFAULT_BLOCKSTREAM_ENDPOINTS.signet
224
+ };
225
+ }
226
+ // ============ UTXO Methods ============
227
+ async getUtxos(address2) {
228
+ const response = await fetchWithTimeout2(`${this.baseUrl}/address/${address2}/utxo`);
229
+ if (!response.ok) {
230
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
231
+ }
232
+ return response.json();
233
+ }
234
+ async getUtxosWithTxHex(address2) {
235
+ const utxos = await this.getUtxos(address2);
236
+ const utxosWithTx = await Promise.all(
237
+ utxos.map(async (utxo) => {
238
+ const txHex = await this.getTxHex(utxo.txid);
239
+ return { ...utxo, txHex };
240
+ })
241
+ );
242
+ return utxosWithTx;
243
+ }
244
+ // ============ Transaction Methods ============
245
+ async getTxHex(txid) {
246
+ const response = await fetchWithTimeout2(`${this.baseUrl}/tx/${txid}/hex`);
247
+ if (!response.ok) {
248
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
249
+ }
250
+ return response.text();
251
+ }
252
+ async getTransaction(txid) {
253
+ const response = await fetchWithTimeout2(`${this.baseUrl}/tx/${txid}`);
254
+ if (!response.ok) {
255
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
256
+ }
257
+ return response.json();
258
+ }
259
+ async getFullTransaction(txid) {
260
+ const response = await fetchWithTimeout2(`${this.baseUrl}/tx/${txid}`);
261
+ if (!response.ok) {
262
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
263
+ }
264
+ return response.json();
265
+ }
266
+ async broadcastTransaction(txHex) {
267
+ const response = await fetchWithTimeout2(
268
+ `${this.baseUrl}/tx`,
269
+ {
270
+ method: "POST",
271
+ body: txHex,
272
+ headers: { "Content-Type": "text/plain" }
273
+ },
274
+ 3e4
275
+ );
276
+ if (!response.ok) {
277
+ const error = await response.text();
278
+ throw new Error(`Blockstream broadcast error: ${error}`);
279
+ }
280
+ return response.text();
281
+ }
282
+ // ============ Address Methods ============
283
+ async getAddressInfo(address2) {
284
+ const response = await fetchWithTimeout2(`${this.baseUrl}/address/${address2}`);
285
+ if (!response.ok) {
286
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
287
+ }
288
+ return response.json();
289
+ }
290
+ async getBalance(address2) {
291
+ const info = await this.getAddressInfo(address2);
292
+ const confirmedBalance = info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum;
293
+ const unconfirmedBalance = info.mempool_stats.funded_txo_sum - info.mempool_stats.spent_txo_sum;
294
+ return confirmedBalance + unconfirmedBalance;
295
+ }
296
+ async getConfirmedBalance(address2) {
297
+ const info = await this.getAddressInfo(address2);
298
+ return info.chain_stats.funded_txo_sum - info.chain_stats.spent_txo_sum;
299
+ }
300
+ // ============ Fee Methods ============
301
+ async getFeeRates() {
302
+ const response = await fetchWithTimeout2(`${this.baseUrl}/fee-estimates`);
303
+ if (!response.ok) {
304
+ throw new Error(`Blockstream API error: ${response.status} ${response.statusText}`);
305
+ }
306
+ const fees = await response.json();
307
+ return {
308
+ fastest: Math.ceil(fees["1"] || fees["2"] || 10),
309
+ halfHour: Math.ceil(fees["3"] || fees["4"] || 8),
310
+ hour: Math.ceil(fees["6"] || fees["12"] || 5),
311
+ economy: Math.ceil(fees["144"] || fees["504"] || 2),
312
+ minimum: Math.ceil(fees["1008"] || 1)
313
+ };
314
+ }
315
+ };
316
+
317
+ // src/utils/btc-service.ts
318
+ var globalConfig = {};
319
+ function configureBtcService(config) {
320
+ globalConfig = config;
321
+ defaultService = null;
322
+ }
323
+ function getBtcServiceConfig() {
324
+ return { ...globalConfig };
325
+ }
326
+ function race(promises) {
327
+ return Promise.race(promises);
328
+ }
329
+ var BtcService = class {
330
+ constructor(network = "mainnet", config) {
331
+ this.name = "btc-service";
332
+ this._network = network;
333
+ this._config = { ...globalConfig, ...config };
334
+ this._mempool = new MempoolService(network, this._config.mempool);
335
+ this._blockstream = new BlockstreamService(network, this._config.blockstream);
336
+ }
337
+ get network() {
338
+ return this._network;
339
+ }
340
+ /**
341
+ * Get the underlying Mempool service for direct access
342
+ */
343
+ get mempool() {
344
+ return this._mempool;
345
+ }
346
+ /**
347
+ * Get the underlying Blockstream service for direct access
348
+ */
349
+ get blockstream() {
350
+ return this._blockstream;
351
+ }
352
+ /**
353
+ * Get current configuration
354
+ */
355
+ get config() {
356
+ return { ...this._config };
357
+ }
358
+ setNetwork(network) {
359
+ this._network = network;
360
+ this._mempool.setNetwork(network);
361
+ this._blockstream.setNetwork(network);
362
+ }
363
+ /**
364
+ * Update configuration
365
+ */
366
+ setConfig(config) {
367
+ this._config = { ...this._config, ...config };
368
+ if (config.mempool) {
369
+ this._mempool.setCustomEndpoints(config.mempool);
370
+ }
371
+ if (config.blockstream) {
372
+ this._blockstream.setCustomEndpoints(config.blockstream);
373
+ }
374
+ }
375
+ /**
376
+ * Execute method based on preferred provider setting
377
+ */
378
+ async executeWithProvider(mempoolFn, blockstreamFn) {
379
+ const provider = this._config.preferredProvider ?? "race";
380
+ switch (provider) {
381
+ case "mempool":
382
+ return mempoolFn();
383
+ case "blockstream":
384
+ return blockstreamFn();
385
+ case "race":
386
+ default:
387
+ return race([mempoolFn(), blockstreamFn()]);
388
+ }
389
+ }
390
+ // ============ UTXO Methods ============
391
+ async getUtxos(address2) {
392
+ return this.executeWithProvider(
393
+ () => this._mempool.getUtxos(address2),
394
+ () => this._blockstream.getUtxos(address2)
395
+ );
396
+ }
397
+ async getUtxosWithTxHex(address2) {
398
+ return this.executeWithProvider(
399
+ () => this._mempool.getUtxosWithTxHex(address2),
400
+ () => this._blockstream.getUtxosWithTxHex(address2)
401
+ );
402
+ }
403
+ // ============ Transaction Methods ============
404
+ async getTxHex(txid) {
405
+ return this.executeWithProvider(
406
+ () => this._mempool.getTxHex(txid),
407
+ () => this._blockstream.getTxHex(txid)
408
+ );
409
+ }
410
+ async getTransaction(txid) {
411
+ return this.executeWithProvider(
412
+ () => this._mempool.getTransaction(txid),
413
+ () => this._blockstream.getTransaction(txid)
414
+ );
415
+ }
416
+ async getFullTransaction(txid) {
417
+ return this.executeWithProvider(
418
+ () => this._mempool.getFullTransaction(txid),
419
+ () => this._blockstream.getFullTransaction(txid)
420
+ );
421
+ }
422
+ async broadcastTransaction(txHex) {
423
+ return this.executeWithProvider(
424
+ () => this._mempool.broadcastTransaction(txHex),
425
+ () => this._blockstream.broadcastTransaction(txHex)
426
+ );
427
+ }
428
+ // ============ Address Methods ============
429
+ async getAddressInfo(address2) {
430
+ return this.executeWithProvider(
431
+ () => this._mempool.getAddressInfo(address2),
432
+ () => this._blockstream.getAddressInfo(address2)
433
+ );
434
+ }
435
+ async getBalance(address2) {
436
+ return this.executeWithProvider(
437
+ () => this._mempool.getBalance(address2),
438
+ () => this._blockstream.getBalance(address2)
439
+ );
440
+ }
441
+ async getConfirmedBalance(address2) {
442
+ return this.executeWithProvider(
443
+ () => this._mempool.getConfirmedBalance(address2),
444
+ () => this._blockstream.getConfirmedBalance(address2)
445
+ );
446
+ }
447
+ // ============ Fee Methods ============
448
+ async getFeeRates() {
449
+ return this.executeWithProvider(
450
+ () => this._mempool.getFeeRates(),
451
+ () => this._blockstream.getFeeRates()
452
+ );
453
+ }
454
+ };
455
+ var defaultService = null;
456
+ function getDefaultService(network = "mainnet") {
457
+ if (!defaultService || defaultService.network !== network) {
458
+ defaultService = new BtcService(network);
459
+ }
460
+ return defaultService;
461
+ }
462
+ async function getUtxos(address2, network = "mainnet") {
463
+ return getDefaultService(network).getUtxos(address2);
464
+ }
465
+ async function getUtxosWithTxHex(address2, network = "mainnet") {
466
+ return getDefaultService(network).getUtxosWithTxHex(address2);
467
+ }
468
+ async function getTxHex(txid, network = "mainnet") {
469
+ return getDefaultService(network).getTxHex(txid);
470
+ }
471
+ async function getTransaction(txid, network = "mainnet") {
472
+ return getDefaultService(network).getTransaction(txid);
473
+ }
474
+ async function getFullTransaction(txid, network = "mainnet") {
475
+ return getDefaultService(network).getFullTransaction(txid);
476
+ }
477
+ async function broadcastTransaction(txHex, network = "mainnet") {
478
+ return getDefaultService(network).broadcastTransaction(txHex);
479
+ }
480
+ async function getAddressInfo(address2, network = "mainnet") {
481
+ return getDefaultService(network).getAddressInfo(address2);
482
+ }
483
+ async function getBalance(address2, network = "mainnet") {
484
+ return getDefaultService(network).getBalance(address2);
485
+ }
486
+ async function getConfirmedBalance(address2, network = "mainnet") {
487
+ return getDefaultService(network).getConfirmedBalance(address2);
488
+ }
489
+ async function getFeeRates(network = "mainnet") {
490
+ return getDefaultService(network).getFeeRates();
491
+ }
492
+ function hexToBytes(hex) {
493
+ const cleanHex = hex.replace(/^0x/, "");
494
+ const bytes = new Uint8Array(cleanHex.length / 2);
495
+ for (let i = 0; i < bytes.length; i++) {
496
+ bytes[i] = parseInt(cleanHex.substring(i * 2, i * 2 + 2), 16);
497
+ }
498
+ return bytes;
499
+ }
500
+ function bytesToHex(bytes) {
501
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
502
+ }
503
+ function toXOnly(pubKey) {
504
+ return pubKey.subarray(1, 33);
505
+ }
506
+ function getAddressType(address2) {
507
+ if (address2.startsWith("bc1q") || address2.startsWith("tb1q")) {
508
+ return "segwit";
509
+ }
510
+ if (address2.startsWith("bc1p") || address2.startsWith("tb1p")) {
511
+ return "taproot";
512
+ }
513
+ if (address2.startsWith("3") || address2.startsWith("2")) {
514
+ return "nested-segwit";
515
+ }
516
+ return "legacy";
517
+ }
518
+ function getBitcoinJsNetwork(network) {
519
+ switch (network) {
520
+ case "mainnet":
521
+ return bitcoin__namespace.networks.bitcoin;
522
+ case "testnet":
523
+ case "testnet4":
524
+ case "signet":
525
+ return bitcoin__namespace.networks.testnet;
526
+ default:
527
+ return bitcoin__namespace.networks.bitcoin;
528
+ }
529
+ }
530
+ function getInputVBytes(addressType) {
531
+ switch (addressType) {
532
+ case "taproot":
533
+ return 58;
534
+ case "segwit":
535
+ return 68;
536
+ case "nested-segwit":
537
+ return 91;
538
+ default:
539
+ return 148;
540
+ }
541
+ }
542
+ function getOutputVBytes(addressType) {
543
+ switch (addressType) {
544
+ case "taproot":
545
+ return 43;
546
+ case "segwit":
547
+ return 31;
548
+ case "nested-segwit":
549
+ return 32;
550
+ default:
551
+ return 34;
552
+ }
553
+ }
554
+ function getDustThreshold(addressType) {
555
+ return addressType === "legacy" ? 546 : 294;
556
+ }
557
+ function selectUtxos(utxos, fromAddressType, toAddressType, amount, feeRate) {
558
+ const inputVBytes = getInputVBytes(fromAddressType);
559
+ const outputVBytes = getOutputVBytes(toAddressType);
560
+ const baseVBytes = 10.5;
561
+ const sortedUtxos = [...utxos].sort((a, b) => b.value - a.value);
562
+ const selectedUtxos = [];
563
+ let totalValue = 0;
564
+ for (const utxo of sortedUtxos) {
565
+ selectedUtxos.push(utxo);
566
+ totalValue += utxo.value;
567
+ const estimatedVBytes2 = baseVBytes + selectedUtxos.length * inputVBytes + 2 * outputVBytes;
568
+ const estimatedFee2 = Math.ceil(estimatedVBytes2 * feeRate);
569
+ if (totalValue >= amount + estimatedFee2) {
570
+ return { selectedUtxos, totalValue, estimatedFee: estimatedFee2 };
571
+ }
572
+ }
573
+ const estimatedVBytes = baseVBytes + selectedUtxos.length * inputVBytes + 2 * outputVBytes;
574
+ const estimatedFee = Math.ceil(estimatedVBytes * feeRate);
575
+ return { selectedUtxos, totalValue, estimatedFee };
576
+ }
577
+ async function generatePsbtForSend(toAddress, amount, fromAddress, publicKey, network, options) {
578
+ const btcService = new BtcService(network);
579
+ const btcNetwork = getBitcoinJsNetwork(network);
580
+ const allUtxos = await btcService.getUtxos(fromAddress);
581
+ const confirmedUtxos = allUtxos.filter(
582
+ (utxo) => utxo.status?.confirmed !== false
583
+ );
584
+ if (confirmedUtxos.length === 0) {
585
+ throw new Error("No confirmed UTXOs available for spending");
586
+ }
587
+ let feeRate = options?.feeRate;
588
+ if (!feeRate) {
589
+ const feeRates = await btcService.getFeeRates();
590
+ feeRate = feeRates.hour;
591
+ }
592
+ if (options?.feeRateMultiplier) {
593
+ feeRate = Math.ceil(feeRate * options.feeRateMultiplier);
594
+ }
595
+ const fromAddressType = getAddressType(fromAddress);
596
+ const toAddressType = getAddressType(toAddress);
597
+ const { selectedUtxos, totalValue, estimatedFee } = selectUtxos(
598
+ confirmedUtxos,
599
+ fromAddressType,
600
+ toAddressType,
601
+ amount,
602
+ feeRate
603
+ );
604
+ if (totalValue < amount + estimatedFee) {
605
+ throw new Error(
606
+ `Insufficient funds. Available: ${totalValue} sats, Required: ${amount + estimatedFee} sats (including fee)`
607
+ );
608
+ }
609
+ const dustThreshold = getDustThreshold(fromAddressType);
610
+ let changeAmount = totalValue - amount - estimatedFee;
611
+ if (changeAmount > 0 && changeAmount <= dustThreshold) {
612
+ changeAmount = 0;
613
+ }
614
+ const psbt = new bitcoin__namespace.Psbt({ network: btcNetwork });
615
+ const publicKeyBytes = hexToBytes(publicKey);
616
+ const inputsToSign = [];
617
+ for (let i = 0; i < selectedUtxos.length; i++) {
618
+ const utxo = selectedUtxos[i];
619
+ const script = bitcoin__namespace.address.toOutputScript(fromAddress, btcNetwork);
620
+ if (fromAddressType === "taproot") {
621
+ psbt.addInput({
622
+ hash: utxo.txid,
623
+ index: utxo.vout,
624
+ witnessUtxo: {
625
+ script,
626
+ value: BigInt(utxo.value)
627
+ },
628
+ tapInternalKey: toXOnly(publicKeyBytes)
629
+ });
630
+ } else if (fromAddressType === "segwit") {
631
+ psbt.addInput({
632
+ hash: utxo.txid,
633
+ index: utxo.vout,
634
+ witnessUtxo: {
635
+ script,
636
+ value: BigInt(utxo.value)
637
+ }
638
+ });
639
+ } else if (fromAddressType === "nested-segwit") {
640
+ const p2wpkh = bitcoin__namespace.payments.p2wpkh({
641
+ pubkey: publicKeyBytes,
642
+ network: btcNetwork
643
+ });
644
+ if (!p2wpkh.output) {
645
+ throw new Error("Failed to generate P2WPKH redeem script");
646
+ }
647
+ psbt.addInput({
648
+ hash: utxo.txid,
649
+ index: utxo.vout,
650
+ witnessUtxo: {
651
+ script,
652
+ value: BigInt(utxo.value)
653
+ },
654
+ redeemScript: p2wpkh.output
655
+ });
656
+ } else {
657
+ psbt.addInput({
658
+ hash: utxo.txid,
659
+ index: utxo.vout,
660
+ witnessUtxo: {
661
+ script,
662
+ value: BigInt(utxo.value)
663
+ }
664
+ });
665
+ }
666
+ inputsToSign.push({ address: fromAddress, index: i });
667
+ }
668
+ psbt.addOutput({
669
+ address: toAddress,
670
+ value: BigInt(amount)
671
+ });
672
+ if (changeAmount > 0) {
673
+ psbt.addOutput({
674
+ address: fromAddress,
675
+ value: BigInt(Math.floor(changeAmount))
676
+ });
677
+ }
678
+ return {
679
+ psbt,
680
+ psbtHex: psbt.toHex(),
681
+ psbtBase64: psbt.toBase64(),
682
+ btcNetwork,
683
+ selectedUtxos,
684
+ totalInputValue: totalValue,
685
+ estimatedFee,
686
+ changeAmount,
687
+ inputsToSign
688
+ };
689
+ }
690
+ function finalizeAllInputs(signedPsbt, inputCount) {
691
+ for (let i = 0; i < inputCount; i++) {
692
+ try {
693
+ signedPsbt.finalizeInput(i);
694
+ } catch (finalizeError) {
695
+ console.warn(
696
+ `Failed to finalize input ${i}, attempting alternative finalization:`,
697
+ finalizeError
698
+ );
699
+ try {
700
+ signedPsbt.finalizeInput(i, () => ({
701
+ finalScriptSig: void 0,
702
+ finalScriptWitness: void 0
703
+ }));
704
+ } catch {
705
+ console.warn(`Could not finalize input ${i}`);
706
+ }
707
+ }
708
+ }
709
+ }
710
+ async function finalizeAndBroadcast(signedPsbtHex, network, inputCount) {
711
+ const btcNetwork = getBitcoinJsNetwork(network);
712
+ const btcService = new BtcService(network);
713
+ const signedPsbt = bitcoin__namespace.Psbt.fromHex(signedPsbtHex, { network: btcNetwork });
714
+ finalizeAllInputs(signedPsbt, inputCount);
715
+ const tx = signedPsbt.extractTransaction();
716
+ const txHex = tx.toHex();
717
+ return await btcService.broadcastTransaction(txHex);
718
+ }
719
+ function deriveAddressFromPublicKey(publicKeyHex, addressType, network) {
720
+ const btcNetwork = getBitcoinJsNetwork(network);
721
+ const publicKeyBytes = hexToBytes(publicKeyHex);
722
+ switch (addressType) {
723
+ case "legacy": {
724
+ const p2pkh = bitcoin__namespace.payments.p2pkh({
725
+ pubkey: publicKeyBytes,
726
+ network: btcNetwork
727
+ });
728
+ if (!p2pkh.address) {
729
+ throw new Error("Failed to derive legacy address from public key");
730
+ }
731
+ return p2pkh.address;
732
+ }
733
+ case "nested-segwit": {
734
+ const p2wpkh = bitcoin__namespace.payments.p2wpkh({
735
+ pubkey: publicKeyBytes,
736
+ network: btcNetwork
737
+ });
738
+ const p2sh = bitcoin__namespace.payments.p2sh({
739
+ redeem: p2wpkh,
740
+ network: btcNetwork
741
+ });
742
+ if (!p2sh.address) {
743
+ throw new Error("Failed to derive nested-segwit address from public key");
744
+ }
745
+ return p2sh.address;
746
+ }
747
+ case "segwit": {
748
+ const p2wpkh = bitcoin__namespace.payments.p2wpkh({
749
+ pubkey: publicKeyBytes,
750
+ network: btcNetwork
751
+ });
752
+ if (!p2wpkh.address) {
753
+ throw new Error("Failed to derive segwit address from public key");
754
+ }
755
+ return p2wpkh.address;
756
+ }
757
+ case "taproot": {
758
+ const xOnlyPubKey = toXOnly(publicKeyBytes);
759
+ const p2tr = bitcoin__namespace.payments.p2tr({
760
+ internalPubkey: xOnlyPubKey,
761
+ network: btcNetwork
762
+ });
763
+ if (!p2tr.address) {
764
+ throw new Error("Failed to derive taproot address from public key");
765
+ }
766
+ return p2tr.address;
767
+ }
768
+ default:
769
+ throw new Error(`Unsupported address type: ${addressType}`);
770
+ }
771
+ }
772
+
773
+ exports.BlockstreamService = BlockstreamService;
774
+ exports.BtcService = BtcService;
775
+ exports.MempoolService = MempoolService;
776
+ exports.broadcastTransaction = broadcastTransaction;
777
+ exports.bytesToHex = bytesToHex;
778
+ exports.configureBtcService = configureBtcService;
779
+ exports.deriveAddressFromPublicKey = deriveAddressFromPublicKey;
780
+ exports.finalizeAllInputs = finalizeAllInputs;
781
+ exports.finalizeAndBroadcast = finalizeAndBroadcast;
782
+ exports.generatePsbtForSend = generatePsbtForSend;
783
+ exports.getAddressInfo = getAddressInfo;
784
+ exports.getAddressType = getAddressType;
785
+ exports.getBalance = getBalance;
786
+ exports.getBitcoinJsNetwork = getBitcoinJsNetwork;
787
+ exports.getBtcServiceConfig = getBtcServiceConfig;
788
+ exports.getConfirmedBalance = getConfirmedBalance;
789
+ exports.getDustThreshold = getDustThreshold;
790
+ exports.getFeeRates = getFeeRates;
791
+ exports.getFullTransaction = getFullTransaction;
792
+ exports.getInputVBytes = getInputVBytes;
793
+ exports.getOutputVBytes = getOutputVBytes;
794
+ exports.getTransaction = getTransaction;
795
+ exports.getTxHex = getTxHex;
796
+ exports.getUtxos = getUtxos;
797
+ exports.getUtxosWithTxHex = getUtxosWithTxHex;
798
+ exports.hexToBytes = hexToBytes;
799
+ exports.selectUtxos = selectUtxos;
800
+ exports.toXOnly = toXOnly;
801
+ //# sourceMappingURL=out.js.map
802
+ //# sourceMappingURL=chunk-FISNQZZ7.js.map