UNPKG

@vbyte/btc-dev

Version:

Batteries-included toolset for plebian bitcoin development

89 lines (88 loc) 2.49 kB
import { Buff } from '@vbyte/buff'; import { is_valid_script } from '../../lib/script/decode.js'; import { TAPLEAF_VERSIONS } from '../../const.js'; export function parse_witness(witness) { const elems = witness.map(e => Buff.bytes(e)); const stack = witness.map(e => Buff.bytes(e).hex); const annex = parse_annex_data(elems); if (annex !== null) elems.pop(); const cblock = parse_cblock_data(elems); if (cblock !== null) elems.pop(); const type = parse_witness_type(elems, cblock); const version = parse_witness_version(type); const script = parse_witness_script(elems, type); if (script !== null) elems.pop(); const params = elems.map(e => e.hex); return { annex, cblock, params, script, stack, type, version }; } function parse_annex_data(data) { let elem = data.at(-1); if (data.length > 1 && elem instanceof Uint8Array && elem[0] === 0x50) { return new Buff(elem).hex; } else { return null; } } function parse_cblock_data(data) { let elem = data.at(-1); if (data.length > 1 && elem instanceof Uint8Array && elem.length > 32 && TAPLEAF_VERSIONS.includes(elem[0] & 0xfe)) { return new Buff(elem).hex; } else { return null; } } function parse_witness_script(elems, type) { let script; switch (type) { case 'p2ts': script = elems.at(-1); case 'p2wsh': script = elems.at(-1); } return (script !== undefined) ? new Buff(script).hex : null; } function parse_witness_type(elems, cblock) { let param_0 = elems.at(0), param_1 = elems.at(1), param_x = elems.at(-1); if (cblock !== null && param_x !== undefined) { return 'p2ts'; } else if (elems.length === 2 && param_0 !== undefined && param_1 !== undefined && param_0.length >= 64 && param_1.length === 33) { return 'p2wpkh'; } else if (elems.length === 1 && param_0 !== undefined && param_0.length === 64) { return 'p2tr'; } else if (elems.length > 1 && param_x !== undefined && is_valid_script(param_x)) { return 'p2wsh'; } else { return null; } } function parse_witness_version(type) { if (type === null) return null; if (type.startsWith('p2w')) return 0; if (type.startsWith('p2t')) return 1; return null; }