This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
/
useBalance.ts
93 lines (82 loc) 路 3.2 KB
/
useBalance.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { BigNumber } from 'ethers';
import { useQuery } from 'react-query';
import { useEthersUpdater } from './useEthersUpdater';
import { useEthersAppContext, useBlockNumberContext } from '~~/context';
import {
asyncForEach,
ethersOverride,
mergeDefaultOverride,
mergeDefaultUpdateOptions,
processQueryOptions,
} from '~~/functions';
import { providerKey, TRequiredKeys } from '~~/functions/keyHelpers';
import { THookResult, TOverride, TUpdateOptions } from '~~/models';
import { keyNamespace } from '~~/models/constants';
const queryKey: TRequiredKeys = { namespace: keyNamespace.signer, key: 'useBalance' };
const zero = BigNumber.from(0);
/**
* @internal
* #### Summary
* A conditional type for useBalance result based on input parameters. It is either a BigNumber or a Record<string, BigNumber> depending on the input addres being a string or string[]
*/
type TUseBalanceResult<GAddress extends string | string[]> = GAddress extends string[]
? Record<string, BigNumber>
: BigNumber;
/**
* #### Summary
* Gets your balance in ETH for the given address.
*
* ##### 鉁忥笍 Notes
* - updates triggered by {@link BlockNumberContext}
* - uses the current provider {@link provider} from {@link useEthersContext}
*
* @category Hooks
*
* @param addresses Addresses of wallets to get balance for
* @param override Options to override adapters and context
* @param options Options for how often and when to update
* @returns current balance
*/
export const useBalance = <GAddress extends string | Array<string>>(
addresses: GAddress | undefined,
options: TUpdateOptions = mergeDefaultUpdateOptions(),
override: TOverride = mergeDefaultOverride()
): THookResult<TUseBalanceResult<GAddress>> => {
const ethersContext = useEthersAppContext(override.alternateContextKey);
const { provider } = ethersOverride(ethersContext, override);
const keys = [{ ...queryKey, ...providerKey(provider) }, { addresses }] as const;
const { data, refetch, status } = useQuery(
keys,
async (keys): Promise<TUseBalanceResult<GAddress> | undefined> => {
const { addresses } = keys.queryKey[1];
if (provider && addresses) {
if (Array.isArray(addresses)) {
const result: TUseBalanceResult<string[]> = {};
await asyncForEach(addresses, async (address: string) => {
const balance = await provider.getBalance(address);
result[address] = balance;
});
return result as TUseBalanceResult<GAddress>;
} else {
const address: string = addresses;
const newBalance = await provider.getBalance(address);
return newBalance as TUseBalanceResult<GAddress>;
}
}
return undefined;
},
{
...processQueryOptions<TUseBalanceResult<GAddress> | undefined>(options),
isDataEqual: (oldResult, newResult) => oldResult?._hex === newResult?._hex,
}
);
const blockNumber = useBlockNumberContext();
useEthersUpdater(refetch, blockNumber, options);
let result: TUseBalanceResult<GAddress>;
if (Array.isArray(addresses)) {
result = data ?? ({} as TUseBalanceResult<GAddress>);
} else {
result = data ?? (zero as TUseBalanceResult<GAddress>);
}
return [result, refetch, status];
};