@bsv/sdk
Version:
BSV Blockchain Software Development Kit
250 lines (176 loc) • 5.42 kB
Markdown
Understanding Bitcoin transaction fees and how they work in the BSV TypeScript SDK.
Transaction fees are payments to miners for including transactions in blocks:
```typescript
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)
```
Fees are calculated based on transaction size:
- **Fee Rate**: Satoshis per kilobyte (sat/kB)
- **Transaction Size**: Total bytes in serialized transaction
- **Total Fee**: Size × Fee Rate
## SDK Fee Handling
### Automatic Fee Calculation
The SDK calculates fees automatically:
```typescript
// Wallet handles fees automatically
const wallet = new WalletClient()
const action = await wallet.createAction({
outputs: [{
satoshis: 1000,
lockingScript: script
}]
})
// Fee calculated and deducted automatically
```
For advanced use cases:
```typescript
// Calculate fee manually
const tx = new Transaction()
tx.addInput(/* input */)
tx.addOutput(/* output */)
const estimatedSize = tx.getSerializedSize()
const feeRequired = estimatedSize * feePerByte
```
BSV typically uses low, predictable fees:
- **Standard Rate**: ~0.5 sat/byte
- **Priority Rate**: ~1.0 sat/byte
- **Economy Rate**: ~0.1 sat/byte
```typescript
// Get current network fee rates
const feeRates = await chainTracker.getFeeRates()
const recommendedFee = feeRates.standard
```
Each input adds to transaction size:
- Previous transaction hash (32 bytes)
- Output index (4 bytes)
- Unlocking script (variable)
- Sequence number (4 bytes)
### Output Costs
Each output adds to transaction size:
- Value (8 bytes)
- Locking script length (1-9 bytes)
- Locking script (variable)
### Base Transaction
Fixed overhead for every transaction:
- Version (4 bytes)
- Input count (1-9 bytes)
- Output count (1-9 bytes)
- Lock time (4 bytes)
## Fee Optimization
### UTXO Selection
Choose UTXOs efficiently:
```typescript
// Prefer fewer, larger UTXOs to reduce fees
const utxos = await wallet.getUTXOs()
const selected = selectOptimalUTXOs(utxos, targetAmount)
```
Combine multiple payments:
```typescript
// Batch multiple outputs in one transaction
const outputs = [
{ satoshis: 1000, lockingScript: script1 },
{ satoshis: 2000, lockingScript: script2 },
{ satoshis: 1500, lockingScript: script3 }
]
```
Use efficient script templates:
```typescript
// P2PKH is more efficient than complex scripts
const p2pkh = new P2PKH()
const efficientScript = p2pkh.lock(publicKeyHash)
```
Estimate transaction size before creation:
```typescript
// Estimate size for fee calculation
const estimatedInputs = 2
const estimatedOutputs = 3
const estimatedSize = estimateTransactionSize(estimatedInputs, estimatedOutputs)
const estimatedFee = estimatedSize * feeRate
```
```typescript
// Use script templates for accurate estimation
const template = new P2PKH()
const scriptSize = template.estimateLength([publicKeyHash])
```
Common fee-related issues:
- Insufficient funds for fees
- Fee rate too low for network
- Transaction size miscalculation
```typescript
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')
}
}
```
- Always account for fees in balance calculations
- Use appropriate fee rates for urgency
- Monitor network conditions for fee adjustments
- Implement fee estimation before transaction creation
- Batch transactions when possible
- Use efficient script templates
- Optimize UTXO selection
- Consider transaction timing
- Display estimated fees to users
- Provide fee rate options (economy, standard, priority)
- Handle insufficient fund errors gracefully
- Show fee breakdown for transparency
## Wallet Integration
Most applications rely on wallets for fee handling:
```typescript
// 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 */]
})
```
Increase fees for faster confirmation:
```typescript
// Create transaction with RBF enabled
const tx = new Transaction()
tx.setRBF(true) // Enable replace-by-fee
```
Use dependent transactions to increase effective fee rate:
```typescript
// Create child transaction with higher fee
const childTx = new Transaction()
childTx.addInput(/* from parent transaction */)
// Higher fee rate pulls parent transaction along
```
- Understand [Transaction Structure](./transaction-structure.md) for size calculation
- Learn about [Wallet Integration](./wallet-integration.md) for automatic fee handling
- Explore [Script Templates](./script-templates.md) for efficient fee optimization