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): Add liquid staking unstaking card #2415

Merged
merged 70 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
7c9e33e
feat(tangle-dapp): Add unstake card
yurixander Jun 30, 2024
bea6113
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 3, 2024
f434c36
feat(tangle-dapp): Add other components to be used
yurixander Jul 3, 2024
9919684
refactor(tangle-dapp): Remove outdated token info card
yurixander Jul 3, 2024
536a101
feat(tangle-dapp): Add Substrate address type utils
yurixander Jul 4, 2024
359170f
feat(tangle-dapp): Add `HexagonAvatar` component
yurixander Jul 6, 2024
07ec2d7
style(tangle-dapp): Adjust overview page to match design
yurixander Jul 7, 2024
55ca8d8
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 7, 2024
3d394e0
Merge branch 'yuri/ls-unstaking-card' of https://github.com/webb-tool…
yurixander Jul 7, 2024
d7e8624
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 8, 2024
531d6f4
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 8, 2024
b0e1276
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 8, 2024
e8f9398
feat(tangle-dapp): Finish design impl. of `StakedAssetsTable`
yurixander Jul 9, 2024
0d66e89
refactor(tangle-dapp): Prefer chain definitions instead of maps
yurixander Jul 9, 2024
b229496
refactor(tangle-dapp): `AvatarGroup` already exists
yurixander Jul 9, 2024
74c136f
feat(tangle-dapp): Create `SelectTokenModal` component
yurixander Jul 10, 2024
29e6970
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 10, 2024
fd2ae76
feat(tangle-dapp): Trigger opening the `Select Token` modal
yurixander Jul 10, 2024
01c8d5b
Merge branch 'yuri/ls-unstaking-card' of github.com:webb-tools/webb-d…
yurixander Jul 10, 2024
f66e009
feat(tangle-dapp): Create `AddressLink` component
yurixander Jul 11, 2024
7fe9dcd
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 11, 2024
1c27a91
feat(tangle-dapp): Add `CancelUnstakeModal`
yurixander Jul 11, 2024
c7670db
refactor(tangle-dapp): There's already a component for external links
yurixander Jul 11, 2024
e507a1c
style(tangle-dapp): Add actions to `UnstakeRequestsTable`
yurixander Jul 11, 2024
fe069aa
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 11, 2024
deea354
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 12, 2024
9042755
style(tangle-dapp): Tidy up UI for unstake card
yurixander Jul 12, 2024
2497421
feat(tangle-dapp): Check available balance
yurixander Jul 12, 2024
6b7a050
refactor(tangle-dapp): Only show tooltip when appropriate
yurixander Jul 12, 2024
734cc8d
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 13, 2024
78fd809
feat(tangle-dapp): Add `Request Submitted` modal
yurixander Jul 13, 2024
77069e5
refactor(tangle-dapp): Hide unused components
yurixander Jul 14, 2024
11ca714
feat(tangle-dapp): Implement some basic LST hooks
yurixander Jul 15, 2024
132bb58
feat(tangle-dapp): Calculate exchange rate
yurixander Jul 15, 2024
50160dc
feat(tangle-dapp): Add `ExchangeRateDetailItem` component
yurixander Jul 15, 2024
5490587
style(tangle-dapp): Improve text copy for unstake button
yurixander Jul 15, 2024
0db665a
refactor(tangle-dapp): Improve implementation of `formatBn`
yurixander Jul 16, 2024
12d02d2
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 16, 2024
14d95b3
fix(tangle-dapp): Fix bug in BN formatting
yurixander Jul 16, 2024
3315e0b
ci(tangle-dapp): Fix warnings causing CI to fail
yurixander Jul 16, 2024
3be14ad
chore: update props field for TableAndChartTabs
vutuanlinh2k2 Jul 16, 2024
2442cef
feat: add search functionalities for Validator tables
vutuanlinh2k2 Jul 16, 2024
f236bac
chore: fix Max on AmountInput
vutuanlinh2k2 Jul 16, 2024
50442c8
chore: fix UI for Nomination modal
vutuanlinh2k2 Jul 16, 2024
dd81063
chore: update Creative Commons Attribution-ShareAlike link
vutuanlinh2k2 Jul 16, 2024
82c5a5f
Merge remote-tracking branch 'origin/linh/add-search-nomination-table…
yurixander Jul 17, 2024
eaf8ed1
refactor(tangle-dapp): Move things around to keep things organized
yurixander Jul 17, 2024
afd9edf
fix(tangle-dapp): Fix nesting errors
yurixander Jul 17, 2024
38a7bbc
fix(tangle-dapp): Consider decimals
yurixander Jul 17, 2024
487c8af
feat(tangle-dapp): Check for ongoing time unit requirement
yurixander Jul 17, 2024
d020ac7
style(tangle-dapp): Improve text copy for alerts
yurixander Jul 17, 2024
b736ee2
feat(tangle-dapp): Progress on unlock durations
yurixander Jul 17, 2024
d6e9c14
fix(tangle-dapp): Fix buttons not disabled when no connected account
yurixander Jul 17, 2024
b872bcc
fix(tangle-dapp): Missing check
yurixander Jul 17, 2024
9740adc
feat(tangle-dapp): Progress on `useOngoingTimeUnits`
yurixander Jul 17, 2024
8c12237
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 17, 2024
3e9a0e7
fix(tangle-dapp): Exchange rate special case, and fees bug
yurixander Jul 18, 2024
8db0661
fix(tangle-dapp): Fix exchange rate edge case
yurixander Jul 18, 2024
50ab796
ci(tangle-dapp): Temporarily disable `getValueOfTangleCurrency`
yurixander Jul 18, 2024
73430e9
style(tangle-dapp): Responsiveness
yurixander Jul 18, 2024
54c1ebe
refactor(tangle-dapp): Minor changes to `UnstakeRequestSubmittedModal`
yurixander Jul 19, 2024
4ff58e0
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 20, 2024
4f4dd39
style(tangle-dapp): Fix some styling inconsistencies
yurixander Jul 20, 2024
feb8efb
fix(tangle-dapp): Fix most requested changes
yurixander Jul 20, 2024
a682d03
Merge branch 'develop' into yuri/ls-unstaking-card
yurixander Jul 20, 2024
eeec595
style(tangle-dapp): Fix some styling requested changes
yurixander Jul 21, 2024
e9906e5
style(tangle-dapp): Fix styling inconsistency of network dropdown button
yurixander Jul 21, 2024
566cdbf
style(tangle-dapp): Revert to using previous styling
yurixander Jul 22, 2024
6a03498
style(tangle-dapp): Fix dropdown chevron icon styling
yurixander Jul 22, 2024
54e0dbb
style(tangle-dapp): Use `DropdownChevronIcon` in `TokenChip`
yurixander Jul 22, 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
5 changes: 0 additions & 5 deletions .yarnrc

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function useAmountToTransfer() {
? parseUnits(
formatBn(amount, decimals, {
includeCommas: false,
fractionLength: undefined,
fractionMaxLength: undefined,
}),
decimals,
).toString()
Expand Down
36 changes: 7 additions & 29 deletions apps/tangle-dapp/app/liquid-staking/[tokenSymbol]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client';

import { notFound } from 'next/navigation';
import { FC } from 'react';

import LiquidStakingCard from '../../../components/LiquidStaking/LiquidStakingCard';
import TokenInfoCard from '../../../components/LiquidStaking/TokenInfoCard';
import { LIQUID_STAKING_TOKEN_PREFIX } from '../../../constants/liquidStaking';
import LiquidStakeAndUnstakeCards from '../../../components/LiquidStaking/LiquidStakeAndUnstakeCards';
import UnstakeRequestsTable from '../../../components/LiquidStaking/UnstakeRequestsTable';
import isLiquidStakingToken from '../../../utils/liquidStaking/isLiquidStakingToken';

type Props = {
Expand All @@ -17,33 +18,10 @@ const LiquidStakingTokenPage: FC<Props> = ({ params: { tokenSymbol } }) => {
}

return (
<div className="grid grid-cols-2 gap-12">
<TokenInfoCard
stakingInfo={{
title: 'Staking',
tooltip: `Total staked ${tokenSymbol}`,
value: '-',
}}
availableInfo={{
title: 'Available',
tooltip: `Available ${LIQUID_STAKING_TOKEN_PREFIX}${tokenSymbol}`,
value: '98.00',
valueTooltip: `Available ${LIQUID_STAKING_TOKEN_PREFIX}${tokenSymbol}`,
}}
unstakingInfo={{
title: 'Unstaking',
tooltip: `Total unstaking ${tokenSymbol} in progress`,
value: '-',
}}
apyInfo={{
title: 'APY',
tooltip: 'APY (Annual Percentage Yield) %',
value: '-',
}}
tokenSymbol={tokenSymbol}
/>
<div className="flex flex-wrap gap-12 items-start">
<LiquidStakeAndUnstakeCards />

<LiquidStakingCard />
<UnstakeRequestsTable />
</div>
);
};
Expand Down
59 changes: 25 additions & 34 deletions apps/tangle-dapp/app/liquid-staking/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@ import { FC } from 'react';
import { GlassCard } from '../../components';
import LiquidStakingTokenItem from '../../components/LiquidStaking/LiquidStakingTokenItem';
import StatItem from '../../components/LiquidStaking/StatItem';
import { LS_CHAIN_TO_TOKEN, TVS_TOOLTIP } from '../../constants/liquidStaking';
import entriesOf from '../../utils/entriesOf';
import { LIQUID_STAKING_CHAINS } from '../../constants/liquidStaking';

const LiquidStakingPage: FC = () => {
return (
<div className="flex flex-col">
<Typography variant="h4" fw="bold">
Overview
</Typography>

<div className="flex flex-col gap-10">
<GlassCard className="flex flex-row items-center justify-between w-full overflow-x-auto">
<div className="flex flex-col gap-2">
<Typography variant="h5" fw="bold">
Expand All @@ -22,44 +17,40 @@ const LiquidStakingPage: FC = () => {

<Typography variant="body1" fw="normal">
Get Liquid Staking Tokens (LSTs) to earn & unleash restaking on
Tangle via delegation.
Tangle Mainnet via delegation.
</Typography>
</div>

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

<StatItem title="$123,412.01" subtitle="TVS" tooltip={TVS_TOOLTIP} />

<StatItem title="3.12 %" subtitle="Est. Daily Rewards" />
</div>
</GlassCard>

<GlassCard className="space-y-4">
<Typography variant="h5" fw="bold">
<div className="flex flex-col gap-4">
<Typography variant="h4" fw="bold">
Liquid Staking Tokens
</Typography>

<div className="overflow-x-auto">
<div className="flex flex-col gap-4 min-w-[750px]">
{entriesOf(LS_CHAIN_TO_TOKEN).map(([chain, token]) => {
return (
<LiquidStakingTokenItem
key={chain}
chain={chain}
title={`Tangle ${chain}`}
tokenSymbol={token}
// TODO: Using dummy values.
annualPercentageYield={0.23456}
// TODO: Can't pass non-plain objects as props to Client components from Server components (this page). For now, passing in as a string then creating BN instance inside the component.
totalStaked="100000000"
totalValueStaked={220_000_123}
/>
);
})}
<GlassCard className="space-y-4">
<div className="overflow-x-auto">
<div className="flex flex-col gap-4 min-w-[750px]">
{LIQUID_STAKING_CHAINS.map((chain) => {
return (
<LiquidStakingTokenItem
key={chain.id}
chainId={chain.id}
title={`Tangle ${chain.name}`}
tokenSymbol={chain.token}
// TODO: Can't pass non-plain objects as props to Client components from Server components (this page). For now, passing in as a string then creating BN instance inside the component.
totalStaked="100000000"
totalValueStaked={220_000_123}
/>
);
})}
</div>
</div>
</div>
</GlassCard>
</GlassCard>
</div>
</div>
);
};
Expand Down
37 changes: 37 additions & 0 deletions apps/tangle-dapp/components/LiquidStaking/AddressLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { HexString } from '@polkadot/util/types';
import { ExternalLinkLine } from '@webb-tools/icons';
import { shortenString, Typography } from '@webb-tools/webb-ui-components';
import { FC, useCallback } from 'react';

import { AnySubstrateAddress } from '../../types/utils';

export type AddressLinkProps = {
address: AnySubstrateAddress | HexString;
};

const AddressLink: FC<AddressLinkProps> = ({ address }) => {
// TODO: Determine href.
const href = '#';

// Stop propagation to prevent a parent modal (if any) from closing.
const handleClick = useCallback((event: any) => {
event.stopPropagation();
}, []);

return (
<a
href={href}
target="_blank"
onClick={handleClick}
className="flex gap-1 items-center justify-start hover:underline"
>
<Typography variant="body1" fw="normal" className="dark:text-mono-0">
{shortenString(address, 6)}
</Typography>

<ExternalLinkLine className="dark:fill-mono-0" />
</a>
);
};

export default AddressLink;
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { CheckboxCircleFill, TimeFillIcon, UndoIcon } from '@webb-tools/icons';
import { Button, Typography } from '@webb-tools/webb-ui-components';
import { FC, ReactElement } from 'react';

import GlassCard from '../GlassCard';

const AvailableWithdrawCard: FC = () => {
return (
<GlassCard className="flex rounded-xl gap-2">
<div className="flex justify-between">
<div className="flex flex-col gap-1">
<Typography variant="body1" fw="semibold">
Available
</Typography>

<Typography variant="h5" fw="bold">
0.0 DOT
</Typography>
</div>

<div className="flex gap-1 items-center justify-center">
<Button variant="utility" size="sm">
Withdraw
</Button>

{/* TODO: Need a tooltip for this, since it's only an icon. */}
<Button variant="utility" size="sm">
<UndoIcon className="dark:fill-blue-40" />
</Button>
</div>
</div>

<hr className="border-mono-0 dark:border-mono-160" />

<div className="flex justify-between items-end">
<div className="flex flex-col gap-1">
<Typography variant="body1" fw="semibold">
My requests
</Typography>

<div className="flex gap-2">
<RequestItem
icon={<CheckboxCircleFill className="fill-green-50" />}
text="0"
/>

<RequestItem
icon={<TimeFillIcon className="fill-blue-50" />}
text="1"
/>
</div>
</div>

<div className="flex items-center justify-center gap-1">
<TimeFillIcon className="dark:fill-mono-0" />

<Typography variant="body1" fw="bold" className="dark:text-mono-0">
1.00 tgDOT
</Typography>
</div>
</div>
</GlassCard>
);
};

type RequestItemProps = {
icon: ReactElement;
text: string;
};

/** @internal */
const RequestItem: FC<RequestItemProps> = ({ icon, text }) => {
return (
<div className="flex items-center justify-center gap-1">
{icon}

<Typography className="dark:text-mono-0" variant="body1" fw="bold">
{text}
</Typography>
</div>
);
};

export default AvailableWithdrawCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { CloseCircleLineIcon } from '@webb-tools/icons';
import {
Button,
Modal,
ModalContent,
ModalFooter,
ModalHeader,
Typography,
} from '@webb-tools/webb-ui-components';
import { FC, useCallback } from 'react';

import ExternalLink from './ExternalLink';
import ModalIcon from './ModalIcon';
import { UnstakeRequestItem } from './UnstakeRequestsTable';

export type CancelUnstakeModalProps = {
isOpen: boolean;
unstakeRequest: UnstakeRequestItem;
onClose: () => void;
};

const CancelUnstakeModal: FC<CancelUnstakeModalProps> = ({
isOpen,
// TODO: Make use of the unstake request data, which is relevant for the link's href.
unstakeRequest: _unstakeRequest,
onClose,
}) => {
const handleConfirm = useCallback(() => {
// TODO: Set button as loading, disable ability to close modal, and proceed to execute the unstake cancellation via its corresponding extrinsic call.
}, []);

return (
<Modal open>
<ModalContent
isCenter
isOpen={isOpen}
className="w-full max-w-[calc(100vw-40px)] md:max-w-[500px] rounded-2xl bg-mono-0 dark:bg-mono-180"
>
<ModalHeader titleVariant="h4" onClose={onClose}>
Cancel Unstake
</ModalHeader>

<div className="flex flex-col items-center justify-center gap-2 p-9">
<ModalIcon Icon={CloseCircleLineIcon} />

<Typography
className="dark:text-mono-0 text-center"
variant="body1"
fw="normal"
>
Are you sure you want to cancel your unstaking request? By
cancelling, your tokens will remain staked and continue earning
rewards.
</Typography>

{/* TODO: External link's href. */}
<ExternalLink href="#">Learn More</ExternalLink>
</div>

<ModalFooter className="flex gap-1 px-8 py-6 space-y-0">
<Button onClick={onClose} isFullWidth variant="secondary">
Cancel
</Button>

<Button onClick={handleConfirm} isFullWidth variant="primary">
Confirm
</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};

export default CancelUnstakeModal;
Loading
Loading