Chore/1653 full asset details (#1700)
* chore: full list of asset details for dialog * chore: show full asset details in market info and dialog (1653) * fixed lint errors
This commit is contained in:
parent
503c831018
commit
64c85b2b4a
@ -16,9 +16,36 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -30,9 +57,36 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '1',
|
||||
withdrawThreshold: '2',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -43,9 +97,20 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
name: 'Asto',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
maxFaucetAmountMint: '3',
|
||||
},
|
||||
quantum: '',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '0',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: null,
|
||||
takerFeeRewardAccount: null,
|
||||
makerFeeRewardAccount: null,
|
||||
lpFeeRewardAccount: null,
|
||||
marketProposerRewardAccount: null,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -17,6 +17,7 @@ import type {
|
||||
} from './__generated__/Delegations';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useContracts } from '../../contexts/contracts/contracts-context';
|
||||
import type { ERC20Asset } from '@vegaprotocol/assets';
|
||||
import { isAssetTypeERC20 } from '@vegaprotocol/assets';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
|
||||
@ -118,8 +119,9 @@ export const usePollForDelegations = () => {
|
||||
.filter((a) => a.type === AccountType.ACCOUNT_TYPE_GENERAL)
|
||||
.map((a) => {
|
||||
const isVega =
|
||||
isAssetTypeERC20(a.asset) &&
|
||||
a.asset.source.contractAddress === vegaToken.address;
|
||||
isAssetTypeERC20(a.asset as ERC20Asset) &&
|
||||
(a.asset as ERC20Asset).source.contractAddress ===
|
||||
vegaToken.address;
|
||||
|
||||
return {
|
||||
isVega,
|
||||
@ -132,8 +134,8 @@ export const usePollForDelegations = () => {
|
||||
),
|
||||
image: isVega ? vegaBlack : noIcon,
|
||||
border: isVega,
|
||||
address: isAssetTypeERC20(a.asset)
|
||||
? a.asset.source.contractAddress
|
||||
address: isAssetTypeERC20(a.asset as ERC20Asset)
|
||||
? (a.asset as ERC20Asset).source.contractAddress
|
||||
: undefined,
|
||||
};
|
||||
})
|
||||
|
@ -71,10 +71,20 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
|
||||
it('settlement asset displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Settlement asset').click();
|
||||
|
||||
validateMarketDataRow(0, 'Name', 'tBTC TEST');
|
||||
validateMarketDataRow(1, 'Symbol', 'tBTC');
|
||||
validateMarketDataRow(2, 'Asset ID', 'market-0');
|
||||
validateMarketDataRow(0, 'ID', 'asset-id');
|
||||
validateMarketDataRow(1, 'Type', 'ERC20');
|
||||
validateMarketDataRow(2, 'Name', 'Euro');
|
||||
validateMarketDataRow(3, 'Symbol', 'tEURO');
|
||||
validateMarketDataRow(4, 'Decimals', '5');
|
||||
validateMarketDataRow(5, 'Quantum', '1');
|
||||
validateMarketDataRow(6, 'Status', 'Enabled');
|
||||
validateMarketDataRow(
|
||||
7,
|
||||
'Contract address',
|
||||
'0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4'
|
||||
);
|
||||
validateMarketDataRow(8, 'Withdrawal threshold', '0.00050');
|
||||
validateMarketDataRow(9, 'Lifetime limit', '1,230.00000');
|
||||
});
|
||||
|
||||
it('metadata displayed', () => {
|
||||
@ -173,7 +183,9 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
afterEach('close toggle', () => {
|
||||
cy.get('[data-state="open"]').find('button').click();
|
||||
cy.get('[data-state="open"]').then((tab) => {
|
||||
if (tab) tab.find('button').trigger('click');
|
||||
});
|
||||
});
|
||||
|
||||
function validateMarketDataRow(
|
||||
|
@ -1,8 +1,59 @@
|
||||
import merge from 'lodash/merge';
|
||||
import type { AssetsQuery } from '@vegaprotocol/assets';
|
||||
import type { AssetQuery, AssetsQuery } from '@vegaprotocol/assets';
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateAsset = (override?: PartialDeep<AssetQuery>) => {
|
||||
const defaultAssets: AssetsQuery = {
|
||||
assetsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'asset-id',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
name: 'Euro',
|
||||
source: {
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
quantum: '1',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
return merge(defaultAssets, override);
|
||||
};
|
||||
|
||||
export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
const defaultAssets: AssetsQuery = {
|
||||
assetsConnection: {
|
||||
@ -14,11 +65,38 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
decimals: 5,
|
||||
name: 'Euro',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
quantum: '1',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -28,11 +106,38 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
decimals: 5,
|
||||
name: 'DAI',
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x26223f9C67871CFcEa329975f7BC0C9cB8FBDb9b',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
quantum: '1',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -42,10 +147,21 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
decimals: 5,
|
||||
name: 'Asto',
|
||||
source: {
|
||||
maxFaucetAmountMint: '5000000000',
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
quantum: '1',
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '0',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: null,
|
||||
takerFeeRewardAccount: null,
|
||||
makerFeeRewardAccount: null,
|
||||
lpFeeRewardAccount: null,
|
||||
marketProposerRewardAccount: null,
|
||||
__typename: 'Asset',
|
||||
},
|
||||
},
|
||||
// NOTE: These assets ids and contract addresses are real assets on Sepolia, this is needed
|
||||
@ -59,10 +175,36 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
decimals: 5,
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x1d525fB145Af5c51766a89706C09fE07E6058D1D',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
quantum: '1',
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
@ -75,10 +217,36 @@ export const generateAssets = (override?: PartialDeep<AssetsQuery>) => {
|
||||
decimals: 5,
|
||||
status: Types.AssetStatus.STATUS_ENABLED,
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: '0x444b9aDA947130Fc320a144cd22bC1641e5c9d81',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
quantum: '1',
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
|
@ -2,7 +2,7 @@ import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import type { MarketState } from '@vegaprotocol/types';
|
||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||
import { generateAccounts } from './mocks/generate-accounts';
|
||||
import { generateAssets } from './mocks/generate-assets';
|
||||
import { generateAsset, generateAssets } from './mocks/generate-assets';
|
||||
import { generateCandles } from './mocks/generate-candles';
|
||||
import { generateChart } from './mocks/generate-chart';
|
||||
import { generateDealTicketQuery } from './mocks/generate-deal-ticket-query';
|
||||
@ -47,6 +47,7 @@ export const mockTradingPage = (
|
||||
aliasQuery(req, 'Margins', generateMargins());
|
||||
aliasQuery(req, 'DealTicket', generateDealTicketQuery({ market: { state } }));
|
||||
aliasQuery(req, 'Assets', generateAssets());
|
||||
aliasQuery(req, 'Asset', generateAsset());
|
||||
|
||||
aliasQuery(
|
||||
req,
|
||||
|
@ -16,8 +16,9 @@ import {
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
import type { Market } from '@vegaprotocol/market-list';
|
||||
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||
import type { AssetsFieldsFragment } from '@vegaprotocol/assets';
|
||||
|
||||
import { assetsProvider } from '@vegaprotocol/assets';
|
||||
import type { Asset } from '@vegaprotocol/assets';
|
||||
|
||||
function isAccount(
|
||||
account:
|
||||
@ -41,7 +42,7 @@ export const getId = (
|
||||
|
||||
export type Account = Omit<AccountFieldsFragment, 'market' | 'asset'> & {
|
||||
market?: Market | null;
|
||||
asset: AssetsFieldsFragment;
|
||||
asset: Asset;
|
||||
};
|
||||
|
||||
const update = (
|
||||
@ -167,7 +168,7 @@ export const accountsDataProvider = makeDerivedDataProvider<Account[], never>(
|
||||
(market: Market) => market.id === account.market?.id
|
||||
);
|
||||
const asset = assets.find(
|
||||
(asset: AssetsFieldsFragment) => asset.id === account.asset?.id
|
||||
(asset: Asset) => asset.id === account.asset?.id
|
||||
);
|
||||
if (asset) {
|
||||
return {
|
||||
|
47
libs/assets/src/lib/Asset.graphql
Normal file
47
libs/assets/src/lib/Asset.graphql
Normal file
@ -0,0 +1,47 @@
|
||||
fragment AssetFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
quantum
|
||||
source {
|
||||
__typename
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
status
|
||||
infrastructureFeeAccount {
|
||||
balance
|
||||
}
|
||||
globalRewardPoolAccount {
|
||||
balance
|
||||
}
|
||||
takerFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
makerFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
lpFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
marketProposerRewardAccount {
|
||||
balance
|
||||
}
|
||||
}
|
||||
|
||||
query Asset($assetId: ID!) {
|
||||
assetsConnection(id: $assetId) {
|
||||
edges {
|
||||
node {
|
||||
...AssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +1,8 @@
|
||||
fragment AssetsFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
quantum
|
||||
status
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query Assets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
...AssetsFields
|
||||
...AssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
92
libs/assets/src/lib/__generated___/Asset.ts
Normal file
92
libs/assets/src/lib/__generated___/Asset.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type AssetFieldsFragment = { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string }, infrastructureFeeAccount: { __typename?: 'Account', balance: string }, globalRewardPoolAccount?: { __typename?: 'Account', balance: string } | null, takerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, makerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, lpFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, marketProposerRewardAccount?: { __typename?: 'Account', balance: string } | null };
|
||||
|
||||
export type AssetQueryVariables = Types.Exact<{
|
||||
assetId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type AssetQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string }, infrastructureFeeAccount: { __typename?: 'Account', balance: string }, globalRewardPoolAccount?: { __typename?: 'Account', balance: string } | null, takerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, makerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, lpFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, marketProposerRewardAccount?: { __typename?: 'Account', balance: string } | null } } | null> | null } | null };
|
||||
|
||||
export const AssetFieldsFragmentDoc = gql`
|
||||
fragment AssetFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
quantum
|
||||
source {
|
||||
__typename
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
}
|
||||
status
|
||||
infrastructureFeeAccount {
|
||||
balance
|
||||
}
|
||||
globalRewardPoolAccount {
|
||||
balance
|
||||
}
|
||||
takerFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
makerFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
lpFeeRewardAccount {
|
||||
balance
|
||||
}
|
||||
marketProposerRewardAccount {
|
||||
balance
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AssetDocument = gql`
|
||||
query Asset($assetId: ID!) {
|
||||
assetsConnection(id: $assetId) {
|
||||
edges {
|
||||
node {
|
||||
...AssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${AssetFieldsFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useAssetQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useAssetQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useAssetQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useAssetQuery({
|
||||
* variables: {
|
||||
* assetId: // value for 'assetId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useAssetQuery(baseOptions: Apollo.QueryHookOptions<AssetQuery, AssetQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<AssetQuery, AssetQueryVariables>(AssetDocument, options);
|
||||
}
|
||||
export function useAssetLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AssetQuery, AssetQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<AssetQuery, AssetQueryVariables>(AssetDocument, options);
|
||||
}
|
||||
export type AssetQueryHookResult = ReturnType<typeof useAssetQuery>;
|
||||
export type AssetLazyQueryHookResult = ReturnType<typeof useAssetLazyQuery>;
|
||||
export type AssetQueryResult = Apollo.QueryResult<AssetQuery, AssetQueryVariables>;
|
@ -1,41 +1,26 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import { AssetFieldsFragmentDoc } from './Asset';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type AssetsFieldsFragment = { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } };
|
||||
|
||||
export type AssetsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type AssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } } | null> | null } | null };
|
||||
export type AssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string }, infrastructureFeeAccount: { __typename?: 'Account', balance: string }, globalRewardPoolAccount?: { __typename?: 'Account', balance: string } | null, takerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, makerFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, lpFeeRewardAccount?: { __typename?: 'Account', balance: string } | null, marketProposerRewardAccount?: { __typename?: 'Account', balance: string } | null } } | null> | null } | null };
|
||||
|
||||
|
||||
export const AssetsFieldsFragmentDoc = gql`
|
||||
fragment AssetsFields on Asset {
|
||||
id
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
quantum
|
||||
status
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const AssetsDocument = gql`
|
||||
query Assets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
...AssetsFields
|
||||
...AssetFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${AssetsFieldsFragmentDoc}`;
|
||||
${AssetFieldsFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useAssetsQuery__
|
||||
|
39
libs/assets/src/lib/asset-data-provider.ts
Normal file
39
libs/assets/src/lib/asset-data-provider.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { makeDataProvider, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import type { AssetQuery, AssetFieldsFragment } from './__generated___/Asset';
|
||||
import { AssetDocument } from './__generated___/Asset';
|
||||
|
||||
export type Asset = AssetFieldsFragment;
|
||||
|
||||
const getData = (responseData: AssetQuery) => {
|
||||
const foundAssets = responseData.assetsConnection?.edges
|
||||
?.filter((e) => Boolean(e?.node))
|
||||
.map((e) => e?.node as Asset);
|
||||
if (foundAssets && foundAssets?.length > 0) return foundAssets[0];
|
||||
return null;
|
||||
};
|
||||
|
||||
export const assetProvider = makeDataProvider<
|
||||
AssetQuery,
|
||||
Asset | null,
|
||||
never,
|
||||
never
|
||||
>({
|
||||
query: AssetDocument,
|
||||
getData,
|
||||
});
|
||||
|
||||
export const useAssetDataProvider = (assetId: string) => {
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
assetId,
|
||||
}),
|
||||
[assetId]
|
||||
);
|
||||
return useDataProvider({
|
||||
dataProvider: assetProvider,
|
||||
variables,
|
||||
skip: !assetId,
|
||||
});
|
||||
};
|
@ -1,267 +1,33 @@
|
||||
import { MockedProvider } from '@apollo/react-testing';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { AssetStatus } from '@vegaprotocol/types';
|
||||
import { AssetDetailsDialog } from './asset-details-dialog';
|
||||
import { AssetDetail, testId } from './asset-details-table';
|
||||
import { AssetsDocument } from './__generated___/Assets';
|
||||
import { generateBuiltinAsset, generateERC20Asset } from './test-helpers';
|
||||
|
||||
const mockedData = {
|
||||
data: {
|
||||
assetsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'XYZalpha',
|
||||
name: 'XYZ (α alpha)',
|
||||
symbol: 'XYZalpha',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
node: generateERC20Asset(1, AssetStatus.STATUS_ENABLED),
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'XYZbeta',
|
||||
name: 'XYZ (β beta)',
|
||||
symbol: 'XYZbeta',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
node: generateBuiltinAsset(1, AssetStatus.STATUS_ENABLED),
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'XYZdelta',
|
||||
name: 'XYZ (δ delta)',
|
||||
symbol: 'XYZdelta',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
node: generateBuiltinAsset(2, AssetStatus.STATUS_PENDING_LISTING),
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'XYZepsilon',
|
||||
name: 'XYZ (ε epsilon)',
|
||||
symbol: 'XYZepsilon',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
node: generateBuiltinAsset(3, AssetStatus.STATUS_PROPOSED),
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'XYZgamma',
|
||||
name: 'XYZ (γ gamma)',
|
||||
symbol: 'XYZgamma',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '2282ffc06a557173d297739305cc69f6444cdbbb1089df7d9aef32bbfd735ba1',
|
||||
name: 'Tim Token (Vega)',
|
||||
symbol: 'TIM',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x920B2375BCAC8cCDfDEFD74426c55C48e0304e4F',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '449dbfb66e7a444c485b4fdc77ddc6bbf81abbf7c8e247ac299c25e9557b99cf',
|
||||
name: 'Taker Reward Token (Vega)',
|
||||
symbol: 'TAK',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xf700Ce952B6EA11c01b43e5579C6D63286ff8CF0',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
name: 'tBTC TEST',
|
||||
symbol: 'tBTC',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xC912F059b4eCCEF6C969B2E0e2544A1A2581C094',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
name: 'tDAI TEST',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xF4A2bcC43D24D14C4189Ef45fCf681E870675333',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
|
||||
name: 'tEURO TEST',
|
||||
symbol: 'tEURO',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xD52b6C949E35A6E4C64b987B1B192A8608931a7b',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '98032ba34576f8012de9b822e1da3ed4b6223a4f4e05f573002d441ffb4bf314',
|
||||
name: 'Liquidity Reward Token (Vega)',
|
||||
symbol: 'LIQ',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xD2f21E37e78dD91b60FE3dD74A112e1a53b33057',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede',
|
||||
name: 'tUSDC TEST',
|
||||
symbol: 'tUSDC',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x3773A5c7aFF77e014cBF067dd31801b4C6dc4136',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'ba98cdeeec849a053e60cc03808e91e90d9d2e62425c76a590617b95ad41a066',
|
||||
name: 'Steve Token (Vega)',
|
||||
symbol: 'STE',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x5a16941cca2Db4AcdFC28Ac77a3e9652Fdf102e1',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'ce3fb1ab0717f0adbce019d7aef53aacdbadefe2d30ad1647b55f134d4072c90',
|
||||
name: 'Woz Token (Vega)',
|
||||
symbol: 'WOZ',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x5E4b9aDA947130Fc320a144cd22bC1641e5c9d81',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'ebcd94151ae1f0d39a4bde3b21a9c7ae81a80ea4352fb075a92e07608d9c953d',
|
||||
name: 'Maker Reward Token (Vega)',
|
||||
symbol: 'MAK',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x8ec701DA58394F5d2c8C2873D31039454D5845C1',
|
||||
lifetimeLimit: '1000000000000',
|
||||
withdrawThreshold: '0',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
|
||||
name: 'Vega (testnet)',
|
||||
symbol: 'VEGA',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0xDc335304979D378255015c33AbFf09B60c31EBAb',
|
||||
lifetimeLimit: '0',
|
||||
withdrawThreshold: '100000000',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
},
|
||||
node: generateBuiltinAsset(4, AssetStatus.STATUS_REJECTED),
|
||||
__typename: 'AssetEdge',
|
||||
},
|
||||
],
|
||||
@ -295,26 +61,122 @@ const WrappedAssetDetailsDialog = ({
|
||||
);
|
||||
|
||||
describe('AssetDetailsDialog', () => {
|
||||
it('should show no data message given unknown asset symbol', () => {
|
||||
it('should show no data message given unknown asset symbol', async () => {
|
||||
render(<WrappedAssetDetailsDialog assetSymbol={'UNKNOWN_FOR_SURE'} />);
|
||||
expect(screen.getByText('No data')).toBeInTheDocument();
|
||||
expect((await screen.findByTestId('splash')).textContent).toContain(
|
||||
'No data'
|
||||
);
|
||||
});
|
||||
|
||||
const cases = [
|
||||
['tDAI', 'tDAI', 'tDAI TEST', '21,000,000'],
|
||||
['VEGA', 'VEGA', 'Vega (testnet)', '64,999,723,000,000,000,000,000,000'],
|
||||
['tUSDC', 'tUSDC', 'tUSDC TEST', '21,000,000'],
|
||||
const cases: [string, { key: AssetDetail; value: string }[]][] = [
|
||||
[
|
||||
'EA01',
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'E-01' },
|
||||
{ key: AssetDetail.TYPE, value: 'ERC20' },
|
||||
{ key: AssetDetail.NAME, value: 'ERC20 01' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'EA01' },
|
||||
{ key: AssetDetail.DECIMALS, value: '3' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Enabled' },
|
||||
{ key: AssetDetail.CONTRACT_ADDRESS, value: '0x123' },
|
||||
{ key: AssetDetail.WITHDRAWAL_THRESHOLD, value: '0.050' },
|
||||
{ key: AssetDetail.LIFETIME_LIMIT, value: '123,000.000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.001',
|
||||
},
|
||||
{
|
||||
key: AssetDetail.GLOBAL_REWARD_POOL_ACCOUNT_BALANCE,
|
||||
value: '0.002',
|
||||
},
|
||||
{ key: AssetDetail.TAKER_FEE_REWARD_ACCOUNT_BALANCE, value: '0.003' },
|
||||
{ key: AssetDetail.MAKER_FEE_REWARD_ACCOUNT_BALANCE, value: '0.004' },
|
||||
{ key: AssetDetail.LP_FEE_REWARD_ACCOUNT_BALANCE, value: '0.005' },
|
||||
{
|
||||
key: AssetDetail.MARKET_PROPOSER_REWARD_ACCOUNT_BALANCE,
|
||||
value: '0.006',
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
'BIA01',
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'B-01' },
|
||||
{ key: AssetDetail.TYPE, value: 'Builtin asset' },
|
||||
{ key: AssetDetail.NAME, value: 'Builtin 01' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'BIA01' },
|
||||
{ key: AssetDetail.DECIMALS, value: '5' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Enabled' },
|
||||
{ key: AssetDetail.MAX_FAUCET_AMOUNT_MINT, value: '50,000.00000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.00000',
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
'BIA02',
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'B-02' },
|
||||
{ key: AssetDetail.TYPE, value: 'Builtin asset' },
|
||||
{ key: AssetDetail.NAME, value: 'Builtin 02' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'BIA02' },
|
||||
{ key: AssetDetail.DECIMALS, value: '5' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Pending listing' },
|
||||
{ key: AssetDetail.MAX_FAUCET_AMOUNT_MINT, value: '50,000.00000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.00000',
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
'BIA03',
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'B-03' },
|
||||
{ key: AssetDetail.TYPE, value: 'Builtin asset' },
|
||||
{ key: AssetDetail.NAME, value: 'Builtin 03' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'BIA03' },
|
||||
{ key: AssetDetail.DECIMALS, value: '5' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Proposed' },
|
||||
{ key: AssetDetail.MAX_FAUCET_AMOUNT_MINT, value: '50,000.00000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.00000',
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
'BIA04',
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'B-04' },
|
||||
{ key: AssetDetail.TYPE, value: 'Builtin asset' },
|
||||
{ key: AssetDetail.NAME, value: 'Builtin 04' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'BIA04' },
|
||||
{ key: AssetDetail.DECIMALS, value: '5' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Rejected' },
|
||||
{ key: AssetDetail.MAX_FAUCET_AMOUNT_MINT, value: '50,000.00000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.00000',
|
||||
},
|
||||
],
|
||||
],
|
||||
];
|
||||
it.each(cases)(
|
||||
'should show correct data given %p symbol',
|
||||
async (requestedSymbol, symbol, name, totalSupply) => {
|
||||
render(<WrappedAssetDetailsDialog assetSymbol={requestedSymbol} />);
|
||||
expect((await screen.findByTestId('symbol_value')).textContent).toContain(
|
||||
symbol
|
||||
);
|
||||
expect((await screen.findByTestId('name_value')).textContent).toContain(
|
||||
name
|
||||
);
|
||||
async (symbol, details) => {
|
||||
render(<WrappedAssetDetailsDialog assetSymbol={symbol} />);
|
||||
for (const detail of details) {
|
||||
expect(
|
||||
(await screen.findByTestId(testId(detail.key, 'value'))).textContent
|
||||
).toContain(detail.value);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -1,21 +1,9 @@
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
t,
|
||||
useDataProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import type { Asset } from './assets-data-provider';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
Icon,
|
||||
KeyValueTable,
|
||||
KeyValueTableRow,
|
||||
Splash,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { assetsProvider } from './assets-data-provider';
|
||||
import type { Schema } from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { useAssetsDataProvider } from './assets-data-provider';
|
||||
import { Button, Dialog, Icon, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import create from 'zustand';
|
||||
import { AssetDetailsTable } from './asset-details-table';
|
||||
import type { Asset } from './asset-data-provider';
|
||||
|
||||
export type AssetDetailsDialogStore = {
|
||||
isOpen: boolean;
|
||||
@ -43,117 +31,30 @@ export const useAssetDetailsDialogStore = create<AssetDetailsDialogStore>(
|
||||
})
|
||||
);
|
||||
|
||||
type AssetDetails = {
|
||||
key: string;
|
||||
label: string;
|
||||
value: string;
|
||||
tooltip: string;
|
||||
}[];
|
||||
|
||||
export interface AssetDetailsDialogProps {
|
||||
assetSymbol: string | Asset;
|
||||
trigger?: HTMLElement | null;
|
||||
open: boolean;
|
||||
onChange: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export const AssetDetailsDialog = ({
|
||||
assetSymbol,
|
||||
trigger,
|
||||
open,
|
||||
onChange,
|
||||
}: AssetDetailsDialogProps) => {
|
||||
const { data } = useDataProvider({ dataProvider: assetsProvider });
|
||||
const { data } = useAssetsDataProvider();
|
||||
|
||||
const symbol =
|
||||
typeof assetSymbol === 'string' ? assetSymbol : assetSymbol.symbol;
|
||||
const asset = data?.find((a) => a?.symbol === symbol);
|
||||
|
||||
let details: AssetDetails = [];
|
||||
if (asset != null) {
|
||||
details = [
|
||||
{
|
||||
key: 'name',
|
||||
label: t('Name'),
|
||||
value: asset.name,
|
||||
tooltip: '', // t('Name of the asset (e.g: Great British Pound)')
|
||||
},
|
||||
{
|
||||
key: 'symbol',
|
||||
label: t('Symbol'),
|
||||
value: asset.symbol,
|
||||
tooltip: '', // t('Symbol of the asset (e.g: GBP)')
|
||||
},
|
||||
{
|
||||
key: 'decimals',
|
||||
label: t('Decimals'),
|
||||
value: asset.decimals.toString(),
|
||||
tooltip: t('Number of decimal / precision handled by this asset'),
|
||||
},
|
||||
{
|
||||
key: 'quantum',
|
||||
label: t('Quantum'),
|
||||
value: asset.quantum,
|
||||
tooltip: t('The minimum economically meaningful amount in the asset'),
|
||||
},
|
||||
{
|
||||
key: 'contractaddress',
|
||||
label: t('Contract address'),
|
||||
value: (asset.source as Schema.ERC20).contractAddress,
|
||||
tooltip: t(
|
||||
'The address of the contract for the token, on the ethereum network'
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'withdrawalthreshold',
|
||||
label: t('Withdrawal threshold'),
|
||||
value: addDecimalsFormatNumber(
|
||||
(asset.source as Schema.ERC20).withdrawThreshold,
|
||||
asset.decimals
|
||||
),
|
||||
tooltip: t(
|
||||
'The maximum allowed per withdraw note: this is a temporary measure for restricted mainnet'
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'lifetimelimit',
|
||||
label: t('Lifetime limit'),
|
||||
value: addDecimalsFormatNumber(
|
||||
(asset.source as Schema.ERC20).lifetimeLimit,
|
||||
asset.decimals
|
||||
),
|
||||
tooltip: t(
|
||||
'The lifetime limits deposit per address note: this is a temporary measure for restricted mainnet'
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const content = asset ? (
|
||||
<div className="my-2">
|
||||
<KeyValueTable>
|
||||
{details
|
||||
.filter(({ value }) => value && value.length > 0)
|
||||
.map(({ key, label, value, tooltip }) => (
|
||||
<KeyValueTableRow key={key}>
|
||||
<div
|
||||
data-testid={`${key}_label`}
|
||||
className="first-letter:uppercase"
|
||||
>
|
||||
{tooltip.length > 0 ? (
|
||||
<Tooltip description={tooltip}>
|
||||
<span>{label}</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<span>{label}</span>
|
||||
)}
|
||||
</div>
|
||||
<div data-testid={`${key}_value`}>{value}</div>
|
||||
</KeyValueTableRow>
|
||||
))}
|
||||
</KeyValueTable>
|
||||
<AssetDetailsTable asset={asset} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="py-12">
|
||||
<div className="py-12" data-testid="splash">
|
||||
<Splash>{t('No data')}</Splash>
|
||||
</div>
|
||||
);
|
||||
@ -183,7 +84,7 @@ export const AssetDetailsDialog = ({
|
||||
size="sm"
|
||||
onClick={() => onChange(false)}
|
||||
>
|
||||
Close
|
||||
{t('Close')}
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
80
libs/assets/src/lib/asset-details-table.spec.tsx
Normal file
80
libs/assets/src/lib/asset-details-table.spec.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { AssetStatus } from '@vegaprotocol/types';
|
||||
import type { Asset } from './asset-data-provider';
|
||||
import {
|
||||
AssetDetail,
|
||||
AssetDetailsTable,
|
||||
rows,
|
||||
testId,
|
||||
} from './asset-details-table';
|
||||
import { generateBuiltinAsset, generateERC20Asset } from './test-helpers';
|
||||
|
||||
describe('AssetDetailsTable', () => {
|
||||
const cases: [string, Asset, { key: AssetDetail; value: string }[]][] = [
|
||||
[
|
||||
'ERC20 asset',
|
||||
generateERC20Asset(1, AssetStatus.STATUS_ENABLED),
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'E-01' },
|
||||
{ key: AssetDetail.TYPE, value: 'ERC20' },
|
||||
{ key: AssetDetail.NAME, value: 'ERC20 01' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'EA01' },
|
||||
{ key: AssetDetail.DECIMALS, value: '3' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Enabled' },
|
||||
{ key: AssetDetail.CONTRACT_ADDRESS, value: '0x123' },
|
||||
{ key: AssetDetail.WITHDRAWAL_THRESHOLD, value: '0.050' },
|
||||
{ key: AssetDetail.LIFETIME_LIMIT, value: '123,000.000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.001',
|
||||
},
|
||||
{
|
||||
key: AssetDetail.GLOBAL_REWARD_POOL_ACCOUNT_BALANCE,
|
||||
value: '0.002',
|
||||
},
|
||||
{ key: AssetDetail.TAKER_FEE_REWARD_ACCOUNT_BALANCE, value: '0.003' },
|
||||
{ key: AssetDetail.MAKER_FEE_REWARD_ACCOUNT_BALANCE, value: '0.004' },
|
||||
{ key: AssetDetail.LP_FEE_REWARD_ACCOUNT_BALANCE, value: '0.005' },
|
||||
{
|
||||
key: AssetDetail.MARKET_PROPOSER_REWARD_ACCOUNT_BALANCE,
|
||||
value: '0.006',
|
||||
},
|
||||
],
|
||||
],
|
||||
[
|
||||
'Builtin asset',
|
||||
generateBuiltinAsset(1, AssetStatus.STATUS_ENABLED),
|
||||
[
|
||||
{ key: AssetDetail.ID, value: 'B-01' },
|
||||
{ key: AssetDetail.TYPE, value: 'Builtin asset' },
|
||||
{ key: AssetDetail.NAME, value: 'Builtin 01' },
|
||||
{ key: AssetDetail.SYMBOL, value: 'BIA01' },
|
||||
{ key: AssetDetail.DECIMALS, value: '5' },
|
||||
{ key: AssetDetail.QUANTUM, value: '1' },
|
||||
{ key: AssetDetail.STATUS, value: 'Enabled' },
|
||||
{ key: AssetDetail.MAX_FAUCET_AMOUNT_MINT, value: '50,000.00000' },
|
||||
{
|
||||
key: AssetDetail.INFRASTRUCTURE_FEE_ACCOUNT_BALANCE,
|
||||
value: '0.00000',
|
||||
},
|
||||
],
|
||||
],
|
||||
];
|
||||
it.each(cases)(
|
||||
"displays the available asset's data of %p with correct labels",
|
||||
async (_type, asset, details) => {
|
||||
render(<AssetDetailsTable asset={asset} />);
|
||||
for (const detail of details) {
|
||||
expect(
|
||||
await (
|
||||
await screen.findByTestId(testId(detail.key, 'label'))
|
||||
).textContent
|
||||
).toContain(rows.find((r) => r.key === detail.key)?.label);
|
||||
expect(
|
||||
(await screen.findByTestId(testId(detail.key, 'value'))).textContent
|
||||
).toContain(detail.value);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
251
libs/assets/src/lib/asset-details-table.tsx
Normal file
251
libs/assets/src/lib/asset-details-table.tsx
Normal file
@ -0,0 +1,251 @@
|
||||
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,
|
||||
TAKER_FEE_REWARD_ACCOUNT_BALANCE,
|
||||
MAKER_FEE_REWARD_ACCOUNT_BALANCE,
|
||||
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 in 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 allowed per withdraw note: this is a temporary measure for restricted mainnet'
|
||||
),
|
||||
value: (asset) =>
|
||||
num(asset, (asset.source as Schema.ERC20).withdrawThreshold),
|
||||
},
|
||||
{
|
||||
key: AssetDetail.LIFETIME_LIMIT,
|
||||
label: t('Lifetime limit'),
|
||||
tooltip: t(
|
||||
'The lifetime limits deposit per address note: this is a temporary measure for restricted mainnet'
|
||||
),
|
||||
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 for 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 reward pool account for this asset'),
|
||||
value: (asset) => num(asset, asset.globalRewardPoolAccount?.balance),
|
||||
},
|
||||
{
|
||||
key: AssetDetail.TAKER_FEE_REWARD_ACCOUNT_BALANCE,
|
||||
label: t('Taker fee reward account balance'),
|
||||
tooltip: t('The taker fee reward account for this asset'),
|
||||
value: (asset) => num(asset, asset.takerFeeRewardAccount?.balance),
|
||||
},
|
||||
{
|
||||
key: AssetDetail.MAKER_FEE_REWARD_ACCOUNT_BALANCE,
|
||||
label: t('Maker fee reward account balance'),
|
||||
tooltip: t('The maker fee reward account for this asset'),
|
||||
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 liquidity provision reward account for 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 market proposer reward account for 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 is pending listing on the ethereum bridge'),
|
||||
},
|
||||
STATUS_PROPOSED: {
|
||||
value: t('Proposed'),
|
||||
tooltip: t('Asset is proposed to be added 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>
|
||||
);
|
||||
};
|
@ -1,19 +1,18 @@
|
||||
import {
|
||||
makeDataProvider,
|
||||
makeDerivedDataProvider,
|
||||
useDataProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { AssetsDocument } from './__generated___/Assets';
|
||||
import { AssetStatus } from '@vegaprotocol/types';
|
||||
import type {
|
||||
AssetsQuery,
|
||||
AssetsFieldsFragment,
|
||||
} from './__generated___/Assets';
|
||||
|
||||
export type Asset = AssetsFieldsFragment;
|
||||
import type { AssetsQuery } from './__generated___/Assets';
|
||||
import type { Asset } from './asset-data-provider';
|
||||
|
||||
export interface ERC20AssetSource {
|
||||
__typename: 'ERC20';
|
||||
contractAddress: string;
|
||||
lifetimeLimit: string;
|
||||
withdrawThreshold: string;
|
||||
}
|
||||
|
||||
export interface BuiltinAssetSource {
|
||||
@ -58,3 +57,8 @@ export const enabledAssetsProvider = makeDerivedDataProvider<
|
||||
(a) => a.status === AssetStatus.STATUS_ENABLED
|
||||
)
|
||||
);
|
||||
|
||||
export const useAssetsDataProvider = () =>
|
||||
useDataProvider({
|
||||
dataProvider: assetsProvider,
|
||||
});
|
||||
|
@ -1,3 +1,6 @@
|
||||
export * from './__generated___/Asset';
|
||||
export * from './__generated___/Assets';
|
||||
export * from './asset-data-provider';
|
||||
export * from './assets-data-provider';
|
||||
export * from './asset-details-dialog';
|
||||
export * from './asset-details-table';
|
||||
|
68
libs/assets/src/lib/test-helpers.ts
Normal file
68
libs/assets/src/lib/test-helpers.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import type { AssetStatus } from '@vegaprotocol/types';
|
||||
import type { Asset } from './asset-data-provider';
|
||||
|
||||
export const generateERC20Asset = (i: number, status: AssetStatus): Asset => ({
|
||||
id: `E-0${i}`,
|
||||
name: `ERC20 0${i}`,
|
||||
symbol: `EA0${i}`,
|
||||
decimals: 3,
|
||||
quantum: '1',
|
||||
source: {
|
||||
contractAddress: '0x123',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
status: status,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
});
|
||||
|
||||
export const generateBuiltinAsset = (
|
||||
i: number,
|
||||
status: AssetStatus
|
||||
): Asset => ({
|
||||
id: `B-0${i}`,
|
||||
name: `Builtin 0${i}`,
|
||||
symbol: `BIA0${i}`,
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
source: {
|
||||
maxFaucetAmountMint: '5000000000',
|
||||
__typename: 'BuiltinAsset',
|
||||
},
|
||||
status: status,
|
||||
infrastructureFeeAccount: {
|
||||
balance: '0',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: null,
|
||||
takerFeeRewardAccount: null,
|
||||
makerFeeRewardAccount: null,
|
||||
lpFeeRewardAccount: null,
|
||||
marketProposerRewardAccount: null,
|
||||
__typename: 'Asset',
|
||||
});
|
@ -23,6 +23,7 @@ import { generatePath } from 'react-router-dom';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { Link as UiToolkitLink } from '@vegaprotocol/ui-toolkit';
|
||||
import Link from 'next/link';
|
||||
import { AssetDetailsTable, useAssetDataProvider } from '@vegaprotocol/assets';
|
||||
|
||||
const Links = {
|
||||
PROPOSAL_PAGE: ':tokenUrl/governance/:proposalId',
|
||||
@ -92,6 +93,11 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
const dayVolume = calcCandleVolume(market);
|
||||
const assetSymbol =
|
||||
market.tradableInstrument.instrument.product?.settlementAsset.symbol;
|
||||
const assetId = useMemo(
|
||||
() => market.tradableInstrument.instrument.product?.settlementAsset.id,
|
||||
[market]
|
||||
);
|
||||
const { data: asset } = useAssetDataProvider(assetId);
|
||||
const marketDataPanels = [
|
||||
{
|
||||
title: t('Current fees'),
|
||||
@ -201,18 +207,16 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
||||
},
|
||||
{
|
||||
title: t('Settlement asset'),
|
||||
content: (
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
name: market.tradableInstrument.instrument.product?.settlementAsset
|
||||
.name,
|
||||
symbol:
|
||||
market.tradableInstrument.instrument.product?.settlementAsset
|
||||
.symbol,
|
||||
assetID:
|
||||
market.tradableInstrument.instrument.product?.settlementAsset.id,
|
||||
}}
|
||||
content: asset ? (
|
||||
<AssetDetailsTable
|
||||
asset={asset}
|
||||
inline={true}
|
||||
noBorder={true}
|
||||
dtClassName="text-black dark:text-white text-ui !px-0 !font-normal"
|
||||
ddClassName="text-black dark:text-white text-ui !px-0 !font-normal max-w-full"
|
||||
/>
|
||||
) : (
|
||||
<Splash>{t('No data')}</Splash>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -11,7 +11,6 @@ import type { Withdrawals_party_withdrawalsConnection_edges_node } from './__gen
|
||||
|
||||
export const generateAsset = (override?: PartialDeep<Asset>) => {
|
||||
const defaultAsset: Asset = {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-id',
|
||||
symbol: 'asset-symbol',
|
||||
name: 'asset-name',
|
||||
@ -19,9 +18,36 @@ export const generateAsset = (override?: PartialDeep<Asset>) => {
|
||||
decimals: 5,
|
||||
status: AssetStatus.STATUS_ENABLED,
|
||||
source: {
|
||||
__typename: 'ERC20',
|
||||
contractAddress: 'contract-address',
|
||||
lifetimeLimit: '123000000',
|
||||
withdrawThreshold: '50',
|
||||
__typename: 'ERC20',
|
||||
},
|
||||
infrastructureFeeAccount: {
|
||||
balance: '1',
|
||||
__typename: 'Account',
|
||||
},
|
||||
globalRewardPoolAccount: {
|
||||
balance: '2',
|
||||
__typename: 'Account',
|
||||
},
|
||||
takerFeeRewardAccount: {
|
||||
balance: '3',
|
||||
__typename: 'Account',
|
||||
},
|
||||
makerFeeRewardAccount: {
|
||||
balance: '4',
|
||||
__typename: 'Account',
|
||||
},
|
||||
lpFeeRewardAccount: {
|
||||
balance: '5',
|
||||
__typename: 'Account',
|
||||
},
|
||||
marketProposerRewardAccount: {
|
||||
balance: '6',
|
||||
__typename: 'Account',
|
||||
},
|
||||
__typename: 'Asset',
|
||||
};
|
||||
return merge(defaultAsset, override);
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ import type {
|
||||
Erc20ApprovalVariables,
|
||||
} from './__generated__/Erc20Approval';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import type { ERC20Asset } from '@vegaprotocol/assets';
|
||||
|
||||
export enum ApprovalStatus {
|
||||
Idle = 'Idle',
|
||||
@ -80,7 +81,7 @@ export const useVerifyWithdrawal = () => {
|
||||
addDecimal(withdrawal.amount, withdrawal.asset.decimals)
|
||||
);
|
||||
|
||||
const threshold = await getThreshold(withdrawal.asset);
|
||||
const threshold = await getThreshold(withdrawal.asset as ERC20Asset);
|
||||
|
||||
if (threshold && amount.isGreaterThan(threshold)) {
|
||||
const delaySecs = await getDelay();
|
||||
|
Loading…
Reference in New Issue
Block a user