From cc44c6d9d87d916921cfa5276e477ea673621aba Mon Sep 17 00:00:00 2001 From: npty Date: Wed, 8 Jan 2025 17:37:19 +0700 Subject: [PATCH 01/40] feat: support chain type vm for flow --- packages/api/src/axelarscan/isomorphic.ts | 27 +++++++----- packages/api/src/axelarscan/types.ts | 51 +++++++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/packages/api/src/axelarscan/isomorphic.ts b/packages/api/src/axelarscan/isomorphic.ts index 8f8b045d8..f77f193d6 100644 --- a/packages/api/src/axelarscan/isomorphic.ts +++ b/packages/api/src/axelarscan/isomorphic.ts @@ -1,5 +1,3 @@ -import { partition } from "rambda"; - import { RestService, type RestServiceOptions } from "../lib/rest-service"; import type { AxelarAssetPrice, @@ -10,6 +8,7 @@ import type { LinkRequestRawResponse, LinkRequestResponse, SearchBatchesResponse, + VMChainConfig, } from "./types"; export type AxelarApiParams> = T & { @@ -21,7 +20,7 @@ export type GetAssetsResponse = AxelarScanAsset[]; export type GetAssetsPriceResponse = AxelarAssetPrice[]; -export type GetChainConfigsResponse = (EVMChainConfig | CosmosChainConfig)[]; +export type GetChainConfigsResponse = (EVMChainConfig | CosmosChainConfig | VMChainConfig)[]; export class AxelarscanClient extends RestService { static init(options: RestServiceOptions) { @@ -47,18 +46,26 @@ export class AxelarscanClient extends RestService { disabledChains?: string[]; } = {} ) { - const [evm, cosmos] = partition( - (c) => c.chain_type === "evm", - await this.client.get("/api/getChains").json() - ); + const chains = await this.client + .get("/api/getChains") + .json(); - const isEligible = (a: EVMChainConfig | CosmosChainConfig) => + const isEligible = ( + a: EVMChainConfig | CosmosChainConfig | VMChainConfig + ) => (!a?.deprecated || params.isStaging) && !params.disabledChains?.includes(a.id); return { - evm: evm.filter(isEligible) as EVMChainConfig[], - cosmos: cosmos.filter(isEligible) as CosmosChainConfig[], + evm: chains.filter( + (c) => c.chain_type === "evm" && isEligible(c) + ) as EVMChainConfig[], + cosmos: chains.filter( + (c) => c.chain_type === "cosmos" && isEligible(c) + ) as CosmosChainConfig[], + vm: chains.filter( + (c) => c.chain_type === "vm" && isEligible(c) + ) as VMChainConfig[], }; } diff --git a/packages/api/src/axelarscan/types.ts b/packages/api/src/axelarscan/types.ts index 4157c651c..1e968230e 100644 --- a/packages/api/src/axelarscan/types.ts +++ b/packages/api/src/axelarscan/types.ts @@ -32,6 +32,57 @@ export type AxelarAssetPrice = Pick< updated_at: number; }; +export type VMChainConfig = { + chain_id: number; + chain_name: string; + maintainer_id: string; + deprecated?: boolean; + multisig_prover: { + address: string; + }; + voting_verifier: { + address: string; + }; + endpoints: { + rpc: string[]; + }; + native_token: { + name: string; + symbol: string; + decimals: number; + }; + name: string; + short_name: string; + image: string; + color: string; + explorer: { + name: string; + url: string; + icon: string; + block_path: string; + address_path: string; + contract_path: string; + transaction_path: string; + }; + id: string; + chain_type: "vm"; + provider_params: [ + { + chainId: string; + chainName: string; + rpcUrls: string[]; + nativeCurrency: { + name: string; + symbol: string; + decimals: number; + }; + blockExplorerUrls: string[]; + }, + ]; + no_inflation: boolean; + no_tvl: boolean; +}; + export type EVMChainConfig = { chain_id: number; chain_name: string; From ab04633a67b34ffcb2004c63781bb7acd81a543d Mon Sep 17 00:00:00 2001 From: npty Date: Wed, 8 Jan 2025 22:06:19 +0700 Subject: [PATCH 02/40] feat: add VMChainConfigs --- apps/maestro/src/server/context.ts | 8 +- .../routers/axelarscan/getEVMChainConfigs.ts | 1 - .../routers/axelarscan/getVMChainConfigs.ts | 108 ++++++++++++++++++ .../src/server/routers/axelarscan/index.ts | 2 + apps/maestro/src/server/utils.ts | 61 +++++++++- 5 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 apps/maestro/src/server/routers/axelarscan/getVMChainConfigs.ts diff --git a/apps/maestro/src/server/context.ts b/apps/maestro/src/server/context.ts index 97752de44..8939aa5cd 100644 --- a/apps/maestro/src/server/context.ts +++ b/apps/maestro/src/server/context.ts @@ -29,7 +29,7 @@ import axelarscanClient from "~/services/axelarscan"; import MaestroKVClient from "~/services/db/kv"; import MaestroPostgresClient from "~/services/db/postgres"; import gmpClient from "~/services/gmp"; -import { axelarConfigs, evmChains } from "./utils"; +import { axelarConfigs, evmChains, vmChains } from "./utils"; export interface ContextConfig { req: NextApiRequest; @@ -74,6 +74,12 @@ const createContextInner = async ({ req, res }: ContextConfig) => { axelarscanClient, "evmChains" as const ), + vmChains: vmChains.bind( + null, + maestroKVClient, + axelarscanClient, + "vmChains" as const + ), axelarConfigs: axelarConfigs.bind( null, maestroKVClient, diff --git a/apps/maestro/src/server/routers/axelarscan/getEVMChainConfigs.ts b/apps/maestro/src/server/routers/axelarscan/getEVMChainConfigs.ts index 3b851e9cc..8d98d0b58 100644 --- a/apps/maestro/src/server/routers/axelarscan/getEVMChainConfigs.ts +++ b/apps/maestro/src/server/routers/axelarscan/getEVMChainConfigs.ts @@ -73,7 +73,6 @@ export const getEVMChainConfigs = publicProcedure const chainsMap = await ctx.configs.evmChains(); const chainInfos = Object.values(chainsMap).map((chain) => chain.info); const uniqueChainInfos = uniqBy((x) => x.chain_id, chainInfos); - const validChainInfos = uniqueChainInfos.filter( (chain) => evmChainConfigSchema.safeParse(chain).success ); diff --git a/apps/maestro/src/server/routers/axelarscan/getVMChainConfigs.ts b/apps/maestro/src/server/routers/axelarscan/getVMChainConfigs.ts new file mode 100644 index 000000000..a4f002c8b --- /dev/null +++ b/apps/maestro/src/server/routers/axelarscan/getVMChainConfigs.ts @@ -0,0 +1,108 @@ +import { TRPCError } from "@trpc/server"; +import { uniqBy } from "rambda"; +import { z } from "zod"; + +import { NEXT_PUBLIC_DISABLED_CHAINS } from "~/config/env"; +import { publicProcedure } from "~/server/trpc"; + +const vmChainConfigSchema = z.object({ + id: z.string(), + chain_id: z.number(), + chain_name: z.string(), + maintainer_id: z.string(), + multisig_prover: z.object({ + address: z.string(), + }), + voting_verifier: z.object({ + address: z.string(), + }), + name: z.string(), + short_name: z.string(), + image: z.string(), + color: z.string(), + chain_type: z.literal("vm"), + no_inflation: z.boolean(), + no_tvl: z.boolean(), + endpoints: z.object({ + rpc: z.array(z.string()), + }), + native_token: z.object({ + name: z.string(), + symbol: z.string(), + decimals: z.number(), + }), + explorer: z.object({ + name: z.string(), + url: z.string(), + icon: z.string(), + block_path: z.string(), + address_path: z.string(), + contract_path: z.string(), + transaction_path: z.string(), + }), + provider_params: z.array( + z.object({ + chainId: z.string(), + chainName: z.string(), + rpcUrls: z.array(z.string()), + nativeCurrency: z.object({ + name: z.string(), + symbol: z.string(), + decimals: z.number(), + }), + blockExplorerUrls: z.array(z.string()), + }) + ), +}); + +export const getVMChainConfigs = publicProcedure + .meta({ + openapi: { + summary: "Get VM chain configs", + description: "Get VM chain configs", + method: "GET", + path: "/chain-configs/vm", + tags: ["chain-configs"], + }, + }) + .input( + z + .object({ + axelarChainId: z.string().max(64).optional(), + chainId: z.number().optional(), + }) + .optional() + ) + .output(z.array(vmChainConfigSchema)) + .query(async ({ ctx, input }) => { + try { + const chainsMap = await ctx.configs.vmChains(); + const chainInfos = Object.values(chainsMap).map((chain) => chain.info); + const uniqueChainInfos = uniqBy((x) => x.chain_id, chainInfos); + const validChainInfos = uniqueChainInfos.filter( + (chain) => vmChainConfigSchema.safeParse(chain).success + ); + + return validChainInfos + .filter( + (chain) => + // filter by axelarChainId if provided + (!input?.axelarChainId || chain.id === input?.axelarChainId) && + // filter by chainId if provided + (!input?.chainId || chain.chain_id === input?.chainId) && + // filter out disabled chains + !NEXT_PUBLIC_DISABLED_CHAINS.includes(chain.id) + ) + .sort((a, b) => a.name.localeCompare(b.name)); + } catch (error) { + // If we get a TRPC error, we throw it + if (error instanceof TRPCError) { + throw error; + } + // otherwise, we throw an internal server error + throw new TRPCError({ + code: "INTERNAL_SERVER_ERROR", + message: "Failed to get VM chain config", + }); + } + }); diff --git a/apps/maestro/src/server/routers/axelarscan/index.ts b/apps/maestro/src/server/routers/axelarscan/index.ts index 09756506a..deba6a388 100644 --- a/apps/maestro/src/server/routers/axelarscan/index.ts +++ b/apps/maestro/src/server/routers/axelarscan/index.ts @@ -2,10 +2,12 @@ import { router } from "~/server/trpc"; import { getChainConfigs } from "./getChainConfigs"; import { getCosmosChainConfigs } from "./getCosmosChainConfigs"; import { getEVMChainConfigs } from "./getEVMChainConfigs"; +import { getVMChainConfigs } from "./getVMChainConfigs"; export const axelarscanRouter = router({ getChainConfigs, getEVMChainConfigs, + getVMChainConfigs, getCosmosChainConfigs, }); diff --git a/apps/maestro/src/server/utils.ts b/apps/maestro/src/server/utils.ts index a476592ac..4fb257ccf 100644 --- a/apps/maestro/src/server/utils.ts +++ b/apps/maestro/src/server/utils.ts @@ -3,6 +3,7 @@ import { AxelarConfigsResponse, AxelarscanClient, EVMChainConfig, + VMChainConfig, } from "@axelarjs/api"; import { invariant } from "@axelarjs/utils"; @@ -20,6 +21,60 @@ export type EVMChainsMap = Record< } >; +export type VMChainsMap = Record< + string | number, + { + info: VMChainConfig; + wagmi?: ExtendedWagmiChainConfig; + } +>; + +export async function vmChains( + kvClient: MaestroKVClient, + axelarscanClient: AxelarscanClient, + cacheKey: TCacheKey +): Promise { + if (process.env.DISABLE_CACHE !== "true") { + const cached = await kvClient.getCached(cacheKey); + + if (cached) { + return cached; + } + } + + const chainConfigs = await axelarscanClient.getChainConfigs(); + + // Add flow config to the list of eligible chains + const vmChainsMap = chainConfigs.vm.reduce((acc, chain) => { + const wagmiConfig = WAGMI_CHAIN_CONFIGS.find( + (config) => config.id === chain.chain_id + ); + + const entry = { + info: chain, + wagmi: wagmiConfig, + }; + + return { + ...acc, + [chain.id]: entry, + [chain.chain_id]: entry, + }; + }, + {} as Record< + string | number, + { + info: VMChainConfig; + wagmi?: ExtendedWagmiChainConfig; + } + > + ); + + // cache for 1 hour + await kvClient.setCached(cacheKey, vmChainsMap, 3600); + + return vmChainsMap; +} export async function evmChains( kvClient: MaestroKVClient, axelarscanClient: AxelarscanClient, @@ -37,11 +92,9 @@ export async function evmChains( const configuredIDs = WAGMI_CHAIN_CONFIGS.map((chain) => chain.id); - const eligibleChains = chainConfigs.evm.filter((chain) => - // filter out chains that are do not have a wagmi config - configuredIDs.includes(chain.chain_id) - ); + const eligibleChains = chainConfigs.evm.filter((chain) => configuredIDs.includes(chain.chain_id)); + // Add flow config to the list of eligible chains const evmChainsMap = eligibleChains.reduce( (acc, chain) => { const wagmiConfig = WAGMI_CHAIN_CONFIGS.find( From 9c49e670edcae2bea719a4836b9700ad35955bfc Mon Sep 17 00:00:00 2001 From: npty Date: Wed, 8 Jan 2025 22:36:17 +0700 Subject: [PATCH 03/40] feat: refactor EVMChainsDropdown to support all chains --- apps/maestro/package.json | 1 + .../RegisteredInterchainTokenCard.tsx | 2 +- .../UnregisteredInterchainTokenCard.tsx | 2 +- .../actions/mint/MintInterchainToken.tsx | 4 +- .../SearchInterchainToken.tsx | 10 +- .../SendInterchainToken.spec.tsx | 2 +- .../SendInterchainToken.tsx | 6 +- .../features/Transactions/Transactions.tsx | 2 +- apps/maestro/src/services/axelarscan/hooks.ts | 47 ++++++- .../ChainsDropdown/ChainsDropdown.state.tsx | 57 ++++++++ .../ChainsDropdown.tsx} | 122 ++++++++++++------ .../src/ui/components/ChainsDropdown/index.ts | 2 + .../EVMChainsDropdown.state.tsx | 40 ------ .../ui/components/EVMChainsDropdown/index.ts | 2 - .../GMPTxStatusMonitor/GMPTxStatusMonitor.tsx | 2 +- .../compounds/MultiStepForm/MultiStepForm.tsx | 4 +- .../src/ui/layouts/MainLayout/Appbar.tsx | 6 +- apps/maestro/src/ui/layouts/Page.tsx | 38 ++++-- .../TokenDetailsSection.tsx | 2 +- .../pages/InterchainTokensPage/TokenList.tsx | 2 +- 20 files changed, 239 insertions(+), 114 deletions(-) create mode 100644 apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.state.tsx rename apps/maestro/src/ui/components/{EVMChainsDropdown/EVMChainsDropdown.tsx => ChainsDropdown/ChainsDropdown.tsx} (64%) create mode 100644 apps/maestro/src/ui/components/ChainsDropdown/index.ts delete mode 100644 apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.state.tsx delete mode 100644 apps/maestro/src/ui/components/EVMChainsDropdown/index.ts diff --git a/apps/maestro/package.json b/apps/maestro/package.json index 98ea71fda..06713336e 100644 --- a/apps/maestro/package.json +++ b/apps/maestro/package.json @@ -115,6 +115,7 @@ "typescript": "^5.4.3", "vite": "^5.2.6", "vitest": "^1.4.0", + "web-streams-polyfill": "^4.1.0", "zx": "^7.2.3" } } diff --git a/apps/maestro/src/features/InterchainTokenList/RegisteredInterchainTokenCard.tsx b/apps/maestro/src/features/InterchainTokenList/RegisteredInterchainTokenCard.tsx index caa89f675..e4ca2bff3 100644 --- a/apps/maestro/src/features/InterchainTokenList/RegisteredInterchainTokenCard.tsx +++ b/apps/maestro/src/features/InterchainTokenList/RegisteredInterchainTokenCard.tsx @@ -24,7 +24,7 @@ import { dexLinks } from "~/config/dex"; import { NEXT_PUBLIC_NETWORK_ENV, shouldDisableSend } from "~/config/env"; import { useInterchainTokenBalanceForOwnerQuery } from "~/services/interchainToken/hooks"; import BigNumberText from "~/ui/components/BigNumberText"; -import { ChainIcon } from "~/ui/components/EVMChainsDropdown"; +import { ChainIcon } from "~/ui/components/ChainsDropdown"; import { AcceptInterchainTokenOwnership } from "../AcceptInterchainTokenOwnership"; import ManageInterchainToken from "../ManageInterchainToken/ManageInterchainToken"; import { SendInterchainToken } from "../SendInterchainToken"; diff --git a/apps/maestro/src/features/InterchainTokenList/UnregisteredInterchainTokenCard.tsx b/apps/maestro/src/features/InterchainTokenList/UnregisteredInterchainTokenCard.tsx index b518268cc..849f5899c 100644 --- a/apps/maestro/src/features/InterchainTokenList/UnregisteredInterchainTokenCard.tsx +++ b/apps/maestro/src/features/InterchainTokenList/UnregisteredInterchainTokenCard.tsx @@ -1,7 +1,7 @@ import { Card, cn, Indicator } from "@axelarjs/ui"; import { type FC } from "react"; -import { ChainIcon } from "~/ui/components/EVMChainsDropdown"; +import { ChainIcon } from "~/ui/components/ChainsDropdown"; import { GMPStatusIndicator } from "~/ui/compounds/GMPTxStatusMonitor"; import type { TokenInfo } from "./types"; diff --git a/apps/maestro/src/features/ManageInterchainToken/actions/mint/MintInterchainToken.tsx b/apps/maestro/src/features/ManageInterchainToken/actions/mint/MintInterchainToken.tsx index aae18ed7e..4b1a8f9ec 100644 --- a/apps/maestro/src/features/ManageInterchainToken/actions/mint/MintInterchainToken.tsx +++ b/apps/maestro/src/features/ManageInterchainToken/actions/mint/MintInterchainToken.tsx @@ -9,7 +9,7 @@ import { useChainId } from "wagmi"; import { logger } from "~/lib/logger"; import { preventNonNumericInput } from "~/lib/utils/validation"; -import EVMChainsDropdown from "~/ui/components/EVMChainsDropdown"; +import ChainsDropdown from "~/ui/components/ChainsDropdown"; import { useMintInterchainTokenState } from "./MintInterchainToken.state"; type FormState = { @@ -95,7 +95,7 @@ export const MintInterchainToken: FC = () => { <> Mint interchain tokens on - +
= (props) => { {isLoading && isAddress(search) ? ( ) : ( - = (props) => { operate in controlled mode */}
- ({ default: () =>
GMPTxStatusMonitor
, })); -vi.mock("~/ui/components/EVMChainsDropdown/index.ts", () => ({ +vi.mock("~/ui/components/ChainsDropdown/index.ts", () => ({ default: () =>
EVMChainsDropdown
, })); diff --git a/apps/maestro/src/features/SendInterchainToken/SendInterchainToken.tsx b/apps/maestro/src/features/SendInterchainToken/SendInterchainToken.tsx index 4587a102d..7d5d6350f 100644 --- a/apps/maestro/src/features/SendInterchainToken/SendInterchainToken.tsx +++ b/apps/maestro/src/features/SendInterchainToken/SendInterchainToken.tsx @@ -19,7 +19,7 @@ import { formatUnits, parseUnits } from "viem"; import { logger } from "~/lib/logger"; import { preventNonNumericInput } from "~/lib/utils/validation"; import BigNumberText from "~/ui/components/BigNumberText"; -import EVMChainsDropdown from "~/ui/components/EVMChainsDropdown"; +import ChainsDropdown from "~/ui/components/ChainsDropdown"; import GMPTxStatusMonitor from "~/ui/compounds/GMPTxStatusMonitor"; import { ShareHaikuButton } from "~/ui/compounds/MultiStepForm"; import { useSendInterchainTokenState } from "./SendInterchainToken.state"; @@ -226,7 +226,7 @@ export const SendInterchainToken: FC = (props) => {
- = (props) => {
- (undefined, { + staleTime: 1000 * 60 * 60, // 1 hour + refetchOnWindowFocus: false, + }); + + // Filter out chains that are not configured in the app + const [configured, unconfigured] = useMemo( + () => partition((x) => x.chain_id in VM_CHAIN_CONFIGS_BY_ID, data ?? []), + [data] + ); + + if (NEXT_PUBLIC_NETWORK_ENV !== "mainnet" && unconfigured?.length) { + logger.once.info( + `excluded ${unconfigured?.length} VM chain configs:\n${unconfigured + ?.map((x) => + JSON.stringify( + { + chain_id: x.chain_id, + name: x.name, + }, + null, + 2 + ) + ) + .join("\n")}` + ); + } + + const vmChains = configured.map( + (x) => VM_CHAIN_CONFIGS_BY_ID[x.chain_id] + ); + + return { + ...queryResult, + data: configured, + computed: { + indexedByChainId: indexBy(prop("chain_id"), configured), + indexedById: indexBy(prop("id"), configured), + vmChains, + }, + }; +} + export function useCosmosChainConfigsQuery() { return trpc.axelarscan.getCosmosChainConfigs.useQuery(); } diff --git a/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.state.tsx b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.state.tsx new file mode 100644 index 000000000..1b4de85d9 --- /dev/null +++ b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.state.tsx @@ -0,0 +1,57 @@ +import { createContainer, useSessionStorageState } from "@axelarjs/utils/react"; +import { type FC } from "react"; + +export const INITIAL_STATE = { + selectedChainId: null as number | null, + selectedChainType: null as "evm" | "vm" | null, +}; + +function useChainsDropdownState(initialState = INITIAL_STATE) { + const [state, setState] = useSessionStorageState( + "@maestro/chains-dropdown", + initialState + ); + + const actions = { + selectChainId: (chainId: number | null, chainType?: "evm" | "vm" | null) => { + setState((state) => { + state.selectedChainId = chainId; + if (chainType !== undefined) { + state.selectedChainType = chainType; + } + }); + }, + setChainType: (chainType: "evm" | "vm" | null) => { + setState((state) => { + state.selectedChainType = chainType; + }); + }, + }; + + return [state, actions] as const; +} + +export const { + Provider: ChainsDropdownProvider, + useContainer: useChainsDropdownContainer, +} = createContainer(useChainsDropdownState); + +export function withChainsDropdownProvider(Component: FC) { + const Inner = (props: TProps) => ( + + + + ); + Inner.displayName = `withChainsDropdownProvider(${ + Component.displayName ?? Component.name ?? "Component" + })`; + return Inner; +} + +// For backwards compatibility (if needed) +export const { + Provider: EVMChainsDropdownProvider, + useContainer: useEVMChainsDropdownContainer, +} = createContainer(useChainsDropdownState); + +export const withEVMChainsDropdownProvider = withChainsDropdownProvider; diff --git a/apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.tsx b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx similarity index 64% rename from apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.tsx rename to apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx index 6e447e49d..5e234b26f 100644 --- a/apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.tsx +++ b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx @@ -1,4 +1,4 @@ -import type { EVMChainConfig } from "@axelarjs/api/axelarscan"; +import type { EVMChainConfig, VMChainConfig } from "@axelarjs/api/axelarscan"; import { Dropdown, HelpCircleIcon } from "@axelarjs/ui"; import { toast } from "@axelarjs/ui/toaster"; import { cn } from "@axelarjs/ui/utils"; @@ -11,11 +11,14 @@ import { TransactionExecutionError } from "viem"; import { useAccount, useSwitchChain } from "wagmi"; import { logger } from "~/lib/logger"; -import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; import { - useEVMChainsDropdownContainer, - withEVMChainsDropdownProvider, -} from "./EVMChainsDropdown.state"; + useEVMChainConfigsQuery, + useVMChainConfigsQuery, +} from "~/services/axelarscan/hooks"; +import { + useChainsDropdownContainer, + withChainsDropdownProvider, +} from "./ChainsDropdown.state"; const ICON_SIZES = { xs: 14, @@ -50,8 +53,10 @@ export const ChainIcon: FC<{ ); }; +type ChainConfig = EVMChainConfig | VMChainConfig; + type Props = { - chains?: EVMChainConfig[]; + chains?: ChainConfig[]; compact?: boolean; hideLabel?: boolean; disabled?: boolean; @@ -59,23 +64,31 @@ type Props = { chainIconClassName?: string; contentClassName?: string; renderTrigger?: () => React.ReactNode; - selectedChain?: EVMChainConfig; - onSelectChain?: (chain: EVMChainConfig | null) => void; + selectedChain?: ChainConfig; + onSelectChain?: (chain: ChainConfig | null) => void; size?: keyof typeof ICON_SIZES; + chainType?: "evm" | "vm"; }; -export const EVMChainIcon: FC = (props) => { +export const ChainIconComponent: FC = (props) => { const { data: evmChains } = useEVMChainConfigsQuery(); + const { data: vmChains } = useVMChainConfigsQuery(); const { chain } = useAccount(); - const [state] = useEVMChainsDropdownContainer(); + const [state] = useChainsDropdownContainer(); + + const chains = useMemo(() => { + if (props.chainType === "vm") return vmChains; + if (props.chainType === "evm") return evmChains; + return [...(evmChains ?? []), ...(vmChains ?? [])]; + }, [evmChains, vmChains, props.chainType]); const selectedChain = useMemo( () => - Maybe.of(evmChains).mapOrUndefined( + Maybe.of(chains).mapOrUndefined( find((x) => [chain?.id, state.selectedChainId].includes(x.chain_id)) ), - [chain?.id, evmChains, state.selectedChainId] + [chain?.id, chains, state.selectedChainId] ); if (props.selectedChain && props.onSelectChain) { @@ -121,26 +134,52 @@ export const EVMChainIcon: FC = (props) => { } }; -const EVMChainsDropdown: FC = (props) => { +const ChainsDropdown: FC = (props) => { const { data: evmChains } = useEVMChainConfigsQuery(); + const { data: vmChains } = useVMChainConfigsQuery(); const { chain } = useAccount(); const { switchChainAsync } = useSwitchChain(); - const [state, actions] = useEVMChainsDropdownContainer(); + const [state, actions] = useChainsDropdownContainer(); + + const chains = useMemo(() => { + // Create a lookup map using chain_id as the key + const chainMap = new Map(); + + // Process EVM chains first + evmChains?.forEach((chain) => { + chainMap.set(chain.chain_id, { + ...chain, + displayName: chain.name, // Store original name + }); + }); + + // Process VM chains, only add if not already present or if it's a special case + vmChains?.forEach((chain) => { + const existingChain = chainMap.get(chain.chain_id); + if (!existingChain) { + chainMap.set(chain.chain_id, { + ...chain, + displayName: `${chain.name} (VM)`, // Add VM suffix to differentiate + }); + } + }); + + return Array.from(chainMap.values()); + }, [evmChains, vmChains, props.chainType]); const selectedChain = useMemo( () => - Maybe.of(evmChains).mapOrUndefined( + Maybe.of(chains).mapOrUndefined( find((x) => [chain?.id, state.selectedChainId].includes(x.chain_id)) ), - [chain?.id, evmChains, state.selectedChainId] + [chain?.id, chains, state.selectedChainId] ); - const eligibleChains = Maybe.of(props.chains ?? evmChains).mapOr( - [], - (chains) => - chains.filter((chain) => chain.chain_id !== selectedChain?.chain_id) - ); + // const eligibleChains = Maybe.of(props.chains ?? chains).mapOr([], (chains) => + // chains.filter((chain) => chain.chain_id !== selectedChain?.chain_id) + // ); + const eligibleChains = Maybe.of(props.chains ?? chains).mapOr([], (chains) => chains.filter((chain) => chain.chain_id !== selectedChain?.chain_id)); const handleChainChange = async (chainId: number) => { try { @@ -149,9 +188,17 @@ const EVMChainsDropdown: FC = (props) => { eligibleChains.find(propEq(chainId, "chain_id")) ?? null ); } else { - await switchChainAsync?.({ chainId }); - if (!chain) { - // only update state if not connected to a chain + // Only attempt to switch chain if it's an EVM chain + const isEVMChain = evmChains?.some( + (chain) => chain.chain_id === chainId + ); + if (isEVMChain) { + await switchChainAsync?.({ chainId }); + if (!chain) { + actions.selectChainId(chainId); + } + } else { + // Handle VM chain selection actions.selectChainId(chainId); } } @@ -185,10 +232,7 @@ const EVMChainsDropdown: FC = (props) => { )} tabIndex={props.compact ? -1 : 0} > - {/* if both selectedChain and onSelectedChain exist, - operate in controlled mode - */} - + )} @@ -205,22 +249,20 @@ const EVMChainsDropdown: FC = (props) => { > {!chain && ( - { + )} {eligibleChains.map((chain) => ( @@ -231,19 +273,18 @@ const EVMChainsDropdown: FC = (props) => { chain.chain_id === selectedChain?.chain_id, })} > - { + ))} @@ -251,4 +292,5 @@ const EVMChainsDropdown: FC = (props) => { ); }; -export default withEVMChainsDropdownProvider(EVMChainsDropdown); + +export default withChainsDropdownProvider(ChainsDropdown); diff --git a/apps/maestro/src/ui/components/ChainsDropdown/index.ts b/apps/maestro/src/ui/components/ChainsDropdown/index.ts new file mode 100644 index 000000000..d560d4d1b --- /dev/null +++ b/apps/maestro/src/ui/components/ChainsDropdown/index.ts @@ -0,0 +1,2 @@ +export * from "./ChainsDropdown"; +export { default } from "./ChainsDropdown"; diff --git a/apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.state.tsx b/apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.state.tsx deleted file mode 100644 index db0d69e8a..000000000 --- a/apps/maestro/src/ui/components/EVMChainsDropdown/EVMChainsDropdown.state.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { createContainer, useSessionStorageState } from "@axelarjs/utils/react"; -import { type FC } from "react"; - -export const INITIAL_STATE = { - selectedChainId: null as number | null, -}; - -function useEVMChainsDropdownState(initialState = INITIAL_STATE) { - const [state, setState] = useSessionStorageState( - "@maestro/evm-chains-dropdown", - initialState - ); - - const actions = { - selectChainId: (chainId: number | null) => { - setState((state) => { - state.selectedChainId = chainId; - }); - }, - }; - - return [state, actions] as const; -} - -export const { - Provider: EVMChainsDropdownProvider, - useContainer: useEVMChainsDropdownContainer, -} = createContainer(useEVMChainsDropdownState); - -export function withEVMChainsDropdownProvider(Component: FC) { - const Inner = (props: TProps) => ( - - - - ); - Inner.displayName = `withEVMChainsDropdownProvider(${ - Component.displayName ?? Component.name ?? "Component" - })`; - return Inner; -} diff --git a/apps/maestro/src/ui/components/EVMChainsDropdown/index.ts b/apps/maestro/src/ui/components/EVMChainsDropdown/index.ts deleted file mode 100644 index 843645e45..000000000 --- a/apps/maestro/src/ui/components/EVMChainsDropdown/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./EVMChainsDropdown"; -export { default } from "./EVMChainsDropdown"; diff --git a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx index 8df17a9a9..c726e0198 100644 --- a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx +++ b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx @@ -11,7 +11,7 @@ import { NEXT_PUBLIC_EXPLORER_URL } from "~/config/env"; import { useChainInfoQuery } from "~/services/axelarjsSDK/hooks"; import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; import { useGetTransactionStatusOnDestinationChainsQuery } from "~/services/gmp/hooks"; -import { ChainIcon } from "~/ui/components/EVMChainsDropdown"; +import { ChainIcon } from "~/ui/components/ChainsDropdown"; export type ExtendedGMPTxStatus = GMPTxStatus | "pending"; diff --git a/apps/maestro/src/ui/compounds/MultiStepForm/MultiStepForm.tsx b/apps/maestro/src/ui/compounds/MultiStepForm/MultiStepForm.tsx index 583d5efb8..5a4456f1c 100644 --- a/apps/maestro/src/ui/compounds/MultiStepForm/MultiStepForm.tsx +++ b/apps/maestro/src/ui/compounds/MultiStepForm/MultiStepForm.tsx @@ -33,7 +33,7 @@ import { useAccount } from "wagmi"; import { trpc } from "~/lib/trpc"; import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; -import EVMChainsDropdown from "~/ui/components/EVMChainsDropdown"; +import ChainsDropdownComponent from "~/ui/components/ChainsDropdown"; import ConnectWalletButton from "../ConnectWalletButton"; type ButtonProps = ComponentProps; @@ -126,7 +126,7 @@ export const ChainsDropdown: FC<{ disabled?: boolean; shift?: boolean }> = ( ) => { const { width } = useWindowSize(); return ( - = (props) => { <> {isConnected && address ? ( <> - @@ -186,7 +186,7 @@ const Appbar: FC = (props) => {
{isConnected && address ? ( <> - +
)}
- ( ); })}
-
From a41ab6c20ec3ef80068e31463dd23748faa8b443 Mon Sep 17 00:00:00 2001 From: npty Date: Thu, 9 Jan 2025 13:04:54 +0700 Subject: [PATCH 06/40] chore: bump axelarjs-sdk to latest to fix gas estimation for flow --- apps/maestro/package.json | 2 +- pnpm-lock.yaml | 315 ++++++++++++++++++++++++++++++++------ 2 files changed, 270 insertions(+), 47 deletions(-) diff --git a/apps/maestro/package.json b/apps/maestro/package.json index 06713336e..985cf00e7 100644 --- a/apps/maestro/package.json +++ b/apps/maestro/package.json @@ -34,7 +34,7 @@ "release": "tsx scripts/release.ts" }, "dependencies": { - "@axelar-network/axelarjs-sdk": "0.15.0", + "@axelar-network/axelarjs-sdk": "0.17.1-alpha.10", "@axelarjs/api": "workspace:*", "@axelarjs/core": "workspace:*", "@axelarjs/evm": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c12582c23..0bdc1d40e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,8 +93,8 @@ importers: apps/maestro: dependencies: '@axelar-network/axelarjs-sdk': - specifier: 0.15.0 - version: 0.15.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) + specifier: 0.17.1-alpha.10 + version: 0.17.1-alpha.10(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3) '@axelarjs/api': specifier: workspace:* version: link:../../packages/api @@ -330,6 +330,9 @@ importers: vitest: specifier: ^1.4.0 version: 1.4.0(@types/node@20.11.30)(happy-dom@13.10.1)(terser@5.37.0) + web-streams-polyfill: + specifier: ^4.1.0 + version: 4.1.0 zx: specifier: ^7.2.3 version: 7.2.3 @@ -344,7 +347,7 @@ importers: version: link:../../packages/utils next: specifier: ^14.1.4 - version: 14.1.4(@babel/core@7.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 14.1.4(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 version: 18.3.1 @@ -1025,6 +1028,20 @@ importers: packages: + '@0no-co/graphql.web@1.0.13': + resolution: {integrity: sha512-jqYxOevheVTU1S36ZdzAkJIdvRp2m3OYIG5SEoKDw5NI8eVwkoI0D/Q3DYNGmXCxkA6CQuoa7zvMiDPTLqUNuw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@0no-co/graphqlsp@1.12.16': + resolution: {integrity: sha512-B5pyYVH93Etv7xjT6IfB7QtMBdaaC07yjbhN6v8H7KgFStMkPvi+oWYBTibMFRMY89qwc9H8YixXg8SXDVgYWw==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + '@aashutoshrathi/word-wrap@1.2.6': resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} @@ -1054,10 +1071,6 @@ packages: peerDependencies: zod: ^3.20.2 - '@axelar-network/axelar-cgp-solidity@4.5.0': - resolution: {integrity: sha512-4F4rmHei0cmzeUR7/mW4Bap5rc/KlPV2crD9HA7HTRfl15mVcN6/3z8p+pAm9We6bOrQplNW9KBZ3HJFP3C1Gw==} - engines: {node: ^16.0.0 || ^18.0.0} - '@axelar-network/axelar-cgp-solidity@6.4.0': resolution: {integrity: sha512-Xnw5xi234B1cmTCzgudV8zq+DDjJ1d1U362CM0vKH1FWmZprKIdqgmOYkiRyu+QiVhnznKiBURiSEHVrNjtYpw==} engines: {node: '>=18'} @@ -1070,8 +1083,8 @@ packages: resolution: {integrity: sha512-o8pv+krIAlEwzid0Ac8qwykDsavc+1DRPvyFQ3V0R0zTQFtYLJIIXXXt7FRb8b+LJDAuX+E0bB3N2X+hlcxk/g==} engines: {node: '>=18'} - '@axelar-network/axelarjs-sdk@0.15.0': - resolution: {integrity: sha512-7DSO/loMu/3p592WZ7rXtL0uUyLgSi5c7JH26OCR2WElzhobScM6twb1JUi+Gu9u3OcrFPJZyBLd/COIVY6S7A==} + '@axelar-network/axelarjs-sdk@0.17.1-alpha.10': + resolution: {integrity: sha512-ZWpTAfnIPsc37UZuZJeobYErq0d9J27n9GDgv/D60cTFdLi06wak8/7zIt0v0HJnzgKVSUG1J27qDum4nbPRKQ==} '@axelar-network/axelarjs-types@0.33.0': resolution: {integrity: sha512-aCbX/5G+tgWPjr9tl3dQfJftWwRMkILz61ytach7dKqxtO9G9jlxpNvELJQ6gKVOodUtSY8qBCO/fWU19v4hdQ==} @@ -2066,6 +2079,7 @@ packages: '@confio/ics23@0.6.8': resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==} + deprecated: Unmaintained. The codebase for this package was moved to https://github.com/cosmos/ics23 but then the JS implementation was removed in https://github.com/cosmos/ics23/pull/353. Please consult the maintainers of https://github.com/cosmos for further assistance. '@cosmjs/amino@0.31.3': resolution: {integrity: sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw==} @@ -3252,6 +3266,31 @@ packages: '@floating-ui/utils@0.2.8': resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} + '@gql.tada/cli-utils@1.6.3': + resolution: {integrity: sha512-jFFSY8OxYeBxdKi58UzeMXG1tdm4FVjXa8WHIi66Gzu9JWtCE6mqom3a8xkmSw+mVaybFW5EN2WXf1WztJVNyQ==} + peerDependencies: + '@0no-co/graphqlsp': ^1.12.13 + '@gql.tada/svelte-support': 1.0.1 + '@gql.tada/vue-support': 1.0.1 + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + '@gql.tada/svelte-support': + optional: true + '@gql.tada/vue-support': + optional: true + + '@gql.tada/internal@1.0.8': + resolution: {integrity: sha512-XYdxJhtHC5WtZfdDqtKjcQ4d7R1s0d1rnlSs3OcBEUbYiPoJJfZU7tWsVXuv047Z6msvmr4ompJ7eLSK5Km57g==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@hapi/bourne@3.0.0': resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} @@ -3549,6 +3588,13 @@ packages: resolution: {integrity: sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==} deprecated: Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion + '@mysten/bcs@1.2.0': + resolution: {integrity: sha512-LuKonrGdGW7dq/EM6U2L9/as7dFwnhZnsnINzB/vu08Xfrj0qzWwpLOiXagAa5yZOPLK7anRZydMonczFkUPzA==} + + '@mysten/sui@1.18.0': + resolution: {integrity: sha512-cFh5LxXZrXb/ZAD1dkKeQxzhgRYFXreyFGmI7w/JQWwdl+/0FrHJBwaWyTmGxJ/6ZC9SlaOPOk63flN7DbUurg==} + engines: {node: '>=18'} + '@neondatabase/serverless@0.7.2': resolution: {integrity: sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==} @@ -4581,6 +4627,10 @@ packages: resolution: {integrity: sha512-x0PYIMWcsTauqxgl7vWUY6sANl+XGKtx7DCVnnY7aOIIlIna0jChTAPANTfA2QrK+VK+4I/4JxatCEZBnXh3Og==} engines: {node: '>= 8'} + '@simplewebauthn/typescript-types@7.4.0': + resolution: {integrity: sha512-8/ZjHeUPe210Bt5oyaOIGx4h8lHdsQs19BiOT44gi/jBEgK7uBGA0Fy7NRsyh777al3m6WM0mBf0UR7xd4R7WQ==} + deprecated: This package has been renamed to @simplewebauthn/types. Please install @simplewebauthn/types instead to ensure you receive future updates. + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -4651,6 +4701,15 @@ packages: '@stablelib/x25519@1.0.3': resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} + '@stellar/js-xdr@3.1.2': + resolution: {integrity: sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==} + + '@stellar/stellar-base@13.0.1': + resolution: {integrity: sha512-Xbd12mc9Oj/130Tv0URmm3wXG77XMshZtZ2yNCjqX5ZbMD5IYpbBs3DVCteLU/4SLj/Fnmhh1dzhrQXnk4r+pQ==} + + '@stellar/stellar-sdk@13.1.0': + resolution: {integrity: sha512-ARQkUdyGefXdTgwSF0eONkzv/geAqUfyfheJ9Nthz6GAr5b41fNwWW9UtE8JpXC4IpvE3t5elIUN5hKJzASN9w==} + '@storybook/addon-actions@8.4.7': resolution: {integrity: sha512-mjtD5JxcPuW74T6h7nqMxWTvDneFtokg88p6kQ5OnC1M259iAXb//yiSZgu/quunMHPCXSiqn4FNOSgASTSbsA==} peerDependencies: @@ -4860,6 +4919,9 @@ packages: peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@suchipi/femver@1.0.0': + resolution: {integrity: sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==} + '@svgr/babel-plugin-add-jsx-attribute@7.0.0': resolution: {integrity: sha512-khWbXesWIP9v8HuKCl2NU2HNAyqpSQ/vkIl36Nbn4HIwEYSRWL0H7Gs6idJdha2DkpFDWlsqMELvoCE8lfFY6Q==} engines: {node: '>=14'} @@ -5696,6 +5758,7 @@ packages: '@web3modal/core@4.2.3': resolution: {integrity: sha512-UykKZTELBpb6ey+IV6fkHWsLkjrIdILmRYzhlznyTPbm9qX5pOR9tH0Z3QGUo7YPFmUqMRH1tC9Irsr3SgIbbw==} + deprecated: Web3Modal is now Reown AppKit. Please follow the upgrade guide at https://docs.reown.com/appkit/upgrade/from-w3m-to-reown '@web3modal/polyfills@4.2.3': resolution: {integrity: sha512-RiGxh2hMLSD1s2aTjoejNK/UL377CJhGf5tzmdF1m5xsYHpil+Dnulpio8Yojnm27cOqQD+QiaYUKnHOxErLjQ==} @@ -5727,9 +5790,11 @@ packages: '@web3modal/siwe@4.2.3': resolution: {integrity: sha512-uPma0U/OxAy3LwnF7pCYYX8tn+ONBYNcssuVZxEGsusJD1kF4ueS8lK7eyQogyK5nXqOGdNESOjY1NImNNjMVw==} + deprecated: Web3Modal is now Reown AppKit. Please follow the upgrade guide at https://docs.reown.com/appkit/upgrade/from-w3m-to-reown '@web3modal/ui@4.2.3': resolution: {integrity: sha512-QPPgE0hii1gpAldTdnrP63D/ryI78Ohz99zRBp8vi81lawot7rbdUbryMoX13hMPCW9vW7JYyvX+jJN7uO3QwA==} + deprecated: Web3Modal is now Reown AppKit. Please follow the upgrade guide at https://docs.reown.com/appkit/upgrade/from-w3m-to-reown '@web3modal/wagmi@4.2.3': resolution: {integrity: sha512-oisBCMrOYn8TBgNaSPrumvMmTGox6+3Ii92zxQJalW5U/K9iBTxoejHT033Ss7mFEFybilcfXBAvGNFXfQmtkA==} @@ -6102,6 +6167,13 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base-x@5.0.0: + resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} + + base32.js@0.1.0: + resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} + engines: {node: '>=0.12.0'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -6174,6 +6246,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -7445,6 +7520,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource@2.0.2: + resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} + engines: {node: '>=12.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -7531,6 +7610,9 @@ packages: picomatch: optional: true + feaxios@0.0.23: + resolution: {integrity: sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g==} + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -7867,6 +7949,12 @@ packages: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} + gql.tada@1.8.10: + resolution: {integrity: sha512-FrvSxgz838FYVPgZHGOSgbpOjhR+yq44rCzww3oOPJYi0OvBJjAgCiP6LEokZIYND2fUTXzQAyLgcvgw1yNP5A==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -7879,6 +7967,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.10.0: + resolution: {integrity: sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gzip-size@6.0.0: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} @@ -8322,6 +8414,10 @@ packages: resolution: {integrity: sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==} engines: {node: '>= 0.4'} + is-retry-allowed@3.0.0: + resolution: {integrity: sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==} + engines: {node: '>=12'} + is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} @@ -8534,6 +8630,9 @@ packages: jose@4.15.9: resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + jose@5.9.6: + resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -9884,6 +9983,9 @@ packages: resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} engines: {node: '>=12.0.0'} + poseidon-lite@0.2.1: + resolution: {integrity: sha512-xIr+G6HeYfOhCuswdqcFpSX47SPhm0EpisWJ6h7fHlWwaVIvH3dLnejpatrtw6Xc6HaLrpq05y7VRfvDmDGIog==} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -10806,6 +10908,9 @@ packages: resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} engines: {node: '>=10.0.0'} + sodium-native@4.3.1: + resolution: {integrity: sha512-YdP64gAdpIKHfL4ttuX4aIfjeunh9f+hNeQJpE9C8UMndB3zkgZ7YmmGT4J2+v6Ibyp6Wem8D1TcSrtdW0bqtg==} + sonic-boom@2.8.0: resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} @@ -11272,6 +11377,9 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -11439,6 +11547,9 @@ packages: resolution: {integrity: sha512-r02GtNmkOPcQvUzVE6lg474QVLyU02r3yh3lUGqrFHf5h5ZEjgDGWILsAUqplVqjri1Y/oOkTssks4CObTAaiw==} hasBin: true + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -11707,6 +11818,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} @@ -11769,6 +11883,9 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + valibot@0.36.0: + resolution: {integrity: sha512-CjF1XN4sUce8sBK9TixrDqFM7RwNkuXdJu174/AwmQUB62QbCQADg5lLe8ldBalFgtj1uKj+pKwDJiNo4Mn+eQ==} + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -11963,6 +12080,10 @@ packages: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} + web-streams-polyfill@4.1.0: + resolution: {integrity: sha512-A7Jxrg7+eV+eZR/CIdESDnRGFb6/bcKukGvJBB5snI6cw3is1c2qamkYstC1bY1p08TyMRlN9eTMkxmnKJBPBw==} + engines: {node: '>= 8'} + web-tree-sitter@0.24.3: resolution: {integrity: sha512-uR9YNewr1S2EzPKE+y39nAwaTyobBaZRG/IsfkB/OT4v0lXtNj5WjtHKgn2h7eOYUWIZh5rK9Px7tI6S9CRKdA==} @@ -12302,6 +12423,16 @@ packages: snapshots: + '@0no-co/graphql.web@1.0.13(graphql@16.10.0)': + optionalDependencies: + graphql: 16.10.0 + + '@0no-co/graphqlsp@1.12.16(graphql@16.10.0)(typescript@5.4.3)': + dependencies: + '@gql.tada/internal': 1.0.8(graphql@16.10.0)(typescript@5.4.3) + graphql: 16.10.0 + typescript: 5.4.3 + '@aashutoshrathi/word-wrap@1.2.6': {} '@adobe/css-tools@4.3.3': {} @@ -12324,8 +12455,6 @@ snapshots: openapi3-ts: 4.4.0 zod: 3.24.1 - '@axelar-network/axelar-cgp-solidity@4.5.0': {} - '@axelar-network/axelar-cgp-solidity@6.4.0': dependencies: '@axelar-network/axelar-gmp-sdk-solidity': 5.10.0 @@ -12334,15 +12463,17 @@ snapshots: '@axelar-network/axelar-gmp-sdk-solidity@6.0.4': {} - '@axelar-network/axelarjs-sdk@0.15.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)': + '@axelar-network/axelarjs-sdk@0.17.1-alpha.10(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3)': dependencies: - '@axelar-network/axelar-cgp-solidity': 4.5.0 + '@axelar-network/axelar-cgp-solidity': 6.4.0 '@axelar-network/axelarjs-types': 0.33.0 '@cosmjs/json-rpc': 0.30.1 '@cosmjs/stargate': 0.31.0-alpha.1(bufferutil@4.0.8)(utf-8-validate@6.0.3) '@ethersproject/abstract-provider': 5.7.0 '@ethersproject/networks': 5.7.1 '@ethersproject/providers': 5.7.2(bufferutil@4.0.8)(utf-8-validate@6.0.3) + '@mysten/sui': 1.18.0(typescript@5.4.3) + '@stellar/stellar-sdk': 13.1.0 '@types/uuid': 8.3.4 bech32: 2.0.0 clone-deep: 4.0.1 @@ -12354,10 +12485,13 @@ snapshots: uuid: 8.3.2 ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' - bufferutil - debug - encoding - supports-color + - typescript - utf-8-validate '@axelar-network/axelarjs-types@0.33.0': @@ -14848,6 +14982,23 @@ snapshots: '@floating-ui/utils@0.2.8': {} + '@gql.tada/cli-utils@1.6.3(@0no-co/graphqlsp@1.12.16(graphql@16.10.0)(typescript@5.4.3))(graphql@16.10.0)(typescript@5.4.3)': + dependencies: + '@0no-co/graphqlsp': 1.12.16(graphql@16.10.0)(typescript@5.4.3) + '@gql.tada/internal': 1.0.8(graphql@16.10.0)(typescript@5.4.3) + graphql: 16.10.0 + typescript: 5.4.3 + + '@gql.tada/internal@1.0.8(graphql@16.10.0)(typescript@5.4.3)': + dependencies: + '@0no-co/graphql.web': 1.0.13(graphql@16.10.0) + graphql: 16.10.0 + typescript: 5.4.3 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.10.0)': + dependencies: + graphql: 16.10.0 + '@hapi/bourne@3.0.0': {} '@headlessui/react@1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -15353,6 +15504,31 @@ snapshots: '@motionone/dom': 10.18.0 tslib: 2.8.1 + '@mysten/bcs@1.2.0': + dependencies: + bs58: 6.0.0 + + '@mysten/sui@1.18.0(typescript@5.4.3)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.10.0) + '@mysten/bcs': 1.2.0 + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.1 + '@scure/bip32': 1.6.0 + '@scure/bip39': 1.5.0 + '@simplewebauthn/typescript-types': 7.4.0 + '@suchipi/femver': 1.0.0 + bech32: 2.0.0 + gql.tada: 1.8.10(graphql@16.10.0)(typescript@5.4.3) + graphql: 16.10.0 + jose: 5.9.6 + poseidon-lite: 0.2.1 + valibot: 0.36.0 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - typescript + '@neondatabase/serverless@0.7.2': dependencies: '@types/pg': 8.6.6 @@ -16382,6 +16558,8 @@ snapshots: - encoding - supports-color + '@simplewebauthn/typescript-types@7.4.0': {} + '@sinclair/typebox@0.27.8': {} '@sindresorhus/is@5.6.0': {} @@ -16478,6 +16656,32 @@ snapshots: '@stablelib/random': 1.0.2 '@stablelib/wipe': 1.0.1 + '@stellar/js-xdr@3.1.2': {} + + '@stellar/stellar-base@13.0.1': + dependencies: + '@stellar/js-xdr': 3.1.2 + base32.js: 0.1.0 + bignumber.js: 9.1.2 + buffer: 6.0.3 + sha.js: 2.4.11 + tweetnacl: 1.0.3 + optionalDependencies: + sodium-native: 4.3.1 + + '@stellar/stellar-sdk@13.1.0': + dependencies: + '@stellar/stellar-base': 13.0.1 + axios: 1.7.9 + bignumber.js: 9.1.2 + eventsource: 2.0.2 + feaxios: 0.0.23 + randombytes: 2.1.0 + toml: 3.0.0 + urijs: 1.19.11 + transitivePeerDependencies: + - debug + '@storybook/addon-actions@8.4.7(storybook@8.4.7(bufferutil@4.0.8)(prettier@3.2.5)(utf-8-validate@6.0.3))': dependencies: '@storybook/global': 5.0.0 @@ -16797,6 +17001,8 @@ snapshots: dependencies: storybook: 8.4.7(bufferutil@4.0.8)(prettier@3.2.5)(utf-8-validate@6.0.3) + '@suchipi/femver@1.0.0': {} + '@svgr/babel-plugin-add-jsx-attribute@7.0.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -19143,6 +19349,10 @@ snapshots: balanced-match@1.0.2: {} + base-x@5.0.0: {} + + base32.js@0.1.0: {} + base64-js@1.5.1: {} bech32@1.1.4: {} @@ -19210,6 +19420,10 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.1(browserslist@4.24.2) + bs58@6.0.0: + dependencies: + base-x: 5.0.0 + bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -20870,6 +21084,8 @@ snapshots: events@3.3.0: {} + eventsource@2.0.2: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -20975,6 +21191,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + feaxios@0.0.23: + dependencies: + is-retry-allowed: 3.0.0 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -21375,6 +21595,18 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 + gql.tada@1.8.10(graphql@16.10.0)(typescript@5.4.3): + dependencies: + '@0no-co/graphql.web': 1.0.13(graphql@16.10.0) + '@0no-co/graphqlsp': 1.12.16(graphql@16.10.0)(typescript@5.4.3) + '@gql.tada/cli-utils': 1.6.3(@0no-co/graphqlsp@1.12.16(graphql@16.10.0)(typescript@5.4.3))(graphql@16.10.0)(typescript@5.4.3) + '@gql.tada/internal': 1.0.8(graphql@16.10.0)(typescript@5.4.3) + typescript: 5.4.3 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - graphql + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -21383,6 +21615,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.10.0: {} + gzip-size@6.0.0: dependencies: duplexer: 0.1.2 @@ -21811,6 +22045,8 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-retry-allowed@3.0.0: {} + is-set@2.0.3: {} is-shared-array-buffer@1.0.2: @@ -22087,6 +22323,8 @@ snapshots: jose@4.15.9: {} + jose@5.9.6: {} + joycon@3.1.1: {} js-file-download@0.4.12: {} @@ -23129,7 +23367,7 @@ snapshots: acorn: 8.11.3 pathe: 1.1.2 pkg-types: 1.0.3 - ufo: 1.5.3 + ufo: 1.5.4 mlly@1.6.1: dependencies: @@ -23211,31 +23449,6 @@ snapshots: next-tick@1.1.0: {} - next@14.1.4(@babel/core@7.24.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 14.1.4 - '@swc/helpers': 0.5.2 - busboy: 1.6.0 - caniuse-lite: 1.0.30001687 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.24.0)(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 14.1.4 - '@next/swc-darwin-x64': 14.1.4 - '@next/swc-linux-arm64-gnu': 14.1.4 - '@next/swc-linux-arm64-musl': 14.1.4 - '@next/swc-linux-x64-gnu': 14.1.4 - '@next/swc-linux-x64-musl': 14.1.4 - '@next/swc-win32-arm64-msvc': 14.1.4 - '@next/swc-win32-ia32-msvc': 14.1.4 - '@next/swc-win32-x64-msvc': 14.1.4 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - next@14.1.4(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.1.4 @@ -23820,6 +24033,8 @@ snapshots: pony-cause@2.1.11: {} + poseidon-lite@0.2.1: {} + possible-typed-array-names@1.0.0: {} postcss-import@15.1.0(postcss@8.4.49): @@ -24871,6 +25086,11 @@ snapshots: transitivePeerDependencies: - supports-color + sodium-native@4.3.1: + dependencies: + node-gyp-build: 4.8.4 + optional: true + sonic-boom@2.8.0: dependencies: atomic-sleep: 1.0.0 @@ -25150,13 +25370,6 @@ snapshots: clsx: 2.1.1 typescript: 5.4.3 - styled-jsx@5.1.1(@babel/core@7.24.0)(react@18.3.1): - dependencies: - client-only: 0.0.1 - react: 18.3.1 - optionalDependencies: - '@babel/core': 7.24.0 - styled-jsx@5.1.1(@babel/core@7.26.0)(react@18.3.1): dependencies: client-only: 0.0.1 @@ -25417,6 +25630,8 @@ snapshots: toidentifier@1.0.1: {} + toml@3.0.0: {} + totalist@3.0.1: {} tr46@0.0.3: {} @@ -25620,6 +25835,8 @@ snapshots: turbo-windows-64: 1.13.0 turbo-windows-arm64: 1.13.0 + tweetnacl@1.0.3: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -25882,6 +26099,8 @@ snapshots: dependencies: punycode: 2.3.1 + urijs@1.19.11: {} + url-parse@1.5.10: dependencies: querystringify: 2.2.0 @@ -25937,6 +26156,8 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + valibot@0.36.0: {} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -26291,6 +26512,8 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} + web-streams-polyfill@4.1.0: {} + web-tree-sitter@0.24.3: optional: true From 3c658fd576b758e6cf656d23e8a5dcc5f375ff8b Mon Sep 17 00:00:00 2001 From: npty Date: Thu, 9 Jan 2025 13:24:03 +0700 Subject: [PATCH 07/40] feat: support vm chains in recordInterchainTokenDeployment --- apps/maestro/src/server/context.ts | 4 +- .../recordInterchainTokenDeployment.ts | 45 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/apps/maestro/src/server/context.ts b/apps/maestro/src/server/context.ts index 8939aa5cd..cec5a0505 100644 --- a/apps/maestro/src/server/context.ts +++ b/apps/maestro/src/server/context.ts @@ -105,8 +105,8 @@ const createContextInner = async ({ req, res }: ContextConfig) => { createInterchainTokenClient(chain: Chain, address: `0x${string}`) { return new InterchainTokenClient({ chain, address }); }, - createTokenManagerClient(chain: Chain, address: `0x${string}`) { - return new TokenManagerClient({ chain, address }); + createTokenManagerClient(chain: Chain, address: string) { + return new TokenManagerClient({ chain, address: address as `0x${string}` }); }, createInterchainTokenServiceClient( chain: Chain, diff --git a/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts b/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts index 34952ae7e..a5465684a 100644 --- a/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts +++ b/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts @@ -1,5 +1,4 @@ import { invariant, Maybe } from "@axelarjs/utils"; - import { always } from "rambda"; import { z } from "zod"; @@ -18,20 +17,23 @@ const recordInterchainTokenDeploymentInput = newInterchainTokenSchema tokenManagerAddress: true, }); -export type RecordInterchainTokenDeploymentInput = z.infer< - typeof recordInterchainTokenDeploymentInput ->; - export const recordInterchainTokenDeployment = protectedProcedure .input(recordInterchainTokenDeploymentInput) .mutation(async ({ ctx, input }) => { invariant(ctx.session?.address, "ctx.session.address is required"); - const chains = await ctx.configs.evmChains(); - const configs = chains[input.axelarChainId]; + const evmChains = await ctx.configs.evmChains(); + const vmChains = await ctx.configs.vmChains(); + const configs = evmChains[input.axelarChainId] || vmChains[input.axelarChainId]; + + invariant(configs, `No configuration found for chain ${input.axelarChainId}`); + + // Handle different chain types + const createServiceClient = () => { + return ctx.contracts.createInterchainTokenServiceClient(configs.wagmi); + }; - const originChainServiceClient = - ctx.contracts.createInterchainTokenServiceClient(configs.wagmi); + const originChainServiceClient = createServiceClient(); const tokenManagerAddress = (await originChainServiceClient.reads .tokenManagerAddress({ @@ -39,20 +41,19 @@ export const recordInterchainTokenDeployment = protectedProcedure }) .catch(() => null)) as `0x${string}`; + const createTokenManagerClient = (address: string) => { + return ctx.contracts.createTokenManagerClient(configs.wagmi, address); + }; + const tokenManagerClient = !tokenManagerAddress ? null - : ctx.contracts.createTokenManagerClient( - configs.wagmi, - tokenManagerAddress - ); + : createTokenManagerClient(tokenManagerAddress); const tokenManagerTypeCode = !tokenManagerClient ? null : await tokenManagerClient.reads.implementationType().catch(() => null); const tokenManagerType = Maybe.of(tokenManagerTypeCode).mapOr( - // default to mint_burn for interchain tokens - // and lock_unlock for canonical tokens input.kind === "canonical" ? "lock_unlock" : "mint_burn", (value) => getTokenManagerTypeFromBigInt(value as bigint) ); @@ -69,12 +70,16 @@ export const recordInterchainTokenDeployment = protectedProcedure const remoteTokens = await Promise.all( input.destinationAxelarChainIds.map(async (axelarChainId) => { - const chains = await ctx.configs.evmChains(); - const configs = chains[axelarChainId]; + const chains = { + ...await ctx.configs.evmChains(), + ...await ctx.configs.vmChains(), + }; + const chainConfig = chains[axelarChainId]; + invariant(chainConfig, `No configuration found for chain ${axelarChainId}`); + + invariant(chainConfig.wagmi, `No wagmi configuration found for chain ${axelarChainId}`); - const itsClient = ctx.contracts.createInterchainTokenServiceClient( - configs.wagmi - ); + const itsClient = ctx.contracts.createInterchainTokenServiceClient(chainConfig.wagmi); const [tokenManagerAddress, tokenAddress] = await Promise.all([ itsClient.reads From acddf362287c389043f7567eb587eebd41946f31 Mon Sep 17 00:00:00 2001 From: npty Date: Thu, 9 Jan 2025 19:39:52 +0700 Subject: [PATCH 08/40] feat: support vm chains for chain picker and tx status monitor --- .../DeployAndRegister.state.ts | 29 ++++++++---- .../deploy-and-register/DeployAndRegister.tsx | 38 ++++++++++++--- .../deploy-and-register/DeployAndRegister.tsx | 18 ++++++- .../GMPTxStatusMonitor/GMPTxStatusMonitor.tsx | 47 +++++++++++++++---- 4 files changed, 104 insertions(+), 28 deletions(-) diff --git a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.state.ts b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.state.ts index 672431463..06879e9e0 100644 --- a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.state.ts +++ b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.state.ts @@ -1,5 +1,5 @@ -import type { EVMChainConfig } from "@axelarjs/api/axelarscan"; -import { useEffect, useState } from "react"; +import type { EVMChainConfig, VMChainConfig } from "@axelarjs/api/axelarscan"; +import { useEffect, useState, useMemo } from "react"; import { formatEther } from "viem"; import { useChainId } from "wagmi"; @@ -9,7 +9,7 @@ import { NEXT_PUBLIC_INTERCHAIN_DEPLOYMENT_GAS_LIMIT, } from "~/config/env"; import { useEstimateGasFeeMultipleChainsQuery } from "~/services/axelarjsSDK/hooks"; -import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; +import { useEVMChainConfigsQuery, useVMChainConfigsQuery } from "~/services/axelarscan/hooks"; import { useCanonicalTokenDeploymentStateContainer } from "../../CanonicalTokenDeployment.state"; export type UseStep3ChainSelectionStateProps = { @@ -18,12 +18,20 @@ export type UseStep3ChainSelectionStateProps = { export function useStep3ChainSelectionState() { const { data: evmChains } = useEVMChainConfigsQuery(); + const { data: vmChains } = useVMChainConfigsQuery(); const chainId = useChainId(); const [isDeploying, setIsDeploying] = useState(false); const [totalGasFee, $setTotalGasFee] = useState(formatEther(0n)); - const [sourceChainId, setSourceChainId] = useState( - evmChains?.find((evmChain: EVMChainConfig) => evmChain.chain_id === chainId) - ?.id as string + + // Find source chain from both EVM and VM chains + const currentChain = useMemo(() => { + const evmChain = evmChains?.find((chain: EVMChainConfig) => chain.chain_id === chainId); + const vmChain = vmChains?.find((chain: VMChainConfig) => chain.chain_id === chainId); + return evmChain || vmChain; + }, [evmChains, vmChains, chainId]); + + const [sourceChainId, setSourceChainId] = useState( + currentChain?.id || "" ); const { state: rootState } = useCanonicalTokenDeploymentStateContainer(); @@ -58,13 +66,13 @@ export function useStep3ChainSelectionState() { }; useEffect(() => { - const candidateChain = evmChains?.find( - (evmChain) => evmChain.chain_id === chainId - ); + const candidateChain = [...(evmChains || []), ...(vmChains || [])] + .find(chain => chain.chain_id === chainId); + if (!candidateChain || candidateChain.chain_name === sourceChainId) return; setSourceChainId(candidateChain.chain_name); - }, [evmChains, chainId, sourceChainId]); + }, [evmChains, vmChains, chainId, sourceChainId]); return { state: { @@ -72,6 +80,7 @@ export function useStep3ChainSelectionState() { totalGasFee, sourceChainId, evmChains, + vmChains, isEstimatingGasFees: isRemoteDeploymentGasFeeLoading, hasGasFeesEstimationError: isRemoteDeploymentGasFeeError, remoteDeploymentGasFees, diff --git a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx index 8b311167b..0b90af71c 100644 --- a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx +++ b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx @@ -30,7 +30,13 @@ export const Step3: FC = () => { const chainId = useChainId(); - const sourceChain = state.evmChains.find((x) => x.chain_id === chainId); + // Support both EVM and VM chains + const sourceChain = useMemo(() => { + return ( + state.evmChains?.find((x) => x.chain_id === chainId) || + state.vmChains?.find((x) => x.chain_id === chainId) + ); + }, [state.evmChains, state.vmChains, chainId]); const [validDestinationChainIds, erroredDestinationChainIds] = useMemo( () => @@ -135,11 +141,24 @@ export const Step3: FC = () => { addTransaction, ] ); - - const eligibleChains = useMemo( - () => state.evmChains?.filter((chain) => chain.chain_id !== chainId), - [state.evmChains, chainId] - ); + const eligibleChains = useMemo(() => { + const uniqueChains = new Map(); + + // Add EVM chains + state.evmChains?.forEach((chain) => { + uniqueChains.set(chain.chain_id, chain); + }); + + // Add VM chains + state.vmChains?.forEach((chain) => { + uniqueChains.set(chain.chain_id, chain); + }); + + // Convert to array and filter out current chain + return Array.from(uniqueChains.values()).filter( + (chain) => chain.chain_id !== chainId + ); + }, [state.evmChains, state.vmChains, chainId]); const formSubmitRef = useRef>(null); @@ -147,7 +166,12 @@ export const Step3: FC = () => { const { data: balance } = useBalance({ address }); - const nativeTokenSymbol = getNativeToken(state.sourceChainId); + const nativeTokenSymbol = useMemo(() => { + if (sourceChain?.chain_type === 'vm') { + return sourceChain.native_token.symbol; + } + return getNativeToken(state.sourceChainId); + }, [sourceChain, state.sourceChainId]); const hasInsufficientGasBalance = useMemo(() => { if (!balance || !state.remoteDeploymentGasFees) { diff --git a/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx b/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx index c93794e9c..fc3344d2f 100644 --- a/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx +++ b/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx @@ -146,8 +146,22 @@ export const Step2: FC = () => { // Combine EVM and VM chains for eligible chains const eligibleChains = useMemo(() => { - const allChains = [...(state.evmChains || []), ...(state.vmChains || [])]; - return allChains.filter((chain) => chain.chain_id !== chainId); + const uniqueChains = new Map(); + + // Add VM chains first (they will be overwritten by VM chains if there are duplicates) + state.vmChains?.forEach((chain) => { + uniqueChains.set(chain.chain_id, chain); + }); + + // Add EVM chains + state.evmChains?.forEach((chain) => { + uniqueChains.set(chain.chain_id, chain); + }); + + // Convert back to array and filter out current chainId + return Array.from(uniqueChains.values()).filter( + (chain) => chain.chain_id !== chainId + ); }, [state.evmChains, state.vmChains, chainId]); const formSubmitRef = useRef>(null); diff --git a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx index c726e0198..ad64d3fea 100644 --- a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx +++ b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx @@ -1,4 +1,4 @@ -import type { EVMChainConfig } from "@axelarjs/api"; +import type { EVMChainConfig, VMChainConfig } from "@axelarjs/api"; import type { GMPTxStatus } from "@axelarjs/api/gmp"; import { Badge, cn, Progress, Tooltip, type BadgeProps } from "@axelarjs/ui"; import { useEffect, useMemo, type FC } from "react"; @@ -9,11 +9,12 @@ import { useBlockNumber, useChainId, useTransaction } from "wagmi"; import { NEXT_PUBLIC_EXPLORER_URL } from "~/config/env"; import { useChainInfoQuery } from "~/services/axelarjsSDK/hooks"; -import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; +import { useEVMChainConfigsQuery, useVMChainConfigsQuery } from "~/services/axelarscan/hooks"; import { useGetTransactionStatusOnDestinationChainsQuery } from "~/services/gmp/hooks"; import { ChainIcon } from "~/ui/components/ChainsDropdown"; export type ExtendedGMPTxStatus = GMPTxStatus | "pending"; +type ChainConfig = EVMChainConfig | VMChainConfig; const STATUS_LABELS: Partial> = { called: "Initialized", @@ -42,14 +43,24 @@ const STATUS_COLORS: Partial< }; export function useGMPTxProgress(txHash: `0x${string}`, chainId: number) { - const { computed } = useEVMChainConfigsQuery(); + const { computed: evmComputed } = useEVMChainConfigsQuery(); + const { computed: vmComputed } = useVMChainConfigsQuery(); + + // Combine the chain configs + const chainConfigs = useMemo(() => ({ + indexedByChainId: { + ...evmComputed.indexedByChainId, + ...vmComputed.indexedByChainId, + } + }), [evmComputed, vmComputed]); + const { data: txInfo } = useTransaction({ hash: txHash, chainId, }); const { data: chainInfo } = useChainInfoQuery({ - axelarChainId: computed.indexedByChainId[chainId]?.id, + axelarChainId: chainConfigs.indexedByChainId[chainId]?.id, }); const { data: currentBlockNumber } = useBlockNumber({ @@ -136,7 +147,20 @@ const GMPTxStatusMonitor = ({ txHash, onAllChainsExecuted }: Props) => { const chainId = useChainId(); - const { computed } = useEVMChainConfigsQuery(); + const { computed: evmComputed } = useEVMChainConfigsQuery(); + const { computed: vmComputed } = useVMChainConfigsQuery(); + + // Combine the chain configs + const chainConfigs = useMemo(() => ({ + indexedById: { + ...evmComputed.indexedById, + ...vmComputed.indexedById, + }, + indexedByChainId: { + ...evmComputed.indexedByChainId, + ...vmComputed.indexedByChainId, + } + }), [evmComputed, vmComputed]); const statusList = Object.values(statuses ?? {}); @@ -180,7 +204,11 @@ const GMPTxStatusMonitor = ({ txHash, onAllChainsExecuted }: Props) => {
    {[...Object.entries(statuses ?? {})].map( ([axelarChainId, { status, logIndex }]) => { - const chain = computed.indexedById[axelarChainId]; + const chain = chainConfigs.indexedById[axelarChainId]; + console.log('chainConfigs', chainConfigs) + console.log("axelarChainId", axelarChainId) + + console.log("chainnnn", chain) return ( & { logIndexes: number[]; - chains: EVMChainConfig[]; + chains: ChainConfig[]; }; const CollapsedChains: FC<{ - chains: EVMChainConfig[]; + chains: ChainConfig[]; offset: number; }> = ({ chains, offset }) => { if (chains.length > offset) { @@ -289,6 +317,7 @@ export const ChainStatusItem: FC = ({ className, compact, }) => { + console.log("chain", chain) return (
  • From 5614260d2d91d232c25a268947635554996fdc0f Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:28:59 +0700 Subject: [PATCH 09/40] chore: fix rpc urls for sepolia testnet --- apps/maestro/src/config/evm-chains.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/maestro/src/config/evm-chains.ts b/apps/maestro/src/config/evm-chains.ts index 1bf6f803c..e082aa99b 100644 --- a/apps/maestro/src/config/evm-chains.ts +++ b/apps/maestro/src/config/evm-chains.ts @@ -80,6 +80,10 @@ export const ALL_CHAINS: ExtendedWagmiChainConfig[] = [ }, { ...sepolia, + rpcUrls: { + default: { http: ["https://endpoints.omniatech.io/v1/eth/sepolia/public", "https://1rpc.io/sepolia"] }, // Temporarily using this url + public: { http: ["https://endpoints.omniatech.io/v1/eth/sepolia/public", "https://1rpc.io/sepolia"] }, + }, axelarChainId: "ethereum-sepolia", axelarChainName: "ethereum-sepolia", environment: ENVIRONMENTS.testnet, From 738e3d5f0a537970b8bf7308fcc44e259a9af929 Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:29:49 +0700 Subject: [PATCH 10/40] chore: remove console.log --- .../ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx index ad64d3fea..d67bdf286 100644 --- a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx +++ b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx @@ -205,10 +205,6 @@ const GMPTxStatusMonitor = ({ txHash, onAllChainsExecuted }: Props) => { {[...Object.entries(statuses ?? {})].map( ([axelarChainId, { status, logIndex }]) => { const chain = chainConfigs.indexedById[axelarChainId]; - console.log('chainConfigs', chainConfigs) - console.log("axelarChainId", axelarChainId) - - console.log("chainnnn", chain) return ( Date: Fri, 10 Jan 2025 13:29:57 +0700 Subject: [PATCH 11/40] chore: bump axelarjs-sdk --- apps/maestro/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/maestro/package.json b/apps/maestro/package.json index 985cf00e7..2a789f371 100644 --- a/apps/maestro/package.json +++ b/apps/maestro/package.json @@ -34,7 +34,7 @@ "release": "tsx scripts/release.ts" }, "dependencies": { - "@axelar-network/axelarjs-sdk": "0.17.1-alpha.10", + "@axelar-network/axelarjs-sdk": "0.17.1-alpha.12", "@axelarjs/api": "workspace:*", "@axelarjs/core": "workspace:*", "@axelarjs/evm": "workspace:*", From 9cbbfdd0ecd74a4cc160de9808cc75a99d665b29 Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:30:13 +0700 Subject: [PATCH 12/40] chore: update lock file --- pnpm-lock.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bdc1d40e..7eb519e62 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,8 +93,8 @@ importers: apps/maestro: dependencies: '@axelar-network/axelarjs-sdk': - specifier: 0.17.1-alpha.10 - version: 0.17.1-alpha.10(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3) + specifier: 0.17.1-alpha.12 + version: 0.17.1-alpha.12(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3) '@axelarjs/api': specifier: workspace:* version: link:../../packages/api @@ -1083,8 +1083,8 @@ packages: resolution: {integrity: sha512-o8pv+krIAlEwzid0Ac8qwykDsavc+1DRPvyFQ3V0R0zTQFtYLJIIXXXt7FRb8b+LJDAuX+E0bB3N2X+hlcxk/g==} engines: {node: '>=18'} - '@axelar-network/axelarjs-sdk@0.17.1-alpha.10': - resolution: {integrity: sha512-ZWpTAfnIPsc37UZuZJeobYErq0d9J27n9GDgv/D60cTFdLi06wak8/7zIt0v0HJnzgKVSUG1J27qDum4nbPRKQ==} + '@axelar-network/axelarjs-sdk@0.17.1-alpha.12': + resolution: {integrity: sha512-yQz3zFOfMjYlAzl1/sN/p6nIkKpDbFu9XjA4ynMCR4EqZav8alscRpRLDNrxZP3LPk1cvB1Ppx6jRBHfRFupzA==} '@axelar-network/axelarjs-types@0.33.0': resolution: {integrity: sha512-aCbX/5G+tgWPjr9tl3dQfJftWwRMkILz61ytach7dKqxtO9G9jlxpNvELJQ6gKVOodUtSY8qBCO/fWU19v4hdQ==} @@ -12463,7 +12463,7 @@ snapshots: '@axelar-network/axelar-gmp-sdk-solidity@6.0.4': {} - '@axelar-network/axelarjs-sdk@0.17.1-alpha.10(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3)': + '@axelar-network/axelarjs-sdk@0.17.1-alpha.12(bufferutil@4.0.8)(typescript@5.4.3)(utf-8-validate@6.0.3)': dependencies: '@axelar-network/axelar-cgp-solidity': 6.4.0 '@axelar-network/axelarjs-types': 0.33.0 From 02b66d2a4b09ae1631bd22ba237dcf8892b8cff3 Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:30:24 +0700 Subject: [PATCH 13/40] chore: add callback type to search gmp api --- packages/api/src/gmp/types.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/packages/api/src/gmp/types.ts b/packages/api/src/gmp/types.ts index 483832e59..bc8e56a8f 100644 --- a/packages/api/src/gmp/types.ts +++ b/packages/api/src/gmp/types.ts @@ -101,6 +101,36 @@ export type SearchGMPCall = { }; }; +export type SearchGMPCallback = { + chain: string; + chain_type: ChainType; + destination_chain_type: ChainType; + created_at: GMPTxCreatedAt; + eventIndex: number; + returnValues: { + sourceChain: string; + destinationChain: string; + sourceAddress: string; + destinationAddress: string; + destinationContractAddress: string; + sender: string; + payload: string; + messageID: string; + messageId: string; + payloadHash: string; + }; + messageIdIndex: number; + blockNumber: number; + block_timestamp: number; + parentMessageID: string; + receipt: SearchGMPReceipt; + _id: string; + id: string; + messageIdHash: string; + event: string; + transaction: SearchGMPTransaction; +}; + type SearchGMPReceipt = { gasUsed: string; blockNumber: number; @@ -280,6 +310,7 @@ export type SearchGMPResponseData = { interchain_transfer?: InterchainTransferEvent; interchain_token_deployment_started?: InterchainTokenDeploymentStartedEvent; token_manager_deployment_started?: TokenManagerDeploymentStartedEvent; + callback?: SearchGMPCallback; }; export type SearchGMPTimespent = { From 7a3d0a3161658a536872c30642abf4b7201b834e Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:32:23 +0700 Subject: [PATCH 14/40] chore: remove log --- .../src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx index d67bdf286..06f2d4649 100644 --- a/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx +++ b/apps/maestro/src/ui/compounds/GMPTxStatusMonitor/GMPTxStatusMonitor.tsx @@ -313,7 +313,6 @@ export const ChainStatusItem: FC = ({ className, compact, }) => { - console.log("chain", chain) return (
  • From 6f9811fa24db0ab60c9c9debb89285a71189a942 Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:33:04 +0700 Subject: [PATCH 15/40] feat: support vm chains for record interchain token deployment --- .../recordInterchainTokenDeployment.ts | 58 +++++++++++++++---- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts b/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts index a5465684a..39925cc83 100644 --- a/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts +++ b/apps/maestro/src/server/routers/interchainToken/recordInterchainTokenDeployment.ts @@ -1,5 +1,6 @@ import { invariant, Maybe } from "@axelarjs/utils"; -import { always } from "rambda"; + +import { always, chain } from "rambda"; import { z } from "zod"; import { getTokenManagerTypeFromBigInt } from "~/lib/drizzle/schema/common"; @@ -24,9 +25,13 @@ export const recordInterchainTokenDeployment = protectedProcedure const evmChains = await ctx.configs.evmChains(); const vmChains = await ctx.configs.vmChains(); - const configs = evmChains[input.axelarChainId] || vmChains[input.axelarChainId]; + const configs = + evmChains[input.axelarChainId] || vmChains[input.axelarChainId]; - invariant(configs, `No configuration found for chain ${input.axelarChainId}`); + invariant( + configs, + `No configuration found for chain ${input.axelarChainId}` + ); // Handle different chain types const createServiceClient = () => { @@ -70,16 +75,45 @@ export const recordInterchainTokenDeployment = protectedProcedure const remoteTokens = await Promise.all( input.destinationAxelarChainIds.map(async (axelarChainId) => { - const chains = { - ...await ctx.configs.evmChains(), - ...await ctx.configs.vmChains(), - }; - const chainConfig = chains[axelarChainId]; - invariant(chainConfig, `No configuration found for chain ${axelarChainId}`); - - invariant(chainConfig.wagmi, `No wagmi configuration found for chain ${axelarChainId}`); + // Fetch both chain types + const vmChains = await ctx.configs.vmChains(); + const evmChains = await ctx.configs.evmChains(); + + // Create a Map using chain_id as the key to ensure uniqueness + const uniqueChains = new Map(); + + // Add VM chains first, accessing the 'info' property + Object.values(vmChains).forEach((chainConfig) => { + uniqueChains.set(chainConfig.info.chain_id, chainConfig); + }); + + // Add EVM chains, overwriting any duplicates + Object.values(evmChains).forEach((chainConfig) => { + uniqueChains.set(chainConfig.info.chain_id, chainConfig); + }); + + // Convert back to an object with axelarChainId as keys + const chains = Array.from(uniqueChains.values()).reduce( + (acc, chainConfig) => { + acc[chainConfig.info.id] = chainConfig; + return acc; + }, + {} as Record + ); - const itsClient = ctx.contracts.createInterchainTokenServiceClient(chainConfig.wagmi); + const chainConfig = chains[axelarChainId]; + invariant( + chainConfig, + `No configuration found for chain ${axelarChainId}` + ); + invariant( + chainConfig.wagmi, + `No wagmi configuration found for chain ${axelarChainId}` + ); + + const itsClient = ctx.contracts.createInterchainTokenServiceClient( + chainConfig.wagmi + ); const [tokenManagerAddress, tokenAddress] = await Promise.all([ itsClient.reads From 0d35f0f1f6dc173bd12df304268262f9b94e9675 Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:34:31 +0700 Subject: [PATCH 16/40] chore: fix the its-hub destination chain --- ...getTransactionStatusOnDestinationChains.ts | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/apps/maestro/src/server/routers/gmp/getTransactionStatusOnDestinationChains.ts b/apps/maestro/src/server/routers/gmp/getTransactionStatusOnDestinationChains.ts index 8f6ea1a13..04f5ff2d4 100644 --- a/apps/maestro/src/server/routers/gmp/getTransactionStatusOnDestinationChains.ts +++ b/apps/maestro/src/server/routers/gmp/getTransactionStatusOnDestinationChains.ts @@ -13,6 +13,7 @@ export const SEARCHGMP_SOURCE = { "approved", "confirm", "executed", + "callback", ], excludes: [ "call.transaction", @@ -54,15 +55,19 @@ export const getTransactionStatusOnDestinationChains = publicProcedure if (data.length) { const result = data.reduce( - (acc, { call, status }) => ({ - ...acc, - [call.returnValues.destinationChain.toLowerCase()]: { - status, - txHash: call.transactionHash, - logIndex: call.logIndex ?? call._logIndex ?? 0, - txId: call.id, - }, - }), + (acc, gmpData) => { + const { call, status } = gmpData; + const destinationChain = gmpData.callback?.returnValues.destinationChain.toLowerCase() || call.returnValues.destinationChain.toLowerCase(); + return { + ...acc, + [destinationChain]: { + status, + txHash: call.transactionHash, + logIndex: call.logIndex ?? call._logIndex ?? 0, + txId: call.id, + }, + }; + }, {} as { [chainId: string]: { status: GMPTxStatus; From e44ac57850de3bc68fc6e9ef2d951e1223f4ffbe Mon Sep 17 00:00:00 2001 From: npty Date: Fri, 10 Jan 2025 13:50:08 +0700 Subject: [PATCH 17/40] fix: Review component --- .../steps/review/Review.tsx | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx b/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx index 46f61ff9c..617a9155e 100644 --- a/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx +++ b/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx @@ -6,14 +6,14 @@ import { ExternalLinkIcon, LinkButton, } from "@axelarjs/ui"; -import { maskAddress, Maybe } from "@axelarjs/utils"; -import { useCallback, useEffect, useState, type FC } from "react"; +import { maskAddress} from "@axelarjs/utils"; +import { useCallback, useEffect, useState, useMemo, type FC } from "react"; import { useRouter } from "next/router"; import { useAccount } from "wagmi"; import { useChainFromRoute } from "~/lib/hooks"; -import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks"; +import { useEVMChainConfigsQuery, useVMChainConfigsQuery } from "~/services/axelarscan/hooks"; import { useInterchainTokensQuery } from "~/services/gmp/hooks"; import GMPTxStatusMonitor from "~/ui/compounds/GMPTxStatusMonitor"; import { ShareHaikuButton } from "~/ui/compounds/MultiStepForm"; @@ -26,7 +26,20 @@ const Review: FC = () => { const { chain } = useAccount(); const routeChain = useChainFromRoute(); - const { computed } = useEVMChainConfigsQuery(); + const { computed: evmComputed } = useEVMChainConfigsQuery(); + const { computed: vmComputed } = useVMChainConfigsQuery(); + + // Combine EVM and VM chain configs + const combinedChainConfigs = useMemo(() => ({ + indexedById: { + ...evmComputed.indexedById, + ...vmComputed.indexedById, + }, + indexedByChainId: { + ...evmComputed.indexedByChainId, + ...vmComputed.indexedByChainId, + } + }), [evmComputed, vmComputed]); const [shouldFetch, setShouldFetch] = useState(false); @@ -47,17 +60,19 @@ const Review: FC = () => { chain.id, state.txState.txHash, state.selectedChains.map( - (axelarChainId) => computed.indexedById[axelarChainId].chain_id + (axelarChainId) => combinedChainConfigs.indexedById[axelarChainId].chain_id ) ); } - }, [chain, computed.indexedById, state.selectedChains, state.txState]); + }, [chain, combinedChainConfigs.indexedById, state.selectedChains, state.txState]); - const chainConfig = Maybe.of(chain).mapOrUndefined( - (chain) => computed.indexedByChainId[chain.id] - ); + const chainConfig = useMemo(() => { + if (!chain) return undefined; + return combinedChainConfigs.indexedByChainId[chain.id]; + }, [chain, combinedChainConfigs.indexedByChainId]); const handleGoToTokenPage = useCallback(async () => { + console.log("handleGoToTokenPage", chainConfig, state.txState.type === "deployed"); if (chainConfig && state.txState.type === "deployed") { actions.reset(); @@ -67,6 +82,8 @@ const Review: FC = () => { } }, [actions, chainConfig, router, state.txState]); + const isVMChain = chainConfig?.chain_type === 'vm'; + return ( <>
    @@ -105,32 +122,32 @@ const Review: FC = () => { {state.selectedChains.length > 0 ? ( ) : ( - - View transaction{" "} - - {maskAddress(state.txState.txHash ?? "")} - {" "} - on {chain?.blockExplorers?.default.name}{" "} - - + !isVMChain && ( + + View transaction{" "} + + {maskAddress(state.txState.txHash ?? "")} + {" "} + on {chain?.blockExplorers?.default.name}{" "} + + + ) )} )}
    {routeChain ? ( - // if the chain is not the same as the route, we need to refresh the page { setShouldFetch(true); - // refresh the page to show the new token await router.replace(router.asPath); }} > @@ -140,7 +157,7 @@ const Review: FC = () => { )}
@@ -238,8 +222,8 @@ const Page: FC = ({ mustBeConnected, handleTokenFound, children, - evmChain, - evmChainFromRoute, + currentChain, + currentChainFromRoute, chain?.id, switchChain, ]); From 29241b4688f84ae6dd60e2d684cd5d6f3dfd5c9b Mon Sep 17 00:00:00 2001 From: npty Date: Tue, 14 Jan 2025 20:38:08 +0700 Subject: [PATCH 37/40] chore: revert its contract addresses --- .../maestro/src/lib/contracts/InterchainTokenFactory.hooks.ts | 2 +- .../maestro/src/lib/contracts/InterchainTokenService.hooks.ts | 2 +- apps/maestro/src/lib/contracts/index.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/maestro/src/lib/contracts/InterchainTokenFactory.hooks.ts b/apps/maestro/src/lib/contracts/InterchainTokenFactory.hooks.ts index 85c2f40a6..55b2b3134 100644 --- a/apps/maestro/src/lib/contracts/InterchainTokenFactory.hooks.ts +++ b/apps/maestro/src/lib/contracts/InterchainTokenFactory.hooks.ts @@ -427,7 +427,7 @@ export const interchainTokenFactoryAbi = [ ] as const; export const interchainTokenFactoryAddress = - "0x6Ae8C8498d5FDA930e6ABeB0E15E5A00471702a7" as const; + "0x83a93500d23Fbc3e82B410aD07A6a9F7A0670D66" as const; export const interchainTokenFactoryConfig = { address: interchainTokenFactoryAddress, diff --git a/apps/maestro/src/lib/contracts/InterchainTokenService.hooks.ts b/apps/maestro/src/lib/contracts/InterchainTokenService.hooks.ts index 6bdce89d4..4d5df3012 100644 --- a/apps/maestro/src/lib/contracts/InterchainTokenService.hooks.ts +++ b/apps/maestro/src/lib/contracts/InterchainTokenService.hooks.ts @@ -1141,7 +1141,7 @@ export const interchainTokenServiceAbi = [ ] as const; export const interchainTokenServiceAddress = - "0x144c3d7A5f5198EF3B46A8258b35E903cf197A66" as const; + "0xB5FB4BE02232B1bBA4dC8f81dc24C26980dE9e3C" as const; export const interchainTokenServiceConfig = { address: interchainTokenServiceAddress, diff --git a/apps/maestro/src/lib/contracts/index.ts b/apps/maestro/src/lib/contracts/index.ts index 064d15443..ba3bc678c 100644 --- a/apps/maestro/src/lib/contracts/index.ts +++ b/apps/maestro/src/lib/contracts/index.ts @@ -18,12 +18,12 @@ export const contracts = [ { name: INTERCHAIN_TOKEN_FACTORY_ABI.contractName, abi: INTERCHAIN_TOKEN_FACTORY_ABI.abi, - address: "0x6Ae8C8498d5FDA930e6ABeB0E15E5A00471702a7" as `0x${string}`, // read from .env.local (NEXT_PUBLIC_INTERCHAIN_TOKEN_FACTORY_ADDRESS) + address: "0x83a93500d23Fbc3e82B410aD07A6a9F7A0670D66" as `0x${string}`, // read from .env.local (NEXT_PUBLIC_INTERCHAIN_TOKEN_FACTORY_ADDRESS) }, { name: INTERCHAIN_TOKEN_SERVICE_ABI.contractName, abi: INTERCHAIN_TOKEN_SERVICE_ABI.abi, - address: "0x144c3d7A5f5198EF3B46A8258b35E903cf197A66" as `0x${string}`, // read from .env.local (NEXT_PUBLIC_INTERCHAIN_TOKEN_SERVICE_ADDRESS) + address: "0xB5FB4BE02232B1bBA4dC8f81dc24C26980dE9e3C" as `0x${string}`, // read from .env.local (NEXT_PUBLIC_INTERCHAIN_TOKEN_SERVICE_ADDRESS) }, { name: TOKEN_MANAGER_ABI.contractName, From 2ce05b0f57a15fe2cd0d25fb5f531824516d8cd7 Mon Sep 17 00:00:00 2001 From: npty Date: Tue, 14 Jan 2025 20:41:00 +0700 Subject: [PATCH 38/40] chore: remove web-streams-polyfill --- apps/maestro/package.json | 1 - pnpm-lock.yaml | 9 --------- 2 files changed, 10 deletions(-) diff --git a/apps/maestro/package.json b/apps/maestro/package.json index 2a789f371..8dd932cbd 100644 --- a/apps/maestro/package.json +++ b/apps/maestro/package.json @@ -115,7 +115,6 @@ "typescript": "^5.4.3", "vite": "^5.2.6", "vitest": "^1.4.0", - "web-streams-polyfill": "^4.1.0", "zx": "^7.2.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7eb519e62..39b1e261e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -330,9 +330,6 @@ importers: vitest: specifier: ^1.4.0 version: 1.4.0(@types/node@20.11.30)(happy-dom@13.10.1)(terser@5.37.0) - web-streams-polyfill: - specifier: ^4.1.0 - version: 4.1.0 zx: specifier: ^7.2.3 version: 7.2.3 @@ -12080,10 +12077,6 @@ packages: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} - web-streams-polyfill@4.1.0: - resolution: {integrity: sha512-A7Jxrg7+eV+eZR/CIdESDnRGFb6/bcKukGvJBB5snI6cw3is1c2qamkYstC1bY1p08TyMRlN9eTMkxmnKJBPBw==} - engines: {node: '>= 8'} - web-tree-sitter@0.24.3: resolution: {integrity: sha512-uR9YNewr1S2EzPKE+y39nAwaTyobBaZRG/IsfkB/OT4v0lXtNj5WjtHKgn2h7eOYUWIZh5rK9Px7tI6S9CRKdA==} @@ -26512,8 +26505,6 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} - web-streams-polyfill@4.1.0: {} - web-tree-sitter@0.24.3: optional: true From 155ab4486ee76f4602b2fbcd4ff105a1315e1500 Mon Sep 17 00:00:00 2001 From: npty Date: Tue, 14 Jan 2025 20:52:06 +0700 Subject: [PATCH 39/40] chore: fix eligible chains and chain name --- .../steps/deploy-and-register/DeployAndRegister.tsx | 2 +- .../steps/deploy-and-register/DeployAndRegister.tsx | 3 +-- apps/maestro/src/ui/compounds/ChainPicker/ChainPicker.tsx | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx index 3e1df7b08..2ce3b318f 100644 --- a/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx +++ b/apps/maestro/src/features/CanonicalTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx @@ -136,7 +136,7 @@ export const Step3: FC = () => { addTransaction, ] ); - const eligibleChains = state.allChains; + const eligibleChains = state.allChains.filter(chain => chain.chain_id !== chainId); const formSubmitRef = useRef>(null); const { address } = useAccount(); diff --git a/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx b/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx index d768afe35..117bf3c82 100644 --- a/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx +++ b/apps/maestro/src/features/InterchainTokenDeployment/steps/deploy-and-register/DeployAndRegister.tsx @@ -140,8 +140,7 @@ export const Step2: FC = () => { ] ); - // Combine EVM and VM chains for eligible chains - const eligibleChains = state.chains; + const eligibleChains = state.chains.filter(chain => chain.chain_id !== chainId); const formSubmitRef = useRef>(null); diff --git a/apps/maestro/src/ui/compounds/ChainPicker/ChainPicker.tsx b/apps/maestro/src/ui/compounds/ChainPicker/ChainPicker.tsx index 85c5d74e8..d8c8714dc 100644 --- a/apps/maestro/src/ui/compounds/ChainPicker/ChainPicker.tsx +++ b/apps/maestro/src/ui/compounds/ChainPicker/ChainPicker.tsx @@ -46,7 +46,7 @@ const ChainPicker: FC = ({ }, [eligibleChains, onChainClick, selectedChains]); const getChainName = (chain: ChainConfig) => { - return chain.chain_name + return chain.name }; return ( From d95cba0860b439ba285984a63e868ee8f92f6d47 Mon Sep 17 00:00:00 2001 From: npty Date: Wed, 15 Jan 2025 13:26:07 +0700 Subject: [PATCH 40/40] chore: remove logs and commented code --- .../features/InterchainTokenDeployment/steps/review/Review.tsx | 1 - .../src/ui/components/ChainsDropdown/ChainsDropdown.tsx | 3 --- 2 files changed, 4 deletions(-) diff --git a/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx b/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx index 14009c688..c708ae303 100644 --- a/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx +++ b/apps/maestro/src/features/InterchainTokenDeployment/steps/review/Review.tsx @@ -59,7 +59,6 @@ const Review: FC = () => { }, [chain, combinedComputed.indexedByChainId]); const handleGoToTokenPage = useCallback(async () => { - console.log("handleGoToTokenPage", chainConfig, state.txState.type === "deployed"); if (chainConfig && state.txState.type === "deployed") { actions.reset(); diff --git a/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx index 3c99fc8be..e12f844ce 100644 --- a/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx +++ b/apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx @@ -141,9 +141,6 @@ const ChainsDropdown: FC = (props) => { [chain?.id, allChains, state.selectedChainId] ); - // const eligibleChains = Maybe.of(props.chains ?? chains).mapOr([], (chains) => - // chains.filter((chain) => chain.chain_id !== selectedChain?.chain_id) - // ); const eligibleChains = Maybe.of(props.chains ?? allChains).mapOr([], (chains) => chains.filter((chain) => chain.chain_id !== selectedChain?.chain_id) );