(TabIds.Empty);
@@ -138,7 +140,7 @@ export const Dashboard = ({
<>
- {restrictedMode ? (
-
- ) : (
+ {enableOis ? (
+ ) : (
+
)}
diff --git a/apps/staking/src/components/Governance/index.tsx b/apps/staking/src/components/Governance/index.tsx
index d5fc12fa6..7af33719f 100644
--- a/apps/staking/src/components/Governance/index.tsx
+++ b/apps/staking/src/components/Governance/index.tsx
@@ -12,7 +12,7 @@ type Props = {
staked: bigint;
cooldown: bigint;
cooldown2: bigint;
- restrictedMode?: boolean | undefined;
+ allowStaking?: boolean | undefined;
};
export const Governance = ({
@@ -23,10 +23,10 @@ export const Governance = ({
staked,
cooldown,
cooldown2,
- restrictedMode,
+ allowStaking,
}: Props) => (
}
tagline="Vote and Influence the Network"
@@ -47,7 +47,7 @@ export const Governance = ({
unstake:
api.type === ApiStateType.Loaded ? api.unstakeGovernance : undefined,
unstakeDescription: "Unstake tokens from the Governance program",
- ...(!restrictedMode && {
+ ...(allowStaking && {
stake:
api.type === ApiStateType.Loaded ? api.stakeGovernance : undefined,
stakeDescription: "Stake funds to participate in governance votes",
diff --git a/apps/staking/src/components/Home/index.tsx b/apps/staking/src/components/Home/index.tsx
index 591dd139d..21b9cd032 100644
--- a/apps/staking/src/components/Home/index.tsx
+++ b/apps/staking/src/components/Home/index.tsx
@@ -20,24 +20,34 @@ const ONE_SECOND_IN_MS = 1000;
const ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;
const REFRESH_INTERVAL = 1 * ONE_MINUTE_IN_MS;
-export const Home = () => ;
-export const RestrictedMode = () => ;
+export const Home = () => ;
+export const GeoBlockedHome = () => ;
+export const GovernanceOnlyHome = () => ;
type HomeImplProps = {
- restrictedMode?: boolean | undefined;
+ enableGovernance?: boolean | undefined;
+ enableOis?: boolean | undefined;
};
-export const HomeImpl = ({ restrictedMode }: HomeImplProps) => {
+export const HomeImpl = ({ enableGovernance, enableOis }: HomeImplProps) => {
const isSSR = useIsSSR();
- return isSSR ? : ;
+ return isSSR ? (
+
+ ) : (
+
+ );
};
type MountedHomeProps = {
- restrictedMode?: boolean | undefined;
+ enableGovernance: boolean;
+ enableOis: boolean;
};
-const MountedHome = ({ restrictedMode }: MountedHomeProps) => {
+const MountedHome = ({ enableGovernance, enableOis }: MountedHomeProps) => {
const api = useApi();
switch (api.type) {
@@ -56,7 +66,11 @@ const MountedHome = ({ restrictedMode }: MountedHomeProps) => {
case ApiStateType.LoadedNoStakeAccount:
case ApiStateType.Loaded: {
return (
-
+
);
}
}
@@ -64,12 +78,14 @@ const MountedHome = ({ restrictedMode }: MountedHomeProps) => {
type StakeAccountLoadedHomeProps = {
api: States[ApiStateType.Loaded] | States[ApiStateType.LoadedNoStakeAccount];
- restrictedMode?: boolean | undefined;
+ enableGovernance: boolean;
+ enableOis: boolean;
};
const StakeAccountLoadedHome = ({
api,
- restrictedMode,
+ enableGovernance,
+ enableOis,
}: StakeAccountLoadedHomeProps) => {
const data = useData(api.dashboardDataCacheKey, api.loadData, {
refreshInterval: REFRESH_INTERVAL,
@@ -87,7 +103,12 @@ const StakeAccountLoadedHome = ({
case DashboardDataStateType.Loaded: {
return (
-
+
);
}
}
diff --git a/apps/staking/src/components/Root/restricted-region-banner.tsx b/apps/staking/src/components/Root/restricted-region-banner.tsx
index 66dde5364..2b8bf5681 100644
--- a/apps/staking/src/components/Root/restricted-region-banner.tsx
+++ b/apps/staking/src/components/Root/restricted-region-banner.tsx
@@ -2,12 +2,16 @@
import { useSelectedLayoutSegment } from "next/navigation";
-import { RESTRICTED_MODE_SEGMENT } from "../../config/isomorphic";
+import {
+ GEO_BLOCKED_SEGMENT,
+ GOVERNANCE_ONLY_SEGMENT,
+} from "../../config/isomorphic";
import { Link } from "../Link";
export const RestrictedRegionBanner = () => {
const segment = useSelectedLayoutSegment();
- const isRestrictedMode = segment === RESTRICTED_MODE_SEGMENT;
+ const isRestrictedMode =
+ segment === GEO_BLOCKED_SEGMENT || segment === GOVERNANCE_ONLY_SEGMENT;
return isRestrictedMode ? (
diff --git a/apps/staking/src/config/isomorphic.ts b/apps/staking/src/config/isomorphic.ts
index eb77bfdd8..666864997 100644
--- a/apps/staking/src/config/isomorphic.ts
+++ b/apps/staking/src/config/isomorphic.ts
@@ -13,19 +13,26 @@
export const IS_PRODUCTION_BUILD = process.env.NODE_ENV === "production";
/**
- * Region or VPN-blocked requests will be redirected here if they are eligible
- * for "restricted mode" (aka only allowing withdrawals). This is used in the
+ * Region blocked requests will be rewritten here. This is used in the
* middleware to implement the block, and also consumed in any components that
* are part of the page layout but need to know if the request is blocked from
* accessing the app, such as the WalletButton in the app header.
*
* Don't change unless you also change the relevant app route path to match.
*/
-export const RESTRICTED_MODE_SEGMENT = "restricted-mode";
+export const GEO_BLOCKED_SEGMENT = "geo-blocked";
/**
- * Similar to `RESTRICTED_MODE_SEGMENT`; this is where vpn-blocked traffic will
- * be rewritten to if it isn't eligible for restricted mode.
+ * Similar to `GEO_BLOCKED_SEGMENT`; this is where governance-only region
+ * requests are rewritten to.
+ *
+ * Don't change unless you also change the relevant app route path to match.
+ */
+export const GOVERNANCE_ONLY_SEGMENT = "governance-only";
+
+/**
+ * Similar to `GEO_BLOCKED_SEGMENT`; this is where vpn-blocked traffic will be
+ * rewritten to.
*
* Don't change unless you also change the relevant app route path to match.
*/
diff --git a/apps/staking/src/config/server.ts b/apps/staking/src/config/server.ts
index c1bb63443..9c83e767b 100644
--- a/apps/staking/src/config/server.ts
+++ b/apps/staking/src/config/server.ts
@@ -54,6 +54,11 @@ export const WALLETCONNECT_PROJECT_ID = demandInProduction(
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 GOVERNANCE_ONLY_REGIONS = transformOr(
+ "GOVERNANCE_ONLY_REGIONS",
+ fromCsv,
+ [],
+);
export const PROXYCHECK_API_KEY = demandInProduction("PROXYCHECK_API_KEY");
class MissingEnvironmentError extends Error {
diff --git a/apps/staking/src/middleware.ts b/apps/staking/src/middleware.ts
index 032296fa4..bd90b2f06 100644
--- a/apps/staking/src/middleware.ts
+++ b/apps/staking/src/middleware.ts
@@ -2,13 +2,19 @@ import { type NextRequest, NextResponse } from "next/server";
import ProxyCheck from "proxycheck-ts";
import {
- RESTRICTED_MODE_SEGMENT,
+ GEO_BLOCKED_SEGMENT,
+ GOVERNANCE_ONLY_SEGMENT,
VPN_BLOCKED_SEGMENT,
} from "./config/isomorphic";
-import { BLOCKED_REGIONS, PROXYCHECK_API_KEY } from "./config/server";
+import {
+ BLOCKED_REGIONS,
+ GOVERNANCE_ONLY_REGIONS,
+ PROXYCHECK_API_KEY,
+} from "./config/server";
-const RESTRICTED_MODE_PATH = `/${RESTRICTED_MODE_SEGMENT}`;
-const VPN_BLOCK_PATH = `/${VPN_BLOCKED_SEGMENT}`;
+const GEO_BLOCKED_PATH = `/${GEO_BLOCKED_SEGMENT}`;
+const GOVERNANCE_ONLY_PATH = `/${GOVERNANCE_ONLY_SEGMENT}`;
+const VPN_BLOCKED_PATH = `/${VPN_BLOCKED_SEGMENT}`;
const proxyCheckClient = PROXYCHECK_API_KEY
? new ProxyCheck({ api_key: PROXYCHECK_API_KEY })
@@ -16,9 +22,11 @@ const proxyCheckClient = PROXYCHECK_API_KEY
export const middleware = async (request: NextRequest) => {
if (await isProxyBlocked(request)) {
- return rewrite(request, VPN_BLOCK_PATH);
+ return rewrite(request, VPN_BLOCKED_PATH);
+ } else if (isGovernanceOnlyRegion(request)) {
+ return rewrite(request, GOVERNANCE_ONLY_PATH);
} else if (isRegionBlocked(request)) {
- return rewrite(request, RESTRICTED_MODE_PATH);
+ return rewrite(request, GEO_BLOCKED_PATH);
} else if (isBlockedSegment(request)) {
return rewrite(request, "/not-found");
} else {
@@ -29,6 +37,10 @@ export const middleware = async (request: NextRequest) => {
const rewrite = (request: NextRequest, path: string) =>
NextResponse.rewrite(new URL(path, request.url));
+const isGovernanceOnlyRegion = ({ geo }: NextRequest) =>
+ geo?.country !== undefined &&
+ GOVERNANCE_ONLY_REGIONS.includes(geo.country.toLowerCase());
+
const isRegionBlocked = ({ geo }: NextRequest) =>
geo?.country !== undefined &&
BLOCKED_REGIONS.includes(geo.country.toLowerCase());
@@ -43,8 +55,9 @@ const isProxyBlocked = async ({ ip }: NextRequest) => {
};
const isBlockedSegment = ({ nextUrl: { pathname } }: NextRequest) =>
- pathname.startsWith(`/${VPN_BLOCKED_SEGMENT}`) ||
- pathname.startsWith(`/${RESTRICTED_MODE_SEGMENT}`);
+ pathname.startsWith(VPN_BLOCKED_PATH) ||
+ pathname.startsWith(GEO_BLOCKED_PATH) ||
+ pathname.startsWith(GOVERNANCE_ONLY_PATH);
export const config = {
// Next.js requires that this is a static string and fails to read it if it's