UNPKG

charms-js

Version:

TypeScript SDK for decoding Bitcoin transactions containing Charms data

113 lines (112 loc) 3.94 kB
"use strict"; /** * WASM-based decoder for Charms.js * Simplified implementation using charms-lib WASM module */ Object.defineProperty(exports, "__esModule", { value: true }); exports.decodeTransactionWithWasm = decodeTransactionWithWasm; const wasm_wrapper_1 = require("./wasm-wrapper"); const formatter_1 = require("./formatter"); /** * Decode transaction using WASM spell extraction * @param txHex - Transaction hex string * @returns Array of CharmInstance objects */ async function decodeTransactionWithWasm(txHex) { try { // Extract and verify spell using WASM const spellData = await (0, wasm_wrapper_1.extractAndVerifySpell)(txHex, false); if (!spellData) { return []; } console.log('WASM extracted spell data:', JSON.stringify(spellData, null, 2)); // Convert WASM output to CharmInstance format return convertWasmDataToCharms(spellData, txHex); } catch (error) { console.error('WASM decoding failed:', error); throw error; } } /** * Convert WASM spell data to CharmInstance array */ function convertWasmDataToCharms(spellData, txHex) { const charms = []; // Extract transaction ID from hex (first 32 bytes reversed) const txId = extractTxIdFromHex(txHex); // Process spell data structure if (spellData.tx && spellData.tx.outs) { spellData.tx.outs.forEach((output, index) => { // Extract value from output const value = extractValueFromOutput(output); if (value > 0) { // Reconstruct app ID from app_public_inputs const appId = (0, formatter_1.reconstructAppId)(spellData, '$0000'); // Extract app data const appData = extractAppData(spellData.app_public_inputs); const charm = { utxo: { tx: txId, index: index }, address: '', // Will be filled by address derivation if needed appId: appId, app: appData, appType: 'unknown', value: value, verified: true // WASM verification passed }; charms.push(charm); } }); } return charms; } /** * Extract transaction ID from hex string */ function extractTxIdFromHex(txHex) { // This is a simplified version - in practice, we'd need to properly parse the transaction // For now, we'll use a placeholder that can be filled by the calling code return 'PLACEHOLDER_TX_ID'; } /** * Extract value from output object */ function extractValueFromOutput(output) { if (typeof output === 'object') { // Look for numeric values in the output for (const [key, value] of Object.entries(output)) { if (typeof value === 'number' && value > 0) { return value; } } } return 0; } /** * Extract app data from app_public_inputs */ function extractAppData(appPublicInputs) { if (!appPublicInputs) { return null; } // If it's already an object with app data, return it if (typeof appPublicInputs === 'object') { // Filter out the app ID keys and keep only the app data const appData = {}; for (const [key, value] of Object.entries(appPublicInputs)) { // Skip app ID keys (they start with 't/') if (typeof key === 'string' && !key.startsWith('t/')) { appData[key] = value; } else if (typeof key === 'string' && key.startsWith('t/') && value && typeof value === 'object') { // If the value contains app data, merge it Object.assign(appData, value); } } return Object.keys(appData).length > 0 ? appData : {}; } return {}; }