Skip to content

Commit

Permalink
Revert "Remove useNativeCurrencyPrice.ts"
Browse files Browse the repository at this point in the history
This reverts commit 58f36a0.
  • Loading branch information
portdeveloper committed Dec 29, 2024
1 parent 58f36a0 commit 3cbf332
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/nextjs/hooks/scaffold-eth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export * from "./useScaffoldWatchContractEvent";
export * from "./useScaffoldWriteContract";
export * from "./useTransactor";
export * from "./useWatchBalance";
export * from "./useNativeCurrencyPrice";
export * from "./useAccountBalance";
35 changes: 35 additions & 0 deletions packages/nextjs/hooks/scaffold-eth/useNativeCurrencyPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useEffect, useState } from "react";
import { useInterval } from "usehooks-ts";
import scaffoldConfig from "~~/scaffold.config";
import { useGlobalState } from "~~/services/store/store";
import { fetchPriceFromUniswap } from "~~/utils/scaffold-eth";

const enablePolling = false;

/**
* Get the price of Native Currency based on Native Token/DAI trading pair from Uniswap SDK
* @returns nativeCurrencyPrice: number
*/
export const useNativeCurrencyPrice = () => {
const targetNetwork = useGlobalState(state => state.targetNetwork);
const [nativeCurrencyPrice, setNativeCurrencyPrice] = useState(0);

// Get the price of ETH from Uniswap on mount
useEffect(() => {
(async () => {
const price = await fetchPriceFromUniswap(targetNetwork);
setNativeCurrencyPrice(price);
})();
}, [targetNetwork]);

// Get the price of ETH from Uniswap at a given interval
useInterval(
async () => {
const price = await fetchPriceFromUniswap(targetNetwork);
setNativeCurrencyPrice(price);
},
enablePolling ? scaffoldConfig.pollingInterval : null,
);

return nativeCurrencyPrice;
};
11 changes: 10 additions & 1 deletion packages/nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Toaster } from "react-hot-toast";
import { WagmiProvider } from "wagmi";
import { getStoredChainsFromLocalStorage } from "~~/components/NetworksDropdown/utils";
import { BlockieAvatar } from "~~/components/scaffold-eth";
import { useNativeCurrencyPrice } from "~~/hooks/scaffold-eth";
import { useGlobalState } from "~~/services/store/store";
import "~~/styles/globals.css";

Expand All @@ -22,8 +23,10 @@ export const queryClient = new QueryClient({
});

const ScaffoldEthApp = ({ Component, pageProps }: AppProps) => {
const { addChain } = useGlobalState(state => ({
const price = useNativeCurrencyPrice();
const { addChain, setNativeCurrencyPrice } = useGlobalState(state => ({
addChain: state.addChain,
setNativeCurrencyPrice: state.setNativeCurrencyPrice,
}));
const { resolvedTheme } = useTheme();
const isDarkMode = resolvedTheme === "dark";
Expand All @@ -41,6 +44,12 @@ const ScaffoldEthApp = ({ Component, pageProps }: AppProps) => {
setMounted(true);
}, []);

useEffect(() => {
if (price > 0) {
setNativeCurrencyPrice(price);
}
}, [setNativeCurrencyPrice, price]);

return (
<RainbowKitProvider
avatar={BlockieAvatar}
Expand Down
2 changes: 2 additions & 0 deletions packages/nextjs/services/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ChainWithAttributes } from "~~/utils/scaffold-eth";

type GlobalState = {
nativeCurrencyPrice: number;
setNativeCurrencyPrice: (newNativeCurrencyPriceState: number) => void;
targetNetwork: ChainWithAttributes;
setTargetNetwork: (newTargetNetwork: ChainWithAttributes) => void;
wagmiConfig: Config;
Expand All @@ -25,6 +26,7 @@ type GlobalState = {

export const useGlobalState = create<GlobalState>(set => ({
nativeCurrencyPrice: 0,
setNativeCurrencyPrice: (newValue: number): void => set(() => ({ nativeCurrencyPrice: newValue })),
targetNetwork: mainnet,
setTargetNetwork: (newTargetNetwork: ChainWithAttributes) => set(() => ({ targetNetwork: newTargetNetwork })),
wagmiConfig: baseWagmiConfig,
Expand Down
73 changes: 73 additions & 0 deletions packages/nextjs/utils/scaffold-eth/fetchPriceFromUniswap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { ChainWithAttributes, getAlchemyHttpUrl } from "./networks";
import { CurrencyAmount, Token } from "@uniswap/sdk-core";
import { Pair, Route } from "@uniswap/v2-sdk";
import { Address, createPublicClient, http, parseAbi } from "viem";
import { mainnet } from "viem/chains";

const publicClient = createPublicClient({
chain: mainnet,
transport: http(getAlchemyHttpUrl(mainnet.id)),
});

const ABI = parseAbi([
"function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)",
"function token0() external view returns (address)",
"function token1() external view returns (address)",
]);

export const fetchPriceFromUniswap = async (targetNetwork: ChainWithAttributes): Promise<number> => {
if (!targetNetwork?.nativeCurrency) {
return 0;
}
if (
targetNetwork.nativeCurrency.symbol !== "ETH" &&
targetNetwork.nativeCurrency.symbol !== "SEP" &&
!targetNetwork.nativeCurrencyTokenAddress
) {
return 0;
}
try {
const DAI = new Token(1, "0x6B175474E89094C44Da98b954EedeAC495271d0F", 18);
const TOKEN = new Token(
1,
targetNetwork.nativeCurrencyTokenAddress || "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
18,
);
const pairAddress = Pair.getAddress(TOKEN, DAI) as Address;

const wagmiConfig = {
address: pairAddress,
abi: ABI,
};

const reserves = await publicClient.readContract({
...wagmiConfig,
functionName: "getReserves",
});

const token0Address = await publicClient.readContract({
...wagmiConfig,
functionName: "token0",
});

const token1Address = await publicClient.readContract({
...wagmiConfig,
functionName: "token1",
});
const token0 = [TOKEN, DAI].find(token => token.address === token0Address) as Token;
const token1 = [TOKEN, DAI].find(token => token.address === token1Address) as Token;
const pair = new Pair(
CurrencyAmount.fromRawAmount(token0, reserves[0].toString()),
CurrencyAmount.fromRawAmount(token1, reserves[1].toString()),
);
const route = new Route([pair], TOKEN, DAI);
const price = parseFloat(route.midPrice.toSignificant(6));
return price;
} catch (error) {
console.error(
`useNativeCurrencyPrice - Error fetching ${targetNetwork.nativeCurrency.symbol} price from Uniswap: `,
error,
);
return 0;
}
};
1 change: 1 addition & 0 deletions packages/nextjs/utils/scaffold-eth/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./fetchPriceFromUniswap";
export * from "./networks";
export * from "./notification";
export * from "./block";
Expand Down

0 comments on commit 3cbf332

Please sign in to comment.