Skip to content

Commit

Permalink
feat(staking): add restricted mode for non-fatf geofenced countries
Browse files Browse the repository at this point in the history
  • Loading branch information
cprussin committed Sep 25, 2024
1 parent 81b80c7 commit d82136f
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 102 deletions.
1 change: 1 addition & 0 deletions apps/staking/src/app/restricted-mode/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RestrictedMode as default } from "../../components/Home";
98 changes: 52 additions & 46 deletions apps/staking/src/components/AccountSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Props = {
availableRewards: bigint;
expiringRewards: Date | undefined;
availableToWithdraw: bigint;
restrictedMode?: boolean | undefined;
};

export const AccountSummary = ({
Expand All @@ -54,6 +55,7 @@ export const AccountSummary = ({
availableToWithdraw,
availableRewards,
expiringRewards,
restrictedMode,
}: Props) => (
<section className="relative w-full overflow-hidden sm:border sm:border-neutral-600/50 sm:bg-pythpurple-800">
<Image
Expand Down Expand Up @@ -145,23 +147,25 @@ export const AccountSummary = ({
className="xl:hidden"
/>
)}
<DialogTrigger>
<Button variant="secondary" className="xl:hidden">
Claim
</Button>
{availableRewards === 0n ||
api.type === ApiStateType.LoadedNoStakeAccount ? (
<ModalDialog title="No Rewards" closeButtonText="Ok">
<p>You have no rewards available to be claimed</p>
</ModalDialog>
) : (
<ClaimDialog
expiringRewards={expiringRewards}
availableRewards={availableRewards}
api={api}
/>
)}
</DialogTrigger>
{!restrictedMode && (
<DialogTrigger>
<Button variant="secondary" className="xl:hidden">
Claim
</Button>
{availableRewards === 0n ||
api.type === ApiStateType.LoadedNoStakeAccount ? (
<ModalDialog title="No Rewards" closeButtonText="Ok">
<p>You have no rewards available to be claimed</p>
</ModalDialog>
) : (
<ClaimDialog
expiringRewards={expiringRewards}
availableRewards={availableRewards}
api={api}
/>
)}
</DialogTrigger>
)}
</div>
</div>
<div className="hidden w-auto items-stretch gap-4 xl:flex">
Expand All @@ -173,35 +177,37 @@ export const AccountSummary = ({
<WithdrawButton api={api} max={availableToWithdraw} size="small" />
}
/>
<BalanceCategory
name="Available Rewards"
amount={availableRewards}
description="Rewards you have earned from OIS"
action={
api.type === ApiStateType.Loaded ? (
<ClaimButton
size="small"
variant="secondary"
isDisabled={availableRewards === 0n}
api={api}
/>
) : (
<Button size="small" variant="secondary" isDisabled={true}>
Claim
</Button>
)
}
{...(expiringRewards !== undefined &&
availableRewards > 0n && {
warning: (
<>
Rewards expire one year from the epoch in which they were
earned. You have rewards expiring on{" "}
{expiringRewards.toLocaleDateString()}.
</>
),
})}
/>
{!restrictedMode && (
<BalanceCategory
name="Available Rewards"
amount={availableRewards}
description="Rewards you have earned from OIS"
action={
api.type === ApiStateType.Loaded ? (
<ClaimButton
size="small"
variant="secondary"
isDisabled={availableRewards === 0n}
api={api}
/>
) : (
<Button size="small" variant="secondary" isDisabled={true}>
Claim
</Button>
)
}
{...(expiringRewards !== undefined &&
availableRewards > 0n && {
warning: (
<>
Rewards expire one year from the epoch in which they were
earned. You have rewards expiring on{" "}
{expiringRewards.toLocaleDateString()}.
</>
),
})}
/>
)}
</div>
</div>
</section>
Expand Down
4 changes: 4 additions & 0 deletions apps/staking/src/components/Dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Props = {
integrityStakingPublishers: ComponentProps<
typeof OracleIntegrityStaking
>["publishers"];
restrictedMode?: boolean | undefined;
};

export const Dashboard = ({
Expand All @@ -57,6 +58,7 @@ export const Dashboard = ({
integrityStakingPublishers,
unlockSchedule,
yieldRate,
restrictedMode,
}: Props) => {
const [tab, setTab] = useState<TabId>(TabIds.Empty);

Expand Down Expand Up @@ -137,6 +139,7 @@ export const Dashboard = ({
availableToWithdraw={availableToWithdraw}
availableRewards={availableRewards}
expiringRewards={expiringRewards}
restrictedMode={restrictedMode}
/>
<Tabs
selectedKey={tab}
Expand Down Expand Up @@ -183,6 +186,7 @@ export const Dashboard = ({
cooldown2={integrityStakingCooldown2}
publishers={integrityStakingPublishers}
yieldRate={yieldRate}
restrictedMode={restrictedMode}
/>
</TabPanel>
<TabPanel id={TabIds.Governance}>
Expand Down
10 changes: 9 additions & 1 deletion apps/staking/src/components/Header/current-stake-account.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
"use client";

import clsx from "clsx";
import { useSelectedLayoutSegment } from "next/navigation";
import { type HTMLProps } from "react";

import {
REGION_BLOCKED_SEGMENT,
VPN_BLOCKED_SEGMENT,
} from "../../config/isomorphic";
import { StateType as ApiStateType, useApi } from "../../hooks/use-api";
import { CopyButton } from "../CopyButton";
import { TruncatedKey } from "../TruncatedKey";
Expand All @@ -11,9 +16,12 @@ export const CurrentStakeAccount = ({
className,
...props
}: HTMLProps<HTMLDivElement>) => {
const segment = useSelectedLayoutSegment();
const isBlocked =
segment === REGION_BLOCKED_SEGMENT || segment === VPN_BLOCKED_SEGMENT;
const api = useApi();

return api.type === ApiStateType.Loaded ? (
return api.type === ApiStateType.Loaded && !isBlocked ? (
<div
className={clsx(
"hidden flex-col items-end justify-center text-xs xs:flex md:flex-row md:items-center md:text-sm",
Expand Down
30 changes: 24 additions & 6 deletions apps/staking/src/components/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,23 @@ 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 = () => {
type Props = {
restrictedMode?: boolean | undefined;
};

export const Home = ({ restrictedMode }: Props) => {
const isSSR = useIsSSR();

return isSSR ? <Loading /> : <MountedHome />;
return isSSR ? <Loading /> : <MountedHome restrictedMode={restrictedMode} />;
};

export const RestrictedMode = () => <Home restrictedMode />;

type MountedHomeProps = {
restrictedMode?: boolean | undefined;
};

const MountedHome = () => {
const MountedHome = ({ restrictedMode }: MountedHomeProps) => {
const api = useApi();

switch (api.type) {
Expand All @@ -44,16 +54,22 @@ const MountedHome = () => {
}
case ApiStateType.LoadedNoStakeAccount:
case ApiStateType.Loaded: {
return <StakeAccountLoadedHome api={api} />;
return (
<StakeAccountLoadedHome restrictedMode={restrictedMode} api={api} />
);
}
}
};

type StakeAccountLoadedHomeProps = {
api: States[ApiStateType.Loaded] | States[ApiStateType.LoadedNoStakeAccount];
restrictedMode?: boolean | undefined;
};

const StakeAccountLoadedHome = ({ api }: StakeAccountLoadedHomeProps) => {
const StakeAccountLoadedHome = ({
api,
restrictedMode,
}: StakeAccountLoadedHomeProps) => {
const data = useData(api.dashboardDataCacheKey, api.loadData, {
refreshInterval: REFRESH_INTERVAL,
});
Expand All @@ -69,7 +85,9 @@ const StakeAccountLoadedHome = ({ api }: StakeAccountLoadedHomeProps) => {
}

case DashboardDataStateType.Loaded: {
return <Dashboard {...data.data} api={api} />;
return (
<Dashboard {...data.data} api={api} restrictedMode={restrictedMode} />
);
}
}
};
Loading

0 comments on commit d82136f

Please sign in to comment.