Last active
December 22, 2019 15:24
-
-
Save christroutner/a1746f6f6033747f058cb5d1b37c411e to your computer and use it in GitHub Desktop.
p-retry BCH transactions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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