From f1ade8584aa0ee4441701dc7ea6ad963a9dae0e5 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Tue, 28 Nov 2023 16:03:19 -0300 Subject: [PATCH] [REF] get status all --- src/store/wallet/effects/rates/rates.ts | 6 +- src/store/wallet/effects/status/status.ts | 418 ++++++++++++---------- 2 files changed, 230 insertions(+), 194 deletions(-) diff --git a/src/store/wallet/effects/rates/rates.ts b/src/store/wallet/effects/rates/rates.ts index 4d416a5d61..25fd833980 100644 --- a/src/store/wallet/effects/rates/rates.ts +++ b/src/store/wallet/effects/rates/rates.ts @@ -179,7 +179,7 @@ export const startGetRates = export const getContractAddresses = (chain: string): Effect> => (dispatch, getState) => { - dispatch(LogActions.info('getContractAddresses: starting...')); + dispatch(LogActions.info(`getContractAddresses ${chain}: starting...`)); const { WALLET: {keys}, } = getState(); @@ -278,6 +278,10 @@ export const getTokenRates = }); } }); + } else { + dispatch( + LogActions.info(`No tokens wallets for ${chain} found. Skipping getTokenRates...`), + ); } } diff --git a/src/store/wallet/effects/status/status.ts b/src/store/wallet/effects/status/status.ts index bbb856b7e8..29a0d1bb3d 100644 --- a/src/store/wallet/effects/status/status.ts +++ b/src/store/wallet/effects/status/status.ts @@ -269,211 +269,243 @@ export const startUpdateWalletStatus = }); }; -export const startUpdateAllWalletStatusForKeys = - ({keys, force}: {keys: Key[]; force?: boolean}): Effect> => - async (dispatch, getState) => { - return new Promise(async (resolve, reject) => { - try { - dispatch( - LogActions.info('starting [startUpdateAllWalletStatusForKeys]'), - ); - const {APP, RATE, WALLET} = getState(); - const {defaultAltCurrency} = APP; - const {balanceCacheKey} = WALLET; - const {rates, lastDayRates} = RATE; +const getBulkStatus = ( + bulkClient: any, + credentials: any, + walletOptions: Record< + string, + { + tokenAddresses: string[] | undefined; + } + >, +) => { + return new Promise((resolve, reject) => { + bulkClient.getStatusAll( + credentials, + { + includeExtendedInfo: true, + twoStep: true, + wallets: walletOptions, + }, + (err: Error, bulkStatus: BulkStatus[]) => { + if (err) { + reject(err); + } else { + resolve(bulkStatus); + } + }, + ); + }); +}; - const keyUpdatesPromises: Promise<{ +const updateKeyStatus = + ( + key: Key, + force: boolean | undefined, + ): Effect< + Promise< + | { keyId: string; totalBalance: number; totalBalanceLastDay: number; - }>[] = []; - - keys.forEach(key => { - if ( - !isCacheKeyStale(balanceCacheKey[key.id], BALANCE_CACHE_DURATION) && - !force - ) { - console.log(`Key: ${key.id} - skipping balance update`); - return; - } + } + | undefined + > + > => + async (dispatch, getState) => { + return new Promise(async (resolve, reject) => { + const {APP, RATE, WALLET} = getState(); + const {defaultAltCurrency} = APP; + const {balanceCacheKey} = WALLET; + const {rates, lastDayRates} = RATE; + if ( + !isCacheKeyStale(balanceCacheKey[key.id], BALANCE_CACHE_DURATION) && + !force + ) { + console.log(`Key: ${key.id} - skipping balance update`); + return; + } - const walletOptions = {} as Record< - string, - { - tokenAddresses: string[] | undefined; - } - >; - - key.wallets - .filter(wallet => { - return ( - !wallet.credentials.token && - !wallet.credentials.multisigEthInfo && - wallet.credentials.isComplete() - ); - }) - .forEach(({credentials: {copayerId}, tokens}) => { - const tokenAddresses = tokens?.map( - address => '0x' + address.split('0x')[1], - ); + const walletOptions = {} as Record< + string, + { + tokenAddresses: string[] | undefined; + } + >; + + // remote token wallets from getStatusAll + const noTokenWallets = key.wallets.filter(wallet => { + return ( + !wallet.credentials.token && + !wallet.credentials.multisigEthInfo && + wallet.credentials.isComplete() + ); + }); - walletOptions[copayerId] = { - tokenAddresses, - }; - }); + const credentials = noTokenWallets.map(wallet => { + const tokenAddresses = wallet.tokens?.map( + address => '0x' + address.split('0x')[1], + ); + + // build tokenAddresses wallet options for getStatusAll + walletOptions[wallet.credentials.copayerId] = { + tokenAddresses, + }; + return wallet.credentials; + }); - const credentials = key.wallets - .filter( - wallet => - !wallet.credentials.token && - !wallet.credentials.multisigEthInfo && - wallet.credentials.isComplete(), - ) - .map(wallet => wallet.credentials); - - if (!credentials.length) { - return; + if (!credentials.length) { + return; + } + + const {bulkClient} = BwcProvider.getInstance().getClient(); + + try { + const bulkStatus = (await getBulkStatus( + bulkClient, + credentials, + walletOptions, + )) as BulkStatus[]; + const balances = key.wallets.map(wallet => { + const {balance: cachedBalance, pendingTxps} = wallet; + + if (!bulkStatus) { + return { + ...cachedBalance, + ...dispatch( + buildFiatBalance({ + wallet, + cryptoBalance: cachedBalance, + defaultAltCurrencyIsoCode: defaultAltCurrency.isoCode, + rates, + lastDayRates, + }), + ), + }; } - const {bulkClient} = BwcProvider.getInstance().getClient(); - keyUpdatesPromises.push( - new Promise(resolveKeyBalanceStatus => { - bulkClient.getStatusAll( - credentials, - { - includeExtendedInfo: true, - twoStep: true, - wallets: walletOptions, - }, - (err: Error, bulkStatus: BulkStatus[]) => { - const balances = key.wallets.map(wallet => { - const {balance: cachedBalance, pendingTxps} = wallet; - - if (err || !bulkStatus) { - if (err) { - let errorStr; - if (err instanceof Error) { - errorStr = err.message; - } else { - errorStr = JSON.stringify(err); - } - dispatch( - LogActions.error( - `[startUpdateAllWalletStatusForKeys] - failed getStatusAll: ${errorStr}`, - ), - ); - } - return { - ...cachedBalance, - ...dispatch( - buildFiatBalance({ - wallet, - cryptoBalance: cachedBalance, - defaultAltCurrencyIsoCode: - defaultAltCurrency.isoCode, - rates, - lastDayRates, - }), - ), - }; - } - - const {status, success} = - bulkStatus.find(bStatus => { - if (typeof bStatus.tokenAddress === 'string') { - return ( - bStatus.tokenAddress === - wallet.credentials.token?.address && - `${bStatus.walletId}-${bStatus.tokenAddress}` === - wallet.id - ); - } - - return bStatus.walletId === wallet.id; - }) || {}; - - if ( - status && - success && - (status.balance.availableAmount !== - cachedBalance?.satAvailable || - status.pendingTxps?.length > 0 || - pendingTxps?.length > 0) - ) { - const cryptoBalance = dispatch( - buildBalance({ - wallet, - status, - }), - ); - - let newBalance = { - ...cryptoBalance, - ...dispatch( - buildFiatBalance({ - wallet, - cryptoBalance, - defaultAltCurrencyIsoCode: - defaultAltCurrency.isoCode, - rates, - lastDayRates, - }), - ), - } as WalletBalance; - - const newPendingTxps = dispatch( - buildPendingTxps({wallet, status}), - ); - - dispatch( - successUpdateWalletStatus({ - keyId: key.id, - walletId: wallet.id, - status: { - balance: cryptoBalance, - pendingTxps: newPendingTxps, - }, - }), - ); - - dispatch( - LogActions.info( - `Wallet: ${wallet.currencyAbbreviation} ${wallet.id} - status updated`, - ), - ); - - return newBalance; - } else { - return { - ...cachedBalance, - ...dispatch( - buildFiatBalance({ - wallet, - cryptoBalance: cachedBalance, - defaultAltCurrencyIsoCode: - defaultAltCurrency.isoCode, - rates, - lastDayRates, - }), - ), - }; - } - }); - - resolveKeyBalanceStatus({ - keyId: key.id, - totalBalance: getTotalFiatBalance(balances), - totalBalanceLastDay: getTotalFiatLastDayBalance(balances), - }); - }, - ); - }), - ); + const {status, success} = + bulkStatus.find(bStatus => { + if (typeof bStatus.tokenAddress === 'string') { + return ( + bStatus.tokenAddress === wallet.credentials.token?.address && + `${bStatus.walletId}-${bStatus.tokenAddress}` === wallet.id + ); + } + + return bStatus.walletId === wallet.id; + }) || {}; + + const amountHasChanged = + status?.balance.availableAmount !== cachedBalance?.satAvailable; + const hasNewPendingTxps = + status?.pendingTxps && status?.pendingTxps.length > 0; + const hasPendingTxps = pendingTxps?.length > 0; + const shouldUpdateStatus = + amountHasChanged || hasNewPendingTxps || hasPendingTxps; + if (status && success && shouldUpdateStatus) { + const cryptoBalance = dispatch( + buildBalance({ + wallet, + status, + }), + ); + + let newBalance = { + ...cryptoBalance, + ...dispatch( + buildFiatBalance({ + wallet, + cryptoBalance, + defaultAltCurrencyIsoCode: defaultAltCurrency.isoCode, + rates, + lastDayRates, + }), + ), + } as WalletBalance; + + const newPendingTxps = dispatch(buildPendingTxps({wallet, status})); + + // properties to update + wallet.balance = cryptoBalance; + wallet.pendingTxps = newPendingTxps; + wallet.isRefreshing = false; + + dispatch( + LogActions.info( + `Wallet to be updated: ${wallet.currencyAbbreviation} ${wallet.id} - status updated`, + ), + ); + + return newBalance; + } else { + return { + ...cachedBalance, + ...dispatch( + buildFiatBalance({ + wallet, + cryptoBalance: cachedBalance, + defaultAltCurrencyIsoCode: defaultAltCurrency.isoCode, + rates, + lastDayRates, + }), + ), + }; + } }); - const keyUpdates = await Promise.all(keyUpdatesPromises); + dispatch(LogActions.info(`Key: ${key.id} - status updated`)); - dispatch(successUpdateKeysTotalBalance(keyUpdates)); + dispatch( + successUpdateKey({ + key, + }), + ); + return resolve({ + keyId: key.id, + totalBalance: getTotalFiatBalance(balances), + totalBalanceLastDay: getTotalFiatLastDayBalance(balances), + }); + } catch (err) { + if (err) { + let errorStr; + if (err instanceof Error) { + errorStr = err.message; + } else { + errorStr = JSON.stringify(err); + } + dispatch( + LogActions.error( + `[startUpdateAllWalletStatusForKeys] - failed getStatusAll: ${errorStr}`, + ), + ); + } + return; + } + }); + }; + +export const startUpdateAllWalletStatusForKeys = + ({keys, force}: {keys: Key[]; force?: boolean}): Effect> => + async (dispatch, getState) => { + return new Promise(async (resolve, reject) => { + try { + dispatch( + LogActions.info('starting [startUpdateAllWalletStatusForKeys]'), + ); + const keyUpdatesPromises = keys.map(key => + dispatch(updateKeyStatus(key, force)), + ); + const keyUpdates = (await Promise.all(keyUpdatesPromises)).filter( + Boolean, + ) as { + keyId: string; + totalBalance: number; + totalBalanceLastDay: number; + }[]; + if (keyUpdates.length > 0) { + dispatch(successUpdateKeysTotalBalance(keyUpdates)); + } dispatch( LogActions.info('success [startUpdateAllWalletStatusForKeys]'), );