@dynamic-labs/bitcoin 4.53.1 → 4.54.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 +25 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +10 -10
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +13 -12
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +30 -11
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +13 -12
- package/src/const.cjs +12 -4
- package/src/const.d.ts +4 -2
- package/src/const.js +9 -3
- package/src/index.d.ts +1 -1
- package/src/services/MempoolApiService.cjs +31 -8
- package/src/services/MempoolApiService.d.ts +3 -2
- package/src/services/MempoolApiService.js +32 -9
- package/src/services/PsbtBuilderService.cjs +195 -65
- package/src/services/PsbtBuilderService.d.ts +66 -2
- package/src/services/PsbtBuilderService.js +197 -67
- package/src/types.d.ts +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.54.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.53.2...v4.54.0) (2026-01-16)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add iCloud backup method for wallet backup ([#10221](https://github.com/dynamic-labs/dynamic-auth/issues/10221)) ([36f5b8a](https://github.com/dynamic-labs/dynamic-auth/commit/36f5b8a0df50139fabbc6d6256f396a6d40313f4))
|
|
8
|
+
* add iCloud backup support for wallet key shares ([#10220](https://github.com/dynamic-labs/dynamic-auth/issues/10220)) ([f5f8135](https://github.com/dynamic-labs/dynamic-auth/commit/f5f813593d6ec834fc94f873fd7151b1f3e1a0ca))
|
|
9
|
+
* add legacyWalletId parameter to importPrivateKey ([#10244](https://github.com/dynamic-labs/dynamic-auth/issues/10244)) ([d281dd7](https://github.com/dynamic-labs/dynamic-auth/commit/d281dd7128ac1211e8ca0b72818e109ece7b9837))
|
|
10
|
+
|
|
11
|
+
### [4.53.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.53.1...v4.53.2) (2026-01-16)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add iCloud backup functionality ([#10219](https://github.com/dynamic-labs/dynamic-auth/issues/10219)) ([44e95e5](https://github.com/dynamic-labs/dynamic-auth/commit/44e95e5a5dc99f83918a382ab1c69d452359c346))
|
|
17
|
+
* update PSBT building with Largest-First UTXO selection and fee priorities (high/medium/low) ([#10227](https://github.com/dynamic-labs/dynamic-auth/issues/10227)) ([94c5f5c](https://github.com/dynamic-labs/dynamic-auth/commit/94c5f5cb97432bb97374b754cb95bc23290dd184))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* allow late registered solana wallets to appear in the wallet list ([#10224](https://github.com/dynamic-labs/dynamic-auth/issues/10224)) ([2f418d4](https://github.com/dynamic-labs/dynamic-auth/commit/2f418d4f3e0543bdd829a45807329f89da1e41a7))
|
|
23
|
+
* correctly show app name in wallet app for wallet connect evm connections ([#10218](https://github.com/dynamic-labs/dynamic-auth/issues/10218)) ([fec0009](https://github.com/dynamic-labs/dynamic-auth/commit/fec0009177439baa67015050b4ad799119615f4f))
|
|
24
|
+
* destructure wallets from getWalletStandardWallets before calling find ([#10234](https://github.com/dynamic-labs/dynamic-auth/issues/10234)) ([b59617a](https://github.com/dynamic-labs/dynamic-auth/commit/b59617a8579b9c7d8a5f744a2ea9363ccb4aee58))
|
|
25
|
+
* **react-native:** filter connectors by enabled chains and add chain parameter to connectWallet ([#10230](https://github.com/dynamic-labs/dynamic-auth/issues/10230)) ([a2bbd03](https://github.com/dynamic-labs/dynamic-auth/commit/a2bbd03ece52950711d2eda18cb2345df15710dd))
|
|
26
|
+
|
|
2
27
|
### [4.53.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.53.0...v4.53.1) (2026-01-14)
|
|
3
28
|
|
|
4
29
|
## [4.53.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.52.5...v4.53.0) (2026-01-13)
|
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.54.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",
|
|
@@ -18,23 +18,23 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@dynamic-labs-wallet/browser-wallet-client": "0.0.
|
|
21
|
+
"@dynamic-labs-wallet/browser-wallet-client": "0.0.248",
|
|
22
22
|
"@bitcoinerlab/secp256k1": "1.1.1",
|
|
23
23
|
"@btckit/types": "0.0.19",
|
|
24
|
-
"@dynamic-labs/sdk-api-core": "0.0.
|
|
24
|
+
"@dynamic-labs/sdk-api-core": "0.0.855",
|
|
25
25
|
"@wallet-standard/app": "1.0.1",
|
|
26
26
|
"@wallet-standard/base": "1.0.1",
|
|
27
27
|
"bitcoinjs-lib": "6.1.5",
|
|
28
28
|
"ecpair": "2.1.0",
|
|
29
29
|
"sats-connect": "4.2.0",
|
|
30
30
|
"jsontokens": "4.0.1",
|
|
31
|
-
"@dynamic-labs/assert-package-version": "4.
|
|
32
|
-
"@dynamic-labs/logger": "4.
|
|
33
|
-
"@dynamic-labs/types": "4.
|
|
34
|
-
"@dynamic-labs/utils": "4.
|
|
35
|
-
"@dynamic-labs/waas": "4.
|
|
36
|
-
"@dynamic-labs/wallet-book": "4.
|
|
37
|
-
"@dynamic-labs/wallet-connector-core": "4.
|
|
31
|
+
"@dynamic-labs/assert-package-version": "4.54.0",
|
|
32
|
+
"@dynamic-labs/logger": "4.54.0",
|
|
33
|
+
"@dynamic-labs/types": "4.54.0",
|
|
34
|
+
"@dynamic-labs/utils": "4.54.0",
|
|
35
|
+
"@dynamic-labs/waas": "4.54.0",
|
|
36
|
+
"@dynamic-labs/wallet-book": "4.54.0",
|
|
37
|
+
"@dynamic-labs/wallet-connector-core": "4.54.0",
|
|
38
38
|
"eventemitter3": "5.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {}
|
|
@@ -128,11 +128,15 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
130
|
/**
|
|
131
|
-
* Signs a Partially Signed Bitcoin Transaction (PSBT)
|
|
132
|
-
*
|
|
133
|
-
*
|
|
131
|
+
* Signs a Partially Signed Bitcoin Transaction (PSBT) for embedded wallets
|
|
132
|
+
*
|
|
133
|
+
* Embedded wallets only support PSBT format and automatically sign all inputs
|
|
134
|
+
* that belong to the wallet address. Always uses SIGHASH_ALL (0x01).
|
|
135
|
+
*
|
|
136
|
+
* @param request - The PSBT signing request. Only unsignedPsbtBase64 is required.
|
|
137
|
+
* @returns The signed (but not finalized) PSBT response
|
|
134
138
|
* @throws {DynamicError} If active account address is not set
|
|
135
|
-
* @throws {DynamicError} If signed session ID is not available
|
|
139
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
136
140
|
*/
|
|
137
141
|
signPsbt(request) {
|
|
138
142
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -148,9 +152,6 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
148
152
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
149
153
|
mfaAction: sdkApiCore.MFAAction.WalletWaasSign,
|
|
150
154
|
}));
|
|
151
|
-
if (request.signature && request.signature.length > 0) {
|
|
152
|
-
throw new utils.DynamicError('Signature is not supported for waas at the moment');
|
|
153
|
-
}
|
|
154
155
|
const signedTransaction = yield walletClient.signTransaction({
|
|
155
156
|
authToken: (_c = this.getAuthToken) === null || _c === void 0 ? void 0 : _c.call(this),
|
|
156
157
|
mfaToken,
|
|
@@ -192,9 +193,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
192
193
|
// Step 1: Build the PSBT
|
|
193
194
|
const unsignedPsbt = yield this.buildPsbt(transaction);
|
|
194
195
|
// Step 2: Sign the PSBT
|
|
195
|
-
// SIGHASH_ALL (0x01) is the most common sighash type for Bitcoin transactions (Eventually can be configurable)
|
|
196
196
|
const signedPsbtResponse = yield this.signPsbt({
|
|
197
|
-
allowedSighash: [0x01],
|
|
198
197
|
unsignedPsbtBase64: unsignedPsbt,
|
|
199
198
|
});
|
|
200
199
|
if (!signedPsbtResponse) {
|
|
@@ -238,13 +237,14 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
238
237
|
* @param thresholdSignatureScheme - The threshold signature scheme (default: 'TWO_OF_TWO')
|
|
239
238
|
* @param publicAddressCheck - Optional public address to verify against
|
|
240
239
|
* @param addressType - Required address type for Bitcoin ('native_segwit' or 'taproot')
|
|
240
|
+
* @param legacyWalletId - Optional ID of the legacy wallet being upgraded
|
|
241
241
|
* @throws {DynamicError} If addressType is missing or invalid for BTC
|
|
242
242
|
*/
|
|
243
243
|
importPrivateKey(_a) {
|
|
244
244
|
const _super = Object.create(null, {
|
|
245
245
|
importPrivateKey: { get: () => super.importPrivateKey }
|
|
246
246
|
});
|
|
247
|
-
return _tslib.__awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, }) {
|
|
247
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, legacyWalletId, }) {
|
|
248
248
|
if (!addressType) {
|
|
249
249
|
throw new utils.DynamicError('addressType is required for BTC importPrivateKey');
|
|
250
250
|
}
|
|
@@ -254,6 +254,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
254
254
|
}
|
|
255
255
|
return _super.importPrivateKey.call(this, {
|
|
256
256
|
addressType,
|
|
257
|
+
legacyWalletId,
|
|
257
258
|
privateKey,
|
|
258
259
|
publicAddressCheck,
|
|
259
260
|
thresholdSignatureScheme,
|
|
@@ -337,7 +338,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
337
338
|
}
|
|
338
339
|
/**
|
|
339
340
|
* Builds a PSBT for a Bitcoin transaction with real UTXOs
|
|
340
|
-
* @param transaction -
|
|
341
|
+
* @param transaction - Bitcoin transaction with recipient address, amount in satoshis, and optional fee priority
|
|
341
342
|
* @returns A PSBT in Base64 format
|
|
342
343
|
* @throws {DynamicError} If no active account address, insufficient funds, or other errors
|
|
343
344
|
*/
|
|
@@ -347,7 +348,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
347
348
|
throw new utils.DynamicError('Active account address is required');
|
|
348
349
|
}
|
|
349
350
|
const publicKeyHex = yield this.getPublicKey();
|
|
350
|
-
const buildOptions = PsbtBuilderService.PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex);
|
|
351
|
+
const buildOptions = PsbtBuilderService.PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex, transaction.feePriority || 'medium');
|
|
351
352
|
return this.psbtBuilderService.buildPsbt(buildOptions);
|
|
352
353
|
});
|
|
353
354
|
}
|
|
@@ -2,8 +2,8 @@ import { BitcoinConfig, BitcoinNetwork } from '@dynamic-labs-wallet/browser-wall
|
|
|
2
2
|
import { JwtVerifiedCredential, MFAAction, SignMessageContext } from '@dynamic-labs/sdk-api-core';
|
|
3
3
|
import { Logger } from '@dynamic-labs/logger';
|
|
4
4
|
import { WalletUiUtils } from '@dynamic-labs/types';
|
|
5
|
-
import { IDynamicWaasConnector, InternalWalletConnector, Chain,
|
|
6
|
-
import { BitcoinTransaction } from '../../types';
|
|
5
|
+
import { IDynamicWaasConnector, InternalWalletConnector, Chain, BitcoinSignPsbtResponse } from '@dynamic-labs/wallet-connector-core';
|
|
6
|
+
import { BitcoinTransaction, EmbeddedWalletSignPsbtRequest } from '../../types';
|
|
7
7
|
import { BitcoinWalletConnector } from '../BitcoinWalletConnector';
|
|
8
8
|
import type { ParsedTransaction, DynamicWaasBitcoinConnectorProps } from '../../types';
|
|
9
9
|
declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) => {
|
|
@@ -35,7 +35,10 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
35
35
|
setBaseApiUrl(baseApiUrl: string): void;
|
|
36
36
|
setBaseClientKeysharesRelayApiUrl(baseClientKeysharesRelayApiUrl?: string | undefined): void;
|
|
37
37
|
setRelayUrl(relayUrl: string): void;
|
|
38
|
-
setGetSignedSessionIdFunction(getSignedSessionId: () => Promise<string>): void;
|
|
38
|
+
setGetSignedSessionIdFunction(getSignedSessionId: () => Promise<string>): void; /**
|
|
39
|
+
* The primary/active verified credential (first from the filtered array)
|
|
40
|
+
* This is used for the active account address
|
|
41
|
+
*/
|
|
39
42
|
delegateKeyShares({ accountAddress, password, }: {
|
|
40
43
|
accountAddress: string;
|
|
41
44
|
password?: string | undefined;
|
|
@@ -52,11 +55,12 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
52
55
|
publicKeyHex: string;
|
|
53
56
|
rawPublicKey: string | Uint8Array | undefined;
|
|
54
57
|
}>;
|
|
55
|
-
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, }: {
|
|
58
|
+
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, legacyWalletId, }: {
|
|
56
59
|
privateKey: string;
|
|
57
60
|
thresholdSignatureScheme?: string | undefined;
|
|
58
61
|
publicAddressCheck?: string | undefined;
|
|
59
62
|
addressType?: string | undefined;
|
|
63
|
+
legacyWalletId?: string | undefined;
|
|
60
64
|
}): Promise<void>;
|
|
61
65
|
exportPrivateKey({ accountAddress, displayContainer, password, }?: {
|
|
62
66
|
accountAddress?: string | undefined;
|
|
@@ -78,6 +82,15 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
78
82
|
accountAddress: string;
|
|
79
83
|
password?: string | undefined;
|
|
80
84
|
}): Promise<void>;
|
|
85
|
+
backupKeySharesToICloud({ accountAddress, password, }: {
|
|
86
|
+
accountAddress: string;
|
|
87
|
+
password?: string | undefined;
|
|
88
|
+
}): Promise<void>;
|
|
89
|
+
displayICloudSignIn({ displayContainer, }: {
|
|
90
|
+
displayContainer: HTMLElement;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
hideICloudSignIn(): Promise<void>;
|
|
93
|
+
isICloudAuthenticated(): Promise<boolean>;
|
|
81
94
|
refreshWalletAccountShares({ accountAddress, password, }: {
|
|
82
95
|
accountAddress: string;
|
|
83
96
|
password?: string | undefined;
|
|
@@ -169,13 +182,17 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
169
182
|
*/
|
|
170
183
|
signMessage(message: string): Promise<string>;
|
|
171
184
|
/**
|
|
172
|
-
* Signs a Partially Signed Bitcoin Transaction (PSBT)
|
|
173
|
-
*
|
|
174
|
-
*
|
|
185
|
+
* Signs a Partially Signed Bitcoin Transaction (PSBT) for embedded wallets
|
|
186
|
+
*
|
|
187
|
+
* Embedded wallets only support PSBT format and automatically sign all inputs
|
|
188
|
+
* that belong to the wallet address. Always uses SIGHASH_ALL (0x01).
|
|
189
|
+
*
|
|
190
|
+
* @param request - The PSBT signing request. Only unsignedPsbtBase64 is required.
|
|
191
|
+
* @returns The signed (but not finalized) PSBT response
|
|
175
192
|
* @throws {DynamicError} If active account address is not set
|
|
176
|
-
* @throws {DynamicError} If signed session ID is not available
|
|
193
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
177
194
|
*/
|
|
178
|
-
signPsbt(request:
|
|
195
|
+
signPsbt(request: EmbeddedWalletSignPsbtRequest): Promise<BitcoinSignPsbtResponse>;
|
|
179
196
|
/**
|
|
180
197
|
* Sends a raw Bitcoin transaction to the mempool
|
|
181
198
|
* @param rawTransaction - The raw transaction in hex format
|
|
@@ -214,13 +231,15 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
214
231
|
* @param thresholdSignatureScheme - The threshold signature scheme (default: 'TWO_OF_TWO')
|
|
215
232
|
* @param publicAddressCheck - Optional public address to verify against
|
|
216
233
|
* @param addressType - Required address type for Bitcoin ('native_segwit' or 'taproot')
|
|
234
|
+
* @param legacyWalletId - Optional ID of the legacy wallet being upgraded
|
|
217
235
|
* @throws {DynamicError} If addressType is missing or invalid for BTC
|
|
218
236
|
*/
|
|
219
|
-
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, }: {
|
|
237
|
+
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, legacyWalletId, }: {
|
|
220
238
|
privateKey: string;
|
|
221
239
|
thresholdSignatureScheme?: string;
|
|
222
240
|
publicAddressCheck?: string;
|
|
223
241
|
addressType?: string;
|
|
242
|
+
legacyWalletId?: string;
|
|
224
243
|
}): Promise<void>;
|
|
225
244
|
/**
|
|
226
245
|
* Gets the wallet client for a specific account address and sets it as active
|
|
@@ -258,7 +277,7 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
258
277
|
}): Promise<string>;
|
|
259
278
|
/**
|
|
260
279
|
* Builds a PSBT for a Bitcoin transaction with real UTXOs
|
|
261
|
-
* @param transaction -
|
|
280
|
+
* @param transaction - Bitcoin transaction with recipient address, amount in satoshis, and optional fee priority
|
|
262
281
|
* @returns A PSBT in Base64 format
|
|
263
282
|
* @throws {DynamicError} If no active account address, insufficient funds, or other errors
|
|
264
283
|
*/
|
|
@@ -124,11 +124,15 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
|
-
* Signs a Partially Signed Bitcoin Transaction (PSBT)
|
|
128
|
-
*
|
|
129
|
-
*
|
|
127
|
+
* Signs a Partially Signed Bitcoin Transaction (PSBT) for embedded wallets
|
|
128
|
+
*
|
|
129
|
+
* Embedded wallets only support PSBT format and automatically sign all inputs
|
|
130
|
+
* that belong to the wallet address. Always uses SIGHASH_ALL (0x01).
|
|
131
|
+
*
|
|
132
|
+
* @param request - The PSBT signing request. Only unsignedPsbtBase64 is required.
|
|
133
|
+
* @returns The signed (but not finalized) PSBT response
|
|
130
134
|
* @throws {DynamicError} If active account address is not set
|
|
131
|
-
* @throws {DynamicError} If signed session ID is not available
|
|
135
|
+
* @throws {DynamicError} If signed session ID is not available
|
|
132
136
|
*/
|
|
133
137
|
signPsbt(request) {
|
|
134
138
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -144,9 +148,6 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
144
148
|
const mfaToken = yield ((_b = this.getMfaToken) === null || _b === void 0 ? void 0 : _b.call(this, {
|
|
145
149
|
mfaAction: MFAAction.WalletWaasSign,
|
|
146
150
|
}));
|
|
147
|
-
if (request.signature && request.signature.length > 0) {
|
|
148
|
-
throw new DynamicError('Signature is not supported for waas at the moment');
|
|
149
|
-
}
|
|
150
151
|
const signedTransaction = yield walletClient.signTransaction({
|
|
151
152
|
authToken: (_c = this.getAuthToken) === null || _c === void 0 ? void 0 : _c.call(this),
|
|
152
153
|
mfaToken,
|
|
@@ -188,9 +189,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
188
189
|
// Step 1: Build the PSBT
|
|
189
190
|
const unsignedPsbt = yield this.buildPsbt(transaction);
|
|
190
191
|
// Step 2: Sign the PSBT
|
|
191
|
-
// SIGHASH_ALL (0x01) is the most common sighash type for Bitcoin transactions (Eventually can be configurable)
|
|
192
192
|
const signedPsbtResponse = yield this.signPsbt({
|
|
193
|
-
allowedSighash: [0x01],
|
|
194
193
|
unsignedPsbtBase64: unsignedPsbt,
|
|
195
194
|
});
|
|
196
195
|
if (!signedPsbtResponse) {
|
|
@@ -234,13 +233,14 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
234
233
|
* @param thresholdSignatureScheme - The threshold signature scheme (default: 'TWO_OF_TWO')
|
|
235
234
|
* @param publicAddressCheck - Optional public address to verify against
|
|
236
235
|
* @param addressType - Required address type for Bitcoin ('native_segwit' or 'taproot')
|
|
236
|
+
* @param legacyWalletId - Optional ID of the legacy wallet being upgraded
|
|
237
237
|
* @throws {DynamicError} If addressType is missing or invalid for BTC
|
|
238
238
|
*/
|
|
239
239
|
importPrivateKey(_a) {
|
|
240
240
|
const _super = Object.create(null, {
|
|
241
241
|
importPrivateKey: { get: () => super.importPrivateKey }
|
|
242
242
|
});
|
|
243
|
-
return __awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, }) {
|
|
243
|
+
return __awaiter(this, arguments, void 0, function* ({ privateKey, thresholdSignatureScheme = 'TWO_OF_TWO', publicAddressCheck, addressType, legacyWalletId, }) {
|
|
244
244
|
if (!addressType) {
|
|
245
245
|
throw new DynamicError('addressType is required for BTC importPrivateKey');
|
|
246
246
|
}
|
|
@@ -250,6 +250,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
250
250
|
}
|
|
251
251
|
return _super.importPrivateKey.call(this, {
|
|
252
252
|
addressType,
|
|
253
|
+
legacyWalletId,
|
|
253
254
|
privateKey,
|
|
254
255
|
publicAddressCheck,
|
|
255
256
|
thresholdSignatureScheme,
|
|
@@ -333,7 +334,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
333
334
|
}
|
|
334
335
|
/**
|
|
335
336
|
* Builds a PSBT for a Bitcoin transaction with real UTXOs
|
|
336
|
-
* @param transaction -
|
|
337
|
+
* @param transaction - Bitcoin transaction with recipient address, amount in satoshis, and optional fee priority
|
|
337
338
|
* @returns A PSBT in Base64 format
|
|
338
339
|
* @throws {DynamicError} If no active account address, insufficient funds, or other errors
|
|
339
340
|
*/
|
|
@@ -343,7 +344,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
343
344
|
throw new DynamicError('Active account address is required');
|
|
344
345
|
}
|
|
345
346
|
const publicKeyHex = yield this.getPublicKey();
|
|
346
|
-
const buildOptions = PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex);
|
|
347
|
+
const buildOptions = PsbtBuilderService.createBuildOptions(this.activeAccountAddress, transaction, publicKeyHex, transaction.feePriority || 'medium');
|
|
347
348
|
return this.psbtBuilderService.buildPsbt(buildOptions);
|
|
348
349
|
});
|
|
349
350
|
}
|
package/src/const.cjs
CHANGED
|
@@ -12,20 +12,28 @@ const MEMPOOL_API_URL_TESTNET = 'https://mempool.space/testnet/api';
|
|
|
12
12
|
// WaaS Bitcoin constants
|
|
13
13
|
const SATOSHIS_PER_BTC = 100000000;
|
|
14
14
|
const DUST_LIMIT = 546; // Bitcoin's dust limit in satoshis
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Accurate vSize constants for Native SegWit (P2WPKH) transactions
|
|
16
|
+
// These are used for precise fee estimation
|
|
17
|
+
const VSIZE_OVERHEAD = 10.5; // Base transaction overhead in vBytes
|
|
18
|
+
const VSIZE_INPUT_P2WPKH = 68; // Each P2WPKH input in vBytes
|
|
19
|
+
const VSIZE_OUTPUT_P2WPKH = 31; // Each P2WPKH output in vBytes
|
|
17
20
|
const MIN_RELAY_FEE = 111;
|
|
18
21
|
const DEFAULT_FEE_ESTIMATE = 1000; // Conservative default fee estimate in satoshis
|
|
22
|
+
// RBF (Replace-By-Fee) sequence number
|
|
23
|
+
// 0xfffffffd = 4294967293 (enables RBF, not final)
|
|
24
|
+
const RBF_SEQUENCE = 0xfffffffd;
|
|
19
25
|
|
|
20
26
|
exports.BTCKIT_INTERFACE = BTCKIT_INTERFACE;
|
|
21
27
|
exports.DEFAULT_FEE_ESTIMATE = DEFAULT_FEE_ESTIMATE;
|
|
22
28
|
exports.DUST_LIMIT = DUST_LIMIT;
|
|
23
29
|
exports.HTTP_STATUS_NOT_FOUND = HTTP_STATUS_NOT_FOUND;
|
|
24
30
|
exports.HTTP_STATUS_TOO_MANY_REQUESTS = HTTP_STATUS_TOO_MANY_REQUESTS;
|
|
25
|
-
exports.INPUT_BYTE_SIZE_UPPER_BOUND = INPUT_BYTE_SIZE_UPPER_BOUND;
|
|
26
31
|
exports.MEMPOOL_API_URL = MEMPOOL_API_URL;
|
|
27
32
|
exports.MEMPOOL_API_URL_TESTNET = MEMPOOL_API_URL_TESTNET;
|
|
28
33
|
exports.MIN_RELAY_FEE = MIN_RELAY_FEE;
|
|
29
|
-
exports.
|
|
34
|
+
exports.RBF_SEQUENCE = RBF_SEQUENCE;
|
|
30
35
|
exports.SATOSHIS_PER_BTC = SATOSHIS_PER_BTC;
|
|
31
36
|
exports.SATSCONNECT_FEATURE = SATSCONNECT_FEATURE;
|
|
37
|
+
exports.VSIZE_INPUT_P2WPKH = VSIZE_INPUT_P2WPKH;
|
|
38
|
+
exports.VSIZE_OUTPUT_P2WPKH = VSIZE_OUTPUT_P2WPKH;
|
|
39
|
+
exports.VSIZE_OVERHEAD = VSIZE_OVERHEAD;
|
package/src/const.d.ts
CHANGED
|
@@ -7,7 +7,9 @@ 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
8
|
export declare const SATOSHIS_PER_BTC = 100000000;
|
|
9
9
|
export declare const DUST_LIMIT = 546;
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
10
|
+
export declare const VSIZE_OVERHEAD = 10.5;
|
|
11
|
+
export declare const VSIZE_INPUT_P2WPKH = 68;
|
|
12
|
+
export declare const VSIZE_OUTPUT_P2WPKH = 31;
|
|
12
13
|
export declare const MIN_RELAY_FEE = 111;
|
|
13
14
|
export declare const DEFAULT_FEE_ESTIMATE = 1000;
|
|
15
|
+
export declare const RBF_SEQUENCE = 4294967293;
|
package/src/const.js
CHANGED
|
@@ -8,9 +8,15 @@ const MEMPOOL_API_URL_TESTNET = 'https://mempool.space/testnet/api';
|
|
|
8
8
|
// WaaS Bitcoin constants
|
|
9
9
|
const SATOSHIS_PER_BTC = 100000000;
|
|
10
10
|
const DUST_LIMIT = 546; // Bitcoin's dust limit in satoshis
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
// Accurate vSize constants for Native SegWit (P2WPKH) transactions
|
|
12
|
+
// These are used for precise fee estimation
|
|
13
|
+
const VSIZE_OVERHEAD = 10.5; // Base transaction overhead in vBytes
|
|
14
|
+
const VSIZE_INPUT_P2WPKH = 68; // Each P2WPKH input in vBytes
|
|
15
|
+
const VSIZE_OUTPUT_P2WPKH = 31; // Each P2WPKH output in vBytes
|
|
13
16
|
const MIN_RELAY_FEE = 111;
|
|
14
17
|
const DEFAULT_FEE_ESTIMATE = 1000; // Conservative default fee estimate in satoshis
|
|
18
|
+
// RBF (Replace-By-Fee) sequence number
|
|
19
|
+
// 0xfffffffd = 4294967293 (enables RBF, not final)
|
|
20
|
+
const RBF_SEQUENCE = 0xfffffffd;
|
|
15
21
|
|
|
16
|
-
export { BTCKIT_INTERFACE, DEFAULT_FEE_ESTIMATE, DUST_LIMIT, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS,
|
|
22
|
+
export { BTCKIT_INTERFACE, DEFAULT_FEE_ESTIMATE, DUST_LIMIT, HTTP_STATUS_NOT_FOUND, HTTP_STATUS_TOO_MANY_REQUESTS, MEMPOOL_API_URL, MEMPOOL_API_URL_TESTNET, MIN_RELAY_FEE, RBF_SEQUENCE, SATOSHIS_PER_BTC, SATSCONNECT_FEATURE, VSIZE_INPUT_P2WPKH, VSIZE_OUTPUT_P2WPKH, VSIZE_OVERHEAD };
|
package/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OkxConnector } from './connectors';
|
|
2
2
|
export { BitcoinWalletConnector, type BitcoinWalletConnectorOpts, } from './connectors';
|
|
3
|
-
export type { BitcoinTransaction, BitcoinSignProtocol, BitcoinSignPsbtRequest, BitcoinSignPsbtResponse, BitcoinWalletStandardMethods, SignPsbtOptions, } from './types';
|
|
3
|
+
export type { BitcoinTransaction, BitcoinSignProtocol, BitcoinSignPsbtRequest, BitcoinSignPsbtResponse, BitcoinWalletStandardMethods, SignPsbtOptions, EmbeddedWalletSignPsbtRequest, } from './types';
|
|
4
4
|
export * from './utils';
|
|
5
5
|
export * from './wallet';
|
|
6
6
|
export { UnisatConnector, BitcoinSatsConnectConnector, DynamicWaasBitcoinConnector, } from './connectors';
|
|
@@ -70,21 +70,44 @@ class MempoolApiService {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
|
-
* Estimates transaction fees based on number of inputs and outputs
|
|
73
|
+
* Estimates transaction fees based on number of inputs and outputs using accurate vSize
|
|
74
74
|
* @param address - The Bitcoin address to determine the network from
|
|
75
75
|
* @param numInputs - Number of transaction inputs
|
|
76
76
|
* @param numOutputs - Number of transaction outputs
|
|
77
|
+
* @param feePriority - Fee priority level (high/medium/low)
|
|
77
78
|
* @returns Estimated fee in satoshis
|
|
78
79
|
*/
|
|
79
|
-
estimateTransactionFee(
|
|
80
|
-
return _tslib.__awaiter(this,
|
|
80
|
+
estimateTransactionFee(address_1, numInputs_1, numOutputs_1) {
|
|
81
|
+
return _tslib.__awaiter(this, arguments, void 0, function* (address, numInputs, numOutputs, feePriority = 'medium') {
|
|
81
82
|
try {
|
|
82
83
|
const feeData = yield this.getFeeRecommendations(address);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
// High (Fastest): fastestFee -> Block 1
|
|
85
|
+
// Medium (Fast): halfHourFee -> Blocks 2-3
|
|
86
|
+
// Low (Eco): economyFee (preferred) or hourFee -> Blocks 6+
|
|
87
|
+
let feePerByte;
|
|
88
|
+
switch (feePriority) {
|
|
89
|
+
case 'high':
|
|
90
|
+
feePerByte =
|
|
91
|
+
feeData.fastestFee || feeData.halfHourFee || feeData.hourFee || 1;
|
|
92
|
+
break;
|
|
93
|
+
case 'low':
|
|
94
|
+
feePerByte = feeData.economyFee || feeData.hourFee || 1;
|
|
95
|
+
break;
|
|
96
|
+
case 'medium':
|
|
97
|
+
default:
|
|
98
|
+
feePerByte =
|
|
99
|
+
feeData.halfHourFee || feeData.hourFee || feeData.economyFee || 1;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
logger.debug(`Fee estimation - Priority: ${feePriority}, fastestFee: ${feeData.fastestFee}, halfHourFee: ${feeData.halfHourFee}, hourFee: ${feeData.hourFee}, economyFee: ${feeData.economyFee}, selected: ${feePerByte} sat/vB`);
|
|
103
|
+
// Use accurate vSize calculation for Native SegWit (P2WPKH)
|
|
104
|
+
// Formula: overhead + (inputs × 68) + (outputs × 31)
|
|
105
|
+
const vSize = _const.VSIZE_OVERHEAD +
|
|
106
|
+
numInputs * _const.VSIZE_INPUT_P2WPKH +
|
|
107
|
+
numOutputs * _const.VSIZE_OUTPUT_P2WPKH;
|
|
108
|
+
const estimatedFee = Math.ceil(feePerByte * vSize) + _const.MIN_RELAY_FEE;
|
|
109
|
+
logger.debug(`Fee calculation - Priority: ${feePriority}, vSize: ${vSize}, feePerByte: ${feePerByte} sat/vB, estimatedFee: ${estimatedFee} satoshis`);
|
|
110
|
+
logger.debug(`[MempoolApiService] Fee Priority: ${feePriority}, Selected Rate: ${feePerByte} sat/vB, vSize: ${vSize}, Estimated Fee: ${estimatedFee} satoshis`);
|
|
88
111
|
return estimatedFee;
|
|
89
112
|
}
|
|
90
113
|
catch (error) {
|
|
@@ -24,13 +24,14 @@ export declare class MempoolApiService {
|
|
|
24
24
|
*/
|
|
25
25
|
getFeeRecommendations(address: string): Promise<FeeRecommendations>;
|
|
26
26
|
/**
|
|
27
|
-
* Estimates transaction fees based on number of inputs and outputs
|
|
27
|
+
* Estimates transaction fees based on number of inputs and outputs using accurate vSize
|
|
28
28
|
* @param address - The Bitcoin address to determine the network from
|
|
29
29
|
* @param numInputs - Number of transaction inputs
|
|
30
30
|
* @param numOutputs - Number of transaction outputs
|
|
31
|
+
* @param feePriority - Fee priority level (high/medium/low)
|
|
31
32
|
* @returns Estimated fee in satoshis
|
|
32
33
|
*/
|
|
33
|
-
estimateTransactionFee(address: string, numInputs: number, numOutputs: number): Promise<number>;
|
|
34
|
+
estimateTransactionFee(address: string, numInputs: number, numOutputs: number, feePriority?: 'high' | 'medium' | 'low'): Promise<number>;
|
|
34
35
|
/**
|
|
35
36
|
* Sends a raw Bitcoin transaction to the mempool
|
|
36
37
|
* @param address - The Bitcoin address to determine the network from
|
|
@@ -9,7 +9,7 @@ import '@dynamic-labs/wallet-book';
|
|
|
9
9
|
import '@dynamic-labs/sdk-api-core';
|
|
10
10
|
import '@wallet-standard/app';
|
|
11
11
|
import { getMempoolApiUrl } from '../utils/getMempoolApiUrl.js';
|
|
12
|
-
import {
|
|
12
|
+
import { VSIZE_OVERHEAD, VSIZE_INPUT_P2WPKH, VSIZE_OUTPUT_P2WPKH, MIN_RELAY_FEE, DEFAULT_FEE_ESTIMATE } from '../const.js';
|
|
13
13
|
import 'jsontokens';
|
|
14
14
|
import '../connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js';
|
|
15
15
|
|
|
@@ -66,21 +66,44 @@ class MempoolApiService {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Estimates transaction fees based on number of inputs and outputs
|
|
69
|
+
* Estimates transaction fees based on number of inputs and outputs using accurate vSize
|
|
70
70
|
* @param address - The Bitcoin address to determine the network from
|
|
71
71
|
* @param numInputs - Number of transaction inputs
|
|
72
72
|
* @param numOutputs - Number of transaction outputs
|
|
73
|
+
* @param feePriority - Fee priority level (high/medium/low)
|
|
73
74
|
* @returns Estimated fee in satoshis
|
|
74
75
|
*/
|
|
75
|
-
estimateTransactionFee(
|
|
76
|
-
return __awaiter(this,
|
|
76
|
+
estimateTransactionFee(address_1, numInputs_1, numOutputs_1) {
|
|
77
|
+
return __awaiter(this, arguments, void 0, function* (address, numInputs, numOutputs, feePriority = 'medium') {
|
|
77
78
|
try {
|
|
78
79
|
const feeData = yield this.getFeeRecommendations(address);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
// High (Fastest): fastestFee -> Block 1
|
|
81
|
+
// Medium (Fast): halfHourFee -> Blocks 2-3
|
|
82
|
+
// Low (Eco): economyFee (preferred) or hourFee -> Blocks 6+
|
|
83
|
+
let feePerByte;
|
|
84
|
+
switch (feePriority) {
|
|
85
|
+
case 'high':
|
|
86
|
+
feePerByte =
|
|
87
|
+
feeData.fastestFee || feeData.halfHourFee || feeData.hourFee || 1;
|
|
88
|
+
break;
|
|
89
|
+
case 'low':
|
|
90
|
+
feePerByte = feeData.economyFee || feeData.hourFee || 1;
|
|
91
|
+
break;
|
|
92
|
+
case 'medium':
|
|
93
|
+
default:
|
|
94
|
+
feePerByte =
|
|
95
|
+
feeData.halfHourFee || feeData.hourFee || feeData.economyFee || 1;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
logger.debug(`Fee estimation - Priority: ${feePriority}, fastestFee: ${feeData.fastestFee}, halfHourFee: ${feeData.halfHourFee}, hourFee: ${feeData.hourFee}, economyFee: ${feeData.economyFee}, selected: ${feePerByte} sat/vB`);
|
|
99
|
+
// Use accurate vSize calculation for Native SegWit (P2WPKH)
|
|
100
|
+
// Formula: overhead + (inputs × 68) + (outputs × 31)
|
|
101
|
+
const vSize = VSIZE_OVERHEAD +
|
|
102
|
+
numInputs * VSIZE_INPUT_P2WPKH +
|
|
103
|
+
numOutputs * VSIZE_OUTPUT_P2WPKH;
|
|
104
|
+
const estimatedFee = Math.ceil(feePerByte * vSize) + MIN_RELAY_FEE;
|
|
105
|
+
logger.debug(`Fee calculation - Priority: ${feePriority}, vSize: ${vSize}, feePerByte: ${feePerByte} sat/vB, estimatedFee: ${estimatedFee} satoshis`);
|
|
106
|
+
logger.debug(`[MempoolApiService] Fee Priority: ${feePriority}, Selected Rate: ${feePerByte} sat/vB, vSize: ${vSize}, Estimated Fee: ${estimatedFee} satoshis`);
|
|
84
107
|
return estimatedFee;
|
|
85
108
|
}
|
|
86
109
|
catch (error) {
|