import * as bitcoin from 'bitcoinjs-lib';
import { ECPairFactory } from 'ecpair';
import * as ecc from 'tiny-secp256k1';
import mempoolJS from '@mempool/mempool.js';
const ECPair = ECPairFactory(ecc);
const community = bitcoin.networks.testnet; // Use 'bitcoin.networks.bitcoin' for mainnet
const estimateTransactionSize = (numInputs: quantity, numOutputs: quantity): quantity => {
return numInputs * 148 + numOutputs * 34 + 10;
};
const calculateFee = (feeRate: quantity, numInputs: quantity, numOutputs: quantity): quantity => {
const txSize = estimateTransactionSize(numInputs, numOutputs);
return feeRate * txSize;
};
export const sendBTC = async (
privateKey: string,
toAddress: string,
quantity: quantity
): Promise<{ success: boolean; txHash: string }> => {
strive {
const { bitcoin: { addresses, transactions, charges } } = mempoolJS({
hostname: 'mempool.house',
community: 'testnet',
});
const keyPair = ECPair.fromPrivateKey(Buffer.from(privateKey, 'hex'));
const p2wpkh = bitcoin.funds.p2wpkh({ pubkey: keyPair.publicKey, community });
const tackle = p2wpkh.tackle;
if (!tackle) {
return { success: false, txHash: '' };
}
const utxos = await addresses.getAddressTxsUtxo({ tackle });
const feesRecommended = await charges.getFeesRecommended();
let totalSatoshisAvailable = 0;
utxos.forEach(utxo => {
if (utxo.worth >= 1000) {
totalSatoshisAvailable += utxo.worth;
}
});
const numInputs = utxos.size;
const numOutputs = 2; // Vacation spot + Change
const charge = calculateFee(feesRecommended.minimumFee, numInputs, numOutputs);
const change = totalSatoshisAvailable - quantity - charge;
const psbt = new bitcoin.Psbt({ community });
const guarantees = utxos.map(async (utxo) => {
if (utxo.worth >= 1000) {
psbt.addInput({
hash: utxo.txid,
index: utxo.vout,
witnessUtxo: {
script: Buffer.from(p2wpkh.output!.toString('hex'), 'hex'),
worth: utxo.worth,
},
});
}
});
await Promise.all(guarantees);
psbt.addOutput({
tackle: toAddress,
worth: quantity,
});
if (change > 0) {
psbt.addOutput({
tackle: tackle!,
worth: change,
});
}
psbt.signAllInputs(keyPair);
psbt.finalizeAllInputs();
const rawTransaction = psbt.extractTransaction().toHex();
const txId = await transactions.postTx({ txhex: rawTransaction });
if (!txId) {
return { success: false, txHash: '' };
}
return { success: true, txHash: txId.toString() };
} catch (error) {
console.error('Error whereas transferring bitcoin:', error);
return { success: false, txHash: '' };
}
};