@dynamic-labs-wallet/btc 1.0.104 → 1.0.106
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/index.cjs +24 -7
- package/index.esm.js +25 -8
- package/package.json +3 -3
- package/src/client/client.d.ts +7 -1
- package/src/client/client.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -498,8 +498,12 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
498
498
|
* @param mfaToken - The MFA token to use for the transaction
|
|
499
499
|
* @param context - The context to use for the transaction
|
|
500
500
|
* @param onError - The error handler
|
|
501
|
+
* @param signingIndexes - Optional subset of PSBT input indexes to sign (must belong to senderAddress)
|
|
502
|
+
* @param allowedSighash - Optional allow-list of sighash types. The type itself is read
|
|
503
|
+
* from the PSBT; this only restricts which declared types are accepted. An empty
|
|
504
|
+
* array permits nothing; omit the parameter to permit any declared type
|
|
501
505
|
* @returns The signed PSBT
|
|
502
|
-
*/ async signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError }) {
|
|
506
|
+
*/ async signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError, signingIndexes, allowedSighash }) {
|
|
503
507
|
try {
|
|
504
508
|
await this.verifyPassword({
|
|
505
509
|
accountAddress: senderAddress,
|
|
@@ -545,7 +549,7 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
545
549
|
const pubKey = btcUtils.normalizePublicKey(derivedPublicKey, addressType);
|
|
546
550
|
const tx = psbt.__CACHE.__TX;
|
|
547
551
|
// Filter inputs to only sign those that belong to the current address
|
|
548
|
-
|
|
552
|
+
let inputsToSign = psbt.data.inputs.map((input, i)=>({
|
|
549
553
|
input,
|
|
550
554
|
index: i
|
|
551
555
|
})).filter(({ input })=>btcUtils.doesInputBelongToAddress(input, senderAddress, network));
|
|
@@ -554,13 +558,24 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
554
558
|
inputsToSign: inputsToSign.length,
|
|
555
559
|
senderAddress
|
|
556
560
|
});
|
|
561
|
+
if (signingIndexes == null ? void 0 : signingIndexes.length) {
|
|
562
|
+
const walletOwnedIndexSet = new Set(inputsToSign.map(({ index })=>index));
|
|
563
|
+
const invalidIndexes = signingIndexes.filter((i)=>!walletOwnedIndexSet.has(i));
|
|
564
|
+
if (invalidIndexes.length > 0) {
|
|
565
|
+
throw new Error(`signingIndexes contains indexes that do not belong to the signing address: ${invalidIndexes.join(', ')}`);
|
|
566
|
+
}
|
|
567
|
+
const requestedIndexSet = new Set(signingIndexes);
|
|
568
|
+
inputsToSign = inputsToSign.filter(({ index })=>requestedIndexSet.has(index));
|
|
569
|
+
}
|
|
557
570
|
if (inputsToSign.length === 0) {
|
|
558
571
|
this.logger.warn('[BTC Client] signTransaction - No inputs found for address', {
|
|
559
572
|
senderAddress,
|
|
560
573
|
totalInputs: psbt.data.inputs.length
|
|
561
574
|
});
|
|
562
575
|
}
|
|
563
|
-
|
|
576
|
+
const isTaproot = addressType === browser.BitcoinAddressType.TAPROOT;
|
|
577
|
+
btcUtils.assertSighashAllowed(inputsToSign, isTaproot, allowedSighash);
|
|
578
|
+
if (isTaproot) {
|
|
564
579
|
const tweak = btcUtils.calculateTaprootTweak(pubKey);
|
|
565
580
|
const completeBitcoinConfig = _extends({}, bitcoinConfig, {
|
|
566
581
|
addressType: addressType,
|
|
@@ -571,7 +586,8 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
571
586
|
if (!input.witnessUtxo) {
|
|
572
587
|
throw new Error(`Input ${i} missing witnessUtxo`);
|
|
573
588
|
}
|
|
574
|
-
const
|
|
589
|
+
const sigHashType = btcUtils.getSigHashType(input, true);
|
|
590
|
+
const hash = Buffer.from(tx.hashForWitnessV1(i, prevOutScripts, values, sigHashType));
|
|
575
591
|
const signature = await this.sign({
|
|
576
592
|
message: new Uint8Array(hash),
|
|
577
593
|
accountAddress: senderAddress,
|
|
@@ -590,7 +606,7 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
590
606
|
bitcoinConfig: completeBitcoinConfig,
|
|
591
607
|
onError
|
|
592
608
|
});
|
|
593
|
-
const sigBuffer = btcUtils.convertSignatureToTaprootBuffer(signature);
|
|
609
|
+
const sigBuffer = btcUtils.convertSignatureToTaprootBuffer(signature, sigHashType);
|
|
594
610
|
psbt.updateInput(i, {
|
|
595
611
|
tapKeySig: sigBuffer
|
|
596
612
|
});
|
|
@@ -613,7 +629,8 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
613
629
|
});
|
|
614
630
|
const scriptCode = p2pkh.output;
|
|
615
631
|
if (!scriptCode) throw new Error('Failed to generate scriptCode');
|
|
616
|
-
const
|
|
632
|
+
const sigHashType = btcUtils.getSigHashType(input, false);
|
|
633
|
+
const hash = tx.hashForWitnessV0(i, scriptCode, value, sigHashType);
|
|
617
634
|
const signature = await this.sign({
|
|
618
635
|
message: new Uint8Array(hash),
|
|
619
636
|
accountAddress: senderAddress,
|
|
@@ -632,7 +649,7 @@ class DynamicBtcWalletClient extends browser.DynamicWalletClient {
|
|
|
632
649
|
bitcoinConfig: completeBitcoinConfig,
|
|
633
650
|
onError
|
|
634
651
|
});
|
|
635
|
-
const derSignature = btcUtils.convertSignatureToDER(signature);
|
|
652
|
+
const derSignature = btcUtils.convertSignatureToDER(signature, sigHashType);
|
|
636
653
|
psbt.updateInput(i, {
|
|
637
654
|
partialSig: [
|
|
638
655
|
{
|
package/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicWalletClient, BitcoinNetwork, BitcoinAddressType, getMPCChainConfig, ERROR_CREATE_WALLET_ACCOUNT, ERROR_PASSWORD_MISMATCH, ERROR_MULTIPLE_WALLETS_PER_CHAIN, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_SIGN_MESSAGE, ERROR_IMPORT_PRIVATE_KEY } from '@dynamic-labs-wallet/browser';
|
|
2
2
|
import * as bitcoin from 'bitcoinjs-lib';
|
|
3
3
|
import ecc from '@bitcoinerlab/secp256k1';
|
|
4
|
-
import { extractPublicKeyHex, normalizePublicKey, publicKeyToBitcoinAddress, getAddressTypeFromDerivationPath, calculateBip322Hash, calculateTaprootTweak, encodeBip322Signature, wifToPrivateKey, getPublicKeyFromPrivateKey, privateKeyToWIF, doesInputBelongToAddress, collectPSBTInputData, convertSignatureToTaprootBuffer, getBitcoinNetwork, convertSignatureToDER, getFeeRates, getUTXOs, selectUTXOs, getDefaultRpcUrl, initEccLib } from '@dynamic-labs-wallet/btc-utils';
|
|
4
|
+
import { extractPublicKeyHex, normalizePublicKey, publicKeyToBitcoinAddress, getAddressTypeFromDerivationPath, calculateBip322Hash, calculateTaprootTweak, encodeBip322Signature, wifToPrivateKey, getPublicKeyFromPrivateKey, privateKeyToWIF, doesInputBelongToAddress, assertSighashAllowed, collectPSBTInputData, getSigHashType, convertSignatureToTaprootBuffer, getBitcoinNetwork, convertSignatureToDER, getFeeRates, getUTXOs, selectUTXOs, getDefaultRpcUrl, initEccLib } from '@dynamic-labs-wallet/btc-utils';
|
|
5
5
|
|
|
6
6
|
function _extends() {
|
|
7
7
|
_extends = Object.assign || function assign(target) {
|
|
@@ -477,8 +477,12 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
477
477
|
* @param mfaToken - The MFA token to use for the transaction
|
|
478
478
|
* @param context - The context to use for the transaction
|
|
479
479
|
* @param onError - The error handler
|
|
480
|
+
* @param signingIndexes - Optional subset of PSBT input indexes to sign (must belong to senderAddress)
|
|
481
|
+
* @param allowedSighash - Optional allow-list of sighash types. The type itself is read
|
|
482
|
+
* from the PSBT; this only restricts which declared types are accepted. An empty
|
|
483
|
+
* array permits nothing; omit the parameter to permit any declared type
|
|
480
484
|
* @returns The signed PSBT
|
|
481
|
-
*/ async signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError }) {
|
|
485
|
+
*/ async signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError, signingIndexes, allowedSighash }) {
|
|
482
486
|
try {
|
|
483
487
|
await this.verifyPassword({
|
|
484
488
|
accountAddress: senderAddress,
|
|
@@ -524,7 +528,7 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
524
528
|
const pubKey = normalizePublicKey(derivedPublicKey, addressType);
|
|
525
529
|
const tx = psbt.__CACHE.__TX;
|
|
526
530
|
// Filter inputs to only sign those that belong to the current address
|
|
527
|
-
|
|
531
|
+
let inputsToSign = psbt.data.inputs.map((input, i)=>({
|
|
528
532
|
input,
|
|
529
533
|
index: i
|
|
530
534
|
})).filter(({ input })=>doesInputBelongToAddress(input, senderAddress, network));
|
|
@@ -533,13 +537,24 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
533
537
|
inputsToSign: inputsToSign.length,
|
|
534
538
|
senderAddress
|
|
535
539
|
});
|
|
540
|
+
if (signingIndexes == null ? void 0 : signingIndexes.length) {
|
|
541
|
+
const walletOwnedIndexSet = new Set(inputsToSign.map(({ index })=>index));
|
|
542
|
+
const invalidIndexes = signingIndexes.filter((i)=>!walletOwnedIndexSet.has(i));
|
|
543
|
+
if (invalidIndexes.length > 0) {
|
|
544
|
+
throw new Error(`signingIndexes contains indexes that do not belong to the signing address: ${invalidIndexes.join(', ')}`);
|
|
545
|
+
}
|
|
546
|
+
const requestedIndexSet = new Set(signingIndexes);
|
|
547
|
+
inputsToSign = inputsToSign.filter(({ index })=>requestedIndexSet.has(index));
|
|
548
|
+
}
|
|
536
549
|
if (inputsToSign.length === 0) {
|
|
537
550
|
this.logger.warn('[BTC Client] signTransaction - No inputs found for address', {
|
|
538
551
|
senderAddress,
|
|
539
552
|
totalInputs: psbt.data.inputs.length
|
|
540
553
|
});
|
|
541
554
|
}
|
|
542
|
-
|
|
555
|
+
const isTaproot = addressType === BitcoinAddressType.TAPROOT;
|
|
556
|
+
assertSighashAllowed(inputsToSign, isTaproot, allowedSighash);
|
|
557
|
+
if (isTaproot) {
|
|
543
558
|
const tweak = calculateTaprootTweak(pubKey);
|
|
544
559
|
const completeBitcoinConfig = _extends({}, bitcoinConfig, {
|
|
545
560
|
addressType: addressType,
|
|
@@ -550,7 +565,8 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
550
565
|
if (!input.witnessUtxo) {
|
|
551
566
|
throw new Error(`Input ${i} missing witnessUtxo`);
|
|
552
567
|
}
|
|
553
|
-
const
|
|
568
|
+
const sigHashType = getSigHashType(input, true);
|
|
569
|
+
const hash = Buffer.from(tx.hashForWitnessV1(i, prevOutScripts, values, sigHashType));
|
|
554
570
|
const signature = await this.sign({
|
|
555
571
|
message: new Uint8Array(hash),
|
|
556
572
|
accountAddress: senderAddress,
|
|
@@ -569,7 +585,7 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
569
585
|
bitcoinConfig: completeBitcoinConfig,
|
|
570
586
|
onError
|
|
571
587
|
});
|
|
572
|
-
const sigBuffer = convertSignatureToTaprootBuffer(signature);
|
|
588
|
+
const sigBuffer = convertSignatureToTaprootBuffer(signature, sigHashType);
|
|
573
589
|
psbt.updateInput(i, {
|
|
574
590
|
tapKeySig: sigBuffer
|
|
575
591
|
});
|
|
@@ -592,7 +608,8 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
592
608
|
});
|
|
593
609
|
const scriptCode = p2pkh.output;
|
|
594
610
|
if (!scriptCode) throw new Error('Failed to generate scriptCode');
|
|
595
|
-
const
|
|
611
|
+
const sigHashType = getSigHashType(input, false);
|
|
612
|
+
const hash = tx.hashForWitnessV0(i, scriptCode, value, sigHashType);
|
|
596
613
|
const signature = await this.sign({
|
|
597
614
|
message: new Uint8Array(hash),
|
|
598
615
|
accountAddress: senderAddress,
|
|
@@ -611,7 +628,7 @@ class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
611
628
|
bitcoinConfig: completeBitcoinConfig,
|
|
612
629
|
onError
|
|
613
630
|
});
|
|
614
|
-
const derSignature = convertSignatureToDER(signature);
|
|
631
|
+
const derSignature = convertSignatureToDER(signature, sigHashType);
|
|
615
632
|
psbt.updateInput(i, {
|
|
616
633
|
partialSig: [
|
|
617
634
|
{
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/btc",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.106",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@dynamic-labs/sdk-api-core": "^0.0.1093",
|
|
9
|
-
"@dynamic-labs-wallet/browser": "1.0.
|
|
10
|
-
"@dynamic-labs-wallet/btc-utils": "1.0.
|
|
9
|
+
"@dynamic-labs-wallet/browser": "1.0.106",
|
|
10
|
+
"@dynamic-labs-wallet/btc-utils": "1.0.106",
|
|
11
11
|
"@bitcoinerlab/secp256k1": "^1.2.0",
|
|
12
12
|
"bitcoinjs-lib": "^7.0.0"
|
|
13
13
|
},
|
package/src/client/client.d.ts
CHANGED
|
@@ -138,9 +138,13 @@ export declare class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
138
138
|
* @param mfaToken - The MFA token to use for the transaction
|
|
139
139
|
* @param context - The context to use for the transaction
|
|
140
140
|
* @param onError - The error handler
|
|
141
|
+
* @param signingIndexes - Optional subset of PSBT input indexes to sign (must belong to senderAddress)
|
|
142
|
+
* @param allowedSighash - Optional allow-list of sighash types. The type itself is read
|
|
143
|
+
* from the PSBT; this only restricts which declared types are accepted. An empty
|
|
144
|
+
* array permits nothing; omit the parameter to permit any declared type
|
|
141
145
|
* @returns The signed PSBT
|
|
142
146
|
*/
|
|
143
|
-
signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError, }: {
|
|
147
|
+
signTransaction({ transaction, senderAddress, network, password, signedSessionId, mfaToken, elevatedAccessToken, context, onError, signingIndexes, allowedSighash, }: {
|
|
144
148
|
transaction: string;
|
|
145
149
|
senderAddress: string;
|
|
146
150
|
network: BitcoinNetwork;
|
|
@@ -150,6 +154,8 @@ export declare class DynamicBtcWalletClient extends DynamicWalletClient {
|
|
|
150
154
|
elevatedAccessToken?: string;
|
|
151
155
|
context?: SignMessageContext;
|
|
152
156
|
onError?: (error: Error) => void;
|
|
157
|
+
signingIndexes?: number[];
|
|
158
|
+
allowedSighash?: number[];
|
|
153
159
|
}): Promise<string>;
|
|
154
160
|
/**
|
|
155
161
|
* Creates a PSBT for a transaction
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EAQnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,kCAAkC,EACvC,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|