Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fee bumping Package #114

Merged
merged 84 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 80 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
5c233db
feat: Initialize @caravan/feebumping package
Legend101Zz Jun 23, 2024
592a875
changes in rbf file
Legend101Zz Jun 23, 2024
4f0755c
Add comprehensive fee bumping package for Caravan
Legend101Zz Jul 19, 2024
b00eaae
Implement fee bumping types and estimation functions
Legend101Zz Jul 22, 2024
9b0c967
Add transaction analysis functionality for fee bumping
Legend101Zz Jul 22, 2024
b7b2fa5
Refactor fee bumping package for improved functionality and integration
Legend101Zz Jul 22, 2024
63c129c
Changes to the RBF functionality in the fees package and added RBF si…
Legend101Zz Jul 26, 2024
4fce4fe
Implement CPFP and RBF classes with tests
Legend101Zz Aug 1, 2024
77f0cbe
Refactored RBF and CPFP classes, introduced TransactionAnalyzer class
Legend101Zz Aug 3, 2024
77f4db4
Refactor RBF, CPFP, and TransactionAnalyzer Classes and their Tests
Legend101Zz Aug 6, 2024
4f4f97a
Enhance RBF class functionality with improved state management and fe…
Legend101Zz Aug 14, 2024
07d5a84
Added methods to handle sequence numbers within PSBTs for better RBF …
Legend101Zz Aug 14, 2024
d71a0ec
minor corrections in requiredFee method
Legend101Zz Aug 14, 2024
ee553e7
minor corrections in requiredFee name , changed to requiredAbsoluteFee
Legend101Zz Aug 14, 2024
9237196
Refactor RBF class with improved state management and error handling
Legend101Zz Aug 16, 2024
63969ab
feat: Implement TransactionAnalyzer for raw transaction analysis
Legend101Zz Aug 19, 2024
0047714
Refactor of TransactionAnalyzer classfor Enhanced Fee Calculation and…
Legend101Zz Aug 22, 2024
28a1ae2
Added Bitcoin Transaction Components and Template
Legend101Zz Aug 22, 2024
8ca1b75
feat: Implemented new CPFP/RBF functions
Legend101Zz Aug 22, 2024
09cceac
chore: changes in utils,types and constants files
Legend101Zz Aug 29, 2024
47e598f
refactor: changes in transactionAnalyzer class and it's tests
Legend101Zz Aug 29, 2024
3c9f3ff
refactor : btcTransactionComponents and btcTransactionTemplate classes
Legend101Zz Aug 29, 2024
93f5e39
refactor: Refactored and corrected RBF and CPFP functions
Legend101Zz Aug 29, 2024
b247da4
changes: add util fn to convert btcTemplate to PSBT
Legend101Zz Sep 1, 2024
6662b2d
refactor : btcComponents and btcTemplate ... toPsbt() method , remove…
Legend101Zz Sep 1, 2024
f6aeea6
refactor: transactionAnalyzer ... removed redundant methods
Legend101Zz Sep 1, 2024
345d6fb
refactor: Changes in btcTransactionInput , Add methods for intiatiati…
Legend101Zz Sep 2, 2024
ad3c6ee
refactor : utils , added more util types for PSBT based calculations
Legend101Zz Sep 2, 2024
a215dea
refactor: RBF/CPFP functions to handle new toPSBT() method of templat…
Legend101Zz Sep 2, 2024
4597dc9
tests: added new btcTransactionComponents tests and refactored other …
Legend101Zz Sep 2, 2024
f39e26d
add README
Legend101Zz Sep 2, 2024
372f919
refactor btcTransactionComponents : Changes to inline docstring comme…
Legend101Zz Sep 9, 2024
d19fd1e
minor README changes
Legend101Zz Sep 9, 2024
272d946
refactor btcTransactionComponents : added methods to validate witness…
Legend101Zz Sep 9, 2024
c75270a
corrected and added new tests to btcTransactionComponents
Legend101Zz Sep 9, 2024
09d9bc5
refactored: btcTransactionTemplate class
Legend101Zz Sep 9, 2024
8da4962
Add ScriptType : Added a new script-type extending MULTISIG_ADDRESS_T…
Legend101Zz Sep 9, 2024
0acce5f
refactot transactionAnalyzer
Legend101Zz Sep 9, 2024
65717ec
minor fix: README link
Legend101Zz Sep 11, 2024
dc02fb5
Refactor: Utils file to remove unnecessary functions, move some util …
Legend101Zz Sep 12, 2024
73dd323
refactor: Transaction Analyzer ... correct rbf-fees calculation , ret…
Legend101Zz Sep 12, 2024
db3ae16
minor-refactor: Add detailed doc strings for ABSURDLY_HIGH_ABS_FEE & …
Legend101Zz Sep 12, 2024
fbd36a1
minor btcTransactionComponents changes
Legend101Zz Sep 12, 2024
82a3c5c
refactor: btcTransactionTemplate add addInputToPsbt & addOutputToPsbt…
Legend101Zz Sep 12, 2024
f142a7f
add: isCPFPFeeSatisfied method from utils to cpfp file
Legend101Zz Sep 12, 2024
104bc75
removed reverseTxid fn from utils
Legend101Zz Sep 16, 2024
e5c98c1
correction: Corrected code to extract input txid from input hash
Legend101Zz Sep 16, 2024
74511cf
correction-tests: Transaction Analyzer
Legend101Zz Sep 16, 2024
6f35442
correction-tests: BTC Components
Legend101Zz Sep 16, 2024
dcffd5e
correction tests: BTC Template
Legend101Zz Sep 22, 2024
788ff6f
correction tests: RBF
Legend101Zz Sep 22, 2024
c3f56c4
correction tests: CPFP
Legend101Zz Sep 22, 2024
74c643b
refactor : tsconfig
Legend101Zz Sep 22, 2024
c570faf
correction : RBF function , ensure that the new bumped tx ,pays gte o…
Legend101Zz Sep 24, 2024
539ac54
RBF : remove console.log statements
Legend101Zz Sep 24, 2024
bddee6e
correction : index file , added all exports
Legend101Zz Sep 24, 2024
ad43a38
correction: RBF calculations
Legend101Zz Sep 24, 2024
e8105cb
refactor: RBF fixtures
Legend101Zz Sep 24, 2024
7150a01
minor changes : Transaction Analyzer - RBF FEE CALCULATION COMMENTS .…
Legend101Zz Sep 27, 2024
a44bedc
added comments : types file
Legend101Zz Sep 27, 2024
663df1e
RBF : Add option in RBF tx creation to prevent
Legend101Zz Sep 27, 2024
09fba1f
RBF-Fixtures : minor comment fixes
Legend101Zz Sep 27, 2024
90b3227
changes: README
Legend101Zz Oct 9, 2024
9b4a174
review-changes: btcTransaction Template
Legend101Zz Oct 16, 2024
cb249e2
review-changes: constants.ts
Legend101Zz Oct 16, 2024
ed9f6c7
review-changes: CPFP
Legend101Zz Oct 16, 2024
1109c68
refactor: CPFP
Legend101Zz Oct 16, 2024
e3fe441
minor-refactor: CPFP
Legend101Zz Oct 16, 2024
d0df3dc
correction : validateCPFPPackage
Legend101Zz Oct 17, 2024
22e5479
Fix-BtcTransactionTemplate: adjustChangeOutput, Preserve sole dust ou…
Legend101Zz Oct 17, 2024
69e44cb
Fix-BtcTransactionTemplate : valildate() function , Enhance BtcTransa…
Legend101Zz Oct 17, 2024
d96b3be
Correction-btcTemplate : validate() function
Legend101Zz Oct 17, 2024
fa292dc
Add-method: needsChange
Legend101Zz Oct 17, 2024
ee59d3f
Fix : TxAnalyzer RBF calculations
Legend101Zz Oct 17, 2024
5c80694
Review-changes: RBF
Legend101Zz Oct 17, 2024
c34de8a
Refactor-RBF: Common-functionality between acceleration and cancellat…
Legend101Zz Oct 18, 2024
787be0d
review-changes : PSBTV2
Legend101Zz Oct 18, 2024
4f6b067
Fix-Utils : estimateTransactionVsize
Legend101Zz Oct 18, 2024
945d644
FINAL NITS
Legend101Zz Oct 21, 2024
96b4e44
Merge branch 'main' into fee-bumping
bucko13 Oct 21, 2024
9676c49
refactor-RBF: remove analysis object
Legend101Zz Oct 22, 2024
4057659
review-changes: CPFP
Legend101Zz Oct 22, 2024
d46fa32
FINAL NITS:2
Legend101Zz Oct 23, 2024
8f2335b
FINAL NITS:3
Legend101Zz Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/real-ravens-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@caravan/psbt": minor
---

