import { TransactionHash } from './transaction-hash.js'; import { binToHex, hexToBin, encodeTransaction, decodeTransaction, isHex, } from '@bitauth/libauth'; import type { TransactionBCH } from '@bitauth/libauth'; /** * Transaction Entity. */ export class Transaction { constructor(public transaction: TransactionBCH) {} /** * Create a Transaction Entity from the given byte data. * * @param bytes {Uint8Array} The raw byte data of the transaction. * * @throws {Error} If transaction data cannot be decoded. * * @returns {Transaction} The created Transaction Entity. */ public static fromBytes(bytes: Uint8Array): Transaction { // Attempt to decode the raw transaction bytes. const decodeResult = decodeTransaction(bytes); // If a string is returned, this indicates an error... if (typeof decodeResult === 'string') { throw new Error(decodeResult); } // Return a new instance of the Transaction Entity created from the decode result. return new Transaction(decodeResult); } /** * Create a Transaction Entity from the given byte data encoded as hexadecimal string. * * @param hex {string} The raw byte data (encoded as hexadecimal string) of the transaction. * * @throws {Error} If transaction cannot be decoded. * * @returns {Transaction} The created Transaction Entity. */ public static fromHex(hex: string): Transaction { // Ensure that the given string is hex. if (!isHex(hex)) { throw new Error('The given string is not valid hexadecimal.'); } // Convert our hex to binary. const bytes = hexToBin(hex); // Return the transaction constructed from our bytes. return Transaction.fromBytes(bytes); } public static fromAny(bytesOrHex: Uint8Array | string) { if (typeof bytesOrHex === 'string') { return Transaction.fromHex(bytesOrHex); } return Transaction.fromBytes(bytesOrHex); } public toBytes(): Uint8Array { const bytes = encodeTransaction(this.transaction); return bytes; } public toHex(): string { const bytes = this.toBytes(); return binToHex(bytes); } public toHash(): TransactionHash { return TransactionHash.fromTransactionBytes(this.toBytes()); } public toHashHex(): string { return this.toHash().toHex(); } public toHashBytes(): Uint8Array { return this.toHash().toBytes(); } public getVersion() { return this.transaction.version; } public getInputs() { return this.transaction.inputs; } public getOutputs() { return this.transaction.outputs; } public getLocktime() { return this.transaction.locktime; } public isCoinbase(): boolean { // TODO: This definitely needs checking. // TODO: You're a moron Jim. outpointTransactionHash is 0x00 x 32 for Coinbase. // A coinbase transaction MUST only have one input. if (this.getInputs().length > 1) { return false; } // Get the input's unlocking bytecode. const unlockingBytecode = this.getInputs()[0].unlockingBytecode; // Get the firt byte. const firstByte = unlockingBytecode[0]; if (firstByte >= 0x01 && firstByte <= 0x4b) { return true; } return false; } }