From 56d7fac5f2c482dc98f32b13f2abd45e524eced0 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 11:41:17 -0600 Subject: [PATCH 01/10] feat: update cannot deposit if Well below min reserves --- .../Common/Form/TokenSelectDialogNew.tsx | 18 +++++--- .../src/components/Silo/Actions/Deposit.tsx | 15 ++++++- .../beanstalk/useCalcWellHasMinReserves.ts | 43 +++++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 projects/ui/src/hooks/beanstalk/useCalcWellHasMinReserves.ts diff --git a/projects/ui/src/components/Common/Form/TokenSelectDialogNew.tsx b/projects/ui/src/components/Common/Form/TokenSelectDialogNew.tsx index 3372ae3c4c..5569362bef 100644 --- a/projects/ui/src/components/Common/Form/TokenSelectDialogNew.tsx +++ b/projects/ui/src/components/Common/Form/TokenSelectDialogNew.tsx @@ -23,10 +23,10 @@ import { displayBN } from '~/util'; import { ZERO_BN } from '~/constants'; import { ApplicableBalance, FarmerBalances } from '~/state/farmer/balances'; import { FarmerSilo } from '~/state/farmer/silo'; -import { BeanstalkPalette, FontSize, IconSize } from '../../App/muiTheme'; import Row from '~/components/Common/Row'; -import BalanceFromRow, { BalanceFrom } from './BalanceFromRow'; import useSdk from '~/hooks/sdk'; +import { BeanstalkPalette, FontSize, IconSize } from '../../App/muiTheme'; +import BalanceFromRow, { BalanceFrom } from './BalanceFromRow'; export enum TokenSelectMode { MULTI, @@ -107,15 +107,18 @@ const TokenSelectDialogNew: TokenSelectDialogC = React.memo( const [selectedInternal, setSelectedInternal] = useState>( new Set() ); - const [balanceFromInternal, setBalanceFromInternal] = useState(BalanceFrom.TOTAL); + const [balanceFromInternal, setBalanceFromInternal] = useState( + BalanceFrom.TOTAL + ); const getBalance = useCallback( (addr: string) => { if (!_balances) return ZERO_BN; if (balancesType === 'farm') return ( - (_balances as TokenBalanceMode['farm'])?.[addr]?.[balanceFromInternal] || - ZERO_BN + (_balances as TokenBalanceMode['farm'])?.[addr]?.[ + balanceFromInternal + ] || ZERO_BN ); return ( (_balances as TokenBalanceMode['silo-deposits'])?.[addr]?.deposited @@ -177,7 +180,7 @@ const TokenSelectDialogNew: TokenSelectDialogC = React.memo( const setBalanceFromAndClose = useCallback(() => { if (setBalanceFrom) { setBalanceFrom(balanceFromInternal); - }; + } handleClose(); // hide dialog }, [handleClose, setBalanceFrom, balanceFromInternal]); @@ -189,7 +192,8 @@ const TokenSelectDialogNew: TokenSelectDialogC = React.memo( (_newSelection: Set) => () => { handleSubmit(_newSelection); // update form state setBalanceFromAndClose(); - }, [handleSubmit, setBalanceFromAndClose] + }, + [handleSubmit, setBalanceFromAndClose] ); // Click an item in the token list. diff --git a/projects/ui/src/components/Silo/Actions/Deposit.tsx b/projects/ui/src/components/Silo/Actions/Deposit.tsx index d475cf3e6d..b007051966 100644 --- a/projects/ui/src/components/Silo/Actions/Deposit.tsx +++ b/projects/ui/src/components/Silo/Actions/Deposit.tsx @@ -63,6 +63,8 @@ import useFormTxnContext from '~/hooks/sdk/useFormTxnContext'; import { ClaimAndDoX, DepositFarmStep, FormTxn } from '~/lib/Txn'; import useGetBalancesUsedBySource from '~/hooks/beanstalk/useBalancesUsedBySource'; import { selectBdvPerToken } from '~/state/beanstalk/silo'; +import { useCalcWellHasMinReserves } from '~/hooks/beanstalk/useCalcWellHasMinReserves'; +import WarningAlert from '~/components/Common/Alert/WarningAlert'; // ----------------------------------------------------------------------- @@ -119,6 +121,9 @@ const DepositForm: FC< const beanstalkSilo = useSilo(); const siblingRef = useRef(null); + const calcHasMinReserves = useCalcWellHasMinReserves(); + const hasMinReserves = calcHasMinReserves(whitelistedToken); + /// Handlers // This handler does not run when _tokenIn = _tokenOut (direct deposit) const handleQuote = useCallback>( @@ -280,6 +285,8 @@ const DepositForm: FC< key={`tokens.${index}`} name={`tokens.${index}`} tokenOut={whitelistedToken} + disabled={!hasMinReserves} + disableTokenSelect={!hasMinReserves} balance={balance} state={tokenState} showTokenSelect={showTokenSelect} @@ -290,6 +297,12 @@ const DepositForm: FC< ); })} {false && } + {!hasMinReserves && ( + + The BEAN reserves for this Well are below the minimum required for + deposit. + + )} {isReady ? ( <> @@ -342,7 +355,7 @@ const DepositForm: FC< ) : null} { + const sdk = useSdk(); + const { BEAN } = useBalanceTokens(); + + const pools = useAppSelector((state) => state._bean.pools); + + const getHasMinReserves = useCallback( + (token: ERC20Token) => { + if (token.equals(BEAN)) return true; + + const well = sdk.pools.getWellByLPToken(token); + const wellData = pools[getTokenIndex(token)]; + + if (!well || !wellData) return true; + + const tokenIndexes = well.getBeanWellTokenIndexes(); + const beanReserve = wellData.reserves[tokenIndexes.bean]; + + const hasMinBeanReserves = beanReserve?.gt(WELL_MINIMUM_BEAN_BALANCE); + + return hasMinBeanReserves; + }, + [BEAN, sdk, pools] + ); + + return getHasMinReserves; +}; From 025ab362f1bb765d88f34f58166556d07e702b24 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 11:41:42 -0600 Subject: [PATCH 02/10] feat: update token input to use index + usetokens hooks --- .../dex-ui/src/components/Swap/TokenInput.tsx | 3 +- projects/ui/src/hooks/beanstalk/useTokens.ts | 48 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/projects/dex-ui/src/components/Swap/TokenInput.tsx b/projects/dex-ui/src/components/Swap/TokenInput.tsx index 1107afce0c..86bdb4a1e5 100644 --- a/projects/dex-ui/src/components/Swap/TokenInput.tsx +++ b/projects/dex-ui/src/components/Swap/TokenInput.tsx @@ -7,6 +7,7 @@ import { Token, TokenValue } from "@beanstalk/sdk"; import { size } from "src/breakpoints"; import { useTokenBalance } from "src/tokens/useTokenBalance"; +import { getTokenIndex } from "src/tokens/utils"; import { FC } from "src/types"; import { BasicInput } from "./BasicInput"; @@ -130,7 +131,7 @@ export const TokenInput: FC = ({ {balanceLabel}:{" "} - {isBalanceLoading ? : balance?.[token.address]?.toHuman("short")} + {isBalanceLoading ? : balance?.[getTokenIndex(token)]?.toHuman("short")} )} diff --git a/projects/ui/src/hooks/beanstalk/useTokens.ts b/projects/ui/src/hooks/beanstalk/useTokens.ts index 41d21844ed..5d98a6b4e6 100644 --- a/projects/ui/src/hooks/beanstalk/useTokens.ts +++ b/projects/ui/src/hooks/beanstalk/useTokens.ts @@ -42,11 +42,7 @@ export function indexTokens(tokens: T[]) { }, {}); } -/** - * - * @returns all balance tokens from the SDK all ERC20 tokens + ETH - */ -export const useTokens = (): { +export interface BalanceTokens { ETH: NativeToken; WETH: ERC20Token; WSTETH: ERC20Token; @@ -55,8 +51,6 @@ export const useTokens = (): { BEAN: ERC20Token; USDC: ERC20Token; USDT: ERC20Token; - DAI: ERC20Token; - ARB: ERC20Token; UNRIPE_BEAN: ERC20Token; UNRIPE_BEAN_WSTETH: ERC20Token; BEAN_ETH_WELL_LP: ERC20Token; @@ -65,6 +59,45 @@ export const useTokens = (): { BEAN_WBTC_WELL_LP: ERC20Token; BEAN_USDC_WELL_LP: ERC20Token; BEAN_USDT_WELL_LP: ERC20Token; +} + +export const useBalanceTokens = (): BalanceTokens => { + const sdk = useSdk(); + + return useMemo(() => { + const tokens = sdk.tokens; + const balanceTokens = { + ETH: tokens.ETH, + WETH: tokens.WETH, + WSTETH: tokens.WSTETH, + WEETH: tokens.WEETH, + WBTC: tokens.WBTC, + BEAN: tokens.BEAN, + USDC: tokens.USDC, + USDT: tokens.USDT, + UNRIPE_BEAN: tokens.UNRIPE_BEAN, + UNRIPE_BEAN_WSTETH: tokens.UNRIPE_BEAN_WSTETH, + BEAN_ETH_WELL_LP: tokens.BEAN_ETH_WELL_LP, + BEAN_WSTETH_WELL_LP: tokens.BEAN_WSTETH_WELL_LP, + BEAN_WEETH_WELL_LP: tokens.BEAN_WEETH_WELL_LP, + BEAN_WBTC_WELL_LP: tokens.BEAN_WBTC_WELL_LP, + BEAN_USDC_WELL_LP: tokens.BEAN_USDC_WELL_LP, + BEAN_USDT_WELL_LP: tokens.BEAN_USDT_WELL_LP, + }; + + return { + ...balanceTokens, + }; + }, [sdk.tokens]); +}; + +/** + * + * @returns all balance tokens from the SDK all ERC20 tokens + ETH + */ +export const useTokens = (): BalanceTokens & { + DAI: ERC20Token; + ARB: ERC20Token; erc20TokenMap: TokenMap; erc20Tokens: ERC20Token[]; addresses: string[]; @@ -128,7 +161,6 @@ export const useSwapTokens = () => { ); }; - /** * @returns all beanstalk tokens from the SDK STALK, SEEDS, SPROUTS, rSPROUTS, PODS */ From 4050c933b29c75e908f4e4ad97c8839180b9af68 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 11:50:40 -0600 Subject: [PATCH 03/10] feat: update convert form --- .../Actions/Convert/DefaultConvertForm.tsx | 18 +++++++++++++++--- .../beanstalk/useCalcWellHasMinReserves.ts | 5 +++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/projects/ui/src/components/Silo/Actions/Convert/DefaultConvertForm.tsx b/projects/ui/src/components/Silo/Actions/Convert/DefaultConvertForm.tsx index f4dc7f4f0f..e6cc003aa8 100644 --- a/projects/ui/src/components/Silo/Actions/Convert/DefaultConvertForm.tsx +++ b/projects/ui/src/components/Silo/Actions/Convert/DefaultConvertForm.tsx @@ -31,6 +31,7 @@ import { FormTxn, ConvertFarmStep } from '~/lib/Txn'; import StatHorizontal from '~/components/Common/StatHorizontal'; import { BeanstalkPalette, FontSize } from '~/components/App/muiTheme'; import { AppState } from '~/state'; +import { useCalcWellHasMinReserves } from '~/hooks/beanstalk/useCalcWellHasMinReserves'; import { ConvertQuoteHandlerParams, BaseConvertFormProps } from './types'; interface Props extends BaseConvertFormProps { @@ -50,6 +51,8 @@ export const DefaultConvertForm: FC = ({ setFieldValue, conversion, }) => { + const calcHasMinReserves = useCalcWellHasMinReserves(); + /// Local state const [isTokenSelectVisible, showTokenSelect, hideTokenSelect] = useToggle(); const getBDV = useBDV(); @@ -72,7 +75,9 @@ export const DefaultConvertForm: FC = ({ const tokenOut = values.tokenOut; // converting to token const amountOut = values.tokens[0].amountOut; // amount of to token const maxAmountIn = values.maxAmountIn; - const canConvert = maxAmountIn?.gt(0) || false; + const hasMinReserves = calcHasMinReserves(tokenOut); + + const canConvert = (maxAmountIn?.gt(0) && hasMinReserves) || false; // FIXME: these use old structs instead of SDK const siloBalance = siloBalances[tokenIn.address]; @@ -246,10 +251,11 @@ export const DefaultConvertForm: FC = ({ } else { pool += ' pool'; } - if (['urBEANETH', 'urBEAN'].includes(tokenIn.symbol)) pool = 'BEANETH Well'; + if (['urBEANwstETH', 'urBEAN'].includes(tokenIn.symbol)) + pool = 'BEANwstETH Well'; const lowerOrGreater = - tokenIn.isLP || tokenIn.symbol === 'urBEANETH' ? 'less' : 'greater'; + tokenIn.isLP || tokenIn.symbol === 'urBEANwstETH' ? 'less' : 'greater'; const message = `${tokenIn.symbol} can only be Converted to ${tokenOut?.symbol} when deltaB in the ${pool} is ${lowerOrGreater} than 0.`; @@ -335,6 +341,12 @@ export const DefaultConvertForm: FC = ({ ) : null} + {!hasMinReserves && ( + + The BEAN reserves for the {tokenOut?.symbol} Well are below the + minimum required to Convert. + + )} {/* Outputs */} {totalAmountIn && tokenOut && diff --git a/projects/ui/src/hooks/beanstalk/useCalcWellHasMinReserves.ts b/projects/ui/src/hooks/beanstalk/useCalcWellHasMinReserves.ts index 0f4b06ab10..bf8bfce342 100644 --- a/projects/ui/src/hooks/beanstalk/useCalcWellHasMinReserves.ts +++ b/projects/ui/src/hooks/beanstalk/useCalcWellHasMinReserves.ts @@ -1,4 +1,4 @@ -import { ERC20Token } from '@beanstalk/sdk'; +import { Token } from '@beanstalk/sdk'; import { useCallback } from 'react'; import { useAppSelector } from '~/state'; import { getTokenIndex } from '~/util'; @@ -21,7 +21,8 @@ export const useCalcWellHasMinReserves = () => { const pools = useAppSelector((state) => state._bean.pools); const getHasMinReserves = useCallback( - (token: ERC20Token) => { + (token: Token | undefined) => { + if (!token) return true; if (token.equals(BEAN)) return true; const well = sdk.pools.getWellByLPToken(token); From bd7bb4a9e11d150bf35ebe2283daec865055edee Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 11:52:54 -0600 Subject: [PATCH 04/10] feat: remove sun toast --- projects/ui/src/state/beanstalk/sun/updater.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/ui/src/state/beanstalk/sun/updater.ts b/projects/ui/src/state/beanstalk/sun/updater.ts index 6702a2cb88..d035043df6 100644 --- a/projects/ui/src/state/beanstalk/sun/updater.ts +++ b/projects/ui/src/state/beanstalk/sun/updater.ts @@ -1,7 +1,6 @@ import { DateTime, Duration } from 'luxon'; import { useCallback, useEffect } from 'react'; import { useDispatch } from 'react-redux'; -import toast from 'react-hot-toast'; import useSeason from '~/hooks/beanstalk/useSeason'; import { useAppSelector } from '~/state'; import { bigNumberResult } from '~/util/Ledger'; @@ -141,9 +140,9 @@ const SunUpdater = () => { dispatch(setAwaitingSunrise(false)); dispatch(setNextSunrise(_next)); setRemainingUntilSunrise(_next.diffNow()); - toast.success( - `The Sun has risen. It is now Season ${newSeason.current.toString()}.` - ); + // toast.success( + // `The Sun has risen. It is now Season ${newSeason.current.toString()}.` + // ); await refreshSeeds(sdk); } })(); From ee8529de5e8517df82b96bae44eb529ccddda2f4 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:25:22 -0600 Subject: [PATCH 05/10] feat: fix gas estimations --- projects/ui/src/components/Common/GasTag.tsx | 15 ++++- projects/ui/src/env.d.ts | 17 +----- .../ui/src/functions/ethprice/ethprice.ts | 58 +++++++------------ projects/ui/src/hooks/ledger/useGasToUSD.ts | 24 ++++++-- projects/ui/src/state/app/actions.ts | 7 +-- projects/ui/src/state/app/index.ts | 12 +++- projects/ui/src/state/app/updater.ts | 36 ++++++++++-- 7 files changed, 94 insertions(+), 75 deletions(-) diff --git a/projects/ui/src/components/Common/GasTag.tsx b/projects/ui/src/components/Common/GasTag.tsx index 26a084cfa4..e76acc9b2f 100644 --- a/projects/ui/src/components/Common/GasTag.tsx +++ b/projects/ui/src/components/Common/GasTag.tsx @@ -1,6 +1,6 @@ -import { Box, Divider, Tooltip, Typography } from '@mui/material'; -import BigNumber from 'bignumber.js'; import React from 'react'; +import BigNumber from 'bignumber.js'; +import { Box, Divider, Tooltip, Typography } from '@mui/material'; import { useSelector } from 'react-redux'; import { DateTime } from 'luxon'; import useGasToUSD from '~/hooks/ledger/useGasToUSD'; @@ -9,6 +9,9 @@ import { displayFullBN, displayUSD } from '~/util'; import { FC } from '~/types'; import StatHorizontal from '~/components/Common/StatHorizontal'; +import { ZERO_BN } from '~/constants'; + +const WEI_TO_GWEI = new BigNumber(10).pow(9); const GasTag: FC<{ gasLimit: BigNumber | null; @@ -19,6 +22,10 @@ const GasTag: FC<{ ); const getGasUSD = useGasToUSD(); const gasUSD = gasLimit ? getGasUSD(gasLimit) : null; + + const baseFeeInWei = prices?.baseFeePerGas ?? ZERO_BN; + const baseFeeGwei = baseFeeInWei.div(WEI_TO_GWEI); + return ( - {prices?.gas.safe ? `${prices.gas.safe} gwei` : '?'} + {baseFeeGwei?.gt(0) + ? `${baseFeeGwei.toExponential(2, BigNumber.ROUND_UP)} gwei` + : '?'} {prices?.ethusd ? `$${prices.ethusd}` : '?'} diff --git a/projects/ui/src/env.d.ts b/projects/ui/src/env.d.ts index 3180c07ec0..429118150e 100644 --- a/projects/ui/src/env.d.ts +++ b/projects/ui/src/env.d.ts @@ -30,22 +30,7 @@ interface ImportMetaEnv { /** * */ - readonly VITE_TENDERLY_ACCOUNT_SLUG: string; - - /** - * - */ - readonly VITE_TENDERLY_PROJECT_SLUG: string; - - /** - * - */ - readonly VITE_TENDERLY_ACCESS_KEY: string; - - /** - * Tenderly Virtual Network ID for testnet - */ - readonly VITE_TENDERLY_VNET_ID?: string; + readonly VITE_ARBISCAN_API_KEY: string; } interface ImportMeta { diff --git a/projects/ui/src/functions/ethprice/ethprice.ts b/projects/ui/src/functions/ethprice/ethprice.ts index 3645ff7445..b765feae9b 100644 --- a/projects/ui/src/functions/ethprice/ethprice.ts +++ b/projects/ui/src/functions/ethprice/ethprice.ts @@ -3,18 +3,21 @@ import axios from 'axios'; import middy from 'middy'; import { cors, rateLimit } from '~/functions/middleware'; -/// https://docs.etherscan.io/api-endpoints/gas-tracker#get-gas-oracle -type EtherscanGasOracleResponse = { - LastBlock: string; - SafeGasPrice: string; - ProposeGasPrice: string; - FastGasPrice: string; - suggestBaseFee: string; - gasUsedRatio: string; -}; +// export type EthPriceResponse = { +// block: string; +// gas: { +// safe: string; +// propose: string; +// fast: string; +// suggestBaseFee: string; +// }; +// ethusd: string; +// ethusdTimestamp: string; +// lastRefreshed: string; +// }; -/// https://docs.etherscan.io/api-endpoints/stats-1#get-ether-last-price -type EtherscanEthPriceResponse = { +/// https://docs.arbiscan.io/api-endpoints/stats-1#get-ether-last-price +export type ArbiscanEthPriceResponse = { ethbtc: string; ethbtc_timestamp: string; ethusd: string; @@ -22,13 +25,6 @@ type EtherscanEthPriceResponse = { }; export type EthPriceResponse = { - block: string; - gas: { - safe: string; - propose: string; - fast: string; - suggestBaseFee: string; - }; ethusd: string; ethusdTimestamp: string; lastRefreshed: string; @@ -70,29 +66,15 @@ const _handler: Handler = async (event) => { if (expired) { try { - const [gasoracle, ethprice] = await Promise.all([ - axios - .get<{ result: EtherscanGasOracleResponse }>( - `https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=${process.env.ETHERSCAN_API_KEY}` - ) - .then((r) => r.data.result), - axios - .get<{ result: EtherscanEthPriceResponse }>( - `https://api.etherscan.io/api?module=stats&action=ethprice&apikey=${process.env.ETHERSCAN_API_KEY}` - ) - .then((r) => r.data.result), + const [arbEthPrice] = await Promise.all([ + axios.get<{ result: ArbiscanEthPriceResponse }>( + `https://api.arbiscan.io/api?module=stats&action=ethprice&apikey=${process.env.VITE_ARBISCAN_API_KEY}` + ), ]); lastRefreshed = new Date().getTime(); data = { - block: gasoracle.LastBlock, - gas: { - safe: gasoracle.SafeGasPrice, - propose: gasoracle.ProposeGasPrice, - fast: gasoracle.FastGasPrice, - suggestBaseFee: gasoracle.suggestBaseFee, - }, - ethusd: ethprice.ethusd, - ethusdTimestamp: ethprice.ethusd_timestamp, + ethusd: arbEthPrice.data.result.ethusd, + ethusdTimestamp: arbEthPrice.data.result.ethusd_timestamp, lastRefreshed: lastRefreshed.toString(), }; } catch (e) { diff --git a/projects/ui/src/hooks/ledger/useGasToUSD.ts b/projects/ui/src/hooks/ledger/useGasToUSD.ts index f9a9b8f7ed..236311cce4 100644 --- a/projects/ui/src/hooks/ledger/useGasToUSD.ts +++ b/projects/ui/src/hooks/ledger/useGasToUSD.ts @@ -2,6 +2,7 @@ import BigNumber from 'bignumber.js'; import { useCallback } from 'react'; import { useSelector } from 'react-redux'; import { AppState } from '~/state'; +import { useBalanceTokens } from '../beanstalk/useTokens'; const ETH_PER_GWEI = new BigNumber(10).pow(-9); @@ -17,15 +18,26 @@ const useGasToUSD = () => { const prices = useSelector( (state) => state.app.ethPrices ); + const { ETH } = useBalanceTokens(); + return useCallback( (gasLimit?: BigNumber) => { - if (!prices || !gasLimit) return null; - return gasLimit - .times(prices.gas.safe) - .times(ETH_PER_GWEI) - .times(prices.ethusd); + const baseFee = prices?.baseFeePerGas; + const gasPrice = prices?.gasPrice; + const ethUsd = prices?.ethusd; + + if (!baseFee || !gasPrice || !ethUsd || !gasLimit) return null; + + const l1Fee = baseFee.times(gasLimit); + const totalFee = l1Fee.plus(gasPrice); + const _ttlFee = new BigNumber( + ETH.fromBlockchain(totalFee.toString()).toHuman() + ); + const usd = _ttlFee.times(ethUsd.toNumber()); + + return usd; }, - [prices] + [prices?.baseFeePerGas, prices?.gasPrice, prices?.ethusd, ETH] ); }; diff --git a/projects/ui/src/state/app/actions.ts b/projects/ui/src/state/app/actions.ts index 59f010f05d..bd25425102 100644 --- a/projects/ui/src/state/app/actions.ts +++ b/projects/ui/src/state/app/actions.ts @@ -1,13 +1,12 @@ import { createAction } from '@reduxjs/toolkit'; -import type { EthPriceResponse } from '~/functions/ethprice/ethprice'; -import { Globals, Settings } from '.'; +import { EthGasPrices, Globals, Settings } from '.'; // export const setAlmanacView = createAction( // 'app/setAlmanacView' // ); -export const setEthPrices = createAction( - 'app/setEthPrices' +export const setEthPrices = createAction( + 'app/setEthGasPrices' ); type SettingsPayload = { diff --git a/projects/ui/src/state/app/index.ts b/projects/ui/src/state/app/index.ts index 5d019bde15..a94072c5d5 100644 --- a/projects/ui/src/state/app/index.ts +++ b/projects/ui/src/state/app/index.ts @@ -1,5 +1,5 @@ import { DataSource } from '@beanstalk/sdk'; -import type { EthPriceResponse } from '~/functions/ethprice/ethprice'; +import BigNumber from 'bignumber.js'; import { SGEnvironments } from '~/graph/endpoints'; export type Settings = { @@ -13,12 +13,20 @@ export type Globals = { showSettings: boolean; }; +export interface EthGasPrices { + ethusd: BigNumber; + ethUsdTimestamp: string; + lastRefreshed: string; + gasPrice: BigNumber; + baseFeePerGas: BigNumber; +} + /// Not included in `App` are "flags", which are values saved in localStorage /// See `useAppFlag` export type App = { /** ETH price data */ - ethPrices: null | EthPriceResponse; + ethPrices: null | EthGasPrices; /** User settings; persisted between page loads */ settings: Settings; /** */ diff --git a/projects/ui/src/state/app/updater.ts b/projects/ui/src/state/app/updater.ts index 925350da63..e3b114fb7a 100644 --- a/projects/ui/src/state/app/updater.ts +++ b/projects/ui/src/state/app/updater.ts @@ -7,29 +7,53 @@ import useTimedRefresh from '~/hooks/app/useTimedRefresh'; import useSetting from '~/hooks/app/useSetting'; import useSdk from '~/hooks/sdk'; import { ChainResolver } from '@beanstalk/sdk-core'; +import BigNumber from 'bignumber.js'; import { setEthPrices, updateSetting } from './actions'; export const useEthPrices = () => { const dispatch = useDispatch(); const sdk = useSdk(); + const getGas = useCallback(() => { (async () => { if (!ChainResolver.isL2Chain(sdk.chainId)) { return; } try { + console.debug('[useEthPrices/fetch] fetching...'); const query = await fetch('/.netlify/functions/ethprice'); - const ethprice = await query.json(); - dispatch(setEthPrices(ethprice)); + + const [ethprice, ethGasPrice, ethL1BaseFee] = await Promise.all([ + query.json(), + sdk.provider.getGasPrice(), + sdk.provider + .getBlock('latest') + .then((result) => result.baseFeePerGas), + ]); + + console.debug('[useEthPrices/fetch] RESULT: ', { + ethprice, + ethGasPrice, + ethL1BaseFee, + }); + + dispatch( + setEthPrices({ + ...ethprice, + ethusd: new BigNumber(ethprice?.ethusd || '0'), + gasPrice: new BigNumber(ethGasPrice?.toString() || '0'), + baseFeePerGas: new BigNumber(ethL1BaseFee?.toString() || '0'), + }) + ); } catch (e) { console.error('Failed to load: ethprice'); } })(); - }, [dispatch, sdk.chainId]); + }, [dispatch, sdk]); - /// Auto-refresh gas prices every 10s. - /// FIXME: refresh every block or N blocks instead? - useTimedRefresh(getGas, 30 * 1000); + // / Auto-refresh gas prices every 60s. + // / FIXME: refresh every block or N blocks instead? + useTimedRefresh(getGas, 60 * 1000); return [getGas, () => {}]; }; From 2e9b54ea4ddb509926cbdf884d561cc084c46c36 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:25:50 -0600 Subject: [PATCH 06/10] feat: update env schema --- projects/ui/.env.development | 3 +- projects/ui/.env.production | 3 +- .../ui/src/graph/schema-beanstalk.graphql | 59 +++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/projects/ui/.env.development b/projects/ui/.env.development index 19b2429dbd..7cbdbeb4ca 100644 --- a/projects/ui/.env.development +++ b/projects/ui/.env.development @@ -8,4 +8,5 @@ VITE_ALCHEMY_API_KEY="ds4ljBC_Pq-PaIQ3aHo04t27y2n8qpry" VITE_THEGRAPH_API_KEY="4c0b9364a121c1f2aa96fe61cb73d705" VITE_WALLETCONNECT_PROJECT_ID=2159ea7542f2b547554f8c85eca0cec1 VITE_SNAPSHOT_API_KEY="83b2ba4f5e943503dad56d4afea4a5205ace935d702cb8c0a1151c995b474f59" -VITE_ZERO_X_API_KEY="" \ No newline at end of file +VITE_ZERO_X_API_KEY="" +VITE_ARBISCAN_API_KEY=" \ No newline at end of file diff --git a/projects/ui/.env.production b/projects/ui/.env.production index 77403a8249..8a3fd9e227 100644 --- a/projects/ui/.env.production +++ b/projects/ui/.env.production @@ -6,4 +6,5 @@ VITE_ALCHEMY_API_KEY="iByabvqm_66b_Bkl9M-wJJGdCTuy19R3" VITE_THEGRAPH_API_KEY="4c0b9364a121c1f2aa96fe61cb73d705" VITE_SNAPSHOT_API_KEY="83b2ba4f5e943503dad56d4afea4a5205ace935d702cb8c0a1151c995b474f59" -VITE_ZERO_X_API_KEY="" \ No newline at end of file +VITE_ZERO_X_API_KEY="" +VITE_ARBISCAN_API_KEY="" \ No newline at end of file diff --git a/projects/ui/src/graph/schema-beanstalk.graphql b/projects/ui/src/graph/schema-beanstalk.graphql index 3781df1338..f3e017e798 100644 --- a/projects/ui/src/graph/schema-beanstalk.graphql +++ b/projects/ui/src/graph/schema-beanstalk.graphql @@ -126,6 +126,7 @@ enum Beanstalk_orderBy { field__sownBeans field__temperature field__unharvestablePods + field__unmigratedL1Pods id lastSeason seasons @@ -142,6 +143,7 @@ enum Beanstalk_orderBy { silo__plantableStalk silo__roots silo__stalk + silo__unmigratedL1DepositedBdv token } @@ -453,6 +455,7 @@ enum Farmer_orderBy { field__sownBeans field__temperature field__unharvestablePods + field__unmigratedL1Pods fills id listings @@ -471,6 +474,7 @@ enum Farmer_orderBy { silo__plantableStalk silo__roots silo__stalk + silo__unmigratedL1DepositedBdv withdraws } @@ -484,6 +488,9 @@ type Fertilizer { """Total overall suppy of fert tokens""" supply: BigInt! tokens(first: Int = 100, orderBy: FertilizerToken_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: FertilizerToken_filter): [FertilizerToken!]! + + """Supply from L1 which has not been minted on L2 yet""" + unmigratedL1Supply: BigInt } type FertilizerBalance { @@ -682,6 +689,7 @@ enum FertilizerToken_orderBy { fertilizer__beanstalk fertilizer__id fertilizer__supply + fertilizer__unmigratedL1Supply humidity id season @@ -849,6 +857,14 @@ input Fertilizer_filter { supply_not: BigInt supply_not_in: [BigInt!] tokens_: FertilizerToken_filter + unmigratedL1Supply: BigInt + unmigratedL1Supply_gt: BigInt + unmigratedL1Supply_gte: BigInt + unmigratedL1Supply_in: [BigInt!] + unmigratedL1Supply_lt: BigInt + unmigratedL1Supply_lte: BigInt + unmigratedL1Supply_not: BigInt + unmigratedL1Supply_not_in: [BigInt!] } enum Fertilizer_orderBy { @@ -856,6 +872,7 @@ enum Fertilizer_orderBy { id supply tokens + unmigratedL1Supply } type Field { @@ -921,6 +938,9 @@ type Field { """Current outstanding non-harvestable pods""" unharvestablePods: BigInt! + + """Pods from L1 which has not been minted on L2 yet""" + unmigratedL1Pods: BigInt } type FieldDailySnapshot { @@ -1292,6 +1312,7 @@ enum FieldDailySnapshot_orderBy { field__sownBeans field__temperature field__unharvestablePods + field__unmigratedL1Pods harvestableIndex harvestablePods harvestedPods @@ -1721,6 +1742,7 @@ enum FieldHourlySnapshot_orderBy { field__sownBeans field__temperature field__unharvestablePods + field__unmigratedL1Pods harvestableIndex harvestablePods harvestedPods @@ -1926,6 +1948,14 @@ input Field_filter { unharvestablePods_lte: BigInt unharvestablePods_not: BigInt unharvestablePods_not_in: [BigInt!] + unmigratedL1Pods: BigInt + unmigratedL1Pods_gt: BigInt + unmigratedL1Pods_gte: BigInt + unmigratedL1Pods_in: [BigInt!] + unmigratedL1Pods_lt: BigInt + unmigratedL1Pods_lte: BigInt + unmigratedL1Pods_not: BigInt + unmigratedL1Pods_not_in: [BigInt!] } enum Field_orderBy { @@ -1955,6 +1985,7 @@ enum Field_orderBy { sownBeans temperature unharvestablePods + unmigratedL1Pods } type Germinating { @@ -2435,6 +2466,7 @@ enum Plot_orderBy { field__sownBeans field__temperature field__unharvestablePods + field__unmigratedL1Pods fullyHarvested harvestablePods harvestedPods @@ -6823,6 +6855,9 @@ type Season { """Block in which the season start was triggered by the sunrise call""" sunriseBlock: BigInt! + + """Beans from L1 which have not migrated yet""" + unmigratedL1Beans: BigInt } input Season_filter { @@ -6939,6 +6974,14 @@ input Season_filter { sunriseBlock_lte: BigInt sunriseBlock_not: BigInt sunriseBlock_not_in: [BigInt!] + unmigratedL1Beans: BigInt + unmigratedL1Beans_gt: BigInt + unmigratedL1Beans_gte: BigInt + unmigratedL1Beans_in: [BigInt!] + unmigratedL1Beans_lt: BigInt + unmigratedL1Beans_lte: BigInt + unmigratedL1Beans_not: BigInt + unmigratedL1Beans_not_in: [BigInt!] } enum Season_orderBy { @@ -6958,6 +7001,7 @@ enum Season_orderBy { rewardBeans season sunriseBlock + unmigratedL1Beans } type Silo { @@ -7015,6 +7059,9 @@ type Silo { """Current stalk balance""" stalk: BigInt! + """Deposited BDV from L1 which has not migrated yet""" + unmigratedL1DepositedBdv: BigInt + """Tokens whitelisted for deposit within the silo""" whitelistedTokens: [Bytes!]! } @@ -7534,6 +7581,7 @@ enum SiloAsset_orderBy { silo__plantableStalk silo__roots silo__stalk + silo__unmigratedL1DepositedBdv token withdrawnAmount } @@ -7821,6 +7869,7 @@ enum SiloDailySnapshot_orderBy { silo__plantableStalk silo__roots silo__stalk + silo__unmigratedL1DepositedBdv stalk updatedAt } @@ -8332,6 +8381,7 @@ enum SiloHourlySnapshot_orderBy { silo__plantableStalk silo__roots silo__stalk + silo__unmigratedL1DepositedBdv stalk updatedAt } @@ -8717,6 +8767,14 @@ input Silo_filter { stalk_lte: BigInt stalk_not: BigInt stalk_not_in: [BigInt!] + unmigratedL1DepositedBdv: BigInt + unmigratedL1DepositedBdv_gt: BigInt + unmigratedL1DepositedBdv_gte: BigInt + unmigratedL1DepositedBdv_in: [BigInt!] + unmigratedL1DepositedBdv_lt: BigInt + unmigratedL1DepositedBdv_lte: BigInt + unmigratedL1DepositedBdv_not: BigInt + unmigratedL1DepositedBdv_not_in: [BigInt!] whitelistedTokens: [Bytes!] whitelistedTokens_contains: [Bytes!] whitelistedTokens_contains_nocase: [Bytes!] @@ -8749,6 +8807,7 @@ enum Silo_orderBy { plantableStalk roots stalk + unmigratedL1DepositedBdv whitelistedTokens } From 14df70ba6394c28af643531fd14c24bdf6c04ca1 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:28:48 -0600 Subject: [PATCH 07/10] feat: update schema + add comments to getGasToUsd() --- projects/ui/src/graph/graphql.schema.json | 586 ++++++++++++++++++++ projects/ui/src/hooks/ledger/useGasToUSD.ts | 6 +- 2 files changed, 588 insertions(+), 4 deletions(-) diff --git a/projects/ui/src/graph/graphql.schema.json b/projects/ui/src/graph/graphql.schema.json index 19912affc7..6612328c3d 100644 --- a/projects/ui/src/graph/graphql.schema.json +++ b/projects/ui/src/graph/graphql.schema.json @@ -13850,6 +13850,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "field__unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "id", "description": null, @@ -13946,6 +13952,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "silo__unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "token", "description": null, @@ -19407,6 +19419,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "field__unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "fills", "description": null, @@ -19515,6 +19533,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "silo__unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "withdraws", "description": null, @@ -19662,6 +19686,18 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Supply", + "description": "Supply from L1 which has not been minted on L2 yet", + "args": [], + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -21901,6 +21937,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "fertilizer__unmigratedL1Supply", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "humidity", "description": null, @@ -23738,6 +23780,118 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Supply", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Supply_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -23776,6 +23930,12 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Supply", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -24255,6 +24415,18 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Pods", + "description": "Pods from L1 which has not been minted on L2 yet", + "args": [], + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -28649,6 +28821,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "field__unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "harvestableIndex", "description": null, @@ -33603,6 +33781,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "field__unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "harvestableIndex", "description": null, @@ -36260,6 +36444,118 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Pods", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Pods_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -36430,6 +36726,12 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -42818,6 +43120,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "field__unmigratedL1Pods", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "fullyHarvested", "description": null, @@ -100506,6 +100814,18 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Beans", + "description": "Beans from L1 which have not migrated yet", + "args": [], + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -102063,6 +102383,118 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Beans", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1Beans_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -102173,6 +102605,12 @@ "description": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "unmigratedL1Beans", + "description": null, + "isDeprecated": false, + "deprecationReason": null } ], "possibleTypes": null @@ -103454,6 +103892,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "unmigratedL1DepositedBdv", + "description": "Deposited BDV from L1 which has not migrated yet", + "args": [], + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "whitelistedTokens", "description": "Tokens whitelisted for deposit within the silo", @@ -109257,6 +109707,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "silo__unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "token", "description": null, @@ -112509,6 +112965,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "silo__unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "stalk", "description": null, @@ -118185,6 +118647,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "silo__unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "stalk", "description": null, @@ -122824,6 +123292,118 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "unmigratedL1DepositedBdv", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_gt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_gte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_lt", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_lte", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_not", + "description": null, + "type": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "unmigratedL1DepositedBdv_not_in", + "description": null, + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigInt", + "ofType": null + } + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "whitelistedTokens", "description": null, @@ -123096,6 +123676,12 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "unmigratedL1DepositedBdv", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "whitelistedTokens", "description": null, diff --git a/projects/ui/src/hooks/ledger/useGasToUSD.ts b/projects/ui/src/hooks/ledger/useGasToUSD.ts index 236311cce4..4d6705cf45 100644 --- a/projects/ui/src/hooks/ledger/useGasToUSD.ts +++ b/projects/ui/src/hooks/ledger/useGasToUSD.ts @@ -4,14 +4,12 @@ import { useSelector } from 'react-redux'; import { AppState } from '~/state'; import { useBalanceTokens } from '../beanstalk/useTokens'; -const ETH_PER_GWEI = new BigNumber(10).pow(-9); - /** * Convert a gas limit from estimateGas into a USD gas price. * * Gas units (limit) beanstalk.estimateGas.someFunction() returns gas limit (gwei) - * (Base Fee + Tip (gwei)) prices.gas.safe (in gwei) - * (1 ETH / 10^9 gwei) constant + * (Base Fee) prices.baseFeePerGas (in wei) + * (gasPrice) prices.gasPrice (in wei) * (X USD / 1 ETH) prices.ethusd */ const useGasToUSD = () => { From 39fbd8ba6ddbefb9766bc427ffa5bb269c1de455 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:45:35 -0600 Subject: [PATCH 08/10] feat: update gql client --- projects/ui/src/graph/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/graph/client.ts b/projects/ui/src/graph/client.ts index 158e39a12d..81fca56ffa 100644 --- a/projects/ui/src/graph/client.ts +++ b/projects/ui/src/graph/client.ts @@ -224,7 +224,7 @@ export const apolloClient = new ApolloClient({ snapshotLabsLink, // true ApolloLink.split( // BS3TODO: Do we need to keep beaNFT support? - ({ getContext }) => getContext().subgraph === 'beanft', + ({ getContext }) => getContext().subgraph === 'beanft_eth', beanftLink, // true ApolloLink.split( ({ getContext }) => getContext().subgraph === 'bean', From a2daeb65169252079079bb58590c21f1408a6a50 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:52:15 -0600 Subject: [PATCH 09/10] feat: update beanft subgraphurl --- projects/ui/codegen-individual.yml | 2 +- projects/ui/src/graph/endpoints.ts | 2 +- projects/ui/src/graph/graphql.schema.json | 34 ++++++++++++++----- .../src/state/farmer/delegations/updater.ts | 26 +++++++------- projects/ui/src/util/BeaNFTs.ts | 2 +- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/projects/ui/codegen-individual.yml b/projects/ui/codegen-individual.yml index 7f5e6d42e0..173be43c4d 100644 --- a/projects/ui/codegen-individual.yml +++ b/projects/ui/codegen-individual.yml @@ -21,7 +21,7 @@ generates: # BSTODO: Do we need beanft subgraph? ./src/graph/schema-beanft.graphql: schema: - - https://graph.node.bean.money/subgraphs/name/beanft + - https://graph.bean.money/beanft_eth plugins: - 'schema-ast' #./src/graph/schema-snapshot2.graphql: diff --git a/projects/ui/src/graph/endpoints.ts b/projects/ui/src/graph/endpoints.ts index 75fbc3a0d1..00f1a75ea1 100644 --- a/projects/ui/src/graph/endpoints.ts +++ b/projects/ui/src/graph/endpoints.ts @@ -18,7 +18,7 @@ type SGEnvironment = { const BASE_SUBGRAPH_URL = 'https://graph.bean.money'; const BEANFT_SUBGRAPH_URL = - 'https://graph.node.bean.money/subgraphs/name/beanft'; + 'https://graph.node.bean.money/subgraphs/name/beanft_eth'; export const SUBGRAPH_ENVIRONMENTS: Record = { [SGEnvironments.BF_PROD]: { diff --git a/projects/ui/src/graph/graphql.schema.json b/projects/ui/src/graph/graphql.schema.json index 6612328c3d..e1d2acde4d 100644 --- a/projects/ui/src/graph/graphql.schema.json +++ b/projects/ui/src/graph/graphql.schema.json @@ -161524,7 +161524,9 @@ "name": "derivedFrom", "description": "creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API.", "isRepeatable": false, - "locations": ["FIELD_DEFINITION"], + "locations": [ + "FIELD_DEFINITION" + ], "args": [ { "name": "field", @@ -161548,14 +161550,20 @@ "name": "entity", "description": "Marks the GraphQL type as indexable entity. Each type that should be an entity is required to be annotated with this directive.", "isRepeatable": false, - "locations": ["OBJECT"], + "locations": [ + "OBJECT" + ], "args": [] }, { "name": "include", "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", "isRepeatable": false, - "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], "args": [ { "name": "if", @@ -161579,14 +161587,20 @@ "name": "oneOf", "description": "Indicates exactly one field must be supplied and this field must not be `null`.", "isRepeatable": false, - "locations": ["INPUT_OBJECT"], + "locations": [ + "INPUT_OBJECT" + ], "args": [] }, { "name": "skip", "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", "isRepeatable": false, - "locations": ["FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"], + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], "args": [ { "name": "if", @@ -161610,7 +161624,9 @@ "name": "specifiedBy", "description": "Exposes a URL that specifies the behavior of this scalar.", "isRepeatable": false, - "locations": ["SCALAR"], + "locations": [ + "SCALAR" + ], "args": [ { "name": "url", @@ -161634,7 +161650,9 @@ "name": "subgraphId", "description": "Defined a Subgraph ID for an object type", "isRepeatable": false, - "locations": ["OBJECT"], + "locations": [ + "OBJECT" + ], "args": [ { "name": "id", @@ -161656,4 +161674,4 @@ } ] } -} +} \ No newline at end of file diff --git a/projects/ui/src/state/farmer/delegations/updater.ts b/projects/ui/src/state/farmer/delegations/updater.ts index e73a039eeb..ff0e0f64dd 100644 --- a/projects/ui/src/state/farmer/delegations/updater.ts +++ b/projects/ui/src/state/farmer/delegations/updater.ts @@ -3,24 +3,24 @@ import { useDispatch } from 'react-redux'; import { DateTime } from 'luxon'; import BigNumber from 'bignumber.js'; import { GovSpace, SNAPSHOT_SPACES } from '~/lib/Beanstalk/Governance'; -import { - useBeaNftUsersLazyQuery, - useDelegatorsStalkLazyQuery, - useVoterDelegatesLazyQuery, - useVoterDelegatorsLazyQuery, -} from '~/generated/graphql'; import useAccount from '~/hooks/ledger/useAccount'; -import { FarmerDelegation, GovSpaceAddressMap } from '.'; -import { - setDelegatorsVotingPower, - setFarmerDelegates, - setFarmerDelegators, -} from './actions'; import { useDelegatesRegistryContract } from '~/hooks/ledger/useContract'; import { GOV_SPACE_BY_ID, tokenResult } from '~/util'; import { STALK } from '~/constants/tokens'; import { useAppSelector } from '~/state'; import { AddressMap, ZERO_ADDRESS } from '~/constants'; +import { + setDelegatorsVotingPower, + setFarmerDelegates, + setFarmerDelegators, +} from './actions'; +import { FarmerDelegation, GovSpaceAddressMap } from '.'; +import { + useBeaNftUsersLazyQuery, + useDelegatorsStalkLazyQuery, + useVoterDelegatesLazyQuery, + useVoterDelegatorsLazyQuery, +} from '~/generated/graphql'; import { getDefaultGovSpaceMap } from './reducer'; export function useReadDelegatesDev() { @@ -212,7 +212,7 @@ export function useFetchNFTVotingPower() { const [triggerQuery] = useBeaNftUsersLazyQuery({ variables: { id_in: delegators }, fetchPolicy: 'cache-and-network', - context: { subgraph: 'beanft' }, + context: { subgraph: 'beanf_eth' }, }); /// handlers diff --git a/projects/ui/src/util/BeaNFTs.ts b/projects/ui/src/util/BeaNFTs.ts index 9a97a1aaf2..f2615ac2cf 100644 --- a/projects/ui/src/util/BeaNFTs.ts +++ b/projects/ui/src/util/BeaNFTs.ts @@ -53,7 +53,7 @@ export async function loadNFTs(account: string) { try { const ownedNFTs = await fetch( - 'https://graph.node.bean.money/subgraphs/name/beanft', + 'https://graph.node.bean.money/subgraphs/name/beanft_eth', { method: 'POST', headers: { From 07d8bc8f40c1adab2dedce306877b42afbfcf503 Mon Sep 17 00:00:00 2001 From: Spacebean Date: Fri, 11 Oct 2024 15:59:51 -0600 Subject: [PATCH 10/10] feat: remove arbiscan eth price api --- projects/ui/.env.development | 3 +- projects/ui/.env.production | 3 +- projects/ui/src/components/Common/GasTag.tsx | 19 +--- projects/ui/src/env.d.ts | 5 - .../ui/src/functions/ethprice/ethprice.ts | 99 ------------------- projects/ui/src/hooks/ledger/useGasToUSD.ts | 10 +- projects/ui/src/state/app/actions.ts | 4 +- projects/ui/src/state/app/index.ts | 3 - projects/ui/src/state/app/reducer.ts | 4 +- projects/ui/src/state/app/updater.ts | 11 +-- 10 files changed, 18 insertions(+), 143 deletions(-) delete mode 100644 projects/ui/src/functions/ethprice/ethprice.ts diff --git a/projects/ui/.env.development b/projects/ui/.env.development index 7cbdbeb4ca..19b2429dbd 100644 --- a/projects/ui/.env.development +++ b/projects/ui/.env.development @@ -8,5 +8,4 @@ VITE_ALCHEMY_API_KEY="ds4ljBC_Pq-PaIQ3aHo04t27y2n8qpry" VITE_THEGRAPH_API_KEY="4c0b9364a121c1f2aa96fe61cb73d705" VITE_WALLETCONNECT_PROJECT_ID=2159ea7542f2b547554f8c85eca0cec1 VITE_SNAPSHOT_API_KEY="83b2ba4f5e943503dad56d4afea4a5205ace935d702cb8c0a1151c995b474f59" -VITE_ZERO_X_API_KEY="" -VITE_ARBISCAN_API_KEY=" \ No newline at end of file +VITE_ZERO_X_API_KEY="" \ No newline at end of file diff --git a/projects/ui/.env.production b/projects/ui/.env.production index 8a3fd9e227..77403a8249 100644 --- a/projects/ui/.env.production +++ b/projects/ui/.env.production @@ -6,5 +6,4 @@ VITE_ALCHEMY_API_KEY="iByabvqm_66b_Bkl9M-wJJGdCTuy19R3" VITE_THEGRAPH_API_KEY="4c0b9364a121c1f2aa96fe61cb73d705" VITE_SNAPSHOT_API_KEY="83b2ba4f5e943503dad56d4afea4a5205ace935d702cb8c0a1151c995b474f59" -VITE_ZERO_X_API_KEY="" -VITE_ARBISCAN_API_KEY="" \ No newline at end of file +VITE_ZERO_X_API_KEY="" \ No newline at end of file diff --git a/projects/ui/src/components/Common/GasTag.tsx b/projects/ui/src/components/Common/GasTag.tsx index e76acc9b2f..4f2a4a8579 100644 --- a/projects/ui/src/components/Common/GasTag.tsx +++ b/projects/ui/src/components/Common/GasTag.tsx @@ -1,10 +1,9 @@ import React from 'react'; import BigNumber from 'bignumber.js'; -import { Box, Divider, Tooltip, Typography } from '@mui/material'; +import { Box, Tooltip } from '@mui/material'; import { useSelector } from 'react-redux'; -import { DateTime } from 'luxon'; import useGasToUSD from '~/hooks/ledger/useGasToUSD'; -import { AppState } from '~/state'; +import { AppState, useAppSelector } from '~/state'; import { displayFullBN, displayUSD } from '~/util'; import { FC } from '~/types'; @@ -20,6 +19,7 @@ const GasTag: FC<{ const prices = useSelector( (state) => state.app.ethPrices ); + const ethPrice = useAppSelector((state) => state._beanstalk.tokenPrices.eth); const getGasUSD = useGasToUSD(); const gasUSD = gasLimit ? getGasUSD(gasLimit) : null; @@ -39,19 +39,8 @@ const GasTag: FC<{ : '?'} - {prices?.ethusd ? `$${prices.ethusd}` : '?'} + {ethPrice ? `$${ethPrice.toFormat(2, BigNumber.ROUND_DOWN)}` : '?'} - {prices?.lastRefreshed && ( - <> - - - Refreshed at{' '} - {DateTime.fromMillis( - parseInt(prices.lastRefreshed, 10) - ).toLocaleString(DateTime.TIME_24_WITH_SHORT_OFFSET)} - - - )} } > diff --git a/projects/ui/src/env.d.ts b/projects/ui/src/env.d.ts index 429118150e..da3005c7ec 100644 --- a/projects/ui/src/env.d.ts +++ b/projects/ui/src/env.d.ts @@ -26,11 +26,6 @@ interface ImportMetaEnv { * API key for used for ZeroX Swap API */ readonly VITE_ZERO_X_API_KEY: string; - - /** - * - */ - readonly VITE_ARBISCAN_API_KEY: string; } interface ImportMeta { diff --git a/projects/ui/src/functions/ethprice/ethprice.ts b/projects/ui/src/functions/ethprice/ethprice.ts deleted file mode 100644 index b765feae9b..0000000000 --- a/projects/ui/src/functions/ethprice/ethprice.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Handler } from '@netlify/functions'; -import axios from 'axios'; -import middy from 'middy'; -import { cors, rateLimit } from '~/functions/middleware'; - -// export type EthPriceResponse = { -// block: string; -// gas: { -// safe: string; -// propose: string; -// fast: string; -// suggestBaseFee: string; -// }; -// ethusd: string; -// ethusdTimestamp: string; -// lastRefreshed: string; -// }; - -/// https://docs.arbiscan.io/api-endpoints/stats-1#get-ether-last-price -export type ArbiscanEthPriceResponse = { - ethbtc: string; - ethbtc_timestamp: string; - ethusd: string; - ethusd_timestamp: string; -}; - -export type EthPriceResponse = { - ethusd: string; - ethusdTimestamp: string; - lastRefreshed: string; -}; - -let data: null | EthPriceResponse = null; -let lastRefreshed = new Date().getTime(); - -/// Allow a refresh every 10s (~1 block) -const REFRESH_MS = 10 * 1000; - -/// If we fail to get new data for this length of time, -/// clear the existing cache to prevent stale price data. -const FORCE_EXPIRY_MS = 120 * 1000; - -const CORS_HEADERS = { - 'Access-Control-Allow-Origin': - process.env.NODE_ENV === 'production' ? 'https://*.bean.money ' : '*', - 'Access-Control-Allow-Headers': - 'Origin, X-Requested-With, Content-Type, Accept', -}; - -/** - * Lookup ETH gas prices and the USD price of ETH via Etherscan's API. - * Cache this value in the active serverless function's memory to reduce - * repeated requests to Etherscan. Apply refresh logic to in-memory cache - * to ensure data doesn't become stale. - */ -const _handler: Handler = async (event) => { - if (event.httpMethod === 'OPTIONS') { - return { - statusCode: 200, - headers: CORS_HEADERS, - }; - } - - const now = new Date().getTime(); - const expired = !data || now - lastRefreshed > REFRESH_MS; - - if (expired) { - try { - const [arbEthPrice] = await Promise.all([ - axios.get<{ result: ArbiscanEthPriceResponse }>( - `https://api.arbiscan.io/api?module=stats&action=ethprice&apikey=${process.env.VITE_ARBISCAN_API_KEY}` - ), - ]); - lastRefreshed = new Date().getTime(); - data = { - ethusd: arbEthPrice.data.result.ethusd, - ethusdTimestamp: arbEthPrice.data.result.ethusd_timestamp, - lastRefreshed: lastRefreshed.toString(), - }; - } catch (e) { - console.error(e); - if (now - lastRefreshed > FORCE_EXPIRY_MS) { - data = null; - } - } - } - - return { - statusCode: 200, - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(data), - }; -}; - -export const handler = middy(_handler) - .use(cors({ origin: '*.bean.money' })) - .use(rateLimit()); diff --git a/projects/ui/src/hooks/ledger/useGasToUSD.ts b/projects/ui/src/hooks/ledger/useGasToUSD.ts index 4d6705cf45..2af1a511b2 100644 --- a/projects/ui/src/hooks/ledger/useGasToUSD.ts +++ b/projects/ui/src/hooks/ledger/useGasToUSD.ts @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js'; import { useCallback } from 'react'; import { useSelector } from 'react-redux'; -import { AppState } from '~/state'; +import { AppState, useAppSelector } from '~/state'; import { useBalanceTokens } from '../beanstalk/useTokens'; /** @@ -17,25 +17,25 @@ const useGasToUSD = () => { (state) => state.app.ethPrices ); const { ETH } = useBalanceTokens(); + const ethPrice = useAppSelector((s) => s._beanstalk.tokenPrices.eth); return useCallback( (gasLimit?: BigNumber) => { const baseFee = prices?.baseFeePerGas; const gasPrice = prices?.gasPrice; - const ethUsd = prices?.ethusd; - if (!baseFee || !gasPrice || !ethUsd || !gasLimit) return null; + if (!baseFee || !gasPrice || !gasLimit || !ethPrice) return null; const l1Fee = baseFee.times(gasLimit); const totalFee = l1Fee.plus(gasPrice); const _ttlFee = new BigNumber( ETH.fromBlockchain(totalFee.toString()).toHuman() ); - const usd = _ttlFee.times(ethUsd.toNumber()); + const usd = _ttlFee.times(ethPrice); return usd; }, - [prices?.baseFeePerGas, prices?.gasPrice, prices?.ethusd, ETH] + [prices?.baseFeePerGas, prices?.gasPrice, ETH, ethPrice] ); }; diff --git a/projects/ui/src/state/app/actions.ts b/projects/ui/src/state/app/actions.ts index bd25425102..a7287bd94a 100644 --- a/projects/ui/src/state/app/actions.ts +++ b/projects/ui/src/state/app/actions.ts @@ -5,8 +5,8 @@ import { EthGasPrices, Globals, Settings } from '.'; // 'app/setAlmanacView' // ); -export const setEthPrices = createAction( - 'app/setEthGasPrices' +export const setGasPrices = createAction( + 'app/setGasPrices' ); type SettingsPayload = { diff --git a/projects/ui/src/state/app/index.ts b/projects/ui/src/state/app/index.ts index a94072c5d5..78d92fdf3e 100644 --- a/projects/ui/src/state/app/index.ts +++ b/projects/ui/src/state/app/index.ts @@ -14,9 +14,6 @@ export type Globals = { }; export interface EthGasPrices { - ethusd: BigNumber; - ethUsdTimestamp: string; - lastRefreshed: string; gasPrice: BigNumber; baseFeePerGas: BigNumber; } diff --git a/projects/ui/src/state/app/reducer.ts b/projects/ui/src/state/app/reducer.ts index e35b1af0a9..0d70b866f7 100644 --- a/projects/ui/src/state/app/reducer.ts +++ b/projects/ui/src/state/app/reducer.ts @@ -3,7 +3,7 @@ import { DataSource } from '@beanstalk/sdk'; import { SGEnvironments } from '~/graph/endpoints'; import { persistedState } from '~/state/persist'; import { App } from '.'; -import { setEthPrices, setGlobal, updateSetting } from './actions'; +import { setGasPrices, setGlobal, updateSetting } from './actions'; export const initialState: App = { ethPrices: null, @@ -21,7 +21,7 @@ export const initialState: App = { export default createReducer(initialState, (builder) => builder - .addCase(setEthPrices, (state, { payload }) => { + .addCase(setGasPrices, (state, { payload }) => { state.ethPrices = payload; }) .addCase(updateSetting, (state, { payload }) => { diff --git a/projects/ui/src/state/app/updater.ts b/projects/ui/src/state/app/updater.ts index e3b114fb7a..a2d93e9015 100644 --- a/projects/ui/src/state/app/updater.ts +++ b/projects/ui/src/state/app/updater.ts @@ -8,7 +8,7 @@ import useSetting from '~/hooks/app/useSetting'; import useSdk from '~/hooks/sdk'; import { ChainResolver } from '@beanstalk/sdk-core'; import BigNumber from 'bignumber.js'; -import { setEthPrices, updateSetting } from './actions'; +import { setGasPrices, updateSetting } from './actions'; export const useEthPrices = () => { const dispatch = useDispatch(); @@ -21,10 +21,8 @@ export const useEthPrices = () => { } try { console.debug('[useEthPrices/fetch] fetching...'); - const query = await fetch('/.netlify/functions/ethprice'); - const [ethprice, ethGasPrice, ethL1BaseFee] = await Promise.all([ - query.json(), + const [ethGasPrice, ethL1BaseFee] = await Promise.all([ sdk.provider.getGasPrice(), sdk.provider .getBlock('latest') @@ -32,15 +30,12 @@ export const useEthPrices = () => { ]); console.debug('[useEthPrices/fetch] RESULT: ', { - ethprice, ethGasPrice, ethL1BaseFee, }); dispatch( - setEthPrices({ - ...ethprice, - ethusd: new BigNumber(ethprice?.ethusd || '0'), + setGasPrices({ gasPrice: new BigNumber(ethGasPrice?.toString() || '0'), baseFeePerGas: new BigNumber(ethL1BaseFee?.toString() || '0'), })