vega-frontend-monorepo/libs/assets/src/lib/asset-details-table.tsx

260 lines
7.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
import type { Schema } from '@vegaprotocol/types';
import type { KeyValueTableRowProps } from '@vegaprotocol/ui-toolkit';
import {
KeyValueTable,
KeyValueTableRow,
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import type { Asset } from './asset-data-provider';
type Rows = {
key: AssetDetail;
label: string;
tooltip: string;
value: (asset: Asset) => string | null | undefined;
valueTooltip?: (asset: Asset) => string | null | undefined;
}[];
export enum AssetDetail {
ID,
TYPE,
NAME,
SYMBOL,
DECIMALS,
QUANTUM,
STATUS,
// erc20 details:
CONTRACT_ADDRESS,
WITHDRAWAL_THRESHOLD,
LIFETIME_LIMIT,
// builtin details:
MAX_FAUCET_AMOUNT_MINT,
// balances:
INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
GLOBAL_REWARD_POOL_ACCOUNT_BALANCE,
MAKER_PAID_FEES_ACCOUNT_BALANCE, // account type: ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES
MAKER_RECEIVED_FEES_ACCOUNT_BALANCE, // account type: ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES
LP_FEE_REWARD_ACCOUNT_BALANCE,
MARKET_PROPOSER_REWARD_ACCOUNT_BALANCE,
}
type Mapping = { [key in string]: { value: string; tooltip: string } };
const num = (asset: Asset, n: string | undefined | null) => {
if (typeof n === 'undefined' || n == null) return '';
return addDecimalsFormatNumber(n, asset.decimals);
};
export const rows: Rows = [
{
key: AssetDetail.ID,
label: t('ID'),
tooltip: '',
value: (asset) => asset.id,
},
{
key: AssetDetail.TYPE,
label: t('Type'),
tooltip: '',
value: (asset) => AssetTypeMapping[asset.source.__typename].value,
valueTooltip: (asset) => AssetTypeMapping[asset.source.__typename].tooltip,
},
{
key: AssetDetail.NAME,
label: t('Name'),
tooltip: '',
value: (asset) => asset.name,
},
{
key: AssetDetail.SYMBOL,
label: t('Symbol'),
tooltip: '',
value: (asset) => asset.symbol,
},
{
key: AssetDetail.DECIMALS,
label: t('Decimals'),
tooltip: t('Number of decimal / precision handled by this asset'),
value: (asset) => asset.decimals.toString(),
},
{
key: AssetDetail.QUANTUM,
label: t('Quantum'),
tooltip: t('The minimum economically meaningful amount of the asset'),
value: (asset) => asset.quantum,
},
{
key: AssetDetail.STATUS,
label: t('Status'),
tooltip: t('The status of the asset in the Vega network'),
value: (asset) => AssetStatusMapping[asset.status].value,
valueTooltip: (asset) => AssetStatusMapping[asset.status].tooltip,
},
{
key: AssetDetail.CONTRACT_ADDRESS,
label: t('Contract address'),
tooltip: t(
'The address of the contract for the token, on the ethereum network'
),
value: (asset) => (asset.source as Schema.ERC20).contractAddress,
},
{
key: AssetDetail.WITHDRAWAL_THRESHOLD,
label: t('Withdrawal threshold'),
tooltip: t(
'The maximum you can withdraw instantly. Theres no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them'
),
value: (asset) =>
num(asset, (asset.source as Schema.ERC20).withdrawThreshold),
},
{
key: AssetDetail.LIFETIME_LIMIT,
label: t('Lifetime limit'),
tooltip: t(
'The lifetime deposit limit per address. Note: this is a temporary measure that can be changed or removed through governance'
),
value: (asset) => num(asset, (asset.source as Schema.ERC20).lifetimeLimit),
},
{
key: AssetDetail.MAX_FAUCET_AMOUNT_MINT,
label: t('Max faucet amount'),
tooltip: t(
'Maximum amount that can be requested by a party through the built-in asset faucet at a time'
),
value: (asset) =>
num(asset, (asset.source as Schema.BuiltinAsset).maxFaucetAmountMint),
},
{
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
label: t('Infrastructure fee account balance'),
tooltip: t('The infrastructure fee account in this asset'),
value: (asset) => num(asset, asset.infrastructureFeeAccount.balance),
},
{
key: AssetDetail.GLOBAL_REWARD_POOL_ACCOUNT_BALANCE,
label: t('Global reward pool account balance'),
tooltip: t('The global rewards acquired in this asset'),
value: (asset) => num(asset, asset.globalRewardPoolAccount?.balance),
},
{
key: AssetDetail.MAKER_PAID_FEES_ACCOUNT_BALANCE,
label: t('Maker paid fees account balance'),
tooltip: t(
'The rewards acquired based on the fees paid to makers in this asset'
),
value: (asset) => num(asset, asset.takerFeeRewardAccount?.balance),
},
{
key: AssetDetail.MAKER_RECEIVED_FEES_ACCOUNT_BALANCE,
label: t('Maker received fees account balance'),
tooltip: t(
'The rewards acquired based on fees received for being a maker on trades'
),
value: (asset) => num(asset, asset.makerFeeRewardAccount?.balance),
},
{
key: AssetDetail.LP_FEE_REWARD_ACCOUNT_BALANCE,
label: t('Liquidity provision fee reward account balance'),
tooltip: t(
'The rewards acquired based on the liquidity provision fees in this asset'
),
value: (asset) => num(asset, asset.lpFeeRewardAccount?.balance),
},
{
key: AssetDetail.MARKET_PROPOSER_REWARD_ACCOUNT_BALANCE,
label: t('Market proposer reward account balance'),
tooltip: t(
'The rewards acquired based on the market proposer reward in this asset'
),
value: (asset) => num(asset, asset.marketProposerRewardAccount?.balance),
},
];
const AssetStatusMapping: Mapping = {
STATUS_ENABLED: {
value: t('Enabled'),
tooltip: t('Asset can be used on the Vega network'),
},
STATUS_PENDING_LISTING: {
value: t('Pending listing'),
tooltip: t('Asset needs to be added to the Ethereum bridge'),
},
STATUS_PROPOSED: {
value: t('Proposed'),
tooltip: t('Asset has been proposed to the network'),
},
STATUS_REJECTED: {
value: t('Rejected'),
tooltip: t('Asset has been rejected'),
},
};
const AssetTypeMapping: Mapping = {
BuiltinAsset: {
value: 'Builtin asset',
tooltip: t('A Vega builtin asset'),
},
ERC20: {
value: 'ERC20',
tooltip: t('An asset originated from an Ethereum ERC20 Token'),
},
};
export const testId = (detail: AssetDetail, field: 'label' | 'value') =>
`${detail}_${field}`;
export type AssetDetailsTableProps = {
asset: Asset;
} & Omit<KeyValueTableRowProps, 'children'>;
export const AssetDetailsTable = ({
asset,
...props
}: AssetDetailsTableProps) => {
const longStringModifiers = (key: AssetDetail, value: string) =>
(value && key === AssetDetail.CONTRACT_ADDRESS) || key === AssetDetail.ID
? { className: 'truncate', title: value }
: {};
const details = rows.map((r) => ({
...r,
value: r.value(asset),
valueTooltip: r.valueTooltip?.(asset),
}));
return (
<KeyValueTable>
{details
.filter(({ value }) => value && value.length > 0)
.map(({ key, label, value, tooltip, valueTooltip }) => (
<KeyValueTableRow key={key} {...props}>
<div
data-testid={testId(key, 'label')}
className="first-letter:uppercase"
>
{tooltip.length > 0 ? (
<Tooltip description={tooltip}>
<span>{label}</span>
</Tooltip>
) : (
<span>{label}</span>
)}
</div>
<div
data-testid={testId(key, 'value')}
{...longStringModifiers(key, value as string)}
>
{valueTooltip && valueTooltip?.length > 0 ? (
<Tooltip description={valueTooltip}>
<span>{value}</span>
</Tooltip>
) : (
value
)}
</div>
</KeyValueTableRow>
))}
</KeyValueTable>
);
};