@dynamic-labs-sdk/bitcoin 0.1.0-alpha.18 → 0.1.0-alpha.20

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 (112) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/addBitcoinInjectedWalletsExtension.cjs.js +538 -0
  3. package/addBitcoinInjectedWalletsExtension.esm.js +532 -0
  4. package/index.cjs.js +137 -7
  5. package/index.esm.js +134 -8
  6. package/injected.cjs.d.ts +1 -0
  7. package/injected.cjs.js +12 -0
  8. package/injected.esm.d.ts +1 -0
  9. package/injected.esm.js +9 -0
  10. package/package.json +11 -3
  11. package/src/BitcoinWalletProvider.types.d.ts +61 -0
  12. package/src/BitcoinWalletProvider.types.d.ts.map +1 -0
  13. package/src/addBitcoinExtension/addBitcoinExtension.d.ts.map +1 -1
  14. package/src/errors/InvalidPsbtError.d.ts +5 -0
  15. package/src/errors/InvalidPsbtError.d.ts.map +1 -0
  16. package/src/errors/NotBitcoinProviderError.d.ts +8 -0
  17. package/src/errors/NotBitcoinProviderError.d.ts.map +1 -0
  18. package/src/errors/SendBitcoinRawTransactionError.d.ts +9 -0
  19. package/src/errors/SendBitcoinRawTransactionError.d.ts.map +1 -0
  20. package/src/exports/index.d.ts +6 -0
  21. package/src/exports/index.d.ts.map +1 -1
  22. package/src/exports/injected.d.ts +2 -0
  23. package/src/exports/injected.d.ts.map +1 -0
  24. package/src/injected/addBitcoinInjectedWalletsExtension/addBitcoinInjectedWalletsExtension.d.ts +10 -0
  25. package/src/injected/addBitcoinInjectedWalletsExtension/addBitcoinInjectedWalletsExtension.d.ts.map +1 -0
  26. package/src/injected/addBitcoinInjectedWalletsExtension/index.d.ts +2 -0
  27. package/src/injected/addBitcoinInjectedWalletsExtension/index.d.ts.map +1 -0
  28. package/src/injected/utils/phantom/PhantomBitcoinInjectedProvider.types.d.ts +26 -0
  29. package/src/injected/utils/phantom/PhantomBitcoinInjectedProvider.types.d.ts.map +1 -0
  30. package/src/injected/utils/phantom/createPhantomBitcoinWalletProvider/createPhantomBitcoinWalletProvider.d.ts +11 -0
  31. package/src/injected/utils/phantom/createPhantomBitcoinWalletProvider/createPhantomBitcoinWalletProvider.d.ts.map +1 -0
  32. package/src/injected/utils/phantom/createPhantomBitcoinWalletProvider/index.d.ts +2 -0
  33. package/src/injected/utils/phantom/createPhantomBitcoinWalletProvider/index.d.ts.map +1 -0
  34. package/src/injected/utils/phantom/getPhantomInjectedProvider/getPhantomInjectedProvider.d.ts +2 -0
  35. package/src/injected/utils/phantom/getPhantomInjectedProvider/getPhantomInjectedProvider.d.ts.map +1 -0
  36. package/src/injected/utils/phantom/getPhantomInjectedProvider/index.d.ts +2 -0
  37. package/src/injected/utils/phantom/getPhantomInjectedProvider/index.d.ts.map +1 -0
  38. package/src/injected/utils/unisat/UnisatInjectedProvider.types.d.ts +46 -0
  39. package/src/injected/utils/unisat/UnisatInjectedProvider.types.d.ts.map +1 -0
  40. package/src/injected/utils/unisat/createUnisatWalletProvider/createUnisatWalletProvider.d.ts +11 -0
  41. package/src/injected/utils/unisat/createUnisatWalletProvider/createUnisatWalletProvider.d.ts.map +1 -0
  42. package/src/injected/utils/unisat/createUnisatWalletProvider/index.d.ts +2 -0
  43. package/src/injected/utils/unisat/createUnisatWalletProvider/index.d.ts.map +1 -0
  44. package/src/injected/utils/unisat/getUnisatInjectedProvider/getUnisatInjectedProvider.d.ts +2 -0
  45. package/src/injected/utils/unisat/getUnisatInjectedProvider/getUnisatInjectedProvider.d.ts.map +1 -0
  46. package/src/injected/utils/unisat/getUnisatInjectedProvider/index.d.ts +2 -0
  47. package/src/injected/utils/unisat/getUnisatInjectedProvider/index.d.ts.map +1 -0
  48. package/src/isBitcoinWalletProvider/index.d.ts +2 -0
  49. package/src/isBitcoinWalletProvider/index.d.ts.map +1 -0
  50. package/src/isBitcoinWalletProvider/isBitcoinWalletProvider.d.ts +4 -0
  51. package/src/isBitcoinWalletProvider/isBitcoinWalletProvider.d.ts.map +1 -0
  52. package/src/sendBitcoin/index.d.ts +2 -0
  53. package/src/sendBitcoin/index.d.ts.map +1 -0
  54. package/src/sendBitcoin/sendBitcoin.d.ts +18 -0
  55. package/src/sendBitcoin/sendBitcoin.d.ts.map +1 -0
  56. package/src/sendRawTransaction/index.d.ts +2 -0
  57. package/src/sendRawTransaction/index.d.ts.map +1 -0
  58. package/src/sendRawTransaction/sendRawTransaction.d.ts +16 -0
  59. package/src/sendRawTransaction/sendRawTransaction.d.ts.map +1 -0
  60. package/src/signPsbt/index.d.ts +2 -0
  61. package/src/signPsbt/index.d.ts.map +1 -0
  62. package/src/signPsbt/signPsbt.d.ts +18 -0
  63. package/src/signPsbt/signPsbt.d.ts.map +1 -0
  64. package/src/signPsbts/index.d.ts +2 -0
  65. package/src/signPsbts/index.d.ts.map +1 -0
  66. package/src/signPsbts/signPsbts.d.ts +18 -0
  67. package/src/signPsbts/signPsbts.d.ts.map +1 -0
  68. package/src/utils/convertNetworkIdForPsbt/convertNetworkIdForPsbt.d.ts +3 -0
  69. package/src/utils/convertNetworkIdForPsbt/convertNetworkIdForPsbt.d.ts.map +1 -0
  70. package/src/utils/convertNetworkIdForPsbt/index.d.ts +2 -0
  71. package/src/utils/convertNetworkIdForPsbt/index.d.ts.map +1 -0
  72. package/src/utils/convertNetworkIdToSatsConnectNetworkType/convertNetworkIdToSatsConnectNetworkType.d.ts +3 -0
  73. package/src/utils/convertNetworkIdToSatsConnectNetworkType/convertNetworkIdToSatsConnectNetworkType.d.ts.map +1 -0
  74. package/src/utils/convertNetworkIdToSatsConnectNetworkType/index.d.ts +2 -0
  75. package/src/utils/convertNetworkIdToSatsConnectNetworkType/index.d.ts.map +1 -0
  76. package/src/utils/createPsbtOptions/createPsbtOptions.d.ts +14 -0
  77. package/src/utils/createPsbtOptions/createPsbtOptions.d.ts.map +1 -0
  78. package/src/utils/createPsbtOptions/index.d.ts +2 -0
  79. package/src/utils/createPsbtOptions/index.d.ts.map +1 -0
  80. package/src/utils/getMempoolApiUrl/getMempoolApiUrl.d.ts +1 -1
  81. package/src/utils/getPsbtInputsToSignForSatsConnect/getPsbtInputsToSignForSatsConnect.d.ts +16 -0
  82. package/src/utils/getPsbtInputsToSignForSatsConnect/getPsbtInputsToSignForSatsConnect.d.ts.map +1 -0
  83. package/src/utils/getPsbtInputsToSignForSatsConnect/index.d.ts +2 -0
  84. package/src/utils/getPsbtInputsToSignForSatsConnect/index.d.ts.map +1 -0
  85. package/src/utils/getSatsConnectSigningProtocol/getSatsConnectSigningProtocol.d.ts +4 -0
  86. package/src/utils/getSatsConnectSigningProtocol/getSatsConnectSigningProtocol.d.ts.map +1 -0
  87. package/src/utils/getSatsConnectSigningProtocol/index.d.ts +2 -0
  88. package/src/utils/getSatsConnectSigningProtocol/index.d.ts.map +1 -0
  89. package/src/utils/getSigHashType/getSigHashType.d.ts +13 -0
  90. package/src/utils/getSigHashType/getSigHashType.d.ts.map +1 -0
  91. package/src/utils/getSigHashType/index.d.ts +2 -0
  92. package/src/utils/getSigHashType/index.d.ts.map +1 -0
  93. package/src/utils/signMultipleTransactionsWithSatsConnect/index.d.ts +2 -0
  94. package/src/utils/signMultipleTransactionsWithSatsConnect/index.d.ts.map +1 -0
  95. package/src/utils/signMultipleTransactionsWithSatsConnect/signMultipleTransactionsWithSatsConnect.d.ts +11 -0
  96. package/src/utils/signMultipleTransactionsWithSatsConnect/signMultipleTransactionsWithSatsConnect.d.ts.map +1 -0
  97. package/src/utils/validatePsbt/extractAddressFromInput/extractAddressFromInput.d.ts +13 -0
  98. package/src/utils/validatePsbt/extractAddressFromInput/extractAddressFromInput.d.ts.map +1 -0
  99. package/src/utils/validatePsbt/extractAddressFromInput/index.d.ts +2 -0
  100. package/src/utils/validatePsbt/extractAddressFromInput/index.d.ts.map +1 -0
  101. package/src/utils/validatePsbt/index.d.ts +2 -0
  102. package/src/utils/validatePsbt/index.d.ts.map +1 -0
  103. package/src/utils/validatePsbt/validatePsbt.d.ts +18 -0
  104. package/src/utils/validatePsbt/validatePsbt.d.ts.map +1 -0
  105. package/src/utils/validatePsbt/validateSigHash/index.d.ts +2 -0
  106. package/src/utils/validatePsbt/validateSigHash/index.d.ts.map +1 -0
  107. package/src/utils/validatePsbt/validateSigHash/validateSigHash.d.ts +8 -0
  108. package/src/utils/validatePsbt/validateSigHash/validateSigHash.d.ts.map +1 -0
  109. package/src/utils/validatePsbt/validateSigningAddress/index.d.ts +2 -0
  110. package/src/utils/validatePsbt/validateSigningAddress/index.d.ts.map +1 -0
  111. package/src/utils/validatePsbt/validateSigningAddress/validateSigningAddress.d.ts +10 -0
  112. package/src/utils/validatePsbt/validateSigningAddress/validateSigningAddress.d.ts.map +1 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.1.0-alpha.20 (2025-10-15)
