Skip to content

Commit

Permalink
feat(tangle-dapp): Create useLsPools hook
Browse files Browse the repository at this point in the history
  • Loading branch information
yurixander committed Sep 7, 2024
1 parent 2d46984 commit 9834217
Show file tree
Hide file tree
Showing 28 changed files with 303 additions and 189 deletions.
6 changes: 3 additions & 3 deletions apps/tangle-dapp/app/liquid-staking/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import LsStakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsStakeC
import LsUnstakeCard from '../../components/LiquidStaking/stakeAndUnstake/LsUnstakeCard';
import UnstakeRequestsTable from '../../components/LiquidStaking/unstakeRequestsTable/UnstakeRequestsTable';
import { LsSearchParamKey } from '../../constants/liquidStaking/types';
import ParachainPoolsTable from '../../containers/ParachainPoolsTable';
import LsPoolsTable from '../../containers/LsPoolsTable';
import { useLsStore } from '../../data/liquidStaking/useLsStore';
import useSearchParamState from '../../hooks/useSearchParamState';
import isLsParachainChainId from '../../utils/liquidStaking/isLsParachainChainId';
Expand All @@ -29,7 +29,7 @@ const LiquidStakingTokenPage: FC = () => {
});

const { selectedProtocolId } = useLsStore();

const isParachainChain = isLsParachainChainId(selectedProtocolId);

