@dynamic-labs-sdk/bitcoin 0.4.0 → 0.6.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/addBitcoinExtension/addBitcoinExtension.d.ts +4 -2
- package/dist/addBitcoinExtension/addBitcoinExtension.d.ts.map +1 -1
- package/dist/{addBitcoinInjectedWalletsExtension-C_-dWLm4.cjs.js → addBitcoinInjectedWalletsExtension-BRn8yV6c.cjs.js} +9 -2
- package/dist/{addBitcoinInjectedWalletsExtension-C_-dWLm4.cjs.js.map → addBitcoinInjectedWalletsExtension-BRn8yV6c.cjs.js.map} +1 -1
- package/dist/{addBitcoinInjectedWalletsExtension-C9RQD2KW.esm.js → addBitcoinInjectedWalletsExtension-CkICdKHm.esm.js} +3 -3
- package/dist/{addBitcoinInjectedWalletsExtension-C9RQD2KW.esm.js.map → addBitcoinInjectedWalletsExtension-CkICdKHm.esm.js.map} +1 -1
- package/dist/buildPsbt/buildPsbt.d.ts +24 -0
- package/dist/buildPsbt/buildPsbt.d.ts.map +1 -0
- package/dist/buildPsbt/index.d.ts +2 -0
- package/dist/buildPsbt/index.d.ts.map +1 -0
- package/dist/errors/FeeRecommendationsFetchError.d.ts +10 -0
- package/dist/errors/FeeRecommendationsFetchError.d.ts.map +1 -0
- package/dist/errors/InsufficientFundsError.d.ts +12 -0
- package/dist/errors/InsufficientFundsError.d.ts.map +1 -0
- package/dist/errors/InvalidAmountError.d.ts +11 -0
- package/dist/errors/InvalidAmountError.d.ts.map +1 -0
- package/dist/errors/NoUTXOsFoundError.d.ts +10 -0
- package/dist/errors/NoUTXOsFoundError.d.ts.map +1 -0
- package/dist/errors/PublicKeyNotFoundError.d.ts +5 -0
- package/dist/errors/PublicKeyNotFoundError.d.ts.map +1 -0
- package/dist/errors/SegwitOutputScriptError.d.ts +5 -0
- package/dist/errors/SegwitOutputScriptError.d.ts.map +1 -0
- package/dist/errors/TaprootAddressNotSupportedError.d.ts +5 -0
- package/dist/errors/TaprootAddressNotSupportedError.d.ts.map +1 -0
- package/dist/errors/TransactionBroadcastFailedError.d.ts +10 -0
- package/dist/errors/TransactionBroadcastFailedError.d.ts.map +1 -0
- package/dist/errors/TransactionRequiredError.d.ts +5 -0
- package/dist/errors/TransactionRequiredError.d.ts.map +1 -0
- package/dist/errors/UTXOsFetchError.d.ts +12 -0
- package/dist/errors/UTXOsFetchError.d.ts.map +1 -0
- package/dist/exports/index.d.ts +2 -0
- package/dist/exports/index.d.ts.map +1 -1
- package/dist/exports/waas.d.ts +4 -0
- package/dist/exports/waas.d.ts.map +1 -0
- package/dist/index.cjs.js +721 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +692 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/injected.cjs.js +2 -1
- package/dist/injected.cjs.js.map +1 -1
- package/dist/injected.esm.js +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/waas/WaasBitcoinWalletProvider.types.d.ts +49 -0
- package/dist/waas/WaasBitcoinWalletProvider.types.d.ts.map +1 -0
- package/dist/waas/addWaasBitcoinExtension/addWaasBitcoinExtension.d.ts +11 -0
- package/dist/waas/addWaasBitcoinExtension/addWaasBitcoinExtension.d.ts.map +1 -0
- package/dist/waas/addWaasBitcoinExtension/index.d.ts +2 -0
- package/dist/waas/addWaasBitcoinExtension/index.d.ts.map +1 -0
- package/dist/waas/constants.d.ts +36 -0
- package/dist/waas/constants.d.ts.map +1 -0
- package/dist/waas/utils/addInputsToPsbt/addInputsToPsbt.d.ts +21 -0
- package/dist/waas/utils/addInputsToPsbt/addInputsToPsbt.d.ts.map +1 -0
- package/dist/waas/utils/addInputsToPsbt/index.d.ts +2 -0
- package/dist/waas/utils/addInputsToPsbt/index.d.ts.map +1 -0
- package/dist/waas/utils/addOutputsToPsbt/addOutputsToPsbt.d.ts +24 -0
- package/dist/waas/utils/addOutputsToPsbt/addOutputsToPsbt.d.ts.map +1 -0
- package/dist/waas/utils/addOutputsToPsbt/index.d.ts +2 -0
- package/dist/waas/utils/addOutputsToPsbt/index.d.ts.map +1 -0
- package/dist/waas/utils/broadcastTransaction/broadcastTransaction.d.ts +10 -0
- package/dist/waas/utils/broadcastTransaction/broadcastTransaction.d.ts.map +1 -0
- package/dist/waas/utils/broadcastTransaction/index.d.ts +2 -0
- package/dist/waas/utils/broadcastTransaction/index.d.ts.map +1 -0
- package/dist/waas/utils/buildPsbt/buildPsbt.d.ts +26 -0
- package/dist/waas/utils/buildPsbt/buildPsbt.d.ts.map +1 -0
- package/dist/waas/utils/buildPsbt/index.d.ts +2 -0
- package/dist/waas/utils/buildPsbt/index.d.ts.map +1 -0
- package/dist/waas/utils/calculateFeeAndChange/calculateFeeAndChange.d.ts +24 -0
- package/dist/waas/utils/calculateFeeAndChange/calculateFeeAndChange.d.ts.map +1 -0
- package/dist/waas/utils/calculateFeeAndChange/index.d.ts +2 -0
- package/dist/waas/utils/calculateFeeAndChange/index.d.ts.map +1 -0
- package/dist/waas/utils/calculateUTXOTotal/calculateUTXOTotal.d.ts +9 -0
- package/dist/waas/utils/calculateUTXOTotal/calculateUTXOTotal.d.ts.map +1 -0
- package/dist/waas/utils/calculateUTXOTotal/index.d.ts +2 -0
- package/dist/waas/utils/calculateUTXOTotal/index.d.ts.map +1 -0
- package/dist/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.d.ts +4 -0
- package/dist/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.d.ts.map +1 -0
- package/dist/waas/utils/createWalletProviderForWaasBitcoin/index.d.ts +2 -0
- package/dist/waas/utils/createWalletProviderForWaasBitcoin/index.d.ts.map +1 -0
- package/dist/waas/utils/estimateTransactionFee/estimateTransactionFee.d.ts +17 -0
- package/dist/waas/utils/estimateTransactionFee/estimateTransactionFee.d.ts.map +1 -0
- package/dist/waas/utils/estimateTransactionFee/index.d.ts +2 -0
- package/dist/waas/utils/estimateTransactionFee/index.d.ts.map +1 -0
- package/dist/waas/utils/getFeeRecommendations/getFeeRecommendations.d.ts +9 -0
- package/dist/waas/utils/getFeeRecommendations/getFeeRecommendations.d.ts.map +1 -0
- package/dist/waas/utils/getFeeRecommendations/index.d.ts +2 -0
- package/dist/waas/utils/getFeeRecommendations/index.d.ts.map +1 -0
- package/dist/waas/utils/getPublicKeyForWalletAccount/getPublicKeyForWalletAccount.d.ts +6 -0
- package/dist/waas/utils/getPublicKeyForWalletAccount/getPublicKeyForWalletAccount.d.ts.map +1 -0
- package/dist/waas/utils/getUTXOs/getUTXOs.d.ts +10 -0
- package/dist/waas/utils/getUTXOs/getUTXOs.d.ts.map +1 -0
- package/dist/waas/utils/getUTXOs/index.d.ts +2 -0
- package/dist/waas/utils/getUTXOs/index.d.ts.map +1 -0
- package/dist/waas/utils/selectUTXOsLargestFirst/index.d.ts +2 -0
- package/dist/waas/utils/selectUTXOsLargestFirst/index.d.ts.map +1 -0
- package/dist/waas/utils/selectUTXOsLargestFirst/selectUTXOsLargestFirst.d.ts +16 -0
- package/dist/waas/utils/selectUTXOsLargestFirst/selectUTXOsLargestFirst.d.ts.map +1 -0
- package/dist/waas/utils/validateAndSelectUTXOs/index.d.ts +2 -0
- package/dist/waas/utils/validateAndSelectUTXOs/index.d.ts.map +1 -0
- package/dist/waas/utils/validateAndSelectUTXOs/validateAndSelectUTXOs.d.ts +22 -0
- package/dist/waas/utils/validateAndSelectUTXOs/validateAndSelectUTXOs.d.ts.map +1 -0
- package/dist/waas/utils/validateNotTaproot/index.d.ts +2 -0
- package/dist/waas/utils/validateNotTaproot/index.d.ts.map +1 -0
- package/dist/waas/utils/validateNotTaproot/validateNotTaproot.d.ts +9 -0
- package/dist/waas/utils/validateNotTaproot/validateNotTaproot.d.ts.map +1 -0
- package/package.json +11 -4
package/dist/index.cjs.js
CHANGED
|
@@ -1,19 +1,734 @@
|
|
|
1
|
-
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
const require_addBitcoinInjectedWalletsExtension = require('./addBitcoinInjectedWalletsExtension-BRn8yV6c.cjs.js');
|
|
2
29
|
let _dynamic_labs_sdk_assert_package_version = require("@dynamic-labs-sdk/assert-package-version");
|
|
3
30
|
let _dynamic_labs_sdk_client_core = require("@dynamic-labs-sdk/client/core");
|
|
4
31
|
let _dynamic_labs_sdk_client = require("@dynamic-labs-sdk/client");
|
|
32
|
+
let _dynamic_labs_sdk_api_core = require("@dynamic-labs/sdk-api-core");
|
|
33
|
+
let bitcoinjs_lib = require("bitcoinjs-lib");
|
|
34
|
+
let _dynamic_labs_sdk_client_waas_core = require("@dynamic-labs-sdk/client/waas/core");
|
|
35
|
+
let _bitcoinerlab_secp256k1 = require("@bitcoinerlab/secp256k1");
|
|
36
|
+
_bitcoinerlab_secp256k1 = __toESM(_bitcoinerlab_secp256k1);
|
|
37
|
+
let ecpair = require("ecpair");
|
|
38
|
+
|
|
39
|
+
//#region src/errors/TransactionBroadcastFailedError.ts
|
|
40
|
+
var TransactionBroadcastFailedError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
41
|
+
response;
|
|
42
|
+
constructor({ response }) {
|
|
43
|
+
super({
|
|
44
|
+
cause: null,
|
|
45
|
+
code: "transaction_broadcast_failed_error",
|
|
46
|
+
details: `Status: ${response.status} ${response.statusText}`,
|
|
47
|
+
docsUrl: null,
|
|
48
|
+
name: "TransactionBroadcastFailedError",
|
|
49
|
+
shortMessage: "Failed to broadcast transaction to mempool"
|
|
50
|
+
});
|
|
51
|
+
this.response = response;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/errors/TransactionRequiredError.ts
|
|
57
|
+
var TransactionRequiredError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
58
|
+
constructor() {
|
|
59
|
+
super({
|
|
60
|
+
cause: null,
|
|
61
|
+
code: "transaction_required_error",
|
|
62
|
+
docsUrl: null,
|
|
63
|
+
name: "TransactionRequiredError",
|
|
64
|
+
shortMessage: "No transaction specified for broadcast"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/waas/constants.ts
|
|
71
|
+
/**
|
|
72
|
+
* Mempool.space API URL for mainnet
|
|
73
|
+
*/
|
|
74
|
+
const MEMPOOL_API_URL = "https://mempool.space/api";
|
|
75
|
+
/**
|
|
76
|
+
* Number of satoshis per Bitcoin
|
|
77
|
+
*/
|
|
78
|
+
const SATOSHIS_PER_BTC = 1e8;
|
|
79
|
+
/**
|
|
80
|
+
* Bitcoin's dust limit in satoshis
|
|
81
|
+
* Outputs below this value are considered "dust" and will be rejected by nodes
|
|
82
|
+
*/
|
|
83
|
+
const DUST_LIMIT = 546;
|
|
84
|
+
/**
|
|
85
|
+
* Accurate vSize constants for Native SegWit (P2WPKH) transactions
|
|
86
|
+
* Used for precise fee estimation
|
|
87
|
+
*/
|
|
88
|
+
const VSIZE_OVERHEAD = 10.5;
|
|
89
|
+
const VSIZE_INPUT_P2WPKH = 68;
|
|
90
|
+
const VSIZE_OUTPUT_P2WPKH = 31;
|
|
91
|
+
/**
|
|
92
|
+
* Minimum relay fee in satoshis
|
|
93
|
+
* Added to fee estimate to ensure transaction propagation
|
|
94
|
+
*/
|
|
95
|
+
const MIN_RELAY_FEE = 111;
|
|
96
|
+
/**
|
|
97
|
+
* Conservative default fee estimate in satoshis
|
|
98
|
+
* Used as fallback when fee estimation fails
|
|
99
|
+
*/
|
|
100
|
+
const DEFAULT_FEE_ESTIMATE = 1e3;
|
|
101
|
+
/**
|
|
102
|
+
* RBF (Replace-By-Fee) sequence number
|
|
103
|
+
* 0xfffffffd = 4294967293 (enables RBF, not final)
|
|
104
|
+
*/
|
|
105
|
+
const RBF_SEQUENCE = 4294967293;
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/waas/utils/broadcastTransaction/broadcastTransaction.ts
|
|
109
|
+
/**
|
|
110
|
+
* Sends a raw Bitcoin transaction to the mempool
|
|
111
|
+
*
|
|
112
|
+
* @param rawTransaction - The raw transaction in hex format
|
|
113
|
+
* @returns The transaction ID
|
|
114
|
+
* @throws {TransactionRequiredError} if no transaction is specified
|
|
115
|
+
* @throws {TransactionBroadcastFailedError} if broadcasting fails
|
|
116
|
+
*/
|
|
117
|
+
const broadcastTransaction = async (rawTransaction) => {
|
|
118
|
+
if (!rawTransaction) throw new TransactionRequiredError();
|
|
119
|
+
const response = await fetch(`${MEMPOOL_API_URL}/tx`, {
|
|
120
|
+
body: rawTransaction,
|
|
121
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
122
|
+
method: "POST"
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) throw new TransactionBroadcastFailedError({ response });
|
|
125
|
+
return response.text();
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/errors/InsufficientFundsError.ts
|
|
130
|
+
var InsufficientFundsError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
131
|
+
availableSatoshis;
|
|
132
|
+
requiredSatoshis;
|
|
133
|
+
constructor({ availableSatoshis, requiredSatoshis }) {
|
|
134
|
+
const availableBtc = availableSatoshis / SATOSHIS_PER_BTC;
|
|
135
|
+
const requiredBtc = requiredSatoshis / SATOSHIS_PER_BTC;
|
|
136
|
+
super({
|
|
137
|
+
cause: null,
|
|
138
|
+
code: "insufficient_funds_error",
|
|
139
|
+
details: `Available: ${availableBtc} BTC (${availableSatoshis} satoshis), Required: ${requiredBtc} BTC (${requiredSatoshis} satoshis)`,
|
|
140
|
+
docsUrl: null,
|
|
141
|
+
name: "InsufficientFundsError",
|
|
142
|
+
shortMessage: "Insufficient funds for transaction"
|
|
143
|
+
});
|
|
144
|
+
this.availableSatoshis = availableSatoshis;
|
|
145
|
+
this.requiredSatoshis = requiredSatoshis;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
5
148
|
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/errors/InvalidAmountError.ts
|
|
151
|
+
var InvalidAmountError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
152
|
+
amountInSatoshis;
|
|
153
|
+
constructor({ amountInSatoshis, reason }) {
|
|
154
|
+
super({
|
|
155
|
+
cause: null,
|
|
156
|
+
code: "invalid_amount_error",
|
|
157
|
+
details: `Amount: ${amountInSatoshis} satoshis`,
|
|
158
|
+
docsUrl: null,
|
|
159
|
+
name: "InvalidAmountError",
|
|
160
|
+
shortMessage: reason
|
|
161
|
+
});
|
|
162
|
+
this.amountInSatoshis = amountInSatoshis;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/errors/NoUTXOsFoundError.ts
|
|
168
|
+
var NoUTXOsFoundError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
169
|
+
address;
|
|
170
|
+
constructor({ address: address$1 }) {
|
|
171
|
+
super({
|
|
172
|
+
cause: null,
|
|
173
|
+
code: "no_utxos_found_error",
|
|
174
|
+
details: `Address: ${address$1}`,
|
|
175
|
+
docsUrl: null,
|
|
176
|
+
name: "NoUTXOsFoundError",
|
|
177
|
+
shortMessage: "No UTXOs found for this address"
|
|
178
|
+
});
|
|
179
|
+
this.address = address$1;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/errors/SegwitOutputScriptError.ts
|
|
185
|
+
var SegwitOutputScriptError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
186
|
+
constructor() {
|
|
187
|
+
super({
|
|
188
|
+
cause: null,
|
|
189
|
+
code: "segwit_output_script_error",
|
|
190
|
+
docsUrl: null,
|
|
191
|
+
name: "SegwitOutputScriptError",
|
|
192
|
+
shortMessage: "Failed to create segwit output script"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/waas/utils/addInputsToPsbt/addInputsToPsbt.ts
|
|
199
|
+
/**
|
|
200
|
+
* Adds inputs to PSBT from selected UTXOs
|
|
201
|
+
*
|
|
202
|
+
* @param options.network - Bitcoin network configuration (mainnet or testnet)
|
|
203
|
+
* @param options.psbt - The PSBT instance to add inputs to
|
|
204
|
+
* @param options.publicKeyPair - Key pair containing the public key for witness script
|
|
205
|
+
* @param options.selectedUTXOs - Array of UTXOs to add as inputs
|
|
206
|
+
*/
|
|
207
|
+
const addInputsToPsbt = (options) => {
|
|
208
|
+
const { network, psbt, publicKeyPair, selectedUTXOs } = options;
|
|
209
|
+
for (const utxo of selectedUTXOs) {
|
|
210
|
+
const outputScript = bitcoinjs_lib.payments.p2wpkh({
|
|
211
|
+
network,
|
|
212
|
+
pubkey: publicKeyPair.publicKey
|
|
213
|
+
}).output;
|
|
214
|
+
if (!outputScript) throw new SegwitOutputScriptError();
|
|
215
|
+
const txidBuffer = new Uint8Array((0, _dynamic_labs_sdk_client_core.getBuffer)().from(utxo.txid, "hex").reverse());
|
|
216
|
+
psbt.addInput({
|
|
217
|
+
hash: txidBuffer,
|
|
218
|
+
index: utxo.vout,
|
|
219
|
+
sequence: RBF_SEQUENCE,
|
|
220
|
+
witnessUtxo: {
|
|
221
|
+
script: outputScript,
|
|
222
|
+
value: BigInt(utxo.value)
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
//#endregion
|
|
229
|
+
//#region src/waas/utils/addOutputsToPsbt/addOutputsToPsbt.ts
|
|
230
|
+
/**
|
|
231
|
+
* Adds outputs to PSBT (recipient and optionally change)
|
|
232
|
+
*
|
|
233
|
+
* @param options.accountAddress - The sender's address for receiving change
|
|
234
|
+
* @param options.amountInSatoshis - Amount to send to the recipient in satoshis
|
|
235
|
+
* @param options.changeAmount - Amount to return as change in satoshis
|
|
236
|
+
* @param options.hasChangeOutput - Whether to include a change output
|
|
237
|
+
* @param options.network - Bitcoin network configuration (mainnet or testnet)
|
|
238
|
+
* @param options.psbt - The PSBT instance to add outputs to
|
|
239
|
+
* @param options.recipientAddress - The recipient's Bitcoin address
|
|
240
|
+
*/
|
|
241
|
+
const addOutputsToPsbt = (options) => {
|
|
242
|
+
const { accountAddress, amountInSatoshis, changeAmount, hasChangeOutput, network, psbt, recipientAddress } = options;
|
|
243
|
+
if (amountInSatoshis < DUST_LIMIT) throw new InvalidAmountError({
|
|
244
|
+
amountInSatoshis,
|
|
245
|
+
reason: `Amount is below dust limit of ${DUST_LIMIT} satoshis (${DUST_LIMIT / SATOSHIS_PER_BTC} BTC)`
|
|
246
|
+
});
|
|
247
|
+
psbt.addOutput({
|
|
248
|
+
script: bitcoinjs_lib.address.toOutputScript(recipientAddress, network),
|
|
249
|
+
value: BigInt(amountInSatoshis)
|
|
250
|
+
});
|
|
251
|
+
if (hasChangeOutput) psbt.addOutput({
|
|
252
|
+
script: bitcoinjs_lib.address.toOutputScript(accountAddress, network),
|
|
253
|
+
value: BigInt(changeAmount)
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/errors/FeeRecommendationsFetchError.ts
|
|
259
|
+
var FeeRecommendationsFetchError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
260
|
+
response;
|
|
261
|
+
constructor({ response }) {
|
|
262
|
+
super({
|
|
263
|
+
cause: null,
|
|
264
|
+
code: "fee_recommendations_fetch_error",
|
|
265
|
+
details: `Status: ${response.status} ${response.statusText}`,
|
|
266
|
+
docsUrl: null,
|
|
267
|
+
name: "FeeRecommendationsFetchError",
|
|
268
|
+
shortMessage: "Failed to fetch fee recommendations from mempool"
|
|
269
|
+
});
|
|
270
|
+
this.response = response;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
//#endregion
|
|
275
|
+
//#region src/waas/utils/getFeeRecommendations/getFeeRecommendations.ts
|
|
276
|
+
/**
|
|
277
|
+
* Gets fee recommendations from mempool.space API
|
|
278
|
+
*
|
|
279
|
+
* @returns Fee recommendation data with rates in sat/vB
|
|
280
|
+
* @throws FeeRecommendationsFetchError if fetching fee recommendations fails
|
|
281
|
+
*/
|
|
282
|
+
const getFeeRecommendations = async () => {
|
|
283
|
+
const response = await fetch(`${MEMPOOL_API_URL}/v1/fees/recommended`);
|
|
284
|
+
if (!response.ok) throw new FeeRecommendationsFetchError({ response });
|
|
285
|
+
return response.json();
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/waas/utils/estimateTransactionFee/estimateTransactionFee.ts
|
|
290
|
+
/**
|
|
291
|
+
* Estimates transaction fees based on number of inputs and outputs using accurate vSize
|
|
292
|
+
*
|
|
293
|
+
* @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')
|
|
294
|
+
* @param options.numInputs - Number of transaction inputs (UTXOs being spent)
|
|
295
|
+
* @param options.numOutputs - Number of transaction outputs
|
|
296
|
+
* @returns Estimated fee in satoshis
|
|
297
|
+
*/
|
|
298
|
+
const estimateTransactionFee = async ({ feePriority = "medium", numInputs, numOutputs }) => {
|
|
299
|
+
try {
|
|
300
|
+
const feeData = await getFeeRecommendations();
|
|
301
|
+
let feePerByte;
|
|
302
|
+
if (feePriority === "high") feePerByte = feeData.fastestFee ?? feeData.halfHourFee ?? 1;
|
|
303
|
+
else if (feePriority === "low") feePerByte = feeData.economyFee ?? feeData.hourFee ?? 1;
|
|
304
|
+
else feePerByte = feeData.halfHourFee ?? feeData.hourFee ?? feeData.economyFee ?? 1;
|
|
305
|
+
const vSize = VSIZE_OVERHEAD + numInputs * VSIZE_INPUT_P2WPKH + numOutputs * VSIZE_OUTPUT_P2WPKH;
|
|
306
|
+
return Math.ceil(feePerByte * vSize) + MIN_RELAY_FEE;
|
|
307
|
+
} catch {
|
|
308
|
+
return DEFAULT_FEE_ESTIMATE;
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region src/waas/utils/calculateFeeAndChange/calculateFeeAndChange.ts
|
|
314
|
+
/**
|
|
315
|
+
* Calculates fee estimate and change amount, handling dust limit
|
|
316
|
+
*
|
|
317
|
+
* @param options.amountInSatoshis - Amount to send in satoshis
|
|
318
|
+
* @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')
|
|
319
|
+
* @param options.selectedTotalValue - Total value of selected UTXOs in satoshis
|
|
320
|
+
* @param options.selectedUTXOs - Array of selected UTXOs for the transaction
|
|
321
|
+
* @returns Object with feeEstimate, changeAmountNumber, and hasChangeOutput
|
|
322
|
+
*/
|
|
323
|
+
const calculateFeeAndChange = async ({ amountInSatoshis, feePriority, selectedTotalValue, selectedUTXOs }) => {
|
|
324
|
+
let feeEstimate = await estimateTransactionFee({
|
|
325
|
+
feePriority,
|
|
326
|
+
numInputs: selectedUTXOs.length,
|
|
327
|
+
numOutputs: 1
|
|
328
|
+
});
|
|
329
|
+
let maxToSpend = selectedTotalValue - feeEstimate;
|
|
330
|
+
let changeAmount = BigInt(maxToSpend) - amountInSatoshis;
|
|
331
|
+
if (changeAmount > 0 && Number(changeAmount) >= DUST_LIMIT) {
|
|
332
|
+
feeEstimate = await estimateTransactionFee({
|
|
333
|
+
feePriority,
|
|
334
|
+
numInputs: selectedUTXOs.length,
|
|
335
|
+
numOutputs: 2
|
|
336
|
+
});
|
|
337
|
+
maxToSpend = selectedTotalValue - feeEstimate;
|
|
338
|
+
changeAmount = BigInt(maxToSpend) - amountInSatoshis;
|
|
339
|
+
}
|
|
340
|
+
const finalChangeAmountNumber = Number(changeAmount);
|
|
341
|
+
const hasChangeOutput = changeAmount > 0 && finalChangeAmountNumber >= DUST_LIMIT;
|
|
342
|
+
if (changeAmount > 0 && finalChangeAmountNumber < DUST_LIMIT) feeEstimate += finalChangeAmountNumber;
|
|
343
|
+
return {
|
|
344
|
+
changeAmountNumber: finalChangeAmountNumber,
|
|
345
|
+
feeEstimate,
|
|
346
|
+
hasChangeOutput
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
//#endregion
|
|
351
|
+
//#region src/waas/utils/calculateUTXOTotal/calculateUTXOTotal.ts
|
|
352
|
+
/**
|
|
353
|
+
* Calculates the total value of UTXOs
|
|
354
|
+
*
|
|
355
|
+
* @param utxos - Array of UTXOs
|
|
356
|
+
* @returns Total value in satoshis
|
|
357
|
+
*/
|
|
358
|
+
const calculateUTXOTotal = (utxos) => utxos.reduce((total, utxo) => total + utxo.value, 0);
|
|
359
|
+
|
|
360
|
+
//#endregion
|
|
361
|
+
//#region src/errors/UTXOsFetchError.ts
|
|
362
|
+
var UTXOsFetchError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
363
|
+
address;
|
|
364
|
+
response;
|
|
365
|
+
constructor({ address: address$1, response }) {
|
|
366
|
+
super({
|
|
367
|
+
cause: null,
|
|
368
|
+
code: "utxos_fetch_error",
|
|
369
|
+
details: `Address: ${address$1}, Status: ${response.status} ${response.statusText}`,
|
|
370
|
+
docsUrl: null,
|
|
371
|
+
name: "UTXOsFetchError",
|
|
372
|
+
shortMessage: "Failed to fetch UTXOs from mempool"
|
|
373
|
+
});
|
|
374
|
+
this.address = address$1;
|
|
375
|
+
this.response = response;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
//#endregion
|
|
380
|
+
//#region src/waas/utils/getUTXOs/getUTXOs.ts
|
|
381
|
+
/**
|
|
382
|
+
* Gets UTXOs for a Bitcoin address from mempool.space API
|
|
383
|
+
*
|
|
384
|
+
* @param address - The Bitcoin address to get UTXOs for
|
|
385
|
+
* @returns Array of UTXOs
|
|
386
|
+
* @throws UTXOsFetchError if fetching UTXOs fails
|
|
387
|
+
*/
|
|
388
|
+
const getUTXOs = async (address$1) => {
|
|
389
|
+
const response = await fetch(`${MEMPOOL_API_URL}/address/${address$1}/utxo`);
|
|
390
|
+
if (!response.ok) throw new UTXOsFetchError({
|
|
391
|
+
address: address$1,
|
|
392
|
+
response
|
|
393
|
+
});
|
|
394
|
+
return response.json();
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/waas/utils/selectUTXOsLargestFirst/selectUTXOsLargestFirst.ts
|
|
399
|
+
/**
|
|
400
|
+
* Selects UTXOs using Largest-First (Accumulator) strategy
|
|
401
|
+
* Sorts UTXOs by value (descending) and selects until we have enough to cover amount + fees
|
|
402
|
+
*
|
|
403
|
+
* @param options.targetAmount - Target amount in satoshis (amount + fees + dust limit)
|
|
404
|
+
* @param options.utxos - Array of available UTXOs to select from
|
|
405
|
+
* @returns Selected UTXOs
|
|
406
|
+
*/
|
|
407
|
+
const selectUTXOsLargestFirst = (options) => {
|
|
408
|
+
const { targetAmount, utxos } = options;
|
|
409
|
+
const sortedUTXOs = [...utxos].sort((a, b) => b.value - a.value);
|
|
410
|
+
const selected = [];
|
|
411
|
+
let total = 0;
|
|
412
|
+
for (const utxo of sortedUTXOs) {
|
|
413
|
+
selected.push(utxo);
|
|
414
|
+
total += utxo.value;
|
|
415
|
+
if (total >= targetAmount) break;
|
|
416
|
+
}
|
|
417
|
+
return selected;
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
//#endregion
|
|
421
|
+
//#region src/waas/utils/validateAndSelectUTXOs/validateAndSelectUTXOs.ts
|
|
422
|
+
/**
|
|
423
|
+
* Validates and ensures sufficient funds for the transaction
|
|
424
|
+
*
|
|
425
|
+
* @param options.allUTXOs - Complete array of available UTXOs for the address
|
|
426
|
+
* @param options.amountInSatoshis - Amount to send in satoshis
|
|
427
|
+
* @param options.feeEstimate - Estimated transaction fee in satoshis
|
|
428
|
+
* @param options.selectedTotal - Total value of initially selected UTXOs in satoshis
|
|
429
|
+
* @param options.selectedUTXOs - Array of initially selected UTXOs
|
|
430
|
+
* @returns Validated selected UTXOs
|
|
431
|
+
* @throws InsufficientFundsError if insufficient funds
|
|
432
|
+
*/
|
|
433
|
+
const validateAndSelectUTXOs = (options) => {
|
|
434
|
+
const { allUTXOs, amountInSatoshis, feeEstimate, selectedTotal, selectedUTXOs } = options;
|
|
435
|
+
const requiredAmount = amountInSatoshis + feeEstimate;
|
|
436
|
+
if (selectedTotal >= requiredAmount) return selectedUTXOs;
|
|
437
|
+
if (selectedUTXOs.length < allUTXOs.length) {
|
|
438
|
+
const allTotal = calculateUTXOTotal(allUTXOs);
|
|
439
|
+
if (allTotal < requiredAmount) throw new InsufficientFundsError({
|
|
440
|
+
availableSatoshis: allTotal,
|
|
441
|
+
requiredSatoshis: amountInSatoshis
|
|
442
|
+
});
|
|
443
|
+
return allUTXOs;
|
|
444
|
+
}
|
|
445
|
+
throw new InsufficientFundsError({
|
|
446
|
+
availableSatoshis: selectedTotal,
|
|
447
|
+
requiredSatoshis: amountInSatoshis
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
//#endregion
|
|
452
|
+
//#region src/errors/TaprootAddressNotSupportedError.ts
|
|
453
|
+
var TaprootAddressNotSupportedError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
454
|
+
constructor() {
|
|
455
|
+
super({
|
|
456
|
+
cause: null,
|
|
457
|
+
code: "taproot_address_not_supported",
|
|
458
|
+
docsUrl: null,
|
|
459
|
+
name: "TaprootAddressNotSupportedError",
|
|
460
|
+
shortMessage: "Taproot addresses are not supported for PSBT building. Only Native SegWit (P2WPKH) addresses are allowed."
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
//#endregion
|
|
466
|
+
//#region src/waas/utils/validateNotTaproot/validateNotTaproot.ts
|
|
467
|
+
/**
|
|
468
|
+
* Validates that the address is not a Taproot address
|
|
469
|
+
* Only Native SegWit (P2WPKH) is supported for PSBT building
|
|
470
|
+
*
|
|
471
|
+
* @param accountAddress - The account address to check
|
|
472
|
+
* @throws TaprootAddressNotSupportedError if address is Taproot
|
|
473
|
+
*/
|
|
474
|
+
const validateNotTaproot = (accountAddress) => {
|
|
475
|
+
if (accountAddress.toLowerCase().startsWith("bc1p") || accountAddress.toLowerCase().startsWith("tb1p")) throw new TaprootAddressNotSupportedError();
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/waas/utils/buildPsbt/buildPsbt.ts
|
|
480
|
+
/**
|
|
481
|
+
* Builds a PSBT for a Bitcoin transaction with real UTXOs
|
|
482
|
+
* Uses Largest-First UTXO selection strategy with accurate vSize fee estimation
|
|
483
|
+
*
|
|
484
|
+
* @param options.accountAddress - The sender's Bitcoin address
|
|
485
|
+
* @param options.amountInSatoshis - Amount to send in satoshis
|
|
486
|
+
* @param options.feePriority - Priority level for fee estimation ('low', 'medium', or 'high')
|
|
487
|
+
* @param options.network - Bitcoin network configuration (mainnet or testnet)
|
|
488
|
+
* @param options.publicKeyHex - The sender's public key in hexadecimal format
|
|
489
|
+
* @param options.recipientAddress - The recipient's Bitcoin address
|
|
490
|
+
* @returns A PSBT in Base64 format
|
|
491
|
+
* @throws Error if insufficient funds, no UTXOs, or other errors
|
|
492
|
+
*/
|
|
493
|
+
const buildPsbt = async ({ accountAddress, amountInSatoshis, feePriority = "medium", network, publicKeyHex, recipientAddress }) => {
|
|
494
|
+
if (amountInSatoshis <= BigInt(0)) throw new InvalidAmountError({
|
|
495
|
+
amountInSatoshis: Number(amountInSatoshis),
|
|
496
|
+
reason: "Amount must be greater than 0"
|
|
497
|
+
});
|
|
498
|
+
validateNotTaproot(accountAddress);
|
|
499
|
+
const allUTXOs = await getUTXOs(accountAddress);
|
|
500
|
+
if (allUTXOs.length === 0) throw new NoUTXOsFoundError({ address: accountAddress });
|
|
501
|
+
const publicKeyBuffer = new Uint8Array((0, _dynamic_labs_sdk_client_core.getBuffer)().from(publicKeyHex, "hex"));
|
|
502
|
+
const publicKeyPair = (0, ecpair.ECPairFactory)(_bitcoinerlab_secp256k1.default).fromPublicKey(publicKeyBuffer, { compressed: true });
|
|
503
|
+
const amountInSatoshisNumber = Number(amountInSatoshis);
|
|
504
|
+
const initialFeeEstimate = await estimateTransactionFee({
|
|
505
|
+
feePriority,
|
|
506
|
+
numInputs: 1,
|
|
507
|
+
numOutputs: 1
|
|
508
|
+
});
|
|
509
|
+
let selectedUTXOs = selectUTXOsLargestFirst({
|
|
510
|
+
targetAmount: amountInSatoshisNumber + initialFeeEstimate + DUST_LIMIT,
|
|
511
|
+
utxos: allUTXOs
|
|
512
|
+
});
|
|
513
|
+
selectedUTXOs = validateAndSelectUTXOs({
|
|
514
|
+
allUTXOs,
|
|
515
|
+
amountInSatoshis: amountInSatoshisNumber,
|
|
516
|
+
feeEstimate: initialFeeEstimate,
|
|
517
|
+
selectedTotal: calculateUTXOTotal(selectedUTXOs),
|
|
518
|
+
selectedUTXOs
|
|
519
|
+
});
|
|
520
|
+
const selectedTotalValue = calculateUTXOTotal(selectedUTXOs);
|
|
521
|
+
const { changeAmountNumber, feeEstimate, hasChangeOutput } = await calculateFeeAndChange({
|
|
522
|
+
amountInSatoshis,
|
|
523
|
+
feePriority,
|
|
524
|
+
selectedTotalValue,
|
|
525
|
+
selectedUTXOs
|
|
526
|
+
});
|
|
527
|
+
const maxToSpend = selectedTotalValue - feeEstimate;
|
|
528
|
+
if (maxToSpend < amountInSatoshisNumber) throw new InsufficientFundsError({
|
|
529
|
+
availableSatoshis: maxToSpend,
|
|
530
|
+
requiredSatoshis: amountInSatoshisNumber
|
|
531
|
+
});
|
|
532
|
+
const psbt = new bitcoinjs_lib.Psbt({ network });
|
|
533
|
+
addInputsToPsbt({
|
|
534
|
+
network,
|
|
535
|
+
psbt,
|
|
536
|
+
publicKeyPair,
|
|
537
|
+
selectedUTXOs
|
|
538
|
+
});
|
|
539
|
+
addOutputsToPsbt({
|
|
540
|
+
accountAddress,
|
|
541
|
+
amountInSatoshis: amountInSatoshisNumber,
|
|
542
|
+
changeAmount: changeAmountNumber,
|
|
543
|
+
hasChangeOutput,
|
|
544
|
+
network,
|
|
545
|
+
psbt,
|
|
546
|
+
recipientAddress
|
|
547
|
+
});
|
|
548
|
+
return psbt.toBase64();
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region src/errors/PublicKeyNotFoundError.ts
|
|
553
|
+
var PublicKeyNotFoundError = class extends _dynamic_labs_sdk_client.BaseError {
|
|
554
|
+
constructor(address$1) {
|
|
555
|
+
super({
|
|
556
|
+
cause: null,
|
|
557
|
+
code: "public_key_not_found_error",
|
|
558
|
+
docsUrl: null,
|
|
559
|
+
name: "PublicKeyNotFoundError",
|
|
560
|
+
shortMessage: `No public key found for address ${address$1}`
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
//#endregion
|
|
566
|
+
//#region src/waas/utils/getPublicKeyForWalletAccount/getPublicKeyForWalletAccount.ts
|
|
567
|
+
/**
|
|
568
|
+
* Gets the public key for a wallet account from the user's verified credentials
|
|
569
|
+
*/
|
|
570
|
+
const getPublicKeyForWalletAccount = (walletAccount, client) => {
|
|
571
|
+
const user = (0, _dynamic_labs_sdk_client_core.getCore)(client).state.get().user;
|
|
572
|
+
for (const credential of user?.verifiedCredentials ?? []) {
|
|
573
|
+
const additionalAddress = credential.walletAdditionalAddresses?.find((addr) => addr.address === walletAccount.address);
|
|
574
|
+
if (additionalAddress?.publicKey) return additionalAddress.publicKey;
|
|
575
|
+
}
|
|
576
|
+
throw new PublicKeyNotFoundError(walletAccount.address);
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/waas/utils/createWalletProviderForWaasBitcoin/createWalletProviderForWaasBitcoin.ts
|
|
581
|
+
const createWalletProviderForWaasBitcoin = (sdkClient) => {
|
|
582
|
+
const chain = "BTC";
|
|
583
|
+
const walletProviderType = _dynamic_labs_sdk_api_core.WalletProviderEnum.EmbeddedWallet;
|
|
584
|
+
const key = (0, _dynamic_labs_sdk_client_core.formatWalletProviderKey)({
|
|
585
|
+
chain,
|
|
586
|
+
displayName: _dynamic_labs_sdk_client_waas_core.DYNAMIC_WAAS_METADATA.displayName,
|
|
587
|
+
walletProviderType
|
|
588
|
+
});
|
|
589
|
+
const waasProvider = (0, _dynamic_labs_sdk_client_waas_core.createWaasProvider)({
|
|
590
|
+
chain,
|
|
591
|
+
sdkClient
|
|
592
|
+
});
|
|
593
|
+
const getActiveNetworkId = async () => (0, _dynamic_labs_sdk_client_core.getActiveNetworkIdFromLastKnownRegistry)({
|
|
594
|
+
client: sdkClient,
|
|
595
|
+
walletProviderKey: key
|
|
596
|
+
});
|
|
597
|
+
const switchActiveNetwork = async ({ networkId }) => (0, _dynamic_labs_sdk_client_core.switchActiveNetworkInLastKnownRegistry)({
|
|
598
|
+
client: sdkClient,
|
|
599
|
+
networkId,
|
|
600
|
+
walletProviderKey: key
|
|
601
|
+
});
|
|
602
|
+
const getConnectedAddresses = async () => {
|
|
603
|
+
return { addresses: (0, _dynamic_labs_sdk_client_waas_core.getAllUserWaasAddressesForChain)({ chain }, sdkClient) };
|
|
604
|
+
};
|
|
605
|
+
const signPsbt$1 = async ({ request, walletAccount }) => {
|
|
606
|
+
(0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
|
|
607
|
+
const waasClient = await waasProvider.getWaasClient();
|
|
608
|
+
const { signature: signedSessionId } = await (0, _dynamic_labs_sdk_client_core.getSignedSessionId)(sdkClient);
|
|
609
|
+
const mfaToken = await (0, _dynamic_labs_sdk_client_core.consumeMfaTokenIfRequiredForAction)({ mfaAction: _dynamic_labs_sdk_api_core.MFAAction.WalletWaasSign }, sdkClient);
|
|
610
|
+
return { signedPsbt: await waasClient.signTransaction({
|
|
611
|
+
authToken: sdkClient.token ?? void 0,
|
|
612
|
+
mfaToken,
|
|
613
|
+
senderAddress: walletAccount.address,
|
|
614
|
+
signedSessionId,
|
|
615
|
+
transaction: request.unsignedPsbtBase64
|
|
616
|
+
}) };
|
|
617
|
+
};
|
|
618
|
+
const signPsbts$1 = async ({ requests, walletAccount }) => {
|
|
619
|
+
(0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
|
|
620
|
+
return { signedPsbts: await Promise.all(requests.map(async (request) => {
|
|
621
|
+
const { signedPsbt } = await signPsbt$1({
|
|
622
|
+
request,
|
|
623
|
+
walletAccount
|
|
624
|
+
});
|
|
625
|
+
return signedPsbt;
|
|
626
|
+
})) };
|
|
627
|
+
};
|
|
628
|
+
const signMessage = async ({ message, walletAccount }) => {
|
|
629
|
+
(0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
|
|
630
|
+
const waasClient = await waasProvider.getWaasClient();
|
|
631
|
+
const { signature: signedSessionId } = await (0, _dynamic_labs_sdk_client_core.getSignedSessionId)(sdkClient);
|
|
632
|
+
const mfaToken = await (0, _dynamic_labs_sdk_client_core.consumeMfaTokenIfRequiredForAction)({ mfaAction: _dynamic_labs_sdk_api_core.MFAAction.WalletWaasSign }, sdkClient);
|
|
633
|
+
return { signature: await waasClient.signMessage({
|
|
634
|
+
accountAddress: walletAccount.address,
|
|
635
|
+
authToken: sdkClient.token ?? void 0,
|
|
636
|
+
bitcoinConfig: { network: "mainnet" },
|
|
637
|
+
message,
|
|
638
|
+
mfaToken,
|
|
639
|
+
signedSessionId
|
|
640
|
+
}) };
|
|
641
|
+
};
|
|
642
|
+
const buildPsbt$1 = async ({ transaction, walletAccount }) => {
|
|
643
|
+
(0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
|
|
644
|
+
const publicKeyHex = getPublicKeyForWalletAccount(walletAccount, sdkClient);
|
|
645
|
+
return buildPsbt({
|
|
646
|
+
accountAddress: walletAccount.address,
|
|
647
|
+
amountInSatoshis: transaction.amount,
|
|
648
|
+
feePriority: transaction.feePriority ?? "medium",
|
|
649
|
+
network: bitcoinjs_lib.networks.bitcoin,
|
|
650
|
+
publicKeyHex,
|
|
651
|
+
recipientAddress: transaction.recipientAddress
|
|
652
|
+
});
|
|
653
|
+
};
|
|
654
|
+
const sendBitcoin$1 = async ({ transaction, walletAccount }) => {
|
|
655
|
+
(0, _dynamic_labs_sdk_client_core.assertDefined)(walletAccount, "Wallet account is required");
|
|
656
|
+
const { signedPsbt } = await signPsbt$1({
|
|
657
|
+
request: {
|
|
658
|
+
allowedSighash: [],
|
|
659
|
+
unsignedPsbtBase64: await buildPsbt$1({
|
|
660
|
+
transaction: {
|
|
661
|
+
amount: transaction.amount,
|
|
662
|
+
recipientAddress: transaction.recipientAddress
|
|
663
|
+
},
|
|
664
|
+
walletAccount
|
|
665
|
+
})
|
|
666
|
+
},
|
|
667
|
+
walletAccount
|
|
668
|
+
});
|
|
669
|
+
const psbt = bitcoinjs_lib.Psbt.fromBase64(signedPsbt, { network: bitcoinjs_lib.networks.bitcoin });
|
|
670
|
+
psbt.finalizeAllInputs();
|
|
671
|
+
return { transactionId: await broadcastTransaction(psbt.extractTransaction().toHex()) };
|
|
672
|
+
};
|
|
673
|
+
return {
|
|
674
|
+
...waasProvider,
|
|
675
|
+
buildPsbt: buildPsbt$1,
|
|
676
|
+
chain,
|
|
677
|
+
getActiveNetworkId,
|
|
678
|
+
getConnectedAddresses,
|
|
679
|
+
groupKey: (0, _dynamic_labs_sdk_client_core.formatWalletProviderGroupKey)(_dynamic_labs_sdk_client_waas_core.DYNAMIC_WAAS_METADATA.displayName),
|
|
680
|
+
key,
|
|
681
|
+
metadata: {
|
|
682
|
+
displayName: _dynamic_labs_sdk_client_waas_core.DYNAMIC_WAAS_METADATA.displayName,
|
|
683
|
+
icon: _dynamic_labs_sdk_client_waas_core.DYNAMIC_WAAS_METADATA.icon
|
|
684
|
+
},
|
|
685
|
+
sendBitcoin: sendBitcoin$1,
|
|
686
|
+
signMessage,
|
|
687
|
+
signPsbt: signPsbt$1,
|
|
688
|
+
signPsbts: signPsbts$1,
|
|
689
|
+
switchActiveNetwork,
|
|
690
|
+
walletProviderType
|
|
691
|
+
};
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
//#endregion
|
|
695
|
+
//#region src/waas/addWaasBitcoinExtension/addWaasBitcoinExtension.ts
|
|
696
|
+
const WAAS_BITCOIN_EXTENSION_KEY = "waasBitcoin";
|
|
697
|
+
/**
|
|
698
|
+
* Adds the Dynamic WaaS (Wallet as a Service) Bitcoin extension to the Dynamic client.
|
|
699
|
+
*
|
|
700
|
+
* This extension enables embedded wallet functionality for Bitcoin blockchain,
|
|
701
|
+
* allowing users to have wallets managed by Dynamic's infrastructure.
|
|
702
|
+
*
|
|
703
|
+
* @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
|
|
704
|
+
*/
|
|
705
|
+
const addWaasBitcoinExtension = (client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
|
|
706
|
+
if ((0, _dynamic_labs_sdk_client_core.hasExtension)({ extensionKey: WAAS_BITCOIN_EXTENSION_KEY }, client)) return;
|
|
707
|
+
(0, _dynamic_labs_sdk_client_core.registerExtension)({ extensionKey: WAAS_BITCOIN_EXTENSION_KEY }, client);
|
|
708
|
+
require_addBitcoinInjectedWalletsExtension.registerBitcoinNetworkProviderBuilder(client);
|
|
709
|
+
const walletProviderRegistry = (0, _dynamic_labs_sdk_client_core.getWalletProviderRegistry)(client);
|
|
710
|
+
const walletProvider = createWalletProviderForWaasBitcoin(client);
|
|
711
|
+
walletProviderRegistry.register({
|
|
712
|
+
priority: _dynamic_labs_sdk_client_core.WalletProviderPriority.WALLET_SDK,
|
|
713
|
+
walletProvider
|
|
714
|
+
});
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
//#endregion
|
|
6
718
|
//#region src/addBitcoinExtension/addBitcoinExtension.ts
|
|
7
719
|
/**
|
|
8
720
|
* Adds the Bitcoin extension to the Dynamic client.
|
|
9
721
|
*
|
|
10
|
-
* This is a convenience function that adds
|
|
11
|
-
*
|
|
722
|
+
* This is a convenience function that adds both the Bitcoin Injected Wallets extension
|
|
723
|
+
* and the Dynamic WaaS Bitcoin extension, enabling support for all Bitcoin wallet types
|
|
724
|
+
* including injected wallets (MagicEden, Xverse, Unisat, and more) and embedded wallets
|
|
725
|
+
* managed by Dynamic's infrastructure.
|
|
12
726
|
*
|
|
13
727
|
* @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
|
|
14
728
|
*/
|
|
15
729
|
const addBitcoinExtension = (client = (0, _dynamic_labs_sdk_client_core.getDefaultClient)()) => {
|
|
16
730
|
require_addBitcoinInjectedWalletsExtension.addBitcoinInjectedWalletsExtension(client);
|
|
731
|
+
addWaasBitcoinExtension(client);
|
|
17
732
|
};
|
|
18
733
|
|
|
19
734
|
//#endregion
|
|
@@ -183,6 +898,9 @@ const signPsbts = async ({ walletAccount, requests }, client = (0, _dynamic_labs
|
|
|
183
898
|
|
|
184
899
|
//#endregion
|
|
185
900
|
exports.InvalidPsbtError = require_addBitcoinInjectedWalletsExtension.InvalidPsbtError;
|
|
901
|
+
exports.TransactionBroadcastFailedError = TransactionBroadcastFailedError;
|
|
902
|
+
exports.TransactionRequiredError = TransactionRequiredError;
|
|
903
|
+
exports.__toESM = __toESM;
|
|
186
904
|
exports.addBitcoinExtension = addBitcoinExtension;
|
|
187
905
|
exports.isBitcoinNetworkProvider = isBitcoinNetworkProvider;
|
|
188
906
|
exports.isBitcoinWalletAccount = isBitcoinWalletAccount;
|