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

This commit is contained in:
madalinaraicu 2022-07-08 16:39:51 +03:00
commit c178ba831a
144 changed files with 3007 additions and 338 deletions

View File

@ -2,9 +2,21 @@
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nrwl/nx", "eslint-plugin-unicorn", "jsx-a11y", "jest"],
"settings": {
"jsx-a11y": {
"components": {
"Button": "button",
"Input": "input",
"Select": "select",
"Radio": "radio",
"TextArea": "textarea"
}
}
},
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"extends": ["plugin:jsx-a11y/strict"],
"rules": {
"@nrwl/nx/enforce-module-boundaries": [
"error",

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
/tmp
/out-tsc
/tools/executors/**/*.js
/tools/utils/*.js
# dependencies
/node_modules

View File

@ -11,6 +11,7 @@ NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=0
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -11,6 +11,7 @@ NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -11,6 +11,7 @@ NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -11,6 +11,7 @@ NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -11,6 +11,7 @@ NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -14,6 +14,7 @@ module.exports = defineConfig({
modifyObstructiveCode: false,
supportFile: './src/support/index.ts',
video: true,
videoUploadOnPasses: false,
videosFolder: '../../dist/cypress/apps/explorer-e2e/videos',
screenshotsFolder: '../../dist/cypress/apps/explorer-e2e/screenshots',
chromeWebSecurity: false,

View File

@ -29,8 +29,10 @@ Feature: Blocks Page
Then previous button is disabled
And I am on the second block when I click next
Scenario: Infinite scroll shows at least 300 new blocks
Given I am on the homepage
When I navigate to the blocks page
And I scroll down to the last block on the page
Then I can expect to see at least 100 blocks if i scroll 7 times
# Skipping these tests for time being - since blockchain in capsule
# is now too small to show historical data - re-enable once addressed
# Scenario: Infinite scroll shows at least 300 new blocks
# Given I am on the homepage
# When I navigate to the blocks page
# And I scroll down to the last block on the page
# Then I can expect to see at least 100 blocks if i scroll 7 times

View File

@ -57,7 +57,7 @@ export default class HomePage extends BasePage {
.should('match', /\d+d \d+h \d+m \d+s/i);
cy.getByTestId(this.statsValue).eq(4).should('have.text', '2');
cy.getByTestId(this.statsValue).eq(5).should('have.text', '0');
cy.getByTestId(this.statsValue).eq(6).should('have.text', '0.00');
cy.getByTestId(this.statsValue).eq(6).should('not.be.empty');
cy.getByTestId(this.statsValue).eq(7).should('have.text', '0');
cy.getByTestId(this.statsValue).eq(8).should('have.text', '0');
cy.getByTestId(this.statsValue).eq(9).should('have.text', '0');

View File

@ -13,6 +13,7 @@ NX_VEGA_ENV=TESTNET
NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
CYPRESS_VEGA_TENDERMINT_URL=https://lb.testnet.vega.xyz/tm
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
# App flags
NX_EXPLORER_ASSETS=1
@ -22,3 +23,4 @@ NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1

View File

@ -6,12 +6,14 @@ NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=CUSTOM
NX_VEGA_REST=http://localhost:3029
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
# App flags
NX_EXPLORER_ASSETS=1
NX_EXPLORER_GENESIS=1
NX_EXPLORER_GOVERNANCE=1
NX_EXPLORER_MARKETS=1
NX_EXPLORER_TXS_LIST=1
NX_EXPLORER_NETWORK_PARAMETERS=1
NX_EXPLORER_PARTIES=1
NX_EXPLORER_VALIDATORS=1

View File

@ -7,3 +7,4 @@ NX_VEGA_URL=https://n04.d.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=DEVNET
NX_VEGA_REST=https://n04.d.vega.xyz/datanode/rest
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -7,3 +7,4 @@ NX_VEGA_URL=https://api.token.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=MAINNET
NX_VEGA_REST=https://api.token.vega.xyz/
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -7,3 +7,4 @@ NX_VEGA_URL=https://n03.s.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=STAGNET
NX_VEGA_REST=https://n03.s.vega.xyz/datanode/rest
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -7,3 +7,4 @@ NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=STAGNET2
NX_VEGA_REST=https://n01.stagnet2.vega.xyz/datanode/rest
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -7,3 +7,4 @@ NX_VEGA_URL=https://lb.testnet.vega.xyz/query
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=TESTNET
NX_VEGA_REST=https://lb.testnet.vega.xyz/datanode/rest
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -5,3 +5,4 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket
NX_VEGA_URL=http://localhost:3003/query
NX_VEGA_ENV=CUSTOM
NX_VEGA_REST=http://localhost:3029/rest
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -58,6 +58,7 @@ There are a few different configuration options offered for this app:
| `NX_EXPLORER_GENESIS` | Enable the genesis page for the explorer |
| `NX_EXPLORER_GOVERNANCE` | Enable the governance page for the explorer |
| `NX_EXPLORER_MARKETS` | Enable the markets page for the explorer |
| `NX_EXPLORER_TXS_LIST` | Enable the transactions list page for the explorer |
| `NX_EXPLORER_NETWORK_PARAMETERS` | Enable the network parameters page for the explorer |
| `NX_EXPLORER_PARTIES` | Enable the parties page for the explorer |
| `NX_EXPLORER_VALIDATORS` | Enable the validators page for the explorer |

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -38,7 +38,7 @@
}
},
"serve": {
"executor": "./tools/executors/serve:serve",
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3000,
"buildTarget": "explorer:build",

View File

@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
import { NetworkInfo } from '@vegaprotocol/network-info';
import { createClient } from './lib/apollo-client';
import { Nav } from './components/nav';
import { Header } from './components/header';
@ -36,6 +37,9 @@ function App() {
/>
<Nav menuOpen={menuOpen} />
<Main />
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
<NetworkInfo />
</footer>
</div>
</div>
</NetworkLoader>

View File

@ -55,14 +55,18 @@ export const Search = () => {
onSubmit={handleSubmit(onSubmit)}
className="flex-1 flex self-center md:ml-16 md:mr-12 md:justify-end"
>
<FormGroup className="relative w-full md:w-2/3 mb-0">
<FormGroup
label={t('Search by block number or transaction hash')}
className="relative w-full md:w-2/3 mb-0"
labelClassName="sr-only"
labelFor="search"
>
<Input
{...register('search')}
id="search"
data-testid="search"
hasError={Boolean(error?.message)}
type="text"
autoFocus={true}
placeholder={t('Enter block number or transaction hash')}
/>
{error?.message && (

View File

@ -1,4 +1,4 @@
import { Lozenge } from '@vegaprotocol/ui-toolkit';
import { Lozenge, Intent } from '@vegaprotocol/ui-toolkit';
interface TxOrderTypeProps {
orderType: string;
@ -36,7 +36,7 @@ const displayString: StringMap = {
export const TxOrderType = ({ orderType, className }: TxOrderTypeProps) => {
return (
<Lozenge data-testid="tx-type" className={className}>
<Lozenge data-testid="tx-type" variant={Intent.None} className={className}>
{displayString[orderType] || orderType}
</Lozenge>
);

View File

@ -24,6 +24,7 @@ export const ENV = {
genesis: truthy.includes(windowOrDefault('NX_EXPLORER_GENESIS')),
governance: truthy.includes(windowOrDefault('NX_EXPLORER_GOVERNANCE')),
markets: truthy.includes(windowOrDefault('NX_EXPLORER_MARKETS')),
txsList: truthy.includes(windowOrDefault('NX_EXPLORER_TXS_LIST')),
networkParameters: truthy.includes(
windowOrDefault('NX_EXPLORER_NETWORK_PARAMETERS')
),

View File

@ -101,7 +101,9 @@ const PROPOSAL_QUERY = gql`
`;
const Governance = () => {
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY);
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY, {
errorPolicy: 'ignore',
});
if (!data) return null;
return (

View File

@ -12,7 +12,7 @@ import Genesis from './genesis';
import { Block } from './blocks/id';
import { Blocks } from './blocks/home';
import { Tx } from './txs/id';
import { TxsHome } from './txs/home';
import { TxsHome, TxsHomeFallback } from './txs/home';
import { PendingTxs } from './pending';
import flags from '../config/flags';
import { t } from '@vegaprotocol/react-helpers';
@ -129,7 +129,7 @@ const routerConfig = [
},
{
index: true,
element: <TxsHome />,
element: flags.txsList ? <TxsHome /> : <TxsHomeFallback />,
},
],
},

View File

@ -94,7 +94,7 @@ const Txs = ({ latestBlockHeight }: TxsProps) => {
);
};
const Wrapper = () => {
export const TxsHome = () => {
const {
state: { data, error, loading },
} = useFetch<TendermintBlockchainResponse>(
@ -119,4 +119,12 @@ const Wrapper = () => {
);
};
export { Wrapper as TxsHome };
export const TxsHomeFallback = () => (
<>
<RouteTitle>{t('Transactions')}</RouteTitle>
<div>
The transactions list is currently disabled. Please use the search bar to
discover transaction data
</div>
</>
);

View File

@ -1,5 +1,13 @@
const { execSync } = require('child_process');
const webpack = require('webpack');
const SentryPlugin = require('@sentry/webpack-plugin');
const gitCommitHash = execSync('git rev-parse HEAD').toString();
const gitOriginUrl = execSync('git remote get-url origin')
.toString()
.replace('ssh://git@github.com', 'https://github.com')
.replace('.git', '');
module.exports = (config, context) => {
const additionalPlugins = process.env.SENTRY_AUTH_TOKEN
? [
@ -9,8 +17,16 @@ module.exports = (config, context) => {
}),
]
: [];
return {
...config,
plugins: [...additionalPlugins, ...config.plugins],
plugins: [
...additionalPlugins,
...config.plugins,
new webpack.DefinePlugin({
'process.env.GIT_COMMIT_HASH': JSON.stringify(gitCommitHash),
'process.env.GIT_ORIGIN_URL': JSON.stringify(gitOriginUrl),
}),
],
};
};

View File

@ -11,6 +11,7 @@ module.exports = defineConfig({
modifyObstructiveCode: false,
supportFile: './src/support/index.ts',
video: true,
videoUploadOnPasses: false,
videosFolder: '../../dist/cypress/apps/explorer-e2e/videos',
screenshotsFolder: '../../dist/cypress/apps/explorer-e2e/screenshots',
chromeWebSecurity: false,

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -41,7 +41,7 @@
}
},
"serve": {
"executor": "./tools/executors/serve:serve",
"executor": "./tools/executors/webpack:serve",
"options": {
"buildTarget": "simple-trading-app:build",
"hmr": true,

View File

@ -5,7 +5,7 @@
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -36,7 +36,7 @@
}
},
"serve": {
"executor": "./tools/executors/serve:serve",
"executor": "./tools/executors/webpack:serve",
"options": {
"buildTarget": "static:build"
},

View File

@ -1,4 +1,37 @@
[
{
"tranche_id": 37,
"tranche_start": "2023-12-01T00:00:00.000Z",
"tranche_end": "2024-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "2500",
"deposits": [
{
"amount": "2500",
"user": "0xc704dA0E96a6b910fFA8d3F9f667d3D35Db8e5a1",
"tx": "0x52de6a9bdedecca430f91808db432cc519c329df4b7a9a1db507bd31edf10ad6"
}
],
"withdrawals": [],
"users": [
{
"address": "0xc704dA0E96a6b910fFA8d3F9f667d3D35Db8e5a1",
"deposits": [
{
"amount": "2500",
"user": "0xc704dA0E96a6b910fFA8d3F9f667d3D35Db8e5a1",
"tranche_id": 37,
"tx": "0x52de6a9bdedecca430f91808db432cc519c329df4b7a9a1db507bd31edf10ad6"
}
],
"withdrawals": [],
"total_tokens": "2500",
"withdrawn_tokens": "0",
"remaining_tokens": "2500"
}
]
},
{
"tranche_id": 34,
"tranche_start": "2023-02-01T00:00:00.000Z",
@ -38,7 +71,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "122585.322768986336032725",
"locked_amount": "122051.500007201064430095",
"deposits": [
{
"amount": "129999.45",
@ -488,7 +521,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "97499.58",
"total_removed": "0",
"locked_amount": "63466.983919940002696632",
"locked_amount": "62943.353518468237579518",
"deposits": [
{
"amount": "97499.58",
@ -521,7 +554,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "135173.4239508",
"total_removed": "0",
"locked_amount": "86748.40990088964062830135308",
"locked_amount": "86032.69754309525024747938908",
"deposits": [
{
"amount": "135173.4239508",
@ -554,7 +587,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "32499.86",
"total_removed": "0",
"locked_amount": "26699.464118930582798084",
"locked_amount": "26479.18185164477572846",
"deposits": [
{
"amount": "32499.86",
@ -587,7 +620,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "10833.29",
"total_removed": "0",
"locked_amount": "8690.416485244757134352",
"locked_amount": "8618.716744811751483477",
"deposits": [
{
"amount": "10833.29",
@ -675,7 +708,7 @@
"tranche_end": "2022-11-01T00:00:00.000Z",
"total_added": "22500",
"total_removed": "0",
"locked_amount": "14398.34550498188325",
"locked_amount": "14123.175668025363",
"deposits": [
{
"amount": "15000",
@ -761,7 +794,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "179856.049568108351",
"locked_amount": "1757875.242625193454140144",
"locked_amount": "1745915.303655345556320574",
"deposits": [
{
"amount": "1852091.69",
@ -1813,7 +1846,7 @@
"tranche_end": "2022-09-30T00:00:00.000Z",
"total_added": "60916.66666633337",
"total_removed": "18705.279504739679372649",
"locked_amount": "13393.305449139288622183147351979",
"locked_amount": "13041.8197535096809291252176374005",
"deposits": [
{
"amount": "2833.333333",
@ -5316,10 +5349,70 @@
"tranche_id": 11,
"tranche_start": "2021-09-03T00:00:00.000Z",
"tranche_end": "2022-09-03T00:00:00.000Z",
"total_added": "20311.000000000000000003",
"total_removed": "5187.51372516574",
"locked_amount": "3269.03986380644276156048284769786910188",
"total_added": "21040.000000000000000003",
"total_removed": "6039.91545614122",
"locked_amount": "3256.65721207508885200046435226407914765",
"deposits": [
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x7f4243c2e337e448bec7c49f8656ec1d87781237b2df6b3c4228d5f4ef21bcae"
},
{
"amount": "10",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x527be17fb3396931abcec7a6b30250f06eccab059ede56cc793dd734e6d3c4ef"
},
{
"amount": "170",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x3875ef8d470421a8db3633b0154869cb1794352d5e94f6998db66733268bd421"
},
{
"amount": "50",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x26ebd4910da507af08a8f4ea8b879dd3cb3b67035919cdf2d94c3ce2666723f9"
},
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x4234389e5bc893bc09ba2539b89208617d15df677c0be9f06e153a7a62a061d5"
},
{
"amount": "30",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0xe95e59638f95070ac53e7db28c6486b48b40c3c21b0212f3ac2ca547d6d552b7"
},
{
"amount": "10",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0xa29c049a7d0d737c3597f1785ef2106d636e564e098fd2a0ab5aae92d9659b3c"
},
{
"amount": "250",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x8155e4bc1ca185b9b9a5b12878f623c1e6d86f7de2f77df433fd86d2db66323b"
},
{
"amount": "35",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0xcad6d0d747c8fd93ef4bdd4d04710650d8bb6da325ad8fcbd57e902bb68dae6e"
},
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0xb5a1cd57ed96be442c76d5ff25938b8f42f337a27410d7c5fc2648e99bfb2cca"
},
{
"amount": "5",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tx": "0x0684f1765543cce5bf5c79fe51963ec4efc121a7778c151e0f8f940a406d0a6e"
},
{
"amount": "25",
"user": "0xd996efF75E43357F04E3f37D61EF6A6851A0b8f1",
"tx": "0x9a86b9e8e9eba0855044551013ae752b8e5f328c1a077d437ad4652cb25e5013"
},
{
"amount": "75",
"user": "0x3a380f7CFdEeb723228cA57d2795EA215094000d",
@ -5460,6 +5553,41 @@
"user": "0x38249D7DcC4eF7dFCa6579C069ADd3a1a4E4DeA3",
"tx": "0xc7927d740f3b981514edfc783b8ced6d45cbce92a3512a165125f08becb0c22e"
},
{
"amount": "12",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0x0a36e69fa542ca075481e08073f159ea7bea4f2c73ef9b52d22d4614db19a5a0"
},
{
"amount": "2",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0x8ab01cde20c499bea4d28c208749cfc8139ac1bbae7b65f3fb77a903e2af1ace"
},
{
"amount": "5",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0x600702eb08091f59365fdf6af580b0e60c81600ae57a8fc3ad7473d67cc738dd"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0xfd7edebf2b9d7359188e31fde4d44674bfa8fc119d7f9c71e673b80dc3913899"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0xd055543cf69ebdb0d8862fd917723705853caa63e97e6dfa942419e707bff520"
},
{
"amount": "20",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0x15da44cda1d0e1d31e82e3cf7f39080b5f61eca6fa870af430c48ceb73ae3dc3"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tx": "0x99b34aa5c033c78b690dbe9262a3e621bc7643f60cafffeeafcc6a8885fabd74"
},
{
"amount": "30",
"user": "0xb4eE687f019A8e48F7087f4b4f8653208B8cc48f",
@ -8482,6 +8610,11 @@
}
],
"withdrawals": [
{
"amount": "842.29689345648",
"user": "0xab6dE081Af6C78433AFDaC5B756804bcE17e9eC1",
"tx": "0xc4ad1fb4198584a79c2e37158723a7d6fb7c88d164e06cceb8fdb203f88d289b"
},
{
"amount": "4.429693048",
"user": "0xc5467213593778E528f0eB8117cc7AFBC5b7491b",
@ -8507,6 +8640,11 @@
"user": "0xCffAAD68a1a538CADab2b82cC3740E66d4c111A5",
"tx": "0xff6bd3ca9820f14ec8f0bde3fd72515064e958d17a270111002a3d832704a324"
},
{
"amount": "10.104837519",
"user": "0x9c90AeF0030F2681b3C7206bE35BB6698220F419",
"tx": "0xefa8e193221c7115cd57b67cdb03c5d8f7cf6bbaa2e1ca6056812c4a2ecbb08a"
},
{
"amount": "8.25227042",
"user": "0xc5467213593778E528f0eB8117cc7AFBC5b7491b",
@ -8789,6 +8927,96 @@
}
],
"users": [
{
"address": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"deposits": [
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x7f4243c2e337e448bec7c49f8656ec1d87781237b2df6b3c4228d5f4ef21bcae"
},
{
"amount": "10",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x527be17fb3396931abcec7a6b30250f06eccab059ede56cc793dd734e6d3c4ef"
},
{
"amount": "170",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x3875ef8d470421a8db3633b0154869cb1794352d5e94f6998db66733268bd421"
},
{
"amount": "50",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x26ebd4910da507af08a8f4ea8b879dd3cb3b67035919cdf2d94c3ce2666723f9"
},
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x4234389e5bc893bc09ba2539b89208617d15df677c0be9f06e153a7a62a061d5"
},
{
"amount": "30",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0xe95e59638f95070ac53e7db28c6486b48b40c3c21b0212f3ac2ca547d6d552b7"
},
{
"amount": "10",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0xa29c049a7d0d737c3597f1785ef2106d636e564e098fd2a0ab5aae92d9659b3c"
},
{
"amount": "250",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x8155e4bc1ca185b9b9a5b12878f623c1e6d86f7de2f77df433fd86d2db66323b"
},
{
"amount": "35",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0xcad6d0d747c8fd93ef4bdd4d04710650d8bb6da325ad8fcbd57e902bb68dae6e"
},
{
"amount": "25",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0xb5a1cd57ed96be442c76d5ff25938b8f42f337a27410d7c5fc2648e99bfb2cca"
},
{
"amount": "5",
"user": "0x2c51Dc5A225a9d8542FBf28BA9dC501f026CD5e8",
"tranche_id": 11,
"tx": "0x0684f1765543cce5bf5c79fe51963ec4efc121a7778c151e0f8f940a406d0a6e"
}
],
"withdrawals": [],
"total_tokens": "635",
"withdrawn_tokens": "0",
"remaining_tokens": "635"
},
{
"address": "0xd996efF75E43357F04E3f37D61EF6A6851A0b8f1",
"deposits": [
{
"amount": "25",
"user": "0xd996efF75E43357F04E3f37D61EF6A6851A0b8f1",
"tranche_id": 11,
"tx": "0x9a86b9e8e9eba0855044551013ae752b8e5f328c1a077d437ad4652cb25e5013"
}
],
"withdrawals": [],
"total_tokens": "25",
"withdrawn_tokens": "0",
"remaining_tokens": "25"
},
{
"address": "0x3a380f7CFdEeb723228cA57d2795EA215094000d",
"deposits": [
@ -9120,6 +9348,57 @@
"withdrawn_tokens": "0",
"remaining_tokens": "100"
},
{
"address": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"deposits": [
{
"amount": "12",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0x0a36e69fa542ca075481e08073f159ea7bea4f2c73ef9b52d22d4614db19a5a0"
},
{
"amount": "2",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0x8ab01cde20c499bea4d28c208749cfc8139ac1bbae7b65f3fb77a903e2af1ace"
},
{
"amount": "5",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0x600702eb08091f59365fdf6af580b0e60c81600ae57a8fc3ad7473d67cc738dd"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0xfd7edebf2b9d7359188e31fde4d44674bfa8fc119d7f9c71e673b80dc3913899"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0xd055543cf69ebdb0d8862fd917723705853caa63e97e6dfa942419e707bff520"
},
{
"amount": "20",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0x15da44cda1d0e1d31e82e3cf7f39080b5f61eca6fa870af430c48ceb73ae3dc3"
},
{
"amount": "10",
"user": "0xC6D7208DaDEe4F431bd0f3f11E7d4c91fF51bfb2",
"tranche_id": 11,
"tx": "0x99b34aa5c033c78b690dbe9262a3e621bc7643f60cafffeeafcc6a8885fabd74"
}
],
"withdrawals": [],
"total_tokens": "69",
"withdrawn_tokens": "0",
"remaining_tokens": "69"
},
{
"address": "0xb4eE687f019A8e48F7087f4b4f8653208B8cc48f",
"deposits": [
@ -13538,6 +13817,12 @@
}
],
"withdrawals": [
{
"amount": "842.29689345648",
"user": "0xab6dE081Af6C78433AFDaC5B756804bcE17e9eC1",
"tranche_id": 11,
"tx": "0xc4ad1fb4198584a79c2e37158723a7d6fb7c88d164e06cceb8fdb203f88d289b"
},
{
"amount": "230.8527534264",
"user": "0xab6dE081Af6C78433AFDaC5B756804bcE17e9eC1",
@ -13576,8 +13861,8 @@
}
],
"total_tokens": "2544",
"withdrawn_tokens": "1307.56687212912",
"remaining_tokens": "1236.43312787088"
"withdrawn_tokens": "2149.8637655856",
"remaining_tokens": "394.1362344144"
},
{
"address": "0x141fb4F2Bf3248FC128a59F833DEB4c3B96CdFF4",
@ -14208,10 +14493,17 @@
"tx": "0x2b4c60d15417e1d44087d94ddfdc6d722a9a6c894ff97064ecc0a1d4f4ec59c3"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "10.104837519",
"user": "0x9c90AeF0030F2681b3C7206bE35BB6698220F419",
"tranche_id": 11,
"tx": "0xefa8e193221c7115cd57b67cdb03c5d8f7cf6bbaa2e1ca6056812c4a2ecbb08a"
}
],
"total_tokens": "12",
"withdrawn_tokens": "0",
"remaining_tokens": "12"
"withdrawn_tokens": "10.104837519",
"remaining_tokens": "1.895162481"
},
{
"address": "0x3278Db713acBADB0f440B9e04073461736C6ef0F",
@ -14553,7 +14845,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "74162.9780761646031",
"locked_amount": "2725743.54548872311209308307",
"locked_amount": "2707365.28330055324662000057",
"deposits": [
{
"amount": "1998.95815",
@ -15265,8 +15557,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15788853.065470999700000001",
"total_removed": "10571.602079948437875",
"locked_amount": "14888383.3676439542541295821844858607799405",
"total_removed": "11846.799077314937625",
"locked_amount": "14823548.8691223714260814929619235344701271",
"deposits": [
{
"amount": "16249.93",
@ -15760,6 +16052,11 @@
}
],
"withdrawals": [
{
"amount": "325.1056930428465",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x709c3417e526abadea6bdd4c1af135fc511f04fb4df85cf80a112f98ef23a5fc"
},
{
"amount": "579.636872035866225",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@ -15830,6 +16127,16 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x8692ff7431a01cd8498d6107e450f71a768587b19b0305e07d538a86a9dce898"
},
{
"amount": "624.054831504537375",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x1bcde25127285cdc67a22c980491bfe02abacafa90706fc81144d40c5ca39043"
},
{
"amount": "326.036472819115875",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0xfc356f66e594deac2ea8be6083b756407d2b32fd4006a7feece906c6ae8d9e7c"
},
{
"amount": "2446.31552516990115",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@ -15916,6 +16223,12 @@
}
],
"withdrawals": [
{
"amount": "325.1056930428465",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x709c3417e526abadea6bdd4c1af135fc511f04fb4df85cf80a112f98ef23a5fc"
},
{
"amount": "579.636872035866225",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@ -16000,6 +16313,18 @@
"tranche_id": 2,
"tx": "0x8692ff7431a01cd8498d6107e450f71a768587b19b0305e07d538a86a9dce898"
},
{
"amount": "624.054831504537375",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x1bcde25127285cdc67a22c980491bfe02abacafa90706fc81144d40c5ca39043"
},
{
"amount": "326.036472819115875",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0xfc356f66e594deac2ea8be6083b756407d2b32fd4006a7feece906c6ae8d9e7c"
},
{
"amount": "2446.31552516990115",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@ -16044,8 +16369,8 @@
}
],
"total_tokens": "194999.1675",
"withdrawn_tokens": "10571.602079948437875",
"remaining_tokens": "184427.565420051562125"
"withdrawn_tokens": "11846.799077314937625",
"remaining_tokens": "183152.368422685062375"
},
{
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
@ -17449,8 +17774,8 @@
"tranche_start": "2021-11-05T00:00:00.000Z",
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "2161684.128707368749930177",
"locked_amount": "8094146.47209339400785385525522692",
"total_removed": "2164043.091765489107775177",
"locked_amount": "8033983.66345089879139837705469571",
"deposits": [
{
"amount": "129284.449",
@ -17659,6 +17984,11 @@
}
],
"withdrawals": [
{
"amount": "600.79246609513746875",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x508f9b462ad07e1f207b014404f0785b84fbd9f9b4f112487d20ac448e7be516"
},
{
"amount": "509.31853983395369725",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@ -17759,6 +18089,16 @@
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0xee1cf9620cd8bd0586be349f91f00e345ae5a22ec87de8e40e8c897a168bc806"
},
{
"amount": "1157.62173015319971725",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x8a82f2f7a3dcedb71dd7e1eaa91620b9cef38d61ccbc49354fa8d74a1d28ca6c"
},
{
"amount": "600.548861872020659",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x6773808e7319b6c3f390409128cb1746b411e6df76d0e585cdc7f4545ac599c4"
},
{
"amount": "652.48254356494551875",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@ -19335,6 +19675,12 @@
}
],
"withdrawals": [
{
"amount": "600.79246609513746875",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x508f9b462ad07e1f207b014404f0785b84fbd9f9b4f112487d20ac448e7be516"
},
{
"amount": "509.31853983395369725",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@ -19431,6 +19777,18 @@
"tranche_id": 3,
"tx": "0xee1cf9620cd8bd0586be349f91f00e345ae5a22ec87de8e40e8c897a168bc806"
},
{
"amount": "1157.62173015319971725",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x8a82f2f7a3dcedb71dd7e1eaa91620b9cef38d61ccbc49354fa8d74a1d28ca6c"
},
{
"amount": "600.548861872020659",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x6773808e7319b6c3f390409128cb1746b411e6df76d0e585cdc7f4545ac599c4"
},
{
"amount": "652.48254356494551875",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@ -20669,8 +21027,8 @@
}
],
"total_tokens": "359123.469575",
"withdrawn_tokens": "158977.92403827626105775",
"remaining_tokens": "200145.54553672373894225"
"withdrawn_tokens": "161336.88709639661890275",
"remaining_tokens": "197786.58247860338109725"
},
{
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
@ -21684,8 +22042,8 @@
"tranche_start": "2021-10-05T00:00:00.000Z",
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "1421861.163897427556121727",
"locked_amount": "2881142.820574213983175666452500158",
"total_removed": "1539572.873831600560839727",
"locked_amount": "2857372.131017926635740554079679699",
"deposits": [
{
"amount": "552496.6455",
@ -21829,6 +22187,11 @@
}
],
"withdrawals": [
{
"amount": "515.054756304992408",
"user": "0x1b4B2372462b391006FAc69f09066Ae8504D75eC",
"tx": "0x157dbf1b28465a758596604a1ee5874977d3b527d63e430ba1a4e21bb702f7be"
},
{
"amount": "4089.266768653121589",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
@ -21854,6 +22217,11 @@
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
"tx": "0x317c7891b92b541a91b43e1718f70544c7479d7fd75bb16e7af8471a55285825"
},
{
"amount": "117196.65517786801231",
"user": "0x83b1a48376E045D26420200345414e6b93066396",
"tx": "0xa2b3ea509a870fb8601f2eb998e5505d139a5ed1c200ffd82d69d04878ff2c14"
},
{
"amount": "13341.31568777778021",
"user": "0xafa64cCa337eFEE0AD827F6C2684e69275226e90",
@ -22596,6 +22964,12 @@
}
],
"withdrawals": [
{
"amount": "117196.65517786801231",
"user": "0x83b1a48376E045D26420200345414e6b93066396",
"tranche_id": 4,
"tx": "0xa2b3ea509a870fb8601f2eb998e5505d139a5ed1c200ffd82d69d04878ff2c14"
},
{
"amount": "78755.58122733127554",
"user": "0x83b1a48376E045D26420200345414e6b93066396",
@ -22622,8 +22996,8 @@
}
],
"total_tokens": "1104995.291",
"withdrawn_tokens": "437960.90697499656084",
"remaining_tokens": "667034.38402500343916"
"withdrawn_tokens": "555157.56215286457315",
"remaining_tokens": "549837.72884713542685"
},
{
"address": "0x5565d64f29Ea17355106DF3bA5903Eb793B3e139",
@ -22803,6 +23177,12 @@
}
],
"withdrawals": [
{
"amount": "515.054756304992408",
"user": "0x1b4B2372462b391006FAc69f09066Ae8504D75eC",
"tranche_id": 4,
"tx": "0x157dbf1b28465a758596604a1ee5874977d3b527d63e430ba1a4e21bb702f7be"
},
{
"amount": "6461.470999848595628375",
"user": "0x1b4B2372462b391006FAc69f09066Ae8504D75eC",
@ -22811,8 +23191,8 @@
}
],
"total_tokens": "13812.4411375",
"withdrawn_tokens": "6461.470999848595628375",
"remaining_tokens": "7350.970137651404371625"
"withdrawn_tokens": "6976.525756153588036375",
"remaining_tokens": "6835.915381346411963625"
},
{
"address": "0x39fEc2e2beaB6a63c1E763D0dc4120AF60BEe39F",
@ -22851,8 +23231,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "106.36782724",
"locked_amount": "431909.6457970537623418539370878",
"total_removed": "175.452149916",
"locked_amount": "428997.50509871284283704377574836",
"deposits": [
{
"amount": "3000",
@ -29495,6 +29875,16 @@
"amount": "15.684119736",
"user": "0x09996E1a67c371400bD5f52DF841f77B1741eB9d",
"tx": "0x7065fa7c06fea3e88435b0db4d7b68f515491ae128580bcd99e2a0ed18c522c3"
},
{
"amount": "34.361998984",
"user": "0xd2033db9c5370aC76ABD80823b5c5adC097E2FBF",
"tx": "0x70c8e4da3ecd0547daf42a0493a12429e973ded0ae1ae730fe71fe60be654996"
},
{
"amount": "34.722323692",
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
"tx": "0x5de09bdb9cd98c5ca24bff1c625a68bb038613e0041103b4a637528a2eda5d5c"
}
],
"users": [
@ -41200,10 +41590,17 @@
"tx": "0x716a7be06da5a7a3d8038907974887a31805ea8eeab5d130cba528e4d2094d9f"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "34.722323692",
"user": "0x4eD2b3c68BB4fda084ce1591a210F4aC8b71234A",
"tranche_id": 5,
"tx": "0x5de09bdb9cd98c5ca24bff1c625a68bb038613e0041103b4a637528a2eda5d5c"
}
],
"total_tokens": "400",
"withdrawn_tokens": "0",
"remaining_tokens": "400"
"withdrawn_tokens": "34.722323692",
"remaining_tokens": "365.277676308"
},
{
"address": "0x5c90765F50629570738fEe7b7FA82ae118f81Ed1",
@ -44276,10 +44673,17 @@
"tx": "0xd23813c30e93f3867eaa257b7aef7052a050b1ee1c1a90102a3f40c5d989fe82"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "34.361998984",
"user": "0xd2033db9c5370aC76ABD80823b5c5adC097E2FBF",
"tranche_id": 5,
"tx": "0x70c8e4da3ecd0547daf42a0493a12429e973ded0ae1ae730fe71fe60be654996"
}
],
"total_tokens": "400",
"withdrawn_tokens": "0",
"remaining_tokens": "400"
"withdrawn_tokens": "34.361998984",
"remaining_tokens": "365.638001016"
},
{
"address": "0xb4B8A71829E5a0b25569d7F6e70C7cC273AE50A4",
@ -48566,7 +48970,7 @@
"tranche_start": "2021-12-05T00:00:00.000Z",
"tranche_end": "2022-06-05T00:00:00.000Z",
"total_added": "171288.42",
"total_removed": "33118.5750837656377",
"total_removed": "34430.0423647506377",
"locked_amount": "0",
"deposits": [
{
@ -52916,6 +53320,51 @@
"user": "0xaF4d3489bC06762e2A683f00ef1758a1F08bA86e",
"tx": "0xae9c76f61a918176f3d69867131e87ae89d9a89f2218faff802f1ee104b22fea"
},
{
"amount": "100",
"user": "0xd25891CfAF13C9Ca8a102709261Da2fFd0Fb0a1F",
"tx": "0xa683de6c82ee8b3a8e3c4ebce0d9e39b8e6cb3869f7a0a12dabee3742ab8b23e"
},
{
"amount": "100",
"user": "0xEE525a275D1f54C22CCCf1a3314F13C712D7F3a8",
"tx": "0x2c76c34c8f292a704fcd454994f2f0aed24b411a3a447bd31676a25583513f58"
},
{
"amount": "200",
"user": "0x435B4D14fFaC8FCB4c1E2AF8c46Dd074a69766b7",
"tx": "0xa592d9280fc83d773e5f9c409c6d8f20d0605b1b3d8ff936530016ebfdc494af"
},
{
"amount": "89",
"user": "0xeB7A9ab2b001254f9Af59E433BBA04f420D8123C",
"tx": "0xf15500ca615c0b7acaf7810ac1b64ebb3728ba4c692c159419ed1753fbb662d7"
},
{
"amount": "100",
"user": "0x0e80E23fa0ae15A06Ad986792F02625f80955E6E",
"tx": "0x0c76100c6853b09bf7c3c2e50b100ae2a04e440f1c8c3a0958969a215fe4a2f9"
},
{
"amount": "250",
"user": "0xF5037DDA4A660d67560200f45380FF8364e35540",
"tx": "0x51776cd419920f96cb60d199117d01f291de5af3642c5b132049ea18318366e0"
},
{
"amount": "250",
"user": "0xEA4DDC1921a322Dae69458920e9c6A61d0A4f7AA",
"tx": "0xb1117e951379c5665ba083c7d80c17c7f7995a9dfd9a95cb1802e39b18a912cc"
},
{
"amount": "192.467280985",
"user": "0x1F605de6CC5A0593685cff92A4f4f5D46b90A830",
"tx": "0x340877e8841569ebf790f6945f818a034a0c8e16ef97eb5fba0f0aa161b7f9ac"
},
{
"amount": "30",
"user": "0x75AB80d94F9F7C0FE4E7973C8fF505882bE80f97",
"tx": "0x0fa800c60c9490474402a4922fb61ed9e344e7efd05232bf117c67eb53478f6c"
},
{
"amount": "183.6335597275",
"user": "0x690Fc36d52eD3f198F0eBDea1557333a1766f786",
@ -60816,10 +61265,17 @@
"tx": "0x96a22c369645e8945b4047374a05332f4054b50a492c43092e8bb8e974a006b9"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "89",
"user": "0xeB7A9ab2b001254f9Af59E433BBA04f420D8123C",
"tranche_id": 6,
"tx": "0xf15500ca615c0b7acaf7810ac1b64ebb3728ba4c692c159419ed1753fbb662d7"
}
],
"total_tokens": "89",
"withdrawn_tokens": "0",
"remaining_tokens": "89"
"withdrawn_tokens": "89",
"remaining_tokens": "0"
},
{
"address": "0x98Bee53140E3f45CD38aED787588DD95b8198d20",
@ -61204,10 +61660,17 @@
"tx": "0x96a22c369645e8945b4047374a05332f4054b50a492c43092e8bb8e974a006b9"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "100",
"user": "0xEE525a275D1f54C22CCCf1a3314F13C712D7F3a8",
"tranche_id": 6,
"tx": "0x2c76c34c8f292a704fcd454994f2f0aed24b411a3a447bd31676a25583513f58"
}
],
"total_tokens": "100",
"withdrawn_tokens": "0",
"remaining_tokens": "100"
"withdrawn_tokens": "100",
"remaining_tokens": "0"
},
{
"address": "0x0315483c35d2c1EA9d5BE576b0F795Ae8CD0d4DE",
@ -61264,10 +61727,17 @@
"tx": "0x96a22c369645e8945b4047374a05332f4054b50a492c43092e8bb8e974a006b9"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "100",
"user": "0xd25891CfAF13C9Ca8a102709261Da2fFd0Fb0a1F",
"tranche_id": 6,
"tx": "0xa683de6c82ee8b3a8e3c4ebce0d9e39b8e6cb3869f7a0a12dabee3742ab8b23e"
}
],
"total_tokens": "100",
"withdrawn_tokens": "0",
"remaining_tokens": "100"
"withdrawn_tokens": "100",
"remaining_tokens": "0"
},
{
"address": "0x3d119d134Ae02650011b45D75c0f6973430Bf716",
@ -63535,10 +64005,17 @@
"tx": "0x9f916cf09e8a3c4ade0ffce5190db464d0a2b1dadba78e1ee7ba5d6e751d6148"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "100",
"user": "0x0e80E23fa0ae15A06Ad986792F02625f80955E6E",
"tranche_id": 6,
"tx": "0x0c76100c6853b09bf7c3c2e50b100ae2a04e440f1c8c3a0958969a215fe4a2f9"
}
],
"total_tokens": "100",
"withdrawn_tokens": "0",
"remaining_tokens": "100"
"withdrawn_tokens": "100",
"remaining_tokens": "0"
},
{
"address": "0x54B1CF34a20276AF6dbDF5159C35860BAD75652e",
@ -63789,6 +64266,12 @@
}
],
"withdrawals": [
{
"amount": "192.467280985",
"user": "0x1F605de6CC5A0593685cff92A4f4f5D46b90A830",
"tranche_id": 6,
"tx": "0x340877e8841569ebf790f6945f818a034a0c8e16ef97eb5fba0f0aa161b7f9ac"
},
{
"amount": "307.532719015",
"user": "0x1F605de6CC5A0593685cff92A4f4f5D46b90A830",
@ -63797,8 +64280,8 @@
}
],
"total_tokens": "500",
"withdrawn_tokens": "307.532719015",
"remaining_tokens": "192.467280985"
"withdrawn_tokens": "500",
"remaining_tokens": "0"
},
{
"address": "0x207EeAb5F72e3F9e831428eF54dCaDc8B8727c85",
@ -63965,10 +64448,17 @@
"tx": "0xb1425d9b0d5f10c5b06236d6f9d61ebddd21c4027e0f41deb5ec227a1753c715"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "250",
"user": "0xF5037DDA4A660d67560200f45380FF8364e35540",
"tranche_id": 6,
"tx": "0x51776cd419920f96cb60d199117d01f291de5af3642c5b132049ea18318366e0"
}
],
"total_tokens": "250",
"withdrawn_tokens": "0",
"remaining_tokens": "250"
"withdrawn_tokens": "250",
"remaining_tokens": "0"
},
{
"address": "0x4e2b2C4F091f0167770822a706f05C6c51B46E85",
@ -67001,10 +67491,17 @@
"tx": "0xb59405747c8088945a412703637a7b422f3639439ec2ee15e180c0a2a0d71ee4"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "200",
"user": "0x435B4D14fFaC8FCB4c1E2AF8c46Dd074a69766b7",
"tranche_id": 6,
"tx": "0xa592d9280fc83d773e5f9c409c6d8f20d0605b1b3d8ff936530016ebfdc494af"
}
],
"total_tokens": "200",
"withdrawn_tokens": "0",
"remaining_tokens": "200"
"withdrawn_tokens": "200",
"remaining_tokens": "0"
},
{
"address": "0x3DB21955A90F83AafD568ecAf55b7CEe52F88BcE",
@ -67493,10 +67990,17 @@
"tx": "0xe32a466fc780a0fb3fd84a804f622931ebfaf3f428bff0dc6d141270410e75f8"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "250",
"user": "0xEA4DDC1921a322Dae69458920e9c6A61d0A4f7AA",
"tranche_id": 6,
"tx": "0xb1117e951379c5665ba083c7d80c17c7f7995a9dfd9a95cb1802e39b18a912cc"
}
],
"total_tokens": "250",
"withdrawn_tokens": "0",
"remaining_tokens": "250"
"withdrawn_tokens": "250",
"remaining_tokens": "0"
},
{
"address": "0xc3B0121A0e0fe2a814cCdCdA0Ba1065666f79413",
@ -67796,10 +68300,17 @@
"tx": "0xe32a466fc780a0fb3fd84a804f622931ebfaf3f428bff0dc6d141270410e75f8"
}
],
"withdrawals": [],
"withdrawals": [
{
"amount": "30",
"user": "0x75AB80d94F9F7C0FE4E7973C8fF505882bE80f97",
"tranche_id": 6,
"tx": "0x0fa800c60c9490474402a4922fb61ed9e344e7efd05232bf117c67eb53478f6c"
}
],
"total_tokens": "30",
"withdrawn_tokens": "0",
"remaining_tokens": "30"
"withdrawn_tokens": "30",
"remaining_tokens": "0"
},
{
"address": "0xC1fd374ca9DE2437004799136D748dB235c5ECED",

View File

@ -38,7 +38,7 @@
"tranche_end": "2022-11-26T13:48:10.000Z",
"total_added": "100",
"total_removed": "0",
"locked_amount": "39.26620687468291",
"locked_amount": "38.649686073059364",
"deposits": [
{
"amount": "100",
@ -242,7 +242,7 @@
"tranche_end": "2022-10-12T00:53:20.000Z",
"total_added": "1100",
"total_removed": "673.04388635",
"locked_amount": "294.69023021308981",
"locked_amount": "287.908501395230826",
"deposits": [
{
"amount": "1000",

View File

@ -69,7 +69,7 @@
"tranche_end": "2022-10-12T00:53:20.000Z",
"total_added": "1010.000000000000000001",
"total_removed": "668.4622323651",
"locked_amount": "270.5792113774733710002679002092846271",
"locked_amount": "264.3523833079655370002617350329781837",
"deposits": [
{
"amount": "1000",

View File

@ -11,6 +11,7 @@ module.exports = defineConfig({
modifyObstructiveCode: false,
supportFile: './src/support/index.ts',
video: true,
videoUploadOnPasses: false,
videosFolder: '../../dist/cypress/apps/explorer-e2e/videos',
screenshotsFolder: '../../dist/cypress/apps/explorer-e2e/screenshots',
chromeWebSecurity: false,

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -37,7 +37,7 @@
}
},
"serve": {
"executor": "./tools/executors/serve:serve",
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3010,
"buildTarget": "stats:build",

View File

@ -10,8 +10,25 @@ module.exports = defineConfig({
modifyObstructiveCode: false,
supportFile: './src/support/index.ts',
video: true,
videoUploadOnPasses: false,
videosFolder: '../../dist/cypress/apps/explorer-e2e/videos',
screenshotsFolder: '../../dist/cypress/apps/explorer-e2e/screenshots',
chromeWebSecurity: false,
},
env: {
ethProviderUrl: 'http://localhost:8545/',
ethWalletPublicKey: '0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F',
ethStakingBridgeContractAddress:
'0x9135f5afd6F055e731bca2348429482eE614CFfA',
vegaWalletName: 'capsule_wallet',
vegaWalletLocation: '~/.vegacapsule/testnet/wallet',
vegaWalletPassphrase: '123',
vegaWalletMnemonic:
'ozone access unlock valid olympic save include omit supply green clown session',
vegaWalletPublicKey:
'02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65',
vegaWalletPublicKeyShort: '02ecea…2f65',
vegaTokenContractAddress: '0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7',
vegaTokenAddress: '0x67175Da1D5e966e40D11c4B2519392B2058373de',
},
});

View File

@ -1,4 +0,0 @@
{
"tokenAddress": "0x67175Da1D5e966e40D11c4B2519392B2058373de",
"vestingContract": "0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7"
}

View File

@ -0,0 +1 @@
123

View File

@ -0,0 +1 @@
ozone access unlock valid olympic save include omit supply green clown session

View File

@ -0,0 +1,338 @@
/// <reference types="cypress" />
import navigation from '../../locators/navigation.locators';
import staking from '../../locators/staking.locators';
import wallet from '../../locators/wallet.locators';
import '../../support/staking.functions';
import '../../support/vega-wallet.functions';
import '../../support/eth-wallet.functions';
import '../../support/wallet-teardown.functions';
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
context('Staking Tab - with eth and vega wallets connected', function () {
before('visit staking tab and connect vega wallet', function () {
cy.vega_wallet_import();
cy.visit('/');
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
cy.vega_wallet_connect();
cy.vega_wallet_set_specified_approval_amount('1000');
cy.reload();
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
cy.ethereum_wallet_connect();
cy.get(navigation.staking).first().click();
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
cy.get(staking.validatorNames).first().invoke('text').as('validatorName');
cy.get(staking.validatorNames)
.last()
.invoke('text')
.as('otherValidatorName');
});
describe('Eth wallet - contains VEGA tokens', function () {
beforeEach(
'teardown wallet & drill into a specific validator',
function () {
cy.vega_wallet_teardown();
cy.get(navigation.staking).first().click();
}
);
it('Able to stake against a validator', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.ethereum_wallet_check_associated_value_is('3.0');
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'3.000000000000000000'
);
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
cy.staking_validator_page_check_stake_this_epoch_value('2.0');
});
it('Able to stake against mulitple validators', function () {
cy.staking_page_associate_tokens('5');
cy.vega_wallet_check_unstaked_value_is('5.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.get(navigation.staking).first().click();
cy.get(staking.validatorNames).contains(this.otherValidatorName).click();
cy.staking_validator_page_add_stake('1');
cy.vega_wallet_check_validator_staked_value_is(
this.otherValidatorName,
'1.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
});
it.skip('Able to remove part of a stake against a validator', function () {
cy.staking_page_associate_tokens('4');
cy.vega_wallet_check_unstaked_value_is('4.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('3');
cy.staking_validator_page_check_stake_next_epoch_value('3.0');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'3.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.get(navigation.staking).first().click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_removeStake('1');
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
cy.staking_validator_page_check_stake_this_epoch_value('3.0');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.vega_wallet_check_validator_stake_this_epoch_value_is(
this.validatorName,
'3.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
cy.staking_validator_page_check_stake_this_epoch_value('2.0');
});
it('Able to remove a full stake against a validator', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('1');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'1.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
cy.get(navigation.staking).first().click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_removeStake('1');
cy.staking_validator_page_check_stake_next_epoch_value('0.0');
cy.vega_wallet_check_validator_stake_this_epoch_value_is(
this.validatorName,
'1.000000000000000000'
);
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'0.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.staking_validator_page_check_stake_next_epoch_value('0.0');
cy.staking_validator_page_check_stake_this_epoch_value('0.0');
cy.vega_wallet_check_validator_no_longer_showing(this.validatorName);
});
it.skip('Unable to remove a stake with a negative value for a validator', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.get(navigation.staking).first().click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.get(staking.removeStakeRadioButton).click({ force: true });
cy.get(staking.tokenAmountInput).type('-0.1');
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
cy.get(staking.tokenInputSubmit)
.should('be.disabled', { timeout: 8000 })
.and('contain', `Remove -0.1 $VEGA tokens at the end of epoch`)
.and('be.visible');
});
it.skip('Unable to remove a stake greater than staked amount next epoch for a validator', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.get(navigation.staking).first().click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.get(staking.removeStakeRadioButton).click({ force: true });
cy.get(staking.tokenAmountInput).type(4);
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
cy.get(staking.tokenInputSubmit)
.should('be.disabled', { timeout: 8000 })
.and('contain', `Remove 4 $VEGA tokens at the end of epoch`)
.and('be.visible');
});
it.skip('Disassociating all tokens - removes all staked tokens', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.get(navigation.staking).first().click();
cy.staking_page_disassociate_all_tokens();
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing(
vegaWalletPublicKeyShort
);
cy.ethereum_wallet_check_associated_value_is('0.0');
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
cy.vega_wallet_check_validator_no_longer_showing(this.validatorName);
});
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
cy.staking_page_associate_tokens('3');
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.get(staking.validatorNames).contains(this.validatorName).click();
cy.staking_validator_page_add_stake('2');
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
cy.get(navigation.staking).first().click();
cy.staking_page_disassociate_tokens('1');
cy.ethereum_wallet_check_associated_value_is('2.0');
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
cy.vega_wallet_check_validator_staked_value_is(
this.validatorName,
'2.000000000000000000'
);
});
after(
'teardown wallet so state/results dont bleed into other test suites',
function () {
cy.vega_wallet_teardown();
}
);
});
cy.staking_validator_page_check_stake_next_epoch_value = (expectedVal) => {
cy.highlight(
`Checking Staking Page - Validator Stake Next Epoch Value is ${expectedVal}`
);
cy.get(staking.stakeNextEpochValue, { timeout: 10000 })
.contains(expectedVal, { timeout: 10000 })
.should('be.visible');
};
cy.staking_validator_page_check_stake_this_epoch_value = (expectedVal) => {
cy.highlight(
`Checking Staking Page - Validator Stake This Epoch Value is ${expectedVal}`
);
cy.get(staking.stakeThisEpochValue, { timeout: 10000 })
.contains(expectedVal, { timeout: 10000 })
.should('be.visible');
};
cy.vega_wallet_check_validator_stake_next_epoch_value_is = (
validatorName,
expectedVal
) => {
cy.highlight(
`Checking vega wallet - Stake Next Epoch Value for ${validatorName} is ${expectedVal}`
);
cy.get(wallet.vegawallet).within(() => {
cy.contains(`${validatorName} (Next epoch)`, { timeout: 40000 })
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
cy.vega_wallet_check_validator_stake_this_epoch_value_is = (
validatorName,
expectedVal
) => {
cy.highlight(
`Checking vega wallet - Stake This Epoch Value for ${validatorName} is ${expectedVal}`
);
cy.get(wallet.vegawallet).within(() => {
cy.contains(`${validatorName} (This Epoch)`, { timeout: 40000 })
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
cy.vega_wallet_check_validator_no_longer_showing = (validatorName) => {
cy.highlight(
`Checking Validator and therefore stake removed for ${validatorName}`
);
cy.get(wallet.vegawallet).within(() => {
cy.contains(`${validatorName}`, { timeout: 40000 }).should('not.exist', {
timeout: 40000,
});
});
};
cy.vega_wallet_check_validator_staked_value_is = (
validatorName,
expectedVal
) => {
cy.highlight(
`Checking Validator Stake Value for ${validatorName} is ${expectedVal}`
);
cy.get(wallet.vegawallet).within(() => {
cy.contains(`${validatorName}`, { timeout: 40000 })
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
});

View File

@ -0,0 +1,118 @@
/// <reference types="cypress" />
import navigation from '../../locators/navigation.locators';
import staking from '../../locators/staking.locators';
import wallet from '../../locators/wallet.locators';
import '../../support/staking.functions';
import '../../support/vega-wallet.functions';
import '../../support/eth-wallet.functions';
import '../../support/wallet-teardown.functions';
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
context('Staking Tab - with eth and vega wallets connected', function () {
before('visit staking tab and connect vega wallet', function () {
cy.vega_wallet_import();
cy.visit('/');
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
cy.vega_wallet_connect();
cy.vega_wallet_set_specified_approval_amount('1000');
cy.reload();
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
cy.ethereum_wallet_connect();
cy.get(navigation.staking).first().click();
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
cy.get(staking.validatorNames).first().invoke('text').as('validatorName');
});
describe('Eth wallet - contains VEGA tokens', function () {
beforeEach(
'teardown wallet & drill into a specific validator',
function () {
cy.vega_wallet_teardown();
cy.get(navigation.staking).first().click();
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
}
);
it('Able to associate tokens - from staking page', function () {
cy.staking_page_associate_tokens('2');
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'2.000000000000000000'
);
cy.ethereum_wallet_check_associated_value_is('2.0');
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
});
it('Able to disassociate tokens - from staking page', function () {
cy.staking_page_associate_tokens('2');
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'2.000000000000000000'
);
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.staking_page_disassociate_tokens('1');
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'1.000000000000000000'
);
cy.ethereum_wallet_check_associated_value_is('1.0');
cy.vega_wallet_check_associated_value_is('1.000000000000000000');
});
it('Able to access associate token form - from eth wallet', function () {
cy.get(wallet.ethWallet).within(() =>
cy.get(wallet.ethWalletAssociate).click()
);
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).should(
'be.enabled'
);
});
it('Able to access disassociate token form - from eth wallet', function () {
cy.get(wallet.ethWallet).within(() =>
cy.get(wallet.ethWalletDisassociate).click()
);
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).should(
'be.enabled'
);
});
it('Able to associate more tokens than the approved amount of 1000 - requires re-approval', function () {
cy.staking_page_associate_tokens('1001', true);
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'1,001.000000000000000000'
);
cy.ethereum_wallet_check_associated_value_is('1,001.00');
cy.vega_wallet_check_associated_value_is('1,001.000000000000000000');
});
it('Able to disassociate a partial amount of tokens currently associated', function () {
cy.staking_page_associate_tokens('2');
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.staking_page_disassociate_tokens('1');
cy.ethereum_wallet_check_associated_vega_key_value_is(
vegaWalletPublicKeyShort,
'1.000000000000000000'
);
cy.ethereum_wallet_check_associated_value_is('1.0');
cy.vega_wallet_check_associated_value_is('1.000000000000000000');
});
it('Able to disassociate all tokens', function () {
cy.staking_page_associate_tokens('2');
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
cy.get('button').contains('Select a validator to nominate').click();
cy.staking_page_disassociate_all_tokens();
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing(
vegaWalletPublicKeyShort
);
cy.ethereum_wallet_check_associated_value_is('0.0');
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
});
});
});

View File

@ -1,6 +1,8 @@
import navigation from '../locators/navigation.locators';
import home from '../locators/home.locators';
import vegaToken from '../data/vegaToken.json';
const vegaTokenAddress = Cypress.env('vegaTokenAddress');
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
context('Home Page - verify elements on page', function () {
before('visit token home page', function () {
@ -51,7 +53,7 @@ context('Home Page - verify elements on page', function () {
cy.get(home.address)
.should('be.visible')
.invoke('text')
.should('be.equal', vegaToken.tokenAddress);
.should('be.equal', vegaTokenAddress);
});
});
it('should have VESTING CONTRACT', function () {
@ -59,7 +61,7 @@ context('Home Page - verify elements on page', function () {
cy.get(home.contract)
.should('be.visible')
.invoke('text')
.should('be.equal', vegaToken.vestingContract);
.should('be.equal', vegaTokenContractAddress);
});
});
it('should have TOTAL SUPPLY', function () {

View File

@ -1,4 +1,7 @@
import common from './common.locators';
export default {
...common,
section: 'nav',
home: '[href="/"]',
vesting: '[href="/vesting"]',
@ -6,4 +9,5 @@ export default {
rewards: '[href="/rewards"]',
withdraw: '[href="/withdraw"]',
governance: '[href="/governance"]',
spinner: 'splash-loader',
};

View File

@ -7,4 +7,20 @@ export default {
step2: '[data-testid="staking-step-2"]',
step3: '[data-testid="staking-step-3"]',
connectToEthBtn: '[data-testid="connect-to-eth-btn"]',
connectToVegaBtn: '[data-testid="connect-to-vega-wallet-btn"]',
validatorNames: '[data-testid="node-list-item-name"]',
epochEndingText: '[data-testid="epoch-countdown"]',
addStakeRadioButton: '[data-testid="add-stake-radio"]',
removeStakeRadioButton: '[data-testid="remove-stake-radio"]',
tokenAmountInput: '[data-testid="token-amount-input"]',
tokenInputApprove: '[data-testid="token-input-approve-button"]',
tokenInputSubmit: '[data-testid="token-input-submit-button"]',
stakedAmounts: '[data-testid="staked-validator-item"]',
stakeNextEpochValue: '[data-testid="stake-next-epoch"]',
stakeThisEpochValue: '[data-testid="stake-this-epoch"]',
stakeMaximumTokens: '[data-testid="token-amount-use-maximum"]',
stakeAssociateWalletRadio: '[data-testid="associate-radio-wallet"]',
disassociateButton: '[data-testid="disassociate-tokens-btn"]',
associateMoreTokensButton: '[data-testid="associate-more-tokens-btn"]',
associateButton: '[data-testid="associate-tokens-btn"]',
};

View File

@ -0,0 +1,14 @@
import common from './common.locators';
export default {
...common,
connectRestForm: '[data-testid="rest-connector-form"]',
name: '#wallet',
passphrase: '#passphrase',
vegawallet: '[data-testid="vega-wallet"]',
ethWallet: '[data-testid="ethereum-wallet"]',
ethWalletConnectToEth: '[data-testid="connect-to-eth-wallet-button"]',
ethWalletConnect: '[data-testid="web3-connector-Unknown"]',
ethWalletAssociate: '[href="/staking/associate"]',
ethWalletDisassociate: '[href="/staking/disassociate"]',
};

View File

@ -0,0 +1,51 @@
import wallet from '../locators/wallet.locators';
cy.ethereum_wallet_connect = () => {
cy.highlight('Connecting Eth Wallet');
cy.get(wallet.ethWalletConnectToEth).within(() => {
cy.contains('Connect Ethereum wallet to associate $VEGA')
.should('be.visible')
.click();
});
cy.get(wallet.ethWalletConnect).click();
cy.get(wallet.ethWalletConnect, { timeout: 60000 }).should('not.exist');
cy.get(wallet.ethWallet).within(() => {
// this check is required since it ensures the wallet is fully (not partially) loaded
cy.contains('Locked', { timeout: 15000 }).should('be.visible');
});
};
cy.ethereum_wallet_check_associated_value_is = (expectedVal) => {
cy.highlight(`Checking Eth Wallet - Associated Value is ${expectedVal}`);
cy.get(wallet.ethWallet).within(() => {
cy.contains('Associated', { timeout: 20000 })
.parent()
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
cy.ethereum_wallet_check_associated_vega_key_value_is = (
vegaShortPublicKey,
expectedVal
) => {
cy.highlight(
`Checking Eth Wallet - Vega Key Associated Value is ${expectedVal} for key ${vegaShortPublicKey}`
);
cy.get(wallet.ethWallet).within(() => {
cy.contains(vegaShortPublicKey, { timeout: 20000 })
.parent()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing = (
vegaShortPublicKey
) => {
cy.highlight('Checking Eth Wallet - Vega Key Associated is not showing');
cy.get(wallet.ethWallet).within(() => {
cy.contains(vegaShortPublicKey, { timeout: 20000 }).should('not.exist');
});
};

2
apps/token-e2e/src/support/index.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
// type definitions for Cypress object "cy"
/// <reference types="cypress" />

View File

@ -1 +1,11 @@
import '@vegaprotocol/cypress';
// Hide fetch/XHR requests - They create a lot of noise in command log
const app = window.top;
if (!app.document.head.querySelector('[data-hide-command-log-request]')) {
const style = app.document.createElement('style');
style.innerHTML =
'.command-name-request, .command-name-xhr { display: none }';
style.setAttribute('data-hide-command-log-request', '');
app.document.head.appendChild(style);
}

View File

@ -0,0 +1,81 @@
import staking from '../locators/staking.locators';
cy.staking_validator_page_add_stake = (stake) => {
cy.highlight(`Adding a stake of ${stake}`);
cy.get(staking.addStakeRadioButton).click({ force: true });
cy.get(staking.tokenAmountInput).type(stake);
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
cy.get(staking.tokenInputSubmit, { timeout: 8000 })
.should('be.enabled')
.and('contain', `Add ${stake} $VEGA tokens`)
.and('be.visible')
.click();
cy.contains(
'At the beginning of the next epoch your $VEGA will be nominated to the validator',
{ timeout: 20000 }
).should('be.visible');
};
cy.staking_validator_page_removeStake = (stake) => {
cy.highlight(`Removing a stake of ${stake}`);
cy.get(staking.removeStakeRadioButton).click({ force: true });
cy.get(staking.tokenAmountInput).type(stake);
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
cy.get(staking.tokenInputSubmit)
.should('be.enabled', { timeout: 8000 })
.and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`)
.and('be.visible')
.click();
cy.contains(`${stake} $VEGA has been removed from validator`).should(
'be.visible'
);
};
cy.staking_page_associate_tokens = (amount, approve = false) => {
cy.highlight(`Associating ${amount} tokens`);
cy.get(staking.associateButton).click();
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).click();
cy.get(staking.tokenAmountInput, { timeout: 10000 }).type(amount);
if (approve) {
cy.get(staking.tokenInputApprove, { timeout: 40000 })
.should('be.enabled')
.click();
cy.contains('Approve $VEGA Tokens for staking on Vega').should(
'be.visible'
);
cy.contains('Approve $VEGA Tokens for staking on Vega', {
timeout: 40000,
}).should('not.exist');
}
cy.get(staking.tokenInputSubmit, { timeout: 40000 })
.should('be.enabled')
.click();
cy.contains('can now participate in governance and nominate a validator', {
timeout: 60000,
}).should('be.visible');
};
cy.staking_page_disassociate_tokens = (amount) => {
cy.highlight(`Disassociating ${amount} tokens via Staking Page`);
cy.get(staking.disassociateButton).click();
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).click();
cy.get(staking.tokenAmountInput, { timeout: 10000 }).type(amount);
cy.get(staking.tokenInputSubmit, { timeout: 40000 })
.should('be.enabled')
.click();
cy.contains(`${amount} $VEGA tokens have been returned to Ethereum wallet`, {
timeout: 60000,
}).should('be.visible');
};
cy.staking_page_disassociate_all_tokens = () => {
cy.highlight(`Disassociating all tokens via Staking Page`);
cy.get(staking.disassociateButton).click();
cy.get(staking.stakeAssociateWalletRadio, { timeout: 20000 }).click();
cy.get(staking.stakeMaximumTokens, { timeout: 60000 }).click();
cy.get(staking.tokenInputSubmit, { timeout: 10000 }).click();
cy.contains('$VEGA tokens have been returned to Ethereum wallet', {
timeout: 60000,
}).should('be.visible');
};

View File

@ -0,0 +1,56 @@
import wallet from '../locators/wallet.locators';
const vegaWalletName = Cypress.env('vegaWalletName');
const vegaWalletLocation = Cypress.env('vegaWalletLocation');
const vegaWalletPassphrase = Cypress.env('vegaWalletPassphrase');
cy.vega_wallet_import = () => {
cy.highlight(`Importing Vega Wallet ${vegaWalletName}`);
cy.exec(`vegawallet init -f --home ${vegaWalletLocation}`);
cy.exec(
`vegawallet import -w ${vegaWalletName} --recovery-phrase-file ./src/fixtures/wallet/recovery -p ./src/fixtures/wallet/passphrase --home ~/.vegacapsule/testnet/wallet`,
{ failOnNonZeroExit: false }
);
cy.exec(
`vegawallet service run --network DV --automatic-consent --home ${vegaWalletLocation}`
);
};
cy.vega_wallet_connect = () => {
cy.highlight('Connecting Vega Wallet');
cy.get(wallet.vegawallet).within(() => {
cy.get('button')
.contains('Connect Vega wallet to use associated $VEGA')
.should('be.enabled')
.and('be.visible')
.click({ force: true });
});
cy.get('button').contains('rest provider').click();
cy.get(wallet.connectRestForm).within(() => {
cy.get(wallet.name).click().type(vegaWalletName);
cy.get(wallet.passphrase).click().type(vegaWalletPassphrase);
cy.get('button').contains('Connect').click();
});
cy.contains(`${vegaWalletName} key`, { timeout: 20000 }).should('be.visible');
};
cy.vega_wallet_check_unstaked_value_is = (expectedVal) => {
cy.highlight(`Checking vega wallet - Unstaked Value is ${expectedVal}`);
cy.get(wallet.vegawallet).within(() => {
cy.contains('Unstaked', { timeout: 40000 })
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};
cy.vega_wallet_check_associated_value_is = (expectedVal) => {
cy.highlight(`Checking vega wallet - Associated Value is ${expectedVal}`);
cy.get(wallet.vegawallet).within(() => {
cy.contains('Associated', { timeout: 40000 })
.parent()
.siblings()
.contains(expectedVal, { timeout: 40000 })
.should('be.visible');
});
};

View File

@ -0,0 +1,106 @@
import {
StakingBridge,
Token,
TokenVesting,
} from '@vegaprotocol/smart-contracts';
import { ethers, Wallet } from 'ethers';
const vegaWalletMnemonic = Cypress.env('vegaWalletMnemonic');
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
const vegaTokenAddress = Cypress.env('vegaTokenAddress');
const ethWalletPubKey = Cypress.env('ethWalletPublicKey');
const ethStakingBridgeContractAddress = Cypress.env(
'ethStakingBridgeContractAddress'
);
const ethProviderUrl = Cypress.env('ethProviderUrl');
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
const transactionTimeout = '50000';
before('Vega wallet teardown prep', function () {
cy.wrap(new ethers.providers.JsonRpcProvider({ url: ethProviderUrl }), {
log: false,
}).as('provider');
cy.wrap(Wallet.fromMnemonic(vegaWalletMnemonic, getAccount(0)).privateKey, {
log: false,
}).then((privateKey) => {
cy.wrap(new Wallet(privateKey, this.provider), { log: false }).as('signer');
});
cy.get('@signer', { log: false }).then((signer) => {
cy.wrap(new StakingBridge(ethStakingBridgeContractAddress, signer), {
log: false,
}).as('stakingBridgeContract');
cy.wrap(new TokenVesting(vegaTokenContractAddress, signer), {
log: false,
}).as('vestingContract');
});
});
Cypress.Commands.add('vega_wallet_teardown', function () {
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
cy.vega_wallet_teardown_vesting(this.vestingContract);
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
});
Cypress.Commands.add(
'vega_wallet_set_specified_approval_amount',
function (resetAmount) {
cy.highlight(`Setting token approval amount to ${resetAmount}`);
cy.wrap(new Token(vegaTokenAddress, this.signer), { log: false }).then(
(token) => {
cy.wrap(
token.approve(
ethStakingBridgeContractAddress,
resetAmount.concat('000000000000000000')
),
{ timeout: transactionTimeout, log: false }
).then((tx) => {
cy.wait_for_transaction(tx);
});
}
);
}
);
cy.vega_wallet_teardown_staking = (stakingBridgeContract) => {
cy.highlight('Tearing down staking tokens from vega wallet if present');
cy.wrap(
stakingBridgeContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey),
{
timeout: transactionTimeout,
log: false,
}
).then((stake_amount) => {
if (String(stake_amount) != '0') {
cy.wrap(
stakingBridgeContract.removeStake(stake_amount, vegaWalletPubKey),
{ timeout: transactionTimeout, log: false }
).then((tx) => {
cy.wait_for_transaction(tx);
});
}
});
};
cy.vega_wallet_teardown_vesting = (vestingContract) => {
cy.highlight('Tearing down vesting tokens from vega wallet if present');
cy.wrap(vestingContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey), {
timeout: transactionTimeout,
log: false,
}).then((vesting_amount) => {
if (String(vesting_amount) != '0') {
cy.wrap(vestingContract.removeStake(vesting_amount, vegaWalletPubKey), {
timeout: transactionTimeout,
log: false,
}).then((tx) => {
cy.wait_for_transaction(tx);
});
}
});
};
cy.wait_for_transaction = (tx) => {
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
};

View File

@ -7,6 +7,7 @@ NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_FAIRGROUND=false
NX_IS_NEW_BRIDGE_CONTRACT=true
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
#Test configuration variables
CYPRESS_FAIRGROUND=false

View File

@ -5,6 +5,7 @@ NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_FAIRGROUND=false
NX_IS_NEW_BRIDGE_CONTRACT=true
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_REST=http://localhost:3029

View File

@ -5,3 +5,4 @@ NX_VEGA_URL=https://n04.d.vega.xyz/query
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -5,3 +5,4 @@ NX_VEGA_URL=https://api.token.vega.xyz/query
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -5,3 +5,4 @@ NX_VEGA_URL=https://n03.s.vega.xyz/query
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -5,3 +5,4 @@ NX_VEGA_URL=https://n03.stagnet2.vega.xyz/query
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -5,3 +5,4 @@ NX_VEGA_URL=https://lb.testnet.vega.xyz/query
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET":"https://dev.token.vega.xyz","STAGNET2":"staging2.token.vega.xyz","TESTNET":"token.fairground.wtf","MAINNET":"token.vega.xyz"}'
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/web:webpack",
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -38,7 +38,7 @@
}
},
"serve": {
"executor": "./tools/executors/serve:serve",
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 4210,
"buildTarget": "token:build",

View File

@ -4,7 +4,7 @@ import React, { useMemo } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { AppLoader } from './app-loader';
import { AppBanner } from './components/app-banner';
import { AppFooter } from './components/app-footer';
import { NetworkInfo } from '@vegaprotocol/network-info';
import { BalanceManager } from './components/balance-manager';
import { EthWallet } from './components/eth-wallet';
import { TemplateSidebar } from './components/page-templates/template-sidebar';
@ -54,7 +54,9 @@ const AppContainer = () => {
<TemplateSidebar sidebar={sideBar}>
<AppRouter />
</TemplateSidebar>
<AppFooter />
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
<NetworkInfo />
</footer>
</div>
<VegaWalletDialogs />
<TransactionModal />

View File

@ -1,28 +0,0 @@
import { Link } from '@vegaprotocol/ui-toolkit';
import { Trans } from 'react-i18next';
import { Links } from '../../config';
import { ENV } from '../../config/env';
export const AppFooter = () => {
return (
<footer className="p-12 text-ui">
<p>Version: {ENV.commit || 'development'}</p>
<p>
<Trans
i18nKey="footerLinksText"
components={{
/* eslint-disable */
feedbackLink: (
<Link className="text-white underline" href={Links.FEEDBACK} />
),
githubLink: (
<Link className="text-white underline" href={Links.GITHUB} />
),
/* eslint-enable */
}}
/>
</p>
</footer>
);
};

