Skip to content

Commit

Permalink
fix: balances issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Majorfi committed Jul 31, 2023
1 parent b877fd9 commit 1a00874
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 42 deletions.
62 changes: 33 additions & 29 deletions packages/web-lib/hooks/useBalances.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {useCallback, useMemo, useRef, useState} from 'react';
import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {erc20ABI, useChainId} from 'wagmi';
import axios from 'axios';
import {useUpdateEffect} from '@react-hookz/web';
import {deserialize, multicall, serialize} from '@wagmi/core';
import {useUI} from '@yearn-finance/web-lib/contexts/useUI';
import {useWeb3} from '@yearn-finance/web-lib/contexts/useWeb3';
Expand Down Expand Up @@ -194,12 +193,9 @@ export function useBalances(props?: TUseBalancesReq): TUseBalancesRes {
}
}));
set_nonce((n): number => n + 1);
set_status({...defaultStatus, isSuccess: true, isFetched: true});
});
onLoadDone();

return data.current[chainID].balances;
}, [onLoadDone, web3Address]);
}, [web3Address]);

/* 🔵 - Yearn Finance ******************************************************
** onUpdate will take the stringified tokens and fetch the balances for each
Expand Down Expand Up @@ -333,35 +329,43 @@ export function useBalances(props?: TUseBalancesReq): TUseBalancesRes {
return _rawData;
}, [props?.prices]);

/* 🔵 - Yearn Finance ******************************************************
** Everytime the stringifiedTokens change, we need to update the balances.
** This is the main hook and is optimized for performance, using a worker
** to fetch the balances, preventing the UI to freeze.
**************************************************************************/
useUpdateEffect((): void => {
if (!web3Address || !provider) {
const asyncUseEffect = useCallback(async (): Promise<void> => {
if (!isActive || !web3Address || !provider) {
return;
}
set_status({...defaultStatus, isLoading: true, isFetching: true, isRefetching: defaultStatus.isFetched});
onLoadStart();

const tokens: TUseBalancesTokens[] = deserialize(stringifiedTokens) || [];
axios
.post('/api/getBatchBalances', {
chainID: chainID || 1,
address: web3Address,
tokens
})
.then((res: AxiosResponse<TGetBatchBalancesResp>): void => {
updateBalancesCall(res.data.chainID, deserialize(res.data.balances));
})
.catch((err): void => {
console.error(err);
onLoadDone();
onUpdateSome(tokens);
});
const tokens = JSON.parse(stringifiedTokens) || [];
const chunks = [];
for (let i = 0; i < tokens.length; i += 200) {
chunks.push(tokens.slice(i, i + 200));
}
const allPromises = [];
for (const chunkTokens of chunks) {
allPromises.push(
axios.post('/api/getBatchBalances', {chainID, address: web3Address, tokens: chunkTokens})
.then((res: AxiosResponse<TGetBatchBalancesResp>): void => {
updateBalancesCall(res.data.chainID, deserialize(res.data.balances));
})
.catch((err): void => {
console.error(err);
})
);
}
await Promise.all(allPromises);
onLoadDone();
set_status({...defaultStatus, isSuccess: true, isFetched: true});
}, [stringifiedTokens, isActive, web3Address, provider, onLoadStart, chainID, updateBalancesCall, onLoadDone]);

}, [stringifiedTokens, isActive, web3Address]);
/* 🔵 - Yearn Finance ******************************************************
** Everytime the stringifiedTokens change, we need to update the balances.
** This is the main hook and is optimized for performance, using a worker
** to fetch the balances, preventing the UI to freeze.
**************************************************************************/
useEffect((): void => {
asyncUseEffect();
}, [asyncUseEffect]);

const contextValue = useMemo((): TUseBalancesRes => ({
data: assignPrices(balances || {})?.[chainID] || {},
Expand Down
13 changes: 4 additions & 9 deletions packages/web-lib/utils/getBatchBalances.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {serialize} from 'wagmi';
import {configureChains, erc20ABI} from '@wagmi/core';
import {erc20ABI} from '@wagmi/core';
import AGGREGATE3_ABI from '@yearn-finance/web-lib/utils/abi/aggregate.abi';
import {toAddress} from '@yearn-finance/web-lib/utils/address';
import {MULTICALL3_ADDRESS} from '@yearn-finance/web-lib/utils/constants';
import {decodeAsBigInt, decodeAsNumber, decodeAsString} from '@yearn-finance/web-lib/utils/decoder';
import {toNormalizedValue} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {isEth} from '@yearn-finance/web-lib/utils/isEth';
import {getConfig, getSupportedProviders} from '@yearn-finance/web-lib/utils/wagmi/config';
import {getNetwork, indexedWagmiChains} from '@yearn-finance/web-lib/utils/wagmi/utils';
import {getClient, getNetwork} from '@yearn-finance/web-lib/utils/wagmi/utils';

import type {NextApiRequest, NextApiResponse} from 'next';
import type {TUseBalancesTokens} from '@yearn-finance/web-lib/hooks/useBalances';
Expand Down Expand Up @@ -58,12 +57,8 @@ async function getBatchBalances({
}

try {
const {chains, publicClient, webSocketPublicClient} = configureChains(
Object.values(indexedWagmiChains),
getSupportedProviders()
);
const config = getConfig({chains, publicClient, webSocketPublicClient});
const multicallInstance = config.getPublicClient({chainId: chainID}).multicall;
const client = getClient(chainID);
const multicallInstance = client.multicall;
const results = await multicallInstance({contracts: calls as never[]});
let rIndex = 0;
for (const element of tokens) {
Expand Down
18 changes: 14 additions & 4 deletions packages/web-lib/utils/wagmi/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,20 @@ export function getClient(chainID: number): PublicClient {
if (!indexedWagmiChains[chainID]) {
throw new Error(`Chain ${chainID} is not supported`);
}
return createPublicClient({
chain: indexedWagmiChains[chainID],
transport: http(process.env.JSON_RPC_URL?.[chainID] || indexedWagmiChains[chainID].rpcUrls.public.http[0])
});
let url = process.env.JSON_RPC_URL?.[chainID] || indexedWagmiChains[chainID].rpcUrls.public.http[0];
const urlAsNodeURL = new URL(url);
let headers = {};
if (urlAsNodeURL.username && urlAsNodeURL.password) {
headers = {
'Authorization': `Basic ${btoa(urlAsNodeURL.username + ':' + urlAsNodeURL.password)}`
};
url = urlAsNodeURL.href.replace(`${urlAsNodeURL.username}:${urlAsNodeURL.password}@`, '');
return createPublicClient({
chain: indexedWagmiChains[chainID],
transport: http(url, {fetchOptions: {headers}}),
});
}
return createPublicClient({chain: indexedWagmiChains[chainID], transport: http(url)});
}

export function assertAddress(addr: string | TAddress | undefined, name?: string): asserts addr is TAddress {
Expand Down

0 comments on commit 1a00874

Please sign in to comment.