Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tangle-dapp): Implement updated design for LS pools #2570

Merged
merged 65 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
abecde9
feat(tangle-dapp): Create table foundations
yurixander Sep 3, 2024
8a60c8a
Merge branch 'develop' into yuri/list-parachain-pools-in-table
yurixander Sep 3, 2024
68cb876
refactor(tangle-dapp): Remove `useTokenPrice` hook
yurixander Sep 3, 2024
09df2ab
feat(tangle-dapp): Add missing columns
yurixander Sep 5, 2024
3e782b7
Merge branch 'develop' into yuri/list-parachain-pools-in-table
yurixander Sep 5, 2024
2d46984
refactor(tangle-dapp): Show corresponding table
yurixander Sep 6, 2024
9834217
feat(tangle-dapp): Create `useLsPools` hook
yurixander Sep 7, 2024
25dd1d6
Merge branch 'develop' into yuri/list-parachain-pools-in-table
yurixander Sep 7, 2024
4e5f8d1
feat(tangle-dapp): Create LS pools data fetching hooks
yurixander Sep 8, 2024
45618d1
Merge branch 'yuri/list-parachain-pools-in-table' of https://github.c…
yurixander Sep 8, 2024
51ec94e
fix(tangle-dapp): Fix errors
yurixander Sep 10, 2024
2e8cda2
feat(tangle-dapp): Derive LS pool owner's stake & TVL
yurixander Sep 12, 2024
c8d04c8
Merge branch 'develop' into yuri/list-parachain-pools-in-table
yurixander Sep 12, 2024
373db83
feat(tangle-dapp): Implement `useLsPoolCompoundApys` hook
yurixander Sep 12, 2024
c94356b
Merge branch 'yuri/list-parachain-pools-in-table' of https://github.c…
yurixander Sep 12, 2024
f40d0db
feat(tangle-dapp): Use `useLsPoolCompoundApys` in `useLsPools`
yurixander Sep 13, 2024
d4482bc
ci(tangle-dapp): Bump Tangle Substrate types package
yurixander Sep 13, 2024
eeaf084
ci(tangle-dapp): Fix lint
yurixander Sep 13, 2024
edef04a
feat(tangle-dapp): Handle unsupported networks
yurixander Sep 13, 2024
e3e3f7c
fix(tangle-dapp): Check for LS pool support
yurixander Sep 13, 2024
490d90f
feat(tangle-dapp): Add empty & loading states
yurixander Sep 14, 2024
46be2de
refactor(tangle-dapp): Resolve some TODOs
yurixander Sep 16, 2024
d564cb5
fix(tangle-dapp): Handle edge case where root role is `None`
yurixander Sep 16, 2024
31834b1
docs(tangle-dapp): Resolve more TODOs
yurixander Sep 16, 2024
7a495fd
feat(tangle-dapp): Add initial Tangle mainnet network
yurixander Sep 17, 2024
5fef25f
feat(tangle-dapp): Add Tangle testnet to LS networks
yurixander Sep 23, 2024
fc6ace6
Merge branch 'develop' into yuri/tangle-mainnet-ls-network
yurixander Sep 23, 2024
fb89adc
feat(tangle-dapp): Add Tangle local to LS networks
yurixander Sep 23, 2024
0dfecdb
feat(tangle-dapp): Create `useLsPoolJoinTx` hook
yurixander Sep 23, 2024
25d41e9
refactor(tangle-dapp): Remove `FeedbackBanner` component
yurixander Sep 23, 2024
154989b
Merge branch 'develop' into yuri/tangle-mainnet-ls-network
yurixander Sep 25, 2024
ebb915e
fix(tangle-dapp): Fix Tangle networks id issue
yurixander Sep 25, 2024
7779488
feat(tangle-dapp): Create `useLsPoolUnbondTx` hook
yurixander Sep 26, 2024
941fb7c
ci(tangle-dapp): Fix lint errors
yurixander Sep 27, 2024
4669f02
fix(tangle-dapp): Use `switchNetwork` instead of `setNetwork`
yurixander Sep 27, 2024
8f56acf
fix(tangle-dapp): Fix network mismatch on load bug
yurixander Sep 27, 2024
fff064d
refactor(tangle-dapp): Get rid of `TotalDetailItem` component
yurixander Sep 27, 2024
75d118c
refactor(tangle-dapp): Start page merge process
yurixander Sep 28, 2024
186ef8e
feat(tangle-dapp): Create `LsMyPoolsTable` container
yurixander Sep 28, 2024
e21795d
feat(tangle-dapp): Filter my pools
yurixander Sep 28, 2024
8a5074b
refactor(tangle-dapp): Move LS cards to overview page
yurixander Sep 28, 2024
1db8032
Merge branch 'develop' into yuri/ls-pools-impl-new-design
yurixander Oct 2, 2024
560d425
refactor(tangle-dapp): Merge both pages
yurixander Oct 2, 2024
aba16cf
refactor(tangle-dapp): Create `useLsPoolsMetadata` hook
yurixander Oct 2, 2024
fcbba20
fix(tangle-dapp): Missing property `showPoolIndicator`
yurixander Oct 2, 2024
8a5dd3f
Merge branch 'develop' into yuri/ls-pools-impl-new-design
yurixander Oct 3, 2024
c62fd67
refactor(tangle-dapp): Get rid of Liquifier remenants
yurixander Oct 3, 2024
3f064fa
refactor(tangle-dapp): Get rid of Liquifier remenants
yurixander Oct 3, 2024
081cdbb
refactor(tangle-dapp): Get rid of Liquifier remenants
yurixander Oct 3, 2024
af6a02e
refactor(tangle-dapp): Add missing table columns
yurixander Oct 3, 2024
5268d61
refactor(tangle-dapp): Progress on the table states
yurixander Oct 3, 2024
131818b
refactor(tangle-dapp): Better names for properties in `useLsStore`
yurixander Oct 3, 2024
8d50504
feat(tangle-dapp): Add `Unstake` action to `LsMyPoolsTable`
yurixander Oct 3, 2024
a1b6318
Merge branch 'develop' into yuri/ls-pools-impl-new-design
yurixander Oct 3, 2024
5b712b5
feat(tangle-dapp): Focus on LS input on mount
yurixander Oct 3, 2024
1871b41
feat(tangle-dapp): Implement `OnboardingModal` component, update doc.…
yurixander Oct 4, 2024
5e284f3
fix(tangle-dapp): Fix bug pool table rows not showing
yurixander Oct 4, 2024
b09eff2
refactor(tangle-dapp): Standardize percentage formatting
yurixander Oct 4, 2024
0d54a91
fix(tangle-dapp): Fix percentage display bug
yurixander Oct 4, 2024
3b8b758
ui(tangle-dapp): UI fixes and improvements
yurixander Oct 4, 2024
e0f6671
feat(tangle-dapp): Create `setLsStakingIntent` hook
yurixander Oct 4, 2024
38e342f
ci(tangle-dapp): Fix linting errors
yurixander Oct 4, 2024
714274c
fix(tangle-dapp): Bug fixes on the `LsNetworkSwitcher` component
yurixander Oct 4, 2024
13c6d2c
fix(tangle-dapp): Forgot to format TVL with commas
yurixander Oct 4, 2024
a0b7bfb
fix(tangle-dapp): Network name & token fits in better
yurixander Oct 4, 2024
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
18 changes: 18 additions & 0 deletions apps/tangle-dapp/app/liquid-staking/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Metadata } from 'next';
import { FC, PropsWithChildren } from 'react';

