diff --git a/apps/tangle-dapp/components/tableCells/PercentageCell.tsx b/apps/tangle-dapp/components/tableCells/PercentageCell.tsx new file mode 100644 index 000000000..b5c78c7c4 --- /dev/null +++ b/apps/tangle-dapp/components/tableCells/PercentageCell.tsx @@ -0,0 +1,26 @@ +import { Typography } from '@webb-tools/webb-ui-components'; +import { FC } from 'react'; + +import { EMPTY_VALUE_PLACEHOLDER } from '../../constants'; + +export type PercentageCellProps = { + percentage?: number; +}; + +const PercentageCell: FC = ({ percentage }) => { + if (percentage === undefined) { + return EMPTY_VALUE_PLACEHOLDER; + } + + return ( + + {`${percentage.toFixed(2)}%`} + + ); +}; + +export default PercentageCell; diff --git a/apps/tangle-dapp/constants/liquidStaking/types.ts b/apps/tangle-dapp/constants/liquidStaking/types.ts index 3949d8e8a..1bf44f5cf 100644 --- a/apps/tangle-dapp/constants/liquidStaking/types.ts +++ b/apps/tangle-dapp/constants/liquidStaking/types.ts @@ -24,10 +24,6 @@ export enum LsProtocolId { MOONBEAM, ASTAR, MANTA, - CHAINLINK, - THE_GRAPH, - LIVEPEER, - POLYGON, TANGLE_MAINNET, TANGLE_TESTNET, TANGLE_LOCAL, diff --git a/apps/tangle-dapp/containers/LsMyPoolsTable.tsx b/apps/tangle-dapp/containers/LsMyPoolsTable.tsx index 60986aaae..ac74eb944 100644 --- a/apps/tangle-dapp/containers/LsMyPoolsTable.tsx +++ b/apps/tangle-dapp/containers/LsMyPoolsTable.tsx @@ -15,19 +15,20 @@ import { LsPool } from '../constants/liquidStaking/types'; import { ActionsDropdown, Avatar, + AvatarGroup, Button, - getRoundedAmountString, Typography, } from '@webb-tools/webb-ui-components'; import TokenAmountCell from '../components/tableCells/TokenAmountCell'; import pluralize from '../utils/pluralize'; -import { EMPTY_VALUE_PLACEHOLDER } from '../constants'; import { ArrowRight } from '@webb-tools/icons'; import useLsPools from '../data/liquidStaking/useLsPools'; import useSubstrateAddress from '../hooks/useSubstrateAddress'; import { BN } from '@polkadot/util'; import assert from 'assert'; import { GlassCard } from '../components'; +import PercentageCell from '../components/tableCells/PercentageCell'; +import { EMPTY_VALUE_PLACEHOLDER } from '../constants'; type MyLsPoolRow = LsPool & { myStake: BN; @@ -51,18 +52,6 @@ const POOL_COLUMNS = [ ), }), - COLUMN_HELPER.accessor('token', { - header: () => 'Token', - cell: (props) => ( - - {props.getValue()} - - ), - }), COLUMN_HELPER.accessor('ownerAddress', { header: () => 'Owner', cell: (props) => ( @@ -73,6 +62,24 @@ const POOL_COLUMNS = [ /> ), }), + COLUMN_HELPER.accessor('validators', { + header: () => 'Validators', + cell: (props) => + props.row.original.validators.length === 0 ? ( + EMPTY_VALUE_PLACEHOLDER + ) : ( + + {props.row.original.validators.map((substrateAddress) => ( + + ))} + + ), + }), COLUMN_HELPER.accessor('totalStaked', { header: () => 'Total Staked (TVL)', // TODO: Decimals. @@ -82,25 +89,13 @@ const POOL_COLUMNS = [ header: () => 'My Stake', cell: (props) => , }), + COLUMN_HELPER.accessor('commissionPercentage', { + header: () => 'Commission', + cell: (props) => , + }), COLUMN_HELPER.accessor('apyPercentage', { header: () => 'APY', - cell: (props) => { - const apy = props.getValue(); - - if (apy === undefined) { - return EMPTY_VALUE_PLACEHOLDER; - } - - return ( - - {getRoundedAmountString(props.getValue()) + '%'} - - ); - }, + cell: (props) => , }), COLUMN_HELPER.display({ id: 'actions', diff --git a/apps/tangle-dapp/containers/LsPoolsTable2/LsPoolsTable2.tsx b/apps/tangle-dapp/containers/LsPoolsTable2/LsPoolsTable2.tsx index a2612e160..8146d6c14 100644 --- a/apps/tangle-dapp/containers/LsPoolsTable2/LsPoolsTable2.tsx +++ b/apps/tangle-dapp/containers/LsPoolsTable2/LsPoolsTable2.tsx @@ -15,8 +15,8 @@ import { twMerge } from 'tailwind-merge'; import { LsPool } from '../../constants/liquidStaking/types'; import { Avatar, + AvatarGroup, Button, - getRoundedAmountString, Typography, } from '@webb-tools/webb-ui-components'; import TokenAmountCell from '../../components/tableCells/TokenAmountCell'; @@ -24,6 +24,7 @@ import pluralize from '../../utils/pluralize'; import { EMPTY_VALUE_PLACEHOLDER } from '../../constants'; import { ArrowRight } from '@webb-tools/icons'; import { useLsStore } from '../../data/liquidStaking/useLsStore'; +import PercentageCell from '../../components/tableCells/PercentageCell'; export interface LsPoolsTable2Props { pools: LsPool[]; @@ -63,18 +64,6 @@ const LsPoolsTable2: FC = ({ pools, isShown }) => { ), }), - COLUMN_HELPER.accessor('token', { - header: () => 'Token', - cell: (props) => ( - - {props.getValue()} - - ), - }), COLUMN_HELPER.accessor('ownerAddress', { header: () => 'Owner', cell: (props) => ( @@ -85,30 +74,36 @@ const LsPoolsTable2: FC = ({ pools, isShown }) => { /> ), }), + COLUMN_HELPER.accessor('validators', { + header: () => 'Validators', + cell: (props) => + props.row.original.validators.length === 0 ? ( + EMPTY_VALUE_PLACEHOLDER + ) : ( + + {props.row.original.validators.map((substrateAddress) => ( + + ))} + + ), + }), COLUMN_HELPER.accessor('totalStaked', { header: () => 'Total Staked (TVL)', // TODO: Decimals. cell: (props) => , }), + COLUMN_HELPER.accessor('commissionPercentage', { + header: () => 'Commission', + cell: (props) => , + }), COLUMN_HELPER.accessor('apyPercentage', { header: () => 'APY', - cell: (props) => { - const apy = props.getValue(); - - if (apy === undefined) { - return EMPTY_VALUE_PLACEHOLDER; - } - - return ( - - {getRoundedAmountString(props.getValue()) + '%'} - - ); - }, + cell: (props) => , }), COLUMN_HELPER.display({ id: 'actions', diff --git a/apps/tangle-dapp/data/liquidStaking/useLsProtocolEntities.ts b/apps/tangle-dapp/data/liquidStaking/useLsProtocolEntities.ts index fa02539dc..4659eb109 100644 --- a/apps/tangle-dapp/data/liquidStaking/useLsProtocolEntities.ts +++ b/apps/tangle-dapp/data/liquidStaking/useLsProtocolEntities.ts @@ -70,10 +70,6 @@ const getDataType = (chain: LsProtocolId): LiquidStakingItem | null => { return LiquidStakingItem.VAULT_OR_STAKE_POOL; case LsProtocolId.ASTAR: return LiquidStakingItem.DAPP; - case LsProtocolId.CHAINLINK: - case LsProtocolId.LIVEPEER: - case LsProtocolId.POLYGON: - case LsProtocolId.THE_GRAPH: case LsProtocolId.TANGLE_MAINNET: case LsProtocolId.TANGLE_TESTNET: case LsProtocolId.TANGLE_LOCAL: diff --git a/apps/tangle-dapp/data/liquidStaking/useLsValidators.ts b/apps/tangle-dapp/data/liquidStaking/useLsValidators.ts index 6462b7b9e..fe5e1b02e 100644 --- a/apps/tangle-dapp/data/liquidStaking/useLsValidators.ts +++ b/apps/tangle-dapp/data/liquidStaking/useLsValidators.ts @@ -84,8 +84,6 @@ const useLsValidators = (selectedChain: LsProtocolId) => { ); break; - // TODO: Add cases for ERC20 tokens/networks (Chainlink, etc.). - default: fetchedItems = []; break; diff --git a/apps/tangle-dapp/hooks/useApiRx.ts b/apps/tangle-dapp/hooks/useApiRx.ts index dd2ecd3ff..8b442c6ab 100644 --- a/apps/tangle-dapp/hooks/useApiRx.ts +++ b/apps/tangle-dapp/hooks/useApiRx.ts @@ -37,8 +37,6 @@ function useApiRx( const [result, setResult] = useState(null); const [isLoading, setLoading] = useState(true); const { rpcEndpoint } = useNetworkStore(); - - // TODO: Consider integrating the error right into the result: `result: T | Error | null`. This will force the consumer to handle the error case, which is what they should be doing anyway. const [error, setError] = useState(null); const { result: apiRx } = usePromise( @@ -62,7 +60,6 @@ function useApiRx( return; } - // TODO: Also allow for `| Error` return value, to allow for error handling in the consumer. let observable: Observable | null; // In certain cases, the factory may fail with an error. For example,