@dynamic-labs-wallet/btc-utils 0.0.261 → 0.0.263
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.js +205 -0
- package/index.esm.js +196 -1
- package/package.json +2 -2
- package/src/computeBip322HashHex/computeBip322HashHex.d.ts +17 -0
- package/src/computeBip322HashHex/computeBip322HashHex.d.ts.map +1 -0
- package/src/computeBip322HashHex/index.d.ts +2 -0
- package/src/computeBip322HashHex/index.d.ts.map +1 -0
- package/src/extractPsbtSighashes/extractPsbtSighashes.d.ts +11 -0
- package/src/extractPsbtSighashes/extractPsbtSighashes.d.ts.map +1 -0
- package/src/extractPsbtSighashes/index.d.ts +2 -0
- package/src/extractPsbtSighashes/index.d.ts.map +1 -0
- package/src/index.d.ts +10 -0
- package/src/index.d.ts.map +1 -1
- package/src/toBitcoinAddressType/index.d.ts +2 -0
- package/src/toBitcoinAddressType/index.d.ts.map +1 -0
- package/src/toBitcoinAddressType/toBitcoinAddressType.d.ts +10 -0
- package/src/toBitcoinAddressType/toBitcoinAddressType.d.ts.map +1 -0
- package/src/toBitcoinNetwork/index.d.ts +2 -0
- package/src/toBitcoinNetwork/index.d.ts.map +1 -0
- package/src/toBitcoinNetwork/toBitcoinNetwork.d.ts +10 -0
- package/src/toBitcoinNetwork/toBitcoinNetwork.d.ts.map +1 -0
package/index.cjs.js
CHANGED
|
@@ -1319,13 +1319,214 @@ function _type_of(obj) {
|
|
|
1319
1319
|
throw new Error('Invalid public key format');
|
|
1320
1320
|
};
|
|
1321
1321
|
|
|
1322
|
+
/**
|
|
1323
|
+
* Creates a legacy P2PKH address
|
|
1324
|
+
*
|
|
1325
|
+
* @param pubKey - The public key
|
|
1326
|
+
* @param networkName - The network name
|
|
1327
|
+
* @returns The legacy P2PKH address
|
|
1328
|
+
*/ var createLegacyAddress = function(pubKey, networkName) {
|
|
1329
|
+
var network = getBitcoinNetwork(networkName);
|
|
1330
|
+
var compressedPubKey = normalizeForCompressed(pubKey);
|
|
1331
|
+
var address = bitcoin.payments.p2pkh({
|
|
1332
|
+
pubkey: compressedPubKey,
|
|
1333
|
+
network: network
|
|
1334
|
+
}).address;
|
|
1335
|
+
return address || '';
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* Creates a SegWit P2SH-P2WPKH address
|
|
1340
|
+
*
|
|
1341
|
+
* @param pubKey - The public key
|
|
1342
|
+
* @param networkName - The network name
|
|
1343
|
+
* @returns The SegWit address
|
|
1344
|
+
*/ var createSegWitAddress = function(pubKey, networkName) {
|
|
1345
|
+
var network = getBitcoinNetwork(networkName);
|
|
1346
|
+
var compressedPubKey = normalizeForCompressed(pubKey);
|
|
1347
|
+
var address = bitcoin.payments.p2sh({
|
|
1348
|
+
redeem: bitcoin.payments.p2wpkh({
|
|
1349
|
+
pubkey: compressedPubKey,
|
|
1350
|
+
network: network
|
|
1351
|
+
}),
|
|
1352
|
+
network: network
|
|
1353
|
+
}).address;
|
|
1354
|
+
return address || '';
|
|
1355
|
+
};
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* Converts a string network identifier to a BitcoinNetwork enum value.
|
|
1359
|
+
* If the input is already a BitcoinNetwork enum, it is returned as-is.
|
|
1360
|
+
*
|
|
1361
|
+
* @param network - BitcoinNetwork enum or 'mainnet' | 'testnet' string
|
|
1362
|
+
* @returns The corresponding BitcoinNetwork enum value
|
|
1363
|
+
*/ var toBitcoinNetwork = function(network) {
|
|
1364
|
+
if (typeof network !== 'string') {
|
|
1365
|
+
return network;
|
|
1366
|
+
}
|
|
1367
|
+
if (network === 'testnet') {
|
|
1368
|
+
return core.BitcoinNetwork.TESTNET;
|
|
1369
|
+
}
|
|
1370
|
+
return core.BitcoinNetwork.MAINNET;
|
|
1371
|
+
};
|
|
1372
|
+
|
|
1373
|
+
/**
|
|
1374
|
+
* Extracts sighashes from a PSBT for validation.
|
|
1375
|
+
* This is used to verify that the message being signed matches the PSBT context.
|
|
1376
|
+
*
|
|
1377
|
+
* @param psbtBase64 - PSBT in base64 format
|
|
1378
|
+
* @param network - 'mainnet' or 'testnet' or BitcoinNetwork enum (defaults to 'mainnet')
|
|
1379
|
+
* @returns Array of sighash hex strings for each input
|
|
1380
|
+
*/ var extractPsbtSighashes = function(psbtBase64) {
|
|
1381
|
+
var network = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 'mainnet';
|
|
1382
|
+
// Convert string network to BitcoinNetwork enum
|
|
1383
|
+
var btcNetwork = toBitcoinNetwork(network);
|
|
1384
|
+
var bitcoinNetwork = getBitcoinNetwork(btcNetwork);
|
|
1385
|
+
var psbt = bitcoin__namespace.Psbt.fromBase64(psbtBase64, {
|
|
1386
|
+
network: bitcoinNetwork
|
|
1387
|
+
});
|
|
1388
|
+
var sighashes = [];
|
|
1389
|
+
// Get the unsigned transaction from PSBT cache
|
|
1390
|
+
var tx = psbt.__CACHE.__TX;
|
|
1391
|
+
// Collect all prevOutScripts and values for Taproot sighash calculation
|
|
1392
|
+
// Taproot (BIP-341) requires all inputs for sighash computation
|
|
1393
|
+
var _collectPSBTInputData = collectPSBTInputData(psbt), prevOutScripts = _collectPSBTInputData.prevOutScripts, values = _collectPSBTInputData.values;
|
|
1394
|
+
for(var i = 0; i < psbt.inputCount; i++){
|
|
1395
|
+
var input = psbt.data.inputs[i];
|
|
1396
|
+
if (input.tapInternalKey) {
|
|
1397
|
+
// Taproot (BIP-341) - uses hashForWitnessV1 with SIGHASH_DEFAULT
|
|
1398
|
+
var hash = tx.hashForWitnessV1(i, prevOutScripts, values, bitcoin__namespace.Transaction.SIGHASH_DEFAULT);
|
|
1399
|
+
sighashes.push(Buffer.from(hash).toString('hex'));
|
|
1400
|
+
} else {
|
|
1401
|
+
// Native SegWit (BIP-143) - uses hashForWitnessV0 with SIGHASH_ALL
|
|
1402
|
+
// witnessUtxo is guaranteed to exist from collectPSBTInputData validation
|
|
1403
|
+
var _input_witnessUtxo = input.witnessUtxo, script = _input_witnessUtxo.script, value = _input_witnessUtxo.value;
|
|
1404
|
+
// Build P2PKH script code from the pubkey hash in the witness program
|
|
1405
|
+
var p2pkh = bitcoin__namespace.payments.p2pkh({
|
|
1406
|
+
hash: toBuffer(script).subarray(2),
|
|
1407
|
+
network: bitcoinNetwork
|
|
1408
|
+
});
|
|
1409
|
+
var scriptCode = p2pkh.output;
|
|
1410
|
+
if (!scriptCode) {
|
|
1411
|
+
throw new Error("Failed to generate scriptCode for input ".concat(i));
|
|
1412
|
+
}
|
|
1413
|
+
var hash1 = tx.hashForWitnessV0(i, scriptCode, value, bitcoin__namespace.Transaction.SIGHASH_ALL);
|
|
1414
|
+
sighashes.push(Buffer.from(hash1).toString('hex'));
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
return sighashes;
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Converts a string address type identifier to a BitcoinAddressType enum value.
|
|
1422
|
+
* If the input is already a BitcoinAddressType enum, it is returned as-is.
|
|
1423
|
+
*
|
|
1424
|
+
* @param addressType - BitcoinAddressType enum or 'native_segwit' | 'taproot' string
|
|
1425
|
+
* @returns The corresponding BitcoinAddressType enum value
|
|
1426
|
+
*/ var toBitcoinAddressType = function(addressType) {
|
|
1427
|
+
if (addressType === 'native_segwit') {
|
|
1428
|
+
return core.BitcoinAddressType.NATIVE_SEGWIT;
|
|
1429
|
+
}
|
|
1430
|
+
if (addressType === 'taproot') {
|
|
1431
|
+
return core.BitcoinAddressType.TAPROOT;
|
|
1432
|
+
}
|
|
1433
|
+
return addressType;
|
|
1434
|
+
};
|
|
1435
|
+
|
|
1436
|
+
/**
|
|
1437
|
+
* Computes the BIP-322 message hash for a given message and public key,
|
|
1438
|
+
* returning the result as a hex string.
|
|
1439
|
+
*
|
|
1440
|
+
* This function implements the BIP-322 hash computation for
|
|
1441
|
+
* native_segwit and taproot address types.
|
|
1442
|
+
*
|
|
1443
|
+
* @param message - The raw message to be signed
|
|
1444
|
+
* @param publicKey - The public key (hex string, Buffer, or Uint8Array)
|
|
1445
|
+
* @param addressType - The address type (BitcoinAddressType enum or 'native_segwit', 'taproot')
|
|
1446
|
+
* @param network - BitcoinNetwork enum or 'mainnet', 'testnet' (defaults to MAINNET)
|
|
1447
|
+
* @param ecc - Optional ECC library instance
|
|
1448
|
+
* @returns The BIP-322 message hash as a hex string
|
|
1449
|
+
*/ var computeBip322HashHex = function(message, publicKey, addressType) {
|
|
1450
|
+
var network = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : core.BitcoinNetwork.MAINNET, ecc = arguments.length > 4 ? arguments[4] : void 0;
|
|
1451
|
+
// Convert string network to BitcoinNetwork enum
|
|
1452
|
+
var btcNetwork = toBitcoinNetwork(network);
|
|
1453
|
+
// Convert string addressType to enum
|
|
1454
|
+
var addressTypeEnum = toBitcoinAddressType(addressType);
|
|
1455
|
+
// Validate address type
|
|
1456
|
+
if (addressTypeEnum !== core.BitcoinAddressType.NATIVE_SEGWIT && addressTypeEnum !== core.BitcoinAddressType.TAPROOT) {
|
|
1457
|
+
throw new Error("Unsupported address type: ".concat(addressType));
|
|
1458
|
+
}
|
|
1459
|
+
// Convert publicKey to Buffer
|
|
1460
|
+
var pubKeyBuffer;
|
|
1461
|
+
if (typeof publicKey === 'string') {
|
|
1462
|
+
pubKeyBuffer = Buffer.from(publicKey.replace(/^0x/, ''), 'hex');
|
|
1463
|
+
} else {
|
|
1464
|
+
pubKeyBuffer = toBuffer(publicKey);
|
|
1465
|
+
}
|
|
1466
|
+
// Compress public key if uncompressed
|
|
1467
|
+
pubKeyBuffer = normalizeForCompressed(pubKeyBuffer);
|
|
1468
|
+
// Generate address from public key
|
|
1469
|
+
var address = publicKeyToBitcoinAddress(pubKeyBuffer, addressTypeEnum, btcNetwork, ecc);
|
|
1470
|
+
// Convert address to scriptPubKey using bip322-js
|
|
1471
|
+
var scriptPubKey = bip322Js.Address.convertAdressToScriptPubkey(address);
|
|
1472
|
+
// Create the BIP-322 to_spend transaction
|
|
1473
|
+
var toSpendTx = bip322Js.BIP322.buildToSpendTx(message, scriptPubKey);
|
|
1474
|
+
// Create the to_sign PSBT
|
|
1475
|
+
var toSignPsbt = bip322Js.BIP322.buildToSignTx(toSpendTx.getId(), scriptPubKey);
|
|
1476
|
+
// Get the transaction from the PSBT
|
|
1477
|
+
var txToSign = toSignPsbt.__CACHE.__TX;
|
|
1478
|
+
// Get bitcoinjs-lib network
|
|
1479
|
+
var bitcoinNetwork = getBitcoinNetwork(btcNetwork);
|
|
1480
|
+
// Compute sighash based on address type
|
|
1481
|
+
if (addressTypeEnum === core.BitcoinAddressType.TAPROOT) {
|
|
1482
|
+
// Taproot (BIP-341) uses hashForWitnessV1 with SIGHASH_DEFAULT
|
|
1483
|
+
var prevOutScripts = [
|
|
1484
|
+
scriptPubKey
|
|
1485
|
+
];
|
|
1486
|
+
var values = [
|
|
1487
|
+
0
|
|
1488
|
+
]; // Use number, not BigInt - BIP-322 uses 0 value
|
|
1489
|
+
var hash = txToSign.hashForWitnessV1(0, prevOutScripts, values, bitcoin__namespace.Transaction.SIGHASH_DEFAULT);
|
|
1490
|
+
return Buffer.from(hash).toString('hex');
|
|
1491
|
+
} else {
|
|
1492
|
+
// SegWit (BIP-143) uses hashForWitnessV0 with SIGHASH_ALL
|
|
1493
|
+
// Create a new transaction for signing
|
|
1494
|
+
var txToSignSegwit = new bitcoin__namespace.Transaction();
|
|
1495
|
+
txToSignSegwit.version = 0;
|
|
1496
|
+
txToSignSegwit.locktime = 0;
|
|
1497
|
+
var prevTxId = toSpendTx.getId();
|
|
1498
|
+
var prevHash = Buffer.from(prevTxId, 'hex').reverse();
|
|
1499
|
+
txToSignSegwit.addInput(prevHash, 0, 0);
|
|
1500
|
+
txToSignSegwit.addOutput(Buffer.from([
|
|
1501
|
+
0x6a
|
|
1502
|
+
]), BigInt(0));
|
|
1503
|
+
// Build P2PKH script code from pubkey
|
|
1504
|
+
var p2pkh = bitcoin__namespace.payments.p2pkh({
|
|
1505
|
+
pubkey: pubKeyBuffer,
|
|
1506
|
+
network: bitcoinNetwork
|
|
1507
|
+
});
|
|
1508
|
+
var scriptCode = p2pkh.output;
|
|
1509
|
+
if (!scriptCode) {
|
|
1510
|
+
throw new Error('Failed to generate scriptCode for BIP-322 hash');
|
|
1511
|
+
}
|
|
1512
|
+
var hash1 = txToSignSegwit.hashForWitnessV0(0, scriptCode, BigInt(0), bitcoin__namespace.Transaction.SIGHASH_ALL);
|
|
1513
|
+
return Buffer.from(hash1).toString('hex');
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1322
1517
|
exports.calculateBip322Hash = calculateBip322Hash;
|
|
1323
1518
|
exports.calculateTaprootTweak = calculateTaprootTweak;
|
|
1324
1519
|
exports.collectPSBTInputData = collectPSBTInputData;
|
|
1520
|
+
exports.computeBip322HashHex = computeBip322HashHex;
|
|
1325
1521
|
exports.convertSignatureToDER = convertSignatureToDER;
|
|
1326
1522
|
exports.convertSignatureToTaprootBuffer = convertSignatureToTaprootBuffer;
|
|
1523
|
+
exports.createLegacyAddress = createLegacyAddress;
|
|
1524
|
+
exports.createNativeSegWitAddress = createNativeSegWitAddress;
|
|
1525
|
+
exports.createSegWitAddress = createSegWitAddress;
|
|
1526
|
+
exports.createTaprootAddress = createTaprootAddress;
|
|
1327
1527
|
exports.doesInputBelongToAddress = doesInputBelongToAddress;
|
|
1328
1528
|
exports.encodeBip322Signature = encodeBip322Signature;
|
|
1529
|
+
exports.extractPsbtSighashes = extractPsbtSighashes;
|
|
1329
1530
|
exports.extractPublicKeyHex = extractPublicKeyHex;
|
|
1330
1531
|
exports.getAddressTypeFromDerivationPath = getAddressTypeFromDerivationPath;
|
|
1331
1532
|
exports.getBitcoinNetwork = getBitcoinNetwork;
|
|
@@ -1334,8 +1535,12 @@ exports.getFeeRates = getFeeRates;
|
|
|
1334
1535
|
exports.getPublicKeyFromPrivateKey = getPublicKeyFromPrivateKey;
|
|
1335
1536
|
exports.getUTXOs = getUTXOs;
|
|
1336
1537
|
exports.initEccLib = initEccLib;
|
|
1538
|
+
exports.normalizeForCompressed = normalizeForCompressed;
|
|
1539
|
+
exports.normalizeForTaproot = normalizeForTaproot;
|
|
1337
1540
|
exports.normalizePublicKey = normalizePublicKey;
|
|
1338
1541
|
exports.privateKeyToWIF = privateKeyToWIF;
|
|
1339
1542
|
exports.publicKeyToBitcoinAddress = publicKeyToBitcoinAddress;
|
|
1340
1543
|
exports.selectUTXOs = selectUTXOs;
|
|
1544
|
+
exports.toBitcoinNetwork = toBitcoinNetwork;
|
|
1545
|
+
exports.toBuffer = toBuffer;
|
|
1341
1546
|
exports.wifToPrivateKey = wifToPrivateKey;
|
package/index.esm.js
CHANGED
|
@@ -1299,4 +1299,199 @@ function _type_of(obj) {
|
|
|
1299
1299
|
throw new Error('Invalid public key format');
|
|
1300
1300
|
};
|
|
1301
1301
|
|
|
1302
|
-
|
|
1302
|
+
/**
|
|
1303
|
+
* Creates a legacy P2PKH address
|
|
1304
|
+
*
|
|
1305
|
+
* @param pubKey - The public key
|
|
1306
|
+
* @param networkName - The network name
|
|
1307
|
+
* @returns The legacy P2PKH address
|
|
1308
|
+
*/ var createLegacyAddress = function(pubKey, networkName) {
|
|
1309
|
+
var network = getBitcoinNetwork(networkName);
|
|
1310
|
+
var compressedPubKey = normalizeForCompressed(pubKey);
|
|
1311
|
+
var address = payments.p2pkh({
|
|
1312
|
+
pubkey: compressedPubKey,
|
|
1313
|
+
network: network
|
|
1314
|
+
}).address;
|
|
1315
|
+
return address || '';
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* Creates a SegWit P2SH-P2WPKH address
|
|
1320
|
+
*
|
|
1321
|
+
* @param pubKey - The public key
|
|
1322
|
+
* @param networkName - The network name
|
|
1323
|
+
* @returns The SegWit address
|
|
1324
|
+
*/ var createSegWitAddress = function(pubKey, networkName) {
|
|
1325
|
+
var network = getBitcoinNetwork(networkName);
|
|
1326
|
+
var compressedPubKey = normalizeForCompressed(pubKey);
|
|
1327
|
+
var address = payments.p2sh({
|
|
1328
|
+
redeem: payments.p2wpkh({
|
|
1329
|
+
pubkey: compressedPubKey,
|
|
1330
|
+
network: network
|
|
1331
|
+
}),
|
|
1332
|
+
network: network
|
|
1333
|
+
}).address;
|
|
1334
|
+
return address || '';
|
|
1335
|
+
};
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Converts a string network identifier to a BitcoinNetwork enum value.
|
|
1339
|
+
* If the input is already a BitcoinNetwork enum, it is returned as-is.
|
|
1340
|
+
*
|
|
1341
|
+
* @param network - BitcoinNetwork enum or 'mainnet' | 'testnet' string
|
|
1342
|
+
* @returns The corresponding BitcoinNetwork enum value
|
|
1343
|
+
*/ var toBitcoinNetwork = function(network) {
|
|
1344
|
+
if (typeof network !== 'string') {
|
|
1345
|
+
return network;
|
|
1346
|
+
}
|
|
1347
|
+
if (network === 'testnet') {
|
|
1348
|
+
return BitcoinNetwork.TESTNET;
|
|
1349
|
+
}
|
|
1350
|
+
return BitcoinNetwork.MAINNET;
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
/**
|
|
1354
|
+
* Extracts sighashes from a PSBT for validation.
|
|
1355
|
+
* This is used to verify that the message being signed matches the PSBT context.
|
|
1356
|
+
*
|
|
1357
|
+
* @param psbtBase64 - PSBT in base64 format
|
|
1358
|
+
* @param network - 'mainnet' or 'testnet' or BitcoinNetwork enum (defaults to 'mainnet')
|
|
1359
|
+
* @returns Array of sighash hex strings for each input
|
|
1360
|
+
*/ var extractPsbtSighashes = function(psbtBase64) {
|
|
1361
|
+
var network = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 'mainnet';
|
|
1362
|
+
// Convert string network to BitcoinNetwork enum
|
|
1363
|
+
var btcNetwork = toBitcoinNetwork(network);
|
|
1364
|
+
var bitcoinNetwork = getBitcoinNetwork(btcNetwork);
|
|
1365
|
+
var psbt = bitcoin.Psbt.fromBase64(psbtBase64, {
|
|
1366
|
+
network: bitcoinNetwork
|
|
1367
|
+
});
|
|
1368
|
+
var sighashes = [];
|
|
1369
|
+
// Get the unsigned transaction from PSBT cache
|
|
1370
|
+
var tx = psbt.__CACHE.__TX;
|
|
1371
|
+
// Collect all prevOutScripts and values for Taproot sighash calculation
|
|
1372
|
+
// Taproot (BIP-341) requires all inputs for sighash computation
|
|
1373
|
+
var _collectPSBTInputData = collectPSBTInputData(psbt), prevOutScripts = _collectPSBTInputData.prevOutScripts, values = _collectPSBTInputData.values;
|
|
1374
|
+
for(var i = 0; i < psbt.inputCount; i++){
|
|
1375
|
+
var input = psbt.data.inputs[i];
|
|
1376
|
+
if (input.tapInternalKey) {
|
|
1377
|
+
// Taproot (BIP-341) - uses hashForWitnessV1 with SIGHASH_DEFAULT
|
|
1378
|
+
var hash = tx.hashForWitnessV1(i, prevOutScripts, values, bitcoin.Transaction.SIGHASH_DEFAULT);
|
|
1379
|
+
sighashes.push(Buffer.from(hash).toString('hex'));
|
|
1380
|
+
} else {
|
|
1381
|
+
// Native SegWit (BIP-143) - uses hashForWitnessV0 with SIGHASH_ALL
|
|
1382
|
+
// witnessUtxo is guaranteed to exist from collectPSBTInputData validation
|
|
1383
|
+
var _input_witnessUtxo = input.witnessUtxo, script = _input_witnessUtxo.script, value = _input_witnessUtxo.value;
|
|
1384
|
+
// Build P2PKH script code from the pubkey hash in the witness program
|
|
1385
|
+
var p2pkh = bitcoin.payments.p2pkh({
|
|
1386
|
+
hash: toBuffer(script).subarray(2),
|
|
1387
|
+
network: bitcoinNetwork
|
|
1388
|
+
});
|
|
1389
|
+
var scriptCode = p2pkh.output;
|
|
1390
|
+
if (!scriptCode) {
|
|
1391
|
+
throw new Error("Failed to generate scriptCode for input ".concat(i));
|
|
1392
|
+
}
|
|
1393
|
+
var hash1 = tx.hashForWitnessV0(i, scriptCode, value, bitcoin.Transaction.SIGHASH_ALL);
|
|
1394
|
+
sighashes.push(Buffer.from(hash1).toString('hex'));
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
return sighashes;
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
/**
|
|
1401
|
+
* Converts a string address type identifier to a BitcoinAddressType enum value.
|
|
1402
|
+
* If the input is already a BitcoinAddressType enum, it is returned as-is.
|
|
1403
|
+
*
|
|
1404
|
+
* @param addressType - BitcoinAddressType enum or 'native_segwit' | 'taproot' string
|
|
1405
|
+
* @returns The corresponding BitcoinAddressType enum value
|
|
1406
|
+
*/ var toBitcoinAddressType = function(addressType) {
|
|
1407
|
+
if (addressType === 'native_segwit') {
|
|
1408
|
+
return BitcoinAddressType.NATIVE_SEGWIT;
|
|
1409
|
+
}
|
|
1410
|
+
if (addressType === 'taproot') {
|
|
1411
|
+
return BitcoinAddressType.TAPROOT;
|
|
1412
|
+
}
|
|
1413
|
+
return addressType;
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Computes the BIP-322 message hash for a given message and public key,
|
|
1418
|
+
* returning the result as a hex string.
|
|
1419
|
+
*
|
|
1420
|
+
* This function implements the BIP-322 hash computation for
|
|
1421
|
+
* native_segwit and taproot address types.
|
|
1422
|
+
*
|
|
1423
|
+
* @param message - The raw message to be signed
|
|
1424
|
+
* @param publicKey - The public key (hex string, Buffer, or Uint8Array)
|
|
1425
|
+
* @param addressType - The address type (BitcoinAddressType enum or 'native_segwit', 'taproot')
|
|
1426
|
+
* @param network - BitcoinNetwork enum or 'mainnet', 'testnet' (defaults to MAINNET)
|
|
1427
|
+
* @param ecc - Optional ECC library instance
|
|
1428
|
+
* @returns The BIP-322 message hash as a hex string
|
|
1429
|
+
*/ var computeBip322HashHex = function(message, publicKey, addressType) {
|
|
1430
|
+
var network = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : BitcoinNetwork.MAINNET, ecc = arguments.length > 4 ? arguments[4] : void 0;
|
|
1431
|
+
// Convert string network to BitcoinNetwork enum
|
|
1432
|
+
var btcNetwork = toBitcoinNetwork(network);
|
|
1433
|
+
// Convert string addressType to enum
|
|
1434
|
+
var addressTypeEnum = toBitcoinAddressType(addressType);
|
|
1435
|
+
// Validate address type
|
|
1436
|
+
if (addressTypeEnum !== BitcoinAddressType.NATIVE_SEGWIT && addressTypeEnum !== BitcoinAddressType.TAPROOT) {
|
|
1437
|
+
throw new Error("Unsupported address type: ".concat(addressType));
|
|
1438
|
+
}
|
|
1439
|
+
// Convert publicKey to Buffer
|
|
1440
|
+
var pubKeyBuffer;
|
|
1441
|
+
if (typeof publicKey === 'string') {
|
|
1442
|
+
pubKeyBuffer = Buffer.from(publicKey.replace(/^0x/, ''), 'hex');
|
|
1443
|
+
} else {
|
|
1444
|
+
pubKeyBuffer = toBuffer(publicKey);
|
|
1445
|
+
}
|
|
1446
|
+
// Compress public key if uncompressed
|
|
1447
|
+
pubKeyBuffer = normalizeForCompressed(pubKeyBuffer);
|
|
1448
|
+
// Generate address from public key
|
|
1449
|
+
var address = publicKeyToBitcoinAddress(pubKeyBuffer, addressTypeEnum, btcNetwork, ecc);
|
|
1450
|
+
// Convert address to scriptPubKey using bip322-js
|
|
1451
|
+
var scriptPubKey = Address.convertAdressToScriptPubkey(address);
|
|
1452
|
+
// Create the BIP-322 to_spend transaction
|
|
1453
|
+
var toSpendTx = BIP322.buildToSpendTx(message, scriptPubKey);
|
|
1454
|
+
// Create the to_sign PSBT
|
|
1455
|
+
var toSignPsbt = BIP322.buildToSignTx(toSpendTx.getId(), scriptPubKey);
|
|
1456
|
+
// Get the transaction from the PSBT
|
|
1457
|
+
var txToSign = toSignPsbt.__CACHE.__TX;
|
|
1458
|
+
// Get bitcoinjs-lib network
|
|
1459
|
+
var bitcoinNetwork = getBitcoinNetwork(btcNetwork);
|
|
1460
|
+
// Compute sighash based on address type
|
|
1461
|
+
if (addressTypeEnum === BitcoinAddressType.TAPROOT) {
|
|
1462
|
+
// Taproot (BIP-341) uses hashForWitnessV1 with SIGHASH_DEFAULT
|
|
1463
|
+
var prevOutScripts = [
|
|
1464
|
+
scriptPubKey
|
|
1465
|
+
];
|
|
1466
|
+
var values = [
|
|
1467
|
+
0
|
|
1468
|
+
]; // Use number, not BigInt - BIP-322 uses 0 value
|
|
1469
|
+
var hash = txToSign.hashForWitnessV1(0, prevOutScripts, values, bitcoin.Transaction.SIGHASH_DEFAULT);
|
|
1470
|
+
return Buffer.from(hash).toString('hex');
|
|
1471
|
+
} else {
|
|
1472
|
+
// SegWit (BIP-143) uses hashForWitnessV0 with SIGHASH_ALL
|
|
1473
|
+
// Create a new transaction for signing
|
|
1474
|
+
var txToSignSegwit = new bitcoin.Transaction();
|
|
1475
|
+
txToSignSegwit.version = 0;
|
|
1476
|
+
txToSignSegwit.locktime = 0;
|
|
1477
|
+
var prevTxId = toSpendTx.getId();
|
|
1478
|
+
var prevHash = Buffer.from(prevTxId, 'hex').reverse();
|
|
1479
|
+
txToSignSegwit.addInput(prevHash, 0, 0);
|
|
1480
|
+
txToSignSegwit.addOutput(Buffer.from([
|
|
1481
|
+
0x6a
|
|
1482
|
+
]), BigInt(0));
|
|
1483
|
+
// Build P2PKH script code from pubkey
|
|
1484
|
+
var p2pkh = bitcoin.payments.p2pkh({
|
|
1485
|
+
pubkey: pubKeyBuffer,
|
|
1486
|
+
network: bitcoinNetwork
|
|
1487
|
+
});
|
|
1488
|
+
var scriptCode = p2pkh.output;
|
|
1489
|
+
if (!scriptCode) {
|
|
1490
|
+
throw new Error('Failed to generate scriptCode for BIP-322 hash');
|
|
1491
|
+
}
|
|
1492
|
+
var hash1 = txToSignSegwit.hashForWitnessV0(0, scriptCode, BigInt(0), bitcoin.Transaction.SIGHASH_ALL);
|
|
1493
|
+
return Buffer.from(hash1).toString('hex');
|
|
1494
|
+
}
|
|
1495
|
+
};
|
|
1496
|
+
|
|
1497
|
+
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 };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/btc-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.263",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@dynamic-labs-wallet/core": "0.0.
|
|
8
|
+
"@dynamic-labs-wallet/core": "0.0.263",
|
|
9
9
|
"bitcoinjs-lib": "^7.0.0",
|
|
10
10
|
"bip322-js": "^3.0.0",
|
|
11
11
|
"@noble/hashes": "1.7.1",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BitcoinAddressType, BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
|
+
/**
|
|
3
|
+
* Computes the BIP-322 message hash for a given message and public key,
|
|
4
|
+
* returning the result as a hex string.
|
|
5
|
+
*
|
|
6
|
+
* This function implements the BIP-322 hash computation for
|
|
7
|
+
* native_segwit and taproot address types.
|
|
8
|
+
*
|
|
9
|
+
* @param message - The raw message to be signed
|
|
10
|
+
* @param publicKey - The public key (hex string, Buffer, or Uint8Array)
|
|
11
|
+
* @param addressType - The address type (BitcoinAddressType enum or 'native_segwit', 'taproot')
|
|
12
|
+
* @param network - BitcoinNetwork enum or 'mainnet', 'testnet' (defaults to MAINNET)
|
|
13
|
+
* @param ecc - Optional ECC library instance
|
|
14
|
+
* @returns The BIP-322 message hash as a hex string
|
|
15
|
+
*/
|
|
16
|
+
export declare const computeBip322HashHex: (message: string, publicKey: string | Buffer | Uint8Array, addressType: BitcoinAddressType | "native_segwit" | "taproot", network?: BitcoinNetwork | "mainnet" | "testnet", ecc?: any) => string;
|
|
17
|
+
//# sourceMappingURL=computeBip322HashHex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"computeBip322HashHex.d.ts","sourceRoot":"","sources":["../../src/computeBip322HashHex/computeBip322HashHex.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ/E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,YACtB,MAAM,aACJ,MAAM,GAAG,MAAM,GAAG,UAAU,eAC1B,kBAAkB,GAAG,eAAe,GAAG,SAAS,YACpD,cAAc,GAAG,SAAS,GAAG,SAAS,QACzC,GAAG,KACR,MA2FF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/computeBip322HashHex/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts sighashes from a PSBT for validation.
|
|
4
|
+
* This is used to verify that the message being signed matches the PSBT context.
|
|
5
|
+
*
|
|
6
|
+
* @param psbtBase64 - PSBT in base64 format
|
|
7
|
+
* @param network - 'mainnet' or 'testnet' or BitcoinNetwork enum (defaults to 'mainnet')
|
|
8
|
+
* @returns Array of sighash hex strings for each input
|
|
9
|
+
*/
|
|
10
|
+
export declare const extractPsbtSighashes: (psbtBase64: string, network?: BitcoinNetwork | "mainnet" | "testnet") => string[];
|
|
11
|
+
//# sourceMappingURL=extractPsbtSighashes.d.ts.map
|
|
@@ -0,0 +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;AAMhE;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,eACnB,MAAM,YACT,cAAc,GAAG,SAAS,GAAG,SAAS,KAC9C,MAAM,EAsDR,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extractPsbtSighashes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/src/index.d.ts
CHANGED
|
@@ -19,4 +19,14 @@ export { getBitcoinNetwork } from './getBitcoinNetwork/index.js';
|
|
|
19
19
|
export { initEccLib } from './initEccLib/index.js';
|
|
20
20
|
export { extractPublicKeyHex } from './extractPublicKeyHex/index.js';
|
|
21
21
|
export type { UTXO } from './types.js';
|
|
22
|
+
export { createLegacyAddress } from './createLegacyAddress/index.js';
|
|
23
|
+
export { createSegWitAddress } from './createSegWitAddress/index.js';
|
|
24
|
+
export { createNativeSegWitAddress } from './createNativeSegWitAddress/index.js';
|
|
25
|
+
export { createTaprootAddress } from './createTaprootAddress/index.js';
|
|
26
|
+
export { toBuffer } from './toBuffer/index.js';
|
|
27
|
+
export { normalizeForCompressed } from './normalizeForCompressed/index.js';
|
|
28
|
+
export { normalizeForTaproot } from './normalizeForTaproot/index.js';
|
|
29
|
+
export { toBitcoinNetwork } from './toBitcoinNetwork/index.js';
|
|
30
|
+
export { extractPsbtSighashes } from './extractPsbtSighashes/index.js';
|
|
31
|
+
export { computeBip322HashHex } from './computeBip322HashHex/index.js';
|
|
22
32
|
//# sourceMappingURL=index.d.ts.map
|
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"}
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/toBitcoinAddressType/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BitcoinAddressType } from '@dynamic-labs-wallet/core';
|
|
2
|
+
/**
|
|
3
|
+
* Converts a string address type identifier to a BitcoinAddressType enum value.
|
|
4
|
+
* If the input is already a BitcoinAddressType enum, it is returned as-is.
|
|
5
|
+
*
|
|
6
|
+
* @param addressType - BitcoinAddressType enum or 'native_segwit' | 'taproot' string
|
|
7
|
+
* @returns The corresponding BitcoinAddressType enum value
|
|
8
|
+
*/
|
|
9
|
+
export declare const toBitcoinAddressType: (addressType: BitcoinAddressType | "native_segwit" | "taproot") => BitcoinAddressType;
|
|
10
|
+
//# sourceMappingURL=toBitcoinAddressType.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBitcoinAddressType.d.ts","sourceRoot":"","sources":["../../src/toBitcoinAddressType/toBitcoinAddressType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,gBAClB,kBAAkB,GAAG,eAAe,GAAG,SAAS,KAC5D,kBAUF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/toBitcoinNetwork/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BitcoinNetwork } from '@dynamic-labs-wallet/core';
|
|
2
|
+
/**
|
|
3
|
+
* Converts a string network identifier to a BitcoinNetwork enum value.
|
|
4
|
+
* If the input is already a BitcoinNetwork enum, it is returned as-is.
|
|
5
|
+
*
|
|
6
|
+
* @param network - BitcoinNetwork enum or 'mainnet' | 'testnet' string
|
|
7
|
+
* @returns The corresponding BitcoinNetwork enum value
|
|
8
|
+
*/
|
|
9
|
+
export declare const toBitcoinNetwork: (network: BitcoinNetwork | "mainnet" | "testnet") => BitcoinNetwork;
|
|
10
|
+
//# sourceMappingURL=toBitcoinNetwork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBitcoinNetwork.d.ts","sourceRoot":"","sources":["../../src/toBitcoinNetwork/toBitcoinNetwork.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,YAClB,cAAc,GAAG,SAAS,GAAG,SAAS,KAC9C,cAUF,CAAC"}
|