Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dadc6141e8 | ||
|
|
13c1044f8e | ||
|
|
cf9f313e4c | ||
|
|
f56d34fe6e | ||
|
|
1379366caa | ||
|
|
8958c12fe3 | ||
|
|
fef13874db | ||
|
|
40f02ecf89 | ||
|
|
41cd6b1455 | ||
|
|
3cd393dac0 | ||
|
|
a52e60d6a2 | ||
|
|
bc13f1b359 | ||
|
|
eb81f4ae44 | ||
|
|
51ab02a2e2 | ||
|
|
ffada1b93d | ||
|
|
8a3657a9b9 | ||
|
|
a59f7dfd29 | ||
|
|
61471228aa | ||
|
|
70d748fb15 |
@@ -77,6 +77,7 @@
|
||||
"fixStyle": "inline-type-imports"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-useless-constructor": 0,
|
||||
"curly": ["error", "multi-line"]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Time } from '../time';
|
||||
import { sideText, statusText, tifFull, tifShort } from './lib/order-labels';
|
||||
import SizeInMarket from '../size-in-market/size-in-market';
|
||||
import { TxOrderPeggedReference } from '../txs/details/order/tx-order-peg';
|
||||
import { OrderTypeMapping } from '@vegaprotocol/types';
|
||||
|
||||
export interface DeterministicOrderDetailsProps {
|
||||
id: string;
|
||||
@@ -69,7 +70,7 @@ const DeterministicOrderDetails = ({
|
||||
<span className="mx-5 text-base">@</span>
|
||||
<PriceInMarket price={o.price} marketId={o.market.id} />
|
||||
</h2>
|
||||
<p className="text-gray-200">
|
||||
<p className="text-gray-400 dark:text-gray-600">
|
||||
In <MarketLink id={o.market.id} /> at <Time date={o.createdAt} />.
|
||||
</p>
|
||||
{o.peggedOrder ? (
|
||||
@@ -83,13 +84,12 @@ const DeterministicOrderDetails = ({
|
||||
/>
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{o.reference ? (
|
||||
<p className="text-gray-500 mt-4">
|
||||
<span>{t('Reference')}</span>: {o.reference}
|
||||
</p>
|
||||
) : null}
|
||||
<div className="grid md:grid-cols-4 gap-x-6 mt-4">
|
||||
<div className="grid md:grid-cols-5 gap-x-6 mt-4">
|
||||
<div className="mb-12 md:mb-0">
|
||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
||||
{t('Status')}
|
||||
@@ -114,6 +114,16 @@ const DeterministicOrderDetails = ({
|
||||
{o.version}
|
||||
</h5>
|
||||
</div>
|
||||
{o.type ? (
|
||||
<div className="">
|
||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
||||
{t('Type')}
|
||||
</h2>
|
||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
||||
{OrderTypeMapping[o.type]}
|
||||
</h5>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,6 +80,12 @@ export function getLabelForOrderType(
|
||||
if (command.orderSubmission.icebergOpts) {
|
||||
return 'Iceberg';
|
||||
}
|
||||
if (command.orderSubmission.type === 'TYPE_MARKET') {
|
||||
return 'Market order';
|
||||
}
|
||||
if (command.orderSubmission.type === 'TYPE_LIMIT') {
|
||||
return 'Limit order';
|
||||
}
|
||||
}
|
||||
return 'Order';
|
||||
}
|
||||
|
||||
@@ -49,12 +49,8 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
|
||||
? activeProvider
|
||||
: defaultProvider;
|
||||
|
||||
if (
|
||||
account &&
|
||||
activeProvider &&
|
||||
typeof activeProvider.getSigner === 'function'
|
||||
) {
|
||||
signer = provider.getSigner();
|
||||
if (account && provider && typeof provider.getSigner === 'function') {
|
||||
signer = provider.getSigner(account);
|
||||
}
|
||||
|
||||
const tokenVestingAddress =
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ export const ProposalReferralProgramDetails = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
const benefitTiers = proposal?.terms?.change?.benefitTiers;
|
||||
const stakingTiers = proposal?.terms?.change?.stakingTiers;
|
||||
const benefitTiers = proposal?.terms?.change?.benefitTiers.slice();
|
||||
const stakingTiers = proposal?.terms?.change?.stakingTiers.slice();
|
||||
const windowLength = proposal?.terms?.change?.windowLength;
|
||||
const endOfProgramTimestamp = proposal?.terms?.change?.endOfProgram;
|
||||
|
||||
|
||||
@@ -104,6 +104,10 @@
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.react-markdown-container a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.jsondiffpatch-delta,
|
||||
.jsondiffpatch-delta pre {
|
||||
font-family: 'Roboto Mono', monospace !important;
|
||||
|
||||
+8
-4
@@ -3,16 +3,17 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_CHROME_EXTENSION_URL=https://chrome.google.com/webstore/detail/vega-wallet-fairground/nmmjkiafpmphlikhefgjbblebfgclikn
|
||||
NX_MOZILLA_EXTENSION_URL=https://addons.mozilla.org/firefox/addon/vega-wallet-fairground
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
@@ -25,3 +26,6 @@ NX_ICEBERG_ORDERS=true
|
||||
# NX_PRODUCT_PERPETUALS
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.testnet.vega.xyz/websocket
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect } from 'react';
|
||||
import { titlefy } from '@vegaprotocol/utils';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
import { FeesContainer } from '../../components/fees-container';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { usePageTitleStore } from '../../stores';
|
||||
import { titlefy } from '@vegaprotocol/utils';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export const Fees = () => {
|
||||
const t = useT();
|
||||
@@ -10,13 +11,17 @@ export const Fees = () => {
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
updateTitle(titlefy([title]));
|
||||
}, [updateTitle, title]);
|
||||
|
||||
return (
|
||||
<div className="container p-4 mx-auto">
|
||||
<h1 className="px-4 pb-4 text-2xl">{title}</h1>
|
||||
<FeesContainer />
|
||||
</div>
|
||||
<ErrorBoundary feature="fees">
|
||||
<div className="container p-4 mx-auto">
|
||||
<h1 className="px-4 pb-4 text-2xl">{title}</h1>
|
||||
<FeesContainer />
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { LiquidityContainer } from '../../components/liquidity-container';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
const enum LiquidityTabs {
|
||||
Active = 'active',
|
||||
@@ -58,19 +59,28 @@ export const LiquidityViewContainer = ({
|
||||
name={t('My liquidity provision')}
|
||||
hidden={!pubKey}
|
||||
>
|
||||
<LiquidityContainer
|
||||
marketId={marketId}
|
||||
filter={{ partyId: pubKey || undefined }}
|
||||
/>
|
||||
<ErrorBoundary feature="liquidity-party">
|
||||
<LiquidityContainer
|
||||
marketId={marketId}
|
||||
filter={{ partyId: pubKey || undefined }}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id={LiquidityTabs.Active} name={t('Active')}>
|
||||
<LiquidityContainer marketId={marketId} filter={{ active: true }} />
|
||||
<ErrorBoundary feature="liquidity-active">
|
||||
<LiquidityContainer
|
||||
marketId={marketId}
|
||||
filter={{ active: true }}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id={LiquidityTabs.Inactive} name={t('Inactive')}>
|
||||
<LiquidityContainer
|
||||
marketId={marketId}
|
||||
filter={{ active: false }}
|
||||
/>
|
||||
<ErrorBoundary feature="liquidity-inactive">
|
||||
<LiquidityContainer
|
||||
marketId={marketId}
|
||||
filter={{ active: false }}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from '../../components/market-banner';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
@@ -62,28 +63,38 @@ const MainGrid = memo(
|
||||
name={t('Chart')}
|
||||
menu={<TradingViews.candles.menu />}
|
||||
>
|
||||
<TradingViews.candles.component marketId={marketId} />
|
||||
<ErrorBoundary feature="chart">
|
||||
<TradingViews.candles.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="depth" name={t('Depth')}>
|
||||
<TradingViews.depth.component marketId={marketId} />
|
||||
<ErrorBoundary feature="depth">
|
||||
<TradingViews.depth.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="liquidity" name={t('Liquidity')}>
|
||||
<TradingViews.liquidity.component marketId={marketId} />
|
||||
<ErrorBoundary feature="liquidity">
|
||||
<TradingViews.liquidity.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
{market &&
|
||||
market.tradableInstrument.instrument.product.__typename ===
|
||||
'Perpetual' ? (
|
||||
<Tab id="funding-history" name={t('Funding history')}>
|
||||
<TradingViews.funding.component marketId={marketId} />
|
||||
<ErrorBoundary feature="funding-history">
|
||||
<TradingViews.funding.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
) : null}
|
||||
{market &&
|
||||
market.tradableInstrument.instrument.product.__typename ===
|
||||
'Perpetual' ? (
|
||||
<Tab id="funding-payments" name={t('Funding payments')}>
|
||||
<TradingViews.fundingPayments.component
|
||||
marketId={marketId}
|
||||
/>
|
||||
<ErrorBoundary feature="funding-payments">
|
||||
<TradingViews.fundingPayments.component
|
||||
marketId={marketId}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
) : null}
|
||||
</Tabs>
|
||||
@@ -96,10 +107,14 @@ const MainGrid = memo(
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-main-right">
|
||||
<Tab id="orderbook" name={t('Orderbook')}>
|
||||
<TradingViews.orderbook.component marketId={marketId} />
|
||||
<ErrorBoundary feature="orderbook">
|
||||
<TradingViews.orderbook.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="trades" name={t('Trades')}>
|
||||
<TradingViews.trades.component marketId={marketId} />
|
||||
<ErrorBoundary feature="trades">
|
||||
<TradingViews.trades.component marketId={marketId} />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
@@ -118,31 +133,43 @@ const MainGrid = memo(
|
||||
name={t('Positions')}
|
||||
menu={<TradingViews.positions.menu />}
|
||||
>
|
||||
<TradingViews.positions.component />
|
||||
<ErrorBoundary feature="positions">
|
||||
<TradingViews.positions.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="open-orders"
|
||||
name={t('Open')}
|
||||
menu={<TradingViews.activeOrders.menu />}
|
||||
>
|
||||
<TradingViews.activeOrders.component />
|
||||
<ErrorBoundary feature="activeOrders">
|
||||
<TradingViews.activeOrders.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="closed-orders" name={t('Closed')}>
|
||||
<TradingViews.closedOrders.component />
|
||||
<ErrorBoundary feature="closedOrders">
|
||||
<TradingViews.closedOrders.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="rejected-orders" name={t('Rejected')}>
|
||||
<TradingViews.rejectedOrders.component />
|
||||
<ErrorBoundary feature="rejectedOrders">
|
||||
<TradingViews.rejectedOrders.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="orders"
|
||||
name={t('All')}
|
||||
menu={<TradingViews.orders.menu />}
|
||||
>
|
||||
<TradingViews.orders.component />
|
||||
<ErrorBoundary feature="orders">
|
||||
<TradingViews.orders.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
{FLAGS.STOP_ORDERS ? (
|
||||
<Tab id="stop-orders" name={t('Stop orders')}>
|
||||
<TradingViews.stopOrders.component />
|
||||
<ErrorBoundary feature="stop-orders">
|
||||
<TradingViews.stopOrders.component />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
) : null}
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
@@ -153,7 +180,11 @@ const MainGrid = memo(
|
||||
name={t('Collateral')}
|
||||
menu={<TradingViews.collateral.menu />}
|
||||
>
|
||||
<TradingViews.collateral.component pinnedAsset={pinnedAsset} />
|
||||
<ErrorBoundary feature="collateral">
|
||||
<TradingViews.collateral.component
|
||||
pinnedAsset={pinnedAsset}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import type { PinnedAsset } from '@vegaprotocol/accounts';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import { type PinnedAsset } from '@vegaprotocol/accounts';
|
||||
import { type Market } from '@vegaprotocol/markets';
|
||||
import { OracleBanner } from '@vegaprotocol/markets';
|
||||
import type { TradingView } from './trade-views';
|
||||
import { TradingViews } from './trade-views';
|
||||
import { useState } from 'react';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import classNames from 'classnames';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import {
|
||||
MarketSuccessorBanner,
|
||||
MarketSuccessorProposalBanner,
|
||||
MarketTerminationBanner,
|
||||
} from '../../components/market-banner';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
import { type TradingView } from './trade-views';
|
||||
import { TradingViews } from './trade-views';
|
||||
|
||||
interface TradePanelsProps {
|
||||
market: Market | null;
|
||||
@@ -34,7 +35,11 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
|
||||
// Watch out here, we don't know what component is being rendered
|
||||
// so watch out for clashes in props
|
||||
return <Component marketId={market?.id} pinnedAsset={pinnedAsset} />;
|
||||
return (
|
||||
<ErrorBoundary feature={view}>
|
||||
<Component marketId={market?.id} pinnedAsset={pinnedAsset} />;
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
const renderMenu = () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
useLinks,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
export const MarketsPage = () => {
|
||||
const t = useT();
|
||||
@@ -34,7 +35,9 @@ export const MarketsPage = () => {
|
||||
<div className="h-full my-1 border rounded-sm border-default">
|
||||
<Tabs storageKey="console-markets">
|
||||
<Tab id="open-markets" name={t('Open markets')}>
|
||||
<OpenMarkets />
|
||||
<ErrorBoundary feature="markets-open">
|
||||
<OpenMarkets />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="proposed-markets"
|
||||
@@ -49,10 +52,14 @@ export const MarketsPage = () => {
|
||||
</TradingAnchorButton>
|
||||
}
|
||||
>
|
||||
<Proposed />
|
||||
<ErrorBoundary feature="markets-proposed">
|
||||
<Proposed />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="closed-markets" name={t('Closed markets')}>
|
||||
<Closed />
|
||||
<ErrorBoundary feature="markets-closed">
|
||||
<Closed />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,7 @@ import { DepositsMenu } from '../../components/deposits-menu';
|
||||
import { WithdrawalsMenu } from '../../components/withdrawals-menu';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
const WithdrawalsIndicator = () => {
|
||||
const { ready } = useIncompleteWithdrawals();
|
||||
@@ -72,19 +73,29 @@ export const Portfolio = () => {
|
||||
name={t('Positions')}
|
||||
menu={<PositionsMenu />}
|
||||
>
|
||||
<PositionsContainer allKeys />
|
||||
<ErrorBoundary feature="portfolio-positions">
|
||||
<PositionsContainer allKeys />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="orders" name={t('Orders')}>
|
||||
<OrdersContainer />
|
||||
<ErrorBoundary feature="portfolio-orders">
|
||||
<OrdersContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="fills" name={t('Fills')}>
|
||||
<FillsContainer />
|
||||
<ErrorBoundary feature="portfolio-fills">
|
||||
<FillsContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="funding-payments" name={t('Funding payments')}>
|
||||
<FundingPaymentsContainer />
|
||||
<ErrorBoundary feature="portfolio-funding-payments">
|
||||
<FundingPaymentsContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="ledger-entries" name={t('Ledger entries')}>
|
||||
<LedgerContainer />
|
||||
<ErrorBoundary feature="portfolio-ledger">
|
||||
<LedgerContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</PortfolioGridChild>
|
||||
@@ -101,10 +112,14 @@ export const Portfolio = () => {
|
||||
name={t('Collateral')}
|
||||
menu={<AccountsMenu />}
|
||||
>
|
||||
<AccountsContainer />
|
||||
<ErrorBoundary feature="portfolio-accounts">
|
||||
<AccountsContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="deposits" name={t('Deposits')} menu={<DepositsMenu />}>
|
||||
<DepositsContainer />
|
||||
<ErrorBoundary feature="portfolio-deposit">
|
||||
<DepositsContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab
|
||||
id="withdrawals"
|
||||
@@ -112,7 +127,9 @@ export const Portfolio = () => {
|
||||
indicator={<WithdrawalsIndicator />}
|
||||
menu={<WithdrawalsMenu />}
|
||||
>
|
||||
<WithdrawalsContainer />
|
||||
<ErrorBoundary feature="portfolio-deposit">
|
||||
<WithdrawalsContainer />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</PortfolioGridChild>
|
||||
|
||||
@@ -18,6 +18,7 @@ import { usePageTitleStore } from '../../stores';
|
||||
import { useEffect } from 'react';
|
||||
import { titlefy } from '@vegaprotocol/utils';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
const Nav = () => {
|
||||
const t = useT();
|
||||
@@ -65,7 +66,7 @@ export const Referrals = () => {
|
||||
}, [updateTitle, t]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ErrorBoundary feature="referrals">
|
||||
<LandingBanner />
|
||||
|
||||
{showNav && <Nav />}
|
||||
@@ -107,6 +108,6 @@ export const Referrals = () => {
|
||||
</TradingAnchorButton>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect } from 'react';
|
||||
import { titlefy } from '@vegaprotocol/utils';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { RewardsContainer } from '../../components/rewards-container';
|
||||
import { usePageTitleStore } from '../../stores';
|
||||
import { titlefy } from '@vegaprotocol/utils';
|
||||
import { useEffect } from 'react';
|
||||
import { ErrorBoundary } from '../../components/error-boundary';
|
||||
|
||||
export const Rewards = () => {
|
||||
const t = useT();
|
||||
@@ -14,9 +15,11 @@ export const Rewards = () => {
|
||||
updateTitle(titlefy([title]));
|
||||
}, [updateTitle, title]);
|
||||
return (
|
||||
<div className="container mx-auto p-4">
|
||||
<h1 className="px-4 pb-4 text-2xl">{title}</h1>
|
||||
<RewardsContainer />
|
||||
</div>
|
||||
<ErrorBoundary feature="rewards">
|
||||
<div className="container mx-auto p-4">
|
||||
<h1 className="px-4 pb-4 text-2xl">{title}</h1>
|
||||
<RewardsContainer />
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ErrorBoundary } from './error-boundary';
|
||||
import { localLoggerFactory } from '@vegaprotocol/logger';
|
||||
|
||||
jest.mock('@vegaprotocol/logger', () => ({
|
||||
localLoggerFactory: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('ErrorBoundary', () => {
|
||||
const mockLogError = jest.fn();
|
||||
const originalConsoleError = console.error;
|
||||
const mockLoggerFactory = localLoggerFactory as jest.Mock;
|
||||
|
||||
beforeAll(() => {
|
||||
console.error = () => {};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
console.error = originalConsoleError;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockLoggerFactory.mockImplementation(() => ({
|
||||
error: mockLogError,
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockLogError.mockClear();
|
||||
});
|
||||
|
||||
it('renders children', () => {
|
||||
render(
|
||||
<ErrorBoundary feature="feature">
|
||||
<div data-testid="child" />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('child')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders fallback ui and logs an error', () => {
|
||||
const error = new Error('bork!');
|
||||
const BorkedComponent = () => {
|
||||
throw error;
|
||||
};
|
||||
|
||||
render(
|
||||
<ErrorBoundary feature="test-feature">
|
||||
<BorkedComponent />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Something went wrong')).toBeInTheDocument();
|
||||
expect(mockLogError).toHaveBeenCalledTimes(1);
|
||||
expect(mockLogError).toHaveBeenCalledWith(
|
||||
error.message,
|
||||
expect.stringContaining('componentStack')
|
||||
);
|
||||
});
|
||||
|
||||
it('renders fallback render prop if error', () => {
|
||||
const error = new Error('bork!');
|
||||
const BorkedComponent = () => {
|
||||
throw error;
|
||||
};
|
||||
|
||||
render(
|
||||
<ErrorBoundary
|
||||
feature="test-feature"
|
||||
fallback={<div data-testid="custom-ui" />}
|
||||
>
|
||||
<BorkedComponent />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
||||
expect(screen.getByTestId('custom-ui')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import { localLoggerFactory, type LocalLogger } from '@vegaprotocol/logger';
|
||||
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
||||
import { useT } from '../../lib/use-t';
|
||||
|
||||
interface ErrorBoundaryProps {
|
||||
children: ReactNode;
|
||||
feature: string;
|
||||
fallback?: ReactNode;
|
||||
}
|
||||
|
||||
interface ErrorBoundaryState {
|
||||
hasError: boolean;
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends Component<
|
||||
ErrorBoundaryProps,
|
||||
ErrorBoundaryState
|
||||
> {
|
||||
logger: LocalLogger | null = null;
|
||||
|
||||
constructor(props: ErrorBoundaryProps) {
|
||||
super(props);
|
||||
|
||||
this.logger = localLoggerFactory({ application: props.feature });
|
||||
|
||||
this.state = {
|
||||
hasError: false,
|
||||
};
|
||||
}
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
return { hasError: true };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
if (this.logger) {
|
||||
this.logger.error(error.message, JSON.stringify(info));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return this.props.fallback || <DefaultFallback />;
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
const DefaultFallback = () => {
|
||||
const t = useT();
|
||||
return <p className="text-xs">{t('Something went wrong')}</p>;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { ErrorBoundary } from './error-boundary';
|
||||
@@ -310,16 +310,25 @@ export const CurrentVolume = ({
|
||||
const t = useT();
|
||||
const nextTier = tiers[tierIndex + 1];
|
||||
const requiredForNextTier = nextTier
|
||||
? Number(nextTier.minimumRunningNotionalTakerVolume) - windowLengthVolume
|
||||
: 0;
|
||||
? new BigNumber(nextTier.minimumRunningNotionalTakerVolume).minus(
|
||||
windowLengthVolume
|
||||
)
|
||||
: new BigNumber(0);
|
||||
const currentVolume = new BigNumber(windowLengthVolume);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3 pt-4">
|
||||
<CardStat
|
||||
value={formatNumberRounded(new BigNumber(windowLengthVolume))}
|
||||
text={t('pastEpochs', 'Past {{count}} epochs', { count: windowLength })}
|
||||
value={
|
||||
currentVolume.isZero()
|
||||
? `<${formatNumberRounded(requiredForNextTier)}`
|
||||
: formatNumberRounded(currentVolume)
|
||||
}
|
||||
text={t('pastEpochs', 'Past {{count}} epochs', {
|
||||
count: windowLength,
|
||||
})}
|
||||
/>
|
||||
{requiredForNextTier > 0 && (
|
||||
{requiredForNextTier.isGreaterThan(0) && (
|
||||
<CardStat
|
||||
value={formatNumber(requiredForNextTier)}
|
||||
text={t('Required for next tier')}
|
||||
|
||||
@@ -40,6 +40,9 @@ const DateRange = {
|
||||
RANGE_ALL: 'All',
|
||||
};
|
||||
|
||||
const priceFormat = (fundingRate: number) =>
|
||||
`${(fundingRate * 100).toFixed(4)}%`;
|
||||
|
||||
export const FundingContainer = ({ marketId }: { marketId: string }) => {
|
||||
const t = useT();
|
||||
const { theme } = useThemeSwitcher();
|
||||
@@ -82,7 +85,7 @@ export const FundingContainer = ({ marketId }: { marketId: string }) => {
|
||||
<LineChart
|
||||
data={values}
|
||||
theme={theme}
|
||||
priceFormat={(fundingRate) => `${(fundingRate * 100).toFixed(4)}%`}
|
||||
priceFormat={priceFormat}
|
||||
yAxisTickFormat="%"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -36,6 +36,26 @@ query RewardsPage($partyId: ID!) {
|
||||
}
|
||||
}
|
||||
|
||||
query ActivityStreak($partyId: ID!) {
|
||||
partiesConnection(id: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
activityStreak {
|
||||
activeFor
|
||||
isActive
|
||||
inactiveFor
|
||||
rewardDistributionMultiplier
|
||||
rewardVestingMultiplier
|
||||
epoch
|
||||
tradedVolume
|
||||
openVolume
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query RewardsHistory(
|
||||
$partyId: ID!
|
||||
$epochRewardSummariesPagination: Pagination
|
||||
|
||||
@@ -10,6 +10,13 @@ export type RewardsPageQueryVariables = Types.Exact<{
|
||||
|
||||
export type RewardsPageQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, vestingStats?: { __typename?: 'PartyVestingStats', rewardBonusMultiplier: string } | null, activityStreak?: { __typename?: 'PartyActivityStreak', rewardVestingMultiplier: string, rewardDistributionMultiplier: string } | null, vestingBalancesSummary: { __typename?: 'PartyVestingBalancesSummary', epoch?: number | null, vestingBalances?: Array<{ __typename?: 'PartyVestingBalance', balance: string, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number, quantum: string } }> | null, lockedBalances?: Array<{ __typename?: 'PartyLockedBalance', balance: string, untilEpoch: number, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number, quantum: string } }> | null } } | null };
|
||||
|
||||
export type ActivityStreakQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ActivityStreakQuery = { __typename?: 'Query', partiesConnection?: { __typename?: 'PartyConnection', edges: Array<{ __typename?: 'PartyEdge', node: { __typename?: 'Party', id: string, activityStreak?: { __typename?: 'PartyActivityStreak', activeFor: number, isActive: boolean, inactiveFor: number, rewardDistributionMultiplier: string, rewardVestingMultiplier: string, epoch: number, tradedVolume: string, openVolume: string } | null } }> } | null };
|
||||
|
||||
export type RewardsHistoryQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
epochRewardSummariesPagination?: Types.InputMaybe<Types.Pagination>;
|
||||
@@ -91,6 +98,55 @@ export function useRewardsPageLazyQuery(baseOptions?: Apollo.LazyQueryHookOption
|
||||
export type RewardsPageQueryHookResult = ReturnType<typeof useRewardsPageQuery>;
|
||||
export type RewardsPageLazyQueryHookResult = ReturnType<typeof useRewardsPageLazyQuery>;
|
||||
export type RewardsPageQueryResult = Apollo.QueryResult<RewardsPageQuery, RewardsPageQueryVariables>;
|
||||
export const ActivityStreakDocument = gql`
|
||||
query ActivityStreak($partyId: ID!) {
|
||||
partiesConnection(id: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
activityStreak {
|
||||
activeFor
|
||||
isActive
|
||||
inactiveFor
|
||||
rewardDistributionMultiplier
|
||||
rewardVestingMultiplier
|
||||
epoch
|
||||
tradedVolume
|
||||
openVolume
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useActivityStreakQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useActivityStreakQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useActivityStreakQuery` 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 } = useActivityStreakQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useActivityStreakQuery(baseOptions: Apollo.QueryHookOptions<ActivityStreakQuery, ActivityStreakQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<ActivityStreakQuery, ActivityStreakQueryVariables>(ActivityStreakDocument, options);
|
||||
}
|
||||
export function useActivityStreakLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ActivityStreakQuery, ActivityStreakQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<ActivityStreakQuery, ActivityStreakQueryVariables>(ActivityStreakDocument, options);
|
||||
}
|
||||
export type ActivityStreakQueryHookResult = ReturnType<typeof useActivityStreakQuery>;
|
||||
export type ActivityStreakLazyQueryHookResult = ReturnType<typeof useActivityStreakLazyQuery>;
|
||||
export type ActivityStreakQueryResult = Apollo.QueryResult<ActivityStreakQuery, ActivityStreakQueryVariables>;
|
||||
export const RewardsHistoryDocument = gql`
|
||||
query RewardsHistory($partyId: ID!, $epochRewardSummariesPagination: Pagination, $partyRewardsPagination: Pagination, $fromEpoch: Int, $toEpoch: Int) {
|
||||
epochRewardSummaries(
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { useRewardsHistoryQuery } from './__generated__/Rewards';
|
||||
import { useReferralProgram } from '../../client-pages/referrals/hooks/use-referral-program';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useRewardsRowData } from './use-reward-row-data';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
Icon,
|
||||
type IconName,
|
||||
Intent,
|
||||
Tooltip,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
|
||||
export const ActiveRewards = ({
|
||||
epoch,
|
||||
pubKey,
|
||||
assets,
|
||||
}: {
|
||||
pubKey: string | null;
|
||||
epoch: number;
|
||||
assets: Record<string, AssetFieldsFragment>;
|
||||
}) => {
|
||||
const [epochVariables] = useState(() => ({
|
||||
from: epoch - 1,
|
||||
to: epoch,
|
||||
}));
|
||||
|
||||
// No need to specify the fromEpoch as it will by default give you the last
|
||||
const { refetch, data } = useRewardsHistoryQuery({
|
||||
variables: {
|
||||
partyId: pubKey || '',
|
||||
fromEpoch: epochVariables.from,
|
||||
toEpoch: epochVariables.to,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(refetch, 30000);
|
||||
return () => clearInterval(interval);
|
||||
}, [refetch]);
|
||||
|
||||
const rowData = useRewardsRowData({
|
||||
epochRewardSummaries: data?.epochRewardSummaries,
|
||||
partyRewards: data?.party?.rewardsConnection,
|
||||
assets,
|
||||
partyId: pubKey,
|
||||
});
|
||||
|
||||
const t = useT();
|
||||
if (!pubKey) {
|
||||
return (
|
||||
<div className="pt-4">
|
||||
<p className="text-muted text-sm">{t('Not connected')}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: extract card component - call it reward tiles
|
||||
return (
|
||||
<div className="grid gap-x-8 gap-y-10 h-fit grid-cols-[repeat(auto-fill,_minmax(230px,_1fr))] md:grid-cols-[repeat(auto-fill,_minmax(230px,_1fr))] lg:grid-cols-[repeat(auto-fill,_minmax(320px,_1fr))] xl:grid-cols-[repeat(auto-fill,_minmax(343px,_1fr))]">
|
||||
{rowData.map((row, i) => {
|
||||
// TODO: filter out 0 values
|
||||
// const entries = Object.entries(row).filter(([key, value]) => {
|
||||
// value !== 0;
|
||||
// });
|
||||
return (
|
||||
<div key={i}>
|
||||
<div
|
||||
className={classNames(
|
||||
'bg-gradient-to-r col-span-full p-0.5 lg:col-auto h-full',
|
||||
'rounded-lg',
|
||||
'from-vega-blue-500 to-vega-green-400'
|
||||
)}
|
||||
>
|
||||
<div className="bg-gradient-to-b from-vega-blue-400 dark:from-vega-blue-600 to-20% bg-vega-clight-800 dark:bg-vega-cdark-800 h-full w-full rounded p-4 flex flex-col gap-4">
|
||||
<div className="flex justify-between gap-4">
|
||||
<div className="flex flex-col gap-2 items-center text-center">
|
||||
<span className="flex items-center p-2 rounded-full border border-gray-600">
|
||||
<VegaIcon name={VegaIconNames.MAN} size={18} />
|
||||
</span>
|
||||
<span className="text-muted text-xs">
|
||||
{t('Individual')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 items-center text-center">
|
||||
<span className="flex flex-col gap-1 font-alpha calt text-2xl shrink-1 text-center">
|
||||
<span>
|
||||
{`${addDecimalsFormatNumber(
|
||||
row.total,
|
||||
row.asset?.decimals || 0
|
||||
)}`}
|
||||
</span>
|
||||
|
||||
<span>{`${row.asset?.symbol}`}</span>
|
||||
</span>
|
||||
|
||||
<Tooltip description={'pro rata'} underline={true}>
|
||||
<span className="text-xs">{t('Pro rata')}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 items-center text-center">
|
||||
<span className="flex items-center p-2 rounded-full border border-gray-600">
|
||||
<VegaIcon name={VegaIconNames.LOCK} size={18} />
|
||||
</span>
|
||||
<span className="text-muted text-xs whitespace-nowrap">
|
||||
{t('11 epochs')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span className="border-[0.5px] border-gray-700" />
|
||||
|
||||
<span>
|
||||
{t('Price taking')} • {row.asset?.symbol} • {row.asset?.name}
|
||||
</span>
|
||||
|
||||
<div className="flex items-center gap-8 flex-wrap">
|
||||
<span className="flex flex-col">
|
||||
<span className="text-muted text-xs">{t('Ends in')}</span>
|
||||
<span>{t('5 epochs')}</span>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col">
|
||||
<span className="text-muted text-xs">
|
||||
{t('Assessed over')}
|
||||
</span>
|
||||
<span>{t('5 epochs')}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span className="text-muted text-sm">
|
||||
{t(
|
||||
'Get rewards for taking prices on the order book and paying fees.'
|
||||
)}
|
||||
</span>
|
||||
|
||||
<span className="border-[0.5px] border-gray-700" />
|
||||
|
||||
{/* <div className="grid grid-cols-3 items-center gap-3"> */}
|
||||
<div className="flex justify-between flex-wrap items-center gap-3">
|
||||
<span className="flex flex-col gap-1">
|
||||
<span className="flex items-center gap-1 text-muted text-xs">
|
||||
{t('Entity scope')}{' '}
|
||||
</span>
|
||||
|
||||
<span className="flex items-center gap-1">
|
||||
<span className="flex items-center p-1 rounded-full border border-gray-600">
|
||||
<VegaIcon name={VegaIconNames.MAN} size={16} />
|
||||
</span>
|
||||
<StatusIndicator
|
||||
intent={Intent.Success}
|
||||
icon={IconNames.TICK_CIRCLE}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col gap-1">
|
||||
<span className="flex items-center gap-1 text-muted text-xs">
|
||||
{t('Amount staked')}{' '}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
{t('200 VEGA')}
|
||||
<StatusIndicator
|
||||
intent={Intent.Success}
|
||||
icon={IconNames.TICK_CIRCLE}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span className="flex flex-col gap-1">
|
||||
<span className="flex items-center gap-1 text-muted text-xs">
|
||||
{t('Average position')}{' '}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
{t('100 USDT')}
|
||||
<StatusIndicator
|
||||
intent={Intent.Success}
|
||||
icon={IconNames.TICK_CIRCLE}
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// const getIconIntent = (status: string) => {
|
||||
// switch (status) {
|
||||
// case 'GOOD':
|
||||
// return { icon: IconNames.TICK_CIRCLE, intent: Intent.Success };
|
||||
// case 'RETIRED':
|
||||
// return { icon: IconNames.MOON, intent: Intent.None };
|
||||
// case 'UNKNOWN':
|
||||
// return { icon: IconNames.HELP, intent: Intent.Primary };
|
||||
// case 'MALICIOUS':
|
||||
// return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
// case 'SUSPICIOUS':
|
||||
// return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
// case 'COMPROMISED':
|
||||
// return { icon: IconNames.ERROR, intent: Intent.Danger };
|
||||
// default:
|
||||
// return { icon: IconNames.HELP, intent: Intent.Primary };
|
||||
// }
|
||||
// };
|
||||
|
||||
const StatusIndicator = ({
|
||||
intent,
|
||||
icon,
|
||||
}: {
|
||||
intent: Intent;
|
||||
icon: string;
|
||||
}) => {
|
||||
return (
|
||||
<span
|
||||
className={classNames(
|
||||
{
|
||||
'text-gray-700 dark:text-gray-300': intent === Intent.None,
|
||||
'text-vega-blue': intent === Intent.Primary,
|
||||
'text-vega-green dark:text-vega-green': intent === Intent.Success,
|
||||
'dark:text-yellow text-yellow-600': intent === Intent.Warning,
|
||||
'text-vega-red': intent === Intent.Danger,
|
||||
},
|
||||
'flex items-start p-1 align-text-bottom'
|
||||
)}
|
||||
>
|
||||
<Icon size={3} name={icon as IconName} />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export const ActivityStreak = ({
|
||||
epoch,
|
||||
pubKey,
|
||||
assets,
|
||||
}: {
|
||||
pubKey: string | null;
|
||||
epoch: number;
|
||||
assets: Record<string, AssetFieldsFragment>;
|
||||
}) => {
|
||||
// const { data } = useActivityStreakQuery({
|
||||
// variables: {
|
||||
// partyId: pubKey || '',
|
||||
// },
|
||||
// });
|
||||
|
||||
const { benefitTiers } = useReferralProgram();
|
||||
|
||||
// const streaks = data?.partiesConnection?.edges?.map(
|
||||
// (edge) => edge?.node?.activityStreak
|
||||
// );
|
||||
|
||||
// @Input()
|
||||
const progress = 30;
|
||||
const total = 100;
|
||||
|
||||
const safeProgress = () => {
|
||||
return (progress / total) * 100;
|
||||
};
|
||||
|
||||
const progressBarHeight = 'h-6';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-1 w-full">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div
|
||||
className="grid"
|
||||
style={{
|
||||
gridTemplateColumns:
|
||||
'repeat(' + benefitTiers.length + ', minmax(0, 1fr))',
|
||||
}}
|
||||
>
|
||||
{benefitTiers.map((tier, index) => {
|
||||
return (
|
||||
<div key={index} className="flex justify-end -mr-10">
|
||||
<span className="flex flex-col items-center gap-1">
|
||||
<span className="flex flex-col items-center font-medium">
|
||||
<span className="text-sm">Tier {tier.tier}</span>
|
||||
<span className="text-muted text-xs">7 days</span>
|
||||
</span>
|
||||
|
||||
<span className="text-xs flex flex-col items-center justify-center px-2 py-1 rounded-lg text-white border border-pink-600 bg-pink-900">
|
||||
<span>Reward 1x</span>
|
||||
<span>Vesting 1.5x</span>
|
||||
</span>
|
||||
|
||||
<span className="text-pink-500 text-xl">•</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
{benefitTiers.map((tier, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-white dark:bg-gray-800 shadow-card rounded-[100px] grow"
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'relative w-full rounded-[100px] bg-gray-200 dark:bg-gray-800',
|
||||
progressBarHeight
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="absolute left-0 top-0 h-full rounded-[100px] bg-gradient-to-r from-vega-pink-600 to-vega-pink-500"
|
||||
style={{ width: safeProgress() + '%' }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<VegaIcon name={VegaIconNames.STREAK} />
|
||||
|
||||
<span className="flex flex-col text-xs">
|
||||
<span>4 days streak</span>
|
||||
<span>
|
||||
<span className="text-vega-pink-500">3 days</span> to Tier 1
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div>{JSON.stringify(stakingTiers)}</div> */}
|
||||
{/* <div>{JSON.stringify(details)}</div> */}
|
||||
{/* <div>{JSON.stringify(benefitTiers)}</div> */}
|
||||
{/* <div>{JSON.stringify(streaks)}</div> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import groupBy from 'lodash/groupBy';
|
||||
import uniq from 'lodash/uniq';
|
||||
import type { Account } from '@vegaprotocol/accounts';
|
||||
import { useAccounts } from '@vegaprotocol/accounts';
|
||||
import {
|
||||
@@ -31,6 +32,13 @@ import { ViewType, useSidebar } from '../sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { RewardsHistoryContainer } from './rewards-history';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
||||
import { ActiveRewards, ActivityStreak } from './activity-rewards';
|
||||
|
||||
const ASSETS_WITH_INCORRECT_VESTING_REWARD_DATA = [
|
||||
'bf1e88d19db4b3ca0d1d5bdb73718a01686b18cf731ca26adedf3c8b83802bba', // USDT mainnet
|
||||
'8ba0b10971f0c4747746cd01ff05a53ae75ca91eba1d4d050b527910c983e27e', // USDT testnet
|
||||
];
|
||||
|
||||
export const RewardsContainer = () => {
|
||||
const t = useT();
|
||||
@@ -40,34 +48,68 @@ export const RewardsContainer = () => {
|
||||
NetworkParams.rewards_activityStreak_benefitTiers,
|
||||
NetworkParams.rewards_vesting_baseRate,
|
||||
]);
|
||||
|
||||
const { data: accounts, loading: accountsLoading } = useAccounts(pubKey);
|
||||
|
||||
const { data: assetMap } = useAssetsMapProvider();
|
||||
|
||||
const { data: epochData } = useRewardsEpochQuery();
|
||||
|
||||
// No need to specify the fromEpoch as it will by default give you the last
|
||||
// Note activityStreak in query will fail
|
||||
|
||||
const { data: rewardsData, loading: rewardsLoading } = useRewardsPageQuery({
|
||||
variables: {
|
||||
partyId: pubKey || '',
|
||||
},
|
||||
// Inclusion of activity streak in query currently fails
|
||||
errorPolicy: 'ignore',
|
||||
});
|
||||
|
||||
if (!epochData?.epoch) return null;
|
||||
if (!epochData?.epoch || !assetMap) return null;
|
||||
|
||||
const loading = paramsLoading || accountsLoading || rewardsLoading;
|
||||
|
||||
const rewardAccounts = accounts
|
||||
? accounts.filter((a) =>
|
||||
[
|
||||
AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
AccountType.ACCOUNT_TYPE_VESTING_REWARDS,
|
||||
].includes(a.type)
|
||||
)
|
||||
? accounts
|
||||
.filter((a) =>
|
||||
[
|
||||
AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
AccountType.ACCOUNT_TYPE_VESTING_REWARDS,
|
||||
].includes(a.type)
|
||||
)
|
||||
.filter((a) => new BigNumber(a.balance).isGreaterThan(0))
|
||||
: [];
|
||||
|
||||
const rewardAssetsMap = groupBy(
|
||||
rewardAccounts.filter((a) => a.asset.id !== params.reward_asset),
|
||||
'asset.id'
|
||||
);
|
||||
const rewardAccountsAssetMap = groupBy(rewardAccounts, 'asset.id');
|
||||
|
||||
const lockedBalances = rewardsData?.party?.vestingBalancesSummary
|
||||
.lockedBalances
|
||||
? rewardsData.party.vestingBalancesSummary.lockedBalances.filter((b) =>
|
||||
new BigNumber(b.balance).isGreaterThan(0)
|
||||
)
|
||||
: [];
|
||||
const lockedAssetMap = groupBy(lockedBalances, 'asset.id');
|
||||
|
||||
const vestingBalances = rewardsData?.party?.vestingBalancesSummary
|
||||
.vestingBalances
|
||||
? rewardsData.party.vestingBalancesSummary.vestingBalances.filter((b) =>
|
||||
new BigNumber(b.balance).isGreaterThan(0)
|
||||
)
|
||||
: [];
|
||||
const vestingAssetMap = groupBy(vestingBalances, 'asset.id');
|
||||
|
||||
// each asset reward pot is made up of:
|
||||
// available to withdraw - ACCOUNT_TYPE_VESTED_REWARDS
|
||||
// vesting - vestingBalancesSummary.vestingBalances
|
||||
// locked - vestingBalancesSummary.lockedBalances
|
||||
//
|
||||
// there can be entires for the same asset in each list so we need a uniq list of assets
|
||||
const assets = uniq([
|
||||
...Object.keys(rewardAccountsAssetMap),
|
||||
...Object.keys(lockedAssetMap),
|
||||
...Object.keys(vestingAssetMap),
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="grid auto-rows-min grid-cols-6 gap-3">
|
||||
@@ -117,28 +159,96 @@ export const RewardsContainer = () => {
|
||||
</Card>
|
||||
|
||||
{/* Show all other reward pots, most of the time users will not have other rewards */}
|
||||
{Object.keys(rewardAssetsMap).map((assetId) => {
|
||||
const asset = rewardAssetsMap[assetId][0].asset;
|
||||
return (
|
||||
<Card
|
||||
key={assetId}
|
||||
title={t('{{assetSymbol}} Reward pot', {
|
||||
assetSymbol: asset.symbol,
|
||||
})}
|
||||
className="lg:col-span-3 xl:col-span-2"
|
||||
loading={loading}
|
||||
>
|
||||
<RewardPot
|
||||
pubKey={pubKey}
|
||||
accounts={accounts}
|
||||
assetId={assetId}
|
||||
vestingBalancesSummary={
|
||||
rewardsData?.party?.vestingBalancesSummary
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
{assets
|
||||
.filter((assetId) => assetId !== params.reward_asset)
|
||||
.map((assetId) => {
|
||||
const asset = assetMap ? assetMap[assetId] : null;
|
||||
|
||||
if (!asset) return null;
|
||||
|
||||
// Following code is for mitigating an issue due to a core bug where locked and vesting
|
||||
// balances were incorrectly increased for infrastructure rewards for USDT on mainnet
|
||||
//
|
||||
// We don't want to incorrectly show the wring locked/vesting values, but we DO want to
|
||||
// show the user that they have rewards available to withdraw
|
||||
if (ASSETS_WITH_INCORRECT_VESTING_REWARD_DATA.includes(asset.id)) {
|
||||
const accountsForAsset = rewardAccountsAssetMap[asset.id];
|
||||
const vestedAccount = accountsForAsset?.find(
|
||||
(a) => a.type === AccountType.ACCOUNT_TYPE_VESTED_REWARDS
|
||||
);
|
||||
|
||||
// No vested rewards available to withdraw, so skip over USDT
|
||||
if (!vestedAccount || Number(vestedAccount.balance) <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={assetId}
|
||||
title={t('{{assetSymbol}} Reward pot', {
|
||||
assetSymbol: asset.symbol,
|
||||
})}
|
||||
className="lg:col-span-3 xl:col-span-2"
|
||||
loading={loading}
|
||||
>
|
||||
<RewardPot
|
||||
pubKey={pubKey}
|
||||
accounts={accounts}
|
||||
assetId={assetId}
|
||||
// Ensure that these values are shown as 0
|
||||
vestingBalancesSummary={{
|
||||
lockedBalances: [],
|
||||
vestingBalances: [],
|
||||
}}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
key={assetId}
|
||||
title={t('{{assetSymbol}} Reward pot', {
|
||||
assetSymbol: asset.symbol,
|
||||
})}
|
||||
className="lg:col-span-3 xl:col-span-2"
|
||||
loading={loading}
|
||||
>
|
||||
<RewardPot
|
||||
pubKey={pubKey}
|
||||
accounts={accounts}
|
||||
assetId={assetId}
|
||||
vestingBalancesSummary={
|
||||
rewardsData?.party?.vestingBalancesSummary
|
||||
}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
<Card
|
||||
title={t('Activity streak')}
|
||||
className="lg:col-span-full"
|
||||
loading={rewardsLoading}
|
||||
>
|
||||
<span className="flex flex-col mx-8">
|
||||
<ActivityStreak
|
||||
epoch={Number(epochData?.epoch.id)}
|
||||
pubKey={pubKey}
|
||||
assets={assetMap}
|
||||
/>
|
||||
</span>
|
||||
</Card>
|
||||
<Card
|
||||
title={t('Active rewards')}
|
||||
className="lg:col-span-full"
|
||||
loading={rewardsLoading}
|
||||
>
|
||||
<ActiveRewards
|
||||
epoch={Number(epochData?.epoch.id)}
|
||||
pubKey={pubKey}
|
||||
assets={assetMap}
|
||||
/>
|
||||
</Card>
|
||||
<Card
|
||||
title={t('Rewards history')}
|
||||
className="lg:col-span-full"
|
||||
@@ -147,6 +257,7 @@ export const RewardsContainer = () => {
|
||||
<RewardsHistoryContainer
|
||||
epoch={Number(epochData?.epoch.id)}
|
||||
pubKey={pubKey}
|
||||
assets={assetMap}
|
||||
/>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -313,14 +424,14 @@ export const RewardPot = ({
|
||||
export const Vesting = ({
|
||||
pubKey,
|
||||
baseRate,
|
||||
multiplier = '1',
|
||||
multiplier,
|
||||
}: {
|
||||
pubKey: string | null;
|
||||
baseRate: string;
|
||||
multiplier?: string;
|
||||
}) => {
|
||||
const t = useT();
|
||||
const rate = new BigNumber(baseRate).times(multiplier);
|
||||
const rate = new BigNumber(baseRate).times(multiplier || 1);
|
||||
const rateFormatted = formatPercentage(Number(rate));
|
||||
const baseRateFormatted = formatPercentage(Number(baseRate));
|
||||
|
||||
@@ -335,7 +446,7 @@ export const Vesting = ({
|
||||
{pubKey && (
|
||||
<tr>
|
||||
<CardTableTH>{t('Vesting multiplier')}</CardTableTH>
|
||||
<CardTableTD>{multiplier}x</CardTableTD>
|
||||
<CardTableTD>{multiplier ? `${multiplier}x` : '-'}</CardTableTD>
|
||||
</tr>
|
||||
)}
|
||||
</CardTable>
|
||||
@@ -345,16 +456,16 @@ export const Vesting = ({
|
||||
|
||||
export const Multipliers = ({
|
||||
pubKey,
|
||||
streakMultiplier = '1',
|
||||
hoarderMultiplier = '1',
|
||||
streakMultiplier,
|
||||
hoarderMultiplier,
|
||||
}: {
|
||||
pubKey: string | null;
|
||||
streakMultiplier?: string;
|
||||
hoarderMultiplier?: string;
|
||||
}) => {
|
||||
const t = useT();
|
||||
const combinedMultiplier = new BigNumber(streakMultiplier).times(
|
||||
hoarderMultiplier
|
||||
const combinedMultiplier = new BigNumber(streakMultiplier || 1).times(
|
||||
hoarderMultiplier || 1
|
||||
);
|
||||
|
||||
if (!pubKey) {
|
||||
@@ -375,11 +486,15 @@ export const Multipliers = ({
|
||||
<CardTable>
|
||||
<tr>
|
||||
<CardTableTH>{t('Streak reward multiplier')}</CardTableTH>
|
||||
<CardTableTD>{streakMultiplier}x</CardTableTD>
|
||||
<CardTableTD>
|
||||
{streakMultiplier ? `${streakMultiplier}x` : '-'}
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
<tr>
|
||||
<CardTableTH>{t('Hoarder reward multiplier')}</CardTableTH>
|
||||
<CardTableTD>{hoarderMultiplier}x</CardTableTD>
|
||||
<CardTableTD>
|
||||
{hoarderMultiplier ? `${hoarderMultiplier}x` : '-'}
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
</CardTable>
|
||||
</div>
|
||||
|
||||
@@ -61,6 +61,14 @@ const rewardSummaries = [
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
epoch: 7,
|
||||
assetId: assets.asset2.id,
|
||||
amount: '300',
|
||||
rewardType: AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const getCell = (cells: HTMLElement[], colId: string) => {
|
||||
@@ -69,7 +77,7 @@ const getCell = (cells: HTMLElement[], colId: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
describe('RewarsHistoryTable', () => {
|
||||
describe('RewardsHistoryTable', () => {
|
||||
const props = {
|
||||
epochRewardSummaries: {
|
||||
edges: rewardSummaries,
|
||||
@@ -88,7 +96,7 @@ describe('RewarsHistoryTable', () => {
|
||||
loading: false,
|
||||
};
|
||||
|
||||
it('Renders table with accounts summed up by asset', () => {
|
||||
it('renders table with accounts summed up by asset', () => {
|
||||
render(<RewardHistoryTable {...props} />);
|
||||
|
||||
const container = within(
|
||||
@@ -110,17 +118,27 @@ describe('RewarsHistoryTable', () => {
|
||||
assets.asset2.name
|
||||
);
|
||||
|
||||
// First row
|
||||
const marketCreationCell = getCell(cells, 'marketCreation');
|
||||
expect(
|
||||
marketCreationCell.getByTestId('stack-cell-primary')
|
||||
).toHaveTextContent('300');
|
||||
expect(
|
||||
marketCreationCell.getByTestId('stack-cell-secondary')
|
||||
).toHaveTextContent('100.00%');
|
||||
).toHaveTextContent('50.00%');
|
||||
|
||||
const infrastructureFeesCell = getCell(cells, 'infrastructureFees');
|
||||
expect(
|
||||
infrastructureFeesCell.getByTestId('stack-cell-primary')
|
||||
).toHaveTextContent('300');
|
||||
expect(
|
||||
infrastructureFeesCell.getByTestId('stack-cell-secondary')
|
||||
).toHaveTextContent('50.00%');
|
||||
|
||||
let totalCell = getCell(cells, 'total');
|
||||
expect(totalCell.getByText('300.00')).toBeInTheDocument();
|
||||
expect(totalCell.getByText('600.00')).toBeInTheDocument();
|
||||
|
||||
// Second row
|
||||
row = within(rows[1]);
|
||||
cells = row.getAllByRole('gridcell');
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@ import debounce from 'lodash/debounce';
|
||||
import { useMemo, useState } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import type { ColDef, ValueFormatterFunc } from 'ag-grid-community';
|
||||
import {
|
||||
useAssetsMapProvider,
|
||||
type AssetFieldsFragment,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { type AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import {
|
||||
addDecimalsFormatNumberQuantum,
|
||||
formatNumberPercentage,
|
||||
@@ -26,17 +23,17 @@ import { useT } from '../../lib/use-t';
|
||||
export const RewardsHistoryContainer = ({
|
||||
epoch,
|
||||
pubKey,
|
||||
assets,
|
||||
}: {
|
||||
pubKey: string | null;
|
||||
epoch: number;
|
||||
assets: Record<string, AssetFieldsFragment>;
|
||||
}) => {
|
||||
const [epochVariables, setEpochVariables] = useState(() => ({
|
||||
from: epoch - 1,
|
||||
to: epoch,
|
||||
}));
|
||||
|
||||
const { data: assets } = useAssetsMapProvider();
|
||||
|
||||
// No need to specify the fromEpoch as it will by default give you the last
|
||||
const { refetch, data, loading } = useRewardsHistoryQuery({
|
||||
variables: {
|
||||
@@ -154,10 +151,12 @@ export const RewardHistoryTable = ({
|
||||
const rewardValueFormatter: ValueFormatterFunc<RewardRow> = ({
|
||||
data,
|
||||
value,
|
||||
...rest
|
||||
}) => {
|
||||
if (!value || !data) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return addDecimalsFormatNumberQuantum(
|
||||
value,
|
||||
data.asset.decimals,
|
||||
@@ -197,6 +196,11 @@ export const RewardHistoryTable = ({
|
||||
},
|
||||
sort: 'desc',
|
||||
},
|
||||
{
|
||||
field: 'infrastructureFees',
|
||||
valueFormatter: rewardValueFormatter,
|
||||
cellRenderer: rewardCellRenderer,
|
||||
},
|
||||
{
|
||||
field: 'staking',
|
||||
valueFormatter: rewardValueFormatter,
|
||||
@@ -251,6 +255,14 @@ export const RewardHistoryTable = ({
|
||||
return colDefs;
|
||||
}, []);
|
||||
|
||||
if (!pubKey) {
|
||||
return (
|
||||
<div className="pt-4">
|
||||
<p className="text-muted text-sm">{t('Not connected')}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-2 flex items-center justify-between gap-2">
|
||||
@@ -338,7 +350,7 @@ export const RewardHistoryTable = ({
|
||||
);
|
||||
};
|
||||
|
||||
const EpochInput = ({
|
||||
export const EpochInput = ({
|
||||
id,
|
||||
value,
|
||||
max,
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
import { type AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { getRewards } from './use-reward-row-data';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const asset1 = {
|
||||
id: 'asset1',
|
||||
name: 'USD (KRW)',
|
||||
symbol: 'USD-KRW',
|
||||
decimals: 6,
|
||||
quantum: '1000000',
|
||||
status: Schema.AssetStatus.STATUS_ENABLED,
|
||||
// @ts-ignore not needed
|
||||
source: {},
|
||||
} as AssetFieldsFragment;
|
||||
|
||||
const asset2 = {
|
||||
id: 'asset2',
|
||||
name: 'tDAI TEST',
|
||||
symbol: 'tDAI',
|
||||
decimals: 5,
|
||||
quantum: '1',
|
||||
status: Schema.AssetStatus.STATUS_ENABLED,
|
||||
// @ts-ignore not needed
|
||||
source: {},
|
||||
} as AssetFieldsFragment;
|
||||
|
||||
const asset3 = {
|
||||
id: 'asset3',
|
||||
name: 'Tether USD',
|
||||
symbol: 'USDT',
|
||||
decimals: 6,
|
||||
quantum: '1000000',
|
||||
status: Schema.AssetStatus.STATUS_ENABLED,
|
||||
// @ts-ignore not needed
|
||||
source: {},
|
||||
} as AssetFieldsFragment;
|
||||
|
||||
const asset4 = {
|
||||
id: 'asset4',
|
||||
name: 'USDT-T',
|
||||
symbol: 'USDT-T',
|
||||
decimals: 18,
|
||||
quantum: '1',
|
||||
status: Schema.AssetStatus.STATUS_ENABLED,
|
||||
// @ts-ignore not needed
|
||||
source: {},
|
||||
} as AssetFieldsFragment;
|
||||
|
||||
const assets: Record<string, AssetFieldsFragment> = {
|
||||
asset1,
|
||||
asset2,
|
||||
asset3,
|
||||
asset4,
|
||||
};
|
||||
|
||||
const testData = {
|
||||
rewards: [
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
assetId: 'asset1',
|
||||
amount: '31897424',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
assetId: 'asset2',
|
||||
amount: '57',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
assetId: 'asset3',
|
||||
amount: '5501',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_REWARD_AVERAGE_POSITION,
|
||||
assetId: 'asset3',
|
||||
amount: '5501',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
|
||||
assetId: 'asset4',
|
||||
amount: '5501',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
|
||||
assetId: 'asset4',
|
||||
amount: '456',
|
||||
},
|
||||
{
|
||||
rewardType: Schema.AccountType.ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING,
|
||||
assetId: 'asset4',
|
||||
amount: '4565',
|
||||
},
|
||||
],
|
||||
assets,
|
||||
};
|
||||
|
||||
describe('getRewards', () => {
|
||||
it('should return the correct rewards when infra fees are included', () => {
|
||||
const rewards = getRewards(testData.rewards, testData.assets);
|
||||
expect(rewards).toEqual([
|
||||
{
|
||||
asset: asset1,
|
||||
infrastructureFees: 31897424,
|
||||
staking: 0,
|
||||
priceTaking: 0,
|
||||
priceMaking: 0,
|
||||
liquidityProvision: 0,
|
||||
marketCreation: 0,
|
||||
averagePosition: 0,
|
||||
relativeReturns: 0,
|
||||
returnsVolatility: 0,
|
||||
validatorRanking: 0,
|
||||
total: 31897424,
|
||||
},
|
||||
{
|
||||
asset: asset2,
|
||||
infrastructureFees: 57,
|
||||
staking: 0,
|
||||
priceTaking: 0,
|
||||
priceMaking: 0,
|
||||
liquidityProvision: 0,
|
||||
marketCreation: 0,
|
||||
averagePosition: 0,
|
||||
relativeReturns: 0,
|
||||
returnsVolatility: 0,
|
||||
validatorRanking: 0,
|
||||
total: 57,
|
||||
},
|
||||
{
|
||||
asset: asset3,
|
||||
infrastructureFees: 5501,
|
||||
staking: 0,
|
||||
priceTaking: 0,
|
||||
priceMaking: 0,
|
||||
liquidityProvision: 0,
|
||||
marketCreation: 0,
|
||||
averagePosition: 5501,
|
||||
relativeReturns: 0,
|
||||
returnsVolatility: 0,
|
||||
validatorRanking: 0,
|
||||
total: 11002,
|
||||
},
|
||||
{
|
||||
asset: asset4,
|
||||
infrastructureFees: 0,
|
||||
staking: 0,
|
||||
priceTaking: 0,
|
||||
priceMaking: 5501,
|
||||
liquidityProvision: 456,
|
||||
marketCreation: 0,
|
||||
averagePosition: 0,
|
||||
relativeReturns: 0,
|
||||
returnsVolatility: 0,
|
||||
validatorRanking: 4565,
|
||||
total: 10522,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -16,9 +16,10 @@ const REWARD_ACCOUNT_TYPES = [
|
||||
AccountType.ACCOUNT_TYPE_REWARD_RELATIVE_RETURN,
|
||||
AccountType.ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY,
|
||||
AccountType.ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING,
|
||||
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
];
|
||||
|
||||
const getRewards = (
|
||||
export const getRewards = (
|
||||
rewards: Array<{
|
||||
rewardType: AccountType;
|
||||
assetId: string;
|
||||
@@ -56,6 +57,9 @@ const getRewards = (
|
||||
|
||||
return {
|
||||
asset,
|
||||
infrastructureFees: totals.get(
|
||||
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE
|
||||
),
|
||||
staking: totals.get(AccountType.ACCOUNT_TYPE_GLOBAL_REWARD),
|
||||
priceTaking: totals.get(AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES),
|
||||
priceMaking: totals.get(
|
||||
@@ -101,7 +105,8 @@ export const useRewardsRowData = ({
|
||||
assetId: r.asset.id,
|
||||
amount: r.amount,
|
||||
}));
|
||||
return getRewards(rewards, assets);
|
||||
const result = getRewards(rewards, assets);
|
||||
return result;
|
||||
}
|
||||
|
||||
const rewards = removePaginationWrapper(epochRewardSummaries?.edges);
|
||||
|
||||
@@ -16,6 +16,7 @@ import { GetStarted } from '../welcome-dialog';
|
||||
import { useVegaWallet, useViewAsDialog } from '@vegaprotocol/wallet';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { ErrorBoundary } from '../error-boundary';
|
||||
|
||||
export enum ViewType {
|
||||
Order = 'Order',
|
||||
@@ -163,12 +164,14 @@ export const SidebarContent = () => {
|
||||
if (params.marketId) {
|
||||
return (
|
||||
<ContentWrapper>
|
||||
<DealTicketContainer
|
||||
marketId={params.marketId}
|
||||
onDeposit={(assetId) =>
|
||||
setViews({ type: ViewType.Deposit, assetId }, currentRouteId)
|
||||
}
|
||||
/>
|
||||
<ErrorBoundary feature="deal-ticket">
|
||||
<DealTicketContainer
|
||||
marketId={params.marketId}
|
||||
onDeposit={(assetId) =>
|
||||
setViews({ type: ViewType.Deposit, assetId }, currentRouteId)
|
||||
}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
<GetStarted />
|
||||
</ContentWrapper>
|
||||
);
|
||||
@@ -181,7 +184,9 @@ export const SidebarContent = () => {
|
||||
if (params.marketId) {
|
||||
return (
|
||||
<ContentWrapper>
|
||||
<MarketInfoAccordionContainer marketId={params.marketId} />
|
||||
<ErrorBoundary feature="market-info">
|
||||
<MarketInfoAccordionContainer marketId={params.marketId} />
|
||||
</ErrorBoundary>
|
||||
</ContentWrapper>
|
||||
);
|
||||
} else {
|
||||
@@ -192,7 +197,9 @@ export const SidebarContent = () => {
|
||||
if (view.type === ViewType.Deposit) {
|
||||
return (
|
||||
<ContentWrapper title={t('Deposit')}>
|
||||
<DepositContainer assetId={view.assetId} />
|
||||
<ErrorBoundary feature="deposit">
|
||||
<DepositContainer assetId={view.assetId} />
|
||||
</ErrorBoundary>
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -200,7 +207,9 @@ export const SidebarContent = () => {
|
||||
if (view.type === ViewType.Withdraw) {
|
||||
return (
|
||||
<ContentWrapper title={t('Withdraw')}>
|
||||
<WithdrawContainer assetId={view.assetId} />
|
||||
<ErrorBoundary feature="withdraw">
|
||||
<WithdrawContainer assetId={view.assetId} />
|
||||
</ErrorBoundary>
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -208,7 +217,9 @@ export const SidebarContent = () => {
|
||||
if (view.type === ViewType.Transfer) {
|
||||
return (
|
||||
<ContentWrapper title={t('Transfer')}>
|
||||
<TransferContainer assetId={view.assetId} />
|
||||
<ErrorBoundary feature="transfer">
|
||||
<TransferContainer assetId={view.assetId} />
|
||||
</ErrorBoundary>
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
@@ -216,7 +227,9 @@ export const SidebarContent = () => {
|
||||
if (view.type === ViewType.Settings) {
|
||||
return (
|
||||
<ContentWrapper title={t('Settings')}>
|
||||
<Settings />
|
||||
<ErrorBoundary feature="settings">
|
||||
<Settings />
|
||||
</ErrorBoundary>
|
||||
</ContentWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from actions.vega import submit_order
|
||||
from actions.utils import change_keys
|
||||
from wallet_config import MM_WALLET, MM_WALLET2
|
||||
import logging
|
||||
|
||||
@@ -196,3 +197,17 @@ def test_price_monitoring(simple_market, vega: VegaService, page: Page):
|
||||
expect(
|
||||
page.get_by_test_id(liquidity_supplied).get_by_test_id(item_value)
|
||||
).to_have_text("50.00 (>100%)")
|
||||
|
||||
COL_ID_FEE = ".ag-center-cols-container [col-id='fee'] .ag-cell-value"
|
||||
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "risk_accepted", "auth")
|
||||
def test_auction_uncross_fees(continuous_market, vega: VegaService, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id("Fills").click()
|
||||
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
|
||||
page.locator(COL_ID_FEE).hover()
|
||||
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text("If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI")
|
||||
change_keys(page,vega, "market_maker")
|
||||
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
|
||||
page.locator(COL_ID_FEE).hover()
|
||||
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text("If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI")
|
||||
|
||||
@@ -5,6 +5,7 @@ from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService, PeggedOrder
|
||||
import vega_sim.api.governance as governance
|
||||
from actions.vega import submit_order
|
||||
from actions.utils import next_epoch
|
||||
from wallet_config import MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET
|
||||
|
||||
|
||||
@@ -58,9 +59,9 @@ def test_market_lifecycle(proposed_market, vega: VegaService, page: Page):
|
||||
|
||||
# "wait" for market to be approved and enacted
|
||||
vega.forward("60s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_fn(10)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
next_epoch(vega=vega)
|
||||
# check that market is in pending state
|
||||
expect(trading_mode).to_have_text("Opening auction")
|
||||
expect(market_state).to_have_text("Pending")
|
||||
|
||||
@@ -118,7 +118,6 @@ def test_perps_market_termination_proposed(page: Page, vega: VegaService):
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth" )
|
||||
def test_perps_market_terminated(page: Page, vega: VegaService):
|
||||
perpetual_market = setup_perps_market(vega)
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
vega.update_market_state(
|
||||
proposal_key=MM_WALLET.name,
|
||||
market_id=perpetual_market,
|
||||
@@ -127,6 +126,11 @@ def test_perps_market_terminated(page: Page, vega: VegaService):
|
||||
approve_proposal = True,
|
||||
forward_time_to_enactment = True,
|
||||
)
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
expect(page.get_by_test_id("market-price")).to_have_text("Mark Price100.00")
|
||||
expect(page.get_by_test_id("market-change")).to_have_text("Change (24h)-")
|
||||
expect(page.get_by_test_id("market-volume")).to_have_text("Volume (24h)-")
|
||||
|
||||
@@ -153,7 +153,8 @@ interface DataProviderParams<
|
||||
pagination?: {
|
||||
getPageInfo: GetPageInfo<QueryData>;
|
||||
append: Append<Data>;
|
||||
first: number;
|
||||
first?: number;
|
||||
last?: number;
|
||||
};
|
||||
fetchPolicy?: FetchPolicy;
|
||||
resetDelay?: number;
|
||||
|
||||
@@ -19,16 +19,27 @@ export const LayoutCell = ({
|
||||
}: LayoutCellProps) => {
|
||||
const t = useT();
|
||||
const classes = [
|
||||
'lg:text-right flex justify-between lg:block',
|
||||
'lg:text-right flex lg:block justify-stretch gap-2',
|
||||
'my-2 lg:my-0',
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={classnames(classes)}>
|
||||
{label && <span className="lg:hidden">{label}</span>}
|
||||
{label && (
|
||||
<>
|
||||
<span className="lg:hidden text-xs text-vega-clight-200 dark:text-vega-cdark-200 whitespace-nowrap">
|
||||
{label}
|
||||
</span>
|
||||
<span
|
||||
/* separator */
|
||||
aria-hidden
|
||||
className="border-b border-dashed border-b-vega-clight-400 dark:border-b-vega-cdark-400 w-full h-[9px]"
|
||||
></span>
|
||||
</>
|
||||
)}
|
||||
<span
|
||||
data-testid={dataTestId}
|
||||
className={classnames('font-mono', {
|
||||
className={classnames('font-mono text-xs lg:text-sm', {
|
||||
'text-danger': !isLoading && hasError,
|
||||
'text-muted': isLoading,
|
||||
})}
|
||||
|
||||
@@ -89,30 +89,30 @@ export const NodeSwitcher = ({ closeDialog }: { closeDialog: () => void }) => {
|
||||
<span className="text-right">{t('Block')}</span>
|
||||
<span className="text-right">{t('Subscription')}</span>
|
||||
</LayoutRow>
|
||||
<div>
|
||||
{nodes.map((node, index) => {
|
||||
return (
|
||||
<LayoutRow key={node} dataTestId="node-row">
|
||||
<ApolloWrapper url={node}>
|
||||
<RowData
|
||||
id={index.toString()}
|
||||
url={node}
|
||||
highestBlock={highestBlock}
|
||||
onBlockHeight={handleHighestBlock}
|
||||
/>
|
||||
</ApolloWrapper>
|
||||
</LayoutRow>
|
||||
);
|
||||
})}
|
||||
<CustomRowWrapper
|
||||
inputText={customUrlText}
|
||||
setInputText={setCustomUrlText}
|
||||
nodes={nodes}
|
||||
highestBlock={highestBlock}
|
||||
onBlockHeight={handleHighestBlock}
|
||||
nodeRadio={nodeRadio}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{nodes.map((node, index) => {
|
||||
return (
|
||||
<LayoutRow key={node} dataTestId="node-row">
|
||||
<ApolloWrapper url={node}>
|
||||
<RowData
|
||||
id={index.toString()}
|
||||
url={node}
|
||||
highestBlock={highestBlock}
|
||||
onBlockHeight={handleHighestBlock}
|
||||
/>
|
||||
</ApolloWrapper>
|
||||
</LayoutRow>
|
||||
);
|
||||
})}
|
||||
<CustomRowWrapper
|
||||
inputText={customUrlText}
|
||||
setInputText={setCustomUrlText}
|
||||
nodes={nodes}
|
||||
highestBlock={highestBlock}
|
||||
onBlockHeight={handleHighestBlock}
|
||||
nodeRadio={nodeRadio}
|
||||
/>
|
||||
</div>
|
||||
</TradingRadioGroup>
|
||||
<div className="mt-4">
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
"Size": "Size",
|
||||
"Size cannot be lower than {{sizeStep}}": "Size cannot be lower than {{sizeStep}}",
|
||||
"sizeAtPrice-market": "market",
|
||||
"Subtotal": "Subtotal",
|
||||
"Stagnet": "Stagnet",
|
||||
"Stop": "Stop",
|
||||
"Stop Limit": "Stop Limit",
|
||||
@@ -87,6 +86,7 @@
|
||||
"Stop order will be triggered immediately": "Stop order will be triggered immediately",
|
||||
"Strategy": "Strategy",
|
||||
"Submit": "Submit",
|
||||
"Subtotal": "Subtotal",
|
||||
"terminated": "terminated",
|
||||
"The expiry date that you have entered appears to be in the past": "The expiry date that you have entered appears to be in the past",
|
||||
"The latest Vega code auto-deployed": "The latest Vega code auto-deployed",
|
||||
@@ -104,9 +104,16 @@
|
||||
"This market is in opening auction until it has reached enough liquidity to move into continuous trading.": "This market is in opening auction until it has reached enough liquidity to move into continuous trading.",
|
||||
"This market may have sufficient liquidity but there are not enough priced limit orders in the order book, which are required to deploy liquidity commitment pegged orders.": "This market may have sufficient liquidity but there are not enough priced limit orders in the order book, which are required to deploy liquidity commitment pegged orders.",
|
||||
"Time in force": "Time in force",
|
||||
"TIME_IN_FORCE_FOK": "Fill or Kill (FOK)",
|
||||
"TIME_IN_FORCE_GFA": "Good for Auction (GFA)",
|
||||
"TIME_IN_FORCE_GFN": "Good for Normal (GFN)",
|
||||
"TIME_IN_FORCE_GTC": "Good 'til Cancelled (GTC)",
|
||||
"TIME_IN_FORCE_GTT": "Good 'til Time (GTT)",
|
||||
"TIME_IN_FORCE_IOC": "Immediate or Cancel (IOC)",
|
||||
"TIME_IN_FORCE_SELECTOR_LIQUIDITY_MONITORING_AUCTION": "This market is in auction until it reaches <0>sufficient liquidity</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
||||
"TIME_IN_FORCE_SELECTOR_PRICE_MONITORING_AUCTION": "This market is in auction due to <0>high price volatility</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
||||
"Total": "Total",
|
||||
"Total fees": "Total fees",
|
||||
"Total margin available": "Total margin available",
|
||||
"TOTAL_MARGIN_AVAILABLE": "Total margin available = general {{assetSymbol}} balance ({{generalAccountBalance}} {{assetSymbol}}) + margin balance ({{marginAccountBalance}} {{assetSymbol}}) - maintenance level ({{marginMaintenance}} {{assetSymbol}}).",
|
||||
"Trading terminated": "Trading terminated",
|
||||
@@ -130,11 +137,5 @@
|
||||
"You need to connect your own wallet to start trading on this market": "You need to connect your own wallet to start trading on this market",
|
||||
"You need to provide a minimum visible size": "You need to provide a minimum visible size",
|
||||
"You need to provide a peak size": "You need to provide a peak size",
|
||||
"You need to provide a size": "You need to provide a size",
|
||||
"TIME_IN_FORCE_FOK": "Fill or Kill (FOK)",
|
||||
"TIME_IN_FORCE_GFA": "Good for Auction (GFA)",
|
||||
"TIME_IN_FORCE_GFN": "Good for Normal (GFN)",
|
||||
"TIME_IN_FORCE_GTC": "Good 'til Cancelled (GTC)",
|
||||
"TIME_IN_FORCE_GTT": "Good 'til Time (GTT)",
|
||||
"TIME_IN_FORCE_IOC": "Immediate or Cancel (IOC)"
|
||||
"You need to provide a size": "You need to provide a size"
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"A release candidate for the staging environment": "A release candidate for the staging environment",
|
||||
"Advanced": "Advanced",
|
||||
"Block": "Block",
|
||||
"blocksBehind": "{{count}} Blocks behind",
|
||||
"blocksBehind_one": "{{count}} Block behind",
|
||||
"blocksBehind_other": "{{count}} Blocks behind",
|
||||
"blocksBehind": "{{count}} Blocks behind",
|
||||
"Change node": "Change node",
|
||||
"Check": "Check",
|
||||
"Checking": "Checking",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"Adjusted stake share": "Adjusted stake share",
|
||||
"Adjusted stake": "Adjusted stake",
|
||||
"Commitment ({{symbol}})": "Commitment ({{symbol}})",
|
||||
"Commitment details": "Commitment details",
|
||||
"Created": "Created",
|
||||
@@ -7,14 +7,14 @@
|
||||
"Fee": "Fee",
|
||||
"Fees accrued this epoch": "Fees accrued this epoch",
|
||||
"Last bond penalty": "Last bond penalty",
|
||||
"Last epoch bond penalty.": "Last epoch bond penalty.",
|
||||
"Last epoch fee penalty.": "Last epoch fee penalty.",
|
||||
"Last epoch fraction of time on the book.": "Last epoch fraction of time on the book.",
|
||||
"Penalty applied on a provider's bond penalty at the end of the last epoch. This percentage increased if an LP: had a shortfall and their bond needed to be used to cover it, did not meet the SLA, and/or reduced their commitment to the point that the market was below its target stake.": "Penalty applied on a provider's bond penalty at the end of the last epoch. This percentage increased if an LP: had a shortfall and their bond needed to be used to cover it, did not meet the SLA, and/or reduced their commitment to the point that the market was below its target stake.",
|
||||
"Penalty applied on the fees a liquidity provider collected in the last epoch. This number increases if an LP did not meet the SLA, or if they met it but other LPs outscored them in the previous epoch.": "Penalty applied on the fees a liquidity provider collected in the last epoch. This percentage increased if an LP did not meet the SLA, or if they met it but other LPs outscored them in the previous epoch.",
|
||||
"Fraction of time on the book at the end of the last epoch.": "Fraction of time on the book at the end of the last epoch.",
|
||||
"Last epoch SLA details": "Last epoch SLA details",
|
||||
"Last fee penalty": "Last fee penalty",
|
||||
"Last time on the book": "Last time on the book",
|
||||
"Last time on book": "Last time on book",
|
||||
"Live liquidity data": "Live liquidity data",
|
||||
"Live liquidity quality score (%)": "Live liquidity quality score (%)",
|
||||
"Live liquidity score (%)": "Live liquidity score (%)",
|
||||
"Live supplied liquidity": "Live supplied liquidity",
|
||||
"Live time on book": "Live time on book",
|
||||
"No liquidity provisions": "No liquidity provisions",
|
||||
@@ -24,7 +24,7 @@
|
||||
"Status": "Status",
|
||||
"The amount committed to the market by this liquidity provider.": "The amount committed to the market by this liquidity provider.",
|
||||
"The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.": "The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.",
|
||||
"The average score of the liquidity provider.": "The average score of the liquidity provider.",
|
||||
"The liquidity score of the provider, used to determine allocation of fees to the best performing LPs. Posting volume closer to the mid on both sides of the book will improve this score.": "The liquidity score of the provider, used to determine allocation of fees to the best performing LPs. Posting volume closer to the mid on both sides of the book will improve this score.",
|
||||
"The current status of this liquidity provision.": "The current status of this liquidity provision.",
|
||||
"The date and time this liquidity provision was created.": "The date and time this liquidity provision was created.",
|
||||
"The date and time this liquidity provision was last updated.": "The date and time this liquidity provision was last updated.",
|
||||
@@ -33,7 +33,7 @@
|
||||
"The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.": "The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.",
|
||||
"The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_volume network parameter to convert into units of liquidity volume.": "The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_volume network parameter to convert into units of liquidity volume.",
|
||||
"The public key of the party making this commitment.": "The public key of the party making this commitment.",
|
||||
"The virtual stake of the liquidity provider.": "The virtual stake of the liquidity provider.",
|
||||
"The effective stake of the liquidity provider, adjusted for length of commitment and impact on equity like share.": "The effective stake of the liquidity provider, adjusted for length of commitment and impact on equity like share.",
|
||||
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than 100%, so they could lose some fees to a better performing LP.": "This LP's time on the book in the current epoch ({{currentEpoch}}) is less than 100%, so they could lose some fees to a better performing LP.",
|
||||
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than the minimum required ({{minimumRequired}}), so they could lose all fee revenue for this epoch.": "This LP's time on the book in the current epoch ({{currentEpoch}}) is less than the minimum required ({{minimumRequired}}), so they could lose all fee revenue for this epoch.",
|
||||
"Updated": "Updated",
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"Insurance pool": "Insurance pool",
|
||||
"Internal conditions": "Internal conditions",
|
||||
"Invalid data source": "Invalid data source",
|
||||
"involvedInMarkets": "Involved in {{count}} markets",
|
||||
"involvedInMarkets_other": "Involved in {{count}} markets",
|
||||
"involvedInMarkets_one": "Involved in {{count}} market",
|
||||
"involvedInMarkets_other": "Involved in {{count}} markets",
|
||||
"involvedInMarkets": "Involved in {{count}} markets",
|
||||
"Key": "Key",
|
||||
"Key details": "Key details",
|
||||
"Liquidity": "Liquidity",
|
||||
@@ -54,9 +54,9 @@
|
||||
"Maximum fraction of an LP's accrued fees that an LP would lose to liquidity providers that achieved a higher SLA performance than them. This is a market parameter.": "Maximum fraction of an LP's accrued fees that an LP would lose to liquidity providers that achieved a higher SLA performance than them. This is a market parameter.",
|
||||
"Maximum value that a proposed fee amount can be, which is submitted as part of the LP commitment transaction. Note that a value of 0.05 = 5%. This is a network parameter.": "Maximum value that a proposed fee amount can be, which is submitted as part of the LP commitment transaction. Note that a value of 0.05 = 5%. This is a network parameter.",
|
||||
"Metadata": "Metadata",
|
||||
"moreProofs": "And {{count}} more proofs",
|
||||
"moreProofs_one": "And {{count}} more proof",
|
||||
"moreProofs_other": "And {{count}} more proofs",
|
||||
"moreProofs": "And {{count}} more proofs",
|
||||
"Multiplier used to translate an LP's commitment amount to their liquidity obligation. This is a network parameter.": "Multiplier used to translate an LP's commitment amount to their liquidity obligation. This is a network parameter.",
|
||||
"No data": "No data",
|
||||
"No oracle proof for settlement data": "No oracle proof for settlement data",
|
||||
@@ -69,16 +69,16 @@
|
||||
"Oracle repository": "Oracle repository",
|
||||
"Oracle status for this market is <0>{{status}}</0>. {{description}} <1>Show more</1>": "Oracle status for this market is <0>{{status}}</0>. {{description}} <1>Show more</1>",
|
||||
"Oracle status: {{status}}. {{description}}": "Oracle status: {{status}}. {{description}}",
|
||||
"oracleInMarkets": "Oracle in {{count}} markets",
|
||||
"oracleInMarkets_one": "Oracle in {{count}} market",
|
||||
"oracleInMarkets_other": "Oracle in {{count}} markets",
|
||||
"oracleInMarkets": "Oracle in {{count}} markets",
|
||||
"Price monitoring bounds {{index}}": "Price monitoring bounds {{index}}",
|
||||
"Probability level for price projection, e.g. value of 0.95 will result in a price range such that over the specified projection horizon, the prices observed in the market should be in that range 95% of the time.": "Probability level for price projection, e.g. value of 0.95 will result in a price range such that over the specified projection horizon, the prices observed in the market should be in that range 95% of the time.",
|
||||
"Probability level used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short": "Probability level used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short",
|
||||
"Projection horizon measured as a year fraction used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short": "Projection horizon measured as a year fraction used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short",
|
||||
"proofsOfOwnership": "{{count}} proofs of ownership",
|
||||
"proofsOfOwnership_one": "{{count}} proof of ownership",
|
||||
"proofsOfOwnership_other": "{{count}} proofs of ownership",
|
||||
"proofsOfOwnership": "{{count}} proofs of ownership",
|
||||
"Proposal": "Proposal",
|
||||
"Propose a change to market": "Propose a change to market",
|
||||
"Read more": "Read more",
|
||||
@@ -135,9 +135,9 @@
|
||||
"Updated": "Updated",
|
||||
"Used to calculate the penalty to liquidity providers when they cannot support their open position with the assets in their margin and general accounts. This is a network parameter.": "Used to calculate the penalty to liquidity providers when they cannot support their open position with the assets in their margin and general accounts. This is a network parameter.",
|
||||
"Verified since {{lastVerified}}": "Verified since {{lastVerified}}",
|
||||
"verifyProofs": "Verify {{count}} proofs of ownership",
|
||||
"verifyProofs_one": "Verify {{count}} proof of ownership",
|
||||
"verifyProofs_other": "Verify {{count}} proofs of ownership",
|
||||
"verifyProofs": "Verify {{count}} proofs of ownership",
|
||||
"View governance proposal": "View governance proposal",
|
||||
"View liquidity provision table": "View liquidity provision table",
|
||||
"View on Etherscan": "View on Etherscan",
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
"Changes have been proposed for this market.": "Changes have been proposed for this market.",
|
||||
"Closing date": "Closing date",
|
||||
"Confirm transaction in wallet": "Confirm transaction in wallet",
|
||||
"Enactment date: {{date}}": "Enactment date: {{date}}",
|
||||
"Enactment date": "Enactment date",
|
||||
"Enactment date: {{date}}": "Enactment date: {{date}}",
|
||||
"estimated time to protocol upgrade": "estimated time to protocol upgrade",
|
||||
"estimating...": "estimating...",
|
||||
"Market": "Market",
|
||||
@@ -41,8 +41,8 @@
|
||||
"Update <0>{{key}}</0> to {{value}}": "Update <0>{{key}}</0> to {{value}}",
|
||||
"View details": "View details",
|
||||
"View in block explorer": "View in block explorer",
|
||||
"View proposal details": "View proposal details",
|
||||
"View proposal": "View proposal",
|
||||
"View proposal details": "View proposal details",
|
||||
"Voting": "Voting",
|
||||
"Your transaction has been confirmed": "Your transaction has been confirmed"
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"{{checkedAssets}} Assets": "{{checkedAssets}} Assets",
|
||||
"{{distance}} ago": "{{distance}} ago",
|
||||
"{{instrumentCode}} liquidity provision": "{{instrumentCode}} liquidity provision",
|
||||
"<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>": "<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>",
|
||||
"24h vol": "24h vol",
|
||||
"24h volume": "24h volume",
|
||||
"A percentage of commission earned by the referrer": "A percentage of commission earned by the referrer",
|
||||
@@ -53,13 +54,11 @@
|
||||
"Countdown": "Countdown",
|
||||
"Create a referral code": "Create a referral code",
|
||||
"Current tier": "Current tier",
|
||||
"combinedVolume": "Combined volume (last {{count}} epochs)",
|
||||
"combinedVolume_one": "Combined volume (last {{count}} epoch)",
|
||||
"combinedVolume_other": "Combined volume (last {{count}} epochs)",
|
||||
"Dark mode": "Dark mode",
|
||||
"Date Joined": "Date Joined",
|
||||
"Deposit": "Deposit",
|
||||
"Deposit funds": "Deposit funds",
|
||||
"Deposits": "Deposits",
|
||||
"Depth": "Depth",
|
||||
"Description": "Description",
|
||||
"Disclaimer": "Disclaimer",
|
||||
@@ -93,15 +92,15 @@
|
||||
"Final commission rate": "Final commission rate",
|
||||
"Find out more": "Find out more",
|
||||
"Free from the risks of real trading, Fairground is a safe and fun place to try out Vega yourself with virtual assets.": "Free from the risks of real trading, Fairground is a safe and fun place to try out Vega yourself with virtual assets.",
|
||||
"From epoch": "From epoch",
|
||||
"Fully decentralised high performance peer-to-network trading.": "Fully decentralised high performance peer-to-network trading.",
|
||||
"Funding": "Funding",
|
||||
"Funding history": "Funding history",
|
||||
"Funding payments": "Funding payments",
|
||||
"Funding Payments": "Funding Payments",
|
||||
"Funding payments": "Funding payments",
|
||||
"Funding Rate": "Funding Rate",
|
||||
"Funding rate": "Funding rate",
|
||||
"Futures": "Futures",
|
||||
"From epoch": "From epoch",
|
||||
"Generate a referral code to share with your friends and start earning commission.": "Generate a referral code to share with your friends and start earning commission.",
|
||||
"Generate code": "Generate code",
|
||||
"Get started": "Get started",
|
||||
@@ -142,14 +141,15 @@
|
||||
"Market triggers cancellation or governance vote has passed to cancel": "Market triggers cancellation or governance vote has passed to cancel",
|
||||
"Markets": "Markets",
|
||||
"Menu": "Menu",
|
||||
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
|
||||
"Min. epochs": "Min. epochs",
|
||||
"Min. trading volume": "Min. trading volume",
|
||||
"My current volume": "My current volume",
|
||||
"My liquidity provision": "My liquidity provision",
|
||||
"My trading fees": "My trading fees",
|
||||
"minTradingVolume": "Min. trading volume (last {{count}} epochs)",
|
||||
"minTradingVolume_one": "Min. trading volume (last {{count}} epoch)",
|
||||
"minTradingVolume_other": "Min. trading volume (last {{count}} epochs)",
|
||||
"My current volume": "My current volume",
|
||||
"My liquidity provision": "My liquidity provision",
|
||||
"My trading fees": "My trading fees",
|
||||
"myVolume": "My volume (last {{count}} epochs)",
|
||||
"myVolume_one": "My volume (last {{count}} epoch)",
|
||||
"myVolume_other": "My volume (last {{count}} epochs)",
|
||||
@@ -163,6 +163,7 @@
|
||||
"No market": "No market",
|
||||
"No markets": "No markets",
|
||||
"No markets.": "No markets.",
|
||||
"No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>": "No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>",
|
||||
"No open orders": "No open orders",
|
||||
"No orders": "No orders",
|
||||
"No party accepts any liability for any losses whatsoever.": "No party accepts any liability for any losses whatsoever.",
|
||||
@@ -177,8 +178,8 @@
|
||||
"Node: {{VEGA_URL}} is unsuitable": "Node: {{VEGA_URL}} is unsuitable",
|
||||
"Non-custodial and pseudonymous": "Non-custodial and pseudonymous",
|
||||
"None": "None",
|
||||
"Number of traders": "Number of traders",
|
||||
"Not connected": "Not connected",
|
||||
"Number of traders": "Number of traders",
|
||||
"Open": "Open",
|
||||
"Open a position": "Open a position",
|
||||
"Open markets": "Open markets",
|
||||
@@ -188,6 +189,9 @@
|
||||
"Orders": "Orders",
|
||||
"Page not found": "Page not found",
|
||||
"Parent of a market": "Parent of a market",
|
||||
"pastEpochs": "Past {{count}} epochs",
|
||||
"pastEpochs_one": "Past {{count}} epoch",
|
||||
"pastEpochs_other": "Past {{count}} epochs",
|
||||
"Perpetuals": "Perpetuals",
|
||||
"Please choose another market from the <0>market list</0>": "Please choose another market from the <0>market list</0>",
|
||||
"Please connect Vega wallet": "Please connect Vega wallet",
|
||||
@@ -201,9 +205,6 @@
|
||||
"Proposed markets": "Proposed markets",
|
||||
"Providing liquidity": "Providing liquidity",
|
||||
"Purpose built proof of stake blockchain": "Purpose built proof of stake blockchain",
|
||||
"pastEpochs": "Past {{count}} epochs",
|
||||
"pastEpochs_one": "Past {{count}} epoch",
|
||||
"pastEpochs_other": "Past {{count}} epochs",
|
||||
"qUSD": "qUSD",
|
||||
"qUSD provides a rough USD equivalent of balances across all assets using the value of \"Quantum\" for that asset": "qUSD provides a rough USD equivalent of balances across all assets using the value of \"Quantum\" for that asset",
|
||||
"Read the terms": "Read the terms",
|
||||
@@ -213,6 +214,9 @@
|
||||
"Referral benefits": "Referral benefits",
|
||||
"Referral discount": "Referral discount",
|
||||
"Referrals": "Referrals",
|
||||
"referralStatisticsCommission": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"referralStatisticsCommission_one": "Commission earned in <0>qUSD</0> (last {{count}} epoch)",
|
||||
"referralStatisticsCommission_other": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"Referrer commission": "Referrer commission",
|
||||
"Referrer trading discount": "Referrer trading discount",
|
||||
"Referrers earn commission based on a percentage of the taker fees their referees pay": "Referrers earn commission based on a percentage of the taker fees their referees pay",
|
||||
@@ -224,9 +228,6 @@
|
||||
"Rewards": "Rewards",
|
||||
"Rewards history": "Rewards history",
|
||||
"Rewards multipliers": "Rewards multipliers",
|
||||
"referralStatisticsCommission": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"referralStatisticsCommission_one": "Commission earned in <0>qUSD</0> (last {{count}} epoch)",
|
||||
"referralStatisticsCommission_other": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"runningNotionalOverEpochs": "Combined running notional over the {{count}} epochs",
|
||||
"runningNotionalOverEpochs_one": "Combined running notional over the {{count}} epoch",
|
||||
"runningNotionalOverEpochs_other": "Combined running notional over the {{count}} epochs",
|
||||
@@ -259,7 +260,6 @@
|
||||
"Successors to this market have been proposed": "Successors to this market have been proposed",
|
||||
"Supplied stake": "Supplied stake",
|
||||
"Suspended due to price or liquidity monitoring trigger": "Suspended due to price or liquidity monitoring trigger",
|
||||
"to": "to",
|
||||
"Target stake": "Target stake",
|
||||
"The amount of fees paid to liquidity providers across the whole market during the last epoch {{epoch}}.": "The amount of fees paid to liquidity providers across the whole market during the last epoch {{epoch}}.",
|
||||
"The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee": "The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee",
|
||||
@@ -278,11 +278,15 @@
|
||||
"This market URL is not available any more.": "This market URL is not available any more.",
|
||||
"This timestamp is user curated metadata and does not drive any on-chain functionality.": "This timestamp is user curated metadata and does not drive any on-chain functionality.",
|
||||
"Tier": "Tier",
|
||||
"to": "to",
|
||||
"Toast location": "Toast location",
|
||||
"Total discount": "Total discount",
|
||||
"Total distributed": "Total distributed",
|
||||
"Total fee after discount": "Total fee after discount",
|
||||
"Total fee before discount": "Total fee before discount",
|
||||
"totalCommission": "Total commission (last {{count}}} epochs)",
|
||||
"totalCommission_one": "Total commission (last {{count}}} epoch)",
|
||||
"totalCommission_other": "Total commission (last {{count}}} epochs)",
|
||||
"Trader": "Trader",
|
||||
"Trades": "Trades",
|
||||
"Trading": "Trading",
|
||||
@@ -292,12 +296,10 @@
|
||||
"Trading on Market {{name}} may stop. There are open proposals to close this market": "Trading on Market {{name}} may stop. There are open proposals to close this market",
|
||||
"Trading on Market {{name}} will stop on {{date}}": "Trading on Market {{name}} will stop on {{date}}",
|
||||
"Transfer": "Transfer",
|
||||
"totalCommission": "Total commission (last {{count}}} epochs)",
|
||||
"totalCommission_one": "Total commission (last {{count}}} epoch)",
|
||||
"totalCommission_other": "Total commission (last {{count}}} epochs)",
|
||||
"Unknown": "Unknown",
|
||||
"Unknown settlement date": "Unknown settlement date",
|
||||
"Vega Reward pot": "Vega Reward pot",
|
||||
"Vega Wallet <0>full featured<0>": "Vega Wallet <0>full featured<0>",
|
||||
"Vesting": "Vesting",
|
||||
"Vesting {{assetSymbol}}": "Vesting {{assetSymbol}}",
|
||||
"Vesting multiplier": "Vesting multiplier",
|
||||
@@ -320,17 +322,18 @@
|
||||
"We're sorry but we don't have an active referral programme currently running. You can propose a new programme <0>here</0>.": "We're sorry but we don't have an active referral programme currently running. You can propose a new programme <0>here</0>.",
|
||||
"Welcome to Vega trading!": "Welcome to Vega trading!",
|
||||
"Withdraw": "Withdraw",
|
||||
"Withdrawals": "Withdrawals",
|
||||
"You can opt out any time via settings": "You can opt out any time via settings",
|
||||
"You may encounter bugs, loss of functionality or loss of assets.": "You may encounter bugs, loss of functionality or loss of assets.",
|
||||
"You must be connected to the Vega wallet.": "You must be connected to the Vega wallet.",
|
||||
"You need a <0>Vega wallet</0> to start trading in this market.": "You need a <0>Vega wallet</0> to start trading in this market.",
|
||||
"You need at least {{requiredStake}} VEGA staked to generate a referral code and participate in the referral program.": "You need at least {{requiredStake}} VEGA staked to generate a referral code and participate in the referral program.",
|
||||
"You will no longer be able to hold a position on this market when it closes in {{duration}}.": "You will no longer be able to hold a position on this market when it closes in {{duration}}.",
|
||||
"youAreJoiningTheGroup": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.",
|
||||
"youAreJoiningTheGroup_one": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epoch.",
|
||||
"youAreJoiningTheGroup_other": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.",
|
||||
"Your code has been rejected": "Your code has been rejected",
|
||||
"Your identity is always anonymous on Vega": "Your identity is always anonymous on Vega",
|
||||
"Your referral code": "Your referral code",
|
||||
"Your tier": "Your tier",
|
||||
"youAreJoiningTheGroup": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.",
|
||||
"youAreJoiningTheGroup_one": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epoch.",
|
||||
"youAreJoiningTheGroup_other": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs."
|
||||
"Your tier": "Your tier"
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"Collapse": "Collapse",
|
||||
"Copied": "Copied",
|
||||
"Dark mode": "Dark mode",
|
||||
"Dismiss all toasts": "Dismiss all toasts",
|
||||
"Dismiss all": "Dismiss all",
|
||||
"Dismiss all toasts": "Dismiss all toasts",
|
||||
"Exit view as": "Exit view as",
|
||||
"Expand": "Expand",
|
||||
"Light mode": "Light mode",
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"Expired on {{date}}": "Expired on {{date}}",
|
||||
"Not time-based": "Not time-based",
|
||||
"Expired": "Expired",
|
||||
"Mark": "Mark",
|
||||
"Required": "Required",
|
||||
"Invalid Ethereum address": "Invalid Ethereum address",
|
||||
"Invalid Vega key": "Invalid Vega key",
|
||||
"Value is below minimum": "Value is below minimum",
|
||||
"Value is above maximum": "Value is above maximum",
|
||||
"Must be valid JSON": "Must be valid JSON",
|
||||
"{{field}} accepts up to {{decimals}} decimal places": "{{field}} accepts up to {{decimals}} decimal places",
|
||||
"{{field}} must be a multiple of {{step}} for this market": "{{field}} must be a multiple of {{step}} for this market",
|
||||
"{{field}} must be whole numbers for this market": "{{field}} must be whole numbers for this market",
|
||||
"{{field}} accepts up to {{decimals}} decimal places": "{{field}} accepts up to {{decimals}} decimal places"
|
||||
"Expired": "Expired",
|
||||
"Expired on {{date}}": "Expired on {{date}}",
|
||||
"Invalid Ethereum address": "Invalid Ethereum address",
|
||||
"Invalid Vega key": "Invalid Vega key",
|
||||
"Mark": "Mark",
|
||||
"Must be valid JSON": "Must be valid JSON",
|
||||
"Not time-based": "Not time-based",
|
||||
"Required": "Required",
|
||||
"Value is above maximum": "Value is above maximum",
|
||||
"Value is below minimum": "Value is below minimum"
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
{
|
||||
"About the Vega wallet": "About the Vega wallet",
|
||||
"Supported browsers": "Supported browsers",
|
||||
"Connect Vega wallet": "Connect Vega wallet",
|
||||
"Get a Vega wallet": "Get a Vega wallet",
|
||||
"Connect securely, deposit funds and approve or reject transactions with the Vega wallet": "Connect securely, deposit funds and approve or reject transactions with the Vega wallet",
|
||||
"Connect": "Connect",
|
||||
"Vega Wallet <0>full featured<0>": "Vega Wallet <0>full featured<0>",
|
||||
"your browser": "your browser",
|
||||
"Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
|
||||
"Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
|
||||
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
|
||||
"Connect directly via Metamask with the Vega Snap for single key support without advanced features.": "Connect directly via Metamask with the Vega Snap for single key support without advanced features.",
|
||||
"Connect via Vega MetaMask Snap": "Connect via Vega MetaMask Snap",
|
||||
"Install Metamask with the Vega Snap for single key support without advanced features.": "Install Metamask with the Vega Snap for single key support without advanced features.",
|
||||
"Install Vega MetaMask Snap": "Install Vega MetaMask Snap",
|
||||
"No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>": "No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>",
|
||||
"Advanced / Other options...": "Advanced / Other options...",
|
||||
"View as party": "View as party",
|
||||
"Get the Vega Wallet": "Get the Vega Wallet",
|
||||
"Custom wallet location": "Custom wallet location",
|
||||
"Go back": "Go back",
|
||||
"Connect the App/CLI": "Connect the App/CLI",
|
||||
"Use the Desktop App/CLI": "Use the Desktop App/CLI",
|
||||
"Enter a custom wallet location": "Enter a custom wallet location",
|
||||
"<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>": "<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>",
|
||||
"Verifying chain": "Verifying chain",
|
||||
"Successfully connected": "Successfully connected",
|
||||
"Connecting...": "Connecting...",
|
||||
"Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.": "Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.",
|
||||
"Understand the risk": "Understand the risk",
|
||||
"Cancel": "Cancel",
|
||||
"I agree": "I agree",
|
||||
"Something went wrong": "Something went wrong",
|
||||
"About the Vega wallet": "About the Vega wallet",
|
||||
"Advanced / Other options...": "Advanced / Other options...",
|
||||
"An unknown error occurred": "An unknown error occurred",
|
||||
"Try again": "Try again",
|
||||
"User rejected": "User rejected",
|
||||
"The user rejected the wallet connection": "The user rejected the wallet connection",
|
||||
"Wrong network": "Wrong network",
|
||||
"No wallet detected": "No wallet detected",
|
||||
"Vega browser extension not installed": "Vega browser extension not installed",
|
||||
"Snap failed": "Snap failed",
|
||||
"Could not connect to Vega MetaMask Snap": "Could not connect to Vega MetaMask Snap",
|
||||
"No wallet application running at {{connectorUrl}}": "No wallet application running at {{connectorUrl}}",
|
||||
"No Vega Wallet application running": "No Vega Wallet application running",
|
||||
"Read the docs to troubleshoot": "Read the docs to troubleshoot",
|
||||
"Connection in progress": "Connection in progress",
|
||||
"Approve the connection from your Vega wallet app.": "Approve the connection from your Vega wallet app.",
|
||||
"To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".": "To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".",
|
||||
"SELECT A VEGA KEY": "SELECT A VEGA KEY",
|
||||
"Select": "Select",
|
||||
"Copy": "Copy",
|
||||
"Disconnect all keys": "Disconnect all keys",
|
||||
"Pubkey must be 64 characters in length": "Pubkey must be 64 characters in length",
|
||||
"Pubkey must be be valid hex": "Pubkey must be be valid hex",
|
||||
"VIEW AS VEGA USER": "VIEW AS VEGA USER",
|
||||
"Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.": "Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.",
|
||||
"Browse from the perspective of another Vega user in read-only mode.": "Browse from the perspective of another Vega user in read-only mode.",
|
||||
"Required": "Required",
|
||||
"Browse network": "Browse network",
|
||||
"Cancel": "Cancel",
|
||||
"Checking wallet version": "Checking wallet version",
|
||||
"Checking your wallet is compatible with this app": "Checking your wallet is compatible with this app",
|
||||
"Wrong Network": "Wrong Network"
|
||||
"Connect": "Connect",
|
||||
"Connect directly via Metamask with the Vega Snap for single key support without advanced features.": "Connect directly via Metamask with the Vega Snap for single key support without advanced features.",
|
||||
"Connect securely, deposit funds and approve or reject transactions with the Vega wallet": "Connect securely, deposit funds and approve or reject transactions with the Vega wallet",
|
||||
"Connect the App/CLI": "Connect the App/CLI",
|
||||
"Connect Vega wallet": "Connect Vega wallet",
|
||||
"Connect via Vega MetaMask Snap": "Connect via Vega MetaMask Snap",
|
||||
"Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
|
||||
"Connecting...": "Connecting...",
|
||||
"Connection in progress": "Connection in progress",
|
||||
"Copy": "Copy",
|
||||
"Could not connect to Vega MetaMask Snap": "Could not connect to Vega MetaMask Snap",
|
||||
"Custom wallet location": "Custom wallet location",
|
||||
"Disconnect all keys": "Disconnect all keys",
|
||||
"Enter a custom wallet location": "Enter a custom wallet location",
|
||||
"Get a Vega wallet": "Get a Vega wallet",
|
||||
"Get the Vega Wallet": "Get the Vega Wallet",
|
||||
"Go back": "Go back",
|
||||
"I agree": "I agree",
|
||||
"Install Metamask with the Vega Snap for single key support without advanced features.": "Install Metamask with the Vega Snap for single key support without advanced features.",
|
||||
"Install Vega MetaMask Snap": "Install Vega MetaMask Snap",
|
||||
"Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
|
||||
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
|
||||
"No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>": "No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>",
|
||||
"No Vega Wallet application running": "No Vega Wallet application running",
|
||||
"No wallet application running at {{connectorUrl}}": "No wallet application running at {{connectorUrl}}",
|
||||
"No wallet detected": "No wallet detected",
|
||||
"Pubkey must be 64 characters in length": "Pubkey must be 64 characters in length",
|
||||
"Pubkey must be be valid hex": "Pubkey must be be valid hex",
|
||||
"Read the docs to troubleshoot": "Read the docs to troubleshoot",
|
||||
"Required": "Required",
|
||||
"Select": "Select",
|
||||
"SELECT A VEGA KEY": "SELECT A VEGA KEY",
|
||||
"Snap failed": "Snap failed",
|
||||
"Something went wrong": "Something went wrong",
|
||||
"Successfully connected": "Successfully connected",
|
||||
"Supported browsers": "Supported browsers",
|
||||
"The user rejected the wallet connection": "The user rejected the wallet connection",
|
||||
"To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".": "To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".",
|
||||
"Try again": "Try again",
|
||||
"Understand the risk": "Understand the risk",
|
||||
"Use the Desktop App/CLI": "Use the Desktop App/CLI",
|
||||
"User rejected": "User rejected",
|
||||
"Vega browser extension not installed": "Vega browser extension not installed",
|
||||
"Vega Wallet <0>full featured<0>": "Vega Wallet <0>full featured<0>",
|
||||
"Verifying chain": "Verifying chain",
|
||||
"View as party": "View as party",
|
||||
"VIEW AS VEGA USER": "VIEW AS VEGA USER",
|
||||
"Wrong Network": "Wrong Network",
|
||||
"Wrong network": "Wrong network",
|
||||
"your browser": "your browser"
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
"Available to withdraw in {{availableTimestamp}}": "Available to withdraw in {{availableTimestamp}}",
|
||||
"Balance available": "Balance available",
|
||||
"Complete the withdrawal to release your funds": "Complete the withdrawal to release your funds",
|
||||
"Complete withdrawal": "Complete withdrawal",
|
||||
"Completed": "Completed",
|
||||
"completeWithdrawals": "Complete these {{count}} withdrawals to release your funds",
|
||||
"completeWithdrawals_one": "Complete these {{count}} withdrawal to release your funds",
|
||||
"completeWithdrawals_other": "Complete these {{count}} withdrawals to release your funds",
|
||||
"Complete withdrawal": "Complete withdrawal",
|
||||
"Completed": "Completed",
|
||||
"Connect Ethereum wallet to complete": "Connect Ethereum wallet to complete",
|
||||
"Connect": "Connect",
|
||||
"Connect Ethereum wallet to complete": "Connect Ethereum wallet to complete",
|
||||
"Created": "Created",
|
||||
"Delay time": "Delay time",
|
||||
"Delayed (ready in {{readyIn}})": "Delayed (ready in {{readyIn}})",
|
||||
@@ -40,9 +40,9 @@
|
||||
"Verifying withdrawal approval": "Verifying withdrawal approval",
|
||||
"View withdrawal details": "View withdrawal details",
|
||||
"View withdrawals": "View withdrawals",
|
||||
"Withdraw": "Withdraw",
|
||||
"Withdraw {{amount}} {{symbol}}": "Withdraw {{amount}} {{symbol}}",
|
||||
"Withdraw funds": "Withdraw funds",
|
||||
"Withdraw": "Withdraw",
|
||||
"Withdrawal ready": "Withdrawal ready",
|
||||
"Withdrawals of {{threshold}} {{symbol}} or more will be delayed for {{delay}}.": "Withdrawals of {{threshold}} {{symbol}} or more will be delayed for {{delay}}.",
|
||||
"Withdrawals ready": "Withdrawals ready",
|
||||
|
||||
@@ -119,6 +119,8 @@ describe('getLiquidityProvision', () => {
|
||||
createdAt: '2022-12-16T09:28:29.071781Z',
|
||||
id: 'dde288688af2aeb5feb349dd72d3679a7a9be34c7375f6a4a48ef2f6140e7e59',
|
||||
fee: '0.001',
|
||||
partyId:
|
||||
'dde288688af2aeb5feb349dd72d3679a7a9be34c7375f6a4a48ef2f6140e7e59',
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
accountsConnection: {
|
||||
|
||||
@@ -159,7 +159,14 @@ export const getLiquidityProvision = (
|
||||
const liquidityProvider = liquidityProviders.find(
|
||||
(f) => liquidityProvision.party.id === f.partyId
|
||||
);
|
||||
if (!liquidityProvider) return liquidityProvision;
|
||||
|
||||
if (!liquidityProvider) {
|
||||
return {
|
||||
...liquidityProvision,
|
||||
partyId: liquidityProvision.party.id,
|
||||
};
|
||||
}
|
||||
|
||||
const accounts = compact(
|
||||
liquidityProvision.party.accountsConnection?.edges
|
||||
).map((e) => e.node);
|
||||
|
||||
@@ -93,13 +93,13 @@ describe('LiquidityTable', () => {
|
||||
'Commitment ()',
|
||||
'Obligation',
|
||||
'Fee',
|
||||
'Adjusted stake share',
|
||||
'Adjusted stake',
|
||||
'Share',
|
||||
'Live supplied liquidity',
|
||||
'Fees accrued this epoch',
|
||||
'Live time on book',
|
||||
'Live liquidity quality score (%)',
|
||||
'Last time on the book',
|
||||
'Live liquidity score (%)',
|
||||
'Last time on book',
|
||||
'Last fee penalty',
|
||||
'Last bond penalty',
|
||||
'Created',
|
||||
|
||||
@@ -357,10 +357,12 @@ export const LiquidityTable = ({
|
||||
},
|
||||
},
|
||||
{
|
||||
headerName: t('Adjusted stake share'),
|
||||
headerName: t('Adjusted stake'),
|
||||
field: 'feeShare.virtualStake',
|
||||
type: 'rightAligned',
|
||||
headerTooltip: t('The virtual stake of the liquidity provider.'),
|
||||
headerTooltip: t(
|
||||
'The effective stake of the liquidity provider, adjusted for length of commitment and impact on equity like share.'
|
||||
),
|
||||
|
||||
valueFormatter: assetDecimalsQuantumFormatter,
|
||||
tooltipValueGetter: assetDecimalsFormatter,
|
||||
@@ -427,10 +429,12 @@ export const LiquidityTable = ({
|
||||
valueFormatter: percentageFormatter,
|
||||
},
|
||||
{
|
||||
headerName: t('Live liquidity quality score (%)'),
|
||||
headerName: t('Live liquidity score (%)'),
|
||||
field: 'feeShare.averageScore',
|
||||
type: 'rightAligned',
|
||||
headerTooltip: t('The average score of the liquidity provider.'),
|
||||
headerTooltip: t(
|
||||
'The liquidity score of the provider, used to determine allocation of fees to the best performing LPs. Posting volume closer to the mid on both sides of the book will improve this score.'
|
||||
),
|
||||
valueFormatter: percentageFormatter,
|
||||
},
|
||||
],
|
||||
@@ -440,24 +444,30 @@ export const LiquidityTable = ({
|
||||
marryChildren: true,
|
||||
children: [
|
||||
{
|
||||
headerName: t(`Last time on the book`),
|
||||
headerName: t(`Last time on book`),
|
||||
field: 'sla.lastEpochFractionOfTimeOnBook',
|
||||
type: 'rightAligned',
|
||||
headerTooltip: t('Last epoch fraction of time on the book.'),
|
||||
headerTooltip: t(
|
||||
'Fraction of time on the book at the end of the last epoch.'
|
||||
),
|
||||
valueFormatter: percentageFormatter,
|
||||
},
|
||||
{
|
||||
headerName: t(`Last fee penalty`),
|
||||
field: 'sla.lastEpochFeePenalty',
|
||||
type: 'rightAligned',
|
||||
headerTooltip: t('Last epoch fee penalty.'),
|
||||
headerTooltip: t(
|
||||
'Penalty applied on the fees a liquidity provider collected in the last epoch. This percentage increased if an LP did not meet the SLA, or if they met it but other LPs outscored them in the previous epoch.'
|
||||
),
|
||||
valueFormatter: percentageFormatter,
|
||||
},
|
||||
{
|
||||
headerName: t(`Last bond penalty`),
|
||||
field: 'sla.lastEpochBondPenalty',
|
||||
type: 'rightAligned',
|
||||
headerTooltip: t('Last epoch bond penalty.'),
|
||||
headerTooltip: t(
|
||||
`Penalty applied on a provider's bond penalty at the end of the last epoch. This percentage increased if an LP: had a shortfall and their bond needed to be used to cover it, did not meet the SLA, and/or reduced their commitment to the point that the market was below its target stake.`
|
||||
),
|
||||
valueFormatter: percentageFormatter,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface LoggerProps extends LoggerConf {
|
||||
|
||||
export const useLogger = ({ dsn, env, ...props }: LoggerProps) => {
|
||||
const logger = useRef<LocalLogger | null>(null);
|
||||
|
||||
if (!logger.current) {
|
||||
logger.current = localLoggerFactory(props);
|
||||
if (dsn) {
|
||||
|
||||
@@ -25,6 +25,7 @@ describe('LocalLogger', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('logger should be properly instantiate', () => {
|
||||
const logger = localLoggerFactory({});
|
||||
expect(logger).toBeInstanceOf(LocalLogger);
|
||||
@@ -50,7 +51,7 @@ describe('LocalLogger', () => {
|
||||
logger[method]('test', 'test2');
|
||||
// eslint-disable-next-line no-console
|
||||
expect(console[consoleMethod]).toHaveBeenCalledWith(
|
||||
`trading:${methodToLevel[i]}: `,
|
||||
`trading:${methodToLevel[i]}:`,
|
||||
'test',
|
||||
'test2'
|
||||
);
|
||||
@@ -110,7 +111,7 @@ describe('LocalLogger', () => {
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
expect(console.debug).toHaveBeenCalledWith(
|
||||
'trading:debug: ',
|
||||
'trading:debug:',
|
||||
'test',
|
||||
'test1'
|
||||
);
|
||||
|
||||
@@ -62,6 +62,7 @@ export class LocalLogger {
|
||||
}
|
||||
private tags: string[] = [];
|
||||
private _application = 'trading';
|
||||
|
||||
constructor(conf: LoggerConf) {
|
||||
if (conf.application) {
|
||||
this._application = conf.application;
|
||||
@@ -69,6 +70,7 @@ export class LocalLogger {
|
||||
this.tags = [...(conf.tags || [])];
|
||||
this._logLevel = conf.logLevel || this._logLevel;
|
||||
}
|
||||
|
||||
public debug(...args: ConsoleArg[]) {
|
||||
this._log('debug', 'debug', args);
|
||||
}
|
||||
@@ -101,7 +103,7 @@ export class LocalLogger {
|
||||
) {
|
||||
// eslint-disable-next-line no-console
|
||||
console[logMethod].apply(console, [
|
||||
`${this._application}:${level}: `,
|
||||
`${this._application}:${level}:`,
|
||||
...args,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -563,7 +563,7 @@ const WarningCell = ({
|
||||
<div className="flex items-center justify-end">
|
||||
{showIcon && (
|
||||
<span className="mr-2 text-black dark:text-white">
|
||||
<VegaIcon name={VegaIconNames.EXCLAIMATION_MARK} size={12} />
|
||||
<VegaIcon name={VegaIconNames.EXCLAMATION_MARK} size={12} />
|
||||
</span>
|
||||
)}
|
||||
<span className="overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
|
||||
@@ -94,7 +94,7 @@ export const ProtocolUpgradeCountdown = ({
|
||||
}
|
||||
)}
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.EXCLAIMATION_MARK} size={12} />{' '}
|
||||
<VegaIcon name={VegaIconNames.EXCLAMATION_MARK} size={12} />{' '}
|
||||
<span className="flex flex-nowrap gap-1 whitespace-nowrap">
|
||||
<span>{t('Network upgrade in {{countdown}}', { countdown })} </span>
|
||||
</span>
|
||||
|
||||
@@ -98,7 +98,7 @@ export const tradesProvider = makeDataProvider<
|
||||
pagination: {
|
||||
getPageInfo,
|
||||
append,
|
||||
first: MAX_TRADES,
|
||||
last: MAX_TRADES,
|
||||
},
|
||||
fetchPolicy: 'no-cache',
|
||||
getSubscriptionVariables: ({ marketId }) => ({ marketId }),
|
||||
|
||||
@@ -37,8 +37,6 @@ export function Dialog({
|
||||
'w-full h-full'
|
||||
);
|
||||
const wrapperClasses = classNames(
|
||||
// Positions the modal in the center of screen
|
||||
'z-20 relative rounded top-[10vh]',
|
||||
// Dimensions
|
||||
'max-w-[90vw] p-4 md:p-8',
|
||||
// Need to apply background and text colors again as content is rendered in a portal
|
||||
@@ -72,27 +70,34 @@ export function Dialog({
|
||||
onInteractOutside={onInteractOutside}
|
||||
data-testid={dataTestId}
|
||||
>
|
||||
<div className={wrapperClasses}>
|
||||
{onChange && (
|
||||
<DialogPrimitives.Close
|
||||
className="absolute p-2 top-0 right-0 md:top-2 md:right-2"
|
||||
data-testid="dialog-close"
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.CROSS} size={24} />
|
||||
</DialogPrimitives.Close>
|
||||
<div
|
||||
className={classNames(
|
||||
// Positions the modal in the center of screen
|
||||
'z-20 relative rounded top-[5vw] pb-[5vw] lg:top-[10vh] lg:pb-[10vh]'
|
||||
)}
|
||||
<div className="flex gap-4 max-w-full">
|
||||
{icon && <div className="fill-current">{icon}</div>}
|
||||
<div data-testid="dialog-content" className="flex-1 max-w-full">
|
||||
{title && (
|
||||
<h1
|
||||
className="text-xl uppercase mb-4 pr-2"
|
||||
data-testid="dialog-title"
|
||||
>
|
||||
{title}
|
||||
</h1>
|
||||
)}
|
||||
<div>{children}</div>
|
||||
>
|
||||
<div className={wrapperClasses}>
|
||||
{onChange && (
|
||||
<DialogPrimitives.Close
|
||||
className="absolute p-2 top-0 right-0 md:top-2 md:right-2"
|
||||
data-testid="dialog-close"
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.CROSS} size={24} />
|
||||
</DialogPrimitives.Close>
|
||||
)}
|
||||
<div className="flex gap-4 max-w-full">
|
||||
{icon && <div className="fill-current">{icon}</div>}
|
||||
<div data-testid="dialog-content" className="flex-1 max-w-full">
|
||||
{title && (
|
||||
<h1
|
||||
className="text-xl uppercase mb-4 pr-2"
|
||||
data-testid="dialog-title"
|
||||
>
|
||||
{title}
|
||||
</h1>
|
||||
)}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export const IconExclaimationMark = ({ size = 16 }: { size: number }) => {
|
||||
export const IconExclamationMark = ({ size = 16 }: { size: number }) => {
|
||||
return (
|
||||
<svg width={size} height={size} viewBox="0 0 16 16">
|
||||
<path d="M8 0.879997L7.57 1.63L0.130005 14.5H15.87L8 0.879997ZM8.75 12H7.25V10.5H8.75V12ZM7.25 9.5V6H8.75V9.5H7.25Z" />
|
||||
@@ -0,0 +1,28 @@
|
||||
export const IconMan = ({ size = 14 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 16 16"
|
||||
className="stroke-current"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M8.00016 7.99996C9.47292 7.99996 10.6668 6.80605 10.6668 5.33329C10.6668 3.86053 9.47292 2.66663 8.00016 2.66663C6.5274 2.66663 5.3335 3.86053 5.3335 5.33329C5.3335 6.80605 6.5274 7.99996 8.00016 7.99996Z"
|
||||
stroke="#DCDEE3"
|
||||
stroke-width="1.33333"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
className="stroke-current"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.00033 9.33333C5.79119 9.33333 4.00033 11.1242 4.00033 13.3333V13.8667C4.00033 13.9403 3.94063 14 3.86699 14H2.80033C2.72669 14 2.66699 13.9403 2.66699 13.8667V13.3333C2.66699 10.3878 5.05481 8 8.00033 8C10.9458 8 13.3337 10.3878 13.3337 13.3333V13.8667C13.3337 13.9403 13.274 14 13.2003 14H12.1337C12.06 14 12.0003 13.9403 12.0003 13.8667V13.3333C12.0003 11.1242 10.2095 9.33333 8.00033 9.33333Z"
|
||||
fill="#DCDEE3"
|
||||
className="stroke-current"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
export const IconStreak = ({ size = 14 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="fillCurrent"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M5.999 4H3.99902V5.99997H5.999V4Z" fill="fillCurrent" />
|
||||
<path
|
||||
d="M7.999 2.0001V0.00012207H5.99902V2.0001V4.00007H7.999V2.0001Z"
|
||||
fill="fillCurrent"
|
||||
/>
|
||||
<path d="M3.99897 6H-0.000976562V7.99997H3.99897V6Z" fill="fillCurrent" />
|
||||
<path
|
||||
d="M5.999 7.99988H3.99902V9.99985H5.999V7.99988Z"
|
||||
fill="fillCurrent"
|
||||
/>
|
||||
<path
|
||||
d="M7.999 9.99994H5.99902V13.9999H7.999V9.99994Z"
|
||||
fill="fillCurrent"
|
||||
/>
|
||||
<path
|
||||
d="M9.999 7.99988H7.99902V9.99985H9.999V7.99988Z"
|
||||
fill="fillCurrent"
|
||||
/>
|
||||
<path d="M13.999 6H9.99902V7.99997H13.999V6Z" fill="fillCurrent" />
|
||||
<path d="M9.999 4H7.99902V5.99997H9.999V4Z" fill="fillCurrent" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export const IconTeam = ({ size = 14 }: { size: number }) => {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g id="Icon">
|
||||
<path
|
||||
id="Vector"
|
||||
d="M13.1282 11.1863C12.7371 10.7949 12.2801 10.4754 11.7782 10.2426C12.486 9.66912 12.9375 8.79412 12.9375 7.81287C12.9375 6.08162 11.4938 4.6613 9.76254 4.68787C8.05785 4.71443 6.68441 6.10349 6.68441 7.81287C6.68441 8.79412 7.13754 9.66912 7.84379 10.2426C7.34177 10.4753 6.88476 10.7947 6.49379 11.1863C5.64066 12.041 5.15629 13.1691 5.12504 14.3722C5.12462 14.3889 5.12755 14.4055 5.13364 14.421C5.13974 14.4366 5.14888 14.4507 5.16053 14.4627C5.17218 14.4746 5.1861 14.4841 5.20147 14.4906C5.21684 14.497 5.23336 14.5004 5.25004 14.5004H6.12504C6.19223 14.5004 6.24848 14.4472 6.25004 14.3801C6.27973 13.4738 6.64691 12.6254 7.29223 11.9816C7.62245 11.6496 8.01523 11.3865 8.44784 11.2073C8.88045 11.0281 9.3443 10.9366 9.81254 10.9379C10.7641 10.9379 11.6594 11.3082 12.3329 11.9816C12.9766 12.6254 13.3438 13.4738 13.375 14.3801C13.3766 14.4472 13.4329 14.5004 13.5 14.5004H14.375C14.3917 14.5004 14.4082 14.497 14.4236 14.4906C14.439 14.4841 14.4529 14.4746 14.4646 14.4627C14.4762 14.4507 14.4853 14.4366 14.4914 14.421C14.4975 14.4055 14.5005 14.3889 14.5 14.3722C14.4688 13.1691 13.9844 12.041 13.1282 11.1863ZM9.81254 9.81287C9.27816 9.81287 8.77504 9.60505 8.39848 9.22693C8.2095 9.03944 8.06022 8.8158 7.95955 8.56937C7.85888 8.32293 7.80888 8.05874 7.81254 7.79255C7.81723 7.28005 8.02191 6.78474 8.37973 6.41755C8.75473 6.03318 9.25629 5.81912 9.79223 5.81287C10.3219 5.80818 10.836 6.01443 11.2141 6.38474C11.6016 6.76443 11.8141 7.27224 11.8141 7.81287C11.8141 8.34724 11.6063 8.8488 11.2282 9.22693C11.0427 9.41333 10.822 9.56109 10.579 9.66167C10.336 9.76224 10.0755 9.81363 9.81254 9.81287ZM5.89848 8.22537C5.88441 8.08943 5.8766 7.95193 5.8766 7.81287C5.8766 7.56443 5.90004 7.32224 5.94379 7.0863C5.95473 7.03005 5.92504 6.97224 5.87348 6.9488C5.66098 6.85349 5.46566 6.72224 5.29691 6.55662C5.09807 6.36382 4.9416 6.13168 4.83748 5.87503C4.73337 5.61837 4.6839 5.34283 4.69223 5.06599C4.70629 4.56443 4.90785 4.08787 5.25941 3.72849C5.64535 3.33318 6.1641 3.11755 6.71566 3.1238C7.2141 3.12849 7.69535 3.32068 8.05941 3.6613C8.18285 3.77693 8.2891 3.90505 8.37817 4.04255C8.40942 4.09099 8.47035 4.1113 8.52348 4.09255C8.79848 3.99724 9.0891 3.93005 9.38754 3.8988C9.47504 3.88943 9.52504 3.79568 9.48598 3.71755C8.97816 2.71287 7.94066 2.01912 6.74066 2.00037C5.00785 1.9738 3.5641 3.39412 3.5641 5.1238C3.5641 6.10505 4.01566 6.98005 4.72348 7.55349C4.2266 7.78318 3.76879 8.10037 3.37191 8.49724C2.51566 9.35193 2.03129 10.4801 2.00004 11.6847C1.99962 11.7014 2.00255 11.718 2.00864 11.7335C2.01474 11.7491 2.02388 11.7632 2.03553 11.7752C2.04718 11.7871 2.0611 11.7966 2.07647 11.8031C2.09184 11.8095 2.10836 11.8129 2.12504 11.8129H3.0016C3.06879 11.8129 3.12504 11.7597 3.1266 11.6926C3.15629 10.7863 3.52348 9.93787 4.16879 9.29412C4.62816 8.83474 5.19066 8.51599 5.80473 8.3613C5.86566 8.34568 5.90629 8.28787 5.89848 8.22537Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -14,7 +14,7 @@ import { IconCopy } from './svg-icons/icon-copy';
|
||||
import { IconCross } from './svg-icons/icon-cross';
|
||||
import { IconDeposit } from './svg-icons/icon-deposit';
|
||||
import { IconEdit } from './svg-icons/icon-edit';
|
||||
import { IconExclaimationMark } from './svg-icons/icon-exclaimation-mark';
|
||||
import { IconExclamationMark } from './svg-icons/icon-exclamation-mark';
|
||||
import { IconEye } from './svg-icons/icon-eye';
|
||||
import { IconEyeOff } from './svg-icons/icon-eye-off';
|
||||
import { IconForum } from './svg-icons/icon-forum';
|
||||
@@ -41,6 +41,9 @@ import { IconTwitter } from './svg-icons/icon-twitter';
|
||||
import { IconVote } from './svg-icons/icon-vote';
|
||||
import { IconWarning } from './svg-icons/icon-warning';
|
||||
import { IconWithdraw } from './svg-icons/icon-withdraw';
|
||||
import { IconMan } from './svg-icons/icon-man';
|
||||
import { IconTeam } from './svg-icons/icon-team';
|
||||
import { IconStreak } from './svg-icons/icon-streak';
|
||||
|
||||
export enum VegaIconNames {
|
||||
ARROW_DOWN = 'arrow-down',
|
||||
@@ -59,7 +62,7 @@ export enum VegaIconNames {
|
||||
CROSS = 'cross',
|
||||
DEPOSIT = 'deposit',
|
||||
EDIT = 'edit',
|
||||
EXCLAIMATION_MARK = 'exclaimation-mark',
|
||||
EXCLAMATION_MARK = 'exclamation-mark',
|
||||
EYE = 'eye',
|
||||
EYE_OFF = 'eye-off',
|
||||
FORUM = 'forum',
|
||||
@@ -76,6 +79,7 @@ export enum VegaIconNames {
|
||||
QUESTION_MARK = 'question-mark',
|
||||
SEARCH = 'search',
|
||||
STAR = 'star',
|
||||
STREAK = 'streak',
|
||||
SUN = 'sun',
|
||||
TICK = 'tick',
|
||||
TICKET = 'ticket',
|
||||
@@ -86,6 +90,8 @@ export enum VegaIconNames {
|
||||
VOTE = 'vote',
|
||||
WITHDRAW = 'withdraw',
|
||||
WARNING = 'warning',
|
||||
MAN = 'man',
|
||||
TEAM = 'team',
|
||||
}
|
||||
|
||||
export const VegaIconNameMap: Record<
|
||||
@@ -102,7 +108,7 @@ export const VegaIconNameMap: Record<
|
||||
'chevron-right': IconChevronRight,
|
||||
'chevron-up': IconChevronUp,
|
||||
'eye-off': IconEyeOff,
|
||||
'exclaimation-mark': IconExclaimationMark,
|
||||
'exclamation-mark': IconExclamationMark,
|
||||
'open-external': IconOpenExternal,
|
||||
'question-mark': IconQuestionMark,
|
||||
'trend-down': IconTrendDown,
|
||||
@@ -135,4 +141,7 @@ export const VegaIconNameMap: Record<
|
||||
vote: IconVote,
|
||||
withdraw: IconWithdraw,
|
||||
warning: IconWarning,
|
||||
man: IconMan,
|
||||
team: IconTeam,
|
||||
streak: IconStreak,
|
||||
};
|
||||
|
||||
@@ -57,12 +57,20 @@ interface RadioProps {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const TradingRadio = ({ id, value, label, disabled }: RadioProps) => {
|
||||
export const TradingRadio = ({
|
||||
id,
|
||||
value,
|
||||
label,
|
||||
disabled,
|
||||
className,
|
||||
}: RadioProps) => {
|
||||
const wrapperClasses = classNames(
|
||||
'flex items-center gap-1.5 text-xs',
|
||||
labelClasses
|
||||
labelClasses,
|
||||
className
|
||||
);
|
||||
const itemClasses = classNames(
|
||||
'flex justify-center items-center',
|
||||
|
||||
@@ -205,9 +205,13 @@ const MultipleReadyToWithdrawToastContent = ({
|
||||
<>
|
||||
<ToastHeading>{t('Withdrawals ready')}</ToastHeading>
|
||||
<p>
|
||||
{t('Complete these {{count}} withdrawals to release your funds', {
|
||||
count,
|
||||
})}
|
||||
{t(
|
||||
'completeWithdrawals',
|
||||
'Complete these {{count}} withdrawals to release your funds',
|
||||
{
|
||||
count,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
<Button
|
||||
|
||||
Reference in New Issue
Block a user