Merge branch 'main' into chore/sync-main
This commit is contained in:
commit
fae66ca4ce
@ -133,7 +133,7 @@ export const proposalsData = {
|
|||||||
instrument: {
|
instrument: {
|
||||||
name: 'UNIDAI Monthly (Dec 2022)',
|
name: 'UNIDAI Monthly (Dec 2022)',
|
||||||
code: 'UNIDAI.MF21',
|
code: 'UNIDAI.MF21',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
|
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
|
||||||
__typename: 'FutureProduct',
|
__typename: 'FutureProduct',
|
||||||
},
|
},
|
||||||
@ -240,7 +240,7 @@ export const proposalsData = {
|
|||||||
instrument: {
|
instrument: {
|
||||||
name: 'ETHBTC Quarterly (Feb 2023)',
|
name: 'ETHBTC Quarterly (Feb 2023)',
|
||||||
code: 'ETHBTC.QM21',
|
code: 'ETHBTC.QM21',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: { symbol: 'tBTC', __typename: 'Asset' },
|
settlementAsset: { symbol: 'tBTC', __typename: 'Asset' },
|
||||||
__typename: 'FutureProduct',
|
__typename: 'FutureProduct',
|
||||||
},
|
},
|
||||||
|
@ -77,7 +77,7 @@ describe('Proposal header', () => {
|
|||||||
__typename: 'InstrumentConfiguration',
|
__typename: 'InstrumentConfiguration',
|
||||||
name: 'Some market',
|
name: 'Some market',
|
||||||
code: 'FX:BTCUSD/DEC99',
|
code: 'FX:BTCUSD/DEC99',
|
||||||
futureProduct: {
|
product: {
|
||||||
__typename: 'FutureProduct',
|
__typename: 'FutureProduct',
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
|
@ -39,6 +39,18 @@ export const ProposalHeader = ({
|
|||||||
|
|
||||||
const titleContent = shorten(title ?? '', 100);
|
const titleContent = shorten(title ?? '', 100);
|
||||||
|
|
||||||
|
const getAsset = (proposal: ProposalQuery['proposal']) => {
|
||||||
|
const terms = proposal?.terms;
|
||||||
|
if (
|
||||||
|
terms?.change.__typename === 'NewMarket' &&
|
||||||
|
(terms.change.instrument.product?.__typename === 'FutureProduct' ||
|
||||||
|
terms.change.instrument.product?.__typename === 'PerpetualProduct')
|
||||||
|
) {
|
||||||
|
return terms.change.instrument.product.settlementAsset;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
switch (change?.__typename) {
|
switch (change?.__typename) {
|
||||||
case 'NewMarket': {
|
case 'NewMarket': {
|
||||||
proposalType =
|
proposalType =
|
||||||
@ -54,10 +66,10 @@ export const ProposalHeader = ({
|
|||||||
<span>
|
<span>
|
||||||
{t('Code')}: {change.instrument.code}.
|
{t('Code')}: {change.instrument.code}.
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
{change.instrument.futureProduct?.settlementAsset.symbol ? (
|
{proposal?.terms && getAsset(proposal)?.symbol ? (
|
||||||
<>
|
<>
|
||||||
<span className="font-semibold">
|
<span className="font-semibold">
|
||||||
{change.instrument.futureProduct.settlementAsset.symbol}
|
{getAsset(proposal)?.symbol}
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
{t('settled future')}.
|
{t('settled future')}.
|
||||||
</>
|
</>
|
||||||
|
@ -130,7 +130,8 @@ query Proposal(
|
|||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
code
|
code
|
||||||
futureProduct {
|
product {
|
||||||
|
... on FutureProduct {
|
||||||
settlementAsset {
|
settlementAsset {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@ -139,7 +140,10 @@ query Proposal(
|
|||||||
quantum
|
quantum
|
||||||
}
|
}
|
||||||
quoteName
|
quoteName
|
||||||
|
dataSourceSpecBinding {
|
||||||
|
settlementDataProperty
|
||||||
|
tradingTerminationProperty
|
||||||
|
}
|
||||||
dataSourceSpecForSettlementData {
|
dataSourceSpecForSettlementData {
|
||||||
sourceType {
|
sourceType {
|
||||||
... on DataSourceDefinitionInternal {
|
... on DataSourceDefinitionInternal {
|
||||||
@ -180,49 +184,16 @@ query Proposal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# dataSourceSpecForTradingTermination {
|
}
|
||||||
# sourceType {
|
... on PerpetualProduct {
|
||||||
# ... on DataSourceDefinitionInternal {
|
settlementAsset {
|
||||||
# sourceType {
|
id
|
||||||
# ... on DataSourceSpecConfigurationTime {
|
name
|
||||||
# conditions {
|
symbol
|
||||||
# operator
|
decimals
|
||||||
# value
|
quantum
|
||||||
# }
|
}
|
||||||
# }
|
quoteName
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# ... on DataSourceDefinitionExternal {
|
|
||||||
# sourceType {
|
|
||||||
# ... on DataSourceSpecConfiguration {
|
|
||||||
# signers {
|
|
||||||
# signer {
|
|
||||||
# ... on PubKey {
|
|
||||||
# key
|
|
||||||
# }
|
|
||||||
# ... on ETHAddress {
|
|
||||||
# address
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# filters {
|
|
||||||
# key {
|
|
||||||
# name
|
|
||||||
# type
|
|
||||||
# }
|
|
||||||
# conditions {
|
|
||||||
# operator
|
|
||||||
# value
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
dataSourceSpecBinding {
|
|
||||||
settlementDataProperty
|
|
||||||
tradingTerminationProperty
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -101,11 +101,18 @@ fragment ProposalFields on Proposal {
|
|||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
code
|
code
|
||||||
futureProduct {
|
product {
|
||||||
|
... on FutureProduct {
|
||||||
settlementAsset {
|
settlementAsset {
|
||||||
symbol
|
symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
... on PerpetualProduct {
|
||||||
|
settlementAsset {
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on UpdateMarket {
|
... on UpdateMarket {
|
||||||
|
@ -11,7 +11,7 @@ export type UpdateReferralProgramsFragment = { __typename?: 'Proposal', terms: {
|
|||||||
|
|
||||||
export type UpdateVolumeDiscountProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } } };
|
export type UpdateVolumeDiscountProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } } };
|
||||||
|
|
||||||
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } };
|
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, product?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename?: 'PerpetualProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename?: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } };
|
||||||
|
|
||||||
export type ProposalsQueryVariables = Types.Exact<{
|
export type ProposalsQueryVariables = Types.Exact<{
|
||||||
includeNewMarketProductFields: Types.Scalars['Boolean'];
|
includeNewMarketProductFields: Types.Scalars['Boolean'];
|
||||||
@ -20,7 +20,7 @@ export type ProposalsQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: any, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
|
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, product?: { __typename: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename: 'PerpetualProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: any, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
|
||||||
|
|
||||||
export const NewMarketProductFieldsFragmentDoc = gql`
|
export const NewMarketProductFieldsFragmentDoc = gql`
|
||||||
fragment NewMarketProductFields on Proposal {
|
fragment NewMarketProductFields on Proposal {
|
||||||
@ -130,11 +130,18 @@ export const ProposalFieldsFragmentDoc = gql`
|
|||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
code
|
code
|
||||||
futureProduct {
|
product {
|
||||||
|
... on FutureProduct {
|
||||||
settlementAsset {
|
settlementAsset {
|
||||||
symbol
|
symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
... on PerpetualProduct {
|
||||||
|
settlementAsset {
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
... on UpdateMarket {
|
... on UpdateMarket {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { Route, Routes, useParams } from 'react-router-dom';
|
import { Route, Routes } from 'react-router-dom';
|
||||||
import { MarketState } from '@vegaprotocol/types';
|
|
||||||
import { useMarket } from '@vegaprotocol/markets';
|
|
||||||
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import {
|
||||||
SidebarButton,
|
SidebarButton,
|
||||||
@ -12,12 +10,7 @@ import { useT } from '../../lib/use-t';
|
|||||||
|
|
||||||
export const MarketsSidebar = () => {
|
export const MarketsSidebar = () => {
|
||||||
const t = useT();
|
const t = useT();
|
||||||
const { marketId } = useParams();
|
|
||||||
const currentRouteId = useGetCurrentRouteId();
|
const currentRouteId = useGetCurrentRouteId();
|
||||||
const { data } = useMarket(marketId);
|
|
||||||
const active =
|
|
||||||
data &&
|
|
||||||
[MarketState.STATE_ACTIVE, MarketState.STATE_PENDING].includes(data.state);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -45,14 +38,12 @@ export const MarketsSidebar = () => {
|
|||||||
element={
|
element={
|
||||||
<>
|
<>
|
||||||
<SidebarDivider />
|
<SidebarDivider />
|
||||||
{active && (
|
|
||||||
<SidebarButton
|
<SidebarButton
|
||||||
view={ViewType.Order}
|
view={ViewType.Order}
|
||||||
icon={VegaIconNames.TICKET}
|
icon={VegaIconNames.TICKET}
|
||||||
tooltip={t('Order')}
|
tooltip={t('Order')}
|
||||||
routeId={currentRouteId}
|
routeId={currentRouteId}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
<SidebarButton
|
<SidebarButton
|
||||||
view={ViewType.Info}
|
view={ViewType.Info}
|
||||||
icon={VegaIconNames.BREAKDOWN}
|
icon={VegaIconNames.BREAKDOWN}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { getAsset, getQuoteName } from '@vegaprotocol/markets';
|
import { getAsset, getProductType, getQuoteName } from '@vegaprotocol/markets';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
@ -297,9 +297,19 @@ export const DealTicketMarginDetails = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const quoteName = getQuoteName(market);
|
const quoteName = getQuoteName(market);
|
||||||
|
const productType = getProductType(market);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full gap-2">
|
<div className="flex flex-col w-full gap-2 pt-2">
|
||||||
|
{/*
|
||||||
|
TODO: remove this conditional check once the following PRs are deployed
|
||||||
|
and the estimatePosition query is working for perps
|
||||||
|
|
||||||
|
- https://github.com/vegaprotocol/vega/pull/10119
|
||||||
|
- https://github.com/vegaprotocol/vega/pull/10122
|
||||||
|
*/}
|
||||||
|
{productType === 'Future' && (
|
||||||
|
<>
|
||||||
<Accordion>
|
<Accordion>
|
||||||
<AccordionPanel
|
<AccordionPanel
|
||||||
itemId="margin"
|
itemId="margin"
|
||||||
@ -307,7 +317,7 @@ export const DealTicketMarginDetails = ({
|
|||||||
<AccordionPrimitive.Trigger
|
<AccordionPrimitive.Trigger
|
||||||
data-testid="accordion-toggle"
|
data-testid="accordion-toggle"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-full pt-2',
|
'w-full',
|
||||||
'flex items-center gap-2 text-xs',
|
'flex items-center gap-2 text-xs',
|
||||||
'group'
|
'group'
|
||||||
)}
|
)}
|
||||||
@ -325,7 +335,9 @@ export const DealTicketMarginDetails = ({
|
|||||||
{ assetSymbol }
|
{ assetSymbol }
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span className="text-muted">{t('Margin required')}</span>
|
<span className="text-muted">
|
||||||
|
{t('Margin required')}
|
||||||
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<AccordionChevron size={10} />
|
<AccordionChevron size={10} />
|
||||||
@ -397,10 +409,7 @@ export const DealTicketMarginDetails = ({
|
|||||||
}
|
}
|
||||||
value={formatValue(marginAccountBalance, assetDecimals)}
|
value={formatValue(marginAccountBalance, assetDecimals)}
|
||||||
symbol={assetSymbol}
|
symbol={assetSymbol}
|
||||||
labelDescription={t(
|
labelDescription={MARGIN_ACCOUNT_TOOLTIP_TEXT}
|
||||||
'MARGIN_ACCOUNT_TOOLTIP_TEXT',
|
|
||||||
MARGIN_ACCOUNT_TOOLTIP_TEXT
|
|
||||||
)}
|
|
||||||
formattedValue={formatValue(
|
formattedValue={formatValue(
|
||||||
marginAccountBalance,
|
marginAccountBalance,
|
||||||
assetDecimals,
|
assetDecimals,
|
||||||
@ -411,6 +420,8 @@ export const DealTicketMarginDetails = ({
|
|||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
{projectedMargin}
|
{projectedMargin}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<KeyValue
|
<KeyValue
|
||||||
label={t('Liquidation')}
|
label={t('Liquidation')}
|
||||||
value={liquidationPriceEstimateRange}
|
value={liquidationPriceEstimateRange}
|
||||||
|
@ -399,7 +399,7 @@ export const LiquidityTable = ({
|
|||||||
headerTooltip: t(
|
headerTooltip: t(
|
||||||
`The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.`
|
`The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.`
|
||||||
),
|
),
|
||||||
valueFormatter: stakeToCcyVolumeQuantumFormatter,
|
valueFormatter: assetDecimalsQuantumFormatter,
|
||||||
tooltipValueGetter: feesAccruedTooltip,
|
tooltipValueGetter: feesAccruedTooltip,
|
||||||
cellClassRules: {
|
cellClassRules: {
|
||||||
'text-warning': ({ data }: { data: LiquidityProvisionData }) => {
|
'text-warning': ({ data }: { data: LiquidityProvisionData }) => {
|
||||||
|
@ -28,6 +28,22 @@ export const getAsset = (market: Partial<Market>) => {
|
|||||||
throw new Error('Failed to retrieve asset. Invalid product type');
|
throw new Error('Failed to retrieve asset. Invalid product type');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getProductType = (market: Partial<Market>) => {
|
||||||
|
if (!market.tradableInstrument?.instrument.product) {
|
||||||
|
throw new Error(
|
||||||
|
'Failed to retrieve product type. Invalid tradable instrument'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = market.tradableInstrument.instrument.product.__typename;
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
throw new Error('Failed to retrieve asset. Invalid product type');
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
};
|
||||||
|
|
||||||
export const getQuoteName = (market: Partial<Market>) => {
|
export const getQuoteName = (market: Partial<Market>) => {
|
||||||
if (!market.tradableInstrument?.instrument.product) {
|
if (!market.tradableInstrument?.instrument.product) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -85,7 +85,6 @@ describe('ProposalsList', () => {
|
|||||||
'Settlement asset',
|
'Settlement asset',
|
||||||
'State',
|
'State',
|
||||||
'Parent market',
|
'Parent market',
|
||||||
'Voting',
|
|
||||||
'Closing date',
|
'Closing date',
|
||||||
'Enactment date',
|
'Enactment date',
|
||||||
'', // actions col
|
'', // actions col
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import {
|
import {
|
||||||
CenteredGridCellWrapper,
|
|
||||||
COL_DEFS,
|
COL_DEFS,
|
||||||
DateRangeFilter,
|
DateRangeFilter,
|
||||||
SetFilter,
|
SetFilter,
|
||||||
@ -11,33 +9,18 @@ import {
|
|||||||
import compact from 'lodash/compact';
|
import compact from 'lodash/compact';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import {
|
|
||||||
NetworkParams,
|
|
||||||
useNetworkParams,
|
|
||||||
} from '@vegaprotocol/network-parameters';
|
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import {
|
import {
|
||||||
ProductTypeMapping,
|
ProposalProductTypeShortName,
|
||||||
ProductTypeShortName,
|
|
||||||
ProposalStateMapping,
|
ProposalStateMapping,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
||||||
import { VoteProgress } from '../voting-progress';
|
|
||||||
import { ProposalActionsDropdown } from '../proposal-actions-dropdown';
|
import { ProposalActionsDropdown } from '../proposal-actions-dropdown';
|
||||||
|
|
||||||
export const useColumnDefs = () => {
|
export const useColumnDefs = () => {
|
||||||
const { params } = useNetworkParams([
|
|
||||||
NetworkParams.governance_proposal_market_requiredMajority,
|
|
||||||
]);
|
|
||||||
const requiredMajorityPercentage = useMemo(() => {
|
|
||||||
const requiredMajority =
|
|
||||||
params?.governance_proposal_market_requiredMajority ?? 1;
|
|
||||||
return new BigNumber(requiredMajority).times(100);
|
|
||||||
}, [params?.governance_proposal_market_requiredMajority]);
|
|
||||||
|
|
||||||
const columnDefs: ColDef[] = useMemo(() => {
|
const columnDefs: ColDef[] = useMemo(() => {
|
||||||
return compact([
|
return compact([
|
||||||
{
|
{
|
||||||
@ -54,27 +37,38 @@ export const useColumnDefs = () => {
|
|||||||
}) => {
|
}) => {
|
||||||
if (!value || !data) return '-';
|
if (!value || !data) return '-';
|
||||||
|
|
||||||
// TODO: update when we switch to ProductConfiguration
|
const getProductType = (data: ProposalListFieldsFragment) => {
|
||||||
const productType = 'Future';
|
if (
|
||||||
|
data.terms.__typename === 'ProposalTerms' &&
|
||||||
|
data.terms.change.__typename === 'NewMarket'
|
||||||
|
) {
|
||||||
|
return data.terms.change.instrument.product?.__typename;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const productType = getProductType(data);
|
||||||
return (
|
return (
|
||||||
|
productType && (
|
||||||
<StackedCell
|
<StackedCell
|
||||||
primary={value}
|
primary={value}
|
||||||
secondary={
|
secondary={
|
||||||
<span
|
<span
|
||||||
title={ProductTypeMapping[productType]}
|
title={ProposalProductTypeShortName[productType]}
|
||||||
className="uppercase"
|
className="uppercase"
|
||||||
>
|
>
|
||||||
{ProductTypeShortName[productType]}
|
{ProposalProductTypeShortName[productType]}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
colId: 'asset',
|
colId: 'asset',
|
||||||
headerName: t('Settlement asset'),
|
headerName: t('Settlement asset'),
|
||||||
field: 'terms.change.instrument.futureProduct.settlementAsset.symbol',
|
field: 'terms.change.instrument.product.settlementAsset.symbol',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
colId: 'state',
|
colId: 'state',
|
||||||
@ -94,32 +88,6 @@ export const useColumnDefs = () => {
|
|||||||
field: 'terms.change.successorConfiguration.parentMarketId',
|
field: 'terms.change.successorConfiguration.parentMarketId',
|
||||||
cellRenderer: 'ParentMarketCell',
|
cellRenderer: 'ParentMarketCell',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
colId: 'voting',
|
|
||||||
headerName: t('Voting'),
|
|
||||||
cellRenderer: ({
|
|
||||||
data,
|
|
||||||
}: VegaICellRendererParams<ProposalListFieldsFragment>) => {
|
|
||||||
if (data) {
|
|
||||||
const yesTokens = new BigNumber(data.votes.yes.totalTokens);
|
|
||||||
const noTokens = new BigNumber(data.votes.no.totalTokens);
|
|
||||||
const totalTokensVoted = yesTokens.plus(noTokens);
|
|
||||||
const yesPercentage = totalTokensVoted.isZero()
|
|
||||||
? new BigNumber(0)
|
|
||||||
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
|
||||||
return (
|
|
||||||
<CenteredGridCellWrapper>
|
|
||||||
<VoteProgress
|
|
||||||
threshold={requiredMajorityPercentage}
|
|
||||||
progress={yesPercentage}
|
|
||||||
/>
|
|
||||||
</CenteredGridCellWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return '-';
|
|
||||||
},
|
|
||||||
filter: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
colId: 'closing-date',
|
colId: 'closing-date',
|
||||||
headerName: t('Closing date'),
|
headerName: t('Closing date'),
|
||||||
@ -156,7 +124,7 @@ export const useColumnDefs = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}, [requiredMajorityPercentage]);
|
}, []);
|
||||||
|
|
||||||
return columnDefs;
|
return columnDefs;
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,8 @@ fragment NewMarketFields on NewMarket {
|
|||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
code
|
code
|
||||||
futureProduct {
|
product {
|
||||||
|
... on FutureProduct {
|
||||||
settlementAsset {
|
settlementAsset {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@ -90,6 +91,17 @@ fragment NewMarketFields on NewMarket {
|
|||||||
tradingTerminationProperty
|
tradingTerminationProperty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
... on PerpetualProduct {
|
||||||
|
settlementAsset {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
symbol
|
||||||
|
decimals
|
||||||
|
quantum
|
||||||
|
}
|
||||||
|
quoteName
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
decimalPlaces
|
decimalPlaces
|
||||||
riskParameters {
|
riskParameters {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -128,7 +128,7 @@ export const createProposalListFieldsFragment = (
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'ETHUSD',
|
code: 'ETHUSD',
|
||||||
name: 'ETHUSD',
|
name: 'ETHUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -262,7 +262,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'ETHUSD',
|
code: 'ETHUSD',
|
||||||
name: 'ETHUSD',
|
name: 'ETHUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -352,7 +352,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'LINKUSD',
|
code: 'LINKUSD',
|
||||||
name: 'LINKUSD',
|
name: 'LINKUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
||||||
name: 'mUSDT-II',
|
name: 'mUSDT-II',
|
||||||
@ -442,7 +442,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'LINKUSD',
|
code: 'LINKUSD',
|
||||||
name: 'LINKUSD',
|
name: 'LINKUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
||||||
name: 'mUSDT-II',
|
name: 'mUSDT-II',
|
||||||
@ -532,7 +532,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'ETHUSD',
|
code: 'ETHUSD',
|
||||||
name: 'ETHUSD',
|
name: 'ETHUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -622,7 +622,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'LINKUSD',
|
code: 'LINKUSD',
|
||||||
name: 'LINKUSD',
|
name: 'LINKUSD',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
id: 'eb30d55e90e1f9e5c4727d6fa2a5a8cd36ab9ae9738eb8f3faf53e2bee4861ee',
|
||||||
name: 'mUSDT-II',
|
name: 'mUSDT-II',
|
||||||
@ -712,7 +712,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'ETHDAI.MF21',
|
code: 'ETHDAI.MF21',
|
||||||
name: 'ETHDAI Monthly (Dec 2022)',
|
name: 'ETHDAI Monthly (Dec 2022)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -802,7 +802,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'AAPL.MF21',
|
code: 'AAPL.MF21',
|
||||||
name: 'Apple Monthly (Dec 2022)',
|
name: 'Apple Monthly (Dec 2022)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'c9fe6fc24fce121b2cc72680543a886055abb560043fda394ba5376203b7527d',
|
id: 'c9fe6fc24fce121b2cc72680543a886055abb560043fda394ba5376203b7527d',
|
||||||
name: 'tUSDC TEST',
|
name: 'tUSDC TEST',
|
||||||
@ -892,7 +892,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'BTCUSD.MF21',
|
code: 'BTCUSD.MF21',
|
||||||
name: 'BTCUSD Monthly (Dec 2022)',
|
name: 'BTCUSD Monthly (Dec 2022)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -982,7 +982,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'TSLA.QM21',
|
code: 'TSLA.QM21',
|
||||||
name: 'Tesla Quarterly (Feb 2023)',
|
name: 'Tesla Quarterly (Feb 2023)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: '177e8f6c25a955bd18475084b99b2b1d37f28f3dec393fab7755a7e69c3d8c3b',
|
id: '177e8f6c25a955bd18475084b99b2b1d37f28f3dec393fab7755a7e69c3d8c3b',
|
||||||
name: 'tEURO TEST',
|
name: 'tEURO TEST',
|
||||||
@ -1072,7 +1072,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'AAVEDAI.MF21',
|
code: 'AAVEDAI.MF21',
|
||||||
name: 'AAVEDAI Monthly (Dec 2022)',
|
name: 'AAVEDAI Monthly (Dec 2022)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
@ -1162,7 +1162,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'ETHBTC.QM21',
|
code: 'ETHBTC.QM21',
|
||||||
name: 'ETHBTC Quarterly (Feb 2023)',
|
name: 'ETHBTC Quarterly (Feb 2023)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'cee709223217281d7893b650850ae8ee8a18b7539b5658f9b4cc24de95dd18ad',
|
id: 'cee709223217281d7893b650850ae8ee8a18b7539b5658f9b4cc24de95dd18ad',
|
||||||
name: 'tBTC TEST',
|
name: 'tBTC TEST',
|
||||||
@ -1252,7 +1252,7 @@ const proposalListFields: ProposalListFieldsFragment[] = [
|
|||||||
instrument: {
|
instrument: {
|
||||||
code: 'UNIDAI.MF21',
|
code: 'UNIDAI.MF21',
|
||||||
name: 'UNIDAI Monthly (Dec 2022)',
|
name: 'UNIDAI Monthly (Dec 2022)',
|
||||||
futureProduct: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
id: 'b340c130096819428a62e5df407fd6abe66e444b89ad64f670beb98621c9c663',
|
||||||
name: 'tDAI TEST',
|
name: 'tDAI TEST',
|
||||||
|
Loading…
Reference in New Issue
Block a user