@dynamic-labs/bitcoin 4.91.3 → 4.91.4
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 +8 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +8 -8
- package/src/connectors/BitcoinWalletConnector.cjs +4 -4
- package/src/connectors/BitcoinWalletConnector.js +4 -4
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +20 -20
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +1 -5
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +20 -20
- package/src/connectors/MagicEdenConnector/MagicEdenConnector.cjs +1 -1
- package/src/connectors/MagicEdenConnector/MagicEdenConnector.js +1 -1
- package/src/services/MempoolApiService.cjs +4 -4
- package/src/services/MempoolApiService.js +4 -4
- package/src/services/PsbtBuilderService.cjs +8 -8
- package/src/services/PsbtBuilderService.js +8 -8
- package/src/utils/btcToSatoshis/btcToSatoshis.cjs +1 -1
- package/src/utils/btcToSatoshis/btcToSatoshis.js +1 -1
- package/src/utils/psbt/validator/validateAddress.cjs +2 -2
- package/src/utils/psbt/validator/validateAddress.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.91.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.3...v4.91.4) (2026-07-01)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* conditionally use /op/ route for AA transactions based on block explorer support ([#11628](https://github.com/dynamic-labs/dynamic-auth/issues/11628)) ([95822dc](https://github.com/dynamic-labs/dynamic-auth/commit/95822dc0edbcd739afe870f0b3881555fdb17eb6))
|
|
8
|
+
* require error codes in all SDK error classes ([#11761](https://github.com/dynamic-labs/dynamic-auth/issues/11761)) ([5744811](https://github.com/dynamic-labs/dynamic-auth/commit/5744811efdd1e415aaf51eec5b3300b323ec1347))
|
|
9
|
+
|
|
2
10
|
### [4.91.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.2...v4.91.3) (2026-06-30)
|
|
3
11
|
|
|
4
12
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/bitcoin",
|
|
3
|
-
"version": "4.91.
|
|
3
|
+
"version": "4.91.4",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
"ecpair": "2.1.0",
|
|
30
30
|
"sats-connect": "4.2.1",
|
|
31
31
|
"jsontokens": "4.0.1",
|
|
32
|
-
"@dynamic-labs/assert-package-version": "4.91.
|
|
33
|
-
"@dynamic-labs/logger": "4.91.
|
|
34
|
-
"@dynamic-labs/types": "4.91.
|
|
35
|
-
"@dynamic-labs/utils": "4.91.
|
|
36
|
-
"@dynamic-labs/waas": "4.91.
|
|
37
|
-
"@dynamic-labs/wallet-book": "4.91.
|
|
38
|
-
"@dynamic-labs/wallet-connector-core": "4.91.
|
|
32
|
+
"@dynamic-labs/assert-package-version": "4.91.4",
|
|
33
|
+
"@dynamic-labs/logger": "4.91.4",
|
|
34
|
+
"@dynamic-labs/types": "4.91.4",
|
|
35
|
+
"@dynamic-labs/utils": "4.91.4",
|
|
36
|
+
"@dynamic-labs/waas": "4.91.4",
|
|
37
|
+
"@dynamic-labs/wallet-book": "4.91.4",
|
|
38
|
+
"@dynamic-labs/wallet-connector-core": "4.91.4",
|
|
39
39
|
"eventemitter3": "5.0.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {}
|
|
@@ -178,11 +178,11 @@ class BitcoinWalletConnector extends walletConnectorCore.WalletConnectorBase {
|
|
|
178
178
|
sendRawTransaction(rawTransaction) {
|
|
179
179
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
180
180
|
if (!rawTransaction) {
|
|
181
|
-
throw new utils.DynamicError('No transaction specified!');
|
|
181
|
+
throw new utils.DynamicError('No transaction specified!', 'no_transaction_specified');
|
|
182
182
|
}
|
|
183
183
|
const [connectedAddress] = yield this.getConnectedAccounts();
|
|
184
184
|
if (!connectedAddress) {
|
|
185
|
-
throw new utils.DynamicError('No connected address found!');
|
|
185
|
+
throw new utils.DynamicError('No connected address found!', 'no_connected_address_found');
|
|
186
186
|
}
|
|
187
187
|
const API_URL = getMempoolApiUrl.getMempoolApiUrl(connectedAddress);
|
|
188
188
|
const response = yield fetch(`${API_URL}/tx`, {
|
|
@@ -194,11 +194,11 @@ class BitcoinWalletConnector extends walletConnectorCore.WalletConnectorBase {
|
|
|
194
194
|
});
|
|
195
195
|
if (!response.ok) {
|
|
196
196
|
if (response.status === _const.HTTP_STATUS_TOO_MANY_REQUESTS) {
|
|
197
|
-
throw new utils.DynamicError('sendRawTransaction - mempool api rate limit exceeded');
|
|
197
|
+
throw new utils.DynamicError('sendRawTransaction - mempool api rate limit exceeded', 'sendrawtransaction_mempool_api_rate_limit_exceeded');
|
|
198
198
|
}
|
|
199
199
|
const error = yield response.text();
|
|
200
200
|
walletConnectorCore.logger.debug(`sendRawTransaction - response not ok: ${JSON.stringify(error)}`);
|
|
201
|
-
throw new utils.DynamicError('sendRawTransaction - failed to send transaction');
|
|
201
|
+
throw new utils.DynamicError('sendRawTransaction - failed to send transaction', 'sendrawtransaction_failed_to_send_transaction');
|
|
202
202
|
}
|
|
203
203
|
// this endpoint returns the transaction ID
|
|
204
204
|
return response.text();
|
|
@@ -174,11 +174,11 @@ class BitcoinWalletConnector extends WalletConnectorBase {
|
|
|
174
174
|
sendRawTransaction(rawTransaction) {
|
|
175
175
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
176
|
if (!rawTransaction) {
|
|
177
|
-
throw new DynamicError('No transaction specified!');
|
|
177
|
+
throw new DynamicError('No transaction specified!', 'no_transaction_specified');
|
|
178
178
|
}
|
|
179
179
|
const [connectedAddress] = yield this.getConnectedAccounts();
|
|
180
180
|
if (!connectedAddress) {
|
|
181
|
-
throw new DynamicError('No connected address found!');
|
|
181
|
+
throw new DynamicError('No connected address found!', 'no_connected_address_found');
|
|
182
182
|
}
|
|
183
183
|
const API_URL = getMempoolApiUrl(connectedAddress);
|
|
184
184
|
const response = yield fetch(`${API_URL}/tx`, {
|
|
@@ -190,11 +190,11 @@ class BitcoinWalletConnector extends WalletConnectorBase {
|
|
|
190
190
|
});
|
|
191
191
|
if (!response.ok) {
|
|
192
192
|
if (response.status === HTTP_STATUS_TOO_MANY_REQUESTS) {
|
|
193
|
-
throw new DynamicError('sendRawTransaction - mempool api rate limit exceeded');
|
|
193
|
+
throw new DynamicError('sendRawTransaction - mempool api rate limit exceeded', 'sendrawtransaction_mempool_api_rate_limit_exceeded');
|
|
194
194
|
}
|
|
195
195
|
const error = yield response.text();
|
|
196
196
|
logger.debug(`sendRawTransaction - response not ok: ${JSON.stringify(error)}`);
|
|
197
|
-
throw new DynamicError('sendRawTransaction - failed to send transaction');
|
|
197
|
+
throw new DynamicError('sendRawTransaction - failed to send transaction', 'sendrawtransaction_failed_to_send_transaction');
|
|
198
198
|
}
|
|
199
199
|
// this endpoint returns the transaction ID
|
|
200
200
|
return response.text();
|
|
@@ -90,7 +90,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
90
90
|
this.setActiveAccount(address);
|
|
91
91
|
return address;
|
|
92
92
|
}
|
|
93
|
-
throw new utils.DynamicError('No active wallet address found');
|
|
93
|
+
throw new utils.DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
94
94
|
}
|
|
95
95
|
return activeAccount.address;
|
|
96
96
|
});
|
|
@@ -180,11 +180,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
180
180
|
var _a, _b, _c, _d;
|
|
181
181
|
const walletClient = yield this.getWaasWalletClient();
|
|
182
182
|
if (!this.activeAccountAddress) {
|
|
183
|
-
throw new utils.DynamicError('Active account address is required');
|
|
183
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
184
184
|
}
|
|
185
185
|
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
186
186
|
if (!signedSessionId) {
|
|
187
|
-
throw new utils.DynamicError('Signed session ID is required');
|
|
187
|
+
throw new utils.DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
188
188
|
}
|
|
189
189
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
190
190
|
mfaAction: sdkApiCore.MFAAction.WalletWaasSign,
|
|
@@ -218,7 +218,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
218
218
|
sendRawTransaction(rawTransaction) {
|
|
219
219
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
220
220
|
if (!this.activeAccountAddress) {
|
|
221
|
-
throw new utils.DynamicError('Active account address is required');
|
|
221
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
222
222
|
}
|
|
223
223
|
return this.mempoolApiService.sendRawTransaction(this.activeAccountAddress, rawTransaction);
|
|
224
224
|
});
|
|
@@ -233,7 +233,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
233
233
|
sendBitcoin(transaction) {
|
|
234
234
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
235
235
|
if (!this.activeAccountAddress) {
|
|
236
|
-
throw new utils.DynamicError('Active account address is required');
|
|
236
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
237
237
|
}
|
|
238
238
|
// Step 1: Build the PSBT
|
|
239
239
|
const unsignedPsbt = yield this.buildPsbt(transaction);
|
|
@@ -242,7 +242,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
242
242
|
unsignedPsbtBase64: unsignedPsbt,
|
|
243
243
|
});
|
|
244
244
|
if (!signedPsbtResponse) {
|
|
245
|
-
throw new utils.DynamicError('Failed to sign PSBT');
|
|
245
|
+
throw new utils.DynamicError('Failed to sign PSBT', 'sign_psbt_failed');
|
|
246
246
|
}
|
|
247
247
|
// Step 3: Finalize the signed PSBT and extract the raw transaction
|
|
248
248
|
const network = this.activeAccountAddress.startsWith('t')
|
|
@@ -297,11 +297,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
297
297
|
});
|
|
298
298
|
return _tslib.__awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, legacyWalletId, }) {
|
|
299
299
|
if (!addressType) {
|
|
300
|
-
throw new utils.DynamicError('addressType is required for BTC importPrivateKey');
|
|
300
|
+
throw new utils.DynamicError('addressType is required for BTC importPrivateKey', 'addresstype_is_required_for_btc_importprivatekey');
|
|
301
301
|
}
|
|
302
302
|
const validAddressTypes = ['native_segwit', 'taproot'];
|
|
303
303
|
if (!validAddressTypes.includes(addressType)) {
|
|
304
|
-
throw new utils.DynamicError(`Invalid addressType: ${addressType}. Must be one of: ${validAddressTypes.join(', ')}
|
|
304
|
+
throw new utils.DynamicError(`Invalid addressType: ${addressType}. Must be one of: ${validAddressTypes.join(', ')}`, 'invalid_addresstype_must_be_one_of');
|
|
305
305
|
}
|
|
306
306
|
return _super.importPrivateKey.call(this, {
|
|
307
307
|
addressType,
|
|
@@ -347,7 +347,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
347
347
|
signedSessionId: '',
|
|
348
348
|
});
|
|
349
349
|
if (!targetWallet) {
|
|
350
|
-
throw new utils.DynamicError('Account not found');
|
|
350
|
+
throw new utils.DynamicError('Account not found', 'account_not_found');
|
|
351
351
|
}
|
|
352
352
|
const isWalletActive = walletConnectorCore.isSameAddress(targetWallet.accountAddress, this.activeAccountAddress || '', this.connectedChain);
|
|
353
353
|
if (!isWalletActive) {
|
|
@@ -368,11 +368,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
368
368
|
var _b, _c, _d, _e;
|
|
369
369
|
const walletClient = yield this.getWaasWalletClient();
|
|
370
370
|
if (!this.activeAccountAddress) {
|
|
371
|
-
throw new utils.DynamicError('Active account address is required');
|
|
371
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
372
372
|
}
|
|
373
373
|
const signedSessionId = yield ((_b = this.getSignedSessionId) === null || _b === void 0 ? void 0 : _b.call(this));
|
|
374
374
|
if (!signedSessionId) {
|
|
375
|
-
throw new utils.DynamicError('Signed session ID is required');
|
|
375
|
+
throw new utils.DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
376
376
|
}
|
|
377
377
|
const mfaToken = yield ((_c = this.getMfaToken) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
378
378
|
mfaAction: sdkApiCore.MFAAction.WalletWaasSign,
|
|
@@ -405,7 +405,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
405
405
|
buildPsbt(transaction) {
|
|
406
406
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
407
407
|
if (!this.activeAccountAddress) {
|
|
408
|
-
throw new utils.DynamicError('Active account address is required');
|
|
408
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
409
409
|
}
|
|
410
410
|
const publicKeyHex = yield this.getPublicKey();
|
|
411
411
|
const buildOptions = PsbtBuilderService.PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex, transaction.feePriority || 'medium');
|
|
@@ -437,7 +437,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
437
437
|
}
|
|
438
438
|
if (!this.activeAccountAddress) {
|
|
439
439
|
logger.error('[DynamicWaasBitcoinConnector] Active account address is required but not set');
|
|
440
|
-
throw new utils.DynamicError('Active account address is required');
|
|
440
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
441
441
|
}
|
|
442
442
|
logger.debug('[DynamicWaasBitcoinConnector] Creating BitcoinUiTransaction', {
|
|
443
443
|
from: this.activeAccountAddress,
|
|
@@ -457,7 +457,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
457
457
|
hasAmount: Boolean(transaction.amount),
|
|
458
458
|
hasRecipientAddress: Boolean(transaction.recipientAddress),
|
|
459
459
|
});
|
|
460
|
-
throw new utils.DynamicError('Recipient address and amount are required');
|
|
460
|
+
throw new utils.DynamicError('Recipient address and amount are required', 'recipient_address_and_amount_are_required');
|
|
461
461
|
}
|
|
462
462
|
try {
|
|
463
463
|
logger.debug('[DynamicWaasBitcoinConnector] Calling sendBitcoin', {
|
|
@@ -475,7 +475,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
475
475
|
});
|
|
476
476
|
if (!txHash) {
|
|
477
477
|
logger.error('[DynamicWaasBitcoinConnector] sendBitcoin returned undefined');
|
|
478
|
-
throw new utils.DynamicError('Failed to send Bitcoin transaction');
|
|
478
|
+
throw new utils.DynamicError('Failed to send Bitcoin transaction', 'send_bitcoin_transaction');
|
|
479
479
|
}
|
|
480
480
|
logger.info('[DynamicWaasBitcoinConnector] Transaction submitted successfully', { txHash });
|
|
481
481
|
return txHash;
|
|
@@ -530,11 +530,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
530
530
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
531
531
|
var _a;
|
|
532
532
|
if (!this.activeAccountAddress) {
|
|
533
|
-
throw new utils.DynamicError('No active account address');
|
|
533
|
+
throw new utils.DynamicError('No active account address', 'no_active_account_address');
|
|
534
534
|
}
|
|
535
535
|
const allCredentials = (_a = this.verifiedCredentials) !== null && _a !== void 0 ? _a : [];
|
|
536
536
|
if (allCredentials.length === 0) {
|
|
537
|
-
throw new utils.DynamicError(`No verified credentials found. The address ${this.activeAccountAddress} may not be properly registered
|
|
537
|
+
throw new utils.DynamicError(`No verified credentials found. The address ${this.activeAccountAddress} may not be properly registered.`, 'no_verified_credentials_found_the_address');
|
|
538
538
|
}
|
|
539
539
|
for (const credential of allCredentials) {
|
|
540
540
|
const { walletAdditionalAddresses } = credential !== null && credential !== void 0 ? credential : {};
|
|
@@ -550,7 +550,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
550
550
|
.flatMap((cred) => { var _a; return (_a = cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
551
551
|
.map((addr) => addr.address)
|
|
552
552
|
.join(', ');
|
|
553
|
-
throw new utils.DynamicError(`No additional address found for ${this.activeAccountAddress}. Available addresses: ${allAvailableAddresses || 'none'}
|
|
553
|
+
throw new utils.DynamicError(`No additional address found for ${this.activeAccountAddress}. Available addresses: ${allAvailableAddresses || 'none'}`, 'no_additional_address_found_for_available');
|
|
554
554
|
});
|
|
555
555
|
}
|
|
556
556
|
/**
|
|
@@ -581,11 +581,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
581
581
|
var _a, _b, _c, _d;
|
|
582
582
|
const walletClient = yield this.getWaasWalletClient();
|
|
583
583
|
if (!this.activeAccountAddress) {
|
|
584
|
-
throw new utils.DynamicError('Active account address is required');
|
|
584
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
585
585
|
}
|
|
586
586
|
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
587
587
|
if (!signedSessionId) {
|
|
588
|
-
throw new utils.DynamicError('Signed session ID is required');
|
|
588
|
+
throw new utils.DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
589
589
|
}
|
|
590
590
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
591
591
|
mfaAction: sdkApiCore.MFAAction.WalletWaasSign,
|
|
@@ -120,11 +120,7 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
120
120
|
hideICloudSignIn(): Promise<void>;
|
|
121
121
|
isICloudAuthenticated(): Promise<boolean>;
|
|
122
122
|
refreshWalletAccountShares({ accountAddress, password, }: {
|
|
123
|
-
accountAddress: string;
|
|
124
|
-
* Gets block explorer URLs for the current network
|
|
125
|
-
* Returns mempool.space for Bitcoin transactions
|
|
126
|
-
* @returns Array containing mempool.space URL
|
|
127
|
-
*/
|
|
123
|
+
accountAddress: string;
|
|
128
124
|
password?: string | undefined;
|
|
129
125
|
}): Promise<void>;
|
|
130
126
|
reshareWalletAccountShares({ accountAddress, thresholdSignatureScheme, password, }: {
|
|
@@ -86,7 +86,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
86
86
|
this.setActiveAccount(address);
|
|
87
87
|
return address;
|
|
88
88
|
}
|
|
89
|
-
throw new DynamicError('No active wallet address found');
|
|
89
|
+
throw new DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
90
90
|
}
|
|
91
91
|
return activeAccount.address;
|
|
92
92
|
});
|
|
@@ -176,11 +176,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
176
176
|
var _a, _b, _c, _d;
|
|
177
177
|
const walletClient = yield this.getWaasWalletClient();
|
|
178
178
|
if (!this.activeAccountAddress) {
|
|
179
|
-
throw new DynamicError('Active account address is required');
|
|
179
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
180
180
|
}
|
|
181
181
|
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
182
182
|
if (!signedSessionId) {
|
|
183
|
-
throw new DynamicError('Signed session ID is required');
|
|
183
|
+
throw new DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
184
184
|
}
|
|
185
185
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
186
186
|
mfaAction: MFAAction.WalletWaasSign,
|
|
@@ -214,7 +214,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
214
214
|
sendRawTransaction(rawTransaction) {
|
|
215
215
|
return __awaiter(this, void 0, void 0, function* () {
|
|
216
216
|
if (!this.activeAccountAddress) {
|
|
217
|
-
throw new DynamicError('Active account address is required');
|
|
217
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
218
218
|
}
|
|
219
219
|
return this.mempoolApiService.sendRawTransaction(this.activeAccountAddress, rawTransaction);
|
|
220
220
|
});
|
|
@@ -229,7 +229,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
229
229
|
sendBitcoin(transaction) {
|
|
230
230
|
return __awaiter(this, void 0, void 0, function* () {
|
|
231
231
|
if (!this.activeAccountAddress) {
|
|
232
|
-
throw new DynamicError('Active account address is required');
|
|
232
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
233
233
|
}
|
|
234
234
|
// Step 1: Build the PSBT
|
|
235
235
|
const unsignedPsbt = yield this.buildPsbt(transaction);
|
|
@@ -238,7 +238,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
238
238
|
unsignedPsbtBase64: unsignedPsbt,
|
|
239
239
|
});
|
|
240
240
|
if (!signedPsbtResponse) {
|
|
241
|
-
throw new DynamicError('Failed to sign PSBT');
|
|
241
|
+
throw new DynamicError('Failed to sign PSBT', 'sign_psbt_failed');
|
|
242
242
|
}
|
|
243
243
|
// Step 3: Finalize the signed PSBT and extract the raw transaction
|
|
244
244
|
const network = this.activeAccountAddress.startsWith('t')
|
|
@@ -293,11 +293,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
293
293
|
});
|
|
294
294
|
return __awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, legacyWalletId, }) {
|
|
295
295
|
if (!addressType) {
|
|
296
|
-
throw new DynamicError('addressType is required for BTC importPrivateKey');
|
|
296
|
+
throw new DynamicError('addressType is required for BTC importPrivateKey', 'addresstype_is_required_for_btc_importprivatekey');
|
|
297
297
|
}
|
|
298
298
|
const validAddressTypes = ['native_segwit', 'taproot'];
|
|
299
299
|
if (!validAddressTypes.includes(addressType)) {
|
|
300
|
-
throw new DynamicError(`Invalid addressType: ${addressType}. Must be one of: ${validAddressTypes.join(', ')}
|
|
300
|
+
throw new DynamicError(`Invalid addressType: ${addressType}. Must be one of: ${validAddressTypes.join(', ')}`, 'invalid_addresstype_must_be_one_of');
|
|
301
301
|
}
|
|
302
302
|
return _super.importPrivateKey.call(this, {
|
|
303
303
|
addressType,
|
|
@@ -343,7 +343,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
343
343
|
signedSessionId: '',
|
|
344
344
|
});
|
|
345
345
|
if (!targetWallet) {
|
|
346
|
-
throw new DynamicError('Account not found');
|
|
346
|
+
throw new DynamicError('Account not found', 'account_not_found');
|
|
347
347
|
}
|
|
348
348
|
const isWalletActive = isSameAddress(targetWallet.accountAddress, this.activeAccountAddress || '', this.connectedChain);
|
|
349
349
|
if (!isWalletActive) {
|
|
@@ -364,11 +364,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
364
364
|
var _b, _c, _d, _e;
|
|
365
365
|
const walletClient = yield this.getWaasWalletClient();
|
|
366
366
|
if (!this.activeAccountAddress) {
|
|
367
|
-
throw new DynamicError('Active account address is required');
|
|
367
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
368
368
|
}
|
|
369
369
|
const signedSessionId = yield ((_b = this.getSignedSessionId) === null || _b === void 0 ? void 0 : _b.call(this));
|
|
370
370
|
if (!signedSessionId) {
|
|
371
|
-
throw new DynamicError('Signed session ID is required');
|
|
371
|
+
throw new DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
372
372
|
}
|
|
373
373
|
const mfaToken = yield ((_c = this.getMfaToken) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
374
374
|
mfaAction: MFAAction.WalletWaasSign,
|
|
@@ -401,7 +401,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
401
401
|
buildPsbt(transaction) {
|
|
402
402
|
return __awaiter(this, void 0, void 0, function* () {
|
|
403
403
|
if (!this.activeAccountAddress) {
|
|
404
|
-
throw new DynamicError('Active account address is required');
|
|
404
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
405
405
|
}
|
|
406
406
|
const publicKeyHex = yield this.getPublicKey();
|
|
407
407
|
const buildOptions = PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex, transaction.feePriority || 'medium');
|
|
@@ -433,7 +433,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
433
433
|
}
|
|
434
434
|
if (!this.activeAccountAddress) {
|
|
435
435
|
logger.error('[DynamicWaasBitcoinConnector] Active account address is required but not set');
|
|
436
|
-
throw new DynamicError('Active account address is required');
|
|
436
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
437
437
|
}
|
|
438
438
|
logger.debug('[DynamicWaasBitcoinConnector] Creating BitcoinUiTransaction', {
|
|
439
439
|
from: this.activeAccountAddress,
|
|
@@ -453,7 +453,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
453
453
|
hasAmount: Boolean(transaction.amount),
|
|
454
454
|
hasRecipientAddress: Boolean(transaction.recipientAddress),
|
|
455
455
|
});
|
|
456
|
-
throw new DynamicError('Recipient address and amount are required');
|
|
456
|
+
throw new DynamicError('Recipient address and amount are required', 'recipient_address_and_amount_are_required');
|
|
457
457
|
}
|
|
458
458
|
try {
|
|
459
459
|
logger.debug('[DynamicWaasBitcoinConnector] Calling sendBitcoin', {
|
|
@@ -471,7 +471,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
471
471
|
});
|
|
472
472
|
if (!txHash) {
|
|
473
473
|
logger.error('[DynamicWaasBitcoinConnector] sendBitcoin returned undefined');
|
|
474
|
-
throw new DynamicError('Failed to send Bitcoin transaction');
|
|
474
|
+
throw new DynamicError('Failed to send Bitcoin transaction', 'send_bitcoin_transaction');
|
|
475
475
|
}
|
|
476
476
|
logger.info('[DynamicWaasBitcoinConnector] Transaction submitted successfully', { txHash });
|
|
477
477
|
return txHash;
|
|
@@ -526,11 +526,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
526
526
|
return __awaiter(this, void 0, void 0, function* () {
|
|
527
527
|
var _a;
|
|
528
528
|
if (!this.activeAccountAddress) {
|
|
529
|
-
throw new DynamicError('No active account address');
|
|
529
|
+
throw new DynamicError('No active account address', 'no_active_account_address');
|
|
530
530
|
}
|
|
531
531
|
const allCredentials = (_a = this.verifiedCredentials) !== null && _a !== void 0 ? _a : [];
|
|
532
532
|
if (allCredentials.length === 0) {
|
|
533
|
-
throw new DynamicError(`No verified credentials found. The address ${this.activeAccountAddress} may not be properly registered
|
|
533
|
+
throw new DynamicError(`No verified credentials found. The address ${this.activeAccountAddress} may not be properly registered.`, 'no_verified_credentials_found_the_address');
|
|
534
534
|
}
|
|
535
535
|
for (const credential of allCredentials) {
|
|
536
536
|
const { walletAdditionalAddresses } = credential !== null && credential !== void 0 ? credential : {};
|
|
@@ -546,7 +546,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
546
546
|
.flatMap((cred) => { var _a; return (_a = cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
547
547
|
.map((addr) => addr.address)
|
|
548
548
|
.join(', ');
|
|
549
|
-
throw new DynamicError(`No additional address found for ${this.activeAccountAddress}. Available addresses: ${allAvailableAddresses || 'none'}
|
|
549
|
+
throw new DynamicError(`No additional address found for ${this.activeAccountAddress}. Available addresses: ${allAvailableAddresses || 'none'}`, 'no_additional_address_found_for_available');
|
|
550
550
|
});
|
|
551
551
|
}
|
|
552
552
|
/**
|
|
@@ -577,11 +577,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
577
577
|
var _a, _b, _c, _d;
|
|
578
578
|
const walletClient = yield this.getWaasWalletClient();
|
|
579
579
|
if (!this.activeAccountAddress) {
|
|
580
|
-
throw new DynamicError('Active account address is required');
|
|
580
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
581
581
|
}
|
|
582
582
|
const signedSessionId = yield ((_a = this.getSignedSessionId) === null || _a === void 0 ? void 0 : _a.call(this));
|
|
583
583
|
if (!signedSessionId) {
|
|
584
|
-
throw new DynamicError('Signed session ID is required');
|
|
584
|
+
throw new DynamicError('Signed session ID is required', 'signed_session_id_is_required');
|
|
585
585
|
}
|
|
586
586
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
587
587
|
mfaAction: MFAAction.WalletWaasSign,
|
|
@@ -174,7 +174,7 @@ class MagicEdenConnector extends BitcoinSatsConnectConnector.BitcoinSatsConnectC
|
|
|
174
174
|
// to ensure we use it rather than the general Sats Connect API for this method
|
|
175
175
|
const provider = this.getProvider();
|
|
176
176
|
if (!provider)
|
|
177
|
-
throw new utils.DynamicError('signTransactions failed: Magic Eden provider not found');
|
|
177
|
+
throw new utils.DynamicError('signTransactions failed: Magic Eden provider not found', 'signtransactions_failed_magic_eden_provider_not');
|
|
178
178
|
return provider.signMultipleTransactions(request);
|
|
179
179
|
});
|
|
180
180
|
}
|
|
@@ -170,7 +170,7 @@ class MagicEdenConnector extends BitcoinSatsConnectConnector {
|
|
|
170
170
|
// to ensure we use it rather than the general Sats Connect API for this method
|
|
171
171
|
const provider = this.getProvider();
|
|
172
172
|
if (!provider)
|
|
173
|
-
throw new DynamicError('signTransactions failed: Magic Eden provider not found');
|
|
173
|
+
throw new DynamicError('signTransactions failed: Magic Eden provider not found', 'signtransactions_failed_magic_eden_provider_not');
|
|
174
174
|
return provider.signMultipleTransactions(request);
|
|
175
175
|
});
|
|
176
176
|
}
|
|
@@ -42,13 +42,13 @@ class MempoolApiService {
|
|
|
42
42
|
const baseUrl = this.getBaseUrl(address);
|
|
43
43
|
const response = yield fetch(`${baseUrl}/address/${address}/utxo`);
|
|
44
44
|
if (!response.ok) {
|
|
45
|
-
throw new utils.DynamicError(`Failed to fetch UTXOs: ${response.statusText}
|
|
45
|
+
throw new utils.DynamicError(`Failed to fetch UTXOs: ${response.statusText}`, 'fetch_utxos_failed');
|
|
46
46
|
}
|
|
47
47
|
return response.json();
|
|
48
48
|
}
|
|
49
49
|
catch (error) {
|
|
50
50
|
logger.error('Error fetching UTXOs:', error);
|
|
51
|
-
throw new utils.DynamicError('Failed to fetch UTXOs');
|
|
51
|
+
throw new utils.DynamicError('Failed to fetch UTXOs', 'fetch_utxos_failed');
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
}
|
|
@@ -127,7 +127,7 @@ class MempoolApiService {
|
|
|
127
127
|
sendRawTransaction(address, rawTransaction) {
|
|
128
128
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
129
129
|
if (!rawTransaction) {
|
|
130
|
-
throw new utils.DynamicError('No transaction specified!');
|
|
130
|
+
throw new utils.DynamicError('No transaction specified!', 'no_transaction_specified');
|
|
131
131
|
}
|
|
132
132
|
const baseUrl = this.getBaseUrl(address);
|
|
133
133
|
const response = yield fetch(`${baseUrl}/tx`, {
|
|
@@ -140,7 +140,7 @@ class MempoolApiService {
|
|
|
140
140
|
if (!response.ok) {
|
|
141
141
|
const error = yield response.text();
|
|
142
142
|
logger.debug(`sendRawTransaction - response not ok: ${JSON.stringify(error)}`);
|
|
143
|
-
throw new utils.DynamicError('sendRawTransaction - failed to send transaction');
|
|
143
|
+
throw new utils.DynamicError('sendRawTransaction - failed to send transaction', 'sendrawtransaction_failed_to_send_transaction');
|
|
144
144
|
}
|
|
145
145
|
return response.text();
|
|
146
146
|
});
|
|
@@ -38,13 +38,13 @@ class MempoolApiService {
|
|
|
38
38
|
const baseUrl = this.getBaseUrl(address);
|
|
39
39
|
const response = yield fetch(`${baseUrl}/address/${address}/utxo`);
|
|
40
40
|
if (!response.ok) {
|
|
41
|
-
throw new DynamicError(`Failed to fetch UTXOs: ${response.statusText}
|
|
41
|
+
throw new DynamicError(`Failed to fetch UTXOs: ${response.statusText}`, 'fetch_utxos_failed');
|
|
42
42
|
}
|
|
43
43
|
return response.json();
|
|
44
44
|
}
|
|
45
45
|
catch (error) {
|
|
46
46
|
logger.error('Error fetching UTXOs:', error);
|
|
47
|
-
throw new DynamicError('Failed to fetch UTXOs');
|
|
47
|
+
throw new DynamicError('Failed to fetch UTXOs', 'fetch_utxos_failed');
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
}
|
|
@@ -123,7 +123,7 @@ class MempoolApiService {
|
|
|
123
123
|
sendRawTransaction(address, rawTransaction) {
|
|
124
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
125
125
|
if (!rawTransaction) {
|
|
126
|
-
throw new DynamicError('No transaction specified!');
|
|
126
|
+
throw new DynamicError('No transaction specified!', 'no_transaction_specified');
|
|
127
127
|
}
|
|
128
128
|
const baseUrl = this.getBaseUrl(address);
|
|
129
129
|
const response = yield fetch(`${baseUrl}/tx`, {
|
|
@@ -136,7 +136,7 @@ class MempoolApiService {
|
|
|
136
136
|
if (!response.ok) {
|
|
137
137
|
const error = yield response.text();
|
|
138
138
|
logger.debug(`sendRawTransaction - response not ok: ${JSON.stringify(error)}`);
|
|
139
|
-
throw new DynamicError('sendRawTransaction - failed to send transaction');
|
|
139
|
+
throw new DynamicError('sendRawTransaction - failed to send transaction', 'sendrawtransaction_failed_to_send_transaction');
|
|
140
140
|
}
|
|
141
141
|
return response.text();
|
|
142
142
|
});
|
|
@@ -36,7 +36,7 @@ class PsbtBuilderService {
|
|
|
36
36
|
if (accountAddress.toLowerCase().startsWith('bc1p') ||
|
|
37
37
|
accountAddress.toLowerCase().startsWith('tb1p')) {
|
|
38
38
|
logger.warn(`Account address ${accountAddress} appears to be Taproot. Only Native SegWit (P2WPKH) is supported.`);
|
|
39
|
-
throw new utils.DynamicError('Taproot addresses are not supported. Only Native SegWit (P2WPKH) addresses are allowed.');
|
|
39
|
+
throw new utils.DynamicError('Taproot addresses are not supported. Only Native SegWit (P2WPKH) addresses are allowed.', 'taproot_addresses_are_not_supported_only');
|
|
40
40
|
}
|
|
41
41
|
return utxos;
|
|
42
42
|
}
|
|
@@ -90,11 +90,11 @@ class PsbtBuilderService {
|
|
|
90
90
|
if (selectedUTXOs.length < allUTXOs.length) {
|
|
91
91
|
const allTotal = this.calculateUTXOTotal(allUTXOs);
|
|
92
92
|
if (allTotal < requiredAmount) {
|
|
93
|
-
throw new utils.DynamicError(`Insufficient funds. Available: ${allTotal / _const.SATOSHIS_PER_BTC} BTC (${allTotal} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees
|
|
93
|
+
throw new utils.DynamicError(`Insufficient funds. Available: ${allTotal / _const.SATOSHIS_PER_BTC} BTC (${allTotal} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees`, 'insufficient_funds_available_btc_satoshis_required');
|
|
94
94
|
}
|
|
95
95
|
return allUTXOs;
|
|
96
96
|
}
|
|
97
|
-
throw new utils.DynamicError(`Insufficient funds. Available: ${selectedTotal / _const.SATOSHIS_PER_BTC} BTC (${selectedTotal} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees
|
|
97
|
+
throw new utils.DynamicError(`Insufficient funds. Available: ${selectedTotal / _const.SATOSHIS_PER_BTC} BTC (${selectedTotal} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees`, 'insufficient_funds_available_btc_satoshis_required');
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Calculates fee estimate and change amount, handling dust limit
|
|
@@ -148,7 +148,7 @@ class PsbtBuilderService {
|
|
|
148
148
|
pubkey: publicKeyPair.publicKey,
|
|
149
149
|
}).output;
|
|
150
150
|
if (!outputScript) {
|
|
151
|
-
throw new utils.DynamicError('Failed to create segwit output script');
|
|
151
|
+
throw new utils.DynamicError('Failed to create segwit output script', 'create_segwit_output_script');
|
|
152
152
|
}
|
|
153
153
|
// Convert txid from hex string to Buffer and reverse it (Bitcoin uses little-endian)
|
|
154
154
|
// The txid from the API is in big-endian format, but bitcoinjs-lib expects little-endian
|
|
@@ -176,7 +176,7 @@ class PsbtBuilderService {
|
|
|
176
176
|
*/
|
|
177
177
|
addOutputsToPsbt(psbt, recipientAddress, accountAddress, amountInSatoshisNumber, changeAmountNumber, hasChangeOutput, network) {
|
|
178
178
|
if (amountInSatoshisNumber < _const.DUST_LIMIT) {
|
|
179
|
-
throw new utils.DynamicError(`Amount is below dust limit of ${_const.DUST_LIMIT} satoshis (${_const.DUST_LIMIT / _const.SATOSHIS_PER_BTC} BTC)
|
|
179
|
+
throw new utils.DynamicError(`Amount is below dust limit of ${_const.DUST_LIMIT} satoshis (${_const.DUST_LIMIT / _const.SATOSHIS_PER_BTC} BTC)`, 'amount_is_below_dust_limit_of');
|
|
180
180
|
}
|
|
181
181
|
psbt.addOutput({
|
|
182
182
|
script: bitcoinjsLib.address.toOutputScript(recipientAddress, network),
|
|
@@ -201,11 +201,11 @@ class PsbtBuilderService {
|
|
|
201
201
|
const { accountAddress, recipientAddress, amountInSatoshis, publicKeyHex, network, feePriority = 'medium', } = options;
|
|
202
202
|
logger.debug(`buildPsbt called with feePriority: ${feePriority}, amount: ${amountInSatoshis} satoshis`);
|
|
203
203
|
if (amountInSatoshis <= BigInt(0)) {
|
|
204
|
-
throw new utils.DynamicError('Amount must be greater than 0');
|
|
204
|
+
throw new utils.DynamicError('Amount must be greater than 0', 'amount_must_be_greater_than_0');
|
|
205
205
|
}
|
|
206
206
|
const allUTXOs = yield this.mempoolApiService.getUTXOs(accountAddress);
|
|
207
207
|
if (allUTXOs.length === 0) {
|
|
208
|
-
throw new utils.DynamicError('No UTXOs found for this address');
|
|
208
|
+
throw new utils.DynamicError('No UTXOs found for this address', 'no_utxos_found_for_this_address');
|
|
209
209
|
}
|
|
210
210
|
const utxos = this.filterTaprootUTXOs(accountAddress, allUTXOs);
|
|
211
211
|
const publicKeyBuffer = Buffer.from(publicKeyHex, 'hex');
|
|
@@ -229,7 +229,7 @@ class PsbtBuilderService {
|
|
|
229
229
|
// Final check: ensure we have enough after final fee calculation
|
|
230
230
|
const maxToSpend = selectedTotalValue - feeEstimate;
|
|
231
231
|
if (maxToSpend < amountInSatoshisNumber) {
|
|
232
|
-
throw new utils.DynamicError(`Insufficient funds. Available: ${maxToSpend / _const.SATOSHIS_PER_BTC} BTC (${maxToSpend} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis)
|
|
232
|
+
throw new utils.DynamicError(`Insufficient funds. Available: ${maxToSpend / _const.SATOSHIS_PER_BTC} BTC (${maxToSpend} satoshis), Required: ${amountInSatoshisNumber / _const.SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis)`, 'insufficient_funds_available_btc_satoshis_required');
|
|
233
233
|
}
|
|
234
234
|
// Create PSBT and add inputs/outputs
|
|
235
235
|
const psbt = new bitcoinjsLib.Psbt({ network });
|
|
@@ -28,7 +28,7 @@ class PsbtBuilderService {
|
|
|
28
28
|
if (accountAddress.toLowerCase().startsWith('bc1p') ||
|
|
29
29
|
accountAddress.toLowerCase().startsWith('tb1p')) {
|
|
30
30
|
logger.warn(`Account address ${accountAddress} appears to be Taproot. Only Native SegWit (P2WPKH) is supported.`);
|
|
31
|
-
throw new DynamicError('Taproot addresses are not supported. Only Native SegWit (P2WPKH) addresses are allowed.');
|
|
31
|
+
throw new DynamicError('Taproot addresses are not supported. Only Native SegWit (P2WPKH) addresses are allowed.', 'taproot_addresses_are_not_supported_only');
|
|
32
32
|
}
|
|
33
33
|
return utxos;
|
|
34
34
|
}
|
|
@@ -82,11 +82,11 @@ class PsbtBuilderService {
|
|
|
82
82
|
if (selectedUTXOs.length < allUTXOs.length) {
|
|
83
83
|
const allTotal = this.calculateUTXOTotal(allUTXOs);
|
|
84
84
|
if (allTotal < requiredAmount) {
|
|
85
|
-
throw new DynamicError(`Insufficient funds. Available: ${allTotal / SATOSHIS_PER_BTC} BTC (${allTotal} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees
|
|
85
|
+
throw new DynamicError(`Insufficient funds. Available: ${allTotal / SATOSHIS_PER_BTC} BTC (${allTotal} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees`, 'insufficient_funds_available_btc_satoshis_required');
|
|
86
86
|
}
|
|
87
87
|
return allUTXOs;
|
|
88
88
|
}
|
|
89
|
-
throw new DynamicError(`Insufficient funds. Available: ${selectedTotal / SATOSHIS_PER_BTC} BTC (${selectedTotal} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees
|
|
89
|
+
throw new DynamicError(`Insufficient funds. Available: ${selectedTotal / SATOSHIS_PER_BTC} BTC (${selectedTotal} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis) + fees`, 'insufficient_funds_available_btc_satoshis_required');
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
92
|
* Calculates fee estimate and change amount, handling dust limit
|
|
@@ -140,7 +140,7 @@ class PsbtBuilderService {
|
|
|
140
140
|
pubkey: publicKeyPair.publicKey,
|
|
141
141
|
}).output;
|
|
142
142
|
if (!outputScript) {
|
|
143
|
-
throw new DynamicError('Failed to create segwit output script');
|
|
143
|
+
throw new DynamicError('Failed to create segwit output script', 'create_segwit_output_script');
|
|
144
144
|
}
|
|
145
145
|
// Convert txid from hex string to Buffer and reverse it (Bitcoin uses little-endian)
|
|
146
146
|
// The txid from the API is in big-endian format, but bitcoinjs-lib expects little-endian
|
|
@@ -168,7 +168,7 @@ class PsbtBuilderService {
|
|
|
168
168
|
*/
|
|
169
169
|
addOutputsToPsbt(psbt, recipientAddress, accountAddress, amountInSatoshisNumber, changeAmountNumber, hasChangeOutput, network) {
|
|
170
170
|
if (amountInSatoshisNumber < DUST_LIMIT) {
|
|
171
|
-
throw new DynamicError(`Amount is below dust limit of ${DUST_LIMIT} satoshis (${DUST_LIMIT / SATOSHIS_PER_BTC} BTC)
|
|
171
|
+
throw new DynamicError(`Amount is below dust limit of ${DUST_LIMIT} satoshis (${DUST_LIMIT / SATOSHIS_PER_BTC} BTC)`, 'amount_is_below_dust_limit_of');
|
|
172
172
|
}
|
|
173
173
|
psbt.addOutput({
|
|
174
174
|
script: address.toOutputScript(recipientAddress, network),
|
|
@@ -193,11 +193,11 @@ class PsbtBuilderService {
|
|
|
193
193
|
const { accountAddress, recipientAddress, amountInSatoshis, publicKeyHex, network, feePriority = 'medium', } = options;
|
|
194
194
|
logger.debug(`buildPsbt called with feePriority: ${feePriority}, amount: ${amountInSatoshis} satoshis`);
|
|
195
195
|
if (amountInSatoshis <= BigInt(0)) {
|
|
196
|
-
throw new DynamicError('Amount must be greater than 0');
|
|
196
|
+
throw new DynamicError('Amount must be greater than 0', 'amount_must_be_greater_than_0');
|
|
197
197
|
}
|
|
198
198
|
const allUTXOs = yield this.mempoolApiService.getUTXOs(accountAddress);
|
|
199
199
|
if (allUTXOs.length === 0) {
|
|
200
|
-
throw new DynamicError('No UTXOs found for this address');
|
|
200
|
+
throw new DynamicError('No UTXOs found for this address', 'no_utxos_found_for_this_address');
|
|
201
201
|
}
|
|
202
202
|
const utxos = this.filterTaprootUTXOs(accountAddress, allUTXOs);
|
|
203
203
|
const publicKeyBuffer = Buffer.from(publicKeyHex, 'hex');
|
|
@@ -221,7 +221,7 @@ class PsbtBuilderService {
|
|
|
221
221
|
// Final check: ensure we have enough after final fee calculation
|
|
222
222
|
const maxToSpend = selectedTotalValue - feeEstimate;
|
|
223
223
|
if (maxToSpend < amountInSatoshisNumber) {
|
|
224
|
-
throw new DynamicError(`Insufficient funds. Available: ${maxToSpend / SATOSHIS_PER_BTC} BTC (${maxToSpend} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis)
|
|
224
|
+
throw new DynamicError(`Insufficient funds. Available: ${maxToSpend / SATOSHIS_PER_BTC} BTC (${maxToSpend} satoshis), Required: ${amountInSatoshisNumber / SATOSHIS_PER_BTC} BTC (${amountInSatoshisNumber} satoshis)`, 'insufficient_funds_available_btc_satoshis_required');
|
|
225
225
|
}
|
|
226
226
|
// Create PSBT and add inputs/outputs
|
|
227
227
|
const psbt = new Psbt({ network });
|
|
@@ -14,7 +14,7 @@ var _const = require('../../const.cjs');
|
|
|
14
14
|
*/
|
|
15
15
|
const btcToSatoshis = (btcAmount) => {
|
|
16
16
|
if (btcAmount < 0) {
|
|
17
|
-
throw new utils.DynamicError('BTC amount cannot be negative');
|
|
17
|
+
throw new utils.DynamicError('BTC amount cannot be negative', 'btc_amount_cannot_be_negative');
|
|
18
18
|
}
|
|
19
19
|
// Convert to satoshis and return as BigInt
|
|
20
20
|
const satoshis = Math.floor(btcAmount * _const.SATOSHIS_PER_BTC);
|
|
@@ -10,7 +10,7 @@ import { SATOSHIS_PER_BTC } from '../../const.js';
|
|
|
10
10
|
*/
|
|
11
11
|
const btcToSatoshis = (btcAmount) => {
|
|
12
12
|
if (btcAmount < 0) {
|
|
13
|
-
throw new DynamicError('BTC amount cannot be negative');
|
|
13
|
+
throw new DynamicError('BTC amount cannot be negative', 'btc_amount_cannot_be_negative');
|
|
14
14
|
}
|
|
15
15
|
// Convert to satoshis and return as BigInt
|
|
16
16
|
const satoshis = Math.floor(btcAmount * SATOSHIS_PER_BTC);
|
|
@@ -11,9 +11,9 @@ const validateAddress = (psbt, signingAddress, index, inputAtIndex) => {
|
|
|
11
11
|
// to be able to compare it to the address provided in the request for the current index
|
|
12
12
|
const extractedAddress = extractAddressFromInput.extractAddressFromInput(psbt, index, inputAtIndex);
|
|
13
13
|
if (!extractedAddress)
|
|
14
|
-
throw new utils.DynamicError(`validateAddress - input not found for the given address: ${signingAddress}
|
|
14
|
+
throw new utils.DynamicError(`validateAddress - input not found for the given address: ${signingAddress}`, 'validateaddress_input_not_found_for_the');
|
|
15
15
|
if (extractedAddress !== signingAddress)
|
|
16
|
-
throw new utils.DynamicError('validateAddress - address mismatch with index');
|
|
16
|
+
throw new utils.DynamicError('validateAddress - address mismatch with index', 'validateaddress_address_mismatch_with_index');
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
exports.validateAddress = validateAddress;
|
|
@@ -7,9 +7,9 @@ const validateAddress = (psbt, signingAddress, index, inputAtIndex) => {
|
|
|
7
7
|
// to be able to compare it to the address provided in the request for the current index
|
|
8
8
|
const extractedAddress = extractAddressFromInput(psbt, index, inputAtIndex);
|
|
9
9
|
if (!extractedAddress)
|
|
10
|
-
throw new DynamicError(`validateAddress - input not found for the given address: ${signingAddress}
|
|
10
|
+
throw new DynamicError(`validateAddress - input not found for the given address: ${signingAddress}`, 'validateaddress_input_not_found_for_the');
|
|
11
11
|
if (extractedAddress !== signingAddress)
|
|
12
|
-
throw new DynamicError('validateAddress - address mismatch with index');
|
|
12
|
+
throw new DynamicError('validateAddress - address mismatch with index', 'validateaddress_address_mismatch_with_index');
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export { validateAddress };
|