import createPageMetadata from '../../utils/createPageMetadata';

export const dynamic = 'force-static';

export const metadata: Metadata = createPageMetadata({
title: 'Liquid Staking',
description:
"Liquid stake onto liquid staking pools to obtain derivative tokens and remain liquid while earning staking rewards and participating in Tangle's restaking infrastructure.",
});

const Layout: FC = ({ children }: PropsWithChildren) => {
return children;
};

export default Layout;
36 changes: 0 additions & 36 deletions apps/tangle-dapp/app/liquid-staking/overview/page.tsx

This file was deleted.

201 changes: 164 additions & 37 deletions apps/tangle-dapp/app/liquid-staking/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
'use client';

import {
CoinIcon,
EditLine,
Search,
SparklingIcon,
WaterDropletIcon,
} from '@webb-tools/icons';
import {
TabContent,
TabsList as WebbTabsList,
TabsRoot,
TabTrigger,
TANGLE_DOCS_LIQUID_STAKING_URL,
Typography,
} from '@webb-tools/webb-ui-components';
import { FC, useEffect } from 'react';

import { LsValidatorTable } from '../../components/LiquidStaking/LsValidatorTable';
import LsStakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsStakeCard';
import LsUnstakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsUnstakeCard';
import UnstakeRequestsTable from '../../components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable';
import OnboardingItem from '../../components/OnboardingModal/OnboardingItem';
import OnboardingModal from '../../components/OnboardingModal/OnboardingModal';
import StatItem from '../../components/StatItem';
import { OnboardingPageKey } from '../../constants';
import { LsSearchParamKey } from '../../constants/liquidStaking/types';
import LsPoolsTable from '../../containers/LsPoolsTable';
import LsMyProtocolsTable from '../../containers/LsMyProtocolsTable';
import { LsProtocolsTable } from '../../containers/LsPoolsTable';
import useNetworkStore from '../../context/useNetworkStore';
import { useLsStore } from '../../data/liquidStaking/useLsStore';
import useNetworkSwitcher from '../../hooks/useNetworkSwitcher';
import useSearchParamState from '../../hooks/useSearchParamState';
import getLsTangleNetwork from '../../utils/liquidStaking/getLsTangleNetwork';
import isLsParachainChainId from '../../utils/liquidStaking/isLsParachainChainId';
import TabListItem from '../restake/TabListItem';
import TabsList from '../restake/TabsList';

