diff --git a/web/cashtab/src/components/Wallet/Wallet.js b/web/cashtab/src/components/Wallet/Wallet.js --- a/web/cashtab/src/components/Wallet/Wallet.js +++ b/web/cashtab/src/components/Wallet/Wallet.js @@ -211,6 +211,7 @@ parsedTxHistory, apiError, } = ContextValue; + const [address, setAddress] = React.useState('cashAddress'); const [activeTab, setActiveTab] = React.useState('txHistory'); 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 @@ -7,7 +7,10 @@ import usePrevious from '@hooks/usePrevious'; import useBCH from '@hooks/useBCH'; import BigNumber from 'bignumber.js'; -import { fromSmallestDenomination } from '@utils/cashMethods'; +import { + fromSmallestDenomination, + tokenBalancesToBigNumber, +} from '@utils/cashMethods'; import localforage from 'localforage'; import { currency } from '@components/Common/Ticker'; import _ from 'lodash'; @@ -19,9 +22,11 @@ const [apiError, setApiError] = useState(false); const [walletState, setWalletState] = useState({ balances: {}, + hydratedUtxoDetails: {}, tokens: [], - slpBalancesAndUtxos: [], + slpBalancesAndUtxos: {}, parsedTxHistory: [], + utxos: [], }); const { getBCH, @@ -118,7 +123,7 @@ }; }; - const haveUtxosChanged = (utxos, previousUtxos) => { + const haveUtxosChanged = (wallet, utxos, previousUtxos) => { // Relevant points for this array comparing exercise // https://stackoverflow.com/questions/13757109/triple-equal-signs-return-false-for-arrays-in-javascript-why // https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript @@ -129,13 +134,43 @@ return true; } // If this is the first time the wallet received utxos - if ( - typeof previousUtxos === 'undefined' || - typeof utxos === 'undefined' - ) { + if (typeof utxos === 'undefined') { // Then they have certainly changed return true; } + if (typeof previousUtxos === 'undefined') { + // Compare to what you have in localStorage on startup + // If previousUtxos are undefined, see if you have previousUtxos in wallet state + // If you do, and it has everything you need, set wallet state with that instead of calling hydrateUtxos on all utxos + if ( + wallet && + wallet.state && + wallet.state.balances && + wallet.state.utxos && + wallet.state.hydratedUtxoDetails && + wallet.state.parsedTxHistory && + wallet.state.slpBalancesAndUtxos && + wallet.state.tokens + ) { + // Convert all the token balance figures to big numbers + const liveWalletState = tokenBalancesToBigNumber(wallet.state); + + return setWalletState(liveWalletState); + } + const cachedUtxos = wallet.state.utxos; + // Compare + const utxoArraysUnchangedFromCache = _.isEqual(utxos, cachedUtxos); + // If utxos are not the same as previousUtxos + if (utxoArraysUnchangedFromCache) { + // then utxos have not changed + console.log(`Utxo set is the same as local wallet`); + return false; + // otherwise, + } else { + // utxos have changed + return true; + } + } // return true for empty array, since this means you definitely do not want to skip the next API call if (utxos && utxos.length === 0) { return true; @@ -178,7 +213,12 @@ } setUtxos(utxos); - const utxosHaveChanged = haveUtxosChanged(utxos, previousUtxos); + // Need to call with wallet as a parameter rather than trusting it is in state, otherwise can sometimes get wallet=false from haveUtxosChanged + const utxosHaveChanged = haveUtxosChanged( + wallet, + utxos, + previousUtxos, + ); // If the utxo set has not changed, if (!utxosHaveChanged) { @@ -227,6 +267,10 @@ newState.parsedTxHistory = parsedWithTokens; + newState.utxos = utxos; + + newState.hydratedUtxoDetails = hydratedUtxoDetails; + setWalletState(newState); // Write this state to indexedDb using localForage @@ -356,10 +400,8 @@ const writeWalletState = async (wallet, newState) => { // Add new state as an object on the active wallet wallet.state = newState; - console.log(`wallet with state`, wallet); try { await localforage.setItem('wallet', wallet); - console.log(`Wallet new state successfully written`); } catch (err) { console.log(`Error in writeWalletState()`); console.log(err); diff --git a/web/cashtab/src/utils/__mocks__/mockCachedUtxos.js b/web/cashtab/src/utils/__mocks__/mockCachedUtxos.js new file mode 100644 --- /dev/null +++ b/web/cashtab/src/utils/__mocks__/mockCachedUtxos.js @@ -0,0 +1,574 @@ +// @generated + +import BigNumber from 'bignumber.js'; + +export const cachedUtxos = { + tokens: [ + { + info: { + height: 681188, + tx_hash: + '5b74e05ced6b7d862fe9cab94071b2ccfa475c0cef94b90c7edb8a06f90e5ad6', + tx_pos: 1, + value: 546, + txid: + '5b74e05ced6b7d862fe9cab94071b2ccfa475c0cef94b90c7edb8a06f90e5ad6', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '7443f7c831cdf2b2b04d5f0465ed0bcf348582675b0e4f17906438c232c22f3d', + tokenTicker: 'WDT', + tokenName: + 'Test Token With Exceptionally Long Name For CSS And Style Revisions', + tokenDocumentUrl: + 'https://www.ImpossiblyLongWebsiteDidYouThinkWebDevWouldBeFun.org', + tokenDocumentHash: + '����\\�IS\u001e9�����k+���\u0018���\u001b]�߷2��', + decimals: 7, + tokenType: 1, + tokenQty: '1e-7', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '7443f7c831cdf2b2b04d5f0465ed0bcf348582675b0e4f17906438c232c22f3d', + balance: { + s: 1, + e: 1, + c: [66, 10000000], + }, + hasBaton: false, + }, + { + info: { + height: 681190, + tx_hash: + '52fe0ccf7b5936095bbdadebc0de9f844a99457096ca4f7b45543a2badefdf35', + tx_pos: 1, + value: 546, + txid: + '52fe0ccf7b5936095bbdadebc0de9f844a99457096ca4f7b45543a2badefdf35', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + tokenTicker: 'NOCOVID', + tokenName: 'Covid19 Lifetime Immunity', + tokenDocumentUrl: + 'https://www.who.int/emergencies/diseases/novel-coronavirus-2019/covid-19-vaccines', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '4', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + balance: { + s: 1, + e: 1, + c: [15], + }, + hasBaton: false, + }, + { + info: { + height: 681190, + tx_hash: + 'e9dca9aa954131a0004325fff11dfddcd6e5843c468116cf4d38cb264032cdc0', + tx_pos: 1, + value: 546, + txid: + 'e9dca9aa954131a0004325fff11dfddcd6e5843c468116cf4d38cb264032cdc0', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '1f6a65e7a4bde92c0a012de2bcf4007034504a765377cdf08a3ee01d1eaa6901', + tokenTicker: '🍔', + tokenName: 'Burger', + tokenDocumentUrl: + 'https://c4.wallpaperflare.com/wallpaper/58/564/863/giant-hamburger-wallpaper-preview.jpg', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '1f6a65e7a4bde92c0a012de2bcf4007034504a765377cdf08a3ee01d1eaa6901', + balance: { + s: 1, + e: 0, + c: [1], + }, + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'b35c502f388cdfbdd6841b7a73e973149b3c8deca76295a3e4665939e0562796', + tx_pos: 1, + value: 546, + txid: + 'b35c502f388cdfbdd6841b7a73e973149b3c8deca76295a3e4665939e0562796', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d', + tokenTicker: 'TAP', + tokenName: 'Thoughts and Prayers', + tokenDocumentUrl: '', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d', + balance: { + s: 1, + e: 0, + c: [1], + }, + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'c70408fca1a5bf48f338f7ef031e586293be6948a5bff1fbbdd4eb923ef11e59', + tx_pos: 1, + value: 546, + txid: + 'c70408fca1a5bf48f338f7ef031e586293be6948a5bff1fbbdd4eb923ef11e59', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb', + tokenTicker: 'NAKAMOTO', + tokenName: 'NAKAMOTO', + tokenDocumentUrl: '', + tokenDocumentHash: '', + decimals: 8, + tokenType: 1, + tokenQty: '1e-8', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb', + balance: { + s: 1, + e: -8, + c: [1000000], + }, + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'e1097932e5a607c100dc73fa18169be2e501e1782c7c94500742974d6353476c', + tx_pos: 1, + value: 546, + txid: + 'e1097932e5a607c100dc73fa18169be2e501e1782c7c94500742974d6353476c', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '7f8889682d57369ed0e32336f8b7e0ffec625a35cca183f4e81fde4e71a538a1', + tokenTicker: 'HONK', + tokenName: 'HONK HONK', + tokenDocumentUrl: 'THE REAL HONK SLP TOKEN', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '7f8889682d57369ed0e32336f8b7e0ffec625a35cca183f4e81fde4e71a538a1', + balance: { + s: 1, + e: 0, + c: [1], + }, + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'f6ef57f697219aaa576bf43d69a7f8b8753dcbcbb502f602259a7d14fafd52c5', + tx_pos: 1, + value: 546, + txid: + 'f6ef57f697219aaa576bf43d69a7f8b8753dcbcbb502f602259a7d14fafd52c5', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '1101bd5d7b6bbc3176fb2b93d08e76ab532b04ff731d71502249e3cb9b6fcb1a', + tokenTicker: 'XBIT', + tokenName: 'eBits', + tokenDocumentUrl: 'https://boomertakes.com/', + tokenDocumentHash: '', + decimals: 9, + tokenType: 1, + tokenQty: '1e-9', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '1101bd5d7b6bbc3176fb2b93d08e76ab532b04ff731d71502249e3cb9b6fcb1a', + balance: { + s: 1, + e: -8, + c: [1600000], + }, + hasBaton: false, + }, + { + info: { + height: 681329, + tx_hash: + '16ccf6a34209b25fe78f6a3cdf685eb89f498a7edf144b9e049958c8eda2b439', + tx_pos: 1, + value: 546, + txid: + '16ccf6a34209b25fe78f6a3cdf685eb89f498a7edf144b9e049958c8eda2b439', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'd849fbb04ce77870deaf0e2d9a67146b055f6d8bba18285f5c5f662e20d23199', + tokenTicker: 'BBT', + tokenName: 'BurnBits', + tokenDocumentUrl: 'https://cashtabapp.com/', + tokenDocumentHash: '', + decimals: 9, + tokenType: 1, + tokenQty: '1e-9', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'd849fbb04ce77870deaf0e2d9a67146b055f6d8bba18285f5c5f662e20d23199', + balance: { + s: 1, + e: -9, + c: [100000], + }, + hasBaton: false, + }, + ], +}; +export const utxosLoadedFromCache = { + tokens: [ + { + info: { + height: 681188, + tx_hash: + '5b74e05ced6b7d862fe9cab94071b2ccfa475c0cef94b90c7edb8a06f90e5ad6', + tx_pos: 1, + value: 546, + txid: + '5b74e05ced6b7d862fe9cab94071b2ccfa475c0cef94b90c7edb8a06f90e5ad6', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '7443f7c831cdf2b2b04d5f0465ed0bcf348582675b0e4f17906438c232c22f3d', + tokenTicker: 'WDT', + tokenName: + 'Test Token With Exceptionally Long Name For CSS And Style Revisions', + tokenDocumentUrl: + 'https://www.ImpossiblyLongWebsiteDidYouThinkWebDevWouldBeFun.org', + tokenDocumentHash: + '����\\�IS\u001e9�����k+���\u0018���\u001b]�߷2��', + decimals: 7, + tokenType: 1, + tokenQty: '1e-7', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '7443f7c831cdf2b2b04d5f0465ed0bcf348582675b0e4f17906438c232c22f3d', + balance: new BigNumber({ + s: 1, + e: 1, + c: [66, 10000000], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681190, + tx_hash: + '52fe0ccf7b5936095bbdadebc0de9f844a99457096ca4f7b45543a2badefdf35', + tx_pos: 1, + value: 546, + txid: + '52fe0ccf7b5936095bbdadebc0de9f844a99457096ca4f7b45543a2badefdf35', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + tokenTicker: 'NOCOVID', + tokenName: 'Covid19 Lifetime Immunity', + tokenDocumentUrl: + 'https://www.who.int/emergencies/diseases/novel-coronavirus-2019/covid-19-vaccines', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '4', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + balance: new BigNumber({ + s: 1, + e: 1, + c: [15], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681190, + tx_hash: + 'e9dca9aa954131a0004325fff11dfddcd6e5843c468116cf4d38cb264032cdc0', + tx_pos: 1, + value: 546, + txid: + 'e9dca9aa954131a0004325fff11dfddcd6e5843c468116cf4d38cb264032cdc0', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '1f6a65e7a4bde92c0a012de2bcf4007034504a765377cdf08a3ee01d1eaa6901', + tokenTicker: '🍔', + tokenName: 'Burger', + tokenDocumentUrl: + 'https://c4.wallpaperflare.com/wallpaper/58/564/863/giant-hamburger-wallpaper-preview.jpg', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '1f6a65e7a4bde92c0a012de2bcf4007034504a765377cdf08a3ee01d1eaa6901', + balance: new BigNumber({ + s: 1, + e: 0, + c: [1], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'b35c502f388cdfbdd6841b7a73e973149b3c8deca76295a3e4665939e0562796', + tx_pos: 1, + value: 546, + txid: + 'b35c502f388cdfbdd6841b7a73e973149b3c8deca76295a3e4665939e0562796', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d', + tokenTicker: 'TAP', + tokenName: 'Thoughts and Prayers', + tokenDocumentUrl: '', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'dd84ca78db4d617221b58eabc6667af8fe2f7eadbfcc213d35be9f1b419beb8d', + balance: new BigNumber({ + s: 1, + e: 0, + c: [1], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'c70408fca1a5bf48f338f7ef031e586293be6948a5bff1fbbdd4eb923ef11e59', + tx_pos: 1, + value: 546, + txid: + 'c70408fca1a5bf48f338f7ef031e586293be6948a5bff1fbbdd4eb923ef11e59', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb', + tokenTicker: 'NAKAMOTO', + tokenName: 'NAKAMOTO', + tokenDocumentUrl: '', + tokenDocumentHash: '', + decimals: 8, + tokenType: 1, + tokenQty: '1e-8', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb', + balance: new BigNumber({ + s: 1, + e: -8, + c: [1000000], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'e1097932e5a607c100dc73fa18169be2e501e1782c7c94500742974d6353476c', + tx_pos: 1, + value: 546, + txid: + 'e1097932e5a607c100dc73fa18169be2e501e1782c7c94500742974d6353476c', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '7f8889682d57369ed0e32336f8b7e0ffec625a35cca183f4e81fde4e71a538a1', + tokenTicker: 'HONK', + tokenName: 'HONK HONK', + tokenDocumentUrl: 'THE REAL HONK SLP TOKEN', + tokenDocumentHash: '', + decimals: 0, + tokenType: 1, + tokenQty: '1', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '7f8889682d57369ed0e32336f8b7e0ffec625a35cca183f4e81fde4e71a538a1', + balance: new BigNumber({ + s: 1, + e: 0, + c: [1], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681191, + tx_hash: + 'f6ef57f697219aaa576bf43d69a7f8b8753dcbcbb502f602259a7d14fafd52c5', + tx_pos: 1, + value: 546, + txid: + 'f6ef57f697219aaa576bf43d69a7f8b8753dcbcbb502f602259a7d14fafd52c5', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + '1101bd5d7b6bbc3176fb2b93d08e76ab532b04ff731d71502249e3cb9b6fcb1a', + tokenTicker: 'XBIT', + tokenName: 'eBits', + tokenDocumentUrl: 'https://boomertakes.com/', + tokenDocumentHash: '', + decimals: 9, + tokenType: 1, + tokenQty: '1e-9', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + '1101bd5d7b6bbc3176fb2b93d08e76ab532b04ff731d71502249e3cb9b6fcb1a', + balance: new BigNumber({ + s: 1, + e: -8, + c: [1600000], + _isBigNumber: true, + }), + hasBaton: false, + }, + { + info: { + height: 681329, + tx_hash: + '16ccf6a34209b25fe78f6a3cdf685eb89f498a7edf144b9e049958c8eda2b439', + tx_pos: 1, + value: 546, + txid: + '16ccf6a34209b25fe78f6a3cdf685eb89f498a7edf144b9e049958c8eda2b439', + vout: 1, + utxoType: 'token', + transactionType: 'send', + tokenId: + 'd849fbb04ce77870deaf0e2d9a67146b055f6d8bba18285f5c5f662e20d23199', + tokenTicker: 'BBT', + tokenName: 'BurnBits', + tokenDocumentUrl: 'https://cashtabapp.com/', + tokenDocumentHash: '', + decimals: 9, + tokenType: 1, + tokenQty: '1e-9', + isValid: true, + address: + 'bitcoincash:qqartrrq3npyzpcqswq2hcslstzu38mq8gvgtuqfpf', + }, + tokenId: + 'd849fbb04ce77870deaf0e2d9a67146b055f6d8bba18285f5c5f662e20d23199', + balance: new BigNumber({ + s: 1, + e: -9, + c: [100000], + _isBigNumber: true, + }), + hasBaton: false, + }, + ], +}; diff --git a/web/cashtab/src/utils/__tests__/cashMethods.test.js b/web/cashtab/src/utils/__tests__/cashMethods.test.js --- a/web/cashtab/src/utils/__tests__/cashMethods.test.js +++ b/web/cashtab/src/utils/__tests__/cashMethods.test.js @@ -3,6 +3,7 @@ formatBalance, batchArray, flattenBatchedHydratedUtxos, + tokenBalancesToBigNumber, } from '@utils/cashMethods'; import { unbatchedArray, @@ -10,11 +11,14 @@ } from '../__mocks__/mockBatchedArrays'; import { - originalFinal, - batchedFinal, unflattenedHydrateUtxosResponse, flattenedHydrateUtxosResponse, } from '../__mocks__/flattenBatchedHydratedUtxosMocks'; +import { + cachedUtxos, + utxosLoadedFromCache, +} from '../__mocks__/mockCachedUtxos'; +import BigNumber from 'bignumber.js'; describe('Correctly executes cash utility functions', () => { it(`Correctly converts smallest base unit to smallest decimal for cashDecimals = 2`, () => { @@ -66,4 +70,9 @@ flattenBatchedHydratedUtxos(unflattenedHydrateUtxosResponse), ).toStrictEqual(flattenedHydrateUtxosResponse); }); + it(`Accepts a cachedWalletState that has not preserved BigNumber object types, and returns the same wallet state with BigNumber type re-instituted`, () => { + expect(tokenBalancesToBigNumber(cachedUtxos)).toStrictEqual( + utxosLoadedFromCache, + ); + }); }); 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 @@ -102,3 +102,18 @@ } return flattenedBatchedHydratedUtxos; }; + +export const tokenBalancesToBigNumber = cachedWalletState => { + // Accept cached tokens array that does not save BigNumber type of BigNumbers + // Return array with BigNumbers converted + // See BigNumber.js api for how to create a BigNumber object from an object + // https://mikemcl.github.io/bignumber.js/ + const liveWalletState = cachedWalletState; + const { tokens } = liveWalletState; + for (let i = 0; i < tokens.length; i += 1) { + const thisTokenBalance = tokens[i].balance; + thisTokenBalance._isBigNumber = true; + tokens[i].balance = new BigNumber(thisTokenBalance); + } + return liveWalletState; +};