@dynamic-labs-wallet/btc-utils 1.0.105 → 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 +103 -14
- package/index.esm.js +102 -15
- package/package.json +2 -2
- package/src/assertSighashAllowed/assertSighashAllowed.d.ts +21 -0
- package/src/assertSighashAllowed/assertSighashAllowed.d.ts.map +1 -0
- package/src/assertSighashAllowed/index.d.ts +2 -0
- package/src/assertSighashAllowed/index.d.ts.map +1 -0
- package/src/convertSignatureToDER/convertSignatureToDER.d.ts +4 -1
- package/src/convertSignatureToDER/convertSignatureToDER.d.ts.map +1 -1
- package/src/convertSignatureToTaprootBuffer/convertSignatureToTaprootBuffer.d.ts +5 -2
- package/src/convertSignatureToTaprootBuffer/convertSignatureToTaprootBuffer.d.ts.map +1 -1
- package/src/extractPsbtSighashes/extractPsbtSighashes.d.ts.map +1 -1
- package/src/getSigHashType/getSigHashType.d.ts +21 -0
- package/src/getSigHashType/getSigHashType.d.ts.map +1 -0
- package/src/getSigHashType/index.d.ts +2 -0
- package/src/getSigHashType/index.d.ts.map +1 -0
- package/src/index.d.ts +2 -0
- package/src/index.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -726,8 +726,12 @@ function _instanceof$3(left, right) {
|
|
|
726
726
|
* Converts an ECDSA signature to DER format
|
|
727
727
|
*
|
|
728
728
|
* @param signature - The ECDSA signature
|
|
729
|
+
* @param sighashType - The sighash type to append as the DER trailing byte.
|
|
730
|
+
* Must match the type the signing hash was built with, or the signature will
|
|
731
|
+
* fail verification at finalize/broadcast. Defaults to SIGHASH_ALL.
|
|
729
732
|
* @returns The DER encoded signature
|
|
730
733
|
*/ var convertSignatureToDER = function(signature) {
|
|
734
|
+
var sighashType = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : bitcoin__namespace.Transaction.SIGHASH_ALL;
|
|
731
735
|
var r = _instanceof$3(signature.r, Uint8Array) ? signature.r : new Uint8Array(signature.r);
|
|
732
736
|
var s = _instanceof$3(signature.s, Uint8Array) ? signature.s : new Uint8Array(signature.s);
|
|
733
737
|
var r32 = new Uint8Array(32);
|
|
@@ -739,7 +743,7 @@ function _instanceof$3(left, right) {
|
|
|
739
743
|
var rawSignature = new Uint8Array(64);
|
|
740
744
|
rawSignature.set(r32, 0);
|
|
741
745
|
rawSignature.set(s32, 32);
|
|
742
|
-
var derSignature = bitcoin__namespace.script.signature.encode(rawSignature,
|
|
746
|
+
var derSignature = bitcoin__namespace.script.signature.encode(rawSignature, sighashType);
|
|
743
747
|
return derSignature;
|
|
744
748
|
};
|
|
745
749
|
|
|
@@ -1210,19 +1214,34 @@ function _instanceof$2(left, right) {
|
|
|
1210
1214
|
* Converts a signature to a Buffer format suitable for Taproot (BIP340/Schnorr)
|
|
1211
1215
|
*
|
|
1212
1216
|
* @param signature - The signature from MPC (can be Uint8Array, Buffer, or EcdsaSignature object)
|
|
1213
|
-
* @
|
|
1217
|
+
* @param sighashType - The sighash type the signing hash was built with. Per
|
|
1218
|
+
* BIP-341 the signature stays 64 bytes for SIGHASH_DEFAULT and gains the
|
|
1219
|
+
* sighash type as a 65th byte for any other type. Defaults to SIGHASH_DEFAULT.
|
|
1220
|
+
* @returns A Buffer containing the 64-byte (or 65-byte) Schnorr signature
|
|
1214
1221
|
*/ var convertSignatureToTaprootBuffer = function(signature) {
|
|
1222
|
+
var sighashType = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : bitcoin__namespace.Transaction.SIGHASH_DEFAULT;
|
|
1223
|
+
var schnorrSignature;
|
|
1215
1224
|
if (_instanceof$2(signature, Uint8Array) || Buffer.isBuffer(signature)) {
|
|
1216
|
-
|
|
1225
|
+
schnorrSignature = Buffer.from(signature);
|
|
1226
|
+
} else {
|
|
1227
|
+
var r = signature.r;
|
|
1228
|
+
var s = signature.s;
|
|
1229
|
+
var rBuf = Buffer.isBuffer(r) ? r : Buffer.from(r);
|
|
1230
|
+
var sBuf = Buffer.isBuffer(s) ? s : Buffer.from(s);
|
|
1231
|
+
// Safe: creates Uint8Array views over Buffer's underlying memory without copying
|
|
1232
|
+
schnorrSignature = Buffer.concat([
|
|
1233
|
+
new Uint8Array(rBuf),
|
|
1234
|
+
new Uint8Array(sBuf)
|
|
1235
|
+
]);
|
|
1236
|
+
}
|
|
1237
|
+
if (sighashType === bitcoin__namespace.Transaction.SIGHASH_DEFAULT) {
|
|
1238
|
+
return schnorrSignature;
|
|
1217
1239
|
}
|
|
1218
|
-
var r = signature.r;
|
|
1219
|
-
var s = signature.s;
|
|
1220
|
-
var rBuf = Buffer.isBuffer(r) ? r : Buffer.from(r);
|
|
1221
|
-
var sBuf = Buffer.isBuffer(s) ? s : Buffer.from(s);
|
|
1222
|
-
// Safe: creates Uint8Array views over Buffer's underlying memory without copying
|
|
1223
1240
|
return Buffer.concat([
|
|
1224
|
-
new Uint8Array(
|
|
1225
|
-
new Uint8Array(
|
|
1241
|
+
new Uint8Array(schnorrSignature),
|
|
1242
|
+
new Uint8Array([
|
|
1243
|
+
sighashType
|
|
1244
|
+
])
|
|
1226
1245
|
]);
|
|
1227
1246
|
};
|
|
1228
1247
|
|
|
@@ -1306,6 +1325,72 @@ function _instanceof$1(left, right) {
|
|
|
1306
1325
|
}
|
|
1307
1326
|
};
|
|
1308
1327
|
|
|
1328
|
+
/**
|
|
1329
|
+
* Resolves the sighash type for a PSBT input.
|
|
1330
|
+
*
|
|
1331
|
+
* The type is read from the PSBT itself (BIP-174 `PSBT_IN_SIGHASH_TYPE`), never
|
|
1332
|
+
* supplied by the caller — the signing hash and the policy layer's verification
|
|
1333
|
+
* hash must be derived from the same bytes, or every non-default signature
|
|
1334
|
+
* would be rejected as tampered.
|
|
1335
|
+
*
|
|
1336
|
+
* When the input declares nothing, falls back to the historical default:
|
|
1337
|
+
* SIGHASH_DEFAULT (0x00) for Taproot, SIGHASH_ALL (0x01) otherwise.
|
|
1338
|
+
*
|
|
1339
|
+
* @param input - The PSBT input to resolve the sighash type for
|
|
1340
|
+
* @param isTaproot - Whether the input is spent as Taproot. Defaults to
|
|
1341
|
+
* detecting `tapInternalKey`; pass explicitly when the caller already knows
|
|
1342
|
+
* which signing branch it is on, so the fallback matches the hash function
|
|
1343
|
+
* actually used.
|
|
1344
|
+
* @returns The sighash type to build and encode the signature with
|
|
1345
|
+
*/ var getSigHashType = function(input) {
|
|
1346
|
+
var isTaproot = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Boolean(input.tapInternalKey);
|
|
1347
|
+
var _input_sighashType;
|
|
1348
|
+
return (_input_sighashType = input.sighashType) !== null && _input_sighashType !== void 0 ? _input_sighashType : isTaproot ? bitcoin__namespace.Transaction.SIGHASH_DEFAULT : bitcoin__namespace.Transaction.SIGHASH_ALL;
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* Throws unless every input's PSBT-declared sighash type is in the allow-list.
|
|
1353
|
+
*
|
|
1354
|
+
* Call this before any signing begins — inputs are signed in parallel, so
|
|
1355
|
+
* throwing partway through would leave a partially signed PSBT behind.
|
|
1356
|
+
*
|
|
1357
|
+
* An empty array permits nothing rather than everything: a caller whose
|
|
1358
|
+
* allow-list computes to empty must not silently get the guard disabled. Omit
|
|
1359
|
+
* the parameter entirely to permit any declared type.
|
|
1360
|
+
*
|
|
1361
|
+
* @param inputsToSign - The wallet-owned inputs about to be signed, with their PSBT indexes
|
|
1362
|
+
* @param isTaproot - Whether signing takes the Taproot branch, so the fallback
|
|
1363
|
+
* sighash type matches the hash function actually used
|
|
1364
|
+
* @param allowedSighash - Optional allow-list of permitted sighash types
|
|
1365
|
+
*/ var assertSighashAllowed = function(inputsToSign, isTaproot, allowedSighash) {
|
|
1366
|
+
if (!allowedSighash) {
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1370
|
+
try {
|
|
1371
|
+
for(var _iterator = inputsToSign[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1372
|
+
var _step_value = _step.value, input = _step_value.input, index = _step_value.index;
|
|
1373
|
+
var sigHashType = getSigHashType(input, isTaproot);
|
|
1374
|
+
if (!allowedSighash.includes(sigHashType)) {
|
|
1375
|
+
throw new Error("Input ".concat(index, " declares sighash type ").concat(sigHashType, ", which is not in allowedSighash: ").concat(allowedSighash.join(', ') || '(empty)'));
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
} catch (err) {
|
|
1379
|
+
_didIteratorError = true;
|
|
1380
|
+
_iteratorError = err;
|
|
1381
|
+
} finally{
|
|
1382
|
+
try {
|
|
1383
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1384
|
+
_iterator.return();
|
|
1385
|
+
}
|
|
1386
|
+
} finally{
|
|
1387
|
+
if (_didIteratorError) {
|
|
1388
|
+
throw _iteratorError;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
|
|
1309
1394
|
function _instanceof(left, right) {
|
|
1310
1395
|
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
1311
1396
|
return !!right[Symbol.hasInstance](left);
|
|
@@ -1412,11 +1497,13 @@ function _type_of(obj) {
|
|
|
1412
1497
|
for(var i = 0; i < psbt.inputCount; i++){
|
|
1413
1498
|
var input = psbt.data.inputs[i];
|
|
1414
1499
|
if (input.tapInternalKey) {
|
|
1415
|
-
// Taproot (BIP-341) - uses hashForWitnessV1 with
|
|
1416
|
-
|
|
1500
|
+
// Taproot (BIP-341) - uses hashForWitnessV1 with the input's declared
|
|
1501
|
+
// sighash type, defaulting to SIGHASH_DEFAULT
|
|
1502
|
+
var hash = tx.hashForWitnessV1(i, prevOutScripts, values, getSigHashType(input, true));
|
|
1417
1503
|
sighashes.push(Buffer.from(hash).toString('hex'));
|
|
1418
1504
|
} else {
|
|
1419
|
-
// Native SegWit (BIP-143) - uses hashForWitnessV0 with
|
|
1505
|
+
// Native SegWit (BIP-143) - uses hashForWitnessV0 with the input's
|
|
1506
|
+
// declared sighash type, defaulting to SIGHASH_ALL
|
|
1420
1507
|
// witnessUtxo is guaranteed to exist from collectPSBTInputData validation
|
|
1421
1508
|
var _input_witnessUtxo = input.witnessUtxo, script = _input_witnessUtxo.script, value = _input_witnessUtxo.value;
|
|
1422
1509
|
// Build P2PKH script code from the pubkey hash in the witness program
|
|
@@ -1428,7 +1515,7 @@ function _type_of(obj) {
|
|
|
1428
1515
|
if (!scriptCode) {
|
|
1429
1516
|
throw new Error("Failed to generate scriptCode for input ".concat(i));
|
|
1430
1517
|
}
|
|
1431
|
-
var hash1 = tx.hashForWitnessV0(i, scriptCode, value,
|
|
1518
|
+
var hash1 = tx.hashForWitnessV0(i, scriptCode, value, getSigHashType(input, false));
|
|
1432
1519
|
sighashes.push(Buffer.from(hash1).toString('hex'));
|
|
1433
1520
|
}
|
|
1434
1521
|
}
|
|
@@ -1470,6 +1557,7 @@ function _type_of(obj) {
|
|
|
1470
1557
|
return Buffer.from(formattedMessage).toString('hex');
|
|
1471
1558
|
};
|
|
1472
1559
|
|
|
1560
|
+
exports.assertSighashAllowed = assertSighashAllowed;
|
|
1473
1561
|
exports.calculateBip322Hash = calculateBip322Hash;
|
|
1474
1562
|
exports.calculateTaprootTweak = calculateTaprootTweak;
|
|
1475
1563
|
exports.collectPSBTInputData = collectPSBTInputData;
|
|
@@ -1489,6 +1577,7 @@ exports.getBitcoinNetwork = getBitcoinNetwork;
|
|
|
1489
1577
|
exports.getDefaultRpcUrl = getDefaultRpcUrl;
|
|
1490
1578
|
exports.getFeeRates = getFeeRates;
|
|
1491
1579
|
exports.getPublicKeyFromPrivateKey = getPublicKeyFromPrivateKey;
|
|
1580
|
+
exports.getSigHashType = getSigHashType;
|
|
1492
1581
|
exports.getUTXOs = getUTXOs;
|
|
1493
1582
|
exports.initEccLib = initEccLib;
|
|
1494
1583
|
exports.normalizeForCompressed = normalizeForCompressed;
|
package/index.esm.js
CHANGED
|
@@ -706,8 +706,12 @@ function _instanceof$3(left, right) {
|
|
|
706
706
|
* Converts an ECDSA signature to DER format
|
|
707
707
|
*
|
|
708
708
|
* @param signature - The ECDSA signature
|
|
709
|
+
* @param sighashType - The sighash type to append as the DER trailing byte.
|
|
710
|
+
* Must match the type the signing hash was built with, or the signature will
|
|
711
|
+
* fail verification at finalize/broadcast. Defaults to SIGHASH_ALL.
|
|
709
712
|
* @returns The DER encoded signature
|
|
710
713
|
*/ var convertSignatureToDER = function(signature) {
|
|
714
|
+
var sighashType = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : bitcoin.Transaction.SIGHASH_ALL;
|
|
711
715
|
var r = _instanceof$3(signature.r, Uint8Array) ? signature.r : new Uint8Array(signature.r);
|
|
712
716
|
var s = _instanceof$3(signature.s, Uint8Array) ? signature.s : new Uint8Array(signature.s);
|
|
713
717
|
var r32 = new Uint8Array(32);
|
|
@@ -719,7 +723,7 @@ function _instanceof$3(left, right) {
|
|
|
719
723
|
var rawSignature = new Uint8Array(64);
|
|
720
724
|
rawSignature.set(r32, 0);
|
|
721
725
|
rawSignature.set(s32, 32);
|
|
722
|
-
var derSignature = bitcoin.script.signature.encode(rawSignature,
|
|
726
|
+
var derSignature = bitcoin.script.signature.encode(rawSignature, sighashType);
|
|
723
727
|
return derSignature;
|
|
724
728
|
};
|
|
725
729
|
|
|
@@ -1190,19 +1194,34 @@ function _instanceof$2(left, right) {
|
|
|
1190
1194
|
* Converts a signature to a Buffer format suitable for Taproot (BIP340/Schnorr)
|
|
1191
1195
|
*
|
|
1192
1196
|
* @param signature - The signature from MPC (can be Uint8Array, Buffer, or EcdsaSignature object)
|
|
1193
|
-
* @
|
|
1197
|
+
* @param sighashType - The sighash type the signing hash was built with. Per
|
|
1198
|
+
* BIP-341 the signature stays 64 bytes for SIGHASH_DEFAULT and gains the
|
|
1199
|
+
* sighash type as a 65th byte for any other type. Defaults to SIGHASH_DEFAULT.
|
|
1200
|
+
* @returns A Buffer containing the 64-byte (or 65-byte) Schnorr signature
|
|
1194
1201
|
*/ var convertSignatureToTaprootBuffer = function(signature) {
|
|
1202
|
+
var sighashType = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : bitcoin.Transaction.SIGHASH_DEFAULT;
|
|
1203
|
+
var schnorrSignature;
|
|
1195
1204
|
if (_instanceof$2(signature, Uint8Array) || Buffer.isBuffer(signature)) {
|
|
1196
|
-
|
|
1205
|
+
schnorrSignature = Buffer.from(signature);
|
|
1206
|
+
} else {
|
|
1207
|
+
var r = signature.r;
|
|
1208
|
+
var s = signature.s;
|
|
1209
|
+
var rBuf = Buffer.isBuffer(r) ? r : Buffer.from(r);
|
|
1210
|
+
var sBuf = Buffer.isBuffer(s) ? s : Buffer.from(s);
|
|
1211
|
+
// Safe: creates Uint8Array views over Buffer's underlying memory without copying
|
|
1212
|
+
schnorrSignature = Buffer.concat([
|
|
1213
|
+
new Uint8Array(rBuf),
|
|
1214
|
+
new Uint8Array(sBuf)
|
|
1215
|
+
]);
|
|
1216
|
+
}
|
|
1217
|
+
if (sighashType === bitcoin.Transaction.SIGHASH_DEFAULT) {
|
|
1218
|
+
return schnorrSignature;
|
|
1197
1219
|
}
|
|
1198
|
-
var r = signature.r;
|
|
1199
|
-
var s = signature.s;
|
|
1200
|
-
var rBuf = Buffer.isBuffer(r) ? r : Buffer.from(r);
|
|
1201
|
-
var sBuf = Buffer.isBuffer(s) ? s : Buffer.from(s);
|
|
1202
|
-
// Safe: creates Uint8Array views over Buffer's underlying memory without copying
|
|
1203
1220
|
return Buffer.concat([
|
|
1204
|
-
new Uint8Array(
|
|
1205
|
-
new Uint8Array(
|
|
1221
|
+
new Uint8Array(schnorrSignature),
|
|
1222
|
+
new Uint8Array([
|
|
1223
|
+
sighashType
|
|
1224
|
+
])
|
|
1206
1225
|
]);
|
|
1207
1226
|
};
|
|
1208
1227
|
|
|
@@ -1286,6 +1305,72 @@ function _instanceof$1(left, right) {
|
|
|
1286
1305
|
}
|
|
1287
1306
|
};
|
|
1288
1307
|
|
|
1308
|
+
/**
|
|
1309
|
+
* Resolves the sighash type for a PSBT input.
|
|
1310
|
+
*
|
|
1311
|
+
* The type is read from the PSBT itself (BIP-174 `PSBT_IN_SIGHASH_TYPE`), never
|
|
1312
|
+
* supplied by the caller — the signing hash and the policy layer's verification
|
|
1313
|
+
* hash must be derived from the same bytes, or every non-default signature
|
|
1314
|
+
* would be rejected as tampered.
|
|
1315
|
+
*
|
|
1316
|
+
* When the input declares nothing, falls back to the historical default:
|
|
1317
|
+
* SIGHASH_DEFAULT (0x00) for Taproot, SIGHASH_ALL (0x01) otherwise.
|
|
1318
|
+
*
|
|
1319
|
+
* @param input - The PSBT input to resolve the sighash type for
|
|
1320
|
+
* @param isTaproot - Whether the input is spent as Taproot. Defaults to
|
|
1321
|
+
* detecting `tapInternalKey`; pass explicitly when the caller already knows
|
|
1322
|
+
* which signing branch it is on, so the fallback matches the hash function
|
|
1323
|
+
* actually used.
|
|
1324
|
+
* @returns The sighash type to build and encode the signature with
|
|
1325
|
+
*/ var getSigHashType = function(input) {
|
|
1326
|
+
var isTaproot = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Boolean(input.tapInternalKey);
|
|
1327
|
+
var _input_sighashType;
|
|
1328
|
+
return (_input_sighashType = input.sighashType) !== null && _input_sighashType !== void 0 ? _input_sighashType : isTaproot ? bitcoin.Transaction.SIGHASH_DEFAULT : bitcoin.Transaction.SIGHASH_ALL;
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Throws unless every input's PSBT-declared sighash type is in the allow-list.
|
|
1333
|
+
*
|
|
1334
|
+
* Call this before any signing begins — inputs are signed in parallel, so
|
|
1335
|
+
* throwing partway through would leave a partially signed PSBT behind.
|
|
1336
|
+
*
|
|
1337
|
+
* An empty array permits nothing rather than everything: a caller whose
|
|
1338
|
+
* allow-list computes to empty must not silently get the guard disabled. Omit
|
|
1339
|
+
* the parameter entirely to permit any declared type.
|
|
1340
|
+
*
|
|
1341
|
+
* @param inputsToSign - The wallet-owned inputs about to be signed, with their PSBT indexes
|
|
1342
|
+
* @param isTaproot - Whether signing takes the Taproot branch, so the fallback
|
|
1343
|
+
* sighash type matches the hash function actually used
|
|
1344
|
+
* @param allowedSighash - Optional allow-list of permitted sighash types
|
|
1345
|
+
*/ var assertSighashAllowed = function(inputsToSign, isTaproot, allowedSighash) {
|
|
1346
|
+
if (!allowedSighash) {
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1350
|
+
try {
|
|
1351
|
+
for(var _iterator = inputsToSign[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1352
|
+
var _step_value = _step.value, input = _step_value.input, index = _step_value.index;
|
|
1353
|
+
var sigHashType = getSigHashType(input, isTaproot);
|
|
1354
|
+
if (!allowedSighash.includes(sigHashType)) {
|
|
1355
|
+
throw new Error("Input ".concat(index, " declares sighash type ").concat(sigHashType, ", which is not in allowedSighash: ").concat(allowedSighash.join(', ') || '(empty)'));
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
} catch (err) {
|
|
1359
|
+
_didIteratorError = true;
|
|
1360
|
+
_iteratorError = err;
|
|
1361
|
+
} finally{
|
|
1362
|
+
try {
|
|
1363
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1364
|
+
_iterator.return();
|
|
1365
|
+
}
|
|
1366
|
+
} finally{
|
|
1367
|
+
if (_didIteratorError) {
|
|
1368
|
+
throw _iteratorError;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
|
|
1289
1374
|
function _instanceof(left, right) {
|
|
1290
1375
|
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
1291
1376
|
return !!right[Symbol.hasInstance](left);
|
|
@@ -1392,11 +1477,13 @@ function _type_of(obj) {
|
|
|
1392
1477
|
for(var i = 0; i < psbt.inputCount; i++){
|
|
1393
1478
|
var input = psbt.data.inputs[i];
|
|
1394
1479
|
if (input.tapInternalKey) {
|
|
1395
|
-
// Taproot (BIP-341) - uses hashForWitnessV1 with
|
|
1396
|
-
|
|
1480
|
+
// Taproot (BIP-341) - uses hashForWitnessV1 with the input's declared
|
|
1481
|
+
// sighash type, defaulting to SIGHASH_DEFAULT
|
|
1482
|
+
var hash = tx.hashForWitnessV1(i, prevOutScripts, values, getSigHashType(input, true));
|
|
1397
1483
|
sighashes.push(Buffer.from(hash).toString('hex'));
|
|
1398
1484
|
} else {
|
|
1399
|
-
// Native SegWit (BIP-143) - uses hashForWitnessV0 with
|
|
1485
|
+
// Native SegWit (BIP-143) - uses hashForWitnessV0 with the input's
|
|
1486
|
+
// declared sighash type, defaulting to SIGHASH_ALL
|
|
1400
1487
|
// witnessUtxo is guaranteed to exist from collectPSBTInputData validation
|
|
1401
1488
|
var _input_witnessUtxo = input.witnessUtxo, script = _input_witnessUtxo.script, value = _input_witnessUtxo.value;
|
|
1402
1489
|
// Build P2PKH script code from the pubkey hash in the witness program
|
|
@@ -1408,7 +1495,7 @@ function _type_of(obj) {
|
|
|
1408
1495
|
if (!scriptCode) {
|
|
1409
1496
|
throw new Error("Failed to generate scriptCode for input ".concat(i));
|
|
1410
1497
|
}
|
|
1411
|
-
var hash1 = tx.hashForWitnessV0(i, scriptCode, value,
|
|
1498
|
+
var hash1 = tx.hashForWitnessV0(i, scriptCode, value, getSigHashType(input, false));
|
|
1412
1499
|
sighashes.push(Buffer.from(hash1).toString('hex'));
|
|
1413
1500
|
}
|
|
1414
1501
|
}
|
|
@@ -1450,4 +1537,4 @@ function _type_of(obj) {
|
|
|
1450
1537
|
return Buffer.from(formattedMessage).toString('hex');
|
|
1451
1538
|
};
|
|
1452
1539
|
|
|
1453
|
-
export { calculateBip322Hash, calculateTaprootTweak, collectPSBTInputData, computeBip322HashHex, convertSignatureToDER, convertSignatureToTaprootBuffer, createLegacyAddress, createNativeSegWitAddress, createSegWitAddress, createTaprootAddress, doesInputBelongToAddress, encodeBip322Signature, extractPsbtSighashes, extractPublicKeyHex, getAddressTypeFromDerivationPath, getBitcoinNetwork, getDefaultRpcUrl, getFeeRates, getPublicKeyFromPrivateKey, getUTXOs, initEccLib, normalizeForCompressed, normalizeForTaproot, normalizePublicKey, privateKeyToWIF, publicKeyToBitcoinAddress, selectUTXOs, toBitcoinNetwork, toBuffer, wifToPrivateKey };
|
|
1540
|
+
export { assertSighashAllowed, calculateBip322Hash, calculateTaprootTweak, collectPSBTInputData, computeBip322HashHex, convertSignatureToDER, convertSignatureToTaprootBuffer, createLegacyAddress, createNativeSegWitAddress, createSegWitAddress, createTaprootAddress, doesInputBelongToAddress, encodeBip322Signature, extractPsbtSighashes, extractPublicKeyHex, getAddressTypeFromDerivationPath, getBitcoinNetwork, getDefaultRpcUrl, getFeeRates, getPublicKeyFromPrivateKey, getSigHashType, getUTXOs, initEccLib, normalizeForCompressed, normalizeForTaproot, normalizePublicKey, privateKeyToWIF, publicKeyToBitcoinAddress, selectUTXOs, toBitcoinNetwork, toBuffer, wifToPrivateKey };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/btc-utils",
|
|
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
|
-
"@dynamic-labs-wallet/core": "1.0.
|
|
8
|
+
"@dynamic-labs-wallet/core": "1.0.106",
|
|
9
9
|
"bitcoinjs-lib": "^7.0.0",
|
|
10
10
|
"bip322-js": "^3.0.0",
|
|
11
11
|
"@noble/hashes": "1.7.1",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as bitcoin from 'bitcoinjs-lib';
|
|
2
|
+
/**
|
|
3
|
+
* Throws unless every input's PSBT-declared sighash type is in the allow-list.
|
|
4
|
+
*
|
|
5
|
+
* Call this before any signing begins — inputs are signed in parallel, so
|
|
6
|
+
* throwing partway through would leave a partially signed PSBT behind.
|
|
7
|
+
*
|
|
8
|
+
* An empty array permits nothing rather than everything: a caller whose
|
|
9
|
+
* allow-list computes to empty must not silently get the guard disabled. Omit
|
|
10
|
+
* the parameter entirely to permit any declared type.
|
|
11
|
+
*
|
|
12
|
+
* @param inputsToSign - The wallet-owned inputs about to be signed, with their PSBT indexes
|
|
13
|
+
* @param isTaproot - Whether signing takes the Taproot branch, so the fallback
|
|
14
|
+
* sighash type matches the hash function actually used
|
|
15
|
+
* @param allowedSighash - Optional allow-list of permitted sighash types
|
|
16
|
+
*/
|
|
17
|
+
export declare const assertSighashAllowed: (inputsToSign: {
|
|
18
|
+
input: bitcoin.Psbt["data"]["inputs"][number];
|
|
19
|
+
index: number;
|
|
20
|
+
}[], isTaproot: boolean, allowedSighash?: number[]) => void;
|
|
21
|
+
//# sourceMappingURL=assertSighashAllowed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertSighashAllowed.d.ts","sourceRoot":"","sources":["../../src/assertSighashAllowed/assertSighashAllowed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,OAAO,MAAM,eAAe,CAAC;AAG9C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,oBAAoB,iBACjB;IAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,aACrE,OAAO,mBACD,MAAM,EAAE,KACxB,IAgBF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assertSighashAllowed/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -3,7 +3,10 @@ import type { EcdsaSignature } from '#internal/core';
|
|
|
3
3
|
* Converts an ECDSA signature to DER format
|
|
4
4
|
*
|
|
5
5
|
* @param signature - The ECDSA signature
|
|
6
|
+
* @param sighashType - The sighash type to append as the DER trailing byte.
|
|
7
|
+
* Must match the type the signing hash was built with, or the signature will
|
|
8
|
+
* fail verification at finalize/broadcast. Defaults to SIGHASH_ALL.
|
|
6
9
|
* @returns The DER encoded signature
|
|
7
10
|
*/
|
|
8
|
-
export declare const convertSignatureToDER: (signature: EcdsaSignature) => Uint8Array;
|
|
11
|
+
export declare const convertSignatureToDER: (signature: EcdsaSignature, sighashType?: number) => Uint8Array;
|
|
9
12
|
//# sourceMappingURL=convertSignatureToDER.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertSignatureToDER.d.ts","sourceRoot":"","sources":["../../src/convertSignatureToDER/convertSignatureToDER.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"convertSignatureToDER.d.ts","sourceRoot":"","sources":["../../src/convertSignatureToDER/convertSignatureToDER.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,cACrB,cAAc,gBACZ,MAAM,eAoBpB,CAAC"}
|
|
@@ -3,7 +3,10 @@ import type { EcdsaSignature } from '#internal/core';
|
|
|
3
3
|
* Converts a signature to a Buffer format suitable for Taproot (BIP340/Schnorr)
|
|
4
4
|
*
|
|
5
5
|
* @param signature - The signature from MPC (can be Uint8Array, Buffer, or EcdsaSignature object)
|
|
6
|
-
* @
|
|
6
|
+
* @param sighashType - The sighash type the signing hash was built with. Per
|
|
7
|
+
* BIP-341 the signature stays 64 bytes for SIGHASH_DEFAULT and gains the
|
|
8
|
+
* sighash type as a 65th byte for any other type. Defaults to SIGHASH_DEFAULT.
|
|
9
|
+
* @returns A Buffer containing the 64-byte (or 65-byte) Schnorr signature
|
|
7
10
|
*/
|
|
8
|
-
export declare const convertSignatureToTaprootBuffer: (signature: EcdsaSignature | Uint8Array | Buffer) => Buffer;
|
|
11
|
+
export declare const convertSignatureToTaprootBuffer: (signature: EcdsaSignature | Uint8Array | Buffer, sighashType?: number) => Buffer;
|
|
9
12
|
//# sourceMappingURL=convertSignatureToTaprootBuffer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertSignatureToTaprootBuffer.d.ts","sourceRoot":"","sources":["../../src/convertSignatureToTaprootBuffer/convertSignatureToTaprootBuffer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"convertSignatureToTaprootBuffer.d.ts","sourceRoot":"","sources":["../../src/convertSignatureToTaprootBuffer/convertSignatureToTaprootBuffer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,cAC/B,cAAc,GAAG,UAAU,GAAG,MAAM,gBAClC,MAAM,KAClB,MAmBF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractPsbtSighashes.d.ts","sourceRoot":"","sources":["../../src/extractPsbtSighashes/extractPsbtSighashes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"extractPsbtSighashes.d.ts","sourceRoot":"","sources":["../../src/extractPsbtSighashes/extractPsbtSighashes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAOhE;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,eACnB,MAAM,YACT,cAAc,GAAG,SAAS,GAAG,SAAS,KAC9C,MAAM,EA8CR,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as bitcoin from 'bitcoinjs-lib';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the sighash type for a PSBT input.
|
|
4
|
+
*
|
|
5
|
+
* The type is read from the PSBT itself (BIP-174 `PSBT_IN_SIGHASH_TYPE`), never
|
|
6
|
+
* supplied by the caller — the signing hash and the policy layer's verification
|
|
7
|
+
* hash must be derived from the same bytes, or every non-default signature
|
|
8
|
+
* would be rejected as tampered.
|
|
9
|
+
*
|
|
10
|
+
* When the input declares nothing, falls back to the historical default:
|
|
11
|
+
* SIGHASH_DEFAULT (0x00) for Taproot, SIGHASH_ALL (0x01) otherwise.
|
|
12
|
+
*
|
|
13
|
+
* @param input - The PSBT input to resolve the sighash type for
|
|
14
|
+
* @param isTaproot - Whether the input is spent as Taproot. Defaults to
|
|
15
|
+
* detecting `tapInternalKey`; pass explicitly when the caller already knows
|
|
16
|
+
* which signing branch it is on, so the fallback matches the hash function
|
|
17
|
+
* actually used.
|
|
18
|
+
* @returns The sighash type to build and encode the signature with
|
|
19
|
+
*/
|
|
20
|
+
export declare const getSigHashType: (input: bitcoin.Psbt["data"]["inputs"][number], isTaproot?: boolean) => number;
|
|
21
|
+
//# sourceMappingURL=getSigHashType.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSigHashType.d.ts","sourceRoot":"","sources":["../../src/getSigHashType/getSigHashType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,eAAe,CAAC;AAEzC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,UAClB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,0BAE5C,MAAkH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/getSigHashType/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
package/src/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export { convertSignatureToTaprootBuffer } from './convertSignatureToTaprootBuff
|
|
|
16
16
|
export { collectPSBTInputData } from './collectPSBTInputData/index.js';
|
|
17
17
|
export { doesInputBelongToAddress } from './doesInputBelongToAddress/index.js';
|
|
18
18
|
export { getBitcoinNetwork } from './getBitcoinNetwork/index.js';
|
|
19
|
+
export { getSigHashType } from './getSigHashType/index.js';
|
|
20
|
+
export { assertSighashAllowed } from './assertSighashAllowed/index.js';
|
|
19
21
|
export { initEccLib } from './initEccLib/index.js';
|
|
20
22
|
export { extractPublicKeyHex } from './extractPublicKeyHex/index.js';
|
|
21
23
|
export type { UTXO } from './types.js';
|
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAGvE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AAC7F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAGvE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC"}
|