Files
bch-js/test/e2e/send-raw-transaction-single/sendrawtransaction.js
T

187 lines
5.6 KiB
JavaScript

/*
This is an end-to-end test adapted from the send-bch example. It's purpose
is to test the sendRawTransaction endpoint.
This version tests the single send call.
Instructions:
- Ensure the address in the wallet.json file has some tBCH.
- Ensure the address in the wallet.json file has a UTXOs between 0.1 and
0.001 tBCH
- This test will generate a single transaction from a UTXOs and broadcast it
using the sendrawtransaction single GET endpoint.
*/
// Replace the address below with the address you want to send the BCH to.
const RECV_ADDR1 = 'bchtest:qzfn2mly05t6fjsh5kjj0dqq0jjtct27ng089dgg05'
const SATOSHIS_TO_SEND = 1000
// Instantiate BITBOX.
const bitboxLib = '../../../lib/BITBOX'
const BITBOXSDK = require(bitboxLib)
const BITBOX = new BITBOXSDK({ restURL: 'https://trest.bitcoin.com/v2/' })
// const BITBOX = new BITBOXSDK({ restURL: "http://localhost:3000/v2/" })
// const util = require('util')
// Open the wallet generated with create-wallet.
let walletInfo = {}
try {
walletInfo = require('./wallet.json')
} catch (err) {
console.log(
'Could not open wallet.json. Generate a wallet with create-wallet first.'
)
process.exit(0)
}
const SEND_ADDR = walletInfo.cashAddress
const SEND_MNEMONIC = walletInfo.mnemonic
async function testSend () {
try {
const hex1 = await buildTx1(RECV_ADDR1)
// const hex2 = await buildTx2(RECV_ADDR2)
console.log(`hex1: ${hex1}\n\n`)
// console.log(`hex2: ${hex2}\n\n`)
const broadcast = await BITBOX.RawTransactions.sendRawTransaction(hex1)
console.log(`Transaction IDs: ${JSON.stringify(broadcast, null, 2)}`)
console.log('Should return a TXID string.')
} catch (err) {
console.log('Error in testSend: ', err)
}
}
testSend()
// Build a TX hex with the largest UTXO.
async function buildTx1 (recAddr) {
try {
// Get the balance of the sending address.
const balance = await getBCHBalance(SEND_ADDR, false)
console.log(`balance: ${JSON.stringify(balance, null, 2)}`)
console.log(`Balance of sending address ${SEND_ADDR} is ${balance} BCH.`)
// Exit if the balance is zero.
if (balance <= 0.0) {
console.log('Balance of sending address is zero. Exiting.')
process.exit(0)
}
const SEND_ADDR_LEGACY = BITBOX.Address.toLegacyAddress(SEND_ADDR)
const RECV_ADDR_LEGACY = BITBOX.Address.toLegacyAddress(recAddr)
console.log(`Sender Legacy Address: ${SEND_ADDR_LEGACY}`)
console.log(`Receiver Legacy Address: ${RECV_ADDR_LEGACY}`)
// const balance2 = await getBCHBalance(recAddr, false)
// console.log(`Balance of recieving address ${recAddr} is ${balance2} BCH.`)
await getBCHBalance(recAddr, false)
const u = await BITBOX.Address.utxo(SEND_ADDR)
// console.log(`u: ${JSON.stringify(u, null, 2)}`)
const utxo = findBiggestUtxo(u.utxos)
console.log(`utxo: ${JSON.stringify(utxo, null, 2)}`)
// instance of transaction builder
const transactionBuilder = new BITBOX.TransactionBuilder('testnet')
const satoshisToSend = SATOSHIS_TO_SEND
const originalAmount = utxo.satoshis
const vout = utxo.vout
const txid = utxo.txid
// add input with txid and index of vout
transactionBuilder.addInput(txid, vout)
// get byte count to calculate fee. paying 1.2 sat/byte
const byteCount = BITBOX.BitcoinCash.getByteCount(
{ P2PKH: 1 },
{ P2PKH: 2 }
)
console.log(`byteCount: ${byteCount}`)
const satoshisPerByte = 1.0
const txFee = Math.floor(satoshisPerByte * byteCount)
console.log(`txFee: ${txFee}`)
// amount to send back to the sending address.
// It's the original amount - 1 sat/byte for tx size
const remainder = originalAmount - satoshisToSend - txFee
// add output w/ address and amount to send
transactionBuilder.addOutput(recAddr, satoshisToSend)
transactionBuilder.addOutput(SEND_ADDR, remainder)
// Generate a change address from a Mnemonic of a private key.
const change = changeAddrFromMnemonic(SEND_MNEMONIC)
// Generate a keypair from the change address.
const keyPair = BITBOX.HDNode.toKeyPair(change)
// Sign the transaction with the HD node.
let redeemScript
transactionBuilder.sign(
0,
keyPair,
redeemScript,
transactionBuilder.hashTypes.SIGHASH_ALL,
originalAmount
)
// build tx
const tx = transactionBuilder.build()
// output rawhex
const hex = tx.toHex()
return hex
} catch (err) {
console.log('Error in buildTx().')
throw err
}
}
// Generate a change address from a Mnemonic of a private key.
function changeAddrFromMnemonic (mnemonic) {
// root seed buffer
const rootSeed = BITBOX.Mnemonic.toSeed(mnemonic)
// master HDNode
const masterHDNode = BITBOX.HDNode.fromSeed(rootSeed, 'testnet')
// HDNode of BIP44 account
const account = BITBOX.HDNode.derivePath(masterHDNode, "m/44'/145'/0'")
// derive the first external change address HDNode which is going to spend utxo
const change = BITBOX.HDNode.derivePath(account, '0/0')
return change
}
// Get the balance in BCH of a BCH address.
async function getBCHBalance (addr, verbose) {
try {
const result = await BITBOX.Address.details(addr)
if (verbose) console.log(result)
const bchBalance = result
return bchBalance.balance
} catch (err) {
console.error('Error in getBCHBalance: ', err)
console.log(`addr: ${addr}`)
throw err
}
}
// Returns the utxo with the biggest balance from an array of utxos.
function findBiggestUtxo (utxos) {
// Sort the utxos by the amount of satoshis, largest first.
utxos.sort(function (a, b) {
return b.satoshis - a.satoshis
})
return utxos[0]
}