-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Token balance display fix Previously the token balances would only be shown after the TokensModal was opened to fetch and set the wallet's balances. The useGetTokenBalance hook is now used to fetch the balances on demand (if not already cached). * TokensModal uses hook, renamed to useGetTokenBalances * style thing * small refactor
- Loading branch information
1 parent
18587e1
commit 88d1106
Showing
6 changed files
with
192 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { RootState } from 'store'; | ||
import { ChainName, TokenId } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
import { useEffect, useState } from 'react'; | ||
import { | ||
accessBalance, | ||
Balances, | ||
formatBalance, | ||
updateBalances, | ||
} from 'store/transferInput'; | ||
import config from 'config'; | ||
import { TokenConfig } from 'config/types'; | ||
|
||
const useGetTokenBalances = ( | ||
walletAddress: string, | ||
chain: ChainName | undefined, | ||
tokens: TokenConfig[], | ||
): { isFetching: boolean; balances: Balances } => { | ||
const [isFetching, setIsFetching] = useState(false); | ||
const [balances, setBalances] = useState<Balances>({}); | ||
const cachedBalances = useSelector( | ||
(state: RootState) => state.transferInput.balances, | ||
); | ||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
setIsFetching(true); | ||
setBalances({}); | ||
if ( | ||
!walletAddress || | ||
!chain || | ||
!config.chains[chain] || | ||
tokens.length === 0 | ||
) { | ||
setIsFetching(false); | ||
return; | ||
} | ||
const chainConfig = config.chains[chain]; | ||
if (!chainConfig) { | ||
setIsFetching(false); | ||
return; | ||
} | ||
|
||
let isActive = true; | ||
|
||
const getBalances = async () => { | ||
const balances: Balances = {}; | ||
type TokenConfigWithId = TokenConfig & { tokenId: TokenId }; | ||
const needsUpdate: TokenConfigWithId[] = []; | ||
const now = Date.now(); | ||
const fiveMinutesAgo = now - 5 * 60 * 1000; | ||
let updateCache = false; | ||
for (const token of tokens) { | ||
const cachedBalance = accessBalance( | ||
cachedBalances, | ||
walletAddress, | ||
chain, | ||
token.key, | ||
); | ||
if (cachedBalance && cachedBalance.lastUpdated > fiveMinutesAgo) { | ||
balances[token.key] = cachedBalance; | ||
} else { | ||
if (token.key === chainConfig.gasToken) { | ||
try { | ||
const balance = await config.wh.getNativeBalance( | ||
walletAddress, | ||
chain, | ||
token.key, | ||
); | ||
balances[token.key] = { | ||
balance: formatBalance(chain, token, balance), | ||
lastUpdated: now, | ||
}; | ||
updateCache = true; | ||
} catch (e) { | ||
console.error('Failed to get native balance', e); | ||
} | ||
} else if (token.tokenId) { | ||
needsUpdate.push(token as TokenConfigWithId); | ||
} | ||
} | ||
} | ||
if (needsUpdate.length > 0) { | ||
try { | ||
const result = await config.wh.getTokenBalances( | ||
walletAddress, | ||
needsUpdate.map((t) => t.tokenId), | ||
chain, | ||
); | ||
result.forEach((balance, i) => { | ||
const token = needsUpdate[i]; | ||
balances[token.key] = { | ||
balance: formatBalance(chain, token, balance), | ||
lastUpdated: now, | ||
}; | ||
}); | ||
updateCache = true; | ||
} catch (e) { | ||
console.error('Failed to get token balances', e); | ||
} | ||
} | ||
if (isActive) { | ||
setIsFetching(false); | ||
setBalances(balances); | ||
if (updateCache) { | ||
dispatch( | ||
updateBalances({ | ||
address: walletAddress, | ||
chain, | ||
balances, | ||
}), | ||
); | ||
} | ||
} | ||
}; | ||
|
||
getBalances(); | ||
|
||
return () => { | ||
isActive = false; | ||
}; | ||
}, [cachedBalances, walletAddress, chain, tokens]); | ||
|
||
return { isFetching, balances }; | ||
}; | ||
|
||
export default useGetTokenBalances; |
Oops, something went wrong.