@bigmi/core
Version:
TypeScript library for Bitcoin apps.
120 lines • 3.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUTXOAddress = exports.UTXOAddressType = exports.UTXONetwork = void 0;
const sha256_1 = require("@noble/hashes/sha256");
const bech32_1 = require("bech32");
const bs58_1 = require("bs58");
var UTXONetwork;
(function (UTXONetwork) {
UTXONetwork["Mainnet"] = "mainnet";
UTXONetwork["Testnet"] = "testnet";
UTXONetwork["Regtest"] = "regtest";
})(UTXONetwork || (exports.UTXONetwork = UTXONetwork = {}));
var UTXOAddressType;
(function (UTXOAddressType) {
UTXOAddressType["p2pkh"] = "p2pkh";
UTXOAddressType["p2sh"] = "p2sh";
UTXOAddressType["p2wpkh"] = "p2wpkh";
UTXOAddressType["p2wsh"] = "p2wsh";
UTXOAddressType["p2tr"] = "p2tr";
})(UTXOAddressType || (exports.UTXOAddressType = UTXOAddressType = {}));
const addressTypes = {
0: {
type: UTXOAddressType.p2pkh,
network: UTXONetwork.Mainnet,
},
111: {
type: UTXOAddressType.p2pkh,
network: UTXONetwork.Testnet,
},
5: {
type: UTXOAddressType.p2sh,
network: UTXONetwork.Mainnet,
},
196: {
type: UTXOAddressType.p2sh,
network: UTXONetwork.Testnet,
},
};
const parseBech32 = (address) => {
let decoded;
try {
if (address.startsWith('bc1p') ||
address.startsWith('tb1p') ||
address.startsWith('bcrt1p')) {
decoded = bech32_1.bech32m.decode(address);
}
else {
decoded = bech32_1.bech32.decode(address);
}
}
catch (_error) {
throw new Error('Invalid address');
}
const mapPrefixToNetwork = {
bc: UTXONetwork.Mainnet,
tb: UTXONetwork.Testnet,
bcrt: UTXONetwork.Regtest,
};
const network = mapPrefixToNetwork[decoded.prefix];
if (network === undefined) {
throw new Error('Invalid address');
}
const witnessVersion = decoded.words[0];
if (witnessVersion < 0 || witnessVersion > 16) {
throw new Error('Invalid address');
}
const data = bech32_1.bech32.fromWords(decoded.words.slice(1));
let type;
if (data.length === 20) {
type = UTXOAddressType.p2wpkh;
}
else if (witnessVersion === 1) {
type = UTXOAddressType.p2tr;
}
else {
type = UTXOAddressType.p2wsh;
}
return {
bech32: true,
network,
address,
type,
};
};
const getUTXOAddress = (address) => {
let decoded;
const prefix = address.substring(0, 2).toLowerCase();
if (prefix === 'bc' || prefix === 'tb') {
return parseBech32(address);
}
try {
decoded = bs58_1.default.decode(address);
}
catch (_error) {
throw new Error('Invalid address');
}
const { length } = decoded;
if (length !== 25) {
throw new Error('Invalid address');
}
const version = decoded[0];
const checksum = decoded.slice(length - 4, length);
const body = decoded.slice(0, length - 4);
const expectedChecksum = (0, sha256_1.sha256)((0, sha256_1.sha256)(body)).slice(0, 4);
if (checksum.some((value, index) => value !== expectedChecksum[index])) {
throw new Error('Invalid address');
}
const validVersions = Object.keys(addressTypes).map(Number);
if (!validVersions.includes(version)) {
throw new Error('Invalid address');
}
const addressType = addressTypes[version];
return {
...addressType,
address,
bech32: false,
};
};
exports.getUTXOAddress = getUTXOAddress;
//# sourceMappingURL=getUTXOAddress.js.map