UNPKG

bmapjs

Version:

A transaction parser for Bitcoin data protocols like B, MAP, BAP, 1Sat Ordinals, SIGMA, METANET, and AIP/HAIP.

805 lines (804 loc) 24.6 kB
import { parse as Ee } from "bpu-ts"; import { Utils as k, Script as Se, Hash as $, Signature as R, BSM as S, BigNumber as J, PublicKey as G } from "@bsv/sdk"; import { decode as F } from "@msgpack/msgpack"; const { toArray: kt } = k, ve = (t) => t.length > 0 && t.every((e) => typeof e == "string"), xe = (t) => t.length > 0 && t.every((e) => e === "object"), x = (t, e) => { if (!t) throw new Error(`cannot get cell value of: ${t}`); return e === "string" ? t.s ? t.s : t.ls || "" : e === "hex" ? t.h ? t.h : t.lh || (t.b ? Buffer.from(t.b, "base64").toString("hex") : t.lb && Buffer.from(t.lb, "base64").toString("hex")) || "" : e === "number" ? Number.parseInt(t.h ? t.h : t.lh || "0", 16) : e === "file" ? `bitfs://${t.f ? t.f : t.lf}` : e === "binary" ? t.b || t.lb || "" : (t.b ? t.b : t.lb) || ""; }, Pe = (t) => t.cell.some((e) => e.op === 106), D = (t) => { var r; if (t.cell.length !== 2) return !1; const e = t.cell.findIndex((n) => n.op === 106); return e !== -1 ? ((r = t.cell[e - 1]) == null ? void 0 : r.op) === 0 : !1; }, w = (t, e, r) => { if (!t[e]) t[e] = [r]; else { if (!Array.isArray(t[e])) { const n = t[e]; t[e] = [], t[e][0] = n; } t[e].push(r); } }, Ae = (t, e, r, n, s) => { const o = {}, c = e.length + 1; if (n.length < c) throw new Error( `${t} requires at least ${c} fields including the prefix: ${s.tx.h}` ); for (const [a, u] of Object.entries(e)) { const f = Number.parseInt(a, 10), [d] = Object.keys(u), [l] = Object.values(u); o[d] = x(n[f + 1], l); } w(r, t, o); }, Ie = (t) => { const e = "(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+/]{3}=)?"; return new RegExp(`^${e}$`, "gi").test(t); }, $e = (t, e) => t.length === e.length && t.every((r, n) => r === e[n]), q = "OP_SIZE <OP_X_PLACEHOLDER> OP_PICK OP_SHA256 OP_SWAP OP_SPLIT OP_DROP OP_EQUALVERIFY OP_DROP OP_CHECKSIG".split( " " ), ke = (t) => { if (t.length !== 12) return !1; const e = [...t].map((s) => s.ops).splice(2, t.length), r = x(t[1], "hex"), n = Buffer.from(r).byteLength; return e[1] = `OP_${n}`, q[1] = `OP_${n}`, e.join() === q.join(); }, Be = ({ dataObj: t, cell: e, out: r }) => { if (!e[0] || !r) throw new Error("Invalid 21e8 tx. dataObj, cell, out and tx are required."); const n = x(e[0], "hex"), s = x(e[1], "hex"); if (!s) throw new Error(`Invalid 21e8 target. ${JSON.stringify(e[0], null, 2)}`); const o = Buffer.from(s, "hex").byteLength, c = { target: s, difficulty: o, value: r.e.v, txid: n }; w(t, "21E8", c); }, _ = { name: "21E8", handler: Be, scriptChecker: ke }, { toArray: y, toHex: H, fromBase58Check: V, toBase58Check: U } = k, W = "15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva", X = [ { algorithm: "string" }, { address: "string" }, { signature: "binary" }, [{ index: "number[]" }] ]; function He(t, e, r) { if (!Array.isArray(r) || r.length < 3) throw new Error("AIP requires at least 3 cells including the prefix"); let n = -1; for (let i = 0; i < r.length; i++) if ($e(r[i].cell, e)) { console.log("[validateSignature] found cell in tape"), n = i; break; } if (n === -1) throw new Error("AIP could not find cell in tape"); console.log( "[validateSignature] tape:", r.map( (i) => i.cell.map( (g) => { var h, p, v; return `c.ii: ${g.ii}, c.h: ${(h = g.h) == null ? void 0 : h.slice(0, 10)}, c.b: ${(p = g.b) == null ? void 0 : p.slice(0, 10)}, c.s: ${(v = g.s) == null ? void 0 : v.slice(0, 10)}`; } ) ) ); let s = t.index || []; const o = [], c = r.flatMap((i) => i.cell).filter((i) => i.ii !== void 0).sort((i, g) => (i.ii || 0) - (g.ii || 0)), a = c[0]; a == null || a.op, o.push(y("6a", "hex")); const u = /* @__PURE__ */ new Map(); for (const i of c) i.ii !== void 0 && u.set(i.ii, i); console.log("[validateSignature] All cells in order:"); for (const i of c) console.log(`ii: ${i.ii}, hex: ${i.h}, s: ${i.s}`); if (s.length > 0) { console.log("[validateSignature] Using indexes:", s); for (let i = 0; i < s.length; i++) { const g = s[i]; if (g === 0) continue; const h = c.find((p) => (p.ii || 0) === g); if (!h) { o.push(y("7c", "hex")); continue; } if (h.h) o.push(y(h.h, "hex")); else if (h.b) o.push(y(h.b, "base64")); else if (h.s) o.push(y(h.s)); else return console.log(`[validateSignature] No usable value found in cell with ii: ${h.ii}`), !1; } } else for (let i = 1; i < n; i++) { const g = r[i].cell; if (!D({ cell: g })) { for (const h of g) h.h ? o.push(y(h.h, "hex")) : h.b ? o.push(y(h.b, "base64")) : h.s && o.push(y(h.s)); o.push(y("7c", "hex")); } } if (t.hashing_algorithm && t.index_unit_size) { const i = t.index_unit_size * 2; s = []; const g = e[6].h; for (let h = 0; h < g.length; h += i) s.push(Number.parseInt(g.substr(h, i), 16)); t.index = s; } console.log( "[validateSignature] Final signature values:", o.map((i) => H(i)) ); let f; if (t.hashing_algorithm) { t.index_unit_size || o.shift(); const i = Se.fromHex(H(o.flat())); let g = y(i.toHex(), "hex"); t.index_unit_size && (g = g.slice(1)), f = $.sha256(g); } else f = o.flat(); const d = t.address || t.signing_address; if (!d || !t.signature) return !1; let l; try { l = R.fromCompact(t.signature, "base64"); } catch (i) { return console.log("[validateSignature] Failed to parse signature:", i), !1; } const m = () => { try { const i = S.magicHash(f), g = z(i); for (let h = 0; h < 4; h++) try { const p = l.RecoverPublicKey(h, g), v = p.toHash(), { prefix: I } = V(d); if (U(v, I) === d) return S.verify(f, l, p); } catch (p) { console.log("[tryNormalLogic] Recovery error:", p); } } catch (i) { console.log("[tryNormalLogic] error:", i); } return !1; }, b = () => { if (o.length <= 2) return !1; try { const i = o.slice(1, -1), g = $.sha256(i.flat()), h = H(g), p = y(h, "utf8"), v = S.magicHash(p), I = z(v); for (let P = 0; P < 4; P++) try { const A = l.RecoverPublicKey(P, I), B = A.toHash(), { prefix: C } = V(d); if (U(B, C) === d) return S.verify(p, l, A); } catch (A) { console.log("[tryTwetchLogic] Recovery error:", A); } } catch (i) { console.log("[tryTwetchLogic] error:", i); } return !1; }; let E = m(); return E || (E = b()), t.verified = E, E; } function z(t) { const e = H(t); return new J(e, 16); } var j = /* @__PURE__ */ ((t) => (t.HAIP = "HAIP", t.AIP = "AIP", t))(j || {}); const ee = async (t, e, r, n, s) => { const o = {}; if (n.length < 4) throw new Error("AIP requires at least 4 fields including the prefix"); for (const [c, a] of Object.entries(t)) { const u = Number.parseInt(c, 10); if (Array.isArray(a)) { const [f] = Object.keys(a[0]); console.log("[AIPhandler] aipField:", f); const d = []; for (let l = u + 1; l < n.length; l++) n[l].h && Array.isArray(d) && d.push(Number.parseInt(n[l].h || "", 16)); console.log("[AIPhandler] fieldData:", d), o[f] = d; } else { const [f] = Object.keys(a), [d] = Object.values(a); o[f] = x(n[u + 1], d) || ""; } } if (n[0].s === W && n[3].s && Ie(n[3].s) && (o.signature = n[3].s), !o.signature) throw new Error("AIP requires a signature"); return He(o, n, s), w(r, e, o), { dataObj: r, cell: n, tape: s }; }, Re = async ({ dataObj: t, cell: e, tape: r }) => { if (!r) throw new Error("Invalid AIP transaction. tape is required"); return ee(X, "AIP", t, e, r); }, te = { name: "AIP", address: W, opReturnSchema: X, handler: Re }, Te = "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut", N = [ { content: ["string", "binary", "file"] }, { "content-type": "string" }, { encoding: "string" }, // we use this field to determine content character encoding. If encoding is not a valid character encoding (gzip), we assume it is binary { filename: "string" } ], Me = ({ dataObj: t, cell: e, tx: r }) => { var o; const n = /* @__PURE__ */ new Map(); if (n.set("utf8", "string"), n.set("text", "string"), n.set("gzip", "binary"), n.set("text/plain", "string"), n.set("image/png", "binary"), n.set("image/jpeg", "binary"), n.set("application/octet-stream", "binary"), !e[1] || !e[2]) throw new Error(`Invalid B tx: ${r}`); if (e.length > N.length + 1) throw new Error("Invalid B tx. Too many fields."); const s = {}; for (const [c, a] of Object.entries(N)) { const u = Number.parseInt(c, 10), f = Object.keys(a)[0]; let d = Object.values(a)[0]; if (f === "content") if (e[1].f) d = "file"; else if ((!e[3] || !e[3].s) && e[2].s) d = n.get(e[2].s), d || (d = "binary"), e[3] || (e[3] = { h: "", b: "", s: "", i: 0, ii: 0 }), e[3].s = d === "string" ? "utf-8" : "binary"; else { const m = (o = e[3]) != null && o.s ? n.get(e[3].s.replace("-", "").toLowerCase()) : null; m ? d = m : d = "binary"; } if (f === "encoding" && !e[u + 1] || f === "filename" && !e[u + 1]) continue; if (!e || !e[u + 1]) throw new Error(`malformed B syntax ${e}`); const l = e[u + 1]; s[f] = x(l, d); } w(t, "B", s); }, re = { name: "B", address: Te, opReturnSchema: N, handler: Me }, Ce = "1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT", ne = [ { type: "string" }, { hash: "string" }, { sequence: "string" } ], Oe = ({ dataObj: t, cell: e, tx: r }) => { if (!r) throw new Error("Invalid BAP tx, tx required"); Ae("BAP", ne, t, e, r); }, se = { name: "BAP", address: Ce, opReturnSchema: ne, handler: Oe }, _e = "$", Ne = [ { su: [{ pubkey: "string" }, { sign_position: "string" }, { signature: "string" }], echo: [{ data: "string" }, { to: "string" }, { filename: "string" }], route: [ [ { add: [ { bitcom_address: "string" }, { route_matcher: "string" }, { endpoint_template: "string" } ] }, { enable: [{ path: "string" }] } ] ], useradd: [{ address: "string" }] } ], Le = ({ dataObj: t, cell: e }) => { if (!e.length || !e.every((n) => n.s)) throw new Error("Invalid Bitcom tx"); const r = e.map((n) => n != null && n.s ? n.s : ""); w(t, "BITCOM", r); }, Ke = { name: "BITCOM", address: _e, opReturnSchema: Ne, handler: Le }, { toArray: Q, toBase58Check: O, toHex: Fe } = k, { magicHash: qe } = S, oe = "13SrNDkVzY5bHBRKNu5iXTQ7K7VqTh5tJC", ie = [ { bitkey_signature: "string" }, { user_signature: "string" }, { paymail: "string" }, { pubkey: "string" } ]; function Ve(t) { const e = Fe(t); return new J(e, 16); } function Y(t, e) { const r = qe(t), n = Ve(r); for (let s = 0; s < 4; s++) try { const o = e.RecoverPublicKey(s, n); if (S.verify(t, e, o)) return o; } catch { } throw new Error("Failed to recover public key from BSM signature"); } const Ue = async ({ dataObj: t, cell: e }) => { if (e.length < 5) throw new Error("Invalid Bitkey tx"); const r = {}; for (const [A, B] of Object.entries(ie)) { const C = Number.parseInt(A, 10), K = Object.keys(B)[0], we = Object.values(B)[0]; r[K] = x(e[C + 1], we); } const n = r.pubkey, o = G.fromString(n).toHash(), c = O(o), u = Buffer.from(r.paymail).toString("hex") + n, f = Buffer.from(u, "hex"), d = $.sha256(Q(f)), l = R.fromCompact(r.bitkey_signature, "base64"), m = Y(d, l), b = m.toHash(), E = O(b), i = S.verify(d, l, m) && E === oe, g = Q(Buffer.from(n, "utf8")), h = R.fromCompact(r.user_signature, "base64"), p = Y(g, h), v = p.toHash(), I = O(v), P = S.verify(g, h, p) && I === c; r.verified = i && P, w(t, "BITKEY", r); }, ze = { name: "BITKEY", address: oe, opReturnSchema: ie, handler: Ue }, { magicHash: Qe } = S, { toArray: Ye } = k, ae = "18pAqbYqhzErT6Zk3a5dwxHtB9icv8jH2p", Ze = [ { paymail: "string" }, { pubkey: "binary" }, { signature: "string" } ], Je = async ({ dataObj: t, cell: e, tape: r, tx: n }) => { if (e[0].s !== ae || !e[1] || !e[2] || !e[3] || !e[1].s || !e[2].b || !e[3].s || !r) throw new Error(`Invalid BITPIC record: ${n}`); const s = { paymail: e[1].s, pubkey: Buffer.from(e[2].b, "base64").toString("hex"), signature: e[3].s || "", verified: !1 }; if (r[1].cell[0].s === "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut") try { const c = e[1].lb || e[1].b, a = $.sha256(Ye(c, "base64")), u = R.fromCompact(s.signature, "base64"), f = G.fromString(s.pubkey), d = Qe(a); s.verified = S.verify(d, u, f); } catch { s.verified = !1; } w(t, "BITPIC", s); }, Ge = { name: "BITPIC", address: ae, opReturnSchema: Ze, handler: Je }, De = "1HA1P2exomAwCUycZHr8WeyFoy5vuQASE3", ce = [ { algorithm: "string" }, { algorithm: "string" }, { address: "string" }, { signature: "string" }, { algorithm: "string" }, [{ index: "binary" }] ], We = async ({ dataObj: t, cell: e, tape: r, tx: n }) => { if (!r) throw new Error("Invalid HAIP tx. Bad tape"); if (!n) throw new Error("Invalid HAIP tx."); return await ee( ce, j.HAIP, t, e, r // tx, ); }, Xe = { name: "HAIP", address: De, opReturnSchema: ce, handler: We }, L = "1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5", fe = [ { cmd: { SET: [{ key: "string" }, { val: "string" }], SELECT: [{ tx: "string" }], ADD: [{ key: "string" }, [{ val: "string" }]], DELETE: [{ key: "string" }, [{ val: "string" }]], JSON: "string", REMOVE: [[{ key: "string" }]], CLEAR: [[{ txid: "string" }]] } } ], je = (t, e) => { let r = null; for (const n of t) { if (n.i === 0 || n.i === 1) continue; const s = n.s; n.i === 2 ? (e[s] = [], r = s) : r && Array.isArray(e[r]) && e[r].push(s); } }, et = (t, e) => { let r = null; for (const n of t) { if (n.i === 0 || n.i === 1) continue; const s = n.s; n.i === 2 ? (e[s] = [], r = s) : r && e[r].push(s); } }, tt = (t, e) => { for (const r of t) (r.i === 0 || r.i === 1) && (e.SELECT = "TODO"); }, rt = (t, e) => { for (const r of t) if (!(r.i === 0 || r.i === 1) && r.i === 2) try { if (!F) throw new Error("Msgpack is required but not loaded"); const n = Buffer.from(r.b, "base64"); e = F(n); } catch { e = {}; } return e; }, nt = (t, e) => { for (const r of t) if (!(r.i === 0 || r.i === 1) && r.i === 2) try { e = JSON.parse(r.s); } catch { e = {}; } return e; }, st = (t, e) => { let r = null; for (const n of t) { if (!n.s || n.i === 0 || n.i === 1) continue; const s = n.s; if (n.i % 2 === 0) e[s] = "", r = s; else { if (!r) throw new Error(`malformed MAP syntax. Cannot parse.${r}`); e[r] = s; } } }, ot = ({ dataObj: t, cell: e, tx: r }) => { if (e[0].s !== L || !e[1] || !e[1].s || !e[2] || !e[2].s) throw new Error(`Invalid MAP record: ${JSON.stringify(r, null, 2).substring(0, 100)}`); let n = {}; const s = []; let o = 0; for (let a = 1; a < e.length; a++) e[a].s === ":::" ? o++ : (s[o] || (s[o] = []), e[a].i = s[o].length + 1, s[o].push(e[a])); const c = Object.keys(fe[0])[0]; n[c] = s[0][0].s; for (const a of s) switch (a.unshift({ s: L, i: 0 }), a[1].s) { // Also check for SELECT commands and strip off the <SELECT> <TXID> part and run it through case "ADD": { je(a, n); break; } case "REMOVE": { n.key = a[2].s; break; } case "DELETE": { et(a, n); break; } case "CLEAR": break; case "SELECT": { tt(a, n); break; } case "MSGPACK": { n = rt(a, n); break; } case "JSON": { n = nt(a, n); break; } case "SET": { st(a, n); break; } } w(t, "MAP", n); }, de = { name: "MAP", address: L, opReturnSchema: fe, handler: ot }, { toArray: it, toHex: at } = k, ct = "meta", ft = [ { address: "string" }, { parent: "string" }, { name: "string" } ], Z = async (t, e) => { const r = Buffer.from(t + e), n = $.sha256(it(r)); return at(n); }, dt = async ({ dataObj: t, cell: e, tx: r }) => { if (!e.length || e[0].s !== "meta" || !e[1] || !e[1].s || !e[2] || !e[2].s || !r) throw new Error(`Invalid Metanet tx ${r}`); const n = await Z(e[1].s, r.tx.h), s = { a: e[1].s, tx: r.tx.h, id: n }; let o = { a: "", tx: "", id: "" }; if (r.in) { const c = await Z(r.in[0].e.a, e[2].s); o = { a: r.in[0].e.a, tx: e[2].s, id: c }; } t.METANET || (t.METANET = []), t.METANET.push({ node: s, parent: o }); }, he = { name: "METANET", address: ct, opReturnSchema: ft, handler: dt }, ht = (t) => { if (t.length < 13) return !1; const e = M(t, (o) => o.ops === "OP_IF"), r = M(t, (o, c) => c > e && o.ops === "OP_ENDIF"), n = t.slice(e, r), s = t[e - 1]; return (s == null ? void 0 : s.op) === 0 && !!n[0] && !!n[1] && n[1].s === "ord"; }, ut = ({ dataObj: t, cell: e, out: r }) => { if (!e[0] || !r) throw new Error("Invalid Ord tx. dataObj, cell, out and tx are required."); const n = M(e, (f) => f.ops === "OP_IF"), s = M(e, (f, d) => d > n && f.ops === "OP_ENDIF") + 1, o = e.slice(n, s); if (!o[0] || !o[1] || o[1].s !== "ord") throw new Error("Invalid Ord tx. Prefix not found."); let c, a; if (o.forEach((f, d, l) => { f.ops === "OP_1" && (a = l[d + 1].s), f.ops === "OP_0" && (c = l[d + 1].b); }), !c) throw new Error("Invalid Ord data."); if (!a) throw new Error("Invalid Ord content type."); const u = { data: c, contentType: a }; t.ORD || (t.ORD = []), t.ORD.push(u); }, T = { name: "ORD", handler: ut, scriptChecker: ht }; function M(t, e) { return lt(t, e); } function lt(t, e, r) { const n = t == null ? 0 : t.length; if (!n) return -1; let s = n - 1; return gt(t, e, s); } function gt(t, e, r, n) { const { length: s } = t; let o = r + 1; for (; o--; ) if (e(t[o], o, t)) return o; return -1; } const ue = "1GvFYzwtFix3qSAZhESQVTz9DeudHZNoh1", pt = [ { pair: "json" }, { address: "string" }, { timestamp: "string" } ], mt = ({ dataObj: t, cell: e, tx: r }) => { if (e[0].s !== ue || !e[1] || !e[2] || !e[3] || !e[1].s || !e[2].s || !e[3].s) throw new Error(`Invalid RON record ${r == null ? void 0 : r.tx.h}`); const n = JSON.parse(e[1].s), s = Number(e[3].s); w(t, "RON", { pair: n, address: e[2].s, timestamp: s }); }, yt = { name: "RON", address: ue, opReturnSchema: pt, handler: mt }, le = "1SymRe7erxM46GByucUWnB9fEEMgo7spd", bt = [{ url: "string" }], wt = ({ dataObj: t, cell: e, tx: r }) => { if (e[0].s !== le || !e[1] || !e[1].s) throw new Error(`Invalid SymRe tx: ${r}`); w(t, "SYMRE", { url: e[1].s }); }, Et = { name: "SYMRE", address: le, opReturnSchema: bt, handler: wt }, ge = /* @__PURE__ */ new Map([]), pe = /* @__PURE__ */ new Map([]), me = /* @__PURE__ */ new Map([]), ye = /* @__PURE__ */ new Map(), be = [ te, re, se, de, he, _, Ke, ze, Ge, Xe, yt, Et, T ], Bt = be.map((t) => t.name), St = [te, re, se, de, he, T]; for (const t of St) t.address && ge.set(t.address, t.name), pe.set(t.name, t.handler), t.opReturnSchema && ye.set(t.name, t.opReturnSchema), t.scriptChecker && me.set(t.name, t.scriptChecker); class vt { enabledProtocols; protocolHandlers; protocolScriptCheckers; protocolOpReturnSchemas; constructor() { this.enabledProtocols = ge, this.protocolHandlers = pe, this.protocolScriptCheckers = me, this.protocolOpReturnSchemas = ye; } addProtocolHandler({ name: e, address: r, opReturnSchema: n, handler: s, scriptChecker: o }) { r && this.enabledProtocols.set(r, e), this.protocolHandlers.set(e, s), n && this.protocolOpReturnSchemas.set(e, n), o && this.protocolScriptCheckers.set(e, o); } transformTx = async (e) => { var n, s, o; if (!e || !e.in || !e.out) throw new Error("Cannot process tx"); let r = { // Initialize blk with default values blk: { i: ((n = e.blk) == null ? void 0 : n.i) ?? 0, t: ((s = e.blk) == null ? void 0 : s.t) ?? 0, h: ((o = e.blk) == null ? void 0 : o.h) ?? "" } }; for (const [c, a] of Object.entries(e)) if (c === "out") for (const u of e.out) { const { tape: f } = u; f != null && f.some((m) => Pe(m)) && (r = await this.processDataProtocols(f, u, e, r)); const d = this.protocolScriptCheckers.get(_.name), l = this.protocolScriptCheckers.get(T.name); if (f != null && f.some((m) => { const { cell: b } = m; if (d != null && d(b) || l != null && l(b)) return !0; })) for (const m of f) { const { cell: b } = m; if (!b) throw new Error("empty cell while parsing"); let E = ""; if (d != null && d(b)) E = _.name; else if (l != null && l(b)) E = T.name; else continue; this.process(E, { tx: e, cell: b, dataObj: r, tape: f, out: u }); } } else c === "in" ? r[c] = a.map((u) => { const f = { ...u }; return f.tape = void 0, f; }) : r[c] = a; if (r.METANET && e.parent) { const c = { ancestor: e.ancestor, parent: e.parent, child: e.child, head: e.head }; r.METANET.push(c), r.ancestor = void 0, r.child = void 0, r.parent = void 0, r.head = void 0, r.node = void 0; } return r; }; processUnknown = (e, r, n) => { e && !r[`_${e}`] && (r[`_${e}`] = []), r[`_${e}`].push({ i: n.i, e: n.e, tape: [] }); }; process = async (e, { cell: r, dataObj: n, tape: s, out: o, tx: c }) => { if (this.protocolHandlers.has(e) && typeof this.protocolHandlers.get(e) == "function") { const a = this.protocolHandlers.get(e); a && await a({ dataObj: n, cell: r, tape: s, out: o, tx: c }); } else w(n, e, r); }; processDataProtocols = async (e, r, n, s) => { for (const o of e) { const { cell: c } = o; if (!c) throw new Error("empty cell while parsing"); if (D(o)) continue; const a = c[0].s; if (a) { const u = this.enabledProtocols.get(a); u ? await this.process(u, { cell: c, dataObj: s, tape: e, out: r, tx: n }) : this.processUnknown(a, s, r); } } return s; }; } const xt = async (t) => { const e = `https://api.whatsonchain.com/v1/bsv/main/tx/${t}/hex`; return console.log("hitting", e), await (await fetch(e)).text(); }, Pt = async (t) => await Ee({ tx: { r: t }, split: [ { token: { op: 106 }, include: "l" }, { token: { s: "|" } } ] }), Ht = async (t, e) => { if (typeof t == "string") { let n; if (t.length === 64 && (n = await xt(t)), Buffer.from(t).byteLength <= 146) throw new Error("Invalid rawTx"); n || (n = t); const s = await Pt(n); if (s) t = s; else throw new Error("Invalid txid"); } const r = new vt(); if (e) if (r.enabledProtocols.clear(), ve(e)) for (const n of be) e != null && e.includes(n.name) && r.addProtocolHandler(n); else if (xe(e)) for (const n of e) { const s = n; s && r.addProtocolHandler(s); } else throw new Error( "Invalid protocol array. Must be either an array of protocol names (string[]), or Protocol objects (Protocol[])." ); return r.transformTx(t); }; export { vt as BMAP, Ht as TransformTx, be as allProtocols, Pt as bobFromRawTx, St as defaultProtocols, xt as fetchRawTx, Bt as supportedProtocols }; //# sourceMappingURL=bmap.es.js.map