View File

@ -1 +0,0 @@
export * from './app-footer';

View File

@ -196,59 +196,62 @@ export const EthWallet = () => {
return (
<WalletCard dark={true}>
<WalletCardHeader>
<h1 className="m-0">{t('ethereumKey')}</h1>
{account && (
<div className="place-self-end font-mono px-4 pb-2">
<div className="font-mono">{truncateMiddle(account)}</div>
{pendingTxs && (
<div>
<button
className="flex items-center gap-4 p-4 border whitespace-nowrap"
data-testid="pending-transactions-btn"
onClick={() =>
appDispatch({
type: AppStateActionType.SET_TRANSACTION_OVERLAY,
isOpen: true,
})
}
>
<Loader size="small" forceTheme="dark" />
{t('pendingTransactions')}
</button>
</div>
)}
</div>
)}
</WalletCardHeader>
<WalletCardContent>
{account ? (
<ConnectedKey />
) : (
<Button
variant={'secondary'}
onClick={() =>
appDispatch({
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
isOpen: true,
})
}
data-test-id="connect-to-eth-wallet-button"
>
{t('connectEthWalletToAssociate')}
</Button>
)}
{account && (
<WalletCardActions>
<button
className="mt-4 underline"
onClick={() => connector.deactivate()}
<section data-testid="ethereum-wallet">
<WalletCardHeader>
<h1 className="text-h3 uppercase">{t('ethereumKey')}</h1>
{account && (
<div className="px-4 text-right">
<div className="font-mono">{truncateMiddle(account)}</div>
{pendingTxs && (
<div>
<button
className="flex items-center gap-4 p-4 border whitespace-nowrap"
data-testid="pending-transactions-btn"
onClick={() =>
appDispatch({
type: AppStateActionType.SET_TRANSACTION_OVERLAY,
isOpen: true,
})
}
>
<Loader size="small" forceTheme="dark" />
{t('pendingTransactions')}
</button>
</div>
)}
</div>
)}
</WalletCardHeader>
<WalletCardContent>
{account ? (
<ConnectedKey />
) : (
<Button
variant={'secondary'}
className="w-full px-28 border h-28"
onClick={() =>
appDispatch({
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
isOpen: true,
})
}
data-testid="connect-to-eth-wallet-button"
>
{t('disconnect')}
</button>
</WalletCardActions>
)}
</WalletCardContent>
{t('connectEthWalletToAssociate')}
</Button>
)}
{account && (
<WalletCardActions>
<button
className="mt-4 underline"
onClick={() => connector.deactivate()}
>
{t('disconnect')}
</button>
</WalletCardActions>
)}
</WalletCardContent>
</section>
</WalletCard>
);
};

