Skip to content

Commit

Permalink
refactor(tangle-dapp): Integrate New Restake API (#2492)
Browse files Browse the repository at this point in the history
  • Loading branch information
AtelyPham authored Aug 7, 2024
1 parent 4497649 commit e91a8ba
Show file tree
Hide file tree
Showing 31 changed files with 588 additions and 387 deletions.
3 changes: 3 additions & 0 deletions .lycheeignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.12
https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.13
# Something happened with conventional commits link, temporary disabled to fix the CI
https://www.conventionalcommits.org/en/v1.0.0/

# Files
/**/CHANGELOG.md
5 changes: 5 additions & 0 deletions apps/tangle-dapp/app/restake/deposit/DepositForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ const DepositForm = ({ ...props }: DepositFormProps) => {
balance.balance,
asset.metadata.decimals,
),
...(asset.metadata.poolId
? {
subContent: `Pool ID: ${asset.metadata.poolId}`,
}
: {}),
},
}
: {}),
Expand Down
11 changes: 2 additions & 9 deletions apps/tangle-dapp/app/restake/deposit/TxDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use client';

import { DEFAULT_DECIMALS } from '@webb-tools/dapp-config/constants';
import FeeDetails from '@webb-tools/webb-ui-components/components/FeeDetails';
import { useMemo } from 'react';
import { UseFormWatch } from 'react-hook-form';
import { formatUnits } from 'viem';

import { useRestakeContext } from '../../../context/RestakeContext';
import useRestakeConsts from '../../../data/restake/useRestakeConsts';
Expand All @@ -29,16 +27,11 @@ export default function TxDetails({ watch }: Props) {
}

const asset = assetMap[assetId];
if (asset === undefined) {
if (asset === undefined || asset.poolId === null) {
return null;
}

const apyRaw = rewardConfig.configs[assetId]?.apy;
if (apyRaw === undefined) {
return null;
}

return formatUnits(apyRaw, assetMap[assetId]?.decimals ?? DEFAULT_DECIMALS);
return rewardConfig.configs[asset.poolId]?.apy ?? null;
}, [assetId, assetMap, rewardConfig.configs]);

