@dynamic-labs/bitcoin 4.93.1 → 4.95.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 +28 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +9 -9
- package/src/connectors/BitcoinWalletConnector.d.ts +1 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +84 -12
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +17 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +84 -12
- package/src/index.cjs +1 -0
- package/src/index.d.ts +1 -1
- package/src/index.js +1 -1
- package/src/services/MempoolApiService.cjs +4 -1
- package/src/services/MempoolApiService.js +4 -1
- package/src/wallet/BitcoinWallet.cjs +15 -0
- package/src/wallet/BitcoinWallet.d.ts +7 -0
- package/src/wallet/BitcoinWallet.js +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.95.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.94.0...v4.95.0) (2026-07-28)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **waas:** expose rawSign sha256/blake2b in SignMessageContext [v4] ([#12076](https://github.com/dynamic-labs/dynamic-auth/issues/12076)) ([5133a71](https://github.com/dynamic-labs/dynamic-auth/commit/5133a713ba5aea0cb19935d99f0795ebbe303d2e))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **bitcoin:** resolve the public key of the active wallet, not the first [v4] ([#12090](https://github.com/dynamic-labs/dynamic-auth/issues/12090)) ([a93b55b](https://github.com/dynamic-labs/dynamic-auth/commit/a93b55b882ec3a7ac2adb37e4f653cb935d16193)), closes [#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970) [#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970) [#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970)
|
|
13
|
+
* **client:** ack sdk__loadedChanged in the webview load controller ([#12084](https://github.com/dynamic-labs/dynamic-auth/issues/12084)) ([8688c7d](https://github.com/dynamic-labs/dynamic-auth/commit/8688c7d1cfc320c3ca20913c730326c6f36266e0)), closes [#12071](https://github.com/dynamic-labs/dynamic-auth/issues/12071)
|
|
14
|
+
* fallback to local wallet balance when token balances API returns no tokens ([9ff87c3](https://github.com/dynamic-labs/dynamic-auth/commit/9ff87c3d1836e72a5a1e635ef7bd53464501fc1a))
|
|
15
|
+
* remediate high-severity dependency vulnerabilities ([#12077](https://github.com/dynamic-labs/dynamic-auth/issues/12077)) ([81e2d91](https://github.com/dynamic-labs/dynamic-auth/commit/81e2d91e16edaba1b6251bfa9b9f9c91d09aab80))
|
|
16
|
+
* remediate high-severity dependency vulnerabilities ([#12087](https://github.com/dynamic-labs/dynamic-auth/issues/12087)) ([9250ede](https://github.com/dynamic-labs/dynamic-auth/commit/9250edede5eaa0d0de8faa7d7aad1d164e1c78f7))
|
|
17
|
+
|
|
18
|
+
## [4.94.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.93.1...v4.94.0) (2026-07-24)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* **bitcoin:** add sendBitcoinWithConfirmation to show confirm modal on BTC sends ([#12023](https://github.com/dynamic-labs/dynamic-auth/issues/12023)) ([22a8b14](https://github.com/dynamic-labs/dynamic-auth/commit/22a8b14286b5612f37591ddba5507dd8f3c87cd3))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* replace deprecated polygon-rpc.com RPC with polygon.drpc.org (v4) ([#12033](https://github.com/dynamic-labs/dynamic-auth/issues/12033)) ([d64623d](https://github.com/dynamic-labs/dynamic-auth/commit/d64623d89f63084eb0b040f4466f057b833b9293))
|
|
29
|
+
|
|
2
30
|
### [4.93.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.93.0...v4.93.1) (2026-07-22)
|
|
3
31
|
|
|
4
32
|
|
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.
|
|
3
|
+
"version": "4.95.0",
|
|
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",
|
|
@@ -22,20 +22,20 @@
|
|
|
22
22
|
"@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
|
|
23
23
|
"@bitcoinerlab/secp256k1": "1.1.1",
|
|
24
24
|
"@btckit/types": "0.0.19",
|
|
25
|
-
"@dynamic-labs/sdk-api-core": "0.0.
|
|
25
|
+
"@dynamic-labs/sdk-api-core": "0.0.1093",
|
|
26
26
|
"@wallet-standard/app": "1.0.1",
|
|
27
27
|
"@wallet-standard/base": "1.0.1",
|
|
28
28
|
"bitcoinjs-lib": "6.1.5",
|
|
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.
|
|
33
|
-
"@dynamic-labs/logger": "4.
|
|
34
|
-
"@dynamic-labs/types": "4.
|
|
35
|
-
"@dynamic-labs/utils": "4.
|
|
36
|
-
"@dynamic-labs/waas": "4.
|
|
37
|
-
"@dynamic-labs/wallet-book": "4.
|
|
38
|
-
"@dynamic-labs/wallet-connector-core": "4.
|
|
32
|
+
"@dynamic-labs/assert-package-version": "4.95.0",
|
|
33
|
+
"@dynamic-labs/logger": "4.95.0",
|
|
34
|
+
"@dynamic-labs/types": "4.95.0",
|
|
35
|
+
"@dynamic-labs/utils": "4.95.0",
|
|
36
|
+
"@dynamic-labs/waas": "4.95.0",
|
|
37
|
+
"@dynamic-labs/wallet-book": "4.95.0",
|
|
38
|
+
"@dynamic-labs/wallet-connector-core": "4.95.0",
|
|
39
39
|
"eventemitter3": "5.0.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {}
|
|
@@ -41,6 +41,7 @@ export declare abstract class BitcoinWalletConnector extends WalletConnectorBase
|
|
|
41
41
|
setAdditionalAddresses(mainAddress: string, additionalAddresses: WalletAdditionalAddress[]): Promise<void>;
|
|
42
42
|
sendRawTransaction(rawTransaction: string): Promise<string>;
|
|
43
43
|
sendBitcoin(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
44
|
+
sendBitcoinWithConfirmation?(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
44
45
|
buildPsbt(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
45
46
|
getProvider<T>(): T & EventEmitter<string | symbol, any>;
|
|
46
47
|
abstract signPsbt(request: BitcoinSignPsbtRequest | EmbeddedWalletSignPsbtRequest): Promise<BitcoinSignPsbtResponse | undefined>;
|
|
@@ -160,22 +160,57 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
160
160
|
return _super.getBalance.call(this, (_a = this.activeAccountAddress) !== null && _a !== void 0 ? _a : address);
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Finds the credential that owns the active address, either as its primary
|
|
165
|
+
* (mainnet) address or as one of its network-tagged additional addresses.
|
|
166
|
+
*
|
|
167
|
+
* This connector is shared across every Bitcoin wallet of the user —
|
|
168
|
+
* `verifiedCredentials` holds them all — so the owning credential must be
|
|
169
|
+
* looked up by the active address. Reading `verifiedCredential` instead
|
|
170
|
+
* would always answer with the user's *first* wallet.
|
|
171
|
+
*/
|
|
172
|
+
findCredentialForActiveAddress() {
|
|
173
|
+
var _a;
|
|
174
|
+
const { activeAccountAddress } = this;
|
|
175
|
+
if (!activeAccountAddress) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
return ((_a = this.verifiedCredentials) !== null && _a !== void 0 ? _a : []).find((credential) => {
|
|
179
|
+
var _a;
|
|
180
|
+
return (credential === null || credential === void 0 ? void 0 : credential.address) === activeAccountAddress ||
|
|
181
|
+
((_a = credential === null || credential === void 0 ? void 0 : credential.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []).some((additionalAddress) => additionalAddress.address === activeAccountAddress);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
163
184
|
/**
|
|
164
185
|
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
165
186
|
* primary (mainnet) address. On testnet the active address is the same
|
|
166
187
|
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
167
188
|
* the primary address (the same key signs both encodings).
|
|
189
|
+
*
|
|
190
|
+
* Resolved from the credential that owns the active address, so a user with
|
|
191
|
+
* several Bitcoin wallets gets the identity of the wallet being spent from.
|
|
192
|
+
* Never falls back to another wallet's address: a substituted key produces a
|
|
193
|
+
* signature that looks valid locally and is rejected by the network, so the
|
|
194
|
+
* failure has to surface here instead.
|
|
168
195
|
*/
|
|
169
196
|
getWalletIdentityAddress() {
|
|
170
|
-
var _a, _b;
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
|
|
197
|
+
var _a, _b, _c, _d;
|
|
198
|
+
const owningCredential = this.findCredentialForActiveAddress();
|
|
199
|
+
// The primary address is normally on the credential itself; fall back to
|
|
200
|
+
// its mainnet-tagged payment address for credentials that only carry
|
|
201
|
+
// network-tagged entries.
|
|
202
|
+
const owningCredentialAddress = (_a = owningCredential === null || owningCredential === void 0 ? void 0 : owningCredential.address) !== null && _a !== void 0 ? _a : (_c = ((_b = owningCredential === null || owningCredential === void 0 ? void 0 : owningCredential.walletAdditionalAddresses) !== null && _b !== void 0 ? _b : []).find((addr) => addr.type === 'payment' &&
|
|
203
|
+
addr.network === 'mainnet')) === null || _c === void 0 ? void 0 : _c.address;
|
|
204
|
+
// With no credential owning the active address there is nothing to
|
|
205
|
+
// identify the wallet by except the active address itself, which on
|
|
206
|
+
// mainnet is the primary encoding. That is still the *requested* wallet,
|
|
207
|
+
// so it is a safe answer — unlike `verifiedCredential`, which is always
|
|
208
|
+
// the user's first wallet and would substitute a different key.
|
|
209
|
+
const identity = owningCredentialAddress !== null && owningCredentialAddress !== void 0 ? owningCredentialAddress : (this.activeNetworkId === BITCOIN_MAINNET_NETWORK_ID
|
|
175
210
|
? this.activeAccountAddress
|
|
176
211
|
: undefined);
|
|
177
212
|
if (!identity) {
|
|
178
|
-
throw new utils.DynamicError(
|
|
213
|
+
throw new utils.DynamicError(`Could not resolve the wallet identity for active address ${(_d = this.activeAccountAddress) !== null && _d !== void 0 ? _d : '(unset)'}`, 'active_account_address_is_required');
|
|
179
214
|
}
|
|
180
215
|
return identity;
|
|
181
216
|
}
|
|
@@ -185,14 +220,18 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
185
220
|
* address (wallets created before per-network registration).
|
|
186
221
|
*/
|
|
187
222
|
getPaymentAddressForNetwork(network) {
|
|
188
|
-
var _a, _b
|
|
189
|
-
|
|
223
|
+
var _a, _b;
|
|
224
|
+
// Resolved against the wallet that is currently active. Reading
|
|
225
|
+
// `verifiedCredential` alone would switch the network on the user's first
|
|
226
|
+
// wallet, handing back an address that belongs to a different wallet.
|
|
227
|
+
const credential = (_a = this.findCredentialForActiveAddress()) !== null && _a !== void 0 ? _a : this.verifiedCredential;
|
|
228
|
+
const tagged = (_b = credential === null || credential === void 0 ? void 0 : credential.walletAdditionalAddresses) === null || _b === void 0 ? void 0 : _b.find((addr) => addr.type === 'payment' &&
|
|
190
229
|
addr.network === network);
|
|
191
230
|
if (tagged === null || tagged === void 0 ? void 0 : tagged.address) {
|
|
192
231
|
return tagged.address;
|
|
193
232
|
}
|
|
194
233
|
if (network === 'mainnet') {
|
|
195
|
-
return
|
|
234
|
+
return credential === null || credential === void 0 ? void 0 : credential.address;
|
|
196
235
|
}
|
|
197
236
|
return undefined;
|
|
198
237
|
}
|
|
@@ -353,6 +392,30 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
353
392
|
return this.sendRawTransaction(signedTransactionHex);
|
|
354
393
|
});
|
|
355
394
|
}
|
|
395
|
+
sendBitcoinWithConfirmation(transaction) {
|
|
396
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
397
|
+
if (!this.activeAccountAddress) {
|
|
398
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
399
|
+
}
|
|
400
|
+
const uiTransaction = new BitcoinUiTransaction.BitcoinUiTransaction({
|
|
401
|
+
from: this.activeAccountAddress,
|
|
402
|
+
mempoolApiService: this.mempoolApiService,
|
|
403
|
+
onSubmit: (tx) => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
404
|
+
const txHash = yield this.sendBitcoin(tx);
|
|
405
|
+
if (!txHash) {
|
|
406
|
+
throw new utils.DynamicError('Failed to send Bitcoin transaction', 'send_bitcoin_transaction');
|
|
407
|
+
}
|
|
408
|
+
return txHash;
|
|
409
|
+
}),
|
|
410
|
+
});
|
|
411
|
+
uiTransaction.to = transaction.recipientAddress;
|
|
412
|
+
uiTransaction.value = transaction.amount;
|
|
413
|
+
if (transaction.feePriority) {
|
|
414
|
+
uiTransaction.feePriority = transaction.feePriority;
|
|
415
|
+
}
|
|
416
|
+
return this.walletUiUtils.sendTransaction(this, uiTransaction);
|
|
417
|
+
});
|
|
418
|
+
}
|
|
356
419
|
/**
|
|
357
420
|
* Creates a new Bitcoin wallet account with Bitcoin-specific defaults.
|
|
358
421
|
* If `bitcoinConfig.addressType` is not provided, the underlying BTC client
|
|
@@ -643,7 +706,16 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
643
706
|
// signs both. Look it up by the wallet identity address rather than the
|
|
644
707
|
// active address, which after a network switch is the testnet encoding.
|
|
645
708
|
const walletIdentityAddress = this.getWalletIdentityAddress();
|
|
646
|
-
|
|
709
|
+
// Scoped to the credential that owns the active address when there is one.
|
|
710
|
+
// Searching every credential would let another wallet of the same user
|
|
711
|
+
// answer for this one, and that is the failure this must not produce: the
|
|
712
|
+
// PSBT then carries a witness script derived from the wrong key and is
|
|
713
|
+
// rejected by the network only after broadcast.
|
|
714
|
+
const owningCredential = this.findCredentialForActiveAddress();
|
|
715
|
+
const credentialsToSearch = owningCredential
|
|
716
|
+
? [owningCredential]
|
|
717
|
+
: allCredentials;
|
|
718
|
+
for (const credential of credentialsToSearch) {
|
|
647
719
|
const { walletAdditionalAddresses } = credential !== null && credential !== void 0 ? credential : {};
|
|
648
720
|
if (!walletAdditionalAddresses) {
|
|
649
721
|
continue;
|
|
@@ -653,8 +725,8 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
653
725
|
return additionalAddress.publicKey;
|
|
654
726
|
}
|
|
655
727
|
}
|
|
656
|
-
const allAvailableAddresses =
|
|
657
|
-
.flatMap((cred) => { var _a; return (_a = cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
728
|
+
const allAvailableAddresses = credentialsToSearch
|
|
729
|
+
.flatMap((cred) => { var _a; return (_a = cred === null || cred === void 0 ? void 0 : cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
658
730
|
.map((addr) => addr.address)
|
|
659
731
|
.join(', ');
|
|
660
732
|
throw new utils.DynamicError(`No additional address found for ${walletIdentityAddress}. Available addresses: ${allAvailableAddresses || 'none'}`, 'no_additional_address_found_for_available');
|
|
@@ -279,11 +279,27 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
279
279
|
* routing is address-driven).
|
|
280
280
|
*/
|
|
281
281
|
getBalance(address: string): Promise<string | undefined>;
|
|
282
|
+
/**
|
|
283
|
+
* Finds the credential that owns the active address, either as its primary
|
|
284
|
+
* (mainnet) address or as one of its network-tagged additional addresses.
|
|
285
|
+
*
|
|
286
|
+
* This connector is shared across every Bitcoin wallet of the user —
|
|
287
|
+
* `verifiedCredentials` holds them all — so the owning credential must be
|
|
288
|
+
* looked up by the active address. Reading `verifiedCredential` instead
|
|
289
|
+
* would always answer with the user's *first* wallet.
|
|
290
|
+
*/
|
|
291
|
+
private findCredentialForActiveAddress;
|
|
282
292
|
/**
|
|
283
293
|
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
284
294
|
* primary (mainnet) address. On testnet the active address is the same
|
|
285
295
|
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
286
296
|
* the primary address (the same key signs both encodings).
|
|
297
|
+
*
|
|
298
|
+
* Resolved from the credential that owns the active address, so a user with
|
|
299
|
+
* several Bitcoin wallets gets the identity of the wallet being spent from.
|
|
300
|
+
* Never falls back to another wallet's address: a substituted key produces a
|
|
301
|
+
* signature that looks valid locally and is rejected by the network, so the
|
|
302
|
+
* failure has to surface here instead.
|
|
287
303
|
*/
|
|
288
304
|
private getWalletIdentityAddress;
|
|
289
305
|
/**
|
|
@@ -346,6 +362,7 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
346
362
|
* @throws {DynamicError} If any step in the process fails
|
|
347
363
|
*/
|
|
348
364
|
sendBitcoin(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
365
|
+
sendBitcoinWithConfirmation(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
349
366
|
/**
|
|
350
367
|
* Creates a new Bitcoin wallet account with Bitcoin-specific defaults.
|
|
351
368
|
* If `bitcoinConfig.addressType` is not provided, the underlying BTC client
|
|
@@ -156,22 +156,57 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
156
156
|
return _super.getBalance.call(this, (_a = this.activeAccountAddress) !== null && _a !== void 0 ? _a : address);
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Finds the credential that owns the active address, either as its primary
|
|
161
|
+
* (mainnet) address or as one of its network-tagged additional addresses.
|
|
162
|
+
*
|
|
163
|
+
* This connector is shared across every Bitcoin wallet of the user —
|
|
164
|
+
* `verifiedCredentials` holds them all — so the owning credential must be
|
|
165
|
+
* looked up by the active address. Reading `verifiedCredential` instead
|
|
166
|
+
* would always answer with the user's *first* wallet.
|
|
167
|
+
*/
|
|
168
|
+
findCredentialForActiveAddress() {
|
|
169
|
+
var _a;
|
|
170
|
+
const { activeAccountAddress } = this;
|
|
171
|
+
if (!activeAccountAddress) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
return ((_a = this.verifiedCredentials) !== null && _a !== void 0 ? _a : []).find((credential) => {
|
|
175
|
+
var _a;
|
|
176
|
+
return (credential === null || credential === void 0 ? void 0 : credential.address) === activeAccountAddress ||
|
|
177
|
+
((_a = credential === null || credential === void 0 ? void 0 : credential.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []).some((additionalAddress) => additionalAddress.address === activeAccountAddress);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
159
180
|
/**
|
|
160
181
|
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
161
182
|
* primary (mainnet) address. On testnet the active address is the same
|
|
162
183
|
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
163
184
|
* the primary address (the same key signs both encodings).
|
|
185
|
+
*
|
|
186
|
+
* Resolved from the credential that owns the active address, so a user with
|
|
187
|
+
* several Bitcoin wallets gets the identity of the wallet being spent from.
|
|
188
|
+
* Never falls back to another wallet's address: a substituted key produces a
|
|
189
|
+
* signature that looks valid locally and is rejected by the network, so the
|
|
190
|
+
* failure has to surface here instead.
|
|
164
191
|
*/
|
|
165
192
|
getWalletIdentityAddress() {
|
|
166
|
-
var _a, _b;
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
|
|
193
|
+
var _a, _b, _c, _d;
|
|
194
|
+
const owningCredential = this.findCredentialForActiveAddress();
|
|
195
|
+
// The primary address is normally on the credential itself; fall back to
|
|
196
|
+
// its mainnet-tagged payment address for credentials that only carry
|
|
197
|
+
// network-tagged entries.
|
|
198
|
+
const owningCredentialAddress = (_a = owningCredential === null || owningCredential === void 0 ? void 0 : owningCredential.address) !== null && _a !== void 0 ? _a : (_c = ((_b = owningCredential === null || owningCredential === void 0 ? void 0 : owningCredential.walletAdditionalAddresses) !== null && _b !== void 0 ? _b : []).find((addr) => addr.type === 'payment' &&
|
|
199
|
+
addr.network === 'mainnet')) === null || _c === void 0 ? void 0 : _c.address;
|
|
200
|
+
// With no credential owning the active address there is nothing to
|
|
201
|
+
// identify the wallet by except the active address itself, which on
|
|
202
|
+
// mainnet is the primary encoding. That is still the *requested* wallet,
|
|
203
|
+
// so it is a safe answer — unlike `verifiedCredential`, which is always
|
|
204
|
+
// the user's first wallet and would substitute a different key.
|
|
205
|
+
const identity = owningCredentialAddress !== null && owningCredentialAddress !== void 0 ? owningCredentialAddress : (this.activeNetworkId === BITCOIN_MAINNET_NETWORK_ID
|
|
171
206
|
? this.activeAccountAddress
|
|
172
207
|
: undefined);
|
|
173
208
|
if (!identity) {
|
|
174
|
-
throw new DynamicError(
|
|
209
|
+
throw new DynamicError(`Could not resolve the wallet identity for active address ${(_d = this.activeAccountAddress) !== null && _d !== void 0 ? _d : '(unset)'}`, 'active_account_address_is_required');
|
|
175
210
|
}
|
|
176
211
|
return identity;
|
|
177
212
|
}
|
|
@@ -181,14 +216,18 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
181
216
|
* address (wallets created before per-network registration).
|
|
182
217
|
*/
|
|
183
218
|
getPaymentAddressForNetwork(network) {
|
|
184
|
-
var _a, _b
|
|
185
|
-
|
|
219
|
+
var _a, _b;
|
|
220
|
+
// Resolved against the wallet that is currently active. Reading
|
|
221
|
+
// `verifiedCredential` alone would switch the network on the user's first
|
|
222
|
+
// wallet, handing back an address that belongs to a different wallet.
|
|
223
|
+
const credential = (_a = this.findCredentialForActiveAddress()) !== null && _a !== void 0 ? _a : this.verifiedCredential;
|
|
224
|
+
const tagged = (_b = credential === null || credential === void 0 ? void 0 : credential.walletAdditionalAddresses) === null || _b === void 0 ? void 0 : _b.find((addr) => addr.type === 'payment' &&
|
|
186
225
|
addr.network === network);
|
|
187
226
|
if (tagged === null || tagged === void 0 ? void 0 : tagged.address) {
|
|
188
227
|
return tagged.address;
|
|
189
228
|
}
|
|
190
229
|
if (network === 'mainnet') {
|
|
191
|
-
return
|
|
230
|
+
return credential === null || credential === void 0 ? void 0 : credential.address;
|
|
192
231
|
}
|
|
193
232
|
return undefined;
|
|
194
233
|
}
|
|
@@ -349,6 +388,30 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
349
388
|
return this.sendRawTransaction(signedTransactionHex);
|
|
350
389
|
});
|
|
351
390
|
}
|
|
391
|
+
sendBitcoinWithConfirmation(transaction) {
|
|
392
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
393
|
+
if (!this.activeAccountAddress) {
|
|
394
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
395
|
+
}
|
|
396
|
+
const uiTransaction = new BitcoinUiTransaction({
|
|
397
|
+
from: this.activeAccountAddress,
|
|
398
|
+
mempoolApiService: this.mempoolApiService,
|
|
399
|
+
onSubmit: (tx) => __awaiter(this, void 0, void 0, function* () {
|
|
400
|
+
const txHash = yield this.sendBitcoin(tx);
|
|
401
|
+
if (!txHash) {
|
|
402
|
+
throw new DynamicError('Failed to send Bitcoin transaction', 'send_bitcoin_transaction');
|
|
403
|
+
}
|
|
404
|
+
return txHash;
|
|
405
|
+
}),
|
|
406
|
+
});
|
|
407
|
+
uiTransaction.to = transaction.recipientAddress;
|
|
408
|
+
uiTransaction.value = transaction.amount;
|
|
409
|
+
if (transaction.feePriority) {
|
|
410
|
+
uiTransaction.feePriority = transaction.feePriority;
|
|
411
|
+
}
|
|
412
|
+
return this.walletUiUtils.sendTransaction(this, uiTransaction);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
352
415
|
/**
|
|
353
416
|
* Creates a new Bitcoin wallet account with Bitcoin-specific defaults.
|
|
354
417
|
* If `bitcoinConfig.addressType` is not provided, the underlying BTC client
|
|
@@ -639,7 +702,16 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
639
702
|
// signs both. Look it up by the wallet identity address rather than the
|
|
640
703
|
// active address, which after a network switch is the testnet encoding.
|
|
641
704
|
const walletIdentityAddress = this.getWalletIdentityAddress();
|
|
642
|
-
|
|
705
|
+
// Scoped to the credential that owns the active address when there is one.
|
|
706
|
+
// Searching every credential would let another wallet of the same user
|
|
707
|
+
// answer for this one, and that is the failure this must not produce: the
|
|
708
|
+
// PSBT then carries a witness script derived from the wrong key and is
|
|
709
|
+
// rejected by the network only after broadcast.
|
|
710
|
+
const owningCredential = this.findCredentialForActiveAddress();
|
|
711
|
+
const credentialsToSearch = owningCredential
|
|
712
|
+
? [owningCredential]
|
|
713
|
+
: allCredentials;
|
|
714
|
+
for (const credential of credentialsToSearch) {
|
|
643
715
|
const { walletAdditionalAddresses } = credential !== null && credential !== void 0 ? credential : {};
|
|
644
716
|
if (!walletAdditionalAddresses) {
|
|
645
717
|
continue;
|
|
@@ -649,8 +721,8 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
649
721
|
return additionalAddress.publicKey;
|
|
650
722
|
}
|
|
651
723
|
}
|
|
652
|
-
const allAvailableAddresses =
|
|
653
|
-
.flatMap((cred) => { var _a; return (_a = cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
724
|
+
const allAvailableAddresses = credentialsToSearch
|
|
725
|
+
.flatMap((cred) => { var _a; return (_a = cred === null || cred === void 0 ? void 0 : cred.walletAdditionalAddresses) !== null && _a !== void 0 ? _a : []; })
|
|
654
726
|
.map((addr) => addr.address)
|
|
655
727
|
.join(', ');
|
|
656
728
|
throw new DynamicError(`No additional address found for ${walletIdentityAddress}. Available addresses: ${allAvailableAddresses || 'none'}`, 'no_additional_address_found_for_available');
|
package/src/index.cjs
CHANGED
|
@@ -69,6 +69,7 @@ exports.PsbtParser = PsbtParser.PsbtParser;
|
|
|
69
69
|
exports.BitcoinWallet = BitcoinWallet.BitcoinWallet;
|
|
70
70
|
exports.isBitcoinWallet = isBitcoinWallet.isBitcoinWallet;
|
|
71
71
|
exports.BitcoinProviderHelper = bitcoinProviderHelper.BitcoinProviderHelper;
|
|
72
|
+
exports.DUST_LIMIT = _const.DUST_LIMIT;
|
|
72
73
|
exports.HTTP_STATUS_NOT_FOUND = _const.HTTP_STATUS_NOT_FOUND;
|
|
73
74
|
exports.HTTP_STATUS_TOO_MANY_REQUESTS = _const.HTTP_STATUS_TOO_MANY_REQUESTS;
|
|
74
75
|
exports.BitcoinWalletConnectors = BitcoinWalletConnectors;
|
package/src/index.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export * from './wallet';
|
|
|
6
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
|
-
export { HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS } from './const';
|
|
9
|
+
export { DUST_LIMIT, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS, } from './const';
|
package/src/index.js
CHANGED
|
@@ -34,7 +34,7 @@ export { PsbtParser } from './utils/psbtParser/PsbtParser.js';
|
|
|
34
34
|
export { BitcoinWallet } from './wallet/BitcoinWallet.js';
|
|
35
35
|
export { isBitcoinWallet } from './wallet/isBitcoinWallet/isBitcoinWallet.js';
|
|
36
36
|
export { BitcoinProviderHelper } from './bitcoinProviderHelper.js';
|
|
37
|
-
export { HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS } from './const.js';
|
|
37
|
+
export { DUST_LIMIT, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS } from './const.js';
|
|
38
38
|
|
|
39
39
|
assertPackageVersion('@dynamic-labs/bitcoin', version);
|
|
40
40
|
const BitcoinWalletConnectors = (props) => [
|
|
@@ -140,7 +140,10 @@ 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
|
-
|
|
143
|
+
// The node's reject reason is the only thing that distinguishes a bad
|
|
144
|
+
// witness from a fee or mempool problem, so it goes in the thrown
|
|
145
|
+
// message rather than only into a debug log the integrator cannot read.
|
|
146
|
+
throw new utils.DynamicError(`sendRawTransaction - failed to send transaction${error ? `: ${error}` : ''}`, 'sendrawtransaction_failed_to_send_transaction');
|
|
144
147
|
}
|
|
145
148
|
return response.text();
|
|
146
149
|
});
|
|
@@ -136,7 +136,10 @@ 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
|
-
|
|
139
|
+
// The node's reject reason is the only thing that distinguishes a bad
|
|
140
|
+
// witness from a fee or mempool problem, so it goes in the thrown
|
|
141
|
+
// message rather than only into a debug log the integrator cannot read.
|
|
142
|
+
throw new DynamicError(`sendRawTransaction - failed to send transaction${error ? `: ${error}` : ''}`, 'sendrawtransaction_failed_to_send_transaction');
|
|
140
143
|
}
|
|
141
144
|
return response.text();
|
|
142
145
|
});
|
|
@@ -42,6 +42,21 @@ class BitcoinWallet extends walletConnectorCore.Wallet {
|
|
|
42
42
|
return this._connector.sendBitcoin(transaction);
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Sends satoshis to a bitcoin address, showing a confirmation modal when
|
|
47
|
+
* the connector supports it (e.g. DynamicWaasBitcoinConnector). Falls back
|
|
48
|
+
* to sendBitcoin for connectors that have no confirmation UI.
|
|
49
|
+
* @returns A promise that resolves to the transaction id
|
|
50
|
+
*/
|
|
51
|
+
sendBitcoinWithConfirmation(transaction) {
|
|
52
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
yield this.sync();
|
|
54
|
+
if (this._connector.sendBitcoinWithConfirmation) {
|
|
55
|
+
return this._connector.sendBitcoinWithConfirmation(transaction);
|
|
56
|
+
}
|
|
57
|
+
return this._connector.sendBitcoin(transaction);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
45
60
|
/**
|
|
46
61
|
* Signs a message using a specific address type (payment or ordinals).
|
|
47
62
|
* @param messageToSign - The message to sign.
|
|
@@ -23,6 +23,13 @@ export declare class BitcoinWallet extends Wallet<BitcoinWalletConnector> {
|
|
|
23
23
|
* @returns A promise that resolves to the transaction id
|
|
24
24
|
*/
|
|
25
25
|
sendBitcoin(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
26
|
+
/**
|
|
27
|
+
* Sends satoshis to a bitcoin address, showing a confirmation modal when
|
|
28
|
+
* the connector supports it (e.g. DynamicWaasBitcoinConnector). Falls back
|
|
29
|
+
* to sendBitcoin for connectors that have no confirmation UI.
|
|
30
|
+
* @returns A promise that resolves to the transaction id
|
|
31
|
+
*/
|
|
32
|
+
sendBitcoinWithConfirmation(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
26
33
|
/**
|
|
27
34
|
* Signs a message using a specific address type (payment or ordinals).
|
|
28
35
|
* @param messageToSign - The message to sign.
|
|
@@ -38,6 +38,21 @@ class BitcoinWallet extends Wallet {
|
|
|
38
38
|
return this._connector.sendBitcoin(transaction);
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Sends satoshis to a bitcoin address, showing a confirmation modal when
|
|
43
|
+
* the connector supports it (e.g. DynamicWaasBitcoinConnector). Falls back
|
|
44
|
+
* to sendBitcoin for connectors that have no confirmation UI.
|
|
45
|
+
* @returns A promise that resolves to the transaction id
|
|
46
|
+
*/
|
|
47
|
+
sendBitcoinWithConfirmation(transaction) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
yield this.sync();
|
|
50
|
+
if (this._connector.sendBitcoinWithConfirmation) {
|
|
51
|
+
return this._connector.sendBitcoinWithConfirmation(transaction);
|
|
52
|
+
}
|
|
53
|
+
return this._connector.sendBitcoin(transaction);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
41
56
|
/**
|
|
42
57
|
* Signs a message using a specific address type (payment or ordinals).
|
|
43
58
|
* @param messageToSign - The message to sign.
|