Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: whitelist dest chains for source vm chain #490

Merged
merged 3 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/maestro/src/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export const NEXT_PUBLIC_EXPLORER_URL = Maybe.of(
process.env.NEXT_PUBLIC_EXPLORER_URL
).mapOr("", String);

export const NEXT_PUBLIC_WHITELISTED_DEST_CHAINS_FOR_VM = Maybe.of(
process.env.NEXT_PUBLIC_WHITELISTED_DEST_CHAINS_FOR_VM
).mapOr("", String);

export const NEXT_PUBLIC_FILE_BUG_REPORT_URL = Maybe.of(
process.env.NEXT_PUBLIC_FILE_BUG_REPORT_URL
).mapOr("", String);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function useStep3ChainSelectionState() {
isDeploying,
totalGasFee,
sourceChainId,
allChains,
chains: allChains,
isEstimatingGasFees: isRemoteDeploymentGasFeeLoading,
hasGasFeesEstimationError: isRemoteDeploymentGasFeeError,
remoteDeploymentGasFees,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { getNativeToken } from "~/lib/utils/getNativeToken";
import ChainPicker from "~/ui/compounds/ChainPicker";
import { NextButton, TokenNameAlert } from "~/ui/compounds/MultiStepForm";
import { useStep3ChainSelectionState } from "./DeployAndRegister.state";
import { filterEligibleChains } from "~/lib/utils/chains";

export const Step3: FC = () => {
const { state: rootState, actions: rootActions } =
Expand All @@ -31,7 +32,7 @@ export const Step3: FC = () => {
const chainId = useChainId();

// Support both EVM and VM chains
const sourceChain = state.allChains?.find((chain) => chain.chain_id === chainId);
const sourceChain = state.chains?.find((chain) => chain.chain_id === chainId);

const [validDestinationChainIds, erroredDestinationChainIds] = useMemo(
() =>
Expand Down Expand Up @@ -136,7 +137,9 @@ export const Step3: FC = () => {
addTransaction,
]
);
const eligibleChains = state.allChains.filter(chain => chain.chain_id !== chainId);

const eligibleChains = filterEligibleChains(state.chains, chainId);

const formSubmitRef = useRef<ComponentRef<"button">>(null);

const { address } = useAccount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { NextButton } from "~/ui/compounds/MultiStepForm";
import { useDeployAndRegisterRemoteInterchainTokenMutation } from "../../hooks";
import { useInterchainTokenDeploymentStateContainer } from "../../InterchainTokenDeployment.state";
import { useStep2ChainSelectionState } from "./DeployAndRegister.state";
import { filterEligibleChains } from "~/lib/utils/chains";

export const Step2: FC = () => {
const { state: rootState, actions: rootActions } =
Expand Down Expand Up @@ -139,8 +140,8 @@ export const Step2: FC = () => {
addTransaction,
]
);

const eligibleChains = state.chains.filter(chain => chain.chain_id !== chainId);
const eligibleChains = filterEligibleChains(state.chains, chainId);

const formSubmitRef = useRef<ComponentRef<"button">>(null);

Expand Down
31 changes: 31 additions & 0 deletions apps/maestro/src/lib/utils/chains.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ITSChainConfig } from "@axelarjs/api";
import { NEXT_PUBLIC_WHITELISTED_DEST_CHAINS_FOR_VM } from "~/config/env";

export const filterEligibleChains = (
chains: ITSChainConfig[],
currentChainId: number,
): ITSChainConfig[] => {
// Early return if no chains to filter
if (!chains.length) return [];

const currentChain = chains.find((chain) => chain.chain_id === currentChainId);
const isCurrentChainVM = currentChain?.chain_type === 'vm';

const whitelistedChains = NEXT_PUBLIC_WHITELISTED_DEST_CHAINS_FOR_VM.split(',').map(chain => chain.trim());

// Normalize whitelist check
const isAllChainsWhitelisted = whitelistedChains[0] === 'all';

return chains.filter((chain) => {
// Always filter out current chain
if (chain.chain_id === currentChainId) return false;

// For EVM chains, check whitelist
if (isCurrentChainVM && chain.chain_type === 'evm') {
return isAllChainsWhitelisted || whitelistedChains.includes(chain.id);
}

// Non-EVM chains are always included
return true;
});
};
14 changes: 6 additions & 8 deletions apps/maestro/src/ui/components/ChainsDropdown/ChainsDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
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";
import { Maybe } from "@axelarjs/utils";
Expand All @@ -18,6 +16,8 @@ import {
useChainsDropdownContainer,
withChainsDropdownProvider,
} from "./ChainsDropdown.state";
import { ITSChainConfig } from "@axelarjs/api";
import { HelpCircleIcon, Dropdown } from "@axelarjs/ui";

const ICON_SIZES = {
xs: 14,
Expand Down Expand Up @@ -52,19 +52,17 @@ export const ChainIcon: FC<{
);
};

type ChainConfig = EVMChainConfig | VMChainConfig;

type Props = {
chains?: ChainConfig[];
chains?: ITSChainConfig[];
compact?: boolean;
hideLabel?: boolean;
disabled?: boolean;
triggerClassName?: string;
chainIconClassName?: string;
contentClassName?: string;
renderTrigger?: () => React.ReactNode;
selectedChain?: ChainConfig;
onSelectChain?: (chain: ChainConfig | null) => void;
selectedChain?: ITSChainConfig;
onSelectChain?: (chain?: ITSChainConfig) => void;
size?: keyof typeof ICON_SIZES;
chainType?: "evm" | "vm";
};
Expand Down Expand Up @@ -217,7 +215,7 @@ const ChainsDropdown: FC<Props> = (props) => {
<button
onClick={(e: React.MouseEvent) => {
e.preventDefault();
props.onSelectChain?.(null);
props.onSelectChain?.(undefined);
actions.selectChainId(null);
}}
className="group flex w-full items-center gap-2"
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/axelarscan/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export type AxelarAssetPrice = Pick<
updated_at: number;
};

export type ITSChainConfig = VMChainConfig | EVMChainConfig;

export type VMChainConfig = {
chain_id: number;
chain_name: string;
Expand Down
Loading