mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-21 16:51:59 -07:00
187 lines
5.6 KiB
JavaScript
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]
|
|
}
|