return (
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ export default function Page() {
symbol: asset.symbol,
assetBalanceProps: {
balance: +formatUnits(amount, asset.decimals),
...(asset.poolId
? {
subContent: `Pool ID: ${asset.poolId}`,
}
: {}),
},
} satisfies TokenListCardProps['selectTokens'][number];
});
Expand Down
25 changes: 19 additions & 6 deletions apps/tangle-dapp/app/restake/unstake/UnstakeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const UnstakeModal = ({
'You can try to deposit or delegate an asset to an operator.',
}}
renderItem={(item) => {
const { uid, amountBonded, assetId, operatorAccountId } = item;
const { amountBonded, assetId, operatorAccountId } = item;
const asset = assetMap[assetId];

const decimals = asset?.decimals || DEFAULT_DECIMALS;
Expand All @@ -96,9 +96,9 @@ const UnstakeModal = ({
<ListItem
className={twMerge(
'cursor-pointer max-w-none dark:bg-transparent',
'flex items-center justify-between px-0',
'flex items-center justify-between px-4',
)}
key={uid}
key={`${operatorAccountId}-${assetId}`}
onClick={() =>
onItemSelected({
...item,
Expand All @@ -118,9 +118,22 @@ const UnstakeModal = ({
}
/>

<Typography variant="h5" fw="bold">
{fmtAmount} {assetSymbol}
</Typography>
<div>
<Typography variant="h5" fw="bold">
{fmtAmount} {assetSymbol}
</Typography>

{asset.poolId && (
<Typography
ta="right"
variant="body3"
fw="semibold"
className="!text-mono-100 mt-1"
>
Pool ID: {asset.poolId}
</Typography>
)}
</div>
</ListItem>
);
}}
Expand Down
104 changes: 52 additions & 52 deletions apps/tangle-dapp/app/restake/unstake/UnstakeRequestTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,41 @@ import { fuzzyFilter } from '@webb-tools/webb-ui-components/components/Filter/ut
import { Table } from '@webb-tools/webb-ui-components/components/Table';
import { Typography } from '@webb-tools/webb-ui-components/typography/Typography';
import cx from 'classnames';
import uniqueId from 'lodash/uniqueId';
import { type ComponentProps, useMemo } from 'react';
import { twMerge } from 'tailwind-merge';
import { formatUnits } from 'viem';

import { useRestakeContext } from '../../../context/RestakeContext';
import useRestakeConsts from '../../../data/restake/useRestakeConsts';
import useRestakeCurrentRound from '../../../data/restake/useRestakeCurrentRound';
import type { DelegatorBondLessRequest } from '../../../types/restake';
import type { DelegatorUnstakeRequest } from '../../../types/restake';
import type { IdentityType } from '../../../utils/polkadot';
import AvatarWithText from '../AvatarWithText';
import type { UnstakeRequestTableData } from './types';
import UnstakeRequestTableActions from './UnstakeRequestTableActions';
import { calculateTimeRemaining } from './utils';

const columnsHelper = createColumnHelper<UnstakeRequestTableData>();

const columns = [
columnsHelper.display({
columnsHelper.accessor('operatorAccountId', {
id: 'select',
enableSorting: false,
header: ({ table }) => (
<CheckBox
isChecked={table.getIsAllRowsSelected()}
// TODO: Add indeterminate state for CheckBox
// indeterminate={table.getIsSomeRowsSelected()}
onChange={table.getToggleAllRowsSelectedHandler()}
wrapperClassName={cx('min-h-0')}
/>
),
cell: ({ row }) => (
<CheckBox
isChecked={row.getIsSelected()}
isDisabled={!row.getCanSelect()}
// TODO: Add indeterminate state for CheckBox
// indeterminate={row.getIsSomeSelected()}
onChange={row.getToggleSelectedHandler()}
wrapperClassName={cx('min-h-0')}
/>
header: () => <TableCell>Select request to cancel</TableCell>,
cell: (props) => (
<div className="flex items-center justify-start gap-2">
<CheckBox
isChecked={props.row.getIsSelected()}
isDisabled={!props.row.getCanSelect()}
onChange={props.row.getToggleSelectedHandler()}
wrapperClassName="pt-0.5 flex items-center justify-center"
/>

<AvatarWithText
accountAddress={props.getValue()}
identityName={props.row.original.operatorIdentityName}
/>
</div>
),
}),
columnsHelper.accessor('amount', {
Expand Down Expand Up @@ -91,55 +89,48 @@ const columns = [
];

type Props = {
delegatorBondLessRequests: DelegatorBondLessRequest[];
unstakeRequests: DelegatorUnstakeRequest[];
operatorIdentities: Record<string, IdentityType | null>;
};

const UnstakeRequestTable = ({ delegatorBondLessRequests }: Props) => {
const UnstakeRequestTable = ({
unstakeRequests,
operatorIdentities,
}: Props) => {
const { assetMap } = useRestakeContext();
const { delegationBondLessDelay } = useRestakeConsts();
const { currentRound } = useRestakeCurrentRound();

// Transforming the array to object with uuid as key
// for easier querying
const unstakeRequestsWithId = useMemo(
() =>
delegatorBondLessRequests.reduce(
(acc, current) => {
const uid = uniqueId('delegator-bond-less-request-');
acc[uid] = { ...current, uid };
return acc;
},
{} as Record<string, DelegatorBondLessRequest & { uid: string }>,
),
[delegatorBondLessRequests],
);

const dataWithId = useMemo(
() =>
Object.values(unstakeRequestsWithId).reduce(
(acc, { assetId, bondLessAmount, requestedRound, uid }) => {
unstakeRequests.reduce(
(acc, { assetId, amount, requestedRound, operatorAccountId }) => {
const asset = assetMap[assetId];
if (!asset) return acc;

const formattedAmount = formatUnits(bondLessAmount, asset.decimals);
const formattedAmount = formatUnits(amount, asset.decimals);
const timeRemaining = calculateTimeRemaining(
currentRound,
requestedRound,
delegationBondLessDelay,
);

acc[uid] = {
acc[getId({ assetId, operatorAccountId })] = {
amount: Number(formattedAmount),
amountRaw: amount,
assetId: assetId,
assetSymbol: asset.symbol,
timeRemaining,
uid,
operatorAccountId,
operatorIdentityName: operatorIdentities?.[operatorAccountId]?.name,
} satisfies UnstakeRequestTableData;

return acc;
},
{} as Record<string, UnstakeRequestTableData>,
),
[assetMap, currentRound, delegationBondLessDelay, unstakeRequestsWithId],
// prettier-ignore
[assetMap, currentRound, delegationBondLessDelay, operatorIdentities, unstakeRequests],
);

const table = useReactTable(
Expand All @@ -152,8 +143,8 @@ const UnstakeRequestTable = ({ delegatorBondLessRequests }: Props) => {
pageSize: 5,
},
},
getRowId: (row) => getId(row),
enableRowSelection: true,
getRowId: (row) => row.uid,
filterFns: {
fuzzy: fuzzyFilter,
},
Expand All @@ -179,16 +170,15 @@ const UnstakeRequestTable = ({ delegatorBondLessRequests }: Props) => {
<Table
tableProps={table}
isPaginated
thClassName={cx(
'!border-t-transparent !bg-transparent px-3 py-2 first:w-[18px]',
)}
tdClassName={cx(
'!border-transparent !bg-transparent px-3 py-2 first:w-[18px]',
)}
thClassName={cx('!border-t-transparent !bg-transparent px-3 py-2')}
tdClassName={cx('!border-transparent !bg-transparent px-3 py-2')}
/>

<div className="flex items-center gap-3">
<UnstakeRequestTableActions selectedRequests={selectedRequests} />
<UnstakeRequestTableActions
allRequests={Object.values(dataWithId)}
selectedRequests={selectedRequests}
/>
</div>
</>
);
Expand Down Expand Up @@ -217,3 +207,13 @@ function TableCell({
</Typography>
);
}

function getId({
assetId,
operatorAccountId,
}: {
assetId: string;
operatorAccountId: string;
}) {
return `${operatorAccountId}-${assetId}`;
}
Loading

0 comments on commit e91a8ba

Please sign in to comment.