Compare commits

..
Author SHA1 Message Date
Artur Siaznik 25e42582da chore: nx upgrade for trading-e2e 2023-04-18 14:00:08 +02:00
Bartłomiej Głownia 721009bec8 chore: upgrade nx, remove custom executors, amend trading app .env files 2023-04-18 13:03:24 +02:00
Bartłomiej Głownia 31859cb779 chore(trading): maintain always up to date active orders list (#3430) 2023-04-18 12:49:42 +02:00
dexturr 20507ecdd1 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-18 06:08:58 +00:00
dexturr 13ba661ea0 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-18 00:16:31 +00:00
dexturr 03f5b9fc7b chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-17 18:07:00 +00:00
dexturr b9fed65615 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-17 12:10:37 +00:00
Mikołaj Młodzikowski d671e51edf fix(ci): adjust timeouts 2023-04-17 12:45:30 +02:00
Mikołaj Młodzikowski 4f3295d3fc feat(ci): rebuild yarn on failed build 2023-04-17 11:24:53 +02:00
dexturr 7be7bab1ca chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-17 06:09:49 +00:00
dexturr 61380f06b9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-17 00:14:49 +00:00
dexturr c113856d63 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-16 18:07:16 +00:00
dexturr 90884beee8 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-16 12:07:18 +00:00
dexturr d9d2e428f4 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-16 06:09:55 +00:00
dexturr ba8d54b761 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-16 00:15:24 +00:00
dexturr dce4edb943 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-15 18:06:56 +00:00
dexturr b468a0fd84 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-15 12:07:02 +00:00
dexturr c98fbe7453 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-15 06:06:58 +00:00
dexturr d20928ec06 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-15 00:15:18 +00:00
dexturr 289559fe4f chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-14 18:09:58 +00:00
Mikołaj Młodzikowski 071fd6128c feat: fix releasing dist 2023-04-14 15:45:14 +02:00
Mikołaj Młodzikowski 554d07a31b feat(ci): fix regressions detected after merging to develop (#3442) 2023-04-14 15:00:20 +02:00
dexturr 48b62380b0 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-14 12:10:09 +00:00
Mikołaj Młodzikowski a9f4604bad feat(governance,trading,explorer): pipelines improvements (#3422) 2023-04-14 11:47:41 +02:00
Sam Keen 54f2519a62 feat(governance): toggles design review tweaks (#3431) 2023-04-14 09:22:22 +01:00
dexturr 260e7bf9cf chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-14 06:09:41 +00:00
dexturr 83db796cdb chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-14 00:14:08 +00:00
m.ray 2f6800212e fix(trading): fix order toast intent on amendments (#3433) 2023-04-13 13:20:28 -07:00
dexturr 77e16ad1b7 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-13 18:09:10 +00:00
dexturr dcce983842 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-13 12:10:33 +00:00
Maciek 53ce9bfaa2 chore(assets): make query for asset list lighter (#3425) 2023-04-13 11:42:09 +00:00
Edd 6ae34d296f fix(explorer): tweak footer to show more detail on smaller screens (#3418) 2023-04-13 10:49:42 +01:00
Joe Tsang ee2aafb99c fix(governance): failing nightly tests (#3351) 2023-04-13 10:46:01 +01:00
dexturr e8fdb63323 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-13 06:09:41 +00:00
dexturr 3df9270b57 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-13 00:13:51 +00:00
dexturr ab26667265 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-12 18:08:22 +00:00
m.ray 9fc6b255c8 fix(orders): update order toast intent and title (#3424) 2023-04-12 15:19:15 +00:00
dexturr 91f61d8bb5 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-12 12:09:32 +00:00
Bartłomiej Głowniaandm.ray bbfda65bcc feat(withdraws): improve ux surrounding withdraw balances thresholds and delays (#3402)
Co-authored-by: m.ray <16125548+MadalinaRaicu@users.noreply.github.com>
2023-04-12 11:21:24 +02:00
Mikołaj Młodzikowski 45f2e926c3 feat(governance,trading,explorer): split steps by logic (#3387) 2023-04-12 09:38:26 +02:00
dexturr ccadbc2cb6 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-12 06:08:40 +00:00
dexturr 7128acb7b8 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-12 00:14:18 +00:00
dexturr 357bdaa4f3 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-11 18:07:51 +00:00
Maciek f3fe43724e fix(deposits): deposit dialog doesn't respect given assetId (#3414) 2023-04-11 16:41:20 +02:00
m.ray 03f5ca3096 fix(trading): fix formatting on clicking on orderbook cell after decimal resolution update (#3409) 2023-04-11 12:23:43 +00:00
dexturr 03d19349af chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-11 12:08:24 +00:00
daro-maj 1f53b2cbb5 test(trading): increase coverage for the remaining ACs (#3412) 2023-04-11 11:59:21 +02:00
Maciek b010c98346 fix(trading): welcome dialog with markets list click on market close window (#3404) 2023-04-11 11:34:44 +02:00
Matthew Russell 29d57af2ba fix(trading): make light theme sell volume bar match candle color (#3405) 2023-04-11 09:06:35 +02:00
Bartłomiej Głownia fd7940c4cf chore(deal-ticket): remove not used code (#3406) 2023-04-11 08:13:41 +02:00
dexturr 8ab7ac8414 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-11 06:07:03 +00:00
dexturr ce7cd03c3e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-11 00:15:30 +00:00
Matthew Russell dfa3355a68 chore(trading): prevent node poll if query fails (#3411) 2023-04-10 14:48:03 -07:00
dexturr 8553904d81 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-10 18:07:16 +00:00
dexturr 10afa3c1d4 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-10 12:10:31 +00:00
Maciek ecd362615e chore(deposits): impove UX on deposit dialog (#3401) 2023-04-10 12:59:02 +01:00
dexturr 0d9bd67465 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-10 06:07:18 +00:00
dexturr b5aa92f007 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-10 00:14:34 +00:00
dexturr 2955790be1 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-09 18:09:21 +00:00
dexturr 89ff9309e9 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-09 12:08:56 +00:00
dexturr e1df3489f6 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-09 06:09:36 +00:00
dexturr f0fa9ca5e1 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-09 00:17:04 +00:00
dexturr 9d92477c2a chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-08 18:08:30 +00:00
dexturr b1a198be85 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-08 12:09:49 +00:00
dexturr 5fb385d43c chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-08 06:07:03 +00:00
dexturr 8014b279fe chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-08 00:14:19 +00:00
dexturr f4bde57294 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-07 18:09:32 +00:00
John Walley 2e5ff07824 chore(candles-chart): upgrade pennant to v1.8.1 (#3399) 2023-04-07 10:35:10 -07:00
Bartłomiej Głownia 7accb42793 fix(market-depth): make market data up to date, use fixed number of decimals in cumulative vol (#3361) 2023-04-07 10:34:51 -07:00
Matthew Russell 9229e7f686 chore(trading): update approval amount to be max uint256 (#3395) 2023-04-07 10:33:53 -07:00
daro-maj b570b9c4c1 test(trading): tests for post and reduce functionality (#3400) 2023-04-07 13:03:15 -04:00
m.ray ed78261aad fix(trading): order tx toasts title and intent should be set by status (#3368) 2023-04-07 13:01:12 -04:00
m.ray 363ca9c6e1 fix(trading): add liquidity provision docs (#3403) 2023-04-07 13:00:57 -04:00
m.ray bafd3c384c feat(trading): include fees in transfer amount (#3345) 2023-04-07 13:00:11 -04:00
dexturr 3b830abe07 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-07 12:09:01 +00:00
dexturr 1787e22b69 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-07 06:07:23 +00:00
dexturr f105133959 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-07 00:14:21 +00:00
dexturr aff0e46d23 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-06 18:08:45 +00:00
Maciek 7e4aafcb77 chore(trading): add filters to the proposals table (#3375) 2023-04-06 15:30:21 +02:00
dexturr 643d5408cd chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-06 12:08:03 +00:00
m.ray 2a2af3ba9c fix(trading): fix docs resources (#3382) 2023-04-06 12:53:08 +01:00
Sam Keen 8d4e4a1228 fix(governance): fix incorrect validator penalties (#3381) 2023-04-06 13:31:21 +02:00
dexturr 84068c8081 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-06 06:09:30 +00:00
dexturr e1185b9a96 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-06 00:13:22 +00:00
dexturr f390448c24 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-05 18:09:37 +00:00
Maciek 70943c523c chore(deposits): persistence of deposit form state (#3348) 2023-04-05 14:53:55 +02:00
dexturr dcb79e70d3 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-05 12:10:10 +00:00
dexturr cc72cdbe16 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-05 06:08:13 +00:00
dexturr 3fd1817e1e chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-05 00:15:53 +00:00
Matthew Russell b483c13f81 chore(trading): fix bad grammar on approval notification (#3354) 2023-04-04 15:14:36 -07:00
Matthew Russell bde7a9fbf9 fix(smart-contracts): add increased gas limit estimation (#3371) 2023-04-04 11:41:11 -07:00
dexturr 5fd93ee9c8 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-04 18:09:38 +00:00
botond 9ac07fd98a fix: add missing announcement config url (#3367) 2023-04-04 15:11:48 +00:00
dexturr 9c975ed822 chore: update tranches
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-04-04 12:10:23 +00:00
Edd 138bf7da00 build(explorer): update validator testnet be url (#3357) 2023-04-04 10:53:47 +00:00
225 changed files with 6649 additions and 6251 deletions
+85 -5
View File
@@ -4,14 +4,54 @@ on:
push:
branches:
- release/*
- develop
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
- reopened
- edited
- synchronize
jobs:
node-modules:
runs-on: ubuntu-22.04
name: 'Cache yarn modules'
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache node modules
id: cache
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
# comment out "resotre-keys" if you need to rebuild yarn from 0
restore-keys: |
${{ runner.os }}-cache-node-modules-
- name: Setup node
uses: actions/setup-node@v3
if: steps.cache.outputs.cache-hit != 'true'
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: yarn install
if: steps.cache.outputs.cache-hit != 'true'
run: yarn install --pure-lockfile
lint-pr-title:
needs: node-modules
if: ${{ github.event_name == 'pull_request' }}
name: Verify PR title
uses: ./.github/workflows/lint-pr.yml
secrets: inherit
lint-test-build:
timeout-minutes: 20
needs: node-modules
runs-on: ubuntu-22.04
name: '(CI) lint + unit test + build'
steps:
@@ -27,8 +67,11 @@ jobs:
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v3
@@ -48,7 +91,7 @@ jobs:
run: yarn nx affected:test
- name: Build affected
run: yarn nx affected:build
run: yarn nx affected:build || (yarn install && yarn nx affected:build)
# See affected apps
- name: See affected apps
@@ -95,6 +138,43 @@ jobs:
with:
projects: ${{ needs.lint-test-build.outputs.projects }}
dist-check:
runs-on: ubuntu-latest
needs: publish-dist
if: ${{ github.event_name == 'pull_request' }}
name: '(CD) comment preview links'
steps:
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
body-includes: Previews
- name: Inject slug/short variables
if: ${{ steps.fc.outputs.comment-id == 0 }}
uses: rlespinasse/github-slug-action@v4
with:
prefix: CI_
- name: Create comment
if: ${{ steps.fc.outputs.comment-id == 0 }}
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
body: |
Previews
- explorer https://explorer.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
- trading https://trading.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
- governance https://governance.${{ env.CI_GITHUB_REF_NAME }}.vega.rocks
cypress-check:
name: '(CI) cypress - check'
runs-on: ubuntu-latest
needs: cypress
steps:
- run: echo Done!
# Report single result at the end, to avoid mess with required checks in PR
cypress-result:
if: ${{ always() }}
@@ -2,15 +2,11 @@
name: Verify PR title
on:
pull_request:
types:
- opened
- ready_for_review
- reopened
- edited
- synchronize
workflow_call:
jobs:
lint_pr:
timeout-minutes: 10
runs-on: ubuntu-22.04
steps:
- name: Checkout
@@ -23,8 +19,11 @@ jobs:
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
- name: Check PR title
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
+92 -29
View File
@@ -15,6 +15,7 @@ jobs:
app: ${{ fromJSON(inputs.projects) }}
name: ${{ matrix.app }}
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v3
@@ -36,66 +37,131 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# https://docs.github.com/en/actions/learn-github-actions/contexts
- name: Check node version
id: tags
run: |
nodeVersion=$(cat .nvmrc | head -n 1)
echo ::set-output name=nodeVersion::${nodeVersion}
- name: Setup node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
cache: yarn
- name: Cache node modules
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
# https://docs.github.com/en/actions/learn-github-actions/contexts
- name: Define variables
run: |
envName=''
dockerfile="dist.Dockerfile"
if [[ "${{ github.event_name }}" = "push" ]]; then
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
bucketName="${{ github.event.repository.name }}-$envName"
echo ::set-output name=bucketName::${bucketName}
echo ::set-output name=envName::${envName}
domain="vega.rocks"
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
if [[ "${{ github.ref }}" =~ .*mainnet.* ]]; then
domain="vega.community"
if [[ "${{ matrix.app }}" = "trading" ]]; then
dockerfile="ipfs.Dockerfile"
fi
fi
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
envName="stagnet3"
fi
bucketName="${{ matrix.app }}.${envName}.${domain}"
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
fi
nodeVersion=$(cat .nvmrc | head -n 1)
echo ENV_NAME=${envName} >> $GITHUB_ENV
echo NODE_VERSION=${nodeVersion} >> $GITHUB_ENV
echo DOCKERFILE=docker/${dockerfile} >> $GITHUB_ENV
- name: Build local dist
if: ${{ env.DOCKERFILE != 'docker/ipfs.Dockerfile' }}
run: |
flags=""
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
if [[ "${{ env.ENV_NAME }}" != "ops-vega" ]]; then
flags="--env=${{ env.ENV_NAME }}"
fi
fi
if [ "${{ matrix.app }}" = "trading" ]; then
yarn nx export trading $flags || (yarn install && yarn nx export trading $flags)
DIST_LOCATION=dist/apps/trading/exported
else
yarn nx build ${{ matrix.app }} $flags || (yarn install && yarn nx build ${{ matrix.app }} $flags)
DIST_LOCATION=dist/apps/${{ matrix.app }}
fi
mv $DIST_LOCATION dist-result
tree dist-result
- name: Build and export to local Docker
id: docker_build
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
uses: docker/build-push-action@v3
with:
context: .
file: ${{ env.DOCKERFILE }}
load: true
build-args: |
APP=${{ matrix.app }}
NODE_VERSION=${{ steps.tags.outputs.nodeVersion }}
ENV_NAME=${{ steps.tags.outputs.envName || '' }}
NODE_VERSION=${{ env.NODE_VERSION }}
ENV_NAME=${{ env.ENV_NAME }}
tags: |
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
- name: Image digest
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
run: echo ${{ steps.docker_build.outputs.digest }}
- name: Sanity check docker image
if: ${{ github.event_name == 'pull_request' || ( env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' ) }}
run: |
echo "Check ipfs-hash"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat ipfs-hash
if [[ "${{ env.DOCKERFILE }}" = "docker/ipfs.Dockerfile" ]]; then
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
fi
echo "List html directory"
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local ls -lah
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree .'
echo "Copy dist to local filesystem"
- name: Copy dist to local filesystem
if: ${{ env.DOCKERFILE == 'docker/ipfs.Dockerfile' && github.event_name == 'push' }}
run: |
docker create --name=dist ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local
docker cp dist:/usr/share/nginx/html dist
echo "Check local dist"
ls -al dist
echo "check local dist files"
tree dist/html
mv dist/html dist-result
- name: Publish dist as docker image
uses: docker/build-push-action@v3
if: ${{ github.event_name == 'pull_request' }}
with:
context: .
file: ${{ env.DOCKERFILE }}
push: true
build-args: |
APP=${{ matrix.app }}
NODE_VERSION=${{ steps.tags.outputs.nodeVersion }}
NODE_VERSION=${{ env.NODE_VERSION }}
ENV_NAME=${{ env.ENV_NAME }}
tags: |
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ github.event.pull_request.head.sha || github.sha }}
# - uses: shallwefootball/s3-upload-action@master
# if: ${{ github.event_name == 'push' }}
# name: Upload dist S3
# with:
# aws_key_id: ${{ secrets.AWS_KEY_ID }}
# aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
# aws_bucket: ${{ steps.tags.outputs.bucketName }}
# source_dir: 'dist'
# bucket creation in github.com/vegaprotocol/terraform//frontend
- name: Publish dist to s3
uses: jakejarvis/s3-sync-action@master
if: ${{ github.event_name == 'push' }}
with:
args: --acl private --follow-symlinks --delete
env:
AWS_S3_BUCKET: ${{ env.BUCKET_NAME }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'eu-west-1'
SOURCE_DIR: 'dist-result'
- name: Add preview label
uses: actions-ecosystem/action-add-labels@v1
@@ -103,6 +169,3 @@ jobs:
with:
labels: ${{ matrix.app }}-preview
number: ${{ github.event.number }}
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
-2
View File
@@ -4,8 +4,6 @@
/dist
/tmp
/out-tsc
/tools/executors/**/*.js
/tools/utils/*.js
# dependencies
/node_modules
+1
View File
@@ -1,4 +1,5 @@
{
"name": "explorer-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/explorer-e2e/src",
"projectType": "application",
+1 -2
View File
@@ -1,10 +1,10 @@
{
"name": "explorer",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/explorer/src",
"projectType": "application",
"targets": {
"build": {
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -38,7 +38,6 @@
}
},
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3000,
"buildTarget": "explorer:build:development",
@@ -10,7 +10,7 @@ export const Footer = () => {
const [nodeSwitcherOpen, setNodeSwitcherOpen] = useState(false);
const { screenSize } = useScreenDimensions();
const showFullFeedbackLabel = useMemo(
() => ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
() => ['md', 'lg', 'xl', 'xxl', 'xxxl'].includes(screenSize),
[screenSize]
);
+1
View File
@@ -1,4 +1,5 @@
{
"name": "governance-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/governance-e2e/src",
"projectType": "application",
@@ -44,7 +44,8 @@ describe(
function () {
before('connect wallets and set approval limit', function () {
cy.visit('/');
vegaWalletSetSpecifiedApprovalAmount('1000');
ethereumWalletConnect();
cy.associateTokensToVegaWallet('1');
});
beforeEach('visit proposals tab', function () {
@@ -213,6 +214,7 @@ describe(
// 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060
it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () {
vegaWalletSetSpecifiedApprovalAmount('1000');
createRawProposal();
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
getSubmittedProposalFromProposalList(rawProposal.rationale.title)
@@ -13,7 +13,6 @@ import {
createUpdateNetworkProposalTxBody,
createFreeFormProposalTxBody,
} from '../../support/proposal.functions';
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
@@ -33,10 +32,6 @@ context(
before('Connect wallets and set approval', function () {
cy.visit('/');
vegaWalletSetSpecifiedApprovalAmount('1000');
cy.connectVegaWallet();
ethereumWalletConnect();
ensureSpecifiedUnstakedTokensAreAssociated('1');
cy.clearLocalStorage();
});
beforeEach('visit proposals', function () {
@@ -114,7 +109,7 @@ context(
navigateTo(navigation.proposals);
cy.reload();
waitForSpinner();
cy.get(openProposals).within(() => {
cy.get(openProposals, { timeout: 6000 }).within(() => {
cy.contains(proposalTitle)
.parentsUntil('[data-testid="proposals-list-item"]')
.within(() => cy.get(viewProposalButton).click());
@@ -232,7 +232,7 @@ context(
it('Unable to create a freeform proposal - when json parent section contains unexpected field', function () {
const errorMsg =
'Invalid params: the transaction does not use a valid Vega command: unknown field unexpected" in vega.commands.v1.ProposalSubmission';
'Invalid params: the transaction does not use a valid Vega command: unknown field "unexpected" in vega.commands.v1.ProposalSubmission';
// 3001-VOTE-038 3002-PROP-013 3002-PROP-014
goToMakeNewProposal(governanceProposalType.RAW);
@@ -313,7 +313,7 @@ context(
it('Unable to vote on a proposal - when vega wallet disconnected - option to connect from within', function () {
createRawProposal();
cy.get('[data-testid="manage-vega-wallet"]').click();
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
cy.get('[data-testid="disconnect"]').click();
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
getSubmittedProposalFromProposalList(
@@ -218,7 +218,7 @@ context(
it('Unable to submit new market proposal with missing/invalid fields', function () {
const errorMsg =
'Invalid params: the transaction is not a valid Vega command: unknown field "filters" in vega.DataSourceDefinition';
'Invalid params: the transaction does not use a valid Vega command: unknown field "invalid" in vega.NewMarket';
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
cy.get(newProposalSubmitButton).should('be.visible').click();
@@ -436,7 +436,7 @@ context(
});
});
it.only('Able to submit update asset proposal using max deadline', function () {
it('Able to submit update asset proposal using max deadline', function () {
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
enterUpdateAssetProposalDetails();
cy.get(maxVoteDeadline).click();
@@ -25,11 +25,11 @@ const vegaWalletUnstakedBalance =
'[data-testid="vega-wallet-balance-unstaked"]';
const txTimeout = Cypress.env('txTimeout');
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
const ethWalletAssociateButton = '[data-testid="associate-btn"]';
const ethWalletAssociateButton = '[data-testid="associate-btn"]:visible';
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="/token/disassociate"]';
const ethWalletDissociateButton = '[href="/token/disassociate"]:visible';
const vestingContractSection = '[data-testid="vega-in-vesting-contract"]';
const vegaInWalletSection = '[data-testid="vega-in-wallet"]';
const connectedVegaKey = '[data-testid="connected-vega-key"]';
@@ -78,12 +78,12 @@ context(
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '0.00');
validateWalletCurrency('Pending association', '2.00');
validateWalletCurrency('Total associated after pending', '2.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
// 0005-ETXN-002
verifyEthWalletAssociatedBalance('2.0');
@@ -111,12 +111,12 @@ context(
stakingPageDisassociateTokens('2');
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '2.00');
validateWalletCurrency('Pending association', '2.00');
validateWalletCurrency('Total associated after pending', '0.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
cy.getByTestId('eth-wallet-associated-balances', txTimeout).should(
'not.exist'
);
@@ -192,12 +192,12 @@ context(
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '0.00');
validateWalletCurrency('Pending association', '2.00');
validateWalletCurrency('Total associated after pending', '2.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
verifyEthWalletAssociatedBalance('2.0');
verifyEthWalletTotalAssociatedBalance('2.0');
cy.get(vegaWallet).within(() => {
@@ -210,12 +210,12 @@ context(
});
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '2.00');
validateWalletCurrency('Pending association', '1.00');
validateWalletCurrency('Total associated after pending', '1.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
verifyEthWalletAssociatedBalance('1.0');
verifyEthWalletTotalAssociatedBalance('1.0');
});
@@ -266,7 +266,7 @@ context(
// 1004-ASSO-008
// 1004-ASSO-010
// No warning visible as described in AC, but the button is disabled
cy.get(ethWalletAssociateButton).first().click();
cy.get(ethWalletAssociateButton).click();
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
cy.get(tokenSubmitButton, txTimeout).should('be.disabled'); // button disabled with no input
cy.get(tokenAmountInputBox, { timeout: 10000 }).type('6500000');
@@ -278,12 +278,12 @@ context(
vegaWalletAssociate('2');
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '0.00');
validateWalletCurrency('Pending association', '2.00');
validateWalletCurrency('Total associated after pending', '2.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
validateWalletCurrency('Associated', '2.00');
});
@@ -294,24 +294,24 @@ context(
});
cy.getByTestId('currency-title', txTimeout).should(
'have.length.above',
3
6
);
validateWalletCurrency('Associated', '2.00');
validateWalletCurrency('Pending association', '2.00');
validateWalletCurrency('Total associated after pending', '0.00');
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
validateWalletCurrency('Associated', '0.00');
});
it('Able to associate tokens to different public key of connected vega wallet', function () {
cy.get(ethWalletAssociateButton).first().click();
cy.get(ethWalletAssociateButton).click();
cy.get(associateWalletRadioButton).click();
cy.get(connectedVegaKey).should(
'have.text',
Cypress.env('vegaWalletPublicKey')
);
cy.get('[data-testid="manage-vega-wallet"]').click();
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
cy.get('[data-testid="select-keypair-button"]').eq(0).click();
cy.get(connectedVegaKey).should(
'have.text',
@@ -166,6 +166,7 @@ export function goToMakeNewProposal(proposalType: string) {
navigateTo(navigation.proposals);
cy.get(newProposalButton).should('be.visible').click();
cy.url().should('include', '/proposals/propose');
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
cy.get('li').should('contain.text', proposalType).and('be.visible');
cy.get('li').contains(proposalType).click();
}
@@ -8,6 +8,7 @@ import {
} from '@vegaprotocol/smart-contracts';
import { ethers, Wallet } from 'ethers';
const associatedAmountInWallet = '[data-testid="associated-amount"]:visible';
const vegaWalletContainer = 'aside [data-testid="vega-wallet"]';
const vegaWalletMnemonic = Cypress.env('vegaWalletMnemonic');
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
@@ -59,7 +60,7 @@ export async function faucetAsset(assetEthAddress: string) {
}
export async function vegaWalletTeardown() {
cy.get('[data-testid="associated-amount"]')
cy.get(associatedAmountInWallet)
.should('be.visible')
.invoke('text')
.then((associatedAmount) => {
@@ -68,12 +69,12 @@ export async function vegaWalletTeardown() {
$body.find('[data-testid="eth-wallet-associated-balances"]').length ||
associatedAmount != '0.00'
) {
vegaWalletTeardownVesting(vestingContract);
vegaWalletTeardownStaking(stakingBridgeContract);
vegaWalletTeardownVesting(vestingContract);
}
});
cy.get(vegaWalletContainer).within(() => {
cy.getByTestId('associated-amount', {
cy.get(associatedAmountInWallet, {
timeout: transactionTimeout,
}).contains('0.00', {
timeout: transactionTimeout,
@@ -90,7 +91,7 @@ export async function vegaWalletSetSpecifiedApprovalAmount(
await promiseWithTimeout(
token.approve(
ethStakingBridgeContractAddress,
resetAmount.concat('000000000000000000')
resetAmount + '0'.repeat(18)
),
10 * 60 * 1000,
'set approval amount'
@@ -104,12 +105,23 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
{ timeout: transactionTimeout, log: false }
).then((stakeBalance) => {
if (Number(stakeBalance) != 0) {
cy.wrap(
stakingBridgeContract.remove_stake(
String(stakeBalance),
vegaWalletPubKey
),
{ timeout: transactionTimeout, log: false }
cy.get('[data-testid="vega-wallet-balance-unstaked"]:visible').within(
() => {
cy.get(associatedAmountInWallet)
.invoke('text')
.then(($walletAmount) => {
cy.wrap(
stakingBridgeContract.remove_stake(
String(stakeBalance),
vegaWalletPubKey
),
{ timeout: transactionTimeout, log: false }
);
cy.get(associatedAmountInWallet, {
timeout: transactionTimeout,
}).should('not.have.text', $walletAmount);
});
}
);
}
});
@@ -124,7 +136,6 @@ async function vegaWalletTeardownVesting(vestingContract: TokenVesting) {
if (Number(vestingAmount) != 0) {
// Wait needed to allow time for ganache to process tx for stakingBridgeContract.remove_stake
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(1000);
cy.wrap(
vestingContract.remove_stake(String(vestingAmount), vegaWalletPubKey),
{ timeout: transactionTimeout, log: false }
+1
View File
@@ -8,3 +8,4 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
+1 -2
View File
@@ -1,10 +1,10 @@
{
"name": "governance",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/governance/src",
"projectType": "application",
"targets": {
"build": {
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -41,7 +41,6 @@
}
},
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 4210,
"buildTarget": "governance:build:development",
@@ -443,8 +443,8 @@
"rewardType": "Reward type",
"rewardsAndFeesReceived": "Rewards and fees received",
"ThisDoesNotIncludeFeesReceivedForMakersOrLiquidityProviders": "This does not include fees received for makers or liquidity providers",
"totalDistributed": "TOTAL DISTRIBUTED",
"earnedByMe": "EARNED BY ME",
"totalDistributed": "Total distributed",
"earnedByMe": "Earned by me",
"noRewardsHaveBeenDistributedYet": "NO REWARDS HAVE BEEN DISTRIBUTED YET",
"rewardsColAssetHeader": "ASSET",
"rewardsColStakingHeader": "STAKING",
@@ -114,7 +114,7 @@ export const RewardsPage = () => {
</p>
</div>
<div className="w-[440px]">
<div className="w-[360px]">
<Toggle
name="epoch-reward-view-toggle"
toggles={[
@@ -7,9 +7,10 @@ query PreviousEpoch($epochId: ID) {
id
rewardScore {
rawValidatorScore
performanceScore
}
rankingScore {
performanceScore
stakeScore
}
}
}
@@ -8,7 +8,7 @@ export type PreviousEpochQueryVariables = Types.Exact<{
}>;
export type PreviousEpochQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, validatorsConnection?: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string } | null, rankingScore: { __typename?: 'RankingScore', performanceScore: string } } } | null> | null } | null } };
export type PreviousEpochQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, validatorsConnection?: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string, performanceScore: string } | null, rankingScore: { __typename?: 'RankingScore', stakeScore: string } } } | null> | null } | null } };
export const PreviousEpochDocument = gql`
@@ -21,9 +21,10 @@ export const PreviousEpochDocument = gql`
id
rewardScore {
rawValidatorScore
performanceScore
}
rankingScore {
performanceScore
stakeScore
}
}
}
@@ -81,9 +81,10 @@ const MOCK_PREVIOUS_EPOCH: PreviousEpochQuery = {
id: 'ccc022b7e63a4d0a6d3a193c3940c88574060e58a184964c994998d86835a1b4',
rewardScore: {
rawValidatorScore: '0.25',
performanceScore: '0.9998677767864936',
},
rankingScore: {
performanceScore: '0.9998677767864936',
stakeScore: '0.2499583402766206',
},
},
},
@@ -92,9 +93,10 @@ const MOCK_PREVIOUS_EPOCH: PreviousEpochQuery = {
id: '966438c6bffac737cfb08173ffcb3f393c4692b099ad80cb45a82e2dc0a8cf99',
rewardScore: {
rawValidatorScore: '0.3',
performanceScore: '1',
},
rankingScore: {
performanceScore: '1',
stakeScore: '0.25',
},
},
},
@@ -103,9 +105,10 @@ const MOCK_PREVIOUS_EPOCH: PreviousEpochQuery = {
id: '12c81b738e8051152e1afe44376ec37bca9216466e6d44cdd772194bad0ada81',
rewardScore: {
rawValidatorScore: '0.35',
performanceScore: '0.999629748500531',
},
rankingScore: {
performanceScore: '0.999629748500531',
stakeScore: '0.2312',
},
},
},
@@ -10,7 +10,6 @@ import {
getFormattedPerformanceScore,
getLastEpochScoreAndPerformance,
getNormalisedVotingPower,
getOverstakedAmount,
getOverstakingPenalty,
getPerformancePenalty,
getTotalPenalties,
@@ -52,7 +51,6 @@ interface CanonisedConsensusNodeProps {
[ValidatorFields.STAKED_BY_OPERATOR]: string;
[ValidatorFields.PERFORMANCE_SCORE]: string;
[ValidatorFields.PERFORMANCE_PENALTY]: string;
[ValidatorFields.OVERSTAKED_AMOUNT]: string;
[ValidatorFields.OVERSTAKING_PENALTY]: string;
[ValidatorFields.TOTAL_PENALTIES]: string;
[ValidatorFields.PENDING_STAKE]: string;
@@ -164,14 +162,11 @@ export const ConsensusValidatorsTable = ({
pendingUserStake,
userStakeShare,
}) => {
const { rawValidatorScore, performanceScore } =
getLastEpochScoreAndPerformance(previousEpochData, id);
const overstakedAmount = getOverstakedAmount(
rawValidatorScore,
stakedTotal,
totalStake
);
const {
rawValidatorScore: previousEpochValidatorScore,
performanceScore: previousEpochPerformanceScore,
stakeScore: previousEpochStakeScore,
} = getLastEpochScoreAndPerformance(previousEpochData, id);
return {
id,
@@ -184,7 +179,7 @@ export const ConsensusValidatorsTable = ({
[ValidatorFields.NORMALISED_VOTING_POWER]:
getNormalisedVotingPower(votingPower),
[ValidatorFields.UNNORMALISED_VOTING_POWER]:
getUnnormalisedVotingPower(rawValidatorScore),
getUnnormalisedVotingPower(previousEpochValidatorScore),
[ValidatorFields.STAKE_SHARE]: stakedTotalPercentage(stakeScore),
[ValidatorFields.STAKED_BY_DELEGATES]: formatNumber(
toBigNum(stakedByDelegates, decimals),
@@ -194,18 +189,19 @@ export const ConsensusValidatorsTable = ({
toBigNum(stakedByOperator, decimals),
2
),
[ValidatorFields.PERFORMANCE_SCORE]:
getFormattedPerformanceScore(performanceScore).toString(),
[ValidatorFields.PERFORMANCE_PENALTY]:
getPerformancePenalty(performanceScore),
[ValidatorFields.OVERSTAKED_AMOUNT]: overstakedAmount.toString(),
[ValidatorFields.PERFORMANCE_SCORE]: getFormattedPerformanceScore(
previousEpochPerformanceScore
).toString(),
[ValidatorFields.PERFORMANCE_PENALTY]: getPerformancePenalty(
previousEpochPerformanceScore
),
[ValidatorFields.OVERSTAKING_PENALTY]: getOverstakingPenalty(
overstakedAmount,
totalStake
previousEpochValidatorScore,
previousEpochStakeScore
),
[ValidatorFields.TOTAL_PENALTIES]: getTotalPenalties(
rawValidatorScore,
performanceScore,
previousEpochValidatorScore,
previousEpochPerformanceScore,
stakedTotal,
totalStake
),
@@ -7,7 +7,6 @@ import { BigNumber } from '../../../../lib/bignumber';
import {
getFormattedPerformanceScore,
getLastEpochScoreAndPerformance,
getOverstakedAmount,
getOverstakingPenalty,
getPerformancePenalty,
getTotalPenalties,
@@ -82,21 +81,21 @@ export const StandbyPendingValidatorsTable = ({
pendingUserStake,
userStakeShare,
}) => {
const { rawValidatorScore, performanceScore } =
getLastEpochScoreAndPerformance(previousEpochData, id);
const {
rawValidatorScore: previousEpochValidatorScore,
performanceScore: previousEpochPerformanceScore,
stakeScore: previousEpochStakeScore,
} = getLastEpochScoreAndPerformance(previousEpochData, id);
const overstakedAmount = getOverstakedAmount(
rawValidatorScore,
stakedTotal,
totalStake
);
let individualStakeNeededForPromotion,
individualStakeNeededForPromotionDescription;
if (stakeNeededForPromotion && performanceScore) {
if (stakeNeededForPromotion && previousEpochPerformanceScore) {
const stakedTotalBigNum = new BigNumber(stakedTotal);
const stakeNeededBigNum = new BigNumber(stakeNeededForPromotion);
const performanceScoreBigNum = new BigNumber(performanceScore);
const performanceScoreBigNum = new BigNumber(
previousEpochPerformanceScore
);
const calc = stakeNeededBigNum
.dividedBy(performanceScoreBigNum)
@@ -142,18 +141,19 @@ export const StandbyPendingValidatorsTable = ({
toBigNum(stakedByOperator, decimals),
2
),
[ValidatorFields.PERFORMANCE_SCORE]:
getFormattedPerformanceScore(performanceScore).toString(),
[ValidatorFields.PERFORMANCE_PENALTY]:
getPerformancePenalty(performanceScore),
[ValidatorFields.OVERSTAKED_AMOUNT]: overstakedAmount.toString(),
[ValidatorFields.PERFORMANCE_SCORE]: getFormattedPerformanceScore(
previousEpochPerformanceScore
).toString(),
[ValidatorFields.PERFORMANCE_PENALTY]: getPerformancePenalty(
previousEpochPerformanceScore
),
[ValidatorFields.OVERSTAKING_PENALTY]: getOverstakingPenalty(
overstakedAmount,
totalStake
previousEpochValidatorScore,
previousEpochStakeScore
),
[ValidatorFields.TOTAL_PENALTIES]: getTotalPenalties(
rawValidatorScore,
performanceScore,
previousEpochValidatorScore,
previousEpochPerformanceScore,
stakedTotal,
totalStake
),
@@ -155,16 +155,16 @@ export const ValidatorTables = ({
return (
<section data-testid="validator-tables">
<div className="grid w-full justify-end">
<div className="w-[400px]">
<div className="w-[340px]">
<Toggle
name="validators-view-toggle"
toggles={[
{
label: t('ALL VALIDATORS'),
label: t('All validators'),
value: 'all',
},
{
label: t('STAKED BY ME'),
label: t('Staked by me'),
value: 'myStake',
},
]}
@@ -20,7 +20,6 @@ import { SubHeading } from '../../../components/heading';
import {
getLastEpochScoreAndPerformance,
getNormalisedVotingPower,
getOverstakedAmount,
getOverstakingPenalty,
getPerformancePenalty,
getTotalPenalties,
@@ -75,15 +74,9 @@ export const ValidatorTable = ({
const stakedOnNode = toBigNum(node.stakedTotal, decimals);
const { rawValidatorScore, performanceScore } =
const { rawValidatorScore, performanceScore, stakeScore } =
getLastEpochScoreAndPerformance(previousEpochData, node.id);
const overstakedAmount = getOverstakedAmount(
rawValidatorScore,
stakedTotal,
node.stakedTotal
);
const stakePercentage = getStakePercentage(total, stakedOnNode);
const totalPenaltiesAmount = getTotalPenalties(
@@ -245,7 +238,7 @@ export const ValidatorTable = ({
<Tooltip description={t('OverstakedPenaltyDescription')}>
<span data-testid="overstaking-penalty">
{getOverstakingPenalty(overstakedAmount, node.stakedTotal)}
{getOverstakingPenalty(rawValidatorScore, stakeScore)}
</span>
</Tooltip>
</KeyValueTableRow>
@@ -4,7 +4,6 @@ import {
getNormalisedVotingPower,
getUnnormalisedVotingPower,
getOverstakingPenalty,
getOverstakedAmount,
getFormattedPerformanceScore,
getPerformancePenalty,
getTotalPenalties,
@@ -22,9 +21,10 @@ describe('getLastEpochScoreAndPerformance', () => {
id: '0x123',
rewardScore: {
rawValidatorScore: '0.25',
performanceScore: '0.75',
},
rankingScore: {
performanceScore: '0.75',
stakeScore: '0.25',
},
},
},
@@ -33,9 +33,10 @@ describe('getLastEpochScoreAndPerformance', () => {
id: '0x234',
rewardScore: {
rawValidatorScore: '0.35',
performanceScore: '0.85',
},
rankingScore: {
performanceScore: '0.85',
stakeScore: '0.25',
},
},
},
@@ -50,12 +51,14 @@ describe('getLastEpochScoreAndPerformance', () => {
).toEqual({
rawValidatorScore: '0.25',
performanceScore: '0.75',
stakeScore: '0.25',
});
expect(
getLastEpochScoreAndPerformance(mockPreviousEpochData, '0x234')
).toEqual({
rawValidatorScore: '0.35',
performanceScore: '0.85',
stakeScore: '0.25',
});
});
});
@@ -79,40 +82,34 @@ describe('getUnnormalisedVotingPower', () => {
});
describe('getOverstakingPenalty', () => {
it('should return the overstaking penalty', () => {
expect(
getOverstakingPenalty(new BigNumber(100), Number(1000).toString())
).toEqual('10.00%');
expect(
getOverstakingPenalty(new BigNumber(500), Number(2000).toString())
).toEqual('25.00%');
});
});
describe('getOverstakedAmount', () => {
it('should return the overstaked amount', () => {
expect(
// If a validator score is 0, any amount staked on the node is considered overstaked
getOverstakedAmount('0', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(20));
expect(
getOverstakedAmount('0.05', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(15));
expect(
getOverstakedAmount('0.1', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(10));
expect(
getOverstakedAmount('0.15', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(5));
expect(
getOverstakedAmount('0.2', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(0));
it('returns "0%" when both arguments are null or undefined', () => {
expect(getOverstakingPenalty(null, null)).toBe('0%');
expect(getOverstakingPenalty(undefined, undefined)).toBe('0%');
expect(getOverstakingPenalty(null, undefined)).toBe('0%');
expect(getOverstakingPenalty(undefined, null)).toBe('0%');
});
it('should return 0 if the overstaked amount is negative', () => {
expect(
getOverstakedAmount('0.8', Number(100).toString(), Number(20).toString())
).toEqual(new BigNumber(0));
it('returns "0%" when one argument is null or undefined', () => {
expect(getOverstakingPenalty('10', null)).toBe('0%');
expect(getOverstakingPenalty(null, '20')).toBe('0%');
expect(getOverstakingPenalty('10', undefined)).toBe('0%');
expect(getOverstakingPenalty(undefined, '20')).toBe('0%');
});
it('returns "0%" when validatorScore or stakeScore is zero', () => {
expect(getOverstakingPenalty('0', '20')).toBe('0%');
expect(getOverstakingPenalty('10', '0')).toBe('0%');
});
it('returns the correct overstaking penalty', () => {
expect(getOverstakingPenalty('0.18', '0.2')).toBe('10.00%');
expect(getOverstakingPenalty('0.2', '0.2')).toBe('0.00%');
expect(getOverstakingPenalty('0.04', '0.2')).toBe('80.00%');
});
it('handles string numbers with decimals', () => {
expect(getOverstakingPenalty('7.5', '15')).toBe('50.00%');
expect(getOverstakingPenalty('12.5', '25')).toBe('50.00%');
});
});
+16 -20
View File
@@ -15,7 +15,8 @@ export const getLastEpochScoreAndPerformance = (
return {
rawValidatorScore: validator?.rewardScore?.rawValidatorScore,
performanceScore: validator?.rankingScore?.performanceScore,
performanceScore: validator?.rewardScore?.performanceScore,
stakeScore: validator?.rankingScore?.stakeScore,
};
};
@@ -42,31 +43,26 @@ export const getPerformancePenalty = (performanceScore?: string) =>
2
);
export const getOverstakedAmount = (
validatorScore: string | null | undefined,
totalStake: string,
stakedOnNode: string
) => {
const toReturn = validatorScore
? new BigNumber(stakedOnNode).minus(
new BigNumber(validatorScore).times(new BigNumber(totalStake))
)
: new BigNumber(0);
return toReturn.isNegative() ? new BigNumber(0) : toReturn;
};
export const getOverstakingPenalty = (
overstakedAmount: BigNumber,
stakedOnNode: string
validatorScore: string | null | undefined,
stakeScore: string | null | undefined
) => {
if (!validatorScore || !stakeScore) {
return '0%';
}
// avoid division by zero
if (new BigNumber(stakedOnNode).isZero() || overstakedAmount.isZero()) {
return '0';
if (
new BigNumber(validatorScore).isZero() ||
new BigNumber(stakeScore).isZero()
) {
return '0%';
}
return formatNumberPercentage(
overstakedAmount.dividedBy(new BigNumber(stakedOnNode)).times(100),
new BigNumber(1)
.minus(new BigNumber(validatorScore).dividedBy(new BigNumber(stakeScore)))
.times(100),
2
);
};
@@ -1,4 +1,5 @@
{
"name": "liquidity-provision-dashboard",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/liquidity-provision-dashboard/src",
"projectType": "application",
@@ -47,7 +48,6 @@
}
},
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"buildTarget": "liquidity-provision-dashboard:build",
"hmr": true,
+1 -2
View File
@@ -1,10 +1,10 @@
{
"name": "multisig-signer",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/multisig-signer/src",
"projectType": "application",
"targets": {
"build": {
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -38,7 +38,6 @@
}
},
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3000,
"buildTarget": "multisig-signer:build:development",
+1 -2
View File
@@ -1,11 +1,11 @@
{
"name": "static",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "apps/static/src",
"tags": [],
"targets": {
"build": {
"executor": "./tools/executors/webpack:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -36,7 +36,6 @@
}
},
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"buildTarget": "static:build"
},
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
apps/trading-e2e/.env.capsule
+1
View File
@@ -0,0 +1 @@
apps/trading-e2e/.env.stagnet3
+4 -1
View File
@@ -1,4 +1,5 @@
{
"name": "trading-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/trading-e2e/src",
"projectType": "application",
@@ -15,7 +16,9 @@
},
"live": {
"devServerTarget": ""
}
},
"capsule": {},
"stagnet3": {}
}
},
"lint": {
@@ -411,6 +411,7 @@ describe('capsule', { tags: '@slow' }, () => {
it('approved amount is less than deposit', function () {
// 1001-DEPO-006
// 1001-DEPO-007
cy.getByTestId(depositsTab).click();
cy.getByTestId('deposit-button').click();
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
@@ -430,8 +431,8 @@ describe('capsule', { tags: '@slow' }, () => {
});
it('withdraw - delay verification', function () {
// 1001-DEPO-007
// 1001-DEPO-024
// 1002-WITH-007
cy.visit('/#/portfolio');
cy.get('main[data-testid="/portfolio"]').should('exist');
@@ -76,6 +76,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
});
it('insufficient funds', () => {
// 1001-DEPO-004
mockWeb3DepositCalls({
allowance: '1000',
depositLifetimeLimit: '1000',
@@ -87,7 +88,10 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
.clear()
.type('850')
.next(`[data-testid="${formFieldError}"]`)
.should('have.text', 'Insufficient amount in Ethereum wallet');
.should(
'have.text',
"You can't deposit more than you have in your Ethereum wallet, 800 tEURO"
);
});
});
+81 -1
View File
@@ -1,5 +1,5 @@
import * as Schema from '@vegaprotocol/types';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { aliasGQLQuery, checkSorting } from '@vegaprotocol/cypress';
import { marketsQuery } from '@vegaprotocol/mock';
import { getDateTimeFormat } from '@vegaprotocol/utils';
@@ -85,6 +85,7 @@ describe('markets table', { tags: '@smoke' }, () => {
cy.getByTestId('view-market-list-link')
.should('have.attr', 'href', '#/markets/all')
.click();
cy.get('[data-testid="All markets"]').should(
'have.attr',
'data-state',
@@ -117,6 +118,85 @@ describe('markets table', { tags: '@smoke' }, () => {
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
);
});
it('proposed markets tab should be sorted properly', () => {
cy.getByTestId('view-market-list-link').click();
cy.get('[data-testid="Proposed markets"]').click();
const marketColDefault = [
'ETHUSD',
'LINKUSD',
'ETHUSD',
'ETHDAI.MF21',
'AAPL.MF21',
'BTCUSD.MF21',
'TSLA.QM21',
'AAVEDAI.MF21',
'ETHBTC.QM21',
'UNIDAI.MF21',
];
const marketColAsc = [
'AAPL.MF21',
'AAVEDAI.MF21',
'BTCUSD.MF21',
'ETHBTC.QM21',
'ETHDAI.MF21',
'ETHUSD',
'ETHUSD',
'LINKUSD',
'TSLA.QM21',
'UNIDAI.MF21',
];
const marketColDesc = [
'UNIDAI.MF21',
'TSLA.QM21',
'LINKUSD',
'ETHUSD',
'ETHUSD',
'ETHDAI.MF21',
'ETHBTC.QM21',
'BTCUSD.MF21',
'AAVEDAI.MF21',
'AAPL.MF21',
];
checkSorting('market', marketColDefault, marketColAsc, marketColDesc);
const stateColDefault = [
'Open',
'Passed',
'Waiting for Node Vote',
'Open',
'Passed',
'Open',
'Passed',
'Open',
'Waiting for Node Vote',
'Open',
];
const stateColAsc = [
'Open',
'Open',
'Open',
'Open',
'Open',
'Passed',
'Passed',
'Passed',
'Waiting for Node Vote',
'Waiting for Node Vote',
];
const stateColDesc = [
'Waiting for Node Vote',
'Waiting for Node Vote',
'Passed',
'Passed',
'Passed',
'Open',
'Open',
'Open',
'Open',
'Open',
];
checkSorting('state', stateColDefault, stateColAsc, stateColDesc);
});
it('opening auction subsets should be properly displayed', () => {
cy.mockTradingPage(
@@ -41,6 +41,12 @@ describe('accounts', { tags: '@smoke' }, () => {
.should('have.text', '100,001.01');
});
it('asset detail should be properly rendered', () => {
cy.getByTestId('Collateral').click();
cy.getByTestId('asset').contains('tEURO').click();
cy.get('[data-testid$="_label"]').should('have.length', 16);
});
describe('sorting by ag-grid columns should work well', () => {
it('sorting by asset', () => {
cy.getByTestId('Collateral').click();
@@ -1,5 +1,5 @@
import * as Schema from '@vegaprotocol/types';
import { aliasGQLQuery, mockConnectWallet } from '@vegaprotocol/cypress';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { testOrderSubmission } from '../support/order-validation';
import type { OrderSubmission } from '@vegaprotocol/wallet';
import {
@@ -13,8 +13,6 @@ const orderSizeField = 'order-size';
const orderPriceField = 'order-price';
const orderTIFDropDown = 'order-tif';
const placeOrderBtn = 'place-order';
const toggleShort = 'order-side-SIDE_SELL';
const toggleLong = 'order-side-SIDE_BUY';
const toggleLimit = 'order-type-TYPE_LIMIT';
const toggleMarket = 'order-type-TYPE_MARKET';
@@ -32,34 +30,6 @@ const displayTomorrow = () => {
return tomorrow.toISOString().substring(0, 16);
};
describe('time in force default values', () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must have market order set up to IOC by default', function () {
// 7002-SORD-031
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
});
it('must have time in force set to GTC for limit order', function () {
// 7002-SORD-031
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTC')[0].text
);
});
});
describe('must submit order', { tags: '@smoke' }, () => {
// 7002-SORD-039
before(() => {
@@ -393,227 +363,6 @@ describe(
}
);
describe('deal ticket validation', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must show place order button and connect wallet if wallet is not connected', () => {
// 0003-WTXN-001
cy.getByTestId('connect-vega-wallet'); // Not connected
cy.getByTestId('order-connect-wallet').should('exist');
cy.getByTestId(placeOrderBtn).should('exist');
cy.getByTestId('deal-ticket-connect-wallet').should('exist');
});
it('must be able to select order direction - long/short', function () {
// 7002-SORD-004
cy.getByTestId(toggleShort).click().children('input').should('be.checked');
cy.getByTestId(toggleLong).click().children('input').should('be.checked');
});
it('must be able to select order type - limit/market', function () {
// 7002-SORD-005
// 7002-SORD-006
// 7002-SORD-007
cy.getByTestId(toggleLimit).click().children('input').should('be.checked');
cy.getByTestId(toggleMarket).click().children('input').should('be.checked');
});
it('order connect vega wallet button should connect', () => {
mockConnectWallet();
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('101');
cy.getByTestId('order-connect-wallet').click();
cy.getByTestId('dialog-content').should('be.visible');
cy.getByTestId('connectors-list')
.find('[data-testid="connector-jsonRpc"]')
.click();
cy.wait('@walletReq');
cy.getByTestId(placeOrderBtn).should('be.visible');
cy.getByTestId(toggleLimit).children('input').should('be.checked');
cy.getByTestId(orderPriceField).should('have.value', '101');
});
});
describe('deal ticket size validation', { tags: '@smoke' }, function () {
beforeEach(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must warn if order size input has too many digits after the decimal place', function () {
// 7002-SORD-016
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('1.234');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId(placeOrderBtn).should('be.disabled');
cy.getByTestId('dealticket-error-message-size-market').should(
'have.text',
'Size must be whole numbers for this market'
);
});
it('must warn if order size is set to 0', function () {
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('0');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId(placeOrderBtn).should('be.disabled');
cy.getByTestId('dealticket-error-message-size-market').should(
'have.text',
'Size cannot be lower than 1'
);
});
});
describe('limit order validations', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.getByTestId(toggleLimit).click();
});
beforeEach(() => {
cy.setVegaWallet();
});
it('must see the price unit', function () {
// 7002-SORD-018
cy.getByTestId(orderPriceField)
.siblings('label')
.should('have.text', 'Price (DAI)');
});
it('must see warning when placing an order with expiry date in past', () => {
const expiresAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const expiresAtInputValue = expiresAt.toISOString().substring(0, 16);
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('0.1');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.log('choosing yesterday');
cy.getByTestId('date-picker-field').type(expiresAtInputValue);
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId('dealticket-error-message-expiry').should(
'have.text',
'The expiry date that you have entered appears to be in the past'
);
});
it('must see warning if price has too many digits after decimal place', function () {
// 7002-SORD-059
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTC');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(orderPriceField).clear().type('1.123456');
cy.getByTestId('dealticket-error-message-price-limit').should(
'have.text',
'Price accepts up to 5 decimal places'
);
});
describe('time in force validations', function () {
const validTIF = TIFlist;
validTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-025
// 7002-SORD-026
// 7002-SORD-027
// 7002-SORD-028
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
it('selections should be remembered', () => {
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_FOK');
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTT')[0].text
);
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'FOK')[0].text
);
});
});
});
describe('market order validations', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.getByTestId(toggleMarket).click();
});
beforeEach(() => {
cy.setVegaWallet();
});
it('must not see the price unit', function () {
// 7002-SORD-019
cy.getByTestId(orderPriceField).should('not.exist');
});
describe('time in force validations', function () {
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
const invalidTIF = TIFlist.filter(
(tif) => !['FOK', 'IOC'].includes(tif.code)
);
validTIF.forEach((tif) => {
// 7002-SORD-025
// 7002-SORD-026
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
invalidTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-027
// 7002-SORD-028
it(`must not be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).should('not.contain', tif.text);
});
});
});
});
describe('suspended market validation', { tags: '@regression' }, () => {
before(() => {
cy.setVegaWallet();
@@ -765,6 +514,8 @@ describe('account validation', { tags: '@regression' }, () => {
it('must show error returned by wallet ', () => {
// 0003-WTXN-009
// 0003-WTXN-011
// 0002-WCON-016
// 0003-WTXN-008
//trigger error from the wallet
cy.intercept('POST', 'http://localhost:1789/api/v2/requests', (req) => {
@@ -788,6 +539,8 @@ describe('account validation', { tags: '@regression' }, () => {
'contain.text',
'The connection to your Vega Wallet has been lost.'
);
cy.getByTestId('connect-vega-wallet').click();
cy.getByTestId('dialog-content').should('be.visible');
});
it('must see that the order was rejected by the connected wallet', () => {
@@ -0,0 +1,329 @@
import * as Schema from '@vegaprotocol/types';
import { mockConnectWallet } from '@vegaprotocol/cypress';
const orderSizeField = 'order-size';
const orderPriceField = 'order-price';
const orderTIFDropDown = 'order-tif';
const placeOrderBtn = 'place-order';
const toggleShort = 'order-side-SIDE_SELL';
const toggleLong = 'order-side-SIDE_BUY';
const toggleLimit = 'order-type-TYPE_LIMIT';
const toggleMarket = 'order-type-TYPE_MARKET';
const TIFlist = Object.values(Schema.OrderTimeInForce).map((value) => {
return {
code: Schema.OrderTimeInForceCode[value],
value,
text: Schema.OrderTimeInForceMapping[value],
};
});
describe('time in force default values', () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must have market order set up to IOC by default', function () {
// 7002-SORD-030
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
});
it('must have time in force set to GTC for limit order', function () {
// 7002-SORD-031
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTC')[0].text
);
});
});
describe('deal ticket validation', { tags: '@smoke' }, () => {
beforeEach(() => {
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must show place order button and connect wallet if wallet is not connected', () => {
// 0003-WTXN-001
cy.getByTestId('connect-vega-wallet'); // Not connected
cy.getByTestId('order-connect-wallet').should('exist');
cy.getByTestId(placeOrderBtn).should('exist');
cy.getByTestId('deal-ticket-connect-wallet').should('exist');
});
it('must be able to select order direction - long/short', function () {
// 7002-SORD-004
cy.getByTestId(toggleShort).click().children('input').should('be.checked');
cy.getByTestId(toggleLong).click().children('input').should('be.checked');
});
it('must be able to select order type - limit/market', function () {
// 7002-SORD-005
// 7002-SORD-006
// 7002-SORD-007
cy.getByTestId(toggleLimit).click().children('input').should('be.checked');
cy.getByTestId(toggleMarket).click().children('input').should('be.checked');
});
it('order connect vega wallet button should connect', () => {
mockConnectWallet();
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('101');
cy.getByTestId('order-connect-wallet').click();
cy.getByTestId('dialog-content').should('be.visible');
cy.getByTestId('connectors-list')
.find('[data-testid="connector-jsonRpc"]')
.click();
cy.wait('@walletReq');
cy.getByTestId(placeOrderBtn).should('be.visible');
cy.getByTestId(toggleLimit).children('input').should('be.checked');
cy.getByTestId(orderPriceField).should('have.value', '101');
});
});
describe('deal ticket size validation', { tags: '@smoke' }, function () {
beforeEach(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
});
it('must warn if order size input has too many digits after the decimal place', function () {
// 7002-SORD-016
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('1.234');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId(placeOrderBtn).should('be.disabled');
cy.getByTestId('dealticket-error-message-size-market').should(
'have.text',
'Size must be whole numbers for this market'
);
});
it('must warn if order size is set to 0', function () {
cy.getByTestId('order-type-TYPE_MARKET').click();
cy.getByTestId(orderSizeField).clear().type('0');
cy.getByTestId(placeOrderBtn).should('not.be.disabled');
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId(placeOrderBtn).should('be.disabled');
cy.getByTestId('dealticket-error-message-size-market').should(
'have.text',
'Size cannot be lower than 1'
);
});
});
describe('limit order validations', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.getByTestId(toggleLimit).click();
});
beforeEach(() => {
cy.setVegaWallet();
});
it('must see the price unit', function () {
// 7002-SORD-018
cy.getByTestId(orderPriceField)
.siblings('label')
.should('have.text', 'Price (DAI)');
});
it('must see warning when placing an order with expiry date in past', () => {
const expiresAt = new Date(Date.now() - 24 * 60 * 60 * 1000);
const expiresAtInputValue = expiresAt.toISOString().substring(0, 16);
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderPriceField).clear().type('0.1');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.log('choosing yesterday');
cy.getByTestId('date-picker-field').type(expiresAtInputValue);
cy.getByTestId(placeOrderBtn).click();
cy.getByTestId('dealticket-error-message-expiry').should(
'have.text',
'The expiry date that you have entered appears to be in the past'
);
});
it('must see warning if price has too many digits after decimal place', function () {
// 7002-SORD-059
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTC');
cy.getByTestId(orderSizeField).clear().type('1');
cy.getByTestId(orderPriceField).clear().type('1.123456');
cy.getByTestId('dealticket-error-message-price-limit').should(
'have.text',
'Price accepts up to 5 decimal places'
);
});
describe('time in force validations', function () {
const validTIF = TIFlist;
validTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-025
// 7002-SORD-026
// 7002-SORD-027
// 7002-SORD-028
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
it('selections should be remembered', () => {
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_GTT');
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'IOC')[0].text
);
cy.getByTestId(orderTIFDropDown).select('TIME_IN_FORCE_FOK');
cy.getByTestId(toggleLimit).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'GTT')[0].text
);
cy.getByTestId(toggleMarket).click();
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
TIFlist.filter((item) => item.code === 'FOK')[0].text
);
});
});
});
describe('market order validations', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.getByTestId(toggleMarket).click();
});
beforeEach(() => {
cy.setVegaWallet();
});
it('must not see the price unit', function () {
// 7002-SORD-019
cy.getByTestId(orderPriceField).should('not.exist');
});
describe('time in force validations', function () {
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
const invalidTIF = TIFlist.filter(
(tif) => !['FOK', 'IOC'].includes(tif.code)
);
validTIF.forEach((tif) => {
// 7002-SORD-025
// 7002-SORD-026
it(`must be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
});
});
invalidTIF.forEach((tif) => {
// 7002-SORD-023
// 7002-SORD-024
// 7002-SORD-027
// 7002-SORD-028
it(`must not be able to select ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).should('not.contain', tif.text);
});
});
});
});
describe('post and reduce order validations', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage();
cy.visit('/#/markets/market-0');
cy.wait('@Markets');
cy.getByTestId(toggleMarket).click();
});
beforeEach(() => {
cy.setVegaWallet();
});
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
validTIF.forEach((tif) => {
// 7002-SORD-025
// 7002-SORD-026
it(`post and reduce order market for ${tif.code}`, function () {
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
cy.getByTestId('post-only').should('be.disabled');
cy.getByTestId('reduce-only').should('be.enabled');
});
});
validTIF.forEach((tif) => {
it(`post and reduce order limit for ${tif.code}`, function () {
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
cy.getByTestId('post-only').should('be.disabled');
cy.getByTestId('reduce-only').should('be.enabled');
});
});
const validTIFLimit = TIFlist.filter((tif) =>
['GFA', 'GFN', 'GTC', 'GTT'].includes(tif.code)
);
validTIFLimit.forEach((tif) => {
it(`post and reduce order for limit ${tif.code}`, function () {
cy.getByTestId(toggleLimit).click();
cy.getByTestId(orderTIFDropDown).select(tif.value);
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
'have.text',
tif.text
);
cy.getByTestId('post-only').should('be.enabled');
cy.getByTestId('reduce-only').should('be.disabled');
});
});
});
@@ -117,6 +117,7 @@ describe('connect vega wallet', { tags: '@smoke' }, () => {
// 0002-WCON-002
// 0002-WCON-005
// 0002-WCON-007
// 0002-WCON-009
mockConnectWallet();
cy.getByTestId(connectVegaBtn).click();
@@ -124,6 +125,10 @@ describe('connect vega wallet', { tags: '@smoke' }, () => {
.find('[data-testid="connector-jsonRpc"]')
.click();
cy.wait('@walletReq');
cy.getByTestId(dialogContent).should(
'contain.text',
'Approve the connection from your Vega wallet app.'
);
cy.getByTestId(dialogContent).should('not.exist');
cy.getByTestId(manageVegaBtn).should('exist');
});
@@ -132,6 +137,7 @@ describe('connect vega wallet', { tags: '@smoke' }, () => {
// 0002-WCON-002
// 0002-WCON-005
// 0002-WCON-007
// 0002-WCON-015
mockConnectWalletWithUserError();
cy.getByTestId(connectVegaBtn).click();
-11
View File
@@ -1,17 +1,6 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=''
NX_VEGA_ENV=CUSTOM
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_URL=http://localhost:3028/query
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
-10
View File
@@ -1,14 +1,4 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_VEGA_ENV=DEVNET
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
+1
View File
@@ -0,0 +1 @@
.env.capsule
+1
View File
@@ -0,0 +1 @@
.env.devnet
+1
View File
@@ -0,0 +1 @@
.env.mainnet
+1
View File
@@ -0,0 +1 @@
.env.stagnet1
+1
View File
@@ -0,0 +1 @@
.env.stagnet3
+1
View File
@@ -0,0 +1 @@
.env.testnet
+1
View File
@@ -0,0 +1 @@
.env.validator-testnet
-5
View File
@@ -1,13 +1,8 @@
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
NX_VEGA_ENV=MAINNET
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.vega.xyz
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
+1
View File
@@ -0,0 +1 @@
.env.capsule
+1
View File
@@ -0,0 +1 @@
.env.devnet
+1
View File
@@ -0,0 +1 @@
.env.mainnet
+1
View File
@@ -0,0 +1 @@
.env.stagnet1
+1
View File
@@ -0,0 +1 @@
.env.stagnet3
+1
View File
@@ -0,0 +1 @@
.env.testnet
+1
View File
@@ -0,0 +1 @@
.env.validator-testnet
-10
View File
@@ -1,14 +1,4 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
NX_VEGA_ENV=STAGNET1
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
-10
View File
@@ -1,14 +1,4 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet3/vegawallet-stagnet3.toml
NX_VEGA_ENV=STAGNET3
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
-11
View File
@@ -1,14 +1,3 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
NX_VEGA_ENV=TESTNET
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
-10
View File
@@ -1,14 +1,4 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.toml
NX_VEGA_ENV=VALIDATOR_TESTNET
NX_VEGA_EXPLORER_URL=https://validator-testnet.explorer.vega.xyz
NX_VEGA_NETWORKS={\"STAGNET3\":\"https://stagnet3.console.vega.xyz\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
NX_VEGA_TOKEN_URL=https://validator-testnet.governance.fairground.wtf
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
@@ -8,6 +8,7 @@ import {
import { tooltipMapping } from '@vegaprotocol/market-info';
import {
addDecimalsFormatNumber,
createDocsLinks,
formatNumberPercentage,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
@@ -23,6 +24,7 @@ import {
Tabs,
Link as UiToolkitLink,
Indicator,
ExternalLink,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { memo, useCallback, useEffect, useRef, useState } from 'react';
@@ -37,6 +39,7 @@ import { Link, useParams } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list';
import { useEnvironment } from '@vegaprotocol/environment';
const enum LiquidityTabs {
Active = 'active',
@@ -144,6 +147,7 @@ const LiquidityViewHeader = memo(({ marketId }: { marketId?: string }) => {
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
const symbol =
market?.tradableInstrument.instrument.product.settlementAsset.symbol;
const { VEGA_DOCS_URL } = useEnvironment();
const { params } = useNetworkParams([
NetworkParams.market_liquidity_stakeToCcyVolume,
@@ -211,6 +215,13 @@ const LiquidityViewHeader = memo(({ marketId }: { marketId?: string }) => {
<HeaderStat heading={t('Market ID')}>
<div className="break-word">{marketId}</div>
</HeaderStat>
<HeaderStat heading={t('Learn more')}>
{VEGA_DOCS_URL && (
<ExternalLink href={createDocsLinks(VEGA_DOCS_URL).LIQUIDITY}>
{t('Providing liquidity')}
</ExternalLink>
)}
</HeaderStat>
</Header>
);
});
@@ -301,7 +301,7 @@ export const AccountHistoryChart = ({
asset: AssetFieldsFragment;
}) => {
const { theme } = useThemeSwitcher();
const values: { cols: string[]; rows: [Date, ...number[]][] } | null =
const values: { cols: [string, string]; rows: [Date, number][] } | null =
useMemo(() => {
if (!data?.balanceChanges.edges.length) {
return null;
@@ -8,6 +8,7 @@ import type { MarketData } from '@vegaprotocol/market-list';
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
import { HeaderStat } from '../header';
import {
ExternalLink,
Indicator,
KeyValueTable,
KeyValueTableRow,
@@ -18,9 +19,11 @@ import { useCheckLiquidityStatus } from '@vegaprotocol/liquidity';
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
import {
addDecimalsFormatNumber,
createDocsLinks,
formatNumberPercentage,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { useEnvironment } from '@vegaprotocol/environment';
interface Props {
marketId?: string;
@@ -44,6 +47,8 @@ export const MarketLiquiditySupplied = ({
params.market_liquidity_targetstake_triggering_ratio
);
const { VEGA_DOCS_URL } = useEnvironment();
const variables = useMemo(
() => ({
marketId: marketId || '',
@@ -126,6 +131,14 @@ export const MarketLiquiditySupplied = ({
<Link href={`/#/liquidity/${marketId}`} data-testid="view-liquidity-link">
{t('View liquidity provision table')}
</Link>
{VEGA_DOCS_URL && (
<ExternalLink
href={createDocsLinks(VEGA_DOCS_URL).LIQUIDITY}
className="mt-2"
>
{t('Learn about providing liquidity')}
</ExternalLink>
)}
{showMessage && (
<p className="mt-4">
{t(
+5 -1
View File
@@ -23,6 +23,7 @@ import {
} from '@vegaprotocol/ui-toolkit';
import { Links, Routes } from '../../pages/client-router';
import { createDocsLinks } from '@vegaprotocol/utils';
export const Navbar = ({
theme = 'system',
@@ -37,6 +38,7 @@ export const Navbar = ({
const tradingPath = marketId
? Links[Routes.MARKET](marketId)
: Links[Routes.MARKET]();
return (
<Navigation
appName="Console"
@@ -89,7 +91,9 @@ export const Navbar = ({
<NavigationContent>
<NavigationList>
<NavigationItem>
<NavExternalLink href={VEGA_DOCS_URL}>
<NavExternalLink
href={createDocsLinks(VEGA_DOCS_URL).NEW_TO_VEGA}
>
{t('Docs')}
</NavExternalLink>
</NavigationItem>
@@ -185,7 +185,7 @@ export const columns = (
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onSelect(market.id, e.metaKey);
onSelect(market.id, e.metaKey || e.ctrlKey);
}}
>
<UILink>{market.tradableInstrument.instrument.code}</UILink>
@@ -366,7 +366,7 @@ export const columnsPositionMarkets = (
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onSelect(market.id, e.metaKey);
onSelect(market.id, e.metaKey || e.ctrlKey);
}}
>
<UILink>{market.tradableInstrument.instrument.code}</UILink>
@@ -44,7 +44,7 @@ export const SelectMarketTableRow = ({
<tr
className={`hover:bg-neutral-200 dark:hover:bg-neutral-700 cursor-pointer relative h-[34px]`}
onClick={(ev) => {
onSelect(marketId, ev.metaKey);
onSelect(marketId, ev.metaKey || ev.ctrlKey);
}}
data-testid={`market-link-${marketId}`}
>
@@ -8,6 +8,10 @@ import type {
MarketData,
} from '@vegaprotocol/market-list';
import { SelectMarketLandingTable } from './welcome-landing-dialog';
const mockMarketClickHandler = jest.fn();
jest.mock('../../lib/hooks/use-market-click-handler', () => ({
useMarketClickHandler: () => mockMarketClickHandler,
}));
type Market = MarketMaybeWithCandles & MarketMaybeWithData;
type PartialMarket = Partial<
@@ -174,4 +178,25 @@ describe('WelcomeLandingDialog', () => {
fireEvent.click(screen.getAllByTestId(`market-link-2`)[0]);
expect(onClose).toHaveBeenCalled();
});
it('should not call onClose when metaKey is held', () => {
const onClose = jest.fn();
render(
<MemoryRouter>
<SelectMarketLandingTable
markets={[MARKET_A as Market, MARKET_B as Market]}
onClose={onClose}
/>
</MemoryRouter>,
{ wrapper: MockedProvider }
);
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0], {
metaKey: true,
});
expect(mockMarketClickHandler).toHaveBeenCalled();
expect(onClose).not.toHaveBeenCalled();
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
expect(onClose).toHaveBeenCalled();
});
});
@@ -12,9 +12,10 @@ import {
SelectMarketTableRow,
} from '../select-market';
import { WelcomeDialogHeader } from './welcome-dialog-header';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { ProposedMarkets } from './proposed-markets';
import { Links, Routes } from '../../pages/client-router';
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
export const SelectMarketLandingTable = ({
markets,
@@ -23,23 +24,13 @@ export const SelectMarketLandingTable = ({
markets: MarketMaybeWithDataAndCandles[] | null;
onClose: () => void;
}) => {
const params = useParams();
const navigate = useNavigate();
const marketId = params.marketId;
const onSelect = useCallback(
(id: string) => {
if (id && id !== marketId) {
navigate(Links[Routes.MARKET](id));
}
},
[marketId, navigate]
);
const onSelect = useMarketClickHandler();
const onSelectMarket = useCallback(
(id: string) => {
onSelect(id);
onClose();
(id: string, metaKey?: boolean) => {
onSelect(id, metaKey);
if (!metaKey) {
onClose();
}
},
[onSelect, onClose]
);
@@ -73,7 +64,7 @@ export const SelectMarketLandingTable = ({
key={i}
detailed={false}
onSelect={onSelectMarket}
columns={columns(market, onSelect, onCellClick)}
columns={columns(market, onSelectMarket, onCellClick)}
/>
))}
</tbody>
@@ -7,7 +7,11 @@ import {
} from '@vegaprotocol/types';
import type { VegaStoredTxState } from '@vegaprotocol/wallet';
import { VegaTxStatus } from '@vegaprotocol/wallet';
import { VegaTransactionDetails } from './use-vega-transaction-toasts';
import {
VegaTransactionDetails,
getVegaTransactionContentIntent,
} from './use-vega-transaction-toasts';
import { Intent } from '@vegaprotocol/ui-toolkit';
jest.mock('@vegaprotocol/assets', () => {
const A1 = {
@@ -278,3 +282,27 @@ describe('VegaTransactionDetails', () => {
expect(queryByTestId('toast-panel')?.textContent).toEqual(details);
});
});
describe('getVegaTransactionContentIntent', () => {
it('returns the correct intent for a transaction', () => {
expect(getVegaTransactionContentIntent(withdraw).intent).toBe(
Intent.Primary
);
expect(getVegaTransactionContentIntent(submitOrder).intent).toBe(
Intent.Success
);
expect(getVegaTransactionContentIntent(editOrder).intent).toBe(
Intent.Primary
);
expect(getVegaTransactionContentIntent(cancelOrder).intent).toBe(
Intent.Primary
);
expect(getVegaTransactionContentIntent(cancelAll).intent).toBe(
Intent.Primary
);
expect(getVegaTransactionContentIntent(closePosition).intent).toBe(
Intent.Primary
);
expect(getVegaTransactionContentIntent(batch).intent).toBe(Intent.Primary);
});
});
@@ -39,10 +39,14 @@ import { t } from '@vegaprotocol/i18n';
import { useAssetsDataProvider } from '@vegaprotocol/assets';
import { useEthWithdrawApprovalsStore } from '@vegaprotocol/web3';
import { DApp, EXPLORER_TX, useLinks } from '@vegaprotocol/environment';
import { getRejectionReason, useOrderByIdQuery } from '@vegaprotocol/orders';
import {
getOrderToastIntent,
getOrderToastTitle,
getRejectionReason,
useOrderByIdQuery,
} from '@vegaprotocol/orders';
import { useMarketList } from '@vegaprotocol/market-list';
import type { Side } from '@vegaprotocol/types';
import { OrderStatus } from '@vegaprotocol/types';
import { OrderStatusMapping } from '@vegaprotocol/types';
import { Size } from '@vegaprotocol/react-helpers';
@@ -478,12 +482,10 @@ const VegaTxCompleteToastsContent = ({ tx }: VegaTxToastContentProps) => {
getRejectionReason(tx.order) || tx.order.rejectionReason || '';
return (
<>
<ToastHeading>{t('Order rejected')}</ToastHeading>
{rejectionReason || tx.order.rejectionReason ? (
<ToastHeading>{getOrderToastTitle(tx.order.status)}</ToastHeading>
{rejectionReason ? (
<p>
{t('Your order has been rejected because: %s', [
rejectionReason || tx.order.rejectionReason,
])}
{t('Your order has been rejected because: %s', [rejectionReason])}
</p>
) : (
<p>{t('Your order has been rejected.')}</p>
@@ -506,7 +508,7 @@ const VegaTxCompleteToastsContent = ({ tx }: VegaTxToastContentProps) => {
if (isOrderSubmissionTransaction(tx.body) && tx.order?.rejectionReason) {
return (
<div>
<h3 className="font-bold">{t('Order rejected')}</h3>
<h3 className="font-bold">{getOrderToastTitle(tx.order.status)}</h3>
<p>{t('Your order was rejected.')}</p>
{tx.txHash && (
<p className="break-all">
@@ -545,7 +547,11 @@ const VegaTxCompleteToastsContent = ({ tx }: VegaTxToastContentProps) => {
return (
<>
<ToastHeading>{t('Confirmed')}</ToastHeading>
<ToastHeading>
{tx.order?.status
? getOrderToastTitle(tx.order.status)
: t('Confirmed')}
</ToastHeading>
<p>{t('Your transaction has been confirmed ')}</p>
{tx.txHash && (
<p className="break-all">
@@ -580,7 +586,7 @@ const VegaTxErrorToastContent = ({ tx }: VegaTxToastContentProps) => {
tx.error instanceof WalletError &&
walletNoConnectionCodes.includes(tx.error.code);
if (orderRejection) {
label = t('Order rejected');
label = getOrderToastTitle(tx.order?.status) || t('Order rejected');
errorMessage = t('Your order has been rejected because: %s', [
orderRejection || tx.order?.rejectionReason || ' ',
]);
@@ -632,30 +638,8 @@ export const useVegaTransactionToasts = () => {
);
const fromVegaTransaction = (tx: VegaStoredTxState): Toast => {
let content: ToastContent;
const closeAfter = isFinal(tx) ? CLOSE_AFTER : undefined;
if (tx.status === VegaTxStatus.Requested) {
content = <VegaTxRequestedToastContent tx={tx} />;
}
if (tx.status === VegaTxStatus.Pending) {
content = <VegaTxPendingToastContentProps tx={tx} />;
}
if (tx.status === VegaTxStatus.Complete) {
content = <VegaTxCompleteToastsContent tx={tx} />;
}
if (tx.status === VegaTxStatus.Error) {
content = <VegaTxErrorToastContent tx={tx} />;
}
// Transaction can be successful but the order can be rejected by the network
const intent =
(tx.order &&
[OrderStatus.STATUS_REJECTED, OrderStatus.STATUS_STOPPED].includes(
tx.order.status
)) ||
tx.order?.rejectionReason
? Intent.Danger
: intentMap[tx.status];
const { intent, content } = getVegaTransactionContentIntent(tx);
return {
id: `vega-${tx.id}`,
@@ -679,3 +663,27 @@ export const useVegaTransactionToasts = () => {
}
);
};
export const getVegaTransactionContentIntent = (tx: VegaStoredTxState) => {
let content: ToastContent;
if (tx.status === VegaTxStatus.Requested) {
content = <VegaTxRequestedToastContent tx={tx} />;
}
if (tx.status === VegaTxStatus.Pending) {
content = <VegaTxPendingToastContentProps tx={tx} />;
}
if (tx.status === VegaTxStatus.Complete) {
content = <VegaTxCompleteToastsContent tx={tx} />;
}
if (tx.status === VegaTxStatus.Error) {
content = <VegaTxErrorToastContent tx={tx} />;
}
// Transaction can be successful but the order can be rejected by the network
const intent =
(tx.order &&
!isOrderAmendmentTransaction(tx.body) &&
getOrderToastIntent(tx.order.status)) ||
intentMap[tx.status];
return { intent, content };
};
+15
View File
@@ -33,6 +33,8 @@ import { ViewingBanner } from '../components/viewing-banner';
import { Banner } from '../components/banner';
import { AppLoader, DynamicLoader } from '../components/app-loader';
import { Navbar } from '../components/navbar';
import { useDataProvider } from '@vegaprotocol/react-helpers';
import { activeOrdersProvider } from '@vegaprotocol/orders';
const DEFAULT_TITLE = t('Welcome to Vega trading!');
@@ -95,6 +97,7 @@ function AppBody({ Component }: AppProps) {
<ToastsManager />
<InitializeHandlers />
<MaybeConnectEagerly />
<PartyData />
</div>
);
}
@@ -127,6 +130,18 @@ function VegaTradingApp(props: AppProps) {
export default VegaTradingApp;
const PartyData = () => {
const { pubKey } = useVegaWallet();
const variables = { partyId: pubKey || '' };
const skip = !pubKey;
useDataProvider({
dataProvider: activeOrdersProvider,
variables,
skip,
});
return null;
};
const MaybeConnectEagerly = () => {
useVegaEagerConnect(Connectors);
useEthereumEagerConnect();
+15
View File
@@ -34,6 +34,18 @@ html [data-theme='dark'] {
/* sell candles only use stroke as the candle is solid (without border) */
--pennant-color-sell-stroke: theme('colors.vega.pink.500');
/* studies */
--pennant-color-eldar-ray-bear-power: theme('colors.vega.pink.500');
--pennant-color-eldar-ray-bull-power: theme('colors.vega.green.650');
--pennant-color-macd-divergence-buy: theme('colors.vega.green.650');
--pennant-color-macd-divergence-sell: theme('colors.vega.pink.500');
--pennant-color-macd-signal: theme('colors.vega.blue.500');
--pennant-color-macd-macd: theme('colors.vega.yellow.500');
--pennant-color-volume-buy: theme('colors.vega.green.650');
--pennant-color-volume-sell: theme('colors.vega.pink.500');
/* depth chart */
--pennant-color-depth-buy-fill: theme('colors.vega.green.650');
--pennant-color-depth-buy-stroke: theme('colors.vega.green.500');
@@ -50,6 +62,9 @@ html [data-theme='light'] {
/* sell candles only use stroke as the candle is solid (without border) */
--pennant-color-sell-stroke: theme('colors.vega.pink.400');
--pennant-color-volume-buy: theme('colors.vega.green.400');
--pennant-color-volume-sell: theme('colors.vega.pink.400');
/* depth chart */
--pennant-color-depth-buy-fill: theme('colors.vega.green.400');
--pennant-color-depth-buy-stroke: theme('colors.vega.green.550');
+29 -5
View File
@@ -1,10 +1,11 @@
{
"name": "trading",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/trading",
"projectType": "application",
"targets": {
"build": {
"executor": "./tools/executors/next:build",
"executor": "@nrwl/next:build",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
@@ -15,11 +16,18 @@
"production": {
"optimization": true,
"sourceMap": true
}
},
"capsule": {},
"devnet": {},
"mainnet": {},
"stagnet1": {},
"stagnet3": {},
"testnet": {},
"validator-testnet": {}
}
},
"serve": {
"executor": "./tools/executors/next:serve",
"executor": "@nrwl/next:server",
"options": {
"buildTarget": "trading:build",
"dev": true
@@ -28,13 +36,29 @@
"production": {
"buildTarget": "trading:build:production",
"dev": false
}
},
"capsule": {},
"devnet": {},
"mainnet": {},
"stagnet1": {},
"stagnet3": {},
"testnet": {},
"validator-testnet": {}
}
},
"export": {
"executor": "./tools/executors/next:export",
"executor": "@nrwl/next:export",
"options": {
"buildTarget": "trading:build:production"
},
"configurations": {
"capsule": {},
"devnet": {},
"mainnet": {},
"stagnet1": {},
"stagnet3": {},
"testnet": {},
"validator-testnet": {}
}
},
"test": {
+6
View File
@@ -0,0 +1,6 @@
FROM --platform=amd64 nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a116c34cc7241532d0d94198fb2c9629
EXPOSE 80
WORKDIR /usr/share/nginx/html
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
RUN rm -rf /usr/share/nginx/html/*
COPY ./dist-result/ /usr/share/nginx/html/
+3 -5
View File
@@ -5,7 +5,9 @@ export PATH="/app/node_modules/.bin:$PATH"
flags="--network-timeout 100000 --pure-lockfile"
if [[ ! -z "${ENV_NAME}" ]]; then
flags="--env=${ENV_NAME} $flags"
if [[ "${ENV_NAME}" != "ops-vega" ]]; then
flags="--env=${ENV_NAME} $flags"
fi
fi
if [ "${APP}" = "trading" ]; then
@@ -16,7 +18,3 @@ if [ "${APP}" = "trading" ]; then
else
yarn nx build ${APP} $flags
fi
env_vars_file="/app/dist/apps/${APP}/.env"
# make sure there are no exposed .env files
rm $env_vars_file || echo "No env vars file"
+5 -4
View File
@@ -13,7 +13,7 @@ RUN apk add --update --no-cache \
COPY . ./
RUN yarn --network-timeout 100000 --pure-lockfile
# work around for different build process in trading
RUN sh ./docker-build.sh
RUN sh docker/docker-build.sh
# Server environment
# if this fails you need to docker pull nginx:1.23-alpine and pin new SHA
@@ -23,6 +23,7 @@ FROM --platform=amd64 nginx:1.23-alpine@sha256:6318314189b40e73145a48060bff4783a
EXPOSE 80
# Copy dist
WORKDIR /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist/apps/${APP} /usr/share/nginx/html
RUN apk add --no-cache go-ipfs; ipfs init && echo "$(ipfs add -rQ .)" > ipfs-hash; apk del go-ipfs
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build /app/dist/apps/${APP}/* /usr/share/nginx/html
RUN apk add --no-cache go-ipfs; ipfs init && echo "$(ipfs add -rQ .)" > /ipfs-hash; apk del go-ipfs
+2 -1
View File
@@ -1,11 +1,12 @@
{
"name": "accounts",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/accounts/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"executor": "@nrwl/rollup:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/accounts",
@@ -1,123 +0,0 @@
import type { Story, Meta } from '@storybook/react';
import { AccountType } from '@vegaprotocol/types';
import { getAccountData } from './accounts-data-provider';
import { AccountTable } from './accounts-table';
export default {
component: AccountTable,
title: 'AccountsTable',
} as Meta;
const Template: Story = (args) => (
<AccountTable data={args.data} onClickAsset={() => null} />
);
export const Primary = Template.bind({});
Primary.args = {
data: getAccountData([
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_MARGIN,
balance: '2781397',
market: {
__typename: 'Market',
id: 'd90fd7c746286625504d7a3f5f420a280875acd3cd611676d9e70acc675f4540',
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'Tesla Quarterly (30 Jun 2022)',
},
},
},
asset: {
__typename: 'Asset',
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_MARGIN,
balance: '406922',
market: {
__typename: 'Market',
id: '9c1ee71959e566c484fcea796513137f8a02219cca2e973b7ae72dc29d099581',
tradableInstrument: {
__typename: 'TradableInstrument',
instrument: {
__typename: 'Instrument',
name: 'AAVEDAI Monthly (30 Jun 2022)',
},
},
},
asset: {
__typename: 'Asset',
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '10001000000',
market: null,
asset: {
__typename: 'Asset',
id: 'XYZalpha',
symbol: 'XYZalpha',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '1990351587',
market: null,
asset: {
__typename: 'Asset',
id: '993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede',
symbol: 'tUSDC',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '2996218603',
market: null,
asset: {
__typename: 'Asset',
id: '8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4',
symbol: 'tEURO',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '5000593078',
market: null,
asset: {
__typename: 'Asset',
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
symbol: 'tDAI',
decimals: 5,
},
},
{
__typename: 'AccountBalance',
type: AccountType.ACCOUNT_TYPE_GENERAL,
balance: '4000000000000001006031',
market: null,
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
decimals: 5,
},
},
]),
};
+221 -72
View File
@@ -1,4 +1,10 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import {
act,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import BigNumber from 'bignumber.js';
import { AddressField, TransferFee, TransferForm } from './transfer-form';
import { AccountType } from '@vegaprotocol/types';
@@ -27,6 +33,34 @@ describe('TransferForm', () => {
submitTransfer: jest.fn(),
};
it('validates a manually entered address', async () => {
render(<TransferForm {...props} />);
submit();
expect(await screen.findAllByText('Required')).toHaveLength(3);
const toggle = screen.getByText('Enter manually');
fireEvent.click(toggle);
// has switched to input
expect(toggle).toHaveTextContent('Select from wallet');
expect(screen.getByLabelText('Vega key')).toHaveAttribute('type', 'text');
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: 'invalid-address' },
});
await waitFor(() => {
const errors = screen.getAllByTestId('input-error-text');
expect(errors[0]).toHaveTextContent('Invalid Vega key');
});
// same pubkey
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: pubKey },
});
await waitFor(() => {
const errors = screen.getAllByTestId('input-error-text');
expect(errors[0]).toHaveTextContent('Vega key is the same');
});
});
it('validates fields and submits', async () => {
render(<TransferForm {...props} />);
@@ -62,15 +96,17 @@ describe('TransferForm', () => {
formatNumber(asset.balance, asset.decimals)
);
const amountInput = screen.getByLabelText('Amount');
// Test amount validation
fireEvent.change(screen.getByLabelText('Amount'), {
fireEvent.change(amountInput, {
target: { value: '0.00000001' },
});
expect(
await screen.findByText('Value is below minimum')
).toBeInTheDocument();
fireEvent.change(screen.getByLabelText('Amount'), {
fireEvent.change(amountInput, {
target: { value: '9999999' },
});
expect(
@@ -78,7 +114,7 @@ describe('TransferForm', () => {
).toBeInTheDocument();
// set valid amount
fireEvent.change(screen.getByLabelText('Amount'), {
fireEvent.change(amountInput, {
target: { value: amount },
});
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(
@@ -100,78 +136,191 @@ describe('TransferForm', () => {
});
});
it('validates a manually entered address', async () => {
render(<TransferForm {...props} />);
submit();
expect(await screen.findAllByText('Required')).toHaveLength(3);
const toggle = screen.getByText('Enter manually');
fireEvent.click(toggle);
// has switched to input
expect(toggle).toHaveTextContent('Select from wallet');
expect(screen.getByLabelText('Vega key')).toHaveAttribute('type', 'text');
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: 'invalid-address' },
});
await waitFor(() => {
const errors = screen.getAllByTestId('input-error-text');
expect(errors[0]).toHaveTextContent('Invalid Vega key');
describe('IncludeFeesCheckbox', () => {
it('validates fields and submits when checkbox is checked', async () => {
render(<TransferForm {...props} />);
// check current pubkey not shown
const keySelect: HTMLSelectElement = screen.getByLabelText('Vega key');
expect(keySelect.children).toHaveLength(2);
expect(Array.from(keySelect.options).map((o) => o.value)).toEqual([
'',
props.pubKeys[1],
]);
submit();
expect(await screen.findAllByText('Required')).toHaveLength(3);
// Select a pubkey
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: props.pubKeys[1] },
});
// Select asset
fireEvent.change(
// Bypass RichSelect and target hidden native select
// eslint-disable-next-line
document.querySelector('select[name="asset"]')!,
{ target: { value: asset.id } }
);
// assert rich select as updated
expect(await screen.findByTestId('select-asset')).toHaveTextContent(
asset.name
);
expect(screen.getByTestId('asset-balance')).toHaveTextContent(
formatNumber(asset.balance, asset.decimals)
);
const amountInput = screen.getByLabelText('Amount');
const checkbox = screen.getByTestId('include-transfer-fee');
expect(checkbox).not.toBeChecked();
act(() => {
/* fire events that update state */
// set valid amount
fireEvent.change(amountInput, {
target: { value: amount },
});
// check include fees checkbox
fireEvent.click(checkbox);
});
expect(checkbox).toBeChecked();
const expectedFee = new BigNumber(amount)
.times(props.feeFactor)
.toFixed();
const expectedAmount = new BigNumber(amount).minus(expectedFee).toFixed();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expectedFee);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(
expectedAmount
);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(
amount
);
submit();
await waitFor(() => {
expect(props.submitTransfer).toHaveBeenCalledTimes(1);
expect(props.submitTransfer).toHaveBeenCalledWith({
fromAccountType: AccountType.ACCOUNT_TYPE_GENERAL,
toAccountType: AccountType.ACCOUNT_TYPE_GENERAL,
to: props.pubKeys[1],
asset: asset.id,
amount: removeDecimal(amount, asset.decimals),
oneOff: {},
});
});
});
// same pubkey
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: pubKey },
it('validates fields when checkbox is not checked', async () => {
render(<TransferForm {...props} />);
// check current pubkey not shown
const keySelect: HTMLSelectElement = screen.getByLabelText('Vega key');
expect(keySelect.children).toHaveLength(2);
expect(Array.from(keySelect.options).map((o) => o.value)).toEqual([
'',
props.pubKeys[1],
]);
submit();
expect(await screen.findAllByText('Required')).toHaveLength(3);
// Select a pubkey
fireEvent.change(screen.getByLabelText('Vega key'), {
target: { value: props.pubKeys[1] },
});
// Select asset
fireEvent.change(
// Bypass RichSelect and target hidden native select
// eslint-disable-next-line
document.querySelector('select[name="asset"]')!,
{ target: { value: asset.id } }
);
// assert rich select as updated
expect(await screen.findByTestId('select-asset')).toHaveTextContent(
asset.name
);
expect(screen.getByTestId('asset-balance')).toHaveTextContent(
formatNumber(asset.balance, asset.decimals)
);
const amountInput = screen.getByLabelText('Amount');
const checkbox = screen.getByTestId('include-transfer-fee');
expect(checkbox).not.toBeChecked();
act(() => {
/* fire events that update state */
// set valid amount
fireEvent.change(amountInput, {
target: { value: amount },
});
});
expect(checkbox).not.toBeChecked();
const expectedFee = new BigNumber(amount)
.times(props.feeFactor)
.toFixed();
const total = new BigNumber(amount).plus(expectedFee).toFixed();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expectedFee);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(amount);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(total);
});
});
describe('AddressField', () => {
const props = {
pubKeys: ['pubkey-1', 'pubkey-2'],
select: <div>select</div>,
input: <div>input</div>,
onChange: jest.fn(),
};
it('toggles content and calls onChange', async () => {
const mockOnChange = jest.fn();
render(<AddressField {...props} onChange={mockOnChange} />);
// select should be shown as multiple pubkeys provided
expect(screen.getByText('select')).toBeInTheDocument();
expect(screen.queryByText('input')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('Enter manually'));
expect(screen.queryByText('select')).not.toBeInTheDocument();
expect(screen.getByText('input')).toBeInTheDocument();
expect(mockOnChange).toHaveBeenCalledTimes(1);
fireEvent.click(screen.getByText('Select from wallet'));
expect(screen.getByText('select')).toBeInTheDocument();
expect(screen.queryByText('input')).not.toBeInTheDocument();
expect(mockOnChange).toHaveBeenCalledTimes(2);
});
await waitFor(() => {
const errors = screen.getAllByTestId('input-error-text');
expect(errors[0]).toHaveTextContent('Vega key is the same');
it('Does not provide select option if there is only a single key', () => {
render(<AddressField {...props} pubKeys={['single-pubKey']} />);
expect(screen.getByText('input')).toBeInTheDocument();
expect(screen.queryByText('Select from wallet')).not.toBeInTheDocument();
});
});
describe('TransferFee', () => {
const props = {
amount: '200',
feeFactor: '0.001',
fee: '0.2',
transferAmount: '200',
decimals: 8,
};
it('calculates and renders the transfer fee', () => {
render(<TransferFee {...props} />);
const expected = new BigNumber(props.amount)
.times(props.feeFactor)
.toFixed();
const total = new BigNumber(props.amount).plus(expected).toFixed();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expected);
expect(screen.getByTestId('transfer-amount')).toHaveTextContent(
props.amount
);
expect(screen.getByTestId('total-transfer-fee')).toHaveTextContent(total);
});
});
});
describe('AddressField', () => {
const props = {
pubKeys: ['pubkey-1', 'pubkey-2'],
select: <div>select</div>,
input: <div>input</div>,
onChange: jest.fn(),
};
it('toggles content and calls onChange', async () => {
const mockOnChange = jest.fn();
render(<AddressField {...props} onChange={mockOnChange} />);
// select should be shown as multiple pubkeys provided
expect(screen.getByText('select')).toBeInTheDocument();
expect(screen.queryByText('input')).not.toBeInTheDocument();
fireEvent.click(screen.getByText('Enter manually'));
expect(screen.queryByText('select')).not.toBeInTheDocument();
expect(screen.getByText('input')).toBeInTheDocument();
expect(mockOnChange).toHaveBeenCalledTimes(1);
fireEvent.click(screen.getByText('Select from wallet'));
expect(screen.getByText('select')).toBeInTheDocument();
expect(screen.queryByText('input')).not.toBeInTheDocument();
expect(mockOnChange).toHaveBeenCalledTimes(2);
});
it('Does not provide select option if there is only a single key', () => {
render(<AddressField {...props} pubKeys={['single-pubKey']} />);
expect(screen.getByText('input')).toBeInTheDocument();
expect(screen.queryByText('Select from wallet')).not.toBeInTheDocument();
});
});
describe('TransferFee', () => {
const props = {
amount: '200',
feeFactor: '0.001',
};
it('calculates and renders the transfer fee', () => {
render(<TransferFee {...props} />);
const expected = new BigNumber(props.amount)
.times(props.feeFactor)
.toFixed();
expect(screen.getByTestId('transfer-fee')).toHaveTextContent(expected);
});
});
+102 -16
View File
@@ -16,6 +16,7 @@ import {
RichSelect,
Select,
Tooltip,
Checkbox,
} from '@vegaprotocol/ui-toolkit';
import type { Transfer } from '@vegaprotocol/wallet';
import { normalizeTransfer } from '@vegaprotocol/wallet';
@@ -63,6 +64,26 @@ export const TransferForm = ({
const amount = watch('amount');
const assetId = watch('asset');
const [includeFee, setIncludeFee] = useState(false);
const transferAmount = useMemo(() => {
if (!amount) return undefined;
if (includeFee && feeFactor) {
return new BigNumber(1).minus(feeFactor).times(amount).toString();
}
return amount;
}, [amount, includeFee, feeFactor]);
const fee = useMemo(() => {
if (!transferAmount) return undefined;
if (includeFee) {
return new BigNumber(amount).minus(transferAmount).toString();
}
return (
feeFactor && new BigNumber(feeFactor).times(transferAmount).toString()
);
}, [amount, includeFee, transferAmount, feeFactor]);
const asset = useMemo(() => {
return assets.find((a) => a.id === assetId);
}, [assets, assetId]);
@@ -72,13 +93,16 @@ export const TransferForm = ({
if (!asset) {
throw new Error('Submitted transfer with no asset selected');
}
const transfer = normalizeTransfer(fields.toAddress, fields.amount, {
if (!transferAmount) {
throw new Error('Submitted transfer with no amount selected');
}
const transfer = normalizeTransfer(fields.toAddress, transferAmount, {
id: asset.id,
decimals: asset.decimals,
});
submitTransfer(transfer);
},
[asset, submitTransfer]
[asset, submitTransfer, transferAmount]
);
const min = useMemo(() => {
@@ -213,7 +237,32 @@ export const TransferForm = ({
<InputError forInput="amount">{errors.amount.message}</InputError>
)}
</FormGroup>
<TransferFee amount={amount} feeFactor={feeFactor} />
<div className="mb-4">
<Checkbox
name="include-transfer-fee"
disabled={!transferAmount}
label={
<Tooltip
description={t(
`The fee will be taken from the amount you are transferring.`
)}
>
<div>{t('Include transfer fee')}</div>
</Tooltip>
}
checked={includeFee}
onCheckedChange={() => setIncludeFee(!includeFee)}
/>
</div>
{transferAmount && fee && (
<TransferFee
amount={transferAmount}
transferAmount={transferAmount}
feeFactor={feeFactor}
fee={fee}
decimals={asset?.decimals}
/>
)}
<Button type="submit" variant="primary" fill={true}>
{t('Confirm transfer')}
</Button>
@@ -223,34 +272,71 @@ export const TransferForm = ({
export const TransferFee = ({
amount,
transferAmount,
feeFactor,
fee,
decimals,
}: {
amount: string;
transferAmount: string;
feeFactor: string | null;
fee?: string;
decimals?: number;
}) => {
if (!feeFactor || !amount) return null;
if (!feeFactor || !amount || !transferAmount || !fee) return null;
// using toFixed without an argument will always return a
// number in normal notation without rounding, formatting functions
// arent working in a way which won't round the decimal places
const value = new BigNumber(amount).times(feeFactor).toFixed();
const totalValue = new BigNumber(transferAmount).plus(fee).toString();
return (
<div className="mb-4 flex justify-between items-center gap-4 flex-wrap">
<div>
<div className="mb-4 flex flex-col gap-2 text-xs">
<div className="flex justify-between gap-1 items-center flex-wrap">
<Tooltip
description={t(
`The transfer fee is set by the network parameter transfer.fee.factor, currently set to ${feeFactor}`
`The transfer fee is set by the network parameter transfer.fee.factor, currently set to %s`,
[feeFactor]
)}
>
<div>{t('Transfer fee')}</div>
</Tooltip>
<div
data-testid="transfer-fee"
className="text-neutral-500 dark:text-neutral-300"
>
{formatNumber(fee, decimals)}
</div>
</div>
<div
data-testid="transfer-fee"
className="text-neutral-500 dark:text-neutral-300"
>
{value}
<div className="flex justify-between gap-1 items-center flex-wrap">
<Tooltip
description={t(
`The total amount to be transferred (without the fee)`
)}
>
<div>{t('Amount to be transferred')}</div>
</Tooltip>
<div
data-testid="transfer-amount"
className="text-neutral-500 dark:text-neutral-300"
>
{formatNumber(amount, decimals)}
</div>
</div>
<div className="flex justify-between gap-1 items-center flex-wrap">
<Tooltip
description={t(
`The total amount taken from your account. The amount to be transferred plus the fee.`
)}
>
<div>{t('Total amount (with fee)')}</div>
</Tooltip>
<div
data-testid="total-transfer-fee"
className="text-neutral-500 dark:text-neutral-300"
>
{formatNumber(totalValue, decimals)}
</div>
</div>
</div>
);
+5
View File
@@ -1 +1,6 @@
import '@testing-library/jest-dom';
import ResizeObserver from 'resize-observer-polyfill';
import { defaultFallbackInView } from 'react-intersection-observer';
defaultFallbackInView(true);
global.ResizeObserver = ResizeObserver;
+2 -1
View File
@@ -1,11 +1,12 @@
{
"name": "announcements",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/announcements/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"executor": "@nrwl/rollup:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/accounts",
+2 -1
View File
@@ -1,10 +1,11 @@
{
"name": "apollo-client",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/apollo-client/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"executor": "@nrwl/rollup:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/apollo-client",
+2 -1
View File
@@ -1,11 +1,12 @@
{
"name": "assets",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/assets/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"executor": "@nrwl/rollup:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/assets",
+18 -1
View File
@@ -1,8 +1,25 @@
fragment AssetListFields on Asset {
id
name
symbol
decimals
quantum
source {
__typename
... on ERC20 {
contractAddress
lifetimeLimit
withdrawThreshold
}
}
status
}
query Assets {
assetsConnection {
edges {
node {
...AssetFields
...AssetListFields
}
}
}
+23 -5
View File
@@ -1,26 +1,44 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import { AssetFieldsFragmentDoc } from './Asset';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type AssetListFieldsFragment = { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string } };
export type AssetsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type AssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string }, infrastructureFeeAccount?: { __typename?: 'AccountBalance', balance: string } | null, globalRewardPoolAccount?: { __typename?: 'AccountBalance', balance: string } | null, takerFeeRewardAccount?: { __typename?: 'AccountBalance', balance: string } | null, makerFeeRewardAccount?: { __typename?: 'AccountBalance', balance: string } | null, lpFeeRewardAccount?: { __typename?: 'AccountBalance', balance: string } | null, marketProposerRewardAccount?: { __typename?: 'AccountBalance', balance: string } | null } } | null> | null } | null };
export type AssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, quantum: string, status: Types.AssetStatus, source: { __typename: 'BuiltinAsset' } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string } } } | null> | null } | null };
export const AssetListFieldsFragmentDoc = gql`
fragment AssetListFields on Asset {
id
name
symbol
decimals
quantum
source {
__typename
... on ERC20 {
contractAddress
lifetimeLimit
withdrawThreshold
}
}
status
}
`;
export const AssetsDocument = gql`
query Assets {
assetsConnection {
edges {
node {
...AssetFields
...AssetListFields
}
}
}
}
${AssetFieldsFragmentDoc}`;
${AssetListFieldsFragmentDoc}`;
/**
* __useAssetsQuery__
@@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/react';
import * as Schema from '@vegaprotocol/types';
import { AssetDetailsDialog } from './asset-details-dialog';
import { AssetDetail, testId } from './asset-details-table';
import { AssetsDocument } from './__generated__/Assets';
import { AssetDocument } from './__generated__/Asset';
import { generateBuiltinAsset, generateERC20Asset } from './test-helpers';
const mockedData = {
@@ -39,15 +39,17 @@ const mockedData = {
},
};
const mocks = [
{
request: {
query: AssetsDocument,
variables: {},
},
result: mockedData,
const mocks = mockedData.data.assetsConnection.edges.map((mock) => ({
request: {
query: AssetDocument,
variables: { assetId: mock.node.id },
},
];
result: {
data: {
assetsConnection: { edges: [mock] },
},
},
}));
const WrappedAssetDetailsDialog = ({ assetId }: { assetId: string }) => (
<MockedProvider mocks={mocks}>
+2 -3
View File
@@ -1,5 +1,4 @@
import { t } from '@vegaprotocol/i18n';
import { useAssetsDataProvider } from './assets-data-provider';
import {
Button,
Dialog,
@@ -10,6 +9,7 @@ import {
import { create } from 'zustand';
import { AssetDetailsTable } from './asset-details-table';
import { AssetProposalNotification } from '@vegaprotocol/proposals';
import { useAssetDataProvider } from './asset-data-provider';
export type AssetDetailsDialogStore = {
isOpen: boolean;
@@ -55,9 +55,8 @@ export const AssetDetailsDialog = ({
onChange,
asJson = false,
}: AssetDetailsDialogProps) => {
const { data } = useAssetsDataProvider();
const { data: asset } = useAssetDataProvider(assetId);
const asset = data?.find((a) => a.id === assetId);
const assetSymbol = asset?.symbol || '';
const content = asset ? (
+2 -3
View File
@@ -11,6 +11,7 @@ import {
} from '@vegaprotocol/ui-toolkit';
import type { ReactNode } from 'react';
import type { Asset } from './asset-data-provider';
import { WITHDRAW_THRESHOLD_TOOLTIP_TEXT } from './constants';
type Rows = {
key: AssetDetail;
@@ -121,9 +122,7 @@ export const rows: Rows = [
{
key: AssetDetail.WITHDRAWAL_THRESHOLD,
label: t('Withdrawal threshold'),
tooltip: t(
'The maximum you can withdraw instantly. Theres no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them'
),
tooltip: WITHDRAW_THRESHOLD_TOOLTIP_TEXT,
value: (asset) =>
num(asset, (asset.source as Schema.ERC20).withdrawThreshold),
},
+5 -119
View File
@@ -1,8 +1,10 @@
import merge from 'lodash/merge';
import type { AssetsQuery } from './__generated__/Assets';
import type {
AssetsQuery,
AssetListFieldsFragment,
} from './__generated__/Assets';
import * as Types from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
import type { AssetFieldsFragment } from './__generated__/Asset';
export const assetsQuery = (
override?: PartialDeep<AssetsQuery>
@@ -18,7 +20,7 @@ export const assetsQuery = (
return merge(defaultAssets, override);
};
const assetFields: AssetFieldsFragment[] = [
const assetFields: AssetListFieldsFragment[] = [
{
__typename: 'Asset',
id: 'asset-id',
@@ -33,30 +35,6 @@ const assetFields: AssetFieldsFragment[] = [
},
quantum: '1',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
},
{
__typename: 'Asset',
@@ -72,30 +50,6 @@ const assetFields: AssetFieldsFragment[] = [
},
quantum: '1',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
},
{
__typename: 'Asset',
@@ -104,20 +58,10 @@ const assetFields: AssetFieldsFragment[] = [
decimals: 5,
name: 'Asto',
source: {
maxFaucetAmountMint: '5000000000',
__typename: 'BuiltinAsset',
},
quantum: '1',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '0',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: null,
takerFeeRewardAccount: null,
makerFeeRewardAccount: null,
lpFeeRewardAccount: null,
marketProposerRewardAccount: null,
},
{
__typename: 'Asset',
@@ -126,20 +70,10 @@ const assetFields: AssetFieldsFragment[] = [
decimals: 5,
name: 'tBTC TEST',
source: {
maxFaucetAmountMint: '5000000000',
__typename: 'BuiltinAsset',
},
quantum: '1',
status: Types.AssetStatus.STATUS_ENABLED,
infrastructureFeeAccount: {
balance: '0',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: null,
takerFeeRewardAccount: null,
makerFeeRewardAccount: null,
lpFeeRewardAccount: null,
marketProposerRewardAccount: null,
},
// NOTE: These assets ids and contract addresses are real assets on Sepolia, this is needed
// because we don't currently mock our seplia infura provider. If we change network these will
@@ -158,30 +92,6 @@ const assetFields: AssetFieldsFragment[] = [
__typename: 'ERC20',
},
quantum: '1',
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
},
{
__typename: 'Asset',
@@ -197,29 +107,5 @@ const assetFields: AssetFieldsFragment[] = [
__typename: 'ERC20',
},
quantum: '1',
infrastructureFeeAccount: {
balance: '1',
__typename: 'AccountBalance',
},
globalRewardPoolAccount: {
balance: '2',
__typename: 'AccountBalance',
},
takerFeeRewardAccount: {
balance: '3',
__typename: 'AccountBalance',
},
makerFeeRewardAccount: {
balance: '4',
__typename: 'AccountBalance',
},
lpFeeRewardAccount: {
balance: '5',
__typename: 'AccountBalance',
},
marketProposerRewardAccount: {
balance: '6',
__typename: 'AccountBalance',
},
},
];
+4
View File
@@ -0,0 +1,4 @@
import { t } from '@vegaprotocol/i18n';
export const WITHDRAW_THRESHOLD_TOOLTIP_TEXT = t(
"The maximum you can withdraw instantly. There's no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them"
);
+1
View File
@@ -5,3 +5,4 @@ export * from './assets-data-provider';
export * from './asset-details-dialog';
export * from './asset-details-table';
export * from './asset-option';
export * from './constants';
+2 -1
View File
@@ -1,11 +1,12 @@
{
"name": "candles-chart",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/candles-chart/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"executor": "@nrwl/rollup:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/candles-chart",
+2 -2
View File
@@ -1,6 +1,6 @@
import 'pennant/dist/style.css';
import {
Chart,
CandlestickChart,
ChartType,
Interval,
Overlay,
@@ -234,7 +234,7 @@ export const CandlesChartContainer = ({
</DropdownMenu>
</div>
<div className="flex-1">
<Chart
<CandlestickChart
dataSource={dataSource}
options={{
chartType: chartType,
+1
View File
@@ -1,4 +1,5 @@
{
"name": "cypress",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/cypress/src",
"projectType": "library",
+3
View File
@@ -52,6 +52,9 @@ export const checkSorting = (
cy.get(`[col-id="${column}"]`).click();
});
checkSortChange(orderTabDesc, column);
cy.get('.ag-header-container').within(() => {
cy.get(`[col-id="${column}"]`).click();
});
};
const checkSortChange = (tabsArr: string[], column: string) => {

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