This guide provides explaining 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 for creating denominations that are easier to split UTXO accurately.
- Usage: Run
npm run splitto 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 mergeto combine several small UTXOs into one.
- Purpose: Facilitates the sending of 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 sendto 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.examplefile to.envand 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.envfile.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
Walletfrom theutils/walletmodule. - 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
getUtxosfunction 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 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
pushBTCpmtfunction.
main(): this asynchronous function with no parameter
-
Create Wallet Instance:
- Instantiate a new wallet, which will autogenerate a new address and keypair.
-
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
getUtxosto 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.
- Telegram @michalstefanow
- Twitter @michalstefanow