This guide explains how to utilize them effectively for managing UTXOs (Unspent Transaction Outputs) in a Bitcoin-based application.
- Purpose: Splits a larger UTXO into multiple 546 sats UTXOs. This is useful for transaction privacy and creating denominations that are easier to split UTXO accurately.
- Usage: Run
npm run split
to divide a large UTXO into small ones according to specified criteria.
- Purpose: Designed to merge multiple UTXOs into a single UTXO, which can be beneficial for simplifying wallet management and reducing the cost of future transactions.
- Usage: Execute
npm run merge
to combine several small UTXOs into one.
- Purpose: Facilitates sending Bitcoins from one address to another. This script likely handles the creation and broadcasting of the transaction to the Bitcoin network.
- Usage: Use
npm run send
to specify the details (e.g., recipient's address) and send the UTXO.
To set up and run this project locally, follow these steps:
-
Clone the Repository: First, clone this repository to your local machine using:
git clone https://github.com/bitmapers/utxo-management.git
-
Install Dependencies: Navigate into your project directory and install the required dependencies:
cd utxo-management npm install
-
Setup Environment Variables: Copy the
.env.example
file to.env
and fill in the necessary Bitcoin network details and key management options.cp .env.example .env
-
Run Scripts: Use the npm run commands listed above to perform different operations like merging, sending, or splitting UTXOs.
-
External Modules:
axios
: For making HTTP requests.bip32
,bip39
: For generating Bitcoin wallet addresses from a hierarchical deterministic (HD) path.bitcoinjs-lib
: A library for Bitcoin protocol functions.dotenv
: Loads environment variables from a.env
file.ecpair
: Represents an elliptic curve pair.tiny-secp256k1
: For elliptic curve cryptography operations.
-
Development Modules:
@types/node
: TypeScript type definitions for Node.js.ts-node
: TypeScript execution environment and REPL for Node.js.typescript
: The TypeScript compiler.
Briefly describe the folder and file structure.
/ - Root directory
|__ /utils - Utility scripts
|__ utxo.ts - Fetch UTXOs for a given address.
|__ wallet.ts - Represents a Bitcoin wallet functionality.
|__ config.ts - Configuration including to Bitcoin network.
|__ index.ts - Main script for executing transactions.
|__ sendUTXO.ts - Send UTXO to other bitcoin address.
|__ splitUTXO.ts - Split UTXO into smaller UTXOs with big UTXO.
|__ mergeUTXO.ts - Merge UTXO into one big UTXO with small UTXOs.
- IUtxo: Interface for Unspent Transaction Outputs which include:
- txid: Transaction ID.
- vout: Output number in the transaction.
- value: Value of the output in satoshis.
Fetches the script pubkey associated with a specific output address in a transaction.
Parameters:
tx
: The transaction ID as a string.address
: The Bitcoin address as a string.
Returns: A promise that resolves to the script pubkey as a string.
Retrieves all UTXOs for a given Bitcoin address.
Parameters:
address
: The Bitcoin address as a string.
Returns: A promise that resolves to an array of UTXOs.
Pushes a raw Bitcoin transaction to the network.
Parameters:
rawtx
: The raw transaction data.
Returns: A promise that resolves to the transaction ID.
postData(url: string, json: any, content_type?: string, apikey?: string): Promise<string | undefined>
General function to send POST requests. Handles error retries related to specific blockchain-related errors.
Parameters:
url
: The API endpoint.json
: The JSON payload for the post request.content_type
: (Optional) Content type of the request, defaults to"text/plain"
.apikey
: (Optional) API key for authenticated requests.
Returns: A promise that resolves to the response data as a string or undefined in case of specific errors.
import { getUtxos } from './path_to_module';
async function displayUtxos() {
const address = 'bitcoin_address_here';
const utxos = await getUtxos(address);
console.log(utxos);
}
displayUtxos();
import { pushBTCpmt } from './path_to_module';
async function sendTransaction() {
const rawTransaction = 'raw_transaction_data_here';
const txid = await pushBTCpmt(rawTransaction);
console.log(`Transaction ID: ${txid}`);
}
sendTransaction();
Calculates the estimated transaction fee for a given PSBT and fee rate. The fee rate is typically expressed in satoshis per byte.
psbt
(Bitcoin.Psbt): The partially signed Bitcoin transaction.feeRate
(number): The fee rate in satoshis per byte.
-
Mock Output Script Creation:
- A dummy output script (
MOCK_OUTPUT_SCRIPT
) and value (MOCK_OUTPUT_VALUE
) are used to mimic a real transaction condition by adding an additional output. This helps in more accurately estimating the size of the final transaction.
- A dummy output script (
-
Transaction Construction:
- A new Bitcoin transaction is instantiated.
- Inputs and their corresponding witness data from the PSBT are added to this new transaction.
- All outputs (from the PSBT and the mock output) are added to the transaction.
-
Size Calculation and Fee Estimation:
- The virtual size of the transaction is calculated. The virtual size is a more accurate measure for fee calculation as it considers the weight of witness data.
- The transaction's virtual size is multiplied by the provided fee rate to estimate the fee in satoshis.
- (number): The calculated transaction fee in satoshis.
const feeRate = 1; // 1 satoshi per byte
const estimatedFee = calculateTxFee(psbt, feeRate);
console.log(`Estimated Transaction Fee: ${estimatedFee} satoshis`);
main(sendToAddress: string)
: this asynchronous function takes a single parameter, sendToAddress
, which is the Bitcoin address where the funds will be sent.
-
Wallet Initialization
- Create an instance of the
Wallet
from theutils/wallet
module. - Log the wallet's address to the console.
- Create an instance of the
-
UTXO Retrieval
- Fetch UTXOs (Unspent Transaction Outputs) associated with the wallet’s address using the
getUtxos
function fromutils/utxo
. - Find a suitable UTXO that has a value greater than 10,000 satoshis. If no such UTXO is found, the function throws an error.
- Fetch UTXOs (Unspent Transaction Outputs) associated with the wallet’s address using the
-
PSBT Creation
- Initialize a new PSBT (Partially Signed Bitcoin Transaction) specifying the Bitcoin testnet.
- Add the selected UTXO as an input to the PSBT.
- Define the transaction outputs:
- One output sending the intended amount (UTXO value minus initial fee) to
sendToAddress
. - Another output is to send the remaining balance (initial fee minus calculated transaction fee) back to the wallet's address as a change.
- One output sending the intended amount (UTXO value minus initial fee) to
-
Transaction Fee Calculation
- Calculate the transaction fee using the transaction’s virtual size and a predefined testnet fee rate.
-
Transaction Signing
- Sign the PSBT using the wallet’s private keys.
-
Transaction Extraction and Broadcast
- Extract the signed transaction from the PSBT.
- Convert the transaction to its hexadecimal representation.
- Broadcast the transaction to the Bitcoin testnet using the
pushBTCpmt
function.
main()
: this asynchronous function with no parameter
-
Create Wallet Instance:
- Instantiate a new wallet, which will autogenerate a new address and key pair.
-
Fetch UTXOs:
- Retrieve all available UTXOs for the wallet address that have a balance greater than a specified amount (10,000 satoshis in this script).
-
Transaction Construction:
- Create a new
Psbt
(Partially Signed Bitcoin Transaction). - Add inputs and outputs to the
Psbt
. Each output sends a fixed amount (546 satoshis in this example) to the wallet address. - Calculate and subtract the transaction fees and send the remaining balance back to the wallet address.
- Create a new
-
Signing the Transaction:
- The transaction is signed using the wallet's private key.
-
Broadcast Transaction:
- The transaction, once signed, is converted to hexadecimal format and broadcasted to the network, returning a transaction ID.
main()
: this asynchronous function with no parameter
-
Initialize Wallet:
- Creates a new wallet instance which will be used to gather UTXOs and sign the transaction.
-
Fetch UTXOs:
- Calls
getUtxos
to retrieve UTXOs for the wallet address.
- Calls
-
Prepare Partially Signed Bitcoin Transaction (PSBT):
- Initializes a PSBT object specific to the Bitcoin testnet.
- Adds inputs for each retrieved UTXO including the necessary details like wallet public key for taproot spend.
-
Calculate Transaction Fee:
- Uses a mock output and fee rate to calculate an appropriate transaction fee based on the virtual size of the transaction.
-
Add Output:
- Adds an output to the transaction, subtracting the calculated fee from the total input value to set the output value.
-
Sign PSBT:
- The wallet signs the PSBT.
-
Broadcast Transaction:
- Extracts the full transaction from PSBT, converts it to hexadecimal, and pushes it to the Bitcoin testnet using
pushBTCpmt
.
- Extracts the full transaction from PSBT, converts it to hexadecimal, and pushes it to the Bitcoin testnet using
The UTXO Management Project is designed to provide a comprehensive suite of utilities to facilitate efficient handling of Bitcoin transactions, ideally suited for developers and organizations involved in cryptocurrency management. By utilizing the split
, merge
, and send
scripts, users can optimize their transaction processes, whether for enhancing privacy, simplifying wallet management, or executing precise fund transfers.