UNPKG

bitcoin-tx-lib

Version:

A Typescript library for building and signing Bitcoin transactions

193 lines 7.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBytesCount = exports.numberToVarTnt = exports.isEqual = exports.mergeUint8Arrays = exports.reverseHexLE = exports.hash160ToScript = exports.numberToHexLE = exports.numberToHex = exports.reverseEndian = exports.checksum = exports.ripemd160 = exports.hash256 = exports.sha256 = exports.hexToBytes = exports.bytesToHex = void 0; const opcodes_1 = require("../constants/opcodes"); const ripemd160_1 = require("@noble/hashes/ripemd160"); const sha256_1 = require("@noble/hashes/sha256"); function bytesToHex(bytes) { if (bytes.length <= 0) throw new Error("The byte array is empty!"); if (typeof (bytes) == "string") throw new Error("Expected the type Uint8Array"); let hexValue = ""; bytes.forEach(byte => { let hexNumber = byte.toString(16); if (hexNumber.length == 1) hexNumber = "0" + hexNumber; hexValue += hexNumber; }); return hexValue; } exports.bytesToHex = bytesToHex; function hexToBytes(hex, hexadecimal = true) { if (hex.length <= 0) throw new Error("hex value is empty"); if (hexadecimal && hex.length % 2 !== 0) throw new Error("Invalid hex value!"); let bytes = new Uint8Array(hexadecimal ? hex.length / 2 : hex.length); for (let i = 0; i <= hex.length; i += hexadecimal ? 2 : 1) { if (hexadecimal) bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); else bytes[i] = hex.charCodeAt(i); } return bytes; } exports.hexToBytes = hexToBytes; function sha256(messageHash, hash256 = false) { let data = messageHash; if (typeof (messageHash) !== "object") data = hexToBytes(messageHash); let hash = (0, sha256_1.sha256)(data); // if is a hash256 return sha256(sha256(content)) (doc: https://en.bitcoin.it/wiki/BIP_0174) if (hash256) hash = (0, sha256_1.sha256)(hash); if (typeof (messageHash) == "string") return bytesToHex(hash); return hash; } exports.sha256 = sha256; function hash256(message) { let data = message; if (typeof (message) !== "object") data = hexToBytes(message); const hash = (0, sha256_1.sha256)((0, sha256_1.sha256)(data)); if (typeof (message) == "string") return bytesToHex(hash); return hash; } exports.hash256 = hash256; function ripemd160(messageHash, address = false) { let data = messageHash; if (typeof (messageHash) !== "object") data = hexToBytes(messageHash); let hash = address ? sha256(data) : data; hash = (0, ripemd160_1.ripemd160)(hash); if (typeof (messageHash) == "string") return bytesToHex(hash); return hash; } exports.ripemd160 = ripemd160; function checksum(messageHash, bytes = 4) { let data = messageHash; if (typeof (messageHash) !== "object") data = hexToBytes(messageHash); // generate the hash256(sha256(content)) and return first 4 bytes (doc: https://en.bitcoin.it/wiki/BIP_0174) let hash = (0, sha256_1.sha256)(data); hash = (0, sha256_1.sha256)(hash).slice(0, bytes); //.substring(0, bytes * 2) if (typeof (messageHash) == "string") return bytesToHex(hash); return hash; } exports.checksum = checksum; function reverseEndian(hex) { if (typeof (hex) == "object") return hex.reverse(); let hexLE = ""; for (let i = hex.length; i > 0; i -= 2) hexLE += hex[i - 2] + hex[i - 1]; return hexLE; } exports.reverseEndian = reverseEndian; function numberToHex(number = 0, bits = 64, result = "hex") { let hexValue = number.toString(16); // string hexadecimal if (hexValue.length == 1) hexValue = "0" + hexValue; for (let i = hexValue.length; i < bits / 4; i++) { hexValue = "0" + hexValue; } if (result == "hex") return hexValue; return hexToBytes(hexValue); } exports.numberToHex = numberToHex; // Convert a integer number in Uint8Array(16) // 64 bits little-endian function numberToHexLE(number = 0, bits = 64, result = "hex") { bits = bits < 8 ? 8 : bits; let hexValue = number.toString(16); // string hexadecimal for (let i = hexValue.length; i < bits / 4; i++) hexValue = "0" + hexValue; if (result == "hex") return reverseEndian(hexValue); return hexToBytes(hexValue).reverse(); } exports.numberToHexLE = numberToHexLE; function hash160ToScript(hash160) { let data = hash160; if (typeof (hash160) !== "object") data = hexToBytes(hash160); let hash160Length = data.length; // 0x14 == 20 && 0x20 == 34 // OP_DUP+OP_HASH160+PK_HASH_LENGTH+PUBKEY_HASH+OP_EQUALVERIFY+OP_CHECKSIG let hexScript = mergeUint8Arrays(new Uint8Array([ opcodes_1.OP_CODES.OP_DUP, opcodes_1.OP_CODES.OP_HASH160, hash160Length ]), data, new Uint8Array([ opcodes_1.OP_CODES.OP_EQUALVERIFY, opcodes_1.OP_CODES.OP_CHECKSIG ])); if (typeof (hash160) == "string") return bytesToHex(hexScript); return hexScript; } exports.hash160ToScript = hash160ToScript; function reverseHexLE(hex, isBytes = true) { if (isBytes && hex.length <= 0) throw new Error("Invalid hex value!"); if (typeof (hex) == "object") return hex.reverse(); let hexLE = ''; for (let i = hex.length; i > 0; i -= 2) hexLE += hex[i - 2] + hex[i - 1]; // return hexadecimal bytes in little-endian return hexLE; } exports.reverseHexLE = reverseHexLE; function mergeUint8Arrays(...arrays) { let length = arrays.reduce((sum, e) => sum + e.length, 0); let mergeArray = new Uint8Array(length); arrays.forEach((array, index, arrays) => { let offset = arrays.slice(0, index).reduce((acc, e) => acc + e.length, 0); mergeArray.set(array, offset); }); return mergeArray; } exports.mergeUint8Arrays = mergeUint8Arrays; function isEqual(...arrays) { let result = true; arrays.forEach((arr, index, arrays) => { if (index < arrays.length - 1) { if (arr.toString() !== arrays[arrays.length - 1].toString()) result = false; } }); return result; } exports.isEqual = isEqual; function numberToVarTnt(value, resultType = "hex") { let result; if (value < 0xfd) { result = new Uint8Array([value]); } else if (value <= 0xffff) { var number = numberToHexLE(value, 16, "bytes"); result = mergeUint8Arrays(new Uint8Array([0xfd]), number); } else if (value <= 0xffffffff) { let number = numberToHexLE(value, 32, "bytes"); result = mergeUint8Arrays(new Uint8Array([0xfe]), number); } else { let number = numberToHexLE(value, 64, "bytes"); result = mergeUint8Arrays(new Uint8Array([0xff]), number); } if (resultType == "hex") return bytesToHex(result); return result; } exports.numberToVarTnt = numberToVarTnt; function getBytesCount(hex) { return hex.length / 2; } exports.getBytesCount = getBytesCount; //# sourceMappingURL=index.js.map