Skip to content
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
72 changes: 54 additions & 18 deletions frontend/src/components/TokenPicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useTokenList } from "../hooks/useTokenList";
import { ChainIdToName, useTokenList, isTestnet } from "../hooks/useTokenList";
import { useTokenSearch } from "../hooks/useTokenSearch";
import { CopyButton } from "./ui/copyButton";
import { Avatar } from "./ui/avatar";
Expand Down Expand Up @@ -216,20 +216,22 @@ export function TokenPicker({
setOpen(false);
};

const isOnTestnet = isTestnet(chainId);

return (
<>
<Button
type="button"
variant="outline"
disabled={disabled}
onClick={() => setOpen(true)}
className={cn(
"h-12 px-4 justify-between bg-white hover:bg-gray-50 border border-gray-300 text-gray-900",
"shadow-sm hover:shadow-md transition-all duration-200 hover:border-gray-400",
disabled && "opacity-50 cursor-not-allowed",
className
)}
>
type="button"
variant="outline"
disabled={disabled || isOnTestnet}
onClick={() => setOpen(true)}
className={cn(
"h-12 px-4 justify-between bg-white hover:bg-gray-50 border border-gray-300 text-gray-900",
"shadow-sm hover:shadow-md transition-all duration-200 hover:border-gray-400",
(disabled || isOnTestnet) && "opacity-50 cursor-not-allowed",
className
)}
>
{selected ? (
<div className="flex items-center gap-3">
<Avatar
Expand Down Expand Up @@ -262,6 +264,15 @@ export function TokenPicker({
<ChevronDown className="w-4 h-4 text-gray-500" />
</Button>

{isOnTestnet && (
<div className="mt-2 flex items-start gap-2 p-3 bg-amber-50 border border-amber-200 rounded-lg">
<AlertCircle className="w-4 h-4 text-amber-600 flex-shrink-0 mt-0.5" />
<p className="text-sm text-amber-800">
Token selection is disabled on testnets. Please switch to a mainnet network to use this feature.
</p>
</div>
)}

<Modal isOpen={open} onClose={() => setOpen(false)}>
<div className="p-6">
<div className="flex items-center gap-2 mb-4">
Expand Down Expand Up @@ -315,12 +326,37 @@ export function TokenPicker({
<div className="flex items-center justify-center py-12">
<div className="flex flex-col items-center gap-3 text-gray-500">
<AlertCircle className="w-8 h-8" />
<span className="text-sm font-medium">
Failed to load tokens
</span>
<span className="text-xs text-center max-w-[280px]">
{tokensError}
</span>
{tokensError.includes("manually input") ? (
<>
<span className="text-sm font-medium">
Testnet:{" "}
{ChainIdToName[chainId] || "Unknown"} (
{chainId})
</span>
<span className="text-xs text-center max-w-[280px]">
Token Selection is not supported in testnets.
</span>
<span className="text-xs text-center max-w-[280px]">
{tokensError}
</span>
</>
) : tokensError.includes("not supported") ? (
<>
<span className="text-sm font-medium">
Chain Not Supported
</span>
<span className="text-xs text-center">{tokensError}</span>
</>
) : (
<>
<span className="text-sm font-medium">
Failed to load tokens
</span>
<span className="text-xs text-center max-w-[280px]">
{tokensError}
</span>
</>
)}
</div>
</div>
) : filteredTokens.length === 0 ? (
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/hooks/useTokenList.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const tokenCache = {};
const TESTNET_CHAIN_IDS = new Set([11155111, 5]); // Sepolia, Goerli

// Helper function to check if a chain is testnet
const isTestnet = (chainId) => TESTNET_CHAIN_IDS.has(chainId);
export const isTestnet = (chainId) => TESTNET_CHAIN_IDS.has(chainId);

export const ChainIdToName = {
1: "ethereum",
Expand All @@ -25,6 +25,8 @@ export function useTokenList(chainId) {
// Return cached tokens if available
if (tokenCache[chainId]) {
setTokens(tokenCache[chainId]);
setError(null);
setLoading(false);
return;
}

Expand Down