diff --git a/web/cashtab/src/hooks/useWallet.js b/web/cashtab/src/hooks/useWallet.js --- a/web/cashtab/src/hooks/useWallet.js +++ b/web/cashtab/src/hooks/useWallet.js @@ -234,7 +234,7 @@ hash160AndAddressObjArray, ); console.log( - `chronikTxHistory as flattened array, sorted by blockheight and time first seen`, + `chronikTxHistory as flattened array, sorted by blockheight and time first seen, with parse info`, chronikTxHistory, ); diff --git a/web/cashtab/src/utils/__tests__/chronik.test.js b/web/cashtab/src/utils/__tests__/chronik.test.js --- a/web/cashtab/src/utils/__tests__/chronik.test.js +++ b/web/cashtab/src/utils/__tests__/chronik.test.js @@ -213,6 +213,7 @@ expect(parseChronikTx(lambdaIncomingXecTx, lambdaHash160s)).toStrictEqual({ incoming: true, xecAmount: '42', + originatingHash160: '4e532257c01b310b3b5c1fd947c79a72addf8523', isEtokenTx: false, }); }); @@ -220,6 +221,7 @@ expect(parseChronikTx(lambdaOutgoingXecTx, lambdaHash160s)).toStrictEqual({ incoming: false, xecAmount: '222', + originatingHash160: '76458db0ed96fe9863fc1ccec9fa2cfab884b0f6', isEtokenTx: false, }); }); @@ -230,6 +232,7 @@ incoming: true, xecAmount: '5.46', isEtokenTx: true, + originatingHash160: '4e532257c01b310b3b5c1fd947c79a72addf8523', slpMeta: { tokenId: '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', @@ -246,6 +249,7 @@ incoming: false, xecAmount: '5.46', isEtokenTx: true, + originatingHash160: '76458db0ed96fe9863fc1ccec9fa2cfab884b0f6', slpMeta: { tokenId: '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', diff --git a/web/cashtab/src/utils/chronik.js b/web/cashtab/src/utils/chronik.js --- a/web/cashtab/src/utils/chronik.js +++ b/web/cashtab/src/utils/chronik.js @@ -420,6 +420,7 @@ // Assign defaults let incoming = true; let xecAmount = new BigNumber(0); + let originatingHash160 = ''; let etokenAmount = new BigNumber(0); const isEtokenTx = 'slpTxData' in tx && typeof tx.slpTxData !== 'undefined'; @@ -427,6 +428,29 @@ for (let i = 0; i < inputs.length; i += 1) { const thisInput = inputs[i]; const thisInputSendingHash160 = thisInput.outputScript; + /* + + Assume the first input is the originating address + + https://en.bitcoin.it/wiki/Script for reference + + Assume standard pay-to-pubkey-hash tx + scriptPubKey: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + 76 + a9 + 14 = OP_DUP + OP_HASH160 + 14 Bytes to push + 88 + ac = OP_EQUALVERIFY + OP_CHECKSIG + + So, the hash160 we want will be in between '76a914' and '88ac' + ...most of the time ;) + */ + try { + originatingHash160 = thisInputSendingHash160.substring( + thisInputSendingHash160.indexOf('76a914') + '76a914'.length, + thisInputSendingHash160.lastIndexOf('88ac'), + ); + } catch (err) { + // If the transaction is nonstandard, don't worry about a reply address for now + originatingHash160 = 'N/A'; + } for (let j = 0; j < walletHash160s.length; j += 1) { const thisWalletHash160 = walletHash160s[j]; if (thisInputSendingHash160.includes(thisWalletHash160)) { @@ -501,13 +525,14 @@ return { incoming, xecAmount, + originatingHash160, isEtokenTx, etokenAmount, slpMeta, }; } // Otherwise do not include these fields - return { incoming, xecAmount, isEtokenTx }; + return { incoming, xecAmount, originatingHash160, isEtokenTx }; }; export const getTxHistoryChronik = async ( @@ -540,5 +565,18 @@ currency.txHistoryCount, ); - return sortedTxHistoryArray; + // Get hash160 array + const hash160array = []; + for (let i = 0; i < hash160AndAddressObjArray.length; i += 1) { + hash160array.push(hash160AndAddressObjArray[i].hash160); + } + // Parse txs + const parsedTxs = []; + for (let i = 0; i < sortedTxHistoryArray.length; i += 1) { + const sortedTx = sortedTxHistoryArray[i]; + sortedTx.parsed = parseChronikTx(sortedTx, hash160array); + parsedTxs.push(sortedTx); + } + + return parsedTxs; };