@dynamic-labs/bitcoin 4.52.5 → 4.53.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/CHANGELOG.md +16 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +11 -6
- package/src/connectors/BitcoinSatsConnectConnector/BitcoinSatsConnectConnector.js +1 -1
- package/src/connectors/BitcoinWalletConnector.cjs +8 -0
- package/src/connectors/BitcoinWalletConnector.d.ts +1 -0
- package/src/connectors/BitcoinWalletConnector.js +10 -2
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +464 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +314 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +460 -0
- package/src/connectors/DynamicWaasBitcoinConnector/index.d.ts +1 -0
- package/src/connectors/index.d.ts +1 -0
- package/src/const.cjs +13 -0
- package/src/const.d.ts +6 -0
- package/src/const.js +8 -1
- package/src/index.cjs +9 -0
- package/src/index.d.ts +2 -2
- package/src/index.js +6 -0
- package/src/services/MempoolApiService.cjs +127 -0
- package/src/services/MempoolApiService.d.ts +42 -0
- package/src/services/MempoolApiService.js +123 -0
- package/src/services/PsbtBuilderService.cjs +132 -0
- package/src/services/PsbtBuilderService.d.ts +27 -0
- package/src/services/PsbtBuilderService.js +124 -0
- package/src/types.d.ts +43 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.cjs +24 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.d.ts +7 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.js +20 -0
- package/src/utils/btcToSatoshis/index.d.ts +1 -0
- package/src/utils/fetchSatsConnectConnectors/fetchSatsConnectConnectors.cjs +1 -0
- package/src/utils/fetchSatsConnectConnectors/fetchSatsConnectConnectors.js +1 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.cjs +15 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.d.ts +7 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.js +11 -0
- package/src/utils/getBitcoinNetwork/index.d.ts +1 -0
- package/src/utils/index.d.ts +3 -0
- package/src/utils/psbtParser/PsbtParser.cjs +185 -0
- package/src/utils/psbtParser/PsbtParser.d.ts +63 -0
- package/src/utils/psbtParser/PsbtParser.js +181 -0
- package/src/utils/psbtParser/index.d.ts +1 -0
- package/src/wallet/BitcoinWallet.cjs +11 -0
- package/src/wallet/BitcoinWallet.d.ts +6 -0
- package/src/wallet/BitcoinWallet.js +11 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
|
+
import { MFAAction } from '@dynamic-labs/sdk-api-core';
|
|
4
|
+
import { Logger } from '@dynamic-labs/logger';
|
|
5
|
+
import { DynamicError } from '@dynamic-labs/utils';
|
|
6
|
+
import { withDynamicWaas } from '@dynamic-labs/waas';
|
|
7
|
+
import { isSameAddress } from '@dynamic-labs/wallet-connector-core';
|
|
8
|
+
import { BitcoinWalletConnector } from '../BitcoinWalletConnector.js';
|
|
9
|
+
import { MempoolApiService } from '../../services/MempoolApiService.js';
|
|
10
|
+
import { PsbtBuilderService } from '../../services/PsbtBuilderService.js';
|
|
11
|
+
import { PsbtParser } from '../../utils/psbtParser/PsbtParser.js';
|
|
12
|
+
import 'sats-connect';
|
|
13
|
+
import 'bitcoinjs-lib';
|
|
14
|
+
import 'jsontokens';
|
|
15
|
+
import { btcToSatoshis } from '../../utils/btcToSatoshis/btcToSatoshis.js';
|
|
16
|
+
|
|
17
|
+
const logger = new Logger('DynamicWaasConnector');
|
|
18
|
+
/**
|
|
19
|
+
* Bitcoin connector for Dynamic WaaS (Wallet as a Service)
|
|
20
|
+
* Extends BitcoinWalletConnector with WaaS functionality for Bitcoin transactions
|
|
21
|
+
*/
|
|
22
|
+
class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector) {
|
|
23
|
+
// Override the key getter to avoid undefined name issues
|
|
24
|
+
get key() {
|
|
25
|
+
return this.overrideKey || 'dynamicwaas';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @param props - Constructor properties including walletUiUtils
|
|
29
|
+
*/
|
|
30
|
+
constructor(props) {
|
|
31
|
+
super(props);
|
|
32
|
+
this.name = 'Dynamic Waas';
|
|
33
|
+
this.logger = logger;
|
|
34
|
+
this.overrideKey = 'dynamicwaas';
|
|
35
|
+
this.isEmbeddedWallet = true;
|
|
36
|
+
this.connectedChain = 'BTC';
|
|
37
|
+
this.walletUiUtils = props.walletUiUtils;
|
|
38
|
+
this.mempoolApiService = new MempoolApiService();
|
|
39
|
+
this.psbtBuilderService = new PsbtBuilderService(this.mempoolApiService);
|
|
40
|
+
}
|
|
41
|
+
set verifiedCredential(verifiedCredential) {
|
|
42
|
+
this._verifiedCredential = verifiedCredential;
|
|
43
|
+
}
|
|
44
|
+
get verifiedCredential() {
|
|
45
|
+
return this._verifiedCredential;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Override setVerifiedCredentials to filter and set Bitcoin WaaS credentials
|
|
49
|
+
* Filters for credentials with walletName === 'dynamicwaas' and chain === 'bip122'
|
|
50
|
+
* The base class already has verifiedCredentials property, so we just filter and set it
|
|
51
|
+
*/
|
|
52
|
+
setVerifiedCredentials(verifiedCredentials) {
|
|
53
|
+
const dynamicWaasBitcoinVerifiedCredentials = verifiedCredentials === null || verifiedCredentials === void 0 ? void 0 : verifiedCredentials.reduce((acc, vc) => {
|
|
54
|
+
if (vc.walletName === 'dynamicwaas' && vc.chain === 'bip122') {
|
|
55
|
+
acc.push(vc);
|
|
56
|
+
}
|
|
57
|
+
return acc;
|
|
58
|
+
}, []);
|
|
59
|
+
const [dynamicWaasBitcoinVerifiedCredential] = dynamicWaasBitcoinVerifiedCredentials;
|
|
60
|
+
const didDynamicWaasBitcoinVerifiedCredentialsChanged = JSON.stringify(this.verifiedCredentials) !==
|
|
61
|
+
JSON.stringify(dynamicWaasBitcoinVerifiedCredentials);
|
|
62
|
+
if (!didDynamicWaasBitcoinVerifiedCredentialsChanged) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Set the filtered credentials using the base class property
|
|
66
|
+
this.verifiedCredentials = dynamicWaasBitcoinVerifiedCredentials;
|
|
67
|
+
// Set the primary credential
|
|
68
|
+
this.verifiedCredential = dynamicWaasBitcoinVerifiedCredential;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Gets the active wallet address
|
|
72
|
+
* Falls back to verified credential address if no active account is set
|
|
73
|
+
* @returns The wallet address or undefined
|
|
74
|
+
* @throws {DynamicError} If no active wallet address is found
|
|
75
|
+
*/
|
|
76
|
+
getAddress() {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
var _a;
|
|
79
|
+
const activeAccount = this.getActiveAccount();
|
|
80
|
+
if (!activeAccount || !activeAccount.address) {
|
|
81
|
+
if ((_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) {
|
|
82
|
+
const { address } = this.verifiedCredential;
|
|
83
|
+
this.setActiveAccount(address);
|
|
84
|
+
return address;
|
|
85
|
+
}
|
|
86
|
+
throw new DynamicError('No active wallet address found');
|
|
87
|
+
}
|
|
88
|
+
return activeAccount.address;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Gets all connected account addresses
|
|
93
|
+
* @returns Array of connected account addresses (currently returns single active address)
|
|
94
|
+
*/
|
|
95
|
+
getConnectedAccounts() {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
if (!this.activeAccountAddress) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
return [this.activeAccountAddress];
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Gets the current Bitcoin network
|
|
105
|
+
* @returns The network name ('mainnet' for Bitcoin)
|
|
106
|
+
*/
|
|
107
|
+
getNetwork() {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
return 'mainnet';
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Signs a message using the wallet UI utils for user interaction
|
|
114
|
+
* @param message - The message to sign
|
|
115
|
+
* @returns The signed message as a string
|
|
116
|
+
*/
|
|
117
|
+
signMessage(message) {
|
|
118
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
return this.walletUiUtils.signMessage({
|
|
120
|
+
handler: () => __awaiter(this, void 0, void 0, function* () { return this.internalSignMessage(message); }),
|
|
121
|
+
message,
|
|
122
|
+
walletConnector: this,
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Signs a Partially Signed Bitcoin Transaction (PSBT)
|
|
128
|
+
* @param request - The PSBT signing request containing the unsigned PSBT
|
|
129
|
+
* @returns The signed PSBT response
|
|
130
|
+
* @throws {DynamicError} If active account address is not set
|
|
131
|
+
* @throws {DynamicError} If signed session ID is not available or signature is provided
|
|
132
|
+
*/
|
|
133
|
+
signPsbt(request) {
|
|
134
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
var _a, _b, _c;
|
|
136
|
+
const walletClient = yield this.getWaasWalletClient();
|
|
137
|
+
if (!this.activeAccountAddress) {
|
|
138
|
+
throw new DynamicError('Active account address is required');
|
|
139
|
+
}
|
|
140
|
+
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
141
|
+
if (!signedSessionId) {
|
|
142
|
+
throw new DynamicError('Signed session ID is required');
|
|
143
|
+
}
|
|
144
|
+
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
145
|
+
mfaAction: MFAAction.WalletWaasSign,
|
|
146
|
+
}));
|
|
147
|
+
if (request.signature && request.signature.length > 0) {
|
|
148
|
+
throw new DynamicError('Signature is not supported for waas at the moment');
|
|
149
|
+
}
|
|
150
|
+
const signedTransaction = yield walletClient.signTransaction({
|
|
151
|
+
authToken: (_c = this.getAuthToken) === null || _c === void 0 ? void 0 : _c.call(this),
|
|
152
|
+
mfaToken,
|
|
153
|
+
senderAddress: this.activeAccountAddress,
|
|
154
|
+
signedSessionId,
|
|
155
|
+
transaction: request.unsignedPsbtBase64,
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
signedPsbt: signedTransaction,
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Sends a raw Bitcoin transaction to the mempool
|
|
164
|
+
* @param rawTransaction - The raw transaction in hex format
|
|
165
|
+
* @returns The transaction ID
|
|
166
|
+
* @throws {DynamicError} If no transaction is specified or sending fails
|
|
167
|
+
*/
|
|
168
|
+
sendRawTransaction(rawTransaction) {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
if (!this.activeAccountAddress) {
|
|
171
|
+
throw new DynamicError('Active account address is required');
|
|
172
|
+
}
|
|
173
|
+
return this.mempoolApiService.sendRawTransaction(this.activeAccountAddress, rawTransaction);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Sends Bitcoin to a recipient address
|
|
178
|
+
* This method combines buildPsbt, signPsbt, and sendRawTransaction into a single flow
|
|
179
|
+
* @param transaction - The Bitcoin transaction containing recipient address and amount
|
|
180
|
+
* @returns The transaction ID
|
|
181
|
+
* @throws {DynamicError} If any step in the process fails
|
|
182
|
+
*/
|
|
183
|
+
sendBitcoin(transaction) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
if (!this.activeAccountAddress) {
|
|
186
|
+
throw new DynamicError('Active account address is required');
|
|
187
|
+
}
|
|
188
|
+
// Step 1: Build the PSBT
|
|
189
|
+
const unsignedPsbt = yield this.buildPsbt(transaction);
|
|
190
|
+
// Step 2: Sign the PSBT
|
|
191
|
+
// SIGHASH_ALL (0x01) is the most common sighash type for Bitcoin transactions (Eventually can be configurable)
|
|
192
|
+
const signedPsbtResponse = yield this.signPsbt({
|
|
193
|
+
allowedSighash: [0x01],
|
|
194
|
+
unsignedPsbtBase64: unsignedPsbt,
|
|
195
|
+
});
|
|
196
|
+
if (!signedPsbtResponse) {
|
|
197
|
+
throw new DynamicError('Failed to sign PSBT');
|
|
198
|
+
}
|
|
199
|
+
// Step 3: Convert signed PSBT to raw transaction
|
|
200
|
+
const signedTransactionHex = signedPsbtResponse.signedPsbt;
|
|
201
|
+
// Step 4: Send the raw transaction
|
|
202
|
+
return this.sendRawTransaction(signedTransactionHex);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Creates a new Bitcoin wallet account with Bitcoin-specific defaults
|
|
207
|
+
* @param thresholdSignatureScheme - The threshold signature scheme (default: 'TWO_OF_TWO')
|
|
208
|
+
* @param password - Optional password for the wallet
|
|
209
|
+
* @param bitcoinConfig - Bitcoin configuration (required for Bitcoin)
|
|
210
|
+
* @returns The created wallet account information
|
|
211
|
+
*/
|
|
212
|
+
createWalletAccount() {
|
|
213
|
+
const _super = Object.create(null, {
|
|
214
|
+
createWalletAccount: { get: () => super.createWalletAccount }
|
|
215
|
+
});
|
|
216
|
+
return __awaiter(this, arguments, void 0, function* ({ thresholdSignatureScheme = 'TWO_OF_TWO', password, bitcoinConfig, } = {}) {
|
|
217
|
+
if (!bitcoinConfig || !bitcoinConfig.addressType) {
|
|
218
|
+
throw new DynamicError('Bitcoin config with address type is required for Bitcoin');
|
|
219
|
+
}
|
|
220
|
+
const finalBitcoinConfig = {
|
|
221
|
+
addressType: bitcoinConfig.addressType,
|
|
222
|
+
network: yield this.getNetwork(),
|
|
223
|
+
};
|
|
224
|
+
return _super.createWalletAccount.call(this, {
|
|
225
|
+
bitcoinConfig: finalBitcoinConfig,
|
|
226
|
+
password,
|
|
227
|
+
thresholdSignatureScheme,
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Override importPrivateKey to require and validate addressType for Bitcoin
|
|
233
|
+
* @param privateKey - The private key to import (WIF format for Bitcoin)
|
|
234
|
+
* @param thresholdSignatureScheme - The threshold signature scheme (default: 'TWO_OF_TWO')
|
|
235
|
+
* @param publicAddressCheck - Optional public address to verify against
|
|
236
|
+
* @param addressType - Required address type for Bitcoin ('native_segwit' or 'taproot')
|
|
237
|
+
* @throws {DynamicError} If addressType is missing or invalid for BTC
|
|
238
|
+
*/
|
|
239
|
+
importPrivateKey(_a) {
|
|
240
|
+
const _super = Object.create(null, {
|
|
241
|
+
importPrivateKey: { get: () => super.importPrivateKey }
|
|
242
|
+
});
|
|
243
|
+
return __awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, }) {
|
|
244
|
+
if (!addressType) {
|
|
245
|
+
throw new DynamicError('addressType is required for BTC importPrivateKey');
|
|
246
|
+
}
|
|
247
|
+
const validAddressTypes = ['native_segwit', 'taproot'];
|
|
248
|
+
if (!validAddressTypes.includes(addressType)) {
|
|
249
|
+
throw new DynamicError(`Invalid addressType: ${addressType}. Must be one of: ${validAddressTypes.join(', ')}`);
|
|
250
|
+
}
|
|
251
|
+
return _super.importPrivateKey.call(this, {
|
|
252
|
+
addressType,
|
|
253
|
+
privateKey,
|
|
254
|
+
publicAddressCheck,
|
|
255
|
+
thresholdSignatureScheme,
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Gets the wallet client for a specific account address and sets it as active
|
|
261
|
+
* @param accountAddress - The Bitcoin account address
|
|
262
|
+
* @returns The WaaS wallet client instance
|
|
263
|
+
*/
|
|
264
|
+
getWalletClientByAddress({ accountAddress }) {
|
|
265
|
+
this.setActiveAccountAddress(accountAddress);
|
|
266
|
+
return this.getWaasWalletClient();
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Gets the currently active account address
|
|
270
|
+
* @returns The active account address or undefined if not set
|
|
271
|
+
*/
|
|
272
|
+
getActiveAccountAddress() {
|
|
273
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
274
|
+
return this.activeAccountAddress;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Validates that the expected wallet address matches the active wallet
|
|
279
|
+
* Updates the active account address if it doesn't match
|
|
280
|
+
* @param expectedAddress - The expected wallet address to validate
|
|
281
|
+
* @throws {DynamicError} If signed session ID is not available or account is not found
|
|
282
|
+
*/
|
|
283
|
+
validateActiveWallet(expectedAddress) {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
285
|
+
var _a, _b;
|
|
286
|
+
const walletClient = yield this.getWaasWalletClient();
|
|
287
|
+
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
288
|
+
if (!signedSessionId) {
|
|
289
|
+
throw new DynamicError('Signed session ID is required');
|
|
290
|
+
}
|
|
291
|
+
const targetWallet = yield walletClient.getWallet({
|
|
292
|
+
accountAddress: expectedAddress,
|
|
293
|
+
authToken: (_b = this.getAuthToken) === null || _b === void 0 ? void 0 : _b.call(this),
|
|
294
|
+
signedSessionId,
|
|
295
|
+
});
|
|
296
|
+
if (!targetWallet) {
|
|
297
|
+
throw new DynamicError('Account not found');
|
|
298
|
+
}
|
|
299
|
+
const isWalletActive = isSameAddress(targetWallet.accountAddress, this.activeAccountAddress || '', this.connectedChain);
|
|
300
|
+
if (!isWalletActive) {
|
|
301
|
+
this.activeAccountAddress = targetWallet.accountAddress;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Signs a message with additional context information
|
|
307
|
+
* @param message - The message to sign (string or object with raw property)
|
|
308
|
+
* @param context - Additional context for the message signing
|
|
309
|
+
* @returns The signed message as a string
|
|
310
|
+
* @throws {DynamicError} If active account address is not set
|
|
311
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
312
|
+
*/
|
|
313
|
+
signMessageWithContext(_a) {
|
|
314
|
+
return __awaiter(this, arguments, void 0, function* ({ message, context, }) {
|
|
315
|
+
var _b, _c;
|
|
316
|
+
const walletClient = yield this.getWaasWalletClient();
|
|
317
|
+
if (!this.activeAccountAddress) {
|
|
318
|
+
throw new DynamicError('Active account address is required');
|
|
319
|
+
}
|
|
320
|
+
const signedSessionId = yield ((_b = this.getSignedSessionId) === null || _b === void 0 ? void 0 : _b.call(this));
|
|
321
|
+
if (!signedSessionId) {
|
|
322
|
+
throw new DynamicError('Signed session ID is required');
|
|
323
|
+
}
|
|
324
|
+
const messageString = typeof message === 'string' ? message : message.raw;
|
|
325
|
+
return walletClient.signMessage({
|
|
326
|
+
accountAddress: this.activeAccountAddress,
|
|
327
|
+
authToken: (_c = this.getAuthToken) === null || _c === void 0 ? void 0 : _c.call(this),
|
|
328
|
+
context,
|
|
329
|
+
message: messageString,
|
|
330
|
+
signedSessionId,
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Builds a PSBT for a Bitcoin transaction with real UTXOs
|
|
336
|
+
* @param transaction - The Bitcoin transaction containing recipient address and amount in satoshis to send
|
|
337
|
+
* @returns A PSBT in Base64 format
|
|
338
|
+
* @throws {DynamicError} If no active account address, insufficient funds, or other errors
|
|
339
|
+
*/
|
|
340
|
+
buildPsbt(transaction) {
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
if (!this.activeAccountAddress) {
|
|
343
|
+
throw new DynamicError('Active account address is required');
|
|
344
|
+
}
|
|
345
|
+
const publicKeyHex = yield this.getPublicKey();
|
|
346
|
+
const buildOptions = PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex);
|
|
347
|
+
return this.psbtBuilderService.buildPsbt(buildOptions);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Parse a PSBT or finalized transaction and extract transaction information
|
|
352
|
+
* Auto-detects format (hex/base64) and type (PSBT/finalized transaction)
|
|
353
|
+
* @param psbtInput - The PSBT or finalized transaction in Base64 or hex format
|
|
354
|
+
* @returns Parsed transaction data with inputs and outputs, or null if parsing fails
|
|
355
|
+
*/
|
|
356
|
+
parsePsbt(psbtInput) {
|
|
357
|
+
return PsbtParser.parsePsbt(psbtInput);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Parse a PSBT or finalized transaction from hex format
|
|
361
|
+
* @param psbtHex - The PSBT or finalized transaction in hex format
|
|
362
|
+
* @returns Parsed transaction data with inputs and outputs, or null if parsing fails
|
|
363
|
+
*/
|
|
364
|
+
parseHexPsbt(psbtHex) {
|
|
365
|
+
return PsbtParser.parseHexPsbt(psbtHex);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Parse a PSBT or finalized transaction from base64 format
|
|
369
|
+
* @param psbtBase64 - The PSBT or finalized transaction in base64 format
|
|
370
|
+
* @returns Parsed transaction data with inputs and outputs, or null if parsing fails
|
|
371
|
+
*/
|
|
372
|
+
parseBase64Psbt(psbtBase64) {
|
|
373
|
+
return PsbtParser.parseBase64Psbt(psbtBase64);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Gets the public key for the active account
|
|
377
|
+
* Falls back to the account address if public key retrieval fails
|
|
378
|
+
* @returns The public key or account address as fallback
|
|
379
|
+
* @throws {DynamicError} If no active account address is set
|
|
380
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
381
|
+
*/
|
|
382
|
+
getPublicKey() {
|
|
383
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
384
|
+
var _a;
|
|
385
|
+
if (!this.activeAccountAddress) {
|
|
386
|
+
throw new DynamicError('No active account address');
|
|
387
|
+
}
|
|
388
|
+
const allCredentials = (_a = this.verifiedCredentials) !== null && _a !== void 0 ? _a : [];
|
|
389
|
+
if (allCredentials.length === 0) {
|
|
390
|
+
throw new DynamicError(`No verified credentials found. The address ${this.activeAccountAddress} may not be properly registered.`);
|
|
391
|
+
}
|
|
392
|
+
for (const credential of allCredentials) {
|
|
393
|
+
const { walletAdditionalAddresses } = credential !== null && credential !== void 0 ? credential : {};
|
|
394
|
+
if (!walletAdditionalAddresses) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
const additionalAddress = walletAdditionalAddresses.find((address) => address.address === this.activeAccountAddress);
|
|
398
|
+
if (additionalAddress === null || additionalAddress === void 0 ? void 0 : additionalAddress.publicKey) {
|
|
399
|
+
return additionalAddress.publicKey;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const allAvailableAddresses = allCredentials
|
|
403
|
+
.flatMap((cred) => { var _a; return (_a = cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
404
|
+
.map((addr) => addr.address)
|
|
405
|
+
.join(', ');
|
|
406
|
+
throw new DynamicError(`No additional address found for ${this.activeAccountAddress}. Available addresses: ${allAvailableAddresses || 'none'}`);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Helper function to convert BTC amount to satoshis
|
|
411
|
+
* @param btcAmount - The Bitcoin amount to convert (number)
|
|
412
|
+
* @returns The amount in satoshis as a BigInt
|
|
413
|
+
* @throws {DynamicError} If the amount is negative
|
|
414
|
+
*/
|
|
415
|
+
btcToSatoshis(btcAmount) {
|
|
416
|
+
return btcToSatoshis(btcAmount);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Sets the active account address for this connector
|
|
420
|
+
* @param accountAddress - The Bitcoin account address to set as active
|
|
421
|
+
*/
|
|
422
|
+
setActiveAccountAddress(accountAddress) {
|
|
423
|
+
this.activeAccountAddress = accountAddress;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Internal method to sign a message with MFA token
|
|
427
|
+
* @param message - The message to sign
|
|
428
|
+
* @returns The signed message as a string
|
|
429
|
+
* @throws {DynamicError} If active account address is not set
|
|
430
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
431
|
+
*/
|
|
432
|
+
internalSignMessage(message) {
|
|
433
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
434
|
+
var _a, _b, _c;
|
|
435
|
+
const walletClient = yield this.getWaasWalletClient();
|
|
436
|
+
if (!this.activeAccountAddress) {
|
|
437
|
+
throw new DynamicError('Active account address is required');
|
|
438
|
+
}
|
|
439
|
+
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
440
|
+
if (!signedSessionId) {
|
|
441
|
+
throw new DynamicError('Signed session ID is required');
|
|
442
|
+
}
|
|
443
|
+
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
444
|
+
mfaAction: MFAAction.WalletWaasSign,
|
|
445
|
+
}));
|
|
446
|
+
return walletClient.signMessage({
|
|
447
|
+
accountAddress: this.activeAccountAddress,
|
|
448
|
+
authToken: (_c = this.getAuthToken) === null || _c === void 0 ? void 0 : _c.call(this),
|
|
449
|
+
bitcoinConfig: {
|
|
450
|
+
network: yield this.getNetwork(),
|
|
451
|
+
},
|
|
452
|
+
message,
|
|
453
|
+
mfaToken,
|
|
454
|
+
signedSessionId,
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export { DynamicWaasBitcoinConnector };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DynamicWaasBitcoinConnector';
|
package/src/const.cjs
CHANGED
|
@@ -9,10 +9,23 @@ const HTTP_STATUS_TOO_MANY_REQUESTS = 429;
|
|
|
9
9
|
const HTTP_STATUS_NOT_FOUND = 404;
|
|
10
10
|
const MEMPOOL_API_URL = 'https://mempool.space/api';
|
|
11
11
|
const MEMPOOL_API_URL_TESTNET = 'https://mempool.space/testnet/api';
|
|
12
|
+
// WaaS Bitcoin constants
|
|
13
|
+
const SATOSHIS_PER_BTC = 100000000;
|
|
14
|
+
const DUST_LIMIT = 546; // Bitcoin's dust limit in satoshis
|
|
15
|
+
const INPUT_BYTE_SIZE_UPPER_BOUND = 90;
|
|
16
|
+
const OUTPUT_BYTE_SIZE_UPPER_BOUND = 45;
|
|
17
|
+
const MIN_RELAY_FEE = 111;
|
|
18
|
+
const DEFAULT_FEE_ESTIMATE = 1000; // Conservative default fee estimate in satoshis
|
|
12
19
|
|
|
13
20
|
exports.BTCKIT_INTERFACE = BTCKIT_INTERFACE;
|
|
21
|
+
exports.DEFAULT_FEE_ESTIMATE = DEFAULT_FEE_ESTIMATE;
|
|
22
|
+
exports.DUST_LIMIT = DUST_LIMIT;
|
|
14
23
|
exports.HTTP_STATUS_NOT_FOUND = HTTP_STATUS_NOT_FOUND;
|
|
15
24
|
exports.HTTP_STATUS_TOO_MANY_REQUESTS = HTTP_STATUS_TOO_MANY_REQUESTS;
|
|
25
|
+
exports.INPUT_BYTE_SIZE_UPPER_BOUND = INPUT_BYTE_SIZE_UPPER_BOUND;
|
|
16
26
|
exports.MEMPOOL_API_URL = MEMPOOL_API_URL;
|
|
17
27
|
exports.MEMPOOL_API_URL_TESTNET = MEMPOOL_API_URL_TESTNET;
|
|
28
|
+
exports.MIN_RELAY_FEE = MIN_RELAY_FEE;
|
|
29
|
+
exports.OUTPUT_BYTE_SIZE_UPPER_BOUND = OUTPUT_BYTE_SIZE_UPPER_BOUND;
|
|
30
|
+
exports.SATOSHIS_PER_BTC = SATOSHIS_PER_BTC;
|
|
18
31
|
exports.SATSCONNECT_FEATURE = SATSCONNECT_FEATURE;
|
package/src/const.d.ts
CHANGED
|
@@ -5,3 +5,9 @@ export declare const HTTP_STATUS_TOO_MANY_REQUESTS = 429;
|
|
|
5
5
|
export declare const HTTP_STATUS_NOT_FOUND = 404;
|
|
6
6
|
export declare const MEMPOOL_API_URL = "https://mempool.space/api";
|
|
7
7
|
export declare const MEMPOOL_API_URL_TESTNET = "https://mempool.space/testnet/api";
|
|
8
|
+
export declare const SATOSHIS_PER_BTC = 100000000;
|
|
9
|
+
export declare const DUST_LIMIT = 546;
|
|
10
|
+
export declare const INPUT_BYTE_SIZE_UPPER_BOUND = 90;
|
|
11
|
+
export declare const OUTPUT_BYTE_SIZE_UPPER_BOUND = 45;
|
|
12
|
+
export declare const MIN_RELAY_FEE = 111;
|
|
13
|
+
export declare const DEFAULT_FEE_ESTIMATE = 1000;
|
package/src/const.js
CHANGED
|
@@ -5,5 +5,12 @@ const HTTP_STATUS_TOO_MANY_REQUESTS = 429;
|
|
|
5
5
|
const HTTP_STATUS_NOT_FOUND = 404;
|
|
6
6
|
const MEMPOOL_API_URL = 'https://mempool.space/api';
|
|
7
7
|
const MEMPOOL_API_URL_TESTNET = 'https://mempool.space/testnet/api';
|
|
8
|
+
// WaaS Bitcoin constants
|
|
9
|
+
const SATOSHIS_PER_BTC = 100000000;
|
|
10
|
+
const DUST_LIMIT = 546; // Bitcoin's dust limit in satoshis
|
|
11
|
+
const INPUT_BYTE_SIZE_UPPER_BOUND = 90;
|
|
12
|
+
const OUTPUT_BYTE_SIZE_UPPER_BOUND = 45;
|
|
13
|
+
const MIN_RELAY_FEE = 111;
|
|
14
|
+
const DEFAULT_FEE_ESTIMATE = 1000; // Conservative default fee estimate in satoshis
|
|
8
15
|
|
|
9
|
-
export { BTCKIT_INTERFACE, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS, MEMPOOL_API_URL, MEMPOOL_API_URL_TESTNET, SATSCONNECT_FEATURE };
|
|
16
|
+
export { BTCKIT_INTERFACE, DEFAULT_FEE_ESTIMATE, DUST_LIMIT, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS, INPUT_BYTE_SIZE_UPPER_BOUND, MEMPOOL_API_URL, MEMPOOL_API_URL_TESTNET, MIN_RELAY_FEE, OUTPUT_BYTE_SIZE_UPPER_BOUND, SATOSHIS_PER_BTC, SATSCONNECT_FEATURE };
|
package/src/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var OylConnector = require('./connectors/OylConnector/OylConnector.cjs');
|
|
|
20
20
|
var UnisatConnector = require('./connectors/UnisatConnector/UnisatConnector.cjs');
|
|
21
21
|
var FallbackBitcoinConnector = require('./connectors/FallbackBitcoinConnector/FallbackBitcoinConnector.cjs');
|
|
22
22
|
var BinanceConnector = require('./connectors/BinanceConnector/BinanceConnector.cjs');
|
|
23
|
+
var DynamicWaasBitcoinConnector = require('./connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs');
|
|
23
24
|
var BitgetConnector = require('./connectors/BitgetConnector/BitgetConnector.cjs');
|
|
24
25
|
var fetchBtcKitConnectors = require('./utils/fetchBtcKitConnectors/fetchBtcKitConnectors.cjs');
|
|
25
26
|
var fetchSatsConnectConnectors = require('./utils/fetchSatsConnectConnectors/fetchSatsConnectConnectors.cjs');
|
|
@@ -27,6 +28,9 @@ var hasSatsConnectFeature = require('./utils/hasSatsConnectFeature.cjs');
|
|
|
27
28
|
var getMempoolApiUrl = require('./utils/getMempoolApiUrl.cjs');
|
|
28
29
|
var createSignPsbtOptions = require('./utils/psbt/createSignPsbtOptions.cjs');
|
|
29
30
|
var satoshisToBtc = require('./utils/satoshisToBtc/satoshisToBtc.cjs');
|
|
31
|
+
var btcToSatoshis = require('./utils/btcToSatoshis/btcToSatoshis.cjs');
|
|
32
|
+
var getBitcoinNetwork = require('./utils/getBitcoinNetwork/getBitcoinNetwork.cjs');
|
|
33
|
+
var PsbtParser = require('./utils/psbtParser/PsbtParser.cjs');
|
|
30
34
|
var BitcoinWallet = require('./wallet/BitcoinWallet.cjs');
|
|
31
35
|
var isBitcoinWallet = require('./wallet/isBitcoinWallet/isBitcoinWallet.cjs');
|
|
32
36
|
var bitcoinProviderHelper = require('./bitcoinProviderHelper.cjs');
|
|
@@ -45,17 +49,22 @@ const BitcoinWalletConnectors = (props) => [
|
|
|
45
49
|
BitgetConnector.BitgetConnector,
|
|
46
50
|
BinanceConnector.BinanceConnector,
|
|
47
51
|
FallbackBitcoinConnector.FallbackBitcoinConnector,
|
|
52
|
+
DynamicWaasBitcoinConnector.DynamicWaasBitcoinConnector,
|
|
48
53
|
];
|
|
49
54
|
|
|
50
55
|
exports.BitcoinWalletConnector = BitcoinWalletConnector.BitcoinWalletConnector;
|
|
51
56
|
exports.BitcoinSatsConnectConnector = BitcoinSatsConnectConnector.BitcoinSatsConnectConnector;
|
|
52
57
|
exports.UnisatConnector = UnisatConnector.UnisatConnector;
|
|
58
|
+
exports.DynamicWaasBitcoinConnector = DynamicWaasBitcoinConnector.DynamicWaasBitcoinConnector;
|
|
53
59
|
exports.fetchBtcKitConnectors = fetchBtcKitConnectors.fetchBtcKitConnectors;
|
|
54
60
|
exports.fetchSatsConnectConnectors = fetchSatsConnectConnectors.fetchSatsConnectConnectors;
|
|
55
61
|
exports.hasSatsConnectFeature = hasSatsConnectFeature.hasSatsConnectFeature;
|
|
56
62
|
exports.getMempoolApiUrl = getMempoolApiUrl.getMempoolApiUrl;
|
|
57
63
|
exports.createPsbtOptions = createSignPsbtOptions.createPsbtOptions;
|
|
58
64
|
exports.satoshisToBtc = satoshisToBtc.satoshisToBtc;
|
|
65
|
+
exports.btcToSatoshis = btcToSatoshis.btcToSatoshis;
|
|
66
|
+
exports.getBitcoinNetwork = getBitcoinNetwork.getBitcoinNetwork;
|
|
67
|
+
exports.PsbtParser = PsbtParser.PsbtParser;
|
|
59
68
|
exports.BitcoinWallet = BitcoinWallet.BitcoinWallet;
|
|
60
69
|
exports.isBitcoinWallet = isBitcoinWallet.isBitcoinWallet;
|
|
61
70
|
exports.BitcoinProviderHelper = bitcoinProviderHelper.BitcoinProviderHelper;
|
package/src/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { OkxConnector } from './connectors';
|
|
2
|
-
export { BitcoinWalletConnector } from './connectors';
|
|
2
|
+
export { BitcoinWalletConnector, type BitcoinWalletConnectorOpts, } from './connectors';
|
|
3
3
|
export type { BitcoinTransaction, BitcoinSignProtocol, BitcoinSignPsbtRequest, BitcoinSignPsbtResponse, BitcoinWalletStandardMethods, SignPsbtOptions, } from './types';
|
|
4
4
|
export * from './utils';
|
|
5
5
|
export * from './wallet';
|
|
6
|
-
export { UnisatConnector, BitcoinSatsConnectConnector } from './connectors';
|
|
6
|
+
export { UnisatConnector, BitcoinSatsConnectConnector, DynamicWaasBitcoinConnector, } from './connectors';
|
|
7
7
|
export declare const BitcoinWalletConnectors: (props: any) => (import("dist/packages/wallet-connector-core/src").WalletConnectorConstructor | typeof OkxConnector)[];
|
|
8
8
|
export { BitcoinProviderHelper } from './bitcoinProviderHelper';
|
|
9
9
|
export { HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS } from './const';
|
package/src/index.js
CHANGED
|
@@ -17,6 +17,8 @@ import { UnisatConnector } from './connectors/UnisatConnector/UnisatConnector.js
|
|
|
17
17
|
export { UnisatConnector } from './connectors/UnisatConnector/UnisatConnector.js';
|
|
18
18
|
import { FallbackBitcoinConnector } from './connectors/FallbackBitcoinConnector/FallbackBitcoinConnector.js';
|
|
19
19
|
import { BinanceConnector } from './connectors/BinanceConnector/BinanceConnector.js';
|
|
20
|
+
import { DynamicWaasBitcoinConnector } from './connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js';
|
|
21
|
+
export { DynamicWaasBitcoinConnector } from './connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js';
|
|
20
22
|
import { BitgetConnector } from './connectors/BitgetConnector/BitgetConnector.js';
|
|
21
23
|
import { fetchBtcKitConnectors } from './utils/fetchBtcKitConnectors/fetchBtcKitConnectors.js';
|
|
22
24
|
export { fetchBtcKitConnectors } from './utils/fetchBtcKitConnectors/fetchBtcKitConnectors.js';
|
|
@@ -26,6 +28,9 @@ export { hasSatsConnectFeature } from './utils/hasSatsConnectFeature.js';
|
|
|
26
28
|
export { getMempoolApiUrl } from './utils/getMempoolApiUrl.js';
|
|
27
29
|
export { createPsbtOptions } from './utils/psbt/createSignPsbtOptions.js';
|
|
28
30
|
export { satoshisToBtc } from './utils/satoshisToBtc/satoshisToBtc.js';
|
|
31
|
+
export { btcToSatoshis } from './utils/btcToSatoshis/btcToSatoshis.js';
|
|
32
|
+
export { getBitcoinNetwork } from './utils/getBitcoinNetwork/getBitcoinNetwork.js';
|
|
33
|
+
export { PsbtParser } from './utils/psbtParser/PsbtParser.js';
|
|
29
34
|
export { BitcoinWallet } from './wallet/BitcoinWallet.js';
|
|
30
35
|
export { isBitcoinWallet } from './wallet/isBitcoinWallet/isBitcoinWallet.js';
|
|
31
36
|
export { BitcoinProviderHelper } from './bitcoinProviderHelper.js';
|
|
@@ -44,6 +49,7 @@ const BitcoinWalletConnectors = (props) => [
|
|
|
44
49
|
BitgetConnector,
|
|
45
50
|
BinanceConnector,
|
|
46
51
|
FallbackBitcoinConnector,
|
|
52
|
+
DynamicWaasBitcoinConnector,
|
|
47
53
|
];
|
|
48
54
|
|
|
49
55
|
export { BitcoinWalletConnectors };
|