PHP WebShell
Текущая директория: /opt/BitGoJS/modules/babylonlabs-io-btc-staking-ts/src/utils
Просмотр файла: btc.ts
import * as ecc from "@bitcoin-js/tiny-secp256k1-asmjs";
import { initEccLib, address, networks } from "bitcoinjs-lib";
import { NO_COORD_PK_BYTE_LENGTH } from "../constants/keys";
// Initialize elliptic curve library
export const initBTCCurve = () => {
initEccLib(ecc);
}
/**
* Check whether the given address is a valid Bitcoin address.
*
* @param {string} btcAddress - The Bitcoin address to check.
* @param {object} network - The Bitcoin network (e.g., bitcoin.networks.bitcoin).
* @returns {boolean} - True if the address is valid, otherwise false.
*/
export const isValidBitcoinAddress = (
btcAddress: string,
network: networks.Network,
): boolean => {
try {
return !!address.toOutputScript(btcAddress, network);
} catch (error) {
return false;
}
};
/**
* Check whether the given address is a Taproot address.
*
* @param {string} taprootAddress - The Bitcoin bech32 encoded address to check.
* @param {object} network - The Bitcoin network (e.g., bitcoin.networks.bitcoin).
* @returns {boolean} - True if the address is a Taproot address, otherwise false.
*/
export const isTaproot = (
taprootAddress: string,
network: networks.Network,
): boolean => {
try {
const decoded = address.fromBech32(taprootAddress);
if (decoded.version !== 1) {
return false;
}
// Compare network properties instead of object reference
// The bech32 is hardcoded in the bitcoinjs-lib library.
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/networks.ts#L36
if (network.bech32 === networks.bitcoin.bech32) {
// Check if address starts with "bc1p"
return taprootAddress.startsWith("bc1p");
} else if (network.bech32 === networks.testnet.bech32) {
// signet, regtest and testnet taproot addresses start with "tb1p" or "sb1p"
return taprootAddress.startsWith("tb1p") || taprootAddress.startsWith("sb1p");
}
return false;
} catch (error) {
return false;
}
};
/**
* Check whether the given address is a Native SegWit address.
*
* @param {string} segwitAddress - The Bitcoin bech32 encoded address to check.
* @param {object} network - The Bitcoin network (e.g., bitcoin.networks.bitcoin).
* @returns {boolean} - True if the address is a Native SegWit address, otherwise false.
*/
export const isNativeSegwit = (
segwitAddress: string,
network: networks.Network,
): boolean => {
try {
const decoded = address.fromBech32(segwitAddress);
if (decoded.version !== 0) {
return false;
}
// Compare network properties instead of object reference
// The bech32 is hardcoded in the bitcoinjs-lib library.
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/networks.ts#L36
if (network.bech32 === networks.bitcoin.bech32) {
// Check if address starts with "bc1q"
return segwitAddress.startsWith("bc1q");
} else if (network.bech32 === networks.testnet.bech32) {
// testnet native segwit addresses start with "tb1q"
return segwitAddress.startsWith("tb1q");
}
return false;
} catch (error) {
return false;
}
};
/**
* Check whether the given public key is a valid public key without a coordinate.
*
* @param {string} pkWithNoCoord - public key without the coordinate.
* @returns {boolean} - True if the public key without the coordinate is valid, otherwise false.
*/
export const isValidNoCoordPublicKey = (pkWithNoCoord: string): boolean => {
try {
const keyBuffer = Buffer.from(pkWithNoCoord, 'hex');
return validateNoCoordPublicKeyBuffer(keyBuffer);
} catch (error) {
return false;
}
}
/**
* Get the public key without the coordinate.
*
* @param {string} pkHex - The public key in hex, with or without the coordinate.
* @returns {string} - The public key without the coordinate in hex.
* @throws {Error} - If the public key is invalid.
*/
export const getPublicKeyNoCoord = (pkHex: string): String => {
const publicKey = Buffer.from(pkHex, "hex");
const publicKeyNoCoordBuffer =
publicKey.length === NO_COORD_PK_BYTE_LENGTH
? publicKey
: publicKey.subarray(1, 33);
// Validate the public key without coordinate
if (!validateNoCoordPublicKeyBuffer(publicKeyNoCoordBuffer)) {
throw new Error("Invalid public key without coordinate");
}
return publicKeyNoCoordBuffer.toString("hex");
};
const validateNoCoordPublicKeyBuffer = (pkBuffer: Buffer): boolean => {
if (pkBuffer.length !== NO_COORD_PK_BYTE_LENGTH) {
return false;
}
// Try both compressed forms: y-coordinate even (0x02) and y-coordinate odd (0x03)
const compressedKeyEven = Buffer.concat([Buffer.from([0x02]), pkBuffer]);
const compressedKeyOdd = Buffer.concat([Buffer.from([0x03]), pkBuffer]);
return (
ecc.isPoint(compressedKeyEven) || ecc.isPoint(compressedKeyOdd)
);
};
/**
* Convert a transaction id to a hash. in buffer format.
*
* @param {string} txId - The transaction id.
* @returns {Buffer} - The transaction hash.
*/
export const transactionIdToHash = (txId: string): Buffer => {
if (txId === "") {
throw new Error("Transaction id cannot be empty");
}
return Buffer.from(txId, 'hex').reverse();
};
Выполнить команду
Для локальной разработки. Не используйте в интернете!