or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

address.mdblocks.mdcrypto.mdindex.mdnetworks.mdpayments.mdpsbt.mdscripts.mdtransactions.mdutilities.md
tile.json

transactions.mddocs/

Transaction Handling

Complete transaction creation, manipulation, and serialization functionality with support for witness data, fee calculation, and transaction signing for all Bitcoin transaction types including legacy, SegWit v0, and Taproot transactions.

Core Types

interface Input {
  /** Previous transaction hash */
  hash: Buffer;
  /** Previous output index */
  index: number;
  /** Input script (scriptSig) */
  script: Buffer;
  /** Sequence number for timelock/RBF */
  sequence: number;
  /** Witness stack data */
  witness: Buffer[];
}

interface Output {
  /** Output script (scriptPubKey) */
  script: Buffer;
  /** Value in satoshis */
  value: number;
}

Capabilities

Transaction Class

Core transaction functionality with comprehensive methods for transaction creation, manipulation, and serialization.

class Transaction {
  /** Default sequence number (0xFFFFFFFF) */
  static readonly DEFAULT_SEQUENCE = 4294967295;
  
  /** Sighash type constants */
  static readonly SIGHASH_DEFAULT = 0;
  static readonly SIGHASH_ALL = 1;
  static readonly SIGHASH_NONE = 2;
  static readonly SIGHASH_SINGLE = 3;
  static readonly SIGHASH_ANYONECANPAY = 128;
  static readonly SIGHASH_OUTPUT_MASK = 3;
  static readonly SIGHASH_INPUT_MASK = 128;
  
  /** Witness transaction markers */
  static readonly ADVANCED_TRANSACTION_MARKER = 0;
  static readonly ADVANCED_TRANSACTION_FLAG = 1;
  
  /** Transaction version */
  version: number;
  /** Transaction locktime */
  locktime: number;
  /** Array of transaction inputs */
  ins: Input[];
  /** Array of transaction outputs */
  outs: Output[];
}

Transaction Creation

Create transactions from various sources including buffers, hex strings, and programmatically.

/**
 * Create transaction from buffer
 * @param buffer - Raw transaction buffer
 * @param _NO_STRICT - Skip strict parsing checks
 * @returns Parsed Transaction object
 */
static fromBuffer(buffer: Buffer, _NO_STRICT?: boolean): Transaction;

/**
 * Create transaction from hex string
 * @param hex - Hex-encoded transaction string
 * @returns Parsed Transaction object
 */
static fromHex(hex: string): Transaction;

/**
 * Check if buffer contains coinbase transaction hash (all zeros)
 * @param buffer - Transaction hash buffer
 * @returns True if coinbase hash
 */
static isCoinbaseHash(buffer: Buffer): boolean;

Usage Examples:

import { Transaction } from 'bitcoinjs-lib';

// Create new transaction
const tx = new Transaction();
tx.version = 2;
tx.locktime = 0;

// Parse from hex
const txHex = '01000000...';
const parsedTx = Transaction.fromHex(txHex);

// Parse from buffer
const txBuffer = Buffer.from(txHex, 'hex');
const parsedTx2 = Transaction.fromBuffer(txBuffer);

Input Management

Add and manage transaction inputs with support for sequence numbers and scripts.

/**
 * Add input to transaction
 * @param hash - Previous transaction hash
 * @param index - Previous output index
 * @param sequence - Sequence number (optional, defaults to DEFAULT_SEQUENCE)
 * @param scriptSig - Input script (optional, defaults to empty)
 * @returns Index of added input
 */
addInput(hash: Buffer, index: number, sequence?: number, scriptSig?: Buffer): number;

/**
 * Set input script for existing input
 * @param index - Input index
 * @param scriptSig - Input script buffer
 */
setInputScript(index: number, scriptSig: Buffer): void;

/**
 * Set witness data for existing input
 * @param index - Input index
 * @param witness - Array of witness stack items
 */
setWitness(index: number, witness: Buffer[]): void;

Usage Examples:

import { Transaction } from 'bitcoinjs-lib';

const tx = new Transaction();

