Compare commits

...
32 changed files with 835 additions and 747 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ env:
jobs:
add_issue:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: 'Add issue to project board'
run: |
@@ -1,10 +1,9 @@
name: PR Validations
name: CI/CD
on:
push:
branches:
- develop
- main
- release/*
pull_request:
types:
- opened
@@ -12,42 +11,55 @@ on:
- synchronize
- ready_for_review
jobs:
pr:
runs-on: ubuntu-latest
lint-test-build:
runs-on: ubuntu-22.04
name: '(CI) lint + unit test + build'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Check node version
id: node-version
run: |
npmVersion=$(cat .nvmrc | head -n 1)
echo ::set-output name=npmVersion::${npmVersion}
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: ${{ steps.node-version.outputs.npmVersion }}
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v3
with:
main-branch-name: develop
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: node_modules-${{ hashFiles('**/yarn.lock') }}
- name: Check formatting
run: yarn nx format:check
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Lint affected
run: yarn nx affected:lint --max-warnings=0
- name: Build affected spec
run: yarn nx affected --target=build-spec
- name: Test affected
run: yarn nx affected:test
- name: Build affected
run: yarn nx affected:build
# See affected apps
- name: See affected apps
run: |
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=HEAD --select=projects)"
echo ">>>> debug"
echo "NX Version: $nx_version"
echo "NX_BASE: ${{ env.NX_BASE }}"
echo "NX_HEAD: ${{ env.NX_HEAD }}"
echo ">>>> eof debug"
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
echo -n "Affected projects: $affected"
projects_e2e=""
@@ -64,32 +76,33 @@ jobs:
projects: ${{ env.PROJECTS }}
projects-e2e: ${{ env.PROJECTS_E2E }}
run-cypress:
needs: pr
if: ${{ needs.pr.outputs.projects != '[]' }}
cypress:
needs: lint-test-build
name: '(CI) cypress'
if: ${{ needs.lint-test-build.outputs.projects != '[]' }}
uses: ./.github/workflows/cypress-run.yml
secrets: inherit
with:
projects: ${{ needs.pr.outputs.projects-e2e }}
projects: ${{ needs.lint-test-build.outputs.projects-e2e }}
tags: '@smoke @regression'
run-docker-build:
needs: pr
if: ${{ needs.pr.outputs.projects != '[]' }}
uses: ./.github/workflows/publish-docker-containers.yml
publish-dist:
needs: lint-test-build
name: '(CD) publish dist'
if: ${{ needs.lint-test-build.outputs.projects != '[]' }}
uses: ./.github/workflows/publish-dist.yml
secrets: inherit
with:
projects: ${{ needs.pr.outputs.projects }}
projects: ${{ needs.lint-test-build.outputs.projects }}
# Report single result at the end, to avoid mess with required checks in PR
result:
cypress-result:
if: ${{ always() }}
needs: run-cypress
runs-on: ubuntu-latest
name: Cypress result
needs: cypress
runs-on: ubuntu-22.04
steps:
- run: |
result="${{ needs.run-cypress.result }}"
result="${{ needs.cypress.result }}"
if [[ $result == "success" || $result == "skipped" ]]; then
exit 0
else
+1 -1
View File
@@ -13,7 +13,7 @@ on:
jobs:
cypress-run:
name: Run Cypress Trading tests -- live environment
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v2
+1 -1
View File
@@ -1,4 +1,4 @@
name: Cypress Run
name: (CI) Cypress Run
on:
workflow_call:
inputs:
+12 -9
View File
@@ -8,22 +8,25 @@ on:
jobs:
master:
name: Generate Queries
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
fetch-depth: 0
- name: Use Node.js 16
id: Node
uses: actions/setup-node@v2
with:
node-version: 16.15.1
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Generate queries
run: node ./scripts/get-queries.js
- uses: actions/upload-artifact@v2
with:
name: queries
+17 -10
View File
@@ -3,21 +3,28 @@ name: Verify PR title
on:
pull_request:
types: [opened, ready_for_review, reopened, edited, synchronize]
types:
- opened
- ready_for_review
- reopened
- edited
- synchronize
jobs:
lint_pr:
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
with:
fetch-depth: 0
- name: Use Node.js 16
id: Node
uses: actions/setup-node@v2
with:
node-version: 16.15.1
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: Check PR title
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs:
master:
name: Generate Queries
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Checkout
@@ -1,4 +1,4 @@
name: Docker build
name: (CD) Publish docker + s3
on:
workflow_call:
@@ -8,13 +8,13 @@ on:
type: string
jobs:
master:
publish-dist:
strategy:
fail-fast: false
matrix:
app: ${{ fromJSON(inputs.projects) }}
name: ${{ matrix.app }}
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@v3
@@ -29,41 +29,6 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# https://docs.github.com/en/actions/learn-github-actions/contexts
# https://github.com/actions/checkout#Checkout-pull-request-HEAD-commit-instead-of-merge-commit
- name: Determine Docker Image tag
id: tags
run: |
npmVersion=$(cat .nvmrc | head -n 1)
versionTag=${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || github.event.pull_request.head.sha }}
echo ::set-output name=npmVersion::${npmVersion}
echo ::set-output name=version::${versionTag}
- name: Print config
run: |
git rev-parse --verify HEAD
git status
echo "steps.tags.outputs.version=${{ steps.tags.outputs.version }}"
- name: Build and export to local Docker
uses: docker/build-push-action@v3
with:
load: true
build-args: |
APP=${{ matrix.app }}
NODE_VERSION=${{ steps.tags.outputs.npmVersion }}
tags: |
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
- name: Sanity check docker image
run: |
echo "Check .env file"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat .env
echo "Check ipfs-hash"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat ipfs-hash
echo "List html directory"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local ls -lah
- name: Log in to the Container registry
uses: docker/login-action@v2
with:
@@ -71,17 +36,66 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
# https://docs.github.com/en/actions/learn-github-actions/contexts
- name: Check node version
id: tags
run: |
nodeVersion=$(cat .nvmrc | head -n 1)
echo ::set-output name=nodeVersion::${nodeVersion}
if [[ "${{ github.event_name }}" = "push" ]]; then
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
bucketName="${{ github.event.repository.name }}-$envName"
echo ::set-output name=bucketName::${bucketName}
echo ::set-output name=envName::${envName}
fi
- name: Build and export to local Docker
id: docker_build
uses: docker/build-push-action@v3
with:
load: true
build-args: |
APP=${{ matrix.app }}
NODE_VERSION=${{ steps.tags.outputs.nodeVersion }}
ENV_NAME=${{ steps.tags.outputs.envName || '' }}
tags: |
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
- name: Sanity check docker image
run: |
echo "Check ipfs-hash"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat ipfs-hash
echo "List html directory"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local ls -lah
echo "Copy dist to local filesystem"
docker create --name=dist ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
docker cp dist:/usr/share/nginx/html dist
echo "Check local dist"
ls -al dist
- name: Publish dist as docker image
uses: docker/build-push-action@v3
if: ${{ github.event_name == 'pull_request' }}
with:
push: true
build-args: |
APP=${{ matrix.app }}
NODE_VERSION=${{ steps.tags.outputs.npmVersion }}
NODE_VERSION=${{ steps.tags.outputs.nodeVersion }}
tags: |
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:latest
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ steps.tags.outputs.version }}
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ github.event.pull_request.head.sha || github.sha }}
# - uses: shallwefootball/s3-upload-action@master
# if: ${{ github.event_name == 'push' }}
# name: Upload dist S3
# with:
# aws_key_id: ${{ secrets.AWS_KEY_ID }}
# aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
# aws_bucket: ${{ steps.tags.outputs.bucketName }}
# source_dir: 'dist'
- name: Add preview label
uses: actions-ecosystem/action-add-labels@v1
+9 -11
View File
@@ -19,29 +19,27 @@ on:
jobs:
publish:
name: Build & Publish - Tag
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
permissions:
contents: 'read'
actions: 'read'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: User Node.js 16
id: Node
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16.15.1
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: node_modules-${{ hashFiles('**/yarn.lock') }}
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Build project
run: yarn nx build ${{inputs.project}}
- name: Publish project to @vegaprotocol
uses: JS-DevTools/npm-publish@v1
with:
-46
View File
@@ -1,46 +0,0 @@
name: Unit tests & build
on:
push:
branches:
- develop
- main
pull_request:
jobs:
pr:
name: Test and lint - PR
runs-on: ubuntu-latest
permissions:
contents: 'read'
actions: 'read'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v2
with:
main-branch-name: ${{ github.base_ref }}
- name: Use Node.js 16
id: Node
uses: actions/setup-node@v3
with:
node-version: 16.15.1
- name: Restore node_modules from cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: node_modules-${{ hashFiles('**/yarn.lock') }}
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Check formatting
run: yarn nx format:check
- name: Lint affected
run: yarn nx affected:lint --max-warnings=0
- name: Test affected
run: yarn nx affected:test
- name: Build affected
run: yarn nx affected:build
- name: Build affected spec
run: yarn nx affected --target=build-spec
+2 -7
View File
@@ -4,6 +4,7 @@ FROM --platform=amd64 node:${NODE_VERSION}-alpine3.16 as build
WORKDIR /app
# Argument to allow building of different apps
ARG APP
ARG ENV_NAME=""
RUN apk add --update --no-cache \
python3 \
make \
@@ -18,16 +19,10 @@ RUN sh ./docker-build.sh
# if this fails you need to docker pull nginx:1.23-alpine and pin new SHA
# this is to ensure that we run always same version of alpine to make sure ipfs is indempotent
FROM --platform=amd64 nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
ARG APP
# configuration of system
RUN apk add --no-cache bash go-ipfs
EXPOSE 80
COPY entrypoint.sh /entrypoint.sh
CMD ["/entrypoint.sh"]
# Copy dist
WORKDIR /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/apps/${APP} /usr/share/nginx/html
COPY ./apps/${APP}/.env .env
RUN ipfs init && echo "$(ipfs add -rQ .)" > ipfs-hash
RUN apk add --no-cache go-ipfs; ipfs init && echo "$(ipfs add -rQ .)" > ipfs-hash; apk del go-ipfs
+2
View File
@@ -13,6 +13,8 @@ NX_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet3-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
#Test configuration variables
CYPRESS_FAIRGROUND=false
@@ -6,159 +6,203 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
cy.get('nav', { timeout: 10000 }).should('be.visible');
});
describe('with wallets disconnected', function () {
describe('Links and buttons', function () {
it('should have link for proposal page', function () {
cy.getByTestId('home-proposals').within(() => {
cy.get('[href="/proposals"]')
.should('exist')
.and('have.text', 'Browse, vote, and propose');
});
});
it('should show open or enacted proposals with proposal summary', function () {
cy.get('body').then(($body) => {
if (!$body.find('[data-testid="proposals-list-item"]').length) {
cy.createMarket();
cy.reload();
waitForSpinner();
}
});
cy.getByTestId('proposals-list-item')
.should('have.length.at.least', 1)
.first()
.within(() => {
cy.getByTestId('proposal-title')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-type')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-description')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-details')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-status')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('vote-details')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('view-proposal-btn').should('be.visible');
});
});
it('should have external link for governance', function () {
cy.getByTestId('home-proposals').within(() => {
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and('contain', 'https://vega.xyz/governance');
});
});
it('should have link for validator page', function () {
cy.getByTestId('home-validators').within(() => {
cy.get('[href="/validators"]')
.first()
.should('exist')
.and('have.text', 'Browse, and stake');
});
});
it('should have external link for validators', function () {
cy.getByTestId('home-validators').within(() => {
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and(
'contain',
'https://community.vega.xyz/c/mainnet-validator-candidates'
);
});
});
it('should have information on active nodes', function () {
cy.getByTestId('node-information')
.first()
.should('contain.text', '2')
.and('contain.text', 'active nodes');
});
it('should have information on consensus nodes', function () {
cy.getByTestId('node-information')
.last()
.should('contain.text', '2')
.and('contain.text', 'consensus nodes');
});
it('should contain link to specific validators', function () {
cy.getByTestId('validators')
.should('have.length', '2')
.each(($validator) => {
cy.wrap($validator).find('a').should('have.attr', 'href');
});
});
it('should have link for rewards page', function () {
cy.getByTestId('home-rewards').within(() => {
cy.get('[href="/rewards"]')
.first()
.should('exist')
.and('have.text', 'See rewards');
});
});
it('should have link for withdrawal page', function () {
cy.getByTestId('home-vega-token').within(() => {
cy.get('[href="/token/withdraw"]')
.first()
.should('exist')
.and('have.text', 'Manage tokens');
});
describe('Links and buttons', function () {
it('should have link for proposal page', function () {
cy.getByTestId('home-proposals').within(() => {
cy.get('[href="/proposals"]')
.should('exist')
.and('have.text', 'Browse, vote, and propose');
});
});
describe('Mobile view - navigation bar', function () {
before('Change to mobile resolution', function () {
cy.viewport('iphone-xr');
});
it('should have burger button', () => {
cy.getByTestId('button-menu-drawer').should('be.visible').click();
cy.getByTestId('menu-drawer').should('be.visible');
});
it('should have link for proposal page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/proposals"]')
.should('exist')
.and('have.text', 'Proposals');
it('should display announcement banner', function () {
cy.getByTestId('app-announcement')
.should('be.visible')
.within(() => {
cy.getByTestId('external-link').should('exist');
});
cy.getByTestId('app-announcement-close').should('be.visible').click();
cy.getByTestId('app-announcement').should('not.exist');
});
it('should show open or enacted proposals with proposal summary', function () {
cy.get('body').then(($body) => {
if (!$body.find('[data-testid="proposals-list-item"]').length) {
cy.createMarket();
cy.reload();
waitForSpinner();
}
});
it('should have link for validator page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/validators"]')
cy.getByTestId('proposals-list-item')
.should('have.length.at.least', 1)
.first()
.within(() => {
cy.getByTestId('proposal-title')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-type').invoke('text').should('not.be.empty');
cy.getByTestId('proposal-description')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-details')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('proposal-status')
.invoke('text')
.should('not.be.empty');
cy.getByTestId('vote-details').invoke('text').should('not.be.empty');
cy.getByTestId('view-proposal-btn').should('be.visible');
});
});
it('should have external link for governance', function () {
cy.getByTestId('home-proposals').within(() => {
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and('contain', 'https://vega.xyz/governance');
});
});
it('should have link for validator page', function () {
cy.getByTestId('home-validators').within(() => {
cy.get('[href="/validators"]')
.first()
.should('exist')
.and('have.text', 'Browse, and stake');
});
});
it('should have external link for validators', function () {
cy.getByTestId('home-validators').within(() => {
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and(
'contain',
'https://community.vega.xyz/c/mainnet-validator-candidates'
);
});
});
it('should have information on active nodes', function () {
cy.getByTestId('node-information')
.first()
.should('contain.text', '2')
.and('contain.text', 'active nodes');
});
it('should have information on consensus nodes', function () {
cy.getByTestId('node-information')
.last()
.should('contain.text', '2')
.and('contain.text', 'consensus nodes');
});
it('should contain link to specific validators', function () {
cy.getByTestId('validators')
.should('have.length', '2')
.each(($validator) => {
cy.wrap($validator).find('a').should('have.attr', 'href');
});
});
it('should have link for rewards page', function () {
cy.getByTestId('home-rewards').within(() => {
cy.get('[href="/rewards"]')
.first()
.should('exist')
.and('have.text', 'See rewards');
});
});
it('should have link for withdrawal page', function () {
cy.getByTestId('home-vega-token').within(() => {
cy.get('[href="/token/withdraw"]')
.first()
.should('exist')
.and('have.text', 'Manage tokens');
});
});
it('should display network data', function () {
cy.getByTestId('git-network-data')
.should('contain.text', 'Reading network data from')
.within(() => {
cy.get('span')
.first()
.should('exist')
.and('have.text', 'Validators');
.should('have.text', 'http://localhost:3028/query');
cy.getByTestId('link').should('exist');
});
});
});
it('should have link for rewards page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/rewards"]')
.first()
.should('exist')
.and('have.text', 'Rewards');
it('should display eth data', function () {
cy.getByTestId('git-eth-data')
.should('contain.text', 'Reading Ethereum data from')
.within(() => {
cy.get('span').should('have.text', 'http://localhost:8545');
});
});
it('should have link for withdrawal page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/token/withdraw"]')
.first()
.should('exist')
.and('have.text', 'Withdraw');
});
});
});
after(function () {
cy.viewport(
Cypress.config('viewportWidth'),
Cypress.config('viewportHeight')
);
it('should contain link for known issues on Github', function () {
cy.getByTestId('git-info').within(() => {
cy.contains('Known issues and feedback on')
.find('[data-testid="link"]')
.should(
'have.attr',
'href',
'https://github.com/vegaprotocol/feedback/discussions'
);
});
});
});
describe('Mobile view - navigation bar', function () {
before('Change to mobile resolution', function () {
cy.viewport('iphone-xr');
});
it('should have burger button', () => {
cy.getByTestId('button-menu-drawer').should('be.visible').click();
cy.getByTestId('menu-drawer').should('be.visible');
});
it('should have link for proposal page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/proposals"]')
.should('exist')
.and('have.text', 'Proposals');
});
});
it('should have link for validator page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/validators"]')
.first()
.should('exist')
.and('have.text', 'Validators');
});
});
it('should have link for rewards page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/rewards"]')
.first()
.should('exist')
.and('have.text', 'Rewards');
});
});
it('should have link for withdrawal page', function () {
cy.getByTestId('menu-drawer').within(() => {
cy.get('[href="/token/withdraw"]')
.first()
.should('exist')
.and('have.text', 'Withdraw');
});
});
after(function () {
cy.viewport(
Cypress.config('viewportWidth'),
Cypress.config('viewportHeight')
);
});
});
});
+1 -1
View File
@@ -5,6 +5,7 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_FAIRGROUND=false
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_CONFIG_URL=''
NX_VEGA_URL=http://localhost:3028/query
@@ -16,7 +17,6 @@ NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet3-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
#Test configuration variables
CYPRESS_FAIRGROUND=false
+4
View File
@@ -12,6 +12,7 @@ const TRUTHY = ['1', 'true'];
interface VegaContracts {
claimAddress: string;
lockedAddress: string;
tokenVestingAddress?: string;
}
const customClaimAddress = process.env['NX_CUSTOM_CLAIM_ADDRESS'] as string;
@@ -51,6 +52,9 @@ export const ContractAddresses: {
VALIDATOR_TESTNET: {
claimAddress: '0x8Cef746ab7C83B61F6461cC92882bD61AB65a994', // TODO not deployed to this env, but random address so app doesn't error
lockedAddress: '0x0', // TODO not deployed to this env
// This is a fallback contract address for the validator testnet network which does not
// have a vesting contract address set and is therefore not in the ethereum config
tokenVestingAddress: '0xadFcb7f93a24F8743a8e548d74d2ecB373c92866',
},
MAINNET: {
claimAddress: '0x0ee1fb382caf98e86e97e51f9f42f8b4654020f3',
@@ -49,6 +49,13 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
signer = provider.getSigner();
}
const tokenVestingAddress =
config.token_vesting_contract?.address ||
ENV.addresses.tokenVestingAddress;
if (!tokenVestingAddress) {
throw new Error('No token vesting address found');
}
if (provider && config) {
const staking = new StakingBridge(
config.staking_bridge_contract.address,
@@ -63,7 +70,7 @@ export const ContractsProvider = ({ children }: { children: JSX.Element }) => {
signer || provider
),
vesting: new TokenVesting(
config.token_vesting_contract.address,
tokenVestingAddress,
signer || provider
),
claim: new Claim(ENV.addresses.claimAddress, signer || provider),
@@ -14,6 +14,7 @@ import { TokenDetailsCirculating } from './token-details-circulating';
import { SplashLoader } from '../../../components/splash-loader';
import { useEthereumConfig } from '@vegaprotocol/web3';
import { useContracts } from '../../../contexts/contracts/contracts-context';
import { ENV } from '../../../config';
export const TokenDetails = ({
totalSupply,
@@ -49,6 +50,9 @@ export const TokenDetails = ({
);
}
const tokenVestingContractAddress =
config.token_vesting_contract?.address || ENV.addresses.tokenVestingAddress;
return (
<div className="token-details">
<RoundedWrapper>
@@ -65,18 +69,20 @@ export const TokenDetails = ({
{token.address}
</Link>
</KeyValueTableRow>
<KeyValueTableRow>
{t('Vesting contract').toUpperCase()}
<Link
data-testid="token-contract"
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>
</KeyValueTableRow>
{tokenVestingContractAddress && (
<KeyValueTableRow>
{t('Vesting contract').toUpperCase()}
<Link
data-testid="token-contract"
title={t('View on Etherscan (opens in a new tab)')}
className="font-mono text-white text-right"
href={`${ETHERSCAN_URL}/address/${tokenVestingContractAddress}`}
target="_blank"
>
{tokenVestingContractAddress}
</Link>
</KeyValueTableRow>
)}
<KeyValueTableRow>
{t('Total supply').toUpperCase()}
<span className="font-mono" data-testid="total-supply">
+169 -41
View File
@@ -3,12 +3,54 @@
"tranche_id": 56,
"tranche_start": "2023-04-20T00:00:00.000Z",
"tranche_end": "2023-05-20T00:00:00.000Z",
"total_added": "0",
"total_added": "6051.25",
"total_removed": "0",
"locked_amount": "0",
"deposits": [],
"locked_amount": "6051.25",
"deposits": [
{
"amount": "50",
"user": "0x15024E62134A8BFFCce11f5ce58CeCDe853038D7",
"tx": "0xc38d2e52912f15452c76b863dbfad88927b49435c284eaf6997be4cf13782fc0"
},
{
"amount": "6001.25",
"user": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"tx": "0xde2c8eedaba7ef1c953a7ca5439a8d7900ff01d92bd49d9dff1c9cdeaaa38d6f"
}
],
"withdrawals": [],
"users": []
"users": [
{
"address": "0x15024E62134A8BFFCce11f5ce58CeCDe853038D7",
"deposits": [
{
"amount": "50",
"user": "0x15024E62134A8BFFCce11f5ce58CeCDe853038D7",
"tranche_id": 56,
"tx": "0xc38d2e52912f15452c76b863dbfad88927b49435c284eaf6997be4cf13782fc0"
}
],
"withdrawals": [],
"total_tokens": "50",
"withdrawn_tokens": "0",
"remaining_tokens": "50"
},
{
"address": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"deposits": [
{
"amount": "6001.25",
"user": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"tranche_id": 56,
"tx": "0xde2c8eedaba7ef1c953a7ca5439a8d7900ff01d92bd49d9dff1c9cdeaaa38d6f"
}
],
"withdrawals": [],
"total_tokens": "6001.25",
"withdrawn_tokens": "0",
"remaining_tokens": "6001.25"
}
]
},
{
"tranche_id": 55,
@@ -67,9 +109,9 @@
"tranche_id": 54,
"tranche_start": "2023-04-06T00:00:00.000Z",
"tranche_end": "2023-05-06T00:00:00.000Z",
"total_added": "2970",
"total_added": "3648",
"total_removed": "0",
"locked_amount": "2970",
"locked_amount": "3648",
"deposits": [
{
"amount": "33",
@@ -86,6 +128,11 @@
"user": "0xE9F41a0090fcc7eaf626037003AAD44B17098E7C",
"tx": "0x09d3e968eb8dbd6851f47b36f7bb9e7d25a078c5c1b23ce5341a66ce19578e65"
},
{
"amount": "678",
"user": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"tx": "0x157b13e78d027a5b6cf35fdae80a8cec7797149f35c23eb43faa07d74a03d70d"
},
{
"amount": "111",
"user": "0x268070d5EEd5b24E34a5F4C17B5482178b18089D",
@@ -214,6 +261,21 @@
"withdrawn_tokens": "0",
"remaining_tokens": "288"
},
{
"address": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"deposits": [
{
"amount": "678",
"user": "0x94097462EF7c43D0aC732E7B18f830096D95207C",
"tranche_id": 54,
"tx": "0x157b13e78d027a5b6cf35fdae80a8cec7797149f35c23eb43faa07d74a03d70d"
}
],
"withdrawals": [],
"total_tokens": "678",
"withdrawn_tokens": "0",
"remaining_tokens": "678"
},
{
"address": "0x268070d5EEd5b24E34a5F4C17B5482178b18089D",
"deposits": [
@@ -561,7 +623,7 @@
"tranche_end": "2023-04-06T00:00:00.000Z",
"total_added": "14099",
"total_removed": "165.10784124668",
"locked_amount": "1247.56462776284332054",
"locked_amount": "1134.24202023596132571",
"deposits": [
{
"amount": "30",
@@ -3349,7 +3411,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "86666.297",
"total_removed": "0",
"locked_amount": "58349.7031275271807221145",
"locked_amount": "58290.540518387909930644",
"deposits": [
{
"amount": "86666.297",
@@ -3415,7 +3477,7 @@
"tranche_end": "2023-06-01T00:00:00.000Z",
"total_added": "2500",
"total_removed": "0",
"locked_amount": "806.91026276963785",
"locked_amount": "803.48764372201875",
"deposits": [
{
"amount": "2500",
@@ -3536,7 +3598,7 @@
"tranche_end": "2023-09-01T00:00:00.000Z",
"total_added": "17500",
"total_removed": "0",
"locked_amount": "14336.97649330716525",
"locked_amount": "14313.27857664049975",
"deposits": [
{
"amount": "12500",
@@ -3802,8 +3864,8 @@
"tranche_start": "2023-02-01T00:00:00.000Z",
"tranche_end": "2023-08-01T00:00:00.000Z",
"total_added": "37500",
"total_removed": "11668.32172695",
"locked_amount": "24808.64650475752125",
"total_removed": "11781.2245815",
"locked_amount": "24757.02357658072125",
"deposits": [
{
"amount": "7500",
@@ -3837,6 +3899,11 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0xf440dd4b160a155a08a3cc6e16706d5e4f9609bddd46c495217c377ef538c76f"
},
{
"amount": "112.90285455",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x69a4b32bad0a702a9e19ec1a77e4bc75d936f323720ca4c6213f2e4f41a750ed"
},
{
"amount": "92.587476975",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -3963,6 +4030,12 @@
"tranche_id": 34,
"tx": "0xf440dd4b160a155a08a3cc6e16706d5e4f9609bddd46c495217c377ef538c76f"
},
{
"amount": "112.90285455",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 34,
"tx": "0x69a4b32bad0a702a9e19ec1a77e4bc75d936f323720ca4c6213f2e4f41a750ed"
},
{
"amount": "92.587476975",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -4073,8 +4146,8 @@
}
],
"total_tokens": "7500",
"withdrawn_tokens": "2432.87244855",
"remaining_tokens": "5067.12755145"
"withdrawn_tokens": "2545.7753031",
"remaining_tokens": "4954.2246969"
},
{
"address": "0x0B4e6fcE839B01ef43DA6F890FAC7B1Afb004600",
@@ -4112,7 +4185,7 @@
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "129999.45",
"total_removed": "0",
"locked_amount": "58296.4663652644736979915",
"locked_amount": "58237.357734561919861248",
"deposits": [
{
"amount": "129999.45",
@@ -4145,7 +4218,7 @@
"tranche_end": "2024-04-01T00:00:00.000Z",
"total_added": "54144.7663",
"total_removed": "0",
"locked_amount": "53810.8835054071292707386",
"locked_amount": "53774.02265585407567509679",
"deposits": [
{
"amount": "54144.7663",
@@ -4178,7 +4251,7 @@
"tranche_end": "2023-09-03T00:00:00.000Z",
"total_added": "62600",
"total_removed": "0",
"locked_amount": "26196.482198122780824",
"locked_amount": "26153.74840816843942",
"deposits": [
{
"amount": "10000",
@@ -4371,7 +4444,7 @@
"tranche_end": "2023-09-17T00:00:00.000Z",
"total_added": "5000",
"total_removed": "0",
"locked_amount": "2284.15160451547415",
"locked_amount": "2280.738362506342",
"deposits": [
{
"amount": "5000",
@@ -4582,7 +4655,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "97499.58",
"total_removed": "0",
"locked_amount": "405.60456575344483061187",
"locked_amount": "347.624505252249029385696",
"deposits": [
{
"amount": "97499.58",
@@ -4615,7 +4688,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "135173.4239508",
"total_removed": "133818.54965292963650862",
"locked_amount": "554.3914166779487086967342868",
"locked_amount": "475.1426838126835492687483956",
"deposits": [
{
"amount": "135173.4239508",
@@ -4672,7 +4745,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "32499.86",
"total_removed": "0",
"locked_amount": "170.63083639627856110929",
"locked_amount": "146.2396262055176868479",
"deposits": [
{
"amount": "32499.86",
@@ -4705,7 +4778,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "10833.29",
"total_removed": "0",
"locked_amount": "55.53868148454478352929",
"locked_amount": "47.59957925415311373976",
"deposits": [
{
"amount": "10833.29",
@@ -4738,7 +4811,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "22749.93",
"total_removed": "4720.860935375",
"locked_amount": "207.61599572971184611278",
"locked_amount": "177.93785842604644066488",
"deposits": [
{
"amount": "6500",
@@ -4889,8 +4962,8 @@
"tranche_start": "2022-11-01T00:00:00.000Z",
"tranche_end": "2023-05-01T00:00:00.000Z",
"total_added": "22500",
"total_removed": "6244.98110415",
"locked_amount": "3448.723814456722875",
"total_removed": "6357.929999175",
"locked_amount": "3417.750057550645125",
"deposits": [
{
"amount": "7500",
@@ -4919,6 +4992,16 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x0e47007cb85268a4e0c3c1143b96e4c98c9880060c4218babcadd0c82f8247a9"
},
{
"amount": "112.943139975",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0xde2d6d5df9d5097adf8a894beb8a02f0bd1cc4da1eccc221f8bfa08403dfed87"
},
{
"amount": "0.00575505",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0xa7a9a0e91b78fd7d8ba4c16bf5b58fb1a3cb19ec1302788e894f5e24ccb07904"
},
{
"amount": "92.593232025",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -5100,6 +5183,18 @@
"tranche_id": 33,
"tx": "0x0e47007cb85268a4e0c3c1143b96e4c98c9880060c4218babcadd0c82f8247a9"
},
{
"amount": "112.943139975",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 33,
"tx": "0xde2d6d5df9d5097adf8a894beb8a02f0bd1cc4da1eccc221f8bfa08403dfed87"
},
{
"amount": "0.00575505",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 33,
"tx": "0xa7a9a0e91b78fd7d8ba4c16bf5b58fb1a3cb19ec1302788e894f5e24ccb07904"
},
{
"amount": "92.593232025",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -5282,8 +5377,8 @@
}
],
"total_tokens": "7500",
"withdrawn_tokens": "6244.98110415",
"remaining_tokens": "1255.01889585"
"withdrawn_tokens": "6357.929999175",
"remaining_tokens": "1142.070000825"
},
{
"address": "0x2539b51EbDE65a75672aBcfE9439a706a99D18D1",
@@ -5308,7 +5403,7 @@
"tranche_end": "2023-06-02T00:00:00.000Z",
"total_added": "1939928.38",
"total_removed": "928642.9598472029154",
"locked_amount": "317526.7710493525900617104",
"locked_amount": "316202.482041087660677789",
"deposits": [
{
"amount": "1852091.69",
@@ -39041,7 +39136,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "3732368.4671",
"total_removed": "700133.348465855088393",
"locked_amount": "512429.420752227829460135708",
"locked_amount": "510394.449614987120008137767",
"deposits": [
{
"amount": "1998.95815",
@@ -40422,8 +40517,8 @@
"tranche_start": "2022-06-05T00:00:00.000Z",
"tranche_end": "2023-12-05T00:00:00.000Z",
"total_added": "15870102.715470999700000001",
"total_removed": "814470.78267520605435452",
"locked_amount": "7116729.41051479466949006868895061288618547",
"total_removed": "814951.95458233668060452",
"locked_amount": "7109513.53351977375094568254105497818788864",
"deposits": [
{
"amount": "16249.93",
@@ -40957,6 +41052,11 @@
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x58bac20de3636c17156dcb64322cc7612c48f553d941bc039c796ef4167eeeb5"
},
{
"amount": "481.17190713062625",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tx": "0x625ce40117b67b756a12ad676cfbfd2c59e264b3c86adbc624bf7107c4dbc5d5"
},
{
"amount": "545.4204142199725",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -42981,6 +43081,12 @@
"tranche_id": 2,
"tx": "0x58bac20de3636c17156dcb64322cc7612c48f553d941bc039c796ef4167eeeb5"
},
{
"amount": "481.17190713062625",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
"tranche_id": 2,
"tx": "0x625ce40117b67b756a12ad676cfbfd2c59e264b3c86adbc624bf7107c4dbc5d5"
},
{
"amount": "545.4204142199725",
"user": "0x20CD77B9FC2f1fEDfb6F184E25f7127BFE991C8b",
@@ -44357,8 +44463,8 @@
}
],
"total_tokens": "259998.8875",
"withdrawn_tokens": "143014.802273444948",
"remaining_tokens": "116984.085226555052"
"withdrawn_tokens": "143495.97418057557425",
"remaining_tokens": "116502.91331942442575"
},
{
"address": "0x89051CAb67Bc7F8CC44F7e270c6EDaf1EC57676c",
@@ -46703,8 +46809,8 @@
"tranche_start": "2021-11-05T00:00:00.000Z",
"tranche_end": "2023-05-05T00:00:00.000Z",
"total_added": "14597706.0446472999",
"total_removed": "5802489.518043560526965506",
"locked_amount": "848673.9247506211806821697552292785",
"total_removed": "5806817.570026167688715156",
"locked_amount": "842012.273182627684837560708413697",
"deposits": [
{
"amount": "129284.449",
@@ -46968,6 +47074,16 @@
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0xae9047ab72d73da1001c570a12dddc5e82fd523454c1b377928e008da9bdfa85"
},
{
"amount": "3666.3885480971028369",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
"tx": "0x54687b81b06562122894e34822a416021671c28f99066a23c5a69399b614409d"
},
{
"amount": "661.66343451005891275",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tx": "0x523cbf99fb25ac9633e40a26cf1aa66ac5442392e577299159bf50e844a860e1"
},
{
"amount": "755.482067130393772",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -50134,6 +50250,12 @@
"tranche_id": 3,
"tx": "0xae9047ab72d73da1001c570a12dddc5e82fd523454c1b377928e008da9bdfa85"
},
{
"amount": "661.66343451005891275",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
"tranche_id": 3,
"tx": "0x523cbf99fb25ac9633e40a26cf1aa66ac5442392e577299159bf50e844a860e1"
},
{
"amount": "755.482067130393772",
"user": "0x4Aa3c35F6CC2d507E5C18205ee57099A4C80B19b",
@@ -52812,8 +52934,8 @@
}
],
"total_tokens": "359123.469575",
"withdrawn_tokens": "337702.576476093841779",
"remaining_tokens": "21420.893098906158221"
"withdrawn_tokens": "338364.23991060390069175",
"remaining_tokens": "20759.22966439609930825"
},
{
"address": "0xBdd412797c1B78535Afc5F71503b91fAbD0160fB",
@@ -53073,6 +53195,12 @@
"tranche_id": 3,
"tx": "0x14811c8d77a39b0331cb2fdc96049b462916877050cc73143c494277304c2496"
},
{
"amount": "3666.3885480971028369",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
"tranche_id": 3,
"tx": "0x54687b81b06562122894e34822a416021671c28f99066a23c5a69399b614409d"
},
{
"amount": "80421.5336580481619385",
"user": "0x66827bCD635f2bB1779d68c46aEB16541bCA6ba8",
@@ -53405,8 +53533,8 @@
}
],
"total_tokens": "1266324.603486",
"withdrawn_tokens": "1189269.53625719263269252",
"remaining_tokens": "77055.06722880736730748"
"withdrawn_tokens": "1192935.92480528973552942",
"remaining_tokens": "73388.67868071026447058"
},
{
"address": "0xC5d9221EB9c28A69859264c0A2Fe0d3272228296",
@@ -54235,7 +54363,7 @@
"tranche_end": "2023-04-05T00:00:00.000Z",
"total_added": "5778205.3912159303",
"total_removed": "3381706.364737906998719578",
"locked_amount": "18412.7968659549219832486449580318",
"locked_amount": "15780.73804210722376807758479921058",
"deposits": [
{
"amount": "552496.6455",
@@ -56363,7 +56491,7 @@
"tranche_end": "2023-06-05T00:00:00.000Z",
"total_added": "472355.6199999996",
"total_removed": "40152.1324861581949",
"locked_amount": "81197.370889637811460062778488072",
"locked_amount": "80874.91808055103674607973921868",
"deposits": [
{
"amount": "3000",
@@ -95,6 +95,16 @@ describe('Console - market info - live env', { tags: '@live' }, () => {
cy.wrap(element).should('have.text', subtitles[index]);
});
});
it('renders correctly liquidity in trading tab', () => {
cy.getByTestId('Liquidity').click();
cy.contains('Loading').should('not.exist');
cy.contains('Something went wrong').should('not.exist');
cy.contains('Application error').should('not.exist');
cy.getByTestId('tab-liquidity').within(() => {
cy.get('[col-id="party.id"]').eq(1).should('not.be.empty');
});
});
});
describe('Console - market summary - live env', { tags: '@live' }, () => {
+41 -163
View File
@@ -1,5 +1,5 @@
import {
getId,
matchFilter,
liquidityProvisionsDataProvider,
LiquidityTable,
lpAggregatedDataProvider,
@@ -17,7 +17,6 @@ import {
useNetworkParams,
updateGridData,
} from '@vegaprotocol/react-helpers';
import * as Schema from '@vegaprotocol/types';
import {
AsyncRenderer,
Tab,
@@ -26,19 +25,18 @@ import {
Indicator,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { Header, HeaderStat, HeaderTitle } from '../../components/header';
import type { AgGridReact } from 'ag-grid-react';
import type { IGetRowsParams } from 'ag-grid-community';
import type { LiquidityProvisionData } from '@vegaprotocol/liquidity';
import type { LiquidityProvisionData, Filter } from '@vegaprotocol/liquidity';
import { Link, useParams } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list';
import isEqual from 'lodash/isEqual';
const enum LiquidityTabs {
Active = 'active',
@@ -67,8 +65,10 @@ const useReloadLiquidityData = (marketId: string | undefined) => {
export const LiquidityContainer = ({
marketId,
filter,
}: {
marketId: string | undefined;
filter?: Filter;
}) => {
const gridRef = useRef<AgGridReact | null>(null);
const { data: market } = useMarket(marketId);
@@ -87,7 +87,7 @@ export const LiquidityContainer = ({
const { data, loading, error } = useDataProvider({
dataProvider: lpAggregatedDataProvider,
update,
variables: { marketId: marketId || '' },
variables: { marketId: marketId || '', filter },
skip: !marketId,
});
@@ -216,178 +216,56 @@ const LiquidityViewHeader = memo(({ marketId }: { marketId?: string }) => {
});
LiquidityViewHeader.displayName = 'LiquidityViewHeader';
const filterLiquidities = (
tab: string,
liquidities?: LiquidityProvisionData[] | null,
pubKey?: string | null
) => {
switch (tab) {
case LiquidityTabs.MyLiquidityProvision:
return pubKey
? (liquidities || []).filter((e) => e.party.id === pubKey)
: [];
break;
case LiquidityTabs.Active:
return (liquidities || []).filter(
(e) => e.status === Schema.LiquidityProvisionStatus.STATUS_ACTIVE
);
case LiquidityTabs.Inactive:
return (liquidities || []).filter(
(e) => e.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE
);
default:
return [];
}
};
export const LiquidityViewContainer = ({
marketId,
}: {
marketId: string | undefined;
}) => {
const [tab, setTab] = useState('');
const [tab, setTab] = useState<string | undefined>(undefined);
const { pubKey } = useVegaWallet();
const [liquidityProviders, setLiquidityProviders] = useState<
LiquidityProvisionData[] | null
>();
const gridRef = useRef<AgGridReact | null>(null);
const { data: market } = useMarket(marketId);
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
// To be removed when liquidityProvision subscriptions are working
useReloadLiquidityData(marketId);
const update = useCallback(
({ data }: { data: LiquidityProvisionData[] | null }) => {
if (!dataRef.current) {
setLiquidityProviders(data);
dataRef.current = data;
}
if (!gridRef.current?.api) {
return false;
}
const updateRows: LiquidityProvisionData[] = [];
const addRows: LiquidityProvisionData[] = [];
if (gridRef.current?.api?.getModel().getType() === 'infinite') {
dataRef.current = data;
gridRef.current.api.refreshInfiniteCache();
} else {
const filteredData = filterLiquidities(tab, data, pubKey as string);
filteredData?.forEach((d) => {
const rowNode = gridRef.current?.api?.getRowNode(getId(d));
if (rowNode) {
if (!isEqual(rowNode.data, d)) {
updateRows.push(d);
}
} else {
addRows.push(d);
}
});
gridRef.current?.api?.applyTransaction({
update: updateRows,
add: addRows,
addIndex: 0,
});
}
return true;
},
[gridRef, tab, pubKey]
);
const { loading, error } = useDataProvider({
const { data } = useDataProvider({
dataProvider: lpAggregatedDataProvider,
update,
skipUpdates: true,
variables: { marketId: marketId || '' },
skip: !marketId,
});
const assetDecimalPlaces =
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
const symbol =
market?.tradableInstrument.instrument.product.settlementAsset.symbol;
const { params } = useNetworkParams([
NetworkParams.market_liquidity_stakeToCcyVolume,
NetworkParams.market_liquidity_targetstake_triggering_ratio,
]);
const stakeToCcyVolume = params.market_liquidity_stakeToCcyVolume;
const myLpEdges = useMemo(
() =>
filterLiquidities(
LiquidityTabs.MyLiquidityProvision,
liquidityProviders,
pubKey
),
[liquidityProviders, pubKey]
);
const activeEdges = useMemo(
() => filterLiquidities(LiquidityTabs.Active, liquidityProviders),
[liquidityProviders]
);
const inactiveEdges = useMemo(
() => filterLiquidities(LiquidityTabs.Inactive, liquidityProviders),
[liquidityProviders]
);
useEffect(() => {
if (tab) {
return;
if (data) {
if (pubKey && data.some((lp) => matchFilter({ partyId: pubKey }, lp))) {
setTab(LiquidityTabs.MyLiquidityProvision);
return;
}
if (data.some((lp) => matchFilter({ active: true }, lp))) {
setTab(LiquidityTabs.Active);
return;
}
setTab(LiquidityTabs.Inactive);
}
let initialTab = LiquidityTabs.Active;
if (myLpEdges.length > 0) {
initialTab = LiquidityTabs.MyLiquidityProvision;
}
if (activeEdges?.length) {
initialTab = LiquidityTabs.Active;
} else if (inactiveEdges.length > 0) {
initialTab = LiquidityTabs.Inactive;
}
setTab(initialTab);
}, [tab, myLpEdges?.length, activeEdges?.length, inactiveEdges?.length]);
}, [data, pubKey]);
return (
<AsyncRenderer loading={loading} error={error} data={liquidityProviders}>
<div className="h-full grid grid-rows-[min-content_1fr]">
<LiquidityViewHeader marketId={marketId} />
<Tabs value={tab} onValueChange={setTab}>
<Tab
id={LiquidityTabs.MyLiquidityProvision}
name={t('My liquidity provision')}
hidden={!pubKey}
>
{myLpEdges && (
<LiquidityTable
ref={gridRef}
rowData={myLpEdges}
symbol={symbol}
stakeToCcyVolume={stakeToCcyVolume}
assetDecimalPlaces={assetDecimalPlaces}
/>
)}
</Tab>
<Tab id={LiquidityTabs.Active} name={t('Active')}>
{activeEdges && (
<LiquidityTable
ref={gridRef}
rowData={activeEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
stakeToCcyVolume={stakeToCcyVolume}
/>
)}
</Tab>
<Tab id={LiquidityTabs.Inactive} name={t('Inactive')}>
{inactiveEdges && (
<LiquidityTable
ref={gridRef}
rowData={inactiveEdges}
symbol={symbol}
assetDecimalPlaces={assetDecimalPlaces}
stakeToCcyVolume={stakeToCcyVolume}
/>
)}
</Tab>
</Tabs>
</div>
</AsyncRenderer>
<div className="h-full grid grid-rows-[min-content_1fr]">
<LiquidityViewHeader marketId={marketId} />
<Tabs value={tab || LiquidityTabs.Active} onValueChange={setTab}>
<Tab
id={LiquidityTabs.MyLiquidityProvision}
name={t('My liquidity provision')}
hidden={!pubKey}
>
<LiquidityContainer
marketId={marketId}
filter={{ partyId: pubKey || undefined }}
/>
</Tab>
<Tab id={LiquidityTabs.Active} name={t('Active')}>
<LiquidityContainer marketId={marketId} filter={{ active: true }} />
</Tab>
<Tab id={LiquidityTabs.Inactive} name={t('Inactive')}>
<LiquidityContainer marketId={marketId} filter={{ active: false }} />
</Tab>
</Tabs>
</div>
);
};
+15 -3
View File
@@ -1,10 +1,22 @@
#!/bin/sh -eux
#!/bin/bash -ex
export PATH="/app/node_modules/.bin:$PATH"
flags="--network-timeout 100000 --pure-lockfile"
if [[ ! -z "${ENV_NAME}" ]]; then
flags="--env=${ENV_NAME} $flags"
fi
if [ "${APP}" = "trading" ]; then
yarn nx export ${APP} --network-timeout 100000 --pure-lockfile
yarn nx export ${APP} $flags
mv /app/dist/apps/trading/exported/ /app/tmp
rm -rf /app/dist/apps/trading
mv /app/tmp /app/dist/apps/trading
else
yarn nx build ${APP} --network-timeout 100000 --pure-lockfile
yarn nx build ${APP} $flags
fi
env_vars_file="/app/dist/apps/${APP}/.env"
# make sure there are no exposed .env files
rm $env_vars_file || echo "No env vars file"
-43
View File
@@ -1,43 +0,0 @@
#!/bin/bash
set -e
# Recreate config file
env_file=/usr/share/nginx/html/assets/env-config.js
mkdir -p $(dirname $env_file)
rm -rf $env_file || echo "no file to delete"
touch $env_file
env_vars_file=/usr/share/nginx/html/.env
sed -i '/^#/d' $env_vars_file # remove comment lines
sed -i '/^$/d' $env_vars_file # remove empty lines
# Add assignment
echo "window._env_ = {" >> $env_file
# Read each line in .env file
# Each line represents key=value pairs
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
fi
# Read value of current variable if exists as Environment variable
value=$(printf '%s\n' "${!varname}")
# Otherwise use value from .env file
[[ -z $value ]] && value=${varvalue}
# Append configuration property to JS file if non-empty
if [ ! -z "$varname" ]; then
echo " $varname: \"$value\"," >> $env_file
fi
done < $env_vars_file
rm $env_vars_file
echo "}" >> $env_file
# start serving
nginx -g 'daemon off;'
@@ -1,4 +1,5 @@
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import classnames from 'classnames';
import type { ReactNode } from 'react';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import type { Market, MarketData } from '@vegaprotocol/market-list';
@@ -11,9 +12,12 @@ interface DealTicketFeeDetailsProps {
order: OrderSubmissionBody['orderSubmission'];
market: Market;
marketData: MarketData;
margin: string;
totalMargin: string;
balance: string;
currentInitialMargin?: string;
currentMaintenanceMargin?: string;
estimatedInitialMargin: string;
estimatedTotalInitialMargin: string;
marginAccountBalance: string;
generalAccountBalance: string;
}
export interface DealTicketFeeDetailProps {
@@ -45,23 +49,22 @@ export const DealTicketFeeDetails = ({
order,
market,
marketData,
margin,
totalMargin,
balance,
...args
}: DealTicketFeeDetailsProps) => {
const feeDetails = useFeeDealTicketDetails(order, market, marketData);
const details = getFeeDetailsValues({
...feeDetails,
margin,
totalMargin,
balance,
...args,
});
return (
<div>
{details.map(({ label, value, labelDescription, symbol }) => (
{details.map(({ label, value, labelDescription, symbol, indent }) => (
<div
key={typeof label === 'string' ? label : 'value-dropdown'}
className="text-xs mt-2 flex justify-between items-center gap-4 flex-wrap"
className={classnames(
'text-xs mt-2 flex justify-between items-center gap-4 flex-wrap',
{ 'ml-2': indent }
)}
>
<div>
<Tooltip description={labelDescription}>
@@ -44,6 +44,9 @@ import {
import { OrderTimeInForce, OrderType } from '@vegaprotocol/types';
import { useOrderForm } from '../../hooks/use-order-form';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { marketMarginDataProvider } from '@vegaprotocol/positions';
export interface DealTicketProps {
market: Market;
@@ -103,6 +106,12 @@ export const DealTicket = ({
const { margin, totalMargin } = useInitialMargin(market.id, normalizedOrder);
const { data: currentMargins } = useDataProvider({
dataProvider: marketMarginDataProvider,
variables: { marketId: market.id, partyId: pubKey || '' },
skip: !pubKey,
});
useEffect(() => {
if (!pubKey) {
setError('summary', {
@@ -367,9 +376,12 @@ export const DealTicket = ({
order={normalizedOrder}
market={market}
marketData={marketData}
margin={margin}
totalMargin={totalMargin}
balance={marginAccountBalance}
estimatedInitialMargin={margin}
estimatedTotalInitialMargin={totalMargin}
currentInitialMargin={currentMargins?.initialLevel}
currentMaintenanceMargin={currentMargins?.maintenanceLevel}
marginAccountBalance={marginAccountBalance}
generalAccountBalance={generalAccountBalance}
/>
</form>
</TinyScroll>
+26 -2
View File
@@ -10,12 +10,36 @@ export const EST_MARGIN_TOOLTIP_TEXT = (settlementAsset: string) =>
export const EST_TOTAL_MARGIN_TOOLTIP_TEXT = t(
'Estimated total margin that will cover open position, active orders and this order.'
);
export const MARGIN_ACCOUNT_TOOLTIP_TEXT = t('Margin account balance');
export const MARGIN_ACCOUNT_TOOLTIP_TEXT = t('Margin account balance.');
export const MARGIN_DIFF_TOOLTIP_TEXT = (settlementAsset: string) =>
t(
"The additional margin required for your new position (taking into account volume and open orders), compared to your current margin. Measured in the market's settlement asset (%s).",
[settlementAsset]
);
export const DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT = (
settlementAsset: string
) =>
t(
'To cover the required margin, this amount will be drawn from your general (%s) account.',
[settlementAsset]
);
export const TOTAL_MARGIN_AVAILABLE = (
generalAccountBalance: string,
marginAccountBalance: string,
marginMaintenance: string,
settlementAsset: string
) =>
t(
'Total margin available = general %s balance (%s) + margin balance (%s) - maintenance level (%s).',
[
settlementAsset,
`${generalAccountBalance} ${settlementAsset}`,
`${marginAccountBalance} ${settlementAsset}`,
`${marginMaintenance} ${settlementAsset}`,
]
);
export const CONTRACTS_MARGIN_TOOLTIP_TEXT = t(
'The number of contracts determines how many units of the futures contract to buy or sell. For example, this is similar to buying one share of a listed company. The value of 1 contract is equivalent to the price of the contract. For example, if the current price is $50, then one contract is worth $50.'
);
@@ -40,7 +64,7 @@ export const EST_SLIPPAGE = t(
);
export const ERROR_SIZE_DECIMAL = t(
'The size field accepts up to X decimal places'
'The size field accepts up to X decimal places.'
);
export enum MarketModeValidationType {
@@ -15,6 +15,8 @@ import {
NOTIONAL_SIZE_TOOLTIP_TEXT,
MARGIN_ACCOUNT_TOOLTIP_TEXT,
MARGIN_DIFF_TOOLTIP_TEXT,
DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT,
TOTAL_MARGIN_AVAILABLE,
} from '../constants';
import { useOrderCloseOut } from './use-order-closeout';
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
@@ -85,24 +87,32 @@ export const useFeeDealTicketDetails = (
};
export interface FeeDetails {
balance: string;
generalAccountBalance?: string;
marginAccountBalance?: string;
market: Market;
assetSymbol: string;
notionalSize: string | null;
estCloseOut: string | null;
estimateOrder: EstimateOrderQuery['estimateOrder'] | undefined;
margin: string;
totalMargin: string;
estimatedInitialMargin: string;
estimatedTotalInitialMargin: string;
currentInitialMargin?: string;
currentMaintenanceMargin?: string;
}
export const getFeeDetailsValues = ({
balance,
marginAccountBalance,
generalAccountBalance,
assetSymbol,
estimateOrder,
market,
notionalSize,
totalMargin,
estimatedTotalInitialMargin,
currentInitialMargin,
currentMaintenanceMargin,
}: FeeDetails) => {
const totalBalance =
BigInt(generalAccountBalance || '0') + BigInt(marginAccountBalance || '0');
const assetDecimals =
market.tradableInstrument.instrument.product.settlementAsset.decimals;
const formatValueWithMarketDp = (
@@ -123,7 +133,8 @@ export const getFeeDetailsValues = ({
label: string;
value?: string | null;
symbol: string;
labelDescription: React.ReactNode;
indent?: boolean;
labelDescription?: React.ReactNode;
}[] = [
{
label: t('Notional'),
@@ -153,38 +164,64 @@ export const getFeeDetailsValues = ({
),
symbol: assetSymbol,
},
/*
{
label: t('Initial margin'),
value: margin && `~${formatValueWithAssetDp(margin)}`,
symbol: assetSymbol,
labelDescription: EST_MARGIN_TOOLTIP_TEXT(assetSymbol),
},
*/
{
label: t('Margin required'),
value: `~${formatValueWithAssetDp(
balance
? (BigInt(totalMargin) - BigInt(balance)).toString()
: totalMargin
currentInitialMargin
? (
BigInt(estimatedTotalInitialMargin) - BigInt(currentInitialMargin)
).toString()
: estimatedTotalInitialMargin
)}`,
symbol: assetSymbol,
labelDescription: MARGIN_DIFF_TOOLTIP_TEXT(assetSymbol),
},
];
if (balance) {
if (totalBalance) {
const totalMarginAvailable = (
currentMaintenanceMargin
? totalBalance - BigInt(currentMaintenanceMargin)
: totalBalance
).toString();
details.push({
indent: true,
label: t('Total margin available'),
value: `~${formatValueWithAssetDp(totalMarginAvailable)}`,
symbol: assetSymbol,
labelDescription: TOTAL_MARGIN_AVAILABLE(
formatValueWithAssetDp(generalAccountBalance),
formatValueWithAssetDp(marginAccountBalance),
formatValueWithAssetDp(currentMaintenanceMargin),
assetSymbol
),
});
if (marginAccountBalance) {
const deductionFromCollateral =
BigInt(estimatedTotalInitialMargin) - BigInt(marginAccountBalance);
details.push({
indent: true,
label: t('Deduction from collateral'),
value: `~${formatValueWithAssetDp(
deductionFromCollateral > 0 ? deductionFromCollateral.toString() : '0'
)}`,
symbol: assetSymbol,
labelDescription: DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT(assetSymbol),
});
}
details.push({
label: t('Projected margin'),
value: `~${formatValueWithAssetDp(totalMargin)}`,
value: `~${formatValueWithAssetDp(estimatedTotalInitialMargin)}`,
symbol: assetSymbol,
labelDescription: EST_TOTAL_MARGIN_TOOLTIP_TEXT,
});
}
details.push({
label: t('Current margin allocation'),
value: balance
? `~${formatValueWithAssetDp(balance)}`
: `${formatValueWithAssetDp(balance)}`,
value: `${formatValueWithAssetDp(marginAccountBalance)}`,
symbol: assetSymbol,
labelDescription: MARGIN_ACCOUNT_TOOLTIP_TEXT,
});
@@ -65,5 +65,11 @@ export const useInitialMargin = (
sellMargin > buyMargin ? sellMargin.toString() : buyMargin.toString();
}
return useMemo(() => ({ totalMargin, margin }), [totalMargin, margin]);
return useMemo(
() => ({
totalMargin,
margin,
}),
[totalMargin, margin]
);
};
+6 -29
View File
@@ -7,7 +7,6 @@ import type { Trade } from './fills-data-provider';
import { FillsTable, getFeesBreakdown } from './fills-table';
import { generateFill } from './test-helpers';
import { MemoryRouter } from 'react-router-dom';
describe('FillsTable', () => {
let defaultFill: PartialDeep<Trade>;
@@ -37,11 +36,7 @@ describe('FillsTable', () => {
it('correct columns are rendered', async () => {
await act(async () => {
render(
<MemoryRouter>
<FillsTable partyId="party-id" rowData={[generateFill()]} />
</MemoryRouter>
);
render(<FillsTable partyId="party-id" rowData={[generateFill()]} />);
});
const headers = screen.getAllByRole('columnheader');
@@ -72,11 +67,7 @@ describe('FillsTable', () => {
liquidityFee: '2',
},
});
render(
<MemoryRouter>
<FillsTable partyId={partyId} rowData={[{ ...buyerFill }]} />
</MemoryRouter>
);
render(<FillsTable partyId={partyId} rowData={[{ ...buyerFill }]} />);
const cells = screen.getAllByRole('gridcell');
const expectedValues = [
buyerFill.market?.tradableInstrument.instrument.name || '',
@@ -109,11 +100,7 @@ describe('FillsTable', () => {
liquidityFee: '1',
},
});
render(
<MemoryRouter>
<FillsTable partyId={partyId} rowData={[buyerFill]} />
</MemoryRouter>
);
render(<FillsTable partyId={partyId} rowData={[buyerFill]} />);
const cells = screen.getAllByRole('gridcell');
const expectedValues = [
@@ -142,9 +129,7 @@ describe('FillsTable', () => {
aggressor: Schema.Side.SIDE_SELL,
});
const { rerender } = render(
<MemoryRouter>
<FillsTable partyId={partyId} rowData={[takerFill]} />
</MemoryRouter>
<FillsTable partyId={partyId} rowData={[takerFill]} />
);
expect(
screen
@@ -158,11 +143,7 @@ describe('FillsTable', () => {
},
aggressor: Schema.Side.SIDE_BUY,
});
rerender(
<MemoryRouter>
<FillsTable partyId={partyId} rowData={[makerFill]} />
</MemoryRouter>
);
rerender(<FillsTable partyId={partyId} rowData={[makerFill]} />);
expect(
screen
@@ -179,11 +160,7 @@ describe('FillsTable', () => {
},
aggressor: Schema.Side.SIDE_SELL,
});
render(
<MemoryRouter>
<FillsTable partyId={partyId} rowData={[takerFill]} />
</MemoryRouter>
);
render(<FillsTable partyId={partyId} rowData={[takerFill]} />);
const feeCell = screen
.getAllByRole('gridcell')
@@ -153,35 +153,84 @@ export const liquidityFeeShareDataProvider = makeDataProvider<
},
});
export type Filter = { partyId?: string; active?: boolean };
export const lpAggregatedDataProvider = makeDerivedDataProvider<
ReturnType<typeof getLiquidityProvision>,
LiquidityProvisionData[],
never,
MarketLpQueryVariables
MarketLpQueryVariables & { filter?: Filter }
>(
[
liquidityProvisionsDataProvider,
marketLiquidityDataProvider,
liquidityFeeShareDataProvider,
(callback, client, variables) =>
liquidityProvisionsDataProvider(callback, client, {
marketId: variables.marketId,
}),
(callback, client, variables) =>
marketLiquidityDataProvider(callback, client, {
marketId: variables.marketId,
}),
(callback, client, variables) =>
liquidityFeeShareDataProvider(callback, client, {
marketId: variables.marketId,
}),
],
([
liquidityProvisions,
marketLiquidity,
liquidityFeeShare,
]): LiquidityProvisionData[] => {
(
[liquidityProvisions, marketLiquidity, liquidityFeeShare],
{ filter }
): LiquidityProvisionData[] => {
return getLiquidityProvision(
liquidityProvisions,
marketLiquidity,
liquidityFeeShare
liquidityFeeShare,
filter
);
}
);
export const matchFilter = (
filter: Filter,
lp: LiquidityProvisionFieldsFragment
) => {
if (filter.partyId && lp.party.id !== filter.partyId) {
return false;
}
if (
filter.active === true &&
lp.status !== Schema.LiquidityProvisionStatus.STATUS_ACTIVE
) {
return false;
}
if (
filter.active === false &&
lp.status === Schema.LiquidityProvisionStatus.STATUS_ACTIVE
) {
return false;
}
return true;
};
export const getLiquidityProvision = (
liquidityProvisions: LiquidityProvisionFieldsFragment[],
marketLiquidity: MarketLpQuery,
liquidityFeeShare: LiquidityProviderFeeShareFieldsFragment[]
liquidityFeeShare: LiquidityProviderFeeShareFieldsFragment[],
filter?: Filter
): LiquidityProvisionData[] => {
return liquidityProvisions
.filter((lp) => {
if (
![
Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
Schema.LiquidityProvisionStatus.STATUS_UNDEPLOYED,
Schema.LiquidityProvisionStatus.STATUS_PENDING,
].includes(lp.status)
) {
return false;
}
if (filter && !matchFilter(filter, lp)) {
return false;
}
return true;
})
.map((lp) => {
const market = marketLiquidity?.market;
const feeShare = liquidityFeeShare.find(
@@ -210,14 +259,7 @@ export const getLiquidityProvision = (
.decimals,
balance,
};
})
.filter((e) =>
[
Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
Schema.LiquidityProvisionStatus.STATUS_UNDEPLOYED,
Schema.LiquidityProvisionStatus.STATUS_PENDING,
].includes(e.status)
);
});
};
export interface LiquidityProvisionData
@@ -13,7 +13,6 @@ import {
limitOrder,
marketOrder,
} from '../mocks/generate-orders';
import { MemoryRouter } from 'react-router-dom';
// Mock theme switcher to get around inconsistent mocking of zustand
// stores
@@ -37,11 +36,9 @@ const generateJsx = (
) => {
return (
<MockedProvider>
<MemoryRouter>
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
<OrderListTable {...defaultProps} {...props} />
</VegaWalletContext.Provider>
</MemoryRouter>
<VegaWalletContext.Provider value={context as VegaWalletContextShape}>
<OrderListTable {...defaultProps} {...props} />
</VegaWalletContext.Provider>
</MockedProvider>
);
};
+5 -8
View File
@@ -1,8 +1,7 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCallback, useRef, useState } from 'react';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { Position } from '../';
import { usePositionsData, PositionsTable } from '../';
import type { FilterChangedEvent } from 'ag-grid-community';
import type { AgGridReact } from 'ag-grid-react';
import * as Schema from '@vegaprotocol/types';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
@@ -23,8 +22,8 @@ export const PositionsManager = ({
noBottomPlaceholder,
}: PositionsManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const [dataCount, setDataCount] = useState(0);
const { data, error, loading, reload } = usePositionsData(partyId, gridRef);
const [dataCount, setDataCount] = useState(data?.length ?? 0);
const create = useVegaTransactionStore((store) => store.create);
const onClose = ({
marketId,
@@ -67,10 +66,7 @@ export const PositionsManager = ({
setId,
disabled: noBottomPlaceholder,
});
useEffect(() => {
setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0);
}, [data]);
const onFilterChanged = useCallback((event: FilterChangedEvent) => {
const updateRowCount = useCallback(() => {
setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0);
}, []);
return (
@@ -83,7 +79,8 @@ export const PositionsManager = ({
suppressLoadingOverlay
suppressNoRowsOverlay
isReadOnly={isReadOnly}
onFilterChanged={onFilterChanged}
onFilterChanged={updateRowCount}
onRowDataUpdated={updateRowCount}
{...bottomPlaceholderProps}
/>
<div className="pointer-events-none absolute inset-0">
+37 -76
View File
@@ -6,7 +6,6 @@ import type { Position } from './positions-data-providers';
import * as Schema from '@vegaprotocol/types';
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
import type { ICellRendererParams } from 'ag-grid-community';
import { MemoryRouter } from 'react-router-dom';
const singleRow: Position = {
marketName: 'ETH/BTC (31 july 2022)',
@@ -38,9 +37,7 @@ const singleRowData = [singleRow];
it('should render successfully', async () => {
await act(async () => {
const { baseElement } = render(
<MemoryRouter>
<PositionsTable rowData={[]} isReadOnly={false} />
</MemoryRouter>
<PositionsTable rowData={[]} isReadOnly={false} />
);
expect(baseElement).toBeTruthy();
});
@@ -48,11 +45,7 @@ it('should render successfully', async () => {
it('render correct columns', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={true} />
</MemoryRouter>
);
render(<PositionsTable rowData={singleRowData} isReadOnly={true} />);
});
const headers = screen.getAllByRole('columnheader');
@@ -76,11 +69,7 @@ it('render correct columns', async () => {
it('renders market name', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
);
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
expect(screen.getByText('ETH/BTC (31 july 2022)')).toBeTruthy();
});
@@ -91,11 +80,7 @@ it('Does not fail if the market name does not match the split pattern', async ()
Object.assign({}, singleRow, { marketName: breakingMarketName }),
];
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={row} isReadOnly={false} />
</MemoryRouter>
);
render(<PositionsTable rowData={row} isReadOnly={false} />);
});
expect(screen.getByText(breakingMarketName)).toBeTruthy();
@@ -105,9 +90,7 @@ it('add color and sign to amount, displays positive notional value', async () =>
let result: RenderResult;
await act(async () => {
result = render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
);
});
let cells = screen.getAllByRole('gridcell');
@@ -118,12 +101,10 @@ it('add color and sign to amount, displays positive notional value', async () =>
expect(cells[1].textContent).toEqual('1,230.0');
await act(async () => {
result.rerender(
<MemoryRouter>
<PositionsTable
rowData={[{ ...singleRow, openVolume: '-100' }]}
isReadOnly={false}
/>
</MemoryRouter>
<PositionsTable
rowData={[{ ...singleRow, openVolume: '-100' }]}
isReadOnly={false}
/>
);
});
cells = screen.getAllByRole('gridcell');
@@ -137,9 +118,7 @@ it('displays mark price', async () => {
let result: RenderResult;
await act(async () => {
result = render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
);
});
@@ -148,18 +127,16 @@ it('displays mark price', async () => {
await act(async () => {
result.rerender(
<MemoryRouter>
<PositionsTable
rowData={[
{
...singleRow,
marketTradingMode:
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
},
]}
isReadOnly={false}
/>
</MemoryRouter>
<PositionsTable
rowData={[
{
...singleRow,
marketTradingMode:
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
},
]}
isReadOnly={false}
/>
);
});
@@ -169,11 +146,7 @@ it('displays mark price', async () => {
it('displays leverage', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
);
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[6].textContent).toEqual('1.1');
@@ -181,11 +154,7 @@ it('displays leverage', async () => {
it('displays allocated margin', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
);
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
const cell = cells[7];
@@ -194,11 +163,7 @@ it('displays allocated margin', async () => {
it('displays realised and unrealised PNL', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable rowData={singleRowData} isReadOnly={false} />
</MemoryRouter>
);
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
});
const cells = screen.getAllByRole('gridcell');
expect(cells[9].textContent).toEqual('4.56');
@@ -207,15 +172,13 @@ it('displays realised and unrealised PNL', async () => {
it('displays close button', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable
rowData={singleRowData}
onClose={() => {
return;
}}
isReadOnly={false}
/>
</MemoryRouter>
<PositionsTable
rowData={singleRowData}
onClose={() => {
return;
}}
isReadOnly={false}
/>
);
});
const cells = screen.getAllByRole('gridcell');
@@ -225,15 +188,13 @@ it('displays close button', async () => {
it('do not display close button if openVolume is zero', async () => {
await act(async () => {
render(
<MemoryRouter>
<PositionsTable
rowData={[{ ...singleRow, openVolume: '0' }]}
onClose={() => {
return;
}}
isReadOnly={false}
/>
</MemoryRouter>
<PositionsTable
rowData={[{ ...singleRow, openVolume: '0' }]}
onClose={() => {
return;
}}
isReadOnly={false}
/>
);
});
const cells = screen.getAllByRole('gridcell');