diff --git a/web/cashtab/src/hooks/__mocks__/mockPublicKeys.js b/web/cashtab/src/hooks/__mocks__/mockPublicKeys.js new file mode 100644 --- /dev/null +++ b/web/cashtab/src/hooks/__mocks__/mockPublicKeys.js @@ -0,0 +1,3 @@ +export default [ + '02c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', +]; diff --git a/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js b/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js --- a/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js +++ b/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js @@ -14,8 +14,6 @@ hex: '473044022064084d72b1bb7ca148d1950cf07494ffb397cb3df53b72afa8bd844b80369ecd02203ae21f14ba5019f38bc0b80b99e7c8cc1d5d3360ca7bab56be28ef583fe5c6a6412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -70,8 +68,6 @@ hex: '4730440220538de8f61d716c899e6a2cd78ca46162edaaa5f0d000ebbbc875608e5639170a02206a7fc8f7c16cef1c56667a8da6d5e480f440ecf43238879ad9f8785a0473a72b412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, { txid: 'b980b35b794ad73d8aae312385e82d9be8086e7b743e1c6a468db8db8ac74bd8', @@ -81,8 +77,6 @@ hex: '483045022100ce03e19bd181b903adc6f192d4ad0900e6816f6e62282cefff05c22cf36a647602202b296a2ed1805f0b0a9aa5f99158685298e7a0aff406fedb8abb8e0afaf48ca4412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -170,8 +164,6 @@ hex: '47304402203ea0558cd917eb8f6c286e79ffcc5dd1f5accb66c2e5836628d6be6f9d03ca260220120a6da92b6f44bdfcd3ef7b08263d3f73d99ff4b1f83b8f998ff1355f3f0d2e412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -248,8 +240,6 @@ hex: '4730440220664f988b86035ddcdff6e9c3b8e140712eca297750d056e41577a0bf0059e7ff022030982b3fcab1cab5d6086bc935e941e7d22efbb0ad5ccca0268515c5c83060894121034509251caa5f01e2787c436949eb94d71dcc451bcde5791ae5b7109255f5f0a3', }, sequence: 4294967295, - address: - 'bitcoincash:qzudj5fd9t0cknnsc3wzdd4sp46u9r42jcnqnwfss0', }, { txid: '50d8292c6255cda7afc6c8566fed3cf42a2794e9619740fe8f4c95431271410e', @@ -259,8 +249,6 @@ hex: '47304402203ce88e0a95d5581ad567c0468c87a08027aa5ecdecd614a168d833d7ecc02c1c022013ddd81147b44ad5488107d5c4d535f7f59e9fa46840451d39422aace284b2b74121034509251caa5f01e2787c436949eb94d71dcc451bcde5791ae5b7109255f5f0a3', }, sequence: 4294967295, - address: - 'bitcoincash:qzudj5fd9t0cknnsc3wzdd4sp46u9r42jcnqnwfss0', }, ], vout: [ @@ -324,8 +312,6 @@ hex: '473044022065622a7aa065f56abe84f3589c983a768e3ef5d72c9352991d6b584a2a16dcb802200c1c0065106207715a024624ed951e851d4f742c55a704e9531bebd2ef84fc1441210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: 'acbb66f826211f40b89e84d9bd2143dfb541d67e1e3c664b17ccd3ba66327a9e', @@ -335,8 +321,6 @@ hex: '483045022100b475cf7d1eaf37641d2107f13be0ef9acbd17b252ed3f9ae349edfdcd6a97cf402202bf2852dfa905e6d50c96a622d2838408ceb979245a4342d5096acc93813580441210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, ], vout: [ @@ -400,8 +384,6 @@ hex: '483045022100f8a8eca8f5d6149511c518d41015512f8164a5be6f01e9efd609db9a429f4872022059121e122043b43eae77b5e132b8f798a290e6eed8a2026a0656540cd1bd752b41210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, ], vout: [ @@ -456,8 +438,6 @@ hex: '483045022100d59e6fad4d1d57796f229a7d4aa3b01fc3241132dae9bc406c66fa33d7aef21c022036a5f432d6d99f65848ac12c00bde2b5ba7e63a9f9a74349d9ab8ec39db26f8e412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -512,8 +492,6 @@ hex: '4730440220184921bfce634a57b5220f06b11b64c0cb7e67ecd9c634335e3e933e35a7a969022038b2074e1d75aa4f6945d150bae5b8a1d426f4284da2b96336fa0fc741eb6de7412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -568,8 +546,6 @@ hex: '483045022100c7f51ff0888c182a1a60c08904d8116c9d2e31cb7d2fd5b63c2bf9fd7b246fc102202ee786d2052448621c4a04d18d13c83ac5ee27008dd079e8ba954f8197ff3c6c412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, { txid: '42d39fbe068a40fe691f987b22fdf04b80f94d71d2fec20a58125e7b1a06d2a9', @@ -579,8 +555,6 @@ hex: '47304402201bbfcd0c120ace9b8c7a6f5e77b61236bb1128e2a757f85ba80101885e9c1212022046fed4006dcd6a236034dede77c566acf74824d14b3ee3da884e9bd93884ff93412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', }, sequence: 4294967295, - address: - 'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9', }, ], vout: [ @@ -635,8 +609,6 @@ hex: '473044022000cc5b79e5da60cf4935f3a172089cd9b631b678462ee29091dc610816d059c4022002e3b6f32e825ac04d2907453d6d647a32a995c798df1c68401cc461f6bfbd3a41210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: '8f73a718d907d94e60c5f73f299bd01dc5b1c163c4ebc26b5304e37a1a7f34af', @@ -646,8 +618,6 @@ hex: '483045022100ac50553448f2a5fab1177ed0bc64541b2dba063d04f2d69a8a1d216fb1435e5802202c7f6abd1685a6d81f14ac3bdb0874d214a5f4260719f9c5dc519ac5d8dffd3741210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: 'd38b76bacd6aa75ad2d6fcfd994533e54d0541435970eace49486fde9d6ee2e3', @@ -657,8 +627,6 @@ hex: '48304502210091836c6cb4c786bd3b74b73e579ddf8b843ba51841e5675fa53608449b67371802203de75f32b684cfe2d2e9cd424ea6eb4f49248e6698365c9364ebf84cd6e50eab41210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: 'd47607a72d6bc093556fa7f2cec9d67719bd627751d5d27bc53c4eb8eb6f54e5', @@ -668,8 +636,6 @@ hex: '483045022100e7727d9d26c645282553aef27947ad6795bc89b505ad089d617b6f696399352802206c736524a1410ed3e30cf1127f7f02c9a249392f8f8e7c670250472909d1c0d641210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: '33f246811f794c4b64098a64c698ae5811054b13e289256a18e2d142beef57e7', @@ -679,8 +645,6 @@ hex: '47304402203fe78ad5aaeefab7b3b2277eefc4a2ace9c2e92694b46bf4a76927bf2b82017102200ded59336aba269a54865d9fdd99e72081c0318ccbc37bc0fc0c72b60ae3538241210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: '25f915d2912524ad602c882211ccaf479d6bf87ef7c24d1be0f325cec3727257', @@ -690,8 +654,6 @@ hex: '4730440220670af03605b9495c8ecee357889ceeb137dadaa1662136fdc55c28fe9434e3c60220285195a62811941745a9f93e136e59c96b81d5b0d9525f3d16d001bc0f6fa9bb41210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: 'c9044b4d7438d006a722ef85474c8127265eced4f72c7d71c2f714444bc0e1f2', @@ -701,8 +663,6 @@ hex: '47304402203f822a0b207ed49e6918663133a18037c24498c2f770c2649333a32f523e259d02203afc42a79d0da123b67f814effeee7c05c7996ea829b3cfa46c5c2e74209c09641210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: '045306f0019ae0d977de7ff17dd55e861b3fe94458693ee2b94ce5dd7003aab9', @@ -712,8 +672,6 @@ hex: '483045022100a7a2cf838a13a19f0e443ca35ac5ee3d55f70edca992f98402a84d4ab5ae1ad90220644a02c746eae7b44a4600199ecbf69f3b0f0bdf8479f461c482d67ef4a84e7641210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, { txid: '1452267e57429edcfdcb1184b24becea6ddf8f8a4f8e130dad6248545d9f8e75', @@ -723,8 +681,6 @@ hex: '4730440220290701c797eb52ad6721db615c7d6f623c0200be0e6d6802df68c527655475450220446c4a4da9a0df5efcb57711ad61cf6167dfdda937bd0477189be8afedaedd0541210352cbc218d193ceaf4fb38a772856380173db7a908905e3190841b3174c7ae22d', }, sequence: 4294967295, - address: - 'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl', }, ], vout: [ @@ -779,9 +735,6 @@ hex: '483045022100fb14c794778e33aa66b861e85650f07e802da8b257cc37ac9dc1ac6346a0171d022051d79d2fc81bcb5bc3c7c7025d4222ecc2060cbdbf71a6fb2c7856b2eeaef7dc412102e4af47715f4db1d2a8d686be40c42bba5e70d715e470314181730e797be2324b', }, sequence: 4294967295, - address: - 'bitcoincash:qzekdmmurl75aazj6uj4vc68yrxgws0pms30lsw8de', - value: 0.61760311, }, ], vout: [ @@ -830,9 +783,6 @@ hex: '47304402205f6f73369ee558a8dd149480dda3d5417aab3c9bc2c4ff97aaebfc2768ceaded022052d7e2cfa0743205db27ac0cd29bcae110f1ca00aeedb6f88694901a7379dc6541210320b7867e815a2b00fa935a44a4c348299f7171995c8470d8221e6485da521164', }, sequence: 4294967295, - address: - 'bitcoincash:qrxkkzsmrxcjmz8x90fx2uztt83cuu0u25vrmw66jk', - value: 0.00005, }, ], vout: [ diff --git a/web/cashtab/src/hooks/__tests__/useBCH.test.js b/web/cashtab/src/hooks/__tests__/useBCH.test.js --- a/web/cashtab/src/hooks/__tests__/useBCH.test.js +++ b/web/cashtab/src/hooks/__tests__/useBCH.test.js @@ -9,6 +9,7 @@ import mockTxHistory from '../__mocks__/mockTxHistory'; import mockFlatTxHistory from '../__mocks__/mockFlatTxHistory'; import mockTxDataWithPassthrough from '../__mocks__/mockTxDataWithPassthrough'; +import mockPublicKeys from '../__mocks__/mockPublicKeys'; import { flattenedHydrateUtxosResponse, legacyHydrateUtxosResponse, @@ -327,30 +328,30 @@ it(`Correctly parses a "send ${currency.ticker}" transaction`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[0]])).toStrictEqual( - mockSentCashTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[0]], mockPublicKeys), + ).toStrictEqual(mockSentCashTx); }); it(`Correctly parses a "receive ${currency.ticker}" transaction`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[5]])).toStrictEqual( - mockReceivedCashTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[5]], mockPublicKeys), + ).toStrictEqual(mockReceivedCashTx); }); it(`Correctly parses a "send ${currency.tokenTicker}" transaction`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[1]])).toStrictEqual( - mockSentTokenTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[1]], mockPublicKeys), + ).toStrictEqual(mockSentTokenTx); }); it(`Correctly parses a "receive ${currency.tokenTicker}" transaction`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[3]])).toStrictEqual( - mockReceivedTokenTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[3]], mockPublicKeys), + ).toStrictEqual(mockReceivedTokenTx); }); it(`Correctly parses a "send ${currency.tokenTicker}" transaction with token details`, () => { @@ -403,15 +404,15 @@ it(`Correctly parses a "send ${currency.ticker}" transaction with an OP_RETURN message`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[10]])).toStrictEqual( - mockSentOpReturnMessageTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[10]], mockPublicKeys), + ).toStrictEqual(mockSentOpReturnMessageTx); }); it(`Correctly parses a "receive ${currency.ticker}" transaction with an OP_RETURN message`, () => { const { parseTxData } = useBCH(); - expect(parseTxData([mockTxDataWithPassthrough[11]])).toStrictEqual( - mockReceivedOpReturnMessageTx, - ); + expect( + parseTxData([mockTxDataWithPassthrough[11]], mockPublicKeys), + ).toStrictEqual(mockReceivedOpReturnMessageTx); }); }); diff --git a/web/cashtab/src/hooks/useBCH.js b/web/cashtab/src/hooks/useBCH.js --- a/web/cashtab/src/hooks/useBCH.js +++ b/web/cashtab/src/hooks/useBCH.js @@ -16,6 +16,7 @@ isValidStoredWallet, checkNullUtxosForTokenStatus, confirmNonEtokenUtxos, + extractPublicKeyFromInputScriptSig, } from '@utils/cashMethods'; export default function useBCH() { @@ -77,7 +78,7 @@ return flatTxHistory.splice(0, txCount); }; - const parseTxData = txData => { + const parseTxData = (txData, publicKeys) => { /* Desired output [ @@ -108,8 +109,7 @@ parsedTx.height = tx.height; let destinationAddress = tx.address; - // If this tx had too many inputs to be parsed by getTxDataWithPassThrough, skip it - // When this occurs, the tx will only have txid and height + // if there was an error in getting the tx data from api, the tx will only have txid and height // So, it will not have 'vin' if (!Object.keys(tx).includes('vin')) { // Populate as a limited-info tx that can be expanded in a block explorer @@ -128,15 +128,22 @@ let tokenTx = false; let substring = ''; - // If vin includes tx address, this is an outgoing tx - // Note that with bch-input data, we do not have input amounts + // If vin's scriptSig contains one of the publicKeys of this wallet + // This is an outgoing tx for (let j = 0; j < tx.vin.length; j += 1) { const thisInput = tx.vin[j]; - if (thisInput.address === tx.address) { - // This is an outgoing transaction - outgoingTx = true; - } + const inputPubKey = extractPublicKeyFromInputScriptSig( + thisInput.scriptSig, + ); + publicKeys.forEach(pubKey => { + if (pubKey === inputPubKey) { + // This is an outgoing transaction + outgoingTx = true; + } + }); + if (outgoingTx === true) break; } + // Iterate over vout to find how much was sent or received for (let j = 0; j < tx.vout.length; j += 1) { const thisOutput = tx.vout[j]; @@ -231,15 +238,16 @@ }; const getTxDataWithPassThrough = async (BCH, flatTx) => { - // necessary as BCH.RawTransactions.getTxData does not return address or blockheight + // necessary as BCH.RawTransactions.getRawTransaction does not return address or blockheight let txDataWithPassThrough = {}; try { - txDataWithPassThrough = await BCH.RawTransactions.getTxData( + txDataWithPassThrough = await BCH.RawTransactions.getRawTransaction( flatTx.txid, + true, ); } catch (err) { console.log( - `Error in BCH.RawTransactions.getTxData(${flatTx.txid})`, + `Error in BCH.RawTransactions.getRawTransaction(${flatTx.txid}, true)`, ); console.log(err); // Include txid if you don't get it from the attempted response @@ -250,7 +258,7 @@ return txDataWithPassThrough; }; - const getTxData = async (BCH, txHistory) => { + const getTxData = async (BCH, txHistory, publicKeys) => { // Flatten tx history let flatTxs = flattenTransactions(txHistory); @@ -269,7 +277,7 @@ try { txDataPromiseResponse = await Promise.all(txDataPromises); - const parsed = parseTxData(txDataPromiseResponse); + const parsed = parseTxData(txDataPromiseResponse, publicKeys); return parsed; } catch (err) { 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 @@ -204,6 +204,12 @@ wallet.Path1899.cashAddress, ]; + const publicKeys = [ + wallet.Path145.publicKey, + wallet.Path245.publicKey, + wallet.Path1899.publicKey, + ]; + const utxos = await getUtxos(BCH, cashAddresses); // If an error is returned or utxos from only 1 address are returned @@ -240,7 +246,9 @@ hydratedUtxoDetails, ); const txHistory = await getTxHistory(BCH, cashAddresses); - const parsedTxHistory = await getTxData(BCH, txHistory); + + // public keys are used to determined if a tx is incoming outgoing + const parsedTxHistory = await getTxData(BCH, txHistory, publicKeys); const parsedWithTokens = await addTokenTxData(BCH, parsedTxHistory); diff --git a/web/cashtab/src/utils/cashMethods.js b/web/cashtab/src/utils/cashMethods.js --- a/web/cashtab/src/utils/cashMethods.js +++ b/web/cashtab/src/utils/cashMethods.js @@ -291,3 +291,9 @@ return false; }; + +export const extractPublicKeyFromInputScriptSig = scriptSig => { + if (!scriptSig || !scriptSig.hex) return undefined; + console.log(scriptSig.hex.substring(scriptSig.hex.length - 66)); + return scriptSig.hex.substring(scriptSig.hex.length - 66); +};