Skip to content

Commit

Permalink
Added e2e test for sendRawTransaction single call
Browse files Browse the repository at this point in the history
  • Loading branch information
christroutner committed Feb 21, 2019
1 parent 9ccbc21 commit ede9b46
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 2 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const SATOSHIS_TO_SEND = 1000
// Instantiate BITBOX.
const bitboxLib = "../../../lib/bitbox-sdk"
const BITBOXSDK = require(bitboxLib).default
//const BITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" })
const BITBOX = new BITBOXSDK({ restURL: "http://localhost:3000/v2/" })
const BITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" })
//const BITBOX = new BITBOXSDK({ restURL: "http://localhost:3000/v2/" })

const util = require("util")

Expand Down Expand Up @@ -51,6 +51,7 @@ async function testSend() {
hex2
])
console.log(`Transaction IDs: ${JSON.stringify(broadcast, null, 2)}`)
console.log(`Should return an array of TXID strings.`)
} catch (err) {
console.log(`Error in testSend: `, err)
}
Expand Down
28 changes: 28 additions & 0 deletions test/e2e/send-raw-transaction-single/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "sendrawtransaction",
"version": "1.0.0",
"description": "e2e test - Send two transactions in parallel.",
"main": "sendrawtransaction.js",
"scripts": {
"test": "echo no tests yet",
"start": "node sendrawtransaction.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Bitcoin-com/bitbox-javascript-sdk.git"
},
"keywords": [
"bitbox",
"bch",
"bitcoin",
"bitcoin cash",
"bitcoin.com",
"javascript"
],
"author": "Chris Troutner <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/Bitcoin-com/bitbox-javascript-sdk/issues"
},
"homepage": "https://github.com/Bitcoin-com/bitbox-javascript-sdk/blob/master/README.md"
}
184 changes: 184 additions & 0 deletions test/e2e/send-raw-transaction-single/sendrawtransaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
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-sdk"
const BITBOXSDK = require(bitboxLib).default
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.
try {
var 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.`)

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]
}

0 comments on commit ede9b46

Please sign in to comment.