UNPKG

@bigmi/core

Version:

TypeScript library for Bitcoin apps.

139 lines 4.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAddressChainId = exports.getAddressInfo = void 0; const sha256_1 = require("@noble/hashes/sha256"); const bech32_1 = require("bech32"); const bs58_1 = require("bs58"); const address_js_1 = require("../types/address.js"); const chain_js_1 = require("../types/chain.js"); const addressTypes = { 0: { type: address_js_1.AddressType.p2pkh, network: chain_js_1.Network.Mainnet, }, 111: { type: address_js_1.AddressType.p2pkh, network: chain_js_1.Network.Testnet, }, 5: { type: address_js_1.AddressType.p2sh, network: chain_js_1.Network.Mainnet, }, 196: { type: address_js_1.AddressType.p2sh, network: chain_js_1.Network.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: chain_js_1.Network.Mainnet, tb: chain_js_1.Network.Testnet, bcrt: chain_js_1.Network.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 = address_js_1.AddressType.p2wpkh; } else if (witnessVersion === 1) { type = address_js_1.AddressType.p2tr; } else { type = address_js_1.AddressType.p2wsh; } const purpose = getAddressPurpose(type); return { bech32: true, network, address, type, purpose, }; }; const getAddressInfo = (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, purpose: getAddressPurpose(addressType.type), }; }; exports.getAddressInfo = getAddressInfo; const getAddressPurpose = (type) => { switch (type) { case address_js_1.AddressType.p2tr: return 'ordinals'; case address_js_1.AddressType.p2wsh: return 'stacks'; case address_js_1.AddressType.p2wpkh: case address_js_1.AddressType.p2sh: case address_js_1.AddressType.p2pkh: return 'payment'; default: throw new Error('Invalid address type'); } }; const getAddressChainId = (address) => { const addressInfo = (0, exports.getAddressInfo)(address); switch (addressInfo.network) { case chain_js_1.Network.Mainnet: return chain_js_1.ChainId.BITCOIN_MAINNET; case chain_js_1.Network.Testnet: return chain_js_1.ChainId.BITCOIN_TESTNET; case chain_js_1.Network.Regtest: return chain_js_1.ChainId.BITCOIN_SIGNET; default: return chain_js_1.ChainId.BITCOIN_MAINNET; } }; exports.getAddressChainId = getAddressChainId; //# sourceMappingURL=getAddressInfo.js.map