Added methods to handle sequence numbers within PSBTs for better RBF (Replace-By-Fee) support:
Legend101Zz marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions packages/caravan-fees/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: ["@caravan/eslint-config/library.js"],
parser: "@typescript-eslint/parser",
rules: {
"@typescript-eslint/no-duplicate-enum-values": "warn",
},
};
4 changes: 4 additions & 0 deletions packages/caravan-fees/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tabWidth": 2,
"useTabs": false
}
336 changes: 336 additions & 0 deletions packages/caravan-fees/README.md
Legend101Zz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,336 @@
# Caravan Fees Package

## Table of Contents
1. [Introduction](#introduction)
2. [Key Components](#key-components)
3. [Transaction Analyzer](#transaction-analyzer)
4. [BTC Transaction Template](#btc-transaction-template)
5. [RBF (Replace-By-Fee)](#rbf-replace-by-fee)
6. [CPFP (Child-Pays-For-Parent)](#cpfp-child-pays-for-parent)
7. [Usage Examples](#usage-examples)
8. [Advanced Customization](#advanced-customization)
9. [Best Practices](#best-practices)
10. [References](#references)

## Introduction

The Caravan Fees Package is a comprehensive toolkit for Bitcoin transaction fee management, focusing on Replace-By-Fee (RBF) and Child-Pays-For-Parent (CPFP) strategies. This package provides developers with powerful tools to analyze existing transactions, estimate appropriate fees, and create new transactions for fee bumping purposes.

### Why Use This Package?

- **Simplified Fee Management**: Automates complex calculations for RBF and CPFP.
- **Flexible Transaction Building**: Utilizes a template-based approach for creating new transactions.
- **Comprehensive Transaction Analysis**: Provides detailed insights into transaction properties and fee structures.
- **Customizable**: Allows for fine-tuned control over fee strategies and transaction construction.

## Key Components

The package consists of several key components:

1. **Transaction Analyzer**: Analyzes existing transactions and provides recommendations.
2. **BTC Transaction Template**: A flexible class for building new Bitcoin transactions.
3. **RBF Functions**: Utilities for creating Replace-By-Fee transactions.
4. **CPFP Functions**: Utilities for creating Child-Pays-For-Parent transactions.
5. **Utility Functions**: Helper functions for various Bitcoin-related calculations.

## Transaction Analyzer

The `TransactionAnalyzer` class is the cornerstone of the package, providing comprehensive analysis of Bitcoin transactions.

### Features:

- Analyzes transaction inputs, outputs, fees, and size.
- Determines RBF and CPFP eligibility.
- Recommends optimal fee bumping strategy.
- Estimates fees for RBF and CPFP operations.

### Usage:

```javascript
const analyzer = new TransactionAnalyzer({
txHex: "raw_transaction_hex",
network: Network.MAINNET,
targetFeeRate: 5, // sats/vbyte
absoluteFee: "1000", // in satoshis
availableUtxos: [...], // array of available UTXOs
requiredSigners: 2,
totalSigners: 3,
addressType: "P2WSH"
});

const analysis = analyzer.analyze();
console.log(analysis);
Legend101Zz marked this conversation as resolved.
Show resolved Hide resolved

```
## Example Output

```json
{
"txid": "1a2b3c4d5e6f...",
"vsize": 140,
"weight": 560,
"fee": "1000",
"feeRate": 7.14,
"inputs": [...],
"outputs": [...],
"isRBFSignaled": true,
"canRBF": true,
"canCPFP": true,
"recommendedStrategy": "RBF",
"estimatedRBFFee": "1200",
"estimatedCPFPFee": "1500"
}
```

# BTC Transaction Template

The `BtcTransactionTemplate` class provides a flexible way to construct new Bitcoin transactions, particularly useful for RBF and CPFP operations.

## Why Use a Template?

The template approach offers several advantages:

- **Flexibility**: Easily add, remove, or modify inputs and outputs.
- **Incremental Building**: Build transactions step-by-step, adjusting as needed and validating as needed.
- **Fee Management**: Automatically calculate and adjust fees based on target rates.
- **Change Handling**: Dynamically manage change outputs.

## Key Methods

- **`addInput(input: BtcTxInputTemplate)`**: Add a new input to the transaction.
- **`addOutput(output: BtcTxOutputTemplate)`**: Add a new output to the transaction.
- **`adjustChangeOutput()`**: Automatically adjust the change output based on fees.
- **`validate()`**: Ensure the transaction meets all necessary criteria.
- **`toPsbt()`**: Convert the transaction to a Partially Signed Bitcoin Transaction (PSBT).

## Usage Example

```javascript
const txTemplate = new BtcTransactionTemplate({
targetFeeRate: 5,
dustThreshold: "546",
network: Network.MAINNET,
scriptType: "P2WSH",
requiredSigners: 2,
totalSigners: 3
});

txTemplate.addInput(new BtcTxInputTemplate({
txid: "previous_txid",
vout: 0,
amountSats: "100000"
}));

txTemplate.addOutput(new BtcTxOutputTemplate({
address: "recipient_address",
amountSats: "90000",
type: TxOutputType.EXTERNAL
}));

txTemplate.adjustChangeOutput();

if (txTemplate.validate()) {
const psbt = txTemplate.toPsbt();
console.log("PSBT:", psbt);
}
```

## RBF (Replace-By-Fee)

The RBF functionality allows for the creation of transactions that replace existing unconfirmed transactions with higher fee versions.

### Key Functions

- **`createCancelRbfTransaction`**: Creates a transaction that cancels an existing unconfirmed transaction.
- **`createAcceleratedRbfTransaction`**: Creates a transaction that accelerates an existing unconfirmed transaction.

### RBF Calculations

The package provides flexibility in defining constraints for fee bumping while ensuring compliance with BIP125 rules.
It performs the following key actions:

- Allows users to specify custom fee rate and absolute fee targets.
- Ensures the new transaction meets BIP125 requirements, including:
- At least one input from the original transaction.
- New fee must be higher than the old fee.
- New absolute fee must meet the minimum relay fee requirement.
- Performs sanity checks to prevent overpayment and ensure transaction validity.


## Usage Example

```javascript
const cancelRbfTx = createCancelRbfTransaction(
{
originalTx: "020000000001...", // original transaction hex
availableInputs: [
{ txid: "abc123...", vout: 0, value: "10000" },
// ... more UTXOs
],
cancelAddress: "bc1q...",
network: Network.MAINNET,
dustThreshold: "546",
scriptType: "P2WSH",
requiredSigners: 2,
totalSigners: 3,
targetFeeRate: 5,
absoluteFee: "1000",
fullRBF: false,
strict: true
}
);

console.log("Cancel RBF PSBT:", cancelRbfTx);
Legend101Zz marked this conversation as resolved.
Show resolved Hide resolved
// Example output:
// Cancel RBF PSBT: cHNidP8BAH0CAAAAAbhbgd8Rm7xkjyGgIPz/tQm8YUH4xXcK...
```

## CPFP (Child-Pays-For-Parent)

The **CPFP** functionality allows for the creation of child transactions that increase the effective fee rate of unconfirmed parent transactions.

### Key Function

**`createCPFPTransaction`**: Creates a child transaction that spends an output from an unconfirmed parent transaction, including a higher fee to incentivize confirmation of both transactions.

### CPFP Calculations

The package calculates the necessary fee for the child transaction to bring the overall package (parent + child) fee rate up to the desired level using the following formula:

```plaintext
child_fee = (target_fee_rate * (parent_size + child_size)) - parent_fee
```
## Usage Example
```javascript
const cpfpTx = createCPFPTransaction(
{
originalTx: "020000000001...", // original transaction hex
availableInputs: [
{ txid: "def456...", vout: 1, value: "20000" },
// ... more UTXOs
],
spendableOutputIndex: 1,
changeAddress: "bc1q...",
network: Network.MAINNET,
dustThreshold: "546",
scriptType: "P2WSH",
targetFeeRate: 10,
absoluteFee: "1000",
requiredSigners: 2,
totalSigners: 3,
strict: true
}
);

console.log("CPFP PSBT:", cpfpTx);
// Example output:
// CPFP PSBT: cHNidP8BAH0CAAAAAT+X8zhpWKt0cK8nYEslhQLwCxFR5Zk3wl...

```


### Manual RBF Implementation:

```javascript
// Analyze the original transaction
const analyzer = new TransactionAnalyzer({...});
const analysis = analyzer.analyze();

// Create a new transaction template
const rbfTemplate = new BtcTransactionTemplate({...});

// Add at least one input from the original transaction
const originalInput = analysis.inputs[0];
rbfTemplate.addInput(new BtcTxInputTemplate({
txid: originalInput.txid,
vout: originalInput.vout,
amountSats: originalInput.amountSats
}));

// Add more inputs if necessary
while (!rbfTemplate.areFeesPaid()) {
// Add additional input...
}

// Add outputs (keeping original outputs for acceleration, or new output for cancellation)
analysis.outputs.forEach(output => {
rbfTemplate.addOutput(new BtcTxOutputTemplate({
address: output.address,
amountSats: output.value.toString(),
type: TxOutputType.EXTERNAL
}));
});

// Adjust change output
rbfTemplate.adjustChangeOutput();

// Validate and create PSBT
if (rbfTemplate.validate()) {
const psbt = rbfTemplate.toPsbt();
console.log("RBF PSBT:", psbt);
}
```

### Manual CPFP Implementation:

```javascript
// Analyze the parent transaction
const analyzer = new TransactionAnalyzer({...});
const analysis = analyzer.analyze();

// Create a new transaction template for the child
const cpfpTemplate = new BtcTransactionTemplate({...});

// Add the spendable output from the parent as an input
const parentOutput = analysis.outputs[spendableOutputIndex];
cpfpTemplate.addInput(new BtcTxInputTemplate({
txid: analysis.txid,
vout: spendableOutputIndex,
amountSats: parentOutput.value.toString()
}));

// Add a change output
cpfpTemplate.addOutput(new BtcTxOutputTemplate({
address: changeAddress,
amountSats: "0", // Will be adjusted later
type: TxOutputType.CHANGE
}));

// Add additional inputs if necessary
while (!cpfpTemplate.areFeesPaid()) {
// Add additional input...
}

// Adjust change output
cpfpTemplate.adjustChangeOutput();

// Validate and create PSBT
if (cpfpTemplate.validate()) {
const psbt = cpfpTemplate.toPsbt();
console.log("CPFP PSBT:", psbt);
}
```
## Advanced Customization

The package allows for advanced customization through various options:

- **Custom Fee Calculations**: Implement custom fee estimation logic by extending the `TransactionAnalyzer` class.
- **Transaction Templates**: Create custom transaction templates for specific use cases by extending `BtcTransactionTemplate`.


## Best Practices

- **Validate Transactions**: Always validate transactions before broadcasting.
- **Consider Mempool State**: Consider the mempool state and current network conditions when setting fee rates.
- **Use Strict Mode**: Use the strict mode in RBF/CPFP transactions for mission-critical operations.
- **Update Regularly**: Regularly update the package to ensure compatibility with the latest Bitcoin network rules.

## References

- **[BIP 125: Opt-in Full Replace-by-Fee Signaling](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki)**
- **[Bitcoin Core RBF Implementation](https://github.com/bitcoin/bitcoin/pull/6871)**
- **[Bitcoin Optech: Replace-by-Fee](https://bitcoinops.org/en/topics/replace-by-fee/)**
- **[Bitcoin Optech: Child Pays for Parent](https://bitcoinops.org/en/topics/cpfp/)**
- **[BIP 174: Partially Signed Bitcoin Transaction Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)**

This package provides a comprehensive solution for managing Bitcoin transaction fees, particularly focusing on RBF and CPFP strategies. By leveraging the `TransactionAnalyzer` and `BtcTransactionTemplate` classes, developers can easily implement complex fee bumping strategies in their applications, ensuring efficient and timely transaction processing on the Bitcoin network.
22 changes: 22 additions & 0 deletions packages/caravan-fees/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { JestConfigWithTsJest } from "ts-jest";

const config: JestConfigWithTsJest = {
extensionsToTreatAsEsm: [".ts"],
verbose: true,

testEnvironment: "node",
testPathIgnorePatterns: ["./lib"],
transformIgnorePatterns: ["/node_modules/(?!uint8array-tools)"],
transform: {
"^.+\\.js$": "babel-jest",
"^.+\\.ts?$": [
"ts-jest",
{
useESM: true,
},
],
},
setupFiles: ["<rootDir>/jest.setup.ts"],
};

export default config;
12 changes: 12 additions & 0 deletions packages/caravan-fees/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { TextEncoder, TextDecoder } from "util";
import "@inrupt/jest-jsdom-polyfills";

// Polyfill TextEncoder and TextDecoder
global.TextEncoder = TextEncoder as any;
global.TextDecoder = TextDecoder as any;

// Define `self` for environments where it's not available (like Node.js)
(global as any).self = global;

// Polyfill missing properties for `Window` type compatibility
(global as any).name = "";
Loading
Loading