Merge branch 'develop' of github.com:vegaprotocol/frontend-monorepo into develop

This commit is contained in:
Madalina Raicu
2022-11-11 10:44:16 +00:00
302 changed files with 5042 additions and 3951 deletions
@@ -28,7 +28,7 @@ on:
default: false
env:
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.58.0'
VEGA_VERSION: 'v0.62.0'
jobs:
manual:
@@ -58,3 +58,4 @@ jobs:
gobin: ${{needs.manual.outputs.gobin}}
skip-cache: ${{needs.manual.outputs.skip-cache}}
tags: ${{needs.manual.outputs.tags}}
capsule-teardown: false
@@ -13,7 +13,8 @@ jobs:
secrets: inherit
with:
project: '[console-lite-e2e, explorer-e2e, liquidity-provision-dashboard-e2e, stats-e2e, token-e2e, trading-e2e]'
vega-version: 'v0.58.0'
vega-version: 'v0.62.0'
gobin: /home/runner/go/bin
tags: --env.grepTags '[ @smoke, @regression, @slow ]'
night-run: true
capsule-teardown: false
+1 -1
View File
@@ -14,7 +14,7 @@ on:
env:
GOBIN: /home/runner/go/bin
VEGA_VERSION: 'v0.58.0'
VEGA_VERSION: 'v0.62.0'
jobs:
pr:
+5 -1
View File
@@ -24,6 +24,10 @@ on:
required: false
type: boolean
default: false
capsule-teardown:
required: false
type: boolean
default: false
jobs:
explorer-e2e:
@@ -99,7 +103,7 @@ jobs:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: false
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
######
+5 -1
View File
@@ -20,6 +20,10 @@ on:
tags:
required: false
type: string
capsule-teardown:
required: false
type: boolean
default: false
jobs:
token-e2e:
@@ -95,7 +99,7 @@ jobs:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: false
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS: ${{ inputs.capsule-teardown }}
######
## Upload logs
+5
View File
@@ -20,6 +20,9 @@ on:
night-run:
required: false
type: boolean
capsule-teardown:
required: false
type: boolean
jobs:
run-console-lite-e2e:
@@ -42,6 +45,7 @@ jobs:
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
night-run: ${{ inputs.night-run }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-liquidity-e2e:
uses: ./.github/workflows/cypress-liquidity-provision-dashboard-e2e.yml
@@ -64,6 +68,7 @@ jobs:
gobin: ${{ inputs.gobin }}
skip-cache: ${{ inputs.skip-cache }}
tags: ${{ inputs.tags }}
capsule-teardown: ${{ inputs.capsule-teardown }}
run-trading-e2e:
uses: ./.github/workflows/cypress-trading-e2e.yml
@@ -138,7 +138,7 @@ export const singleMarket: SingleMarketFieldsFragment = {
id: 'dai-id',
name: 'DAI Name',
},
oracleSpecForTradingTermination: {
dataSourceSpecForTradingTermination: {
id: 'oid',
},
},
+3 -3
View File
@@ -17,9 +17,9 @@ NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
NX_URL=$URL
NX_DEPLOY_URL=$DEPLOY_URL
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/testnet-network.json"
NX_VEGA_ENV = 'TESTNET'
NX_VEGA_URL="https://api.n11.testnet.vega.xyz/graphql"
NX_VEGA_CONFIG_URL="https://static.vega.xyz/assets/stagnet3-network.json"
NX_VEGA_ENV=STAGNET3
NX_VEGA_URL="https://api.n01.stagnet3.vega.xyz/graphql"
NX_VEGA_WALLET_URL=http://localhost:1789
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
+26 -2
View File
@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { createClient } from './lib/apollo-client';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
@@ -16,6 +15,7 @@ import Header from './components/header';
import { Main } from './components/main';
import LocalContext from './context/local-context';
import useLocalValues from './hooks/use-local-values';
import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const [theme, toggleTheme] = useThemeSwitcher();
@@ -30,10 +30,34 @@ function App() {
setMenuOpen(false);
}, [location, setMenuOpen]);
const cacheConfig: InMemoryCacheConfig = {
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
};
return (
<EnvironmentProvider>
<ThemeContext.Provider value={theme}>
<NetworkLoader createClient={createClient}>
<NetworkLoader cache={cacheConfig}>
<VegaWalletProvider>
<LocalContext.Provider value={localValues}>
<AppLoader>
@@ -1,88 +0,0 @@
import {
ApolloClient,
from,
HttpLink,
InMemoryCache,
split,
} from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient as createWSClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const wsLink = new GraphQLWsLink(
createWSClient({
url: urlWS.href,
})
);
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink
);
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, splitLink]),
cache,
});
}
+3 -3
View File
@@ -1,10 +1,10 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
NX_TENDERMINT_URL=https://be.explorer.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://be.explorer.vega.xyz
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/mainnet-network.json
NX_VEGA_URL=https://api.vega.xyz/query
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
NX_VEGA_ENV=MAINNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_BLOCK_EXPLORER=
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest/
+10 -2
View File
@@ -9,12 +9,12 @@ import {
useEnvironment,
} from '@vegaprotocol/environment';
import { NetworkInfo } from '@vegaprotocol/network-info';
import { createClient } from './lib/apollo-client';
import { Nav } from './components/nav';
import { Header } from './components/header';
import { Main } from './components/main';
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
import { ENV } from './config/env';
import type { InMemoryCacheConfig } from '@apollo/client';
function App() {
const { VEGA_ENV } = useEnvironment();
@@ -36,10 +36,18 @@ function App() {
});
}, [VEGA_ENV]);
const cacheConfig: InMemoryCacheConfig = {
typePolicies: {
Node: {
keyFields: false,
},
},
};
return (
<ThemeContext.Provider value={theme}>
<TendermintWebsocketProvider>
<NetworkLoader createClient={createClient}>
<NetworkLoader cache={cacheConfig}>
<div
className={`${
menuOpen && 'h-[100vh] overflow-hidden'
+15 -6
View File
@@ -17,17 +17,26 @@ export interface IUseTxsData {
filters?: string;
}
export const getTxsDataUrl = ({ limit = 10, filters = '' }) => {
let url = `${DATA_SOURCES.blockExplorerUrl}/transactions?limit=${limit}`;
interface IGetTxsDataUrl {
limit?: string;
filters?: string;
}
export const getTxsDataUrl = ({ limit, filters }: IGetTxsDataUrl) => {
const url = new URL(`${DATA_SOURCES.blockExplorerUrl}/transactions`);
if (limit) {
url.searchParams.append('limit', limit);
}
if (filters) {
url = `${url}&${filters}`;
url.searchParams.append('filters', filters);
}
return url;
};
export const useTxsData = ({ limit = 10, filters }: IUseTxsData) => {
export const useTxsData = ({ limit, filters }: IUseTxsData) => {
const [{ txsData, hasMoreTxs, lastCursor }, setTxsState] =
useState<TxsStateProps>({
txsData: [],
@@ -35,12 +44,12 @@ export const useTxsData = ({ limit = 10, filters }: IUseTxsData) => {
lastCursor: '',
});
const url = getTxsDataUrl({ limit, filters });
const url = getTxsDataUrl({ limit: limit?.toString(), filters });
const {
state: { data, error, loading },
refetch,
} = useFetch<BlockExplorerTransactions>(url, {}, false);
} = useFetch<BlockExplorerTransactions>(url.href, {}, false);
useEffect(() => {
if (data?.transactions?.length) {
@@ -1,52 +0,0 @@
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}
@@ -1,27 +0,0 @@
query AssetsQuery {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
... on BuiltinAsset {
maxFaucetAmountMint
}
}
infrastructureFeeAccount {
type
balance
market {
id
}
}
}
}
}
}
@@ -1,67 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type AssetsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type AssetsQueryQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string }, infrastructureFeeAccount?: { __typename?: 'AccountBalance', type: Types.AccountType, balance: string, market?: { __typename?: 'Market', id: string } | null } | null } } | null> | null } | null };
export const AssetsQueryDocument = gql`
query AssetsQuery {
assetsConnection {
edges {
node {
id
name
symbol
decimals
source {
... on ERC20 {
contractAddress
}
... on BuiltinAsset {
maxFaucetAmountMint
}
}
infrastructureFeeAccount {
type
balance
market {
id
}
}
}
}
}
}
`;
/**
* __useAssetsQueryQuery__
*
* To run a query within a React component, call `useAssetsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useAssetsQueryQuery` 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 } = useAssetsQueryQuery({
* variables: {
* },
* });
*/
export function useAssetsQueryQuery(baseOptions?: Apollo.QueryHookOptions<AssetsQueryQuery, AssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<AssetsQueryQuery, AssetsQueryQueryVariables>(AssetsQueryDocument, options);
}
export function useAssetsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AssetsQueryQuery, AssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<AssetsQueryQuery, AssetsQueryQueryVariables>(AssetsQueryDocument, options);
}
export type AssetsQueryQueryHookResult = ReturnType<typeof useAssetsQueryQuery>;
export type AssetsQueryLazyQueryHookResult = ReturnType<typeof useAssetsQueryLazyQuery>;
export type AssetsQueryQueryResult = Apollo.QueryResult<AssetsQueryQuery, AssetsQueryQueryVariables>;
@@ -1,74 +0,0 @@
query ProposalsQuery {
proposals {
id
reference
state
datetime
rejectionReason
party {
id
}
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
}
... on UpdateMarket {
marketId
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
}
... on ERC20 {
contractAddress
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
votes {
yes {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
no {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
}
}
}
@@ -1,114 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ProposalsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ProposalsQueryQuery = { __typename?: 'Query', proposals?: Array<{ __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', symbol: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string } } }> | null } } }> | null };
export const ProposalsQueryDocument = gql`
query ProposalsQuery {
proposals {
id
reference
state
datetime
rejectionReason
party {
id
}
terms {
closingDatetime
enactmentDatetime
change {
... on NewMarket {
instrument {
name
}
}
... on UpdateMarket {
marketId
}
... on NewAsset {
__typename
symbol
source {
... on BuiltinAsset {
maxFaucetAmountMint
}
... on ERC20 {
contractAddress
}
}
}
... on UpdateNetworkParameter {
networkParameter {
key
value
}
}
}
}
votes {
yes {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
no {
totalTokens
totalNumber
votes {
value
party {
id
stakingSummary {
currentStakeAvailable
}
}
datetime
}
}
}
}
}
`;
/**
* __useProposalsQueryQuery__
*
* To run a query within a React component, call `useProposalsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useProposalsQueryQuery` 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 } = useProposalsQueryQuery({
* variables: {
* },
* });
*/
export function useProposalsQueryQuery(baseOptions?: Apollo.QueryHookOptions<ProposalsQueryQuery, ProposalsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ProposalsQueryQuery, ProposalsQueryQueryVariables>(ProposalsQueryDocument, options);
}
export function useProposalsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ProposalsQueryQuery, ProposalsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ProposalsQueryQuery, ProposalsQueryQueryVariables>(ProposalsQueryDocument, options);
}
export type ProposalsQueryQueryHookResult = ReturnType<typeof useProposalsQueryQuery>;
export type ProposalsQueryLazyQueryHookResult = ReturnType<typeof useProposalsQueryLazyQuery>;
export type ProposalsQueryQueryResult = Apollo.QueryResult<ProposalsQueryQuery, ProposalsQueryQueryVariables>;
@@ -1,133 +0,0 @@
query MarketsQuery {
markets {
id
fees {
factors {
makerFee
infrastructureFee
liquidityFee
}
}
tradableInstrument {
instrument {
name
metadata {
tags
}
id
code
product {
... on Future {
settlementAsset {
id
name
decimals
globalRewardPoolAccount {
balance
}
}
}
}
}
riskModel {
... on LogNormalRiskModel {
tau
riskAversionParameter
params {
r
sigma
mu
}
}
... on SimpleRiskModel {
params {
factorLong
factorShort
}
}
}
marginCalculator {
scalingFactors {
searchLevel
initialMargin
collateralRelease
}
}
}
decimalPlaces
openingAuction {
durationSecs
volume
}
priceMonitoringSettings {
parameters {
triggers {
horizonSecs
probability
auctionExtensionSecs
}
}
}
liquidityMonitoringParameters {
triggeringRatio
targetStakeParameters {
timeWindow
scalingFactor
}
}
tradingMode
state
proposal {
id
}
state
accounts {
asset {
id
name
}
balance
type
}
data {
markPrice
bestBidPrice
bestBidVolume
bestOfferPrice
bestOfferVolume
bestStaticBidPrice
bestStaticBidVolume
bestStaticOfferPrice
bestStaticOfferVolume
midPrice
staticMidPrice
timestamp
openInterest
auctionEnd
auctionStart
indicativePrice
indicativeVolume
trigger
extensionTrigger
targetStake
suppliedStake
priceMonitoringBounds {
minValidPrice
maxValidPrice
trigger {
auctionExtensionSecs
probability
}
referencePrice
}
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
@@ -1,173 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketsQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type MarketsQueryQuery = { __typename?: 'Query', markets?: Array<{ __typename?: 'Market', id: string, decimalPlaces: number, tradingMode: Types.MarketTradingMode, state: Types.MarketState, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, id: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', settlementAsset: { __typename?: 'Asset', id: string, name: string, decimals: number, globalRewardPoolAccount?: { __typename?: 'AccountBalance', balance: string } | null } } }, riskModel: { __typename?: 'LogNormalRiskModel', tau: number, riskAversionParameter: number, params: { __typename?: 'LogNormalModelParams', r: number, sigma: number, mu: number } } | { __typename?: 'SimpleRiskModel', params: { __typename?: 'SimpleRiskModelParams', factorLong: number, factorShort: number } }, marginCalculator?: { __typename?: 'MarginCalculator', scalingFactors: { __typename?: 'ScalingFactors', searchLevel: number, initialMargin: number, collateralRelease: number } } | null }, openingAuction: { __typename?: 'AuctionDuration', durationSecs: number, volume: number }, priceMonitoringSettings: { __typename?: 'PriceMonitoringSettings', parameters?: { __typename?: 'PriceMonitoringParameters', triggers?: Array<{ __typename?: 'PriceMonitoringTrigger', horizonSecs: number, probability: number, auctionExtensionSecs: number }> | null } | null }, liquidityMonitoringParameters: { __typename?: 'LiquidityMonitoringParameters', triggeringRatio: number, targetStakeParameters: { __typename?: 'TargetStakeParameters', timeWindow: number, scalingFactor: number } }, proposal?: { __typename?: 'Proposal', id?: string | null } | null, accounts?: Array<{ __typename?: 'AccountBalance', balance: string, type: Types.AccountType, asset: { __typename?: 'Asset', id: string, name: string } }> | null, data?: { __typename?: 'MarketData', markPrice: string, bestBidPrice: string, bestBidVolume: string, bestOfferPrice: string, bestOfferVolume: string, bestStaticBidPrice: string, bestStaticBidVolume: string, bestStaticOfferPrice: string, bestStaticOfferVolume: string, midPrice: string, staticMidPrice: string, timestamp: string, openInterest: string, auctionEnd?: string | null, auctionStart?: string | null, indicativePrice: string, indicativeVolume: string, trigger: Types.AuctionTrigger, extensionTrigger: Types.AuctionTrigger, targetStake?: string | null, suppliedStake?: string | null, marketValueProxy: string, priceMonitoringBounds?: Array<{ __typename?: 'PriceMonitoringBounds', minValidPrice: string, maxValidPrice: string, referencePrice: string, trigger: { __typename?: 'PriceMonitoringTrigger', auctionExtensionSecs: number, probability: number } }> | null, liquidityProviderFeeShare?: Array<{ __typename?: 'LiquidityProviderFeeShare', equityLikeShare: string, averageEntryValuation: string, party: { __typename?: 'Party', id: string } }> | null } | null }> | null };
export const MarketsQueryDocument = gql`
query MarketsQuery {
markets {
id
fees {
factors {
makerFee
infrastructureFee
liquidityFee
}
}
tradableInstrument {
instrument {
name
metadata {
tags
}
id
code
product {
... on Future {
settlementAsset {
id
name
decimals
globalRewardPoolAccount {
balance
}
}
}
}
}
riskModel {
... on LogNormalRiskModel {
tau
riskAversionParameter
params {
r
sigma
mu
}
}
... on SimpleRiskModel {
params {
factorLong
factorShort
}
}
}
marginCalculator {
scalingFactors {
searchLevel
initialMargin
collateralRelease
}
}
}
decimalPlaces
openingAuction {
durationSecs
volume
}
priceMonitoringSettings {
parameters {
triggers {
horizonSecs
probability
auctionExtensionSecs
}
}
}
liquidityMonitoringParameters {
triggeringRatio
targetStakeParameters {
timeWindow
scalingFactor
}
}
tradingMode
state
proposal {
id
}
state
accounts {
asset {
id
name
}
balance
type
}
data {
markPrice
bestBidPrice
bestBidVolume
bestOfferPrice
bestOfferVolume
bestStaticBidPrice
bestStaticBidVolume
bestStaticOfferPrice
bestStaticOfferVolume
midPrice
staticMidPrice
timestamp
openInterest
auctionEnd
auctionStart
indicativePrice
indicativeVolume
trigger
extensionTrigger
targetStake
suppliedStake
priceMonitoringBounds {
minValidPrice
maxValidPrice
trigger {
auctionExtensionSecs
probability
}
referencePrice
}
marketValueProxy
liquidityProviderFeeShare {
party {
id
}
equityLikeShare
averageEntryValuation
}
}
}
}
`;
/**
* __useMarketsQueryQuery__
*
* To run a query within a React component, call `useMarketsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useMarketsQueryQuery` 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 } = useMarketsQueryQuery({
* variables: {
* },
* });
*/
export function useMarketsQueryQuery(baseOptions?: Apollo.QueryHookOptions<MarketsQueryQuery, MarketsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<MarketsQueryQuery, MarketsQueryQueryVariables>(MarketsQueryDocument, options);
}
export function useMarketsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketsQueryQuery, MarketsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<MarketsQueryQuery, MarketsQueryQueryVariables>(MarketsQueryDocument, options);
}
export type MarketsQueryQueryHookResult = ReturnType<typeof useMarketsQueryQuery>;
export type MarketsQueryLazyQueryHookResult = ReturnType<typeof useMarketsQueryLazyQuery>;
export type MarketsQueryQueryResult = Apollo.QueryResult<MarketsQueryQuery, MarketsQueryQueryVariables>;
@@ -1,26 +0,0 @@
query OracleSpecs {
oracleSpecsConnection {
edges {
node {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
}
}
data {
pubKeys
}
}
}
}
}
@@ -3,25 +3,13 @@
// @generated
// This file was automatically generated and should not be edited.
import { OracleSpecStatus, PropertyKeyType, ConditionOperator } from "@vegaprotocol/types";
import { DataSourceSpecStatus, ConditionOperator, PropertyKeyType } from "@vegaprotocol/types";
// ====================================================
// GraphQL query operation: OracleSpecs
// ====================================================
export interface OracleSpecs_oracleSpecs_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface OracleSpecs_oracleSpecs_filters_conditions {
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The value to compare against.
@@ -33,35 +21,101 @@ export interface OracleSpecs_oracleSpecs_filters_conditions {
operator: ConditionOperator;
}
export interface OracleSpecs_oracleSpecs_filters {
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export type OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress | OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey;
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The value to compare against.
*/
value: string | null;
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
* key is the data source data property key targeted by the filter.
*/
key: OracleSpecs_oracleSpecs_filters_key;
key: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: OracleSpecs_oracleSpecs_filters_conditions[] | null;
conditions: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface OracleSpecs_oracleSpecs_data {
__typename: "OracleData";
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* The list of public keys that signed the data
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
pubKeys: string[] | null;
signers: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface OracleSpecs_oracleSpecs {
__typename: "OracleSpec";
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType = OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionInternal | OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType_DataSourceDefinitionExternal;
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec_data {
__typename: "DataSourceDefinition";
sourceType: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data_sourceType;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec_spec {
__typename: "DataSourceSpec";
/**
* Status describes the status of the oracle spec
*/
status: OracleSpecStatus;
/**
* ID is a hash generated from the OracleSpec data.
* ID is a hash generated from the DataSourceSpec data.
*/
id: string;
/**
@@ -73,20 +127,102 @@ export interface OracleSpecs_oracleSpecs {
*/
updatedAt: string | null;
/**
* The list of authorized public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
* Status describes the status of the data source spec
*/
pubKeys: string[] | null;
status: DataSourceSpecStatus;
data: OracleSpecs_oracleSpecs_dataSourceSpec_spec_data;
}
export interface OracleSpecs_oracleSpecs_dataSourceSpec {
__typename: "ExternalDataSourceSpec";
spec: OracleSpecs_oracleSpecs_dataSourceSpec_spec;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export type OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer = OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_ETHAddress | OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer_PubKey;
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers {
__typename: "Signer";
signer: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers_signer;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_data {
__typename: "Property";
/**
* Filters describes which oracle data are considered of interest or not for
* the product (or the risk model).
* Name of the property
*/
filters: OracleSpecs_oracleSpecs_filters[] | null;
name: string;
/**
* Value of the property
*/
value: string;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data {
__typename: "Data";
/**
* signers is the list of public keys/ETH addresses that signed the data
*/
signers: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_signers[] | null;
/**
* properties contains all the properties sent by a data source
*/
data: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data_data[] | null;
/**
* List of all the data specs that matched this source data.
* When the array is empty, it means no data spec matched this source data.
*/
matchedSpecIds: string[] | null;
/**
* RFC3339Nano formatted date and time for when the data was broadcast to the markets
* with a matching data spec.
* It has no value when the source data does not match any data spec.
*/
broadcastAt: string;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData {
__typename: "ExternalData";
data: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData_data;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges_node {
__typename: "OracleData";
externalData: OracleSpecs_oracleSpecs_dataConnection_edges_node_externalData;
}
export interface OracleSpecs_oracleSpecs_dataConnection_edges {
__typename: "OracleDataEdge";
/**
* The oracle data source
*/
node: OracleSpecs_oracleSpecs_dataConnection_edges_node;
}
export interface OracleSpecs_oracleSpecs_dataConnection {
__typename: "OracleDataConnection";
/**
* The oracle data spec
*/
edges: (OracleSpecs_oracleSpecs_dataConnection_edges | null)[] | null;
}
export interface OracleSpecs_oracleSpecs {
__typename: "OracleSpec";
dataSourceSpec: OracleSpecs_oracleSpecs_dataSourceSpec;
/**
* Data list all the oracle data broadcast to this spec
*/
data: OracleSpecs_oracleSpecs_data[];
dataConnection: OracleSpecs_oracleSpecs_dataConnection;
}
export interface OracleSpecs {
@@ -1,66 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type OracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type OracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', status: Types.OracleSpecStatus, id: string, createdAt: string, updatedAt?: string | null, pubKeys?: Array<string> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null, data: Array<{ __typename?: 'OracleData', pubKeys?: Array<string> | null }> } } | null> | null } | null };
export const OracleSpecsDocument = gql`
query OracleSpecs {
oracleSpecsConnection {
edges {
node {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
}
}
data {
pubKeys
}
}
}
}
}
`;
/**
* __useOracleSpecsQuery__
*
* To run a query within a React component, call `useOracleSpecsQuery` and pass it any options that fit your needs.
* When your component renders, `useOracleSpecsQuery` 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 } = useOracleSpecsQuery({
* variables: {
* },
* });
*/
export function useOracleSpecsQuery(baseOptions?: Apollo.QueryHookOptions<OracleSpecsQuery, OracleSpecsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<OracleSpecsQuery, OracleSpecsQueryVariables>(OracleSpecsDocument, options);
}
export function useOracleSpecsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<OracleSpecsQuery, OracleSpecsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<OracleSpecsQuery, OracleSpecsQueryVariables>(OracleSpecsDocument, options);
}
export type OracleSpecsQueryHookResult = ReturnType<typeof useOracleSpecsQuery>;
export type OracleSpecsLazyQueryHookResult = ReturnType<typeof useOracleSpecsLazyQuery>;
export type OracleSpecsQueryResult = Apollo.QueryResult<OracleSpecsQuery, OracleSpecsQueryVariables>;
+80 -21
View File
@@ -11,23 +11,79 @@ import { SubHeading } from '../../components/sub-heading';
const ORACLE_SPECS_QUERY = gql`
query OracleSpecs {
oracleSpecs {
status
id
createdAt
updatedAt
pubKeys
filters {
key {
name
type
}
conditions {
value
operator
dataSourceSpec {
spec {
id
createdAt
updatedAt
status
data {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
value
operator
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
filters {
key {
name
type
}
conditions {
value
operator
}
}
}
}
}
}
}
}
}
data {
pubKeys
dataConnection {
edges {
node {
externalData {
data {
signers {
signer {
... on ETHAddress {
address
}
... on PubKey {
key
}
}
}
data {
name
value
}
matchedSpecIds
broadcastAt
}
}
}
}
}
}
}
@@ -53,12 +109,15 @@ const Oracles = () => {
<section>
<RouteTitle data-testid="oracle-specs-heading">{t('Oracles')}</RouteTitle>
{data?.oracleSpecs
? data.oracleSpecs.map((o) => (
<React.Fragment key={o.id}>
<SubHeading id={o.id.toString()}>{o.id}</SubHeading>
<SyntaxHighlighter data={o} />
</React.Fragment>
))
? data.oracleSpecs.map((o) => {
const id = o.dataSourceSpec.spec.id;
return (
<React.Fragment key={id}>
<SubHeading id={id.toString()}>{id}</SubHeading>
<SyntaxHighlighter data={o} />
</React.Fragment>
);
})
: null}
</section>
);
@@ -1,32 +0,0 @@
query PartyAssetsQuery($partyId: ID!) {
party(id: $partyId) {
id
delegations {
amount
node {
id
name
}
epoch
}
stakingSummary {
currentStakeAvailable
}
accounts {
asset {
name
id
decimals
symbol
source {
__typename
... on ERC20 {
contractAddress
}
}
}
type
balance
}
}
}
@@ -1,75 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type PartyAssetsQueryQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
}>;
export type PartyAssetsQueryQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, delegations?: Array<{ __typename?: 'Delegation', amount: string, epoch: number, node: { __typename?: 'Node', id: string, name: string } }> | null, stakingSummary: { __typename?: 'StakingSummary', currentStakeAvailable: string }, accounts?: Array<{ __typename?: 'AccountBalance', type: Types.AccountType, balance: string, asset: { __typename?: 'Asset', name: string, id: string, decimals: number, symbol: string, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string } } }> | null } | null };
export const PartyAssetsQueryDocument = gql`
query PartyAssetsQuery($partyId: ID!) {
party(id: $partyId) {
id
delegations {
amount
node {
id
name
}
epoch
}
stakingSummary {
currentStakeAvailable
}
accounts {
asset {
name
id
decimals
symbol
source {
__typename
... on ERC20 {
contractAddress
}
}
}
type
balance
}
}
}
`;
/**
* __usePartyAssetsQueryQuery__
*
* To run a query within a React component, call `usePartyAssetsQueryQuery` and pass it any options that fit your needs.
* When your component renders, `usePartyAssetsQueryQuery` 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 } = usePartyAssetsQueryQuery({
* variables: {
* partyId: // value for 'partyId'
* },
* });
*/
export function usePartyAssetsQueryQuery(baseOptions: Apollo.QueryHookOptions<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>(PartyAssetsQueryDocument, options);
}
export function usePartyAssetsQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>(PartyAssetsQueryDocument, options);
}
export type PartyAssetsQueryQueryHookResult = ReturnType<typeof usePartyAssetsQueryQuery>;
export type PartyAssetsQueryLazyQueryHookResult = ReturnType<typeof usePartyAssetsQueryLazyQuery>;
export type PartyAssetsQueryQueryResult = Apollo.QueryResult<PartyAssetsQueryQuery, PartyAssetsQueryQueryVariables>;
@@ -4,7 +4,7 @@ import { BlocksRefetch } from '../../../components/blocks';
import { TxsInfiniteList, TxsStatsInfo } from '../../../components/txs';
import { useTxsData } from '../../../hooks/use-txs-data';
const BE_TXS_PER_REQUEST = 100;
const BE_TXS_PER_REQUEST = 20;
export const TxsList = () => {
const { hasMoreTxs, loadTxs, error, txsData, refreshTxs, loading } =
@@ -1,22 +0,0 @@
query NodesQuery {
nodes {
id
name
infoUrl
avatarUrl
pubkey
tmPubkey
ethereumAddress
location
stakedByOperator
stakedByDelegates
stakedTotal
pendingStake
epochData {
total
offline
online
}
status
}
}
@@ -1,62 +0,0 @@
import { Schema as Types } from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type NodesQueryQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type NodesQueryQuery = { __typename?: 'Query', nodes?: Array<{ __typename?: 'Node', id: string, name: string, infoUrl: string, avatarUrl?: string | null, pubkey: string, tmPubkey: string, ethereumAddress: string, location: string, stakedByOperator: string, stakedByDelegates: string, stakedTotal: string, pendingStake: string, status: Types.NodeStatus, epochData?: { __typename?: 'EpochData', total: number, offline: number, online: number } | null }> | null };
export const NodesQueryDocument = gql`
query NodesQuery {
nodes {
id
name
infoUrl
avatarUrl
pubkey
tmPubkey
ethereumAddress
location
stakedByOperator
stakedByDelegates
stakedTotal
pendingStake
epochData {
total
offline
online
}
status
}
}
`;
/**
* __useNodesQueryQuery__
*
* To run a query within a React component, call `useNodesQueryQuery` and pass it any options that fit your needs.
* When your component renders, `useNodesQueryQuery` 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 } = useNodesQueryQuery({
* variables: {
* },
* });
*/
export function useNodesQueryQuery(baseOptions?: Apollo.QueryHookOptions<NodesQueryQuery, NodesQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<NodesQueryQuery, NodesQueryQueryVariables>(NodesQueryDocument, options);
}
export function useNodesQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<NodesQueryQuery, NodesQueryQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<NodesQueryQuery, NodesQueryQueryVariables>(NodesQueryDocument, options);
}
export type NodesQueryQueryHookResult = ReturnType<typeof useNodesQueryQuery>;
export type NodesQueryLazyQueryHookResult = ReturnType<typeof useNodesQueryLazyQuery>;
export type NodesQueryQueryResult = Apollo.QueryResult<NodesQueryQuery, NodesQueryQueryVariables>;
+2 -2
View File
@@ -20,7 +20,7 @@
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
<script src="./assets/env-config.js"></script>
</head>
<body>
<div id="root"></div>
<body class="dark:bg-black h-full w-full">
<div id="root" class="h-full w-full"></div>
</body>
</html>
@@ -1,14 +1,17 @@
import { useRoutes } from 'react-router-dom';
import '../styles.scss';
import { Header } from './components/header';
import { Intro } from './components/intro';
import { MarketList } from './components/market-list';
import { Navbar } from './components/navbar';
import { routerConfig } from './routes/router-config';
const AppRouter = () => useRoutes(routerConfig);
export function App() {
return (
<div className="max-h-full min-h-full bg-white">
<Header />
<Intro />
<MarketList />
<Navbar />
<AppRouter />
</div>
);
}
@@ -0,0 +1,25 @@
import { t } from '@vegaprotocol/react-helpers';
import { Intro } from './intro';
import { MarketList } from './market-list';
export function Dashboard() {
return (
<>
<div className="px-16 pt-20 pb-12 bg-greys-light-100">
<div className="max-w-screen-xl mx-auto">
<h1 className="font-alpha uppercase text-5xl mb-8">
{t('Top liquidity opportunities')}
</h1>
<Intro />
</div>
</div>
<div className="px-16 py-6">
<div className="max-w-screen-xl mx-auto">
<MarketList />
</div>
</div>
</>
);
}
@@ -0,0 +1 @@
export * from './dashboard';
@@ -5,19 +5,19 @@ import { ExternalLink } from '@vegaprotocol/ui-toolkit';
const LINKS = {
testnet: [
{
label: 'Understand how liquidity fees are calculated',
url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#resources',
label: 'Learn about liquidity fees',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#resources',
},
{
label: 'How to provide liquidity',
url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#overview',
label: 'Provide liquidity',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#overview',
},
{
label: 'How to view existing liquidity provisions',
url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#viewing-existing-liquidity-provisions',
label: 'View your liquidity provisions',
url: 'https://docs.vega.xyz/docs/testnet/tutorials/providing-liquidity#viewing-existing-liquidity-provisions',
},
{
label: 'How to amend or remove liquidity',
label: 'Amend or remove liquidity',
url: 'https://docs.vega.xyz/testnet/tutorials/providing-liquidity#amending-a-liquidity-commitment',
},
],
@@ -29,12 +29,11 @@ type Network = 'testnet' | 'mainnet';
export const Intro = ({ network = 'testnet' }: { network?: Network }) => {
return (
<div className="mx-6 my-6 px-6 py-6 bg-neutral-100" data-testid="intro">
<h2 className="text-xl font-medium mb-1">
{t('Become a liquidity provider')}
</h2>
<p className="text-base mb-2">
{t('Earn a cut of the fees paid by price takers during trading.')}
<div>
<p className="font-alpha text-2xl font-medium mb-2">
{t(
'Become a liquidity provider and earn a cut of the fees paid during trading.'
)}
</p>
<div>
<ul className="flex flex-wrap">
@@ -0,0 +1,171 @@
import { useCallback, useState } from 'react';
import { AgGridColumn } from 'ag-grid-react';
import type {
ValueFormatterParams,
GetRowIdParams,
RowClickedEvent,
} from 'ag-grid-community';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { Icon, AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { Market } from '@vegaprotocol/liquidity';
import {
useMarketsLiquidity,
formatWithAsset,
displayChange,
} from '@vegaprotocol/liquidity';
import type { MarketTradingMode } from '@vegaprotocol/types';
import { HealthBar } from '../../health-bar';
import { Grid } from '../../grid';
import { HealthDialog } from '../../health-dialog';
import { Status } from '../../status';
export const MarketList = () => {
const { data, error, loading } = useMarketsLiquidity();
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
const localData = data?.markets;
return (
<AsyncRenderer loading={loading} error={error} data={localData}>
<div
className="grow w-full"
style={{ minHeight: 500, overflow: 'hidden' }}
>
<Grid
gridOptions={{
onRowClicked: ({ data }: RowClickedEvent) => {
window.open(
`/markets/${data.id}`,
'_blank',
'noopener,noreferrer'
);
},
}}
rowData={localData}
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
isRowClickable
>
<AgGridColumn
headerName={t('Market (futures)')}
field="tradableInstrument.instrument.name"
cellRenderer={({
value,
data,
}: {
value: string;
data: Market;
}) => {
return (
<>
<span className="leading-3">{value}</span>
<span className="leading-3">
{
data?.tradableInstrument?.instrument?.product
?.settlementAsset?.symbol
}
</span>
</>
);
}}
minWidth={100}
flex="1"
/>
<AgGridColumn
headerName={t('Volume (24h)')}
field="dayVolume"
valueFormatter={({ value, data }: ValueFormatterParams) =>
`${addDecimalsFormatNumber(
value,
data.tradableInstrument.instrument.product.settlementAsset
.decimals
)} (${displayChange(data.volumeChange)})`
}
/>
<AgGridColumn
headerName={t('Committed bond/stake')}
field="liquidityCommitted"
valueFormatter={({ value, data }: ValueFormatterParams) =>
formatWithAsset(
value,
data.tradableInstrument.instrument.product.settlementAsset
)
}
/>
<AgGridColumn
headerName={t('Status')}
field="tradingMode"
cellRenderer={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return (
<Status trigger={data.data?.trigger} tradingMode={value} />
);
}}
/>
<AgGridColumn
headerComponent={() => {
return (
<div>
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
>
<Icon name="info-sign" />
</button>
</div>
);
}}
field="tradingMode"
cellRenderer={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => (
<HealthBar
status={value}
target={data.target}
decimals={
data.tradableInstrument.instrument.product.settlementAsset
.decimals
}
levels={data.feeLevels}
/>
)}
sortable={false}
cellStyle={{ overflow: 'unset' }}
/>
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
</Grid>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
</AsyncRenderer>
);
};
@@ -0,0 +1,107 @@
import { useParams } from 'react-router-dom';
import { useMemo } from 'react';
import {
t,
useDataProvider,
makeDerivedDataProvider,
} from '@vegaprotocol/react-helpers';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import {
getFeeLevels,
sumLiquidityCommitted,
marketLiquidityDataProvider,
lpAggregatedDataProvider,
} from '@vegaprotocol/liquidity';
import type { MarketLpQuery } from '@vegaprotocol/liquidity';
import { Market } from './market';
import { Header } from './header';
import { LPProvidersGrid } from './providers';
const formatMarket = (data: MarketLpQuery) => {
return {
name: data?.market?.tradableInstrument.instrument.name,
symbol:
data?.market?.tradableInstrument.instrument.product.settlementAsset
.symbol,
settlementAsset:
data?.market?.tradableInstrument.instrument.product.settlementAsset,
targetStake: data?.market?.data?.targetStake,
tradingMode: data?.market?.data?.marketTradingMode,
trigger: data?.market?.data?.trigger,
};
};
export const lpDataProvider = makeDerivedDataProvider(
[marketLiquidityDataProvider, lpAggregatedDataProvider],
([market, lpAggregatedData]) => ({
market: { ...formatMarket(market) },
liquidityProviders: lpAggregatedData || [],
})
);
const useMarketDetails = (marketId: string | undefined) => {
const { data, loading, error } = useDataProvider({
dataProvider: lpDataProvider,
noUpdate: true,
variables: useMemo(() => ({ marketId }), [marketId]),
});
const liquidityProviders = data?.liquidityProviders || [];
return {
data: {
name: data?.market?.name,
symbol: data?.market?.symbol,
liquidityProviders: liquidityProviders,
feeLevels: getFeeLevels(liquidityProviders),
comittedLiquidity: sumLiquidityCommitted(liquidityProviders) || 0,
settlementAsset: data?.market?.settlementAsset || {},
targetStake: data?.market?.targetStake || '0',
tradingMode: data?.market.tradingMode,
},
error,
loading: loading,
};
};
export const Detail = () => {
const { marketId } = useParams<{ marketId: string }>();
const { data, loading, error } = useMarketDetails(marketId);
return (
<AsyncRenderer loading={loading} error={error} data={data}>
<div className="px-16 pt-14 pb-12 bg-greys-light-100">
<div className="max-w-screen-xl mx-auto">
<Header name={data.name} symbol={data.symbol} />
</div>
</div>
<div className="px-16">
<div className="max-w-screen-xl mx-auto">
<div className="py-12">
{marketId && (
<Market
marketId={marketId}
feeLevels={data.feeLevels}
comittedLiquidity={data.comittedLiquidity}
settlementAsset={data.settlementAsset}
targetStake={data.targetStake}
tradingMode={data.tradingMode}
/>
)}
</div>
<div>
<h2 className="font-alpha text-2xl mb-4">
{t('Current Liquidity Provision')}
</h2>
<LPProvidersGrid
liquidityProviders={data.liquidityProviders}
settlementAsset={data.settlementAsset}
/>
</div>
</div>
</div>
</AsyncRenderer>
);
};
@@ -0,0 +1,26 @@
import { t } from '@vegaprotocol/react-helpers';
import { Link } from 'react-router-dom';
import { Icon } from '@vegaprotocol/ui-toolkit';
export const Header = ({
name,
symbol,
}: {
name?: string;
symbol?: string;
}) => {
return (
<div>
<div className="mb-6">
<Link to="/">
<Icon name="chevron-left" className="mr-2" />
<span className="underline font-alpha text-lg font-medium">
{t('Liquidity opportunities')}
</span>
</Link>
</div>
<h1 className="font-alpha text-5xl mb-6">{name}</h1>
<p className="font-alpha text-4xl">{symbol}</p>
</div>
);
};
@@ -0,0 +1 @@
export * from './detail';
@@ -0,0 +1 @@
export * from './last-24h-volume';
@@ -0,0 +1,114 @@
import { useState, useMemo, useRef, useCallback } from 'react';
import throttle from 'lodash/throttle';
import {
useYesterday,
useDataProvider,
addDecimalsFormatNumber,
} from '@vegaprotocol/react-helpers';
import { Interval } from '@vegaprotocol/types';
import {
calcDayVolume,
getChange,
displayChange,
} from '@vegaprotocol/liquidity';
import type { Candle } from '@vegaprotocol/market-list';
import { marketCandlesProvider } from '@vegaprotocol/market-list';
const DEBOUNCE_UPDATE_TIME = 500;
export const Last24hVolume = ({
marketId,
decimals,
}: {
marketId: string;
decimals: number;
}) => {
const [candleVolume, setCandleVolume] = useState<string>();
const [volumeChange, setVolumeChange] = useState<string>(' - ');
const yesterday = useYesterday();
const yTimestamp = useMemo(() => {
return new Date(yesterday).toISOString();
}, [yesterday]);
const variables = useMemo(
() => ({
marketId: marketId,
interval: Interval.INTERVAL_I1H,
since: yTimestamp,
}),
[marketId, yTimestamp]
);
const variables24hAgo = useMemo(
() => ({
marketId: marketId,
interval: Interval.INTERVAL_I1D,
since: yTimestamp,
}),
[marketId, yTimestamp]
);
const throttledSetCandles = useRef(
throttle((data: Candle[]) => {
setCandleVolume(calcDayVolume(data));
}, DEBOUNCE_UPDATE_TIME)
).current;
const update = useCallback(
({ data }: { data: Candle[] | null }) => {
if (data) {
throttledSetCandles(data);
}
return true;
},
[throttledSetCandles]
);
const { data, error } = useDataProvider<Candle[], Candle>({
dataProvider: marketCandlesProvider,
variables: variables,
update,
skip: !marketId,
});
const throttledSetVolumeChange = useRef(
throttle((candles: Candle[]) => {
const candle24hAgo = candles?.[0];
setVolumeChange(getChange(data || [], candle24hAgo?.close));
}, DEBOUNCE_UPDATE_TIME)
).current;
const updateCandle24hAgo = useCallback(
({ data }: { data: Candle[] | null }) => {
if (data) {
throttledSetVolumeChange(data);
}
return true;
},
[throttledSetVolumeChange]
);
useDataProvider<Candle[], Candle>({
dataProvider: marketCandlesProvider,
update: updateCandle24hAgo,
variables: variables24hAgo,
skip: !marketId || !data,
updateOnInit: true,
});
return (
<div>
<span className="text-3xl">
{!error && candleVolume
? addDecimalsFormatNumber(candleVolume, decimals)
: '0'}{' '}
</span>
<span className="text-lg text-greys-light-400">
({displayChange(volumeChange)})
</span>
</div>
);
};
@@ -0,0 +1 @@
export * from './market';
@@ -0,0 +1,118 @@
import { useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
import { Icon } from '@vegaprotocol/ui-toolkit';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import type { MarketTradingMode, AuctionTrigger } from '@vegaprotocol/types';
import { HealthBar } from '../../health-bar';
import { HealthDialog } from '../../health-dialog';
import { Last24hVolume } from '../last-24h-volume';
import { Status } from '../../status';
interface Levels {
fee: string;
commitmentAmount: number;
}
interface settlementAsset {
symbol?: string;
decimals?: number;
}
export const Market = ({
marketId,
feeLevels,
comittedLiquidity,
settlementAsset,
targetStake,
tradingMode,
trigger,
}: {
marketId: string;
feeLevels: Levels[];
comittedLiquidity: number;
targetStake: string;
settlementAsset?: settlementAsset;
tradingMode?: MarketTradingMode;
trigger?: AuctionTrigger;
}) => {
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
return (
<div>
<div className="border border-greys-light-200 rounded-2xl px-2 py-6">
<table className="w-full">
<thead>
<tr
className="text-sm text-greys-light-400 text-left font-alpha"
style={{ fontFeatureSettings: "'liga' off, 'calt' off" }}
>
<th className="font-medium px-4">{t('Volume (24h)')}</th>
<th className="font-medium px-4">{t('Commited Liquidity')}</th>
<th className="font-medium px-4">{t('Status')}</th>
<th className="font-medium flex items-center px-4">
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
className="flex ml-1"
>
<Icon name="info-sign" />
</button>
</th>
<th className="font-medium">{t('Est. APY')}</th>
</tr>
</thead>
<tbody>
<tr>
<td className="px-4">
<div>
{marketId && settlementAsset?.decimals && (
<Last24hVolume
marketId={marketId}
decimals={settlementAsset.decimals}
/>
)}
</div>
</td>
<td className="px-4">
<span className="text-3xl">
{comittedLiquidity && settlementAsset
? formatWithAsset(`${comittedLiquidity}`, settlementAsset)
: '0'}
</span>
</td>
<td className="px-4">
<Status
trigger={trigger}
tradingMode={tradingMode}
size="large"
/>
</td>
<td className="px-4">
{tradingMode && settlementAsset?.decimals && feeLevels && (
<HealthBar
status={tradingMode}
target={targetStake}
decimals={settlementAsset.decimals}
levels={feeLevels}
/>
)}
</td>
<td className="px-4">
<span className="text-3xl"></span>
</td>
</tr>
</tbody>
</table>
</div>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
);
};
@@ -0,0 +1 @@
export * from './providers';
@@ -0,0 +1,88 @@
import { useCallback } from 'react';
import { AgGridColumn } from 'ag-grid-react';
import type { GetRowIdParams } from 'ag-grid-community';
import { t } from '@vegaprotocol/react-helpers';
import type {
LiquidityProviderFeeShareFieldsFragment,
LiquidityProvisionFieldsFragment,
} from '@vegaprotocol/liquidity';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import { Grid } from '../../grid';
const formatToHours = ({ value }: { value?: string | null }) => {
if (!value) {
return '-';
}
const MS_IN_HOUR = 1000 * 60 * 60;
const created = new Date(value).getTime();
const now = new Date().getTime();
return `${Math.round(Math.abs(now - created) / MS_IN_HOUR)}h`;
};
export const LPProvidersGrid = ({
liquidityProviders,
settlementAsset,
}: {
liquidityProviders: LiquidityProvisionFieldsFragment &
LiquidityProviderFeeShareFieldsFragment[];
settlementAsset: {
decimals?: number;
symbol?: string;
};
}) => {
const getRowId = useCallback(({ data }: GetRowIdParams) => data.party.id, []);
return (
<Grid
rowData={liquidityProviders}
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
rowHeight={92}
>
<AgGridColumn
headerName={t('LPs')}
field="party.id"
flex="1"
minWidth={100}
/>
<AgGridColumn
headerName={t('Time in market')}
valueFormatter={formatToHours}
field="createdAt"
/>
<AgGridColumn
headerName={t('Equity-like share')}
field="equityLikeShare"
valueFormatter={({ value }: { value?: string | null }) => {
const valueOr0 = value ? value : '';
return `${parseInt(valueOr0) * 100}%`;
}}
/>
<AgGridColumn
headerName={t('committed bond/stake')}
field="commitmentAmount"
valueFormatter={({ value }: { value?: string | null }) =>
value ? formatWithAsset(value, settlementAsset) : '0'
}
/>
<AgGridColumn headerName={t('Margin Req.')} field="margin" />
<AgGridColumn headerName={t('24h Fees')} field="fees" />
<AgGridColumn
headerName={t('Fee level')}
valueFormatter={({ value }: { value?: string | null }) => `${value}%`}
field="fee"
/>
<AgGridColumn headerName={t('APY')} field="apy" />
</Grid>
);
};
@@ -0,0 +1,50 @@
.ag-theme-alpine {
--ag-line-height: 24px;
--ag-row-hover-color: transparent;
--ag-header-background-color: transparent;
--ag-odd-row-background-color: transparent;
--ag-header-foreground-color: #626262;
--ag-secondary-foreground-color: #626262;
--ag-font-size: 16px;
--ag-background-color: transparent;
--ag-range-selection-border-color: transparent;
font-family: AlphaLyrae, Helvetica Neue, -apple-system, BlinkMacSystemFont,
Segoe UI, Roboto, Arial, Noto Sans, sans-serif, Apple Color Emoji,
Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
font-feature-settings: 'liga' off, 'calt' off;
}
.ag-theme-alpine .ag-cell {
display: flex;
}
.ag-theme-alpine .ag-header {
border-bottom: 1px solid #a7a7a7;
font-size: 15px;
line-height: 1em;
text-transform: uppercase;
}
.ag-theme-alpine .ag-root-wrapper {
border: none;
}
.ag-theme-alpine .ag-header-row {
font-weight: 500;
}
.ag-theme-alpine .ag-row {
border: none;
border-bottom: 1px solid #bfccd6;
font-size: 12px;
}
.ag-theme-alpine .ag-root-wrapper-body.ag-layout-normal {
height: auto;
}
.ag-theme-alpine.row-hover .ag-row:hover {
background: #f0f0f0;
cursor: pointer;
}
@@ -0,0 +1,51 @@
import { useRef, useCallback, useEffect } from 'react';
import type { ReactNode } from 'react';
import { AgGridReact } from 'ag-grid-react';
import type {
AgGridReactProps,
AgReactUiProps,
AgGridReact as AgGridReactType,
} from 'ag-grid-react';
import classNames from 'classnames';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import './grid.scss';
type Props = (AgGridReactProps | AgReactUiProps) & {
isRowClickable?: boolean;
style?: React.CSSProperties;
children: ReactNode;
};
export const Grid = ({ isRowClickable, children, ...props }: Props) => {
const gridRef = useRef<AgGridReactType | null>(null);
const resizeGrid = useCallback(() => {
gridRef.current?.api?.sizeColumnsToFit();
}, [gridRef]);
const handleOnGridReady = useCallback(() => {
resizeGrid();
}, [resizeGrid]);
useEffect(() => {
window.addEventListener('resize', resizeGrid);
return () => window.removeEventListener('resize', resizeGrid);
}, [resizeGrid]);
return (
<AgGridReact
className={classNames('ag-theme-alpine h-full font-alpha', {
'row-hover': isRowClickable,
})}
rowHeight={92}
ref={gridRef}
onGridReady={handleOnGridReady}
suppressRowClickSelection
{...props}
>
{children}
</AgGridReact>
);
};
@@ -0,0 +1 @@
export * from './grid';
@@ -1,12 +0,0 @@
import { t } from '@vegaprotocol/react-helpers';
export const Header = () => {
return (
<div className="flex items-stretch px-6 py-6" data-testid="header">
<h1 className="text-3xl">{t('Top liquidity opportunities')}</h1>
<div className="flex items-center gap-2 ml-auto relative z-10">
{t('Network switcher')}
</div>
</div>
);
};
@@ -1,18 +1,19 @@
import classNames from 'classnames';
import { MarketTradingMode } from '@vegaprotocol/types';
import type { MarketTradingMode } from '@vegaprotocol/types';
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
import { BigNumber } from 'bignumber.js';
import type { ReactNode } from 'react';
const marketTradingModeStyle = {
[MarketTradingMode.TRADING_MODE_CONTINUOUS]: '#00a88a',
[MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: '#fb8e7f',
[MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: '#68e2e4',
[MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: 'batch',
[MarketTradingMode.TRADING_MODE_NO_TRADING]: 'none',
};
import { getColorForStatus } from '../../lib/utils';
const COPY_CLASS = 'text-[8px] leading-[1.2em] font-medium';
import { Indicator } from '../indicator';
const Remainder = () => (
<div className="bg-greys-light-200 h-[inherit] relative flex-1"></div>
);
const COPY_CLASS =
'text-sm font-medium whitespace-nowrap text-white font-alpha';
const Tooltip = ({
children,
@@ -24,27 +25,13 @@ const Tooltip = ({
return (
<div
className={classNames(
'absolute top-0 left-1/2 -translate-x-2/4 -translate-y-[120%] border border-[#bfccd6] py-0.5 px-2 flex-col z-10 bg-white group-hover:flex min-w-[65px]',
'absolute top-0 left-1/2 -translate-x-2/4 -translate-y-[80%] p-2 z-10 bg-greys-light-400 group-hover:flex rounded',
{
flex: isExpanded,
hidden: !isExpanded,
}
)}
>
<div
className="absolute w-0 h-0 translate-y-full translate-x-2/4 left-[calc(50% - 8px)] -bottom-px border-4"
style={{
left: 'calc(50% - 8px)',
borderColor: '#bfccd6 transparent transparent transparent',
}}
></div>
<div
style={{
left: 'calc(50% - 8px)',
borderColor: 'white transparent transparent transparent',
}}
className="absolute bottom-0 w-0 h-0 translate-y-full translate-x-2/4 left-[calc(50% - 8px)] border-4"
></div>
{children}
</div>
);
@@ -62,17 +49,20 @@ const Target = ({
return (
<div
className={classNames(
'absolute top-0 left-1/2 -translate-x-2/4 px-1.5 group'
'absolute top-1/2 left-1/2 -translate-x-2/4 -translate-y-1/2 px-1.5 group'
)}
style={{ left: `${targetPercent}%` }}
>
<div
className={classNames('health-target w-0.5 h-8 bg-black', {
'h-[72px]': isLarge,
})}
>
{children}
</div>
className={classNames(
'health-target w-0.5 bg-black group-hover:scale-x-150 group-hover:scale-y-108',
{
'h-6': !isLarge,
'h-12': isLarge,
}
)}
></div>
{children}
</div>
);
};
@@ -81,14 +71,14 @@ const Level = ({
children,
commitmentAmount,
total,
index,
status,
backgroundColor,
opacity,
}: {
children: ReactNode;
index: number;
status: MarketTradingMode;
commitmentAmount: number;
total: number;
backgroundColor: string;
opacity: number;
}) => {
const width = new BigNumber(commitmentAmount)
.div(total)
@@ -97,26 +87,26 @@ const Level = ({
return (
<div
className={classNames(`relative h-[inherit] w-full group`)}
className={classNames(`relative h-[inherit] w-full group min-w-[1px]`)}
style={{
width: `${width}%`,
opacity: 1 - 0.1 * index,
}}
>
<div
className="relative w-full h-[inherit]"
className="relative w-full h-[inherit] group-hover:scale-y-150"
style={{
opacity: 1 - 0.1 * index,
backgroundColor: marketTradingModeStyle[status],
opacity,
backgroundColor,
}}
></div>
{children}
</div>
);
};
const Full = () => (
<div className="bg-neutral-100 w-full h-[inherit] absolute bottom-0 left-0"></div>
<div className="bg-transparent w-full h-[inherit] absolute bottom-0 left-0"></div>
);
interface Levels {
@@ -126,7 +116,7 @@ interface Levels {
export const HealthBar = ({
status,
target,
target = '0',
decimals,
levels,
size = 'small',
@@ -151,6 +141,7 @@ export const HealthBar = ({
targetNumber * 2 >= committedNumber ? targetNumber * 2 : committedNumber;
const targetPercent = (targetNumber / total) * 100;
const isLarge = size === 'large';
const backgroundColor = getColorForStatus(status);
return (
<div className="w-full">
@@ -168,36 +159,50 @@ export const HealthBar = ({
>
<Full />
<div className="health-bars h-[inherit] flex w-full">
<div className="health-bars h-[inherit] flex w-full gap-0.5">
{levels.map((p, index) => {
const { commitmentAmount, fee } = p;
const prevLevel = levels[index - 1]?.commitmentAmount;
const opacity = 1 - 0.2 * index;
return (
<Level
status={status}
commitmentAmount={commitmentAmount}
index={index}
total={total}
backgroundColor={backgroundColor}
opacity={opacity}
>
<Tooltip isExpanded={isExpanded}>
<span className={COPY_CLASS}>
{fee}% {t('Fee')}
</span>
<span className={COPY_CLASS}>
{addDecimalsFormatNumber(commitmentAmount, decimals)}
</span>
<div className="mt-1.5 inline-flex">
<Indicator status={status} opacity={opacity} />
</div>
<div className="flex flex-col">
<span className={COPY_CLASS}>
{fee}% {t('Fee')}
</span>
<span className={classNames(COPY_CLASS, 'opacity-60')}>
{prevLevel
? addDecimalsFormatNumber(prevLevel, decimals)
: '0'}{' '}
- {addDecimalsFormatNumber(commitmentAmount, decimals)}
</span>
</div>
</Tooltip>
</Level>
);
})}
{(total !== committedNumber || levels.length === 0) && (
<Remainder />
)}
</div>
</div>
<Target targetPercent={targetPercent} isLarge={isLarge}>
<Tooltip isExpanded={isExpanded}>
<span className={COPY_CLASS}>{t('Target stake')}</span>
<div className="mt-1.5 inline-flex">
<Indicator />
</div>
<span className={COPY_CLASS}>
{addDecimalsFormatNumber(target, decimals)}
{t('Target stake')} {addDecimalsFormatNumber(target, decimals)}
</span>
</Tooltip>
</Target>
@@ -0,0 +1 @@
export * from './health-bar';
@@ -1,8 +1,9 @@
import { t } from '@vegaprotocol/react-helpers';
import { Dialog } from '@vegaprotocol/ui-toolkit';
import { MarketTradingMode } from '@vegaprotocol/types';
import classNames from 'classnames';
import { HealthBar } from './health-bar';
import { HealthBar } from '../health-bar';
interface HealthDialogProps {
isOpen: boolean;
@@ -58,36 +59,48 @@ const ROWS = [
export const HealthDialog = ({ onChange, isOpen }: HealthDialogProps) => {
return (
<Dialog size="medium" open={isOpen} onChange={onChange}>
<h1 className="text-xl mb-4 pr-2 font-bold" data-testid="dialog-title">
<h1 className="text-2xl mb-5 pr-2 font-medium font-alpha uppercase liga-0-calt-0">
{t('Health')}
</h1>
<p className="text-xl mb-4">
<p className="text-lg font-medium font-alpha mb-8 liga-0-calt-0">
{t(
'Market health is a representation of market and liquidity status and how close that market is to moving from one fee level to another.'
)}
</p>
<table className="table-fixed">
<thead>
<th className="w-1/2 text-left">{t('Market status')}</th>
<th className="w-1/2 text-left">{t('Liquidity status')}</th>
<thead className="border-b border-greys-light-300">
<th className="w-1/2 text-left font-medium font-alpha text-base pb-4 uppercase liga-0-calt-0">
{t('Market status')}
</th>
<th className="w-1/2 text-lef font-medium font-alpha text-base pb-4 uppercase liga-0-calt-0">
{t('Liquidity status')}
</th>
</thead>
<tbody>
{ROWS.map((r) => {
{ROWS.map((r, index) => {
const isFirstRow = index === 0;
return (
<tr key={r.key}>
<td className="pr-4 py-10">
<h2 className="font-bold text-base">{t(r.title)}</h2>
<p className="text-base">{t(r.copy)}</p>
<td
className={classNames('pr-4 pb-10', { 'pt-8': isFirstRow })}
>
<h2 className="font-medium font-alpha uppercase text-base liga-0-calt-0">
{t(r.title)}
</h2>
<p className="font-medium font-alpha text-lg liga-0-calt-0">
{t(r.copy)}
</p>
</td>
<td className="py-10">
<td
className={classNames('pl-4 pb-10', { 'pt-8': isFirstRow })}
>
<HealthBar
size="large"
levels={r.data.levels}
status={r.data.status}
target={r.data.target}
decimals={r.data.decimals}
isExpanded
/>
</td>
</tr>
@@ -0,0 +1 @@
export * from './health-dialog';
@@ -0,0 +1 @@
export * from './indicator';
@@ -0,0 +1,24 @@
import type { MarketTradingMode } from '@vegaprotocol/types';
import { getColorForStatus } from '../../lib/utils';
export const Indicator = ({
status,
opacity,
}: {
status?: MarketTradingMode;
opacity?: number;
}) => {
const backgroundColor = status ? getColorForStatus(status) : undefined;
return (
<div className="inline-block w-2 h-2 mr-1 rounded-full bg-white overflow-hidden shrink-0">
<div
className="h-full bg-black"
style={{
opacity,
backgroundColor,
}}
/>
</div>
);
};
@@ -1,189 +0,0 @@
import { useCallback, useRef, useEffect, useState } from 'react';
import { AgGridReact, AgGridColumn } from 'ag-grid-react';
import type { AgGridReact as AgGridReactType } from 'ag-grid-react';
import type {
GroupCellRendererParams,
ValueFormatterParams,
GetRowIdParams,
} from 'ag-grid-community';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { formatNumber, t } from '@vegaprotocol/react-helpers';
import { useMarketsLiquidity } from '@vegaprotocol/liquidity';
import { Icon } from '@vegaprotocol/ui-toolkit';
import type { Market } from '@vegaprotocol/liquidity';
import { formatWithAsset } from '@vegaprotocol/liquidity';
import {
MarketTradingModeMapping,
MarketTradingMode,
AuctionTrigger,
AuctionTriggerMapping,
} from '@vegaprotocol/types';
import { HealthBar } from './health-bar';
import { HealthDialog } from './health-dialog';
import './market-list.scss';
const displayValue = (value: string) => {
return parseFloat(value) > 0 ? `+${value}` : value;
};
const marketNameCellRenderer = ({
value,
data,
}: {
value: string;
data: Market;
}) => {
return (
<>
<span style={{ lineHeight: '12px' }}>{value}</span>
<span style={{ lineHeight: '12px' }}>
{data?.tradableInstrument?.instrument?.product?.settlementAsset?.symbol}
</span>
</>
);
};
const healthCellRenderer = ({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return (
<div>
<HealthBar
status={value}
target={data.target}
decimals={
data.tradableInstrument.instrument.product.settlementAsset.decimals
}
levels={data.feeLevels}
/>
</div>
);
};
export const MarketList = () => {
const { data, error, loading } = useMarketsLiquidity();
const [isHealthDialogOpen, setIsHealthDialogOpen] = useState(false);
const gridRef = useRef<AgGridReactType | null>(null);
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
const handleOnGridReady = useCallback(() => {
gridRef.current?.api?.sizeColumnsToFit();
}, [gridRef]);
useEffect(() => {
window.addEventListener('resize', handleOnGridReady);
return () => window.removeEventListener('resize', handleOnGridReady);
}, [handleOnGridReady]);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :( </p>;
const localData = data?.markets;
return (
<div
className="px-6 py-6 grow"
data-testid="market-list"
style={{ minHeight: 500, overflow: 'hidden' }}
>
<AgGridReact
rowData={localData}
className="ag-theme-alpine h-full"
defaultColDef={{
resizable: true,
sortable: true,
unSortIcon: true,
cellClass: ['flex', 'flex-col', 'justify-center'],
}}
getRowId={getRowId}
rowHeight={92}
ref={gridRef}
>
<AgGridColumn
headerName={t('Market (futures)')}
field="tradableInstrument.instrument.name"
cellRenderer={marketNameCellRenderer}
minWidth={100}
/>
<AgGridColumn
headerName={t('Volume (24h)')}
field="dayVolume"
cellRenderer={({ value, data }: GroupCellRendererParams) => {
return (
<div>
{formatNumber(value)} ({displayValue(data.volumeChange)})
</div>
);
}}
/>
<AgGridColumn
headerName={t('Committed bond/stake')}
field="liquidityCommitted"
valueFormatter={({ value, data }: ValueFormatterParams) =>
formatWithAsset(
value,
data.tradableInstrument.instrument.product.settlementAsset
)
}
/>
<AgGridColumn
headerName={t('Status')}
field="tradingMode"
valueFormatter={({
value,
data,
}: {
value: MarketTradingMode;
data: Market;
}) => {
return value ===
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
data.data?.trigger &&
data.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
? `${MarketTradingModeMapping[value]}
- ${AuctionTriggerMapping[data.data.trigger]}`
: MarketTradingModeMapping[value];
}}
/>
<AgGridColumn
headerComponent={() => {
return (
<div>
<span>{t('Health')}</span>{' '}
<button
onClick={() => setIsHealthDialogOpen(true)}
aria-label={t('open tooltip')}
>
<Icon name="info-sign" />
</button>
</div>
);
}}
field="tradingMode"
cellRenderer={healthCellRenderer}
sortable={false}
cellStyle={{ overflow: 'unset' }}
/>
<AgGridColumn headerName={t('Est. return / APY')} field="apy" />
</AgGridReact>
<HealthDialog
isOpen={isHealthDialogOpen}
onChange={() => {
setIsHealthDialogOpen(!isHealthDialogOpen);
}}
/>
</div>
);
};
@@ -0,0 +1 @@
export * from './navbar';
@@ -0,0 +1,15 @@
import { Link } from 'react-router-dom';
import { VegaLogo } from '@vegaprotocol/ui-toolkit';
export const Navbar = () => {
return (
<div className="px-8 py-4 flex items-stretch border-b border-greys-light-200">
<div className="flex gap-4 mr-4 items-center h-full">
<Link to="/">
<VegaLogo />
</Link>
</div>
<div className="flex items-center gap-2 ml-auto"></div>
</div>
);
};
@@ -0,0 +1 @@
export * from './status';
@@ -0,0 +1,45 @@
import { Lozenge } from '@vegaprotocol/ui-toolkit';
import classNames from 'classnames';
import {
MarketTradingModeMapping,
MarketTradingMode,
AuctionTrigger,
AuctionTriggerMapping,
} from '@vegaprotocol/types';
import { Indicator } from '../indicator';
export const Status = ({
tradingMode,
trigger,
size = 'small',
}: {
tradingMode?: MarketTradingMode;
trigger?: AuctionTrigger;
size?: 'small' | 'large';
}) => {
const getStatus = () => {
if (!tradingMode) return '';
if (tradingMode === MarketTradingMode.TRADING_MODE_MONITORING_AUCTION) {
if (trigger && trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED) {
return `${MarketTradingModeMapping[tradingMode]} - ${AuctionTriggerMapping[trigger]}`;
}
}
return MarketTradingModeMapping[tradingMode];
};
return (
<div
className={classNames('inline-flex whitespace-normal', {
'text-base': size === 'large',
'text-sm': size === 'small',
})}
>
<Lozenge className="border border-greys-light-300 bg-greys-light-100 flex items-center">
<Indicator status={tradingMode} />
{getStatus()}
</Lozenge>
</div>
);
};
@@ -1,88 +0,0 @@
import {
ApolloClient,
from,
HttpLink,
InMemoryCache,
split,
} from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient as createWSClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const wsLink = new GraphQLWsLink(
createWSClient({
url: urlWS.href,
})
);
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink
);
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, splitLink]),
cache,
});
}
@@ -0,0 +1,12 @@
import { MarketTradingMode } from '@vegaprotocol/types';
const marketTradingModeStyle = {
[MarketTradingMode.TRADING_MODE_CONTINUOUS]: '#00D46E',
[MarketTradingMode.TRADING_MODE_MONITORING_AUCTION]: '#CF0064',
[MarketTradingMode.TRADING_MODE_OPENING_AUCTION]: '#0046CD',
[MarketTradingMode.TRADING_MODE_BATCH_AUCTION]: '#CF0064',
[MarketTradingMode.TRADING_MODE_NO_TRADING]: '#CF0064',
};
export const getColorForStatus = (status: MarketTradingMode) =>
marketTradingModeStyle[status];
@@ -0,0 +1 @@
export * from './router-config';
@@ -0,0 +1,25 @@
import { t } from '@vegaprotocol/react-helpers';
import { Dashboard } from '../components/dashboard';
import { Detail } from '../components/detail';
export const ROUTES = {
MARKETS: 'markets',
};
export const routerConfig = [
{ path: '/', element: <Dashboard />, icon: '' },
{
path: ROUTES.MARKETS,
name: 'Markets',
text: t('Markets'),
children: [
{
path: ':marketId',
element: <Detail />,
},
],
icon: 'trade',
isNavItem: true,
},
];
@@ -1,22 +1,47 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
import { createClient } from './app/lib/apollo-client';
import App from './app/app';
import type { InMemoryCacheConfig } from '@apollo/client';
const rootElement = document.getElementById('root');
const root = rootElement && createRoot(rootElement);
const cache: InMemoryCacheConfig = {
typePolicies: {
Market: {
merge: true,
},
Party: {
merge: true,
},
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
Instrument: {
keyFields: false,
},
},
};
root?.render(
<StrictMode>
<EnvironmentProvider>
<ThemeContext.Provider value="light">
<NetworkLoader createClient={createClient}>
<App />
</NetworkLoader>
</ThemeContext.Provider>
</EnvironmentProvider>
<BrowserRouter>
<EnvironmentProvider>
<ThemeContext.Provider value="light">
<NetworkLoader cache={cache}>
<App />
</NetworkLoader>
</ThemeContext.Provider>
</EnvironmentProvider>
</BrowserRouter>
</StrictMode>
);
@@ -11,6 +11,19 @@ module.exports = {
...createGlobPatternsForDependencies(__dirname),
],
darkMode: 'class',
theme,
theme: {
...theme,
colors: {
...theme.colors,
greys: {
light: {
100: '#F0F0F0',
200: '#D2D2D2',
300: '#A7A7A7',
400: '#626262',
},
},
},
},
plugins: [vegaCustomClasses, vegaCustomClassesLite],
};
+19 -3
View File
@@ -11,7 +11,6 @@ import { AsyncRenderer, Button, Lozenge } from '@vegaprotocol/ui-toolkit';
import type { EthereumConfig } from '@vegaprotocol/web3';
import { useEthereumConfig, Web3Provider } from '@vegaprotocol/web3';
import { ThemeContext, useThemeSwitcher, t } from '@vegaprotocol/react-helpers';
import { createClient } from './lib/apollo-client';
import { ENV } from './config/env';
import { ContractsProvider } from './config/contracts/contracts-provider';
import {
@@ -24,6 +23,7 @@ import { createConnectors } from './lib/web3-connectors';
import { Web3Connector } from './components/web3-connector';
import { EthWalletContainer } from './components/eth-wallet-container';
import { useWeb3React } from '@web3-react/core';
import type { InMemoryCacheConfig } from '@apollo/client';
const pageWrapperClasses = classnames(
'min-h-screen w-screen',
@@ -96,10 +96,26 @@ function App() {
}
const Wrapper = () => {
const cache: InMemoryCacheConfig = {
typePolicies: {
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
},
};
return (
<EnvironmentProvider>
<NetworkLoader createClient={createClient}>
<App />
<NetworkLoader cache={cache}>
<ContractsProvider>
<App />
</ContractsProvider>
</NetworkLoader>
</EnvironmentProvider>
);
@@ -1,54 +0,0 @@
import * as Sentry from '@sentry/react';
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
Sentry.captureException(graphQLErrors);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}
+392 -73
View File
@@ -274,7 +274,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "92872.835269924084875675",
"locked_amount": "92220.581085028265986725",
"deposits": [
{
"amount": "129999.45",
@@ -340,7 +340,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "52600",
"total_removed": "0",
"locked_amount": "43016.19026509386238",
"locked_amount": "42619.95894850329646",
"deposits": [
{
"amount": "2600",
@@ -513,7 +513,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "4280.7722919837645",
"locked_amount": "4243.107718163369",
"deposits": [
{
"amount": "5000",
@@ -724,7 +724,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "97499.58",
"total_removed": "0",
"locked_amount": "34321.801526768423093772",
"locked_amount": "33682.0009316113152362808",
"deposits": [
{
"amount": "97499.58",
@@ -757,7 +757,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "135173.4239508",
"total_removed": "0",
"locked_amount": "46911.977275253228146197269112",
"locked_amount": "46037.48031863819208030137556",
"deposits": [
{
"amount": "135173.4239508",
@@ -790,7 +790,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "32499.86",
"total_removed": "0",
"locked_amount": "14438.589196501979358214",
"locked_amount": "14169.4361348846779119576",
"deposits": [
{
"amount": "32499.86",
@@ -823,7 +823,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "10833.29",
"total_removed": "0",
"locked_amount": "4699.6206747082650270343",
"locked_amount": "4612.0139649513209677735",
"deposits": [
{
"amount": "10833.29",
@@ -856,7 +856,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "22749.93",
"total_removed": "0",
"locked_amount": "17568.231723380234933316",
"locked_amount": "17240.738275703534195079",
"deposits": [
{
"amount": "6500",
@@ -995,7 +995,7 @@
"tranche_end": "2023-05-01T00:00:00.000Z",
"total_added": "22500",
"total_removed": "0",
"locked_amount": "21567.22922421731025",
"locked_amount": "21225.438823664826",
"deposits": [
{
"amount": "7500",
@@ -1048,7 +1048,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "626880.6921411330574",
"locked_amount": "1092186.99819232165908148",
"locked_amount": "1077573.68305736380241946",
"deposits": [
{
"amount": "1852091.69",
@@ -1345,7 +1345,7 @@
"tranche_end": "2023-02-01T00:00:00.000Z",
"total_added": "42500",
"total_removed": "0",
"locked_amount": "19516.8262819545095",
"locked_amount": "18881.74834566223655",
"deposits": [
{
"amount": "12500",
@@ -6102,10 +6102,15 @@
"tranche_id": 11,
"tranche_start": "2021-09-03T00:00:00.000Z",
"tranche_end": "2022-09-03T00:00:00.000Z",
"total_added": "41642.000000000000000003",
"total_added": "41662.000000000000000003",
"total_removed": "26053.75324099301",
"locked_amount": "0",
"deposits": [
{
"amount": "20",
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
"tx": "0x6c84b5728f0d2de25345a7a05cc42de530dc49eb3cafedaebc220069ae904c6b"
},
{
"amount": "10",
"user": "0xABD95f7D67e76280df18220AA6F5A7358956C58b",
@@ -13820,6 +13825,21 @@
}
],
"users": [
{
"address": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
"deposits": [
{
"amount": "20",
"user": "0xB12Cdb63E38f9a6ff2C0F68aBC3CA9beFCb7148c",
"tranche_id": 11,
"tx": "0x6c84b5728f0d2de25345a7a05cc42de530dc49eb3cafedaebc220069ae904c6b"
}
],
"withdrawals": [],
"total_tokens": "20",
"withdrawn_tokens": "0",
"remaining_tokens": "20"
},
{
"address": "0xABD95f7D67e76280df18220AA6F5A7358956C58b",
"deposits": [
@@ -25338,8 +25358,8 @@
"tranche_start": "2022-03-05T00:00:00.000Z",
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "226454.4904408472047",
"locked_amount": "1702812.48182581737177363478",
"total_removed": "284657.8276980546609",
"locked_amount": "1680356.90427933501869095582",
"deposits": [
{
"amount": "1998.95815",
@@ -25508,6 +25528,21 @@
}
],
"withdrawals": [
{
"amount": "2893.9492727166165",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
"tx": "0x645d29df4e2c50f6102245cc728bf0c554a1fc6b87050b3cbeed2ec7c8d3ac7b"
},
{
"amount": "34960.394886",
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
"tx": "0x3afea28baa4dda8810bcfe97cfbf7c59c0b9c3f850bc283e91b816ebb8bcb1a7"
},
{
"amount": "20348.9930984908397",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
"tx": "0x0fb4a88d2096baf63f88071b946e442173ac48cb50f68975c741b9c5fb69434d"
},
{
"amount": "1788.901802058876",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
@@ -25722,6 +25757,12 @@
}
],
"withdrawals": [
{
"amount": "2893.9492727166165",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
"tranche_id": 1,
"tx": "0x645d29df4e2c50f6102245cc728bf0c554a1fc6b87050b3cbeed2ec7c8d3ac7b"
},
{
"amount": "1788.901802058876",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
@@ -25850,8 +25891,8 @@
}
],
"total_tokens": "187637.95",
"withdrawn_tokens": "99212.021610780791",
"remaining_tokens": "88425.928389219209"
"withdrawn_tokens": "102105.9708834974075",
"remaining_tokens": "85531.9791165025925"
},
{
"address": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
@@ -25864,6 +25905,12 @@
}
],
"withdrawals": [
{
"amount": "20348.9930984908397",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
"tranche_id": 1,
"tx": "0x0fb4a88d2096baf63f88071b946e442173ac48cb50f68975c741b9c5fb69434d"
},
{
"amount": "9385.4817110261074",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
@@ -25884,8 +25931,8 @@
}
],
"total_tokens": "112323.67",
"withdrawn_tokens": "40990.3648975722083",
"remaining_tokens": "71333.3051024277917"
"withdrawn_tokens": "61339.357996063048",
"remaining_tokens": "50984.312003936952"
},
{
"address": "0x3D7944C81794Bc621076958cA0dC0F0b31BDc3e2",
@@ -26242,6 +26289,12 @@
}
],
"withdrawals": [
{
"amount": "34960.394886",
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
"tranche_id": 1,
"tx": "0x3afea28baa4dda8810bcfe97cfbf7c59c0b9c3f850bc283e91b816ebb8bcb1a7"
},
{
"amount": "17985.817328",
"user": "0x93b478148FF792B00076B7EdC89Db1FdE7772079",
@@ -26262,8 +26315,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "74256.291028",
"remaining_tokens": "125743.708972"
"withdrawn_tokens": "109216.685914",
"remaining_tokens": "90783.314086"
},
{
"address": "0xB523235B6c7C74DDB26b10E78bFb2d0Cb63Ae289",
@@ -26332,8 +26385,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "302999.2316026066361394",
"locked_amount": "11337751.3151841262003771862944779976547715",
"total_removed": "453748.5475981423200744",
"locked_amount": "11258125.2789901849270326963417939365436605",
"deposits": [
{
"amount": "16249.93",
@@ -26847,6 +26900,61 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x885851fab37258350e0fe4735b6cc1d1ff0bb523710fdd1a6bb4d0f8ed6485ef"
},
{
"amount": "2102.78771261784997",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
"tx": "0xdafb045be53447fbfe2a8db5f4c996bf7350a326d2f9f79bafa697af57e46901"
},
{
"amount": "1363.189376",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
"tx": "0xa55f1e1e471f79617820ed7ae524d23b1962442bca2e23991433d60b634cb55e"
},
{
"amount": "158.9965914292145",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
"tx": "0x3b625782c9f9cd08f1b2c3988d3c5f5fb5530bb87b90b28611444be2b797ada2"
},
{
"amount": "464.500242866418",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x1afadba80f67e2343f1903ae9d110361091b74f71b21f6be2085c9c4a61900d3"
},
{
"amount": "13246.0770207423553",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
"tx": "0x29ef7d6e50ea9025421303a3e9604348fc9dec54051a221031c2935874781c1d"
},
{
"amount": "30360.0931",
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
"tx": "0xa805c716e5fc26f0a0550ea6cca3a8c47f09fa873d2db76aa3f7d16c5b845524"
},
{
"amount": "10964.26423788708204",
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
"tx": "0xe139e4d5b20437f4462766ae68d2dc475aae97e21f359f16d3b5596848b252a6"
},
{
"amount": "30374.150954",
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
"tx": "0x6b8738a5323f6bf9c7f9e3d21d5d9ae0b9eab49814b2c664326e6f339d59a7bd"
},
{
"amount": "30570.627196",
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
"tx": "0x77a1cc738e568bcb14790007caad9bb82a32eff8a4334d91a01a3b23ed6bb1c3"
},
{
"amount": "765.578639992764125",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x018dba68269feb7f62a70a34003335313778cadec655e52d93e813b33760231c"
},
{
"amount": "30379.050924",
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
"tx": "0x1563a54327368be50e0b2f0507b6821698c38038b51a6ac60fe242647b227c8b"
},
{
"amount": "477.9430069466525",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -27772,6 +27880,18 @@
"tranche_id": 2,
"tx": "0x885851fab37258350e0fe4735b6cc1d1ff0bb523710fdd1a6bb4d0f8ed6485ef"
},
{
"amount": "464.500242866418",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x1afadba80f67e2343f1903ae9d110361091b74f71b21f6be2085c9c4a61900d3"
},
{
"amount": "765.578639992764125",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x018dba68269feb7f62a70a34003335313778cadec655e52d93e813b33760231c"
},
{
"amount": "477.9430069466525",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -28542,8 +28662,8 @@
}
],
"total_tokens": "259998.8875",
"withdrawn_tokens": "73983.173481428171125",
"remaining_tokens": "186015.714018571828875"
"withdrawn_tokens": "75213.25236428735325",
"remaining_tokens": "184785.63513571264675"
},
{
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
@@ -28661,6 +28781,12 @@
}
],
"withdrawals": [
{
"amount": "30379.050924",
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
"tranche_id": 2,
"tx": "0x1563a54327368be50e0b2f0507b6821698c38038b51a6ac60fe242647b227c8b"
},
{
"amount": "27478.406326",
"user": "0x21ff84851BdF79de9AA357E47856d58b2d825392",
@@ -28669,8 +28795,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "27478.406326",
"remaining_tokens": "172521.593674"
"withdrawn_tokens": "57857.45725",
"remaining_tokens": "142142.54275"
},
{
"address": "0x8DA3586FF7526E122093EE6dD86DFBf067ad8704",
@@ -28758,6 +28884,12 @@
}
],
"withdrawals": [
{
"amount": "2102.78771261784997",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
"tranche_id": 2,
"tx": "0xdafb045be53447fbfe2a8db5f4c996bf7350a326d2f9f79bafa697af57e46901"
},
{
"amount": "1136.00674690441244",
"user": "0xe3eB4CF43C072658401996b71D43eE26E573562D",
@@ -28826,8 +28958,8 @@
}
],
"total_tokens": "150551.801",
"withdrawn_tokens": "40920.46931853489141",
"remaining_tokens": "109631.33168146510859"
"withdrawn_tokens": "43023.25703115274138",
"remaining_tokens": "107528.54396884725862"
},
{
"address": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
@@ -28840,6 +28972,12 @@
}
],
"withdrawals": [
{
"amount": "10964.26423788708204",
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
"tranche_id": 2,
"tx": "0xe139e4d5b20437f4462766ae68d2dc475aae97e21f359f16d3b5596848b252a6"
},
{
"amount": "3294.60955363161788",
"user": "0x4d982Ab0823fD2f48e934a7be2bb0a5374a26148",
@@ -28848,8 +28986,8 @@
}
],
"total_tokens": "49294.676",
"withdrawn_tokens": "3294.60955363161788",
"remaining_tokens": "46000.06644636838212"
"withdrawn_tokens": "14258.87379151869992",
"remaining_tokens": "35035.80220848130008"
},
{
"address": "0x4092E429B149b5495265b608FD6Fae69fa5bfBe6",
@@ -28877,6 +29015,12 @@
}
],
"withdrawals": [
{
"amount": "30570.627196",
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
"tranche_id": 2,
"tx": "0x77a1cc738e568bcb14790007caad9bb82a32eff8a4334d91a01a3b23ed6bb1c3"
},
{
"amount": "13920.51906",
"user": "0x74b521F96c641FD59631Dc6a24c558ed39D64352",
@@ -28891,8 +29035,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "27285.917646",
"remaining_tokens": "172714.082354"
"withdrawn_tokens": "57856.544842",
"remaining_tokens": "142143.455158"
},
{
"address": "0x834b777E3aB758C84FeBbfb9d6BB675bc4B16915",
@@ -29017,6 +29161,12 @@
}
],
"withdrawals": [
{
"amount": "1363.189376",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
"tranche_id": 2,
"tx": "0xa55f1e1e471f79617820ed7ae524d23b1962442bca2e23991433d60b634cb55e"
},
{
"amount": "52330.338436",
"user": "0xF4c75FdbAe821C6B5DBB9f001bB23cBA58D1bA37",
@@ -29031,8 +29181,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "55791.611752",
"remaining_tokens": "144208.388248"
"withdrawn_tokens": "57154.801128",
"remaining_tokens": "142845.198872"
},
{
"address": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
@@ -29045,6 +29195,12 @@
}
],
"withdrawals": [
{
"amount": "30374.150954",
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
"tranche_id": 2,
"tx": "0x6b8738a5323f6bf9c7f9e3d21d5d9ae0b9eab49814b2c664326e6f339d59a7bd"
},
{
"amount": "14117.751418",
"user": "0x1b956E6c00E238194B331eddEFF72Cb5f28A8d01",
@@ -29059,8 +29215,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "27480.518382",
"remaining_tokens": "172519.481618"
"withdrawn_tokens": "57854.669336",
"remaining_tokens": "142145.330664"
},
{
"address": "0xA5d8726fFaD226e65D136ef9C2185750863b4850",
@@ -29193,6 +29349,12 @@
}
],
"withdrawals": [
{
"amount": "13246.0770207423553",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
"tranche_id": 2,
"tx": "0x29ef7d6e50ea9025421303a3e9604348fc9dec54051a221031c2935874781c1d"
},
{
"amount": "6104.7463161966015",
"user": "0x1A71e3ED1996CAbB91bB043f880CE963D601707e",
@@ -29207,8 +29369,8 @@
}
],
"total_tokens": "87676.33",
"withdrawn_tokens": "11963.3992294756653",
"remaining_tokens": "75712.9307705243347"
"withdrawn_tokens": "25209.4762502180206",
"remaining_tokens": "62466.8537497819794"
},
{
"address": "0x9cF9B305601154C85ff86014d10a8762C802db0B",
@@ -29416,6 +29578,12 @@
}
],
"withdrawals": [
{
"amount": "30360.0931",
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
"tranche_id": 2,
"tx": "0xa805c716e5fc26f0a0550ea6cca3a8c47f09fa873d2db76aa3f7d16c5b845524"
},
{
"amount": "14125.439308",
"user": "0x29f1856E73262fc4372BBF442EbB550919459308",
@@ -29430,8 +29598,8 @@
}
],
"total_tokens": "200000",
"withdrawn_tokens": "27481.599756",
"remaining_tokens": "172518.400244"
"withdrawn_tokens": "57841.692856",
"remaining_tokens": "142158.307144"
},
{
"address": "0x87D71adAbC11c35aF566eD51421eDA0c82828a3A",
@@ -29474,6 +29642,12 @@
}
],
"withdrawals": [
{
"amount": "158.9965914292145",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
"tranche_id": 2,
"tx": "0x3b625782c9f9cd08f1b2c3988d3c5f5fb5530bb87b90b28611444be2b797ada2"
},
{
"amount": "98.307999550294",
"user": "0xE6CacAE56Cca8dFdB7910b5A13578719D4E57DA0",
@@ -29584,8 +29758,8 @@
}
],
"total_tokens": "12362.05",
"withdrawn_tokens": "3375.5512344457205",
"remaining_tokens": "8986.4987655542795"
"withdrawn_tokens": "3534.547825874935",
"remaining_tokens": "8827.502174125065"
},
{
"address": "0xb091D456d0dFCB94dcba6f355379056C5bb995fC",
@@ -30209,8 +30383,8 @@
"tranche_start": "2021-11-05T00:00:00.000Z",
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "3220305.754003071035812167",
"locked_amount": "4745494.39566203358336223529784765",
"total_removed": "3318543.503199759478065457",
"locked_amount": "4671984.14746482543382160494763163",
"deposits": [
{
"amount": "129284.449",
@@ -30429,6 +30603,56 @@
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0xf026d1a247e312ffc63fdef08f2298e5a40ea3fe1f763a1869bbc79f96413a52"
},
{
"amount": "643.7584181695498715",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x08f245aa9ff7933288360988e2d64c806f12d16394814f99bcf68d07ffa00181"
},
{
"amount": "25568.08330108048809984",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
"tx": "0x2edd28d6d6c1af28f49eefde29ee46bade61185decb9a466b0e3259699c0b873"
},
{
"amount": "9224.162860659198",
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
"tx": "0x2f9f897455367cae34cb84c1db2352d930ecefc55addd474b575656a7cedc217"
},
{
"amount": "1061.23762361202723475",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x6addfa4e2b033e00b8db59a4e80807b1d707668db2caea0f501f4a1b25c5f250"
},
{
"amount": "12063.855243783915",
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
"tx": "0xb48ad3da83a01b03918819494b9dc0cd7da3b524604dc8b6792a89e356f384d5"
},
{
"amount": "7096.654181850842",
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
"tx": "0x1cda21554d02033bc909b593fb177c87317e17875488737625b89c9262099601"
},
{
"amount": "14902.31933949408",
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
"tx": "0x0a840cc1dd827309187b547c11797f88ad8ceac70041574da82c08c375d54ac1"
},
{
"amount": "9935.44459047968",
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
"tx": "0x2a1f660a82b1163b59e68f0547f979bd218be4a69632c30491a71fc60cc65e31"
},
{
"amount": "10645.268077994374",
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
"tx": "0x56978496ef5a52ccbaf15d673cc309b555a0d51b294c21d071d697c39e8f0e6b"
},
{
"amount": "7096.9655595642880472",
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
"tx": "0x22ead1c7f3c9dae483cdc92ba7b302d14224db50b64f3722398daf358a9bf892"
},
{
"amount": "662.4856010075998305",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -32812,6 +33036,18 @@
"tranche_id": 3,
"tx": "0xf026d1a247e312ffc63fdef08f2298e5a40ea3fe1f763a1869bbc79f96413a52"
},
{
"amount": "643.7584181695498715",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x08f245aa9ff7933288360988e2d64c806f12d16394814f99bcf68d07ffa00181"
},
{
"amount": "1061.23762361202723475",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x6addfa4e2b033e00b8db59a4e80807b1d707668db2caea0f501f4a1b25c5f250"
},
{
"amount": "662.4856010075998305",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -34872,8 +35108,8 @@
}
],
"total_tokens": "359123.469575",
"withdrawn_tokens": "242002.63956544498952675",
"remaining_tokens": "117120.83000955501047325"
"withdrawn_tokens": "243707.635607226566633",
"remaining_tokens": "115415.833967773433367"
},
{
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
@@ -35078,6 +35314,12 @@
}
],
"withdrawals": [
{
"amount": "25568.08330108048809984",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
"tranche_id": 3,
"tx": "0x2edd28d6d6c1af28f49eefde29ee46bade61185decb9a466b0e3259699c0b873"
},
{
"amount": "70096.56864144460372878",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
@@ -35314,8 +35556,8 @@
}
],
"total_tokens": "1266324.603486",
"withdrawn_tokens": "831650.73230252039399862",
"remaining_tokens": "434673.87118347960600138"
"withdrawn_tokens": "857218.81560360088209846",
"remaining_tokens": "409105.78788239911790154"
},
{
"address": "0xC5d9221EB9c28A69859264c0A2Fe0d3272228296",
@@ -35717,6 +35959,12 @@
}
],
"withdrawals": [
{
"amount": "7096.654181850842",
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
"tranche_id": 3,
"tx": "0x1cda21554d02033bc909b593fb177c87317e17875488737625b89c9262099601"
},
{
"amount": "2752.406564582654",
"user": "0x97E5985117F47c8d110Be1c422DdCB9bE9b46e62",
@@ -35737,8 +35985,8 @@
}
],
"total_tokens": "31784.9",
"withdrawn_tokens": "14473.699552598202",
"remaining_tokens": "17311.200447401798"
"withdrawn_tokens": "21570.353734449044",
"remaining_tokens": "10214.546265550956"
},
{
"address": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
@@ -35751,6 +35999,12 @@
}
],
"withdrawals": [
{
"amount": "7096.9655595642880472",
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
"tranche_id": 3,
"tx": "0x22ead1c7f3c9dae483cdc92ba7b302d14224db50b64f3722398daf358a9bf892"
},
{
"amount": "10176.8802962853078536",
"user": "0x17d93ca9263fCaEADf29088b3aCa8C290d5423FB",
@@ -35771,8 +36025,8 @@
}
],
"total_tokens": "31786.09544",
"withdrawn_tokens": "14475.072686757359908",
"remaining_tokens": "17311.022753242640092"
"withdrawn_tokens": "21572.0382463216479552",
"remaining_tokens": "10214.0571936783520448"
},
{
"address": "0xbEb7f1B85626Fd9BdA69765d7abb3832C542A62E",
@@ -35800,6 +36054,12 @@
}
],
"withdrawals": [
{
"amount": "9935.44459047968",
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
"tranche_id": 3,
"tx": "0x2a1f660a82b1163b59e68f0547f979bd218be4a69632c30491a71fc60cc65e31"
},
{
"amount": "3853.3118498576",
"user": "0xd4632B682228Db5f38E2283869AEe8c29ee6Eec8",
@@ -35832,8 +36092,8 @@
}
],
"total_tokens": "44499.2",
"withdrawn_tokens": "20264.19825260736",
"remaining_tokens": "24235.00174739264"
"withdrawn_tokens": "30199.64284308704",
"remaining_tokens": "14299.55715691296"
},
{
"address": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
@@ -35846,6 +36106,12 @@
}
],
"withdrawals": [
{
"amount": "14902.31933949408",
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
"tranche_id": 3,
"tx": "0x0a840cc1dd827309187b547c11797f88ad8ceac70041574da82c08c375d54ac1"
},
{
"amount": "5780.03710676496",
"user": "0xe2E6F37cb1f1980418012BF69f43910d6Bc73e73",
@@ -35872,8 +36138,8 @@
}
],
"total_tokens": "66748.8",
"withdrawn_tokens": "30395.990337100992",
"remaining_tokens": "36352.809662899008"
"withdrawn_tokens": "45298.309676595072",
"remaining_tokens": "21450.490323404928"
},
{
"address": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
@@ -35886,6 +36152,12 @@
}
],
"withdrawals": [
{
"amount": "10645.268077994374",
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
"tranche_id": 3,
"tx": "0x56978496ef5a52ccbaf15d673cc309b555a0d51b294c21d071d697c39e8f0e6b"
},
{
"amount": "4128.34689631801",
"user": "0x83BB032E371D7f18195037d85b3A1d459322C20c",
@@ -35912,8 +36184,8 @@
}
],
"total_tokens": "47678.2",
"withdrawn_tokens": "21712.003666243982",
"remaining_tokens": "25966.196333756018"
"withdrawn_tokens": "32357.271744238356",
"remaining_tokens": "15320.928255761644"
},
{
"address": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
@@ -35926,6 +36198,12 @@
}
],
"withdrawals": [
{
"amount": "9224.162860659198",
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
"tranche_id": 3,
"tx": "0x2f9f897455367cae34cb84c1db2352d930ecefc55addd474b575656a7cedc217"
},
{
"amount": "3578.334540394068",
"user": "0xCe068b733CDB8D1455E72Ede39705E209251269f",
@@ -35946,8 +36224,8 @@
}
],
"total_tokens": "41320.2",
"withdrawn_tokens": "18815.657554933032",
"remaining_tokens": "22504.542445066968"
"withdrawn_tokens": "28039.82041559223",
"remaining_tokens": "13280.37958440777"
},
{
"address": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
@@ -35960,6 +36238,12 @@
}
],
"withdrawals": [
{
"amount": "12063.855243783915",
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
"tranche_id": 3,
"tx": "0xb48ad3da83a01b03918819494b9dc0cd7da3b524604dc8b6792a89e356f384d5"
},
{
"amount": "4678.855033842795",
"user": "0xc01F2E57554Bb392384feCA6a54c8E3A3Ca94E42",
@@ -35986,8 +36270,8 @@
}
],
"total_tokens": "54034.5",
"withdrawn_tokens": "24605.627807061795",
"remaining_tokens": "29428.872192938205"
"withdrawn_tokens": "36669.48305084571",
"remaining_tokens": "17365.01694915429"
}
]
},
@@ -35997,7 +36281,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "2147526.429852157556378517",
"locked_amount": "1558070.13269704205809870084381899",
"locked_amount": "1529025.789048046189829286706556968",
"deposits": [
{
"amount": "552496.6455",
@@ -37648,8 +37932,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "9045.246212512296",
"locked_amount": "269820.37143641976017681738102484",
"total_removed": "13621.800119156296",
"locked_amount": "266262.15681262597894487928665652",
"deposits": [
{
"amount": "3000",
@@ -44288,6 +44572,21 @@
"user": "0x20cda61dcB20b8B9eC265973F2B558C864d3e183",
"tx": "0x191c16303f1499f9d499a570f8b071a774ab5e9c54d38500bc1ac76cb1a8d189"
},
{
"amount": "78.04403856",
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
"tx": "0x7ef6e6a8e3fdf0c1afc447073d761a5944dcf44f848b1942d0f3fd13b1f95210"
},
{
"amount": "4325.0301243",
"user": "0x727f82E843617c79c5E5aa7368B92f2C790D8257",
"tx": "0x7c2fd8d9effeb3cf85eab924f679c34fc9da50d9afe33df3ab1a300fb4be5590"
},
{
"amount": "173.479743784",
"user": "0xb2Fb11d69DC52B76fa1Bb06Af05d4fF016cA2836",
"tx": "0x2559939f2ffdbff179b9ba0526892dc332fc076ea858081b56abad8a960fce07"
},
{
"amount": "68.9518436058",
"user": "0xED71B9A9b5633e9d31A0986693658CBbf23c3c1B",
@@ -44996,10 +45295,17 @@
"tx": "0xc764c14bbbb2b0897a712b999fd59c33a9535ed372a51593fe602cba137b0921"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "4325.0301243",
"user": "0x727f82E843617c79c5E5aa7368B92f2C790D8257",
"tranche_id": 5,
"tx": "0x7c2fd8d9effeb3cf85eab924f679c34fc9da50d9afe33df3ab1a300fb4be5590"
}
],
"total_tokens": "10000",
"withdrawn_tokens": "0",
"remaining_tokens": "10000"
"withdrawn_tokens": "4325.0301243",
"remaining_tokens": "5674.9698757"
},
{
"address": "0xA8987205C04A547a4eB3Ae1468221a013553F97D",
@@ -62722,10 +63028,17 @@
"tx": "0xc8541da6a57f410b6faba47a5e5184bae700193b7bd042914fffc562114d92f5"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "173.479743784",
"user": "0xb2Fb11d69DC52B76fa1Bb06Af05d4fF016cA2836",
"tranche_id": 5,
"tx": "0x2559939f2ffdbff179b9ba0526892dc332fc076ea858081b56abad8a960fce07"
}
],
"total_tokens": "400",
"withdrawn_tokens": "0",
"remaining_tokens": "400"
"withdrawn_tokens": "173.479743784",
"remaining_tokens": "226.520256216"
},
{
"address": "0x33f011bfc2Aa2231632E6ACa93751287Ff5f0A02",
@@ -63487,6 +63800,12 @@
}
],
"withdrawals": [
{
"amount": "78.04403856",
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
"tranche_id": 5,
"tx": "0x7ef6e6a8e3fdf0c1afc447073d761a5944dcf44f848b1942d0f3fd13b1f95210"
},
{
"amount": "93.494913748",
"user": "0xb1169C6daAc76bAcaf0D8f87641Fc38fbabe569F",
@@ -63495,8 +63814,8 @@
}
],
"total_tokens": "400",
"withdrawn_tokens": "93.494913748",
"remaining_tokens": "306.505086252"
"withdrawn_tokens": "171.538952308",
"remaining_tokens": "228.461047692"
},
{
"address": "0xF53D81D9f3A1465df9AD1b12ddDB5cC585D96877",
+1 -2
View File
@@ -3,14 +3,13 @@ import { Header } from './components/header';
import { StatsManager } from '@vegaprotocol/network-stats';
import { ThemeContext } from '@vegaprotocol/react-helpers';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { createClient } from './lib/apollo-client';
function App() {
const [theme, toggleTheme] = useThemeSwitcher();
return (
<ThemeContext.Provider value={theme}>
<NetworkLoader createClient={createClient}>
<NetworkLoader>
<div className="w-screen min-h-screen grid pb-6 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
<div className="layout-grid w-screen justify-self-center">
<Header theme={theme} toggleTheme={toggleTheme} />
-52
View File
@@ -1,52 +0,0 @@
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const urlHTTP = new URL(base);
const urlWS = new URL(base);
// Replace http with ws, preserving if its a secure connection eg. https => wss
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
const cache = new InMemoryCache({
typePolicies: {
Query: {},
Account: {
keyFields: false,
fields: {
balanceFormatted: {},
},
},
Node: {
keyFields: false,
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: urlHTTP.href,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
console.log(graphQLErrors);
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}
-1
View File
@@ -14,4 +14,3 @@ NX_VEGA_WALLET_URL=http://localhost:1789
#Test configuration variables
CYPRESS_FAIRGROUND=false
CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS=true
+1
View File
@@ -51,5 +51,6 @@ module.exports = defineConfig({
grepTags: '@regression @smoke @slow',
grepFilterSpecs: true,
grepOmitFiltered: true,
TEARDOWN_NETWORK_AFTER_FLOWS: false,
},
});
@@ -9,8 +9,15 @@
"settlementAsset": "8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4",
"quoteName": "tEuro",
"settlementDataDecimals": 5,
"oracleSpecForSettlementPrice": {
"pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"],
"dataSourceSpecForSettlementData": {
"signers": [
{
"signer": {
"__typename": "ETHAddress",
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
}
}
],
"filters": [
{
"key": {
@@ -26,8 +33,15 @@
}
]
},
"oracleSpecForTradingTermination": {
"pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"],
"dataSourceSpecForTradingTermination": {
"signers": [
{
"signer": {
"__typename": "ETHAddress",
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
}
}
],
"filters": [
{
"key": {
@@ -43,7 +57,7 @@
}
]
},
"oracleSpecBinding": {
"dataSourceSpecBinding": {
"settlementPriceProperty": "prices.BTC.value",
"tradingTerminationProperty": "vegaprotocol.builtin.timestamp"
}
@@ -6,8 +6,15 @@
"future": {
"quoteName": "tEuro",
"settlementDataDecimals": 5,
"oracleSpecForSettlementPrice": {
"pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"],
"dataSourceSpecForSettlementData": {
"signers": [
{
"signer": {
"__typename": "ETHAddress",
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
}
}
],
"filters": [
{
"key": {
@@ -23,8 +30,15 @@
}
]
},
"oracleSpecForTradingTermination": {
"pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"],
"dataSourceSpecForTradingTermination": {
"signers": [
{
"signer": {
"__typename": "ETHAddress",
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
}
}
],
"filters": [
{
"key": {
@@ -40,7 +54,7 @@
}
]
},
"oracleSpecBinding": {
"dataSourceSpecBinding": {
"settlementPriceProperty": "prices.BTC.value",
"tradingTerminationProperty": "vegaprotocol.builtin.timestamp"
}
@@ -414,8 +414,6 @@ context(
.should('be.visible');
}
);
// 3001-VOTE-043
cy.contains('3 days left to vote').should('be.visible');
});
it('Newly created proposal details - shows default status set to fail', function () {
@@ -425,7 +423,6 @@ context(
cy.get_submitted_proposal_from_proposal_list().within(() =>
cy.get(viewProposalButton).click()
);
cy.contains('currently set to fail').should('be.visible');
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
'be.visible'
);
@@ -365,7 +365,7 @@ context(
.contains(2.0, epochTimeout)
.should('be.visible');
cy.get(totalStake, epochTimeout).should('have.text', '2');
cy.get(totalStake, epochTimeout).should('contain.text', '2');
cy.get(stakeShare, epochTimeout).should('have.text', '100%');
cy.navigate_to('staking');
@@ -543,6 +543,7 @@ context(
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_disassociate_all_tokens('wallet');
cy.get(ethWalletContainer).within(() => {
@@ -596,7 +597,7 @@ context(
2.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_disassociate_all_tokens('contract');
cy.get(ethWalletContainer).within(() => {
@@ -648,7 +649,7 @@ context(
2.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_disassociate_tokens('1');
cy.get(ethWalletTotalAssociatedBalance, txTimeout)
@@ -696,7 +697,7 @@ context(
3.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_associate_tokens('4');
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
@@ -732,7 +733,7 @@ context(
3.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_associate_tokens('4', { type: 'contract' });
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
@@ -768,7 +769,7 @@ context(
3.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_associate_tokens('4', { type: 'contract' });
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
@@ -804,8 +805,7 @@ context(
0.0,
txTimeout
);
cy.navigate_to('staking');
cy.close_staking_dialog();
cy.click_on_validator_from_list(1);
@@ -816,7 +816,7 @@ context(
0.0,
txTimeout
);
cy.close_staking_dialog();
cy.staking_page_associate_tokens('6');
cy.get(vegaWallet).within(() => {
@@ -860,8 +860,7 @@ context(
1.0,
txTimeout
);
cy.navigate_to('staking');
cy.close_staking_dialog();
cy.click_on_validator_from_list(0);
@@ -5,7 +5,6 @@ const amountInput = 'amount-input';
const balanceAvailable = 'BALANCE_AVAILABLE_value';
const withdrawalThreshold = 'WITHDRAWAL_THRESHOLD_value';
const delayTime = 'DELAY_TIME_value';
const useMaximum = 'use-maximum';
const submitWithdrawalButton = 'submit-withdrawal';
const dialogTitle = 'dialog-title';
const dialogClose = 'dialog-close';
@@ -37,31 +36,33 @@ context(
cy.navigate_to('withdrawals');
cy.vega_wallet_connect();
cy.ethereum_wallet_connect();
waitForAssetsDisplayed(usdtName);
});
it('Able to open withdrawal form with vega wallet connected', function () {
// needs to reload page for withdrawal form to be displayed in ci - not reproducible outside of ci
cy.getByTestId(withdraw).should('be.visible').click();
cy.visit('/');
cy.navigate_to('withdrawals');
cy.ethereum_wallet_connect();
cy.getByTestId(withdraw).should('be.visible').click();
cy.getByTestId(selectAsset)
.find('option')
.should('have.length.at.least', 5);
.should('have.length.at.least', 2);
cy.getByTestId(ethAddressInput).should('be.visible');
cy.getByTestId(amountInput).should('be.visible');
});
it('Unable to submit withdrawal with invalid fields', function () {
cy.getByTestId(withdraw).should('be.visible').click();
cy.getByTestId(selectAsset).select('BTC (local)');
cy.getByTestId(balanceAvailable).should('have.text', '0.00000');
cy.getByTestId(selectAsset).select(usdtName);
cy.getByTestId(submitWithdrawalButton).click();
cy.getByTestId(formValidationError).should('have.length', 1);
cy.getByTestId(useMaximum).click();
cy.getByTestId(amountInput).clear().click().type('0.0000001');
cy.getByTestId(submitWithdrawalButton).click();
cy.getByTestId(formValidationError).should(
'have.text',
'Value is below minimum'
);
cy.getByTestId(selectAsset).select(usdtName);
cy.getByTestId(amountInput).clear().click().type('10');
cy.getByTestId(ethAddressInput).click().type('123');
cy.getByTestId(submitWithdrawalButton).click();
@@ -216,3 +216,13 @@ Cypress.Commands.add(
});
}
);
Cypress.Commands.add('close_staking_dialog', () => {
cy.getByTestId('dialog-title').should(
'contain.text',
'At the beginning of the next epoch'
);
cy.getByTestId('dialog-content').within(() => {
cy.get('a').should('have.text', 'Back to Staking').click();
});
});
+3 -3
View File
@@ -1,7 +1,7 @@
# App configuration variables
NX_VEGA_ENV=TESTNET
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
NX_VEGA_ENV=STAGNET3
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
NX_VEGA_URL=https://api.n01.stagnet3.vega.xyz/graphql
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_FAIRGROUND=false
+111 -2
View File
@@ -26,9 +26,118 @@ import {
EnvironmentProvider,
NetworkLoader,
} from '@vegaprotocol/environment';
import { createClient } from './lib/apollo-client';
import { createConnectors } from './lib/web3-connectors';
import { ENV } from './config/env';
import type {
FieldFunctionOptions,
InMemoryCacheConfig,
Reference,
} from '@apollo/client';
import { addDecimal } from '@vegaprotocol/react-helpers';
const formatUintToNumber = (amount: string, decimals = 18) =>
addDecimal(amount, decimals).toString();
const createReadField = (fieldName: string) => ({
[`${fieldName}Formatted`]: {
read(_: string, options: FieldFunctionOptions) {
const amount = options.readField(fieldName) as string;
return amount ? formatUintToNumber(amount) : '0';
},
},
});
const cache: InMemoryCacheConfig = {
typePolicies: {
Account: {
keyFields: false,
fields: {
balanceFormatted: {
read(_: string, options: FieldFunctionOptions) {
const balance = options.readField('balance');
const asset = options.readField('asset');
const decimals = options.readField('decimals', asset as Reference);
if (typeof balance !== 'string') return '0';
if (typeof decimals !== 'number') return '0';
return balance && decimals
? formatUintToNumber(balance, decimals)
: '0';
},
},
},
},
Delegation: {
keyFields: false,
// Only get full updates
merge(_, incoming) {
return incoming;
},
fields: {
...createReadField('amount'),
},
},
Reward: {
keyFields: false,
fields: {
...createReadField('amount'),
},
},
RewardPerAssetDetail: {
keyFields: false,
fields: {
...createReadField('totalAmount'),
},
},
Node: {
keyFields: false,
fields: {
...createReadField('pendingStake'),
...createReadField('stakedByOperator'),
...createReadField('stakedByDelegates'),
...createReadField('stakedTotal'),
},
},
NodeData: {
merge: (existing = {}, incoming) => {
return { ...existing, ...incoming };
},
fields: {
...createReadField('stakedTotal'),
},
},
Party: {
fields: {
stake: {
merge(existing, incoming) {
return {
...existing,
...incoming,
};
},
read(stake) {
if (stake) {
return {
...stake,
currentStakeAvailableFormatted: formatUintToNumber(
stake.currentStakeAvailable
),
};
}
return stake;
},
},
},
},
Withdrawal: {
fields: {
pendingOnForeignChain: {
read: (isPending = false) => isPending,
},
},
},
},
};
const Web3Container = ({
chainId,
@@ -129,7 +238,7 @@ const AppContainer = () => {
function App() {
return (
<EnvironmentProvider>
<NetworkLoader createClient={createClient}>
<NetworkLoader cache={cache}>
<AppContainer />
</NetworkLoader>
</EnvironmentProvider>
+1 -1
View File
@@ -206,7 +206,7 @@
"noGovernanceTokens": "You need some VEGA tokens to participate in governance",
"youVoted": "You voted",
"changeVote": "Change vote",
"voteRequested": "Please confirm transaction in wallet",
"txRequested": "Confirm transaction in wallet",
"votePending": "Casting vote",
"voteError": "Something went wrong, and your vote was not seen by the network",
"back": "back",
-150
View File
@@ -1,150 +0,0 @@
import type { FieldFunctionOptions, Reference } from '@apollo/client';
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
import { addDecimal } from '@vegaprotocol/react-helpers';
import sortBy from 'lodash/sortBy';
import uniqBy from 'lodash/uniqBy';
import { deterministicShuffle } from './deterministic-shuffle';
// Create seed in memory. Validator list order will remain the same
// until the page is refreshed.
const VALIDATOR_RANDOMISER_SEED = (
Math.floor(Math.random() * 1000) + 1
).toString();
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const formatUintToNumber = (amount: string, decimals = 18) =>
addDecimal(amount, decimals).toString();
const createReadField = (fieldName: string) => ({
[`${fieldName}Formatted`]: {
read(_: string, options: FieldFunctionOptions) {
const amount = options.readField(fieldName) as string;
return amount ? formatUintToNumber(amount) : '0';
},
},
});
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
nodes: {
// Merge function to make the validator list random but remain consistent
// as the user navigates around the site. If the user refreshes the list
// will be randomised.
merge: (existing = [], incoming) => {
// uniqBy will take the first of any matches
const uniq = uniqBy([...incoming, ...existing], 'id');
// sort result so that the input is consistent
const sorted = sortBy(uniq, 'id');
// randomise based on seed string
const random = deterministicShuffle(
VALIDATOR_RANDOMISER_SEED,
sorted
);
return random;
},
},
},
},
Account: {
keyFields: false,
fields: {
balanceFormatted: {
read(_: string, options: FieldFunctionOptions) {
const balance = options.readField('balance');
const asset = options.readField('asset');
const decimals = options.readField(
'decimals',
asset as Reference
);
if (typeof balance !== 'string') return '0';
if (typeof decimals !== 'number') return '0';
return balance && decimals
? formatUintToNumber(balance, decimals)
: '0';
},
},
},
},
Delegation: {
keyFields: false,
// Only get full updates
merge(_, incoming) {
return incoming;
},
fields: {
...createReadField('amount'),
},
},
Reward: {
keyFields: false,
fields: {
...createReadField('amount'),
},
},
RewardPerAssetDetail: {
keyFields: false,
fields: {
...createReadField('totalAmount'),
},
},
Node: {
keyFields: false,
fields: {
...createReadField('pendingStake'),
...createReadField('stakedByOperator'),
...createReadField('stakedByDelegates'),
...createReadField('stakedTotal'),
},
},
NodeData: {
merge: (existing = {}, incoming) => {
return { ...existing, ...incoming };
},
fields: {
...createReadField('stakedTotal'),
},
},
Withdrawal: {
fields: {
pendingOnForeignChain: {
read: (isPending = false) => isPending,
},
},
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: base,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
// eslint-disable-next-line no-console
console.log(graphQLErrors);
// eslint-disable-next-line no-console
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}
@@ -1,111 +0,0 @@
import {
stringTo32BitHash,
createRandomGenerator,
deterministicShuffle,
} from './deterministic-shuffle';
it('Converts a string to a hash as expected', () => {
expect(stringTo32BitHash('test')).toEqual(1706);
expect(stringTo32BitHash('0x0ddba11')).toEqual(31040);
expect(stringTo32BitHash('Rhosllannerchrugog')).toEqual(27853302);
});
it('Random generator is deterministic by seed: matching output', () => {
const genSeedOne = createRandomGenerator(1);
const anotherGenSeedOne = createRandomGenerator(1);
expect(genSeedOne()).toEqual(anotherGenSeedOne());
expect(genSeedOne()).toEqual(anotherGenSeedOne());
expect(genSeedOne()).toEqual(anotherGenSeedOne());
// Throw a result away so they are out of step
genSeedOne();
expect(genSeedOne()).not.toEqual(anotherGenSeedOne());
});
it('Random generator is deterministic by seed: non-matching output', () => {
const genSeedOne = createRandomGenerator(1);
const genSeedTwo = createRandomGenerator(2);
expect(genSeedOne()).not.toEqual(genSeedTwo());
expect(genSeedOne()).not.toEqual(genSeedTwo());
expect(genSeedOne()).not.toEqual(genSeedTwo());
});
it('Random generator is deterministic by seed: switching seed overrides original seed and produces deterministic output', () => {
const genSeedOne = createRandomGenerator(1);
const genSeedTwo = createRandomGenerator(2);
const firstTwoSeed = genSeedTwo();
expect(genSeedOne()).not.toEqual(firstTwoSeed);
const secondTwoSeed = genSeedTwo();
expect(genSeedOne()).not.toEqual(secondTwoSeed);
expect(genSeedOne(2)).toEqual(firstTwoSeed);
expect(genSeedOne()).toEqual(secondTwoSeed);
});
it('deterministicShuffle shuffles deterministically: strings', () => {
const defaultInputStrings = ['one', 'two', 'three', 'four', 'five'];
const testSeedOne = deterministicShuffle('test', defaultInputStrings);
const testSeedTwo = deterministicShuffle('test', defaultInputStrings);
const testSeedThree = deterministicShuffle('test', defaultInputStrings);
expect(testSeedOne).toEqual(['three', 'four', 'one', 'two', 'five']);
expect(testSeedTwo).not.toEqual(testSeedOne);
expect(testSeedThree).not.toEqual(testSeedOne);
const altSeedOne = deterministicShuffle(
'anything-except-test',
defaultInputStrings
);
expect(altSeedOne).not.toEqual(testSeedOne);
});
it('deterministicShuffle shuffles deterministically: numbers', () => {
const defaultInputNumbers = [1, 2, 3, 4, 5];
const testSeedOne = deterministicShuffle('test', defaultInputNumbers);
const testSeedTwo = deterministicShuffle('test', defaultInputNumbers);
const testSeedThree = deterministicShuffle('test', defaultInputNumbers);
expect(testSeedOne).toEqual([3, 4, 1, 2, 5]);
expect(testSeedTwo).not.toEqual(testSeedOne);
expect(testSeedThree).not.toEqual(testSeedOne);
const altSeedOne = deterministicShuffle(
'anything-except-test',
defaultInputNumbers
);
expect(altSeedOne).not.toEqual(testSeedOne);
});
it('deterministicShuffle shuffles deterministically: objects', () => {
const defaultInputObjects = [
{ test: 1 },
{ test: 2 },
{ test: 3 },
{ test: 4 },
{ test: 5 },
];
const testSeedOne = deterministicShuffle('test', defaultInputObjects);
const testSeedTwo = deterministicShuffle('test', defaultInputObjects);
const testSeedThree = deterministicShuffle('test', defaultInputObjects);
expect(testSeedOne).toEqual([
{ test: 3 },
{ test: 4 },
{ test: 1 },
{ test: 2 },
{ test: 5 },
]);
expect(testSeedTwo).not.toEqual(testSeedOne);
expect(testSeedThree).not.toEqual(testSeedOne);
const altSeedOne = deterministicShuffle(
'anything-except-test',
defaultInputObjects
);
expect(altSeedOne).not.toEqual(testSeedOne);
});
@@ -1,36 +0,0 @@
// creates a random number generator function.
export function createRandomGenerator(seed: number) {
const a = 5486230734; // some big numbers
const b = 6908969830;
const m = 9853205067;
let x = seed;
// returns a random value 0 <= num < 1
return function (seed = x) {
// seed is optional. If supplied sets a new seed
x = (seed * a + b) % m;
return x / m;
};
}
// function creates a 32bit hash of a string
export function stringTo32BitHash(str: string) {
let v = 0;
for (let i = 0; i < str.length; i += 1) {
v += str.charCodeAt(i) << i % 24;
}
return v % 0xffffffff;
}
// shuffle array using the str as a key.
export function deterministicShuffle(
str: string,
arr: Array<string | number | object>
) {
const rArr = [];
const random = createRandomGenerator(stringTo32BitHash(str));
while (arr.length > 1) {
rArr.push(arr.splice(Math.floor(random() * arr.length), 1)[0]);
}
rArr.push(arr[0]);
return rArr;
}
@@ -10,7 +10,7 @@ interface VoteTransactionDialogProps {
const dialogTitle = (voteState: VoteState): string | undefined => {
switch (voteState) {
case VoteState.Requested:
return t('voteRequested');
return t('txRequested');
case VoteState.Pending:
return t('votePending');
default:
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
import { ProposalState, ProposalRejectionReason, PropertyKeyType, ConditionOperator, VoteValue } from "@vegaprotocol/types";
import { ProposalState, ProposalRejectionReason, ConditionOperator, PropertyKeyType, VoteValue } from "@vegaprotocol/types";
// ====================================================
// GraphQL query operation: Proposal
@@ -61,19 +61,7 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProdu
quantum: string;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters_conditions {
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
@@ -85,35 +73,34 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProdu
value: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters_conditions[] | null;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData {
__typename: "OracleSpecConfiguration";
/**
* The list of authorised public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
*/
pubKeys: string[] | null;
/**
* Filters describes which oracle data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData_filters[] | null;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters_key {
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export type Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey | Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
@@ -125,7 +112,7 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProdu
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters_conditions {
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
@@ -137,36 +124,151 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProdu
value: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters {
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
* key is the data source data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters_key;
key: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters_conditions[] | null;
conditions: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination {
__typename: "OracleSpecConfiguration";
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* The list of authorised public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
pubKeys: string[] | null;
signers: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* Filters describes which oracle data are considered of interest or not for
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination_filters[] | null;
filters: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecBinding {
__typename: "OracleSpecToFutureBinding";
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType = Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal | Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData {
__typename: "DataSourceDefinition";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData_sourceType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
/**
* The value to compare against.
*/
value: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export type Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey | Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
/**
* The value to compare against.
*/
value: string | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* key is the data source data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
signers: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType = Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal | Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal;
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination {
__typename: "DataSourceDefinition";
sourceType: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination_sourceType;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecBinding {
__typename: "DataSourceSpecToFutureBinding";
settlementDataProperty: string;
tradingTerminationProperty: string;
}
@@ -186,18 +288,18 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument_futureProdu
*/
settlementDataDecimals: number;
/**
* Describes the oracle data that an instrument wants to get from the oracle engine for settlement data.
* Describes the data source data that an instrument wants to get from the data source engine for settlement data.
*/
oracleSpecForSettlementData: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForSettlementData;
dataSourceSpecForSettlementData: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForSettlementData;
/**
* Describes the oracle data that an instrument wants to get from the oracle engine for trading termination.
* Describes the source data that an instrument wants to get from the data source engine for trading termination.
*/
oracleSpecForTradingTermination: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecForTradingTermination;
dataSourceSpecForTradingTermination: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecForTradingTermination;
/**
* OracleSpecToFutureBinding tells on which property oracle data should be
* DataSourceSpecToFutureBinding tells on which property source data should be
* used as settlement data.
*/
oracleSpecBinding: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_oracleSpecBinding;
dataSourceSpecBinding: Proposal_proposal_terms_change_NewMarket_instrument_futureProduct_dataSourceSpecBinding;
}
export interface Proposal_proposal_terms_change_NewMarket_instrument {
@@ -232,19 +334,7 @@ export interface Proposal_proposal_terms_change_NewMarket {
instrument: Proposal_proposal_terms_change_NewMarket_instrument;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters_conditions {
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
@@ -256,35 +346,34 @@ export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfigu
value: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters_conditions[] | null;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData {
__typename: "OracleSpecConfiguration";
/**
* The list of authorised public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
*/
pubKeys: string[] | null;
/**
* Filters describes which oracle data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData_filters[] | null;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters_key {
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export type Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey | Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
@@ -296,7 +385,7 @@ export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfigu
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters_conditions {
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
@@ -308,36 +397,151 @@ export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfigu
value: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters {
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* The oracle data property key targeted by the filter.
* key is the data source data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters_key;
key: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters_conditions[] | null;
conditions: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination {
__typename: "OracleSpecConfiguration";
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* The list of authorised public keys that signed the data for this
* oracle. All the public keys in the oracle data should be contained in these
* public keys.
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
pubKeys: string[] | null;
signers: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* Filters describes which oracle data are considered of interest or not for
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination_filters[] | null;
filters: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecBinding {
__typename: "OracleSpecToFutureBinding";
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType = Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionInternal | Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType_DataSourceDefinitionExternal;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData {
__typename: "DataSourceDefinition";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData_sourceType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
/**
* The value to compare against.
*/
value: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType {
__typename: "DataSourceSpecConfigurationTime";
conditions: (Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType_conditions | null)[];
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal {
__typename: "DataSourceDefinitionInternal";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal_sourceType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey {
__typename: "PubKey";
key: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress {
__typename: "ETHAddress";
address: string | null;
}
export type Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer = Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_PubKey | Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer_ETHAddress;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers {
__typename: "Signer";
signer: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers_signer;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_key {
__typename: "PropertyKey";
/**
* The name of the property.
*/
name: string | null;
/**
* The type of the property.
*/
type: PropertyKeyType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions {
__typename: "Condition";
/**
* The type of comparison to make on the value.
*/
operator: ConditionOperator;
/**
* The value to compare against.
*/
value: string | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters {
__typename: "Filter";
/**
* key is the data source data property key targeted by the filter.
*/
key: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_key;
/**
* The conditions that should be matched by the data to be
* considered of interest.
*/
conditions: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters_conditions[] | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType {
__typename: "DataSourceSpecConfiguration";
/**
* signers is the list of authorized signatures that signed the data for this
* data source. All the public keys in the data should be contained in this
* list.
*/
signers: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_signers[] | null;
/**
* filters describes which source data are considered of interest or not for
* the product (or the risk model).
*/
filters: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType_filters[] | null;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal {
__typename: "DataSourceDefinitionExternal";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal_sourceType;
}
export type Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType = Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionInternal | Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType_DataSourceDefinitionExternal;
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination {
__typename: "DataSourceDefinition";
sourceType: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination_sourceType;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecBinding {
__typename: "DataSourceSpecToFutureBinding";
settlementDataProperty: string;
tradingTerminationProperty: string;
}
@@ -345,9 +549,9 @@ export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfigu
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product {
__typename: "UpdateFutureProduct";
quoteName: string;
oracleSpecForSettlementData: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForSettlementData;
oracleSpecForTradingTermination: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecForTradingTermination;
oracleSpecBinding: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_oracleSpecBinding;
dataSourceSpecForSettlementData: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForSettlementData;
dataSourceSpecForTradingTermination: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecForTradingTermination;
dataSourceSpecBinding: Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument_product_dataSourceSpecBinding;
}
export interface Proposal_proposal_terms_change_UpdateMarket_updateMarketConfiguration_instrument {
@@ -46,33 +46,87 @@ export const PROPOSAL_QUERY = gql`
}
quoteName
settlementDataDecimals
oracleSpecForSettlementData {
pubKeys
filters {
key {
name
type
dataSourceSpecForSettlementData {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
}
}
}
}
conditions {
operator
value
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
}
oracleSpecForTradingTermination {
pubKeys
filters {
key {
name
type
dataSourceSpecForTradingTermination {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
}
}
}
}
conditions {
operator
value
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
}
oracleSpecBinding {
dataSourceSpecBinding {
settlementDataProperty
tradingTerminationProperty
}
@@ -86,33 +140,87 @@ export const PROPOSAL_QUERY = gql`
code
product {
quoteName
oracleSpecForSettlementData {
pubKeys
filters {
key {
name
type
dataSourceSpecForSettlementData {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
}
}
}
}
conditions {
operator
value
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
}
oracleSpecForTradingTermination {
pubKeys
filters {
key {
name
type
dataSourceSpecForTradingTermination {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
}
}
}
}
conditions {
operator
value
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
}
oracleSpecBinding {
dataSourceSpecBinding {
settlementDataProperty
tradingTerminationProperty
}
@@ -3,15 +3,22 @@ import { useTranslation } from 'react-i18next';
interface StakeFailureProps {
nodeName: string;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeFailure = ({ nodeName }: StakeFailureProps) => {
export const StakeFailure = ({
nodeName,
isDialogVisible,
toggleDialog,
}: StakeFailureProps) => {
const { t } = useTranslation();
return (
<Dialog
intent={Intent.Danger}
title={t('Something went wrong')}
open={true}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>
{t('stakeFailed', {
@@ -7,12 +7,16 @@ interface StakePendingProps {
action: StakeAction;
amount: string;
nodeName: string;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakePending = ({
action,
amount,
nodeName,
isDialogVisible,
toggleDialog,
}: StakePendingProps) => {
const { t } = useTranslation();
const titleArgs = { amount, node: nodeName };
@@ -22,7 +26,12 @@ export const StakePending = ({
: t('stakeRemovePendingTitle', titleArgs);
return (
<Dialog icon={<Loader size="small" />} title={title} open={true}>
<Dialog
icon={<Loader size="small" />}
title={title}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>{t('timeForConfirmation')}</p>
</Dialog>
);
@@ -0,0 +1,25 @@
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import React from 'react';
interface StakeRequestedProps {
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeRequested = ({
isDialogVisible,
toggleDialog,
}: StakeRequestedProps) => {
const { t } = useTranslation();
return (
<Dialog
title={t('txRequested')}
intent={Intent.Warning}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>{t('stakingConfirm')}</p>
</Dialog>
);
};
@@ -10,6 +10,8 @@ interface StakeSuccessProps {
amount: string;
nodeName: string;
removeType: RemoveType;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeSuccess = ({
@@ -17,6 +19,8 @@ export const StakeSuccess = ({
amount,
nodeName,
removeType,
isDialogVisible,
toggleDialog,
}: StakeSuccessProps) => {
const { t } = useTranslation();
const isAdd = action === Actions.Add;
@@ -34,7 +38,8 @@ export const StakeSuccess = ({
icon={<Icon name="tick" />}
intent={Intent.Success}
title={title}
open={true}
open={isDialogVisible}
onChange={toggleDialog}
>
<div>
<p>{message}</p>
@@ -0,0 +1,67 @@
import { StakeFailure } from './stake-failure';
import { StakeRequested } from './stake-requested';
import { StakePending } from './stake-pending';
import { StakeSuccess } from './stake-success';
import { FormState } from './staking-form';
import type { RemoveType, StakeAction } from './staking-form';
interface StakeFormTxStatusesProps {
formState: FormState;
nodeName: string;
amount: string;
action: StakeAction;
removeType: RemoveType;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakingFormTxStatuses = ({
formState,
nodeName,
amount,
action,
removeType,
isDialogVisible,
toggleDialog,
}: StakeFormTxStatusesProps) => {
switch (formState) {
case FormState.Requested:
return (
<StakeRequested
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
case FormState.Pending:
return (
<StakePending
action={action}
amount={amount}
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
case FormState.Success:
return (
<StakeSuccess
action={action}
amount={amount}
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
removeType={removeType}
/>
);
case FormState.Failure:
return (
<StakeFailure
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
default:
return null;
}
};
@@ -1,6 +1,6 @@
import { gql, useApolloClient } from '@apollo/client';
import * as Sentry from '@sentry/react';
import React from 'react';
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
@@ -12,14 +12,10 @@ import type {
PartyDelegations,
PartyDelegationsVariables,
} from './__generated__/PartyDelegations';
import { StakeFailure } from './stake-failure';
import { StakePending } from './stake-pending';
import { StakeSuccess } from './stake-success';
import { StakingFormTxStatuses } from './staking-form-tx-statuses';
import {
ButtonLink,
Dialog,
FormGroup,
Intent,
Radio,
RadioGroup,
} from '@vegaprotocol/ui-toolkit';
@@ -54,7 +50,7 @@ export const PARTY_DELEGATIONS_QUERY = gql`
}
`;
enum FormState {
export enum FormState {
Default,
Requested,
Pending,
@@ -93,6 +89,7 @@ export const StakingForm = ({
const { appState } = useAppState();
const { sendTx } = useVegaWallet();
const [formState, setFormState] = React.useState(FormState.Default);
const [isDialogVisible, setIsDialogVisible] = useState(false);
const { t } = useTranslation();
const [action, setAction] = React.useState<StakeAction>(
params.action as StakeAction
@@ -129,6 +126,7 @@ export const StakingForm = ({
async function onSubmit() {
setFormState(FormState.Requested);
setIsDialogVisible(true);
const delegateInput: DelegateSubmissionBody = {
delegateSubmission: {
nodeId,
@@ -196,43 +194,24 @@ export const StakingForm = ({
return () => clearInterval(interval);
}, [formState, client, pubKey, nodeId]);
if (formState === FormState.Failure) {
return <StakeFailure nodeName={nodeName} />;
} else if (formState === FormState.Requested) {
return (
<Dialog
title="Confirm transaction in wallet"
intent={Intent.Warning}
open={true}
>
<p>{t('stakingConfirm')}</p>
</Dialog>
);
} else if (formState === FormState.Pending) {
return <StakePending action={action} amount={amount} nodeName={nodeName} />;
} else if (formState === FormState.Success) {
return (
<StakeSuccess
action={action}
amount={amount}
nodeName={nodeName}
removeType={removeType}
/>
);
} else if (
availableStakeToAdd.isEqualTo(0) &&
availableStakeToRemove.isEqualTo(0)
) {
if (appState.lien.isGreaterThan(0)) {
return <span className="text-red">{t('stakeNodeWrongVegaKey')}</span>;
} else {
return <span className="text-red">{t('stakeNodeNone')}</span>;
}
}
const toggleDialog = useCallback(() => {
setIsDialogVisible(!isDialogVisible);
}, [isDialogVisible]);
return (
<>
<h2>{t('Manage your stake')}</h2>
{formState === FormState.Default &&
availableStakeToAdd.isEqualTo(0) &&
availableStakeToRemove.isEqualTo(0) && (
<div>
{appState.lien.isGreaterThan(0) ? (
<span className="text-red">{t('stakeNodeWrongVegaKey')}</span>
) : (
<span className="text-red">{t('stakeNodeNone')}</span>
)}
</div>
)}
<FormGroup
label={t('Select if you want to add or remove stake')}
labelFor="radio-stake-options"
@@ -331,6 +310,15 @@ export const StakingForm = ({
)}
</>
)}
<StakingFormTxStatuses
formState={formState}
nodeName={nodeName}
amount={amount}
action={action}
removeType={removeType}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
</>
);
};
+12 -4
View File
@@ -1,3 +1,5 @@
import { connectVegaWallet } from '../support/vega-wallet';
const connectEthWalletBtn = 'connect-eth-wallet-btn';
const assetSelectField = 'select[name="asset"]';
const toAddressField = 'input[name="to"]';
@@ -9,8 +11,14 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
cy.mockWeb3Provider();
cy.mockGQLSubscription();
cy.mockTradingPage();
cy.visit('/#/portfolio/deposit');
cy.visit('/#/portfolio');
cy.get('main[data-testid="/portfolio"]').should('exist');
cy.getByTestId('Deposits').click();
cy.getByTestId('tab-deposits').contains('Connect your Vega wallet');
connectVegaWallet();
// validateFillsDisplayed();
cy.getByTestId('deposit-button').click();
// Deposit page requires connection Ethereum wallet first
cy.getByTestId(connectEthWalletBtn).click();
cy.getByTestId('web3-connector-MetaMask').click();
@@ -19,11 +27,11 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
});
it('handles empty fields', () => {
// Submit form to trigger any empty validaion messages
// Submit form to trigger any empty validation messages
cy.getByTestId('deposit-submit').click();
cy.getByTestId(formFieldError).should('contain.text', 'Required');
cy.getByTestId(formFieldError).should('have.length', 3);
cy.getByTestId(formFieldError).should('have.length', 2);
// Invalid public key
cy.get(toAddressField)
@@ -64,7 +72,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
cy.get('#ethereum-address').should('have.value', ethWalletAddress).click();
cy.getByTestId('dialog-content').within(() => {
cy.get('p').should('have.text', `Connected with ${ethWalletAddress}`);
cy.get('button')
cy.getByTestId('disconnect-ethereum-wallet')
.should('have.text', 'Disconnect Ethereum Wallet')
.click();
});
@@ -219,7 +219,7 @@ describe('market states', { tags: '@smoke' }, function () {
states.forEach((marketState) => {
describe(marketState, function () {
before(function () {
beforeEach(function () {
cy.mockTradingPage(marketState);
cy.mockGQLSubscription();
cy.visit('/#/markets/market-0');
@@ -121,6 +121,43 @@ const testOrder = (order: Order, expected?: Partial<Order>) => {
cy.getByTestId('dialog-close').click();
};
const clearPersistedOrder = () => {
cy.clearLocalStorage().should((ls) => {
expect(ls.getItem('deal-ticket-order-market-0')).to.be.null;
});
};
beforeEach(() => clearPersistedOrder());
afterEach(() => clearPersistedOrder());
describe('time in force default values', () => {
before(() => {
cy.mockTradingPage();
cy.mockGQLSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Market');
connectVegaWallet();
});
it('must have market order set up to IOC by default', function () {
//7002-SORD-031
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
});
it('must have time in force set to GTC for limit order', function () {
//7002-SORD-031
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTC')[0].text
);
});
});
describe('must submit order', { tags: '@smoke' }, () => {
// 7002-SORD-039
before(() => {
@@ -181,13 +218,14 @@ describe('must submit order', { tags: '@smoke' }, () => {
it('successfully places GTT limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '1.00',
timeInForce: 'TIME_IN_FORCE_GTT',
expiresAt: '2022-01-01T00:00',
expiresAt: expiresAt.toISOString().substring(0, 16),
};
testOrder(order, {
price: '100000',
@@ -202,6 +240,183 @@ describe('must submit order', { tags: '@smoke' }, () => {
});
});
describe(
'must submit order for market in batch auction',
{ tags: '@regression' },
() => {
before(() => {
cy.mockTradingPage(
MarketState.STATE_PENDING,
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
);
cy.mockGQLSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Market');
connectVegaWallet();
});
it('successfully places limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_BUY',
size: '100',
price: '200',
timeInForce: 'TIME_IN_FORCE_GTC',
};
testOrder(order, { price: '20000000' });
});
it('successfully places limit sell order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '50000',
timeInForce: 'TIME_IN_FORCE_GFN',
};
testOrder(order, { price: '5000000000' });
});
it('successfully places GTT limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '1.00',
timeInForce: 'TIME_IN_FORCE_GTT',
expiresAt: '2022-01-01T00:00',
};
testOrder(order, {
price: '100000',
expiresAt:
new Date(order.expiresAt as string).getTime().toString() + '000000',
});
});
}
);
describe(
'must submit order for market in batch auction',
{ tags: '@regression' },
() => {
before(() => {
cy.mockTradingPage(
MarketState.STATE_PENDING,
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
);
cy.mockGQLSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Market');
connectVegaWallet();
});
it('successfully places limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_BUY',
size: '100',
price: '200',
timeInForce: 'TIME_IN_FORCE_GTC',
};
testOrder(order, { price: '20000000' });
});
it('successfully places limit sell order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '50000',
timeInForce: 'TIME_IN_FORCE_GFN',
};
testOrder(order, { price: '5000000000' });
});
it('successfully places GTT limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '1.00',
timeInForce: 'TIME_IN_FORCE_GTT',
expiresAt: '2022-01-01T00:00',
};
testOrder(order, {
price: '100000',
expiresAt:
new Date(order.expiresAt as string).getTime().toString() + '000000',
});
});
}
);
describe(
'must submit order for market in batch auction',
{ tags: '@regression' },
() => {
before(() => {
cy.mockTradingPage(
MarketState.STATE_PENDING,
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
);
cy.mockGQLSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Market');
connectVegaWallet();
});
it('successfully places limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_BUY',
size: '100',
price: '200',
timeInForce: 'TIME_IN_FORCE_GTC',
};
testOrder(order, { price: '20000000' });
});
it('successfully places limit sell order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '50000',
timeInForce: 'TIME_IN_FORCE_GFN',
};
testOrder(order, { price: '5000000000' });
});
it('successfully places GTT limit buy order', () => {
cy.mockVegaCommandSync(mockTx);
const order: Order = {
type: 'TYPE_LIMIT',
side: 'SIDE_SELL',
size: '100',
price: '1.00',
timeInForce: 'TIME_IN_FORCE_GTT',
expiresAt: '2022-01-01T00:00',
};
testOrder(order, {
price: '100000',
expiresAt:
new Date(order.expiresAt as string).getTime().toString() + '000000',
});
});
}
);
describe('deal ticket validation', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockTradingPage();
@@ -259,6 +474,7 @@ describe('deal ticket size validation', { tags: '@smoke' }, function () {
});
it('must warn if order size input has too many digits after the decimal place', function () {
//7002-SORD-016
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('1.234');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
@@ -270,6 +486,7 @@ describe('deal ticket size validation', { tags: '@smoke' }, function () {
});
it('must warn if order size is set to 0', function () {
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('0');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
@@ -285,6 +502,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
before(() => {
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
connectVegaWallet();
cy.wait('@Market');
cy.getByTestId(toggleLimit).click();
});
@@ -296,9 +514,23 @@ describe('limit order validations', { tags: '@smoke' }, () => {
.should('have.text', 'Price (BTC)');
});
it.skip('must see warning when placing an order with expiry date in past', function () {
// Test to be created after the bug below is fixed
// https://github.com/vegaprotocol/frontend-monorepo/issues/1694
it('must see warning when placing an order with expiry date in past', function () {
const expiresAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const expiresAtInputValue = expiresAt.toISOString().substring(0, 16);
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('0.1');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.log('choosing yesterday');
cy.getByTestId('date-picker-field').type(expiresAtInputValue);
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId('dealticket-error-message-force').should(
'have.text',
'The expiry date that you have entered appears to be in the past'
);
});
it.skip('must receive warning if price has too many digits after decimal place', function () {
@@ -307,14 +539,6 @@ describe('limit order validations', { tags: '@smoke' }, () => {
});
describe('time in force validations', function () {
it('must have limit order set to GTC by default', function () {
//7002-SORD-031
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTC')[0].text
);
});
const validTIF = TIFlist;
validTIF.forEach((tif) => {
//7002-SORD-023
@@ -368,14 +592,6 @@ describe('market order validations', { tags: '@smoke' }, () => {
});
describe('time in force validations', function () {
it('must have market order set up to IOC by default', function () {
//7002-SORD-031
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
});
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
const invalidTIF = TIFlist.filter(
(tif) => !['FOK', 'IOC'].includes(tif.code)
@@ -430,6 +646,8 @@ describe('suspended market validation', { tags: '@regression' }, () => {
});
it('should show info for allowed TIF', function () {
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('0.1');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(placeOrderBtn).should('be.enabled');
cy.getByTestId(errorMessage).should(
'have.text',
@@ -10,7 +10,7 @@ describe('withdraw', { tags: '@smoke' }, () => {
const submitWithdrawBtn = 'submit-withdrawal';
const ethAddressValue = Cypress.env('ETHEREUM_WALLET_ADDRESS');
const asset1Name = 'Sepolia tBTC';
const asset2Name = 'Sepolia tUSDC';
const asset2Name = 'Euro';
beforeEach(() => {
cy.mockWeb3Provider();
@@ -52,7 +52,7 @@ describe('withdraw', { tags: '@smoke' }, () => {
});
it('max amount', () => {
selectAsset(asset2Name); // Will be above maximum because the vega wallet doesnt have any collateral
cy.get(amountField).clear().type('1');
cy.get(amountField).clear().type('1001', { delay: 100 });
cy.getByTestId(submitWithdrawBtn).click();
cy.get('[data-testid="input-error-text"]').should(
'contain.text',

Some files were not shown because too many files have changed in this diff Show More