From 8921ee7fd94afdcbffb50b47628192c63c3dae18 Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Fri, 3 Jan 2025 17:44:03 +0100 Subject: [PATCH 1/9] init commit --- .../queries/useFetchSimulateDeposit.ts | 8 +- .../meta-data-queries/useFullTokenData.ts | 25 ++---- .../UserRewardsByStrategy.fetch.ts | 5 +- .../UserStrategyProfit.fetch.ts | 5 +- .../statev3/metadata/FullStrategyData.all.ts | 13 ++- src/app/statev3/metadata/TokenData.fetch.ts | 66 --------------- src/app/statev3/queries/AssetBalance.hook.ts | 5 +- .../statev3/queries/AssetTotalSupply.hook.ts | 5 +- .../queries/AvailableStrategyCap.hook.ts | 5 +- src/app/statev3/queries/Collateral.fetch.ts | 5 +- src/app/statev3/queries/Equity.hook.ts | 10 +-- .../statev3/queries/MetadataLoader.hook.ts | 6 +- src/app/statev3/queries/StrategyCap.hook.ts | 4 +- src/app/statev3/settings/config.tsx | 39 --------- .../forms/deposit-form/FormButtons.tsx | 13 ++- .../deposit-form/RHFDepositAmountField.tsx | 5 +- .../deposit-form/RHFReceiveAmountField.tsx | 4 +- .../withdraw-form/RHFReceiveAmountField.tsx | 5 +- .../RHFWithdrawStrategyAmountField.tsx | 5 +- .../current-holdings/CurrentHoldings.tsx | 13 ++- .../components/graph/GraphComponent.tsx | 7 +- .../strategy-picker/StrategyPickerButton.tsx | 6 +- .../tabs/dashboard/table/TableDesktopRow.tsx | 2 +- .../tabs/dashboard/table/TableMobileRow.tsx | 2 +- .../tabs/ilms/table/ILMDesktopTableRow.tsx | 7 +- .../tabs/ilms/table/ILMMobileTableRow.tsx | 2 +- src/meta/TokenDataDict.ts | 82 ------------------- src/meta/icons.ts | 47 +++++++++++ src/meta/index.ts | 2 +- .../components/form/rhf/RHFAmountInput.tsx | 4 +- .../components/form/rhf/RHFAmountInputV3.tsx | 4 +- .../WatchAssetComponentv2.tsx | 4 +- .../fetchTokenLogoFromCoinGecko.ts | 27 ++++++ .../fetchTrustWalletLogoUrl.ts | 24 ++++++ .../state/meta-data-queries/useToken.ts | 67 +++++++++++---- 35 files changed, 235 insertions(+), 298 deletions(-) delete mode 100644 src/app/statev3/metadata/TokenData.fetch.ts delete mode 100644 src/meta/TokenDataDict.ts create mode 100644 src/meta/icons.ts create mode 100644 src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts create mode 100644 src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts diff --git a/src/app/state/loop-strategy/queries/useFetchSimulateDeposit.ts b/src/app/state/loop-strategy/queries/useFetchSimulateDeposit.ts index a5db53aa..fd19c699 100644 --- a/src/app/state/loop-strategy/queries/useFetchSimulateDeposit.ts +++ b/src/app/state/loop-strategy/queries/useFetchSimulateDeposit.ts @@ -30,10 +30,10 @@ export const useFetchSimulateDeposit = (account: Address, amount: string, subStr enabled ? rest : { - ...rest, - // todo: solve this differently, review displayvalue component, and render loading state in different way. - isFetched: true, - }, + ...rest, + // todo: solve this differently, review displayvalue component, and render loading state in different way. + isFetched: true, + }, ]), data: { bigIntValue: data?.sharesToReceive, diff --git a/src/app/statev3/common/meta-data-queries/useFullTokenData.ts b/src/app/statev3/common/meta-data-queries/useFullTokenData.ts index f56992de..a37c76e6 100644 --- a/src/app/statev3/common/meta-data-queries/useFullTokenData.ts +++ b/src/app/statev3/common/meta-data-queries/useFullTokenData.ts @@ -6,6 +6,7 @@ import { useReadContract } from "wagmi"; import { strategyConfig } from "../../settings/config"; import { AssetBaseConfig } from "../../settings/configTypes"; import { assetsConfig } from "../../settings/landingMarketConfig"; +import { useToken } from "@shared"; export interface FullAssetData extends Omit { decimals?: number; @@ -13,23 +14,9 @@ export interface FullAssetData extends Omit { // todo rename hook export const useFullTokenData = (asset?: Address | undefined): FetchData => { - const config = asset - ? assetsConfig[asset] || strategyConfig[asset] - : undefined; + const config = asset ? assetsConfig[asset] || strategyConfig[asset] : undefined; - const { data: decimals, ...decimalRest } = useReadContract({ - address: asset, - abi: erc20Abi, - functionName: "decimals", - query: { ...metadataQueryConfig, enabled: !!asset }, - }); - - const { data: symbol, ...symbolRest } = useReadContract({ - address: asset, - abi: erc20Abi, - functionName: "symbol", - query: { ...metadataQueryConfig, enabled: !!asset }, - }); + const { data, ...dataRest } = useToken(asset); const { data: name, ...nameRest } = useReadContract({ address: asset, @@ -39,12 +26,12 @@ export const useFullTokenData = (asset?: Address | undefined): FetchData { const [{ decimals, symbol }, tokenPrice] = await Promise.all([ - fetchTokenData(address), + fetchToken(address), fetchAssetPriceInBlock(address), ]); diff --git a/src/app/statev3/hooks/user-strategy-profit/UserStrategyProfit.fetch.ts b/src/app/statev3/hooks/user-strategy-profit/UserStrategyProfit.fetch.ts index 904ff0f7..e3bcc86c 100644 --- a/src/app/statev3/hooks/user-strategy-profit/UserStrategyProfit.fetch.ts +++ b/src/app/statev3/hooks/user-strategy-profit/UserStrategyProfit.fetch.ts @@ -2,8 +2,7 @@ import { Address, parseAbiItem } from "viem"; import { getPublicClient } from "wagmi/actions"; import { getExtensiveOperationsConfig } from "../../../utils/queryContractUtils"; import { TransfersWithStrategyPrice, cUserStrategyProfit } from "./UserStrategyProfit.math"; -import { fetchTokenData } from "../../metadata/TokenData.fetch"; -import { FetchBigIntStrict, formatFetchBigInt, formatUsdValue } from "../../../../shared"; +import { FetchBigIntStrict, fetchToken, formatFetchBigInt, formatUsdValue } from "../../../../shared"; import { fetchAssetPriceInBlock } from "../../queries/AssetPrice.hook"; import { getQueryClient } from "../../../contexts/CustomQueryClientProvider"; import { heavyDataQueryConfig } from "../../settings/queryConfig"; @@ -142,7 +141,7 @@ export async function fetchUserStrategyProfit( const [logs, { decimals: strategyDecimals, symbol: strategySymbol }] = await Promise.all([ getStrategyEventLogsForUser({ strategy, user }), - fetchTokenData(strategy), + fetchToken(strategy), ]); const [transferWithStrategyPrice, currStrategyPrice] = await Promise.all([ diff --git a/src/app/statev3/metadata/FullStrategyData.all.ts b/src/app/statev3/metadata/FullStrategyData.all.ts index d505fd4a..f62359f2 100644 --- a/src/app/statev3/metadata/FullStrategyData.all.ts +++ b/src/app/statev3/metadata/FullStrategyData.all.ts @@ -1,11 +1,11 @@ import { Address } from "viem"; -import { fetchTokenData } from "./TokenData.fetch"; import { fetchStrategyAssets } from "./StrategyAssets.fetch"; import { useQuery } from "@tanstack/react-query"; import { disableCacheQueryConfig } from "../settings/queryConfig"; -import { addressIconMap, strategyConfig } from "../settings/config"; +import { strategyConfig } from "../settings/config"; import { TagType } from "../common/types/StateTypes"; -import { Displayable } from "../../../shared"; +import { Displayable, fetchToken } from "@shared"; +import { addressIconMap } from "@meta"; export interface FullStrategyData { underlying?: Address; @@ -16,14 +16,14 @@ export interface FullStrategyData { address?: Address; diagram?: string; - icon: string; + logo?: string; symbol?: string; decimals?: number; name: string; } export async function fetchFullStrategyData(strategy: Address): Promise { - const [tokenData, assets] = await Promise.all([fetchTokenData(strategy), fetchStrategyAssets(strategy)]); + const [tokenData, assets] = await Promise.all([fetchToken(strategy), fetchStrategyAssets(strategy)]); const config = strategy ? strategyConfig[strategy] : undefined; if (!config) throw new Error(`No config found for ${strategy}`); @@ -31,7 +31,6 @@ export async function fetchFullStrategyData(strategy: Address): Promise { - const [symbol, decimals, name] = await Promise.all([ - queryContract({ - ...readContractQueryOptions(getConfig(), { - address: token, - abi: erc20Abi, - functionName: "symbol", - }), - ...metadataQueryConfig, - }), - queryContract({ - ...readContractQueryOptions(getConfig(), { - address: token, - abi: erc20Abi, - functionName: "decimals", - }), - ...metadataQueryConfig, - }), - queryContract({ - ...readContractQueryOptions(getConfig(), { - address: token, - abi: erc20Abi, - functionName: "name", - }), - ...metadataQueryConfig, - }), - ]); - - return { - name, - symbol, - decimals, - icon: addressIconMap.get(token) || "", - }; -} - -export const useFetchTokenData = (asset?: Address) => { - const { data, ...rest } = useQuery({ - queryKey: ["hookTokenData", asset], - queryFn: () => fetchTokenData(asset!), - enabled: !!asset, - ...disableCacheQueryConfig, - }); - - return { - ...rest, - data: { - ...data, - icon: addressIconMap.get(asset || "") || "", - }, - }; -}; diff --git a/src/app/statev3/queries/AssetBalance.hook.ts b/src/app/statev3/queries/AssetBalance.hook.ts index e73b1170..a054a3f9 100644 --- a/src/app/statev3/queries/AssetBalance.hook.ts +++ b/src/app/statev3/queries/AssetBalance.hook.ts @@ -1,6 +1,5 @@ import { Address, erc20Abi } from "viem"; -import { FetchBigIntStrict } from "../../../shared"; -import { fetchTokenData } from "../metadata/TokenData.fetch"; +import { FetchBigIntStrict, fetchToken } from "@shared"; import { getConfig, queryContract } from "../../utils/queryContractUtils"; import { walletDataQueryConfig } from "../settings/queryConfig"; import { readContractQueryOptions } from "wagmi/query"; @@ -21,7 +20,7 @@ export async function fetchAssetBalance({ account, asset }: FetchAssetBalanceInp }), ...walletDataQueryConfig, }), - fetchTokenData(asset), + fetchToken(asset), ]); return { diff --git a/src/app/statev3/queries/AssetTotalSupply.hook.ts b/src/app/statev3/queries/AssetTotalSupply.hook.ts index 2ee3fd98..ed177728 100644 --- a/src/app/statev3/queries/AssetTotalSupply.hook.ts +++ b/src/app/statev3/queries/AssetTotalSupply.hook.ts @@ -1,7 +1,6 @@ import { Address, erc20Abi } from "viem"; -import { FetchBigIntStrict } from "../../../shared"; +import { FetchBigIntStrict, fetchToken } from "../../../shared"; import { getConfig, queryContract } from "../../utils/queryContractUtils"; -import { fetchTokenData } from "../metadata/TokenData.fetch"; import { infiniteCacheQueryConfig, platformDataQueryConfig } from "../settings/queryConfig"; import { readContractQueryOptions } from "wagmi/query"; @@ -26,7 +25,7 @@ export async function fetchAssetTotalSupplyInBlock({ }), ...cacheConfig, }), - fetchTokenData(asset), + fetchToken(asset), ]); return { diff --git a/src/app/statev3/queries/AvailableStrategyCap.hook.ts b/src/app/statev3/queries/AvailableStrategyCap.hook.ts index 7246019e..798d3dd9 100644 --- a/src/app/statev3/queries/AvailableStrategyCap.hook.ts +++ b/src/app/statev3/queries/AvailableStrategyCap.hook.ts @@ -1,10 +1,10 @@ import { Address, zeroAddress } from "viem"; -import { fetchTokenData } from "../metadata/TokenData.fetch"; import { loopStrategyAbi } from "../../generated"; import { Displayable, FetchTokenAmountWithUsdValueStrict, ViewBigIntWithUsdValue, + fetchToken, formatFetchBigInt, formatFetchBigIntToViewBigInt, formatUsdValue, @@ -29,6 +29,7 @@ export async function fetchMaxDeposit(strategy: Address): Promise { ...infiniteCacheQueryConfig, }).catch((error) => { if (error.cause.reason === OVERFLOW_UNDERFLOW_REASON_MESSAGE) { + // eslint-disable-next-line no-console console.info(`Failed to fetch available strategy cap for strategy ${strategy}`, error); return 0n; } @@ -49,7 +50,7 @@ export async function fetchAvailableStrategyCap(strategy: Address): Promise { const cacheConfig = blockNumber ? infiniteCacheQueryConfig : platformDataQueryConfig; - const { symbol, decimals } = await fetchTokenData(strategy); + const { symbol, decimals } = await fetchToken(strategy); const [equity, equityUsd] = await Promise.all([ queryContract({ diff --git a/src/app/statev3/queries/MetadataLoader.hook.ts b/src/app/statev3/queries/MetadataLoader.hook.ts index 9ca10918..ec3fbfcb 100644 --- a/src/app/statev3/queries/MetadataLoader.hook.ts +++ b/src/app/statev3/queries/MetadataLoader.hook.ts @@ -1,12 +1,12 @@ import { fetchStrategies } from "./Strategies.hook"; -import { fetchTokenData, TokenData } from "../metadata/TokenData.fetch"; import { useQuery } from "@tanstack/react-query"; import { disableCacheQueryConfig } from "../settings/queryConfig"; +import { fetchToken, Token } from "@shared"; -export async function fetchAllStrategyTokenData(): Promise { +export async function fetchAllStrategyTokenData(): Promise { const strategies = await fetchStrategies(); - const allStrategyData = await Promise.all(strategies.map((strategy) => fetchTokenData(strategy))); + const allStrategyData = await Promise.all(strategies.map((strategy) => fetchToken(strategy))); return allStrategyData; } diff --git a/src/app/statev3/queries/StrategyCap.hook.ts b/src/app/statev3/queries/StrategyCap.hook.ts index 7efeb1bb..49c9a895 100644 --- a/src/app/statev3/queries/StrategyCap.hook.ts +++ b/src/app/statev3/queries/StrategyCap.hook.ts @@ -3,6 +3,7 @@ import { Displayable, FetchTokenAmountWithUsdValueStrict, ViewBigIntWithUsdValue, + fetchToken, formatFetchBigInt, formatFetchBigIntToViewBigInt, formatUsdValue, @@ -10,7 +11,6 @@ import { import { fetchStrategyAssets } from "../metadata/StrategyAssets.fetch"; import { getConfig, queryContract } from "../../utils/queryContractUtils"; import { fetchAssetPriceInBlock } from "./AssetPrice.hook"; -import { fetchTokenData } from "../metadata/TokenData.fetch"; import { loopStrategyAbi } from "../../generated"; import { cValueInUsd } from "../math/utils"; import { useQuery } from "@tanstack/react-query"; @@ -31,7 +31,7 @@ export async function fetchStrategyCap(strategy: Address): Promise = new Map([ - [SEAM_ADDRESS, seamLogo], - [ESSEAM_ADDRESS, esSeamLogo], - [OG_POINTS_ADDRESS, ogPointsLogo], - [USDC_ADDRESS, usdcLogo], - [BRETT_ADDRESS, brettLogo], - [WETH_ADDRESS, wethLogo], - [wstETHBooster_3x, wstETHIlmIcon], - [ethLong_1_5x, ilmIcon], - [ethLong_3x, ilmIcon], - [ethShort_ADDRESS_1_5_x, ilmIcon], - [WSTETH_ADDRESS, wsteth], - [cbBTCLong_1_5x, ilmcbBTCIcon], - [cbBTCLong_3x, ilmcbBTCIcon], - [cbBTC_ADDRESS, cbBTCIcon], -]); diff --git a/src/app/v3/components/forms/deposit-form/FormButtons.tsx b/src/app/v3/components/forms/deposit-form/FormButtons.tsx index 1d00e746..dd50f327 100644 --- a/src/app/v3/components/forms/deposit-form/FormButtons.tsx +++ b/src/app/v3/components/forms/deposit-form/FormButtons.tsx @@ -1,9 +1,16 @@ -import { FlexCol, AuthGuardv2, Buttonv2, useERC20Approve, getApproveState, useNotificationContext } from "@shared"; +import { + FlexCol, + AuthGuardv2, + Buttonv2, + useERC20Approve, + getApproveState, + useNotificationContext, + useToken, +} from "@shared"; import React from "react"; import { useFormContext } from "react-hook-form"; import { parseUnits } from "viem"; import { FullStrategyData } from "../../../../statev3/metadata/FullStrategyData.all"; -import { useFetchTokenData } from "../../../../statev3/metadata/TokenData.fetch"; export const FormButtons: React.FC<{ strategy: FullStrategyData; @@ -11,7 +18,7 @@ export const FormButtons: React.FC<{ isDisabled?: boolean; }> = ({ strategy, isLoading, isDisabled }) => { const { showNotification } = useNotificationContext(); - const { data: { decimals } = {} } = useFetchTokenData(strategy.underlying); + const { data: { decimals } = {} } = useToken(strategy.underlying); const { watch, diff --git a/src/app/v3/components/forms/deposit-form/RHFDepositAmountField.tsx b/src/app/v3/components/forms/deposit-form/RHFDepositAmountField.tsx index d08b83c9..922d3755 100644 --- a/src/app/v3/components/forms/deposit-form/RHFDepositAmountField.tsx +++ b/src/app/v3/components/forms/deposit-form/RHFDepositAmountField.tsx @@ -1,4 +1,4 @@ -import { IRHFAmountInputProps, RHFAmountInputV3, fParseUnits, formatFetchBigIntToViewBigInt } from "@shared"; +import { IRHFAmountInputProps, RHFAmountInputV3, fParseUnits, formatFetchBigIntToViewBigInt, useToken } from "@shared"; import { useFormContext } from "react-hook-form"; import { useMemo } from "react"; import { USD_VALUE_DECIMALS, walletBalanceDecimalsOptions } from "@meta"; @@ -7,7 +7,6 @@ import { cValueInUsd } from "../../../../statev3/common/math/cValueInUsd"; import { useFormSettingsContext } from "../contexts/useFormSettingsContext"; import { useFetchViewMaxUserDeposit } from "../../../../state/loop-strategy/hooks/useFetchViewMaxUserDeposit"; import { useFetchFormattedAssetPrice } from "../../../../statev3/queries/AssetPrice.hook"; -import { useFetchTokenData } from "../../../../statev3/metadata/TokenData.fetch"; import { useFetchFullStrategyData } from "../../../../statev3/metadata/FullStrategyData.all"; type IProps = Omit & { @@ -62,7 +61,7 @@ export function RHFDepositAmountField({ ...other }: IProps) { const underlyingAssetAddress = underlying; // *** metadata *** // - const tokenData = useFetchTokenData(underlyingAssetAddress); + const tokenData = useToken(underlyingAssetAddress); // *** form functions *** // const { watch } = useFormContext(); diff --git a/src/app/v3/components/forms/deposit-form/RHFReceiveAmountField.tsx b/src/app/v3/components/forms/deposit-form/RHFReceiveAmountField.tsx index 5cd8350b..4dec994b 100644 --- a/src/app/v3/components/forms/deposit-form/RHFReceiveAmountField.tsx +++ b/src/app/v3/components/forms/deposit-form/RHFReceiveAmountField.tsx @@ -4,6 +4,7 @@ import { fParseUnits, formatFetchBigIntToViewBigInt, mergeQueryStates, + useToken, } from "@shared"; import { useMemo } from "react"; import { cValueInUsd } from "../../../../statev3/common/math/cValueInUsd"; @@ -11,7 +12,6 @@ import { useFormSettingsContext } from "../contexts/useFormSettingsContext"; import { useFetchDepositSharesToReceive } from "../../../../state/loop-strategy/hooks/useFetchDepositSharesToReceive"; import { formatUnits } from "viem"; import { useFetchFormattedAssetPrice } from "../../../../statev3/queries/AssetPrice.hook"; -import { useFetchTokenData } from "../../../../statev3/metadata/TokenData.fetch"; import { USD_VALUE_DECIMALS } from "../../../../../meta"; type IProps = Omit & { @@ -65,7 +65,7 @@ export function RHFReceiveAmountField({ debouncedAmount, ...other }: IProps = Omit & { name: keyof T; @@ -13,7 +12,7 @@ export function RHFReceiveAmountField({ debouncedAmount, ...other }: IProps = Omit< IRHFAmountInputProps, @@ -44,7 +43,7 @@ type IProps = Omit< */ export function RHFWithdrawStrategyAmountField({ strategy, focusOnAssetChange = true, ...other }: IProps) { // *** metadata *** // - const tokenData = useFetchTokenData(strategy); + const tokenData = useToken(strategy); // *** form functions *** // const { watch } = useFormContext(); diff --git a/src/app/v3/pages/ilm-details/components/current-holdings/CurrentHoldings.tsx b/src/app/v3/pages/ilm-details/components/current-holdings/CurrentHoldings.tsx index 669580a7..acfde650 100644 --- a/src/app/v3/pages/ilm-details/components/current-holdings/CurrentHoldings.tsx +++ b/src/app/v3/pages/ilm-details/components/current-holdings/CurrentHoldings.tsx @@ -1,5 +1,4 @@ -import { DisplayMoney, DisplayTokenAmount, FlexCol, FlexRow, Icon, Typography } from "@shared"; -import { useFetchTokenData } from "../../../../../statev3/metadata/TokenData.fetch"; +import { DisplayMoney, DisplayTokenAmount, FlexCol, FlexRow, Icon, Typography, useToken } from "@shared"; import { useFetchFormattedAssetBalanceWithUsdValue } from "../../../../../statev3/queries/AssetBalanceWithUsdValue.hook"; import { UserProfit } from "./UserProfit"; import { useParams } from "react-router-dom"; @@ -9,7 +8,7 @@ export const CurrentHoldings = () => { const { address } = useParams(); const strategy = address as Address | undefined; - const { data: strategyData, ...strategyDataRest } = useFetchTokenData(strategy); + const { data: strategyData, ...strategyDataRest } = useToken(strategy); const { data: strategyBalance, ...strategyBalanceRest } = useFetchFormattedAssetBalanceWithUsdValue({ asset: strategy, @@ -23,7 +22,13 @@ export const CurrentHoldings = () => { - + { const { data: { symbol }, ...debtTokenDataRest - } = useFetchTokenData(strategyData?.debt); + } = useToken(strategyData?.debt); const { showNotification } = useNotificationContext(); @@ -185,7 +184,7 @@ export const GraphComponent = () => { setChartSeries(series); }; processData(); - }, [filterOption, showPriceInDebtAsset, showPriceInUsd, strategy, symbol, debtTokenDataRest.status]); + }, [filterOption, showPriceInDebtAsset, showPriceInUsd, strategy, symbol, debtTokenDataRest.isLoading]); return (
diff --git a/src/app/v3/pages/ilm-details/components/strategy-picker/StrategyPickerButton.tsx b/src/app/v3/pages/ilm-details/components/strategy-picker/StrategyPickerButton.tsx index 381b1136..01b62b62 100644 --- a/src/app/v3/pages/ilm-details/components/strategy-picker/StrategyPickerButton.tsx +++ b/src/app/v3/pages/ilm-details/components/strategy-picker/StrategyPickerButton.tsx @@ -3,14 +3,14 @@ import { FlexRow, Icon, Modal, ModalHandles, Typography } from "@shared"; import polygonIcon from "@assets/common/polygon-black-down.svg"; import { IlmTableContainer } from "../../../landing-page/tabs/ilms/table/IlmTableContainer"; -import { useFetchTokenData } from "../../../../../statev3/metadata/TokenData.fetch"; import { useRef, useEffect } from "react"; +import { useFullTokenData } from "../../../../../statev3/common/meta-data-queries/useFullTokenData"; export const StrategyPickerButton: React.FC<{ strategy?: Address; }> = ({ strategy }) => { - const { data: tokenData } = useFetchTokenData(strategy); - const { name, icon } = tokenData || {}; + const { data: tokenData } = useFullTokenData(strategy); + const { name, logo: icon } = tokenData || {}; const modalRef = useRef(null); useEffect(() => { diff --git a/src/app/v3/pages/landing-page/tabs/dashboard/table/TableDesktopRow.tsx b/src/app/v3/pages/landing-page/tabs/dashboard/table/TableDesktopRow.tsx index a83f0844..f8b5bc5b 100644 --- a/src/app/v3/pages/landing-page/tabs/dashboard/table/TableDesktopRow.tsx +++ b/src/app/v3/pages/landing-page/tabs/dashboard/table/TableDesktopRow.tsx @@ -42,7 +42,7 @@ export const TableDesktopRow: React.FC<{ > - + diff --git a/src/app/v3/pages/landing-page/tabs/dashboard/table/TableMobileRow.tsx b/src/app/v3/pages/landing-page/tabs/dashboard/table/TableMobileRow.tsx index a2e7526b..b5b7586d 100644 --- a/src/app/v3/pages/landing-page/tabs/dashboard/table/TableMobileRow.tsx +++ b/src/app/v3/pages/landing-page/tabs/dashboard/table/TableMobileRow.tsx @@ -28,7 +28,7 @@ export const TableMobileRow: React.FC<{ strategy: Address }> = ({ strategy }) => - + {strategyData?.name} {strategyData?.description} diff --git a/src/app/v3/pages/landing-page/tabs/ilms/table/ILMDesktopTableRow.tsx b/src/app/v3/pages/landing-page/tabs/ilms/table/ILMDesktopTableRow.tsx index 435f3509..f81376d7 100644 --- a/src/app/v3/pages/landing-page/tabs/ilms/table/ILMDesktopTableRow.tsx +++ b/src/app/v3/pages/landing-page/tabs/ilms/table/ILMDesktopTableRow.tsx @@ -25,13 +25,14 @@ export const ILMDesktopTableRow: React.FC<{ return (
- + diff --git a/src/app/v3/pages/landing-page/tabs/ilms/table/ILMMobileTableRow.tsx b/src/app/v3/pages/landing-page/tabs/ilms/table/ILMMobileTableRow.tsx index 10f4e4c0..dd59c2b1 100644 --- a/src/app/v3/pages/landing-page/tabs/ilms/table/ILMMobileTableRow.tsx +++ b/src/app/v3/pages/landing-page/tabs/ilms/table/ILMMobileTableRow.tsx @@ -29,7 +29,7 @@ export const ILMMobileTableRow: React.FC<{ - + {strategyData?.name} {strategyData?.symbol} diff --git a/src/meta/TokenDataDict.ts b/src/meta/TokenDataDict.ts deleted file mode 100644 index f1cae80e..00000000 --- a/src/meta/TokenDataDict.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - CBETH_ADDRESS, - DAI_ADDRESS, - USDBC_ADDRESS, - USDC_ADDRESS, - WETH_ADDRESS, - WSTETH_ADDRESS, - sWETH_ADDRESS, - wstETHBooster_3x, - DEGEN_ADDRESS, - SEAM_ADDRESS, - ethLong_1_5x, - AERO_ADDRESS, - BRETT_ADDRESS, -} from "./constants"; -import { Address } from "viem"; - -import wethLogo from "@assets/tokens/weth.svg"; -import WstEthLogo from "@assets/tokens/wsteth.svg"; -import ilmwstETHLogo from "@assets/tokens/ilmWstethEth.svg"; -import cbethLogo from "@assets/tokens/cbeth.svg"; -import ethLongLogo from "@assets/tokens/ilmEthUsdc.svg"; -import usdbcLogo from "@assets/tokens/usdbc.svg"; -import daiLogo from "@assets/tokens/dai.svg"; -import usdcLogo from "@assets/tokens/usdc.svg"; -import degenLogo from "@assets/tokens/degen.svg"; -import seamLogo from "@assets/tokens/seam.svg"; -import aeroLogo from "@assets/tokens/aero.svg"; -import brettLogo from "@assets/tokens/brett.svg"; - -interface ITokenDataDict { - [address: Address]: { - name?: string; - nameOverride?: string; - logo: string; - }; -} - -export const TokenDataDict: ITokenDataDict = { - [WETH_ADDRESS]: { - logo: wethLogo, - }, - [sWETH_ADDRESS]: { - logo: WstEthLogo, - }, - [WSTETH_ADDRESS]: { - logo: WstEthLogo, - }, - [wstETHBooster_3x]: { - name: "wstETH Booster", - logo: ilmwstETHLogo, - }, - [ethLong_1_5x]: { - name: "Multiply ETH Long", - logo: ethLongLogo, - }, - // Adding the missing contracts - [CBETH_ADDRESS]: { - logo: cbethLogo, - }, - [USDBC_ADDRESS]: { - logo: usdbcLogo, - }, - [DAI_ADDRESS]: { - logo: daiLogo, - }, - [USDC_ADDRESS]: { - logo: usdcLogo, - }, - [DEGEN_ADDRESS]: { - logo: degenLogo, - }, - [SEAM_ADDRESS]: { - logo: seamLogo, - }, - [AERO_ADDRESS]: { - logo: aeroLogo, - }, - [BRETT_ADDRESS]: { - logo: brettLogo, - }, -}; diff --git a/src/meta/icons.ts b/src/meta/icons.ts new file mode 100644 index 00000000..10a51fc6 --- /dev/null +++ b/src/meta/icons.ts @@ -0,0 +1,47 @@ +import seamLogo from "@assets/logos/logo-seamless.svg"; +import esSeamLogo from "@assets/tokens/esSeam.svg"; +import usdcLogo from "@assets/tokens/usdc.svg"; +import ogPointsLogo from "@assets/tokens/og-points.svg"; +import brettLogo from "@assets/tokens/brett.svg"; +import wethLogo from "@assets/tokens/weth.svg"; +import wsteth from "@assets/tokens/wsteth.svg"; +import ilmcbBTCIcon from "@assets/tokens/ilmcbBTC.svg"; +import cbBTCIcon from "@assets/tokens/cbBTC.svg"; +import wstETHIlmIcon from "@assets/ilms/wstETH-ilm.svg"; +import ilmIcon from "@assets/ilms/ethLong-ilm.svg"; +import { + SEAM_ADDRESS, + ESSEAM_ADDRESS, + OG_POINTS_ADDRESS, + USDC_ADDRESS, + BRETT_ADDRESS, + WETH_ADDRESS, + wstETHBooster_3x, + ethLong_1_5x, + ethLong_3x, + ethShort_ADDRESS_1_5_x, + WSTETH_ADDRESS, + cbBTCLong_1_5x, + cbBTCLong_3x, + cbBTC_ADDRESS, +} from "./constants"; + +/* --------- */ +/* Icons */ +/* --------- */ +export const addressIconMap: Map = new Map([ + [SEAM_ADDRESS, seamLogo], + [ESSEAM_ADDRESS, esSeamLogo], + [OG_POINTS_ADDRESS, ogPointsLogo], + [USDC_ADDRESS, usdcLogo], + [BRETT_ADDRESS, brettLogo], + [WETH_ADDRESS, wethLogo], + [wstETHBooster_3x, wstETHIlmIcon], + [ethLong_1_5x, ilmIcon], + [ethLong_3x, ilmIcon], + [ethShort_ADDRESS_1_5_x, ilmIcon], + [WSTETH_ADDRESS, wsteth], + [cbBTCLong_1_5x, ilmcbBTCIcon], + [cbBTCLong_3x, ilmcbBTCIcon], + [cbBTC_ADDRESS, cbBTCIcon], +]); diff --git a/src/meta/index.ts b/src/meta/index.ts index 73de109b..6696aa09 100644 --- a/src/meta/index.ts +++ b/src/meta/index.ts @@ -1,3 +1,3 @@ export * from "./constants"; -export * from "./TokenDataDict"; +export * from "./icons"; export * from "./query-params"; diff --git a/src/shared/components/form/rhf/RHFAmountInput.tsx b/src/shared/components/form/rhf/RHFAmountInput.tsx index 443b7ce6..1e9a3bf5 100644 --- a/src/shared/components/form/rhf/RHFAmountInput.tsx +++ b/src/shared/components/form/rhf/RHFAmountInput.tsx @@ -15,7 +15,7 @@ import { DisplayText } from "../../display/DisplayText"; import { Tooltip } from "../../tooltip/Tooltip"; // todo: remove this from shared. actually delete this file after v3 migration? import { useFocusOnAssetChange } from "../../../hooks/ui-hooks/useFocusOnAssetChange"; -import { useFullTokenData } from "../../../../app/statev3/common/meta-data-queries/useFullTokenData"; +import { useToken } from "../../../state"; export interface IRHFAmountInputProps extends RHFInputFieldProps { assetAddress?: Address; @@ -44,7 +44,7 @@ export const RHFAmountInput = React.forwardRef { const { setValue, getValues } = useFormContext(); const { isConnected } = useAccount(); - const tokenDataResult = useFullTokenData(assetAddress); + const tokenDataResult = useToken(assetAddress); const { data: tokenData } = tokenDataResult; const max = protocolMaxValue?.data?.value; diff --git a/src/shared/components/form/rhf/RHFAmountInputV3.tsx b/src/shared/components/form/rhf/RHFAmountInputV3.tsx index d54f3585..f864bda1 100644 --- a/src/shared/components/form/rhf/RHFAmountInputV3.tsx +++ b/src/shared/components/form/rhf/RHFAmountInputV3.tsx @@ -26,7 +26,7 @@ export interface IRHFAmountInputPropsV3 extends RHFInputFieldProps { tokenData?: Displayable<{ symbol?: string; decimals?: number; - icon?: string; + logo?: string; }>; } @@ -101,7 +101,7 @@ export const RHFAmountInputV3 = React.forwardRef = ({ address, icon }) => { const { mutateAsync, isPending } = useWatchAsset(); const { data: { decimals, symbol }, - } = useFetchTokenData(address); + } = useToken(address); const handleAddToWalletClick = async () => { if (!address || !decimals || !symbol) return; diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts new file mode 100644 index 00000000..28a8c795 --- /dev/null +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts @@ -0,0 +1,27 @@ +import { Address } from "viem"; + +interface CoinGeckoTokenResponse { + image: { + thumb: string; + small: string; + large: string; + }; + // other fields as needed +} + +export async function fetchTokenLogoFromCoinGecko(tokenAddress: Address): Promise { + try { + const url = `https://api.coingecko.com/api/v3/coins/base/contract/${tokenAddress}`; + const response = await fetch(url); + + if (!response.ok) { + return null; + } + + const data = (await response.json()) as CoinGeckoTokenResponse; + return data.image?.thumb || null; + } catch (error) { + console.error("Failed to fetch token logo from CoinGecko", error); + return null; + } +} diff --git a/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts b/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts new file mode 100644 index 00000000..a910dec6 --- /dev/null +++ b/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts @@ -0,0 +1,24 @@ +import { Address } from "viem"; + +/** + * Returns the Trust Wallet asset logo URL for an ERC-20 token on Ethereum. + * Replace `base` with a different chain name for other EVM blockchains, if needed. + */ +export function getTrustWalletLogoUrl(tokenAddress: string): string { + const baseUrl = "https://raw.githubusercontent.com/trustwallet/assets/master"; + return `${baseUrl}/blockchains/base/assets/${tokenAddress}/logo.png`; +} + +export async function fetchTokenLogoFromTrustWallet(tokenAddress: Address): Promise { + const trustWalletLogoUrl = getTrustWalletLogoUrl(tokenAddress); + try { + const resp = await fetch(trustWalletLogoUrl, { method: "HEAD" }); + if (resp.ok) { + return trustWalletLogoUrl; + } + } catch (e) { + console.error(e); + } + + return null; +} diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 8ede2d88..2394f599 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -5,10 +5,14 @@ import { getQueryClient } from "../../../app/contexts/CustomQueryClientProvider" import { readContractQueryOptions } from "wagmi/query"; import { queryConfig } from "../../../app/statev3/settings/queryConfig"; import { useQuery } from "@tanstack/react-query"; +import { fetchTokenLogoFromTrustWallet } from "./fetchTrustWalletLogoUrl"; +import { addressIconMap } from "@meta"; +import { fetchTokenLogoFromCoinGecko } from "./fetchTokenLogoFromCoinGecko"; export interface Token { - symbol?: string; - decimals?: number; + symbol: string; + decimals: number; + logo?: string; } export async function fetchDecimals(token: Address): Promise { @@ -20,7 +24,7 @@ export async function fetchDecimals(token: Address): Promise { abi: erc20Abi, functionName: "decimals", }), - ...queryConfig.metadataQueryConfig + ...queryConfig.metadataQueryConfig, }); return decimals; @@ -35,36 +39,71 @@ export async function fetchSymbol(token: Address): Promise { abi: erc20Abi, functionName: "symbol", }), - ...queryConfig.metadataQueryConfig + ...queryConfig.metadataQueryConfig, }); return symbol; } +/** + * Fetches the logo URL for a given token address. + * Before fetching from CoinGecko, it checks if the logo is available in the addressIconMap. + * If not, it fetches the logo from Trust Wallet if it fails, it fetches the logo from CoinGecko. + */ +export async function fetchTokenLogoWithFallbacks(token: Address): Promise { + const logoFromConfig = addressIconMap.get(token); + if (logoFromConfig) return logoFromConfig; + // eslint-disable-next-line no-console + console.warn("Logo not found in addressIconMap", token); + + const trustWalletUrl = await fetchTokenLogoFromTrustWallet(token); + if (trustWalletUrl) return trustWalletUrl; + console.error("Could not fetch trust wallet logo", token); + + const coinGeckoUrl = await fetchTokenLogoFromCoinGecko(token); + if (coinGeckoUrl) return coinGeckoUrl; + console.error("Could not fetch coin gecko logo", token); + + return undefined; +} export async function fetchToken(token: Address): Promise { - const [symbol, decimals] = await Promise.all([fetchSymbol(token), fetchDecimals(token)]); + const [symbol, decimals, logoURI] = await Promise.all([ + fetchSymbol(token), + fetchDecimals(token), + fetchTokenLogoWithFallbacks(token), + ]); + if (!symbol || !decimals) { + throw new Error("Failed to fetch token data"); + } return { symbol, - decimals - } + decimals, + logo: logoURI, + }; +} + +interface TokenHookData { + symbol?: string; + decimals?: number; + logo?: string; } -// todo reconsider optional param token ticket #218 -export const useToken = (asset?: Address): FetchData => { +export const useToken = (asset?: Address): FetchData => { const { data, ...rest } = useQuery({ queryKey: ["hookFetchToken", asset], - queryFn: () => - fetchToken(asset!), + queryFn: () => fetchToken(asset!), enabled: !!asset, - ...queryConfig.disableCacheQueryConfig + ...queryConfig.disableCacheQueryConfig, }); return { + ...rest, data: data || { symbol: undefined, - decimals: undefined - }, ...rest + decimals: undefined, + logo: undefined, + }, }; }; From 4d801f65508e6196bdfe78e020140f4fe95a9c6f Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Fri, 3 Jan 2025 17:48:52 +0100 Subject: [PATCH 2/9] added comments --- .../state/meta-data-queries/useToken.ts | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 2394f599..b2423e11 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -46,9 +46,16 @@ export async function fetchSymbol(token: Address): Promise { } /** - * Fetches the logo URL for a given token address. - * Before fetching from CoinGecko, it checks if the logo is available in the addressIconMap. - * If not, it fetches the logo from Trust Wallet if it fails, it fetches the logo from CoinGecko. + * Attempts to retrieve a token logo URL from multiple sources, in this order: + * 1. **Local icon map** (addressIconMap) + * 2. **Trust Wallet Assets** + * 3. **CoinGecko** + * + * If a valid logo URL is found at any step, it returns immediately. + * Otherwise, returns `undefined` if no logo is found. + * + * @param token - The token address. + * @returns The logo URL, or `undefined` if none is available. */ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { const logoFromConfig = addressIconMap.get(token); @@ -67,6 +74,17 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { const [symbol, decimals, logoURI] = await Promise.all([ fetchSymbol(token), From 517fe39e79de41ab66f95e1f9a0dc0b2dd171dac Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Fri, 3 Jan 2025 17:55:29 +0100 Subject: [PATCH 3/9] removed comment --- .../state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts index 28a8c795..bd33d799 100644 --- a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts @@ -6,7 +6,6 @@ interface CoinGeckoTokenResponse { small: string; large: string; }; - // other fields as needed } export async function fetchTokenLogoFromCoinGecko(tokenAddress: Address): Promise { From 53c525e950a511e1d5f860d7b9bec856798308c3 Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Fri, 3 Jan 2025 18:03:28 +0100 Subject: [PATCH 4/9] added query client --- .../meta-data-queries/fetchTrustWalletLogoUrl.ts | 9 +++------ src/shared/state/meta-data-queries/useToken.ts | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts b/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts index a910dec6..7f9ce8cf 100644 --- a/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts +++ b/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts @@ -1,9 +1,5 @@ import { Address } from "viem"; -/** - * Returns the Trust Wallet asset logo URL for an ERC-20 token on Ethereum. - * Replace `base` with a different chain name for other EVM blockchains, if needed. - */ export function getTrustWalletLogoUrl(tokenAddress: string): string { const baseUrl = "https://raw.githubusercontent.com/trustwallet/assets/master"; return `${baseUrl}/blockchains/base/assets/${tokenAddress}/logo.png`; @@ -16,8 +12,9 @@ export async function fetchTokenLogoFromTrustWallet(tokenAddress: Address): Prom if (resp.ok) { return trustWalletLogoUrl; } - } catch (e) { - console.error(e); + } catch (error) { + console.error("Failed to fetch token logo from TrustWallet", error); + return null; } return null; diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index b2423e11..42ae289e 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -58,16 +58,26 @@ export async function fetchSymbol(token: Address): Promise { * @returns The logo URL, or `undefined` if none is available. */ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { + const queryClient = getQueryClient(); + const logoFromConfig = addressIconMap.get(token); if (logoFromConfig) return logoFromConfig; // eslint-disable-next-line no-console console.warn("Logo not found in addressIconMap", token); - const trustWalletUrl = await fetchTokenLogoFromTrustWallet(token); + const trustWalletUrl = await queryClient.fetchQuery({ + queryKey: ["fetchTokenLogoFromTrustWallet", token], + queryFn: () => fetchTokenLogoFromTrustWallet(token), + ...queryConfig.metadataQueryConfig, + }); if (trustWalletUrl) return trustWalletUrl; console.error("Could not fetch trust wallet logo", token); - const coinGeckoUrl = await fetchTokenLogoFromCoinGecko(token); + const coinGeckoUrl = await queryClient.fetchQuery({ + queryKey: ["fetchTokenLogoFromCoinGecko", token], + queryFn: () => fetchTokenLogoFromCoinGecko(token), + ...queryConfig.metadataQueryConfig, + }); if (coinGeckoUrl) return coinGeckoUrl; console.error("Could not fetch coin gecko logo", token); From 3c1e212d02420d0a9733ba3db86d74e769cd307f Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Fri, 3 Jan 2025 18:05:45 +0100 Subject: [PATCH 5/9] changed the order --- src/shared/state/meta-data-queries/useToken.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 42ae289e..6a43aab5 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -58,13 +58,13 @@ export async function fetchSymbol(token: Address): Promise { * @returns The logo URL, or `undefined` if none is available. */ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { - const queryClient = getQueryClient(); - const logoFromConfig = addressIconMap.get(token); if (logoFromConfig) return logoFromConfig; // eslint-disable-next-line no-console console.warn("Logo not found in addressIconMap", token); + const queryClient = getQueryClient(); + const trustWalletUrl = await queryClient.fetchQuery({ queryKey: ["fetchTokenLogoFromTrustWallet", token], queryFn: () => fetchTokenLogoFromTrustWallet(token), From 7045f51cdfdd2daccb1d5cd4799ab4ba5871beab Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Wed, 8 Jan 2025 11:37:40 +0100 Subject: [PATCH 6/9] added moralis API --- package-lock.json | 839 +++++++++++++++++- package.json | 3 +- src/shared/components/images/Icon.tsx | 2 +- .../fetchTokenLogoFromCoinGecko.ts | 3 +- .../fetchTokenLogoFromMoralis.ts | 21 + .../state/meta-data-queries/useToken.ts | 14 +- 6 files changed, 850 insertions(+), 32 deletions(-) create mode 100644 src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts diff --git a/package-lock.json b/package-lock.json index 9d63a6b6..cb0b3572 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "dotenv": "^16.3.1", "ethereum-blockies-base64": "^1.0.2", "graphql": "^16.10.0", + "moralis": "^2.27.2", "path": "^0.12.7", "react": "^18.2.0", "react-apexcharts": "^1.4.1", @@ -3311,6 +3312,419 @@ "node": ">=14" } }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key/node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/@ethersproject/signing-key/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz", + "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==" + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -5815,6 +6229,146 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/@moralisweb3/api-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/api-utils/-/api-utils-2.27.2.tgz", + "integrity": "sha512-Z1Ipe+bJZqQcL3p6vtlB8Ih5ne0UJJpXutv4Qg/OGym+YrQpBNCummEQWSAMt6874IQDqNcCJzeBEpcipkzQ+Q==", + "dependencies": { + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "axios": "^1.2.1" + } + }, + "node_modules/@moralisweb3/aptos-api": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/aptos-api/-/aptos-api-2.27.2.tgz", + "integrity": "sha512-x/dUZhlp4ocMfRTLXcLRXdBHx62l8WCNPOWCSSg5Z10WngU1REgL2WTnZPQ2ic+13re3Iv2x1YhZW098xkw0vA==", + "dependencies": { + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/common-aptos-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2" + } + }, + "node_modules/@moralisweb3/auth": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/auth/-/auth-2.27.2.tgz", + "integrity": "sha512-q3f0AQo7RCgTtxnAvj66yoj8cBCe/Rz7AfXM4M3+irEmCjs9f+94E/e410qAztGAI2VSQIq/3gGNheJ+nviYCQ==", + "dependencies": { + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/common-aptos-utils": "^2.27.2", + "@moralisweb3/common-auth-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "@moralisweb3/common-sol-utils": "^2.27.2" + } + }, + "node_modules/@moralisweb3/common-aptos-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-aptos-utils/-/common-aptos-utils-2.27.2.tgz", + "integrity": "sha512-Th0+9nOV+rQnT39d9rXu24ff+LDtKzGuk8WzRIYAdpIo0Yv7jrWsqkJL2DwZ5vrkNOcNLabktTrLjZEXRCHw3A==", + "dependencies": { + "@moralisweb3/common-core": "^2.27.2", + "@noble/hashes": "^1.2.0" + } + }, + "node_modules/@moralisweb3/common-auth-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-auth-utils/-/common-auth-utils-2.27.2.tgz", + "integrity": "sha512-h35RkVNT+sD7C1PbSi/LwfjNdq7CyhhBShSrImXpl9Fs66jFVzronbiKFe9HOxJjn8tIz9ajxKQU46aJC2ZaHA==", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@moralisweb3/common-aptos-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "@moralisweb3/common-sol-utils": "^2.27.2", + "@moralisweb3/streams-typings": "^1.0.6" + } + }, + "node_modules/@moralisweb3/common-core": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-core/-/common-core-2.27.2.tgz", + "integrity": "sha512-/rGs2kdK/f41LizpfWTMfkyO5zFkbiOrn6wxpCTXzrzGequ+D5fWSCeYvA9BEH/XVH0aYR89eVYtQgxs5Zd0Dg==", + "dependencies": { + "axios": "^1.2.1" + } + }, + "node_modules/@moralisweb3/common-evm-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-evm-utils/-/common-evm-utils-2.27.2.tgz", + "integrity": "sha512-VGhS6f2+PRUqokl3sgp6yVDxbpTPvGdhcITiPxuym6eKWhHbHkp10eS9SR0LRmR1oog6p5HS1fSkGjl0aLr6Dg==", + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@moralisweb3/common-core": "^2.27.2" + } + }, + "node_modules/@moralisweb3/common-sol-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-sol-utils/-/common-sol-utils-2.27.2.tgz", + "integrity": "sha512-MzIFxFLtz9a8SVTvfh/WS1f7fBENtxAzpF3xiXI3SBKuoZExnR/ah8pKzY4DVL8FpswoFzVsO+yVBmToxc0aSw==", + "dependencies": { + "@moralisweb3/common-core": "^2.27.2", + "bn.js": "^5.2.1", + "bs58": "^5.0.0", + "buffer": "^6.0.3" + } + }, + "node_modules/@moralisweb3/common-streams-utils": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/common-streams-utils/-/common-streams-utils-2.27.2.tgz", + "integrity": "sha512-4bYUONJB5vpTnc045iSFlVIOgh/2HoEuNFj3jOzLRj/WD/H4SIeua1x1I33Z8sjTATvRKYJYuXxI1JrgAtNFtA==", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@moralisweb3/common-aptos-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "@moralisweb3/streams-typings": "^1.0.7" + } + }, + "node_modules/@moralisweb3/evm-api": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/evm-api/-/evm-api-2.27.2.tgz", + "integrity": "sha512-CLT5bAZQdBkgmz/LydavrpVAKe0aAY1pjafihgyV2nh520rQ3ZSzMHJN2ptGotPJ6ryYXAJgzWXIS4IC0dY4Tw==", + "dependencies": { + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2" + } + }, + "node_modules/@moralisweb3/sol-api": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/sol-api/-/sol-api-2.27.2.tgz", + "integrity": "sha512-mlm0RrcDdpgRCIxMenmJ/4CLDbvrJ/26g5Fl7m5oaVT6Lug1KERksTlSYp2PxPqlHme+AU0AfvOiln5A1MorEA==", + "dependencies": { + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-sol-utils": "^2.27.2" + } + }, + "node_modules/@moralisweb3/streams": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/@moralisweb3/streams/-/streams-2.27.2.tgz", + "integrity": "sha512-I/y8D/VZGHPA9GM5Tkpa8uNLu3z2q3sBV9r2dzSKy7QX7p5iNTGey+FAfczC9yM+jWo2eDCJK4Il8UTRmUrk8g==", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "@moralisweb3/common-streams-utils": "^2.27.2", + "@moralisweb3/streams-typings": "^1.0.7", + "ethereumjs-util": "^7.1.0", + "web3-eth-abi": "^1.8.0" + } + }, + "node_modules/@moralisweb3/streams-typings": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@moralisweb3/streams-typings/-/streams-typings-1.0.7.tgz", + "integrity": "sha512-ShbVqil0KLOTyTjO6z9JewPcVVE3S6kzkQFnW2flGBRsGdKucpkUdOx1HijOLoaikz/9gH92n+lzTvRFIj0AoA==" + }, "node_modules/@motionone/animation": { "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", @@ -10445,6 +10999,14 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/bn.js": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz", + "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -10542,6 +11104,14 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -10572,6 +11142,14 @@ "@types/react": "*" } }, + "node_modules/@types/secp256k1": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", + "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -13121,8 +13699,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -13230,10 +13807,9 @@ } }, "node_modules/axios": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", - "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", - "dev": true, + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -13244,7 +13820,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -13521,6 +14096,11 @@ "readable-stream": "^3.4.0" } }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -13614,7 +14194,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -13839,8 +14418,7 @@ "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, "node_modules/bufferutil": { "version": "4.0.8", @@ -14302,7 +14880,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -14590,7 +15167,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -14975,7 +15551,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -14988,7 +15563,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -15797,7 +16371,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -17856,6 +18429,14 @@ "pnglib": "0.0.1" } }, + "node_modules/ethereum-bloom-filters": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, "node_modules/ethereum-cryptography": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", @@ -17914,6 +18495,106 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/base-x": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.10.tgz", + "integrity": "sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ethereumjs-util/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ethereumjs-util/node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-util/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + }, + "node_modules/ethereumjs-util/node_modules/secp256k1": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -17945,7 +18626,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -18486,7 +19166,6 @@ "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, "funding": [ { "type": "individual", @@ -19113,7 +19792,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -20063,6 +20741,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/is-inside-container": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", @@ -20984,6 +21671,11 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==" }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -22113,7 +22805,6 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -22953,6 +23644,26 @@ "resolved": "https://registry.npmjs.org/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz", "integrity": "sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==" }, + "node_modules/moralis": { + "version": "2.27.2", + "resolved": "https://registry.npmjs.org/moralis/-/moralis-2.27.2.tgz", + "integrity": "sha512-SVPJDVRgqUEkLxC8R/QlBHOtAxvUBzK4b/w1oBW9m9oJigywhgNQMKLfu9eJZ3lMxvnVOMBUD+hzw47I4dEg7g==", + "dependencies": { + "@moralisweb3/api-utils": "^2.27.2", + "@moralisweb3/aptos-api": "^2.27.2", + "@moralisweb3/auth": "^2.27.2", + "@moralisweb3/common-aptos-utils": "^2.27.2", + "@moralisweb3/common-auth-utils": "^2.27.2", + "@moralisweb3/common-core": "^2.27.2", + "@moralisweb3/common-evm-utils": "^2.27.2", + "@moralisweb3/common-sol-utils": "^2.27.2", + "@moralisweb3/common-streams-utils": "^2.27.2", + "@moralisweb3/evm-api": "^2.27.2", + "@moralisweb3/sol-api": "^2.27.2", + "@moralisweb3/streams": "^2.27.2", + "@moralisweb3/streams-typings": "^1.0.7" + } + }, "node_modules/motion": { "version": "10.16.2", "resolved": "https://registry.npmjs.org/motion/-/motion-10.16.2.tgz", @@ -23315,6 +24026,24 @@ "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==" + }, "node_modules/ob1": { "version": "0.80.7", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.80.7.tgz", @@ -24044,7 +24773,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -24650,8 +25378,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/psl": { "version": "1.9.0", @@ -24835,7 +25562,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -25790,12 +26516,22 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, "node_modules/rollup": { "version": "4.27.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.2.tgz", @@ -26004,6 +26740,11 @@ "loose-envify": "^1.1.0" } }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, "node_modules/scuid": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/scuid/-/scuid-1.1.0.tgz", @@ -26197,8 +26938,7 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -26748,6 +27488,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -28133,6 +28885,11 @@ "node": ">=6.14.2" } }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -28999,6 +29756,36 @@ "defaults": "^1.0.3" } }, + "node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/webauthn-p256": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.10.tgz", diff --git a/package.json b/package.json index ce7a9062..004ffc8e 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "dotenv": "^16.3.1", "ethereum-blockies-base64": "^1.0.2", "graphql": "^16.10.0", + "moralis": "^2.27.2", "path": "^0.12.7", "react": "^18.2.0", "react-apexcharts": "^1.4.1", @@ -92,4 +93,4 @@ "vitest": "^1.2.2", "wait-on": "^7.2.0" } -} \ No newline at end of file +} diff --git a/src/shared/components/images/Icon.tsx b/src/shared/components/images/Icon.tsx index 5e0c0e5b..c4de4472 100644 --- a/src/shared/components/images/Icon.tsx +++ b/src/shared/components/images/Icon.tsx @@ -57,5 +57,5 @@ export const Icon: React.FC = ({ /> ); } - return {alt}; + return {alt}; }; diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts index bd33d799..2179d723 100644 --- a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts @@ -10,9 +10,8 @@ interface CoinGeckoTokenResponse { export async function fetchTokenLogoFromCoinGecko(tokenAddress: Address): Promise { try { - const url = `https://api.coingecko.com/api/v3/coins/base/contract/${tokenAddress}`; + const url = `https://cg-price-cache.seamlessprotocol.com/coins/base/contract/${tokenAddress}`; const response = await fetch(url); - if (!response.ok) { return null; } diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts new file mode 100644 index 00000000..98c348c6 --- /dev/null +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts @@ -0,0 +1,21 @@ +import Moralis from "moralis"; + +import { Address } from "viem"; + +await Moralis.start({ + apiKey: import.meta.env.VITE_MORALIS_API_KEY, +}); + +export const fetchTokenLogoFromMoralis = async (tokenAddress: Address) => { + try { + const response = await Moralis.EvmApi.token.getTokenMetadata({ + chain: "0x2105", + addresses: [tokenAddress], + }); + + return response.raw[0].logo; + } catch (e) { + console.error(e); + } + return undefined; +}; diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 6a43aab5..98520f03 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -5,9 +5,10 @@ import { getQueryClient } from "../../../app/contexts/CustomQueryClientProvider" import { readContractQueryOptions } from "wagmi/query"; import { queryConfig } from "../../../app/statev3/settings/queryConfig"; import { useQuery } from "@tanstack/react-query"; -import { fetchTokenLogoFromTrustWallet } from "./fetchTrustWalletLogoUrl"; -import { addressIconMap } from "@meta"; import { fetchTokenLogoFromCoinGecko } from "./fetchTokenLogoFromCoinGecko"; +import { fetchTokenLogoFromMoralis } from "./fetchTokenLogoFromMoralis"; +import { addressIconMap } from "@meta"; +import { fetchTokenLogoFromTrustWallet } from "./fetchTrustWalletLogoUrl"; export interface Token { symbol: string; @@ -48,6 +49,7 @@ export async function fetchSymbol(token: Address): Promise { /** * Attempts to retrieve a token logo URL from multiple sources, in this order: * 1. **Local icon map** (addressIconMap) + * 2. **Moralis** * 2. **Trust Wallet Assets** * 3. **CoinGecko** * @@ -65,6 +67,14 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise fetchTokenLogoFromMoralis(token), + ...queryConfig.metadataQueryConfig, + }); + if (moralisLogo) return moralisLogo; + console.error("Could not fetch moralis logo", token); + const trustWalletUrl = await queryClient.fetchQuery({ queryKey: ["fetchTokenLogoFromTrustWallet", token], queryFn: () => fetchTokenLogoFromTrustWallet(token), From e8f7c323df070e34e669ae2ea9b47f63a73b5b85 Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Wed, 8 Jan 2025 13:19:25 +0100 Subject: [PATCH 7/9] added name to fetch token Function --- .../state/meta-data-queries/useToken.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 98520f03..d4febba2 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -13,6 +13,7 @@ import { fetchTokenLogoFromTrustWallet } from "./fetchTrustWalletLogoUrl"; export interface Token { symbol: string; decimals: number; + name: string; logo?: string; } @@ -46,6 +47,21 @@ export async function fetchSymbol(token: Address): Promise { return symbol; } +export async function fetchName(token: Address): Promise { + const queryClient = getQueryClient(); + + const name = await queryClient.fetchQuery({ + ...readContractQueryOptions(getConfig(), { + address: token, + abi: erc20Abi, + functionName: "name", + }), + ...queryConfig.metadataQueryConfig, + }); + + return name; +} + /** * Attempts to retrieve a token logo URL from multiple sources, in this order: * 1. **Local icon map** (addressIconMap) @@ -106,9 +122,10 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { - const [symbol, decimals, logoURI] = await Promise.all([ + const [symbol, decimals, name, logoURI] = await Promise.all([ fetchSymbol(token), fetchDecimals(token), + fetchName(token), fetchTokenLogoWithFallbacks(token), ]); if (!symbol || !decimals) { @@ -118,6 +135,7 @@ export async function fetchToken(token: Address): Promise { return { symbol, decimals, + name, logo: logoURI, }; } From 4f8ded344fdb5c043b92f0755df9288ef03e8505 Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Wed, 8 Jan 2025 13:28:31 +0100 Subject: [PATCH 8/9] added name to usetoken, fied compile error --- .../meta-data-queries/fetchTokenLogoFromMoralis.ts | 10 ++++++---- src/shared/state/meta-data-queries/useToken.ts | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts index 98c348c6..2f7913dc 100644 --- a/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromMoralis.ts @@ -1,10 +1,12 @@ import Moralis from "moralis"; - import { Address } from "viem"; -await Moralis.start({ - apiKey: import.meta.env.VITE_MORALIS_API_KEY, -}); +export const StartMoralis = async () => { + await Moralis.start({ + apiKey: import.meta.env.VITE_MORALIS_API_KEY, + }); +}; +StartMoralis(); export const fetchTokenLogoFromMoralis = async (tokenAddress: Address) => { try { diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index d4febba2..3c8311c1 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -143,6 +143,7 @@ export async function fetchToken(token: Address): Promise { interface TokenHookData { symbol?: string; decimals?: number; + name?: string; logo?: string; } @@ -159,6 +160,7 @@ export const useToken = (asset?: Address): FetchData => { data: data || { symbol: undefined, decimals: undefined, + name: undefined, logo: undefined, }, }; From 4167b8457003342b03c2293107874142b442dc73 Mon Sep 17 00:00:00 2001 From: WingsDevelopment Date: Wed, 8 Jan 2025 21:00:38 +0100 Subject: [PATCH 9/9] updated --- src/app/v3/pages/ilm-details/ILMDetails.tsx | 2 +- .../fetchTokenLogoFromCoinGecko.ts | 4 +-- .../fetchTrustWalletLogoUrl.ts | 21 ------------- .../state/meta-data-queries/useToken.ts | 31 +++++++------------ 4 files changed, 14 insertions(+), 44 deletions(-) delete mode 100644 src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts diff --git a/src/app/v3/pages/ilm-details/ILMDetails.tsx b/src/app/v3/pages/ilm-details/ILMDetails.tsx index da5a94f7..da192d89 100644 --- a/src/app/v3/pages/ilm-details/ILMDetails.tsx +++ b/src/app/v3/pages/ilm-details/ILMDetails.tsx @@ -24,7 +24,7 @@ export const ILMDetails = () => { diff --git a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts index 2179d723..22503c8f 100644 --- a/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts +++ b/src/shared/state/meta-data-queries/fetchTokenLogoFromCoinGecko.ts @@ -10,14 +10,14 @@ interface CoinGeckoTokenResponse { export async function fetchTokenLogoFromCoinGecko(tokenAddress: Address): Promise { try { - const url = `https://cg-price-cache.seamlessprotocol.com/coins/base/contract/${tokenAddress}`; + const url = `${import.meta.env.VITE_COIN_GECKO_API_URL}/coins/base/contract/${tokenAddress}`; const response = await fetch(url); if (!response.ok) { return null; } const data = (await response.json()) as CoinGeckoTokenResponse; - return data.image?.thumb || null; + return data.image?.large || null; } catch (error) { console.error("Failed to fetch token logo from CoinGecko", error); return null; diff --git a/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts b/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts deleted file mode 100644 index 7f9ce8cf..00000000 --- a/src/shared/state/meta-data-queries/fetchTrustWalletLogoUrl.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Address } from "viem"; - -export function getTrustWalletLogoUrl(tokenAddress: string): string { - const baseUrl = "https://raw.githubusercontent.com/trustwallet/assets/master"; - return `${baseUrl}/blockchains/base/assets/${tokenAddress}/logo.png`; -} - -export async function fetchTokenLogoFromTrustWallet(tokenAddress: Address): Promise { - const trustWalletLogoUrl = getTrustWalletLogoUrl(tokenAddress); - try { - const resp = await fetch(trustWalletLogoUrl, { method: "HEAD" }); - if (resp.ok) { - return trustWalletLogoUrl; - } - } catch (error) { - console.error("Failed to fetch token logo from TrustWallet", error); - return null; - } - - return null; -} diff --git a/src/shared/state/meta-data-queries/useToken.ts b/src/shared/state/meta-data-queries/useToken.ts index 3c8311c1..f0a6e651 100644 --- a/src/shared/state/meta-data-queries/useToken.ts +++ b/src/shared/state/meta-data-queries/useToken.ts @@ -7,8 +7,7 @@ import { queryConfig } from "../../../app/statev3/settings/queryConfig"; import { useQuery } from "@tanstack/react-query"; import { fetchTokenLogoFromCoinGecko } from "./fetchTokenLogoFromCoinGecko"; import { fetchTokenLogoFromMoralis } from "./fetchTokenLogoFromMoralis"; -import { addressIconMap } from "@meta"; -import { fetchTokenLogoFromTrustWallet } from "./fetchTrustWalletLogoUrl"; +import { addressIconMap } from "../../../meta"; export interface Token { symbol: string; @@ -83,22 +82,6 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise fetchTokenLogoFromMoralis(token), - ...queryConfig.metadataQueryConfig, - }); - if (moralisLogo) return moralisLogo; - console.error("Could not fetch moralis logo", token); - - const trustWalletUrl = await queryClient.fetchQuery({ - queryKey: ["fetchTokenLogoFromTrustWallet", token], - queryFn: () => fetchTokenLogoFromTrustWallet(token), - ...queryConfig.metadataQueryConfig, - }); - if (trustWalletUrl) return trustWalletUrl; - console.error("Could not fetch trust wallet logo", token); - const coinGeckoUrl = await queryClient.fetchQuery({ queryKey: ["fetchTokenLogoFromCoinGecko", token], queryFn: () => fetchTokenLogoFromCoinGecko(token), @@ -107,6 +90,14 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise fetchTokenLogoFromMoralis(token), + ...queryConfig.metadataQueryConfig, + }); + if (moralisLogo) return moralisLogo; + console.error("Could not fetch moralis logo", token); + return undefined; } @@ -122,7 +113,7 @@ export async function fetchTokenLogoWithFallbacks(token: Address): Promise { - const [symbol, decimals, name, logoURI] = await Promise.all([ + const [symbol, decimals, name, logo] = await Promise.all([ fetchSymbol(token), fetchDecimals(token), fetchName(token), @@ -136,7 +127,7 @@ export async function fetchToken(token: Address): Promise { symbol, decimals, name, - logo: logoURI, + logo, }; }