Compare commits

..
Author SHA1 Message Date
sam-keen 08b27a30a8 feat(3548): ensure the data node urls in the monorepo are valid 2023-04-26 11:48:55 +01:00
118 changed files with 542 additions and 2416 deletions
+17 -38
View File
@@ -105,44 +105,19 @@ jobs:
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
echo -n "Affected projects: $affected"
branch_slug="$(echo ${{ github.head_ref || github.ref_name }} | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g )"
projects_e2e=""
preview_governance="not deployed"
preview_trading="not deployed"
preview_explorer="not deployed"
if [[ -z "$projects_e2e" ]]; then
projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
else
if [[ $affected == *"governance"* ]]; then
projects_e2e+='"governance-e2e" '
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
fi
if [[ $affected == *"trading"* ]]; then
projects_e2e+='"trading-e2e" '
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
fi
if [[ $affected == *"explorer"* ]]; then
projects_e2e+='"explorer-e2e" '
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
fi
fi
if [[ $affected == *"governance"* ]]; then projects_e2e+='"governance-e2e" '; fi
if [[ $affected == *"trading"* ]]; then projects_e2e+='"trading-e2e" '; fi
if [[ $affected == *"explorer"* ]]; then projects_e2e+='"explorer-e2e" '; fi
if [[ -z "$projects_e2e" ]]; then projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '; fi
projects_e2e=${projects_e2e%?}
projects_e2e=[${projects_e2e// /,}]
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
echo PROJECTS=$(echo $projects_e2e | sed 's|-e2e||g') >> $GITHUB_ENV
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
outputs:
projects: ${{ env.PROJECTS }}
projects-e2e: ${{ env.PROJECTS_E2E }}
preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
preview_trading: ${{ env.PREVIEW_TRADING }}
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
cypress:
needs: lint-test-build
@@ -165,9 +140,7 @@ jobs:
dist-check:
runs-on: ubuntu-latest
needs:
- publish-dist
- lint-test-build
needs: publish-dist
if: ${{ github.event_name == 'pull_request' }}
name: '(CD) comment preview links'
steps:
@@ -178,16 +151,22 @@ jobs:
issue-number: ${{ github.event.pull_request.number }}
body-includes: Previews
- name: Create comment
uses: peter-evans/create-or-update-comment@v3
- name: Inject slug/short variables
if: ${{ steps.fc.outputs.comment-id == 0 }}
uses: rlespinasse/github-slug-action@v4
with:
prefix: CI_
- name: Create comment
if: ${{ steps.fc.outputs.comment-id == 0 }}
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
Previews:
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
Previews
- explorer https://explorer.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
- trading https://trading.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
- governance https://governance.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
cypress-check:
name: '(CI) cypress - check'
Vendored
+19 -1
View File
@@ -1,2 +1,20 @@
@Library('vega-shared-library') _
runApprobation ignoreFailure: false, frontendBranch: env.BRANCH_NAME, type: 'frontend'
def commitHash = 'UNKNOWN'
pipeline {
agent any
options {
skipDefaultCheckout true
parallelsAlwaysFailFast()
}
stages {
stage('approbation') {
steps {
sh 'printenv'
checkout scm
runApprobation ignoreFailure: false, frontendBranch: env.BRANCH_NAME, type: 'frontend'
}
}
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=http://localhost:26617
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_ENV=CUSTOM
NX_VEGA_CONFIG_URL=
@@ -18,4 +18,4 @@ NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1
CYPRESS_VEGA_WALLET_API_TOKEN=
CYPRESS_VEGA_URL=http://localhost:3008/graphql
CYPRESS_VEGA_URL=http://localhost:3028/query
+1 -1
View File
@@ -25,7 +25,7 @@ module.exports = defineConfig({
},
env: {
environment: 'CUSTOM',
networkQueryUrl: 'http://localhost:3008/graphql',
networkQueryUrl: 'http://localhost:3028/query',
ethUrl: 'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
commitHash: 'dev',
tsConfig: 'tsconfig.json',
+46 -18
View File
@@ -9,22 +9,21 @@ context('Home Page', function () {
it('should show connected environment stats', function () {
const statTitles = {
0: 'Status',
1: 'Epoch',
2: 'Block height',
3: 'Uptime',
4: 'Total nodes',
5: 'Total staked',
6: 'Backlog',
7: 'Trades / second',
8: 'Orders / block',
9: 'Orders / second',
10: 'Transactions / block',
11: 'Block time',
12: 'Time',
13: 'App',
14: 'Tendermint',
15: 'Up since',
16: 'Chain ID',
1: 'Block height',
2: 'Uptime',
3: 'Total nodes',
4: 'Total staked',
5: 'Backlog',
6: 'Trades / second',
7: 'Orders / block',
8: 'Orders / second',
9: 'Transactions / block',
10: 'Block time',
11: 'Time',
12: 'App',
13: 'Tendermint',
14: 'Up since',
15: 'Chain ID',
};
cy.get('[data-testid="stats-title"]')
@@ -32,13 +31,42 @@ context('Home Page', function () {
cy.wrap($list).should('contain.text', statTitles[index]);
})
.then(($list) => {
cy.wrap($list).should('have.length', 17);
cy.wrap($list).should('have.length', 16);
});
cy.get(statsValue).eq(0).should('contain.text', 'CONNECTED');
cy.get(statsValue).eq(1).should('not.be.empty');
cy.get(statsValue)
.eq(2)
.invoke('text')
.should('match', /\d+d \d+h \d+m \d+s/i);
cy.get(statsValue).eq(3).should('contain.text', '2');
cy.get(statsValue)
.eq(4)
.invoke('text')
.should('match', /\d+\.\d\d(?!\d)/i);
cy.get(statsValue).eq(5).should('contain.text', '0');
cy.get(statsValue).eq(6).should('contain.text', '0');
cy.get(statsValue).eq(7).should('contain.text', '0');
cy.get(statsValue).eq(8).should('contain.text', '0');
cy.get(statsValue).eq(9).should('not.be.empty');
cy.get(statsValue).eq(10).should('not.be.empty');
cy.get(statsValue).eq(11).should('not.be.empty');
cy.get(statsValue)
.eq(12)
.invoke('text')
.should('match', /v\d+\.\d+\.\d+/i);
cy.get(statsValue)
.eq(13)
.invoke('text')
.should('match', /\d+\.\d+\.\d+/i);
cy.get(statsValue).eq(14).should('not.be.empty');
cy.get(statsValue).eq(15).should('not.be.empty');
});
it('Block height should be updating', function () {
cy.get(statsValue)
.eq(2)
.eq(1)
.invoke('text')
.then((blockHeightTxt) => {
cy.get(statsValue)
@@ -6,7 +6,7 @@ const customNodeBtn = 'custom-node';
context.skip('Node switcher', { tags: '@regression' }, function () {
beforeEach('visit home page', function () {
cy.intercept('GET', 'https://static.vega.xyz/assets/capsule-network.json', {
hosts: ['http://localhost:3008/graphql'],
hosts: ['http://localhost:3028/query'],
}).as('nodeData');
cy.visit('/');
cy.wait('@nodeData');
@@ -219,7 +219,7 @@ context.skip('Parties page', { tags: '@regression' }, function () {
balance type asset {id symbol decimals}}}}}}}}';
cy.request({
method: 'POST',
url: `http://localhost:3008/graphql`,
url: `http://localhost:3028/query`,
body: {
query: mutation,
},
@@ -43,7 +43,7 @@ export const AssetLink = ({
if (asDialog) {
open(assetId, e.target as HTMLElement);
} else {
navigate(`/${Routes.ASSETS}/${asset?.id}`);
navigate(`${Routes.ASSETS}/${asset?.id}`);
}
}}
{...props}
@@ -9,7 +9,7 @@ import SizeInMarket from '../size-in-market/size-in-market';
export interface DeterministicOrderDetailsProps {
id: string;
// Version to fetch, with 0 being 'latest' and 1 being 'first'. Defaults to 0
version?: number | null;
version?: number;
}
export const wrapperClasses =
@@ -28,7 +28,7 @@ export const wrapperClasses =
*/
const DeterministicOrderDetails = ({
id,
version = null,
version = 0,
}: DeterministicOrderDetailsProps) => {
const { data, error } = useExplorerDeterministicOrderQuery({
variables: { orderId: id, version },
@@ -71,7 +71,7 @@ export const PartyAccounts = ({ accounts }: PartyAccountsProps) => {
/>
</td>
<td className="text-md">
<AssetLink assetId={account.asset.id} asDialog={true} />
<AssetLink assetId={account.asset.id} />
</td>
</TableRow>
);
+3 -2
View File
@@ -5,7 +5,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_FAIRGROUND=false
NX_VEGA_NETWORKS={}
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_ETHEREUM_CHAIN_ID=1440
NX_ETH_URL_CONNECT=1
NX_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
@@ -20,7 +20,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
#Test configuration variables
CYPRESS_FAIRGROUND=false
CYPRESS_VEGA_URL=http://localhost:3008/graphql
CYPRESS_VEGA_URL=http://localhost:3028/query
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
@@ -31,5 +31,6 @@ CYPRESS_VEGA_ENV=CUSTOM
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
CYPRESS_VEGA_URL=http://localhost:3028/query
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
CYPRESS_VEGA_WALLET_API_TOKEN=
@@ -50,8 +50,6 @@ const liquidityVoteStatus = 'liquidity-votes-status';
const tokenVoteStatus = 'token-votes-status';
const proposalTermsSection = 'proposal';
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
const fUSDCId =
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
const epochTimeout = Cypress.env('epochTimeout');
const proposalTimeout = { timeout: 14000 };
@@ -266,7 +264,7 @@ context(
it('Unable to submit update market proposal without minimum amount of tokens', function () {
vegaWalletTeardown();
vegaWalletFaucetAssetsWithoutCheck(
fUSDCId,
'fUSDC',
'1000000',
vegaWalletPublicKey
);
@@ -292,7 +290,7 @@ context(
// 3001-VOTE-092 3004-PMAC-001
it('Able to submit update market proposal and vote for proposal', function () {
vegaWalletFaucetAssetsWithoutCheck(
fUSDCId,
'fUSDC',
'1000000',
vegaWalletPublicKey
);
@@ -55,6 +55,7 @@ context(
function () {
// 2001-STKE-002, 2001-STKE-032
before('visit staking tab and connect vega wallet', function () {
cy.clearAllLocalStorage();
cy.visit('/');
ethereumWalletConnect();
// this is a workaround for #2422 which can be removed once issue is resolved
@@ -66,7 +67,6 @@ context(
beforeEach(
'teardown wallet & drill into a specific validator',
function () {
cy.clearAllLocalStorage();
cy.reload();
waitForSpinner();
cy.connectVegaWallet();
@@ -131,7 +131,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
.within(() => {
cy.get('span')
.first()
.should('have.text', 'http://localhost:3008/graphql');
.should('have.text', 'http://localhost:3028/query');
cy.getByTestId('link').should('exist');
});
});
@@ -17,15 +17,10 @@ const banner = 'view-banner';
context('View functionality with public key', { tags: '@smoke' }, function () {
before('send asset to wallet', function () {
vegaWalletFaucetAssetsWithoutCheck(
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc',
'1000000',
vegaWalletPubKey
);
vegaWalletFaucetAssetsWithoutCheck('fUSDC', '1000000', vegaWalletPubKey);
});
beforeEach('visit home page', function () {
cy.clearLocalStorage();
cy.visit('/');
waitForSpinner();
cy.connectPublicKey(vegaWalletPubKey);
@@ -13,7 +13,6 @@ context(
{ tags: '@regression' },
function () {
before('navigate to rewards page', function () {
cy.clearLocalStorage();
cy.visit('/');
navigateTo(navigation.rewards);
});
@@ -282,30 +282,26 @@ context(
describe('Vega wallet with assets', function () {
const assets = [
{
id: '816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc',
id: 'fUSDC',
name: 'USDC (fake)',
symbol: 'fUSDC',
amount: '1000000',
expectedAmount: '10.00',
},
{
id: '8566db7257222b5b7ef2886394ad28b938b28680a54a169bbc795027b89d6665',
id: 'fDAI',
name: 'DAI (fake)',
symbol: 'fDAI',
amount: '200000',
expectedAmount: '2.00',
},
{
id: '73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0',
id: 'fBTC',
name: 'BTC (fake)',
symbol: 'fBTC',
amount: '600000',
expectedAmount: '6.00',
},
{
id: 'e02d4c15d790d1d2dffaf2dcd1cf06a1fe656656cf4ed18c8ce99f9e83643567',
id: 'fEURO',
name: 'EURO (fake)',
symbol: 'fEURO',
amount: '800000',
expectedAmount: '8.00',
},
@@ -326,15 +322,15 @@ context(
});
});
for (const { name, symbol, expectedAmount } of assets) {
it(`should see ${name} within vega wallet`, () => {
for (const { id, name, expectedAmount } of assets) {
it(`should see ${id} within vega wallet`, () => {
cy.get(walletContainer).within(() => {
cy.get(vegaWalletCurrencyTitle)
.contains(name, txTimeout)
.contains(id, txTimeout)
.should('be.visible');
cy.get(vegaWalletCurrencyTitle)
.contains(name)
.contains(id)
.parent()
.siblings()
.invoke('text')
@@ -342,9 +338,9 @@ context(
.should('be.gte', parseFloat(expectedAmount));
cy.get(vegaWalletCurrencyTitle)
.contains(name)
.contains(id)
.parent()
.contains(symbol);
.contains(name);
});
});
}
@@ -54,7 +54,7 @@ export function stakingValidatorPageRemoveStake(stake: string) {
.and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`)
.and('be.visible')
.click();
cy.contains('been removed from validator', txTimeout).should('be.visible');
cy.contains('been removed from validator').should('be.visible');
closeDialog();
}
@@ -185,7 +185,7 @@ export function validateValidatorListTotalStakeAndShare(
) {
cy.contains('Loading...', epochTimeout).should('not.exist');
waitForBeginningOfEpoch();
cy.get(`[row-id="${positionOnList}"]`)
cy.get(`[row-id="${positionOnList}"]:visible`)
.eq(1)
.within(() => {
cy.getByTestId(stakeValidatorListTotalStake, epochTimeout).should(
@@ -221,12 +221,12 @@ export function ensureSpecifiedUnstakedTokensAreAssociated(
}
export function closeStakingDialog() {
cy.getByTestId('dialog-title').should(
cy.get('[data-testid="dialog-title"]:visible').should(
'contain.text',
'At the beginning of the next epoch'
);
cy.getByTestId('dialog-content')
.last()
cy.get('[data-testid="dialog-content"]:visible')
.first()
.within(() => {
cy.get('a').should('have.text', 'Back to Staking').click();
});
@@ -9,7 +9,7 @@ import {
import { ethers, Wallet } from 'ethers';
const associatedAmountInWallet = '[data-testid="associated-amount"]:visible';
const vegaWalletContainer = 'aside [data-testid="vega-wallet"]';
const vegaWalletContainer = 'aside [data-testid="vega-wallet"]:visible';
const vegaWalletMnemonic = Cypress.env('vegaWalletMnemonic');
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
@@ -105,24 +105,25 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
{ timeout: transactionTimeout, log: false }
).then((stakeBalance) => {
if (Number(stakeBalance) != 0) {
cy.get('[data-testid="vega-wallet-balance-unstaked"]:visible').within(
() => {
cy.get(associatedAmountInWallet)
.invoke('text')
.then(($walletAmount) => {
cy.wrap(
stakingBridgeContract.remove_stake(
String(stakeBalance),
vegaWalletPubKey
),
{ timeout: transactionTimeout, log: false }
);
cy.get(associatedAmountInWallet, {
cy.get(vegaWalletContainer).within(() => {
cy.getByTestId('currency-value')
.invoke('text')
.then(($associatedAmount) => {
cy.wrap(
stakingBridgeContract.remove_stake(
String(stakeBalance),
vegaWalletPubKey
),
{ timeout: transactionTimeout, log: false }
);
cy.get("[data-testid='currency-value']")
.first()
.invoke('text', {
timeout: transactionTimeout,
}).should('not.have.text', $walletAmount);
});
}
);
})
.should('not.eq', $associatedAmount);
});
});
}
});
}
+1 -1
View File
@@ -8,7 +8,7 @@ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_VEGA_CONFIG_URL=''
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_ETHEREUM_CHAIN_ID=1440
NX_ETH_URL_CONNECT=1
NX_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
@@ -14,7 +14,7 @@ export const AppLayout = ({ children }: AppLayoutProps) => {
const { isReadOnly } = useVegaWallet();
const AppLayoutClasses = classNames(
'app w-full max-w-[1500px] mx-auto grid',
'font-alpha lg:text-body-large',
'lg:text-body-large',
{
'grid-rows-[repeat(2,min-content)_1fr_min-content]': !isReadOnly,
'grid-rows-[repeat(3,min-content)_1fr_min-content]': isReadOnly,
@@ -14,17 +14,13 @@ import { ContractsContext } from './contracts-context';
import { createDefaultProvider } from '../../lib/web3-connectors';
import { useEthereumConfig } from '@vegaprotocol/web3';
import { useEnvironment } from '@vegaprotocol/environment';
import { ENV } from '../../config';
import { ENV } from '../../config/env';
/**
* Provides Vega Ethereum contract instances to its children.
*/
export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
const {
provider: activeProvider,
account,
chainId: activeChainId,
} = useWeb3React();
const { provider: activeProvider, account } = useWeb3React();
const { config } = useEthereumConfig();
const { VEGA_ENV, ETHEREUM_PROVIDER_URL } = useEnvironment();
const [contracts, setContracts] =
@@ -43,11 +39,7 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
ETHEREUM_PROVIDER_URL,
Number(config.chain_id)
);
const provider =
activeProvider && activeChainId === Number(config.chain_id)
? activeProvider
: defaultProvider;
const provider = activeProvider ? activeProvider : defaultProvider;
if (
account &&
@@ -92,14 +84,7 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
// TODO: hacky quick fix for release to prevent race condition, find a better fix for this.
cancelled = true;
};
}, [
activeProvider,
activeChainId,
account,
config,
VEGA_ENV,
ETHEREUM_PROVIDER_URL,
]);
}, [activeProvider, account, config, VEGA_ENV, ETHEREUM_PROVIDER_URL]);
if (!contracts) {
return (
@@ -1,3 +1,3 @@
# App configuration variables
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_ENV=LOCAL
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -8,7 +8,7 @@ NX_VEGA_ENV=CUSTOM
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_WALLET_URL=http://localhost:1789
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
@@ -27,6 +27,6 @@ CYPRESS_VEGA_ENV=CUSTOM
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
CYPRESS_VEGA_URL=http://localhost:3008/graphql
CYPRESS_VEGA_URL=http://localhost:3028/query
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
CYPRESS_VEGA_WALLET_API_TOKEN=
+2 -2
View File
@@ -7,7 +7,7 @@ NX_VEGA_ENV=CUSTOM
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_WALLET_URL=http://localhost:1789
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
@@ -24,6 +24,6 @@ CYPRESS_VEGA_ENV=CUSTOM
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
CYPRESS_VEGA_URL=http://localhost:3008/graphql
CYPRESS_VEGA_URL=http://localhost:3028/query
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
CYPRESS_VEGA_WALLET_API_TOKEN=
@@ -1,5 +1,4 @@
import { MarketTradingModeMapping } from '@vegaprotocol/types';
import { MarketState } from '@vegaprotocol/types';
const marketInfoBtn = 'Info';
const row = 'key-value-table-row';
@@ -13,12 +12,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
});
before(() => {
cy.mockTradingPage(
MarketState.STATE_ACTIVE,
undefined,
undefined,
'COMPROMISED'
);
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
@@ -26,11 +20,6 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
cy.wait('@MarketInfo');
});
it('show oracle banner', () => {
cy.getByTestId(marketTitle).contains('Oracle').click();
cy.getByTestId('oracle-status').should('contain.text', 'COMPROMISED');
});
it('current fees displayed', () => {
cy.getByTestId(marketTitle).contains('Current fees').click();
validateMarketDataRow(0, 'Maker Fee', '0.02%');
@@ -32,7 +32,7 @@ describe('Navbar', { tags: '@smoke' }, () => {
});
it('Resources dropdown should be correctly rendered', () => {
const resourceSelector = 'ul li:contains(Resources)';
const resourceSelector = 'ul li:last-child';
['Docs', 'Give Feedback'].forEach((text, index) => {
cy.get('nav').find(resourceSelector).contains('Resources').click();
cy.get('nav')
@@ -91,7 +91,7 @@ describe('Navbar', { tags: '@smoke' }, () => {
cy.getByTestId('button-menu-drawer').click();
cy.getByTestId('menu-drawer').should('be.visible');
cy.getByTestId('menu-drawer')
.find('[data-testid="Settings"]')
.find('[data-testid="theme-switcher"]')
.should('be.visible');
cy.getByTestId('button-menu-drawer').click();
cy.getByTestId('menu-drawer').should('not.be.visible');
@@ -1,45 +0,0 @@
import { closeWelcomeDialog } from '../support/helpers';
describe('Settings page', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.clearLocalStorage().then(() => {
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/');
closeWelcomeDialog();
cy.get('[aria-label="cog icon"]').click();
});
});
it('telemetry checkbox should work well', () => {
cy.location('hash').should('equal', '#/settings');
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
cy.get('[for="telemetry-approval"]').click();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'checked'
);
cy.reload();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'checked'
);
cy.get('[for="telemetry-approval"]').click();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
cy.reload();
cy.getByTestId('telemetry-approval').should(
'have.attr',
'data-state',
'unchecked'
);
});
});
@@ -1,25 +1,17 @@
import { checkSorting } from '@vegaprotocol/cypress';
const dialogClose = 'dialog-close';
describe('accounts', { tags: '@smoke' }, () => {
beforeEach(() => {
before(() => {
cy.clearAllLocalStorage();
cy.mockTradingPage();
cy.mockWeb3Provider();
cy.mockSubscription();
cy.setVegaWallet();
cy.visit('/#/markets/market-0');
cy.wait('@Assets');
});
it('renders accounts', () => {
// 7001-COLL-001
// 7001-COLL-002
// 7001-COLL-003
// 7001-COLL-004
// 7001-COLL-005
// 7001-COLL-006
// 7001-COLL-007
const tradingAccountRowId = '[row-id="t-0"]';
cy.getByTestId('Collateral').click();
@@ -30,115 +22,31 @@ describe('accounts', { tags: '@smoke' }, () => {
.find('[col-id="asset.symbol"]')
.should('have.text', 'AST0');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="used"]')
.should('have.text', '1.010.00%');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="available"]')
.should('have.text', '100,000.00');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="total"]')
.should('have.text', '100,001.01');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="accounts-actions"]')
.should('have.text', ' ');
.should('have.text', 'DepositWithdraw');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[data-testid="deposit"]')
.should('have.text', 'Deposit');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="accounts-actions"] [data-testid="withdraw"]')
.should('have.text', 'Withdraw');
cy.getByTestId('tab-accounts')
.get(tradingAccountRowId)
.find('[col-id="total"]')
.should('have.text', '100,001.01');
cy.getByTestId('tab-accounts')
.get('[col-id="accounts-actions"]')
.find('[data-testid="dropdown-menu"]')
.eq(1)
.click();
cy.getByTestId('deposit').should('be.visible');
cy.getByTestId('withdraw').should('be.visible');
cy.getByTestId('breakdown').should('be.visible');
cy.getByTestId('Collateral').click({ force: true });
});
it('should open asset details dialog when clicked on symbol', () => {
// 7001-COLL-008
// 6501-ASSE-001
// 6501-ASSE-002
// 6501-ASSE-003
// 6501-ASSE-004
// 6501-ASSE-005
// 6501-ASSE-006
// 6501-ASSE-007
// 6501-ASSE-008
// 6501-ASSE-009
// 6501-ASSE-010
// 6501-ASSE-011
// 6501-ASSE-012
// 6501-ASSE-013
const titles = [
'ID',
'Type',
'Name',
'Symbol',
'Decimals',
'Quantum',
'Status',
'Contract address',
'Withdrawal threshold',
'Lifetime limit',
'Infrastructure fee account balance',
'Global reward pool account balance',
'Maker paid fees account balance',
'Maker received fees account balance',
'Liquidity provision fee reward account balance',
'Market proposer reward account balance',
];
cy.getByTestId('asset').contains('tEURO').click();
cy.get('[data-testid$="_label"]').should('have.length', 16);
cy.get('[data-testid$="_label"]').each((element, index) => {
cy.wrap(element).should('have.text', titles[index]);
});
cy.getByTestId(dialogClose).click();
cy.getByTestId(dialogClose).should('not.exist');
});
it('should open usage breakdown dialog when clicked on used', () => {
// 7001-COLL-009
cy.getByTestId('breakdown').contains('1.01').click();
const headers = ['Market', 'Account type', 'Balance'];
cy.getByTestId('usage-breakdown').within(($headers) => {
cy.wrap($headers)
.get('.ag-header-cell-text')
.each(($header, i) => {
cy.wrap($header).should('have.text', headers[i]);
});
});
cy.getByTestId(dialogClose).click();
});
it('sorting usage breakdown columns should work well', () => {
// 7001-COLL-010
cy.getByTestId('breakdown').contains('1.01').click();
cy.getByTestId('usage-breakdown')
.find('[col-id="type"]')
.eq(1)
.should('have.text', 'Margin');
cy.getByTestId('usage-breakdown')
.find('[col-id="type"]')
.eq(2)
.should('have.text', 'Margin');
cy.getByTestId('usage-breakdown')
.find('[col-id="type"]')
.eq(3)
.should('have.text', 'General');
cy.getByTestId(dialogClose).click();
cy.get('[data-testid="dialog-content"]:visible').should('exist');
cy.get('[data-testid="dialog-close"]:visible').click();
});
describe('sorting by ag-grid columns should work well', () => {
@@ -88,18 +88,5 @@ describe('deal ticker order validation', { tags: '@smoke' }, () => {
'Size cannot be lower than 1'
);
});
it('must have total margin available', () => {
// 7001-COLL-011
cy.getByTestId('tab-ticket')
.find('.text-xs')
.eq(5)
.within(() => {
cy.get('[data-state="closed"]').should(
'have.text',
'Total margin available'
);
cy.get('.text-neutral-500').should('have.text', '~100,000.01 tDAI');
});
});
});
});
@@ -455,7 +455,7 @@ describe('amend and cancel order', { tags: '@smoke' }, () => {
});
});
it('must be warned (pre-submit) if the input price has too many digits after the decimal place for the market', () => {
// 7003-MORD-013
// 7003-MORD-016
updateOrder({
id: orderId,
status: Schema.OrderStatus.STATUS_ACTIVE,
-5
View File
@@ -9,8 +9,3 @@ export const selectAsset = (assetIndex: number) => {
// eslint-disable-next-line
cy.wait(100);
};
export const closeWelcomeDialog = () => {
cy.getByTestId('select-market-list').should('exist');
cy.getByTestId('dialog-close').click();
};
+29 -35
View File
@@ -1,7 +1,6 @@
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import * as Schema from '@vegaprotocol/types';
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
import type { Provider, Status } from '@vegaprotocol/oracles';
import {
accountsQuery,
assetQuery,
@@ -156,6 +155,7 @@ const mockTradingPage = (
aliasGQLQuery(req, 'ProposalsList', proposalListQuery());
aliasGQLQuery(req, 'Deposits', depositsQuery());
};
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
@@ -164,56 +164,50 @@ declare global {
mockTradingPage(
state?: Schema.MarketState,
tradingMode?: Schema.MarketTradingMode,
trigger?: Schema.AuctionTrigger,
oracleStatus?: Status
trigger?: Schema.AuctionTrigger
): void;
}
}
}
export const addMockTradingPage = () => {
Cypress.Commands.add(
'mockTradingPage',
(
state = Schema.MarketState.STATE_ACTIVE,
tradingMode,
trigger,
oracleStatus
) => {
(state = Schema.MarketState.STATE_ACTIVE, tradingMode, trigger) => {
cy.mockGQL((req) => {
mockTradingPage(req, state, tradingMode, trigger);
});
const oracle: Provider = {
name: 'Another oracle',
url: 'https://zombo.com',
description_markdown:
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
oracle: {
status: oracleStatus || 'GOOD',
status_reason: '',
first_verified: '2022-01-01T00:00:00.000Z',
last_verified: '2022-12-31T00:00:00.000Z',
type: 'public_key',
public_key: ORACLE_PUBKEY,
},
proofs: [
{
format: 'signed_message',
available: true,
type: 'public_key',
public_key: ORACLE_PUBKEY,
message: 'SOMEHEX',
},
],
github_link: `https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/public_key-${ORACLE_PUBKEY}.toml`,
};
// Prevent request to github, return some dummy content
cy.intercept(
'GET',
/^https:\/\/raw.githubusercontent.com\/vegaprotocol\/well-known/,
{
body: [oracle],
body: [
{
name: 'Another oracle',
url: 'https://zombo.com',
description_markdown:
'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
oracle: {
status: 'GOOD',
status_reason: '',
first_verified: '2022-01-01T00:00:00.000Z',
last_verified: '2022-12-31T00:00:00.000Z',
type: 'public_key',
public_key: ORACLE_PUBKEY,
},
proofs: [
{
format: 'signed_message',
available: true,
type: 'public_key',
public_key: ORACLE_PUBKEY,
message: 'SOMEHEX',
},
],
github_link: `https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/public_key-${ORACLE_PUBKEY}.toml`,
},
],
}
);
}
+1 -1
View File
@@ -7,7 +7,7 @@ NX_VEGA_ENV=CUSTOM
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_URL=http://localhost:3008/graphql
NX_VEGA_URL=http://localhost:3028/query
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
+1 -1
View File
@@ -11,4 +11,4 @@ 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_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
@@ -350,10 +350,7 @@ export const TradePanels = ({
return (
<div className="h-full grid grid-rows-[min-content_1fr_min-content]">
<div>
<TradeMarketHeader market={market} onSelect={onSelect} />
<OracleBanner marketId={market?.id || ''} />
</div>
<TradeMarketHeader market={market} onSelect={onSelect} />
<div className="h-full">
<AutoSizer>
{({ width, height }) => (
@@ -1,2 +0,0 @@
export { Settings as default } from './settings';
export { SettingsButton } from './settings-button';
@@ -1,16 +0,0 @@
import { Icon, NavigationLink } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { Links, Routes } from '../../pages/client-router';
import { COG } from '@blueprintjs/icons/src/generated/iconNames';
export const SettingsButton = ({ withMobile }: { withMobile?: boolean }) => {
return (
<NavigationLink data-testid="Settings" to={Links[Routes.SETTINGS]()}>
{withMobile ? (
t('Settings')
) : (
<Icon name={COG} className="!align-middle" />
)}
</NavigationLink>
);
};
@@ -1,45 +0,0 @@
import { t } from '@vegaprotocol/i18n';
import { TelemetryApproval } from '../../components/welcome-dialog/telemetry-approval';
import {
Divider,
RoundedWrapper,
Switch,
ThemeSwitcher,
} from '@vegaprotocol/ui-toolkit';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
export const Settings = () => {
const { theme, setTheme } = useThemeSwitcher();
const text = t(theme === 'dark' ? 'Light mode' : 'Dark mode');
return (
<div className="py-16 px-8 flex w-full justify-center">
<div className="lg:min-w-[700px] min-w-[300px]">
<h1 className="text-4xl xl:text-5xl uppercase font-alpha calt">
{t('Settings')}
</h1>
<div className="mt-8 text-base text-neutral-500 dark:text-neutral-400">
{t('Changes are applied automatically.')}
</div>
<div className="mt-10 w-full">
<RoundedWrapper paddingBottom>
<div className="flex justify-between py-3">
<div className="flex shrink">
<ThemeSwitcher />
<label htmlFor="theme-switcher" className="self-center text-lg">
{text}
</label>
</div>
<Switch
name="settings-theme-switch"
onCheckedChange={() => setTheme()}
checked={theme === 'dark'}
/>
</div>
<Divider />
<TelemetryApproval isSettingsPage />
</RoundedWrapper>
</div>
</div>
</div>
);
};
@@ -26,8 +26,7 @@ export const OracleBanner = ({ marketId }: { marketId: string }) => {
return (
<NotificationBanner intent={Intent.Danger}>
<div>
Oracle status for this market is{' '}
<span data-testId="oracle-status">{oracle.status}</span>.{' '}
Oracle status for this market is {oracle.status}.{' '}
{oracleStatuses[oracle.status]}
</div>
{oracle.status_reason ? (
+5 -5
View File
@@ -10,6 +10,7 @@ import { t } from '@vegaprotocol/i18n';
import { useGlobalStore } from '../../stores';
import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
import {
ThemeSwitcher,
Navigation,
NavigationList,
NavigationItem,
@@ -23,7 +24,6 @@ import {
import { Links, Routes } from '../../pages/client-router';
import { createDocsLinks } from '@vegaprotocol/utils';
import { SettingsButton } from '../../client-pages/settings';
export const Navbar = ({
theme = 'system',
@@ -45,7 +45,7 @@ export const Navbar = ({
theme={theme}
actions={
<>
<SettingsButton />
<ThemeSwitcher />
<VegaWalletConnectButton />
</>
}
@@ -108,15 +108,15 @@ export const Navbar = ({
)}
</NavigationList>
<NavigationList
className="[.drawer-content_&]:border-t [.drawer-content_&]:border-t-vega-light-200 dark:[.drawer-content_&]:border-t-vega-dark-200 [.drawer-content_&]:pt-4 [.drawer-content_&]:mt-4"
className="[.drawer-content_&]:border-t [.drawer-content_&]:border-t-vega-light-200 dark:[.drawer-content_&]:border-t-vega-dark-200 [.drawer-content_&]:pt-8 [.drawer-content_&]:mt-4"
hide={[
NavigationBreakpoint.Small,
NavigationBreakpoint.Narrow,
NavigationBreakpoint.Full,
]}
>
<NavigationItem className="[.drawer-content_&]:w-full">
<SettingsButton withMobile />
<NavigationItem className="[.drawer-content_&]:w-full text-black dark:text-white">
<ThemeSwitcher withMobile />
</NavigationItem>
</NavigationList>
</Navigation>
@@ -21,12 +21,12 @@ describe('Risk notice dialog', () => {
});
it.each`
assertion | network
${'displays'} | ${Networks.MAINNET}
${'displays'} | ${Networks.CUSTOM}
${'displays'} | ${Networks.DEVNET}
${'displays'} | ${Networks.STAGNET3}
${'displays'} | ${Networks.TESTNET}
assertion | network
${'displays'} | ${Networks.MAINNET}
${'does not display'} | ${Networks.CUSTOM}
${'does not display'} | ${Networks.DEVNET}
${'does not display'} | ${Networks.STAGNET3}
${'does not display'} | ${Networks.TESTNET}
`(
'$assertion the risk notice on $network',
async ({ assertion, network }) => {
@@ -43,7 +43,13 @@ describe('Risk notice dialog', () => {
{ wrapper: BrowserRouter }
);
expect(screen.queryByText(introText)).toBeInTheDocument();
if (assertion === 'displays') {
// eslint-disable-next-line jest/no-conditional-expect
expect(screen.queryByText(introText)).toBeInTheDocument();
} else {
// eslint-disable-next-line jest/no-conditional-expect
expect(screen.queryByText(introText)).not.toBeInTheDocument();
}
}
);
@@ -3,7 +3,6 @@ import { t } from '@vegaprotocol/i18n';
import { Button } from '@vegaprotocol/ui-toolkit';
import { LocalStorage } from '@vegaprotocol/utils';
import { RISK_ACCEPTED_KEY } from '../constants';
import { TelemetryApproval } from './telemetry-approval';
interface Props {
onClose: () => void;
@@ -33,9 +32,6 @@ export const RiskNoticeDialog = ({ onClose }: Props) => {
)}
</p>
<Button onClick={handleAcceptRisk}>{t('I understand, Continue')}</Button>
<div className="text-base mt-8">
<TelemetryApproval />
</div>
</>
);
};
@@ -1,19 +0,0 @@
import { render, screen, act } from '@testing-library/react';
import { TelemetryApproval } from './telemetry-approval';
describe('TelemetryApproval', () => {
it('click on checkbox should be properly handled', () => {
render(<TelemetryApproval />);
expect(screen.getByRole('checkbox')).toHaveAttribute(
'data-state',
'unchecked'
);
act(() => {
screen.getByRole('checkbox').click();
});
expect(screen.getByRole('checkbox')).toHaveAttribute(
'data-state',
'checked'
);
});
});
@@ -1,32 +0,0 @@
import { Checkbox } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
export const TelemetryApproval = ({
isSettingsPage,
}: {
isSettingsPage?: boolean;
}) => {
const [isApproved, setIsApproved] = useTelemetryApproval();
return (
<div className="flex flex-col px-2 py-3">
<div className="mr-4" role="form">
<Checkbox
label={<span className="text-lg pl-1">{t('Share usage data')}</span>}
checked={isApproved}
name="telemetry-approval"
onCheckedChange={() => setIsApproved(!isApproved)}
/>
</div>
<div className="text-sm text-vega-light-300 dark:text-vega-dark-300 ml-6">
<span>
{t(
'Help identify bugs and improve the service by sharing anonymous usage data.'
)}
{!isSettingsPage &&
' ' + t('You can change this in your settings at any time.')}
</span>
</div>
</div>
);
};
@@ -4,6 +4,7 @@ import { Dialog } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useDataProvider, useLocalStorage } from '@vegaprotocol/react-helpers';
import { activeMarketsProvider } from '@vegaprotocol/market-list';
import { useEnvironment, Networks } from '@vegaprotocol/environment';
import * as constants from '../constants';
import { RiskNoticeDialog } from './risk-notice-dialog';
import { WelcomeNoticeDialog } from './welcome-notice-dialog';
@@ -12,38 +13,37 @@ import { useGlobalStore } from '../../stores';
export const WelcomeDialog = () => {
const { pathname } = useLocation();
let dialogContent: React.ReactNode;
const { VEGA_ENV } = useEnvironment();
let dialogContent: React.ReactNode = null;
let title = '';
let size: 'small' | 'medium' = 'small';
let onClose: ((open: boolean) => void) | undefined = undefined;
const [riskAccepted] = useLocalStorage(constants.RISK_ACCEPTED_KEY);
const { data } = useDataProvider({
dataProvider: activeMarketsProvider,
variables: undefined,
});
const update = useGlobalStore((store) => store.update);
const shouldDisplayWelcomeDialog = useGlobalStore(
(store) => store.shouldDisplayWelcomeDialog
);
const isRiskDialogNeeded = riskAccepted !== 'true' && !('Cypress' in window);
const { update, shouldDisplayWelcomeDialog } = useGlobalStore((store) => ({
update: store.update,
shouldDisplayWelcomeDialog: store.shouldDisplayWelcomeDialog,
}));
const isRiskDialogNeeded =
riskAccepted !== 'true' && VEGA_ENV === Networks.MAINNET;
const isWelcomeDialogNeeded = pathname === '/' || shouldDisplayWelcomeDialog;
const onCloseDialog = useCallback(() => {
const onClose = useCallback(() => {
update({ shouldDisplayWelcomeDialog: isRiskDialogNeeded });
// eslint-disable-next-line react-hooks/exhaustive-deps
dialogContent = null;
}, [update, isRiskDialogNeeded]);
if (isRiskDialogNeeded) {
dialogContent = <RiskNoticeDialog onClose={onCloseDialog} />;
dialogContent = <RiskNoticeDialog onClose={onClose} />;
title = t('WARNING');
size = 'medium';
} else if (isWelcomeDialogNeeded && data?.length === 0) {
dialogContent = <WelcomeNoticeDialog />;
onClose = onCloseDialog;
} else if (isWelcomeDialogNeeded && (data?.length || 0) > 0) {
dialogContent = <WelcomeLandingDialog onClose={onCloseDialog} />;
onClose = onCloseDialog;
} else {
dialogContent = null as React.ReactNode;
dialogContent = <WelcomeLandingDialog onClose={onClose} />;
}
return (
@@ -1,48 +0,0 @@
import { renderHook, act, waitFor } from '@testing-library/react';
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { SentryInit, SentryClose } from '@vegaprotocol/utils';
import { STORAGE_KEY, useTelemetryApproval } from './use-telemetry-approval';
const mockSetValue = jest.fn();
const mockRemoveValue = jest.fn();
jest.mock('@vegaprotocol/utils');
jest.mock('@vegaprotocol/react-helpers', () => ({
...jest.requireActual('@vegaprotocol/react-helpers'),
useLocalStorage: jest
.fn()
.mockImplementation(() => [false, mockSetValue, mockRemoveValue]),
}));
describe('useTelemetryApproval', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('hook should return proper array', () => {
const res = renderHook(() => useTelemetryApproval());
expect(res.result.current[0]).toEqual(false);
expect(res.result.current[1]).toEqual(expect.any(Function));
expect(useLocalStorage).toHaveBeenCalledWith(STORAGE_KEY);
});
it('hook should init stuff properly', async () => {
const res = renderHook(() => useTelemetryApproval());
await act(() => {
res.result.current[1](true);
});
await waitFor(() => {
expect(SentryInit).toHaveBeenCalled();
expect(mockSetValue).toHaveBeenCalledWith('1');
});
});
it('hook should close stuff properly', async () => {
const res = renderHook(() => useTelemetryApproval());
await act(() => {
res.result.current[1](false);
});
await waitFor(() => {
expect(SentryClose).toHaveBeenCalled();
expect(mockRemoveValue).toHaveBeenCalledWith();
});
});
});
@@ -1,24 +0,0 @@
import { useLocalStorage } from '@vegaprotocol/react-helpers';
import { useCallback } from 'react';
import { SentryInit, SentryClose } from '@vegaprotocol/utils';
import { ENV } from '../config';
export const STORAGE_KEY = 'vega_telemetry_approval';
export const useTelemetryApproval = (): [
value: boolean,
setValue: (value: boolean) => void
] => {
const [value, setValue, removeValue] = useLocalStorage(STORAGE_KEY);
const setApprove = useCallback(
(value: boolean) => {
if (value) {
SentryInit(ENV.dsn, ENV.envName);
return setValue('1');
}
SentryClose();
removeValue();
},
[setValue, removeValue]
);
return [Boolean(value), setApprove];
};
+1 -5
View File
@@ -36,7 +36,6 @@ import { Navbar } from '../components/navbar';
import { ENV } from '../lib/config';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { activeOrdersProvider } from '@vegaprotocol/orders';
import { useTelemetryApproval } from '../lib/hooks/use-telemetry-approval';
const DEFAULT_TITLE = t('Welcome to Vega trading!');
@@ -146,10 +145,7 @@ const PartyData = () => {
const MaybeConnectEagerly = () => {
useVegaEagerConnect(Connectors);
const [isTelemetryApproved] = useTelemetryApproval();
useEthereumEagerConnect(
isTelemetryApproved ? { dsn: ENV.dsn, env: ENV.envName } : {}
);
useEthereumEagerConnect(ENV.dsn);
const { pubKey, connect } = useVegaWallet();
const [searchParams] = useSearchParams();
+1 -11
View File
@@ -26,17 +26,12 @@ const LazyPortfolio = dynamic(() => import('../client-pages/portfolio'), {
ssr: false,
});
const LazySettings = dynamic(() => import('../client-pages/settings'), {
ssr: false,
});
export enum Routes {
HOME = '/',
MARKET = '/markets',
MARKETS = '/markets/all',
PORTFOLIO = '/portfolio',
LIQUIDITY = 'liquidity/:marketId',
SETTINGS = 'settings',
LIQUIDITY = '/liquidity',
}
type ConsoleLinks = { [r in Routes]: (...args: string[]) => string };
@@ -50,7 +45,6 @@ export const Links: ConsoleLinks = {
marketId
? trimEnd(`${Routes.LIQUIDITY}/${marketId}`, '/')
: Routes.LIQUIDITY,
[Routes.SETTINGS]: () => Routes.SETTINGS,
};
const routerConfig: RouteObject[] = [
@@ -93,10 +87,6 @@ const routerConfig: RouteObject[] = [
path: Routes.PORTFOLIO,
element: <LazyPortfolio />,
},
{
path: Routes.SETTINGS,
element: <LazySettings />,
},
{
path: '*',
element: (
+11 -6
View File
@@ -1,9 +1,14 @@
import * as Sentry from '@sentry/nextjs';
import { BrowserTracing } from '@sentry/tracing';
import { ENV } from './lib/config/env';
import { LocalStorage, SentryInit } from '@vegaprotocol/utils';
import { STORAGE_KEY } from './lib/hooks/use-telemetry-approval';
const { dsn, envName } = ENV;
const isTelemetryApproved = !!LocalStorage.getItem(STORAGE_KEY);
if (dsn && isTelemetryApproved) {
SentryInit(dsn, envName);
const { dsn } = ENV;
if (dsn) {
Sentry.init({
dsn,
integrations: [new BrowserTracing()],
tracesSampleRate: 1,
environment: ENV.envName,
});
}
@@ -61,7 +61,14 @@ describe('AccountsTable', () => {
);
});
const cells = await screen.findAllByRole('gridcell');
const expectedValues = ['tBTC', '1,256.00', '1,256.00', '2,512.00', ''];
const expectedValues = [
'tBTC',
'1,256.00',
'1,256.00',
'2,512.00',
'Deposit',
'Withdraw',
];
cells.forEach((cell, i) => {
expect(cell).toHaveTextContent(expectedValues[i]);
});
+28 -77
View File
@@ -9,17 +9,7 @@ import type {
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import {
Button,
ButtonLink,
Dialog,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { Button, ButtonLink, Dialog } from '@vegaprotocol/ui-toolkit';
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
import {
AgGridDynamic as AgGrid,
@@ -132,7 +122,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
params.data.asset.id === pinnedAssetId &&
new BigNumber(params.data.total).isLessThanOrEqualTo(0)
? 32
: 24,
: 22,
[pinnedAssetId]
);
@@ -266,7 +256,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
colId="accounts-actions"
headerName=""
sortable={false}
maxWidth={200}
minWidth={200}
type="rightAligned"
cellRenderer={({
data,
@@ -293,66 +283,30 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
);
}
return (
!props.isReadOnly && (
<DropdownMenu
trigger={
<DropdownMenuTrigger
iconName="more"
className="hover:bg-vega-light-200 dark:hover:bg-vega-dark-200 p-0.5 focus:rounded-full hover:rounded-full"
data-testid="dropdown-menu"
></DropdownMenuTrigger>
}
>
<DropdownMenuContent>
<DropdownMenuItem
key={'deposit'}
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
<span>
<VegaIcon
name={VegaIconNames.DEPOSIT}
size={16}
/>
{t('Deposit')}
</span>
</DropdownMenuItem>
<DropdownMenuItem
key={'withdraw'}
data-testid="withdraw"
onClick={() =>
onClickWithdraw && onClickWithdraw(data.asset.id)
}
>
<span>
<VegaIcon
name={VegaIconNames.WITHDRAW}
size={16}
/>
{t('Withdraw')}
</span>
</DropdownMenuItem>
<DropdownMenuItem
key={'breakdown'}
data-testid="breakdown"
onClick={() => {
setOpenBreakdown(!openBreakdown);
setRow(data);
}}
>
<span>
<VegaIcon
name={VegaIconNames.BREAKDOWN}
size={16}
/>
{t('Breakdown')}
</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
<>
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="deposit"
onClick={() => {
onClickDeposit && onClickDeposit(data.asset.id);
}}
>
{t('Deposit')}
</ButtonLink>
)}
<span className="mx-1" />
{!props.isReadOnly && (
<ButtonLink
data-testid="withdraw"
onClick={() =>
onClickWithdraw && onClickWithdraw(data.asset.id)
}
>
{t('Withdraw')}
</ButtonLink>
)}
</>
);
}
}}
@@ -360,10 +314,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
}
</AgGrid>
<Dialog size="medium" open={openBreakdown} onChange={setOpenBreakdown}>
<div
className="h-[35vh] w-full m-auto flex flex-col"
data-testid="usage-breakdown"
>
<div className="h-[35vh] w-full m-auto flex flex-col">
<h1 className="text-xl mb-4">
{row?.asset?.symbol} {t('usage breakdown')}
</h1>
+1 -4
View File
@@ -1,4 +1 @@
export const ASSET_ID_FOR_MARKET =
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
export const ASSET_SYMBOL = 'fUSDC';
export const ASSET_ID_FOR_MARKET = 'fUSDC';
@@ -4,7 +4,7 @@ import { createLog } from './logging';
import type { ProposalSubmissionBody } from '@vegaprotocol/wallet';
import { getProposal } from './get-proposal';
import { sendVegaTx } from './wallet-client';
import { ASSET_ID_FOR_MARKET, ASSET_SYMBOL } from './contants';
import { ASSET_ID_FOR_MARKET } from './contants';
const log = createLog('propose-market');
@@ -43,7 +43,7 @@ function createNewMarketProposal(): ProposalSubmissionBody {
code: 'TEST.24h',
future: {
settlementAsset: ASSET_ID_FOR_MARKET,
quoteName: ASSET_SYMBOL,
quoteName: ASSET_ID_FOR_MARKET,
dataSourceSpecForSettlementData: {
external: {
oracle: {
+1 -1
View File
@@ -66,7 +66,7 @@ export function addGetAssets() {
cy.request({
method: 'POST',
url: 'http://localhost:3008/graphql',
url: 'http://localhost:3028/query',
body: {
query: print(query),
},
@@ -24,7 +24,7 @@ export function addGetNetworkParameters() {
}`;
cy.request({
method: 'POST',
url: `http://localhost:3008/graphql`,
url: `http://localhost:3028/query`,
body: {
query: mutation,
},
+1 -1
View File
@@ -43,7 +43,7 @@ export function addGetNodes() {
cy.request({
method: 'POST',
url: `http://localhost:3008/graphql`,
url: `http://localhost:3028/query`,
body: {
query: print(query),
},
@@ -70,7 +70,7 @@ const NetworkLabel = ({
isCurrent = false,
isAvailable = false,
}: NetworkLabelProps) => (
<span className="text-vega-dark-300 dark:text-vega-light-300">
<span className="text-neutral-800">
{getLabelText({ isCurrent, isAvailable })}
</span>
);
@@ -111,12 +111,9 @@ export const NetworkSwitcher = ({
trigger={
<DropdownMenuTrigger
ref={menuRef}
className={classNames(
'flex justify-between items-center text-sm text-vega-dark-600 dark:text-vega-light-600 py-1 px-2 rounded border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500 hover:bg-vega-light-500',
className
)}
className={classNames('flex justify-between items-center', className)}
>
<span className="mr-2"> {envTriggerMapping[current]}</span>
{envTriggerMapping[current]}
</DropdownMenuTrigger>
}
>
+2 -36
View File
@@ -120,40 +120,6 @@ describe('FillsTable', () => {
expect(amountCell).toHaveClass('text-vega-pink');
});
it('should format cells correctly for side unspecified', async () => {
const partyId = 'party-id';
const buyerFill = generateFill({
...defaultFill,
seller: {
id: partyId,
},
aggressor: Schema.Side.SIDE_UNSPECIFIED,
sellerFee: {
makerFee: '1',
infrastructureFee: '1',
liquidityFee: '1',
},
});
render(<FillsTable partyId={partyId} rowData={[buyerFill]} />);
const cells = screen.getAllByRole('gridcell');
const expectedValues = [
buyerFill.market?.tradableInstrument.instrument.name || '',
'-3.00',
'1.00 BTC',
'3.00 BTC',
'-',
'0.03 BTC',
getDateTimeFormat().format(new Date(buyerFill.createdAt)),
];
cells.forEach((cell, i) => {
expect(cell).toHaveTextContent(expectedValues[i]);
});
const amountCell = cells.find((c) => c.getAttribute('col-id') === 'size');
expect(amountCell).toHaveClass('text-vega-pink');
});
it('should render correct maker or taker role', async () => {
const partyId = 'party-id';
const takerFill = generateFill({
@@ -224,7 +190,7 @@ describe('FillsTable', () => {
makerFee: '1000',
totalFee: '6000',
};
expect(getFeesBreakdown('Taker', fees)).toEqual(expectedBreakdown);
expect(getFeesBreakdown('TAKER', fees)).toEqual(expectedBreakdown);
});
it('should return correct fees breakdown for a maker', () => {
@@ -239,7 +205,7 @@ describe('FillsTable', () => {
makerFee: '-1000',
totalFee: '4000',
};
expect(getFeesBreakdown('Maker', fees)).toEqual(expectedBreakdown);
expect(getFeesBreakdown('MAKER', fees)).toEqual(expectedBreakdown);
});
});
});
+39 -48
View File
@@ -26,10 +26,8 @@ import BigNumber from 'bignumber.js';
import type { Trade } from './fills-data-provider';
import type { FillFieldsFragment } from './__generated__/Fills';
const TAKER = 'Taker';
const MAKER = 'Maker';
export type Role = typeof TAKER | typeof MAKER | '-';
const TAKER = 'TAKER';
const MAKER = 'MAKER';
export type Props = (AgGridReactProps | AgReactUiProps) & {
partyId: string;
@@ -182,10 +180,24 @@ const formatTotal = ({
};
const formatRole = (partyId: string) => {
return ({ data }: VegaValueFormatterParams<Trade, 'aggressor'>) => {
if (!data) return '-';
const { role } = getRoleAndFees({ data, partyId });
return role;
return ({ value, data }: VegaValueFormatterParams<Trade, 'aggressor'>) => {
const taker = t('Taker');
const maker = t('Maker');
if (data?.buyer.id === partyId) {
if (value === Schema.Side.SIDE_BUY) {
return taker;
} else {
return maker;
}
} else if (data?.seller.id === partyId) {
if (value === Schema.Side.SIDE_SELL) {
return taker;
} else {
return maker;
}
} else {
return '-';
}
};
};
@@ -210,15 +222,6 @@ const formatFee = (partyId: string) => {
};
};
export const isEmptyFeeObj = (feeObj: Schema.TradeFee) => {
if (!feeObj) return true;
return (
feeObj.liquidityFee === '0' &&
feeObj.makerFee === '0' &&
feeObj.infrastructureFee === '0'
);
};
export const getRoleAndFees = ({
data,
partyId,
@@ -229,30 +232,14 @@ export const getRoleAndFees = ({
>;
partyId?: string;
}) => {
let role: Role;
let role;
let feesObj;
if (data?.buyer.id === partyId) {
if (data.aggressor === Schema.Side.SIDE_BUY) {
role = TAKER;
feesObj = data?.buyerFee;
} else if (data.aggressor === Schema.Side.SIDE_SELL) {
role = MAKER;
feesObj = data?.sellerFee;
} else {
role = '-';
feesObj = !isEmptyFeeObj(data?.buyerFee) ? data.buyerFee : data.sellerFee;
}
role = data.aggressor === Schema.Side.SIDE_BUY ? TAKER : MAKER;
feesObj = role === TAKER ? data?.buyerFee : data.sellerFee;
} else if (data?.seller.id === partyId) {
if (data.aggressor === Schema.Side.SIDE_SELL) {
role = TAKER;
feesObj = data?.sellerFee;
} else if (data.aggressor === Schema.Side.SIDE_BUY) {
role = MAKER;
feesObj = data?.buyerFee;
} else {
role = '-';
feesObj = !isEmptyFeeObj(data.sellerFee) ? data.sellerFee : data.buyerFee;
}
role = data.aggressor === Schema.Side.SIDE_SELL ? TAKER : MAKER;
feesObj = role === TAKER ? data?.sellerFee : data.buyerFee;
} else {
return { role: '-', feesObj: '-' };
}
@@ -283,6 +270,11 @@ const FeesBreakdownTooltip = ({
{role === MAKER && (
<>
<p className="mb-1">{t('The maker will receive the maker fee.')}</p>
<p className="mb-1">
{t(
'If the market is in monitoring auction the maker will pay half of the infrastructure and liquidity fees.'
)}
</p>
<p className="mb-1">
{t(
'If the market is active the maker will pay zero infrastructure and liquidity fees.'
@@ -291,14 +283,14 @@ const FeesBreakdownTooltip = ({
</>
)}
{role === TAKER && (
<p className="mb-1">{t('Fees to be paid by the taker.')}</p>
)}
{role === '-' && (
<p className="mb-1">
{t(
'If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.'
)}
</p>
<>
<p className="mb-1">{t('Fees to be paid by the taker.')}</p>
<p className="mb-1">
{t(
'If the market is in monitoring auction the taker will pay half of the infrastructure and liquidity fees.'
)}
</p>
</>
)}
<dl className="grid grid-cols-2 gap-x-1">
<dt className="col-span-1">{t('Infrastructure fee')}</dt>
@@ -324,7 +316,7 @@ const FeesBreakdownTooltip = ({
};
export const getFeesBreakdown = (
role: Role,
role: string,
feesObj: {
__typename?: 'TradeFee' | undefined;
makerFee: string;
@@ -336,7 +328,6 @@ export const getFeesBreakdown = (
role === MAKER
? new BigNumber(feesObj.makerFee).times(-1).toString()
: feesObj.makerFee;
const infrastructureFee = feesObj.infrastructureFee;
const liquidityFee = feesObj.liquidityFee;
-1
View File
@@ -12,5 +12,4 @@ export default {
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/libs/ledger',
setupFilesAfterEnv: ['./src/setup-tests.ts'],
};
@@ -30,10 +30,7 @@ export type LedgerEntry = LedgerEntryFragment & {
};
export type AggregatedLedgerEntriesEdge = Schema.AggregatedLedgerEntriesEdge;
export type AggregatedLedgerEntriesNode = Omit<
AggregatedLedgerEntriesEdge,
'node'
> & {
export type AggregatedLedgerEntriesNode = AggregatedLedgerEntriesEdge & {
node: LedgerEntry;
};
+2 -1
View File
@@ -32,7 +32,7 @@ export const ledgerEntriesQuery = (
return merge(defaultResult, override);
};
export const ledgerEntries: LedgerEntryFragment[] = [
const ledgerEntries: LedgerEntryFragment[] = [
{
vegaTime: '1669224476734364000',
quantity: '0',
@@ -180,6 +180,7 @@ export const ledgerEntries: LedgerEntryFragment[] = [
toAccountBalance: '0',
fromAccountBalance: '0',
},
{
vegaTime: '2022-11-24T12:41:22.054428Z',
quantity: '1000000000',
@@ -1,85 +0,0 @@
import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LedgerExportLink } from './ledger-export-link';
import * as Types from '@vegaprotocol/types';
import { ledgerEntries } from './ledger-entries.mock';
import type { LedgerEntry } from './ledger-entries-data-provider';
const VEGA_URL = 'https://vega-url.co.uk/querystuff';
const mockEnvironment = jest.fn(() => VEGA_URL);
jest.mock('@vegaprotocol/environment', () => ({
useEnvironment: jest.fn(() => mockEnvironment()),
}));
const asset = {
id: 'assetID',
name: 'assetName',
symbol: 'assetSymbol',
decimals: 1,
quantum: '1',
status: Types.AssetStatus,
source: {
__typename: 'ERC20',
contractAddress: 'contractAddres',
lifetimeLimit: 'lifetimeLimit',
withdrawThreshold: 'withdraw',
},
};
describe('LedgerExportLink', () => {
const partyId = 'partyId';
const entries = ledgerEntries.map((entry) => {
return {
...entry,
asset: entry.assetId
? {
...asset,
id: entry.assetId,
name: `name ${entry.assetId}`,
symbol: `symbol ${entry.assetId}`,
}
: null,
marketSender: null,
marketReceiver: null,
} as LedgerEntry;
});
it('should be properly rendered', async () => {
render(<LedgerExportLink partyId={partyId} entries={entries} />);
await waitFor(() => {
expect(screen.getByRole('link')).toBeInTheDocument();
expect(screen.getByRole('link')).toHaveAttribute(
'href',
`https://vega-url.co.uk/api/v2/ledgerentry/export?partyId=${partyId}&assetId=asset-id`
);
expect(
screen.getByRole('button', { name: /^symbol asset-id/ })
).toBeInTheDocument();
});
});
it('should be properly change link url', async () => {
render(<LedgerExportLink partyId={partyId} entries={entries} />);
await waitFor(() => {
expect(
screen.getByRole('button', { name: /^symbol asset-id/ })
).toBeInTheDocument();
});
act(() => {
userEvent.click(screen.getByRole('button', { name: /^symbol asset-id/ }));
});
await waitFor(() => {
expect(screen.getByRole('menu')).toBeInTheDocument();
});
act(() => {
userEvent.click(
screen.getByRole('menuitem', { name: /^symbol asset-id-2/ })
);
});
await waitFor(() => {
expect(screen.getByRole('link')).toHaveAttribute(
'href',
`https://vega-url.co.uk/api/v2/ledgerentry/export?partyId=${partyId}&assetId=asset-id-2`
);
});
});
});
@@ -1,71 +0,0 @@
import type { LedgerEntry } from './ledger-entries-data-provider';
import { useMemo, useState } from 'react';
import { useEnvironment } from '@vegaprotocol/environment';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
Link,
Button,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
const getProtoHost = (vegaurl: string) => {
const loc = new URL(vegaurl);
return `${loc.protocol}//${loc.host}`;
};
export const LedgerExportLink = ({
partyId,
entries,
}: {
partyId: string;
entries: LedgerEntry[];
}) => {
const assets = entries.reduce((aggr, item) => {
if (item.asset && !(item.asset.id in aggr)) {
aggr[item.asset.id] = item.asset.symbol;
}
return aggr;
}, {} as Record<string, string>);
const [assetId, setAssetId] = useState(Object.keys(assets)[0]);
const VEGA_URL = useEnvironment((store) => store.VEGA_URL);
const protohost = VEGA_URL ? getProtoHost(VEGA_URL) : '';
const assetDropDown = useMemo(() => {
return (
<DropdownMenu
trigger={<DropdownMenuTrigger>{assets[assetId]}</DropdownMenuTrigger>}
>
<DropdownMenuContent>
{Object.keys(assets).map((assetKey) => (
<DropdownMenuItem
key={assetKey}
onSelect={() => setAssetId(assetKey)}
>
{assets[assetKey]}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}, [assetId, assets]);
if (!protohost) {
return null;
}
return (
<div className="flex shrink items-stretch gap-2 p-2">
<div className="flex items-center">Export all</div>
{assetDropDown}
<Link
className="text-sm"
title={t('Download all to .csv file')}
href={`${protohost}/api/v2/ledgerentry/export?partyId=${partyId}&assetId=${assetId}`}
>
<Button size="sm">{t('Download')}</Button>
</Link>
</div>
);
};
+1 -6
View File
@@ -3,13 +3,12 @@ import type * as Schema from '@vegaprotocol/types';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { FilterChangedEvent } from 'ag-grid-community';
import type { AgGridReact } from 'ag-grid-react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { subDays, formatRFC3339 } from 'date-fns';
import type { AggregatedLedgerEntriesNode } from './ledger-entries-data-provider';
import { useLedgerEntriesDataProvider } from './ledger-entries-data-provider';
import { LedgerTable } from './ledger-table';
import type * as Types from '@vegaprotocol/types';
import { LedgerExportLink } from './ledger-export-link';
export interface Filter {
vegaTime?: {
@@ -23,7 +22,6 @@ const defaultFilter = {
value: { start: formatRFC3339(subDays(Date.now(), 7)) },
},
};
export const LedgerManager = ({ partyId }: { partyId: string }) => {
const gridRef = useRef<AgGridReact | null>(null);
const [filter, setFilter] = useState<Filter>(defaultFilter);
@@ -57,9 +55,6 @@ export const LedgerManager = ({ partyId }: { partyId: string }) => {
rowData={extractedData}
onFilterChanged={onFilterChanged}
/>
{extractedData && (
<LedgerExportLink entries={extractedData} partyId={partyId} />
)}
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer
loading={loading}
+1 -1
View File
@@ -49,7 +49,7 @@ export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
(props, ref) => {
return (
<AgGrid
style={{ width: '100%', height: 'calc(100% - 50px)' }}
style={{ width: '100%', height: '100%' }}
ref={ref}
tooltipShowDelay={500}
defaultColDef={{
-24
View File
@@ -1,24 +0,0 @@
import '@testing-library/jest-dom';
import 'jest-canvas-mock';
import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;
global.DOMRect = class DOMRect {
bottom = 0;
left = 0;
right = 0;
top = 0;
constructor(
public x = 0,
public y = 0,
public width = 0,
public height = 0
) {}
static fromRect(other?: DOMRectInit): DOMRect {
return new DOMRect(other?.x, other?.y, other?.width, other?.height);
}
toJSON() {
return JSON.stringify(this);
}
};
+19 -23
View File
@@ -19,29 +19,25 @@ export const useMarketOracle = (marketId: string) => {
marketInfo.tradableInstrument.instrument.product
.dataSourceSpecForSettlementData.data;
return data.find((provider) =>
provider.proofs.some((proof) => {
if (
proof.type === 'eth_address' &&
dataSource.sourceType.__typename === 'DataSourceDefinitionExternal'
) {
return dataSource.sourceType.sourceType.signers?.some(
(signer) =>
signer.signer.__typename === 'ETHAddress' &&
signer.signer.address === proof.eth_address
);
}
if (
proof.type === 'public_key' &&
dataSource.sourceType.__typename === 'DataSourceDefinitionExternal'
) {
return dataSource.sourceType.sourceType.signers?.some(
(signer) =>
signer.signer.__typename === 'PubKey' &&
signer.signer.key === proof.public_key
);
}
return false;
})
provider.proofs.some(
(proof) =>
(proof.type === 'eth_address' &&
dataSource.sourceType.__typename ===
'DataSourceDefinitionExternal' &&
dataSource.sourceType.sourceType.signers?.some(
(signer) =>
signer.signer.__typename === 'ETHAddress' &&
signer.signer.address === proof.eth_address
)) ||
(proof.type === 'public_key' &&
dataSource.sourceType.__typename ===
'DataSourceDefinitionExternal' &&
dataSource.sourceType.sourceType.signers?.some(
(signer) =>
signer.signer.__typename === 'PubKey' &&
signer.signer.key === proof.public_key
))
)
)?.oracle;
}, [data, marketInfo]);
};
@@ -1,7 +1,4 @@
query Stats {
epoch {
id
}
nodeData {
stakedTotal
totalNodes
@@ -6,14 +6,11 @@ const defaultOptions = {} as const;
export type StatsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type StatsQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string }, nodeData?: { __typename?: 'NodeData', stakedTotal: string, totalNodes: number, inactiveNodes: number } | null, statistics: { __typename?: 'Statistics', status: string, blockHeight: string, blockDuration: string, backlogLength: string, txPerBlock: string, tradesPerSecond: string, ordersPerSecond: string, averageOrdersPerBlock: string, vegaTime: any, appVersion: string, chainVersion: string, chainId: string, genesisTime: any } };
export type StatsQuery = { __typename?: 'Query', nodeData?: { __typename?: 'NodeData', stakedTotal: string, totalNodes: number, inactiveNodes: number } | null, statistics: { __typename?: 'Statistics', status: string, blockHeight: string, blockDuration: string, backlogLength: string, txPerBlock: string, tradesPerSecond: string, ordersPerSecond: string, averageOrdersPerBlock: string, vegaTime: any, appVersion: string, chainVersion: string, chainId: string, genesisTime: any } };
export const StatsDocument = gql`
query Stats {
epoch {
id
}
nodeData {
stakedTotal
totalNodes
@@ -19,14 +19,10 @@ export const StatsManager = ({ className }: StatsManagerProps) => {
return () => stopPolling();
}, [startPolling, stopPolling]);
const getValue = (field: keyof NodeData | keyof Statistics | 'epoch') => {
if (['stakedTotal', 'totalNodes', 'inactiveNodes'].includes(field)) {
return data?.nodeData?.[field as keyof NodeData];
} else if (field === 'epoch') {
return data?.epoch.id;
}
return data?.statistics?.[field as keyof Statistics];
};
const getValue = (field: keyof NodeData | keyof Statistics) =>
['stakedTotal', 'totalNodes', 'inactiveNodes'].includes(field)
? data?.nodeData?.[field as keyof NodeData]
: data?.statistics?.[field as keyof Statistics];
const panels = fieldsDefinition.map(
({ field, title, description, formatter, goodThreshold }) => ({
@@ -54,7 +50,7 @@ export const StatsManager = ({ className }: StatsManagerProps) => {
className={classNames(
'border rounded p-2 relative border-vega-light-200 dark:border-vega-dark-200',
{
'col-span-2': field === 'chainId',
'col-span-2': field === 'chainId' || field === 'status',
},
{
'bg-transparent border-vega-light-200 dark:border-vega-dark-200':
@@ -20,7 +20,7 @@ export type FieldValue = any;
export type GoodThreshold = (...args: FieldValue[]) => boolean;
export interface Stats {
field: keyof NodeData | keyof Statistics | 'epoch';
field: keyof NodeData | keyof Statistics;
title: string;
goodThreshold?: GoodThreshold;
// eslint-disable-next-line
@@ -161,11 +161,6 @@ const VEGA_TIME: Stats = {
description: t('The time on the blockchain'),
};
const EPOCH: Stats = {
field: 'epoch',
title: 'Epoch',
};
const APP_VERSION: Stats = {
field: 'appVersion',
title: t('App'),
@@ -222,7 +217,6 @@ const CHAIN_ID: Stats = {
export const fieldsDefinition: Stats[] = [
STATUS,
EPOCH,
BLOCK_HEIGHT,
UPTIME,
TOTAL_NODES,
+11 -5
View File
@@ -1,18 +1,24 @@
import { useRef } from 'react';
import { BrowserTracing } from '@sentry/tracing';
import * as Sentry from '@sentry/browser';
import type { LocalLogger, LoggerConf } from '@vegaprotocol/utils';
import { localLoggerFactory, SentryInit } from '@vegaprotocol/utils';
import { localLoggerFactory } from '@vegaprotocol/utils';
export interface LoggerProps extends LoggerConf {
interface Props extends LoggerConf {
dsn?: string;
env?: string;
}
export const useLogger = ({ dsn, env, ...props }: LoggerProps) => {
export const useLogger = ({ dsn, ...props }: Props) => {
const logger = useRef<LocalLogger | null>(null);
if (!logger.current) {
logger.current = localLoggerFactory(props);
if (dsn) {
SentryInit(dsn, env);
Sentry.init({
dsn,
integrations: [new BrowserTracing()],
tracesSampleRate: 1,
defaultIntegrations: false,
});
}
}
return logger.current;
+52 -271
View File
@@ -796,67 +796,6 @@ export type ETHAddress = {
address?: Maybe<Scalars['String']>;
};
/** List of all entities created by transaction hash */
export type Entities = {
__typename?: 'Entities';
/** List of accounts created by the transaction hash */
accounts?: Maybe<Array<Maybe<AccountEvent>>>;
/** List of assets created by the transaction hash */
assets?: Maybe<Array<Maybe<Asset>>>;
/** List of balance changes created by the transaction hash */
balanceChanges?: Maybe<Array<Maybe<AccountBalance>>>;
/** List of delegations created by the transaction hash */
delegations?: Maybe<Array<Maybe<Delegation>>>;
/** List of deposits created by the transaction hash */
deposits?: Maybe<Array<Maybe<Deposit>>>;
/** List of ERC-20 multisig signer added bundles created by the transaction hash */
erc20MultiSigSignerAddedBundles?: Maybe<Array<Maybe<ERC20MultiSigSignerAddedBundle>>>;
/** List of ERC-20 multisig signer removed bundles created by the transaction hash */
erc20MultiSigSignerRemovedBundles?: Maybe<Array<Maybe<ERC20MultiSigSignerRemovedBundle>>>;
/** List of ethereum key rotations created by the transaction hash */
ethereumKeyRotations?: Maybe<Array<Maybe<EthereumKeyRotation>>>;
/** List of key rotations created by the transaction hash */
keyRotations?: Maybe<Array<Maybe<KeyRotation>>>;
/** List of ledger entries created by the transaction hash */
ledgerEntries?: Maybe<Array<Maybe<LedgerEntry>>>;
/** List of liquidity provisions created by the transaction hash */
liquidityProvisions?: Maybe<Array<Maybe<LiquidityProvision>>>;
/** List of margin levels created by the transaction hash */
marginLevels?: Maybe<Array<Maybe<MarginLevels>>>;
/** List of markets created by the transaction hash */
markets?: Maybe<Array<Maybe<Market>>>;
/** List of network parameters created by the transaction hash */
networkParameters?: Maybe<Array<Maybe<NetworkParameter>>>;
/** List of node signatures created by the transaction hash */
nodeSignatures?: Maybe<Array<Maybe<NodeSignature>>>;
/** List of nodes created by the transaction hash */
nodes?: Maybe<Array<Maybe<NodeBasic>>>;
/** List of oracle data created by the transaction hash */
oracleData?: Maybe<Array<Maybe<OracleData>>>;
/** List of oracle specs created by the transaction hash */
oracleSpecs?: Maybe<Array<Maybe<OracleSpec>>>;
/** List of orders created by the transaction hash */
orders?: Maybe<Array<Maybe<Order>>>;
/** List of parties created by the transaction hash */
parties?: Maybe<Array<Maybe<Party>>>;
/** List of positions created by the transaction hash */
positions?: Maybe<Array<Maybe<Position>>>;
/** List of proposals created by the transaction hash */
proposals?: Maybe<Array<Maybe<ProposalDetail>>>;
/** List of protocol upgrade proposals created by the transaction hash */
protocolUpgradeProposals?: Maybe<Array<Maybe<ProtocolUpgradeProposal>>>;
/** List of rewards created by the transaction hash */
rewards?: Maybe<Array<Maybe<Reward>>>;
/** List of trades created by the transaction hash */
trades?: Maybe<Array<Maybe<Trade>>>;
/** List of transfers created by the transaction hash */
transfers?: Maybe<Array<Maybe<Transfer>>>;
/** List of votes created by the transaction hash */
votes?: Maybe<Array<Maybe<Vote>>>;
/** List of withdrawals created by the transaction hash */
withdrawals?: Maybe<Array<Maybe<Withdrawal>>>;
};
/** Epoch describes a specific period of time in the Vega network */
export type Epoch = {
__typename?: 'Epoch';
@@ -1049,15 +988,6 @@ export type ExternalDataSourceSpec = {
spec: DataSourceSpec;
};
/** An estimate of the fee to be paid for the order */
export type FeeEstimate = {
__typename?: 'FeeEstimate';
/** The estimated fees if the order was to trade */
fees: TradeFee;
/** The total estimated amount of fees if the order was to trade */
totalFeeAmount: Scalars['String'];
};
/** The factors applied to calculate the fees */
export type FeeFactors = {
__typename?: 'FeeFactors';
@@ -1248,26 +1178,6 @@ export type LedgerEntryFilter = {
TransferTypes?: InputMaybe<Array<InputMaybe<TransferType>>>;
};
/** Liquidation estimate for both worst and best case possible */
export type LiquidationEstimate = {
__typename?: 'LiquidationEstimate';
/** Liquidation price estimate assuming no slippage */
bestCase: LiquidationPrice;
/** Liquidation price estimate assuming slippage cap is applied */
worstCase: LiquidationPrice;
};
/** Liquidation price estimate for either only the current open volume and position given some or all buy orders get filled, or position given some or all sell orders get filled */
export type LiquidationPrice = {
__typename?: 'LiquidationPrice';
/** Liquidation price assuming buy orders start getting filled */
including_buy_orders: Scalars['String'];
/** Liquidation price assuming sell orders start getting filled */
including_sell_orders: Scalars['String'];
/** Liquidation price for current open volume ignoring any active orders */
open_volume_only: Scalars['String'];
};
/** Configuration of a market liquidity monitoring parameters */
export type LiquidityMonitoringParameters = {
__typename?: 'LiquidityMonitoringParameters';
@@ -1457,15 +1367,6 @@ export type MarginEdge = {
node: MarginLevels;
};
/** Margin level estimate for both worst and best case possible */
export type MarginEstimate = {
__typename?: 'MarginEstimate';
/** Margin level estimate assuming no slippage */
bestCase: MarginLevels;
/** Margin level estimate assuming slippage cap is applied */
worstCase: MarginLevels;
};
/** Margins for a given a party */
export type MarginLevels = {
__typename?: 'MarginLevels';
@@ -1476,7 +1377,7 @@ export type MarginLevels = {
* the general account of the party for the given asset.
*/
collateralReleaseLevel: Scalars['String'];
/** This is the minimum margin required for a party to place a new order on the network, expressed as unsigned integer */
/** This is the minimum margin required for a party to place a new order on the network (unsigned integer) */
initialLevel: Scalars['String'];
/** Minimal margin for the position to be maintained in the network (unsigned integer) */
maintenanceLevel: Scalars['String'];
@@ -1484,7 +1385,7 @@ export type MarginLevels = {
market: Market;
/** The party for this margin */
party: Party;
/** If the margin is between maintenance and search, the network will initiate a collateral search, expressed as unsigned integer */
/** If the margin is between maintenance and search, the network will initiate a collateral search (unsigned integer) */
searchLevel: Scalars['String'];
/** RFC3339Nano time from at which this margin level was relevant */
timestamp: Scalars['Timestamp'];
@@ -1582,7 +1483,6 @@ export type Market = {
state: MarketState;
/** An instance of, or reference to, a tradable instrument. */
tradableInstrument: TradableInstrument;
/** @deprecated Simplify and consolidate trades query and remove nesting. Use trades query instead */
tradesConnection?: Maybe<TradeConnection>;
/** Current mode of execution of the market */
tradingMode: MarketTradingMode;
@@ -1994,28 +1894,6 @@ export type NodedelegationsConnectionArgs = {
partyId?: InputMaybe<Scalars['ID']>;
};
export type NodeBasic = {
__typename?: 'NodeBasic';
/** The URL of an avatar */
avatarUrl?: Maybe<Scalars['String']>;
/** Ethereum public key of the node */
ethereumAddress: Scalars['String'];
/** The node URL, for example n01.vega.xyz */
id: Scalars['ID'];
/** URL that provides more information about the node */
infoUrl: Scalars['String'];
/** Country code for the location of the node */
location: Scalars['String'];
/** The name of the node operator */
name: Scalars['String'];
/** Public key of the node operator */
pubkey: Scalars['String'];
/** Validator status of the node */
status: NodeStatus;
/** Tendermint public key of the node */
tmPubkey: Scalars['String'];
};
/** Summary of data across all nodes */
export type NodeData = {
__typename?: 'NodeData';
@@ -2229,6 +2107,18 @@ export type ObservableMarketDepthUpdate = {
sequenceNumber: Scalars['String'];
};
export type OffsetPagination = {
/**
* Descending reverses the order of the records returned
* default is true, if false the results will be returned in ascending order
*/
descending: Scalars['Boolean'];
/** Limit the number of returned records to the value specified, default is 50 */
limit: Scalars['Int'];
/** Skip the number of records specified, default is 0 */
skip: Scalars['Int'];
};
/** The specific details for a one-off transfer */
export type OneOffTransfer = {
__typename?: 'OneOffTransfer';
@@ -2323,10 +2213,7 @@ export type Order = {
status: OrderStatus;
/** The timeInForce of order (determines how and if it executes, and whether it persists on the book) */
timeInForce: OrderTimeInForce;
/**
* Trades relating to this order
* @deprecated Simplify and consolidate trades query and remove nesting. Use trades query instead
*/
/** Trades relating to this order */
tradesConnection?: Maybe<TradeConnection>;
/** The order type */
type?: Maybe<OrderType>;
@@ -2392,28 +2279,11 @@ export type OrderFilter = {
/** Date range to retrieve orders from/to. Start and end time should be expressed as an integer value of nano-seconds past the Unix epoch */
dateRange?: InputMaybe<DateRange>;
excludeLiquidity?: InputMaybe<Scalars['Boolean']>;
/**
* If true, only orders that are live will be returned. Orders are live if they have STATUS_ACTIVE or STATUS_PARKED
* as per https://github.com/vegaprotocol/specs-internal/blob/master/protocol/0024-OSTA-order_status.md
*/
liveOnly?: InputMaybe<Scalars['Boolean']>;
status?: InputMaybe<Array<OrderStatus>>;
timeInForce?: InputMaybe<Array<OrderTimeInForce>>;
types?: InputMaybe<Array<OrderType>>;
};
/** Basic description of an order */
export type OrderInfo = {
/** Boolean indicating a market order */
isMarketOrder: Scalars['Boolean'];
/** Price for the order */
price: Scalars['String'];
/** Number of units remaining of the total that have not yet been bought or sold (uint64) */
remaining: Scalars['String'];
/** Whether the order is to buy or sell */
side: Side;
};
/** Why the order was rejected by the core node */
export enum OrderRejectionReason {
/** Amending the order failed */
@@ -2434,8 +2304,6 @@ export enum OrderRejectionReason {
ORDER_ERROR_CANNOT_HAVE_GTC_AND_EXPIRYAT = 'ORDER_ERROR_CANNOT_HAVE_GTC_AND_EXPIRYAT',
/** Cannot send FOK orders during an auction */
ORDER_ERROR_CANNOT_SEND_FOK_ORDER_DURING_AUCTION = 'ORDER_ERROR_CANNOT_SEND_FOK_ORDER_DURING_AUCTION',
/** Good for Auction order received during continuous trading */
ORDER_ERROR_CANNOT_SEND_GFA_ORDER_DURING_CONTINUOUS_TRADING = 'ORDER_ERROR_CANNOT_SEND_GFA_ORDER_DURING_CONTINUOUS_TRADING',
/** Good for Normal order received during an auction */
ORDER_ERROR_CANNOT_SEND_GFN_ORDER_DURING_AN_AUCTION = 'ORDER_ERROR_CANNOT_SEND_GFN_ORDER_DURING_AN_AUCTION',
/** Cannot send IOC orders during an auction */
@@ -2444,8 +2312,8 @@ export enum OrderRejectionReason {
ORDER_ERROR_EDIT_NOT_ALLOWED = 'ORDER_ERROR_EDIT_NOT_ALLOWED',
/** Attempt to amend expiry time to a value before time order was created */
ORDER_ERROR_EXPIRYAT_BEFORE_CREATEDAT = 'ORDER_ERROR_EXPIRYAT_BEFORE_CREATEDAT',
/** Order was submitted with an incorrect or invalid market type */
ORDER_ERROR_INCORRECT_MARKET_TYPE = 'ORDER_ERROR_INCORRECT_MARKET_TYPE',
/** Good for Auction order received during continuous trading */
ORDER_ERROR_GFA_CANNOT_SEND_ORDER_DURING_CONTINUOUS_TRADING = 'ORDER_ERROR_GFA_CANNOT_SEND_ORDER_DURING_CONTINUOUS_TRADING',
/** Insufficient balance to submit the order (no deposit made) */
ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE = 'ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE',
/** Insufficient funds to pay fees */
@@ -2492,10 +2360,6 @@ export enum OrderRejectionReason {
ORDER_ERROR_OFFSET_MUST_BE_GREATER_THAN_ZERO = 'ORDER_ERROR_OFFSET_MUST_BE_GREATER_THAN_ZERO',
/** Order is out of sequence */
ORDER_ERROR_OUT_OF_SEQUENCE = 'ORDER_ERROR_OUT_OF_SEQUENCE',
/** A post-only order would produce an aggressive trade and thus it has been rejected */
ORDER_ERROR_POST_ONLY_ORDER_WOULD_TRADE = 'ORDER_ERROR_POST_ONLY_ORDER_WOULD_TRADE',
/** A reduce-ony order would not reduce the party's position and thus it has been rejected */
ORDER_ERROR_REDUCE_ONLY_ORDER_WOULD_NOT_REDUCE = 'ORDER_ERROR_REDUCE_ONLY_ORDER_WOULD_NOT_REDUCE',
/** Unable to remove the order */
ORDER_ERROR_REMOVAL_FAILURE = 'ORDER_ERROR_REMOVAL_FAILURE',
/** Order cannot be filled because it would require self trading */
@@ -2504,8 +2368,6 @@ export enum OrderRejectionReason {
ORDER_ERROR_SELL_CANNOT_REFERENCE_BEST_BID_PRICE = 'ORDER_ERROR_SELL_CANNOT_REFERENCE_BEST_BID_PRICE',
/** Time has failed us */
ORDER_ERROR_TIME_FAILURE = 'ORDER_ERROR_TIME_FAILURE',
/** Unable to submit pegged order, temporarily too many pegged orders across all markets */
ORDER_ERROR_TOO_MANY_PEGGED_ORDERS = 'ORDER_ERROR_TOO_MANY_PEGGED_ORDERS',
/** Unable to amend pegged order price */
ORDER_ERROR_UNABLE_TO_AMEND_PRICE_ON_PEGGED_ORDER = 'ORDER_ERROR_UNABLE_TO_AMEND_PRICE_ON_PEGGED_ORDER',
/** Unable to reprice a pegged order */
@@ -2664,7 +2526,6 @@ export type Party = {
rewardsConnection?: Maybe<RewardsConnection>;
/** The staking information for this Party */
stakingSummary: StakingSummary;
/** @deprecated Simplify and consolidate trades query and remove nesting. Use trades query instead */
tradesConnection?: Maybe<TradeConnection>;
/** All transfers for a public key */
transfersConnection?: Maybe<TransferConnection>;
@@ -2893,15 +2754,6 @@ export type PositionEdge = {
node: Position;
};
/** Response for the estimate of the margin level and, if available, collateral was provided in the request, liqudation price for the specified position */
export type PositionEstimate = {
__typename?: 'PositionEstimate';
/** Liquidation price range estimate for the specified position. Only populated if available collateral was specified in the request */
liquidation?: Maybe<LiquidationEstimate>;
/** Margin level range estimate for the specified position */
margin: MarginEstimate;
};
export type PositionResolution = {
__typename?: 'PositionResolution';
/** Number of parties closed out */
@@ -2918,8 +2770,6 @@ export type PositionResolution = {
export enum PositionStatus {
/** The position was distressed, and had to be closed out entirely - orders were removed from the book, and the open volume was closed out by the network */
POSITION_STATUS_CLOSED_OUT = 'POSITION_STATUS_CLOSED_OUT',
/** The position was distressed, but could not be closed out - orders were removed from the book, and the open volume will be closed out once there is sufficient volume on the book */
POSITION_STATUS_DISTRESSED = 'POSITION_STATUS_DISTRESSED',
/** The position was distressed, but removing open orders from the book brought the margin level back to a point where the open position could be maintained */
POSITION_STATUS_ORDERS_CLOSED = 'POSITION_STATUS_ORDERS_CLOSED',
/** The position is either healthy, or if closed out, was closed out normally */
@@ -3073,9 +2923,9 @@ export type Proposal = {
reference: Scalars['String'];
/** Why the proposal was rejected by the core */
rejectionReason?: Maybe<ProposalRejectionReason>;
/** Equity-like share required for a market amendment proposal to be enacted (if not met, the proposal will not be enacted), represented as a fraction that can be converted to a percentage */
/** Required liquidity provider equity like share majority for this proposal to succeed */
requiredLpMajority?: Maybe<Scalars['String']>;
/** The market share of LPs' equity-like share that must take part in the market amendment vote for the proposal to pass. This means the votes of LPs that have submitted more liquidity to that market, or have been LPs from the start carry more weight. If it requires 50% of a market's equity-like share for a majority, and the proposal receives only YES votes but only LPs with 49% of the equity-like share voted, the proposal will not pass */
/** Required liquidity provider equity like share participation for this proposal to succeed */
requiredLpParticipation?: Maybe<Scalars['String']>;
/** Required majority for this proposal to succeed */
requiredMajority: Scalars['String'];
@@ -3091,36 +2941,6 @@ export type Proposal = {
export type ProposalChange = NewAsset | NewFreeform | NewMarket | UpdateAsset | UpdateMarket | UpdateNetworkParameter;
export type ProposalDetail = {
__typename?: 'ProposalDetail';
/** RFC3339Nano time and date when the proposal reached the Vega network */
datetime: Scalars['Timestamp'];
/** Error details of the rejectionReason */
errorDetails?: Maybe<Scalars['String']>;
/** Proposal ID that is provided by Vega once proposal reaches the network */
id?: Maybe<Scalars['ID']>;
/** Party that prepared the proposal */
party: Party;
/** Rationale behind the proposal */
rationale: ProposalRationale;
/** A UUID reference to aid tracking proposals on Vega */
reference: Scalars['String'];
/** Why the proposal was rejected by the core */
rejectionReason?: Maybe<ProposalRejectionReason>;
/** Equity-like share required for a market amendment proposal to be enacted (if not met, the proposal will not be enacted), represented as a fraction that can be converted to a percentage */
requiredLpMajority?: Maybe<Scalars['String']>;
/** The market share of LPs' equity-like share that must take part in the market amendment vote for the proposal to pass. This means the votes of LPs that have submitted more liquidity to that market, or have been LPs from the start carry more weight. If it requires 50% of a market's equity-like share for a majority, and the proposal receives only YES votes but only LPs with 49% of the equity-like share voted, the proposal will not pass */
requiredLpParticipation?: Maybe<Scalars['String']>;
/** Required majority for this proposal to succeed */
requiredMajority: Scalars['String'];
/** Required participation for this proposal to succeed */
requiredParticipation: Scalars['String'];
/** State of the proposal */
state: ProposalState;
/** Terms of the proposal */
terms: ProposalTerms;
};
/** Edge type containing the proposals and cursor information returned by a ProposalsConnection */
export type ProposalEdge = {
__typename?: 'ProposalEdge';
@@ -3414,8 +3234,6 @@ export type Query = {
deposit?: Maybe<Deposit>;
/** Fetch all deposits */
deposits?: Maybe<DepositsConnection>;
/** Fetch all entities for a given transaction hash */
entities: Entities;
/** Get data for a specific epoch, if ID omitted it gets the current epoch. If the string is 'next', fetch the next epoch */
epoch: Epoch;
/** List reward summary per epoch by asset, market, reward type */
@@ -3431,17 +3249,15 @@ export type Query = {
/** Find an erc20 withdrawal approval using its withdrawal ID */
erc20WithdrawalApproval?: Maybe<Erc20WithdrawalApproval>;
/** Return an estimation of the potential cost for a new order */
estimateFees: FeeEstimate;
/**
* Return an estimation of the potential cost for a new order
* @deprecated Use estimateFees and estimatePosition instead
*/
estimateOrder: OrderEstimate;
/** Return a margin range for the specified position and liquidation price range if available collateral is supplied */
estimatePosition?: Maybe<PositionEstimate>;
/** Query for historic ethereum key rotations */
ethereumKeyRotations: EthereumKeyRotationsConnection;
/** Get market data history for a specific market. If no dates are given, the latest snapshot will be returned. If only the start date is provided all history from the given date will be provided, and if only the end date is provided, all history from the start up to and including the end date will be provided. */
/**
* Get market data history for a specific market. If no dates are given, the latest snapshot will be returned. If only the start date is provided, all history from the given date will be provided, and if only the end date is provided, all history from the start up to and including the end date will be provided.
* @deprecated Use getMarketDataHistoryConnectionByID instead
*/
getMarketDataHistoryByID?: Maybe<Array<Maybe<MarketData>>>;
/** Get market data history for a specific market. If no dates are given, the latest snapshot will be returned. If only the start date is provided all history from the given date will be provided, and if only the end date is provided, all history from the start up to and including the end date will be provided. Pagination is provided using a cursor based pagination model */
getMarketDataHistoryConnectionByID?: Maybe<MarketDataConnection>;
/** Query for historic key rotations */
keyRotationsConnection: KeyRotationConnection;
@@ -3499,8 +3315,6 @@ export type Query = {
protocolUpgradeStatus?: Maybe<ProtocolUpgradeStatus>;
/** Get statistics about the Vega node */
statistics: Statistics;
/** Get a list of all trades and apply any given filters to the results */
trades?: Maybe<TradeConnection>;
/** Get a list of all transfers for a public key */
transfersConnection?: Maybe<TransferConnection>;
/** Find a withdrawal using its ID */
@@ -3550,12 +3364,6 @@ export type QuerydepositsArgs = {
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryentitiesArgs = {
txHash: Scalars['String'];
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryepochArgs = {
id?: InputMaybe<Scalars['ID']>;
@@ -3605,19 +3413,6 @@ export type Queryerc20WithdrawalApprovalArgs = {
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryestimateFeesArgs = {
expiration?: InputMaybe<Scalars['Timestamp']>;
marketId: Scalars['ID'];
partyId: Scalars['ID'];
price?: InputMaybe<Scalars['String']>;
side: Side;
size: Scalars['String'];
timeInForce: OrderTimeInForce;
type: OrderType;
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryestimateOrderArgs = {
expiration?: InputMaybe<Scalars['Timestamp']>;
@@ -3632,17 +3427,19 @@ export type QueryestimateOrderArgs = {
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryestimatePositionArgs = {
collateralAvailable?: InputMaybe<Scalars['String']>;
marketId: Scalars['ID'];
openVolume: Scalars['String'];
orders?: InputMaybe<Array<OrderInfo>>;
export type QueryethereumKeyRotationsArgs = {
nodeId?: InputMaybe<Scalars['ID']>;
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QueryethereumKeyRotationsArgs = {
nodeId?: InputMaybe<Scalars['ID']>;
export type QuerygetMarketDataHistoryByIDArgs = {
end?: InputMaybe<Scalars['Timestamp']>;
first?: InputMaybe<Scalars['Int']>;
id: Scalars['ID'];
last?: InputMaybe<Scalars['Int']>;
skip?: InputMaybe<Scalars['Int']>;
start?: InputMaybe<Scalars['Timestamp']>;
};
@@ -3803,14 +3600,6 @@ export type QueryprotocolUpgradeProposalsArgs = {
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QuerytradesArgs = {
dateRange?: InputMaybe<DateRange>;
filter?: InputMaybe<TradesFilter>;
pagination?: InputMaybe<Pagination>;
};
/** Queries allow a caller to read data and filter data via GraphQL. */
export type QuerytransfersConnectionArgs = {
direction?: InputMaybe<TransferDirection>;
@@ -4009,9 +3798,7 @@ export enum Side {
/** The placer of the order is aiming to buy */
SIDE_BUY = 'SIDE_BUY',
/** The placer of the order is aiming to sell */
SIDE_SELL = 'SIDE_SELL',
/** Unspecified is only used for trades at the end of an auction, where neither party acts as the aggressor. */
SIDE_UNSPECIFIED = 'SIDE_UNSPECIFIED'
SIDE_SELL = 'SIDE_SELL'
}
/** Signer is the authorized signature used for the data. */
@@ -4191,6 +3978,8 @@ export type Subscription = {
busEvents?: Maybe<Array<BusEvent>>;
/** Subscribe to the candles updates */
candles: Candle;
/** Subscribe to delegation data */
delegations: Delegation;
/** Subscribe to liquidity provisioning data */
liquidityProvisions?: Maybe<Array<LiquidityProvisionUpdate>>;
/** Subscribe to the margin changes */
@@ -4207,13 +3996,10 @@ export type Subscription = {
positions: Array<PositionUpdate>;
/** Subscribe to proposals. Leave out all arguments to receive all proposals */
proposals: Proposal;
/**
* Subscribe to the trades updates
* @deprecated Use tradesStream instead as it allows for filtering multiple markets and/or parties at once
*/
trades?: Maybe<Array<TradeUpdate>>;
/** Subscribe to reward details data */
rewards: Reward;
/** Subscribe to the trades updates */
tradesStream?: Maybe<Array<TradeUpdate>>;
trades?: Maybe<Array<TradeUpdate>>;
/** Subscribe to votes, either by proposal ID or party ID */
votes: ProposalVote;
};
@@ -4244,6 +4030,13 @@ export type SubscriptioncandlesArgs = {
};
/** Subscriptions allow a caller to receive new information as it is available from the Vega network. */
export type SubscriptiondelegationsArgs = {
nodeId?: InputMaybe<Scalars['ID']>;
partyId?: InputMaybe<Scalars['ID']>;
};
/** Subscriptions allow a caller to receive new information as it is available from the Vega network. */
export type SubscriptionliquidityProvisionsArgs = {
marketId?: InputMaybe<Scalars['ID']>;
@@ -4296,15 +4089,16 @@ export type SubscriptionproposalsArgs = {
/** Subscriptions allow a caller to receive new information as it is available from the Vega network. */
export type SubscriptiontradesArgs = {
marketId?: InputMaybe<Scalars['ID']>;
export type SubscriptionrewardsArgs = {
assetId?: InputMaybe<Scalars['ID']>;
partyId?: InputMaybe<Scalars['ID']>;
};
/** Subscriptions allow a caller to receive new information as it is available from the Vega network. */
export type SubscriptiontradesStreamArgs = {
filter: TradesSubscriptionFilter;
export type SubscriptiontradesArgs = {
marketId?: InputMaybe<Scalars['ID']>;
partyId?: InputMaybe<Scalars['ID']>;
};
@@ -4457,19 +4251,6 @@ export type TradeUpdate = {
type: TradeType;
};
/** Filter to apply to the trade connection query */
export type TradesFilter = {
marketIds?: InputMaybe<Array<Scalars['ID']>>;
orderIds?: InputMaybe<Array<Scalars['ID']>>;
partyIds?: InputMaybe<Array<Scalars['ID']>>;
};
/** Filter to apply to the trade subscription request */
export type TradesSubscriptionFilter = {
marketIds?: InputMaybe<Array<Scalars['ID']>>;
partyIds?: InputMaybe<Array<Scalars['ID']>>;
};
/** The result from processing a transaction */
export type TransactionResult = {
__typename?: 'TransactionResult';
+1 -8
View File
@@ -172,7 +172,7 @@ export const OrderRejectionReasonMapping: {
'Cannot send IOC order during auction',
ORDER_ERROR_EDIT_NOT_ALLOWED: 'Edit not allowed',
ORDER_ERROR_EXPIRYAT_BEFORE_CREATEDAT: 'Expiry time before creation time',
ORDER_ERROR_CANNOT_SEND_GFA_ORDER_DURING_CONTINUOUS_TRADING:
ORDER_ERROR_GFA_CANNOT_SEND_ORDER_DURING_CONTINUOUS_TRADING:
'Cannot send GFA order during continuous trading',
ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE: 'Insufficient asset balance',
ORDER_ERROR_INSUFFICIENT_FUNDS_TO_PAY_FEES: 'Insufficient funds to pay fees',
@@ -209,11 +209,6 @@ export const OrderRejectionReasonMapping: {
'Unable to amend price on pegged order',
ORDER_ERROR_UNABLE_TO_REPRICE_PEGGED_ORDER: 'Unable to reprice pegged order',
ORDER_ERROR_WITHOUT_REFERENCE_PRICE: 'Without reference price',
ORDER_ERROR_INCORRECT_MARKET_TYPE: 'Incorrect market type',
ORDER_ERROR_POST_ONLY_ORDER_WOULD_TRADE: 'Post only order would trade',
ORDER_ERROR_REDUCE_ONLY_ORDER_WOULD_NOT_REDUCE:
'Reduce only order would not reduce',
ORDER_ERROR_TOO_MANY_PEGGED_ORDERS: 'Too many pegged orders',
};
/**
@@ -350,7 +345,6 @@ export const SideMapping: {
} = {
SIDE_BUY: 'Long',
SIDE_SELL: 'Short',
SIDE_UNSPECIFIED: 'Unspecified',
};
/**
@@ -464,7 +458,6 @@ export const PositionStatusMapping: {
POSITION_STATUS_CLOSED_OUT: 'Closed by network',
POSITION_STATUS_ORDERS_CLOSED: 'Maintained by network',
POSITION_STATUS_UNSPECIFIED: 'Normal',
POSITION_STATUS_DISTRESSED: 'Distressed',
};
export const ConditionOperatorMapping: { [C in ConditionOperator]: string } = {
@@ -62,7 +62,7 @@ export function Dialog({
<DialogPrimitives.Root open={open} onOpenChange={(x) => onChange?.(x)}>
<DialogPrimitives.Portal>
<DialogPrimitives.Overlay
className="fixed inset-0 dark:bg-black/80 bg-black/50 z-20"
className="fixed inset-0 bg-black/50 z-20"
data-testid="dialog-overlay"
/>
<DialogPrimitives.Content
@@ -1,41 +0,0 @@
import type { ComponentStory, ComponentMeta } from '@storybook/react';
import className from 'classnames';
import { Divider } from './divider';
export default {
title: 'Divider',
component: Divider,
} as ComponentMeta<typeof Divider>;
const Template: ComponentStory<typeof Divider> = (args) => {
return (
<div
className={className('flex', {
'flex-col': args?.orientation !== 'vertical',
'h-[50px]': args?.orientation === 'vertical',
})}
>
<div
className={className(
'h-[50px]',
args?.orientation !== 'vertical' ? 'w-full' : 'w-1/2'
)}
/>
<Divider orientation={args?.orientation} />
<div
className={className(
'h-[50px]',
args?.orientation !== 'vertical' ? 'w-full' : 'w-2/2'
)}
/>
</div>
);
};
export const Default = Template.bind({});
Default.args = {};
export const Vertical = Template.bind({});
Vertical.args = {
orientation: 'vertical',
};
@@ -1,19 +0,0 @@
import { forwardRef } from 'react';
import * as Separator from '@radix-ui/react-separator';
interface DividerProps {
orientation?: 'horizontal' | 'vertical';
decorative?: boolean;
}
export const Divider = forwardRef<HTMLDivElement, DividerProps>(
({ orientation = 'horizontal', decorative }, ref) => {
return (
<Separator.Root
ref={ref}
className="bg-neutral-700 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px data-[orientation=vertical]:mx-3 data-[orientation=horizontal]:my-3"
{...{ orientation, decorative }}
/>
);
}
);
@@ -1 +0,0 @@
export { Divider } from './divider';
@@ -2,14 +2,13 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { forwardRef } from 'react';
import type { IconName } from '../icon';
import { Icon } from '../icon';
const itemClass = classNames(
'relative flex items-center justify-between rounded-sm p-2 text-sm',
'cursor-default hover:cursor-pointer',
'hover:bg-white dark:hover:bg-vega-dark-200',
'focus:bg-white dark:focus:bg-vega-dark-200',
'hover:bg-white dark:hover:bg-neutral-200',
'focus:bg-white dark:focus:bg-neutral-200',
'select-none',
'whitespace-nowrap'
);
@@ -17,11 +16,6 @@ const itemClass = classNames(
type DropdownMenuProps = DropdownMenuPrimitive.DropdownMenuProps & {
trigger: ReactNode;
};
type DropdownTriggerProps = DropdownMenuPrimitive.DropdownMenuTriggerProps & {
iconName?: IconName;
};
/**
* Contains all the parts of a dropdown menu.
*/
@@ -43,20 +37,22 @@ export const DropdownMenu = ({
*/
export const DropdownMenuTrigger = forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
DropdownTriggerProps
>(({ className, children, iconName, ...props }, forwardedRef) => {
const defaultClasses =
'text-sm py-1 px-2 rounded bg-transparent border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500/20 hover:bg-vega-light-500/40';
React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>
>(({ className, children, ...props }, forwardedRef) => {
const triggerClasses = classNames(
className,
'text-sm py-1 px-2 rounded bg-transparent border border-neutral-500 whitespace-nowrap',
'hover:bg-neutral-500/20 dark:hover:bg-neutral-500/40'
);
return (
<DropdownMenuPrimitive.Trigger
asChild={true}
ref={forwardedRef}
className={className || defaultClasses}
className={triggerClasses}
{...props}
>
<button>
{children} <Icon name={iconName || 'chevron-down'} />
{children} <Icon name="chevron-down" className="ml-2" />
</button>
</DropdownMenuPrimitive.Trigger>
);
@@ -77,7 +73,7 @@ export const DropdownMenuContent = forwardRef<
<DropdownMenuPrimitive.Content
{...contentProps}
ref={forwardedRef}
className="min-w-[290px] bg-vega-light-100 dark:bg-vega-dark-100 p-2 rounded z-20 text-black dark:text-white border-vega-light-200 dark:border-vega-dark-200"
className="min-w-[290px] bg-neutral-200 dark:bg-white p-2 rounded z-20 dark:text-black"
align="start"
sideOffset={10}
/>
@@ -119,9 +115,9 @@ export const DropdownMenuRadioItem = forwardRef<
React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
inset?: boolean;
}
>(({ className, inset = false, ...radioItemProps }, forwardedRef) => (
>(({ className, inset = false, ...radioItemprops }, forwardedRef) => (
<DropdownMenuPrimitive.RadioItem
{...radioItemProps}
{...radioItemprops}
ref={forwardedRef}
className={classNames(itemClass, className)}
/>
@@ -155,7 +151,7 @@ export const DropdownMenuSeparator = forwardRef<
{...separatorProps}
ref={forwardedRef}
className={classNames(
'h-px my-1 mx-2 bg-vega-dark-400 dark:bg-vega-dark-300',
'h-px my-1 mx-2 bg-neutral-400 dark:bg-neutral-300',
className
)}
/>
@@ -1 +0,0 @@
export * from './icon';
+1 -2
View File
@@ -1,2 +1 @@
export * from './blueprint-icons';
export * from './vega-icons';
export * from './icon';
@@ -1,3 +0,0 @@
export * from './vega-icon';
export * from './vega-icon.stories';
export * from './vega-icon-record';
@@ -1,29 +0,0 @@
export const IconBreakdown = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="8" cy="8" r="6.5" stroke="stroke-current" />
<rect
x="8.5"
y="11"
width="1"
height="4"
transform="rotate(-180 8.5 11)"
fill="white"
/>
<rect
x="8.5"
y="6"
width="1"
height="1"
transform="rotate(-180 8.5 6)"
fill="white"
/>
</svg>
);
};
@@ -1,18 +0,0 @@
export const IconCopy = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.47021 1.46997H14.5302V11.53H12.5002V10.47H13.4702V2.52997H5.53021V3.49997H4.47021V1.46997ZM1.47021 4.46997H11.5302V14.53H1.47021V4.46997ZM2.53021 5.52997V13.47H10.4702V5.52997H2.53021Z"
fill="white"
/>
</svg>
);
};
@@ -1,17 +0,0 @@
export const IconDeposit = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="4" y="13" width="8" height="1" fill="white" />
<path
d="M8.52977 8.72048L11.625 5.62524L12.3745 6.37478L7.99977 10.7495L3.625 6.37478L4.37453 5.62524L7.46977 8.72048V2H8.52977V8.72048Z"
fill="white"
/>
</svg>
);
};
@@ -1,18 +0,0 @@
export const IconEdit = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M2.31 10.44L1.5 14.5L5.56 13.69L14.5 4.75L11.25 1.5V1.51L9.97784 2.78074L9.97356 2.77646L9.26645 3.48357L9.27033 3.48745L2.31 10.44ZM11.25 2.92L13.08 4.75L12.5135 5.31645L10.6835 3.48645L11.25 2.92ZM9.97644 4.19356L11.8064 6.02356L6.02355 11.8064L4.19355 9.97645L9.97644 4.19356ZM5.31644 12.5136L5.07 12.76L2.78 13.22L3.24 10.93L3.48644 10.6836L5.31644 12.5136Z"
fill="white"
/>
</svg>
);
};
@@ -1,18 +0,0 @@
export const IconForum = ({ size = 24 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8.20755 15.7736H6V4H8.20755V15.7736ZM10.4151 17.8585V15.7736H8.20755V17.9811H10.4151V20.066H12.6226V17.9811H14.8302V15.7736H12.6226V17.8585H10.4151ZM16.7925 13.566H14.5849V4H16.7925V13.566ZM16.7925 13.566H19V15.7736H16.7925V13.566Z"
fill="white"
/>
</svg>
);
};
@@ -1,18 +0,0 @@
export const IconGlobe = ({ size = 24 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M11.9946 3C10.2165 3.00106 8.47842 3.52883 6.99987 4.51677C5.51983 5.5057 4.36628 6.91131 3.68509 8.55585C3.0039 10.2004 2.82567 12.01 3.17294 13.7558C3.5202 15.5016 4.37737 17.1053 5.63604 18.364C6.89471 19.6226 8.49836 20.4798 10.2442 20.8271C11.99 21.1743 13.7996 20.9961 15.4442 20.3149C17.0887 19.6337 18.4943 18.4802 19.4832 17.0001C20.4722 15.5201 21 13.78 21 12C21 9.61305 20.0518 7.32386 18.364 5.63604C16.6761 3.94821 14.3869 3 12 3C12.0001 3 11.9999 3 12 3M11.9959 3.936C11.9972 3.936 11.9985 3.936 11.9999 3.936C13.2976 3.93617 14.3772 5.83592 14.9515 8.22998H9.04712C9.62068 5.83664 10.6991 3.93971 11.9959 3.936ZM9.8073 4.24157C9.05208 5.16925 8.44481 6.56185 8.07534 8.22998H4.87438C5.24741 7.52551 5.72602 6.87397 6.3 6.3C7.28288 5.31711 8.49319 4.61388 9.8073 4.24157ZM4.42885 9.22998C4.10667 10.1091 3.93685 11.0458 3.936 12C3.936 12.9499 4.10378 13.8872 4.42669 14.77H7.88922C7.75324 13.8973 7.67969 12.9663 7.67969 12C7.67969 11.0336 7.7527 10.1027 7.8879 9.22998H4.42885ZM4.87153 15.77C5.00006 16.013 5.14133 16.2501 5.29503 16.4801C6.18112 17.8062 7.44054 18.8398 8.91404 19.4502C9.20977 19.5727 9.51146 19.677 9.81744 19.763C9.06048 18.8354 8.44956 17.4409 8.07765 15.77H4.87153ZM14.1834 19.7628C15.5101 19.3896 16.7227 18.6815 17.7021 17.7021C18.2744 17.1298 18.7541 16.4778 19.1285 15.77H15.9224C15.5508 17.4416 14.9402 18.8355 14.1834 19.7628ZM19.5733 14.77C19.7153 14.3819 19.8278 13.9819 19.9091 13.5732C20.1981 12.12 20.0808 10.6174 19.5733 9.22998H16.1106C16.2463 10.1024 16.3197 11.0333 16.3197 12C16.3197 12.9667 16.2463 13.8976 16.1106 14.77H19.5733ZM19.1285 8.22998C18.5047 7.05058 17.596 6.04063 16.4801 5.29503C15.7711 4.82129 14.9955 4.46564 14.1834 4.23723C14.9402 5.16453 15.5508 6.55844 15.9224 8.22998H19.1285ZM8.60129 12C8.60129 11.0806 8.68603 10.1352 8.84194 9.22998H15.1569C15.3132 10.1358 15.3981 11.0814 15.3981 12C15.3981 12.9186 15.314 13.8642 15.1588 14.77H8.84003C8.68519 13.8648 8.60129 12.9194 8.60129 12ZM11.9997 20.064C10.6916 20.064 9.61486 18.1657 9.04394 15.77H14.9547C14.3836 18.1642 13.3072 20.064 11.9997 20.064Z"
fill="white"
/>
</svg>
);
};
@@ -1,16 +0,0 @@
export const IconLinkedIn = ({ size = 24 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21 4.32353V19.6765C21 20.0275 20.8606 20.3641 20.6123 20.6123C20.3641 20.8606 20.0275 21 19.6765 21H4.32353C3.97251 21 3.63586 20.8606 3.38765 20.6123C3.13944 20.3641 3 20.0275 3 19.6765V4.32353C3 3.97251 3.13944 3.63586 3.38765 3.38765C3.63586 3.13944 3.97251 3 4.32353 3H19.6765C20.0275 3 20.3641 3.13944 20.6123 3.38765C20.8606 3.63586 21 3.97251 21 4.32353V4.32353ZM8.29412 9.88235H5.64706V18.3529H8.29412V9.88235ZM8.53235 6.97059C8.53375 6.77036 8.49569 6.57182 8.42035 6.3863C8.34502 6.20078 8.23387 6.03191 8.09328 5.88935C7.95268 5.74678 7.78537 5.6333 7.60091 5.5554C7.41646 5.47749 7.21846 5.43668 7.01824 5.43529H6.97059C6.5634 5.43529 6.1729 5.59705 5.88497 5.88497C5.59705 6.1729 5.43529 6.5634 5.43529 6.97059C5.43529 7.37777 5.59705 7.76828 5.88497 8.05621C6.1729 8.34413 6.5634 8.50588 6.97059 8.50588V8.50588C7.17083 8.51081 7.37008 8.47623 7.55696 8.40413C7.74383 8.33202 7.91467 8.2238 8.0597 8.08565C8.20474 7.94749 8.32113 7.78212 8.40223 7.59897C8.48333 7.41582 8.52755 7.21848 8.53235 7.01824V6.97059ZM18.3529 13.2071C18.3529 10.6606 16.7329 9.67059 15.1235 9.67059C14.5966 9.6442 14.0719 9.75644 13.6019 9.9961C13.1318 10.2358 12.7328 10.5945 12.4447 11.0365H12.3706V9.88235H9.88235V18.3529H12.5294V13.8476C12.4911 13.3862 12.6365 12.9283 12.9339 12.5735C13.2313 12.2186 13.6567 11.9954 14.1176 11.9524H14.2182C15.06 11.9524 15.6847 12.4818 15.6847 13.8159V18.3529H18.3318L18.3529 13.2071Z"
fill="white"
/>
</svg>
);
};
@@ -1,23 +0,0 @@
export const IconMoon = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96C6.34 6.48 6.43 6.06 6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z"
fill="white"
/>
<circle cx="8" cy="8" r="7" fill="white" />
<path
d="M6.15393 5.69232C6.15393 5.10304 6.24054 4.5075 6.46161 4C4.99179 4.63982 4 6.14089 4 7.84607C4 10.1402 5.85982 12 8.15393 12C9.85911 12 11.3602 11.0082 12 9.53839C11.4925 9.75946 10.8964 9.84607 10.3077 9.84607C8.01357 9.84607 6.15393 7.98643 6.15393 5.69232Z"
fill="black"
/>
</svg>
);
};
@@ -1,16 +0,0 @@
export const IconOpenExternal = ({ size = 24 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.9605 4.28998H3.76002V3.22998H12.77V12.24H11.71V5.03952L4.13479 12.6148L3.38525 11.8652L10.9605 4.28998Z"
fill="white"
/>
</svg>
);
};
@@ -1,18 +0,0 @@
export const IconQuestionMark = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M8 1C4.13 1 1 4.13 1 8C1 11.87 4.13 15 8 15C11.87 15 15 11.87 15 8C15 4.13 11.87 1 8 1ZM8.66 12.44H7.32V11.1H8.66V12.44ZM10.38 6.78C10.29 7.01 10.18 7.2 10.05 7.36C9.92 7.52 9.75 7.7 9.53 7.91C9.3 8.14 9.11 8.34 8.98 8.51C8.85 8.68 8.73 8.89 8.64 9.14C8.55 9.37 8.51 9.65 8.51 9.96V10.04V10.13H7.3V10.04C7.3 9.61 7.36 9.24 7.47 8.92C7.58 8.61 7.71 8.34 7.87 8.13C8.03 7.92 8.22 7.69 8.47 7.43C8.75 7.13 8.96 6.87 9.09 6.66C9.22 6.46 9.28 6.2 9.28 5.88C9.28 5.47 9.16 5.16 8.93 4.93C8.7 4.7 8.38 4.58 7.96 4.58C7.6 4.58 7.28 4.68 7.01 4.89C6.75 5.09 6.56 5.44 6.45 5.96L6.43 6.06L5.26 5.62L5.28 5.54C5.47 4.87 5.81 4.35 6.29 4.02C6.77 3.69 7.34 3.53 8 3.53C8.75 3.53 9.37 3.75 9.82 4.18C10.28 4.62 10.5 5.22 10.5 5.97C10.5 6.27 10.46 6.53 10.37 6.76L10.38 6.78Z"
fill="white"
/>
</svg>
);
};
@@ -1,20 +0,0 @@
export const IconTransfer = ({ size = 16 }: { size: number }) => {
return (
<svg
width={size}
height={size}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.27952 5.90477L5.37476 8L4.62522 8.74953L1.25046 5.37477L4.62522 2L5.37476 2.74953L3.27952 4.84477L9 4.84477L9 5.90477L3.27952 5.90477Z"
fill="white"
/>
<path
d="M12.7205 10.0952L10.6252 8L11.3748 7.25047L14.7495 10.6252L11.3748 14L10.6252 13.2505L12.7205 11.1552L7 11.1552L7 10.0952L12.7205 10.0952Z"
fill="white"
/>
</svg>
);
};

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