2
+
3
+ This was a version bump only, there were no code changes.
4
+
5
+ ## 0.1.0-alpha.19 (2025-10-10)
6
+
7
+ This was a version bump only, there were no code changes.
8
+
1
9
  ## 0.1.0-alpha.18 (2025-10-08)
2
10
 
3
11
  ### 🚀 Features
@@ -0,0 +1,538 @@
1
+ 'use strict';
2
+
3
+ var core = require('@dynamic-labs-sdk/client/core');
4
+ var client = require('@dynamic-labs-sdk/client');
5
+ var sdkApiCore = require('@dynamic-labs/sdk-api-core');
6
+ var bitcoinjsLib = require('bitcoinjs-lib');
7
+
8
+ var name = "@dynamic-labs-sdk/bitcoin";
9
+ var version = "0.1.0-alpha.20";
10
+
11
+ function _extends() {
12
+ _extends = Object.assign || function assign(target) {
13
+ for(var i = 1; i < arguments.length; i++){
14
+ var source = arguments[i];
15
+ for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
16
+ }
17
+ return target;
18
+ };
19
+ return _extends.apply(this, arguments);
20
+ }
21
+
22
+ const MEMPOOL_API_URL = 'https://mempool.space/api';
23
+ const MEMPOOL_API_URL_TESTNET = 'https://mempool.space/testnet/api';
24
+
25
+ const getMempoolApiUrl = (address)=>address.startsWith('t') ? MEMPOOL_API_URL_TESTNET : MEMPOOL_API_URL;
26
+
27
+ const satoshisToBtc = (satoshis)=>satoshis / 100000000;
28
+
29
+ const fetchBtcBalance = async ({ address })=>{
30
+ const API_URL = getMempoolApiUrl(address);
31
+ const response = await fetch(`${API_URL}/address/${address}`);
32
+ if (!response.ok) {
33
+ return null;
34
+ }
35
+ const addressInfo = await response.json();
36
+ if (!(addressInfo == null ? void 0 : addressInfo.chain_stats) || !(addressInfo == null ? void 0 : addressInfo.mempool_stats)) {
37
+ return null;
38
+ }
39
+ const confirmedBalanceInSats = Number(addressInfo.chain_stats.funded_txo_sum) - Number(addressInfo.chain_stats.spent_txo_sum);
40
+ const unconfirmedBalanceInSats = Number(addressInfo.mempool_stats.funded_txo_sum) - Number(addressInfo.mempool_stats.spent_txo_sum);
41
+ const balance = satoshisToBtc(confirmedBalanceInSats + unconfirmedBalanceInSats);
42
+ return balance.toString();
43
+ };
44
+
45
+ const createBitcoinNetworkProvider = (networkData)=>_extends({}, core.createBaseNetworkProvider('BTC', networkData), {
46
+ getBalance: async ({ address })=>({
47
+ balance: await fetchBtcBalance({
48
+ address
49
+ })
50
+ })
51
+ });
52
+
53
+ const registerBitcoinNetworkProviderBuilder = (client)=>{
54
+ const networkProviderBuilderRegistry = core.getNetworkProviderBuilderRegistry(client);
55
+ /**
56
+ * If the Bitcoin network provider builder is already registered, return.
57
+ */ if (networkProviderBuilderRegistry.get().get('BTC')) {
58
+ return;
59
+ }
60
+ networkProviderBuilderRegistry.register({
61
+ builder: createBitcoinNetworkProvider,
62
+ chain: 'BTC'
63
+ });
64
+ };
65
+
66
+ const PHANTOM_METADATA = {
67
+ displayName: 'Phantom',
68
+ icon: `${core.DYNAMIC_ICONIC_SPRITE_URL}#phantom`
69
+ };
70
+ const createPhantomBitcoinWalletProvider = ({ dynamicClient, injectedProvider })=>{
71
+ const chain = 'BTC';
72
+ const walletProviderType = sdkApiCore.WalletProviderEnum.BrowserExtension;
73
+ const key = core.formatWalletProviderKey({
74
+ chain,
75
+ displayName: PHANTOM_METADATA.displayName,
76
+ walletProviderType
77
+ });
78
+ const connect = async ()=>{
79
+ const accounts = await injectedProvider.requestAccounts();
80
+ const addresses = accounts.map((account)=>({
81
+ address: account.address,
82
+ publicKey: account.publicKey,
83
+ type: account.purpose === 'payment' ? 'payment' : 'ordinals'
84
+ }));
85
+ // put ordinals addresses first, as they should be the main walletAccount address
86
+ addresses.sort((a)=>a.type === 'ordinals' ? -1 : 1);
87
+ return {
88
+ addresses
89
+ };
90
+ };
91
+ const getActiveNetworkId = async ()=>core.getActiveNetworkIdFromLastKnownRegistry({
92
+ client: dynamicClient,
93
+ walletProviderKey: key
94
+ });
95
+ // there's no specific method to get connected addresses in Phantom
96
+ // so we use the connect method to get the addresses
97
+ const getConnectedAddresses = async ()=>{
98
+ const { addresses } = await connect();
99
+ return {
100
+ addresses: addresses.map((address)=>address.address)
101
+ };
102
+ };
103
+ const signMessage = async ({ message, walletAccount })=>{
104
+ core.assertDefined(walletAccount, 'Wallet account not found');
105
+ await client.assertWalletAccountSigningAvailability({
106
+ walletAccount
107
+ }, dynamicClient);
108
+ const result = await injectedProvider.signMessage(walletAccount.address, new TextEncoder().encode(message));
109
+ return {
110
+ signature: core.getBuffer().from(result.signature).toString('base64')
111
+ };
112
+ };
113
+ const signPsbt = async ({ request, walletAccount })=>{
114
+ var _request_signature;
115
+ await client.assertWalletAccountSigningAvailability({
116
+ walletAccount
117
+ }, dynamicClient);
118
+ const psbtFromBase64 = bitcoinjsLib.Psbt.fromBase64(request.unsignedPsbtBase64);
119
+ var _request_signature_map;
120
+ const inputsToSign = (_request_signature_map = (_request_signature = request.signature) == null ? void 0 : _request_signature.map((sig)=>{
121
+ var _sig_signingIndexes;
122
+ return {
123
+ address: sig.address,
124
+ sigHash: request.allowedSighash[0],
125
+ signingIndexes: (_sig_signingIndexes = sig.signingIndexes) != null ? _sig_signingIndexes : []
126
+ };
127
+ })) != null ? _request_signature_map : [];
128
+ const signedPsbt = await injectedProvider.signPSBT(psbtFromBase64.toBuffer(), {
129
+ inputsToSign
130
+ });
131
+ return {
132
+ signedPsbt: bitcoinjsLib.Psbt.fromBuffer(signedPsbt).toBase64()
133
+ };
134
+ };
135
+ const signPsbts = async ({ requests, walletAccount })=>{
136
+ await client.assertWalletAccountSigningAvailability({
137
+ walletAccount
138
+ }, dynamicClient);
139
+ const signedPsbts = [];
140
+ for (const request of requests){
141
+ const signedPsbtResponse = await signPsbt({
142
+ request,
143
+ walletAccount
144
+ });
145
+ if (signedPsbtResponse) {
146
+ signedPsbts.push(signedPsbtResponse.signedPsbt);
147
+ }
148
+ }
149
+ return {
150
+ signedPsbts
151
+ };
152
+ };
153
+ const { getEventEmitter, cleanupEventEmitter } = core.createWalletProviderEventEmitter({
154
+ removeEventListeners: ()=>{
155
+ injectedProvider == null ? void 0 : injectedProvider.removeAllListeners();
156
+ },
157
+ setupEventListeners: ({ handleAccountsChanged })=>{
158
+ injectedProvider == null ? void 0 : injectedProvider.on('accountsChanged', (accounts)=>{
159
+ handleAccountsChanged({
160
+ addresses: accounts.map((account)=>account.address)
161
+ });
162
+ });
163
+ }
164
+ });
165
+ const terminate = async ()=>{
166
+ cleanupEventEmitter();
167
+ };
168
+ return {
169
+ chain,
170
+ connect,
171
+ get events () {
172
+ return getEventEmitter();
173
+ },
174
+ getActiveNetworkId,
175
+ getConnectedAddresses,
176
+ groupKey: core.formatWalletProviderGroupKey(PHANTOM_METADATA.displayName),
177
+ key,
178
+ metadata: PHANTOM_METADATA,
179
+ signMessage,
180
+ signPsbt,
181
+ signPsbts,
182
+ terminate,
183
+ walletProviderType
184
+ };
185
+ };
186
+
187
+ const PHANTOM_BITCOIN_PROVIDER_LOCATOR = 'phantom.bitcoin';
188
+ const getPhantomInjectedProvider = ()=>{
189
+ return core.getInjectedProviderFromWindow(PHANTOM_BITCOIN_PROVIDER_LOCATOR);
190
+ };
191
+
192
+ class InvalidPsbtError extends client.BaseError {
193
+ constructor(message){
194
+ super({
195
+ cause: null,
196
+ code: 'invalid_psbt_error',
197
+ docsUrl: null,
198
+ name: 'InvalidPsbtError',
199
+ shortMessage: message
200
+ });
201
+ }
202
+ }
203
+
204
+ /**
205
+ * This method will return the signature hash type for the current input.
206
+ * If there is a sighashType, it will return that
207
+ * If there is a witnessUtxo AND it is a taproot address, then it will return SIGHASH_DEFAULT
208
+ * Otherwise, it will return SIGHASH_ALL
209
+ */ const getSigHashType = ({ input })=>{
210
+ var _input_witnessUtxo;
211
+ if (input == null ? void 0 : input.sighashType) {
212
+ return input.sighashType;
213
+ }
214
+ let isTaprootAddress = false;
215
+ if ((_input_witnessUtxo = input.witnessUtxo) == null ? void 0 : _input_witnessUtxo.script) {
216
+ try {
217
+ bitcoinjsLib.payments.p2tr({
218
+ output: input.witnessUtxo.script
219
+ });
220
+ isTaprootAddress = true;
221
+ } catch (e) {
222
+ // do nothing - address is not taproot
223
+ }
224
+ }
225
+ return isTaprootAddress ? bitcoinjsLib.Transaction.SIGHASH_DEFAULT : bitcoinjsLib.Transaction.SIGHASH_ALL;
226
+ };
227
+
228
+ const validateSigHash = ({ allowedSigHashTypes, input })=>{
229
+ const sigHashType = getSigHashType({
230
+ input
231
+ });
232
+ // if the request has allowedSigHashTypes, then we need to make sure that the sigHashType
233
+ // is a member of that array before continuing
234
+ if ((allowedSigHashTypes == null ? void 0 : allowedSigHashTypes.length) && !allowedSigHashTypes.includes(sigHashType)) {
235
+ throw new InvalidPsbtError(`sigHashType ${sigHashType} not in allowed list`);
236
+ }
237
+ };
238
+
239
+ /**
240
+ * This method extracts the address from the input data of the psbt.
241
+ * The address is stored as script (Buffer) in either the witnessUtxo or nonWitnessUtxo as an output
242
+ */ const extractAddressFromInput = ({ index, input, psbt })=>{
243
+ let extractedAddress;
244
+ try {
245
+ var _input_witnessUtxo;
246
+ if ((_input_witnessUtxo = input.witnessUtxo) == null ? void 0 : _input_witnessUtxo.script) {
247
+ extractedAddress = bitcoinjsLib.address.fromOutputScript(input.witnessUtxo.script);
248
+ }
249
+ if (input.nonWitnessUtxo) {
250
+ const nonWitnessTxn = bitcoinjsLib.Transaction.fromBuffer(input.nonWitnessUtxo);
251
+ const txOut = nonWitnessTxn.outs[psbt.txInputs[index].index];
252
+ extractedAddress = bitcoinjsLib.address.fromOutputScript(txOut.script);
253
+ }
254
+ return extractedAddress;
255
+ } catch (e) {
256
+ return extractedAddress;
257
+ }
258
+ };
259
+
260
+ const validateSigningAddress = ({ index, inputAtIndex, psbt, signingAddress })=>{
261
+ // we need to extract the address from the input at the current signing index
262
+ // to be able to compare it to the address provided in the request for the current index
263
+ const extractedAddress = extractAddressFromInput({
264
+ index,
265
+ input: inputAtIndex,
266
+ psbt
267
+ });
268
+ if (!extractedAddress) {
269
+ throw new InvalidPsbtError(`Could not extract address from input at index ${index}`);
270
+ }
271
+ if (extractedAddress !== signingAddress) {
272
+ throw new InvalidPsbtError(`Signing address does not match with address extracted from input at index ${index}`);
273
+ }
274
+ };
275
+
276
+ /**
277
+ * This method will validate the psbt against the signature data provided in the request
278
+ * It checks 3 things:
279
+ * - That the signing index exists in the input
280
+ * - That the address provided in the request matches the address in the input,
281
+ * unless the disableAddressValidation flag is set
282
+ * - That the sigHashType of the input is a member of the allowedSigHashTypes array
283
+ */ const validatePsbt = ({ allowedSigHashTypes, psbt, signatureData })=>{
284
+ if (!(signatureData == null ? void 0 : signatureData.length)) {
285
+ return;
286
+ }
287
+ for (const input of signatureData){
288
+ const { address: signingAddress, signingIndexes, // request from ME in cases of multi-sig. Steven wanted this defaulted to true
289
+ disableAddressValidation = true } = input;
290
+ if (!(signingIndexes == null ? void 0 : signingIndexes.length)) {
291
+ return;
292
+ }
293
+ if (!signingAddress) {
294
+ throw new InvalidPsbtError('Missing signing address');
295
+ }
296
+ for (const index of signingIndexes){
297
+ const inputAtIndex = psbt.data.inputs[index];
298
+ if (!inputAtIndex) {
299
+ throw new InvalidPsbtError(`Missing input for index ${index}`);
300
+ }
301
+ if (!disableAddressValidation) {
302
+ validateSigningAddress({
303
+ index,
304
+ inputAtIndex,
305
+ psbt,
306
+ signingAddress
307
+ });
308
+ }
309
+ validateSigHash({
310
+ allowedSigHashTypes,
311
+ input: inputAtIndex
312
+ });
313
+ }
314
+ }
315
+ };
316
+
317
+ /**
318
+ * This method will create the psbt sign options for the given request
319
+ * It will validate the psbt against the signature data provided in the request
320
+ * It will return the psbt sign options with the toSignInputs added if the signature data is provided
321
+ */ const createPsbtOptions = ({ psbt, request })=>{
322
+ const psbtSignOptions = {
323
+ autoFinalized: false
324
+ };
325
+ if (!request.signature) {
326
+ return psbtSignOptions;
327
+ }
328
+ validatePsbt({
329
+ allowedSigHashTypes: request.allowedSighash,
330
+ psbt,
331
+ signatureData: request.signature
332
+ });
333
+ const toSignInputs = [];
334
+ for (const signature of request.signature){
335
+ var _signature_signingIndexes;
336
+ if ((_signature_signingIndexes = signature.signingIndexes) == null ? void 0 : _signature_signingIndexes.length) {
337
+ for (const index of signature.signingIndexes){
338
+ toSignInputs.push({
339
+ address: signature.address,
340
+ disableAddressValidation: signature.disableAddressValidation,
341
+ index,
342
+ sighashTypes: request.allowedSighash
343
+ });
344
+ }
345
+ }
346
+ }
347
+ psbtSignOptions.toSignInputs = toSignInputs;
348
+ return psbtSignOptions;
349
+ };
350
+
351
+ const UNISAT_METADATA = {
352
+ displayName: 'UniSat',
353
+ icon: `${core.DYNAMIC_ICONIC_SPRITE_URL}#unisat`
354
+ };
355
+ const createUnisatWalletProvider = ({ dynamicClient, injectedProvider })=>{
356
+ const chain = 'BTC';
357
+ const walletProviderType = sdkApiCore.WalletProviderEnum.BrowserExtension;
358
+ const key = core.formatWalletProviderKey({
359
+ chain,
360
+ displayName: UNISAT_METADATA.displayName,
361
+ walletProviderType
362
+ });
363
+ const connect = async ()=>{
364
+ const addresses = await injectedProvider.requestAccounts();
365
+ return {
366
+ addresses: addresses.map((address)=>({
367
+ address
368
+ }))
369
+ };
370
+ };
371
+ const disconnect = async ()=>{
372
+ return injectedProvider.disconnect();
373
+ };
374
+ const getActiveNetworkId = async ()=>core.getActiveNetworkIdFromLastKnownRegistry({
375
+ client: dynamicClient,
376
+ walletProviderKey: key
377
+ });
378
+ const getConnectedAddresses = async ()=>{
379
+ const accounts = await injectedProvider.getAccounts();
380
+ return {
381
+ addresses: accounts
382
+ };
383
+ };
384
+ const sendBitcoin = async ({ transaction, walletAccount })=>{
385
+ await client.assertWalletAccountSigningAvailability({
386
+ walletAccount
387
+ }, dynamicClient);
388
+ const transactionId = await injectedProvider.sendBitcoin(transaction.recipientAddress, Number(transaction.amount));
389
+ return {
390
+ transactionId
391
+ };
392
+ };
393
+ const signMessage = async ({ message, walletAccount, protocol })=>{
394
+ core.assertDefined(walletAccount, 'Wallet account not found');
395
+ await client.assertWalletAccountSigningAvailability({
396
+ walletAccount
397
+ }, dynamicClient);
398
+ const signedMessage = await injectedProvider.signMessage(message, protocol);
399
+ return {
400
+ signature: signedMessage
401
+ };
402
+ };
403
+ const signPsbt = async ({ request, walletAccount })=>{
404
+ await client.assertWalletAccountSigningAvailability({
405
+ walletAccount
406
+ }, dynamicClient);
407
+ const psbtFromBase64 = bitcoinjsLib.Psbt.fromBase64(request.unsignedPsbtBase64);
408
+ const signedPsbtHex = await injectedProvider.signPsbt(psbtFromBase64.toHex(), createPsbtOptions({
409
+ psbt: psbtFromBase64,
410
+ request
411
+ }));
412
+ return {
413
+ signedPsbt: bitcoinjsLib.Psbt.fromHex(signedPsbtHex).toBase64()
414
+ };
415
+ };
416
+ const signPsbts = async ({ requests, walletAccount })=>{
417
+ await client.assertWalletAccountSigningAvailability({
418
+ walletAccount
419
+ }, dynamicClient);
420
+ const psbtHexs = [];
421
+ const psbtOptions = [];
422
+ for (const request of requests){
423
+ const psbtFromBase64 = bitcoinjsLib.Psbt.fromBase64(request.unsignedPsbtBase64);
424
+ psbtHexs.push(psbtFromBase64.toHex());
425
+ psbtOptions.push(createPsbtOptions({
426
+ psbt: psbtFromBase64,
427
+ request
428
+ }));
429
+ }
430
+ const signedPsbtHexs = await injectedProvider.signPsbts(psbtHexs, psbtOptions);
431
+ return {
432
+ signedPsbts: signedPsbtHexs.map((signedPsbtHex)=>bitcoinjsLib.Psbt.fromHex(signedPsbtHex).toBase64())
433
+ };
434
+ };
435
+ const { getEventEmitter, cleanupEventEmitter } = core.createWalletProviderEventEmitter({
436
+ removeEventListeners: ()=>{
437
+ injectedProvider == null ? void 0 : injectedProvider.removeAllListeners();
438
+ },
439
+ setupEventListeners: ({ handleAccountsChanged, handleNetworkChanged })=>{
440
+ injectedProvider == null ? void 0 : injectedProvider.on('accountsChanged', (addresses)=>{
441
+ handleAccountsChanged({
442
+ addresses
443
+ });
444
+ });
445
+ injectedProvider == null ? void 0 : injectedProvider.on('networkChanged', (network)=>{
446
+ handleNetworkChanged({
447
+ networkId: network
448
+ });
449
+ });
450
+ }
451
+ });
452
+ const terminate = async ()=>{
453
+ cleanupEventEmitter();
454
+ };
455
+ return {
456
+ chain,
457
+ connect,
458
+ disconnect,
459
+ get events () {
460
+ return getEventEmitter();
461
+ },
462
+ getActiveNetworkId,
463
+ getConnectedAddresses,
464
+ groupKey: core.formatWalletProviderGroupKey(UNISAT_METADATA.displayName),
465
+ key,
466
+ metadata: UNISAT_METADATA,
467
+ sendBitcoin,
468
+ signMessage,
469
+ signPsbt,
470
+ signPsbts,
471
+ terminate,
472
+ walletProviderType
473
+ };
474
+ };
475
+
476
+ const UNISAT_PROVIDER_LOCATOR = 'unisat';
477
+ const getUnisatInjectedProvider = ()=>{
478
+ return core.getInjectedProviderFromWindow(UNISAT_PROVIDER_LOCATOR);
479
+ };
480
+
481
+ const BITCOIN_INJECTED_WALLETS_EXTENSION_KEY = 'bitcoinInjectedWallets';
482
+ /**
483
+ * Adds the Bitcoin Injected Wallets extension to the Dynamic client.
484
+ *
485
+ * This extension enables integration with many Bitcoin wallets, like MagicEden, Xverse, Unisat, Phantom, and more.
486
+ *
487
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
488
+ */ const addBitcoinInjectedWalletsExtension = (client = core.getDefaultClient())=>{
489
+ if (core.hasExtension({
490
+ extensionKey: BITCOIN_INJECTED_WALLETS_EXTENSION_KEY
491
+ }, client)) {
492
+ return;
493
+ }
494
+ core.registerExtension({
495
+ extensionKey: BITCOIN_INJECTED_WALLETS_EXTENSION_KEY
496
+ }, client);
497
+ registerBitcoinNetworkProviderBuilder(client);
498
+ const walletProviderRegistry = core.getWalletProviderRegistry(client);
499
+ const injectedWalletProviders = [];
500
+ // Create and register Unisat wallet provider
501
+ const unisatInjectedProvider = getUnisatInjectedProvider();
502
+ if (unisatInjectedProvider) {
503
+ const unisatWalletProvider = createUnisatWalletProvider({
504
+ dynamicClient: client,
505
+ injectedProvider: unisatInjectedProvider
506
+ });
507
+ injectedWalletProviders.push(unisatWalletProvider);
508
+ }
509
+ // Create and register Phantom wallet provider
510
+ const phantomInjectedProvider = getPhantomInjectedProvider();
511
+ if (phantomInjectedProvider) {
512
+ const phantomWalletProvider = createPhantomBitcoinWalletProvider({
513
+ dynamicClient: client,
514
+ injectedProvider: phantomInjectedProvider
515
+ });
516
+ injectedWalletProviders.push(phantomWalletProvider);
517
+ }
518
+ // TODO: create and register MagicEden wallet provider
519
+ // TODO: create and register Xverse wallet provider
520
+ // TODO: create and register OKX wallet provider
521
+ // TODO: create and register Bitget wallet provider
522
+ // TODO: create and register OneKey wallet provider
523
+ // TODO: create and register Oyl wallet provider
524
+ // TODO: create and register Binance wallet provider
525
+ // TODO: create and register Leather wallet provider
526
+ injectedWalletProviders.forEach((walletProvider)=>{
527
+ walletProviderRegistry.register({
528
+ priority: core.WalletProviderPriority.WINDOW_INJECT,
529
+ walletProvider
530
+ });
531
+ });
532
+ };
533
+
534
+ exports.InvalidPsbtError = InvalidPsbtError;
535
+ exports.addBitcoinInjectedWalletsExtension = addBitcoinInjectedWalletsExtension;
536
+ exports.getMempoolApiUrl = getMempoolApiUrl;
537
+ exports.name = name;
538
+ exports.version = version;