UNPKG

@btc-stamps/tx-builder

Version:

Transaction builder for Bitcoin Stamps and SRC-20 tokens with advanced UTXO selection

153 lines (136 loc) 3.78 kB
/** * SRC-20 Decoder Utility * * Utility for decoding SRC-20 data from various sources including * raw transactions, hex data, and P2WSH outputs. */ import * as bitcoin from 'bitcoinjs-lib'; import { Buffer } from 'node:buffer'; import { SRC20Encoder } from '../encoders/src20-encoder.ts'; import type { SRC20Data } from '../interfaces/src20.interface.ts'; /** * Standalone SRC-20 decoder utility */ export class SRC20Decoder { private encoder: SRC20Encoder; constructor(network: bitcoin.Network = bitcoin.networks.bitcoin) { this.encoder = new SRC20Encoder(network); } /** * Decode SRC-20 data from transaction hex */ async decodeFromTxHex(txHex: string): Promise<SRC20Data | null> { try { const tx = bitcoin.Transaction.fromHex(txHex); return await this.encoder.decode(tx); } catch (error) { console.error('Error decoding transaction hex:', error); return null; } } /** * Decode SRC-20 data from transaction ID * Note: This requires a provider to fetch the transaction */ async decodeFromTxid(txid: string, provider?: any): Promise<SRC20Data | null> { if (!provider || !provider.getTransaction) { throw new Error('Provider with getTransaction method required'); } try { const txData = await provider.getTransaction(txid); if (!txData || !txData.hex) { return null; } return await this.decodeFromTxHex(txData.hex); } catch (error) { console.error('Error fetching transaction:', error); return null; } } /** * Decode SRC-20 data from P2WSH outputs */ async decodeFromOutputs( outputs: Array<{ script: Buffer; value: number }>, ): Promise<SRC20Data | null> { return await this.encoder.decodeFromOutputs(outputs); } /** * Validate that data is valid SRC-20 */ validate(data: any): boolean { return this.encoder.validate(data); } /** * Get validation errors for SRC-20 data */ getValidationErrors(data: SRC20Data): string[] { return this.encoder.getValidationErrors(data); } /** * Check if a transaction contains SRC-20 data */ async containsSRC20Data(tx: bitcoin.Transaction): Promise<boolean> { try { const decoded = await this.encoder.decode(tx); return decoded !== null; } catch { return false; } } /** * Extract SRC-20 operation type from transaction */ async getOperationType(tx: bitcoin.Transaction): Promise<string | null> { try { const decoded = await this.encoder.decode(tx); return decoded?.op || null; } catch { return null; } } /** * Extract ticker symbol from transaction */ async getTickerSymbol(tx: bitcoin.Transaction): Promise<string | null> { try { const decoded = await this.encoder.decode(tx); return decoded?.tick || null; } catch { return null; } } } /** * Create a new SRC-20 decoder instance */ export function createSRC20Decoder( network: bitcoin.Network = bitcoin.networks.bitcoin, ): SRC20Decoder { return new SRC20Decoder(network); } /** * Decode SRC-20 data from transaction hex (convenience function) */ export async function decodeSRC20FromHex( txHex: string, network?: bitcoin.Network, ): Promise<SRC20Data | null> { const decoder = new SRC20Decoder(network); return await decoder.decodeFromTxHex(txHex); } /** * Check if transaction hex contains SRC-20 data (convenience function) */ export async function isSRC20Transaction( txHex: string, network?: bitcoin.Network, ): Promise<boolean> { try { const decoder = new SRC20Decoder(network); const tx = bitcoin.Transaction.fromHex(txHex); return await decoder.containsSRC20Data(tx); } catch { return false; } }