UNPKG

@vbyte/btc-dev

Version:

Batteries-included toolset for plebian bitcoin development

90 lines (80 loc) 3.44 kB
import { Buff } from '@vbyte/buff' import { Test } from '@vbyte/micro-lib' import { Assert } from '@vbyte/micro-lib/assert' import { hash256 } from '@vbyte/micro-lib/hash' import { encode_tx } from './encode.js' import { parse_tx } from './parse.js' import { assert_tx_template } from './validate.js' import { DEFAULT } from '@/const.js' import type { TxData, TxOutput, TxOutputTemplate, TxValue } from '@/types/index.js' export function get_txid (txdata : string | Uint8Array | TxData) : string { // If the transaction data is an object, if (typeof txdata === 'object') { // Assert the structure of the transaction data is valid. assert_tx_template(txdata) // Encode the transaction data. txdata = encode_tx(txdata, false) } // Return the txid of the transaction data. return hash256(txdata).reverse().hex } export function get_txhash (txdata : string | Uint8Array | TxData) : string { // If the transaction data is an object, if (typeof txdata === 'object') { // Assert the structure of the transaction data is valid. assert_tx_template(txdata) // Encode the transaction data. txdata = encode_tx(txdata, true) } // Return the txhash of the transaction data. return hash256(txdata).reverse().hex } export function get_tx_value (txdata : string | Uint8Array | TxData) : TxValue { // Parse the transaction data. const tx = parse_tx(txdata) // Assert the structure of the transaction data is valid. assert_tx_template(tx) // Calculate the value of the transaction. const vin = tx.vin.reduce((acc, txin) => acc + (txin.prevout?.value ?? 0n), 0n) const vout = tx.vout.reduce((acc, txout) => acc + txout.value, 0n) const fees = (vin > vout) ? (vin - vout) : 0n // Return the value of the transaction. return { fees, vin, vout } } export function get_prevouts (txdata : TxData) : TxOutput[] { // Assert the structure of the transaction data is valid. assert_tx_template(txdata) // Collect the prevouts from the transaction. const prevouts = txdata.vin.map(e => e.prevout) // Assert that all the prevouts are defined. Assert.ok(prevouts.every(e => e !== null), 'prevouts missing from tx') // Return the array of prevouts. return prevouts } export function normalize_sequence (sequence? : number | string | null) : number { // If sequence is not defined, return a default sequence value. if (!Test.exists(sequence)) return DEFAULT.SEQUENCE // If sequence is a hex string, decode it and return the number value. if (Test.is_hex(sequence)) return Buff.hex(sequence as string, 4).reverse().num // If sequence is a valid unsigned integer, return the value. if (Test.is_uint(sequence)) return sequence // Else, throw an error. throw new Error('invalid sequence value: ' + String(sequence)) } export function normalize_value (value : number | bigint) : bigint { // If value is a unsigned integer, return it as a bigint. if (Test.is_uint(value)) return BigInt(value) // If value is a bigint, return it as-is. if (typeof value === 'bigint') return value // Else, throw an error. throw new TypeError('invalid output value: ' + String(value)) } export function normalize_prevout (prevout : TxOutputTemplate) : TxOutput { // Return the output with a normalized value. return { script_pk: prevout.script_pk, value: normalize_value(prevout.value) } }