ts-sdk

Transaction Fees

Understanding Bitcoin transaction fees and how they work in the BSV TypeScript SDK.

What are Transaction Fees?

Transaction fees are payments to miners for including transactions in blocks:

import { Transaction } from '@bsv/sdk'

// Calculate transaction fee
const tx = new Transaction()
const feeRequired = tx.getFee()

// Set custom fee rate
const customFee = tx.getFee(feePerKB)

Fee Calculation

Fees are calculated based on transaction size:

SDK Fee Handling

Automatic Fee Calculation

The SDK calculates fees automatically:

// Wallet handles fees automatically
const wallet = new WalletClient()
const action = await wallet.createAction({
  outputs: [{
    satoshis: 1000,
    lockingScript: script
  }]
})
// Fee calculated and deducted automatically

Manual Fee Control

For advanced use cases:

// Calculate fee manually
const tx = new Transaction()
tx.addInput(/* input */)
tx.addOutput(/* output */)

const estimatedSize = tx.getSerializedSize()
const feeRequired = estimatedSize * feePerByte

Fee Rates

Network Fee Rates

BSV typically uses low, predictable fees:

Dynamic Fee Estimation

// Get current network fee rates
const feeRates = await chainTracker.getFeeRates()
const recommendedFee = feeRates.standard

Fee Components

Input Costs

Each input adds to transaction size:

Output Costs

Each output adds to transaction size:

Base Transaction

Fixed overhead for every transaction:

Fee Optimization

UTXO Selection

Choose UTXOs efficiently:

// Prefer fewer, larger UTXOs to reduce fees
const utxos = await wallet.getUTXOs()
const selected = selectOptimalUTXOs(utxos, targetAmount)

Output Consolidation

Combine multiple payments:

// Batch multiple outputs in one transaction
const outputs = [
  { satoshis: 1000, lockingScript: script1 },
  { satoshis: 2000, lockingScript: script2 },
  { satoshis: 1500, lockingScript: script3 }
]

Script Efficiency

Use efficient script templates:

// P2PKH is more efficient than complex scripts
const p2pkh = new P2PKH()
const efficientScript = p2pkh.lock(publicKeyHash)

Fee Estimation

Size Estimation

Estimate transaction size before creation:

// Estimate size for fee calculation
const estimatedInputs = 2
const estimatedOutputs = 3
const estimatedSize = estimateTransactionSize(estimatedInputs, estimatedOutputs)
const estimatedFee = estimatedSize * feeRate

Template-Based Estimation

// Use script templates for accurate estimation
const template = new P2PKH()
const scriptSize = template.estimateLength([publicKeyHash])

Error Handling

Common fee-related issues:

try {
  const action = await wallet.createAction({
    outputs: outputs
  })
} catch (error) {
  if (error.message.includes('Insufficient funds')) {
    // Handle insufficient balance for fees
    console.log('Not enough funds to cover transaction and fees')
  }
}

Best Practices

Fee Management

Cost Optimization

User Experience

Wallet Integration

Most applications rely on wallets for fee handling:

// Wallet manages fees automatically
const wallet = new WalletClient()

// Fees are calculated and deducted automatically
const result = await wallet.createAction({
  description: 'Payment with automatic fees',
  outputs: [/* outputs */]
})

Advanced Fee Strategies

Replace-by-Fee (RBF)

Increase fees for faster confirmation:

// Create transaction with RBF enabled
const tx = new Transaction()
tx.setRBF(true) // Enable replace-by-fee

Child-Pays-for-Parent (CPFP)

Use dependent transactions to increase effective fee rate:

// Create child transaction with higher fee
const childTx = new Transaction()
childTx.addInput(/* from parent transaction */)
// Higher fee rate pulls parent transaction along

Next Steps