Expand All @@ -22,7 +39,12 @@ enum SearchParamAction {
UNSTAKE = 'unstake',
}

const LiquidStakingTokenPage: FC = () => {
enum Tab {
ALL_POOLS = 'All Pools',
MY_POOLS = 'My Pools',
}

const LiquidStakingPage: FC = () => {
const [isStaking, setIsStaking] = useSearchParamState({
defaultValue: true,
key: LsSearchParamKey.ACTION,
Expand All @@ -31,12 +53,16 @@ const LiquidStakingTokenPage: FC = () => {
value ? SearchParamAction.STAKE : SearchParamAction.UNSTAKE,
});

const { selectedProtocolId, selectedNetworkId } = useLsStore();
const {
lsNetworkId,
setIsStaking: setIsStakingInStore,
isStaking: isStakingInStore,
} = useLsStore();

const { network } = useNetworkStore();
const { switchNetwork } = useNetworkSwitcher();

const lsTangleNetwork = getLsTangleNetwork(selectedNetworkId);
const isParachainChain = isLsParachainChainId(selectedProtocolId);
const lsTangleNetwork = getLsTangleNetwork(lsNetworkId);

// Sync the network with the selected liquid staking network on load.
// It might differ initially if the user navigates to the page and
Expand All @@ -45,40 +71,141 @@ const LiquidStakingTokenPage: FC = () => {
if (lsTangleNetwork !== null && lsTangleNetwork.id !== network.id) {
switchNetwork(lsTangleNetwork, false);
}
}, [lsTangleNetwork, network.id, selectedNetworkId, switchNetwork]);
}, [lsTangleNetwork, network.id, lsNetworkId, switchNetwork]);

// Sync the Zustand store state of whether liquid staking or unstaking with
// the URL param state.
useEffect(() => {
setIsStakingInStore(isStaking);
}, [isStaking, setIsStakingInStore]);

// Sync the URL param state of whether liquid staking or unstaking with
// the Zustand store state.
useEffect(() => {
setIsStaking(isStakingInStore);
}, [isStakingInStore, setIsStaking]);

