Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/hooks/useBCH.js
Show All 27 Lines | const getRestUrl = (apiIndex = 0) => { | ||||
: process.env.REACT_APP_BCHA_APIS_TEST; | : process.env.REACT_APP_BCHA_APIS_TEST; | ||||
const apiArray = apiString.split(','); | const apiArray = apiString.split(','); | ||||
return apiArray[apiIndex]; | return apiArray[apiIndex]; | ||||
}; | }; | ||||
// filter out prefixes for OP_RETURN encoded messages | // filter out prefixes for OP_RETURN encoded messages | ||||
// Note: only for use with encoded message strings | // Note: only for use with encoded message strings | ||||
const removeOpReturnPrefixes = asmStr => { | const removeOpReturnPrefixes = asmStr => { | ||||
if (asmStr.includes(' 621')) { | let msgPrefix = ' ' + currency.opReturn.opreturnMessagePrefixAsm; | ||||
//strip out the 621 (6d02) prefix if exists | if (asmStr.includes(msgPrefix)) { | ||||
asmStr = asmStr.replace(' 621', ''); | //strip out the message prefix if exists | ||||
asmStr = asmStr.replace(msgPrefix, ''); | |||||
} | } | ||||
return asmStr; | return asmStr; | ||||
}; | }; | ||||
const flattenTransactions = ( | const flattenTransactions = ( | ||||
txHistory, | txHistory, | ||||
txCount = currency.txHistoryCount, | txCount = currency.txHistoryCount, | ||||
) => { | ) => { | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | const parseTxData = txData => { | ||||
continue; | continue; | ||||
} | } | ||||
parsedTx.confirmations = tx.confirmations; | parsedTx.confirmations = tx.confirmations; | ||||
parsedTx.blocktime = tx.blocktime; | parsedTx.blocktime = tx.blocktime; | ||||
let amountSent = 0; | let amountSent = 0; | ||||
let amountReceived = 0; | let amountReceived = 0; | ||||
let opReturnMessage = ''; | let opReturnMessage = ''; | ||||
let isCashtabMessage = false; | |||||
// Assume an incoming transaction | // Assume an incoming transaction | ||||
let outgoingTx = false; | let outgoingTx = false; | ||||
let tokenTx = false; | let tokenTx = false; | ||||
// If vin includes tx address, this is an outgoing tx | // If vin includes tx address, this is an outgoing tx | ||||
// Note that with bch-input data, we do not have input amounts | // Note that with bch-input data, we do not have input amounts | ||||
for (let j = 0; j < tx.vin.length; j += 1) { | for (let j = 0; j < tx.vin.length; j += 1) { | ||||
const thisInput = tx.vin[j]; | const thisInput = tx.vin[j]; | ||||
if (thisInput.address === tx.address) { | if (thisInput.address === tx.address) { | ||||
// This is an outgoing transaction | // This is an outgoing transaction | ||||
outgoingTx = true; | outgoingTx = true; | ||||
} | } | ||||
} | } | ||||
// Iterate over vout to find how much was sent or received | // Iterate over vout to find how much was sent or received | ||||
for (let j = 0; j < tx.vout.length; j += 1) { | for (let j = 0; j < tx.vout.length; j += 1) { | ||||
const thisOutput = tx.vout[j]; | const thisOutput = tx.vout[j]; | ||||
// If there is no addresses object in the output, it's either an OP_RETURN msg or token tx | // If there is no addresses object in the output, it's either an OP_RETURN msg or token tx | ||||
if ( | if ( | ||||
!Object.keys(thisOutput.scriptPubKey).includes('addresses') | !Object.keys(thisOutput.scriptPubKey).includes('addresses') | ||||
) { | ) { | ||||
let asm = thisOutput.scriptPubKey.asm; | let asm = thisOutput.scriptPubKey.asm; | ||||
if (asm.includes('OP_RETURN 5262419')) { | let eTokenSubstring = | ||||
'OP_RETURN ' + currency.opReturn.eTokenPrefixAsm; | |||||
if (asm.includes(eTokenSubstring)) { | |||||
// assume this is an eToken tx for now | // assume this is an eToken tx for now | ||||
// future diffs will add additional NFT parsing logic in this segment | // future diffs will add additional NFT parsing logic in this segment | ||||
tokenTx = true; | tokenTx = true; | ||||
} else { | } else { | ||||
// if this is not an eToken tx and does not contain addresses, then assume encoded message | // if this is not an eToken tx and does not contain addresses, then assume encoded message | ||||
asm = removeOpReturnPrefixes(asm); | asm = removeOpReturnPrefixes(asm); | ||||
let msgBody = asm.substr(asm.indexOf(' ') + 1); // extract everything after the OP_RETURN opcode | let msgBody = asm.substr(asm.indexOf(' ') + 1); // extract everything after the OP_RETURN opcode | ||||
try { | try { | ||||
if ( | |||||
msgBody.split(' ')[0] === | |||||
currency.opReturn.cashtabPrefixAsm | |||||
) { | |||||
// this is a Cashtab.com generated message | |||||
opReturnMessage = Buffer.from( | |||||
msgBody.substr(msgBody.indexOf(' ') + 1), | |||||
'hex', | |||||
); // extract everything after the Cashtab prefix | |||||
isCashtabMessage = true; | |||||
} else { | |||||
opReturnMessage = Buffer.from(msgBody, 'hex'); | opReturnMessage = Buffer.from(msgBody, 'hex'); | ||||
} | |||||
} catch (err) { | } catch (err) { | ||||
// if an unexpected or invalid hex is encountered | |||||
opReturnMessage = ''; | opReturnMessage = ''; | ||||
} | } | ||||
} | } | ||||
continue; // skipping the remainder of tx data parsing logic in both token and OP_RETURN tx cases | continue; // skipping the remainder of tx data parsing logic in both token and OP_RETURN tx cases | ||||
} | } | ||||
if ( | if ( | ||||
thisOutput.scriptPubKey.addresses && | thisOutput.scriptPubKey.addresses && | ||||
thisOutput.scriptPubKey.addresses[0] === tx.address | thisOutput.scriptPubKey.addresses[0] === tx.address | ||||
Show All 11 Lines | const parseTxData = txData => { | ||||
} | } | ||||
// Construct parsedTx | // Construct parsedTx | ||||
parsedTx.amountSent = amountSent; | parsedTx.amountSent = amountSent; | ||||
parsedTx.amountReceived = amountReceived; | parsedTx.amountReceived = amountReceived; | ||||
parsedTx.tokenTx = tokenTx; | parsedTx.tokenTx = tokenTx; | ||||
parsedTx.outgoingTx = outgoingTx; | parsedTx.outgoingTx = outgoingTx; | ||||
parsedTx.destinationAddress = destinationAddress; | parsedTx.destinationAddress = destinationAddress; | ||||
parsedTx.opReturnMessage = opReturnMessage; | parsedTx.opReturnMessage = opReturnMessage; | ||||
parsedTx.isCashtabMessage = isCashtabMessage; | |||||
parsedTxHistory.push(parsedTx); | parsedTxHistory.push(parsedTx); | ||||
} | } | ||||
return parsedTxHistory; | return parsedTxHistory; | ||||
}; | }; | ||||
const getTxHistory = async (BCH, addresses) => { | const getTxHistory = async (BCH, addresses) => { | ||||
let txHistoryResponse; | let txHistoryResponse; | ||||
try { | try { | ||||
▲ Show 20 Lines • Show All 787 Lines • ▼ Show 20 Lines | ) => { | ||||
// Start of building the OP_RETURN output. | // Start of building the OP_RETURN output. | ||||
// only build the OP_RETURN output if the user supplied it | // only build the OP_RETURN output if the user supplied it | ||||
if ( | if ( | ||||
typeof optionalOpReturnMsg !== 'undefined' && | typeof optionalOpReturnMsg !== 'undefined' && | ||||
optionalOpReturnMsg.trim() !== '' | optionalOpReturnMsg.trim() !== '' | ||||
) { | ) { | ||||
const script = [ | const script = [ | ||||
BCH.Script.opcodes.OP_RETURN, | BCH.Script.opcodes.OP_RETURN, | ||||
Buffer.from('6d02', 'hex'), | Buffer.from( | ||||
currency.opReturn.opReturnPrefixHex + | |||||
currency.opReturn.opReturnPushDataHex, | |||||
'hex', | |||||
), | |||||
Buffer.from(currency.opReturn.cashtabPrefixHex, 'hex'), | |||||
Buffer.from(optionalOpReturnMsg), | Buffer.from(optionalOpReturnMsg), | ||||
]; | ]; | ||||
const data = BCH.Script.encode(script); | const data = BCH.Script.encode(script); | ||||
transactionBuilder.addOutput(data, 0); | transactionBuilder.addOutput(data, 0); | ||||
} | } | ||||
// End of building the OP_RETURN output. | // End of building the OP_RETURN output. | ||||
let originalAmount = new BigNumber(0); | let originalAmount = new BigNumber(0); | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | return { | ||||
parseTokenInfoForTxHistory, | parseTokenInfoForTxHistory, | ||||
getTxData, | getTxData, | ||||
getRestUrl, | getRestUrl, | ||||
signPkMessage, | signPkMessage, | ||||
sendBch, | sendBch, | ||||
sendToken, | sendToken, | ||||
createToken, | createToken, | ||||
getTokenStats, | getTokenStats, | ||||
removeOpReturnPrefixes, | |||||
}; | }; | ||||
} | } |