Skip to content

Commit

Permalink
feat: refactor EVMChainsDropdown to support all chains
Browse files Browse the repository at this point in the history
  • Loading branch information
npty committed Jan 9, 2025
1 parent ab04633 commit 9c49e67
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 114 deletions.
1 change: 1 addition & 0 deletions apps/maestro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
@@ -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";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -95,7 +95,7 @@ export const MintInterchainToken: FC = () => {
<>
<Dialog.Title className="flex">
<span>Mint interchain tokens on</span>
<EVMChainsDropdown disabled compact />
<ChainsDropdown disabled compact />
</Dialog.Title>
<form
className="flex flex-1 flex-col justify-between gap-4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import useQueryStringState from "~/lib/hooks/useQueryStringStyate";
import { useEVMChainConfigsQuery } from "~/services/axelarscan/hooks";
import { useERC20TokenDetailsQuery } from "~/services/erc20";
import { useInterchainTokensQuery } from "~/services/gmp/hooks";
import EVMChainsDropdown, {
EVMChainIcon,
} from "~/ui/components/EVMChainsDropdown";
import ChainsDropdown, {
ChainIcon,
} from "~/ui/components/ChainsDropdown";

export type TokenFoundResult = {
tokenId?: `0x${string}`;
Expand Down Expand Up @@ -133,7 +133,7 @@ const SearchInterchainToken: FC<SearchInterchainTokenProps> = (props) => {
{isLoading && isAddress(search) ? (
<SpinnerIcon className="h-6 w-6 animate-spin text-primary" />
) : (
<EVMChainsDropdown
<ChainsDropdown
triggerClassName="btn btn-sm btn-circle"
contentClassName="translate-x-4 translate-y-2 sm:w-96 md:w-[448px]"
compact
Expand All @@ -157,7 +157,7 @@ const SearchInterchainToken: FC<SearchInterchainTokenProps> = (props) => {
operate in controlled mode
*/}
<div className="flex items-center">
<EVMChainIcon
<ChainIcon
size="md"
hideLabel
selectedChain={defaultChain}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ vi.mock("~/ui/compounds/GMPTxStatusMonitor/index.ts", () => ({
default: () => <div>GMPTxStatusMonitor</div>,
}));

vi.mock("~/ui/components/EVMChainsDropdown/index.ts", () => ({
vi.mock("~/ui/components/ChainsDropdown/index.ts", () => ({
default: () => <div>EVMChainsDropdown</div>,
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -226,7 +226,7 @@ export const SendInterchainToken: FC<Props> = (props) => {
<div className="grid grid-cols-2 gap-4 p-1">
<div className="flex items-center gap-2">
<label className="text-md align-top">From:</label>
<EVMChainsDropdown
<ChainsDropdown
disabled
compact
selectedChain={props.sourceChain}
Expand All @@ -237,7 +237,7 @@ export const SendInterchainToken: FC<Props> = (props) => {
</div>
<div className="flex items-center gap-2">
<label className="text-md align-top">To:</label>
<EVMChainsDropdown
<ChainsDropdown
compact
hideLabel={false}
selectedChain={state.selectedToChain}
Expand Down
2 changes: 1 addition & 1 deletion apps/maestro/src/features/Transactions/Transactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { groupBy } from "rambda";
import type { TxType } from "~/lib/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";
import {
CollapsedChainStatusGroup,
ExtendedGMPTxStatus,
Expand Down
47 changes: 46 additions & 1 deletion apps/maestro/src/services/axelarscan/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { EVMChainConfig } from "@axelarjs/api";
import type { EVMChainConfig, VMChainConfig } from "@axelarjs/api";
import { useMemo } from "react";

import { useQuery } from "@tanstack/react-query";
Expand All @@ -11,6 +11,7 @@ import { trpc } from "~/lib/trpc";
import axelarscanClient from ".";

const EVM_CHAIN_CONFIGS_BY_ID = indexBy(prop("id"), WAGMI_CHAIN_CONFIGS);
const VM_CHAIN_CONFIGS_BY_ID = indexBy(prop("id"), WAGMI_CHAIN_CONFIGS);

export function useEVMChainConfigsQuery() {
const { data, ...queryResult } = trpc.axelarscan.getEVMChainConfigs.useQuery<
Expand Down Expand Up @@ -59,6 +60,50 @@ export function useEVMChainConfigsQuery() {
};
}

export function useVMChainConfigsQuery() {
const { data, ...queryResult } = trpc.axelarscan.getVMChainConfigs.useQuery<VMChainConfig[]>(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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<TProps>(Component: FC<TProps>) {
const Inner = (props: TProps) => (
<ChainsDropdownProvider>
<Component {...(props as TProps & JSX.IntrinsicAttributes)} />
</ChainsDropdownProvider>
);
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;
Loading

0 comments on commit 9c49e67

Please sign in to comment.