Skip to content

Commit

Permalink
Merge pull request #1989 from cprussin/add-devnet-switch
Browse files Browse the repository at this point in the history
feat(staking): add a switch to flip between mainnet & devnet
  • Loading branch information
cprussin authored Oct 2, 2024
2 parents cec695e + b83ab65 commit 7643f98
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 97 deletions.
12 changes: 5 additions & 7 deletions apps/staking/src/app/api/v1/cmc/supply/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import { clusterApiUrl, Connection } from "@solana/web3.js";
import type { NextRequest } from "next/server";
import { z } from "zod";

import { IS_MAINNET, RPC } from "../../../../../config/server";
import { MAINNET_RPC } from "../../../../../config/server";

const querySchema = z.enum(["totalSupply", "circulatingSupply"]);

export async function GET(req: NextRequest) {
const isMainnet = req.nextUrl.searchParams.get("devnet") !== "true";
const stakingClient = new PythStakingClient({
connection: new Connection(
RPC ??
clusterApiUrl(
IS_MAINNET
? WalletAdapterNetwork.Mainnet
: WalletAdapterNetwork.Devnet,
),
isMainnet && MAINNET_RPC !== undefined
? MAINNET_RPC
: clusterApiUrl(WalletAdapterNetwork.Devnet),
{
httpHeaders: {
Origin: req.nextUrl.origin,
Expand Down
12 changes: 5 additions & 7 deletions apps/staking/src/app/api/v1/locked_accounts/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import type { NextRequest } from "next/server";
import { z } from "zod";

import { IS_MAINNET, RPC } from "../../../../config/server";
import { MAINNET_RPC } from "../../../../config/server";
import { tokensToString } from "../../../../tokens";

const UnlockScheduleSchema = z.object({
Expand Down Expand Up @@ -35,14 +35,12 @@ const isValidPublicKey = (publicKey: string) => {
};

export async function GET(req: NextRequest) {
const isMainnet = req.nextUrl.searchParams.get("devnet") !== "true";
const stakingClient = new PythStakingClient({
connection: new Connection(
RPC ??
clusterApiUrl(
IS_MAINNET
? WalletAdapterNetwork.Mainnet
: WalletAdapterNetwork.Devnet,
),
isMainnet && MAINNET_RPC !== undefined
? MAINNET_RPC
: clusterApiUrl(WalletAdapterNetwork.Devnet),
{
httpHeaders: {
Origin: req.nextUrl.origin,
Expand Down
15 changes: 6 additions & 9 deletions apps/staking/src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,13 @@ export const Menu = <T extends object>({
...props
}: MenuProps<T>) => (
<Popover
className="data-[entering]:animate-in data-[exiting]:animate-out data-[entering]:fade-in data-[exiting]:fade-out"
className={clsx(
"flex origin-top-right flex-col border border-neutral-400 bg-pythpurple-100 py-2 text-sm text-pythpurple-950 shadow shadow-neutral-400 data-[entering]:animate-in data-[exiting]:animate-out data-[entering]:fade-in data-[exiting]:fade-out",
className,
)}
{...(placement && { placement })}
>
<BaseMenu
className={clsx(
"flex origin-top-right flex-col border border-neutral-400 bg-pythpurple-100 py-2 text-sm text-pythpurple-950 shadow shadow-neutral-400 outline-none",
className,
)}
{...props}
/>
<BaseMenu className="outline-none" {...props} />
</Popover>
);

Expand All @@ -51,7 +48,7 @@ export const MenuItem = ({
<BaseMenuItem
textValue={textValue ?? (typeof children === "string" ? children : "")}
className={clsx(
"flex cursor-pointer items-center gap-2 whitespace-nowrap px-4 py-2 text-left data-[disabled]:cursor-default data-[focused]:bg-pythpurple-800/20 data-[has-submenu]:data-[open]:bg-pythpurple-800/10 data-[has-submenu]:data-[open]:data-[focused]:bg-pythpurple-800/20 focus:outline-none focus-visible:outline-none",
"flex cursor-pointer items-center gap-2 whitespace-nowrap px-4 py-2 text-left outline-none data-[disabled]:cursor-default data-[focused]:bg-pythpurple-800/20 data-[has-submenu]:data-[open]:bg-pythpurple-800/10 data-[has-submenu]:data-[open]:data-[focused]:bg-pythpurple-800/20",
className,
)}
{...props}
Expand Down
13 changes: 3 additions & 10 deletions apps/staking/src/components/OracleIntegrityStaking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
Label,
TextField,
Form,
Switch,
MenuTrigger,
} from "react-aria-components";

Expand All @@ -50,6 +49,7 @@ import { Select } from "../Select";
import { SparkChart } from "../SparkChart";
import { StakingTimeline } from "../StakingTimeline";
import { Styled } from "../Styled";
import { Switch } from "../Switch";
import { Tokens } from "../Tokens";
import { AmountType, TransferButton } from "../TransferButton";
import { TruncatedKey } from "../TruncatedKey";
Expand Down Expand Up @@ -709,15 +709,8 @@ const PublisherList = ({
<Switch
isSelected={yoursFirst}
onChange={updateYoursFirst}
className="group flex cursor-pointer flex-row items-center gap-2"
>
<div className="whitespace-nowrap opacity-80">
Show your positions first
</div>
<div className="h-8 w-16 flex-none rounded-full border border-neutral-400/50 bg-neutral-800/50 p-1 transition group-data-[selected]:border-pythpurple-600 group-data-[selected]:bg-pythpurple-600/10">
<div className="aspect-square h-full rounded-full bg-neutral-400/50 transition group-data-[selected]:translate-x-8 group-data-[selected]:bg-pythpurple-600" />
</div>
</Switch>
preLabel="Show your positions first"
/>
</div>
</div>

Expand Down
86 changes: 42 additions & 44 deletions apps/staking/src/components/Root/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { GoogleAnalytics } from "@next/third-parties/google";
import { WalletAdapterNetwork } from "@solana/wallet-adapter-base";
import clsx from "clsx";
import { Red_Hat_Text, Red_Hat_Mono } from "next/font/google";
import type { ReactNode, CSSProperties } from "react";
import type { ReactNode, CSSProperties, HTMLProps } from "react";

import { I18nProvider } from "./i18n-provider";
import { RestrictedRegionBanner } from "./restricted-region-banner";
Expand All @@ -11,12 +10,12 @@ import {
GOOGLE_ANALYTICS_ID,
AMPLITUDE_API_KEY,
WALLETCONNECT_PROJECT_ID,
RPC,
MAINNET_RPC,
HERMES_URL,
IS_MAINNET,
} from "../../config/server";
import { ApiProvider } from "../../hooks/use-api";
import { LoggerProvider } from "../../hooks/use-logger";
import { NetworkProvider } from "../../hooks/use-network";
import { Amplitude } from "../Amplitude";
import { Footer } from "../Footer";
import { Header } from "../Header";
Expand All @@ -40,49 +39,48 @@ type Props = {
};

export const Root = ({ children }: Props) => (
<HtmlWithProviders
lang="en"
dir="ltr"
style={
{
"--header-height": "4rem",
} as CSSProperties
}
className={clsx(
"scroll-pt-header-height",
redHatText.variable,
redHatMono.variable,
)}
>
<body className="grid min-h-dvh grid-rows-[auto_auto_1fr_auto] text-pythpurple-100 [background:radial-gradient(20rem_50rem_at_50rem_10rem,_rgba(119,_49,_234,_0.20)_0%,_rgba(17,_15,_35,_0.00)_100rem),_#0A0814] selection:bg-pythpurple-600/60">
<Header className="z-10" />
<RestrictedRegionBanner />
<MaxWidth className="z-0 min-h-[calc(100dvh_-_var(--header-height))] py-8 sm:min-h-0">
{children}
</MaxWidth>
<Footer className="z-10" />
</body>
{GOOGLE_ANALYTICS_ID && <GoogleAnalytics gaId={GOOGLE_ANALYTICS_ID} />}
{AMPLITUDE_API_KEY && <Amplitude apiKey={AMPLITUDE_API_KEY} />}
{!IS_PRODUCTION_SERVER && <ReportAccessibility />}
</HtmlWithProviders>
);

const HtmlWithProviders = ({ lang, ...props }: HTMLProps<HTMLHtmlElement>) => (
<I18nProvider>
<RouterProvider>
<LoggerProvider>
<WalletProvider
walletConnectProjectId={WALLETCONNECT_PROJECT_ID}
rpc={RPC}
network={
IS_MAINNET
? WalletAdapterNetwork.Mainnet
: WalletAdapterNetwork.Devnet
}
>
<ApiProvider hermesUrl={HERMES_URL}>
<html
lang="en"
dir="ltr"
style={
{
"--header-height": "4rem",
} as CSSProperties
}
className={clsx(
"scroll-pt-header-height",
redHatText.variable,
redHatMono.variable,
)}
>
<body className="grid min-h-dvh grid-rows-[auto_auto_1fr_auto] text-pythpurple-100 [background:radial-gradient(20rem_50rem_at_50rem_10rem,_rgba(119,_49,_234,_0.20)_0%,_rgba(17,_15,_35,_0.00)_100rem),_#0A0814] selection:bg-pythpurple-600/60">
<Header className="z-10" />
<RestrictedRegionBanner />
<MaxWidth className="z-0 min-h-[calc(100dvh_-_var(--header-height))] py-8 sm:min-h-0">
{children}
</MaxWidth>
<Footer className="z-10" />
</body>
{GOOGLE_ANALYTICS_ID && (
<GoogleAnalytics gaId={GOOGLE_ANALYTICS_ID} />
)}
{AMPLITUDE_API_KEY && <Amplitude apiKey={AMPLITUDE_API_KEY} />}
{!IS_PRODUCTION_SERVER && <ReportAccessibility />}
</html>
</ApiProvider>
</WalletProvider>
<NetworkProvider>
<WalletProvider
walletConnectProjectId={WALLETCONNECT_PROJECT_ID}
mainnetRpc={MAINNET_RPC}
>
<ApiProvider hermesUrl={HERMES_URL}>
<html lang={lang} {...props} />
</ApiProvider>
</WalletProvider>
</NetworkProvider>
</LoggerProvider>
</RouterProvider>
</I18nProvider>
Expand Down
45 changes: 45 additions & 0 deletions apps/staking/src/components/Switch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import clsx from "clsx";
import type { ComponentProps, ReactNode } from "react";
import { Switch as BaseSwitch } from "react-aria-components";

type Props = Omit<ComponentProps<typeof BaseSwitch>, "children"> & {
preLabel?: ReactNode;
postLabel?: ReactNode;
size?: "small";
};

export const Switch = ({
preLabel,
postLabel,
className,
size,
...props
}: Props) => (
<BaseSwitch
className={clsx(
"group flex cursor-pointer flex-row items-center gap-2",
className,
)}
{...props}
>
{preLabel && <div className="whitespace-nowrap opacity-80">{preLabel}</div>}
<div
className={clsx(
"flex-none rounded-full border border-neutral-400/50 bg-neutral-800/50 p-1 transition group-data-[selected]:border-pythpurple-600 group-data-[selected]:bg-pythpurple-600/10",
size === "small" ? "h-6 w-10" : "h-8 w-16",
)}
>
<div
className={clsx(
"aspect-square h-full rounded-full bg-neutral-400/50 transition group-data-[selected]:bg-pythpurple-600",
size === "small"
? "group-data-[selected]:translate-x-4"
: "group-data-[selected]:translate-x-8",
)}
/>
</div>
{postLabel && (
<div className="whitespace-nowrap opacity-80">{postLabel}</div>
)}
</BaseSwitch>
);
18 changes: 18 additions & 0 deletions apps/staking/src/components/WalletButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
SubmenuTrigger,
Header,
Collection,
MenuItem as BaseMenuItem,
} from "react-aria-components";

import { VPN_BLOCKED_SEGMENT } from "../../config/isomorphic";
Expand All @@ -36,9 +37,11 @@ import {
} from "../../hooks/use-api";
import { StateType as DataStateType, useData } from "../../hooks/use-data";
import { useLogger } from "../../hooks/use-logger";
import { useNetwork } from "../../hooks/use-network";
import { usePrimaryDomain } from "../../hooks/use-primary-domain";
import { Button } from "../Button";
import { Menu, MenuItem, Section, Separator } from "../Menu";
import { Switch } from "../Switch";
import { TruncatedKey } from "../TruncatedKey";

const ONE_SECOND_IN_MS = 1000;
Expand Down Expand Up @@ -106,6 +109,7 @@ const ConnectedButton = ({
logger.error(error);
});
}, [wallet, logger]);
const { isMainnet, toggleMainnet } = useNetwork();

return (
<MenuTrigger>
Expand Down Expand Up @@ -139,6 +143,20 @@ const ConnectedButton = ({
Disconnect
</MenuItem>
</Section>
<Separator />
<Section>
<BaseMenuItem
className="outline-none data-[focused]:bg-pythpurple-800/20"
onAction={toggleMainnet}
>
<Switch
isSelected={isMainnet}
postLabel="Mainnet"
className="px-4 py-1"
size="small"
/>
</BaseMenuItem>
</Section>
</Menu>
</MenuTrigger>
);
Expand Down
23 changes: 18 additions & 5 deletions apps/staking/src/components/WalletProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,35 @@ import {
import { clusterApiUrl } from "@solana/web3.js";
import { type ReactNode, useMemo } from "react";

import { useNetwork } from "../../hooks/use-network";
import { metadata } from "../../metadata";

type Props = {
network: WalletAdapterNetwork.Devnet | WalletAdapterNetwork.Mainnet;
children?: ReactNode | ReactNode[] | undefined;
walletConnectProjectId?: string | undefined;
rpc?: string | undefined;
mainnetRpc?: string | undefined;
};

export const WalletProvider = ({
network,
children,
walletConnectProjectId,
rpc,
mainnetRpc,
}: Props) => {
const endpoint = useMemo(() => rpc ?? clusterApiUrl(network), [rpc, network]);
const { isMainnet } = useNetwork();

const network = useMemo(
() =>
isMainnet ? WalletAdapterNetwork.Mainnet : WalletAdapterNetwork.Devnet,
[isMainnet],
);

const endpoint = useMemo(
() =>
network === WalletAdapterNetwork.Mainnet && mainnetRpc !== undefined
? mainnetRpc
: clusterApiUrl(network),
[mainnetRpc, network],
);

const wallets = useMemo(
() => [
Expand Down
3 changes: 1 addition & 2 deletions apps/staking/src/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export const AMPLITUDE_API_KEY = demandInProduction("AMPLITUDE_API_KEY");
export const WALLETCONNECT_PROJECT_ID = demandInProduction(
"WALLETCONNECT_PROJECT_ID",
);
export const RPC = process.env.RPC;
export const IS_MAINNET = process.env.IS_MAINNET !== undefined;
export const MAINNET_RPC = process.env.MAINNET_RPC;
export const HERMES_URL = getOr("HERMES_URL", "https://hermes.pyth.network");
export const BLOCKED_REGIONS = transformOr("BLOCKED_REGIONS", fromCsv, []);
export const PROXYCHECK_API_KEY = demandInProduction("PROXYCHECK_API_KEY");
Expand Down
Loading

0 comments on commit 7643f98

Please sign in to comment.