return (
<div className="flex flex-wrap gap-12">
<div className="flex flex-col gap-4 w-full min-w-[450px] max-w-[600px]">
<TabsList className="w-full">
<TabListItem isActive={isStaking} onClick={() => setIsStaking(true)}>
Stake
</TabListItem>

<TabListItem
isActive={!isStaking}
onClick={() => setIsStaking(false)}
>
Unstake
</TabListItem>
</TabsList>

{isStaking ? <LsStakeCard /> : <LsUnstakeCard />}
</div>
<div>
<OnboardingModal
title="Get Started with Liquid Staking"
pageKey={OnboardingPageKey.LIQUID_STAKING}
learnMoreHref={TANGLE_DOCS_LIQUID_STAKING_URL}
>
<OnboardingItem
Icon={Search}
title="Explore Liquid Staking Pools"
description="Browse existing liquid staking pools on Tangle or the Restaking Parachain. Sort them by APY, TVL, or create your own pool."
/>

<OnboardingItem
Icon={WaterDropletIcon}
title="Stake Your Assets"
description="Select a pool, enter the amount you'd like to stake, and click 'Stake' to start staking in the pool."
/>

<OnboardingItem
Icon={EditLine}
title="View and Manage Your Pools"
description="After staking, use the 'My Pools' tab to view, increase stake, unstake, or manage your pools."
/>

<OnboardingItem
Icon={CoinIcon}
title="Obtain derivative tokens"
description="When you join a pool, you'll automatically receive its derivative asset, which can be traded and used within Tangle's restaking infrastructure."
/>

<OnboardingItem
Icon={SparklingIcon}
title="Earn Rewards While Staying Liquid"
description="Use or trade your derivative tokens while automatically earning staking rewards. That's the magic of liquid staking!"
/>
</OnboardingModal>

<div className="flex items-stretch flex-col gap-10">
<div className="p-6 space-y-0 rounded-2xl flex flex-row items-center justify-between w-full overflow-x-auto bg-liquid_staking_banner dark:bg-liquid_staking_banner_dark">
<div className="flex flex-col gap-2">
<Typography variant="h5" fw="bold">
Tangle Liquid Staking
</Typography>

<Typography
variant="body1"
fw="normal"
className="text-mono-120 dark:text-mono-100"
>
Get Liquid Staking Tokens (LSTs) to earn & unleash restaking on
Tangle Mainnet via delegation.
</Typography>
</div>

<div className="flex gap-6 h-full">
<StatItem
title="$123.01"
subtitle="My Total Staking"
largeSubtitle
/>
</div>
</div>

<div className="flex flex-col self-center gap-4 w-full min-w-[450px] max-w-[532px]">
<TabsList className="w-full">
<TabListItem
isActive={isStaking}
onClick={() => setIsStaking(true)}
>
Stake
</TabListItem>

<TabListItem
isActive={!isStaking}
onClick={() => setIsStaking(false)}
>
Unstake
</TabListItem>
</TabsList>

{isStaking ? <LsStakeCard /> : <LsUnstakeCard />}
</div>

<TabsRoot defaultValue={Tab.ALL_POOLS} className="space-y-4">
<div className="flex justify-between items-center gap-4">
{/* Tabs List on the left */}
<WebbTabsList className="space-x-4">
{Object.values(Tab).map((tab, idx) => {
return (
<TabTrigger
key={idx}
value={tab}
isDisableStyle
className="text-mono-100 radix-state-active:text-mono-200 dark:radix-state-active:!text-mono-0"
>
<Typography
variant="h5"
fw="bold"
className="!text-inherit"
>
{tab}
</Typography>
</TabTrigger>
);
})}
</WebbTabsList>
</div>

{/* Tabs Content */}
<TabContent value={Tab.ALL_POOLS}>
<LsProtocolsTable />
</TabContent>

<div className="flex flex-col flex-grow w-min gap-4 min-w-[370px]">
{isStaking ? (
isParachainChain ? (
<LsPoolsTable />
) : (
<LsValidatorTable />
)
) : (
<UnstakeRequestsTable />
)}
<TabContent value={Tab.MY_POOLS}>
<LsMyProtocolsTable />
</TabContent>
</TabsRoot>
</div>
</div>
);
};

export default LiquidStakingTokenPage;
export default LiquidStakingPage;
Loading
Loading