View File

@ -6,6 +6,7 @@ import {
FormGroup,
Lozenge,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -49,7 +50,10 @@ export const AmountInput = ({
min={0}
step="any"
appendElement={
<Lozenge className="text-[10px] relative top-[-2px]">
<Lozenge
variant={Intent.None}
className="text-[10px] relative top-[-2px]"
>
{currency}
</Lozenge>
}
@ -171,7 +175,11 @@ export const TokenInput = ({
return (
<>
<FormGroup label="" labelFor={inputName}>
<FormGroup
labelClassName="sr-only"
label={t('Input Amount')}
labelFor={inputName}
>
<AmountInput
amount={amount}
setAmount={setAmount}

View File

@ -37,7 +37,7 @@ export const VegaWallet = () => {
);
return (
<section className="vega-wallet">
<section className="vega-wallet" data-testid="vega-wallet">
<WalletCard dark={true}>
<WalletCardHeader dark={true}>
<h1 className="col-start-1 m-0">{t('vegaWallet')}</h1>

View File

@ -545,5 +545,9 @@
"proposalTerms": "Proposal terms",
"currentlySetTo": "Currently set to ",
"pass": "Pass",
"fail": "Fail"
"fail": "Fail",
"rankingScore": "Ranking score",
"stakeScore": "Stake score",
"performanceScore": "Performance score",
"votingPower": "Voting score"
}

View File

@ -42,6 +42,7 @@ const Contracts = () => {
<Link
title={t('View address on Etherscan')}
href={`${ETHERSCAN_URL}/address/${contract.address}`}
target="_blank"
>
{contract.address}
</Link>
@ -57,6 +58,7 @@ const Contracts = () => {
<Link
title={t('View address on Etherscan')}
href={`${ETHERSCAN_URL}/address/${value}`}
target="_blank"
>
{value}
</Link>

View File

@ -50,6 +50,7 @@ export const TokenDetails = ({
title={t('View on Etherscan (opens in a new tab)')}
className="font-mono text-white text-right"
href={`${ETHERSCAN_URL}/address/${token.address}`}
target="_blank"
>
{token.address}
</Link>
@ -61,6 +62,7 @@ export const TokenDetails = ({
title={t('View on Etherscan (opens in a new tab)')}
className="font-mono text-white text-right"
href={`${ETHERSCAN_URL}/address/${config.token_vesting_contract.address}`}
target="_blank"
>
{config.token_vesting_contract.address}
</Link>

View File

@ -25,6 +25,26 @@ export interface Nodes_nodes_epochData {
online: number;
}
export interface Nodes_nodes_rankingScore {
__typename: "RankingScore";
/**
* The ranking score of the validator
*/
rankingScore: string;
/**
* The stake based score of the validator (no anti-whaling)
*/
stakeScore: string;
/**
* The performance score of the validator
*/
performanceScore: string;
/**
* The tendermint voting power of the validator (uint32)
*/
votingPower: string;
}
export interface Nodes_nodes {
__typename: "Node";
/**
@ -66,6 +86,10 @@ export interface Nodes_nodes {
pendingStakeFormatted: string;
epochData: Nodes_nodes_epochData | null;
status: NodeStatus;
/**
* Ranking scores and status for the validator for the current epoch
*/
rankingScore: Nodes_nodes_rankingScore;
}
export interface Nodes_nodeData {

View File

@ -100,6 +100,26 @@ export interface Staking_nodes_epochData {
online: number;
}
export interface Staking_nodes_rankingScore {
__typename: "RankingScore";
/**
* The ranking score of the validator
*/
rankingScore: string;
/**
* The stake based score of the validator (no anti-whaling)
*/
stakeScore: string;
/**
* The performance score of the validator
*/
performanceScore: string;
/**
* The tendermint voting power of the validator (uint32)
*/
votingPower: string;
}
export interface Staking_nodes {
__typename: "Node";
/**
@ -145,6 +165,10 @@ export interface Staking_nodes {
pendingStakeFormatted: string;
epochData: Staking_nodes_epochData | null;
status: NodeStatus;
/**
* Ranking scores and status for the validator for the current epoch
*/
rankingScore: Staking_nodes_rankingScore;
}
export interface Staking_nodeData {

View File

@ -0,0 +1,204 @@
import { render, screen, waitFor, within } from '@testing-library/react';
import { NodeList, NODES_QUERY } from './node-list';
import { MockedProvider } from '@apollo/client/testing';
import { MemoryRouter } from 'react-router-dom';
import { addDecimal } from '@vegaprotocol/react-helpers';
import type { Nodes_nodes } from './__generated__/Nodes';
jest.mock('../../components/epoch-countdown', () => ({
EpochCountdown: () => <div data-testid="epoch-info"></div>,
}));
const nodeFactory = (overrides?: Partial<Nodes_nodes>) => ({
id: 'ccc022b7e63a4d0a6d3a193c3940c88574060e58a184964c994998d86835a1b4',
name: 'Skynet',
pubkey: '6abc23391a9f888ab240415bf63d6844b03fc360be822f4a1d2cd832d87b2917',
infoUrl: 'https://en.wikipedia.org/wiki/Skynet_(Terminator)',
location: '',
stakedByOperator: '3000000000000000000000',
stakedByDelegates: '11182454495731682635157',
stakedTotal: '14182454495731682635157',
pendingStake: '0',
stakedByOperatorFormatted: addDecimal(
overrides?.stakedByOperator || '3000000000000000000000',
18
),
stakedByDelegatesFormatted: addDecimal(
overrides?.stakedByDelegates || '11182454495731682635157',
18
),
stakedTotalFormatted: addDecimal(
overrides?.stakedTotal || '14182454495731682635157',
18
),
pendingStakeFormatted: addDecimal(overrides?.pendingStake || '0', 18),
epochData: null,
status: 'Validator',
rankingScore: {
rankingScore: '0.67845061012234727427532760837568',
stakeScore: '0.3392701644525644',
performanceScore: '0.9998677767864936',
votingPower: '2407',
__typename: 'RankingScore',
},
__typename: 'Node',
...overrides,
});
const MOCK_NODES = {
nodes: [
nodeFactory(),
nodeFactory({
id: '966438c6bffac737cfb08173ffcb3f393c4692b099ad80cb45a82e2dc0a8cf99',
name: 'T-800 Terminator',
pubkey:
'ccc3b8362c25b09d20df8ea407b0a476d6b24a0e72bc063d0033c8841652ddd4',
infoUrl: 'https://en.wikipedia.org/wiki/Terminator_(character)',
stakedByOperator: '3000000000000000000000',
stakedByDelegates: '6618711883996159534058',
stakedTotal: '9618711883996159534058',
rankingScore: {
rankingScore: '0.4601942440481428',
stakeScore: '0.2300971220240714',
performanceScore: '1',
votingPower: '2408',
__typename: 'RankingScore',
},
}),
nodeFactory({
id: '12c81b738e8051152e1afe44376ec37bca9216466e6d44cdd772194bad0ada81',
name: 'NCC-1701-E',
pubkey:
'0931a8fd8cc935458f470e435a05414387cea6f329d648be894fcd44bd517a2b',
infoUrl: 'https://en.wikipedia.org/wiki/USS_Enterprise_(NCC-1701-E)',
stakedByOperator: '3000000000000000000000',
stakedByDelegates: '1041343338923442976709',
stakedTotal: '4041343338923442976709',
pendingStake: '0',
rankingScore: {
rankingScore: '0.1932810100133910357676209647912',
stakeScore: '0.0966762995515676',
performanceScore: '0.999629748500531',
votingPower: '1163',
__typename: 'RankingScore',
},
}),
],
nodeData: {
stakedTotal: '27842509718651285145924',
stakedTotalFormatted: addDecimal('27842509718651285145924', 18),
totalNodes: 3,
inactiveNodes: 0,
validatingNodes: 3,
uptime: 1560.266845703125,
__typename: 'NodeData',
},
};
const renderNodeList = () => {
return render(
<MemoryRouter>
<MockedProvider
mocks={[
{
request: { query: NODES_QUERY },
result: { data: MOCK_NODES },
},
]}
>
<NodeList
epoch={{
__typename: 'Epoch',
id: '1',
timestamps: {
__typename: 'EpochTimestamps',
start: new Date(0).toISOString(),
end: '',
expiry: new Date(1000 * 60 * 60 * 24).toISOString(),
},
}}
party={{
__typename: 'Party',
id: 'foo',
delegations: [
{
__typename: 'Delegation',
amount: '0',
amountFormatted: '0',
epoch: 1,
node: {
__typename: 'Node',
id: 'bar',
},
},
],
stake: {
__typename: 'PartyStake',
currentStakeAvailable: '0',
currentStakeAvailableFormatted: '0',
},
}}
/>
</MockedProvider>
</MemoryRouter>
);
};
beforeAll(() => {
jest.useFakeTimers();
jest.setSystemTime(0);
});
afterAll(() => {
jest.useRealTimers();
});
describe('Nodes list', () => {
it('should render epoch info', async () => {
renderNodeList();
await waitFor(() => {
expect(screen.getByText(MOCK_NODES.nodes[0].name)).toBeInTheDocument();
});
expect(screen.getByTestId('epoch-info')).toBeInTheDocument();
});
it('should a lit of all nodes', async () => {
renderNodeList();
await waitFor(() => {
expect(screen.getByText(MOCK_NODES.nodes[0].name)).toBeInTheDocument();
});
const items = screen.queryAllByTestId('node-list-item');
expect(items).toHaveLength(3);
for (const item of MOCK_NODES.nodes) {
expect(screen.getByText(item.name)).toBeInTheDocument();
}
});
it('should list the total stake and rewards of each node', async () => {
renderNodeList();
await waitFor(() => {
expect(screen.getByText(MOCK_NODES.nodes[0].name)).toBeInTheDocument();
});
const items = screen.queryAllByTestId('node-list-item');
const item = within(items[0]);
const rows = item.getAllByRole('row');
const expectedValues = [
['Total stake', '14,182.45 (50.94%)'],
['Ranking score', '0.6785'],
['Stake score', '0.3393'],
['Performance score', '0.9999'],
['Voting score', '2,407.0000'],
];
for (const [i, r] of rows.entries()) {
const row = within(r);
const cell = row.getByRole('cell');
const header = row.getByRole('rowheader');
expect(header).toHaveTextContent(expectedValues[i][0]);
expect(cell).toHaveTextContent(expectedValues[i][1]);
}
});
});

View File

@ -8,7 +8,7 @@ import { EpochCountdown } from '../../components/epoch-countdown';
import { BigNumber } from '../../lib/bignumber';
import { formatNumber } from '../../lib/format-number';
import { truncateMiddle } from '../../lib/truncate-middle';
import type { Nodes } from './__generated__/Nodes';
import type { Nodes, Nodes_nodes_rankingScore } from './__generated__/Nodes';
import type { Staking_epoch, Staking_party } from './__generated__/Staking';
export const NODES_QUERY = gql`
@ -33,6 +33,13 @@ export const NODES_QUERY = gql`
online
}
status
rankingScore {
rankingScore
stakeScore
performanceScore
votingPower
stakeScore
}
}
nodeData {
stakedTotal
@ -54,7 +61,10 @@ const NodeListTr = ({ children }: { children: React.ReactNode }) => (
);
const NodeListTh = ({ children }: { children: React.ReactNode }) => (
<th className="flex-1 break-words py-1 pr-4 pl-0 text-white-60 font-normal">
<th
role="rowheader"
className="flex-1 break-words py-1 pr-4 pl-0 text-white-60 font-normal"
>
{children}
</th>
);
@ -113,6 +123,7 @@ export const NodeList = ({ epoch, party }: NodeListProps) => {
userStake,
userStakePercentage,
epoch,
scores: node.rankingScore,
};
});
@ -160,6 +171,7 @@ export interface NodeListItemProps {
stakedTotalPercentage: string;
userStake: BigNumber;
userStakePercentage: string;
scores: Nodes_nodes_rankingScore;
}
export const NodeListItem = ({
@ -169,6 +181,7 @@ export const NodeListItem = ({
stakedTotalPercentage,
userStake,
userStakePercentage,
scores,
}: NodeListItemProps) => {
const { t } = useTranslation();
@ -186,24 +199,36 @@ export const NodeListItem = ({
<span
className="uppercase text-white-60"
title={`${t('id')}: ${id}`}
data-testid="node-list-item-name"
>
{truncateMiddle(id)}
</span>
</>
)}
</Link>
<table className="flex-1 text-body border-collapse mt-4">
<table
className="flex-1 text-body border-collapse mt-4"
data-testid="node-list-item-table"
>
<tbody>
<NodeListTr>
<NodeListTh>{t('Total stake')}</NodeListTh>
<NodeListTd>{formatNumber(stakedOnNode, 2)}</NodeListTd>
<NodeListTd>{stakedTotalPercentage}</NodeListTd>
</NodeListTr>
<NodeListTr>
<NodeListTh>{t('Your stake')}</NodeListTh>
<NodeListTd>{formatNumber(userStake, 2)}</NodeListTd>
<NodeListTd>{userStakePercentage}</NodeListTd>
<NodeListTd>
{formatNumber(stakedOnNode, 2)} ({stakedTotalPercentage})
</NodeListTd>
</NodeListTr>
{scores
? Object.entries(scores)
.filter(([key]) => key !== '__typename')
.map(([key, value]) => (
<NodeListTr key={`${id}_${key}`}>
<NodeListTh>{t(key)}</NodeListTh>
<NodeListTd>
{formatNumber(new BigNumber(value), 4)}
</NodeListTd>
</NodeListTr>
))
: null}
</tbody>
</table>
</li>

View File

@ -224,8 +224,13 @@ export const StakingForm = ({
return (
<>
<h2>{t('Manage your stake')}</h2>
<FormGroup>
<FormGroup
label={t('Select if you want to add or remove stake')}
labelFor="radio-stake-options"
labelClassName="sr-only"
>
<RadioGroup
name="radio-stake-options"
onChange={(value) => {
// @ts-ignore value does exist on target
setAction(value);

View File

@ -53,6 +53,13 @@ export const STAKING_QUERY = gql`
online
}
status
rankingScore {
rankingScore
stakeScore
performanceScore
votingPower
stakeScore
}
}
nodeData {
stakedTotal

View File

@ -22,6 +22,7 @@ module.exports = defineConfig({
supportFile: './src/support/index.ts',
video: true,
videosFolder: '../../dist/cypress/apps/trading-e2e/videos',
videoUploadOnPasses: false,
screenshotsFolder: '../../dist/cypress/apps/trading-e2e/screenshots',
chromeWebSecurity: false,
projectId: 'et4snf',

View File

@ -34,7 +34,10 @@ describe('home', () => {
cy.visit('/');
cy.wait('@GQL');
cy.contains('Loading...').should('be.visible');
cy.contains('Loading...').should('not.exist');
cy.get('main[data-testid="market"]').should('exist'); // Wait for page to be rendered to before checking url
cy.url().should('include', `/markets/${oldestMarket.id}`); // Should redirect to oldest market
});

View File

@ -69,6 +69,7 @@ describe('markets table', () => {
cy.get('[role="gridcell"][col-id=data]').contains('Active').click();
cy.wait('@Market');
cy.get('.ag-root-wrapper').should('be.visible');
cy.contains('ACTIVE MARKET');
cy.url().should('include', '/markets/market-0');

View File

@ -24,6 +24,12 @@ Example configurations are provided here:
- [Stagnet1](./.env.stagnet1)
- [Stagnet2](./.env.stagnet2)
For convenience, you can boot the app injecting one of the configurations above by running:
```bash
yarn nx run token:serve --env={env} # e.g. stagnet1
```
There are a few different configuration options offered for this app:
The network configuration for the app

View File

@ -8,6 +8,7 @@ export const Navbar = () => {
return (
<nav className="flex items-center">
<Link href="/" passHref={true}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a className="px-[26px]">
<Vega className="fill-black dark:fill-white" />
</a>
@ -43,6 +44,7 @@ const NavLink = ({ name, path, exact, testId = name }: NavLinkProps) => {
);
return (
<Link data-testid={testId} href={path} passHref={true}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a className={linkClasses}>{name}</a>
</Link>
);

View File

@ -41,6 +41,14 @@ const networkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
},
};
const mockEnvironment = {
VEGA_ENV: 'TESTNET',
VEGA_NETWORKS: JSON.stringify({}),
GIT_BRANCH: 'test',
GIT_COMMIT_HASH: 'abcdef',
GIT_ORIGIN_URL: 'https://github.com/test/repo',
};
jest.mock('@web3-react/core', () => {
const original = jest.requireActual('@web3-react/core');
return {
@ -51,7 +59,7 @@ jest.mock('@web3-react/core', () => {
function setup(mock = networkParamsQueryMock) {
return render(
<EnvironmentProvider>
<EnvironmentProvider definitions={mockEnvironment}>
<MockedProvider mocks={[mock]}>
<Web3Container>
<div>

View File

@ -72,7 +72,8 @@ export const WithdrawPageContainer = ({
{hasIncompleteWithdrawals ? (
<p className="mb-12">
{t('You have incomplete withdrawals.')}{' '}
<Link href="/portfolio/withdrawals">
<Link href="/portfolio/withdrawals" passHref={true}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
className="underline"
data-testid="complete-withdrawals-prompt"

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/next:build",
"executor": "./tools/executors/next:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@ -19,7 +19,7 @@
}
},
"serve": {
"executor": "@nrwl/next:server",
"executor": "./tools/executors/next:serve",
"options": {
"buildTarget": "trading:build",
"dev": true

View File

@ -3,11 +3,13 @@ import { addMockGQLCommand } from './lib/commands/mock-gql';
import { addMockVegaWalletCommands } from './lib/commands/mock-vega-wallet';
import { addMockWeb3ProviderCommand } from './lib/commands/mock-web3-provider';
import { addSlackCommand } from './lib/commands/slack';
import { addHighlightLog } from './lib/commands/highlight-log';
addGetTestIdcommand();
addSlackCommand();
addMockGQLCommand();
addMockVegaWalletCommands();
addMockWeb3ProviderCommand();
addHighlightLog();
export * from './lib/graphql-test-utils';

View File

@ -0,0 +1,16 @@
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
highlight(message: string): void;
}
}
}
export function addHighlightLog() {
// @ts-ignore - ignoring Cypress type error which gets resolved when Cypress uses the command
Cypress.Commands.add('highlight', (message) => {
cy.log(`👉 **_${message}_**`);
});
}

View File

@ -1,4 +1,5 @@
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { validateSize } from '../utils/validate-size';
import type { DealTicketAmountProps } from './deal-ticket-amount';
@ -15,8 +16,9 @@ export const DealTicketLimitAmount = ({
return (
<div className="flex items-center gap-8">
<div className="flex-1">
<FormGroup label="Amount">
<FormGroup label={t('Amount')} labelFor="input-order-size-limit">
<Input
id="input-order-size-limit"
className="w-full"
type="number"
step={step}
@ -32,8 +34,13 @@ export const DealTicketLimitAmount = ({
</div>
<div>@</div>
<div className="flex-1">
<FormGroup label={`Price (${quoteName})`} labelAlign="right">
<FormGroup
labelFor="input-price-quote"
label={t(`Price (${quoteName})`)}
labelAlign="right"
>
<Input
id="input-price-quote"
className="w-full"
type="number"
step={step}

View File

@ -1,4 +1,5 @@
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { validateSize } from '../utils/validate-size';
import type { DealTicketAmountProps } from './deal-ticket-amount';
@ -16,8 +17,9 @@ export const DealTicketMarketAmount = ({
return (
<div className="flex items-center gap-8">
<div className="flex-1">
<FormGroup label="Amount">
<FormGroup label={t('Amount')} labelFor="input-order-size-market">
<Input
id="input-order-size-market"
className="w-full"
type="number"
step={step}

View File

@ -1,5 +1,6 @@
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
import { formatForInput } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/react-helpers';
interface ExpirySelectorProps {
value?: Date;
@ -11,7 +12,7 @@ export const ExpirySelector = ({ value, onSelect }: ExpirySelectorProps) => {
const dateFormatted = formatForInput(date);
const minDate = formatForInput(date);
return (
<FormGroup label="Expiry time/date" labelFor="expiration">
<FormGroup label={t('Expiry time/date')} labelFor="expiration">
<Input
data-testid="date-picker-field"
id="expiration"

View File

@ -1,6 +1,7 @@
import { FormGroup } from '@vegaprotocol/ui-toolkit';
import { OrderSide } from '@vegaprotocol/wallet';
import { Toggle } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
interface SideSelectorProps {
value: OrderSide;
@ -14,8 +15,9 @@ export const SideSelector = ({ value, onSelect }: SideSelectorProps) => {
}));
return (
<FormGroup label="Direction">
<FormGroup label={t('Direction')} labelFor="order-side-toggle">
<Toggle
id="order-side-toggle"
name="order-side"
toggles={toggles}
checkedValue={value}

View File

@ -1,5 +1,6 @@
import { FormGroup, Select } from '@vegaprotocol/ui-toolkit';
import { OrderTimeInForce, OrderType } from '@vegaprotocol/wallet';
import { t } from '@vegaprotocol/react-helpers';
interface TimeInForceSelectorProps {
value: OrderTimeInForce;
@ -22,8 +23,9 @@ export const TimeInForceSelector = ({
);
return (
<FormGroup label="Time in force">
<FormGroup label={t('Time in force')} labelFor="select-time-in-force">
<Select
id="select-time-in-force"
value={value}
onChange={(e) => onSelect(e.target.value as OrderTimeInForce)}
className="w-full"

View File

@ -1,4 +1,5 @@
import { FormGroup } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { OrderType } from '@vegaprotocol/wallet';
import { Toggle } from '@vegaprotocol/ui-toolkit';
@ -14,8 +15,9 @@ const toggles = Object.entries(OrderType).map(([label, value]) => ({
export const TypeSelector = ({ value, onSelect }: TypeSelectorProps) => {
return (
<FormGroup label="Order type">
<FormGroup label={t('Order type')} labelFor="order-type">
<Toggle
id="order-type"
name="order-type"
toggles={toggles}
checkedValue={value}

View File

@ -190,9 +190,9 @@ export const DepositForm = ({
)}
</FormGroup>
{selectedAsset && limits && (
<FormGroup>
<div className="mb-20">
<DepositLimits limits={limits} />
</FormGroup>
</div>
)}
<FormGroup label={t('Amount')} labelFor="amount" className="relative">
<Input

View File

@ -40,6 +40,10 @@ const mockEnvironmentState: EnvironmentState = {
},
ETHEREUM_PROVIDER_URL: 'https://ether.provider',
ETHERSCAN_URL: 'https://etherscan.url',
GIT_BRANCH: 'test',
GIT_ORIGIN_URL: 'https://github.com/test/repo',
GIT_COMMIT_HASH: 'abcde01234',
GITHUB_FEEDBACK_URL: 'https://github.com/test/feedback',
};
beforeEach(() => {
@ -59,6 +63,11 @@ beforeEach(() => {
process.env['NX_VEGA_NETWORKS'] = JSON.stringify(
mockEnvironmentState.VEGA_NETWORKS
);
process.env['NX_GIT_BRANCH'] = mockEnvironmentState.GIT_BRANCH;
process.env['NX_GIT_ORIGIN_URL'] = mockEnvironmentState.GIT_ORIGIN_URL;
process.env['NX_GIT_COMMIT_HASH'] = mockEnvironmentState.GIT_COMMIT_HASH;
process.env['NX_GITHUB_FEEDBACK_URL'] =
mockEnvironmentState.GITHUB_FEEDBACK_URL;
});
afterAll(() => {

View File

@ -58,6 +58,14 @@ const getBundledEnvironmentValue = (key: EnvKey) => {
return process.env['NX_ETHERSCAN_URL'];
case 'VEGA_NETWORKS':
return process.env['NX_VEGA_NETWORKS'];
case 'GIT_BRANCH':
return process.env['NX_GIT_BRANCH'];
case 'GIT_COMMIT_HASH':
return process.env['NX_GIT_COMMIT_HASH'];
case 'GIT_ORIGIN_URL':
return process.env['NX_GIT_ORIGIN_URL'];
case 'GITHUB_FEEDBACK_URL':
return process.env['NX_GITHUB_FEEDBACK_URL'];
case 'VEGA_EXPLORER_URL':
return process.env['NX_VEGA_EXPLORER_URL'];
}

View File

@ -23,6 +23,10 @@ const schemaObject = {
ETHERSCAN_URL: z.string().url({
message: 'The NX_ETHERSCAN_URL environment variable must be a valid url',
}),
GIT_BRANCH: z.optional(z.string()),
GIT_COMMIT_HASH: z.optional(z.string()),
GIT_ORIGIN_URL: z.optional(z.string()),
GITHUB_FEEDBACK_URL: z.optional(z.string()),
VEGA_ENV: z.nativeEnum(Networks),
VEGA_NETWORKS: z
.object(

View File

@ -18,6 +18,14 @@ export const SelectMarketList = ({
data,
onSelect,
}: SelectMarketListDataProps) => {
const handleKeyPress = (
event: React.KeyboardEvent<HTMLAnchorElement>,
id: string
) => {
if (event.key === 'Enter') {
return onSelect(id);
}
};
const thClassNames = (direction: 'left' | 'right') =>
`px-8 text-${direction} font-sans font-normal text-ui-small leading-9 mb-0 text-dark/80 dark:text-white/80`;
const tdClassNames =
@ -54,8 +62,9 @@ export const SelectMarketList = ({
>
<td className={`${boldUnderlineClassNames} relative`}>
<Link href={`/markets/${id}`} passHref={true}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid,jsx-a11y/no-static-element-interactions */}
<a
onKeyPress={(event) => handleKeyPress(event, id)}
onClick={() => onSelect(id)}
data-testid={`market-link-${id}`}
>

View File

@ -0,0 +1,12 @@
{
"presets": [
[
"@nrwl/react/babel",
{
"runtime": "automatic",
"useBuiltIns": "usage"
}
]
],
"plugins": []
}

View File

@ -0,0 +1,18 @@
{
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@ -0,0 +1,21 @@
# network-info
This library was generated with [Nx](https://nx.dev).
## Prerequisites
The environment variables needed to be present for any app consuming this library.
`NX_VEGA_URL` OR `NX_VEGA_CONFIG_URL` - either the network configuration url or a url to a node to directly connect to
`NX_VEGA_NETWORKS` - JSON object with key-value pairs for environments and their deployed URLs
`NX_GITHUB_FEEDBACK_URL` - the repository's feedback URL to point to
`NX_ETHEREUM_PROVIDER_URL` - the Ethereum provider url
For examples, see Block Explorer's .env files [here](../../apps/explorer)
## Running unit tests
Run `nx test network-info` to execute the unit tests via [Jest](https://jestjs.io).

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