@@ -4,13 +4,22 @@ import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
44import type React from "react" ;
55import type { JSX } from "react" ;
66import type { Chain } from "../../../../../chains/types.js" ;
7+ import { NATIVE_TOKEN_ADDRESS } from "../../../../../constants/addresses.js" ;
8+ import { convertCryptoToFiat } from "../../../../../exports/pay.js" ;
79import { useActiveWalletChain } from "../../../../../react/core/hooks/wallets/useActiveWalletChain.js" ;
8- import {
9- type GetWalletBalanceResult ,
10- getWalletBalance ,
11- } from "../../../../../wallets/utils/getWalletBalance.js" ;
10+ import { getWalletBalance } from "../../../../../wallets/utils/getWalletBalance.js" ;
1211import { useAccountContext } from "./provider.js" ;
1312
13+ /**
14+ * @internal
15+ */
16+ export type AccountBalanceFormatParams = {
17+ tokenBalance : number ;
18+ tokenSymbol : string ;
19+ fiatBalance ?: number ;
20+ fiatSymbol ?: string ;
21+ } ;
22+
1423/**
1524 * Props for the AccountBalance component
1625 * @component
@@ -33,7 +42,7 @@ export interface AccountBalanceProps
3342 * use this function to transform the balance display value like round up the number
3443 * Particularly useful to avoid overflowing-UI issues
3544 */
36- formatFn ?: ( num : number ) => number ;
45+ formatFn ?: ( props : AccountBalanceFormatParams ) => string ;
3746 /**
3847 * This component will be shown while the balance of the account is being fetched
3948 * If not passed, the component will return `null`.
@@ -67,9 +76,11 @@ export interface AccountBalanceProps
6776 * Optional `useQuery` params
6877 */
6978 queryOptions ?: Omit <
70- UseQueryOptions < GetWalletBalanceResult > ,
79+ UseQueryOptions < AccountBalanceFormatParams > ,
7180 "queryFn" | "queryKey"
7281 > ;
82+
83+ showFiatValue ?: "USD" ;
7384}
7485
7586/**
@@ -149,10 +160,11 @@ export interface AccountBalanceProps
149160export function AccountBalance ( {
150161 chain,
151162 tokenAddress,
152- formatFn,
153163 loadingComponent,
154164 fallbackComponent,
155165 queryOptions,
166+ formatFn,
167+ showFiatValue,
156168 ...restProps
157169} : AccountBalanceProps ) {
158170 const { address, client } = useAccountContext ( ) ;
@@ -164,20 +176,61 @@ export function AccountBalance({
164176 chainToLoad ?. id || - 1 ,
165177 address || "0x0" ,
166178 { tokenAddress } ,
179+ showFiatValue ,
167180 ] as const ,
168- queryFn : async ( ) => {
181+ queryFn : async ( ) : Promise < AccountBalanceFormatParams > => {
169182 if ( ! chainToLoad ) {
170183 throw new Error ( "chain is required" ) ;
171184 }
172185 if ( ! client ) {
173186 throw new Error ( "client is required" ) ;
174187 }
175- return getWalletBalance ( {
188+ const tokenBalanceData = await getWalletBalance ( {
176189 chain : chainToLoad ,
177190 client,
178191 address,
179192 tokenAddress,
180193 } ) ;
194+
195+ if ( ! tokenBalanceData ) {
196+ throw new Error (
197+ `Failed to retrieve ${ tokenAddress ? `token: ${ tokenAddress } ` : "native token" } balance for address: ${ address } on chainId:${ chainToLoad . id } ` ,
198+ ) ;
199+ }
200+
201+ if ( showFiatValue ) {
202+ const fiatData = await convertCryptoToFiat ( {
203+ fromAmount : Number ( tokenBalanceData . displayValue ) ,
204+ fromTokenAddress : tokenAddress || NATIVE_TOKEN_ADDRESS ,
205+ to : showFiatValue ,
206+ chain : chainToLoad ,
207+ client,
208+ } ) . catch ( ( ) => undefined ) ;
209+
210+ // We can never support 100% of token out there, so if something fails to resolve, it's expected
211+ // in that case just return the tokenBalance and symbol
212+ return {
213+ tokenBalance : Number ( tokenBalanceData . displayValue ) ,
214+ tokenSymbol : tokenBalanceData . symbol ,
215+ fiatBalance : fiatData ?. result ,
216+ fiatSymbol : fiatData ?. result
217+ ? new Intl . NumberFormat ( "en" , {
218+ style : "currency" ,
219+ currency : showFiatValue ,
220+ minimumFractionDigits : 0 ,
221+ maximumFractionDigits : 0 ,
222+ } )
223+ . formatToParts ( 0 )
224+ . find ( ( p ) => p . type === "currency" ) ?. value ||
225+ showFiatValue . toUpperCase ( )
226+ : undefined ,
227+ } ;
228+ }
229+
230+ return {
231+ tokenBalance : Number ( tokenBalanceData . displayValue ) ,
232+ tokenSymbol : tokenBalanceData . symbol ,
233+ } ;
181234 } ,
182235 ...queryOptions ,
183236 } ) ;
@@ -190,13 +243,24 @@ export function AccountBalance({
190243 return fallbackComponent || null ;
191244 }
192245
193- const displayValue = formatFn
194- ? formatFn ( Number ( balanceQuery . data . displayValue ) )
195- : balanceQuery . data . displayValue ;
246+ if ( formatFn ) {
247+ return < span { ...restProps } > { formatFn ( balanceQuery . data ) } </ span > ;
248+ }
249+
250+ const { tokenBalance, tokenSymbol, fiatBalance, fiatSymbol } =
251+ balanceQuery . data ;
252+
253+ if ( fiatBalance && fiatSymbol ) {
254+ return (
255+ < span { ...restProps } >
256+ { `${ tokenBalance } ${ tokenSymbol } (${ fiatSymbol } ${ fiatBalance } )` }
257+ </ span >
258+ ) ;
259+ }
196260
197261 return (
198262 < span { ...restProps } >
199- { displayValue } { balanceQuery . data . symbol }
263+ { tokenBalance } { tokenSymbol }
200264 </ span >
201265 ) ;
202266}
0 commit comments