UNPKG

charms-js

Version:

TypeScript SDK for decoding Bitcoin transactions containing Charms data

131 lines (130 loc) 4.93 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.decodeCbor = decodeCbor; exports.denormalizeSpell = denormalizeSpell; const cbor = __importStar(require("cbor")); // Converts CBOR Maps to plain objects recursively function convertMapsToObjects(obj) { if (obj instanceof Map) { const result = {}; for (const [key, value] of obj.entries()) { result[key] = convertMapsToObjects(value); } return result; } else if (Array.isArray(obj)) { return obj.map(item => convertMapsToObjects(item)); } else if (obj && typeof obj === 'object') { const result = {}; for (const [key, value] of Object.entries(obj)) { result[key] = convertMapsToObjects(value); } return result; } return obj; } // Decodes CBOR data from Bitcoin transaction function decodeCbor(cborData) { try { if (!cborData || cborData.length === 0) { return null; } const rawDecoded = cbor.decode(cborData); const decoded = convertMapsToObjects(rawDecoded); console.log('Parsing spell data:', JSON.stringify(decoded, null, 2).substring(0, 200) + '...'); // CBOR structure: [NormalizedSpell, Proof] if (!Array.isArray(decoded) || decoded.length < 2) { console.log('Invalid CBOR structure: expected [spell, proof] array'); return null; } const normalizedSpell = decoded[0]; // Validate spell structure if (normalizedSpell && typeof normalizedSpell === 'object' && 'version' in normalizedSpell && 'tx' in normalizedSpell && 'app_public_inputs' in normalizedSpell) { return normalizedSpell; } console.log('Invalid spell structure in CBOR data'); return null; } catch (error) { console.log(`Error in decodeCbor: ${error.message}`); return null; } } // Converts NormalizedSpell to ParsedCharmData format function denormalizeSpell(normalizedSpell) { // Convert app_public_inputs to $xxxx indexed format const apps = {}; const appKeys = Object.keys(normalizedSpell.app_public_inputs); appKeys.forEach((appKey, index) => { const indexKey = `$${String(index).padStart(4, '0')}`; apps[indexKey] = normalizedSpell.app_public_inputs[appKey]; }); const ins = normalizedSpell.tx.ins || []; // Extract charms from outputs const outs = normalizedSpell.tx.outs.map((normalizedCharms) => { const output = {}; if (Object.keys(normalizedCharms).length > 0) { const charms = {}; // Convert numeric indices to $xxxx format Object.entries(normalizedCharms).forEach(([appIndexStr, charmData]) => { const appIndex = parseInt(appIndexStr); const indexKey = `$${String(appIndex).padStart(4, '0')}`; // Preserve original CBOR structure if (charmData && typeof charmData === 'object' && 'value' in charmData) { charms[indexKey] = charmData.value; } else { charms[indexKey] = charmData; } }); if (Object.keys(charms).length > 0) { output.charms = charms; } } return output; }); return { version: normalizedSpell.version, apps, ins: ins.map(utxoId => ({ utxo_id: utxoId })), outs }; }