From 59b6ef842b2e1ecfa9a9188df5128c31dfbf5331 Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Sun, 22 Dec 2024 19:23:29 +0000 Subject: [PATCH] Dynamically populate the Environment dropdown --- components/Header/Header.tsx | 13 +++++-------- providers/Providers.tsx | 24 ++++-------------------- providers/useEnv.ts | 32 +++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/components/Header/Header.tsx b/components/Header/Header.tsx index b2f3b88..aaabbf4 100644 --- a/components/Header/Header.tsx +++ b/components/Header/Header.tsx @@ -3,7 +3,7 @@ import { IconChevronDown } from '@tabler/icons-react'; import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'; import classes from './Header.module.css'; -import { Env } from '@/providers/useEnv'; +import { Env, EnvOption } from '@/providers/useEnv'; import RetainQueryLink from '../RetainQueryLink'; const HeaderLink = ({ label, link, disabled }: { label: string, link: string, disabled?: boolean }) => { @@ -15,7 +15,7 @@ const HeaderLink = ({ label, link, disabled }: { label: string, link: string, di ); }; -export function Header({ env, setEnv }: { env: string; setEnv: (env: Env) => void }) { +export function Header({ env, envOptions, setEnv }: { env: string; envOptions: EnvOption[], setEnv: (env: Env) => void }) { return ( voi - setEnv('mainnet')}>Solana Mainnet - setEnv('devnet')}>Solana Devnet - setEnv('eclipse-mainnet')}>Eclipse Mainnet - setEnv('eclipse-devnet')}>Eclipse Devnet - setEnv('sonic-devnet')}>Sonic Devnet - setEnv('localhost')}>Localhost + {envOptions.map(({ env: e, label }) => ( + setEnv(e)}>{label} + ))} diff --git a/providers/Providers.tsx b/providers/Providers.tsx index 7ccdc75..6a7d7ae 100644 --- a/providers/Providers.tsx +++ b/providers/Providers.tsx @@ -12,7 +12,7 @@ import { useSearchParams, useRouter, usePathname } from 'next/navigation'; import { Header } from '@/components/Header/Header'; import { UmiProvider } from './UmiProvider'; import { EnvProvider } from './EnvProvider'; -import { Env } from './useEnv'; +import { Env, envOptions } from './useEnv'; export function Providers({ children }: { children: ReactNode }) { const router = useRouter(); @@ -20,7 +20,7 @@ export function Providers({ children }: { children: ReactNode }) { const pathname = usePathname(); const queryEnv = searchParams.get('env'); const [client] = useState(new QueryClient()); - const [env, setEnv] = useState((queryEnv === 'mainnet' || queryEnv === 'devnet') ? queryEnv : 'mainnet'); + const [env, setEnv] = useState((queryEnv === 'mainnet' || queryEnv === 'devnet') ? queryEnv : envOptions[0]?.env); const wallets = useMemo( () => [ new PhantomWalletAdapter(), @@ -43,23 +43,7 @@ export function Providers({ children }: { children: ReactNode }) { // } // }, []); - const endpoint = useMemo(() => { - switch (env) { - case 'mainnet': - return process.env.NEXT_PUBLIC_MAINNET_RPC_URL; - case 'eclipse-mainnet': - return process.env.NEXT_PUBLIC_ECLIPSE_MAINNET_RPC_URL; - case 'sonic-devnet': - return process.env.NEXT_PUBLIC_SONIC_DEVNET_RPC_URL; - case 'eclipse-devnet': - return process.env.NEXT_PUBLIC_ECLIPSE_DEVNET_RPC_URL; - case 'localhost': - return 'http://localhost:8899'; - case 'devnet': - default: - return process.env.NEXT_PUBLIC_DEVNET_RPC_URL; - } - }, [env]); + const endpoint = useMemo(() => envOptions.find(({ env: e }) => e === env)?.endpoint, [env]); return ( @@ -77,7 +61,7 @@ export function Providers({ children }: { children: ReactNode }) { }} > -
+
{children} diff --git a/providers/useEnv.ts b/providers/useEnv.ts index 539f607..c52f27c 100644 --- a/providers/useEnv.ts +++ b/providers/useEnv.ts @@ -1,6 +1,36 @@ import { createContext, useContext } from 'react'; -export type Env = 'devnet' | 'testnet' | 'mainnet' | 'localhost' | 'eclipse-devnet' | 'eclipse-mainnet' | 'sonic-devnet'; +export type Env = 'devnet' | 'mainnet' | 'localhost' | 'eclipse-devnet' | 'eclipse-mainnet' | 'sonic-devnet'; +export type EnvOption = { env: Env, endpoint: string, label: string }; + +const endpoints: Record = { + mainnet: process.env.NEXT_PUBLIC_MAINNET_RPC_URL, + devnet: process.env.NEXT_PUBLIC_DEVNET_RPC_URL, + 'eclipse-mainnet': process.env.NEXT_PUBLIC_ECLIPSE_MAINNET_RPC_URL, + 'eclipse-devnet': process.env.NEXT_PUBLIC_ECLIPSE_DEVNET_RPC_URL, + 'sonic-devnet': process.env.NEXT_PUBLIC_SONIC_DEVNET_RPC_URL, + localhost: 'http://localhost:8899', +}; + +const labels: Record = { + mainnet: 'Solana Mainnet', + devnet: 'Solana Devnet', + 'eclipse-mainnet': 'Eclipse Mainnet', + 'eclipse-devnet': 'Eclipse Devnet', + 'sonic-devnet': 'Sonic Devnet', + localhost: 'Localhost', +}; + +const envs: Env[] = Object + .entries(endpoints) + .map(([env, endpoint]) => endpoint ? env as Env : null) + .filter(Boolean) as Env[]; + +export const envOptions: EnvOption[] = envs.map((env) => ({ + env, + endpoint: endpoints[env] as string, + label: labels[env] as string, +})); type EnvContext = { env: Env;