@@ -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 ( ) ;
@@ -165,19 +177,59 @@ export function AccountBalance({
165177 address || "0x0" ,
166178 { tokenAddress } ,
167179 ] as const ,
168- queryFn : async ( ) => {
180+ queryFn : async ( ) : Promise < AccountBalanceFormatParams > => {
169181 if ( ! chainToLoad ) {
170182 throw new Error ( "chain is required" ) ;
171183 }
172184 if ( ! client ) {
173185 throw new Error ( "client is required" ) ;
174186 }
175- return getWalletBalance ( {
187+ const tokenBalanceData = await getWalletBalance ( {
176188 chain : chainToLoad ,
177189 client,
178190 address,
179191 tokenAddress,
180192 } ) ;
193+
194+ if ( ! tokenBalanceData ) {
195+ throw new Error (
196+ `Failed to retrieve ${ tokenAddress ? `token: ${ tokenAddress } ` : "native token" } balance for address: ${ address } on chainId:${ chainToLoad . id } ` ,
197+ ) ;
198+ }
199+
200+ if ( showFiatValue ) {
201+ const fiatData = await convertCryptoToFiat ( {
202+ fromAmount : Number ( tokenBalanceData . displayValue ) ,
203+ fromTokenAddress : tokenAddress || NATIVE_TOKEN_ADDRESS ,
204+ to : showFiatValue ,
205+ chain : chainToLoad ,
206+ client,
207+ } ) . catch ( ( ) => undefined ) ;
208+
209+ // We can never support 100% of token out there, so if something fails to resolve, it's expected
210+ // in that case just return the tokenBalance and symbol
211+ return {
212+ tokenBalance : Number ( tokenBalanceData . displayValue ) ,
213+ tokenSymbol : tokenBalanceData . symbol ,
214+ fiatBalance : fiatData ?. result ,
215+ fiatSymbol : fiatData ?. result
216+ ? new Intl . NumberFormat ( "en" , {
217+ style : "currency" ,
218+ currency : showFiatValue ,
219+ minimumFractionDigits : 0 ,
220+ maximumFractionDigits : 0 ,
221+ } )
222+ . formatToParts ( 0 )
223+ . find ( ( p ) => p . type === "currency" ) ?. value ||
224+ showFiatValue . toUpperCase ( )
225+ : undefined ,
226+ } ;
227+ }
228+
229+ return {
230+ tokenBalance : Number ( tokenBalanceData . displayValue ) ,
231+ tokenSymbol : tokenBalanceData . symbol ,
232+ } ;
181233 } ,
182234 ...queryOptions ,
183235 } ) ;
@@ -190,13 +242,24 @@ export function AccountBalance({
190242 return fallbackComponent || null ;
191243 }
192244
193- const displayValue = formatFn
194- ? formatFn ( Number ( balanceQuery . data . displayValue ) )
195- : balanceQuery . data . displayValue ;
245+ if ( formatFn ) {
246+ return < span { ...restProps } > { formatFn ( balanceQuery . data ) } </ span > ;
247+ }
248+
249+ const { tokenBalance, tokenSymbol, fiatBalance, fiatSymbol } =
250+ balanceQuery . data ;
251+
252+ if ( fiatBalance && fiatSymbol ) {
253+ return (
254+ < span { ...restProps } >
255+ { `${ tokenBalance } ${ tokenSymbol } (${ fiatSymbol } ${ fiatBalance } )` }
256+ </ span >
257+ ) ;
258+ }
196259
197260 return (
198261 < span { ...restProps } >
199- { displayValue } { balanceQuery . data . symbol }
262+ { tokenBalance } { tokenSymbol }
200263 </ span >
201264 ) ;
202265}
0 commit comments