@dynamic-labs-sdk/bitcoin 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{addBitcoinInjectedWalletsExtension-BD_sDgf9.esm.js → addBitcoinInjectedWalletsExtension-B7E0hK1o.esm.js} +2 -2
- package/dist/{addBitcoinInjectedWalletsExtension-BD_sDgf9.esm.js.map → addBitcoinInjectedWalletsExtension-B7E0hK1o.esm.js.map} +1 -1
- package/dist/{addBitcoinInjectedWalletsExtension-Bg3KI_MJ.cjs → addBitcoinInjectedWalletsExtension-CTMHhM9_.cjs} +3 -3
- package/dist/{addBitcoinInjectedWalletsExtension-Bg3KI_MJ.cjs.map → addBitcoinInjectedWalletsExtension-CTMHhM9_.cjs.map} +1 -1
- package/dist/{addWaasBitcoinExtension-D69lYSx2.esm.js → addWaasBitcoinExtension-DD7tP-MB.esm.js} +140 -49
- package/dist/addWaasBitcoinExtension-DD7tP-MB.esm.js.map +1 -0
- package/dist/{addWaasBitcoinExtension-BuxHED6F.cjs → addWaasBitcoinExtension-Du9epD-l.cjs} +150 -47
- package/dist/addWaasBitcoinExtension-Du9epD-l.cjs.map +1 -0
- package/dist/{bitcoinTransferAmount-vyn5gKOV.cjs → bitcoinTransferAmount-Bz15MjRP.cjs} +22 -3
- package/dist/{bitcoinTransferAmount-vyn5gKOV.cjs.map → bitcoinTransferAmount-Bz15MjRP.cjs.map} +1 -1
- package/dist/{bitcoinTransferAmount-D6zp-bUs.esm.js → bitcoinTransferAmount-DvQ6eq1s.esm.js} +4 -3
- package/dist/{bitcoinTransferAmount-D6zp-bUs.esm.js.map → bitcoinTransferAmount-DvQ6eq1s.esm.js.map} +1 -1
- package/dist/errors/UnsupportedBitcoinNetworkError.d.ts +5 -0
- package/dist/errors/UnsupportedBitcoinNetworkError.d.ts.map +1 -0
- package/dist/exports/waas.d.ts +3 -0
- package/dist/exports/waas.d.ts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.esm.js +3 -3
- package/dist/injected.cjs +3 -3
- package/dist/injected.esm.js +2 -2
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/waas/constants.d.ts +0 -4
- package/dist/waas/constants.d.ts.map +1 -1
- package/dist/waas/utils/broadcastTransaction/broadcastTransaction.d.ts +6 -2
- package/dist/waas/utils/broadcastTransaction/broadcastTransaction.d.ts.map +1 -1
- package/dist/waas/utils/buildPsbt/buildPsbt.d.ts +2 -1
- package/dist/waas/utils/buildPsbt/buildPsbt.d.ts.map +1 -1
- package/dist/waas/utils/calculateFeeAndChange/calculateFeeAndChange.d.ts +2 -1
- package/dist/waas/utils/calculateFeeAndChange/calculateFeeAndChange.d.ts.map +1 -1
- package/dist/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.d.ts.map +1 -1
- package/dist/waas/utils/estimateTransactionFee/estimateTransactionFee.d.ts +2 -1
- package/dist/waas/utils/estimateTransactionFee/estimateTransactionFee.d.ts.map +1 -1
- package/dist/waas/utils/getActiveBitcoinNetworkConfig/getActiveBitcoinNetworkConfig.d.ts +22 -0
- package/dist/waas/utils/getActiveBitcoinNetworkConfig/getActiveBitcoinNetworkConfig.d.ts.map +1 -0
- package/dist/waas/utils/getActiveBitcoinNetworkConfig/index.d.ts +3 -0
- package/dist/waas/utils/getActiveBitcoinNetworkConfig/index.d.ts.map +1 -0
- package/dist/waas/utils/getFeeRecommendations/getFeeRecommendations.d.ts +4 -1
- package/dist/waas/utils/getFeeRecommendations/getFeeRecommendations.d.ts.map +1 -1
- package/dist/waas/utils/getUTXOs/getUTXOs.d.ts +6 -2
- package/dist/waas/utils/getUTXOs/getUTXOs.d.ts.map +1 -1
- package/dist/waas/utils/getWaasBitcoinAddressForNetwork/getWaasBitcoinAddressForNetwork.d.ts +19 -0
- package/dist/waas/utils/getWaasBitcoinAddressForNetwork/getWaasBitcoinAddressForNetwork.d.ts.map +1 -0
- package/dist/waas/utils/getWaasBitcoinAddressForNetwork/index.d.ts +2 -0
- package/dist/waas/utils/getWaasBitcoinAddressForNetwork/index.d.ts.map +1 -0
- package/dist/waas.cjs +4 -2
- package/dist/waas.cjs.map +1 -1
- package/dist/waas.esm.js +3 -3
- package/dist/waas.esm.js.map +1 -1
- package/package.json +3 -3
- package/dist/addWaasBitcoinExtension-BuxHED6F.cjs.map +0 -1
- package/dist/addWaasBitcoinExtension-D69lYSx2.esm.js.map +0 -1
package/dist/{addWaasBitcoinExtension-D69lYSx2.esm.js → addWaasBitcoinExtension-DD7tP-MB.esm.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as registerBitcoinNetworkProviderBuilder, i as bitcoinExecuteSwapTransaction, t as bitcoinTransferAmount } from "./bitcoinTransferAmount-
|
|
1
|
+
import { c as registerBitcoinNetworkProviderBuilder, d as MEMPOOL_API_URL_SIGNET, f as MEMPOOL_API_URL_TESTNET, i as bitcoinExecuteSwapTransaction, t as bitcoinTransferAmount, u as MEMPOOL_API_URL } from "./bitcoinTransferAmount-DvQ6eq1s.esm.js";
|
|
2
2
|
import { WalletProviderPriority, assertDefined, consumeMfaTokenIfRequiredForAction, formatWalletProviderGroupKey, formatWalletProviderKey, getActiveNetworkIdFromLastKnownRegistry, getBuffer, getCore, getDefaultClient, getSignedSessionId, getWalletProviderRegistry, hasExtension, registerExtension, switchActiveNetworkInLastKnownRegistry } from "@dynamic-labs-sdk/client/core";
|
|
3
3
|
import { BaseError } from "@dynamic-labs-sdk/client";
|
|
4
|
-
import { MFAAction, WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
|
|
4
|
+
import { MFAAction, WalletAddressType, WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
|
|
5
5
|
import { Psbt, address, networks, payments } from "bitcoinjs-lib";
|
|
6
6
|
import { DYNAMIC_WAAS_METADATA, createWaasProvider, getAllUserWaasAddressesForChain } from "@dynamic-labs-sdk/client/waas/core";
|
|
7
7
|
import ecc from "@bitcoinerlab/secp256k1";
|
|
@@ -38,11 +38,30 @@ var TransactionRequiredError = class extends BaseError {
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
//#endregion
|
|
41
|
-
//#region src/waas/
|
|
41
|
+
//#region src/waas/utils/broadcastTransaction/broadcastTransaction.ts
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Sends a raw Bitcoin transaction to the mempool
|
|
44
|
+
*
|
|
45
|
+
* @param options.rawTransaction - The raw transaction in hex format
|
|
46
|
+
* @param options.mempoolApiUrl - Base mempool API URL for the active network
|
|
47
|
+
* @returns The transaction ID
|
|
48
|
+
* @throws {TransactionRequiredError} if no transaction is specified
|
|
49
|
+
* @throws {TransactionBroadcastFailedError} if broadcasting fails
|
|
50
|
+
* @notInstrumented
|
|
44
51
|
*/
|
|
45
|
-
const
|
|
52
|
+
const broadcastTransaction = async ({ mempoolApiUrl = MEMPOOL_API_URL, rawTransaction }) => {
|
|
53
|
+
if (!rawTransaction) throw new TransactionRequiredError();
|
|
54
|
+
const response = await fetch(`${mempoolApiUrl}/tx`, {
|
|
55
|
+
body: rawTransaction,
|
|
56
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
57
|
+
method: "POST"
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) throw new TransactionBroadcastFailedError({ response });
|
|
60
|
+
return response.text();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/waas/constants.ts
|
|
46
65
|
/**
|
|
47
66
|
* Number of satoshis per Bitcoin
|
|
48
67
|
*/
|
|
@@ -75,28 +94,6 @@ const DEFAULT_FEE_ESTIMATE = 1e3;
|
|
|
75
94
|
*/
|
|
76
95
|
const RBF_SEQUENCE = 4294967293;
|
|
77
96
|
|
|
78
|
-
//#endregion
|
|
79
|
-
//#region src/waas/utils/broadcastTransaction/broadcastTransaction.ts
|
|
80
|
-
/**
|
|
81
|
-
* Sends a raw Bitcoin transaction to the mempool
|
|
82
|
-
*
|
|
83
|
-
* @param rawTransaction - The raw transaction in hex format
|
|
84
|
-
* @returns The transaction ID
|
|
85
|
-
* @throws {TransactionRequiredError} if no transaction is specified
|
|
86
|
-
* @throws {TransactionBroadcastFailedError} if broadcasting fails
|
|
87
|
-
* @notInstrumented
|
|
88
|
-
*/
|
|
89
|
-
const broadcastTransaction = async (rawTransaction) => {
|
|
90
|
-
if (!rawTransaction) throw new TransactionRequiredError();
|
|
91
|
-
const response = await fetch(`${MEMPOOL_API_URL}/tx`, {
|
|
92
|
-
body: rawTransaction,
|
|
93
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
94
|
-
method: "POST"
|
|
95
|
-
});
|
|
96
|
-
if (!response.ok) throw new TransactionBroadcastFailedError({ response });
|
|
97
|
-
return response.text();
|
|
98
|
-
};
|
|
99
|
-
|
|
100
97
|
//#endregion
|
|
101
98
|
//#region src/errors/InsufficientFundsError.ts
|
|
102
99
|
var InsufficientFundsError = class extends BaseError {
|
|
@@ -250,12 +247,13 @@ var FeeRecommendationsFetchError = class extends BaseError {
|
|
|
250
247
|
/**
|
|
251
248
|
* Gets fee recommendations from mempool.space API
|
|
252
249
|
*
|
|
250
|
+
* @param options.mempoolApiUrl - Base mempool API URL for the active network
|
|
253
251
|
* @returns Fee recommendation data with rates in sat/vB
|
|
254
252
|
* @throws FeeRecommendationsFetchError if fetching fee recommendations fails
|
|
255
253
|
* @notInstrumented
|
|
256
254
|
*/
|
|
257
|
-
const getFeeRecommendations = async () => {
|
|
258
|
-
const response = await fetch(`${
|
|
255
|
+
const getFeeRecommendations = async ({ mempoolApiUrl = MEMPOOL_API_URL } = {}) => {
|
|
256
|
+
const response = await fetch(`${mempoolApiUrl}/v1/fees/recommended`);
|
|
259
257
|
if (!response.ok) throw new FeeRecommendationsFetchError({ response });
|
|
260
258
|
return response.json();
|
|
261
259
|
};
|
|
@@ -271,9 +269,9 @@ const getFeeRecommendations = async () => {
|
|
|
271
269
|
* @returns Estimated fee in satoshis
|
|
272
270
|
* @notInstrumented
|
|
273
271
|
*/
|
|
274
|
-
const estimateTransactionFee = async ({ feePriority = "medium", numInputs, numOutputs }) => {
|
|
272
|
+
const estimateTransactionFee = async ({ feePriority = "medium", mempoolApiUrl, numInputs, numOutputs }) => {
|
|
275
273
|
try {
|
|
276
|
-
const feeData = await getFeeRecommendations();
|
|
274
|
+
const feeData = await getFeeRecommendations({ mempoolApiUrl });
|
|
277
275
|
let feePerByte;
|
|
278
276
|
if (feePriority === "high") feePerByte = feeData.fastestFee ?? feeData.halfHourFee ?? 1;
|
|
279
277
|
else if (feePriority === "low") feePerByte = feeData.economyFee ?? feeData.hourFee ?? 1;
|
|
@@ -297,9 +295,10 @@ const estimateTransactionFee = async ({ feePriority = "medium", numInputs, numOu
|
|
|
297
295
|
* @returns Object with feeEstimate, changeAmountNumber, and hasChangeOutput
|
|
298
296
|
* @notInstrumented
|
|
299
297
|
*/
|
|
300
|
-
const calculateFeeAndChange = async ({ amountInSatoshis, feePriority, selectedTotalValue, selectedUTXOs }) => {
|
|
298
|
+
const calculateFeeAndChange = async ({ amountInSatoshis, feePriority, mempoolApiUrl, selectedTotalValue, selectedUTXOs }) => {
|
|
301
299
|
let feeEstimate = await estimateTransactionFee({
|
|
302
300
|
feePriority,
|
|
301
|
+
mempoolApiUrl,
|
|
303
302
|
numInputs: selectedUTXOs.length,
|
|
304
303
|
numOutputs: 1
|
|
305
304
|
});
|
|
@@ -308,6 +307,7 @@ const calculateFeeAndChange = async ({ amountInSatoshis, feePriority, selectedTo
|
|
|
308
307
|
if (changeAmount > 0 && Number(changeAmount) >= DUST_LIMIT) {
|
|
309
308
|
feeEstimate = await estimateTransactionFee({
|
|
310
309
|
feePriority,
|
|
310
|
+
mempoolApiUrl,
|
|
311
311
|
numInputs: selectedUTXOs.length,
|
|
312
312
|
numOutputs: 2
|
|
313
313
|
});
|
|
@@ -359,13 +359,14 @@ var UTXOsFetchError = class extends BaseError {
|
|
|
359
359
|
/**
|
|
360
360
|
* Gets UTXOs for a Bitcoin address from mempool.space API
|
|
361
361
|
*
|
|
362
|
-
* @param address - The Bitcoin address to get UTXOs for
|
|
362
|
+
* @param options.address - The Bitcoin address to get UTXOs for
|
|
363
|
+
* @param options.mempoolApiUrl - Base mempool API URL for the active network
|
|
363
364
|
* @returns Array of UTXOs
|
|
364
365
|
* @throws UTXOsFetchError if fetching UTXOs fails
|
|
365
366
|
* @notInstrumented
|
|
366
367
|
*/
|
|
367
|
-
const getUTXOs = async (address$1) => {
|
|
368
|
-
const response = await fetch(`${
|
|
368
|
+
const getUTXOs = async ({ address: address$1, mempoolApiUrl = MEMPOOL_API_URL }) => {
|
|
369
|
+
const response = await fetch(`${mempoolApiUrl}/address/${address$1}/utxo`);
|
|
369
370
|
if (!response.ok) throw new UTXOsFetchError({
|
|
370
371
|
address: address$1,
|
|
371
372
|
response
|
|
@@ -473,19 +474,23 @@ const validateNotTaproot = (accountAddress) => {
|
|
|
473
474
|
* @throws Error if insufficient funds, no UTXOs, or other errors
|
|
474
475
|
* @notInstrumented
|
|
475
476
|
*/
|
|
476
|
-
const buildPsbt = async ({ accountAddress, amountInSatoshis, feePriority = "medium", network, publicKeyHex, recipientAddress }) => {
|
|
477
|
+
const buildPsbt = async ({ accountAddress, amountInSatoshis, feePriority = "medium", mempoolApiUrl, network, publicKeyHex, recipientAddress }) => {
|
|
477
478
|
if (amountInSatoshis <= BigInt(0)) throw new InvalidAmountError({
|
|
478
479
|
amountInSatoshis: Number(amountInSatoshis),
|
|
479
480
|
reason: "Amount must be greater than 0"
|
|
480
481
|
});
|
|
481
482
|
validateNotTaproot(accountAddress);
|
|
482
|
-
const allUTXOs = await getUTXOs(
|
|
483
|
+
const allUTXOs = await getUTXOs({
|
|
484
|
+
address: accountAddress,
|
|
485
|
+
mempoolApiUrl
|
|
486
|
+
});
|
|
483
487
|
if (allUTXOs.length === 0) throw new NoUTXOsFoundError({ address: accountAddress });
|
|
484
488
|
const publicKeyBuffer = new Uint8Array(getBuffer().from(publicKeyHex, "hex"));
|
|
485
489
|
const publicKeyPair = ECPairFactory(ecc).fromPublicKey(publicKeyBuffer, { compressed: true });
|
|
486
490
|
const amountInSatoshisNumber = Number(amountInSatoshis);
|
|
487
491
|
const initialFeeEstimate = await estimateTransactionFee({
|
|
488
492
|
feePriority,
|
|
493
|
+
mempoolApiUrl,
|
|
489
494
|
numInputs: 1,
|
|
490
495
|
numOutputs: 1
|
|
491
496
|
});
|
|
@@ -504,6 +509,7 @@ const buildPsbt = async ({ accountAddress, amountInSatoshis, feePriority = "medi
|
|
|
504
509
|
const { changeAmountNumber, feeEstimate, hasChangeOutput } = await calculateFeeAndChange({
|
|
505
510
|
amountInSatoshis,
|
|
506
511
|
feePriority,
|
|
512
|
+
mempoolApiUrl,
|
|
507
513
|
selectedTotalValue,
|
|
508
514
|
selectedUTXOs
|
|
509
515
|
});
|
|
@@ -531,6 +537,55 @@ const buildPsbt = async ({ accountAddress, amountInSatoshis, feePriority = "medi
|
|
|
531
537
|
return psbt.toBase64();
|
|
532
538
|
};
|
|
533
539
|
|
|
540
|
+
//#endregion
|
|
541
|
+
//#region src/errors/UnsupportedBitcoinNetworkError.ts
|
|
542
|
+
var UnsupportedBitcoinNetworkError = class extends BaseError {
|
|
543
|
+
constructor(networkId) {
|
|
544
|
+
super({
|
|
545
|
+
cause: null,
|
|
546
|
+
code: "unsupported_bitcoin_network_error",
|
|
547
|
+
docsUrl: null,
|
|
548
|
+
name: "UnsupportedBitcoinNetworkError",
|
|
549
|
+
shortMessage: `Unsupported Bitcoin network id: ${networkId}`
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region src/waas/utils/getActiveBitcoinNetworkConfig/getActiveBitcoinNetworkConfig.ts
|
|
556
|
+
/**
|
|
557
|
+
* Resolves a Dynamic Bitcoin network id (1 mainnet, 2 testnet, 3 signet) to
|
|
558
|
+
* the per-network configuration used by the WaaS provider. An undefined id
|
|
559
|
+
* (network never switched) resolves to mainnet.
|
|
560
|
+
*
|
|
561
|
+
* @throws {UnsupportedBitcoinNetworkError} for any other network id
|
|
562
|
+
* @notInstrumented
|
|
563
|
+
*/
|
|
564
|
+
const getActiveBitcoinNetworkConfig = ({ networkId }) => {
|
|
565
|
+
const id = networkId ?? "1";
|
|
566
|
+
switch (id) {
|
|
567
|
+
case "1": return {
|
|
568
|
+
bitcoinNetwork: "mainnet",
|
|
569
|
+
mempoolApiUrl: MEMPOOL_API_URL,
|
|
570
|
+
networkId: id,
|
|
571
|
+
psbtNetwork: networks.bitcoin
|
|
572
|
+
};
|
|
573
|
+
case "2": return {
|
|
574
|
+
bitcoinNetwork: "testnet",
|
|
575
|
+
mempoolApiUrl: MEMPOOL_API_URL_TESTNET,
|
|
576
|
+
networkId: id,
|
|
577
|
+
psbtNetwork: networks.testnet
|
|
578
|
+
};
|
|
579
|
+
case "3": return {
|
|
580
|
+
bitcoinNetwork: "testnet",
|
|
581
|
+
mempoolApiUrl: MEMPOOL_API_URL_SIGNET,
|
|
582
|
+
networkId: id,
|
|
583
|
+
psbtNetwork: networks.testnet
|
|
584
|
+
};
|
|
585
|
+
default: throw new UnsupportedBitcoinNetworkError(id);
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
|
|
534
589
|
//#endregion
|
|
535
590
|
//#region src/errors/PublicKeyNotFoundError.ts
|
|
536
591
|
var PublicKeyNotFoundError = class extends BaseError {
|
|
@@ -560,6 +615,25 @@ const getPublicKeyForWalletAccount = (walletAccount, client) => {
|
|
|
560
615
|
throw new PublicKeyNotFoundError(walletAccount.address);
|
|
561
616
|
};
|
|
562
617
|
|
|
618
|
+
//#endregion
|
|
619
|
+
//#region src/waas/utils/getWaasBitcoinAddressForNetwork/getWaasBitcoinAddressForNetwork.ts
|
|
620
|
+
/**
|
|
621
|
+
* Resolves the wallet's payment address for the given Bitcoin network. One
|
|
622
|
+
* WaaS wallet (one MPC key) exposes a per-network payment address via its
|
|
623
|
+
* network-tagged additional addresses. Falls back to the wallet account's
|
|
624
|
+
* primary address (the mainnet encoding) for legacy wallets without tagged
|
|
625
|
+
* rows.
|
|
626
|
+
*
|
|
627
|
+
* The wallet identity (keyshare/password lookups, signing) is always the
|
|
628
|
+
* primary address — this resolver is only for address-driven operations
|
|
629
|
+
* (UTXOs, balance, broadcast source).
|
|
630
|
+
*
|
|
631
|
+
* @notInstrumented
|
|
632
|
+
*/
|
|
633
|
+
const getWaasBitcoinAddressForNetwork = ({ bitcoinNetwork, walletAccount }) => {
|
|
634
|
+
return walletAccount.addressesWithTypes?.find((address$1) => address$1.type === WalletAddressType.Payment && address$1.network === bitcoinNetwork)?.address ?? walletAccount.address;
|
|
635
|
+
};
|
|
636
|
+
|
|
563
637
|
//#endregion
|
|
564
638
|
//#region src/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.ts
|
|
565
639
|
/** @notInstrumented */
|
|
@@ -579,11 +653,18 @@ const createWalletProviderForWaasBitcoin = (sdkClient) => {
|
|
|
579
653
|
client: sdkClient,
|
|
580
654
|
walletProviderKey: key
|
|
581
655
|
});
|
|
582
|
-
const switchActiveNetwork = async ({ networkId }) =>
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
656
|
+
const switchActiveNetwork = async ({ networkId }) => {
|
|
657
|
+
getActiveBitcoinNetworkConfig({ networkId });
|
|
658
|
+
return switchActiveNetworkInLastKnownRegistry({
|
|
659
|
+
client: sdkClient,
|
|
660
|
+
networkId,
|
|
661
|
+
walletProviderKey: key
|
|
662
|
+
});
|
|
663
|
+
};
|
|
664
|
+
const getActiveNetworkConfig = async () => {
|
|
665
|
+
const { networkId } = await getActiveNetworkId();
|
|
666
|
+
return getActiveBitcoinNetworkConfig({ networkId });
|
|
667
|
+
};
|
|
587
668
|
const getConnectedAddresses = async () => {
|
|
588
669
|
return { addresses: getAllUserWaasAddressesForChain({ chain }, sdkClient) };
|
|
589
670
|
};
|
|
@@ -615,10 +696,11 @@ const createWalletProviderForWaasBitcoin = (sdkClient) => {
|
|
|
615
696
|
const waasClient = await waasProvider.getWaasClient();
|
|
616
697
|
const { signature: signedSessionId } = await getSignedSessionId(sdkClient);
|
|
617
698
|
const mfaToken = await consumeMfaTokenIfRequiredForAction({ mfaAction: MFAAction.WalletWaasSign }, sdkClient);
|
|
699
|
+
const { bitcoinNetwork } = await getActiveNetworkConfig();
|
|
618
700
|
return { signature: await waasClient.signMessage({
|
|
619
701
|
accountAddress: walletAccount.address,
|
|
620
702
|
authToken: sdkClient.token ?? void 0,
|
|
621
|
-
bitcoinConfig: { network:
|
|
703
|
+
bitcoinConfig: { network: bitcoinNetwork },
|
|
622
704
|
message,
|
|
623
705
|
mfaToken,
|
|
624
706
|
signedSessionId
|
|
@@ -627,11 +709,16 @@ const createWalletProviderForWaasBitcoin = (sdkClient) => {
|
|
|
627
709
|
const buildPsbt$1 = async ({ transaction, walletAccount }) => {
|
|
628
710
|
assertDefined(walletAccount, "Wallet account is required");
|
|
629
711
|
const publicKeyHex = getPublicKeyForWalletAccount(walletAccount, sdkClient);
|
|
712
|
+
const { bitcoinNetwork, mempoolApiUrl, psbtNetwork } = await getActiveNetworkConfig();
|
|
630
713
|
return buildPsbt({
|
|
631
|
-
accountAddress:
|
|
714
|
+
accountAddress: getWaasBitcoinAddressForNetwork({
|
|
715
|
+
bitcoinNetwork,
|
|
716
|
+
walletAccount
|
|
717
|
+
}),
|
|
632
718
|
amountInSatoshis: transaction.amount,
|
|
633
719
|
feePriority: transaction.feePriority ?? "medium",
|
|
634
|
-
|
|
720
|
+
mempoolApiUrl,
|
|
721
|
+
network: psbtNetwork,
|
|
635
722
|
publicKeyHex,
|
|
636
723
|
recipientAddress: transaction.recipientAddress
|
|
637
724
|
});
|
|
@@ -651,9 +738,13 @@ const createWalletProviderForWaasBitcoin = (sdkClient) => {
|
|
|
651
738
|
},
|
|
652
739
|
walletAccount
|
|
653
740
|
});
|
|
654
|
-
const
|
|
741
|
+
const { mempoolApiUrl, psbtNetwork } = await getActiveNetworkConfig();
|
|
742
|
+
const psbt = Psbt.fromBase64(signedPsbt, { network: psbtNetwork });
|
|
655
743
|
psbt.finalizeAllInputs();
|
|
656
|
-
return { transactionId: await broadcastTransaction(
|
|
744
|
+
return { transactionId: await broadcastTransaction({
|
|
745
|
+
mempoolApiUrl,
|
|
746
|
+
rawTransaction: psbt.extractTransaction().toHex()
|
|
747
|
+
}) };
|
|
657
748
|
};
|
|
658
749
|
return {
|
|
659
750
|
...waasProvider,
|
|
@@ -703,5 +794,5 @@ const addWaasBitcoinExtension = (client = getDefaultClient()) => {
|
|
|
703
794
|
};
|
|
704
795
|
|
|
705
796
|
//#endregion
|
|
706
|
-
export { TransactionRequiredError as n,
|
|
707
|
-
//# sourceMappingURL=addWaasBitcoinExtension-
|
|
797
|
+
export { TransactionBroadcastFailedError as a, TransactionRequiredError as i, getWaasBitcoinAddressForNetwork as n, getActiveBitcoinNetworkConfig as r, addWaasBitcoinExtension as t };
|
|
798
|
+
//# sourceMappingURL=addWaasBitcoinExtension-DD7tP-MB.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addWaasBitcoinExtension-DD7tP-MB.esm.js","names":["address","feePerByte: number","address","address","selected: UTXO[]","address","address","getActiveNetworkId: WaasBitcoinWalletProvider['getActiveNetworkId']","switchActiveNetwork: WaasBitcoinWalletProvider['switchActiveNetwork']","getConnectedAddresses: WaasBitcoinWalletProvider['getConnectedAddresses']","signPsbt: WaasBitcoinWalletProvider['signPsbt']","signPsbts: WaasBitcoinWalletProvider['signPsbts']","signMessage: WaasBitcoinWalletProvider['signMessage']","buildPsbt: WaasBitcoinWalletProvider['buildPsbt']","buildPsbtUtil","sendBitcoin: WaasBitcoinWalletProvider['sendBitcoin']","buildPsbt"],"sources":["../src/errors/TransactionBroadcastFailedError.ts","../src/errors/TransactionRequiredError.ts","../src/waas/utils/broadcastTransaction/broadcastTransaction.ts","../src/waas/constants.ts","../src/errors/InsufficientFundsError.ts","../src/errors/InvalidAmountError.ts","../src/errors/NoUTXOsFoundError.ts","../src/errors/SegwitOutputScriptError.ts","../src/waas/utils/addInputsToPsbt/addInputsToPsbt.ts","../src/waas/utils/addOutputsToPsbt/addOutputsToPsbt.ts","../src/errors/FeeRecommendationsFetchError.ts","../src/waas/utils/getFeeRecommendations/getFeeRecommendations.ts","../src/waas/utils/estimateTransactionFee/estimateTransactionFee.ts","../src/waas/utils/calculateFeeAndChange/calculateFeeAndChange.ts","../src/waas/utils/calculateUTXOTotal/calculateUTXOTotal.ts","../src/errors/UTXOsFetchError.ts","../src/waas/utils/getUTXOs/getUTXOs.ts","../src/waas/utils/selectUTXOsLargestFirst/selectUTXOsLargestFirst.ts","../src/waas/utils/validateAndSelectUTXOs/validateAndSelectUTXOs.ts","../src/errors/TaprootAddressNotSupportedError.ts","../src/waas/utils/validateNotTaproot/validateNotTaproot.ts","../src/waas/utils/buildPsbt/buildPsbt.ts","../src/errors/UnsupportedBitcoinNetworkError.ts","../src/waas/utils/getActiveBitcoinNetworkConfig/getActiveBitcoinNetworkConfig.ts","../src/errors/PublicKeyNotFoundError.ts","../src/waas/utils/getPublicKeyForWalletAccount/getPublicKeyForWalletAccount.ts","../src/waas/utils/getWaasBitcoinAddressForNetwork/getWaasBitcoinAddressForNetwork.ts","../src/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.ts","../src/waas/addWaasBitcoinExtension/addWaasBitcoinExtension.ts"],"sourcesContent":["import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype TransactionBroadcastFailedErrorParams = {\n response: Response;\n};\n\nexport class TransactionBroadcastFailedError extends BaseError {\n public readonly response: Response;\n\n constructor({ response }: TransactionBroadcastFailedErrorParams) {\n super({\n cause: null,\n code: 'transaction_broadcast_failed_error',\n details: `Status: ${response.status} ${response.statusText}`,\n docsUrl: null,\n name: 'TransactionBroadcastFailedError',\n shortMessage: 'Failed to broadcast transaction to mempool',\n });\n\n this.response = response;\n }\n}\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class TransactionRequiredError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'transaction_required_error',\n docsUrl: null,\n name: 'TransactionRequiredError',\n shortMessage: 'No transaction specified for broadcast',\n });\n }\n}\n","import { MEMPOOL_API_URL } from '../../../constants';\nimport { TransactionBroadcastFailedError } from '../../../errors/TransactionBroadcastFailedError';\nimport { TransactionRequiredError } from '../../../errors/TransactionRequiredError';\n\n/**\n * Sends a raw Bitcoin transaction to the mempool\n *\n * @param options.rawTransaction - The raw transaction in hex format\n * @param options.mempoolApiUrl - Base mempool API URL for the active network\n * @returns The transaction ID\n * @throws {TransactionRequiredError} if no transaction is specified\n * @throws {TransactionBroadcastFailedError} if broadcasting fails\n * @notInstrumented\n */\nexport const broadcastTransaction = async ({\n mempoolApiUrl = MEMPOOL_API_URL,\n rawTransaction,\n}: {\n mempoolApiUrl?: string;\n rawTransaction: string;\n}): Promise<string> => {\n if (!rawTransaction) {\n throw new TransactionRequiredError();\n }\n\n const response = await fetch(`${mempoolApiUrl}/tx`, {\n body: rawTransaction,\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n method: 'POST',\n });\n\n if (!response.ok) {\n throw new TransactionBroadcastFailedError({ response });\n }\n\n return response.text();\n};\n","/**\n * Number of satoshis per Bitcoin\n */\nexport const SATOSHIS_PER_BTC = 100_000_000;\n\n/**\n * Bitcoin's dust limit in satoshis\n * Outputs below this value are considered \"dust\" and will be rejected by nodes\n */\nexport const DUST_LIMIT = 546;\n\n/**\n * Accurate vSize constants for Native SegWit (P2WPKH) transactions\n * Used for precise fee estimation\n */\nexport const VSIZE_OVERHEAD = 10.5;\n\nexport const VSIZE_INPUT_P2WPKH = 68;\n\nexport const VSIZE_OUTPUT_P2WPKH = 31;\n\n/**\n * Minimum relay fee in satoshis\n * Added to fee estimate to ensure transaction propagation\n */\nexport const MIN_RELAY_FEE = 111;\n\n/**\n * Conservative default fee estimate in satoshis\n * Used as fallback when fee estimation fails\n */\nexport const DEFAULT_FEE_ESTIMATE = 1000;\n\n/**\n * RBF (Replace-By-Fee) sequence number\n * 0xfffffffd = 4294967293 (enables RBF, not final)\n */\nexport const RBF_SEQUENCE = 0xfffffffd;\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nimport { SATOSHIS_PER_BTC } from '../waas/constants';\n\ntype InsufficientFundsErrorParams = {\n availableSatoshis: number;\n requiredSatoshis: number;\n};\n\nexport class InsufficientFundsError extends BaseError {\n public readonly availableSatoshis: number;\n\n public readonly requiredSatoshis: number;\n\n constructor({ availableSatoshis, requiredSatoshis }: InsufficientFundsErrorParams) {\n const availableBtc = availableSatoshis / SATOSHIS_PER_BTC;\n const requiredBtc = requiredSatoshis / SATOSHIS_PER_BTC;\n\n super({\n cause: null,\n code: 'insufficient_funds_error',\n details: `Available: ${availableBtc} BTC (${availableSatoshis} satoshis), Required: ${requiredBtc} BTC (${requiredSatoshis} satoshis)`,\n docsUrl: null,\n name: 'InsufficientFundsError',\n shortMessage: 'Insufficient funds for transaction',\n });\n\n this.availableSatoshis = availableSatoshis;\n\n this.requiredSatoshis = requiredSatoshis;\n }\n}\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype InvalidAmountErrorParams = {\n amountInSatoshis: number;\n reason: string;\n};\n\nexport class InvalidAmountError extends BaseError {\n public readonly amountInSatoshis: number;\n\n constructor({ amountInSatoshis, reason }: InvalidAmountErrorParams) {\n super({\n cause: null,\n code: 'invalid_amount_error',\n details: `Amount: ${amountInSatoshis} satoshis`,\n docsUrl: null,\n name: 'InvalidAmountError',\n shortMessage: reason,\n });\n\n this.amountInSatoshis = amountInSatoshis;\n }\n}\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype NoUTXOsFoundErrorParams = {\n address: string;\n};\n\nexport class NoUTXOsFoundError extends BaseError {\n public readonly address: string;\n\n constructor({ address }: NoUTXOsFoundErrorParams) {\n super({\n cause: null,\n code: 'no_utxos_found_error',\n details: `Address: ${address}`,\n docsUrl: null,\n name: 'NoUTXOsFoundError',\n shortMessage: 'No UTXOs found for this address',\n });\n\n this.address = address;\n }\n}\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class SegwitOutputScriptError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'segwit_output_script_error',\n docsUrl: null,\n name: 'SegwitOutputScriptError',\n shortMessage: 'Failed to create segwit output script',\n });\n }\n}\n","import { getBuffer } from '@dynamic-labs-sdk/client/core';\nimport type { Network, Psbt } from 'bitcoinjs-lib';\nimport { payments } from 'bitcoinjs-lib';\n\nimport { SegwitOutputScriptError } from '../../../errors/SegwitOutputScriptError';\nimport { RBF_SEQUENCE } from '../../constants';\nimport type { UTXO } from '../../WaasBitcoinWalletProvider.types';\n\ntype AddInputsToPsbtOptions = {\n network: Network;\n psbt: Psbt;\n publicKeyPair: { publicKey: Uint8Array };\n selectedUTXOs: UTXO[];\n};\n\n/**\n * Adds inputs to PSBT from selected UTXOs\n *\n * @param options.network - Bitcoin network configuration (mainnet or testnet)\n * @param options.psbt - The PSBT instance to add inputs to\n * @param options.publicKeyPair - Key pair containing the public key for witness script\n * @param options.selectedUTXOs - Array of UTXOs to add as inputs\n * @notInstrumented\n */\nexport const addInputsToPsbt = (options: AddInputsToPsbtOptions): void => {\n const { network, psbt, publicKeyPair, selectedUTXOs } = options;\n\n for (const utxo of selectedUTXOs) {\n const outputScript = payments.p2wpkh({\n network,\n pubkey: publicKeyPair.publicKey,\n }).output;\n\n if (!outputScript) {\n throw new SegwitOutputScriptError();\n }\n\n const txidBuffer = new Uint8Array(\n getBuffer().from(utxo.txid, 'hex').reverse()\n );\n\n psbt.addInput({\n hash: txidBuffer,\n index: utxo.vout,\n sequence: RBF_SEQUENCE,\n witnessUtxo: {\n script: outputScript,\n value: BigInt(utxo.value),\n },\n });\n }\n};\n","import type { Network, Psbt } from 'bitcoinjs-lib';\nimport { address } from 'bitcoinjs-lib';\n\nimport { InvalidAmountError } from '../../../errors/InvalidAmountError';\nimport { DUST_LIMIT, SATOSHIS_PER_BTC } from '../../constants';\n\ntype AddOutputsToPsbtOptions = {\n accountAddress: string;\n amountInSatoshis: number;\n changeAmount: number;\n hasChangeOutput: boolean;\n network: Network;\n psbt: Psbt;\n recipientAddress: string;\n};\n\n/**\n * Adds outputs to PSBT (recipient and optionally change)\n *\n * @param options.accountAddress - The sender's address for receiving change\n * @param options.amountInSatoshis - Amount to send to the recipient in satoshis\n * @param options.changeAmount - Amount to return as change in satoshis\n * @param options.hasChangeOutput - Whether to include a change output\n * @param options.network - Bitcoin network configuration (mainnet or testnet)\n * @param options.psbt - The PSBT instance to add outputs to\n * @param options.recipientAddress - The recipient's Bitcoin address\n * @notInstrumented\n */\nexport const addOutputsToPsbt = (options: AddOutputsToPsbtOptions): void => {\n const {\n accountAddress,\n amountInSatoshis,\n changeAmount,\n hasChangeOutput,\n network,\n psbt,\n recipientAddress,\n } = options;\n\n if (amountInSatoshis < DUST_LIMIT) {\n throw new InvalidAmountError({\n amountInSatoshis,\n reason: `Amount is below dust limit of ${DUST_LIMIT} satoshis (${DUST_LIMIT / SATOSHIS_PER_BTC} BTC)`,\n });\n }\n\n psbt.addOutput({\n script: address.toOutputScript(recipientAddress, network),\n value: BigInt(amountInSatoshis),\n });\n\n if (hasChangeOutput) {\n psbt.addOutput({\n script: address.toOutputScript(accountAddress, network),\n value: BigInt(changeAmount),\n });\n }\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype FeeRecommendationsFetchErrorParams = {\n response: Response;\n};\n\nexport class FeeRecommendationsFetchError extends BaseError {\n public readonly response: Response;\n\n constructor({ response }: FeeRecommendationsFetchErrorParams) {\n super({\n cause: null,\n code: 'fee_recommendations_fetch_error',\n details: `Status: ${response.status} ${response.statusText}`,\n docsUrl: null,\n name: 'FeeRecommendationsFetchError',\n shortMessage: 'Failed to fetch fee recommendations from mempool',\n });\n\n this.response = response;\n }\n}\n","import { MEMPOOL_API_URL } from '../../../constants';\nimport { FeeRecommendationsFetchError } from '../../../errors/FeeRecommendationsFetchError';\nimport type { FeeRecommendations } from '../../WaasBitcoinWalletProvider.types';\n\n/**\n * Gets fee recommendations from mempool.space API\n *\n * @param options.mempoolApiUrl - Base mempool API URL for the active network\n * @returns Fee recommendation data with rates in sat/vB\n * @throws FeeRecommendationsFetchError if fetching fee recommendations fails\n * @notInstrumented\n */\nexport const getFeeRecommendations = async ({\n mempoolApiUrl = MEMPOOL_API_URL,\n}: {\n mempoolApiUrl?: string;\n} = {}): Promise<FeeRecommendations> => {\n const response = await fetch(`${mempoolApiUrl}/v1/fees/recommended`);\n\n if (!response.ok) {\n throw new FeeRecommendationsFetchError({ response });\n }\n\n return response.json();\n};\n","import {\n DEFAULT_FEE_ESTIMATE,\n MIN_RELAY_FEE,\n VSIZE_INPUT_P2WPKH,\n VSIZE_OUTPUT_P2WPKH,\n VSIZE_OVERHEAD,\n} from '../../constants';\nimport type { FeePriority } from '../../WaasBitcoinWalletProvider.types';\nimport { getFeeRecommendations } from '../getFeeRecommendations';\n\ntype EstimateTransactionFeeOptions = {\n feePriority?: FeePriority;\n mempoolApiUrl?: string;\n numInputs: number;\n numOutputs: number;\n};\n\n/**\n * Estimates transaction fees based on number of inputs and outputs using accurate vSize\n *\n * @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')\n * @param options.numInputs - Number of transaction inputs (UTXOs being spent)\n * @param options.numOutputs - Number of transaction outputs\n * @returns Estimated fee in satoshis\n * @notInstrumented\n */\nexport const estimateTransactionFee = async ({\n feePriority = 'medium',\n mempoolApiUrl,\n numInputs,\n numOutputs,\n}: EstimateTransactionFeeOptions): Promise<number> => {\n try {\n const feeData = await getFeeRecommendations({ mempoolApiUrl });\n\n let feePerByte: number;\n\n if (feePriority === 'high') {\n feePerByte = feeData.fastestFee ?? feeData.halfHourFee ?? 1;\n } else if (feePriority === 'low') {\n feePerByte = feeData.economyFee ?? feeData.hourFee ?? 1;\n } else {\n feePerByte =\n feeData.halfHourFee ?? feeData.hourFee ?? feeData.economyFee ?? 1;\n }\n\n const vSize =\n VSIZE_OVERHEAD +\n numInputs * VSIZE_INPUT_P2WPKH +\n numOutputs * VSIZE_OUTPUT_P2WPKH;\n\n return Math.ceil(feePerByte * vSize) + MIN_RELAY_FEE;\n } catch {\n return DEFAULT_FEE_ESTIMATE;\n }\n};\n","import { DUST_LIMIT } from '../../constants';\nimport type { FeePriority, UTXO } from '../../WaasBitcoinWalletProvider.types';\nimport { estimateTransactionFee } from '../estimateTransactionFee';\n\ntype CalculateFeeAndChangeOptions = {\n amountInSatoshis: bigint;\n feePriority: FeePriority;\n mempoolApiUrl?: string;\n selectedTotalValue: number;\n selectedUTXOs: UTXO[];\n};\n\ntype CalculateFeeAndChangeResult = {\n changeAmountNumber: number;\n feeEstimate: number;\n hasChangeOutput: boolean;\n};\n\n/**\n * Calculates fee estimate and change amount, handling dust limit\n *\n * @param options.amountInSatoshis - Amount to send in satoshis\n * @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')\n * @param options.selectedTotalValue - Total value of selected UTXOs in satoshis\n * @param options.selectedUTXOs - Array of selected UTXOs for the transaction\n * @returns Object with feeEstimate, changeAmountNumber, and hasChangeOutput\n * @notInstrumented\n */\nexport const calculateFeeAndChange = async ({\n amountInSatoshis,\n feePriority,\n mempoolApiUrl,\n selectedTotalValue,\n selectedUTXOs,\n}: CalculateFeeAndChangeOptions): Promise<CalculateFeeAndChangeResult> => {\n let feeEstimate = await estimateTransactionFee({\n feePriority,\n mempoolApiUrl,\n numInputs: selectedUTXOs.length,\n numOutputs: 1,\n });\n\n let maxToSpend = selectedTotalValue - feeEstimate;\n let changeAmount = BigInt(maxToSpend) - amountInSatoshis;\n\n const changeAmountNumber = Number(changeAmount);\n\n if (changeAmount > 0 && changeAmountNumber >= DUST_LIMIT) {\n feeEstimate = await estimateTransactionFee({\n feePriority,\n mempoolApiUrl,\n numInputs: selectedUTXOs.length,\n numOutputs: 2,\n });\n maxToSpend = selectedTotalValue - feeEstimate;\n changeAmount = BigInt(maxToSpend) - amountInSatoshis;\n }\n\n const finalChangeAmountNumber = Number(changeAmount);\n const hasChangeOutput =\n changeAmount > 0 && finalChangeAmountNumber >= DUST_LIMIT;\n\n if (changeAmount > 0 && finalChangeAmountNumber < DUST_LIMIT) {\n feeEstimate += finalChangeAmountNumber;\n }\n\n return {\n changeAmountNumber: finalChangeAmountNumber,\n feeEstimate,\n hasChangeOutput,\n };\n};\n","import type { UTXO } from '../../WaasBitcoinWalletProvider.types';\n\n/**\n * Calculates the total value of UTXOs\n *\n * @param utxos - Array of UTXOs\n * @returns Total value in satoshis\n * @notInstrumented\n */\nexport const calculateUTXOTotal = (utxos: UTXO[]): number =>\n utxos.reduce((total: number, utxo: UTXO) => total + utxo.value, 0);\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\ntype UTXOsFetchErrorParams = {\n address: string;\n response: Response;\n};\n\nexport class UTXOsFetchError extends BaseError {\n public readonly address: string;\n\n public readonly response: Response;\n\n constructor({ address, response }: UTXOsFetchErrorParams) {\n super({\n cause: null,\n code: 'utxos_fetch_error',\n details: `Address: ${address}, Status: ${response.status} ${response.statusText}`,\n docsUrl: null,\n name: 'UTXOsFetchError',\n shortMessage: 'Failed to fetch UTXOs from mempool',\n });\n\n this.address = address;\n\n this.response = response;\n }\n}\n","import { MEMPOOL_API_URL } from '../../../constants';\nimport { UTXOsFetchError } from '../../../errors/UTXOsFetchError';\nimport type { UTXO } from '../../WaasBitcoinWalletProvider.types';\n\n/**\n * Gets UTXOs for a Bitcoin address from mempool.space API\n *\n * @param options.address - The Bitcoin address to get UTXOs for\n * @param options.mempoolApiUrl - Base mempool API URL for the active network\n * @returns Array of UTXOs\n * @throws UTXOsFetchError if fetching UTXOs fails\n * @notInstrumented\n */\nexport const getUTXOs = async ({\n address,\n mempoolApiUrl = MEMPOOL_API_URL,\n}: {\n address: string;\n mempoolApiUrl?: string;\n}): Promise<UTXO[]> => {\n const response = await fetch(`${mempoolApiUrl}/address/${address}/utxo`);\n\n if (!response.ok) {\n throw new UTXOsFetchError({ address, response });\n }\n\n return response.json();\n};\n","import type { UTXO } from '../../WaasBitcoinWalletProvider.types';\n\ntype SelectUTXOsLargestFirstOptions = {\n targetAmount: number;\n utxos: UTXO[];\n};\n\n/**\n * Selects UTXOs using Largest-First (Accumulator) strategy\n * Sorts UTXOs by value (descending) and selects until we have enough to cover amount + fees\n *\n * @param options.targetAmount - Target amount in satoshis (amount + fees + dust limit)\n * @param options.utxos - Array of available UTXOs to select from\n * @returns Selected UTXOs\n * @notInstrumented\n */\nexport const selectUTXOsLargestFirst = (\n options: SelectUTXOsLargestFirstOptions\n) => {\n const { targetAmount, utxos } = options;\n\n const sortedUTXOs = [...utxos].sort((a, b) => b.value - a.value);\n\n const selected: UTXO[] = [];\n let total = 0;\n\n for (const utxo of sortedUTXOs) {\n selected.push(utxo);\n total += utxo.value;\n\n if (total >= targetAmount) {\n break;\n }\n }\n\n return selected;\n};\n","import { InsufficientFundsError } from '../../../errors/InsufficientFundsError';\nimport type { UTXO } from '../../WaasBitcoinWalletProvider.types';\nimport { calculateUTXOTotal } from '../calculateUTXOTotal';\n\ntype ValidateAndSelectUTXOsOptions = {\n allUTXOs: UTXO[];\n amountInSatoshis: number;\n feeEstimate: number;\n selectedTotal: number;\n selectedUTXOs: UTXO[];\n};\n\n/**\n * Validates and ensures sufficient funds for the transaction\n *\n * @param options.allUTXOs - Complete array of available UTXOs for the address\n * @param options.amountInSatoshis - Amount to send in satoshis\n * @param options.feeEstimate - Estimated transaction fee in satoshis\n * @param options.selectedTotal - Total value of initially selected UTXOs in satoshis\n * @param options.selectedUTXOs - Array of initially selected UTXOs\n * @returns Validated selected UTXOs\n * @throws InsufficientFundsError if insufficient funds\n * @notInstrumented\n */\nexport const validateAndSelectUTXOs = (\n options: ValidateAndSelectUTXOsOptions\n) => {\n const {\n allUTXOs,\n amountInSatoshis,\n feeEstimate,\n selectedTotal,\n selectedUTXOs,\n } = options;\n\n const requiredAmount = amountInSatoshis + feeEstimate;\n\n if (selectedTotal >= requiredAmount) {\n return selectedUTXOs;\n }\n\n if (selectedUTXOs.length < allUTXOs.length) {\n const allTotal = calculateUTXOTotal(allUTXOs);\n\n if (allTotal < requiredAmount) {\n throw new InsufficientFundsError({\n availableSatoshis: allTotal,\n requiredSatoshis: amountInSatoshis,\n });\n }\n\n return allUTXOs;\n }\n\n throw new InsufficientFundsError({\n availableSatoshis: selectedTotal,\n requiredSatoshis: amountInSatoshis,\n });\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class TaprootAddressNotSupportedError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'taproot_address_not_supported',\n docsUrl: null,\n name: 'TaprootAddressNotSupportedError',\n shortMessage:\n 'Taproot addresses are not supported for PSBT building. Only Native SegWit (P2WPKH) addresses are allowed.',\n });\n }\n}\n","import { TaprootAddressNotSupportedError } from '../../../errors/TaprootAddressNotSupportedError';\n\n/**\n * Validates that the address is not a Taproot address\n * Only Native SegWit (P2WPKH) is supported for PSBT building\n *\n * @param accountAddress - The account address to check\n * @throws TaprootAddressNotSupportedError if address is Taproot\n * @notInstrumented\n */\n// eslint-disable-next-line custom-rules/require-single-object-param\nexport const validateNotTaproot = (accountAddress: string): void => {\n if (\n accountAddress.toLowerCase().startsWith('bc1p') ||\n accountAddress.toLowerCase().startsWith('tb1p')\n ) {\n throw new TaprootAddressNotSupportedError();\n }\n};\n","import ecc from '@bitcoinerlab/secp256k1';\nimport { getBuffer } from '@dynamic-labs-sdk/client/core';\nimport type { Network } from 'bitcoinjs-lib';\nimport { Psbt } from 'bitcoinjs-lib';\nimport { ECPairFactory } from 'ecpair';\n\nimport { InsufficientFundsError } from '../../../errors/InsufficientFundsError';\nimport { InvalidAmountError } from '../../../errors/InvalidAmountError';\nimport { NoUTXOsFoundError } from '../../../errors/NoUTXOsFoundError';\nimport { DUST_LIMIT } from '../../constants';\nimport type { FeePriority } from '../../WaasBitcoinWalletProvider.types';\nimport { addInputsToPsbt } from '../addInputsToPsbt';\nimport { addOutputsToPsbt } from '../addOutputsToPsbt';\nimport { calculateFeeAndChange } from '../calculateFeeAndChange';\nimport { calculateUTXOTotal } from '../calculateUTXOTotal';\nimport { estimateTransactionFee } from '../estimateTransactionFee';\nimport { getUTXOs } from '../getUTXOs';\nimport { selectUTXOsLargestFirst } from '../selectUTXOsLargestFirst';\nimport { validateAndSelectUTXOs } from '../validateAndSelectUTXOs';\nimport { validateNotTaproot } from '../validateNotTaproot';\n\ntype BuildPsbtOptions = {\n accountAddress: string;\n amountInSatoshis: bigint;\n feePriority?: FeePriority;\n mempoolApiUrl?: string;\n network: Network;\n publicKeyHex: string;\n recipientAddress: string;\n};\n\n/**\n * Builds a PSBT for a Bitcoin transaction with real UTXOs\n * Uses Largest-First UTXO selection strategy with accurate vSize fee estimation\n *\n * @param options.accountAddress - The sender's Bitcoin address\n * @param options.amountInSatoshis - Amount to send in satoshis\n * @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')\n * @param options.network - Bitcoin network configuration (mainnet or testnet)\n * @param options.publicKeyHex - The sender's public key in hexadecimal format\n * @param options.recipientAddress - The recipient's Bitcoin address\n * @returns A PSBT in Base64 format\n * @throws Error if insufficient funds, no UTXOs, or other errors\n * @notInstrumented\n */\nexport const buildPsbt = async ({\n accountAddress,\n amountInSatoshis,\n feePriority = 'medium',\n mempoolApiUrl,\n network,\n publicKeyHex,\n recipientAddress,\n}: BuildPsbtOptions): Promise<string> => {\n if (amountInSatoshis <= BigInt(0)) {\n throw new InvalidAmountError({\n amountInSatoshis: Number(amountInSatoshis),\n reason: 'Amount must be greater than 0',\n });\n }\n\n validateNotTaproot(accountAddress);\n\n const allUTXOs = await getUTXOs({ address: accountAddress, mempoolApiUrl });\n\n if (allUTXOs.length === 0) {\n throw new NoUTXOsFoundError({ address: accountAddress });\n }\n\n const publicKeyBuffer = new Uint8Array(getBuffer().from(publicKeyHex, 'hex'));\n const ECPair = ECPairFactory(ecc);\n\n // @ts-expect-error - ecpair types are incompatible with valibot >=1.2.0\n // The options are actually optional at runtime, but TypeScript infers them as required\n const publicKeyPair = ECPair.fromPublicKey(publicKeyBuffer, {\n compressed: true,\n });\n\n const amountInSatoshisNumber = Number(amountInSatoshis);\n\n const initialFeeEstimate = await estimateTransactionFee({\n feePriority,\n mempoolApiUrl,\n numInputs: 1,\n numOutputs: 1,\n });\n\n const targetAmount = amountInSatoshisNumber + initialFeeEstimate + DUST_LIMIT;\n\n let selectedUTXOs = selectUTXOsLargestFirst({\n targetAmount,\n utxos: allUTXOs,\n });\n const selectedTotal = calculateUTXOTotal(selectedUTXOs);\n\n selectedUTXOs = validateAndSelectUTXOs({\n allUTXOs,\n amountInSatoshis: amountInSatoshisNumber,\n feeEstimate: initialFeeEstimate,\n selectedTotal,\n selectedUTXOs,\n });\n\n const selectedTotalValue = calculateUTXOTotal(selectedUTXOs);\n\n const { changeAmountNumber, feeEstimate, hasChangeOutput } =\n await calculateFeeAndChange({\n amountInSatoshis,\n feePriority,\n mempoolApiUrl,\n selectedTotalValue,\n selectedUTXOs,\n });\n\n const maxToSpend = selectedTotalValue - feeEstimate;\n\n if (maxToSpend < amountInSatoshisNumber) {\n throw new InsufficientFundsError({\n availableSatoshis: maxToSpend,\n requiredSatoshis: amountInSatoshisNumber,\n });\n }\n\n const psbt = new Psbt({ network });\n\n addInputsToPsbt({\n network,\n psbt,\n publicKeyPair,\n selectedUTXOs,\n });\n\n addOutputsToPsbt({\n accountAddress,\n amountInSatoshis: amountInSatoshisNumber,\n changeAmount: changeAmountNumber,\n hasChangeOutput,\n network,\n psbt,\n recipientAddress,\n });\n\n return psbt.toBase64();\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class UnsupportedBitcoinNetworkError extends BaseError {\n // eslint-disable-next-line custom-rules/require-single-object-param\n constructor(networkId: string) {\n super({\n cause: null,\n code: 'unsupported_bitcoin_network_error',\n docsUrl: null,\n name: 'UnsupportedBitcoinNetworkError',\n shortMessage: `Unsupported Bitcoin network id: ${networkId}`,\n });\n }\n}\n","import type { Network } from 'bitcoinjs-lib';\nimport { networks } from 'bitcoinjs-lib';\n\nimport {\n MEMPOOL_API_URL,\n MEMPOOL_API_URL_SIGNET,\n MEMPOOL_API_URL_TESTNET,\n} from '../../../constants';\nimport { UnsupportedBitcoinNetworkError } from '../../../errors/UnsupportedBitcoinNetworkError';\n\nexport type ActiveBitcoinNetworkConfig = {\n /** WaaS signing network for `bitcoinConfig.network`. */\n bitcoinNetwork: 'mainnet' | 'testnet';\n /** Base mempool.space API URL for the network. */\n mempoolApiUrl: string;\n networkId: string;\n /** bitcoinjs-lib network for PSBT encoding. */\n psbtNetwork: Network;\n};\n\n/**\n * Resolves a Dynamic Bitcoin network id (1 mainnet, 2 testnet, 3 signet) to\n * the per-network configuration used by the WaaS provider. An undefined id\n * (network never switched) resolves to mainnet.\n *\n * @throws {UnsupportedBitcoinNetworkError} for any other network id\n * @notInstrumented\n */\nexport const getActiveBitcoinNetworkConfig = ({\n networkId,\n}: {\n networkId: string | undefined;\n}): ActiveBitcoinNetworkConfig => {\n const id = networkId ?? '1';\n\n switch (id) {\n case '1':\n return {\n bitcoinNetwork: 'mainnet',\n mempoolApiUrl: MEMPOOL_API_URL,\n networkId: id,\n psbtNetwork: networks.bitcoin,\n };\n case '2':\n return {\n bitcoinNetwork: 'testnet',\n mempoolApiUrl: MEMPOOL_API_URL_TESTNET,\n networkId: id,\n psbtNetwork: networks.testnet,\n };\n case '3':\n return {\n bitcoinNetwork: 'testnet',\n mempoolApiUrl: MEMPOOL_API_URL_SIGNET,\n networkId: id,\n psbtNetwork: networks.testnet,\n };\n default:\n throw new UnsupportedBitcoinNetworkError(id);\n }\n};\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class PublicKeyNotFoundError extends BaseError {\n // eslint-disable-next-line custom-rules/require-single-object-param\n constructor(address: string) {\n super({\n cause: null,\n code: 'public_key_not_found_error',\n docsUrl: null,\n name: 'PublicKeyNotFoundError',\n shortMessage: `No public key found for address ${address}`,\n });\n }\n}\n\n","import type { DynamicClient, WalletAccount } from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\nimport { PublicKeyNotFoundError } from '../../../errors/PublicKeyNotFoundError';\n\n/**\n * Gets the public key for a wallet account from the user's verified credentials\n * @notInstrumented\n */\nexport const getPublicKeyForWalletAccount = (\n walletAccount: WalletAccount,\n client: DynamicClient\n): string => {\n const user = getCore(client).state.get().user;\n\n for (const credential of user?.verifiedCredentials ?? []) {\n const additionalAddress = credential.walletAdditionalAddresses?.find(\n (addr) => addr.address === walletAccount.address\n );\n\n if (additionalAddress?.publicKey) {\n return additionalAddress.publicKey;\n }\n }\n\n throw new PublicKeyNotFoundError(walletAccount.address);\n};\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\nimport { WalletAddressType } from '@dynamic-labs/sdk-api-core';\n\n/**\n * Resolves the wallet's payment address for the given Bitcoin network. One\n * WaaS wallet (one MPC key) exposes a per-network payment address via its\n * network-tagged additional addresses. Falls back to the wallet account's\n * primary address (the mainnet encoding) for legacy wallets without tagged\n * rows.\n *\n * The wallet identity (keyshare/password lookups, signing) is always the\n * primary address — this resolver is only for address-driven operations\n * (UTXOs, balance, broadcast source).\n *\n * @notInstrumented\n */\nexport const getWaasBitcoinAddressForNetwork = ({\n bitcoinNetwork,\n walletAccount,\n}: {\n bitcoinNetwork: 'mainnet' | 'testnet';\n walletAccount: WalletAccount;\n}): string => {\n const taggedAddress = walletAccount.addressesWithTypes?.find(\n (address) =>\n address.type === WalletAddressType.Payment &&\n address.network === bitcoinNetwork\n )?.address;\n\n return taggedAddress ?? walletAccount.address;\n};\n","import type { DynamicClient } from '@dynamic-labs-sdk/client';\nimport {\n assertDefined,\n consumeMfaTokenIfRequiredForAction,\n formatWalletProviderGroupKey,\n formatWalletProviderKey,\n getActiveNetworkIdFromLastKnownRegistry,\n getSignedSessionId,\n switchActiveNetworkInLastKnownRegistry,\n} from '@dynamic-labs-sdk/client/core';\nimport type { BitcoinNetwork } from '@dynamic-labs-sdk/client/waas/core';\nimport {\n DYNAMIC_WAAS_METADATA,\n createWaasProvider,\n getAllUserWaasAddressesForChain,\n} from '@dynamic-labs-sdk/client/waas/core';\nimport { MFAAction, WalletProviderEnum } from '@dynamic-labs/sdk-api-core';\nimport { Psbt } from 'bitcoinjs-lib';\n\nimport type { BitcoinSendTransactionResponse } from '../../../BitcoinWalletProvider.types';\nimport { bitcoinExecuteSwapTransaction } from '../../../utils/bitcoinExecuteSwapTransaction';\nimport { bitcoinTransferAmount } from '../../../utils/bitcoinTransferAmount';\nimport type {\n WaasBitcoinTransaction,\n WaasBitcoinWalletProvider,\n} from '../../WaasBitcoinWalletProvider.types';\nimport { broadcastTransaction } from '../broadcastTransaction';\nimport { buildPsbt as buildPsbtUtil } from '../buildPsbt';\nimport { getActiveBitcoinNetworkConfig } from '../getActiveBitcoinNetworkConfig';\nimport { getPublicKeyForWalletAccount } from '../getPublicKeyForWalletAccount/getPublicKeyForWalletAccount';\nimport { getWaasBitcoinAddressForNetwork } from '../getWaasBitcoinAddressForNetwork';\n\n/** @notInstrumented */\nexport const createWalletProviderForWaasBitcoin = (\n sdkClient: DynamicClient\n): WaasBitcoinWalletProvider => {\n const chain = 'BTC' as const;\n\n const walletProviderType = WalletProviderEnum.EmbeddedWallet;\n\n const key = formatWalletProviderKey({\n chain,\n displayName: DYNAMIC_WAAS_METADATA.displayName,\n walletProviderType,\n });\n\n const waasProvider = createWaasProvider({ chain, sdkClient });\n\n const getActiveNetworkId: WaasBitcoinWalletProvider['getActiveNetworkId'] =\n async () =>\n getActiveNetworkIdFromLastKnownRegistry({\n client: sdkClient,\n walletProviderKey: key,\n });\n\n const switchActiveNetwork: WaasBitcoinWalletProvider['switchActiveNetwork'] =\n async ({ networkId }) => {\n // Validates the id before persisting it — an unsupported network must\n // fail the switch rather than silently degrade to mainnet later.\n getActiveBitcoinNetworkConfig({ networkId });\n\n return switchActiveNetworkInLastKnownRegistry({\n client: sdkClient,\n networkId,\n walletProviderKey: key,\n });\n };\n\n const getActiveNetworkConfig = async () => {\n const { networkId } = await getActiveNetworkId();\n\n return getActiveBitcoinNetworkConfig({ networkId });\n };\n\n const getConnectedAddresses: WaasBitcoinWalletProvider['getConnectedAddresses'] =\n async () => {\n const waasBitcoinAddresses = getAllUserWaasAddressesForChain(\n { chain },\n sdkClient\n );\n\n return {\n addresses: waasBitcoinAddresses,\n };\n };\n\n const signPsbt: WaasBitcoinWalletProvider['signPsbt'] = async ({\n request,\n walletAccount,\n }) => {\n assertDefined(walletAccount, 'Wallet account is required');\n\n const waasClient = await waasProvider.getWaasClient();\n\n const { signature: signedSessionId } = await getSignedSessionId(sdkClient);\n\n const mfaToken = await consumeMfaTokenIfRequiredForAction(\n { mfaAction: MFAAction.WalletWaasSign },\n sdkClient\n );\n\n const signedPsbt = await waasClient.signTransaction({\n authToken: sdkClient.token ?? undefined,\n mfaToken,\n senderAddress: walletAccount.address,\n signedSessionId,\n transaction: request.unsignedPsbtBase64,\n });\n\n return { signedPsbt };\n };\n\n const signPsbts: WaasBitcoinWalletProvider['signPsbts'] = async ({\n requests,\n walletAccount,\n }) => {\n assertDefined(walletAccount, 'Wallet account is required');\n\n const signedPsbts = await Promise.all(\n requests.map(async (request) => {\n const { signedPsbt } = await signPsbt({ request, walletAccount });\n\n return signedPsbt;\n })\n );\n\n return { signedPsbts };\n };\n\n const signMessage: WaasBitcoinWalletProvider['signMessage'] = async ({\n message,\n walletAccount,\n }) => {\n assertDefined(walletAccount, 'Wallet account is required');\n\n const waasClient = await waasProvider.getWaasClient();\n\n const { signature: signedSessionId } = await getSignedSessionId(sdkClient);\n\n const mfaToken = await consumeMfaTokenIfRequiredForAction(\n { mfaAction: MFAAction.WalletWaasSign },\n sdkClient\n );\n\n const { bitcoinNetwork } = await getActiveNetworkConfig();\n\n const signature = await waasClient.signMessage({\n accountAddress: walletAccount.address,\n authToken: sdkClient.token ?? undefined,\n bitcoinConfig: {\n network: bitcoinNetwork as BitcoinNetwork,\n },\n message,\n mfaToken,\n signedSessionId,\n });\n\n return { signature };\n };\n\n const buildPsbt: WaasBitcoinWalletProvider['buildPsbt'] = async ({\n transaction,\n walletAccount,\n }) => {\n assertDefined(walletAccount, 'Wallet account is required');\n\n const publicKeyHex = getPublicKeyForWalletAccount(walletAccount, sdkClient);\n\n const { bitcoinNetwork, mempoolApiUrl, psbtNetwork } =\n await getActiveNetworkConfig();\n\n return buildPsbtUtil({\n // UTXO source and change output use the active network's payment\n // address; signing identity stays the wallet account's primary address.\n accountAddress: getWaasBitcoinAddressForNetwork({\n bitcoinNetwork,\n walletAccount,\n }),\n amountInSatoshis: transaction.amount,\n feePriority: transaction.feePriority ?? 'medium',\n mempoolApiUrl,\n network: psbtNetwork,\n publicKeyHex,\n recipientAddress: transaction.recipientAddress,\n });\n };\n\n const sendBitcoin: WaasBitcoinWalletProvider['sendBitcoin'] = async ({\n transaction,\n walletAccount,\n }): Promise<BitcoinSendTransactionResponse> => {\n assertDefined(walletAccount, 'Wallet account is required');\n\n const waasTransaction: WaasBitcoinTransaction = {\n amount: transaction.amount,\n recipientAddress: transaction.recipientAddress,\n };\n\n const unsignedPsbt = await buildPsbt({\n transaction: waasTransaction,\n walletAccount,\n });\n\n const { signedPsbt } = await signPsbt({\n request: { allowedSighash: [], unsignedPsbtBase64: unsignedPsbt },\n walletAccount,\n });\n\n const { mempoolApiUrl, psbtNetwork } = await getActiveNetworkConfig();\n\n const psbt = Psbt.fromBase64(signedPsbt, { network: psbtNetwork });\n\n psbt.finalizeAllInputs();\n\n const rawTx = psbt.extractTransaction().toHex();\n\n const transactionId = await broadcastTransaction({\n mempoolApiUrl,\n rawTransaction: rawTx,\n });\n\n return { transactionId };\n };\n\n return {\n ...waasProvider,\n buildPsbt,\n chain,\n executeSwapTransaction: (args) =>\n bitcoinExecuteSwapTransaction(args, sdkClient),\n getActiveNetworkId,\n getConnectedAddresses,\n groupKey: formatWalletProviderGroupKey(DYNAMIC_WAAS_METADATA.displayName),\n key,\n metadata: {\n displayName: DYNAMIC_WAAS_METADATA.displayName,\n icon: DYNAMIC_WAAS_METADATA.icon,\n },\n sendBitcoin,\n signMessage,\n signPsbt,\n signPsbts,\n switchActiveNetwork,\n transferAmount: (args) => bitcoinTransferAmount(args, sdkClient),\n walletProviderType,\n };\n};\n","import {\n WalletProviderPriority,\n getDefaultClient,\n getWalletProviderRegistry,\n hasExtension,\n registerExtension,\n} from '@dynamic-labs-sdk/client/core';\n\nimport { registerBitcoinNetworkProviderBuilder } from '../../registerBitcoinNetworkProviderBuilder';\nimport { createWalletProviderForWaasBitcoin } from '../utils/createWalletProviderForWaasBitcoin';\n\nexport const WAAS_BITCOIN_EXTENSION_KEY = 'waasBitcoin';\n\n/**\n * Adds the Dynamic WaaS (Wallet as a Service) Bitcoin extension to the Dynamic client.\n *\n * This extension enables embedded wallet functionality for Bitcoin blockchain,\n * allowing users to have wallets managed by Dynamic's infrastructure.\n *\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @notInstrumented\n */\nexport const addWaasBitcoinExtension = (client = getDefaultClient()): void => {\n if (hasExtension({ extensionKey: WAAS_BITCOIN_EXTENSION_KEY }, client)) {\n return;\n }\n\n registerExtension({ extensionKey: WAAS_BITCOIN_EXTENSION_KEY }, client);\n registerBitcoinNetworkProviderBuilder(client);\n\n const walletProviderRegistry = getWalletProviderRegistry(client);\n\n const walletProvider = createWalletProviderForWaasBitcoin(client);\n\n walletProviderRegistry.register({\n priority: WalletProviderPriority.WALLET_SDK,\n walletProvider,\n });\n};\n\n"],"mappings":"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"}
|