Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85a70cb172 | ||
|
|
3a7e9e72af | ||
|
|
5d613396e1 | ||
|
|
da551f9d3c | ||
|
|
47e4861fdb | ||
|
|
1a85a89440 | ||
|
|
7ab412a8f7 | ||
|
|
5a14174a81 | ||
|
|
5e00b93783 | ||
|
|
31d9b023e6 | ||
|
|
103e503a47 | ||
|
|
1952cb0e78 | ||
|
|
69340f4ddf | ||
|
|
c52bf2200e | ||
|
|
8dccee69f2 | ||
|
|
c7a6fdd879 | ||
|
|
8bcdaf4cda | ||
|
|
3eb1359504 | ||
|
|
39cf8ad4d6 | ||
|
|
faef98f0ae | ||
|
|
710e2daa27 | ||
|
|
06ea3924fa | ||
|
|
965e2d8972 | ||
|
|
73de2fed43 | ||
|
|
536859e067 | ||
|
|
54bfaef473 | ||
|
|
e2cad707a7 | ||
|
|
ec8d9798ab | ||
|
|
e629c1e81a | ||
|
|
25feed793c | ||
|
|
2867367e16 | ||
|
|
50b408e74d | ||
|
|
8f531c7c05 | ||
|
|
350d16fee1 | ||
|
|
c052c66266 | ||
|
|
e2032df236 | ||
|
|
9ece19869d | ||
|
|
22abc8160c | ||
|
|
b1a7a22bf9 | ||
|
|
c4b38cc0dc | ||
|
|
44d6d931d5 | ||
|
|
7f1e47d7fd | ||
|
|
0eddfa4073 | ||
|
|
83a034ce91 | ||
|
|
5ab5aa01a2 | ||
|
|
b22f9156b5 | ||
|
|
bab5e2018b | ||
|
|
3f7692ce75 | ||
|
|
b69fb3b0e5 | ||
|
|
83af6e74f6 | ||
|
|
b9908003ba | ||
|
|
1f9af79215 | ||
|
|
e31e40a7ef | ||
|
|
81f6b3cc15 | ||
|
|
8adb208a91 | ||
|
|
545c3a17d2 | ||
|
|
ad76988f63 | ||
|
|
d2bbd7e1fc | ||
|
|
fb1ebb3bdf | ||
|
|
b2489537ef | ||
|
|
382a7ea411 | ||
|
|
1ae2b4c153 | ||
|
|
e8875e817e | ||
|
|
4a01c880f3 | ||
|
|
f7f00dc7bb | ||
|
|
d151b6e923 | ||
|
|
8f8e9c1061 | ||
|
|
b40358a723 | ||
|
|
01f0934da3 | ||
|
|
df7755dbc4 | ||
|
|
9073234040 | ||
|
|
053cd0fa27 | ||
|
|
961dc88dc7 | ||
|
|
b16607a844 | ||
|
|
d0d804631c | ||
|
|
3e778a88dc | ||
|
|
dbb09c9c79 | ||
|
|
06f44b67de | ||
|
|
1861852852 | ||
|
|
3ee0eee80d | ||
|
|
69ce870a81 | ||
|
|
d8467c3206 | ||
|
|
de87f40a01 |
@@ -50,6 +50,20 @@ jobs:
|
|||||||
projects=[${projects// /,}]
|
projects=[${projects// /,}]
|
||||||
echo PROJECTS=$projects >> $GITHUB_ENV
|
echo PROJECTS=$projects >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# Rename required because some of the files contains the colon character (in the dates)
|
||||||
|
- name: Rename files to allow archive
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
while read -r file; do
|
||||||
|
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||||
|
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
name: logs-${{ matrix.project }}
|
||||||
|
path: /home/runner/.vegacapsule/testnet/logs
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
projects: ${{ env.PROJECTS }}
|
projects: ${{ env.PROJECTS }}
|
||||||
|
|
||||||
|
|||||||
@@ -64,12 +64,11 @@ jobs:
|
|||||||
######
|
######
|
||||||
|
|
||||||
- name: Run Cypress tests
|
- name: Run Cypress tests
|
||||||
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome --env.grepTags="${{ inputs.tags }}"
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||||
CYPRESS_grepTags: ${{ inputs.tags }}
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Upload logs
|
## Upload logs
|
||||||
|
|||||||
@@ -8,14 +8,16 @@ jobs:
|
|||||||
lint_pr:
|
lint_pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- name: Use Node.js 16
|
- name: Use Node.js 16
|
||||||
id: Node
|
id: Node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 16.14.0
|
node-version: 16.14.0
|
||||||
- name: Install commitlint cli and config
|
- name: Install root dependencies
|
||||||
run: npm install @commitlint/cli @commitlint/config-conventional
|
run: yarn install
|
||||||
- name: Create config
|
|
||||||
run: echo "module.exports = {extends:['@commitlint/config-conventional']};" > commitlint.config.js
|
|
||||||
- name: Check PR title
|
- name: Check PR title
|
||||||
run: echo "${{ github.event.pull_request.title }}" | npx commitlint
|
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
|||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
NX_VEGA_NETWORKS={\"MAINNET"\:\"https://explorer.vega.xyz"\,\"TESTNET\":\"https://explorer.fairground.wtf\"}
|
||||||
NX_TENDERMINT_URL=https://tm.n01.sandbox.vega.xyz
|
NX_TENDERMINT_URL=https://tm.sandbox.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.sandbox.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.sandbox.vega.xyz/websocket
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_VEGA_GOVERNANCE_URL=https://sandbox.token.vega.xyz
|
NX_VEGA_GOVERNANCE_URL=https://sandbox.token.vega.xyz
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ NX_VEGA_ENV=STAGNET3
|
|||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
|
||||||
NX_VEGA_GOVERNANCE_URL=https://stagnet3.token.vega.xyz
|
NX_VEGA_GOVERNANCE_URL=https://stagnet3.token.vega.xyz
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases/
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Main } from './components/main';
|
|||||||
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
||||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||||
import { Footer } from './components/footer/footer';
|
import { Footer } from './components/footer/footer';
|
||||||
|
import { AnnouncementBanner, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
@@ -40,6 +41,15 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<TendermintWebsocketProvider>
|
<TendermintWebsocketProvider>
|
||||||
<NetworkLoader cache={cacheConfig}>
|
<NetworkLoader cache={cacheConfig}>
|
||||||
|
<AnnouncementBanner>
|
||||||
|
<div className="font-alpha calt uppercase text-center text-lg text-white">
|
||||||
|
<span className="pr-4">The Mainnet sims are live!</span>
|
||||||
|
<ExternalLink href="https://fairground.wtf/">
|
||||||
|
Come help stress test the network
|
||||||
|
</ExternalLink>
|
||||||
|
</div>
|
||||||
|
</AnnouncementBanner>
|
||||||
|
|
||||||
<div className={layoutClasses}>
|
<div className={layoutClasses}>
|
||||||
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
|
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
|
||||||
<Nav menuOpen={menuOpen} />
|
<Nav menuOpen={menuOpen} />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ query ExplorerMarket($id: ID!) {
|
|||||||
market(id: $id) {
|
market(id: $id) {
|
||||||
id
|
id
|
||||||
decimalPlaces
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
tradableInstrument {
|
tradableInstrument {
|
||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
|
|||||||
+2
-1
@@ -8,7 +8,7 @@ export type ExplorerMarketQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } } } } | null };
|
export type ExplorerMarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', decimals: number } } } } } | null };
|
||||||
|
|
||||||
|
|
||||||
export const ExplorerMarketDocument = gql`
|
export const ExplorerMarketDocument = gql`
|
||||||
@@ -16,6 +16,7 @@ export const ExplorerMarketDocument = gql`
|
|||||||
market(id: $id) {
|
market(id: $id) {
|
||||||
id
|
id
|
||||||
decimalPlaces
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
tradableInstrument {
|
tradableInstrument {
|
||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ describe('Market link component', () => {
|
|||||||
market: {
|
market: {
|
||||||
id: '123',
|
id: '123',
|
||||||
decimalPlaces: 5,
|
decimalPlaces: 5,
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
state: 'irrelevant-test-data',
|
state: 'irrelevant-test-data',
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ const NestedDataListItem = ({
|
|||||||
)}
|
)}
|
||||||
</h4>
|
</h4>
|
||||||
{!hasChildren && (
|
{!hasChildren && (
|
||||||
<code className="text-vega-light-400 mb-2 last:mb-0 dark:text-vega-dark-400 break-all">
|
<code className="text-vega-light-100 mb-2 last:mb-0 dark:text-vega-dark-100 break-all">
|
||||||
{JSON.stringify(value, null, ' ')}
|
{JSON.stringify(value, null, ' ')}
|
||||||
</code>
|
</code>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ fragment ExplorerDeterministicOrderFields on Order {
|
|||||||
market {
|
market {
|
||||||
id
|
id
|
||||||
decimalPlaces
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
tradableInstrument {
|
tradableInstrument {
|
||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import * as Apollo from '@apollo/client';
|
import * as Apollo from '@apollo/client';
|
||||||
const defaultOptions = {} as const;
|
const defaultOptions = {} as const;
|
||||||
export type ExplorerDeterministicOrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } };
|
export type ExplorerDeterministicOrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } };
|
||||||
|
|
||||||
export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
|
export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
|
||||||
orderId: Types.Scalars['ID'];
|
orderId: Types.Scalars['ID'];
|
||||||
@@ -11,7 +11,7 @@ export type ExplorerDeterministicOrderQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type ExplorerDeterministicOrderQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } } };
|
export type ExplorerDeterministicOrderQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, reference: string, status: Types.OrderStatus, version: string, createdAt: any, updatedAt?: any | null, expiresAt?: any | null, timeInForce: Types.OrderTimeInForce, price: string, side: Types.Side, remaining: string, size: string, rejectionReason?: Types.OrderRejectionReason | null, party: { __typename?: 'Party', id: string }, market: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, product: { __typename?: 'Future', quoteName: string } } } } } };
|
||||||
|
|
||||||
export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
|
export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
|
||||||
fragment ExplorerDeterministicOrderFields on Order {
|
fragment ExplorerDeterministicOrderFields on Order {
|
||||||
@@ -35,6 +35,7 @@ export const ExplorerDeterministicOrderFieldsFragmentDoc = gql`
|
|||||||
market {
|
market {
|
||||||
id
|
id
|
||||||
decimalPlaces
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
tradableInstrument {
|
tradableInstrument {
|
||||||
instrument {
|
instrument {
|
||||||
name
|
name
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ function renderExistingAmend(id: string, version: number, amend: Amend) {
|
|||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
id: '789',
|
id: '789',
|
||||||
state: 'STATUS_ACTIVE',
|
state: 'STATUS_ACTIVE',
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
decimalPlaces: '5',
|
decimalPlaces: '5',
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
@@ -88,6 +89,7 @@ function renderExistingAmend(id: string, version: number, amend: Amend) {
|
|||||||
market: {
|
market: {
|
||||||
id: '789',
|
id: '789',
|
||||||
decimalPlaces: 5,
|
decimalPlaces: 5,
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
state: 'irrelevant-test-data',
|
state: 'irrelevant-test-data',
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { MarketLink } from '../links';
|
|||||||
import PriceInMarket from '../price-in-market/price-in-market';
|
import PriceInMarket from '../price-in-market/price-in-market';
|
||||||
import { Time } from '../time';
|
import { Time } from '../time';
|
||||||
import { sideText, statusText, tifFull, tifShort } from './lib/order-labels';
|
import { sideText, statusText, tifFull, tifShort } from './lib/order-labels';
|
||||||
|
import SizeInMarket from '../size-in-market/size-in-market';
|
||||||
|
|
||||||
export interface DeterministicOrderDetailsProps {
|
export interface DeterministicOrderDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -90,7 +91,7 @@ const DeterministicOrderDetails = ({
|
|||||||
<div className="mb-12 md:mb-0">
|
<div className="mb-12 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">{t('Size')}</h2>
|
<h2 className="text-2xl font-bold text-dark mb-4">{t('Size')}</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
||||||
{o.size}
|
<SizeInMarket size={o.size} marketId={o.market.id} />
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const mock = {
|
|||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
id: '789',
|
id: '789',
|
||||||
state: 'STATE_ACTIVE',
|
state: 'STATE_ACTIVE',
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ describe('Order TX Summary component', () => {
|
|||||||
market: {
|
market: {
|
||||||
id: '123',
|
id: '123',
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
state: 'irrelevant-test-data',
|
state: 'irrelevant-test-data',
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ const fullMock = {
|
|||||||
market: {
|
market: {
|
||||||
id: '123',
|
id: '123',
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
state: 'irrelevant-test-data',
|
state: 'irrelevant-test-data',
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import React from 'react';
|
|
||||||
import { StatusMessage } from '../status-message';
|
import { StatusMessage } from '../status-message';
|
||||||
|
|
||||||
interface RenderFetchedProps {
|
interface RenderFetchedProps {
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ export const Search = () => {
|
|||||||
className="text-white"
|
className="text-white"
|
||||||
hasError={Boolean(error?.message)}
|
hasError={Boolean(error?.message)}
|
||||||
type="text"
|
type="text"
|
||||||
placeholder={t('Enter block number, party id or transaction hash')}
|
placeholder={t(
|
||||||
|
'Enter block number, public key or transaction hash'
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
{error?.message && (
|
{error?.message && (
|
||||||
<div className="bg-white border border-t-0 border-accent absolute top-[100%] flex-1 w-full pb-2 px-2 rounded-b text-black">
|
<div className="bg-white border border-t-0 border-accent absolute top-[100%] flex-1 w-full pb-2 px-2 rounded-b text-black">
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import type { MockedResponse } from '@apollo/client/testing';
|
||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import SizeInMarket from './size-in-market';
|
||||||
|
import type { DecimalSource } from './size-in-market';
|
||||||
|
import { ExplorerMarketDocument } from '../links/market-link/__generated__/Market';
|
||||||
|
|
||||||
|
function renderComponent(
|
||||||
|
price: string,
|
||||||
|
marketId: string,
|
||||||
|
mocks: MockedResponse[],
|
||||||
|
decimalSource: DecimalSource = 'MARKET'
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<MockedProvider mocks={mocks} addTypename={false}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<SizeInMarket
|
||||||
|
marketId={marketId}
|
||||||
|
size={price}
|
||||||
|
decimalSource={decimalSource}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullMock = {
|
||||||
|
request: {
|
||||||
|
query: ExplorerMarketDocument,
|
||||||
|
variables: {
|
||||||
|
id: '123',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: '123',
|
||||||
|
decimalPlaces: 2,
|
||||||
|
positionDecimalPlaces: 2,
|
||||||
|
state: 'irrelevant-test-data',
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
name: 'test dai',
|
||||||
|
product: {
|
||||||
|
__typename: 'Future',
|
||||||
|
quoteName: 'dai',
|
||||||
|
settlementAsset: {
|
||||||
|
decimals: 18,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Size in Market component', () => {
|
||||||
|
it('Renders the raw size when there is no market data', () => {
|
||||||
|
const res = render(renderComponent('100', '123', []));
|
||||||
|
expect(res.getByText('100')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Renders the formatted size when market data is fetched', async () => {
|
||||||
|
const res = render(renderComponent('100', '123', [fullMock]));
|
||||||
|
expect(await res.findByText('1.00')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||||
|
import { useExplorerMarketQuery } from '../links/market-link/__generated__/Market';
|
||||||
|
|
||||||
|
export type DecimalSource = 'MARKET';
|
||||||
|
|
||||||
|
export type PriceInMarketProps = {
|
||||||
|
marketId: string;
|
||||||
|
size: string | number;
|
||||||
|
decimalSource?: DecimalSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a market ID and an order size it will fetch the market
|
||||||
|
* order size, and format the size accordingly
|
||||||
|
*/
|
||||||
|
const SizeInMarket = ({
|
||||||
|
marketId,
|
||||||
|
size,
|
||||||
|
decimalSource = 'MARKET',
|
||||||
|
}: PriceInMarketProps) => {
|
||||||
|
const { data } = useExplorerMarketQuery({
|
||||||
|
variables: { id: marketId },
|
||||||
|
fetchPolicy: 'cache-first',
|
||||||
|
});
|
||||||
|
|
||||||
|
let label = size;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (decimalSource === 'MARKET' && data.market?.positionDecimalPlaces) {
|
||||||
|
label = addDecimalsFormatNumber(size, data.market.positionDecimalPlaces);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label>
|
||||||
|
<span>{label}</span>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SizeInMarket;
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
import { BlockLink } from '../../links';
|
||||||
|
import { StatusMessage } from '../../status-message';
|
||||||
|
import { ENV } from '../../../config/env';
|
||||||
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import type { components } from '../../../../types/explorer';
|
||||||
|
|
||||||
|
interface TxDetailsProtocolUpgradeProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validator event: Protocol Upgrade proposal
|
||||||
|
*/
|
||||||
|
export const TxDetailsProtocolUpgrade = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsProtocolUpgradeProps) => {
|
||||||
|
if (!txData) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const upgrade: components['schemas']['v1ProtocolUpgradeProposal'] =
|
||||||
|
txData.command.protocolUpgradeProposal;
|
||||||
|
|
||||||
|
if (!upgrade || !upgrade.upgradeBlockHeight || !upgrade.vegaReleaseTag) {
|
||||||
|
return (
|
||||||
|
<StatusMessage>{t('Invalid upgrade proposal format')}</StatusMessage>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlBase = ENV.dataSources.vegaRepoUrl;
|
||||||
|
const release = upgrade.vegaReleaseTag;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableWithTbody className="mb-8">
|
||||||
|
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Upgrade at block')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<BlockLink height={upgrade.upgradeBlockHeight} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Upgrade to')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<ExternalLink href={`${urlBase}${release}`}>
|
||||||
|
{upgrade.vegaReleaseTag}
|
||||||
|
</ExternalLink>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableWithTbody>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -19,6 +19,8 @@ import { TxDetailsLiquidityAmendment } from './tx-liquidity-amend';
|
|||||||
import { TxDetailsLiquidityCancellation } from './tx-liquidity-cancel';
|
import { TxDetailsLiquidityCancellation } from './tx-liquidity-cancel';
|
||||||
import { TxDetailsDataSubmission } from './tx-data-submission';
|
import { TxDetailsDataSubmission } from './tx-data-submission';
|
||||||
import { TxProposalVote } from './tx-proposal-vote';
|
import { TxProposalVote } from './tx-proposal-vote';
|
||||||
|
import { TxDetailsProtocolUpgrade } from './tx-details-protocol-upgrade';
|
||||||
|
import { TxDetailsIssueSignatures } from './tx-issue-signatures';
|
||||||
|
|
||||||
interface TxDetailsWrapperProps {
|
interface TxDetailsWrapperProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -66,10 +68,14 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
|
|||||||
|
|
||||||
// These come from https://github.com/vegaprotocol/vega/blob/develop/core/txn/command.go#L72-L98
|
// These come from https://github.com/vegaprotocol/vega/blob/develop/core/txn/command.go#L72-L98
|
||||||
switch (txData.type) {
|
switch (txData.type) {
|
||||||
|
case 'Issue Signatures':
|
||||||
|
return TxDetailsIssueSignatures;
|
||||||
case 'Submit Order':
|
case 'Submit Order':
|
||||||
return TxDetailsOrder;
|
return TxDetailsOrder;
|
||||||
case 'Submit Oracle Data':
|
case 'Submit Oracle Data':
|
||||||
return TxDetailsDataSubmission;
|
return TxDetailsDataSubmission;
|
||||||
|
case 'Protocol Upgrade':
|
||||||
|
return TxDetailsProtocolUpgrade;
|
||||||
case 'Cancel Order':
|
case 'Cancel Order':
|
||||||
return TxDetailsOrderCancel;
|
return TxDetailsOrderCancel;
|
||||||
case 'Amend Order':
|
case 'Amend Order':
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ interface TxDetailsGenericProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If there is not yet a custom component for a transaction, just display
|
* A node is
|
||||||
* the basic details. This allows someone to view the decoded transaction.
|
|
||||||
*/
|
*/
|
||||||
export const TxDetailsGeneric = ({
|
export const TxDetailsGeneric = ({
|
||||||
txData,
|
txData,
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableRow, TableCell, TableWithTbody } from '../../table';
|
||||||
|
|
||||||
|
import type { components } from '../../../../types/explorer';
|
||||||
|
import {
|
||||||
|
EthExplorerLink,
|
||||||
|
EthExplorerLinkTypes,
|
||||||
|
} from '../../links/eth-explorer-link/eth-explorer-link';
|
||||||
|
import { NodeLink } from '../../links';
|
||||||
|
|
||||||
|
type Command = components['schemas']['v1IssueSignatures'];
|
||||||
|
|
||||||
|
const kind: Record<components['schemas']['v1NodeSignatureKind'], string> = {
|
||||||
|
NODE_SIGNATURE_KIND_UNSPECIFIED: 'Unspecified',
|
||||||
|
NODE_SIGNATURE_KIND_ASSET_NEW: 'New asset',
|
||||||
|
NODE_SIGNATURE_KIND_ASSET_WITHDRAWAL: 'Asset withdrawal',
|
||||||
|
NODE_SIGNATURE_KIND_ASSET_UPDATE: ' Asset update',
|
||||||
|
NODE_SIGNATURE_KIND_ERC20_MULTISIG_SIGNER_ADDED: 'Multisig signer added',
|
||||||
|
NODE_SIGNATURE_KIND_ERC20_MULTISIG_SIGNER_REMOVED: 'Multisig signer removed',
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TxDetailsGenericProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is not yet a custom component for a transaction, just display
|
||||||
|
* the basic details. This allows someone to view the decoded transaction.
|
||||||
|
*/
|
||||||
|
export const TxDetailsIssueSignatures = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsGenericProps) => {
|
||||||
|
if (!txData) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmd: Command = txData.command;
|
||||||
|
const k = cmd.kind ? kind[cmd.kind] : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableWithTbody className="mb-8">
|
||||||
|
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||||
|
{k ? (
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Kind')}</TableCell>
|
||||||
|
<TableCell>{k}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
) : null}
|
||||||
|
{cmd.submitter ? (
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('ETH key')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<EthExplorerLink
|
||||||
|
id={cmd.submitter}
|
||||||
|
type={EthExplorerLinkTypes.address}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
) : null}
|
||||||
|
{cmd.validatorNodeId ? (
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Validator')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<NodeLink id={cmd.validatorNodeId} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
) : null}
|
||||||
|
</TableWithTbody>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
|
||||||
import { MarketLink } from '../../links';
|
import { MarketLink } from '../../links';
|
||||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
|
||||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
|
||||||
import type { components } from '../../../../types/explorer';
|
import type { components } from '../../../../types/explorer';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
|
||||||
export type LiquidityCancellation =
|
export type LiquidityCancellation =
|
||||||
components['schemas']['v1LiquidityProvisionCancellation'];
|
components['schemas']['v1LiquidityProvisionCancellation'];
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export const TxDataView = ({ txData, blockData }: TxDataViewProps) => {
|
|||||||
<Select
|
<Select
|
||||||
placeholder="View as..."
|
placeholder="View as..."
|
||||||
onChange={(v) => setShowTxData(v.target.value as ShowTxDataType)}
|
onChange={(v) => setShowTxData(v.target.value as ShowTxDataType)}
|
||||||
value={'JSON'}
|
value={showTxData}
|
||||||
>
|
>
|
||||||
<option value={'JSON'}>JSON</option>
|
<option value={'JSON'}>JSON</option>
|
||||||
<option value={'base64'}>Base64</option>
|
<option value={'base64'}>Base64</option>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const truthy = ['1', 'true'];
|
|||||||
export const ENV = {
|
export const ENV = {
|
||||||
// Data sources
|
// Data sources
|
||||||
// Environment
|
// Environment
|
||||||
|
env: windowOrDefault('NX_VEGA_ENV'),
|
||||||
dsn: windowOrDefault('NX_EXPLORER_SENTRY_DSN'),
|
dsn: windowOrDefault('NX_EXPLORER_SENTRY_DSN'),
|
||||||
dataSources: {
|
dataSources: {
|
||||||
blockExplorerUrl: windowOrDefault('NX_BLOCK_EXPLORER'),
|
blockExplorerUrl: windowOrDefault('NX_BLOCK_EXPLORER'),
|
||||||
@@ -17,6 +18,7 @@ export const ENV = {
|
|||||||
tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'),
|
tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'),
|
||||||
ethExplorerUrl: windowOrDefault('NX_ETHERSCAN_URL'),
|
ethExplorerUrl: windowOrDefault('NX_ETHERSCAN_URL'),
|
||||||
governanceUrl: windowOrDefault('NX_VEGA_GOVERNANCE_URL'),
|
governanceUrl: windowOrDefault('NX_VEGA_GOVERNANCE_URL'),
|
||||||
|
vegaRepoUrl: windowOrDefault('NX_VEGA_REPO_URL'),
|
||||||
},
|
},
|
||||||
flags: {
|
flags: {
|
||||||
assets: truthy.includes(windowOrDefault('NX_EXPLORER_ASSETS')),
|
assets: truthy.includes(windowOrDefault('NX_EXPLORER_ASSETS')),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type {
|
|||||||
BlockExplorerTransactions,
|
BlockExplorerTransactions,
|
||||||
} from '../routes/types/block-explorer-response';
|
} from '../routes/types/block-explorer-response';
|
||||||
import { DATA_SOURCES } from '../config';
|
import { DATA_SOURCES } from '../config';
|
||||||
|
import isNumber from 'lodash/isNumber';
|
||||||
|
|
||||||
export interface TxsStateProps {
|
export interface TxsStateProps {
|
||||||
txsData: BlockExplorerTransactionResult[];
|
txsData: BlockExplorerTransactionResult[];
|
||||||
@@ -54,15 +55,15 @@ export const useTxsData = ({ limit, filters }: IUseTxsData) => {
|
|||||||
} = useFetch<BlockExplorerTransactions>(url, {}, false);
|
} = useFetch<BlockExplorerTransactions>(url, {}, false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.transactions?.length) {
|
if (data && isNumber(data?.transactions?.length)) {
|
||||||
setTxsState((prev) => ({
|
setTxsState((prev) => ({
|
||||||
txsData: [...prev.txsData, ...data.transactions],
|
txsData: [...prev.txsData, ...data.transactions],
|
||||||
hasMoreTxs: true,
|
hasMoreTxs: data.transactions.length > 0,
|
||||||
lastCursor:
|
lastCursor:
|
||||||
data.transactions[data.transactions.length - 1].cursor || '',
|
data.transactions[data.transactions.length - 1]?.cursor || '',
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}, [setTxsState, data?.transactions]);
|
}, [setTxsState, data]);
|
||||||
|
|
||||||
const loadTxs = useCallback(() => {
|
const loadTxs = useCallback(() => {
|
||||||
return refetch({
|
return refetch({
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec',
|
|||||||
export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null };
|
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } } } } } } } | null> | null } | null };
|
||||||
|
|
||||||
export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{
|
export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{
|
||||||
id: Types.Scalars['ID'];
|
id: Types.Scalars['ID'];
|
||||||
@@ -73,7 +73,7 @@ export const ExplorerOracleDataSourceFragmentDoc = gql`
|
|||||||
`;
|
`;
|
||||||
export const ExplorerOracleDataConnectionFragmentDoc = gql`
|
export const ExplorerOracleDataConnectionFragmentDoc = gql`
|
||||||
fragment ExplorerOracleDataConnection on OracleSpec {
|
fragment ExplorerOracleDataConnection on OracleSpec {
|
||||||
dataConnection(pagination: {first: 1}) {
|
dataConnection {
|
||||||
pageInfo {
|
pageInfo {
|
||||||
hasNextPage
|
hasNextPage
|
||||||
}
|
}
|
||||||
@@ -113,13 +113,11 @@ export const ExplorerOracleSpecsDocument = gql`
|
|||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ExplorerOracleDataSource
|
...ExplorerOracleDataSource
|
||||||
...ExplorerOracleDataConnection
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
${ExplorerOracleDataSourceFragmentDoc}
|
${ExplorerOracleDataSourceFragmentDoc}`;
|
||||||
${ExplorerOracleDataConnectionFragmentDoc}`;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __useExplorerOracleSpecsQuery__
|
* __useExplorerOracleSpecsQuery__
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export type SourceType =
|
|||||||
interface OracleDetailsProps {
|
interface OracleDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
dataSource: ExplorerOracleDataSourceFragment;
|
dataSource: ExplorerOracleDataSourceFragment;
|
||||||
dataConnection: ExplorerOracleDataConnectionFragment;
|
dataConnection?: ExplorerOracleDataConnectionFragment;
|
||||||
// Defaults to false. Hides the count of 'broadcasts' this oracle has seen
|
// Defaults to false. Hides the count of 'broadcasts' this oracle has seen
|
||||||
showBroadcasts?: boolean;
|
showBroadcasts?: boolean;
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,8 @@ export const OracleDetails = ({
|
|||||||
showBroadcasts = false,
|
showBroadcasts = false,
|
||||||
}: OracleDetailsProps) => {
|
}: OracleDetailsProps) => {
|
||||||
const sourceType = dataSource.dataSourceSpec.spec.data.sourceType;
|
const sourceType = dataSource.dataSourceSpec.spec.data.sourceType;
|
||||||
const reportsCount: number = dataConnection.dataConnection.edges?.length || 0;
|
const reportsCount: number =
|
||||||
|
dataConnection?.dataConnection.edges?.length || 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -63,7 +64,9 @@ export const OracleDetails = ({
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableWithTbody>
|
</TableWithTbody>
|
||||||
<OracleFilter data={dataSource} />
|
<OracleFilter data={dataSource} />
|
||||||
{showBroadcasts ? <OracleData data={dataConnection} /> : null}
|
{showBroadcasts && dataConnection ? (
|
||||||
|
<OracleData data={dataConnection} />
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const Oracles = () => {
|
|||||||
<OracleDetails
|
<OracleDetails
|
||||||
id={id}
|
id={id}
|
||||||
dataSource={o?.node}
|
dataSource={o?.node}
|
||||||
dataConnection={o?.node}
|
showBroadcasts={false}
|
||||||
/>
|
/>
|
||||||
<details>
|
<details>
|
||||||
<summary className="pointer">JSON</summary>
|
<summary className="pointer">JSON</summary>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { useDocumentTitle } from '../../../hooks/use-document-title';
|
|||||||
export const JumpToParty = () => {
|
export const JumpToParty = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useDocumentTitle(['Parties']);
|
useDocumentTitle(['Public keys']);
|
||||||
|
|
||||||
const handleSubmit = (e: React.SyntheticEvent) => {
|
const handleSubmit = (e: React.SyntheticEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -27,8 +27,8 @@ export const JumpToParty = () => {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<JumpTo
|
<JumpTo
|
||||||
label={t('Go to party')}
|
label={t('Go to public key')}
|
||||||
placeholder={t('Party id')}
|
placeholder={t('Public key')}
|
||||||
inputId="party-input"
|
inputId="party-input"
|
||||||
inputType="text"
|
inputType="text"
|
||||||
inputName="partyId"
|
inputName="partyId"
|
||||||
@@ -40,7 +40,7 @@ export const JumpToParty = () => {
|
|||||||
const Parties = () => {
|
const Parties = () => {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<RouteTitle data-testid="parties-header">{t('Parties')}</RouteTitle>
|
<RouteTitle data-testid="parties-header">{t('Public keys')}</RouteTitle>
|
||||||
<JumpToParty />
|
<JumpToParty />
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type PartyIdErrorProps = {
|
|||||||
const PartyIdError = ({ id, error }: PartyIdErrorProps) => {
|
const PartyIdError = ({ id, error }: PartyIdErrorProps) => {
|
||||||
const end = isValidPartyId(id)
|
const end = isValidPartyId(id)
|
||||||
? t('No accounts or transactions found for: ')
|
? t('No accounts or transactions found for: ')
|
||||||
: 'Invalid party id: ';
|
: 'Invalid public key: ';
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { PartyAccounts } from './components/party-accounts';
|
|||||||
const Party = () => {
|
const Party = () => {
|
||||||
const { party } = useParams<{ party: string }>();
|
const { party } = useParams<{ party: string }>();
|
||||||
|
|
||||||
useDocumentTitle(['Parties', party || '-']);
|
useDocumentTitle(['Public keys', party || '-']);
|
||||||
const partyId = toNonHex(party ? party : '');
|
const partyId = toNonHex(party ? party : '');
|
||||||
const { isMobile } = useScreenDimensions();
|
const { isMobile } = useScreenDimensions();
|
||||||
const visibleChars = useMemo(() => (isMobile ? 10 : 14), [isMobile]);
|
const visibleChars = useMemo(() => (isMobile ? 10 : 14), [isMobile]);
|
||||||
@@ -44,7 +44,7 @@ const Party = () => {
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Panel>
|
<Panel>
|
||||||
<p>No party found for key {party}</p>
|
<p>No data found for public key {party}</p>
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ const Party = () => {
|
|||||||
className="font-alpha uppercase font-xl mb-4 text-zinc-800 dark:text-zinc-200"
|
className="font-alpha uppercase font-xl mb-4 text-zinc-800 dark:text-zinc-200"
|
||||||
data-testid="parties-header"
|
data-testid="parties-header"
|
||||||
>
|
>
|
||||||
{t('Party')}
|
{t('Public key')}
|
||||||
</h1>
|
</h1>
|
||||||
{partyRes.data ? (
|
{partyRes.data ? (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const Tx = () => {
|
|||||||
to={`/${Routes.TX}`}
|
to={`/${Routes.TX}`}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
className="text-vega-light-300 dark:text-vega-light-300"
|
className="text-vega-light-150 dark:text-vega-light-150"
|
||||||
name={IconNames.CHEVRON_LEFT}
|
name={IconNames.CHEVRON_LEFT}
|
||||||
/>
|
/>
|
||||||
All Transactions
|
All Transactions
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
File diff suppressed because it is too large
Load Diff
@@ -16,4 +16,16 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
|||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
CYPRESS_VEGA_URL=http://localhost:3028/query
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||||
|
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
|
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||||
|
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
||||||
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
|
||||||
|
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
|||||||
@@ -2,27 +2,29 @@
|
|||||||
"changes": {
|
"changes": {
|
||||||
"decimalPlaces": "5",
|
"decimalPlaces": "5",
|
||||||
"positionDecimalPlaces": "5",
|
"positionDecimalPlaces": "5",
|
||||||
|
"lpPriceRange": "10",
|
||||||
"instrument": {
|
"instrument": {
|
||||||
"name": "Oranges Daily",
|
"name": "Token test market",
|
||||||
"code": "ORANGES.24h",
|
"code": "Token.24h",
|
||||||
"future": {
|
"future": {
|
||||||
"settlementAsset": "8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4",
|
"settlementAsset": "fBTC",
|
||||||
"quoteName": "tEuro",
|
"quoteName": "fBTC",
|
||||||
"settlementDataDecimals": 5,
|
|
||||||
"dataSourceSpecForSettlementData": {
|
"dataSourceSpecForSettlementData": {
|
||||||
|
"external": {
|
||||||
|
"oracle": {
|
||||||
"signers": [
|
"signers": [
|
||||||
{
|
{
|
||||||
"signer": {
|
"pubKey": {
|
||||||
"__typename": "ETHAddress",
|
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
||||||
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"key": {
|
"key": {
|
||||||
"name": "prices.BTC.value",
|
"name": "prices.ETH.value",
|
||||||
"type": "TYPE_INTEGER"
|
"type": "TYPE_INTEGER",
|
||||||
|
"numberDecimalPlaces": "0"
|
||||||
},
|
},
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
@@ -32,26 +34,27 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dataSourceSpecForTradingTermination": {
|
"dataSourceSpecForTradingTermination": {
|
||||||
"signers": [
|
"signers": [
|
||||||
{
|
{
|
||||||
"signer": {
|
"pubKey": {
|
||||||
"__typename": "ETHAddress",
|
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
||||||
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"key": {
|
"key": {
|
||||||
"name": "vegaprotocol.builtin.timestamp",
|
"name": "trading.terminated.ETH5",
|
||||||
"type": "TYPE_TIMESTAMP"
|
"type": "TYPE_BOOLEAN"
|
||||||
},
|
},
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
"operator": "OPERATOR_GREATER_THAN_OR_EQUAL",
|
"operator": "OPERATOR_EQUALS",
|
||||||
"value": "1648684800000000000"
|
"value": "true"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
},
|
},
|
||||||
"dataSourceSpecBinding": {
|
"dataSourceSpecBinding": {
|
||||||
"settlementPriceProperty": "prices.BTC.value",
|
"settlementPriceProperty": "prices.BTC.value",
|
||||||
"tradingTerminationProperty": "vegaprotocol.builtin.timestamp"
|
"tradingTerminationProperty": "trading.terminated.ETH5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
{
|
{
|
||||||
"marketId": "315a8e48db0a292c92b617264728048c82c20efc922c75fd292fc54e5c727c81",
|
|
||||||
"changes": {
|
|
||||||
"instrument": {
|
"instrument": {
|
||||||
"code": "ORANGES.24h",
|
"code": "TEST.24h",
|
||||||
"future": {
|
"future": {
|
||||||
"quoteName": "tEuro",
|
"quoteName": "fUSDC",
|
||||||
"settlementDataDecimals": 5,
|
"settlementDataDecimals": 5,
|
||||||
"dataSourceSpecForSettlementData": {
|
"dataSourceSpecForSettlementData": {
|
||||||
"signers": [
|
"signers": [
|
||||||
{
|
{
|
||||||
"signer": {
|
"pubKey": {
|
||||||
"__typename": "ETHAddress",
|
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
||||||
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"key": {
|
"key": {
|
||||||
"name": "prices.BTC.value",
|
"name": "prices.ETH.value",
|
||||||
"type": "TYPE_INTEGER"
|
"type": "TYPE_INTEGER"
|
||||||
},
|
},
|
||||||
"conditions": [
|
"conditions": [
|
||||||
@@ -33,17 +30,16 @@
|
|||||||
"dataSourceSpecForTradingTermination": {
|
"dataSourceSpecForTradingTermination": {
|
||||||
"signers": [
|
"signers": [
|
||||||
{
|
{
|
||||||
"signer": {
|
"pubKey": {
|
||||||
"__typename": "ETHAddress",
|
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
||||||
"address": "0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
"key": {
|
"key": {
|
||||||
"name": "vegaprotocol.builtin.timestamp",
|
"name": "trading.terminated.ETH5",
|
||||||
"type": "TYPE_TIMESTAMP"
|
"type": "TYPE_BOOLEAN"
|
||||||
},
|
},
|
||||||
"conditions": [
|
"conditions": [
|
||||||
{
|
{
|
||||||
@@ -55,8 +51,8 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dataSourceSpecBinding": {
|
"dataSourceSpecBinding": {
|
||||||
"settlementPriceProperty": "prices.BTC.value",
|
"settlementPriceProperty": "prices.ETH.value",
|
||||||
"tradingTerminationProperty": "vegaprotocol.builtin.timestamp"
|
"tradingTerminationProperty": "trading.terminated.ETH5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -79,5 +75,4 @@
|
|||||||
"sigma": 0.3
|
"sigma": 0.3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
123
|
0123245
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
|||||||
const dialogCloseButton = '[data-testid="dialog-close"]';
|
const dialogCloseButton = '[data-testid="dialog-close"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
|
const closedProposals = '[data-testid="closed-proposals"]';
|
||||||
const proposalVoteProgressForPercentage =
|
const proposalVoteProgressForPercentage =
|
||||||
'[data-testid="vote-progress-indicator-percentage-for"]';
|
'[data-testid="vote-progress-indicator-percentage-for"]';
|
||||||
const proposalVoteProgressAgainstPercentage =
|
const proposalVoteProgressAgainstPercentage =
|
||||||
@@ -22,7 +23,9 @@ const proposalVoteProgressAgainstTokens =
|
|||||||
const changeVoteButton = '[data-testid="change-vote-button"]';
|
const changeVoteButton = '[data-testid="change-vote-button"]';
|
||||||
const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
||||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||||
|
const proposalStatus = '[data-testid="proposal-status"]';
|
||||||
const rawProposalData = '[data-testid="proposal-data"]';
|
const rawProposalData = '[data-testid="proposal-data"]';
|
||||||
|
const votesTable = '[data-testid="votes-table"]';
|
||||||
const minVoteButton = '[data-testid="min-vote"]';
|
const minVoteButton = '[data-testid="min-vote"]';
|
||||||
const maxVoteButton = '[data-testid="max-vote"]';
|
const maxVoteButton = '[data-testid="max-vote"]';
|
||||||
const voteButtons = '[data-testid="vote-buttons"]';
|
const voteButtons = '[data-testid="vote-buttons"]';
|
||||||
@@ -37,6 +40,10 @@ const txTimeout = Cypress.env('txTimeout');
|
|||||||
const epochTimeout = Cypress.env('epochTimeout');
|
const epochTimeout = Cypress.env('epochTimeout');
|
||||||
const proposalTimeout = { timeout: 14000 };
|
const proposalTimeout = { timeout: 14000 };
|
||||||
|
|
||||||
|
const minCloseDays = 2;
|
||||||
|
const maxCloseDays = 3;
|
||||||
|
const requiredParticipation = 0.001;
|
||||||
|
|
||||||
const governanceProposalType = {
|
const governanceProposalType = {
|
||||||
NETWORK_PARAMETER: 'Network parameter',
|
NETWORK_PARAMETER: 'Network parameter',
|
||||||
NEW_MARKET: 'New market',
|
NEW_MARKET: 'New market',
|
||||||
@@ -65,21 +72,6 @@ context(
|
|||||||
network_parameters['governance.proposal.freeform.requiredMajority'] *
|
network_parameters['governance.proposal.freeform.requiredMajority'] *
|
||||||
100
|
100
|
||||||
).as('requiredMajority');
|
).as('requiredMajority');
|
||||||
cy.wrap(
|
|
||||||
network_parameters[
|
|
||||||
'governance.proposal.freeform.requiredParticipation'
|
|
||||||
] * 100
|
|
||||||
).as('requiredParticipation');
|
|
||||||
cy.wrap(
|
|
||||||
network_parameters['governance.proposal.freeform.minClose'].split(
|
|
||||||
'h'
|
|
||||||
)[0] / 24
|
|
||||||
).as('minCloseDays');
|
|
||||||
cy.wrap(
|
|
||||||
network_parameters['governance.proposal.freeform.maxClose'].split(
|
|
||||||
'h'
|
|
||||||
)[0] / 24
|
|
||||||
).as('maxCloseDays');
|
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
network_parameters['governance.proposal.freeform.minClose'].split(
|
network_parameters['governance.proposal.freeform.minClose'].split(
|
||||||
'h'
|
'h'
|
||||||
@@ -108,21 +100,6 @@ context(
|
|||||||
0.00001,
|
0.00001,
|
||||||
'Asserting that value is at least 0.00001 for network parameter minVoterBalance'
|
'Asserting that value is at least 0.00001 for network parameter minVoterBalance'
|
||||||
);
|
);
|
||||||
assert.isAtLeast(
|
|
||||||
parseFloat(this.requiredParticipation),
|
|
||||||
0.00001,
|
|
||||||
'Asserting that value is at least 0.00001 for network parameter requiredParticipation'
|
|
||||||
);
|
|
||||||
assert.isAtLeast(
|
|
||||||
parseInt(this.minCloseDays),
|
|
||||||
1,
|
|
||||||
'Asserting that value is at least 1 for network parameter minCloseDays'
|
|
||||||
);
|
|
||||||
assert.isAtLeast(
|
|
||||||
parseInt(this.maxCloseDays),
|
|
||||||
parseInt(this.minCloseDays + 1),
|
|
||||||
'Asserting that network parameter maxCloseDays is at least 1 day higher than minCloseDays'
|
|
||||||
);
|
|
||||||
// workaround for first eth tx hanging
|
// workaround for first eth tx hanging
|
||||||
associateTokenStartOfTests();
|
associateTokenStartOfTests();
|
||||||
}
|
}
|
||||||
@@ -182,10 +159,10 @@ context(
|
|||||||
this.minProposerBalance
|
this.minProposerBalance
|
||||||
);
|
);
|
||||||
let proposalDays = [
|
let proposalDays = [
|
||||||
this.minCloseDays + 1,
|
minCloseDays + 1,
|
||||||
this.maxCloseDays,
|
maxCloseDays,
|
||||||
this.minCloseDays + 3,
|
minCloseDays + 3,
|
||||||
this.minCloseDays + 2,
|
minCloseDays + 2,
|
||||||
];
|
];
|
||||||
for (var index = 0; index < proposalDays.length; index++) {
|
for (var index = 0; index < proposalDays.length; index++) {
|
||||||
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
cy.go_to_make_new_proposal(governanceProposalType.RAW);
|
||||||
@@ -227,6 +204,7 @@ context(
|
|||||||
cy.navigate_to('validators');
|
cy.navigate_to('validators');
|
||||||
cy.click_on_validator_from_list(0);
|
cy.click_on_validator_from_list(0);
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
|
cy.close_staking_dialog();
|
||||||
|
|
||||||
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
||||||
|
|
||||||
@@ -297,10 +275,12 @@ context(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Skipping test due to bug: #1320
|
// 3001-VOTE-071
|
||||||
it.skip('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
||||||
createFreeformProposal(this.minProposerBalance);
|
const proposalTitle = generateProposalTitle();
|
||||||
cy.get_submitted_proposal_from_proposal_list()
|
createFreeformProposal(this.minProposerBalance, proposalTitle);
|
||||||
|
|
||||||
|
cy.get_submitted_proposal_from_proposal_list(proposalTitle)
|
||||||
.as('submittedProposal')
|
.as('submittedProposal')
|
||||||
.within(() => {
|
.within(() => {
|
||||||
// 3001-VOTE-039
|
// 3001-VOTE-039
|
||||||
@@ -312,7 +292,7 @@ context(
|
|||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((totalSupply) => {
|
.then((totalSupply) => {
|
||||||
let tokensRequiredToAchieveResult = parseFloat(
|
let tokensRequiredToAchieveResult = parseFloat(
|
||||||
(totalSupply.replace(/,/g, '') * this.requiredParticipation) / 100
|
(totalSupply.replace(/,/g, '') * requiredParticipation) / 100
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
tokensRequiredToAchieveResult
|
tokensRequiredToAchieveResult
|
||||||
@@ -321,16 +301,17 @@ context(
|
|||||||
cy.get('@submittedProposal').within(() =>
|
cy.get('@submittedProposal').within(() =>
|
||||||
cy.get(viewProposalButton).click()
|
cy.get(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.get_proposal_information_from_table('Participation met')
|
cy.get_proposal_information_from_table('Token participation met')
|
||||||
.contains('👍')
|
.contains('👍')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
cy.navigate_to('proposals');
|
cy.navigate_to('proposals');
|
||||||
cy.get('@submittedProposal').within(() =>
|
cy.get('@submittedProposal').within(() =>
|
||||||
cy.get(voteStatus).should('have.text', 'Participation met')
|
cy.get(voteStatus).should('have.text', 'Set to pass')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-055
|
||||||
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get('@rawProposal').then((rawProposal) => {
|
cy.get('@rawProposal').then((rawProposal) => {
|
||||||
@@ -357,6 +338,7 @@ context(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-043
|
||||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||||
const closingVoteHrs = '72';
|
const closingVoteHrs = '72';
|
||||||
const proposalTitle = generateProposalTitle();
|
const proposalTitle = generateProposalTitle();
|
||||||
@@ -399,6 +381,7 @@ context(
|
|||||||
it('Newly created proposal details - shows default status set to fail', function () {
|
it('Newly created proposal details - shows default status set to fail', function () {
|
||||||
// 3001-VOTE-037
|
// 3001-VOTE-037
|
||||||
// 3001-VOTE-040
|
// 3001-VOTE-040
|
||||||
|
// 3001-VOTE-067
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get('@rawProposal').then((rawProposal) => {
|
cy.get('@rawProposal').then((rawProposal) => {
|
||||||
cy.get_submitted_proposal_from_proposal_list(
|
cy.get_submitted_proposal_from_proposal_list(
|
||||||
@@ -413,15 +396,17 @@ context(
|
|||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
// 3001-VOTE-062
|
// 3001-VOTE-062
|
||||||
// 3001-VOTE-040
|
// 3001-VOTE-040
|
||||||
|
// 3001-VOTE-070
|
||||||
cy.get_proposal_information_from_table('Token majority met')
|
cy.get_proposal_information_from_table('Token majority met')
|
||||||
.contains('👎')
|
.contains('👎')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
|
// 3001-VOTE-068
|
||||||
cy.get_proposal_information_from_table('Token participation met')
|
cy.get_proposal_information_from_table('Token participation met')
|
||||||
.contains('👎')
|
.contains('👎')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-080 3001-VOTE-090
|
// 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073
|
||||||
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get('@rawProposal').then((rawProposal) => {
|
cy.get('@rawProposal').then((rawProposal) => {
|
||||||
@@ -446,7 +431,7 @@ context(
|
|||||||
.contains(votedDate)
|
.contains(votedDate)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
cy.get(proposalVoteProgressForPercentage)
|
cy.get(proposalVoteProgressForPercentage) // 3001-VOTE-072
|
||||||
.contains('100.00%')
|
.contains('100.00%')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.get(proposalVoteProgressAgainstPercentage)
|
cy.get(proposalVoteProgressAgainstPercentage)
|
||||||
@@ -466,10 +451,10 @@ context(
|
|||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
// 3001-VOTE-061
|
// 3001-VOTE-061
|
||||||
cy.get_proposal_information_from_table('Participation required')
|
cy.get_proposal_information_from_table('Participation required')
|
||||||
.contains(`${this.requiredParticipation}%`)
|
.contains(`${requiredParticipation}%`)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
// 3001-VOTE-066
|
// 3001-VOTE-066
|
||||||
cy.get_proposal_information_from_table('Majority Required')
|
cy.get_proposal_information_from_table('Majority Required') // 3001-VOTE-073
|
||||||
.contains(`${parseFloat(this.requiredMajority).toFixed(2)}%`)
|
.contains(`${parseFloat(this.requiredMajority).toFixed(2)}%`)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
cy.get_proposal_information_from_table('Number of voting parties')
|
cy.get_proposal_information_from_table('Number of voting parties')
|
||||||
@@ -512,7 +497,7 @@ context(
|
|||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((totalSupply) => {
|
.then((totalSupply) => {
|
||||||
let tokensRequiredToAchieveResult = parseFloat(
|
let tokensRequiredToAchieveResult = parseFloat(
|
||||||
(totalSupply.replace(/,/g, '') * this.requiredParticipation) / 100
|
(totalSupply.replace(/,/g, '') * requiredParticipation) / 100
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
tokensRequiredToAchieveResult
|
tokensRequiredToAchieveResult
|
||||||
@@ -536,6 +521,11 @@ context(
|
|||||||
cy.get(proposalVoteProgressAgainstTokens)
|
cy.get(proposalVoteProgressAgainstTokens)
|
||||||
.contains('0.00')
|
.contains('0.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
|
cy.get_proposal_information_from_table(
|
||||||
|
'Total tokens voted percentage'
|
||||||
|
)
|
||||||
|
.should('have.text', '0.00%')
|
||||||
|
.and('be.visible');
|
||||||
cy.get_proposal_information_from_table('Tokens for proposal')
|
cy.get_proposal_information_from_table('Tokens for proposal')
|
||||||
.should('have.text', tokensRequiredToAchieveResult)
|
.should('have.text', tokensRequiredToAchieveResult)
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -588,6 +578,7 @@ context(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-006
|
||||||
it('Creating a proposal - proposal rejected - able to access rejected proposals', function () {
|
it('Creating a proposal - proposal rejected - able to access rejected proposals', function () {
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
this.minProposerBalance
|
this.minProposerBalance
|
||||||
@@ -649,6 +640,7 @@ context(
|
|||||||
cy.get(dialogCloseButton).click();
|
cy.get(dialogCloseButton).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3002-PROP-009
|
||||||
it('Unable to create a proposal - when some but not enough tokens are associated', function () {
|
it('Unable to create a proposal - when some but not enough tokens are associated', function () {
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
this.minProposerBalance - 0.000001
|
this.minProposerBalance - 0.000001
|
||||||
@@ -669,7 +661,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Unable to create a freeform proposal - when json parent section contains unexpected field', function () {
|
it('Unable to create a freeform proposal - when json parent section contains unexpected field', function () {
|
||||||
// 3001-VOTE-038
|
// 3001-VOTE-038 3002-PROP-013 3002-PROP-014
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
this.minProposerBalance
|
this.minProposerBalance
|
||||||
);
|
);
|
||||||
@@ -695,6 +687,9 @@ context(
|
|||||||
'Invalid params: the transaction is malformed'
|
'Invalid params: the transaction is malformed'
|
||||||
);
|
);
|
||||||
cy.get(dialogCloseButton).click();
|
cy.get(dialogCloseButton).click();
|
||||||
|
cy.get(rawProposalData)
|
||||||
|
.invoke('val')
|
||||||
|
.should('contain', "i shouldn't be here");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Unable to create a freeform proposal - when json terms section contains unexpected field', function () {
|
it('Unable to create a freeform proposal - when json terms section contains unexpected field', function () {
|
||||||
@@ -792,6 +787,107 @@ context(
|
|||||||
cy.contains('You voted: Against').should('be.visible');
|
cy.contains('You voted: Against').should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-006
|
||||||
|
it('Able to view enacted proposal', function () {
|
||||||
|
cy.createMarket();
|
||||||
|
cy.reload();
|
||||||
|
cy.wait_for_spinner();
|
||||||
|
cy.get(closedProposals).within(() => {
|
||||||
|
cy.get(proposalDetailsTitle).should(
|
||||||
|
'have.text',
|
||||||
|
'Add Lorem Ipsum market'
|
||||||
|
);
|
||||||
|
cy.get(proposalStatus).should('have.text', 'Enacted ');
|
||||||
|
cy.get(viewProposalButton).click();
|
||||||
|
});
|
||||||
|
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Enacted')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.get(votesTable).within(() => {
|
||||||
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-047
|
||||||
|
it('Able to enact freeform proposal', function () {
|
||||||
|
const proposalTitle = 'Add New free form proposal with short enactment';
|
||||||
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
|
this.minProposerBalance
|
||||||
|
);
|
||||||
|
cy.sendWalletTxFreeFormProposal();
|
||||||
|
cy.navigate_to('proposals');
|
||||||
|
cy.reload();
|
||||||
|
cy.wait_for_spinner();
|
||||||
|
cy.contains(proposalTitle)
|
||||||
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.vote_for_proposal('for');
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Enacted', epochTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-046 3001-VOTE-044 3001-VOTE-074 3001-VOTE-074
|
||||||
|
it('Able to enact proposal by voting', function () {
|
||||||
|
const proposalTitle = 'Add New proposal with short enactment';
|
||||||
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
|
this.minProposerBalance
|
||||||
|
);
|
||||||
|
cy.sendWalletTxUpdateNetworkProposal();
|
||||||
|
cy.navigate_to('proposals');
|
||||||
|
cy.reload();
|
||||||
|
cy.wait_for_spinner();
|
||||||
|
cy.contains(proposalTitle)
|
||||||
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.vote_for_proposal('for');
|
||||||
|
cy.get_proposal_information_from_table('State') // 3001-VOTE-047
|
||||||
|
.contains('Passed', txTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Enacted', epochTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
cy.get(votesTable).within(() => {
|
||||||
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
|
});
|
||||||
|
cy.get(proposalVoteProgressForPercentage)
|
||||||
|
.contains('100.00%')
|
||||||
|
.and('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3001-VOTE-048 3001-VOTE-049
|
||||||
|
it('Able to fail proposal due to lack of participation', function () {
|
||||||
|
const proposalTitle = 'Add New free form proposal with short enactment';
|
||||||
|
cy.ensure_specified_unstaked_tokens_are_associated(
|
||||||
|
this.minProposerBalance
|
||||||
|
);
|
||||||
|
cy.sendWalletTxFreeFormProposal();
|
||||||
|
cy.navigate_to('proposals');
|
||||||
|
cy.reload();
|
||||||
|
cy.wait_for_spinner();
|
||||||
|
cy.contains(proposalTitle)
|
||||||
|
.parentsUntil('[data-testid="proposals-list-item"]')
|
||||||
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
|
cy.get_proposal_information_from_table('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.get_proposal_information_from_table('State') // 3001-VOTE-047
|
||||||
|
.contains('Declined', txTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
cy.get_proposal_information_from_table('Rejection reason')
|
||||||
|
.contains('PROPOSAL_ERROR_PARTICIPATION_THRESHOLD_NOT_REACHED')
|
||||||
|
.and('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
function createRawProposal(proposerBalance) {
|
function createRawProposal(proposerBalance) {
|
||||||
if (proposerBalance)
|
if (proposerBalance)
|
||||||
cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance);
|
cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance);
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||||
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
|
const proposalType = '[data-testid="proposal-type"]';
|
||||||
|
const proposalDetails = '[data-testid="proposal-details"]';
|
||||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||||
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
||||||
const proposalValidationDeadline =
|
const proposalValidationDeadline =
|
||||||
@@ -209,18 +213,15 @@ context(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// skipped because no markets available to select in capsule
|
|
||||||
it.skip('Able to submit update market proposal', function () {
|
it.skip('Able to submit update market proposal', function () {
|
||||||
const marketId =
|
|
||||||
'315a8e48db0a292c92b617264728048c82c20efc922c75fd292fc54e5c727c81';
|
|
||||||
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET);
|
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET);
|
||||||
cy.get(newProposalTitle).type('Test update asset proposal');
|
cy.get(newProposalTitle).type('Test update market proposal');
|
||||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||||
cy.get(proposalMarketSelect).select(marketId);
|
cy.get(proposalMarketSelect).select('Test market 1');
|
||||||
cy.get('[data-testid="update-market-details"]').within(() => {
|
cy.get('[data-testid="update-market-details"]').within(() => {
|
||||||
cy.get('dd').eq(0).should('have.text', 'Oranges Daily');
|
cy.get('dd').eq(0).should('have.text', 'Test market 1');
|
||||||
cy.get('dd').eq(1).should('have.text', 'ORANGES.24h');
|
cy.get('dd').eq(1).should('have.text', 'TEST.24h');
|
||||||
cy.get('dd').eq(2).should('have.text', marketId);
|
cy.get('dd').eq(2).should('not.be.empty');
|
||||||
});
|
});
|
||||||
cy.fixture('/proposals/update-market').then((updateMarketProposal) => {
|
cy.fixture('/proposals/update-market').then((updateMarketProposal) => {
|
||||||
let newUpdateMarketProposal = JSON.stringify(updateMarketProposal);
|
let newUpdateMarketProposal = JSON.stringify(updateMarketProposal);
|
||||||
@@ -281,12 +282,28 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Able to submit update asset proposal using min deadline', function () {
|
it('Able to submit update asset proposal using min deadline', function () {
|
||||||
|
const assetId =
|
||||||
|
'ebcd94151ae1f0d39a4bde3b21a9c7ae81a80ea4352fb075a92e07608d9c953d';
|
||||||
|
|
||||||
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_ASSET);
|
cy.go_to_make_new_proposal(governanceProposalType.UPDATE_ASSET);
|
||||||
enterUpdateAssetProposalDetails();
|
enterUpdateAssetProposalDetails();
|
||||||
cy.get(minVoteDeadline).click();
|
cy.get(minVoteDeadline).click();
|
||||||
cy.get(minEnactDeadline).click();
|
cy.get(minEnactDeadline).click();
|
||||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.wait_for_proposal_submitted();
|
cy.wait_for_proposal_submitted();
|
||||||
|
cy.navigate_to('proposals');
|
||||||
|
cy.get(openProposals).within(() => {
|
||||||
|
cy.get(proposalType)
|
||||||
|
.contains('Update asset')
|
||||||
|
.parentsUntil(proposalListItem)
|
||||||
|
.within(() => {
|
||||||
|
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
||||||
|
cy.getByTestId('view-proposal-btn').click();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
cy.get_proposal_information_from_table('Proposed enactment') // 3001-VOTE-044
|
||||||
|
.invoke('text')
|
||||||
|
.should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to submit update asset proposal using max deadline', function () {
|
it('Able to submit update asset proposal using max deadline', function () {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ context(
|
|||||||
function () {
|
function () {
|
||||||
cy.reload();
|
cy.reload();
|
||||||
cy.wait_for_spinner();
|
cy.wait_for_spinner();
|
||||||
cy.connectVegaWallet();
|
|
||||||
cy.ethereum_wallet_connect();
|
cy.ethereum_wallet_connect();
|
||||||
|
cy.connectVegaWallet();
|
||||||
cy.vega_wallet_teardown();
|
cy.vega_wallet_teardown();
|
||||||
cy.navigate_to('validators');
|
cy.navigate_to('validators');
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,16 @@ context(
|
|||||||
//0005-ETXN-006
|
//0005-ETXN-006
|
||||||
//0005-ETXN-003
|
//0005-ETXN-003
|
||||||
//0005-ETXN-005
|
//0005-ETXN-005
|
||||||
cy.staking_page_associate_tokens('2');
|
cy.staking_page_associate_tokens('2', { skipConfirmation: true });
|
||||||
|
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '0.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '2.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '2.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
|
||||||
// 0005-ETXN-002
|
// 0005-ETXN-002
|
||||||
cy.get(ethWalletAssociatedBalances, txTimeout)
|
cy.get(ethWalletAssociatedBalances, txTimeout)
|
||||||
@@ -98,6 +107,15 @@ context(
|
|||||||
|
|
||||||
cy.staking_page_disassociate_tokens('2');
|
cy.staking_page_disassociate_tokens('2');
|
||||||
|
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '2.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '2.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '0.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
|
||||||
cy.get(ethWalletAssociatedBalances, txTimeout).should('not.exist');
|
cy.get(ethWalletAssociatedBalances, txTimeout).should('not.exist');
|
||||||
|
|
||||||
cy.get(ethWalletTotalAssociatedBalance, txTimeout)
|
cy.get(ethWalletTotalAssociatedBalance, txTimeout)
|
||||||
@@ -194,7 +212,19 @@ context(
|
|||||||
// 1004-ASSO-024
|
// 1004-ASSO-024
|
||||||
// 1004-ASSO-023
|
// 1004-ASSO-023
|
||||||
|
|
||||||
cy.staking_page_associate_tokens('2', { type: 'contract' });
|
cy.staking_page_associate_tokens('2', {
|
||||||
|
type: 'contract',
|
||||||
|
skipConfirmation: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '0.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '2.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '2.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
|
||||||
cy.get(ethWalletAssociatedBalances, txTimeout)
|
cy.get(ethWalletAssociatedBalances, txTimeout)
|
||||||
.contains(vegaWalletPublicKeyShort)
|
.contains(vegaWalletPublicKeyShort)
|
||||||
@@ -210,7 +240,19 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||||
cy.staking_page_disassociate_tokens('1', { type: 'contract' });
|
cy.staking_page_disassociate_tokens('1', {
|
||||||
|
type: 'contract',
|
||||||
|
skipConfirmation: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '2.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '1.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '1.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
|
||||||
cy.get(ethWalletAssociatedBalances, txTimeout)
|
cy.get(ethWalletAssociatedBalances, txTimeout)
|
||||||
.contains(vegaWalletPublicKeyShort)
|
.contains(vegaWalletPublicKeyShort)
|
||||||
@@ -286,6 +328,35 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 1004-ASSO-004
|
// 1004-ASSO-004
|
||||||
|
|
||||||
|
it('Pending association outside of app is shown', function () {
|
||||||
|
cy.vega_wallet_associate('2');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '0.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '2.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '2.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
cy.validate_wallet_currency('Associated', '2.00');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Disassociation outside of app is shown', function () {
|
||||||
|
cy.staking_page_associate_tokens('2');
|
||||||
|
cy.validate_wallet_currency('Associated', '2.00');
|
||||||
|
cy.vega_wallet_disassociate('2');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
cy.validate_wallet_currency('Associated', '2.00');
|
||||||
|
cy.validate_wallet_currency('Pending association', '2.00');
|
||||||
|
cy.validate_wallet_currency('Total associated after pending', '0.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 3);
|
||||||
|
cy.validate_wallet_currency('Associated', '0.00');
|
||||||
|
});
|
||||||
|
|
||||||
it('Able to associate tokens to different public key of connected vega wallet', function () {
|
it('Able to associate tokens to different public key of connected vega wallet', function () {
|
||||||
cy.get(ethWalletAssociateButton).first().click();
|
cy.get(ethWalletAssociateButton).first().click();
|
||||||
cy.get(associateWalletRadioButton).click();
|
cy.get(associateWalletRadioButton).click();
|
||||||
@@ -310,6 +381,7 @@ context(
|
|||||||
'vegaWalletPublicKey2Short'
|
'vegaWalletPublicKey2Short'
|
||||||
)} can now participate in governance and nominate a validator with your associated $VEGA.`
|
)} can now participate in governance and nominate a validator with your associated $VEGA.`
|
||||||
);
|
);
|
||||||
|
cy.staking_page_disassociate_all_tokens();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
|||||||
|
|
||||||
it('Able to connect public key via wallet', function () {
|
it('Able to connect public key via wallet', function () {
|
||||||
verifyConnectedToPubKey();
|
verifyConnectedToPubKey();
|
||||||
cy.getByTestId('currency-title').should('contain.text', 'USDC (fake)');
|
cy.getByTestId('currency-title', Cypress.env('epochTimeout')).should(
|
||||||
|
'contain.text',
|
||||||
|
'USDC (fake)'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to connect public key using url', function () {
|
it('Able to connect public key using url', function () {
|
||||||
|
|||||||
@@ -321,6 +321,8 @@ context(
|
|||||||
'200000',
|
'200000',
|
||||||
vegaWalletPublicKey
|
vegaWalletPublicKey
|
||||||
);
|
);
|
||||||
|
cy.reload();
|
||||||
|
cy.wait_for_spinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
cy.ethereum_wallet_connect();
|
cy.ethereum_wallet_connect();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ Cypress.Commands.add('verify_page_header', (text) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('wait_for_spinner', () => {
|
Cypress.Commands.add('wait_for_spinner', () => {
|
||||||
cy.get(navigation.pageSpinner).should('exist');
|
cy.get(navigation.pageSpinner, Cypress.env('epochTimeout')).should('exist');
|
||||||
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
|
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import './governance.functions.js';
|
|||||||
import './wallet-eth.functions.js';
|
import './wallet-eth.functions.js';
|
||||||
import './wallet-teardown.functions.js';
|
import './wallet-teardown.functions.js';
|
||||||
import './wallet-vega.functions.js';
|
import './wallet-vega.functions.js';
|
||||||
|
import './proposal.functions.js';
|
||||||
import registerCypressGrep from '@cypress/grep';
|
import registerCypressGrep from '@cypress/grep';
|
||||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||||
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { addSeconds, millisecondsToSeconds } from 'date-fns';
|
||||||
|
|
||||||
|
const walletName = Cypress.env('vegaWalletName');
|
||||||
|
const walletPubKey = Cypress.env('vegaWalletPublicKey');
|
||||||
|
const walletLocation = Cypress.env('vegaWalletLocation');
|
||||||
|
const walletPassphraseFile = './src/fixtures/wallet/passphrase';
|
||||||
|
|
||||||
|
Cypress.Commands.add('sendWalletTxUpdateNetworkProposal', () => {
|
||||||
|
const MIN_CLOSE_SEC = 8;
|
||||||
|
const MIN_ENACT_SEC = 5;
|
||||||
|
|
||||||
|
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
|
||||||
|
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
|
||||||
|
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
|
||||||
|
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
|
||||||
|
|
||||||
|
cy.exec(
|
||||||
|
`vegawallet transaction send --wallet ${walletName} --pubkey ${walletPubKey} -p ${walletPassphraseFile} --network DV '{
|
||||||
|
"proposalSubmission": {
|
||||||
|
"rationale": {
|
||||||
|
"title": "Add New proposal with short enactment",
|
||||||
|
"description": "E2E enactment test"
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"updateNetworkParameter": {
|
||||||
|
"changes": {
|
||||||
|
"key": "governance.proposal.updateNetParam.minProposerBalance",
|
||||||
|
"value": "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"closingTimestamp": ${closingTimestamp},
|
||||||
|
"enactmentTimestamp": ${enactmentTimestamp}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}' --home ${walletLocation}`,
|
||||||
|
{ failOnNonZeroExit: false }
|
||||||
|
)
|
||||||
|
.its('stderr')
|
||||||
|
.should('contain', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('sendWalletTxUpdateAssetProposal', () => {
|
||||||
|
const MIN_CLOSE_SEC = 8;
|
||||||
|
const MIN_ENACT_SEC = 5;
|
||||||
|
|
||||||
|
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
|
||||||
|
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
|
||||||
|
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
|
||||||
|
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
|
||||||
|
|
||||||
|
cy.exec(
|
||||||
|
`vegawallet transaction send --wallet ${walletName} --pubkey ${walletPubKey} -p ${walletPassphraseFile} --network DV '{
|
||||||
|
"proposalSubmission": {
|
||||||
|
"rationale": {
|
||||||
|
"title": "Update Asset set to fail",
|
||||||
|
"description": "E2E fail test"
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"updateAsset": {
|
||||||
|
"assetId": "ebcd94151ae1f0d39a4bde3b21a9c7ae81a80ea4352fb075a92e07608d9c953d",
|
||||||
|
"changes": {
|
||||||
|
"quantum": "1",
|
||||||
|
"erc20": {
|
||||||
|
"withdrawThreshold": "10",
|
||||||
|
"lifetimeLimit": "10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"closingTimestamp": ${closingTimestamp},
|
||||||
|
"enactmentTimestamp": ${enactmentTimestamp}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}' --home ${walletLocation}`,
|
||||||
|
{ failOnNonZeroExit: false }
|
||||||
|
)
|
||||||
|
.its('stderr')
|
||||||
|
.should('contain', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('sendWalletTxFreeFormProposal', () => {
|
||||||
|
const MIN_CLOSE_SEC = 5;
|
||||||
|
|
||||||
|
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
|
||||||
|
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
|
||||||
|
|
||||||
|
cy.exec(
|
||||||
|
`vegawallet transaction send --wallet ${walletName} --pubkey ${walletPubKey} -p ${walletPassphraseFile} --network DV '{
|
||||||
|
"proposalSubmission": {
|
||||||
|
"rationale": {
|
||||||
|
"title": "Add New free form proposal with short enactment",
|
||||||
|
"description": "E2E enactment test"
|
||||||
|
},
|
||||||
|
"terms": {
|
||||||
|
"newFreeform": {},
|
||||||
|
"closingTimestamp": ${closingTimestamp}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}' --home ${walletLocation}`,
|
||||||
|
{ failOnNonZeroExit: false }
|
||||||
|
)
|
||||||
|
.its('stderr')
|
||||||
|
.should('contain', '');
|
||||||
|
});
|
||||||
@@ -58,6 +58,8 @@ Cypress.Commands.add('staking_validator_page_remove_stake', (stake) => {
|
|||||||
Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => {
|
Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => {
|
||||||
let approve = options && options.approve ? options.approve : false;
|
let approve = options && options.approve ? options.approve : false;
|
||||||
let type = options && options.type ? options.type : 'wallet';
|
let type = options && options.type ? options.type : 'wallet';
|
||||||
|
let skipConfirmation =
|
||||||
|
options && options.skipConfirmation ? options.skipConfirmation : false;
|
||||||
|
|
||||||
cy.highlight(`Associating ${amount} tokens from ${type}`);
|
cy.highlight(`Associating ${amount} tokens from ${type}`);
|
||||||
cy.get(ethWalletAssociateButton).first().click();
|
cy.get(ethWalletAssociateButton).first().click();
|
||||||
@@ -79,6 +81,8 @@ Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
cy.get(tokenSubmitButton, txTimeout).should('be.enabled').click();
|
cy.get(tokenSubmitButton, txTimeout).should('be.enabled').click();
|
||||||
|
|
||||||
|
if (!skipConfirmation) {
|
||||||
cy.contains(
|
cy.contains(
|
||||||
`Associating with Vega key. Waiting for ${Cypress.env(
|
`Associating with Vega key. Waiting for ${Cypress.env(
|
||||||
'blockConfirmations'
|
'blockConfirmations'
|
||||||
@@ -89,6 +93,7 @@ Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => {
|
|||||||
'can now participate in governance and nominate a validator',
|
'can now participate in governance and nominate a validator',
|
||||||
txTimeout
|
txTimeout
|
||||||
).should('be.visible');
|
).should('be.visible');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('staking_page_disassociate_tokens', (amount, options) => {
|
Cypress.Commands.add('staking_page_disassociate_tokens', (amount, options) => {
|
||||||
@@ -216,3 +221,19 @@ Cypress.Commands.add('close_staking_dialog', () => {
|
|||||||
cy.get('a').should('have.text', 'Back to Staking').click();
|
cy.get('a').should('have.text', 'Back to Staking').click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'validate_wallet_currency',
|
||||||
|
(currencyTitle, expectedAmount) => {
|
||||||
|
cy.get("[data-testid='currency-title']")
|
||||||
|
.contains(currencyTitle)
|
||||||
|
.parent()
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.getByTestId('currency-value', txTimeout).should(
|
||||||
|
'have.text',
|
||||||
|
expectedAmount
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
import { ethers, Wallet } from 'ethers';
|
import { ethers, Wallet } from 'ethers';
|
||||||
|
|
||||||
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
||||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
|
||||||
const vegaWalletMnemonic = Cypress.env('vegaWalletMnemonic');
|
const vegaWalletMnemonic = Cypress.env('vegaWalletMnemonic');
|
||||||
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
|
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
|
||||||
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
|
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
|
||||||
@@ -43,6 +42,11 @@ before('Vega wallet teardown prep', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
cy.wrap(this.stakingBridgeContract).as('stakingBridgeContract');
|
||||||
|
cy.wrap(this.vestingContract).as('vestingContract');
|
||||||
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('deposit_asset', function (assetEthAddress) {
|
Cypress.Commands.add('deposit_asset', function (assetEthAddress) {
|
||||||
cy.get('@signer', { log: false }).then((signer) => {
|
cy.get('@signer', { log: false }).then((signer) => {
|
||||||
// Approve asset
|
// Approve asset
|
||||||
@@ -91,29 +95,18 @@ Cypress.Commands.add('faucet_asset', function (assetEthAddress) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('vega_wallet_teardown', function () {
|
Cypress.Commands.add('vega_wallet_teardown', function () {
|
||||||
cy.get(vegaWalletContainer).within(() => {
|
cy.get('body').then(($body) => {
|
||||||
cy.get(vegaWalletAssociatedBalance)
|
if ($body.find('[data-testid="eth-wallet-associated-balances"]').length) {
|
||||||
.first()
|
|
||||||
.invoke('text')
|
|
||||||
.then((balance) => {
|
|
||||||
if (balance != '0.00') {
|
|
||||||
cy.vega_wallet_teardown_vesting(this.vestingContract);
|
cy.vega_wallet_teardown_vesting(this.vestingContract);
|
||||||
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
|
cy.vega_wallet_teardown_staking(this.stakingBridgeContract);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.get('[data-testid="associated-amount"]', { timeout: 30000 }).should(
|
cy.get('[data-testid="associated-amount"]', { timeout: 30000 }).should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'0.00'
|
'0.00'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get(vegaWalletContainer).within(() => {
|
|
||||||
cy.get(vegaWalletAssociatedBalance, { timeout: transactionTimeout }).should(
|
|
||||||
'contain',
|
|
||||||
'0.00',
|
|
||||||
{ timeout: transactionTimeout }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add(
|
Cypress.Commands.add(
|
||||||
@@ -176,6 +169,22 @@ Cypress.Commands.add('vega_wallet_teardown_vesting', (vestingContract) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('vega_wallet_associate', (amount) => {
|
||||||
|
amount = amount + '0'.repeat(18);
|
||||||
|
cy.highlight('Associating tokens');
|
||||||
|
cy.get('@stakingBridgeContract').then((stakingBridgeContract) => {
|
||||||
|
stakingBridgeContract.stake(amount, vegaWalletPubKey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('vega_wallet_disassociate', (amount) => {
|
||||||
|
amount = amount + '0'.repeat(18);
|
||||||
|
cy.highlight('Disassociating tokens');
|
||||||
|
cy.get('@stakingBridgeContract').then((stakingBridgeContract) => {
|
||||||
|
stakingBridgeContract.remove_stake(amount, vegaWalletPubKey);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('wait_for_transaction', (tx) => {
|
Cypress.Commands.add('wait_for_transaction', (tx) => {
|
||||||
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
|
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_ENV=TESTNET
|
NX_VEGA_ENV=TESTNET
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||||
NX_VEGA_URL=https://api.n10.testnet.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n08.testnet.vega.xyz/graphql
|
||||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
|||||||
@@ -12,5 +12,10 @@ export default {
|
|||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^d3-(.*)$': `d3-$1/dist/d3-$1`,
|
'^d3-(.*)$': `d3-$1/dist/d3-$1`,
|
||||||
},
|
},
|
||||||
collectCoverageFrom: ['**/*.{ts,tsx}', '!**/node_modules/**'],
|
collectCoverageFrom: [
|
||||||
|
'**/*.{ts,tsx}',
|
||||||
|
'!**/node_modules/**',
|
||||||
|
'!**/__generated__/**',
|
||||||
|
'!**/__generated___/**',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { AppLoader } from './app-loader';
|
|||||||
import { NetworkInfo } from '@vegaprotocol/network-info';
|
import { NetworkInfo } from '@vegaprotocol/network-info';
|
||||||
import { BalanceManager } from './components/balance-manager';
|
import { BalanceManager } from './components/balance-manager';
|
||||||
import { EthWallet } from './components/eth-wallet';
|
import { EthWallet } from './components/eth-wallet';
|
||||||
|
import { AppLayout } from './components/page-templates/app-layout';
|
||||||
import { TemplateSidebar } from './components/page-templates/template-sidebar';
|
import { TemplateSidebar } from './components/page-templates/template-sidebar';
|
||||||
import { TransactionModal } from './components/transactions-modal';
|
import { TransactionModal } from './components/transactions-modal';
|
||||||
import { VegaWallet } from './components/vega-wallet';
|
import { VegaWallet } from './components/vega-wallet';
|
||||||
@@ -88,14 +89,14 @@ const Web3Container = ({
|
|||||||
<AppLoader>
|
<AppLoader>
|
||||||
<BalanceManager>
|
<BalanceManager>
|
||||||
<>
|
<>
|
||||||
<div className="app w-full max-w-[1500px] mx-auto grid grid-rows-[min-content_min-content_1fr_min-content] min-h-full border-neutral-700 lg:border-l lg:border-r lg:text-body-large">
|
<AppLayout>
|
||||||
<TemplateSidebar sidebar={sideBar}>
|
<TemplateSidebar sidebar={sideBar}>
|
||||||
<AppRouter />
|
<AppRouter />
|
||||||
</TemplateSidebar>
|
</TemplateSidebar>
|
||||||
<footer className="p-4 border-t border-neutral-700">
|
<footer className="p-4 border-t border-neutral-700">
|
||||||
<NetworkInfo />
|
<NetworkInfo />
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</AppLayout>
|
||||||
<VegaWalletDialogs />
|
<VegaWalletDialogs />
|
||||||
<TransactionModal />
|
<TransactionModal />
|
||||||
<WithdrawalDialog />
|
<WithdrawalDialog />
|
||||||
|
|||||||
@@ -2,20 +2,24 @@ import * as Sentry from '@sentry/react';
|
|||||||
import { toBigNum } from '@vegaprotocol/react-helpers';
|
import { toBigNum } from '@vegaprotocol/react-helpers';
|
||||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import React from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useAppState } from '../../contexts/app-state/app-state-context';
|
import { useAppState } from '../../contexts/app-state/app-state-context';
|
||||||
import { useContracts } from '../../contexts/contracts/contracts-context';
|
import { useContracts } from '../../contexts/contracts/contracts-context';
|
||||||
import { useGetAssociationBreakdown } from '../../hooks/use-get-association-breakdown';
|
import { useGetAssociationBreakdown } from '../../hooks/use-get-association-breakdown';
|
||||||
import { useGetUserTrancheBalances } from '../../hooks/use-get-user-tranche-balances';
|
import { useGetUserTrancheBalances } from '../../hooks/use-get-user-tranche-balances';
|
||||||
import { useBalances } from '../../lib/balances/balances-store';
|
import { useBalances } from '../../lib/balances/balances-store';
|
||||||
|
import type { ReactElement } from 'react';
|
||||||
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
import { useListenForStakingEvents as useListenForAssociationEvents } from '../../hooks/use-listen-for-staking-events';
|
||||||
|
|
||||||
interface BalanceManagerProps {
|
interface BalanceManagerProps {
|
||||||
children: React.ReactElement;
|
children: ReactElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
||||||
const contracts = useContracts();
|
const contracts = useContracts();
|
||||||
|
const { pubKey } = useVegaWallet();
|
||||||
const { account } = useWeb3React();
|
const { account } = useWeb3React();
|
||||||
const {
|
const {
|
||||||
appState: { decimals },
|
appState: { decimals },
|
||||||
@@ -23,6 +27,20 @@ export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
|||||||
const { updateBalances: updateStoreBalances } = useBalances();
|
const { updateBalances: updateStoreBalances } = useBalances();
|
||||||
const { config } = useEthereumConfig();
|
const { config } = useEthereumConfig();
|
||||||
|
|
||||||
|
const numberOfConfirmations = config?.confirmations || 0;
|
||||||
|
|
||||||
|
useListenForAssociationEvents(
|
||||||
|
contracts?.staking.contract,
|
||||||
|
pubKey,
|
||||||
|
numberOfConfirmations
|
||||||
|
);
|
||||||
|
|
||||||
|
useListenForAssociationEvents(
|
||||||
|
contracts?.vesting.contract,
|
||||||
|
pubKey,
|
||||||
|
numberOfConfirmations
|
||||||
|
);
|
||||||
|
|
||||||
const getUserTrancheBalances = useGetUserTrancheBalances(
|
const getUserTrancheBalances = useGetUserTrancheBalances(
|
||||||
account || '',
|
account || '',
|
||||||
contracts?.vesting
|
contracts?.vesting
|
||||||
@@ -34,7 +52,7 @@ export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// update balances on connect to Ethereum
|
// update balances on connect to Ethereum
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
const updateBalances = async () => {
|
const updateBalances = async () => {
|
||||||
if (!account || !config) return;
|
if (!account || !config) return;
|
||||||
try {
|
try {
|
||||||
@@ -75,13 +93,13 @@ export const BalanceManager = ({ children }: BalanceManagerProps) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// This use effect hook is very expensive and is kept separate to prevent expensive reloading of data.
|
// This use effect hook is very expensive and is kept separate to prevent expensive reloading of data.
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (account) {
|
if (account) {
|
||||||
getUserTrancheBalances();
|
getUserTrancheBalances();
|
||||||
}
|
}
|
||||||
}, [account, getUserTrancheBalances]);
|
}, [account, getUserTrancheBalances]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (account) {
|
if (account) {
|
||||||
getAssociationBreakdown();
|
getAssociationBreakdown();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ export const LockedProgress = ({
|
|||||||
unlocked,
|
unlocked,
|
||||||
leftLabel,
|
leftLabel,
|
||||||
rightLabel,
|
rightLabel,
|
||||||
leftColor = Colors.vega.pink,
|
leftColor = Colors.vega.pink.DEFAULT,
|
||||||
rightColor = Colors.vega.green,
|
rightColor = Colors.vega.green.DEFAULT,
|
||||||
decimals = 2,
|
decimals = 2,
|
||||||
}: LockedProgressProps) => {
|
}: LockedProgressProps) => {
|
||||||
const lockedPercentage = React.useMemo(() => {
|
const lockedPercentage = React.useMemo(() => {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const NavDropDown = ({ navbarTheme }: { navbarTheme: NavbarTheme }) => {
|
|||||||
<AppNavLink
|
<AppNavLink
|
||||||
name={
|
name={
|
||||||
<NavDropdownMenuTrigger
|
<NavDropdownMenuTrigger
|
||||||
className="w-auto text-capMenu"
|
className="w-auto flex items-center"
|
||||||
data-testid="state-trigger"
|
data-testid="state-trigger"
|
||||||
onClick={() => setOpen(!isOpen)}
|
onClick={() => setOpen(!isOpen)}
|
||||||
>
|
>
|
||||||
@@ -38,6 +38,7 @@ export const NavDropDown = ({ navbarTheme }: { navbarTheme: NavbarTheme }) => {
|
|||||||
name={t(r.name)}
|
name={t(r.name)}
|
||||||
path={r.path}
|
path={r.path}
|
||||||
navbarTheme={'inherit'}
|
navbarTheme={'inherit'}
|
||||||
|
subNav={true}
|
||||||
end={true}
|
end={true}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ interface AppNavLinkProps {
|
|||||||
target?: HTMLAttributeAnchorTarget;
|
target?: HTMLAttributeAnchorTarget;
|
||||||
end?: boolean;
|
end?: boolean;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
|
subNav?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AppNavLink = ({
|
export const AppNavLink = ({
|
||||||
@@ -23,28 +24,32 @@ export const AppNavLink = ({
|
|||||||
testId,
|
testId,
|
||||||
end = false,
|
end = false,
|
||||||
fullWidth = false,
|
fullWidth = false,
|
||||||
|
subNav = false,
|
||||||
}: AppNavLinkProps) => {
|
}: AppNavLinkProps) => {
|
||||||
const borderClasses = classNames('absolute h-1 w-full bottom-[-1px] left-0', {
|
const borderClasses = classNames(
|
||||||
|
'absolute h-0.5 w-full bottom-[-1px] left-0',
|
||||||
|
{
|
||||||
'bg-black dark:bg-vega-yellow': navbarTheme !== 'yellow',
|
'bg-black dark:bg-vega-yellow': navbarTheme !== 'yellow',
|
||||||
'bg-black': navbarTheme === 'yellow',
|
'bg-black': navbarTheme === 'yellow',
|
||||||
});
|
}
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<NavLink
|
<NavLink
|
||||||
key={path}
|
key={path}
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
to={{ pathname: path }}
|
to={{ pathname: path }}
|
||||||
className={getNavLinkClassNames(navbarTheme, fullWidth)}
|
className={getNavLinkClassNames(navbarTheme, fullWidth, subNav)}
|
||||||
target={target}
|
target={target}
|
||||||
end={end}
|
end={end}
|
||||||
>
|
>
|
||||||
{({ isActive }) => {
|
{({ isActive }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={subNav ? 'inline-block relative pb-1' : undefined}>
|
||||||
{name}
|
{name}
|
||||||
{isActive && (
|
{isActive && (
|
||||||
<span data-testid="link-active" className={borderClasses} />
|
<span data-testid="link-active" className={borderClasses} />
|
||||||
)}
|
)}
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ const renderComponent = (initialEntries?: string[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
describe('nav', () => {
|
describe('nav', () => {
|
||||||
it('Renders title and logo with link to home', () => {
|
it('Renders logo with link to home', () => {
|
||||||
renderComponent();
|
renderComponent();
|
||||||
expect(screen.getByText('Governance')).toBeInTheDocument();
|
|
||||||
expect(screen.getByTestId('logo-link')).toHaveProperty(
|
expect(screen.getByTestId('logo-link')).toHaveProperty(
|
||||||
'href',
|
'href',
|
||||||
'http://localhost/'
|
'http://localhost/'
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { NetworkSwitcher } from '@vegaprotocol/environment';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { TOP_LEVEL_ROUTES } from '../../routes/routes';
|
import { TOP_LEVEL_ROUTES } from '../../routes/routes';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import vegaWhite from '../../images/vega_white.png';
|
import logoWhiteText from '../../images/logo-white-text.png';
|
||||||
|
import logoBlackText from '../../images/logo-black-text.png';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { NavDrawer } from './nav-draw';
|
import { NavDrawer } from './nav-draw';
|
||||||
import { Nav as ToolkitNav } from '@vegaprotocol/ui-toolkit';
|
import { Nav as ToolkitNav } from '@vegaprotocol/ui-toolkit';
|
||||||
@@ -46,14 +47,19 @@ export const Nav = ({ navbarTheme = 'inherit' }: NavbarProps) => {
|
|||||||
navbarTheme={navbarTheme}
|
navbarTheme={navbarTheme}
|
||||||
icon={
|
icon={
|
||||||
<Link to="/" data-testid="logo-link">
|
<Link to="/" data-testid="logo-link">
|
||||||
<img alt="Vega" src={vegaWhite} height={30} width={30} />
|
<img
|
||||||
|
alt="Vega"
|
||||||
|
src={navbarTheme === 'yellow' ? logoBlackText : logoWhiteText}
|
||||||
|
height={30}
|
||||||
|
width={250}
|
||||||
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
title={t('Governance')}
|
title={undefined}
|
||||||
titleContent={<NetworkSwitcher />}
|
titleContent={<NetworkSwitcher />}
|
||||||
>
|
>
|
||||||
{isDesktop ? (
|
{isDesktop ? (
|
||||||
<nav className="flex items-center flex-1 px-2">
|
<nav className="flex items-center flex-1 px-4">
|
||||||
{TOP_LEVEL_ROUTES.map((r) => (
|
{TOP_LEVEL_ROUTES.map((r) => (
|
||||||
<AppNavLink
|
<AppNavLink
|
||||||
key={r.path}
|
key={r.path}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import classNames from 'classnames';
|
||||||
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
interface AppLayoutProps {
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
export const AppLayout = ({ children }: AppLayoutProps) => {
|
||||||
|
const { isReadOnly } = useVegaWallet();
|
||||||
|
const AppLayoutClasses = classNames(
|
||||||
|
'app w-full max-w-[1500px] mx-auto grid min-h-full',
|
||||||
|
'border-neutral-700 lg:border-l lg:border-r',
|
||||||
|
'lg:text-body-large',
|
||||||
|
{
|
||||||
|
'grid-rows-[repeat(2,min-content)_1fr_min-content]': !isReadOnly,
|
||||||
|
'grid-rows-[repeat(3,min-content)_1fr_min-content]': isReadOnly,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return <div className={AppLayoutClasses}>{children}</div>;
|
||||||
|
};
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit';
|
import {
|
||||||
|
ViewingAsBanner,
|
||||||
|
AnnouncementBanner,
|
||||||
|
ExternalLink,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
@@ -15,12 +19,18 @@ export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
|
|||||||
const { isReadOnly, pubKey, disconnect } = useVegaWallet();
|
const { isReadOnly, pubKey, disconnect } = useVegaWallet();
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<AnnouncementBanner>
|
||||||
|
<div className="font-alpha calt uppercase text-center text-lg text-white">
|
||||||
|
<span className="pr-4">The Mainnet sims are live!</span>
|
||||||
|
<ExternalLink href="https://fairground.wtf/">
|
||||||
|
Come help stress test the network
|
||||||
|
</ExternalLink>
|
||||||
|
</div>
|
||||||
|
</AnnouncementBanner>
|
||||||
<Nav navbarTheme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'} />
|
<Nav navbarTheme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'} />
|
||||||
{isReadOnly ? (
|
{isReadOnly ? (
|
||||||
<ViewingAsBanner pubKey={pubKey} disconnect={disconnect} />
|
<ViewingAsBanner pubKey={pubKey} disconnect={disconnect} />
|
||||||
) : (
|
) : null}
|
||||||
<div />
|
|
||||||
)}
|
|
||||||
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[1fr] lg:grid-cols-[1fr_450px]">
|
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[1fr] lg:grid-cols-[1fr_450px]">
|
||||||
<main className="col-start-1 p-4">{children}</main>
|
<main className="col-start-1 p-4">{children}</main>
|
||||||
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import { usePollForDelegations } from './hooks';
|
|||||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||||
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import { toBigNum } from '@vegaprotocol/react-helpers';
|
import { toBigNum } from '@vegaprotocol/react-helpers';
|
||||||
|
import { usePendingBalancesStore } from '../../hooks/use-pending-balances-manager';
|
||||||
|
import { StakingEventType } from '../../hooks/use-get-association-breakdown';
|
||||||
|
|
||||||
export const VegaWallet = () => {
|
export const VegaWallet = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -119,6 +121,10 @@ interface VegaWalletConnectedProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
||||||
|
const pendingBalances = usePendingBalancesStore(
|
||||||
|
(state) => state.pendingBalances
|
||||||
|
);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const {
|
const {
|
||||||
appDispatch,
|
appDispatch,
|
||||||
@@ -126,6 +132,27 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
|||||||
} = useAppState();
|
} = useAppState();
|
||||||
const { delegations, currentStakeAvailable, delegatedNodes, accounts } =
|
const { delegations, currentStakeAvailable, delegatedNodes, accounts } =
|
||||||
usePollForDelegations();
|
usePollForDelegations();
|
||||||
|
const amountRemoved = BigNumber.sum.apply(null, [
|
||||||
|
new BigNumber(0),
|
||||||
|
...pendingBalances
|
||||||
|
.filter(({ event }) => event === StakingEventType.Stake_Removed)
|
||||||
|
.map(({ args }) => toBigNum(args?.[1].toString(), decimals)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const amountAdded = BigNumber.sum.apply(null, [
|
||||||
|
new BigNumber(0),
|
||||||
|
...pendingBalances
|
||||||
|
.filter(({ event }) => event === StakingEventType.Stake_Deposited)
|
||||||
|
.map(({ args }) => toBigNum(args?.[1].toString(), decimals)),
|
||||||
|
]);
|
||||||
|
const totalPending = React.useMemo(
|
||||||
|
() => amountRemoved.plus(amountAdded),
|
||||||
|
[amountAdded, amountRemoved]
|
||||||
|
);
|
||||||
|
const pendingStakeAmount = React.useMemo(
|
||||||
|
() => currentStakeAvailable.plus(amountAdded).minus(amountRemoved),
|
||||||
|
[amountAdded, amountRemoved, currentStakeAvailable]
|
||||||
|
);
|
||||||
|
|
||||||
const unstaked = React.useMemo(() => {
|
const unstaked = React.useMemo(() => {
|
||||||
const totalDelegated = delegations.reduce<BigNumber>(
|
const totalDelegated = delegations.reduce<BigNumber>(
|
||||||
@@ -161,6 +188,26 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
|
|||||||
symbol="VEGA"
|
symbol="VEGA"
|
||||||
balance={currentStakeAvailable}
|
balance={currentStakeAvailable}
|
||||||
/>
|
/>
|
||||||
|
{totalPending.eq(0) ? null : (
|
||||||
|
<>
|
||||||
|
<WalletCardAsset
|
||||||
|
image={vegaWhite}
|
||||||
|
decimals={decimals}
|
||||||
|
name="VEGA"
|
||||||
|
subheading={t('Pending association')}
|
||||||
|
symbol="VEGA"
|
||||||
|
balance={totalPending}
|
||||||
|
/>
|
||||||
|
<WalletCardAsset
|
||||||
|
image={vegaWhite}
|
||||||
|
decimals={decimals}
|
||||||
|
name="VEGA"
|
||||||
|
subheading={t('Total associated after pending')}
|
||||||
|
symbol="VEGA"
|
||||||
|
balance={pendingStakeAmount}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div data-testid="vega-wallet-balance-unstaked">
|
<div data-testid="vega-wallet-balance-unstaked">
|
||||||
<WalletCardRow label={t('unstaked')} value={unstaked} />
|
<WalletCardRow label={t('unstaked')} value={unstaked} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -30,9 +30,12 @@ export function useAnimateValue(
|
|||||||
) {
|
) {
|
||||||
elRef.current?.animate(
|
elRef.current?.animate(
|
||||||
[
|
[
|
||||||
{ backgroundColor: customColors.vega.pink, color: colors.white },
|
|
||||||
{
|
{
|
||||||
backgroundColor: customColors.vega.pink,
|
backgroundColor: customColors.vega.pink.DEFAULT,
|
||||||
|
color: colors.white,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
backgroundColor: customColors.vega.pink.DEFAULT,
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
offset: 0.8,
|
offset: 0.8,
|
||||||
},
|
},
|
||||||
@@ -53,11 +56,11 @@ export function useAnimateValue(
|
|||||||
elRef.current?.animate(
|
elRef.current?.animate(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
backgroundColor: customColors.vega.green,
|
backgroundColor: customColors.vega.green.DEFAULT,
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
backgroundColor: customColors.vega.green,
|
backgroundColor: customColors.vega.green.DEFAULT,
|
||||||
color: colors.white,
|
color: colors.white,
|
||||||
offset: 0.8,
|
offset: 0.8,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import { useAppState } from '../contexts/app-state/app-state-context';
|
|||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { useBalances } from '../lib/balances/balances-store';
|
import { useBalances } from '../lib/balances/balances-store';
|
||||||
|
|
||||||
|
export enum StakingEventType {
|
||||||
|
Stake_Removed = 'Stake_Removed',
|
||||||
|
Stake_Deposited = 'Stake_Deposited',
|
||||||
|
}
|
||||||
|
|
||||||
export function useGetAssociationBreakdown(
|
export function useGetAssociationBreakdown(
|
||||||
ethAddress: string,
|
ethAddress: string,
|
||||||
staking: StakingBridge,
|
staking: StakingBridge,
|
||||||
@@ -63,8 +68,8 @@ function combineStakeEventsByVegaKey(
|
|||||||
const res = events.reduce((obj, e) => {
|
const res = events.reduce((obj, e) => {
|
||||||
const vegaKey = e.args?.vega_public_key;
|
const vegaKey = e.args?.vega_public_key;
|
||||||
const amount = parseEventAmount(e, decimals);
|
const amount = parseEventAmount(e, decimals);
|
||||||
const isDeposit = e.event === 'Stake_Deposited';
|
const isDeposit = e.event === StakingEventType.Stake_Deposited;
|
||||||
const isRemove = e.event === 'Stake_Removed';
|
const isRemove = e.event === StakingEventType.Stake_Removed;
|
||||||
|
|
||||||
if (!isDeposit && !isRemove) return obj;
|
if (!isDeposit && !isRemove) return obj;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import { useListenForPendingEthEvents } from './use-listen-for-pending-eth-events';
|
||||||
|
import { renderHook, cleanup, waitFor } from '@testing-library/react';
|
||||||
|
import type { Contract, EventFilter, Event } from 'ethers';
|
||||||
|
|
||||||
|
let contract: Contract;
|
||||||
|
let filter: EventFilter;
|
||||||
|
let addPendingTxs: (event: Event[]) => void;
|
||||||
|
let removePendingTx: (event: Event) => void;
|
||||||
|
let resetPendingTxs: () => void;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
contract = {
|
||||||
|
on: jest.fn(),
|
||||||
|
off: jest.fn(),
|
||||||
|
queryFilter: jest.fn().mockResolvedValue([]),
|
||||||
|
} as unknown as Contract;
|
||||||
|
filter = {} as EventFilter;
|
||||||
|
addPendingTxs = jest.fn();
|
||||||
|
removePendingTx = jest.fn();
|
||||||
|
resetPendingTxs = jest.fn();
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.mock('@web3-react/core', () => ({
|
||||||
|
useWeb3React: () => ({
|
||||||
|
provider: {
|
||||||
|
getBlockNumber: jest.fn().mockResolvedValue(1),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('useListenForPendingEthEvents', () => {
|
||||||
|
it('listens for events on contract', async () => {
|
||||||
|
renderHook(() =>
|
||||||
|
useListenForPendingEthEvents(
|
||||||
|
1,
|
||||||
|
contract,
|
||||||
|
filter,
|
||||||
|
addPendingTxs,
|
||||||
|
removePendingTx,
|
||||||
|
resetPendingTxs
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(contract.on).toHaveBeenCalledWith(filter, expect.any(Function));
|
||||||
|
cleanup();
|
||||||
|
expect(contract.off).toHaveBeenCalledWith(filter, expect.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('waits for correct number of confirmations before removing tx from pending txs', async () => {
|
||||||
|
renderHook(() => {
|
||||||
|
useListenForPendingEthEvents(
|
||||||
|
2,
|
||||||
|
contract,
|
||||||
|
filter,
|
||||||
|
addPendingTxs,
|
||||||
|
removePendingTx,
|
||||||
|
resetPendingTxs
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const listener = (contract.on as jest.Mock).mock.calls[0][1];
|
||||||
|
const event = {
|
||||||
|
getTransaction: jest.fn().mockResolvedValue({
|
||||||
|
wait: jest.fn().mockResolvedValue({}),
|
||||||
|
}),
|
||||||
|
} as unknown as Event;
|
||||||
|
listener(null, null, null, event);
|
||||||
|
|
||||||
|
expect(addPendingTxs).toHaveBeenCalledWith([event]);
|
||||||
|
expect(removePendingTx).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(removePendingTx).toHaveBeenCalledWith(event);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets existing transactions', async () => {
|
||||||
|
const event = {
|
||||||
|
getTransaction: jest.fn().mockResolvedValue({
|
||||||
|
wait: jest.fn().mockResolvedValue(null),
|
||||||
|
}),
|
||||||
|
} as unknown as Event;
|
||||||
|
|
||||||
|
contract.queryFilter = jest.fn().mockResolvedValue([event]);
|
||||||
|
|
||||||
|
renderHook(() => {
|
||||||
|
useListenForPendingEthEvents(
|
||||||
|
2,
|
||||||
|
contract,
|
||||||
|
filter,
|
||||||
|
addPendingTxs,
|
||||||
|
removePendingTx,
|
||||||
|
resetPendingTxs
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(contract.queryFilter).toHaveBeenCalledWith(filter, -1);
|
||||||
|
expect(addPendingTxs).toHaveBeenCalledWith([event]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { useWeb3React } from '@web3-react/core';
|
||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import * as Sentry from '@sentry/react';
|
||||||
|
import type { Contract, Event, EventFilter } from 'ethers';
|
||||||
|
|
||||||
|
export const useListenForPendingEthEvents = (
|
||||||
|
numberOfConfirmations: number,
|
||||||
|
contract: Contract | undefined,
|
||||||
|
filter: EventFilter | null,
|
||||||
|
addPendingTxs: (event: Event[]) => void,
|
||||||
|
removePendingTx: (event: Event) => void,
|
||||||
|
resetPendingTxs: () => void
|
||||||
|
) => {
|
||||||
|
const { provider } = useWeb3React();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add listener for the ethereum events on the contract passed in for the filter passed in.
|
||||||
|
* Push the event into the store and wait for the correct number of confirmations before removing it.
|
||||||
|
*/
|
||||||
|
useEffect(() => {
|
||||||
|
if (!contract || !filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const listener = async (...args: any[]) => {
|
||||||
|
try {
|
||||||
|
const event = args[3] as Event;
|
||||||
|
addPendingTxs([event]);
|
||||||
|
const tx = await event.getTransaction();
|
||||||
|
await tx.wait(numberOfConfirmations);
|
||||||
|
removePendingTx(event);
|
||||||
|
} catch (e) {
|
||||||
|
Sentry.captureException(`Error listening for pending eth events ${e}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
contract.on(filter, listener);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
contract.off(filter, listener);
|
||||||
|
};
|
||||||
|
}, [addPendingTxs, contract, filter, numberOfConfirmations, removePendingTx]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all transactions that exist on the blockchain but have yet to reach the number of confirmations
|
||||||
|
*/
|
||||||
|
const getExistingTransactions = useCallback(async () => {
|
||||||
|
const blockNumber = (await provider?.getBlockNumber()) || 0;
|
||||||
|
if (!filter || !contract) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return await contract.queryFilter(
|
||||||
|
filter,
|
||||||
|
blockNumber - numberOfConfirmations
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Sentry.captureException(`Error getting existing transactions ${e}`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}, [contract, filter, numberOfConfirmations, provider]);
|
||||||
|
|
||||||
|
const waitForExistingTransactions = useCallback(
|
||||||
|
(events: Event[], numberOfConfirmations: number) => {
|
||||||
|
events.map(async (event) => {
|
||||||
|
try {
|
||||||
|
const tx = await event.getTransaction();
|
||||||
|
|
||||||
|
await tx.wait(Math.max(numberOfConfirmations, 0));
|
||||||
|
|
||||||
|
removePendingTx(event);
|
||||||
|
} catch (e) {
|
||||||
|
Sentry.captureException(
|
||||||
|
`Error waiting for existing transactions ${e}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[removePendingTx]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
resetPendingTxs();
|
||||||
|
getExistingTransactions().then((events) => {
|
||||||
|
if (!cancelled) {
|
||||||
|
addPendingTxs([...events]);
|
||||||
|
waitForExistingTransactions([...events], numberOfConfirmations);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [
|
||||||
|
addPendingTxs,
|
||||||
|
getExistingTransactions,
|
||||||
|
numberOfConfirmations,
|
||||||
|
resetPendingTxs,
|
||||||
|
waitForExistingTransactions,
|
||||||
|
]);
|
||||||
|
};
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import { usePendingBalancesStore } from './use-pending-balances-manager';
|
||||||
|
import type { Contract } from 'ethers';
|
||||||
|
import { useListenForPendingEthEvents } from './use-listen-for-pending-eth-events';
|
||||||
|
import { prepend0x } from '@vegaprotocol/smart-contracts';
|
||||||
|
|
||||||
|
export const useListenForStakingEvents = (
|
||||||
|
contract: Contract | undefined,
|
||||||
|
vegaPublicKey: string | null,
|
||||||
|
numberOfConfirmations: number
|
||||||
|
) => {
|
||||||
|
const { addPendingTxs, removePendingTx, resetPendingTxs } =
|
||||||
|
usePendingBalancesStore((state) => ({
|
||||||
|
addPendingTxs: state.addPendingTxs,
|
||||||
|
removePendingTx: state.removePendingTx,
|
||||||
|
resetPendingTxs: state.resetPendingTxs,
|
||||||
|
}));
|
||||||
|
const addFilter = useMemo(
|
||||||
|
() =>
|
||||||
|
vegaPublicKey && contract
|
||||||
|
? contract.filters.Stake_Deposited(null, null, prepend0x(vegaPublicKey))
|
||||||
|
: null,
|
||||||
|
[contract, vegaPublicKey]
|
||||||
|
);
|
||||||
|
const removeFilter = useMemo(
|
||||||
|
() =>
|
||||||
|
vegaPublicKey && contract
|
||||||
|
? contract.filters.Stake_Removed(null, null, prepend0x(vegaPublicKey))
|
||||||
|
: null,
|
||||||
|
[contract, vegaPublicKey]
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for all add stake events
|
||||||
|
*/
|
||||||
|
useListenForPendingEthEvents(
|
||||||
|
numberOfConfirmations,
|
||||||
|
contract,
|
||||||
|
addFilter,
|
||||||
|
addPendingTxs,
|
||||||
|
removePendingTx,
|
||||||
|
resetPendingTxs
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for all remove stake events
|
||||||
|
*/
|
||||||
|
useListenForPendingEthEvents(
|
||||||
|
numberOfConfirmations,
|
||||||
|
contract,
|
||||||
|
removeFilter,
|
||||||
|
addPendingTxs,
|
||||||
|
removePendingTx,
|
||||||
|
resetPendingTxs
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { act } from '@testing-library/react-hooks';
|
||||||
|
import { usePendingBalancesStore } from './use-pending-balances-manager';
|
||||||
|
import type { Event } from 'ethers';
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
usePendingBalancesStore.setState((state) => ({
|
||||||
|
...state,
|
||||||
|
pendingBalances: [],
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
const event1 = { transactionHash: 'tx1' } as Event;
|
||||||
|
const event2 = { transactionHash: 'tx2' } as Event;
|
||||||
|
|
||||||
|
describe('usePendingBalancesStore', () => {
|
||||||
|
it('should add new events to the pendingBalances state and remove duplicates', () => {
|
||||||
|
const { addPendingTxs } = usePendingBalancesStore.getState();
|
||||||
|
const duplicateEvent = { transactionHash: 'tx1' } as Event;
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
addPendingTxs([event1, duplicateEvent]);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([
|
||||||
|
event1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
addPendingTxs([event2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([
|
||||||
|
event1,
|
||||||
|
event2,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove a specific event from the pendingBalances state', () => {
|
||||||
|
const { addPendingTxs, removePendingTx } =
|
||||||
|
usePendingBalancesStore.getState();
|
||||||
|
const eventToRemove = { transactionHash: 'tx1' } as Event;
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
addPendingTxs([eventToRemove, event2]);
|
||||||
|
});
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([
|
||||||
|
eventToRemove,
|
||||||
|
event2,
|
||||||
|
]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
removePendingTx(eventToRemove);
|
||||||
|
});
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([
|
||||||
|
event2,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset the pendingBalances state', () => {
|
||||||
|
const { addPendingTxs, resetPendingTxs } =
|
||||||
|
usePendingBalancesStore.getState();
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
addPendingTxs([event1, event2]);
|
||||||
|
});
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([
|
||||||
|
event1,
|
||||||
|
event2,
|
||||||
|
]);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
resetPendingTxs();
|
||||||
|
});
|
||||||
|
expect(usePendingBalancesStore.getState().pendingBalances).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import type { Event } from 'ethers';
|
||||||
|
import uniqBy from 'lodash/uniqBy';
|
||||||
|
|
||||||
|
import create from 'zustand';
|
||||||
|
|
||||||
|
export type PendingTxsStore = {
|
||||||
|
pendingBalances: Event[];
|
||||||
|
addPendingTxs: (event: Event[]) => void;
|
||||||
|
removePendingTx: (event: Event) => void;
|
||||||
|
resetPendingTxs: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const usePendingBalancesStore = create<PendingTxsStore>((set, get) => ({
|
||||||
|
pendingBalances: [],
|
||||||
|
addPendingTxs: (event: Event[]) => {
|
||||||
|
set({
|
||||||
|
pendingBalances: uniqBy(
|
||||||
|
[...get().pendingBalances, ...event],
|
||||||
|
'transactionHash'
|
||||||
|
),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removePendingTx: (event: Event) => {
|
||||||
|
set({
|
||||||
|
pendingBalances: [
|
||||||
|
...get().pendingBalances.filter(
|
||||||
|
({ transactionHash }) => transactionHash !== event.transactionHash
|
||||||
|
),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetPendingTxs: () => {
|
||||||
|
set({ pendingBalances: [] });
|
||||||
|
},
|
||||||
|
}));
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
+1
-1
@@ -15,7 +15,7 @@ export const ProposalFormTransactionDialog = ({
|
|||||||
finalizedProposal,
|
finalizedProposal,
|
||||||
TransactionDialog,
|
TransactionDialog,
|
||||||
}: ProposalFormTransactionDialogProps) => {
|
}: ProposalFormTransactionDialogProps) => {
|
||||||
// Render a custom complete UI if the proposal was rejected other wise
|
// Render a custom complete UI if the proposal was rejected otherwise
|
||||||
// pass undefined so that the default vega transaction dialog UI gets used
|
// pass undefined so that the default vega transaction dialog UI gets used
|
||||||
const completeContent = finalizedProposal?.rejectionReason ? (
|
const completeContent = finalizedProposal?.rejectionReason ? (
|
||||||
<p>{finalizedProposal.rejectionReason}</p>
|
<p>{finalizedProposal.rejectionReason}</p>
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export const VoteDetails = ({
|
|||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
<section>
|
<section data-testid="votes-table">
|
||||||
<SubHeading title={t('tokenVotes')} />
|
<SubHeading title={t('tokenVotes')} />
|
||||||
<p>
|
<p>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -90,23 +90,16 @@ describe('Raw proposal form', () => {
|
|||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
data: {
|
data: {
|
||||||
busEvents: [
|
proposals: {
|
||||||
{
|
|
||||||
__typename: 'BusEvent',
|
|
||||||
type: Schema.BusEventType.Proposal,
|
|
||||||
event: {
|
|
||||||
__typename: 'Proposal',
|
__typename: 'Proposal',
|
||||||
id: '2fca514cebf9f465ae31ecb4c5721e3a6f5f260425ded887ca50ba15b81a5d50',
|
id: '2fca514cebf9f465ae31ecb4c5721e3a6f5f260425ded887ca50ba15b81a5d50',
|
||||||
reference: 'proposal-reference',
|
reference: 'proposal-reference',
|
||||||
state: Schema.ProposalState.STATE_OPEN,
|
state: Schema.ProposalState.STATE_OPEN,
|
||||||
rejectionReason:
|
rejectionReason:
|
||||||
Schema.ProposalRejectionReason
|
Schema.ProposalRejectionReason.PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE,
|
||||||
.PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE,
|
|
||||||
errorDetails: 'error-details',
|
errorDetails: 'error-details',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
delay: 300,
|
delay: 300,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ interface TotalPenaltiesRendererProps {
|
|||||||
performanceScore: string;
|
performanceScore: string;
|
||||||
performancePenalty: string;
|
performancePenalty: string;
|
||||||
overstakedAmount: string;
|
overstakedAmount: string;
|
||||||
overstakedPenalty: string;
|
overstakingPenalty: string;
|
||||||
totalPenalties: string;
|
totalPenalties: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -192,20 +192,10 @@ export const TotalPenaltiesRenderer = ({
|
|||||||
description={
|
description={
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<span>
|
|
||||||
{t('performancePenalty')}: {data.performancePenalty}
|
{t('performancePenalty')}: {data.performancePenalty}
|
||||||
</span>
|
|
||||||
<span className="pl-2">
|
|
||||||
({t('score')} {data.performanceScore})
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>
|
{t('overstakedPenalty')}: {data.overstakingPenalty}
|
||||||
{t('overstakedPenalty')}: {data.overstakedPenalty}
|
|
||||||
</span>
|
|
||||||
<span className="pl-2">
|
|
||||||
({t('overstaked')} {data.overstakedAmount})
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{t('totalPenalties')}:{' '}
|
{t('totalPenalties')}:{' '}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Dialog, Icon, Intent } from '@vegaprotocol/ui-toolkit';
|
import { Dialog, Icon, Intent } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import Routes from '../../routes';
|
import Routes from '../../routes';
|
||||||
import type { StakeAction } from './staking-form';
|
import type { StakeAction } from './staking-form';
|
||||||
import { Actions, RemoveType } from './staking-form';
|
import { Actions, RemoveType } from './staking-form';
|
||||||
@@ -23,6 +23,7 @@ export const StakeSuccess = ({
|
|||||||
toggleDialog,
|
toggleDialog,
|
||||||
}: StakeSuccessProps) => {
|
}: StakeSuccessProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
const isAdd = action === Actions.Add;
|
const isAdd = action === Actions.Add;
|
||||||
const title = isAdd
|
const title = isAdd
|
||||||
? t('stakeAddSuccessTitle', { amount })
|
? t('stakeAddSuccessTitle', { amount })
|
||||||
@@ -44,7 +45,15 @@ export const StakeSuccess = ({
|
|||||||
<div>
|
<div>
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
<p>
|
<p>
|
||||||
<Link className="underline" to={Routes.VALIDATORS}>
|
<Link
|
||||||
|
className="underline"
|
||||||
|
to={Routes.VALIDATORS}
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
toggleDialog();
|
||||||
|
setTimeout(() => navigate(Routes.VALIDATORS), 0);
|
||||||
|
}}
|
||||||
|
>
|
||||||
{t('backToStaking')}
|
{t('backToStaking')}
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const TrancheProgress = ({
|
|||||||
<span className="tranches__progress-title">{t('Locked')}</span>
|
<span className="tranches__progress-title">{t('Locked')}</span>
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
width={220}
|
width={220}
|
||||||
color={Colors.vega.pink}
|
color={Colors.vega.pink.DEFAULT}
|
||||||
percentage={lockedPercentage}
|
percentage={lockedPercentage}
|
||||||
/>
|
/>
|
||||||
<span className="tranches__progress-numbers">
|
<span className="tranches__progress-numbers">
|
||||||
@@ -40,7 +40,7 @@ export const TrancheProgress = ({
|
|||||||
<span className="tranches__progress-title">{t('Redeemed')}</span>
|
<span className="tranches__progress-title">{t('Redeemed')}</span>
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
width={220}
|
width={220}
|
||||||
color={Colors.vega.green}
|
color={Colors.vega.green.DEFAULT}
|
||||||
percentage={removedPercentage}
|
percentage={removedPercentage}
|
||||||
/>
|
/>
|
||||||
<span className="tranches__progress-numbers">
|
<span className="tranches__progress-numbers">
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ export const VestingChart = () => {
|
|||||||
<AreaChart data={data}>
|
<AreaChart data={data}>
|
||||||
<defs>
|
<defs>
|
||||||
{[
|
{[
|
||||||
['pink', Colors.vega.pink],
|
['pink', Colors.vega.pink.DEFAULT],
|
||||||
['green', Colors.vega.green],
|
['green', Colors.vega.green.DEFAULT],
|
||||||
['orange', Colors.warning],
|
['orange', Colors.warning],
|
||||||
['yellow', Colors.vega.yellow],
|
['yellow', Colors.vega.yellow.DEFAULT],
|
||||||
].map(([key, color]) => (
|
].map(([key, color]) => (
|
||||||
<linearGradient key={key} id={key} x1="0" y1="0" x2="0" y2="1">
|
<linearGradient key={key} id={key} x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="0%" stopColor={color} stopOpacity={0.85} />
|
<stop offset="0%" stopColor={color} stopOpacity={0.85} />
|
||||||
@@ -97,7 +97,7 @@ export const VestingChart = () => {
|
|||||||
dot={false}
|
dot={false}
|
||||||
type="linear"
|
type="linear"
|
||||||
dataKey="team"
|
dataKey="team"
|
||||||
stroke={Colors.vega.pink}
|
stroke={Colors.vega.pink.DEFAULT}
|
||||||
fill="url(#pink)"
|
fill="url(#pink)"
|
||||||
yAxisId={0}
|
yAxisId={0}
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
@@ -109,7 +109,7 @@ export const VestingChart = () => {
|
|||||||
dot={false}
|
dot={false}
|
||||||
type="monotone"
|
type="monotone"
|
||||||
dataKey="earlyInvestors"
|
dataKey="earlyInvestors"
|
||||||
stroke={Colors.vega.green}
|
stroke={Colors.vega.green.DEFAULT}
|
||||||
fill="url(#green)"
|
fill="url(#green)"
|
||||||
yAxisId={0}
|
yAxisId={0}
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
@@ -121,7 +121,7 @@ export const VestingChart = () => {
|
|||||||
dot={false}
|
dot={false}
|
||||||
type="monotone"
|
type="monotone"
|
||||||
dataKey="publicSale"
|
dataKey="publicSale"
|
||||||
stroke={Colors.vega.yellow}
|
stroke={Colors.vega.yellow.DEFAULT}
|
||||||
fill="url(#yellow)"
|
fill="url(#yellow)"
|
||||||
yAxisId={0}
|
yAxisId={0}
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
|
|||||||
@@ -13,3 +13,9 @@
|
|||||||
@apply mb-2 text-neutral-400;
|
@apply mb-2 text-neutral-400;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.border-default {
|
||||||
|
@apply border-vega-dark-200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,15 +21,127 @@ const orderUpdatedAt = 'updatedAt';
|
|||||||
const assetSelectField = 'select[name="asset"]';
|
const assetSelectField = 'select[name="asset"]';
|
||||||
const amountField = 'input[name="amount"]';
|
const amountField = 'input[name="amount"]';
|
||||||
const txTimeout = Cypress.env('txTimeout');
|
const txTimeout = Cypress.env('txTimeout');
|
||||||
const btcName = 'BTC (local)';
|
const sepoliaUrl = Cypress.env('ETHERSCAN_URL');
|
||||||
|
const btcName =
|
||||||
|
'BTC (local)5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c - tBTC';
|
||||||
|
const vegaName =
|
||||||
|
'Vegab4f2726571fbe8e33b442dc92ed2d7f0d810e21835b7371a7915a365f07ccd9b - VEGA';
|
||||||
const btcSymbol = 'tBTC';
|
const btcSymbol = 'tBTC';
|
||||||
|
const vegaSymbol = 'VEGA';
|
||||||
const usdcSymbol = 'fUSDC';
|
const usdcSymbol = 'fUSDC';
|
||||||
const toastContent = 'toast-content';
|
const toastContent = 'toast-content';
|
||||||
const ordersTab = 'Orders';
|
const ordersTab = 'Orders';
|
||||||
const depositsTab = 'Deposits';
|
const depositsTab = 'Deposits';
|
||||||
const toastCloseBtn = 'toast-close';
|
const toastCloseBtn = 'toast-close';
|
||||||
|
const price = '390';
|
||||||
|
const size = '0.0005';
|
||||||
|
const newPrice = '200';
|
||||||
|
const completeWithdrawalBtn = 'complete-withdrawal';
|
||||||
|
|
||||||
|
// Because the tests are run on a live network to optimize time, the tests are interdependent and must be run in the given order.
|
||||||
|
describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||||
|
before(() => {
|
||||||
|
cy.createMarket();
|
||||||
|
cy.get('@markets').then((markets) => {
|
||||||
|
cy.wrap(markets[0]).as('market');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.setVegaWallet();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can deposit', function () {
|
||||||
|
cy.visit('/#/portfolio');
|
||||||
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
|
|
||||||
|
// 1001-DEPO-001
|
||||||
|
// 1001-DEPO-002
|
||||||
|
// 1001-DEPO-003
|
||||||
|
// 1001-DEPO-005
|
||||||
|
// 1001-DEPO-006
|
||||||
|
// 1001-DEPO-007
|
||||||
|
// 1001-DEPO-008
|
||||||
|
// 1001-DEPO-009
|
||||||
|
// 1001-DEPO-010
|
||||||
|
|
||||||
|
cy.getByTestId(depositsTab).click();
|
||||||
|
cy.getByTestId('deposit-button').click();
|
||||||
|
connectEthereumWallet('Unknown');
|
||||||
|
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
|
||||||
|
cy.getByTestId('deposit-approve-submit').click();
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
|
||||||
|
cy.get('[data-testid="Return to deposit"]').click();
|
||||||
|
cy.get(amountField).clear().type('10');
|
||||||
|
cy.getByTestId('deposit-submit').click();
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
|
'contain.text',
|
||||||
|
`Transaction confirmedYour transaction has been confirmed.View on EtherscanDeposit 10.00 ${btcSymbol}`,
|
||||||
|
{ matchCase: false }
|
||||||
|
);
|
||||||
|
cy.getByTestId(toastCloseBtn).click();
|
||||||
|
cy.getByTestId('Collateral').click();
|
||||||
|
|
||||||
|
cy.highlight('deposit verification');
|
||||||
|
|
||||||
|
cy.getByTestId('asset', txTimeout).should('contain.text', btcSymbol);
|
||||||
|
cy.getByTestId(depositsTab).click();
|
||||||
|
cy.get('.ag-cell-value', txTimeout).should('contain.text', btcSymbol);
|
||||||
|
cy.get('[col-id="status"]').should('not.have.text', 'Open', txTimeout);
|
||||||
|
|
||||||
|
cy.get('[col-id="txHash"]')
|
||||||
|
.should('have.length.above', 2)
|
||||||
|
.eq(1)
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.get('[col-id="asset.symbol"]').should('have.text', btcSymbol);
|
||||||
|
cy.get('[col-id="amount"]').should('have.text', '10.00');
|
||||||
|
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||||
|
cy.get('[col-id="status"]').should('have.text', 'Finalized');
|
||||||
|
cy.get('[col-id="txHash"]')
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('contain', `${sepoliaUrl}/tx/0x`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can not withdrawal because of no MultiSign', function () {
|
||||||
|
// 1002-WITH-022
|
||||||
|
// 1002-WITH-023
|
||||||
|
|
||||||
|
cy.getByTestId('Withdrawals').click();
|
||||||
|
cy.getByTestId('withdraw-dialog-button').click();
|
||||||
|
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
|
||||||
|
cy.get(amountField).clear().type('1');
|
||||||
|
cy.getByTestId('submit-withdrawal').click();
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
|
'contain.text',
|
||||||
|
'Funds unlocked'
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.getByTestId('tab-withdrawals').within(() => {
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.within(() => {
|
||||||
|
cy.get('[col-id="status"]').should('contain.text', 'Pending');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.highlight('withdrawals verification');
|
||||||
|
cy.getByTestId('toast-complete-withdrawal').click();
|
||||||
|
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
|
'contain.text',
|
||||||
|
'Error occurredprocessing response error'
|
||||||
|
);
|
||||||
|
cy.getByTestId(completeWithdrawalBtn).should(
|
||||||
|
'contain.text',
|
||||||
|
'Complete withdrawal'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: ensure this test runs only if capsule is running via workflow
|
|
||||||
describe('capsule', { tags: '@slow' }, () => {
|
describe('capsule', { tags: '@slow' }, () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.createMarket();
|
cy.createMarket();
|
||||||
@@ -50,8 +162,8 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
marketId: market.id,
|
marketId: market.id,
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
side: Schema.Side.SIDE_BUY,
|
side: Schema.Side.SIDE_BUY,
|
||||||
size: '0.0005',
|
size: size,
|
||||||
price: '390',
|
price: price,
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
};
|
};
|
||||||
const rawPrice = removeDecimal(order.price, market.decimalPlaces);
|
const rawPrice = removeDecimal(order.price, market.decimalPlaces);
|
||||||
@@ -64,7 +176,8 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
|
|
||||||
cy.getByTestId(toastContent).should(
|
cy.getByTestId(toastContent).should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
`ConfirmedYour transaction has been confirmed View in block explorerSubmit order - activeTEST.24h+0.0005 @ 390.00 ${usdcSymbol}`
|
`ConfirmedYour transaction has been confirmed View in block explorerSubmit order - activeTEST.24h+${order.size} @ ${order.price}.00 ${usdcSymbol}`,
|
||||||
|
{ matchCase: false }
|
||||||
);
|
);
|
||||||
cy.getByTestId(toastCloseBtn).click();
|
cy.getByTestId(toastCloseBtn).click();
|
||||||
// orderbook cells are keyed by price level
|
// orderbook cells are keyed by price level
|
||||||
@@ -75,7 +188,7 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
.should('contain.text', rawSize);
|
.should('contain.text', rawSize);
|
||||||
|
|
||||||
cy.getByTestId(ordersTab).click();
|
cy.getByTestId(ordersTab).click();
|
||||||
cy.getByTestId('edit').should('contain.text', 'Edit');
|
cy.getByTestId('edit', txTimeout).should('contain.text', 'Edit');
|
||||||
cy.getByTestId('tab-orders').within(() => {
|
cy.getByTestId('tab-orders').within(() => {
|
||||||
cy.get('.ag-center-cols-container')
|
cy.get('.ag-center-cols-container')
|
||||||
.children()
|
.children()
|
||||||
@@ -113,35 +226,43 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderCreatedAt);
|
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderCreatedAt);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//edit order
|
});
|
||||||
|
|
||||||
|
it('can edit order', function () {
|
||||||
cy.getByTestId(ordersTab).click();
|
cy.getByTestId(ordersTab).click();
|
||||||
cy.getByTestId('edit').first().should('be.visible').click();
|
cy.getByTestId('edit').first().should('be.visible').click();
|
||||||
cy.getByTestId('dialog-title').should('contain.text', 'Edit order');
|
cy.getByTestId('dialog-title').should('contain.text', 'Edit order');
|
||||||
cy.get('#limitPrice').focus().clear().type('200');
|
cy.get('#limitPrice').focus().clear().type(newPrice);
|
||||||
cy.getByTestId('edit-order').find('[type="submit"]').click();
|
cy.getByTestId('edit-order').find('[type="submit"]').click();
|
||||||
|
|
||||||
cy.getByTestId(toastContent).should(
|
cy.getByTestId(toastContent).should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
`ConfirmedYour transaction has been confirmed View in block explorerEdit order - activeTEST.24h+0.0005 @ 200.00 ${usdcSymbol}+0.0005 @ 200.00 ${usdcSymbol}`
|
`ConfirmedYour transaction has been confirmed View in block explorerEdit order - activeTEST.24h+${size} @ ${price}.00 ${usdcSymbol}+${size} @ ${newPrice}.00 ${usdcSymbol}`,
|
||||||
|
{ matchCase: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cy.getByTestId(toastCloseBtn).click({ multiple: true });
|
||||||
cy.getByTestId(ordersTab).click();
|
cy.getByTestId(ordersTab).click();
|
||||||
cy.getByTestId(toastCloseBtn).click();
|
|
||||||
cy.get('.ag-center-cols-container')
|
cy.get('.ag-center-cols-container')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(`[col-id='${orderPrice}']`).then(($price) => {
|
cy.get(`[col-id='${orderPrice}']`).then(($price) => {
|
||||||
expect(parseFloat($price.text())).to.equal(parseFloat('200'));
|
expect(parseFloat($price.text())).to.equal(parseFloat(newPrice));
|
||||||
});
|
});
|
||||||
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderUpdatedAt);
|
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderUpdatedAt);
|
||||||
});
|
});
|
||||||
//cancel order
|
});
|
||||||
|
|
||||||
|
it('can cancel order', function () {
|
||||||
cy.getByTestId(ordersTab).click();
|
cy.getByTestId(ordersTab).click();
|
||||||
cy.getByTestId('cancel').first().click();
|
cy.getByTestId('cancel').first().click();
|
||||||
cy.getByTestId(toastContent).should(
|
cy.getByTestId(toastContent).should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
`ConfirmedYour transaction has been confirmed View in block explorerCancel order - cancelledTEST.24h+0.0005 @ 200.00 ${usdcSymbol}`
|
`ConfirmedYour transaction has been confirmed View in block explorerCancel order - cancelledTEST.24h+${size} @ ${newPrice}.00 ${usdcSymbol}`,
|
||||||
|
{ matchCase: false }
|
||||||
);
|
);
|
||||||
cy.getByTestId(toastCloseBtn).click();
|
cy.getByTestId(toastCloseBtn).click({ multiple: true });
|
||||||
|
|
||||||
cy.getByTestId('tab-orders')
|
cy.getByTestId('tab-orders')
|
||||||
.get('.ag-center-cols-container')
|
.get('.ag-center-cols-container')
|
||||||
@@ -151,78 +272,29 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
.should('contain.text', OrderStatusMapping.STATUS_CANCELLED);
|
.should('contain.text', OrderStatusMapping.STATUS_CANCELLED);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can deposit and withdrawal', function () {
|
it('can withdrawal', function () {
|
||||||
// 1001-DEPO-001
|
// 1002-WITH-0014
|
||||||
// 1001-DEPO-002
|
|
||||||
// 1001-DEPO-003
|
|
||||||
// 1001-DEPO-005
|
|
||||||
// 1001-DEPO-006
|
|
||||||
// 1001-DEPO-007
|
|
||||||
// 1001-DEPO-008
|
|
||||||
// 1001-DEPO-009
|
|
||||||
// 1002-WITH-001
|
|
||||||
// 1002-WITH-006
|
// 1002-WITH-006
|
||||||
// 1002-WITH-009
|
// 1002-WITH-009
|
||||||
// 002-WITH-011
|
// 1002-WITH-011
|
||||||
// 1002-WITH-024
|
// 1002-WITH-024
|
||||||
// 1002-WITH-012
|
// 1002-WITH-012
|
||||||
// 1002-WITH-013
|
// 1002-WITH-013
|
||||||
// 1002-WITH-014
|
// 1002-WITH-014
|
||||||
// 1002-WITH-015
|
// 1002-WITH-015
|
||||||
// 1002-WITH-016
|
// 1002-WITH-016
|
||||||
|
// 1002-WITH-017
|
||||||
// 1002-WITH-019
|
// 1002-WITH-019
|
||||||
|
// 1002-WITH-020
|
||||||
|
// 1002-WITH-021
|
||||||
|
|
||||||
cy.visit('/#/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
cy.get('main[data-testid="/portfolio"]').should('exist');
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
|
|
||||||
cy.highlight('creating deposit');
|
|
||||||
|
|
||||||
cy.getByTestId(depositsTab).click();
|
|
||||||
cy.getByTestId('deposit-button').click();
|
|
||||||
connectEthereumWallet('Unknown');
|
|
||||||
cy.get(assetSelectField, txTimeout).select(btcName);
|
|
||||||
cy.getByTestId('deposit-approve-submit').click();
|
|
||||||
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
|
|
||||||
cy.get('[data-testid="Return to deposit"]').click();
|
|
||||||
cy.get(amountField).clear().type('1');
|
|
||||||
cy.getByTestId('deposit-submit').click();
|
|
||||||
cy.getByTestId(toastContent, txTimeout).should(
|
|
||||||
'contain.text',
|
|
||||||
`Transaction completedYour transaction has been completedView on EtherscanDeposit 1.00 ${btcSymbol}`
|
|
||||||
);
|
|
||||||
cy.getByTestId(toastCloseBtn).click();
|
|
||||||
cy.getByTestId('Collateral').click();
|
|
||||||
|
|
||||||
cy.highlight('deposit verification');
|
|
||||||
|
|
||||||
cy.getByTestId('asset', txTimeout).should('contain.text', btcSymbol);
|
|
||||||
// need to reload page to see deposit history complete
|
|
||||||
cy.reload();
|
|
||||||
cy.getByTestId(depositsTab).click();
|
|
||||||
cy.get('.ag-cell-value', txTimeout).should('contain.text', btcSymbol);
|
|
||||||
cy.get('[col-id="status"]').should('not.have.text', 'Open', txTimeout);
|
|
||||||
|
|
||||||
cy.get('[col-id="txHash"]')
|
|
||||||
.should('have.length.above', 2)
|
|
||||||
.eq(1)
|
|
||||||
.parent()
|
|
||||||
.within(() => {
|
|
||||||
cy.get('[col-id="asset.symbol"]').should('have.text', btcSymbol);
|
|
||||||
cy.get('[col-id="amount"]').should('have.text', '1.00');
|
|
||||||
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
|
||||||
cy.get('[col-id="status"]').should('have.text', 'Finalized');
|
|
||||||
cy.get('[col-id="txHash"]')
|
|
||||||
.find('a')
|
|
||||||
.should('have.attr', 'href')
|
|
||||||
.and('contain', 'https://sepolia.etherscan.io/tx');
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.highlight('creating withdrawals');
|
|
||||||
|
|
||||||
cy.getByTestId('Withdrawals').click();
|
cy.getByTestId('Withdrawals').click();
|
||||||
cy.getByTestId('withdraw-dialog-button').click();
|
cy.getByTestId('withdraw-dialog-button').click();
|
||||||
connectEthereumWallet('Unknown');
|
connectEthereumWallet('Unknown');
|
||||||
cy.get(assetSelectField).select(btcName);
|
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
|
||||||
cy.get(amountField).clear().type('1');
|
cy.get(amountField).clear().type('1');
|
||||||
cy.getByTestId('submit-withdrawal').click();
|
cy.getByTestId('submit-withdrawal').click();
|
||||||
cy.getByTestId(toastContent, txTimeout).should(
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
@@ -241,12 +313,13 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
|
|
||||||
cy.highlight('withdrawals verification');
|
cy.highlight('withdrawals verification');
|
||||||
cy.getByTestId('toast-complete-withdrawal').click();
|
cy.getByTestId('toast-complete-withdrawal').click();
|
||||||
|
|
||||||
cy.getByTestId(toastContent, txTimeout).should(
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'Transaction completed'
|
'Transaction confirmed'
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.getByTestId('complete-withdrawal', txTimeout).should('not.exist');
|
cy.getByTestId(completeWithdrawalBtn).eq(0, txTimeout).should('not.exist');
|
||||||
|
|
||||||
cy.get('[col-id="txHash"]', txTimeout)
|
cy.get('[col-id="txHash"]', txTimeout)
|
||||||
.should('have.length.above', 1)
|
.should('have.length.above', 1)
|
||||||
@@ -258,17 +331,92 @@ describe('capsule', { tags: '@slow' }, () => {
|
|||||||
cy.get('[col-id="details.receiverAddress"]')
|
cy.get('[col-id="details.receiverAddress"]')
|
||||||
.find('a')
|
.find('a')
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('contain', 'https://sepolia.etherscan.io/address/');
|
.and('contain', `${sepoliaUrl}/address/`);
|
||||||
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||||
cy.get('[col-id="withdrawnTimestamp"]').should('not.be.empty');
|
cy.get('[col-id="withdrawnTimestamp"]').should('not.be.empty');
|
||||||
cy.get('[col-id="status"]').should('have.text', 'Completed');
|
cy.get('[col-id="status"]').should('have.text', 'Completed');
|
||||||
cy.get('[col-id="txHash"]')
|
cy.get('[col-id="txHash"]')
|
||||||
.find('a')
|
.find('a')
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('contain', 'https://sepolia.etherscan.io/tx/0x');
|
.and('contain', `${sepoliaUrl}/tx/0x`);
|
||||||
});
|
});
|
||||||
|
// comment because of bug #2819
|
||||||
|
// cy.getByTestId('withdraw-dialog-button').click();
|
||||||
|
// cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '0')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('approved amount is less than deposit', function () {
|
||||||
|
// 1001-DEPO-006
|
||||||
|
|
||||||
|
cy.getByTestId(depositsTab).click();
|
||||||
|
cy.getByTestId('deposit-button').click();
|
||||||
|
cy.get(assetSelectField, txTimeout).select(btcName, { force: true });
|
||||||
|
cy.get(amountField).clear().type('20000000');
|
||||||
|
cy.getByTestId('deposit-approve-submit').should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('withdraw - delay verification', function () {
|
||||||
|
// 1001-DEPO-007
|
||||||
|
// 1001-DEPO-024
|
||||||
|
|
||||||
|
cy.visit('/#/portfolio');
|
||||||
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
|
|
||||||
|
cy.getByTestId(depositsTab).click();
|
||||||
|
cy.getByTestId('deposit-button').click();
|
||||||
|
connectEthereumWallet('Unknown');
|
||||||
|
cy.get(assetSelectField, txTimeout).select(vegaName, { force: true });
|
||||||
|
cy.getByTestId('deposit-approve-submit').click();
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Approve complete');
|
||||||
|
cy.get('[data-testid="Return to deposit"]').click();
|
||||||
|
cy.get(amountField).clear().type('10000');
|
||||||
|
cy.getByTestId('deposit-submit').click();
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
|
'contain.text',
|
||||||
|
`Your transaction has been confirmed.`,
|
||||||
|
{ matchCase: false }
|
||||||
|
);
|
||||||
|
cy.getByTestId(toastCloseBtn).click();
|
||||||
|
cy.getByTestId('Collateral').click();
|
||||||
|
|
||||||
|
cy.highlight('deposit verification');
|
||||||
|
|
||||||
|
cy.getByTestId('asset', txTimeout).should('contain.text', vegaSymbol);
|
||||||
|
cy.getByTestId(depositsTab).click();
|
||||||
|
cy.get('.ag-cell-value', txTimeout).should('contain.text', vegaSymbol);
|
||||||
|
cy.get('[col-id="status"]').should('not.have.text', 'Open', txTimeout);
|
||||||
|
|
||||||
|
cy.get('[col-id="txHash"]')
|
||||||
|
.should('have.length.above', 2)
|
||||||
|
.eq(1)
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.get('[col-id="asset.symbol"]').should('have.text', vegaSymbol);
|
||||||
|
cy.get('[col-id="amount"]').should('have.text', '10,000.00');
|
||||||
|
cy.get('[col-id="createdTimestamp"]').should('not.be.empty');
|
||||||
|
cy.get('[col-id="status"]').should('have.text', 'Finalized');
|
||||||
|
cy.get('[col-id="txHash"]')
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('contain', `${sepoliaUrl}/tx/0x`);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('Withdrawals').click();
|
||||||
|
cy.getByTestId('withdraw-dialog-button').click();
|
||||||
|
cy.get(assetSelectField, txTimeout).select(vegaName, { force: true });
|
||||||
|
cy.get(amountField).clear().type('10000');
|
||||||
|
cy.getByTestId('DELAY_TIME_value').should('have.text', '5 days');
|
||||||
|
cy.getByTestId('submit-withdrawal').click();
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should(
|
||||||
|
'contain.text',
|
||||||
|
'Your funds have been unlocked'
|
||||||
|
);
|
||||||
|
cy.getByTestId(toastCloseBtn).click();
|
||||||
|
cy.getByTestId(completeWithdrawalBtn).first().should('be.visible').click();
|
||||||
|
cy.getByTestId(toastContent, txTimeout).should('contain.text', 'Delayed');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkIfDataAndTimeOfCreationAndUpdateIsEqual(date: string) {
|
function checkIfDataAndTimeOfCreationAndUpdateIsEqual(date: string) {
|
||||||
cy.get(`[col-id='${date}'] .ag-cell-wrapper`)
|
cy.get(`[col-id='${date}'] .ag-cell-wrapper`)
|
||||||
.children('span')
|
.children('span')
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('insufficient funds', () => {
|
it('insufficient funds', () => {
|
||||||
|
// 1001-DEPO-005
|
||||||
// Deposit amount is valid, but less than approved. This will always be the case because our
|
// Deposit amount is valid, but less than approved. This will always be the case because our
|
||||||
// CI wallet wont have approved any assets
|
// CI wallet wont have approved any assets
|
||||||
cy.get(amountField)
|
cy.get(amountField)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const marketInfoBtn = 'Info';
|
|||||||
const row = 'key-value-table-row';
|
const row = 'key-value-table-row';
|
||||||
const marketTitle = 'accordion-title';
|
const marketTitle = 'accordion-title';
|
||||||
const externalLink = 'external-link';
|
const externalLink = 'external-link';
|
||||||
|
const accordionContent = 'accordion-content';
|
||||||
|
|
||||||
describe('market info is displayed', { tags: '@smoke' }, () => {
|
describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
@@ -179,7 +180,8 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
|||||||
'termination.BTC.value'
|
'termination.BTC.value'
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.getByTestId(externalLink)
|
cy.getByTestId(accordionContent)
|
||||||
|
.find(`[data-testid="${externalLink}"]`)
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('contain', '/oracles');
|
.and('contain', '/oracles');
|
||||||
});
|
});
|
||||||
@@ -187,12 +189,14 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
|||||||
it('proposal displayed', () => {
|
it('proposal displayed', () => {
|
||||||
cy.getByTestId(marketTitle).contains('Proposal').click();
|
cy.getByTestId(marketTitle).contains('Proposal').click();
|
||||||
|
|
||||||
cy.getByTestId(externalLink)
|
cy.getByTestId(accordionContent)
|
||||||
|
.find(`[data-testid="${externalLink}"]`)
|
||||||
.first()
|
.first()
|
||||||
.should('have.text', 'View governance proposal')
|
.should('have.text', 'View governance proposal')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
.and('contain', '/proposals/market-0');
|
.and('contain', '/proposals/market-0');
|
||||||
cy.getByTestId(externalLink)
|
cy.getByTestId(accordionContent)
|
||||||
|
.find(`[data-testid="${externalLink}"]`)
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.should('have.text', 'Propose a change to market')
|
.should('have.text', 'Propose a change to market')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||||
|
import { marketQuery } from '@vegaprotocol/mock';
|
||||||
|
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
describe('markets table', { tags: '@smoke' }, () => {
|
describe('markets table', { tags: '@smoke' }, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -101,7 +104,8 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
'have.length',
|
'have.length',
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
cy.getByTestId('external-link')
|
cy.getByTestId('tab-proposed-markets')
|
||||||
|
.find('[data-testid="external-link"]')
|
||||||
.should('have.length', 11)
|
.should('have.length', 11)
|
||||||
.last()
|
.last()
|
||||||
.should('have.text', 'Propose a new market')
|
.should('have.text', 'Propose a new market')
|
||||||
@@ -111,6 +115,53 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
|
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('opening auction subsets should be properly displayed', () => {
|
||||||
|
cy.mockTradingPage(
|
||||||
|
Schema.MarketState.STATE_ACTIVE,
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
||||||
|
);
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
const override = {
|
||||||
|
market: {
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
name: `opening auction MARKET`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
|
tradingMode: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const market = marketQuery(override);
|
||||||
|
aliasGQLQuery(req, 'Market', market);
|
||||||
|
aliasGQLQuery(req, 'ProposalOfMarket', {
|
||||||
|
proposal: { terms: { enactmentDatetime: '2023-01-31 12:00:01' } },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
cy.visit('/');
|
||||||
|
cy.visit('#/markets/market-0');
|
||||||
|
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||||
|
cy.getByTestId('opening-auction-sub-status').should(
|
||||||
|
'contain.text',
|
||||||
|
'Opening auction: Not enough liquidity to open'
|
||||||
|
);
|
||||||
|
|
||||||
|
const now = new Date(Date.parse('2023-01-30 12:00:01')).getTime();
|
||||||
|
cy.clock(now, ['Date']); // Set "now" to BEFORE reservation
|
||||||
|
cy.visit('/');
|
||||||
|
cy.visit('#/markets/market-0');
|
||||||
|
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||||
|
cy.getByTestId('opening-auction-sub-status').should(
|
||||||
|
'contain.text',
|
||||||
|
`Opening auction: Closing on ${getDateTimeFormat().format(
|
||||||
|
new Date('2023-01-31 12:00:01')
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
cy.clock().then((clock) => {
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function openMarketDropDown() {
|
function openMarketDropDown() {
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
|
|||||||
//7002-SORD-018
|
//7002-SORD-018
|
||||||
cy.getByTestId(orderPriceField)
|
cy.getByTestId(orderPriceField)
|
||||||
.siblings('label')
|
.siblings('label')
|
||||||
.should('have.text', 'Price (tBTC)');
|
.should('have.text', 'Price (BTC)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must see warning when placing an order with expiry date in past', () => {
|
it('must see warning when placing an order with expiry date in past', () => {
|
||||||
|
|||||||
@@ -454,8 +454,4 @@ describe('amend and cancel order', { tags: '@smoke' }, () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it.skip('tbd for 7003-MORD', () => {
|
|
||||||
// NOT COVERED: must see the reference, offset and direction for each part pegged order - waiting for clarification
|
|
||||||
// NOT COVERED: must see the reference, offset and direction for each part liquidity order order - waiting for clarification
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
|||||||
cy.get(toAddressField).should('have.value', ethAddressValue);
|
cy.get(toAddressField).should('have.value', ethAddressValue);
|
||||||
});
|
});
|
||||||
it('min amount', () => {
|
it('min amount', () => {
|
||||||
|
// 1002-WITH-010
|
||||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||||
cy.get(amountField).clear().type('0');
|
cy.get(amountField).clear().type('0');
|
||||||
cy.getByTestId(submitWithdrawBtn).click();
|
cy.getByTestId(submitWithdrawBtn).click();
|
||||||
@@ -50,6 +51,8 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('max amount', () => {
|
it('max amount', () => {
|
||||||
|
// 1002-WITH-005
|
||||||
|
// 1002-WITH-008
|
||||||
selectAsset(ASSET_EURO); // Will be above maximum because the vega wallet doesn't have any collateral
|
selectAsset(ASSET_EURO); // Will be above maximum because the vega wallet doesn't have any collateral
|
||||||
cy.get(amountField).clear().type('1001', { delay: 100 });
|
cy.get(amountField).clear().type('1001', { delay: 100 });
|
||||||
cy.getByTestId(submitWithdrawBtn).click();
|
cy.getByTestId(submitWithdrawBtn).click();
|
||||||
@@ -60,6 +63,7 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can set amount using use maximum button', () => {
|
it('can set amount using use maximum button', () => {
|
||||||
|
// 1002-WITH-004
|
||||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||||
cy.getByTestId(useMaximumAmount).click();
|
cy.getByTestId(useMaximumAmount).click();
|
||||||
cy.get(amountField).should('have.value', '1000.00000');
|
cy.get(amountField).should('have.value', '1000.00000');
|
||||||
@@ -68,6 +72,9 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
describe('withdraw actions', { tags: '@regression' }, () => {
|
describe('withdraw actions', { tags: '@regression' }, () => {
|
||||||
// this is extremely ugly hack, but setting it properly in contract is too much effort for such simple validation
|
// this is extremely ugly hack, but setting it properly in contract is too much effort for such simple validation
|
||||||
|
|
||||||
|
// 1002-WITH-018
|
||||||
|
|
||||||
const withdrawalThreshold =
|
const withdrawalThreshold =
|
||||||
Cypress.env('VEGA_ENV') === 'CUSTOM' ? '0.00' : '100.00';
|
Cypress.env('VEGA_ENV') === 'CUSTOM' ? '0.00' : '100.00';
|
||||||
before(() => {
|
before(() => {
|
||||||
@@ -88,6 +95,8 @@ describe('withdraw actions', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('triggers transaction when submitted', () => {
|
it('triggers transaction when submitted', () => {
|
||||||
|
// 1002-WITH-002
|
||||||
|
// 1002-WITH-003
|
||||||
selectAsset(ASSET_SEPOLIA_TBTC);
|
selectAsset(ASSET_SEPOLIA_TBTC);
|
||||||
cy.getByTestId('BALANCE_AVAILABLE_label').should(
|
cy.getByTestId('BALANCE_AVAILABLE_label').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
@@ -108,7 +117,4 @@ describe('withdraw actions', { tags: '@regression' }, () => {
|
|||||||
cy.getByTestId(submitWithdrawBtn).click();
|
cy.getByTestId(submitWithdrawBtn).click();
|
||||||
cy.getByTestId('toast').should('contain.text', 'Awaiting confirmation');
|
cy.getByTestId('toast').should('contain.text', 'Awaiting confirmation');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('creates a withdrawal on submit'); // Needs capsule
|
|
||||||
it.skip('creates a withdrawal on submit and prompts to complete withdrawal'); // Needs capsule
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
|||||||
NX_VEGA_URL=http://localhost:3028/query
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|
||||||
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
NX_ETH_LOCAL_PROVIDER_URL=http://localhost:8545/
|
||||||
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supply green clown session"
|
||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"h
|
|||||||
NX_VEGA_TOKEN_URL=https://token.vega.xyz
|
NX_VEGA_TOKEN_URL=https://token.vega.xyz
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://mainnet-mirror.token.vega.xyz
|
NX_VEGA_TOKEN_URL=https://mainnet-mirror.token.vega.xyz
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ NX_VEGA_NETWORKS={\"DEVNET\":\"https://dev.token.vega.xyz\",\"STAGNET3\":\"https
|
|||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/sandbox-network.json
|
||||||
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
|
NX_VEGA_EXPLORER_URL=https://sandbox.explorer.vega.xyz
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
NX_VEGA_TOKEN_URL=https://stagnet1.token.vega.xyz
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega-dev-releases/releases
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"
|
|||||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/validator-testnet-network.json
|
||||||
|
NX_VEGA_ENV=VALIDATOR_TESTNET
|
||||||
|
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||||
|
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||||
|
NX_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
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@ import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
|||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
export const DepositsContainer = () => {
|
export const DepositsContainer = () => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
const { data, loading, error } = useDataProvider({
|
const { data, loading, error } = useDataProvider({
|
||||||
dataProvider: depositsProvider,
|
dataProvider: depositsProvider,
|
||||||
variables: { partyId: pubKey || '' },
|
variables: { partyId: pubKey || '' },
|
||||||
@@ -30,6 +30,7 @@ export const DepositsContainer = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{!isReadOnly && (
|
||||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -39,6 +40,7 @@ export const DepositsContainer = () => {
|
|||||||
{t('Deposit')}
|
{t('Deposit')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
|||||||
import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
||||||
|
|
||||||
export const WithdrawalsContainer = () => {
|
export const WithdrawalsContainer = () => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
const { data, loading, error } = useDataProvider({
|
const { data, loading, error } = useDataProvider({
|
||||||
dataProvider: withdrawalProvider,
|
dataProvider: withdrawalProvider,
|
||||||
variables: { partyId: pubKey || '' },
|
variables: { partyId: pubKey || '' },
|
||||||
@@ -36,6 +36,7 @@ export const WithdrawalsContainer = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{!isReadOnly && (
|
||||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -45,6 +46,7 @@ export const WithdrawalsContainer = () => {
|
|||||||
{t('Make withdrawal')}
|
{t('Make withdrawal')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</VegaWalletContainer>
|
</VegaWalletContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user