// Add input
const prevTxHash = Buffer.from('abc123...', 'hex').reverse(); // Note: reverse for little-endian
const inputIndex = tx.addInput(prevTxHash, 0);

// Add input with custom sequence for RBF
const rbfInput = tx.addInput(prevTxHash, 1, 0xfffffffd);

// Set input script later
const scriptSig = Buffer.from('473044...', 'hex');
tx.setInputScript(0, scriptSig);

// Set witness data for SegWit input
const witness = [
  Buffer.from('304402...', 'hex'), // signature
  Buffer.from('03a34b...', 'hex')  // pubkey
];
tx.setWitness(0, witness);

Output Management

Add transaction outputs with scripts and values.

/**
 * Add output to transaction
 * @param scriptPubKey - Output script
 * @param value - Value in satoshis
 * @returns Index of added output
 */
addOutput(scriptPubKey: Buffer, value: number): number;

Usage Examples:

import { Transaction, payments, networks } from 'bitcoinjs-lib';

const tx = new Transaction();

// Add P2PKH output
const p2pkh = payments.p2pkh({ 
  hash: Buffer.from('a54d...', 'hex'),
  network: networks.bitcoin 
});
tx.addOutput(p2pkh.output!, 50000); // 0.0005 BTC

// Add P2WPKH output
const p2wpkh = payments.p2wpkh({
  hash: Buffer.from('b65e...', 'hex'),
  network: networks.bitcoin
});
tx.addOutput(p2wpkh.output!, 25000); // 0.00025 BTC

// Add OP_RETURN output
const data = [Buffer.from('Hello Bitcoin!', 'utf8')];
const opReturn = payments.embed({ data });
tx.addOutput(opReturn.output!, 0); // No value for data outputs

Transaction Properties

Retrieve transaction properties and metadata.

/**
 * Check if transaction is coinbase
 * @returns True if coinbase transaction
 */
isCoinbase(): boolean;

/**
 * Check if transaction has witness data
 * @returns True if any input has witness data
 */
hasWitnesses(): boolean;

/**
 * Calculate transaction weight (BIP 141)
 * @returns Transaction weight in weight units
 */
weight(): number;

/**
 * Calculate virtual size (weight / 4, rounded up)
 * @returns Virtual size in vbytes
 */
virtualSize(): number;

/**
 * Calculate transaction byte length
 * @param _ALLOW_WITNESS - Include witness data in calculation
 * @returns Byte length
 */
byteLength(_ALLOW_WITNESS?: boolean): number;

/**
 * Clone transaction
 * @returns Deep copy of transaction
 */
clone(): Transaction;

Usage Examples:

const tx = Transaction.fromHex('01000000...');

console.log('Is coinbase:', tx.isCoinbase());
console.log('Has witnesses:', tx.hasWitnesses());
console.log('Weight:', tx.weight());
console.log('Virtual size:', tx.virtualSize());
console.log('Byte length:', tx.byteLength());

// Clone for modification
const modifiedTx = tx.clone();
modifiedTx.locktime = 650000;

Transaction Hashing

Generate transaction hashes for signing with support for all signature hash types.

/**
 * Hash transaction for legacy signature (pre-SegWit)
 * @param inIndex - Input index being signed
 * @param prevOutScript - Previous output script
 * @param hashType - Signature hash type
 * @returns Hash for signing
 */
hashForSignature(inIndex: number, prevOutScript: Buffer, hashType: number): Buffer;

/**
 * Hash transaction for SegWit v0 signature (BIP 143)
 * @param inIndex - Input index being signed
 * @param prevOutScript - Previous output script
 * @param value - Previous output value
 * @param hashType - Signature hash type
 * @returns Hash for signing
 */
hashForWitnessV0(inIndex: number, prevOutScript: Buffer, value: number, hashType: number): Buffer;

/**
 * Hash transaction for Taproot signature (BIP 341)
 * @param inIndex - Input index being signed
 * @param prevOutScripts - All previous output scripts
 * @param values - All previous output values
 * @param hashType - Signature hash type
 * @param leafHash - Script leaf hash (for script-path spending)
 * @param annex - Annex data (optional)
 * @returns Hash for signing
 */
