Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@christroutner
Last active December 22, 2019 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christroutner/a1746f6f6033747f058cb5d1b37c411e to your computer and use it in GitHub Desktop.
Save christroutner/a1746f6f6033747f058cb5d1b37c411e to your computer and use it in GitHub Desktop.
p-retry BCH transactions
/*
This is a snippet of a bigget program that I wrote. The code in this file is not stand-alone.
It captures the code used to generate BCH transactions with auto-retry, so that the software
keeps trying to send the transaction if it runs into issues.
It's a good example of how to use the p-retry npm library for auto-retrying promise-based
functions.
*/
// Parent function that starts funding.
async fundTestWallet(flags) {
try {
const source = flags.name // Name of the source wallet.
const dest = flags.dest // Name of the destination wallet.
// Open the source wallet data file.
const sourceFilename = `${__dirname}/../../wallets/${source}.json`
const sourceWalletInfo = this.appUtils.openWallet(sourceFilename)
sourceWalletInfo.name = source
// Open the destination wallet data file.
const destFilename = `${__dirname}/../../wallets/${dest}.json`
const destWalletInfo = this.appUtils.openWallet(destFilename)
destWalletInfo.name = dest
// Determine if this is a testnet wallet or a mainnet wallet.
if (sourceWalletInfo.network === "testnet") {
this.BITBOX = new config.BCHLIB({ restURL: config.TESTNET_REST })
this.appUtils.BITBOX = this.BITBOX
this.send.BITBOX = this.BITBOX
}
// Generate 300 addresses from the test wallet.
const addresses = await this.generateAddresses(
destWalletInfo,
NUMBER_OF_ADDRESSES
)
console.log(`addresses: ${JSON.stringify(addresses, null, 2)}`)
// Fund each of the 300 addresses.
await this.fundAddresses(sourceWalletInfo, addresses)
} catch (err) {
console.log(`Error in fundTestWallet()`)
throw err
}
}
// Generates a series of transactions to fund an array of addresses.
// Funds one addresss at a time, and will auto-retry in the event of failure.
async fundAddresses(walletInfo, addresses) {
try {
// Loop through each address and generate a transaction for each one.
// Add each transaction to a queue with automatic retry.
for (let i = 0; i < addresses.length; i++) {
const address = addresses[i]
console.log(`funding index ${i}, address ${address}`)
// Load the state. p-retry functions can't pass arguments, so they
// are passed this way.
_this.queueState = {
walletInfo,
bch: BCH_TO_SEND,
addr: address
}
const txid = await pRetry(_this.generateTx, {
onFailedAttempt: async () => {
// failed attempt.
console.log("P-retry error")
await _this.sleep(60000 * 2) // Sleep for 2 minutes
},
retries: 5 // Retry 5 times
})
console.log(`Successfully funded address ${address}`)
console.log(`TXID: ${txid}`)
console.log(" ")
console.log(" ")
await _this.sleep(60000 * 1) // Wait some period of time before sending next tx.
}
} catch (err) {
console.log(`Error in fund-test-wallet.js/fundAddresses()`)
throw err
}
}
// Promise-based sleep function.
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
// Returns a promise that resolves to a txid string
// The intention is for the promise to be added to a retry-queue that will
// auto-retry if there is an error.
async generateTx() {
try {
// Retrieve the state. p-rety functions can't pass arguments.
let { walletInfo, bch, addr } = _this.queueState
// Update the wallet
walletInfo = await _this.updateBalances.updateBalances(_this.flags)
// Get info on UTXOs controlled by this wallet.
const utxos = await _this.appUtils.getUTXOs(walletInfo)
console.log(`send utxos: ${JSON.stringify(utxos, null, 2)}`)
// Select optimal UTXO
const utxo = await _this.send.selectUTXO(bch, utxos)
console.log(`selected utxo: ${JSON.stringify(utxo, null, 2)}`)
if (!utxo.txid) throw new Error(`No valid UTXO could be found`)
// For now, change is sent to the root address of the source wallet.
const changeAddr = walletInfo.rootAddress
const hex = await _this.send.sendBCH(
utxo,
bch,
changeAddr,
addr,
walletInfo
)
const txid = await _this.appUtils.broadcastTx(hex)
return txid
} catch (err) {
console.log(`Error in fund-test-wallet.js/generateTx: `, err)
throw new Error(`Error caught in generateTx()`)
// throw err
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment