@vbyte/btc-dev
Version:
Batteries-included toolset for plebian bitcoin development
89 lines (88 loc) • 2.49 kB
JavaScript
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;
}