diff --git a/packages/nextjs/components/Footer.tsx b/packages/nextjs/components/Footer.tsx index 66feda99..b8eab224 100644 --- a/packages/nextjs/components/Footer.tsx +++ b/packages/nextjs/components/Footer.tsx @@ -8,6 +8,9 @@ import { import { HeartIcon } from "@heroicons/react/24/outline"; import { SwitchTheme } from "~~/components/SwitchTheme"; import { BuidlGuidlLogo } from "~~/components/assets/BuidlGuidlLogo"; +import { useTargetNetwork } from "~~/hooks/scaffold-stark/useTargetNetwork"; +import { useGlobalState } from "~~/services/store/store"; +import { devnet } from "@starknet-react/chains"; // import { Faucet } from "~~/components/scaffold-eth"; // import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork"; // import { useGlobalState } from "~~/services/store/store"; @@ -16,18 +19,18 @@ import { BuidlGuidlLogo } from "~~/components/assets/BuidlGuidlLogo"; * Site footer */ export const Footer = () => { - // const nativeCurrencyPrice = useGlobalState( - // (state) => state.nativeCurrencyPrice - // ); - // const { targetNetwork } = useTargetNetwork(); - const isLocalNetwork = false; + const nativeCurrencyPrice = useGlobalState( + (state) => state.nativeCurrencyPrice, + ); + const { targetNetwork } = useTargetNetwork(); + const isLocalNetwork = targetNetwork.id === devnet.id; return (
- {/* {nativeCurrencyPrice > 0 && ( + {nativeCurrencyPrice > 0 && (
@@ -37,7 +40,7 @@ export const Footer = () => { )} {isLocalNetwork && ( <> - + {/**/} { Block Explorer - )} */} + )}
{ + useNativeCurrencyPrice(); + return ( <>
diff --git a/packages/nextjs/components/scaffold-stark/Balance.tsx b/packages/nextjs/components/scaffold-stark/Balance.tsx index f5fa9eef..cde2f5f4 100644 --- a/packages/nextjs/components/scaffold-stark/Balance.tsx +++ b/packages/nextjs/components/scaffold-stark/Balance.tsx @@ -70,7 +70,12 @@ export const Balance = ({ address, className = "", usdMode }: BalanceProps) => { {displayUsdMode ? ( <> $ - {(formattedBalance * price).toFixed(2)} + + {(formattedBalance * price).toLocaleString("en-US", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + })} + ) : ( <> diff --git a/packages/nextjs/hooks/scaffold-stark/useNativeCurrencyPrice.ts b/packages/nextjs/hooks/scaffold-stark/useNativeCurrencyPrice.ts new file mode 100644 index 00000000..b117ba96 --- /dev/null +++ b/packages/nextjs/hooks/scaffold-stark/useNativeCurrencyPrice.ts @@ -0,0 +1,39 @@ +import { useEffect } from "react"; +import { useTargetNetwork } from "./useTargetNetwork"; +import { useInterval } from "usehooks-ts"; +import scaffoldConfig from "~~/scaffold.config"; +import { fetchPriceFromCoingecko } from "~~/utils/scaffold-stark"; +import { useGlobalState } from "~~/services/store/store"; + +/** + * Get the price of Native Currency based on Native Token/DAI trading pair from Uniswap SDK + */ +export const useNativeCurrencyPrice = () => { + const { targetNetwork } = useTargetNetwork(); + const nativeCurrencyPrice = useGlobalState( + (state) => state.nativeCurrencyPrice, + ); + const setNativeCurrencyPrice = useGlobalState( + (state) => state.setNativeCurrencyPrice, + ); + // Get the price of ETH from Coingecko on mount + useEffect(() => { + (async () => { + if (nativeCurrencyPrice == 0) { + const price = await fetchPriceFromCoingecko(targetNetwork); + setNativeCurrencyPrice(price); + } + })(); + }, [targetNetwork]); + + // Get the price of ETH from Coingecko at a given interval + useInterval( + async () => { + const price = await fetchPriceFromCoingecko(targetNetwork); + setNativeCurrencyPrice(price); + }, + scaffoldConfig.pollingInterval ? 4000 : scaffoldConfig.pollingInterval, + ); + + //return nativeCurrencyPrice; +}; diff --git a/packages/nextjs/scaffold.config.ts b/packages/nextjs/scaffold.config.ts index 9d010910..3daf09e4 100644 --- a/packages/nextjs/scaffold.config.ts +++ b/packages/nextjs/scaffold.config.ts @@ -2,6 +2,7 @@ import * as chains from "@starknet-react/chains"; export type ScaffoldConfig = { targetNetworks: readonly chains.Chain[]; + pollingInterval?: number | null; onlyLocalBurnerWallet: boolean; rpcProviderUrl: string; walletAutoConnect: boolean; @@ -12,6 +13,9 @@ const scaffoldConfig = { // Only show the Burner Wallet when running on devnet onlyLocalBurnerWallet: false, rpcProviderUrl: process.env.NEXT_PUBLIC_PROVIDER_URL || "", + // The interval at which your front-end polls the RPC servers for new data + // it has no effect if you only target the local network (default is 4000) + pollingInterval: null, /** * Auto connect: * 1. If the user was connected into a wallet before, on page reload reconnect automatically diff --git a/packages/nextjs/utils/scaffold-stark/fetchPriceFromCoingecko.ts b/packages/nextjs/utils/scaffold-stark/fetchPriceFromCoingecko.ts new file mode 100644 index 00000000..a0e42af7 --- /dev/null +++ b/packages/nextjs/utils/scaffold-stark/fetchPriceFromCoingecko.ts @@ -0,0 +1,27 @@ +import { ChainWithAttributes } from "~~/utils/scaffold-stark"; + +export const fetchPriceFromCoingecko = async ( + targetNetwork: ChainWithAttributes, +): Promise => { + if ( + targetNetwork.nativeCurrency.symbol !== "ETH" && + targetNetwork.nativeCurrency.symbol !== "SEP" && + !targetNetwork.nativeCurrencyTokenAddress + ) { + return 0; + } + + try { + const response = await fetch( + "https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd", + ); + const data = await response.json(); + return data.ethereum.usd; + } catch (error) { + console.error( + `useNativeCurrencyPrice - Error fetching ${targetNetwork.nativeCurrency.symbol} price from Coingecko: `, + error, + ); + return 0; + } +}; diff --git a/packages/nextjs/utils/scaffold-stark/index.ts b/packages/nextjs/utils/scaffold-stark/index.ts index eaa4e9b4..1a102ac0 100644 --- a/packages/nextjs/utils/scaffold-stark/index.ts +++ b/packages/nextjs/utils/scaffold-stark/index.ts @@ -1,2 +1,3 @@ export * from "./networks"; export * from "./notification"; +export * from "./fetchPriceFromCoingecko"; diff --git a/packages/nextjs/utils/scaffold-stark/networks.ts b/packages/nextjs/utils/scaffold-stark/networks.ts index 2e5b71c6..4e44e005 100644 --- a/packages/nextjs/utils/scaffold-stark/networks.ts +++ b/packages/nextjs/utils/scaffold-stark/networks.ts @@ -4,6 +4,7 @@ import scaffoldConfig from "~~/scaffold.config"; type ChainAttributes = { // color | [lightThemeColor, darkThemeColor] color: string | [string, string]; + nativeCurrencyTokenAddress?: string; }; export type ChainWithAttributes = chains.Chain & Partial;