Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/hooks/useBCH.js
Show First 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | const getSlpBalancesAndUtxos = async (BCH, utxos) => { | ||||
} | } | ||||
// Prevent app from treating slpUtxos as nonSlpUtxos | // Prevent app from treating slpUtxos as nonSlpUtxos | ||||
// Must enforce === false as api will occasionally return utxo.isValid === null | // Must enforce === false as api will occasionally return utxo.isValid === null | ||||
// Do not classify utxos with 546 satoshis as nonSlpUtxos as a precaution | // Do not classify utxos with 546 satoshis as nonSlpUtxos as a precaution | ||||
// Do not classify any utxos that include token information as nonSlpUtxos | // Do not classify any utxos that include token information as nonSlpUtxos | ||||
const nonSlpUtxos = hydratedUtxos.filter( | const nonSlpUtxos = hydratedUtxos.filter( | ||||
utxo => | utxo => | ||||
utxo.isValid === false && | utxo.isValid === false && utxo.value !== 546 && !utxo.tokenName, | ||||
utxo.satoshis !== 546 && | |||||
!utxo.tokenName, | |||||
); | ); | ||||
const slpUtxos = hydratedUtxos.filter(utxo => utxo.isValid); | const slpUtxos = hydratedUtxos.filter(utxo => utxo.isValid); | ||||
let tokensById = {}; | let tokensById = {}; | ||||
slpUtxos.forEach(slpUtxo => { | slpUtxos.forEach(slpUtxo => { | ||||
let token = tokensById[slpUtxo.tokenId]; | let token = tokensById[slpUtxo.tokenId]; | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | ) => { | ||||
// Handle error of user having no BCH | // Handle error of user having no BCH | ||||
if (slpBalancesAndUtxos.nonSlpUtxos.length === 0) { | if (slpBalancesAndUtxos.nonSlpUtxos.length === 0) { | ||||
throw new Error( | throw new Error( | ||||
`You need some ${currency.ticker} to send ${currency.tokenTicker}`, | `You need some ${currency.ticker} to send ${currency.tokenTicker}`, | ||||
); | ); | ||||
} | } | ||||
const largestBchUtxo = slpBalancesAndUtxos.nonSlpUtxos.reduce( | const largestBchUtxo = slpBalancesAndUtxos.nonSlpUtxos.reduce( | ||||
(previous, current) => | (previous, current) => | ||||
previous.satoshis > current.satoshis ? previous : current, | previous.value > current.value ? previous : current, | ||||
); | ); | ||||
const bchECPair = BCH.ECPair.fromWIF(largestBchUtxo.wif); | const bchECPair = BCH.ECPair.fromWIF(largestBchUtxo.wif); | ||||
const tokenUtxos = slpBalancesAndUtxos.slpUtxos.filter( | const tokenUtxos = slpBalancesAndUtxos.slpUtxos.filter( | ||||
(utxo, index) => { | (utxo, index) => { | ||||
if ( | if ( | ||||
utxo && // UTXO is associated with a token. | utxo && // UTXO is associated with a token. | ||||
utxo.tokenId === tokenId && // UTXO matches the token ID. | utxo.tokenId === tokenId && // UTXO matches the token ID. | ||||
▲ Show 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | ) => { | ||||
transactionBuilder = new BCH.TransactionBuilder(); | transactionBuilder = new BCH.TransactionBuilder(); | ||||
else transactionBuilder = new BCH.TransactionBuilder('testnet'); | else transactionBuilder = new BCH.TransactionBuilder('testnet'); | ||||
const satoshisToSend = BCH.BitcoinCash.toSatoshi(value.toFixed(8)); | const satoshisToSend = BCH.BitcoinCash.toSatoshi(value.toFixed(8)); | ||||
let originalAmount = new BigNumber(0); | let originalAmount = new BigNumber(0); | ||||
let txFee = 0; | let txFee = 0; | ||||
for (let i = 0; i < utxos.length; i++) { | for (let i = 0; i < utxos.length; i++) { | ||||
const utxo = utxos[i]; | const utxo = utxos[i]; | ||||
originalAmount = originalAmount.plus(utxo.satoshis); | originalAmount = originalAmount.plus(utxo.value); | ||||
const vout = utxo.vout; | const vout = utxo.vout; | ||||
const txid = utxo.txid; | const txid = utxo.txid; | ||||
// add input with txid and index of vout | // add input with txid and index of vout | ||||
transactionBuilder.addInput(txid, vout); | transactionBuilder.addInput(txid, vout); | ||||
inputUtxos.push(utxo); | inputUtxos.push(utxo); | ||||
txFee = encodedOpReturn | txFee = encodedOpReturn | ||||
? calcFee(BCH, inputUtxos, addresses.length + 2) | ? calcFee(BCH, inputUtxos, addresses.length + 2) | ||||
Show All 34 Lines | ) => { | ||||
// Sign the transactions with the HD node. | // Sign the transactions with the HD node. | ||||
for (let i = 0; i < inputUtxos.length; i++) { | for (let i = 0; i < inputUtxos.length; i++) { | ||||
const utxo = inputUtxos[i]; | const utxo = inputUtxos[i]; | ||||
transactionBuilder.sign( | transactionBuilder.sign( | ||||
i, | i, | ||||
BCH.ECPair.fromWIF(utxo.wif), | BCH.ECPair.fromWIF(utxo.wif), | ||||
undefined, | undefined, | ||||
transactionBuilder.hashTypes.SIGHASH_ALL, | transactionBuilder.hashTypes.SIGHASH_ALL, | ||||
utxo.satoshis, | utxo.value, | ||||
); | ); | ||||
} | } | ||||
// build tx | // build tx | ||||
const tx = transactionBuilder.build(); | const tx = transactionBuilder.build(); | ||||
// output rawhex | // output rawhex | ||||
const hex = tx.toHex(); | const hex = tx.toHex(); | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |