Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c81c5f895 | ||
|
|
898d3a329f | ||
|
|
90b38478ae | ||
|
|
f1b8d613bf | ||
|
|
e3c8e0359f | ||
|
|
96fcd285f5 | ||
|
|
e82e4f91ac | ||
|
|
127467bdd0 | ||
|
|
0e87d7acbc | ||
|
|
45ae5cd781 | ||
|
|
f837ed37f2 | ||
|
|
904bdc11a9 | ||
|
|
594eb0aa28 | ||
|
|
284756decc | ||
|
|
3b88fd6926 | ||
|
|
99f16e9882 | ||
|
|
c27edced16 | ||
|
|
d91b100d42 | ||
|
|
906fc2a241 | ||
|
|
92d6999c1f | ||
|
|
43f46aa94a | ||
|
|
2c5cc66706 | ||
|
|
9fa2ee6351 | ||
|
|
1c3dd1daf6 | ||
|
|
bb2f7fa33c | ||
|
|
5433b7ee01 | ||
|
|
49117bf9d5 | ||
|
|
871c6907ac | ||
|
|
eca2005c44 | ||
|
|
fd5454faf5 | ||
|
|
c9feb63b9a | ||
|
|
33f50ea8dc | ||
|
|
d52577f2e6 | ||
|
|
22dc12149b | ||
|
|
9442fe2012 | ||
|
|
8c19d99b6b | ||
|
|
0d9c0e396c | ||
|
|
9f88c7e031 |
@@ -1,6 +1,18 @@
|
||||
outputs:
|
||||
token:
|
||||
description: 'api-token of wallet'
|
||||
value: ${{ steps.generate-api-token.outputs.api-token }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Vegacapsule version
|
||||
shell: bash
|
||||
run: vegacapsule version
|
||||
|
||||
- name: Vega wallet version
|
||||
shell: bash
|
||||
run: vega wallet software version
|
||||
|
||||
- name: Start nomad
|
||||
shell: bash
|
||||
run: vegacapsule nomad &
|
||||
@@ -8,3 +20,32 @@ runs:
|
||||
- name: Bootstrap network
|
||||
shell: bash
|
||||
run: vegacapsule network bootstrap --config-path=./frontend-monorepo/vegacapsule/config.hcl --force
|
||||
|
||||
- name: Initialize wallet
|
||||
shell: bash
|
||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import wallet
|
||||
shell: bash
|
||||
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Generate second public key
|
||||
shell: bash
|
||||
run: vega wallet key generate -w capsule_wallet -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import network
|
||||
shell: bash
|
||||
run: vega wallet network import --force --from-file ./frontend-monorepo/vegacapsule/wallet-config.toml --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Init api-token
|
||||
shell: bash
|
||||
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file ./frontend-monorepo/vegacapsule/passphrase
|
||||
|
||||
- name: Generate api-token
|
||||
id: generate-api-token
|
||||
shell: bash
|
||||
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --wallet-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Start service using capsule network
|
||||
shell: bash
|
||||
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
outputs:
|
||||
token:
|
||||
description: 'api-token of wallet'
|
||||
value: ${{ steps.generate-api-token.outputs.api-token }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Initialize wallet
|
||||
shell: bash
|
||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import wallet
|
||||
shell: bash
|
||||
run: vega wallet import -w capsule_wallet --recovery-phrase-file ./frontend-monorepo/vegacapsule/recovery -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Generate second public key
|
||||
shell: bash
|
||||
run: vega wallet key generate -w capsule_wallet -p ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import network
|
||||
shell: bash
|
||||
run: vega wallet network import --force --from-file ./frontend-monorepo/vegacapsule/wallet-config.toml --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Init api-token
|
||||
shell: bash
|
||||
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file ./frontend-monorepo/vegacapsule/passphrase
|
||||
|
||||
- name: Generate api-token
|
||||
id: generate-api-token
|
||||
shell: bash
|
||||
run: echo api-token=$(vega wallet api-token generate --wallet-name capsule_wallet --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --wallet-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Start service using capsule network
|
||||
shell: bash
|
||||
run: vega wallet service run -n DV --load-tokens --tokens-passphrase-file ./frontend-monorepo/vegacapsule/passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
@@ -1,48 +0,0 @@
|
||||
inputs:
|
||||
recovery:
|
||||
description: 'Recovery phrase'
|
||||
passphrase:
|
||||
description: 'Wallet password'
|
||||
outputs:
|
||||
token:
|
||||
description: 'api-token of wallet'
|
||||
value: ${{ steps.generate-api-token.outputs.api-token }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Create passphrase
|
||||
shell: bash
|
||||
run: echo "${{ inputs.passphrase }}" > ./passphrase
|
||||
|
||||
- name: Create recovery
|
||||
shell: bash
|
||||
run: echo "${{ inputs.recovery }}" > ./recovery
|
||||
|
||||
- name: Initialize wallet
|
||||
shell: bash
|
||||
run: vega wallet init -f --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import wallet
|
||||
shell: bash
|
||||
run: vega wallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Create public key 2
|
||||
shell: bash
|
||||
run: vega wallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Import network
|
||||
shell: bash
|
||||
run: vega wallet network import --from-url="https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml" --force --home ~/.vegacapsule/testnet/wallet
|
||||
|
||||
- name: Init api-token
|
||||
shell: bash
|
||||
run: vega wallet api-token init --home ~/.vegacapsule/testnet/wallet --passphrase-file passphrase
|
||||
|
||||
- name: Generate api-token
|
||||
id: generate-api-token
|
||||
shell: bash
|
||||
run: echo api-token=$(vega wallet api-token generate --wallet-name UI_Trading_Test --tokens-passphrase-file passphrase --wallet-passphrase-file passphrase --home ~/.vegacapsule/testnet/wallet | grep -Eo '[a-zA-Z0-9]{64}') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Start service using stagnet3 network
|
||||
shell: bash
|
||||
run: vega wallet service run -n stagnet3 --load-tokens --tokens-passphrase-file passphrase --no-version-check --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
@@ -1,49 +0,0 @@
|
||||
name: Cypress tests -- manual trigger
|
||||
|
||||
# This workflow runs the frontend tests against chosen branch
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
project:
|
||||
description: 'Project'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- explorer-e2e
|
||||
- token-e2e
|
||||
- trading-e2e
|
||||
tags:
|
||||
description: 'Test tags to run'
|
||||
required: true
|
||||
type: string
|
||||
default: '@smoke, @regression, @slow'
|
||||
skip-nx-cache:
|
||||
description: 'Add --skip-nx-cache to cypress test'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
jobs:
|
||||
manual:
|
||||
name: Run Cypress tests -- manual trigger
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set tags
|
||||
run: echo TAGS="--env.grepTags '[ ${{ github.event.inputs.tags }} ]'" >> $GITHUB_ENV
|
||||
|
||||
- name: Set --skip-nx-cache flag
|
||||
if: ${{ github.event.inputs.skip-nx-cache == 'true' }}
|
||||
run: echo SKIP_NX_CACHE="--skip-nx-cache" >> $GITHUB_ENV
|
||||
|
||||
outputs:
|
||||
skip-cache: ${{env.SKIP_NX_CACHE}}
|
||||
tags: ${{env.TAGS}}
|
||||
|
||||
dispatch:
|
||||
needs: manual
|
||||
uses: ./.github/workflows/tests-dispatcher.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
project: ${{ inputs.project }}
|
||||
skip-cache: ${{needs.manual.outputs.skip-cache}}
|
||||
tags: ${{needs.manual.outputs.tags}}
|
||||
@@ -1,17 +0,0 @@
|
||||
name: Cypress tests -- night run
|
||||
|
||||
# This workflow runs the frontend tests against latest develop of the core to preempt breaking changes
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 4 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
nightly:
|
||||
uses: ./.github/workflows/tests-dispatcher.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
project: '[explorer-e2e, token-e2e, trading-e2e]'
|
||||
tags: --env.grepTags '[ @smoke, @regression, @slow ]'
|
||||
night-run: true
|
||||
@@ -1,61 +0,0 @@
|
||||
name: Cypress tests - PR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
jobs:
|
||||
pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: './frontend-monorepo'
|
||||
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock', 'frontend-monorepo/package.json') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
# Check SHAs
|
||||
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||
uses: nrwl/nx-set-shas@v2
|
||||
with:
|
||||
working-directory: frontend-monorepo
|
||||
main-branch-name: ${{ github.base_ref || github.ref_name }}
|
||||
set-environment-variables-for-job: true
|
||||
|
||||
# See affected projects
|
||||
- name: See affected apps
|
||||
run: echo AFFECTED=$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects) >> $GITHUB_ENV
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
outputs:
|
||||
projects: ${{ env.AFFECTED }}
|
||||
|
||||
dispatch:
|
||||
needs: pr
|
||||
uses: ./.github/workflows/tests-dispatcher.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
project: ${{ needs.pr.outputs.projects }}
|
||||
tags: "--env.grepTags='[ @smoke, @regression ]'"
|
||||
@@ -1,99 +0,0 @@
|
||||
name: Cypress - explorer
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
trigger:
|
||||
required: true
|
||||
type: string
|
||||
default: 'false'
|
||||
skip-cache:
|
||||
required: false
|
||||
type: string
|
||||
tags:
|
||||
required: false
|
||||
type: string
|
||||
night-run:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
explorer-e2e:
|
||||
if: ${{ inputs.trigger == 'true' }}
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
- name: Vegacapsule version
|
||||
run: vegacapsule version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: './frontend-monorepo'
|
||||
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock', 'frontend-monorepo/package.json') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
######
|
||||
## Setup a Vega wallet for our user
|
||||
######
|
||||
|
||||
- name: Run Vegacapsule network
|
||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||
|
||||
- name: Set up Vegawallet for capsule
|
||||
id: setup-vega
|
||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||
|
||||
######
|
||||
## Run some tests
|
||||
######
|
||||
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: npx nx run explorer-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
|
||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||
|
||||
######
|
||||
## Upload logs
|
||||
######
|
||||
|
||||
# Artifact path is not valid: /ganache-1/capsule-logscolletor.stderr-2022-12-22T10:20:30Z.log. Contains the following character: Colon :
|
||||
- name: Rename files to allow archive
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
while read -r file; do
|
||||
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs
|
||||
path: /home/runner/.vegacapsule/testnet/logs
|
||||
@@ -0,0 +1,33 @@
|
||||
name: Cypress tests -- manual trigger
|
||||
|
||||
# This workflow runs the frontend tests against chosen branch
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
project:
|
||||
description: 'Project'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- explorer-e2e
|
||||
- token-e2e
|
||||
- trading-e2e
|
||||
tags:
|
||||
description: 'Test tags to run'
|
||||
required: true
|
||||
type: string
|
||||
default: '@smoke @regression @slow'
|
||||
skip-nx-cache:
|
||||
description: 'Skip NX cache'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
jobs:
|
||||
manual:
|
||||
uses: ./.github/workflows/cypress-run.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
projects: '["${{inputs.project}}"]'
|
||||
skip-cache: ${{inputs.skip-nx-cache}}
|
||||
tags: ${{inputs.tags}}
|
||||
@@ -0,0 +1,14 @@
|
||||
name: Cypress tests -- night run
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 4 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
nightly:
|
||||
uses: ./.github/workflows/cypress-run.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
projects: '["explorer-e2e","token-e2e","trading-e2e"]'
|
||||
tags: '@smoke @regression @slow'
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Cypress tests - PR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
- ready_for_review
|
||||
jobs:
|
||||
pr:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
|
||||
- name: Remove package.json & yarn.lock to avoid installing everything
|
||||
run: rm package.json yarn.lock
|
||||
|
||||
- name: Install nx
|
||||
run: yarn add nx
|
||||
|
||||
# Check SHAs
|
||||
- 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 || github.ref_name }}
|
||||
set-environment-variables-for-job: true
|
||||
|
||||
# See affected apps
|
||||
- name: See affected apps
|
||||
run: |
|
||||
affected=$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)
|
||||
projects=""
|
||||
if [[ $affected == *"token"* ]]; then projects+='"token-e2e" '; fi
|
||||
if [[ $affected == *"trading"* ]]; then projects+='"trading-e2e" '; fi
|
||||
if [[ $affected == *"explorer"* ]]; then projects+='"explorer-e2e" '; fi
|
||||
projects=${projects%?}
|
||||
projects=[${projects// /,}]
|
||||
echo PROJECTS=$projects >> $GITHUB_ENV
|
||||
|
||||
outputs:
|
||||
projects: ${{ env.PROJECTS }}
|
||||
|
||||
run:
|
||||
needs: pr
|
||||
if: ${{ needs.pr.outputs.projects != '[]' }}
|
||||
uses: ./.github/workflows/cypress-run.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
projects: ${{ needs.pr.outputs.projects }}
|
||||
tags: '@smoke @regression'
|
||||
|
||||
# Report single result at the end, to avoid mess with required checks in PR
|
||||
result:
|
||||
if: ${{ always() }}
|
||||
needs: run
|
||||
runs-on: ubuntu-latest
|
||||
name: Cypress result
|
||||
steps:
|
||||
- run: |
|
||||
result="${{ needs.run.result }}"
|
||||
if [[ $result == "success" || $result == "skipped" ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,30 +1,29 @@
|
||||
name: Cypress - token
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
trigger:
|
||||
projects:
|
||||
required: true
|
||||
type: string
|
||||
default: 'false'
|
||||
skip-cache:
|
||||
required: false
|
||||
type: string
|
||||
type: boolean
|
||||
tags:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
token-e2e:
|
||||
if: ${{ inputs.trigger == 'true' }}
|
||||
runs-on: self-hosted
|
||||
timeout-minutes: 60
|
||||
e2e:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
project: ${{ fromJSON(inputs.projects) }}
|
||||
runs-on: self-hosted-runner
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
- name: Vegacapsule version
|
||||
run: vegacapsule version
|
||||
# Checks if skip cache was requested
|
||||
- name: Set skip-nx-cache flag
|
||||
if: ${{ inputs.skip-cache == true }}
|
||||
run: echo "SKIP_CACHE=--skip-nx-cache" >> $GITHUB_ENV
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
@@ -47,33 +46,31 @@ jobs:
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
# Make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
######
|
||||
## Setup a Vega wallet for our user
|
||||
## Setup Vegacapsule and Vega wallet
|
||||
######
|
||||
|
||||
- name: Run Vegacapsule network
|
||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||
|
||||
- name: Set up Vegawallet for capsule
|
||||
- name: Run Vegacapsule network and Vega wallet
|
||||
id: setup-vega
|
||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||
|
||||
######
|
||||
## Run some tests
|
||||
######
|
||||
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: npx nx run token-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||
CYPRESS_grepTags: ${{ inputs.tags }}
|
||||
|
||||
######
|
||||
## Upload logs
|
||||
@@ -87,8 +84,8 @@ jobs:
|
||||
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs-token
|
||||
name: logs-${{ matrix.project }}
|
||||
path: /home/runner/.vegacapsule/testnet/logs
|
||||
@@ -1,86 +0,0 @@
|
||||
name: Cypress - trading
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
trigger:
|
||||
required: true
|
||||
type: string
|
||||
default: 'false'
|
||||
skip-cache:
|
||||
required: false
|
||||
type: string
|
||||
tags:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
trading-e2e:
|
||||
if: ${{ inputs.trigger == 'true' }}
|
||||
timeout-minutes: 30
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Vega version
|
||||
run: vega version
|
||||
|
||||
# Checkout front ends
|
||||
- name: Checkout frontend mono repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: './frontend-monorepo'
|
||||
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock', 'frontend-monorepo/package.json') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
######
|
||||
## Setup a Vega wallet for our user
|
||||
######
|
||||
|
||||
- name: Run Vegacapsule network
|
||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||
|
||||
- name: Set up Vegawallet for capsule
|
||||
id: setup-vega
|
||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: npx nx run trading-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||
|
||||
######
|
||||
## Upload logs
|
||||
######
|
||||
|
||||
- name: Rename files to allow archive
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
while read -r file; do
|
||||
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: logs-trading
|
||||
path: /home/runner/.vegacapsule/testnet/logs
|
||||
@@ -1,41 +0,0 @@
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
project:
|
||||
required: true
|
||||
type: string
|
||||
skip-cache:
|
||||
required: false
|
||||
type: string
|
||||
tags:
|
||||
required: false
|
||||
type: string
|
||||
night-run:
|
||||
required: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
run-explorer-e2e:
|
||||
uses: ./.github/workflows/cypress-explorer-e2e.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ contains(inputs.project, 'explorer-e2e') || contains(inputs.project, 'explorer') }}
|
||||
skip-cache: ${{ inputs.skip-cache }}
|
||||
tags: ${{ inputs.tags }}
|
||||
night-run: ${{ inputs.night-run }}
|
||||
|
||||
run-token-e2e:
|
||||
uses: ./.github/workflows/cypress-token-e2e.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ contains(inputs.project, 'token-e2e') || contains(inputs.project, 'token') }}
|
||||
skip-cache: ${{ inputs.skip-cache }}
|
||||
tags: ${{ inputs.tags }}
|
||||
|
||||
run-trading-e2e:
|
||||
uses: ./.github/workflows/cypress-trading-e2e.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
trigger: ${{ contains(inputs.project, 'trading-e2e') || contains(inputs.project, 'trading') }}
|
||||
skip-cache: ${{ inputs.skip-cache }}
|
||||
tags: ${{ inputs.tags }}
|
||||
@@ -60,12 +60,10 @@ context('Home Page', function () {
|
||||
cy.get(statsValue).eq(9).should('not.be.empty');
|
||||
cy.get(statsValue).eq(10).should('not.be.empty');
|
||||
cy.get(statsValue).eq(11).should('not.be.empty');
|
||||
if (Cypress.env('NIGHTLY_RUN') != true) {
|
||||
cy.get(statsValue)
|
||||
.eq(12)
|
||||
.invoke('text')
|
||||
.should('match', /v\d+\.\d+\.\d+/i);
|
||||
}
|
||||
cy.get(statsValue)
|
||||
.eq(12)
|
||||
.invoke('text')
|
||||
.should('match', /v\d+\.\d+\.\d+/i);
|
||||
cy.get(statsValue)
|
||||
.eq(13)
|
||||
.invoke('text')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# App configuration variables
|
||||
NX_TENDERMINT_URL=https://tm.be.testnet.vega.xyz
|
||||
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.be.testnet.vega.xyz/websocket/
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||
NX_VEGA_ENV=TESTNET
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -829,7 +829,7 @@ context(
|
||||
cy.highlight(`Associating tokens for first time`);
|
||||
cy.ethereum_wallet_connect();
|
||||
cy.connectVegaWallet();
|
||||
cy.get('[href="/validators/associate"]').first().click();
|
||||
cy.get('[href="/token/associate"]').first().click();
|
||||
cy.getByTestId('associate-radio-wallet', { timeout: 30000 }).click();
|
||||
cy.getByTestId('token-amount-input', epochTimeout).type('1');
|
||||
cy.getByTestId('token-input-submit-button', txTimeout)
|
||||
|
||||
@@ -61,7 +61,7 @@ context(
|
||||
// 3002-PROP-007
|
||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||
|
||||
cy.get(proposalParameterSelect).find('option').should('have.length', 115);
|
||||
cy.get(proposalParameterSelect).find('option').should('have.length', 116);
|
||||
cy.get(proposalParameterSelect).select(
|
||||
// 3007-PNEC-002
|
||||
'governance_proposal_asset_minEnact'
|
||||
|
||||
@@ -93,6 +93,7 @@ context(
|
||||
.contains(2.0, epochTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
// 2002-SINC-007
|
||||
@@ -145,6 +146,7 @@ context(
|
||||
.contains(2.0, epochTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.validate_validator_list_total_stake_and_share(
|
||||
@@ -209,6 +211,7 @@ context(
|
||||
.contains(6.0, epochTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.validate_validator_list_total_stake_and_share(
|
||||
@@ -243,6 +246,7 @@ context(
|
||||
.parent()
|
||||
.should('contain', 2.0, txTimeout);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.click_on_validator_from_list(1);
|
||||
@@ -264,6 +268,7 @@ context(
|
||||
.eq(1)
|
||||
.should('contain', 1.0, txTimeout);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.get(`[row-id="${0}"]`).within(() => {
|
||||
@@ -323,6 +328,7 @@ context(
|
||||
txTimeout
|
||||
);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
// 2001-STKE-040
|
||||
cy.click_on_validator_from_list(0);
|
||||
@@ -388,6 +394,7 @@ context(
|
||||
txTimeout
|
||||
);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.click_on_validator_from_list('0');
|
||||
@@ -447,6 +454,7 @@ context(
|
||||
txTimeout
|
||||
);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.click_on_validator_from_list(0);
|
||||
@@ -488,6 +496,7 @@ context(
|
||||
txTimeout
|
||||
);
|
||||
|
||||
cy.close_staking_dialog();
|
||||
cy.navigate_to('validators');
|
||||
|
||||
cy.click_on_validator_from_list(0);
|
||||
|
||||
@@ -7,11 +7,11 @@ const vegaWalletUnstakedBalance =
|
||||
'[data-testid="vega-wallet-balance-unstaked"]';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
|
||||
const ethWalletAssociateButton = '[href="/validators/associate"]';
|
||||
const ethWalletAssociateButton = '[href="/token/associate"]';
|
||||
const associateWalletRadioButton = '[data-testid="associate-radio-wallet"]';
|
||||
const tokenAmountInputBox = '[data-testid="token-amount-input"]';
|
||||
const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
||||
const ethWalletDissociateButton = '[href="/validators/disassociate"]';
|
||||
const ethWalletDissociateButton = '[href="/token/disassociate"]';
|
||||
const vestingContractSection = '[data-testid="vega-in-vesting-contract"]';
|
||||
const vegaInWalletSection = '[data-testid="vega-in-wallet"]';
|
||||
const connectedVegaKey = '[data-testid="connected-vega-key"]';
|
||||
|
||||
@@ -170,6 +170,27 @@ context(
|
||||
});
|
||||
});
|
||||
|
||||
it('Unable to withdraw asset on pub key view', function () {
|
||||
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
|
||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||
|
||||
// Disconnect vega wallet
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('disconnect').click();
|
||||
|
||||
cy.connectPublicKey(vegaWalletPubKey);
|
||||
cy.getByTestId(withdraw).should('be.visible').click();
|
||||
cy.getByTestId(selectAsset).select(usdtName);
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
|
||||
cy.getByTestId('dialog-content').within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||
});
|
||||
});
|
||||
|
||||
function waitForAssetsDisplayed(expectedAsset) {
|
||||
cy.contains(expectedAsset, txTimeout).should('be.visible');
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
cy.get(associateVegaLink)
|
||||
.should('be.visible')
|
||||
.and('have.attr', 'href')
|
||||
.and('equal', '/validators/associate');
|
||||
.and('equal', '/token/associate');
|
||||
});
|
||||
it('should have STAKING button', function () {
|
||||
cy.get(stakingBtn)
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/// <reference types="cypress" />
|
||||
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey2');
|
||||
const vegaPubkeyTruncated = Cypress.env('vegaWalletPublicKey2Short');
|
||||
const banner = 'view-banner';
|
||||
|
||||
context('View functionality with public key', { tags: '@smoke' }, function () {
|
||||
before('send asset to wallet', function () {
|
||||
cy.vega_wallet_faucet_assets_without_check(
|
||||
'fUSDC',
|
||||
'1000000',
|
||||
vegaWalletPubKey
|
||||
);
|
||||
});
|
||||
|
||||
beforeEach('visit home page', function () {
|
||||
cy.visit('/');
|
||||
cy.wait_for_spinner();
|
||||
cy.connectPublicKey(vegaWalletPubKey);
|
||||
});
|
||||
|
||||
it('Able to connect public key via wallet', function () {
|
||||
verifyConnectedToPubKey();
|
||||
cy.getByTestId('currency-title').should('contain.text', 'USDC (fake)');
|
||||
});
|
||||
|
||||
it('Able to connect public key using url', function () {
|
||||
cy.getByTestId('exit-view').click();
|
||||
cy.visit(`/?address=${vegaWalletPubKey}`);
|
||||
verifyConnectedToPubKey();
|
||||
});
|
||||
|
||||
it('Unable to submit proposal with public key', function () {
|
||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||
|
||||
cy.navigate_to('proposals');
|
||||
cy.go_to_make_new_proposal('Freeform');
|
||||
cy.enter_unique_freeform_proposal_body('50', 'pub key proposal test');
|
||||
cy.getByTestId('proposal-submit').should('be.visible').click();
|
||||
cy.getByTestId('dialog-content').within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to disconnect via banner', function () {
|
||||
cy.getByTestId('exit-view').click();
|
||||
cy.getByTestId(banner).should('not.exist');
|
||||
});
|
||||
|
||||
it('Able to disconnect via wallet', function () {
|
||||
cy.getByTestId('manage-vega-wallet').click();
|
||||
cy.getByTestId('disconnect').click();
|
||||
cy.getByTestId(banner).should('not.exist');
|
||||
});
|
||||
|
||||
function verifyConnectedToPubKey() {
|
||||
cy.getByTestId(banner).should(
|
||||
'contain.text',
|
||||
`Viewing as Vega user: ${vegaPubkeyTruncated}`
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -2,8 +2,8 @@ const walletContainer = '[data-testid="ethereum-wallet"]';
|
||||
const walletHeader = '[data-testid="wallet-header"] h1';
|
||||
const connectToEthButton = '[data-testid="connect-to-eth-wallet-button"]';
|
||||
const connectorList = '[data-testid="web3-connector-list"]';
|
||||
const associate = '[href="/validators/associate"]';
|
||||
const disassociate = '[href="/validators/disassociate"]';
|
||||
const associate = '[href="/token/associate"]';
|
||||
const disassociate = '[href="/token/disassociate"]';
|
||||
const disconnect = '[data-testid="disconnect-from-eth-wallet-button"]';
|
||||
const accountNo = '[data-testid="ethereum-account-truncated"]';
|
||||
const currencyTitle = '[data-testid="currency-title"]';
|
||||
|
||||
@@ -3,8 +3,8 @@ const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
||||
const tokenInputApprove = '[data-testid="token-input-approve-button"]';
|
||||
const addStakeRadioButton = '[data-testid="add-stake-radio"]';
|
||||
const removeStakeRadioButton = '[data-testid="remove-stake-radio"]';
|
||||
const ethWalletAssociateButton = '[href="/validators/associate"]';
|
||||
const ethWalletDissociateButton = '[href="/validators/disassociate"]';
|
||||
const ethWalletAssociateButton = '[href="/token/associate"]';
|
||||
const ethWalletDissociateButton = '[href="/token/disassociate"]';
|
||||
const vegaWalletUnstakedBalance =
|
||||
'[data-testid="vega-wallet-balance-unstaked"]';
|
||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
||||
@@ -40,7 +40,6 @@ Cypress.Commands.add('staking_validator_page_add_stake', (stake) => {
|
||||
.and('contain', `Add ${stake} $VEGA tokens`)
|
||||
.and('be.visible')
|
||||
.click();
|
||||
cy.get(dialogCloseButton).click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('staking_validator_page_remove_stake', (stake) => {
|
||||
|
||||
@@ -164,12 +164,12 @@ const ConnectedKey = () => {
|
||||
)}
|
||||
</section>
|
||||
<WalletCardActions>
|
||||
<Link className="flex-1" to={`${Routes.VALIDATORS}/associate`}>
|
||||
<Link className="flex-1" to={Routes.ASSOCIATE}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('associate')}
|
||||
</Button>
|
||||
</Link>
|
||||
<Link className="flex-1" to={`${Routes.VALIDATORS}/disassociate`}>
|
||||
<Link className="flex-1" to={Routes.DISASSOCIATE}>
|
||||
<Button size="sm" fill={true}>
|
||||
{t('disassociate')}
|
||||
</Button>
|
||||
|
||||
@@ -21,7 +21,7 @@ export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[min-content_1fr] lg:grid-cols-[1fr_450px]">
|
||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[1fr] lg:grid-cols-[1fr_450px]">
|
||||
<main className="col-start-1 p-4">{children}</main>
|
||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
||||
{sidebar.map((Component, i) => (
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SplashLoader = ({ text = 'Loading' }: { text?: string }) => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center" data-testid="splash-loader">
|
||||
<div className="flex flex-wrap w-[50px] h-[50px] mb-20">
|
||||
<div className="flex flex-wrap w-[50px] h-[50px] mb-4">
|
||||
{new Array(25).fill(null).map((_, i) => {
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -3,16 +3,17 @@ import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import { Url } from './url-connector';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { ENV } from '../config/env';
|
||||
import { UrlConnector } from '@vegaprotocol/web3';
|
||||
|
||||
const [metamask, metamaskHooks] = initializeConnector<MetaMask>(
|
||||
(actions) => new MetaMask(actions)
|
||||
);
|
||||
|
||||
const [urlConnector, urlHooks] = initializeConnector<Url>(
|
||||
(actions) => new Url(actions, ENV.localProviderUrl)
|
||||
const [urlConnector, urlHooks] = initializeConnector<UrlConnector>(
|
||||
(actions) =>
|
||||
new UrlConnector(actions, ENV.localProviderUrl, ENV.ethWalletMnemonic)
|
||||
);
|
||||
|
||||
export const createDefaultProvider = (providerUrl: string, chainId: number) => {
|
||||
|
||||
@@ -264,8 +264,6 @@ const routerConfig = [
|
||||
path: Routes.VALIDATORS,
|
||||
element: <LazyStaking name="Staking" />,
|
||||
children: [
|
||||
{ path: 'associate', element: <LazyStakingAssociate /> },
|
||||
{ path: 'disassociate', element: <LazyStakingDisassociate /> },
|
||||
{ path: ':node', element: <LazyStakingNode /> },
|
||||
{
|
||||
index: true,
|
||||
@@ -311,6 +309,8 @@ const routerConfig = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{ path: 'associate', element: <LazyStakingAssociate /> },
|
||||
{ path: 'disassociate', element: <LazyStakingDisassociate /> },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -12,8 +12,8 @@ const Routes = {
|
||||
REDEEM: '/token/redeem',
|
||||
WITHDRAWALS: '/token/withdraw',
|
||||
SUPPLY: '/token/tranches',
|
||||
ASSOCIATE: '/validators/associate',
|
||||
DISASSOCIATE: '/validators/disassociate',
|
||||
ASSOCIATE: '/token/associate',
|
||||
DISASSOCIATE: '/token/disassociate',
|
||||
};
|
||||
|
||||
export default Routes;
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
NodesFragmentFragment,
|
||||
} from '../__generated___/Nodes';
|
||||
import type { PreviousEpochQuery } from '../../__generated___/PreviousEpoch';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export interface ValidatorsTableProps {
|
||||
data: NodesQuery | undefined;
|
||||
@@ -77,8 +78,8 @@ export const ValidatorTables = ({
|
||||
const lowestRankingConsensusScore = consensusValidators.reduce(
|
||||
(lowest: NodesFragmentFragment, validator: NodesFragmentFragment) => {
|
||||
if (
|
||||
validator?.rankingScore &&
|
||||
Number(validator.rankingScore) < Number(lowest.rankingScore)
|
||||
Number(validator.rankingScore.rankingScore) <
|
||||
Number(lowest.rankingScore.rankingScore)
|
||||
) {
|
||||
lowest = validator;
|
||||
}
|
||||
@@ -87,10 +88,12 @@ export const ValidatorTables = ({
|
||||
).rankingScore.rankingScore;
|
||||
|
||||
const lowestRankingBigNum = toBigNum(lowestRankingConsensusScore, 0);
|
||||
const totalStakeBigNum = toBigNum(totalStake, decimals);
|
||||
const consensusStakedTotal = consensusValidators.reduce((acc, cur) => {
|
||||
return acc.plus(toBigNum(cur.stakedTotal, decimals));
|
||||
}, new BigNumber(0));
|
||||
|
||||
stakeNeededForPromotion = formatNumber(
|
||||
lowestRankingBigNum.times(totalStakeBigNum),
|
||||
lowestRankingBigNum.times(consensusStakedTotal),
|
||||
2
|
||||
).toString();
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@ interface StakeFailureProps {
|
||||
nodeName: string;
|
||||
isDialogVisible: boolean;
|
||||
toggleDialog: () => void;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
export const StakeFailure = ({
|
||||
nodeName,
|
||||
isDialogVisible,
|
||||
toggleDialog,
|
||||
error,
|
||||
}: StakeFailureProps) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
@@ -20,11 +22,15 @@ export const StakeFailure = ({
|
||||
open={isDialogVisible}
|
||||
onChange={toggleDialog}
|
||||
>
|
||||
<p>
|
||||
{t('stakeFailed', {
|
||||
node: nodeName,
|
||||
})}
|
||||
</p>
|
||||
{error ? (
|
||||
<p>{error.message}</p>
|
||||
) : (
|
||||
<p>
|
||||
{t('stakeFailed', {
|
||||
node: nodeName,
|
||||
})}
|
||||
</p>
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ interface StakeFormTxStatusesProps {
|
||||
removeType: RemoveType;
|
||||
isDialogVisible: boolean;
|
||||
toggleDialog: () => void;
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
export const StakingFormTxStatuses = ({
|
||||
@@ -23,6 +24,7 @@ export const StakingFormTxStatuses = ({
|
||||
removeType,
|
||||
isDialogVisible,
|
||||
toggleDialog,
|
||||
error,
|
||||
}: StakeFormTxStatusesProps) => {
|
||||
switch (formState) {
|
||||
case FormState.Requested:
|
||||
@@ -59,6 +61,7 @@ export const StakingFormTxStatuses = ({
|
||||
nodeName={nodeName}
|
||||
isDialogVisible={isDialogVisible}
|
||||
toggleDialog={toggleDialog}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
|
||||
@@ -70,6 +70,7 @@ export const StakingForm = ({
|
||||
const { appState } = useAppState();
|
||||
const { sendTx } = useVegaWallet();
|
||||
const [formState, setFormState] = React.useState(FormState.Default);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [isDialogVisible, setIsDialogVisible] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const [action, setAction] = React.useState<StakeAction>(
|
||||
@@ -135,12 +136,15 @@ export const StakingForm = ({
|
||||
|
||||
// await success via poll
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
setError(err);
|
||||
}
|
||||
setFormState(FormState.Failure);
|
||||
Sentry.captureException(err);
|
||||
}
|
||||
}
|
||||
|
||||
const [delegationSearch, { data, error }] = usePartyDelegationsLazyQuery({
|
||||
const [delegationSearch, { data }] = usePartyDelegationsLazyQuery({
|
||||
variables: {
|
||||
partyId: pubKey,
|
||||
},
|
||||
@@ -170,10 +174,6 @@ export const StakingForm = ({
|
||||
clearInterval(interval);
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
Sentry.captureException(error);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ export const StakingForm = ({
|
||||
removeType={removeType}
|
||||
isDialogVisible={isDialogVisible}
|
||||
toggleDialog={toggleDialog}
|
||||
error={error}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -93,7 +93,7 @@ const Home = ({ name }: RouteChildProps) => {
|
||||
<p>
|
||||
<Link
|
||||
data-testid="associate-vega-tokens-link-on-homepage"
|
||||
to={`${Routes.VALIDATORS}/associate`}
|
||||
to={Routes.ASSOCIATE}
|
||||
className="underline text-white"
|
||||
>
|
||||
{t('Associate VEGA tokens')}
|
||||
|
||||
@@ -9,6 +9,8 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3028/query
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
|
||||
# Expose some env vars to cypress environment for market setup
|
||||
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||
|
||||
@@ -9,6 +9,8 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3028/query
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
|
||||
# Expose some env vars to cypress environment for market setup
|
||||
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||
|
||||
@@ -42,5 +42,6 @@ module.exports = defineConfig({
|
||||
grepTags: '@regression @smoke @slow',
|
||||
grepFilterSpecs: true,
|
||||
grepOmitFiltered: true,
|
||||
txTimeout: { timeout: 70000 },
|
||||
},
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '@vegaprotocol/types';
|
||||
import { isBefore, isAfter, addSeconds, subSeconds } from 'date-fns';
|
||||
import { createOrder } from '../support/create-order';
|
||||
import { connectEthereumWallet } from '../support/ethereum-wallet';
|
||||
|
||||
const orderSize = 'size';
|
||||
const orderType = 'type';
|
||||
@@ -17,6 +18,16 @@ const orderPrice = 'price';
|
||||
const orderTimeInForce = 'timeInForce';
|
||||
const orderCreatedAt = 'createdAt';
|
||||
const orderUpdatedAt = 'updatedAt';
|
||||
const assetSelectField = 'select[name="asset"]';
|
||||
const amountField = 'input[name="amount"]';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
const btcName = 'BTC (local)';
|
||||
const btcSymbol = 'tBTC';
|
||||
const usdcSymbol = 'fUSDC';
|
||||
const toastContent = 'toast-content';
|
||||
const ordersTab = 'Orders';
|
||||
const depositsTab = 'Deposits';
|
||||
const toastCloseBtn = 'toast-close';
|
||||
|
||||
// TODO: ensure this test runs only if capsule is running via workflow
|
||||
describe('capsule', { tags: '@slow' }, () => {
|
||||
@@ -25,6 +36,7 @@ describe('capsule', { tags: '@slow' }, () => {
|
||||
cy.get('@markets').then((markets) => {
|
||||
cy.wrap(markets[0]).as('market');
|
||||
});
|
||||
cy.updateCapsuleMultiSig();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -45,15 +57,16 @@ describe('capsule', { tags: '@slow' }, () => {
|
||||
const rawPrice = removeDecimal(order.price, market.decimalPlaces);
|
||||
const rawSize = removeDecimal(order.size, market.positionDecimalPlaces);
|
||||
|
||||
cy.getByTestId('Collateral').click();
|
||||
cy.getByTestId('asset', txTimeout).should('contain.text', usdcSymbol);
|
||||
|
||||
createOrder(order);
|
||||
|
||||
cy.getByTestId('dialog-title').should(
|
||||
cy.getByTestId(toastContent).should(
|
||||
'contain.text',
|
||||
'Awaiting network confirmation'
|
||||
`ConfirmedYour transaction has been confirmed View in block explorerSubmit order - activeTEST.24h+0.0005 @ 390.00 ${usdcSymbol}`
|
||||
);
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Order submitted');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
|
||||
cy.getByTestId(toastCloseBtn).click();
|
||||
// orderbook cells are keyed by price level
|
||||
cy.getByTestId('tab-orderbook')
|
||||
.get(`[data-testid="price-${rawPrice}"]`)
|
||||
@@ -61,7 +74,8 @@ describe('capsule', { tags: '@slow' }, () => {
|
||||
.get(`[data-testid="bid-vol-${rawPrice}"]`)
|
||||
.should('contain.text', rawSize);
|
||||
|
||||
cy.getByTestId('Orders').click();
|
||||
cy.getByTestId(ordersTab).click();
|
||||
cy.getByTestId('edit').should('contain.text', 'Edit');
|
||||
cy.getByTestId('tab-orders').within(() => {
|
||||
cy.get('.ag-center-cols-container')
|
||||
.children()
|
||||
@@ -99,14 +113,18 @@ describe('capsule', { tags: '@slow' }, () => {
|
||||
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderCreatedAt);
|
||||
});
|
||||
});
|
||||
|
||||
cy.getByTestId('edit').first().click();
|
||||
//edit order
|
||||
cy.getByTestId(ordersTab).click();
|
||||
cy.getByTestId('edit').first().should('be.visible').click();
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Edit order');
|
||||
cy.get('#limitPrice').focus().clear().type('200');
|
||||
cy.getByTestId('edit-order').find('[type="submit"]').click();
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Order updated');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
|
||||
cy.getByTestId(toastContent).should(
|
||||
'contain.text',
|
||||
`ConfirmedYour transaction has been confirmed View in block explorerEdit order - activeTEST.24h+0.0005 @ 200.00 ${usdcSymbol}+0.0005 @ 200.00 ${usdcSymbol}`
|
||||
);
|
||||
cy.getByTestId(ordersTab).click();
|
||||
cy.getByTestId(toastCloseBtn).click();
|
||||
cy.get('.ag-center-cols-container')
|
||||
.children()
|
||||
.first()
|
||||
@@ -116,26 +134,144 @@ describe('capsule', { tags: '@slow' }, () => {
|
||||
});
|
||||
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderUpdatedAt);
|
||||
});
|
||||
|
||||
//cancel order
|
||||
cy.getByTestId(ordersTab).click();
|
||||
cy.getByTestId('cancel').first().click();
|
||||
|
||||
cy.getByTestId('dialog-title').should(
|
||||
cy.getByTestId(toastContent).should(
|
||||
'contain.text',
|
||||
'Awaiting network confirmation'
|
||||
`ConfirmedYour transaction has been confirmed View in block explorerCancel order - cancelledTEST.24h+0.0005 @ 200.00 ${usdcSymbol}`
|
||||
);
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Order cancelled');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId(toastCloseBtn).click();
|
||||
|
||||
cy.getByTestId('tab-orders')
|
||||
.get('.ag-center-cols-container')
|
||||
.children()
|
||||
.first()
|
||||
.get(`[col-id='${orderStatus}']`)
|
||||
.get(`[col-id='${orderStatus}']`, txTimeout)
|
||||
.should('contain.text', OrderStatusMapping.STATUS_CANCELLED);
|
||||
});
|
||||
|
||||
it('can deposit and withdrawal', function () {
|
||||
// 1001-DEPO-001
|
||||
// 1001-DEPO-002
|
||||
// 1001-DEPO-003
|
||||
// 1001-DEPO-005
|
||||
// 1001-DEPO-006
|
||||
// 1001-DEPO-007
|
||||
// 1001-DEPO-008
|
||||
// 1001-DEPO-009
|
||||
// 1002-WITH-001
|
||||
// 1002-WITH-006
|
||||
// 1002-WITH-009
|
||||
// 002-WITH-011
|
||||
// 1002-WITH-024
|
||||
// 1002-WITH-012
|
||||
// 1002-WITH-013
|
||||
// 1002-WITH-014
|
||||
// 1002-WITH-015
|
||||
// 1002-WITH-016
|
||||
// 1002-WITH-019
|
||||
|
||||
cy.visit('/#/portfolio');
|
||||
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||
|
||||
cy.highlight('creating deposit');
|
||||
|
||||
cy.getByTestId(depositsTab).click();
|
||||
cy.getByTestId('deposit-button').click();
|
||||
connectEthereumWallet('Unknown');
|
||||
cy.get(assetSelectField, txTimeout).select(btcName);
|
||||
cy.getByTestId('deposit-approve-submit').click();
|
||||
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
|
||||
cy.get('[data-testid="Return to deposit"]').click();
|
||||
cy.get(amountField).clear().type('1');
|
||||
cy.getByTestId('deposit-submit').click();
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
'contain.text',
|
||||
`Transaction completedYour transaction has been completedView on EtherscanDeposit 1.00 ${btcSymbol}`
|
||||
);
|
||||
cy.getByTestId(toastCloseBtn).click();
|
||||
cy.getByTestId('Collateral').click();
|
||||
|
||||
cy.highlight('deposit verification');
|
||||
|
||||
cy.getByTestId('asset', txTimeout).should('contain.text', btcSymbol);
|
||||
// need to reload page to see deposit history complete
|
||||
cy.reload();
|
||||
cy.getByTestId(depositsTab).click();
|
||||
cy.get('.ag-cell-value', txTimeout).should('contain.text', btcSymbol);
|
||||
cy.get('[col-id="status"]').should('not.have.text', 'Open', txTimeout);
|
||||
|
||||
cy.get('[col-id="txHash"]')
|
||||
.should('have.length.above', 2)
|
||||
.eq(1)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', btcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '1.00');
|
||||
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||
cy.get('[col-id="status"]').should('have.text', 'Finalized');
|
||||
cy.get('[col-id="txHash"]')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/tx');
|
||||
});
|
||||
|
||||
cy.highlight('creating withdrawals');
|
||||
|
||||
cy.getByTestId('Withdrawals').click();
|
||||
cy.getByTestId('withdraw-dialog-button').click();
|
||||
connectEthereumWallet('Unknown');
|
||||
cy.get(assetSelectField).select(btcName);
|
||||
cy.get(amountField).clear().type('1');
|
||||
cy.getByTestId('submit-withdrawal').click();
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
'contain.text',
|
||||
'Funds unlocked'
|
||||
);
|
||||
|
||||
cy.getByTestId('tab-withdrawals').within(() => {
|
||||
cy.get('.ag-center-cols-container')
|
||||
.children()
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get('[col-id="status"]').should('contain.text', 'Pending');
|
||||
});
|
||||
});
|
||||
|
||||
cy.highlight('withdrawals verification');
|
||||
cy.getByTestId('toast-complete-withdrawal').click();
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
'contain.text',
|
||||
'Transaction completed'
|
||||
);
|
||||
|
||||
cy.getByTestId('complete-withdrawal', txTimeout).should('not.exist');
|
||||
|
||||
cy.get('[col-id="txHash"]', txTimeout)
|
||||
.should('have.length.above', 1)
|
||||
.eq(1)
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('[col-id="asset.symbol"]').should('have.text', btcSymbol);
|
||||
cy.get('[col-id="amount"]').should('have.text', '1.00');
|
||||
cy.get('[col-id="details.receiverAddress"]')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/address/');
|
||||
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||
cy.get('[col-id="withdrawnTimestamp"]').should('not.be.empty');
|
||||
cy.get('[col-id="status"]').should('have.text', 'Completed');
|
||||
cy.get('[col-id="txHash"]')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://sepolia.etherscan.io/tx/0x');
|
||||
});
|
||||
});
|
||||
});
|
||||
function checkIfDataAndTimeOfCreationAndUpdateIsEqual(date: string) {
|
||||
cy.get(`[col-id='${date}']`)
|
||||
cy.get(`[col-id='${date}'] .ag-cell-wrapper`)
|
||||
.children('span')
|
||||
.children('span')
|
||||
.invoke('data', 'value')
|
||||
.then(($dateTime) => {
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('Deposits').click();
|
||||
cy.getByTestId('deposit-button').click();
|
||||
cy.wait('@Assets');
|
||||
connectEthereumWallet();
|
||||
connectEthereumWallet('MetaMask');
|
||||
cy.getByTestId('deposit-submit').click();
|
||||
});
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('vega wallet v1', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(form).find('#wallet').click().type('invalid name');
|
||||
cy.getByTestId(form).find('#passphrase').click().type('invalid password');
|
||||
cy.getByTestId('rest-connector-form').find('button[type=submit]').click();
|
||||
cy.getByTestId('form-error').should('have.text', 'No wallet detected');
|
||||
cy.getByTestId('form-error').should('have.text', 'Invalid credentials');
|
||||
});
|
||||
|
||||
it('doesnt connect with invalid fields', () => {
|
||||
@@ -119,7 +119,7 @@ describe('ethereum wallet', { tags: '@smoke' }, () => {
|
||||
const ethWalletAddress = Cypress.env('ETHEREUM_WALLET_ADDRESS');
|
||||
cy.getByTestId('Deposits').click();
|
||||
cy.getByTestId('deposit-button').click();
|
||||
connectEthereumWallet();
|
||||
connectEthereumWallet('MetaMask');
|
||||
cy.get('#ethereum-address').should('have.value', ethWalletAddress);
|
||||
cy.getByTestId('disconnect-ethereum-wallet')
|
||||
.should('have.text', 'Disconnect')
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId('withdraw-dialog-button').click();
|
||||
|
||||
// It also requires connection Ethereum wallet
|
||||
connectEthereumWallet();
|
||||
connectEthereumWallet('MetaMask');
|
||||
|
||||
cy.wait('@Accounts');
|
||||
cy.wait('@Assets');
|
||||
@@ -79,7 +79,7 @@ describe('withdraw actions', { tags: '@regression' }, () => {
|
||||
cy.getByTestId('Withdrawals').click();
|
||||
cy.getByTestId('withdraw-dialog-button').click();
|
||||
|
||||
connectEthereumWallet();
|
||||
connectEthereumWallet('MetaMask');
|
||||
|
||||
cy.wait('@Accounts');
|
||||
cy.wait('@Assets');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const connectEthereumWallet = () => {
|
||||
export const connectEthereumWallet = (connectorName: string) => {
|
||||
cy.getByTestId('connect-eth-wallet-btn').should('be.enabled').click();
|
||||
cy.getByTestId('web3-connector-list').should('be.visible');
|
||||
cy.getByTestId('web3-connector-MetaMask').click();
|
||||
cy.getByTestId(`web3-connector-${connectorName}`).click();
|
||||
};
|
||||
|
||||
@@ -58,13 +58,16 @@ export const testOrderCancellation = (
|
||||
|
||||
const vegaWalletTransaction = (transaction: Transaction) => {
|
||||
cy.wait('@VegaWalletTransaction')
|
||||
.its('request.body.params')
|
||||
.should('deep.equal', {
|
||||
token: JSON.parse(localStorage.getItem('vega_wallet_config') || '{}')
|
||||
?.token,
|
||||
publicKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
sendingMode: 'TYPE_SYNC',
|
||||
transaction,
|
||||
.its('request')
|
||||
.then((req) => {
|
||||
expect(req.body.params).to.deep.equal({
|
||||
publicKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
sendingMode: 'TYPE_SYNC',
|
||||
transaction,
|
||||
});
|
||||
expect(req.headers.authorization).to.equal(
|
||||
`VWT ${Cypress.env('VEGA_WALLET_API_TOKEN')}`
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -8,3 +8,6 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
@@ -9,3 +9,6 @@ NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3028/query
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
|
||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||
@@ -1,3 +1,3 @@
|
||||
import { Market } from './market';
|
||||
import { MarketPage } from './market';
|
||||
|
||||
export default Market;
|
||||
export default MarketPage;
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
t,
|
||||
titlefy,
|
||||
useDataProvider,
|
||||
useThrottledDataProvider,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import type {
|
||||
@@ -31,7 +32,47 @@ export interface SingleMarketData extends SingleMarketFieldsFragment {
|
||||
data: MarketData;
|
||||
}
|
||||
|
||||
export const Market = () => {
|
||||
const TitleUpdater = ({
|
||||
marketId,
|
||||
marketName,
|
||||
decimalPlaces,
|
||||
}: {
|
||||
marketId?: string;
|
||||
marketName?: string;
|
||||
decimalPlaces?: number;
|
||||
}) => {
|
||||
const pageTitle = usePageTitleStore((store) => store.pageTitle);
|
||||
const updateTitle = usePageTitleStore((store) => store.updateTitle);
|
||||
const { data: marketData } = useThrottledDataProvider<
|
||||
MarketData,
|
||||
MarketDataUpdateFieldsFragment
|
||||
>(
|
||||
{
|
||||
dataProvider: marketDataProvider,
|
||||
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||
skip: !marketId,
|
||||
},
|
||||
1000
|
||||
);
|
||||
useEffect(() => {
|
||||
const marketPrice = calculatePrice(marketData?.markPrice, decimalPlaces);
|
||||
if (marketName) {
|
||||
const newPageTitle = titlefy([marketName, marketPrice]);
|
||||
if (pageTitle !== newPageTitle) {
|
||||
updateTitle(newPageTitle);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
decimalPlaces,
|
||||
marketName,
|
||||
marketData?.markPrice,
|
||||
pageTitle,
|
||||
updateTitle,
|
||||
]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MarketPage = () => {
|
||||
const { marketId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -39,9 +80,6 @@ export const Market = () => {
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
const lastMarketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
const pageTitle = usePageTitleStore((store) => store.pageTitle);
|
||||
const updateTitle = usePageTitleStore((store) => store.updateTitle);
|
||||
|
||||
const onSelect = useCallback(
|
||||
(id: string) => {
|
||||
if (id && id !== marketId) {
|
||||
@@ -51,56 +89,20 @@ export const Market = () => {
|
||||
[marketId, navigate]
|
||||
);
|
||||
|
||||
const variables = useMemo(
|
||||
() => ({
|
||||
marketId: marketId || '',
|
||||
}),
|
||||
[marketId]
|
||||
);
|
||||
|
||||
const updateMarketId = useCallback(
|
||||
({ data }: { data: { id?: string } | null }) => {
|
||||
if (data?.id && data.id !== lastMarketId) {
|
||||
update({ marketId: data.id });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[update, lastMarketId]
|
||||
);
|
||||
const { data, error, loading } = useDataProvider<
|
||||
SingleMarketFieldsFragment,
|
||||
never
|
||||
>({
|
||||
dataProvider: marketProvider,
|
||||
variables,
|
||||
update: updateMarketId,
|
||||
variables: useMemo(() => ({ marketId: marketId || '' }), [marketId]),
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const marketName = data?.tradableInstrument.instrument.name;
|
||||
const updateProvider = useCallback(
|
||||
({ data: marketData }: { data: MarketData | null }) => {
|
||||
const marketPrice = calculatePrice(
|
||||
marketData?.markPrice,
|
||||
data?.decimalPlaces
|
||||
);
|
||||
if (marketName) {
|
||||
const newPageTitle = titlefy([marketName, marketPrice]);
|
||||
if (pageTitle !== newPageTitle) {
|
||||
updateTitle(newPageTitle);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[updateTitle, pageTitle, marketName, data?.decimalPlaces]
|
||||
);
|
||||
|
||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||
dataProvider: marketDataProvider,
|
||||
update: updateProvider,
|
||||
variables,
|
||||
skip: !marketId || !data,
|
||||
});
|
||||
useEffect(() => {
|
||||
if (data?.id && data.id !== lastMarketId) {
|
||||
update({ marketId: data.id });
|
||||
}
|
||||
}, [update, lastMarketId, data?.id]);
|
||||
|
||||
const tradeView = useMemo(() => {
|
||||
if (w > 960) {
|
||||
@@ -123,6 +125,11 @@ export const Market = () => {
|
||||
data={data || undefined}
|
||||
noDataCondition={(data) => false}
|
||||
>
|
||||
<TitleUpdater
|
||||
marketId={data?.id}
|
||||
marketName={data?.tradableInstrument.instrument.name}
|
||||
decimalPlaces={data?.decimalPlaces}
|
||||
/>
|
||||
{tradeView}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
|
||||
@@ -28,7 +28,8 @@ export function AppLoader({ children }: AppLoaderProps) {
|
||||
|
||||
export const Web3Provider = ({ children }: { children: ReactNode }) => {
|
||||
const { config, loading, error } = useEthereumConfig();
|
||||
const { ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||
const { ETHEREUM_PROVIDER_URL, ETH_LOCAL_PROVIDER_URL, ETH_WALLET_MNEMONIC } =
|
||||
useEnvironment();
|
||||
const [connectors, initializeConnectors] = useWeb3ConnectStore((store) => [
|
||||
store.connectors,
|
||||
store.initialize,
|
||||
@@ -37,11 +38,22 @@ export const Web3Provider = ({ children }: { children: ReactNode }) => {
|
||||
useEffect(() => {
|
||||
if (config?.chain_id) {
|
||||
return initializeConnectors(
|
||||
createConnectors(ETHEREUM_PROVIDER_URL, Number(config?.chain_id)),
|
||||
createConnectors(
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
Number(config?.chain_id),
|
||||
ETH_LOCAL_PROVIDER_URL,
|
||||
ETH_WALLET_MNEMONIC
|
||||
),
|
||||
Number(config.chain_id)
|
||||
);
|
||||
}
|
||||
}, [config?.chain_id, ETHEREUM_PROVIDER_URL, initializeConnectors]);
|
||||
}, [
|
||||
config?.chain_id,
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
initializeConnectors,
|
||||
ETH_LOCAL_PROVIDER_URL,
|
||||
ETH_WALLET_MNEMONIC,
|
||||
]);
|
||||
|
||||
return (
|
||||
<AsyncRenderer
|
||||
|
||||
@@ -430,6 +430,7 @@ const VegaTxCompleteToastsContent = ({ tx }: VegaTxToastContentProps) => {
|
||||
const completeWithdrawalButton = tx.withdrawal && (
|
||||
<div className="mt-[10px]">
|
||||
<Button
|
||||
data-testid="toast-complete-withdrawal"
|
||||
size="xs"
|
||||
onClick={() => {
|
||||
createEthWithdrawalApproval(
|
||||
|
||||
@@ -17,15 +17,11 @@ export const useAccountBalance = (assetId?: string) => {
|
||||
const account = assetId
|
||||
? getSettlementAccount({ accounts: data, assetId })
|
||||
: undefined;
|
||||
if (accountBalance !== account?.balance) {
|
||||
setAccountBalance(account?.balance || '');
|
||||
}
|
||||
if (accountDecimals !== account?.asset.decimals) {
|
||||
setAccountDecimals(account?.asset.decimals || null);
|
||||
}
|
||||
setAccountBalance(account?.balance || '');
|
||||
setAccountDecimals(account?.asset.decimals || null);
|
||||
return true;
|
||||
},
|
||||
[accountBalance, accountDecimals, assetId]
|
||||
[assetId]
|
||||
);
|
||||
|
||||
useDataProvider({
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
} from './lib/commands/vega-wallet-connect';
|
||||
import { addMockTransactionResponse } from './lib/commands/mock-transaction-response';
|
||||
import { addCreateMarket } from './lib/commands/create-market';
|
||||
import { addConnectPublicKey } from './lib/commands/add-connect-public-key';
|
||||
|
||||
addGetTestIdcommand();
|
||||
addSlackCommand();
|
||||
@@ -33,6 +34,7 @@ addVegaWalletConnect();
|
||||
addSetVegaWallet();
|
||||
addMockTransactionResponse();
|
||||
addCreateMarket();
|
||||
addConnectPublicKey();
|
||||
|
||||
export { mockConnectWallet } from './lib/commands/vega-wallet-connect';
|
||||
export type { onMessage } from './lib/mock-ws';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { requestGQL } from './request';
|
||||
|
||||
export async function getEthereumConfig() {
|
||||
const query = gql`
|
||||
{
|
||||
query {
|
||||
networkParameter(key: "blockchains.ethereumConfig") {
|
||||
value
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { requestGQL } from './request';
|
||||
|
||||
export async function getMarkets() {
|
||||
const query = gql`
|
||||
{
|
||||
query {
|
||||
marketsConnection {
|
||||
edges {
|
||||
node {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { requestGQL } from './request';
|
||||
|
||||
export async function getPartyStake(partyId: string) {
|
||||
const query = gql`
|
||||
{
|
||||
query {
|
||||
party(id:"${partyId}") {
|
||||
stakingSummary {
|
||||
currentStakeAvailable
|
||||
|
||||
@@ -3,7 +3,7 @@ import { requestGQL } from './request';
|
||||
|
||||
export async function getProposal(id: string) {
|
||||
const query = gql`
|
||||
{
|
||||
query {
|
||||
proposal(id: "${id}") {
|
||||
id
|
||||
state
|
||||
|
||||
@@ -3,7 +3,7 @@ import { requestGQL } from './request';
|
||||
|
||||
export async function getVegaAsset() {
|
||||
const query = gql`
|
||||
{
|
||||
query {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
|
||||
@@ -38,7 +38,6 @@ export function request(
|
||||
params: {
|
||||
...params,
|
||||
sendingMode: 'TYPE_SYNC',
|
||||
token,
|
||||
},
|
||||
id: (requestId++).toString(),
|
||||
};
|
||||
@@ -47,6 +46,7 @@ export function request(
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `VWT ${token}`,
|
||||
Origin: 'market-setup',
|
||||
Referer: 'market-setup',
|
||||
},
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Cypress {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Chainable<Subject> {
|
||||
connectPublicKey(publicKey: string): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const addConnectPublicKey = () => {
|
||||
Cypress.Commands.add('connectPublicKey', (publicKey) => {
|
||||
cy.getByTestId('connect-vega-wallet').then((connectWallet) => {
|
||||
if (connectWallet.length) {
|
||||
cy.getByTestId('connect-vega-wallet').click();
|
||||
cy.getByTestId('connector-view').should('be.visible').click();
|
||||
cy.getByTestId('address').click();
|
||||
cy.getByTestId('address').type(publicKey);
|
||||
cy.getByTestId('connect').click();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { aliasWalletQuery } from '../mock-rest';
|
||||
import { aliasWalletConnectQuery } from '../mock-rest';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
@@ -15,12 +15,8 @@ declare global {
|
||||
}
|
||||
|
||||
export const mockConnectWallet = () => {
|
||||
const data = {
|
||||
token: Cypress.env('VEGA_WALLET_API_TOKEN'),
|
||||
};
|
||||
console.log('mockConnectWallet', data);
|
||||
cy.mockWallet((req) => {
|
||||
aliasWalletQuery(req, 'client.connect_wallet', data);
|
||||
aliasWalletConnectQuery(req, Cypress.env('VEGA_WALLET_API_TOKEN'));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -50,7 +46,7 @@ export function addSetVegaWallet() {
|
||||
win.localStorage.setItem(
|
||||
'vega_wallet_config',
|
||||
JSON.stringify({
|
||||
token: Cypress.env('VEGA_WALLET_API_TOKEN'),
|
||||
token: `VWT ${Cypress.env('VEGA_WALLET_API_TOKEN')}`,
|
||||
connector: 'jsonRpc',
|
||||
url: 'http://localhost:1789',
|
||||
})
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
import {
|
||||
StakingBridge,
|
||||
Token,
|
||||
TokenVesting,
|
||||
TokenFaucetable,
|
||||
CollateralBridge,
|
||||
} from '@vegaprotocol/smart-contracts';
|
||||
import { ethers, Wallet } from 'ethers';
|
||||
|
||||
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
||||
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 = '90000';
|
||||
const Erc20BridgeAddress = '0x9708FF7510D4A7B9541e1699d15b53Ecb1AFDc54';
|
||||
|
||||
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('deposit_asset', function (assetEthAddress) {
|
||||
cy.get('@signer', { log: false }).then((signer) => {
|
||||
// Approve asset
|
||||
cy.wrap(
|
||||
new TokenFaucetable(assetEthAddress, signer).approve(
|
||||
Erc20BridgeAddress,
|
||||
'10000000000'
|
||||
)
|
||||
)
|
||||
.then((tx) => {
|
||||
cy.wait_for_transaction(tx);
|
||||
})
|
||||
.then(() => {
|
||||
cy.wrap(new CollateralBridge(Erc20BridgeAddress, signer), {
|
||||
log: false,
|
||||
}).then((bridge) => {
|
||||
// Deposit asset into vega wallet
|
||||
cy.wrap(
|
||||
bridge.deposit_asset(
|
||||
assetEthAddress,
|
||||
'1000000000',
|
||||
'0x' + vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
).then((tx) => {
|
||||
cy.wait_for_transaction(tx);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('faucet_asset', function (assetEthAddress) {
|
||||
cy.get('@signer', { log: false }).then((signer) => {
|
||||
cy.wrap(new TokenFaucetable(assetEthAddress, signer), { log: false }).then(
|
||||
(token) => {
|
||||
cy.wrap(token.faucet(), {
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}).then((tx) => {
|
||||
cy.wait_for_transaction(tx);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('vega_wallet_teardown', function () {
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.then((balance) => {
|
||||
if (balance != '0.00') {
|
||||
cy.vega_wallet_teardown_vesting(this.vestingContract);
|
||||
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
|
||||
}
|
||||
});
|
||||
cy.get('[data-testid="associated-amount"]', { timeout: 30000 }).should(
|
||||
'contain.text',
|
||||
'0.00'
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, { timeout: transactionTimeout }).should(
|
||||
'contain',
|
||||
'0.00',
|
||||
{ timeout: transactionTimeout }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'vega_wallet_teardown_staking',
|
||||
(stakingBridgeContract) => {
|
||||
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
||||
cy.wrap(
|
||||
stakingBridgeContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
{
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}
|
||||
).then((stake_amount) => {
|
||||
if (String(stake_amount) != '0') {
|
||||
cy.wrap(
|
||||
stakingBridgeContract.remove_stake(stake_amount, vegaWalletPubKey),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
).then((tx) => {
|
||||
cy.wait_for_transaction(tx);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('vega_wallet_teardown_vesting', (vestingContract) => {
|
||||
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
||||
cy.wrap(vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey), {
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}).then((vesting_amount) => {
|
||||
if (String(vesting_amount) != '0') {
|
||||
cy.wrap(vestingContract.remove_stake(vesting_amount, vegaWalletPubKey), {
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}).then((tx) => {
|
||||
cy.wait_for_transaction(tx);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('wait_for_transaction', (tx) => {
|
||||
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
|
||||
});
|
||||
@@ -43,3 +43,23 @@ export const aliasWalletQuery = (
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const aliasWalletConnectQuery = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
token: string
|
||||
) => {
|
||||
if (hasMethod(req, 'client.connect_wallet')) {
|
||||
req.alias = 'client.connect_wallet';
|
||||
req.reply({
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'Access-Control-Expose-Headers': 'Authorization',
|
||||
Authorization: `VWT ${token}`,
|
||||
},
|
||||
body: {
|
||||
jsonrpc: '2.0',
|
||||
id: '0',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,7 +52,9 @@ function generateJsx(order?: OrderSubmissionBody['orderSubmission']) {
|
||||
}
|
||||
|
||||
describe('DealTicket', () => {
|
||||
beforeEach(() => window.localStorage.clear());
|
||||
beforeEach(() => {
|
||||
window.localStorage.clear();
|
||||
});
|
||||
afterEach(() => {
|
||||
window.localStorage.clear();
|
||||
jest.clearAllMocks();
|
||||
@@ -87,38 +89,6 @@ describe('DealTicket', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('can edit deal ticket', async () => {
|
||||
render(generateJsx());
|
||||
|
||||
// BUY is selected by default
|
||||
expect(
|
||||
screen.getByTestId('order-side-SIDE_BUY')?.querySelector('input')
|
||||
).toBeChecked();
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.getByTestId('order-size'), {
|
||||
target: { value: '200' },
|
||||
});
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('order-size')).toHaveDisplayValue('200');
|
||||
|
||||
fireEvent.change(screen.getByTestId('order-tif'), {
|
||||
target: { value: Schema.OrderTimeInForce.TIME_IN_FORCE_IOC },
|
||||
});
|
||||
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC
|
||||
);
|
||||
|
||||
// Switch to limit order
|
||||
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
||||
|
||||
// Check all TIF options shown
|
||||
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
||||
Object.keys(Schema.OrderTimeInForce).length
|
||||
);
|
||||
});
|
||||
|
||||
it('handles TIF select box dependent on order type', () => {
|
||||
render(generateJsx());
|
||||
|
||||
@@ -221,4 +191,36 @@ describe('DealTicket', () => {
|
||||
).toHaveTextContent('Wrong trading mode');
|
||||
});
|
||||
});
|
||||
|
||||
it('can edit deal ticket', async () => {
|
||||
render(generateJsx());
|
||||
|
||||
// BUY is selected by default
|
||||
expect(
|
||||
screen.getByTestId('order-side-SIDE_BUY')?.querySelector('input')
|
||||
).toBeChecked();
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(screen.getByTestId('order-size'), {
|
||||
target: { value: '200' },
|
||||
});
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('order-size')).toHaveDisplayValue('200');
|
||||
|
||||
fireEvent.change(screen.getByTestId('order-tif'), {
|
||||
target: { value: Schema.OrderTimeInForce.TIME_IN_FORCE_IOC },
|
||||
});
|
||||
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC
|
||||
);
|
||||
|
||||
// Switch to limit order
|
||||
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
||||
|
||||
// Check all TIF options shown
|
||||
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
||||
Object.keys(Schema.OrderTimeInForce).length
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { useOrderMarginValidation } from '../../hooks/use-order-margin-validation';
|
||||
import { MarginWarning } from '../deal-ticket-validation/margin-warning';
|
||||
import { usePersistedOrder } from '../../hooks/use-persisted-order';
|
||||
import { usePersistedOrderStore } from '../../hooks/use-persisted-order';
|
||||
import {
|
||||
getDefaultOrder,
|
||||
validateMarketState,
|
||||
@@ -43,7 +43,13 @@ export type DealTicketFormFields = OrderSubmissionBody['orderSubmission'] & {
|
||||
|
||||
export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const [persistedOrder, setPersistedOrder] = usePersistedOrder(market);
|
||||
// const [persistedOrder, setPersistedOrder] = usePersistedOrder(market);
|
||||
const { getPersistedOrder, setPersistedOrder } = usePersistedOrderStore(
|
||||
(store) => ({
|
||||
getPersistedOrder: store.getOrder,
|
||||
setPersistedOrder: store.setOrder,
|
||||
})
|
||||
);
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
@@ -53,7 +59,7 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
||||
clearErrors,
|
||||
formState: { errors },
|
||||
} = useForm<DealTicketFormFields>({
|
||||
defaultValues: persistedOrder || getDefaultOrder(market),
|
||||
defaultValues: getPersistedOrder(market.id) || getDefaultOrder(market),
|
||||
});
|
||||
|
||||
const order = watch();
|
||||
|
||||
@@ -1,20 +1,43 @@
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import produce from 'immer';
|
||||
import create from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
|
||||
type OrderData = OrderSubmissionBody['orderSubmission'] | null;
|
||||
|
||||
export const usePersistedOrder = (market: {
|
||||
id: string;
|
||||
}): [OrderData, (value: OrderData) => void] => {
|
||||
const [value, setValue] = useLocalStorage(`deal-ticket-order-${market.id}`);
|
||||
const order = value != null ? (JSON.parse(value) as OrderData) : null;
|
||||
const setOrder = useCallback(
|
||||
(order: OrderData) => setValue(JSON.stringify(order)),
|
||||
[setValue]
|
||||
);
|
||||
return useMemo<[OrderData, (value: OrderData) => void]>(
|
||||
() => [order, setOrder],
|
||||
[order, setOrder]
|
||||
);
|
||||
type PersistedOrderStore = {
|
||||
orders: OrderData[];
|
||||
getOrder: (marketId: string) => OrderData | undefined;
|
||||
setOrder: (order: OrderData) => void;
|
||||
clear: () => void;
|
||||
};
|
||||
|
||||
export const usePersistedOrderStore = create(
|
||||
persist<PersistedOrderStore>(
|
||||
(set, get) => ({
|
||||
orders: [],
|
||||
getOrder: (marketId) => {
|
||||
const persisted = get().orders.find((o) => o?.marketId === marketId);
|
||||
return persisted;
|
||||
},
|
||||
setOrder: (order) => {
|
||||
set(
|
||||
produce((store: PersistedOrderStore) => {
|
||||
const persisted = store.orders.find(
|
||||
(o) => o?.marketId === order?.marketId
|
||||
);
|
||||
if (persisted) {
|
||||
Object.assign(persisted, order);
|
||||
} else {
|
||||
store.orders.push(order);
|
||||
}
|
||||
})
|
||||
);
|
||||
},
|
||||
clear: () => set({ orders: [] }),
|
||||
}),
|
||||
{
|
||||
name: 'VEGA_DEAL_TICKET_ORDER_STORE',
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -78,6 +78,10 @@ const getBundledEnvironmentValue = (key: EnvKey) => {
|
||||
return process.env['NX_VEGA_DOCS_URL'];
|
||||
case 'HOSTED_WALLET_URL':
|
||||
return process.env['NX_HOSTED_WALLET_URL'];
|
||||
case 'ETH_LOCAL_PROVIDER_URL':
|
||||
return process.env['NX_ETH_LOCAL_PROVIDER_URL'];
|
||||
case 'ETH_WALLET_MNEMONIC':
|
||||
return process.env['NX_ETH_WALLET_MNEMONIC'];
|
||||
case 'MAINTENANCE_PAGE':
|
||||
return (
|
||||
process.env['MAINTENANCE_PAGE'] || process.env['NX_MAINTENANCE_PAGE']
|
||||
|
||||
@@ -50,6 +50,8 @@ const schemaObject = {
|
||||
}),
|
||||
HOSTED_WALLET_URL: z.optional(z.string()),
|
||||
MAINTENANCE_PAGE: z.optional(z.boolean()),
|
||||
ETH_LOCAL_PROVIDER_URL: z.optional(z.string()),
|
||||
ETH_WALLET_MNEMONIC: z.optional(z.string()),
|
||||
};
|
||||
|
||||
export const ENV_KEYS = Object.keys(schemaObject) as Array<
|
||||
|
||||
@@ -161,6 +161,13 @@ describe('useDataProvider hook', () => {
|
||||
});
|
||||
expect(update).toBeCalledTimes(1);
|
||||
|
||||
// setting same variables, with different object reference
|
||||
await act(async () => {
|
||||
rerender({ dataProvider, update, variables: { ...variables } });
|
||||
});
|
||||
expect(unsubscribe).toBeCalledTimes(0);
|
||||
expect(dataProvider).toBeCalledTimes(1);
|
||||
|
||||
// changing variables after date was loaded
|
||||
await act(async () => {
|
||||
rerender({ dataProvider, update, variables: { partyId: '0x321' } });
|
||||
@@ -173,7 +180,7 @@ describe('useDataProvider hook', () => {
|
||||
await act(async () => {
|
||||
callback({ ...updateCallbackPayload });
|
||||
});
|
||||
expect(update).toBeCalledTimes(2);
|
||||
expect(update).toBeCalledTimes(3);
|
||||
|
||||
// changing variables, apollo query will return error
|
||||
await act(async () => {
|
||||
@@ -193,7 +200,7 @@ describe('useDataProvider hook', () => {
|
||||
pageInfo: null,
|
||||
});
|
||||
});
|
||||
expect(update).toBeCalledTimes(3);
|
||||
expect(update).toBeCalledTimes(5);
|
||||
});
|
||||
|
||||
it('do not create data provider instance when skip is true', async () => {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { usePrevious } from './use-previous';
|
||||
import type { OperationVariables } from '@apollo/client';
|
||||
import type {
|
||||
Subscribe,
|
||||
@@ -52,9 +54,9 @@ export const useDataProvider = <
|
||||
dataProvider,
|
||||
update,
|
||||
insert,
|
||||
variables,
|
||||
skipUpdates,
|
||||
skip,
|
||||
...props
|
||||
}: useDataProviderParams<Data, Delta, Variables>) => {
|
||||
const client = useApolloClient();
|
||||
const [data, setData] = useState<Data | null>(null);
|
||||
@@ -65,6 +67,13 @@ export const useDataProvider = <
|
||||
const reloadRef = useRef<((force?: boolean) => void) | undefined>(undefined);
|
||||
const loadRef = useRef<Load<Data> | undefined>(undefined);
|
||||
const initialized = useRef<boolean>(false);
|
||||
const prevVariables = usePrevious(props.variables);
|
||||
const [variables, setVariables] = useState(props.variables);
|
||||
useEffect(() => {
|
||||
if (!isEqual(prevVariables, props.variables)) {
|
||||
setVariables(props.variables);
|
||||
}
|
||||
}, [props.variables, prevVariables]);
|
||||
const flush = useCallback(() => {
|
||||
if (flushRef.current) {
|
||||
flushRef.current();
|
||||
@@ -125,6 +134,9 @@ export const useDataProvider = <
|
||||
setData(null);
|
||||
setError(undefined);
|
||||
setTotalCount(undefined);
|
||||
if (initialized.current && update) {
|
||||
update({ data: null });
|
||||
}
|
||||
initialized.current = false;
|
||||
if (skip) {
|
||||
setLoading(false);
|
||||
|
||||
@@ -21,11 +21,16 @@ export const ViewingAsBanner = ({
|
||||
disconnect,
|
||||
}: ViewingAsBannerProps) => {
|
||||
return (
|
||||
<div className="w-full p-2 bg-neutral-800 flex justify-between text-neutral-400">
|
||||
<div
|
||||
data-testid="view-banner"
|
||||
className="w-full p-2 bg-neutral-800 flex justify-between text-neutral-400"
|
||||
>
|
||||
<div className="text-base flex items-center justify-center">
|
||||
{t('Viewing as Vega user:')} {pubKey && truncateMiddle(pubKey)}
|
||||
</div>
|
||||
<Button onClick={disconnect}>{t('Exit view as')}</Button>
|
||||
<Button data-testid="exit-view" onClick={disconnect}>
|
||||
{t('Exit view as')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -223,7 +223,7 @@ describe('VegaConnectDialog', () => {
|
||||
.mockImplementation(() => delayedResolve({ chainID: mockChainId }));
|
||||
spyOnConnectWallet = jest
|
||||
.spyOn(connectors.jsonRpc, 'connectWallet')
|
||||
.mockImplementation(() => delayedResolve({ token: 'token' }));
|
||||
.mockImplementation(() => delayedResolve(null));
|
||||
spyOnConnect = jest
|
||||
.spyOn(connectors.jsonRpc, 'connect')
|
||||
.mockImplementation(() =>
|
||||
|
||||
@@ -56,7 +56,7 @@ export function ViewConnectorForm({
|
||||
<InputError intent="danger">{errors.address.message}</InputError>
|
||||
)}
|
||||
</FormGroup>
|
||||
<Button variant="primary" type="submit" fill={true}>
|
||||
<Button data-testid="connect" variant="primary" type="submit" fill={true}>
|
||||
{t('Connect')}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -46,6 +46,13 @@ export class JsonRpcConnector implements VegaConnector {
|
||||
this.client = new WalletClient({
|
||||
address: cfg.url,
|
||||
token: cfg.token ?? undefined,
|
||||
onTokenChange: (token) => {
|
||||
setConfig({
|
||||
token,
|
||||
connector: 'jsonRpc',
|
||||
url: this._url,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -55,6 +62,12 @@ export class JsonRpcConnector implements VegaConnector {
|
||||
this.client = new WalletClient({
|
||||
address: url,
|
||||
token: this.token ?? undefined,
|
||||
onTokenChange: (token) =>
|
||||
setConfig({
|
||||
token,
|
||||
url,
|
||||
connector: 'jsonRpc',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -76,13 +89,8 @@ export class JsonRpcConnector implements VegaConnector {
|
||||
}
|
||||
|
||||
try {
|
||||
const { result } = await this.client.ConnectWallet();
|
||||
setConfig({
|
||||
token: result.token,
|
||||
connector: 'jsonRpc',
|
||||
url: this._url,
|
||||
});
|
||||
return result;
|
||||
await this.client.ConnectWallet();
|
||||
return null;
|
||||
} catch (err) {
|
||||
const clientErr =
|
||||
err instanceof WalletClientError && err.code === 3001
|
||||
|
||||
@@ -20,3 +20,5 @@ export * from './lib/web3-connectors';
|
||||
export * from './lib/web3-connect-dialog';
|
||||
export * from './lib/web3-connect-store';
|
||||
export * from './lib/web3-container';
|
||||
export * from './lib/url-connector';
|
||||
export * from './lib/eip-1193-custom-bridge';
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import { ethers, Wallet } from 'ethers';
|
||||
import { Connector } from '@web3-react/types';
|
||||
|
||||
import { Eip1193Bridge } from '@ethersproject/experimental';
|
||||
import type { ConnectionInfo } from '@ethersproject/web';
|
||||
import type { Actions } from '@web3-react/types';
|
||||
import { ENV } from '../config/env';
|
||||
import { ethers } from 'ethers';
|
||||
|
||||
export class CustomizedBridge extends Eip1193Bridge {
|
||||
export class Eip1193CustomBridge extends Eip1193Bridge {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
async sendAsync(...args: any) {
|
||||
console.debug('sendAsync called', ...args);
|
||||
@@ -89,63 +84,3 @@ export class CustomizedBridge extends Eip1193Bridge {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type url = string | ConnectionInfo;
|
||||
|
||||
export class Url extends Connector {
|
||||
/** {@inheritdoc Connector.provider} */
|
||||
public override provider: Eip1193Bridge | undefined;
|
||||
|
||||
private eagerConnection?: Promise<void>;
|
||||
private url: url;
|
||||
|
||||
/**
|
||||
* @param url - An RPC url.
|
||||
* @param connectEagerly - A flag indicating whether connection should be initiated when the class is constructed.
|
||||
*/
|
||||
constructor(actions: Actions, url: url, connectEagerly = false) {
|
||||
super(actions);
|
||||
|
||||
if (connectEagerly && typeof window === 'undefined') {
|
||||
throw new Error(
|
||||
'connectEagerly = true is invalid for SSR, instead use the activate method in a useEffect'
|
||||
);
|
||||
}
|
||||
|
||||
this.url = url;
|
||||
|
||||
if (connectEagerly) void this.activate();
|
||||
}
|
||||
|
||||
private async isomorphicInitialize() {
|
||||
if (this.eagerConnection) return this.eagerConnection;
|
||||
|
||||
await (this.eagerConnection = import('@ethersproject/providers')
|
||||
.then(({ JsonRpcProvider }) => JsonRpcProvider)
|
||||
.then((JsonRpcProvider) => {
|
||||
const provider = new JsonRpcProvider(this.url);
|
||||
const privateKey = Wallet.fromMnemonic(
|
||||
ENV.ethWalletMnemonic,
|
||||
`m/44'/60'/0'/0/0`
|
||||
).privateKey;
|
||||
const signer = new Wallet(privateKey, provider);
|
||||
this.provider = new CustomizedBridge(signer, provider);
|
||||
this.actions.update({ accounts: [signer.address], chainId: 1440 });
|
||||
}));
|
||||
}
|
||||
|
||||
/** {@inheritdoc Connector.activate} */
|
||||
public async activate(): Promise<void> {
|
||||
this.actions.startActivation();
|
||||
|
||||
await this.isomorphicInitialize();
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const chainId = await this.provider!.request({ method: 'eth_chainId' });
|
||||
this.actions.update({ chainId: Number(chainId) });
|
||||
} catch (error) {
|
||||
this.actions.reportError(error as Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,12 @@ export const getTransactionContent = ({
|
||||
/>
|
||||
)}
|
||||
{(status === EthTxStatus.Confirmed || status === EthTxStatus.Error) && (
|
||||
<Button size="sm" className="mt-2" onClick={reset}>
|
||||
<Button
|
||||
size="sm"
|
||||
className="mt-2"
|
||||
data-testid={returnLabel}
|
||||
onClick={reset}
|
||||
>
|
||||
{returnLabel ? returnLabel : t('Return')}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Wallet } from 'ethers';
|
||||
import { Connector } from '@web3-react/types';
|
||||
|
||||
import type { ConnectionInfo } from '@ethersproject/web';
|
||||
import type { Actions } from '@web3-react/types';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import type { Eip1193Bridge } from '@ethersproject/experimental';
|
||||
import { Eip1193CustomBridge } from './eip-1193-custom-bridge';
|
||||
|
||||
type url = string | ConnectionInfo;
|
||||
|
||||
export class UrlConnector extends Connector {
|
||||
/** {@inheritdoc Connector.provider} */
|
||||
public override provider: Eip1193Bridge | undefined;
|
||||
|
||||
private eagerConnection?: Promise<void>;
|
||||
private url: url;
|
||||
private ethWalletMnemonic: string;
|
||||
|
||||
/**
|
||||
* @param url - An RPC url.
|
||||
* @param connectEagerly - A flag indicating whether connection should be initiated when the class is constructed.
|
||||
*/
|
||||
constructor(
|
||||
actions: Actions,
|
||||
url: url,
|
||||
ethWalletMnemonic: string,
|
||||
connectEagerly = false
|
||||
) {
|
||||
super(actions);
|
||||
|
||||
if (connectEagerly && typeof window === 'undefined') {
|
||||
throw new Error(
|
||||
'connectEagerly = true is invalid for SSR, instead use the activate method in a useEffect'
|
||||
);
|
||||
}
|
||||
|
||||
this.url = url;
|
||||
this.ethWalletMnemonic = ethWalletMnemonic;
|
||||
|
||||
if (connectEagerly) void this.activate();
|
||||
}
|
||||
|
||||
private async isomorphicInitialize() {
|
||||
if (this.eagerConnection) return this.eagerConnection;
|
||||
|
||||
await (this.eagerConnection = import('@ethersproject/providers')
|
||||
.then(({ JsonRpcProvider }) => JsonRpcProvider)
|
||||
.then((JsonRpcProvider) => {
|
||||
const provider = new JsonRpcProvider(this.url);
|
||||
const privateKey = Wallet.fromMnemonic(
|
||||
this.ethWalletMnemonic,
|
||||
`m/44'/60'/0'/0/0`
|
||||
).privateKey;
|
||||
const signer = new Wallet(privateKey, provider);
|
||||
this.provider = new Eip1193CustomBridge(signer, provider);
|
||||
this.actions.update({ accounts: [signer.address], chainId: 1440 });
|
||||
}));
|
||||
}
|
||||
|
||||
/** {@inheritdoc Connector.activate} */
|
||||
public async activate(): Promise<void> {
|
||||
this.actions.startActivation();
|
||||
|
||||
await this.isomorphicInitialize();
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const chainId = await this.provider!.request({ method: 'eth_chainId' });
|
||||
this.actions.update({ chainId: Number(chainId) });
|
||||
} catch (error) {
|
||||
this.actions.reportError(error as Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const initializeUrlConnector = (
|
||||
localProviderUrl?: string,
|
||||
walletMnemonic?: string
|
||||
) =>
|
||||
localProviderUrl &&
|
||||
walletMnemonic &&
|
||||
localProviderUrl.length > 0 &&
|
||||
walletMnemonic.length > 0
|
||||
? initializeConnector<UrlConnector>(
|
||||
(actions) => new UrlConnector(actions, localProviderUrl, walletMnemonic)
|
||||
)
|
||||
: null;
|
||||
@@ -1,6 +1,4 @@
|
||||
import create from 'zustand';
|
||||
import type { MetaMask } from '@web3-react/metamask';
|
||||
import type { WalletConnect } from '@web3-react/walletconnect';
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
|
||||
@@ -10,10 +8,7 @@ interface State {
|
||||
desiredChainId?: number;
|
||||
}
|
||||
interface Actions {
|
||||
initialize: (
|
||||
connectors: [MetaMask | WalletConnect, Web3ReactHooks][],
|
||||
desiredChainId: number
|
||||
) => void;
|
||||
initialize: (connectors: State['connectors'], desiredChainId: number) => void;
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import type { Web3ReactHooks } from '@web3-react/core';
|
||||
import { initializeConnector } from '@web3-react/core';
|
||||
import type { Connector } from '@web3-react/types';
|
||||
import { MetaMask } from '@web3-react/metamask';
|
||||
import { WalletConnect } from '@web3-react/walletconnect';
|
||||
import { initializeUrlConnector } from './url-connector';
|
||||
|
||||
export const createConnectors = (providerUrl: string, chainId: number) => {
|
||||
export const createConnectors = (
|
||||
providerUrl: string,
|
||||
chainId: number,
|
||||
localProviderUrl?: string,
|
||||
walletMnemonic?: string
|
||||
) => {
|
||||
if (isNaN(chainId)) {
|
||||
throw new Error('Invalid Ethereum chain ID for environment');
|
||||
}
|
||||
@@ -23,7 +30,8 @@ export const createConnectors = (providerUrl: string, chainId: number) => {
|
||||
[chainId]
|
||||
);
|
||||
return [
|
||||
initializeUrlConnector(localProviderUrl, walletMnemonic),
|
||||
[metamask, metamaskHooks],
|
||||
[walletconnect, walletconnectHooks],
|
||||
] as [MetaMask | WalletConnect, Web3ReactHooks][];
|
||||
].filter(Boolean) as [Connector, Web3ReactHooks][];
|
||||
};
|
||||
|
||||
@@ -22,13 +22,24 @@ export const Web3Container = ({
|
||||
connectEagerly,
|
||||
}: Web3ContainerProps) => {
|
||||
const { config, loading, error } = useEthereumConfig();
|
||||
const { ETHEREUM_PROVIDER_URL } = useEnvironment();
|
||||
const { ETHEREUM_PROVIDER_URL, ETH_LOCAL_PROVIDER_URL, ETH_WALLET_MNEMONIC } =
|
||||
useEnvironment();
|
||||
const connectors = useMemo(() => {
|
||||
if (config?.chain_id) {
|
||||
return createConnectors(ETHEREUM_PROVIDER_URL, Number(config?.chain_id));
|
||||
return createConnectors(
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
Number(config?.chain_id),
|
||||
ETH_LOCAL_PROVIDER_URL,
|
||||
ETH_WALLET_MNEMONIC
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}, [config?.chain_id, ETHEREUM_PROVIDER_URL]);
|
||||
}, [
|
||||
config?.chain_id,
|
||||
ETHEREUM_PROVIDER_URL,
|
||||
ETH_LOCAL_PROVIDER_URL,
|
||||
ETH_WALLET_MNEMONIC,
|
||||
]);
|
||||
return (
|
||||
<AsyncRenderer data={config} loading={loading} error={error}>
|
||||
{connectors && config && (
|
||||
|
||||
@@ -110,6 +110,7 @@ export const WithdrawalsTable = (
|
||||
complete: (withdrawal: WithdrawalFieldsFragment) => {
|
||||
createWithdrawApproval(withdrawal);
|
||||
},
|
||||
ethUrl: ETHERSCAN_URL,
|
||||
}}
|
||||
cellRendererSelector={({
|
||||
data,
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@
|
||||
"@sentry/nextjs": "^6.19.3",
|
||||
"@sentry/react": "^6.19.2",
|
||||
"@sentry/tracing": "^6.19.2",
|
||||
"@vegaprotocol/wallet-client": "0.1.5",
|
||||
"@vegaprotocol/wallet-client": "0.1.8",
|
||||
"@walletconnect/ethereum-provider": "^1.7.5",
|
||||
"@web3-react/core": "8.0.20-beta.0",
|
||||
"@web3-react/metamask": "8.0.16-beta.0",
|
||||
|
||||
@@ -9,9 +9,13 @@ const ignore = [
|
||||
'libs/fills/src/lib/fills-data-provider.ts',
|
||||
'libs/orders/src/lib/components/order-data-provider/order-data-provider.ts',
|
||||
'libs/trades/src/lib/trades-data-provider.ts',
|
||||
// any queries in libs/cypress run against capsule
|
||||
'libs/cypress/**/*.ts',
|
||||
'libs/cypress/**/*.js',
|
||||
];
|
||||
|
||||
const globPromise = util.promisify(glob);
|
||||
const globOptions = { ignore };
|
||||
|
||||
const processTsFiles = (files) => {
|
||||
for (const file of files) {
|
||||
@@ -44,15 +48,11 @@ ${textContent}
|
||||
};
|
||||
|
||||
const run = async () => {
|
||||
const files1 = await globPromise('apps/**/*.ts');
|
||||
const files2 = await globPromise('libs/**/*.ts');
|
||||
const files3 = await globPromise('apps/**/*.tsx');
|
||||
const files4 = await globPromise('lib/**/*.tsx');
|
||||
processTsFiles(
|
||||
[...files1, ...files2, ...files3, ...files4].filter(
|
||||
(f) => !ignore.includes(f)
|
||||
)
|
||||
);
|
||||
const files1 = await globPromise('apps/**/*.ts', globOptions);
|
||||
const files2 = await globPromise('libs/**/*.ts', globOptions);
|
||||
const files3 = await globPromise('apps/**/*.tsx', globOptions);
|
||||
const files4 = await globPromise('lib/**/*.tsx', globOptions);
|
||||
processTsFiles([...files1, ...files2, ...files3, ...files4]);
|
||||
const gqlFiles1 = await globPromise('lib/**/*.graphql');
|
||||
const gqlFiles2 = await globPromise('apps/**/*.graphql');
|
||||
processGraphQlFiles([...gqlFiles1, ...gqlFiles2]);
|
||||
|
||||
@@ -42,11 +42,11 @@ GatewayEnabled = true
|
||||
[Broker.SocketConfig]
|
||||
Port = {{add 300 .NodeNumber}}5
|
||||
|
||||
[DeHistory]
|
||||
[NetworkHistory]
|
||||
Enabled = true
|
||||
[DeHistory.Store]
|
||||
PeerID = "{{.GetDehistoryPeerID .NodeNumber}}"
|
||||
PrivKey = "{{.GetDehistoryPrivKey .NodeNumber}}"
|
||||
[NetworkHistory.Store]
|
||||
PeerID = "{{.GetNetworkHistoryPeerID .NodeNumber}}"
|
||||
PrivKey = "{{.GetNetworkHistoryPrivKey .NodeNumber}}"
|
||||
|
||||
BootstrapPeers = [{{- range $i, $peer := .IPSFPeers -}}
|
||||
{{- if ne $i 0 }},{{end -}}
|
||||
|
||||
@@ -41,15 +41,15 @@ GatewayEnabled = true
|
||||
[Broker.SocketConfig]
|
||||
Port = {{add 300 .NodeNumber}}5
|
||||
|
||||
[DeHistory]
|
||||
[NetworkHistory]
|
||||
Level = "Info"
|
||||
Enabled = true
|
||||
WipeOnStartup = true
|
||||
AddSnapshotsToStore = true
|
||||
AddSnapshotsInterval = "5s"
|
||||
[DeHistory.Store]
|
||||
PeerID = "{{.GetDehistoryPeerID .NodeNumber}}"
|
||||
PrivKey = "{{.GetDehistoryPrivKey .NodeNumber}}"
|
||||
[NetworkHistory.Store]
|
||||
PeerID = "{{.GetNetworkHistoryPeerID .NodeNumber}}"
|
||||
PrivKey = "{{.GetNetworkHistoryPrivKey .NodeNumber}}"
|
||||
|
||||
BootstrapPeers = [{{- range $i, $peer := .IPSFPeers -}}
|
||||
{{- if ne $i 0 }},{{end -}}
|
||||
@@ -60,6 +60,6 @@ GatewayEnabled = true
|
||||
SwarmPort = {{add 400 .NodeNumber}}5
|
||||
StartWebUI = false
|
||||
WebUIPort = {{add 500 .NodeNumber}}5
|
||||
[DeHistory.Snapshot]
|
||||
[NetworkHistory.Snapshot]
|
||||
PanicOnSnapshotCreationError = true
|
||||
WaitForCreationLockTimeout = "5s"
|
||||
|
||||
@@ -7559,10 +7559,10 @@
|
||||
"@typescript-eslint/types" "5.40.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@vegaprotocol/wallet-client@0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vegaprotocol/wallet-client/-/wallet-client-0.1.5.tgz#9d72a7fc9ceb9767f5119c9b7eebe29a2c30f682"
|
||||
integrity sha512-7FmIBFxissr3h2QsEjvD+HXEXJ3u/oaVUg055IgZ08dmy1+4Nx22BOffFyidLBmaH1xJYjyiqxHnhLGnN5BfwA==
|
||||
"@vegaprotocol/wallet-client@0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vegaprotocol/wallet-client/-/wallet-client-0.1.8.tgz#38ca8566d78b9f6694b12ad9364bb34d6482935d"
|
||||
integrity sha512-FVvDvvlccKyXn0ujhivPUCVnkZYQJxtI1q8OgipNnbmAjU1mLyeuRTBw0Isu330yPI1KppNbW6Qicd8OTHBmxw==
|
||||
dependencies:
|
||||
express "4.18.2"
|
||||
nanoid "3.3.4"
|
||||
|
||||
Reference in New Issue
Block a user