return (
Expand All @@ -54,7 +54,7 @@ const LiquidStakingTokenPage: FC = () => {
<div className="flex flex-col flex-grow w-min gap-4 min-w-[370px]">
{isStaking ? (
isParachainChain ? (
<ParachainPoolsTable />
<LsPoolsTable />
) : (
<LsValidatorTable />
)
Expand Down
4 changes: 2 additions & 2 deletions apps/tangle-dapp/components/LiquidStaking/AddressLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ 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';
import { SubstrateAddress } from '../../types/utils';

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

const AddressLink: FC<AddressLinkProps> = ({ address }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { twMerge } from 'tailwind-merge';
import useVaults from '../../app/liquid-staking/useVaults';
import StatItem from '../../components/StatItem';
import TableCellWrapper from '../../components/tables/TableCellWrapper';
import { PagePath } from '../../types';
import { Asset, Vault } from '../../types/liquidStaking';
import LsTokenIcon from '../LsTokenIcon';

Expand Down Expand Up @@ -80,8 +81,7 @@ const vaultColumns = [
cell: ({ row }) => (
<TableCellWrapper removeBorder>
<div className="flex items-center justify-end flex-1 gap-2">
{/* TODO: add proper href */}
<Link href="#" passHref>
<Link href={PagePath.LIQUID_STAKING} passHref>
<Button
variant="utility"
className="uppercase body4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { FC, useMemo } from 'react';
import { LsProtocolId } from '../../../constants/liquidStaking/types';
import formatBn from '../../../utils/formatBn';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
import scaleAmountByPermill from '../../../utils/scaleAmountByPermill';
import scaleAmountByPercentage from '../../../utils/scaleAmountByPercentage';
import DetailItem from './DetailItem';
import useLsFeePermill from './useLsFeePermill';
import useLsFeePercentage from './useLsFeePercentage';

export type FeeDetailItemProps = {
isMinting: boolean;
Expand All @@ -19,20 +19,20 @@ const FeeDetailItem: FC<FeeDetailItemProps> = ({
inputAmount,
protocolId,
}) => {
const feePermill = useLsFeePermill(protocolId, isMinting);
const feePercentage = useLsFeePercentage(protocolId, isMinting);

const protocol = getLsProtocolDef(protocolId);

// TODO: Add liquifier fees, and select either parachain or liquifier fees based on the given protocol's id.

const feeAmount = useMemo(() => {
// Propagate error or loading state.
if (typeof feePermill !== 'number') {
return feePermill;
if (typeof feePercentage !== 'number') {
return feePercentage;
}

return scaleAmountByPermill(inputAmount ?? BN_ZERO, feePermill);
}, [feePermill, inputAmount]);
return scaleAmountByPercentage(inputAmount ?? BN_ZERO, feePercentage);
}, [feePercentage, inputAmount]);

const formattedFeeAmount = useMemo(() => {
// Propagate error or loading state.
Expand All @@ -48,9 +48,9 @@ const FeeDetailItem: FC<FeeDetailItemProps> = ({
}, [feeAmount, protocol.decimals, protocol.token]);

const feeTitle =
typeof feePermill !== 'number'
typeof feePercentage !== 'number'
? 'Fee'
: `Fee (${(feePermill * 100).toFixed(2)}%)`;
: `Fee (${(feePercentage * 100).toFixed(2)}%)`;

return <DetailItem title={feeTitle} value={formattedFeeAmount} />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ import { Alert } from '@webb-tools/webb-ui-components';
import { FC } from 'react';

import { LsProtocolId } from '../../../constants/liquidStaking/types';
import useLsFeePermill from './useLsFeePermill';
import useLsFeePercentage from './useLsFeePercentage';

// 10%.
const THRESHOLD_PERMILL = 0.1;
const THRESHOLD_PERCENTAGE = 0.1;

export type LsFeeWarningProps = {
isMinting: boolean;
selectedProtocolId: LsProtocolId;
};

const LsFeeWarning: FC<LsFeeWarningProps> = ({ selectedProtocolId }) => {
const fee = useLsFeePermill(selectedProtocolId, true);
const fee = useLsFeePercentage(selectedProtocolId, true);

return (
typeof fee === 'number' &&
fee >= THRESHOLD_PERMILL && (
fee >= THRESHOLD_PERCENTAGE && (
<Alert
type="warning"
title="High fees"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import {
} from '@webb-tools/webb-ui-components';
import { FC, useEffect, useMemo } from 'react';

import { AnySubstrateAddress } from '../../../types/utils';
import { SubstrateAddress } from '../../../types/utils';
import formatBn from '../../../utils/formatBn';
import LsTokenIcon from '../../LsTokenIcon';
import AddressLink from '../AddressLink';

export type SelectTokenModalProps = {
isOpen: boolean;
options: Omit<TokenListItemProps, 'onClick'>[];
onTokenSelect: (address: AnySubstrateAddress) => void;
onTokenSelect: (address: SubstrateAddress) => void;
onClose: () => void;
};

Expand All @@ -28,7 +28,7 @@ const SelectTokenModal: FC<SelectTokenModalProps> = ({
}) => {
// Sanity check: Ensure all addresses are unique.
useEffect(() => {
const seenAddresses = new Set<AnySubstrateAddress>();
const seenAddresses = new Set<SubstrateAddress>();

for (const option of options) {
if (seenAddresses.has(option.address)) {
Expand Down Expand Up @@ -81,7 +81,7 @@ const SelectTokenModal: FC<SelectTokenModalProps> = ({
};

export type TokenListItemProps = {
address: AnySubstrateAddress;
address: SubstrateAddress;
decimals: number;
amount: BN;
onClick: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import useLsExchangeRate, {
} from '../../../data/liquidStaking/useLsExchangeRate';
import formatBn from '../../../utils/formatBn';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';
import scaleAmountByPermill from '../../../utils/scaleAmountByPermill';
import scaleAmountByPercentage from '../../../utils/scaleAmountByPercentage';
import DetailItem from './DetailItem';
import useLsFeePermill from './useLsFeePermill';
import useLsFeePercentage from './useLsFeePercentage';

export type TotalDetailItemProps = {
isMinting: boolean;
Expand All @@ -24,7 +24,7 @@ const TotalDetailItem: FC<TotalDetailItemProps> = ({
inputAmount,
protocolId,
}) => {
const feePermill = useLsFeePermill(protocolId, isMinting);
const feePercentage = useLsFeePercentage(protocolId, isMinting);

const { exchangeRate } = useLsExchangeRate(
isMinting
Expand All @@ -36,22 +36,26 @@ const TotalDetailItem: FC<TotalDetailItemProps> = ({
const protocol = getLsProtocolDef(protocolId);

const totalAmount = useMemo(() => {
if (inputAmount === null || exchangeRate === null || feePermill === null) {
if (
inputAmount === null ||
exchangeRate === null ||
feePercentage === null
) {
return null;
}
// Propagate errors.
else if (feePermill instanceof Error) {
return feePermill;
else if (feePercentage instanceof Error) {
return feePercentage;
} else if (exchangeRate instanceof Error) {
return exchangeRate;
}

const feeAmount = scaleAmountByPermill(inputAmount, feePermill);
const feeAmount = scaleAmountByPercentage(inputAmount, feePercentage);

return isMinting
? inputAmount.muln(exchangeRate).sub(feeAmount)
: inputAmount.divn(exchangeRate).sub(feeAmount);
}, [exchangeRate, feePermill, inputAmount, isMinting]);
}, [exchangeRate, feePercentage, inputAmount, isMinting]);

const formattedTotalAmount = useMemo(() => {
// Nothing to show if the input amount is not set.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import useContractRead from '../../../data/liquifier/useContractRead';
import { ContractReadOptions } from '../../../data/liquifier/useContractReadOnce';
import getLsProtocolDef from '../../../utils/liquidStaking/getLsProtocolDef';

const useLsFeePermill = (
const useLsFeePercentage = (
protocolId: LsProtocolId,
isMinting: boolean,
): number | Error | null => {
Expand All @@ -23,8 +23,8 @@ const useLsFeePermill = (
parachainFees === null
? null
: isMinting
? parachainFees.mintFee
: parachainFees.redeemFee;
? parachainFees.mintFeePercentage
: parachainFees.redeemFeePercentage;

const getLiquifierFeeOptions = useCallback((): ContractReadOptions<
typeof LIQUIFIER_REGISTRY_ABI,
Expand Down Expand Up @@ -56,7 +56,7 @@ const useLsFeePermill = (
}, [protocol.networkId, setIsLiquifierFeePaused]);

// The fee should be returned as a per-mill value from the liquifier contract.
const liquifierFeePermillOrError =
const liquifierFeePercentageOrError =
rawLiquifierFeeOrError instanceof Error
? rawLiquifierFeeOrError
: rawLiquifierFeeOrError === null
Expand All @@ -65,7 +65,7 @@ const useLsFeePermill = (

return protocol.networkId === LsNetworkId.TANGLE_RESTAKING_PARACHAIN
? parachainFee
: liquifierFeePermillOrError;
: liquifierFeePercentageOrError;
};

export default useLsFeePermill;
export default useLsFeePercentage;
16 changes: 8 additions & 8 deletions apps/tangle-dapp/constants/liquidStaking/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {
LsNetworkEntityAdapter,
ProtocolEntity,
} from '../../data/liquidStaking/adapter';
import { CrossChainTimeUnit } from '../../utils/CrossChainTime';
import { SubstrateAddress } from '../../types/utils';
import { TANGLE_MAINNET_SS58_PREFIX } from '../../../../libs/dapp-config/src/constants/tangle';
import { CrossChainTimeUnit } from '../../utils/CrossChainTime';

export enum LsProtocolId {
POLKADOT,
Expand Down Expand Up @@ -140,13 +139,14 @@ export type LsNetwork = {
protocols: LsProtocolDef[];
};

export type LsParachainPool = {
id: string;
owner: SubstrateAddress<typeof TANGLE_MAINNET_SS58_PREFIX>;
export type LsPool = {
id: number;
metadata?: string;
owner: SubstrateAddress;
ownerStaked: BN;
chainId: LsParachainChainId;
validators: SubstrateAddress<typeof TANGLE_MAINNET_SS58_PREFIX>[];
validators: SubstrateAddress[];
totalStaked: BN;
apyPermill: number;
commissionPermill: number;
apyPercentage: number;
commissionPercentage?: number;
};
9 changes: 6 additions & 3 deletions apps/tangle-dapp/constants/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ export const DEFAULT_NETWORK = TANGLE_MAINNET_NETWORK;
export const NETWORK_FEATURE_MAP: Record<NetworkId, NetworkFeature[]> = {
[NetworkId.TANGLE_TESTNET]: [NetworkFeature.Faucet],
[NetworkId.TANGLE_MAINNET]: [NetworkFeature.EraStakersOverview],
[NetworkId.TANGLE_RESTAKING_PARACHAIN_LOCAL_DEV]: [],
[NetworkId.TANGLE_RESTAKING_PARACHAIN_TESTNET]: [],
[NetworkId.TANGLE_LOCAL_DEV]: [
NetworkFeature.EraStakersOverview,
NetworkFeature.LsPools,
],
// Assume that local and custom endpoints are using an updated runtime
// version which includes support for the era stakers overview query.
[NetworkId.TANGLE_LOCAL_DEV]: [NetworkFeature.EraStakersOverview],
[NetworkId.CUSTOM]: [NetworkFeature.EraStakersOverview],
[NetworkId.TANGLE_RESTAKING_PARACHAIN_LOCAL_DEV]: [],
[NetworkId.TANGLE_RESTAKING_PARACHAIN_TESTNET]: [],
};
Loading

0 comments on commit 9834217

Please sign in to comment.