diff --git a/app/containers/receive.js b/app/containers/receive.js index de6a5a6..d55c519 100644 --- a/app/containers/receive.js +++ b/app/containers/receive.js @@ -16,8 +16,10 @@ import { } from '../redux/modules/receive'; import { asyncMap } from '../utils/async-map'; +import { getLatestAddressKey } from '../utils/get-latest-address-key'; import rpc from '../../services/api'; +import electronStore from '../../config/electron-store'; import type { AppState } from '../types/app-state'; import type { Dispatch } from '../types/redux'; @@ -43,21 +45,18 @@ const mapDispatchToProps = (dispatch: Dispatch): MapDispatchToProps => ({ if (zAddressesErr || tAddressesErr) return dispatch(loadAddressesError({ error: 'Something went wrong!' })); - const latestZAddress = zAddresses[0] - ? { - address: zAddresses[0], - balance: await rpc.z_getbalance(zAddresses[0]), - } - : null; - const latestTAddress = transparentAddresses[0] - ? { - address: transparentAddresses[0], - balance: await rpc.z_getbalance(transparentAddresses[0]), - } - : null; + const latestZAddress = zAddresses.find(addr => addr === electronStore.get(getLatestAddressKey('shielded'))) + || zAddresses[0]; + + const latestTAddress = transparentAddresses.find( + addr => addr === electronStore.get(getLatestAddressKey('transparent')), + ) || transparentAddresses[0]; const allAddresses = await asyncMap( - [...zAddresses.slice(1), ...transparentAddresses.slice(1)], + [ + ...zAddresses.filter(cur => cur !== latestZAddress), + ...transparentAddresses.filter(cur => cur !== latestTAddress), + ], async (address) => { const [err, response] = await eres(rpc.z_getbalance(address)); @@ -69,7 +68,18 @@ const mapDispatchToProps = (dispatch: Dispatch): MapDispatchToProps => ({ dispatch( loadAddressesSuccess({ - addresses: [latestZAddress, latestTAddress, ...allAddresses].filter(Boolean), + addresses: [ + latestZAddress + ? { + address: latestZAddress, + balance: await rpc.z_getbalance(latestZAddress), + } + : null, + latestTAddress + ? { address: latestTAddress, balance: await rpc.z_getbalance(latestTAddress) } + : null, + ...allAddresses, + ].filter(Boolean), }), ); }, @@ -80,6 +90,10 @@ const mapDispatchToProps = (dispatch: Dispatch): MapDispatchToProps => ({ if (error || !address) return dispatch(getNewAddressError({ error: 'Unable to generate a new address' })); + // the list addresses rpc method does not guarantee the order of creation of the addresses + // so we need to save the last address created in the store + electronStore.set(getLatestAddressKey(type), address); + dispatch(getNewAddressSuccess({ address })); }, }); diff --git a/app/containers/send.js b/app/containers/send.js index 0efd4e9..2b74e71 100644 --- a/app/containers/send.js +++ b/app/containers/send.js @@ -22,6 +22,7 @@ import { import { filterObjectNullKeys } from '../utils/filter-object-null-keys'; import { asyncMap } from '../utils/async-map'; +import { getLatestAddressKey } from '../utils/get-latest-address-key'; import { saveShieldedTransaction } from '../../services/shielded-transactions'; import type { AppState } from '../types/app-state'; @@ -165,22 +166,16 @@ const mapDispatchToProps = (dispatch: Dispatch): MapDispatchToProps => ({ if (zAddressesErr || tAddressesErr) return dispatch(loadAddressesError({ error: 'Something went wrong!' })); - const latestZAddress = zAddresses[0] - ? { - address: zAddresses[0], - balance: await rpc.z_getbalance(zAddresses[0]), - } - : null; + const latestZAddress = zAddresses.find(addr => addr === store.get(getLatestAddressKey('shielded'))) || zAddresses[0]; - const latestTAddress = transparentAddresses[0] - ? { - address: transparentAddresses[0], - balance: await rpc.z_getbalance(transparentAddresses[0]), - } - : null; + const latestTAddress = transparentAddresses.find(addr => addr === store.get(getLatestAddressKey('transparent'))) + || transparentAddresses[0]; const allAddresses = await asyncMap( - [...zAddresses.slice(1), ...transparentAddresses.slice(1)], + [ + ...zAddresses.filter(cur => cur !== latestZAddress), + ...transparentAddresses.filter(cur => cur !== latestTAddress), + ], async (address) => { const [err, response] = await eres(rpc.z_getbalance(address)); @@ -192,7 +187,18 @@ const mapDispatchToProps = (dispatch: Dispatch): MapDispatchToProps => ({ return dispatch( loadAddressesSuccess({ - addresses: [latestTAddress, latestZAddress, ...allAddresses].filter(Boolean), + addresses: [ + latestZAddress + ? { + address: latestZAddress, + balance: await rpc.z_getbalance(latestZAddress), + } + : null, + latestTAddress + ? { address: latestTAddress, balance: await rpc.z_getbalance(latestTAddress) } + : null, + ...allAddresses, + ].filter(Boolean), }), ); }, diff --git a/app/utils/get-latest-address-key.js b/app/utils/get-latest-address-key.js new file mode 100644 index 0000000..6ede931 --- /dev/null +++ b/app/utils/get-latest-address-key.js @@ -0,0 +1,8 @@ +// @flow + +import { isTestnet } from '../../config/is-testnet'; +import { TESTNET, MAINNET } from '../constants/zcash-network'; + +export const getLatestAddressKey = (type: string) => `LATEST_${type === 'shielded' ? 'SHIELDED' : 'TRANSPARENT'}_ADDRESS_${ + isTestnet() ? TESTNET : MAINNET +}`;