hashForWitnessV1(
  inIndex: number, 
  prevOutScripts: Buffer[], 
  values: number[], 
  hashType: number, 
  leafHash?: Buffer, 
  annex?: Buffer
): Buffer;

Usage Examples:

import { Transaction } from 'bitcoinjs-lib';

const tx = Transaction.fromHex('01000000...');

// Legacy P2PKH signing
const prevOutScript = Buffer.from('76a914...88ac', 'hex');
const legacyHash = tx.hashForSignature(0, prevOutScript, Transaction.SIGHASH_ALL);

// SegWit v0 signing
const segwitHash = tx.hashForWitnessV0(0, prevOutScript, 50000, Transaction.SIGHASH_ALL);

// Taproot signing (key-path)
const prevOutScripts = [Buffer.from('5120...', 'hex')];
const values = [50000];
const taprootHash = tx.hashForWitnessV1(0, prevOutScripts, values, Transaction.SIGHASH_DEFAULT);

Serialization

Convert transactions to various formats for storage and transmission.

/**
 * Get transaction hash (double SHA256)
 * @param forWitness - Calculate witness transaction ID
 * @returns Transaction hash
 */
getHash(forWitness?: boolean): Buffer;

/**
 * Get transaction ID (hex-encoded reversed hash)
 * @returns Transaction ID string
 */
getId(): string;

/**
 * Serialize transaction to buffer
 * @param buffer - Optional buffer to write to
 * @param initialOffset - Starting offset in buffer
 * @returns Serialized transaction buffer
 */
toBuffer(buffer?: Buffer, initialOffset?: number): Buffer;

/**
 * Serialize transaction to hex string
 * @returns Hex-encoded transaction
 */
toHex(): string;

Usage Examples:

const tx = new Transaction();
// ... add inputs and outputs ...

// Get transaction ID
const txid = tx.getId();
console.log('Transaction ID:', txid);

// Get raw hash
const hash = tx.getHash();
console.log('Transaction hash:', hash.toString('hex'));

// Serialize to hex
const txHex = tx.toHex();
console.log('Transaction hex:', txHex);

// Serialize to buffer
const txBuffer = tx.toBuffer();

Transaction Manipulation

Modify existing transactions with witness data handling.

/**
 * Remove all witness data from transaction
 */
stripWitnesses(): void;

Usage Examples:

const tx = Transaction.fromHex('02000000..'); // SegWit transaction

console.log('Original has witnesses:', tx.hasWitnesses());
console.log('Original weight:', tx.weight());

// Remove witness data
tx.stripWitnesses();

console.log('After strip has witnesses:', tx.hasWitnesses());
console.log('After strip weight:', tx.weight());

Advanced Usage

Replace-by-Fee (RBF)

Enable transaction replacement using sequence numbers:

import { Transaction } from 'bitcoinjs-lib';

const tx = new Transaction();

// Add RBF-enabled input (sequence < 0xfffffffe)
tx.addInput(prevTxHash, 0, 0xfffffffd);

// Later, create replacement transaction with higher fee
const replacementTx = tx.clone();
// ... modify outputs for higher fee ...

Timelock Transactions

Create time-locked transactions using locktime and sequence:

import { Transaction } from 'bitcoinjs-lib';

const tx = new Transaction();
tx.version = 2;

// Set locktime (block height or timestamp)
tx.locktime = 650000; // Block height

// Add input with sequence for relative timelock
tx.addInput(prevTxHash, 0, 144); // 144 blocks relative timelock

Fee Calculation

Calculate transaction fees:

const tx = Transaction.fromHex('01000000...');

// Calculate fee (requires knowing input values)
const inputValues = [100000, 50000]; // Previous output values
const outputValues = tx.outs.reduce((sum, out) => sum + out.value, 0);
const inputTotal = inputValues.reduce((sum, val) => sum + val, 0);
const fee = inputTotal - outputValues;

console.log('Transaction fee:', fee, 'satoshis');
console.log('Fee rate:', fee / tx.virtualSize(), 'sat/vB');

Types

interface Input {
  hash: Buffer;
  index: number;
  script: Buffer;
  sequence: number;
  witness: Buffer[];
}

interface Output {
  script: Buffer;
  value: number;
}