Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69f4bdb62e | ||
|
|
1e0fdb11ee | ||
|
|
20b25bbb6a | ||
|
|
93643f1737 | ||
|
|
464d5af6be | ||
|
|
b2a62f16bc | ||
|
|
9ec03a04ea | ||
|
|
2a0727ec4b | ||
|
|
0d39c2354c | ||
|
|
ad6f0c5798 | ||
|
|
38d13085fb | ||
|
|
c0f4278b81 | ||
|
|
b2777043b4 |
@@ -290,5 +290,5 @@ jobs:
|
||||
if [[ $result == "success" || $result == "skipped" ]]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -6,7 +6,12 @@ export const SUPPORTED_INTERVALS = [
|
||||
Interval.INTERVAL_I1M,
|
||||
Interval.INTERVAL_I5M,
|
||||
Interval.INTERVAL_I15M,
|
||||
Interval.INTERVAL_I30M,
|
||||
Interval.INTERVAL_I1H,
|
||||
Interval.INTERVAL_I4H,
|
||||
Interval.INTERVAL_I6H,
|
||||
Interval.INTERVAL_I8H,
|
||||
Interval.INTERVAL_I12H,
|
||||
Interval.INTERVAL_I1D,
|
||||
Interval.INTERVAL_I7D,
|
||||
] as const;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { ProfileDialog } from './profile-dialog';
|
||||
@@ -0,0 +1,150 @@
|
||||
import {
|
||||
Dialog,
|
||||
FormGroup,
|
||||
Input,
|
||||
InputError,
|
||||
Intent,
|
||||
TradingButton,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useProfileDialogStore } from '../../stores/profile-dialog-store';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useRequired } from '@vegaprotocol/utils';
|
||||
import {
|
||||
useSimpleTransaction,
|
||||
type Status,
|
||||
useVegaWallet,
|
||||
} from '@vegaprotocol/wallet-react';
|
||||
import {
|
||||
usePartyProfilesQuery,
|
||||
type PartyProfilesQuery,
|
||||
} from '../vega-wallet-connect-button/__generated__/PartyProfiles';
|
||||
|
||||
export const ProfileDialog = () => {
|
||||
const t = useT();
|
||||
const { pubKeys } = useVegaWallet();
|
||||
const { data, refetch } = usePartyProfilesQuery({
|
||||
variables: { partyIds: pubKeys.map((pk) => pk.publicKey) },
|
||||
skip: pubKeys.length <= 0,
|
||||
});
|
||||
const open = useProfileDialogStore((store) => store.open);
|
||||
const pubKey = useProfileDialogStore((store) => store.pubKey);
|
||||
const setOpen = useProfileDialogStore((store) => store.setOpen);
|
||||
|
||||
const { send, status, error, reset } = useSimpleTransaction({
|
||||
onSuccess: () => {
|
||||
refetch();
|
||||
},
|
||||
});
|
||||
|
||||
const profileEdge = data?.partiesProfilesConnection?.edges.find(
|
||||
(e) => e.node.partyId === pubKey
|
||||
);
|
||||
|
||||
const sendTx = (field: FormFields) => {
|
||||
send({
|
||||
updatePartyProfile: {
|
||||
alias: field.alias,
|
||||
metadata: [],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onChange={() => {
|
||||
setOpen(undefined);
|
||||
reset();
|
||||
}}
|
||||
title={t('Edit profile')}
|
||||
>
|
||||
<ProfileForm
|
||||
profile={profileEdge?.node}
|
||||
status={status}
|
||||
error={error}
|
||||
onSubmit={sendTx}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
interface FormFields {
|
||||
alias: string;
|
||||
}
|
||||
|
||||
type Profile = NonNullable<
|
||||
PartyProfilesQuery['partiesProfilesConnection']
|
||||
>['edges'][number]['node'];
|
||||
|
||||
const ProfileForm = ({
|
||||
profile,
|
||||
onSubmit,
|
||||
status,
|
||||
error,
|
||||
}: {
|
||||
profile: Profile | undefined;
|
||||
onSubmit: (fields: FormFields) => void;
|
||||
status: Status;
|
||||
error: string | undefined;
|
||||
}) => {
|
||||
const t = useT();
|
||||
const required = useRequired();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FormFields>({
|
||||
defaultValues: {
|
||||
alias: profile?.alias,
|
||||
},
|
||||
});
|
||||
|
||||
const renderButtonText = () => {
|
||||
if (status === 'requested') {
|
||||
return t('Confirm in wallet...');
|
||||
}
|
||||
|
||||
if (status === 'pending') {
|
||||
return t('Confirming transaction...');
|
||||
}
|
||||
|
||||
return t('Submit');
|
||||
};
|
||||
|
||||
const errorMessage = errors.alias?.message || error;
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mt-3">
|
||||
<FormGroup label="Alias" labelFor="alias">
|
||||
<Input
|
||||
{...register('alias', {
|
||||
validate: {
|
||||
required,
|
||||
},
|
||||
})}
|
||||
/>
|
||||
{errorMessage && (
|
||||
<InputError>
|
||||
<p className="break-words max-w-full first-letter:uppercase">
|
||||
{errorMessage}
|
||||
</p>
|
||||
</InputError>
|
||||
)}
|
||||
|
||||
{status === 'confirmed' && (
|
||||
<p className="mt-2 mb-4 text-sm text-success">
|
||||
{t('Profile updated')}
|
||||
</p>
|
||||
)}
|
||||
</FormGroup>
|
||||
<TradingButton
|
||||
type="submit"
|
||||
intent={Intent.Info}
|
||||
disabled={status === 'requested' || status === 'pending'}
|
||||
>
|
||||
{renderButtonText()}
|
||||
</TradingButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
query PartyProfiles($partyIds: [ID!]) {
|
||||
partiesProfilesConnection(ids: $partyIds) {
|
||||
edges {
|
||||
node {
|
||||
partyId
|
||||
alias
|
||||
metadata {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type PartyProfilesQueryVariables = Types.Exact<{
|
||||
partyIds?: Types.InputMaybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type PartyProfilesQuery = { __typename?: 'Query', partiesProfilesConnection?: { __typename?: 'PartiesProfilesConnection', edges: Array<{ __typename?: 'PartyProfileEdge', node: { __typename?: 'PartyProfile', partyId: string, alias: string, metadata: Array<{ __typename?: 'Metadata', key: string, value: string }> } }> } | null };
|
||||
|
||||
|
||||
export const PartyProfilesDocument = gql`
|
||||
query PartyProfiles($partyIds: [ID!]) {
|
||||
partiesProfilesConnection(ids: $partyIds) {
|
||||
edges {
|
||||
node {
|
||||
partyId
|
||||
alias
|
||||
metadata {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __usePartyProfilesQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePartyProfilesQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePartyProfilesQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = usePartyProfilesQuery({
|
||||
* variables: {
|
||||
* partyIds: // value for 'partyIds'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePartyProfilesQuery(baseOptions?: Apollo.QueryHookOptions<PartyProfilesQuery, PartyProfilesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PartyProfilesQuery, PartyProfilesQueryVariables>(PartyProfilesDocument, options);
|
||||
}
|
||||
export function usePartyProfilesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PartyProfilesQuery, PartyProfilesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PartyProfilesQuery, PartyProfilesQueryVariables>(PartyProfilesDocument, options);
|
||||
}
|
||||
export type PartyProfilesQueryHookResult = ReturnType<typeof usePartyProfilesQuery>;
|
||||
export type PartyProfilesLazyQueryHookResult = ReturnType<typeof usePartyProfilesLazyQuery>;
|
||||
export type PartyProfilesQueryResult = Apollo.QueryResult<PartyProfilesQuery, PartyProfilesQueryVariables>;
|
||||
+52
-12
@@ -1,21 +1,57 @@
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import { act, fireEvent, render, screen, within } from '@testing-library/react';
|
||||
import { VegaWalletConnectButton } from './vega-wallet-connect-button';
|
||||
import { truncateByChars } from '@vegaprotocol/utils';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import {
|
||||
mockConfig,
|
||||
MockedWalletProvider,
|
||||
} from '@vegaprotocol/wallet-react/testing';
|
||||
import { MockedProvider, type MockedResponse } from '@apollo/react-testing';
|
||||
import {
|
||||
PartyProfilesDocument,
|
||||
type PartyProfilesQuery,
|
||||
} from './__generated__/PartyProfiles';
|
||||
|
||||
jest.mock('../../lib/hooks/use-get-current-route-id', () => ({
|
||||
useGetCurrentRouteId: jest.fn().mockReturnValue('current-route-id'),
|
||||
}));
|
||||
|
||||
const key = { publicKey: '123456__123456', name: 'test' };
|
||||
const key2 = { publicKey: 'abcdef__abcdef', name: 'test2' };
|
||||
const keys = [key, key2];
|
||||
const keyProfile = {
|
||||
__typename: 'PartyProfile' as const,
|
||||
partyId: key.publicKey,
|
||||
alias: `${key.name} alias`,
|
||||
metadata: [],
|
||||
};
|
||||
|
||||
const renderComponent = (mockOnClick = jest.fn()) => {
|
||||
const partyProfilesMock: MockedResponse<PartyProfilesQuery> = {
|
||||
request: {
|
||||
query: PartyProfilesDocument,
|
||||
variables: { partyIds: keys.map((k) => k.publicKey) },
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
partiesProfilesConnection: {
|
||||
__typename: 'PartiesProfilesConnection',
|
||||
edges: [
|
||||
{
|
||||
__typename: 'PartyProfileEdge',
|
||||
node: keyProfile,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<MockedWalletProvider>
|
||||
<VegaWalletConnectButton onClick={mockOnClick} />
|
||||
</MockedWalletProvider>
|
||||
<MockedProvider mocks={[partyProfilesMock]}>
|
||||
<MockedWalletProvider>
|
||||
<VegaWalletConnectButton onClick={mockOnClick} />
|
||||
</MockedWalletProvider>
|
||||
</MockedProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,10 +79,6 @@ describe('VegaWalletConnectButton', () => {
|
||||
});
|
||||
|
||||
it('should open dropdown and refresh keys when connected', async () => {
|
||||
const key = { publicKey: '123456__123456', name: 'test' };
|
||||
const key2 = { publicKey: 'abcdef__abcdef', name: 'test2' };
|
||||
const keys = [key, key2];
|
||||
|
||||
mockConfig.store.setState({
|
||||
status: 'connected',
|
||||
keys,
|
||||
@@ -61,14 +93,22 @@ describe('VegaWalletConnectButton', () => {
|
||||
|
||||
expect(screen.queryByTestId('connect-vega-wallet')).not.toBeInTheDocument();
|
||||
const button = screen.getByTestId('manage-vega-wallet');
|
||||
expect(button).toHaveTextContent(truncateByChars(key.publicKey));
|
||||
expect(button).toHaveTextContent(key.name);
|
||||
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(await screen.findByRole('menu')).toBeInTheDocument();
|
||||
expect(await screen.findAllByRole('menuitemradio')).toHaveLength(
|
||||
keys.length
|
||||
const menuItems = await screen.findAllByRole('menuitemradio');
|
||||
expect(menuItems).toHaveLength(keys.length);
|
||||
|
||||
expect(within(menuItems[0]).getByTestId('alias')).toHaveTextContent(
|
||||
keyProfile.alias
|
||||
);
|
||||
|
||||
expect(within(menuItems[1]).getByTestId('alias')).toHaveTextContent(
|
||||
'No alias'
|
||||
);
|
||||
|
||||
expect(refreshKeys).toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(screen.getByTestId(`key-${key2.publicKey}`));
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
TradingDropdownItem,
|
||||
TradingDropdownRadioItem,
|
||||
TradingDropdownItemIndicator,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { isBrowserWalletInstalled, type Key } from '@vegaprotocol/wallet';
|
||||
import { useDialogStore, useVegaWallet } from '@vegaprotocol/wallet-react';
|
||||
@@ -22,6 +23,8 @@ import classNames from 'classnames';
|
||||
import { ViewType, useSidebar } from '../sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { usePartyProfilesQuery } from './__generated__/PartyProfiles';
|
||||
import { useProfileDialogStore } from '../../stores/profile-dialog-store';
|
||||
|
||||
export const VegaWalletConnectButton = ({
|
||||
intent = Intent.None,
|
||||
@@ -68,10 +71,10 @@ export const VegaWalletConnectButton = ({
|
||||
{activeKey ? (
|
||||
<>
|
||||
{activeKey && (
|
||||
<span className="uppercase">{activeKey.name}</span>
|
||||
<span className="uppercase">
|
||||
{activeKey.name ? activeKey.name : t('Unnamed key')}
|
||||
</span>
|
||||
)}
|
||||
{' | '}
|
||||
{truncateByChars(activeKey.publicKey)}
|
||||
</>
|
||||
) : (
|
||||
<>{'Select key'}</>
|
||||
@@ -88,20 +91,11 @@ export const VegaWalletConnectButton = ({
|
||||
onEscapeKeyDown={() => setDropdownOpen(false)}
|
||||
>
|
||||
<div className="min-w-[340px]" data-testid="keypair-list">
|
||||
<TradingDropdownRadioGroup
|
||||
value={pubKey || undefined}
|
||||
onValueChange={(value) => {
|
||||
selectPubKey(value);
|
||||
}}
|
||||
>
|
||||
{pubKeys.map((pk) => (
|
||||
<KeypairItem
|
||||
key={pk.publicKey}
|
||||
pk={pk}
|
||||
active={pk.publicKey === pubKey}
|
||||
/>
|
||||
))}
|
||||
</TradingDropdownRadioGroup>
|
||||
<KeypairRadioGroup
|
||||
pubKey={pubKey}
|
||||
pubKeys={pubKeys}
|
||||
onSelect={selectPubKey}
|
||||
/>
|
||||
<TradingDropdownSeparator />
|
||||
{!isReadOnly && (
|
||||
<TradingDropdownItem
|
||||
@@ -141,28 +135,52 @@ export const VegaWalletConnectButton = ({
|
||||
);
|
||||
};
|
||||
|
||||
const KeypairItem = ({ pk, active }: { pk: Key; active: boolean }) => {
|
||||
const KeypairRadioGroup = ({
|
||||
pubKey,
|
||||
pubKeys,
|
||||
onSelect,
|
||||
}: {
|
||||
pubKey: string | undefined;
|
||||
pubKeys: Key[];
|
||||
onSelect: (pubKey: string) => void;
|
||||
}) => {
|
||||
const { data } = usePartyProfilesQuery({
|
||||
variables: { partyIds: pubKeys.map((pk) => pk.publicKey) },
|
||||
skip: pubKeys.length <= 0,
|
||||
});
|
||||
|
||||
return (
|
||||
<TradingDropdownRadioGroup value={pubKey} onValueChange={onSelect}>
|
||||
{pubKeys.map((pk) => {
|
||||
const profile = data?.partiesProfilesConnection?.edges.find(
|
||||
(e) => e.node.partyId === pk.publicKey
|
||||
);
|
||||
return (
|
||||
<KeypairItem key={pk.publicKey} pk={pk} alias={profile?.node.alias} />
|
||||
);
|
||||
})}
|
||||
</TradingDropdownRadioGroup>
|
||||
);
|
||||
};
|
||||
|
||||
const KeypairItem = ({ pk, alias }: { pk: Key; alias: string | undefined }) => {
|
||||
const t = useT();
|
||||
const [copied, setCopied] = useCopyTimeout();
|
||||
const setOpen = useProfileDialogStore((store) => store.setOpen);
|
||||
|
||||
return (
|
||||
<TradingDropdownRadioItem value={pk.publicKey}>
|
||||
<div
|
||||
className={classNames('flex-1 mr-2', {
|
||||
'text-default': active,
|
||||
'text-muted': !active,
|
||||
})}
|
||||
data-testid={`key-${pk.publicKey}`}
|
||||
>
|
||||
<span className={classNames('mr-2 uppercase')}>
|
||||
{pk.name}
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{pk.name ? pk.name : t('Unnamed key')}</span>
|
||||
{' | '}
|
||||
{truncateByChars(pk.publicKey)}
|
||||
</span>
|
||||
<span className="inline-flex items-center gap-1">
|
||||
<span className="font-mono">
|
||||
{truncateByChars(pk.publicKey, 3, 3)}
|
||||
</span>
|
||||
<CopyToClipboard text={pk.publicKey} onCopy={() => setCopied(true)}>
|
||||
<button
|
||||
data-testid="copy-vega-public-key"
|
||||
className="relative -top-px"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<span className="sr-only">{t('Copy')}</span>
|
||||
@@ -170,7 +188,17 @@ const KeypairItem = ({ pk, active }: { pk: Key; active: boolean }) => {
|
||||
</button>
|
||||
</CopyToClipboard>
|
||||
{copied && <span className="text-xs">{t('Copied')}</span>}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={classNames('flex-1 mr-2 text-secondary text-sm')}
|
||||
data-testid={`key-${pk.publicKey}`}
|
||||
>
|
||||
<Tooltip description={t('Public facing key alias. Click to edit')}>
|
||||
<button data-testid="alias" onClick={() => setOpen(pk.publicKey)}>
|
||||
{alias ? alias : t('No alias')}
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<TradingDropdownItemIndicator />
|
||||
</TradingDropdownRadioItem>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
|
||||
VEGA_VERSION=v0.74.6
|
||||
VEGA_VERSION=v0.75.0-preview.2
|
||||
LOCAL_SERVER=false
|
||||
|
||||
@@ -50,8 +50,6 @@ def truncate_middle(market_id, start=6, end=4):
|
||||
def change_keys(page: Page, vega: VegaServiceNull, key_name):
|
||||
page.get_by_test_id("manage-vega-wallet").click()
|
||||
page.get_by_test_id("key-" + vega.wallet.public_key(key_name)).click()
|
||||
page.click(
|
||||
f'data-testid=key-{vega.wallet.public_key(key_name)} >> .inline-flex')
|
||||
page.reload()
|
||||
|
||||
|
||||
|
||||
@@ -339,4 +339,3 @@ def retry_on_http_error(request):
|
||||
print(f"Retrying due to HTTPError (attempt {i+1}/{retry_count})")
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
Generated
+4
-4
@@ -877,13 +877,13 @@ testing = ["filelock"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
version = "2.9.0.post0"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
||||
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1166,7 +1166,7 @@ profile = ["pytest-profiling", "snakeviz"]
|
||||
type = "git"
|
||||
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
|
||||
reference = "HEAD"
|
||||
resolved_reference = "33fec45ce8044ef7f53b625584ce590d174f9057"
|
||||
resolved_reference = "53eed8942acb670783105cb1115bab76710a46dc"
|
||||
|
||||
[[package]]
|
||||
name = "websocket-client"
|
||||
|
||||
@@ -18,7 +18,7 @@ expire = "expire"
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ class TestStopOcoValidation:
|
||||
@pytest.fixture(scope="class")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from typing import Tuple, Generator
|
||||
from fees_test_ids import *
|
||||
from playwright.sync_api import Page, expect
|
||||
from playwright.sync_api import expect, Page
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
from wallet_config import MM_WALLET
|
||||
@@ -16,77 +17,70 @@ from fixtures.market import setup_continuous_market
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(
|
||||
request, browser
|
||||
) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
market = setup_continuous_market(vega_instance, custom_quantum=100000)
|
||||
vega_instance.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
yield vega_instance
|
||||
next_epoch(vega_instance)
|
||||
|
||||
vega_instance.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
vega_instance.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega_instance)
|
||||
referral_set_id = list(vega_instance.list_referral_sets().keys())[0]
|
||||
vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega_instance)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 2, 110)
|
||||
forward_time(vega_instance, True if _ < 2 - 1 else False)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page_instance:
|
||||
risk_accepted_setup(page_instance)
|
||||
auth_setup(vega_instance, page_instance)
|
||||
yield vega_instance, market, page_instance
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_combined_market(vega: VegaServiceNull):
|
||||
market = setup_continuous_market(vega, custom_quantum=100000)
|
||||
vega.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
vega.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
vega.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega=vega)
|
||||
referral_set_id = list(vega.list_referral_sets().keys())[0]
|
||||
vega.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega, "Key 1", market, "SIDE_BUY", 2, 110)
|
||||
forward_time(vega, True if _ < 2 - 1 else False)
|
||||
return market
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
def test_fees_page_discount_program_my_trading_fees(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("6.432%-6.432%")
|
||||
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
|
||||
@@ -97,10 +91,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fees_page_discount_program_total_discount(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("36%")
|
||||
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount20%")
|
||||
@@ -113,8 +107,10 @@ def test_fees_page_discount_program_total_discount(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
def test_fees_page_discount_program_fees_by_market(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
pinned = page.locator(PINNED_ROW_LOCATOR)
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
@@ -126,12 +122,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_deal_ticket_discount_program(
|
||||
page: Page,
|
||||
setup_combined_market,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_combined_market}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(ORDER_SIZE).fill("1")
|
||||
page.get_by_test_id(ORDER_PRICE).fill("1")
|
||||
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-36%")
|
||||
@@ -150,12 +145,9 @@ def test_deal_ticket_discount_program(
|
||||
expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.06432 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fills_taker_discount_program(
|
||||
page: Page,
|
||||
setup_combined_market,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_combined_market}")
|
||||
def test_fills_taker_discount_program(setup_environment):
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
expect(row.locator(COL_SIZE)).to_have_text("+2")
|
||||
@@ -166,13 +158,11 @@ def test_fills_taker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("7.48926 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fills_maker_discount_program(
|
||||
vega: VegaServiceNull,
|
||||
page: Page,
|
||||
setup_combined_market,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_combined_market}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -184,11 +174,11 @@ def test_fills_maker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("7.452 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fills_maker_fee_tooltip_discount_program(
|
||||
vega: VegaServiceNull, page: Page, setup_combined_market
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_combined_market}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -200,12 +190,11 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_combo_tier_2")
|
||||
def test_fills_taker_fee_tooltip_discount_program(
|
||||
page: Page,
|
||||
setup_combined_market,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_combined_market}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
# tbd - tooltip is not visible without this wait
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import pytest
|
||||
from typing import Tuple, Generator
|
||||
from fees_test_ids import *
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
@@ -14,63 +15,58 @@ from conftest import (
|
||||
from actions.utils import next_epoch, change_keys, forward_time
|
||||
from fixtures.market import setup_continuous_market
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(
|
||||
request, browser
|
||||
) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
# Setup the market with the referral discount program
|
||||
market = setup_continuous_market(vega_instance, custom_quantum=100000)
|
||||
vega_instance.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
yield vega_instance
|
||||
vega_instance.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega_instance)
|
||||
referral_set_id = list(vega_instance.list_referral_sets().keys())[0]
|
||||
vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega_instance)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega_instance, True if _ < 2 - 1 else False)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page_instance:
|
||||
risk_accepted_setup(page_instance)
|
||||
auth_setup(vega_instance, page_instance)
|
||||
yield vega_instance, market, page_instance
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_referral_discount_program(vega: VegaServiceNull):
|
||||
market = setup_continuous_market(vega, custom_quantum=100000)
|
||||
vega.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
vega.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega=vega)
|
||||
referral_set_id = list(vega.list_referral_sets().keys())[0]
|
||||
vega.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega, True if _ < 2 - 1 else False)
|
||||
|
||||
return market
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
def test_fees_page_discount_program_my_trading_fees(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("9.045%-9.045%")
|
||||
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
|
||||
@@ -81,8 +77,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fees_page_discount_program_total_discount(page: Page):
|
||||
def test_fees_page_discount_program_total_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("10%")
|
||||
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount0%")
|
||||
@@ -95,15 +93,19 @@ def test_fees_page_discount_program_total_discount(page: Page):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fees_page_referral_discount_program_referral_benefits(page: Page):
|
||||
def test_fees_page_referral_discount_program_referral_benefits(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(RUNNING_NOTIONAL_TAKER_VOLUME)).to_have_text("103")
|
||||
expect(page.get_by_test_id(EPOCHS_IN_REFERRAL_SET)).to_have_text("1")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fees_page_discount_program_discount(page: Page):
|
||||
def test_fees_page_discount_program_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1")
|
||||
expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2")
|
||||
@@ -119,8 +121,10 @@ def test_fees_page_discount_program_discount(page: Page):
|
||||
expect(page.get_by_test_id("your-referral-tier-0").nth(1)).to_have_text("Your tier")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
def test_fees_page_discount_program_fees_by_market(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
pinned = page.locator(PINNED_ROW_LOCATOR)
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
@@ -132,11 +136,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_deal_ticket_discount_program(
|
||||
page: Page, setup_market_with_referral_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(ORDER_SIZE).fill("1")
|
||||
page.get_by_test_id(ORDER_PRICE).fill("1")
|
||||
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-10%")
|
||||
@@ -155,12 +159,11 @@ def test_deal_ticket_discount_program(
|
||||
expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.09045 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fills_taker_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
expect(row.locator(COL_SIZE)).to_have_text("+1")
|
||||
@@ -171,13 +174,11 @@ def test_fills_taker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.04017 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fills_maker_discount_program(
|
||||
vega: VegaServiceNull,
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -189,11 +190,11 @@ def test_fills_maker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.035 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fills_maker_fee_tooltip_discount_program(
|
||||
vega: VegaServiceNull, page: Page, setup_market_with_referral_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -205,12 +206,11 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_1")
|
||||
def test_fills_taker_fee_tooltip_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
# tbd - tooltip is not visible without this wait
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from fees_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
@@ -16,62 +17,56 @@ from fixtures.market import setup_continuous_market
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(
|
||||
request, browser
|
||||
) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
# Setup market with referral discount program
|
||||
market = setup_continuous_market(vega_instance, custom_quantum=100000)
|
||||
vega_instance.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
yield vega_instance
|
||||
vega_instance.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega_instance)
|
||||
referral_set_id = list(vega_instance.list_referral_sets().keys())[0]
|
||||
vega_instance.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega_instance)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 2, 110)
|
||||
forward_time(vega_instance, True if _ < 2 - 1 else False)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page_instance:
|
||||
risk_accepted_setup(page_instance)
|
||||
auth_setup(vega_instance, page_instance)
|
||||
yield vega_instance, market, page_instance
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_referral_discount_program(vega: VegaServiceNull):
|
||||
market = setup_continuous_market(vega, custom_quantum=100000)
|
||||
vega.update_referral_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"minimum_epochs": 1,
|
||||
"referral_reward_factor": 0.1,
|
||||
"referral_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"minimum_epochs": 2,
|
||||
"referral_reward_factor": 0.2,
|
||||
"referral_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
staking_tiers=[
|
||||
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
|
||||
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
|
||||
],
|
||||
window_length=1,
|
||||
)
|
||||
vega.create_referral_set(key_name=MM_WALLET.name)
|
||||
next_epoch(vega=vega)
|
||||
referral_set_id = list(vega.list_referral_sets().keys())[0]
|
||||
vega.apply_referral_code(key_name="Key 1", id=referral_set_id)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega, "Key 1", market, "SIDE_BUY", 2, 110)
|
||||
forward_time(vega, True if _ < 2 - 1 else False)
|
||||
|
||||
return market
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
def test_fees_page_discount_program_my_trading_fees(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("8.04%-8.04%")
|
||||
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
|
||||
@@ -82,8 +77,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fees_page_discount_program_total_discount(page: Page):
|
||||
def test_fees_page_discount_program_total_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("20%")
|
||||
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount0%")
|
||||
@@ -96,15 +93,19 @@ def test_fees_page_discount_program_total_discount(page: Page):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fees_page_referral_discount_program_referral_benefits(page: Page):
|
||||
def test_fees_page_referral_discount_program_referral_benefits(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(RUNNING_NOTIONAL_TAKER_VOLUME)).to_have_text("207")
|
||||
expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).not_to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fees_page_discount_program_discount(page: Page):
|
||||
def test_fees_page_discount_program_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1")
|
||||
expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2")
|
||||
@@ -120,8 +121,10 @@ def test_fees_page_discount_program_discount(page: Page):
|
||||
expect(page.get_by_test_id("your-referral-tier-1").nth(1)).to_have_text("Your tier")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
def test_fees_page_discount_program_fees_by_market(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
pinned = page.locator(PINNED_ROW_LOCATOR)
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
@@ -133,11 +136,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_deal_ticket_discount_program(
|
||||
page: Page, setup_market_with_referral_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(ORDER_SIZE).fill("1")
|
||||
page.get_by_test_id(ORDER_PRICE).fill("1")
|
||||
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-20%")
|
||||
@@ -156,12 +159,11 @@ def test_deal_ticket_discount_program(
|
||||
expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.0804 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fills_taker_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
expect(row.locator(COL_SIZE)).to_have_text("+2")
|
||||
@@ -172,13 +174,11 @@ def test_fills_taker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("4.1607 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fills_maker_discount_program(
|
||||
vega: VegaServiceNull,
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -190,11 +190,11 @@ def test_fills_maker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("4.14 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fills_maker_fee_tooltip_discount_program(
|
||||
vega: VegaServiceNull, page: Page, setup_market_with_referral_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -206,12 +206,11 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_referral_tier_2")
|
||||
def test_fills_taker_fee_tooltip_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_referral_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_referral_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
# tbd - tooltip is not visible without this wait
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from fees_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
@@ -16,49 +17,45 @@ from fixtures.market import setup_continuous_market
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(
|
||||
request, browser
|
||||
) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
# Setup the market with volume discount program
|
||||
market = setup_continuous_market(vega_instance, custom_quantum=100000)
|
||||
vega_instance.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
yield vega_instance
|
||||
next_epoch(vega=vega_instance)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega_instance, True if _ < 2 - 1 else False)
|
||||
|
||||
# Initialize and setup page
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
yield vega_instance, market, page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_volume_discount_program(vega: VegaServiceNull):
|
||||
market = setup_continuous_market(vega, custom_quantum=100000)
|
||||
vega.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
for _ in range(2):
|
||||
submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega, True if _ < 2 - 1 else False)
|
||||
return market
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
def test_fees_page_discount_program_my_trading_fees(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("9.045%-9.045%")
|
||||
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
|
||||
@@ -69,10 +66,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fees_page_discount_program_total_discount(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("10%")
|
||||
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount10%")
|
||||
@@ -85,20 +82,20 @@ def test_fees_page_discount_program_total_discount(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fees_page_volume_discount_program_my_current_volume(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(PAST_EPOCHS_VOLUME)).to_have_text("103")
|
||||
|
||||
expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).to_have_text("97")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fees_page_discount_program_discount(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1")
|
||||
expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2")
|
||||
@@ -111,8 +108,10 @@ def test_fees_page_discount_program_discount(
|
||||
expect(page.get_by_test_id("your-volume-tier-0").nth(1)).to_have_text("Your tier")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
def test_fees_page_discount_program_fees_by_market(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
pinned = page.locator(PINNED_ROW_LOCATOR)
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
@@ -124,11 +123,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_deal_ticket_discount_program_testing(
|
||||
page: Page, setup_market_with_volume_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(ORDER_SIZE).fill("1")
|
||||
page.get_by_test_id(ORDER_PRICE).fill("1")
|
||||
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-10%")
|
||||
@@ -149,9 +148,10 @@ def test_deal_ticket_discount_program_testing(
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fills_taker_discount_program(
|
||||
page: Page, setup_market_with_volume_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
expect(row.locator(COL_SIZE)).to_have_text("+1")
|
||||
@@ -164,9 +164,10 @@ def test_fills_taker_discount_program(
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fills_maker_discount_program(
|
||||
page: Page, setup_market_with_volume_discount_program, vega: VegaServiceNull
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -178,11 +179,11 @@ def test_fills_maker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("1.035 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fills_maker_fee_tooltip_discount_program(
|
||||
vega: VegaServiceNull, page: Page, setup_market_with_volume_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -194,12 +195,11 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_1")
|
||||
def test_fills_taker_fee_tooltip_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_volume_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
# tbd - tooltip is not visible without this wait
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from fees_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
@@ -14,51 +15,47 @@ from conftest import (
|
||||
from actions.utils import next_epoch, change_keys, forward_time
|
||||
from fixtures.market import setup_continuous_market
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(
|
||||
request, browser
|
||||
) -> Generator[Tuple[VegaServiceNull, str, Page], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(
|
||||
lambda: cleanup_container(vega_instance)
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
# Setup the market with volume discount program
|
||||
market = setup_continuous_market(vega_instance, custom_quantum=100000)
|
||||
vega_instance.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
yield vega_instance
|
||||
next_epoch(vega=vega_instance)
|
||||
|
||||
for _ in range(3):
|
||||
submit_order(vega_instance, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega_instance, True if _ < 3 - 1 else False)
|
||||
|
||||
# Initialize page and apply setups
|
||||
with init_page(vega_instance, browser, request) as page_instance:
|
||||
risk_accepted_setup(page_instance)
|
||||
auth_setup(vega_instance, page_instance)
|
||||
yield vega_instance, market, page_instance
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_volume_discount_program(vega: VegaServiceNull):
|
||||
market = setup_continuous_market(vega, custom_quantum=100000)
|
||||
vega.update_volume_discount_program(
|
||||
proposal_key=MM_WALLET.name,
|
||||
benefit_tiers=[
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 100,
|
||||
"volume_discount_factor": 0.1,
|
||||
},
|
||||
{
|
||||
"minimum_running_notional_taker_volume": 200,
|
||||
"volume_discount_factor": 0.2,
|
||||
},
|
||||
],
|
||||
window_length=7,
|
||||
)
|
||||
next_epoch(vega=vega)
|
||||
|
||||
for _ in range(3):
|
||||
submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110)
|
||||
forward_time(vega, True if _ < 3 - 1 else False)
|
||||
|
||||
return market
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
def test_fees_page_discount_program_my_trading_fees(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text("8.04%-8.04%")
|
||||
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
|
||||
@@ -69,8 +66,10 @@ def test_fees_page_discount_program_my_trading_fees(page: Page):
|
||||
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fees_page_discount_program_total_discount(page: Page):
|
||||
def test_fees_page_discount_program_total_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text("20%")
|
||||
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text("Volume discount20%")
|
||||
@@ -83,15 +82,19 @@ def test_fees_page_discount_program_total_discount(page: Page):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fees_page_volume_discount_program_my_current_volume(page: Page):
|
||||
def test_fees_page_volume_discount_program_my_current_volume(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(PAST_EPOCHS_VOLUME)).to_have_text("206")
|
||||
expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).not_to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fees_page_discount_program_discount(page: Page):
|
||||
def test_fees_page_discount_program_discount(
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1")
|
||||
expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2")
|
||||
@@ -104,8 +107,8 @@ def test_fees_page_discount_program_discount(page: Page):
|
||||
expect(page.get_by_test_id("your-volume-tier-1").nth(1)).to_have_text("Your tier")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
def test_fees_page_discount_program_fees_by_market(setup_environment):
|
||||
vega, market, page = setup_environment
|
||||
page.goto("/#/fees")
|
||||
pinned = page.locator(PINNED_ROW_LOCATOR)
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
@@ -117,12 +120,11 @@ def test_fees_page_discount_program_fees_by_market(page: Page):
|
||||
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_deal_ticket_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_volume_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(ORDER_SIZE).fill("1")
|
||||
page.get_by_test_id(ORDER_PRICE).fill("1")
|
||||
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text("-20%")
|
||||
@@ -141,12 +143,11 @@ def test_deal_ticket_discount_program(
|
||||
expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text("0.0804 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fills_taker_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_volume_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
expect(row.locator(COL_SIZE)).to_have_text("+1")
|
||||
@@ -159,13 +160,11 @@ def test_fills_taker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("2.08035 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fills_maker_discount_program(
|
||||
vega: VegaServiceNull,
|
||||
page: Page,
|
||||
setup_market_with_volume_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -177,11 +176,11 @@ def test_fills_maker_discount_program(
|
||||
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text("2.07 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fills_maker_fee_tooltip_discount_program(
|
||||
vega, page: Page, setup_market_with_volume_discount_program
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
change_keys(page, vega, MM_WALLET.name)
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
@@ -193,12 +192,11 @@ def test_fills_maker_fee_tooltip_discount_program(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_fees_volume_tier_2")
|
||||
def test_fills_taker_fee_tooltip_discount_program(
|
||||
page: Page,
|
||||
setup_market_with_volume_discount_program,
|
||||
):
|
||||
page.goto(f"/#/markets/{setup_market_with_volume_discount_program}")
|
||||
setup_environment: Tuple[VegaServiceNull, str, Page],
|
||||
) -> None:
|
||||
vega, market, page = setup_environment
|
||||
page.goto(f"/#/markets/{market}")
|
||||
page.get_by_test_id(FILLS).click()
|
||||
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
|
||||
# tbd - tooltip is not visible without this wait
|
||||
|
||||
@@ -37,19 +37,16 @@ def validate_info_section(page: Page, fields: [[str, str]]):
|
||||
for rowNumber, field in enumerate(fields):
|
||||
name, value = field
|
||||
expect(
|
||||
page.get_by_test_id(
|
||||
"key-value-table-row").nth(rowNumber).locator("dt")
|
||||
page.get_by_test_id("key-value-table-row").nth(rowNumber).locator("dt")
|
||||
).to_contain_text(name)
|
||||
expect(
|
||||
page.get_by_test_id(
|
||||
"key-value-table-row").nth(rowNumber).locator("dd")
|
||||
page.get_by_test_id("key-value-table-row").nth(rowNumber).locator("dd")
|
||||
).to_contain_text(value)
|
||||
|
||||
|
||||
def test_market_info_current_fees(page: Page):
|
||||
# 6002-MDET-101
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Current fees").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Current fees").click()
|
||||
fields = [
|
||||
["Maker Fee", "10%"],
|
||||
["Infrastructure Fee", "0.05%"],
|
||||
@@ -61,8 +58,7 @@ def test_market_info_current_fees(page: Page):
|
||||
|
||||
def test_market_info_market_price(page: Page):
|
||||
# 6002-MDET-102
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Market price").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Market price").click()
|
||||
fields = [
|
||||
["Mark Price", "107.50"],
|
||||
["Best Bid Price", "101.50"],
|
||||
@@ -71,11 +67,10 @@ def test_market_info_market_price(page: Page):
|
||||
]
|
||||
validate_info_section(page, fields)
|
||||
|
||||
|
||||
def test_market_info_market_volume(page: Page):
|
||||
#TODO: remove skip once volume is fixed
|
||||
""" def test_market_info_market_volume(page: Page):
|
||||
# 6002-MDET-103
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Market volume").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Market volume").click()
|
||||
fields = [
|
||||
["24 Hour Volume", "0 (0 )"],
|
||||
["Open Interest", "1"],
|
||||
@@ -84,12 +79,13 @@ def test_market_info_market_volume(page: Page):
|
||||
["Best Static Bid Volume", "1"],
|
||||
["Best Static Offer Volume", "1"],
|
||||
]
|
||||
validate_info_section(page, fields)
|
||||
validate_info_section(page, fields) """
|
||||
|
||||
|
||||
def test_market_info_liquidation_strategy(page: Page):
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Liquidation strategy").click()
|
||||
"Liquidation strategy"
|
||||
).click()
|
||||
fields = [
|
||||
["Disposal Fraction", "1"],
|
||||
["Disposal Time Step", "1"],
|
||||
@@ -101,16 +97,14 @@ def test_market_info_liquidation_strategy(page: Page):
|
||||
|
||||
def test_market_info_liquidation(page: Page):
|
||||
# 6002-MDET-104
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Liquidations").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Liquidations").click()
|
||||
fields = [["Insurance Pool Balance", "0.00 tDAI"]]
|
||||
validate_info_section(page, fields)
|
||||
|
||||
|
||||
def test_market_info_key_details(page: Page, vega: VegaServiceNull):
|
||||
# 6002-MDET-201
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Key details").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Key details").click()
|
||||
market_id = vega.find_market_id("BTC:DAI_2023")
|
||||
short_market_id = market_id[:6] + "…" + market_id[-4:]
|
||||
fields = [
|
||||
@@ -156,8 +150,7 @@ def test_market_info_oracle(page: Page):
|
||||
|
||||
def test_market_info_settlement_asset(page: Page, vega: VegaServiceNull):
|
||||
# 6002-MDET-206
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Settlement asset").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Settlement asset").click()
|
||||
tdai_id = vega.find_asset_id("tDAI")
|
||||
tdai_id_short = tdai_id[:6] + "…" + tdai_id[-4:]
|
||||
fields = [
|
||||
@@ -211,8 +204,7 @@ def test_market_info_margin_scaling_factors(page: Page):
|
||||
|
||||
def test_market_info_risk_factors(page: Page):
|
||||
# 6002-MDET-210
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Risk factors").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Risk factors").click()
|
||||
fields = [
|
||||
["Long", "0.05153"],
|
||||
["Short", "0.05422"],
|
||||
@@ -232,8 +224,7 @@ def test_market_info_price_monitoring_bounds(page: Page):
|
||||
expect(page.locator("p.col-span-1").nth(0)).to_contain_text(
|
||||
"99.9999% probability price bounds"
|
||||
)
|
||||
expect(page.locator("p.col-span-1").nth(1)
|
||||
).to_contain_text("Within 86,400 seconds")
|
||||
expect(page.locator("p.col-span-1").nth(1)).to_contain_text("Within 86,400 seconds")
|
||||
fields = [
|
||||
["Highest Price", "138.66685 BTC"],
|
||||
["Lowest Price", "83.11038 BTC"],
|
||||
@@ -254,7 +245,7 @@ def test_market_info_liquidity_monitoring_parameters(page: Page):
|
||||
|
||||
|
||||
# Liquidity resolves to 3 results
|
||||
def test_market_info_liquidit(page: Page):
|
||||
def test_market_info_liquidity(page: Page):
|
||||
# 6002-MDET-213
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Liquidity", exact=True
|
||||
@@ -283,17 +274,14 @@ def test_market_info_proposal(page: Page, vega: VegaServiceNull):
|
||||
# 6002-MDET-301
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Proposal").click()
|
||||
first_link = (
|
||||
page.get_by_test_id(
|
||||
"accordion-content").get_by_test_id("external-link").first
|
||||
page.get_by_test_id("accordion-content").get_by_test_id("external-link").first
|
||||
)
|
||||
second_link = (
|
||||
page.get_by_test_id(
|
||||
"accordion-content").get_by_test_id("external-link").nth(1)
|
||||
page.get_by_test_id("accordion-content").get_by_test_id("external-link").nth(1)
|
||||
)
|
||||
expect(first_link).to_have_text("View governance proposal")
|
||||
expect(first_link).to_have_attribute(
|
||||
"href", re.compile(
|
||||
rf'(\/proposals\/{vega.find_market_id("BTC:DAI_2023")})')
|
||||
"href", re.compile(rf'(\/proposals\/{vega.find_market_id("BTC:DAI_2023")})')
|
||||
)
|
||||
expect(second_link).to_have_text("Propose a change to market")
|
||||
|
||||
@@ -304,12 +292,10 @@ def test_market_info_proposal(page: Page, vega: VegaServiceNull):
|
||||
|
||||
|
||||
def test_market_info_succession_line(page: Page, vega: VegaServiceNull):
|
||||
page.get_by_test_id(market_title_test_id).get_by_text(
|
||||
"Succession line").click()
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click()
|
||||
market_id = vega.find_market_id("BTC:DAI_2023")
|
||||
succession_line = page.get_by_test_id("succession-line-item")
|
||||
expect(succession_line.get_by_test_id(
|
||||
"external-link")).to_have_text("BTC:DAI_2023")
|
||||
expect(succession_line.get_by_test_id("external-link")).to_have_text("BTC:DAI_2023")
|
||||
expect(succession_line.get_by_test_id("external-link")).to_have_attribute(
|
||||
"href", re.compile(rf"(\/proposals\/{market_id})")
|
||||
)
|
||||
|
||||
@@ -15,13 +15,13 @@ def test_market_selector(continuous_market, page: Page):
|
||||
# 6001-MARK-025
|
||||
btc_market = page.locator('[data-testid="market-selector-list"] a')
|
||||
expect(btc_market.locator("h3")).to_have_text("BTC:DAI_2023Futr")
|
||||
expect(btc_market.locator('[data-testid="market-selector-volume"]')).to_have_text(
|
||||
"1"
|
||||
)
|
||||
# tbd - 5465
|
||||
# expect(btc_market.locator('[data-testid="market-selector-volume"]')).to_have_text(
|
||||
# "1"
|
||||
# )
|
||||
expect(btc_market.locator('[data-testid="market-selector-price"]')).to_have_text(
|
||||
"107.50 tDAI"
|
||||
)
|
||||
expect(btc_market.locator("span.rounded-md.leading-none")).to_be_visible()
|
||||
expect(btc_market.locator("span.rounded-md.leading-none")).to_have_text("Futr")
|
||||
expect(btc_market.locator(
|
||||
'[data-testid="sparkline-svg"]')).not_to_be_visible
|
||||
expect(btc_market.locator('[data-testid="sparkline-svg"]')).not_to_be_visible
|
||||
|
||||
@@ -10,228 +10,218 @@ order_tab = "tab-orders"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser):
|
||||
# Initialize Vega with cleanup
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function
|
||||
yield vega_instance
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
# Setup multiple markets
|
||||
markets = {
|
||||
"market_1": setup_continuous_market(vega_instance, custom_market_name="market-1"),
|
||||
"market_2": setup_continuous_market(vega_instance, custom_market_name="market-2"),
|
||||
"market_3": setup_continuous_market(vega_instance, custom_market_name="market-3"),
|
||||
"market_4": setup_continuous_market(vega_instance, custom_market_name="market-4"),
|
||||
"market_5": setup_simple_market(vega_instance, custom_market_name="market-5"),
|
||||
}
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def markets(vega: VegaServiceNull):
|
||||
market_1 = setup_continuous_market(
|
||||
vega,
|
||||
custom_market_name="market-1",
|
||||
)
|
||||
market_2 = setup_continuous_market(
|
||||
vega,
|
||||
custom_market_name="market-2",
|
||||
)
|
||||
market_3 = setup_continuous_market(
|
||||
vega,
|
||||
custom_market_name="market-3",
|
||||
)
|
||||
market_4 = setup_continuous_market(
|
||||
vega,
|
||||
custom_market_name="market-4",
|
||||
)
|
||||
market_5 = setup_simple_market(
|
||||
vega,
|
||||
custom_market_name="market-5",
|
||||
)
|
||||
# Execute a series of orders across different markets
|
||||
# Example for market_1 orders, adjust as necessary for your test scenario
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_1"],
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=130,
|
||||
)
|
||||
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_1,
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=130,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_1"],
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=88,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_1,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=88,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_1"],
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=88,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_1,
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=100,
|
||||
price=88,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_1"],
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=1e10,
|
||||
price=130,
|
||||
wait=False,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_1,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=1e10,
|
||||
price=130,
|
||||
wait=False,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_2"],
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_BUY",
|
||||
volume=100,
|
||||
price=104,
|
||||
)
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_3"],
|
||||
time_in_force="TIME_IN_FORCE_GTT",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=120,
|
||||
expires_at=vega_instance.get_blockchain_time() + 5 * 1e9,
|
||||
)
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_2,
|
||||
time_in_force="TIME_IN_FORCE_IOC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_BUY",
|
||||
volume=100,
|
||||
price=104,
|
||||
)
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_3,
|
||||
time_in_force="TIME_IN_FORCE_GTT",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=120,
|
||||
expires_at=vega.get_blockchain_time() + 5 * 1e9,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
market_id=markets["market_4"],
|
||||
trading_key="Key 1",
|
||||
side="SIDE_BUY",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=5),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=20,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
market_id=market_4,
|
||||
trading_key="Key 1",
|
||||
side="SIDE_BUY",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_MID", offset=5),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=20,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
market_id=markets["market_4"],
|
||||
trading_key="Key 1",
|
||||
side="SIDE_BUY",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_BID", offset=10),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=40,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
market_id=market_4,
|
||||
trading_key="Key 1",
|
||||
side="SIDE_BUY",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_BID", offset=10),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=40,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
market_id=markets["market_4"],
|
||||
trading_key="Key 1",
|
||||
side="SIDE_SELL",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=60,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
market_id=market_4,
|
||||
trading_key="Key 1",
|
||||
side="SIDE_SELL",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15),
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=60,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
market_id=markets["market_5"],
|
||||
trading_key="Key 1",
|
||||
side="SIDE_SELL",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15),
|
||||
wait=False,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=60,
|
||||
)
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.forward("2s")
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
market_id=market_5,
|
||||
trading_key="Key 1",
|
||||
side="SIDE_SELL",
|
||||
order_type="TYPE_LIMIT",
|
||||
pegged_order=PeggedOrder(reference="PEGGED_REFERENCE_BEST_ASK", offset=15),
|
||||
wait=False,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
volume=60,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_2"],
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=150,
|
||||
)
|
||||
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.forward("2s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_2"],
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=160,
|
||||
)
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_2,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=150,
|
||||
)
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_2,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_SELL",
|
||||
volume=10,
|
||||
price=160,
|
||||
)
|
||||
vega_instance.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=markets["market_3"],
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_BUY",
|
||||
volume=10,
|
||||
price=60,
|
||||
)
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
vega.submit_order(
|
||||
trading_key="Key 1",
|
||||
market_id=market_3,
|
||||
time_in_force="TIME_IN_FORCE_GTC",
|
||||
order_type="TYPE_LIMIT",
|
||||
side="SIDE_BUY",
|
||||
volume=10,
|
||||
price=60,
|
||||
)
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
vega_instance.wait_fn(1)
|
||||
vega_instance.wait_for_total_catchup()
|
||||
# Initialize page and setup
|
||||
|
||||
yield vega_instance, markets
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
def page(setup_environment, browser, request):
|
||||
vega_instance, markets = setup_environment
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto("/")
|
||||
page.get_by_test_id("All").click()
|
||||
yield page
|
||||
|
||||
|
||||
# close toast that is still opened after test
|
||||
@pytest.fixture(autouse=True)
|
||||
def after_each(page: Page):
|
||||
yield
|
||||
@@ -381,7 +371,8 @@ def test_order_status_pegged_mid(page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_amend_order(vega: VegaServiceNull, page: Page):
|
||||
def test_order_amend_order(setup_environment, page:Page):
|
||||
vega, markets = setup_environment
|
||||
# 7002-SORD-053
|
||||
# 7003-MORD-012
|
||||
# 7003-MORD-014
|
||||
@@ -402,13 +393,13 @@ def test_order_amend_order(vega: VegaServiceNull, page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_cancel_single_order(vega: VegaServiceNull, page: Page):
|
||||
def test_order_cancel_single_order(setup_environment, page:Page):
|
||||
vega, markets = setup_environment
|
||||
# 7003-MORD-009
|
||||
# 7003-MORD-010
|
||||
# 7003-MORD-011
|
||||
# 7002-SORD-043
|
||||
page.get_by_test_id("cancel").first.click()
|
||||
|
||||
wait_for_toast_confirmation(page, timeout=5000)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
@@ -420,7 +411,8 @@ def test_order_cancel_single_order(vega: VegaServiceNull, page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_cancel_all_orders(vega: VegaServiceNull, page: Page):
|
||||
def test_order_cancel_all_orders(setup_environment, page:Page):
|
||||
vega, markets = setup_environment
|
||||
# 7003-MORD-009
|
||||
# 7003-MORD-010
|
||||
# 7003-MORD-011
|
||||
|
||||
@@ -57,7 +57,7 @@ class TestPerpetuals:
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
page.get_by_test_id("Funding payments").click()
|
||||
row = page.locator(row_selector)
|
||||
expect(row.locator(col_amount)).to_have_text("9.00 tDAI")
|
||||
expect(row.locator(col_amount)).to_have_text("4.45 tDAI")
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_payment_loss(self, perps_market, page: Page, vega):
|
||||
@@ -65,7 +65,7 @@ class TestPerpetuals:
|
||||
change_keys(page, vega, "market_maker")
|
||||
page.get_by_test_id("Funding payments").click()
|
||||
row = page.locator(row_selector)
|
||||
expect(row.locator(col_amount)).to_have_text("-27.00 tDAI")
|
||||
expect(row.locator(col_amount)).to_have_text("-13.35 tDAI")
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_header(self, perps_market, page: Page):
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import pytest
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
from typing import Tuple, Generator
|
||||
from rewards_test_ids import *
|
||||
from playwright.sync_api import Page, expect
|
||||
from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container
|
||||
from conftest import (
|
||||
init_vega,
|
||||
init_page,
|
||||
auth_setup,
|
||||
risk_accepted_setup,
|
||||
cleanup_container,
|
||||
)
|
||||
from fixtures.market import setup_continuous_market
|
||||
from actions.utils import next_epoch, change_keys
|
||||
from wallet_config import MM_WALLET
|
||||
@@ -10,22 +17,20 @@ from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega, PARTY_B)
|
||||
yield page
|
||||
tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega_instance, PARTY_B)
|
||||
yield page, tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
tDAI_market = setup_continuous_market(vega)
|
||||
PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega)
|
||||
@@ -83,39 +88,39 @@ def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
return tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0")
|
||||
def test_network_reward_pot(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("50.00 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0")
|
||||
def test_reward_multiplier(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("1x")
|
||||
expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0")
|
||||
def test_hoarder_bonus(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(HOARDER_BONUS_TOTAL_HOARDED)).to_contain_text(
|
||||
"5,000,000"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_0")
|
||||
def test_reward_history(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
page.locator('[name="fromEpoch"]').fill("1")
|
||||
expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text(
|
||||
"100.00100.00%"
|
||||
)
|
||||
expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("100.00")
|
||||
page.get_by_test_id(EARNED_BY_ME_BUTTON).click()
|
||||
expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("50.00")
|
||||
expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("50.00")
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import pytest
|
||||
from rewards_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
from playwright.sync_api import Page, expect
|
||||
from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container
|
||||
from conftest import (
|
||||
init_vega,
|
||||
init_page,
|
||||
auth_setup,
|
||||
risk_accepted_setup,
|
||||
cleanup_container,
|
||||
)
|
||||
from fixtures.market import setup_continuous_market
|
||||
from actions.utils import next_epoch, change_keys
|
||||
from wallet_config import MM_WALLET
|
||||
@@ -10,23 +17,21 @@ from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
|
||||
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
|
||||
tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega_instance, PARTY_B)
|
||||
yield page, tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega, PARTY_B)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
tDAI_market = setup_continuous_market(vega)
|
||||
PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega)
|
||||
@@ -135,31 +140,35 @@ def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
return tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1")
|
||||
def test_network_reward_pot(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("166.66666 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1")
|
||||
def test_reward_multiplier(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("2x")
|
||||
expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("2x")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1")
|
||||
def test_hoarder_bonus(page: Page):
|
||||
def test_hoarder_bonus(
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(HOARDER_BONUS_TOTAL_HOARDED)).to_contain_text(
|
||||
"16,666,666"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_hoarder_tier_1")
|
||||
def test_reward_history(page: Page):
|
||||
def test_reward_history(
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
page.locator('[name="fromEpoch"]').fill("1")
|
||||
expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text(
|
||||
"299.99999100.00%"
|
||||
@@ -170,4 +179,4 @@ def test_reward_history(page: Page):
|
||||
page.get_by_test_id(EARNED_BY_ME_BUTTON).click()
|
||||
expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text(
|
||||
"166.66666"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from rewards_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
from playwright.sync_api import Page, expect
|
||||
from conftest import (
|
||||
@@ -16,23 +17,23 @@ from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
|
||||
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega_instance, PARTY_B)
|
||||
yield page, tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega, PARTY_B)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
tDAI_market = setup_continuous_market(vega)
|
||||
PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega)
|
||||
@@ -90,25 +91,23 @@ def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
return tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_0")
|
||||
def test_network_reward_pot(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("50.00 tDAI")
|
||||
page.pause()
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_0")
|
||||
def test_reward_multiplier(
|
||||
page: Page,
|
||||
):
|
||||
page.pause()
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("1x")
|
||||
expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
|
||||
|
||||
""" @pytest.mark.xdist_group(name="test_rewards_activity_tier_0")
|
||||
"""
|
||||
def test_activity_streak(
|
||||
page: Page,
|
||||
):
|
||||
@@ -117,7 +116,6 @@ def test_activity_streak(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_0")
|
||||
def test_reward_history(
|
||||
page: Page,
|
||||
):
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import pytest
|
||||
from rewards_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
from playwright.sync_api import Page, expect
|
||||
from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container
|
||||
from conftest import (
|
||||
init_vega,
|
||||
init_page,
|
||||
auth_setup,
|
||||
risk_accepted_setup,
|
||||
cleanup_container,
|
||||
)
|
||||
from fixtures.market import setup_continuous_market
|
||||
from actions.utils import next_epoch, change_keys
|
||||
from wallet_config import MM_WALLET
|
||||
@@ -10,22 +17,21 @@ from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
|
||||
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega_instance, PARTY_B)
|
||||
yield page, tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega, PARTY_B)
|
||||
yield page
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
tDAI_market = setup_continuous_market(vega)
|
||||
PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega)
|
||||
@@ -128,34 +134,35 @@ def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
return tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_1")
|
||||
def test_network_reward_pot(page: Page):
|
||||
|
||||
def test_network_reward_pot(
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("116.66666 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_1")
|
||||
def test_reward_multiplier(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("2x")
|
||||
expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("2x")
|
||||
expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_1")
|
||||
def test_activity_streak(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(EPOCH_STREAK)).to_have_text(
|
||||
"Active trader: 7 epochs so far (Tier 1 as of last epoch)"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_1")
|
||||
def test_reward_history(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
page.locator('[name="fromEpoch"]').fill("1")
|
||||
expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text(
|
||||
"300.00100.00%"
|
||||
@@ -167,10 +174,10 @@ def test_reward_history(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_activity_tier_1")
|
||||
def test_redeem(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
page.get_by_test_id("redeem-rewards-button").click()
|
||||
available_to_withdraw = page.get_by_test_id(
|
||||
"available-to-withdraw-value"
|
||||
@@ -184,4 +191,4 @@ def test_redeem(
|
||||
)
|
||||
|
||||
page.get_by_test_id("use-max-button").first.click()
|
||||
expect(page.get_by_test_id(TRANSFER_AMOUNT)).to_have_text(available_to_withdraw)
|
||||
expect(page.get_by_test_id(TRANSFER_AMOUNT)).to_have_text(available_to_withdraw)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
from rewards_test_ids import *
|
||||
from typing import Tuple, Generator
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
from playwright.sync_api import Page, expect
|
||||
from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container
|
||||
@@ -9,24 +10,20 @@ from wallet_config import MM_WALLET
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
def setup_environment(request, browser) -> Generator[Tuple[Page, str, str], None, None]:
|
||||
with init_vega(request) as vega_instance:
|
||||
request.addfinalizer(lambda: cleanup_container(vega_instance))
|
||||
yield vega_instance
|
||||
|
||||
tDAI_market, tDAI_asset_id = setup_market_with_reward_program(vega_instance)
|
||||
|
||||
with init_page(vega_instance, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega_instance, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega_instance, PARTY_B)
|
||||
yield page, tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto(REWARDS_URL)
|
||||
change_keys(page, vega, PARTY_B)
|
||||
yield page
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
tDAI_market = setup_continuous_market(vega)
|
||||
PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega)
|
||||
@@ -140,16 +137,18 @@ def setup_market_with_reward_program(vega: VegaServiceNull):
|
||||
return tDAI_market, tDAI_asset_id
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_combo_tier_1")
|
||||
def test_network_reward_pot( page: Page
|
||||
):
|
||||
|
||||
def test_network_reward_pot( setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("183.33333 tDAI")
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_combo_tier_1")
|
||||
|
||||
def test_reward_multiplier(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("4x")
|
||||
expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text(
|
||||
"2x"
|
||||
@@ -159,10 +158,11 @@ def test_reward_multiplier(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.xdist_group(name="test_rewards_combo_tier_1")
|
||||
|
||||
def test_reward_history(
|
||||
page: Page,
|
||||
):
|
||||
setup_environment: Tuple[Page, str, str],
|
||||
) -> None:
|
||||
page, tDAI_market, tDAI_asset_id = setup_environment
|
||||
page.locator('[name="fromEpoch"]').fill("1")
|
||||
expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text(
|
||||
"299.99999100.00%"
|
||||
|
||||
@@ -97,10 +97,13 @@ def test_banners(vega: VegaServiceNull, page: Page):
|
||||
settlement_price=100,
|
||||
market_id=parent_market_id,
|
||||
)
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
successor_name = "successor market name"
|
||||
propose_successor(vega, parent_market_id, tdai_id, successor_name)
|
||||
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
page.reload()
|
||||
# Check that the banners notifying about the successor proposal and market has been settled are shown
|
||||
banner = page.get_by_test_id(market_banner)
|
||||
expect(banner).to_be_attached()
|
||||
|
||||
@@ -299,10 +299,10 @@ def test_leaderboard(competitions_page: Page, setup_teams_and_games):
|
||||
|
||||
|
||||
def test_game_card(competitions_page: Page):
|
||||
expect(competitions_page.get_by_test_id("active-rewards-card")).to_have_count(2)
|
||||
expect(competitions_page.get_by_test_id("active-rewards-card")).to_have_count(1)
|
||||
game_1 = competitions_page.get_by_test_id("active-rewards-card").first
|
||||
expect(game_1).to_be_visible()
|
||||
expect(game_1.get_by_test_id("entity-scope")).to_have_text("Individual")
|
||||
expect(game_1.get_by_test_id("entity-scope")).to_have_text("Team")
|
||||
expect(game_1.get_by_test_id("locked-for")).to_have_text("1 epoch")
|
||||
expect(game_1.get_by_test_id("reward-value")).to_have_text("100.00")
|
||||
expect(game_1.get_by_test_id("reward-asset")).to_have_text("VEGA")
|
||||
@@ -311,7 +311,7 @@ def test_game_card(competitions_page: Page):
|
||||
"Price maker fees paid • tDAI"
|
||||
)
|
||||
expect(game_1.get_by_test_id("assessed-over")).to_have_text("15 epochs")
|
||||
expect(game_1.get_by_test_id("scope")).to_have_text("In team")
|
||||
expect(game_1.get_by_test_id("scope")).to_have_text("All teams")
|
||||
expect(game_1.get_by_test_id("staking-requirement")).to_have_text("0.00")
|
||||
expect(game_1.get_by_test_id("average-position")).to_have_text("0.00")
|
||||
|
||||
|
||||
@@ -25,8 +25,12 @@ fragment GameFields on Game {
|
||||
}
|
||||
}
|
||||
|
||||
query Games($epochFrom: Int) {
|
||||
games(epochFrom: $epochFrom, entityScope: ENTITY_SCOPE_TEAMS) {
|
||||
query Games($epochFrom: Int, $teamId: ID) {
|
||||
games(
|
||||
epochFrom: $epochFrom
|
||||
teamId: $teamId
|
||||
entityScope: ENTITY_SCOPE_TEAMS
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...GameFields
|
||||
|
||||
+4
-2
@@ -9,6 +9,7 @@ export type GameFieldsFragment = { __typename?: 'Game', id: string, epoch: numbe
|
||||
|
||||
export type GamesQueryVariables = Types.Exact<{
|
||||
epochFrom?: Types.InputMaybe<Types.Scalars['Int']>;
|
||||
teamId?: Types.InputMaybe<Types.Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
@@ -44,8 +45,8 @@ export const GameFieldsFragmentDoc = gql`
|
||||
}
|
||||
${TeamEntityFragmentDoc}`;
|
||||
export const GamesDocument = gql`
|
||||
query Games($epochFrom: Int) {
|
||||
games(epochFrom: $epochFrom, entityScope: ENTITY_SCOPE_TEAMS) {
|
||||
query Games($epochFrom: Int, $teamId: ID) {
|
||||
games(epochFrom: $epochFrom, teamId: $teamId, entityScope: ENTITY_SCOPE_TEAMS) {
|
||||
edges {
|
||||
node {
|
||||
...GameFields
|
||||
@@ -68,6 +69,7 @@ export const GamesDocument = gql`
|
||||
* const { data, loading, error } = useGamesQuery({
|
||||
* variables: {
|
||||
* epochFrom: // value for 'epochFrom'
|
||||
* teamId: // value for 'teamId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@@ -51,6 +51,7 @@ export const useGames = (teamId?: string, epochFrom?: number): GamesData => {
|
||||
const { data, loading, error } = useGamesQuery({
|
||||
variables: {
|
||||
epochFrom: from,
|
||||
teamId: teamId,
|
||||
},
|
||||
skip: !from,
|
||||
fetchPolicy: 'cache-and-network',
|
||||
|
||||
@@ -194,11 +194,11 @@ describe('isScopedToTeams', () => {
|
||||
undefined,
|
||||
makeDispatchStrategy(
|
||||
EntityScope.ENTITY_SCOPE_INDIVIDUALS,
|
||||
IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM // individual in teams
|
||||
IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM // individual in teams but not a team game
|
||||
),
|
||||
'RecurringTransfer'
|
||||
),
|
||||
true,
|
||||
false,
|
||||
],
|
||||
[
|
||||
makeReward(
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
TransferStatus,
|
||||
type DispatchStrategy,
|
||||
EntityScope,
|
||||
IndividualScope,
|
||||
MarketState,
|
||||
AccountType,
|
||||
} from '@vegaprotocol/types';
|
||||
@@ -75,20 +74,11 @@ export const isActiveReward = (node: RewardTransfer, currentEpoch: number) => {
|
||||
|
||||
/**
|
||||
* Checks if given reward (transfer) is scoped to teams.
|
||||
*
|
||||
* A reward is scoped to teams if it's entity scope is set to teams or
|
||||
* if the scope is set to individuals but the individuals are in a team.
|
||||
*/
|
||||
export const isScopedToTeams = (node: EnrichedRewardTransfer) =>
|
||||
// scoped to teams
|
||||
node.transfer.kind.dispatchStrategy?.entityScope ===
|
||||
EntityScope.ENTITY_SCOPE_TEAMS ||
|
||||
// or to individuals
|
||||
(node.transfer.kind.dispatchStrategy?.entityScope ===
|
||||
EntityScope.ENTITY_SCOPE_INDIVIDUALS &&
|
||||
// but they have to be in a team
|
||||
node.transfer.kind.dispatchStrategy?.individualScope ===
|
||||
IndividualScope.INDIVIDUAL_SCOPE_IN_TEAM);
|
||||
EntityScope.ENTITY_SCOPE_TEAMS;
|
||||
|
||||
/** Retrieves rewards (transfers) */
|
||||
export const useRewards = ({
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
ProtocolUpgradeInProgressNotification,
|
||||
ProtocolUpgradeProposalNotification,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { ViewingBanner } from '../components/viewing-banner';
|
||||
import { Telemetry } from '../components/telemetry';
|
||||
import { SSRLoader } from './ssr-loader';
|
||||
import { PartyActiveOrdersHandler } from './party-active-orders-handler';
|
||||
@@ -77,7 +76,6 @@ function AppBody({ Component }: AppProps) {
|
||||
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
|
||||
/>
|
||||
<ProtocolUpgradeInProgressNotification />
|
||||
<ViewingBanner />
|
||||
</div>
|
||||
<div data-testid={`pathname-${location.pathname}`}>
|
||||
<Component />
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '@vegaprotocol/web3';
|
||||
import { WelcomeDialog } from '../components/welcome-dialog';
|
||||
import { VegaWalletConnectDialog } from '../components/vega-wallet-connect-dialog';
|
||||
import { ProfileDialog } from '../components/profile-dialog';
|
||||
|
||||
const DialogsContainer = () => {
|
||||
const { isOpen, id, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
@@ -24,6 +25,7 @@ const DialogsContainer = () => {
|
||||
<WelcomeDialog />
|
||||
<Web3ConnectUncontrolledDialog />
|
||||
<WithdrawalApprovalDialogContainer />
|
||||
<ProfileDialog />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
interface ProfileDialogStore {
|
||||
open: boolean;
|
||||
pubKey: string | undefined;
|
||||
setOpen: (pubKey: string | undefined) => void;
|
||||
}
|
||||
|
||||
export const useProfileDialogStore = create<ProfileDialogStore>((set) => ({
|
||||
open: false,
|
||||
pubKey: undefined,
|
||||
setOpen: (pubKey) => {
|
||||
if (pubKey) {
|
||||
set({ open: true, pubKey });
|
||||
} else {
|
||||
set({ open: false, pubKey: undefined });
|
||||
}
|
||||
},
|
||||
}));
|
||||
@@ -6,7 +6,12 @@ export const PENNANT_INTERVAL_MAP = {
|
||||
[Interval.INTERVAL_I1M]: PennantInterval.I1M,
|
||||
[Interval.INTERVAL_I5M]: PennantInterval.I5M,
|
||||
[Interval.INTERVAL_I15M]: PennantInterval.I15M,
|
||||
[Interval.INTERVAL_I30M]: PennantInterval.I30M,
|
||||
[Interval.INTERVAL_I1H]: PennantInterval.I1H,
|
||||
[Interval.INTERVAL_I4H]: PennantInterval.I4H,
|
||||
[Interval.INTERVAL_I6H]: PennantInterval.I6H,
|
||||
[Interval.INTERVAL_I8H]: PennantInterval.I8H,
|
||||
[Interval.INTERVAL_I12H]: PennantInterval.I12H,
|
||||
[Interval.INTERVAL_I1D]: PennantInterval.I1D,
|
||||
[Interval.INTERVAL_I7D]: PennantInterval.I7D,
|
||||
} as const;
|
||||
|
||||
@@ -34,18 +34,28 @@ const INTERVAL_TO_PENNANT_MAP = {
|
||||
[PennantInterval.I1M]: Schema.Interval.INTERVAL_I1M,
|
||||
[PennantInterval.I5M]: Schema.Interval.INTERVAL_I5M,
|
||||
[PennantInterval.I15M]: Schema.Interval.INTERVAL_I15M,
|
||||
[PennantInterval.I30M]: Schema.Interval.INTERVAL_I30M,
|
||||
[PennantInterval.I1H]: Schema.Interval.INTERVAL_I1H,
|
||||
[PennantInterval.I4H]: Schema.Interval.INTERVAL_I4H,
|
||||
[PennantInterval.I6H]: Schema.Interval.INTERVAL_I6H,
|
||||
[PennantInterval.I8H]: Schema.Interval.INTERVAL_I8H,
|
||||
[PennantInterval.I12H]: Schema.Interval.INTERVAL_I12H,
|
||||
[PennantInterval.I1D]: Schema.Interval.INTERVAL_I1D,
|
||||
[PennantInterval.I7D]: Schema.Interval.INTERVAL_I7D,
|
||||
};
|
||||
|
||||
const defaultConfig = {
|
||||
decimalPlaces: 5,
|
||||
supportedIntervals: [
|
||||
PennantInterval.I7D,
|
||||
PennantInterval.I1D,
|
||||
PennantInterval.I12H,
|
||||
PennantInterval.I8H,
|
||||
PennantInterval.I6H,
|
||||
PennantInterval.I4H,
|
||||
PennantInterval.I1H,
|
||||
PennantInterval.I15M,
|
||||
PennantInterval.I30M,
|
||||
PennantInterval.I5M,
|
||||
PennantInterval.I1M,
|
||||
],
|
||||
@@ -137,10 +147,15 @@ export class VegaDataSource implements DataSource {
|
||||
decimalPlaces: this._decimalPlaces,
|
||||
positionDecimalPlaces: this._positionDecimalPlaces,
|
||||
supportedIntervals: [
|
||||
PennantInterval.I7D,
|
||||
PennantInterval.I1D,
|
||||
PennantInterval.I12H,
|
||||
PennantInterval.I8H,
|
||||
PennantInterval.I6H,
|
||||
PennantInterval.I4H,
|
||||
PennantInterval.I1H,
|
||||
PennantInterval.I15M,
|
||||
PennantInterval.I30M,
|
||||
PennantInterval.I5M,
|
||||
PennantInterval.I1M,
|
||||
],
|
||||
@@ -255,6 +270,10 @@ const getDuration = (
|
||||
multiplier: number
|
||||
): Duration => {
|
||||
switch (interval) {
|
||||
case 'I7D':
|
||||
return {
|
||||
days: 7 * multiplier,
|
||||
};
|
||||
case 'I1D':
|
||||
return {
|
||||
days: 1 * multiplier,
|
||||
@@ -271,14 +290,30 @@ const getDuration = (
|
||||
return {
|
||||
minutes: 5 * multiplier,
|
||||
};
|
||||
case 'I4H':
|
||||
return {
|
||||
hours: 4 * multiplier,
|
||||
};
|
||||
case 'I6H':
|
||||
return {
|
||||
hours: 6 * multiplier,
|
||||
};
|
||||
case 'I8H':
|
||||
return {
|
||||
hours: 8 * multiplier,
|
||||
};
|
||||
case 'I12H':
|
||||
return {
|
||||
hours: 12 * multiplier,
|
||||
};
|
||||
case 'I15M':
|
||||
return {
|
||||
minutes: 15 * multiplier,
|
||||
};
|
||||
case 'I30M':
|
||||
return {
|
||||
minutes: 30 * multiplier,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -288,14 +323,24 @@ const getDifference = (
|
||||
dateRight: Date
|
||||
): number => {
|
||||
switch (interval) {
|
||||
case 'I7D':
|
||||
return differenceInDays(dateRight, dateLeft) / 7;
|
||||
case 'I1D':
|
||||
return differenceInDays(dateRight, dateLeft);
|
||||
case 'I12H':
|
||||
return differenceInHours(dateRight, dateLeft) / 12;
|
||||
case 'I8H':
|
||||
return differenceInHours(dateRight, dateLeft) / 8;
|
||||
case 'I6H':
|
||||
return differenceInHours(dateRight, dateLeft) / 6;
|
||||
case 'I4H':
|
||||
return differenceInHours(dateRight, dateLeft) / 4;
|
||||
case 'I1H':
|
||||
return differenceInHours(dateRight, dateLeft);
|
||||
case 'I15M':
|
||||
return differenceInMinutes(dateRight, dateLeft) / 15;
|
||||
case 'I30M':
|
||||
return differenceInMinutes(dateRight, dateLeft) / 30;
|
||||
case 'I5M':
|
||||
return differenceInMinutes(dateRight, dateLeft) / 5;
|
||||
case 'I1M':
|
||||
|
||||
@@ -73,7 +73,7 @@ export const DealTicketContainer = ({
|
||||
market={market}
|
||||
marketPrice={marketPrice}
|
||||
marketData={marketData}
|
||||
submit={(orderSubmission) => create({ orderSubmission })}
|
||||
submit={(transaction) => create(transaction)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
import { Controller, type Control } from 'react-hook-form';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import type { OrderFormValues } from '../../hooks/use-form-values';
|
||||
import { toDecimal, useValidateAmount } from '@vegaprotocol/utils';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
TradingInputError,
|
||||
Tooltip,
|
||||
FormGroup,
|
||||
Input,
|
||||
InputError,
|
||||
Pill,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useT } from '../../use-t';
|
||||
|
||||
export interface DealTicketPriceTakeProfitStopLossProps {
|
||||
control: Control<OrderFormValues>;
|
||||
market: Market;
|
||||
takeProfitError?: string;
|
||||
stopLossError?: string;
|
||||
quoteName?: string;
|
||||
}
|
||||
|
||||
export const DealTicketPriceTakeProfitStopLoss = ({
|
||||
control,
|
||||
market,
|
||||
takeProfitError,
|
||||
stopLossError,
|
||||
quoteName,
|
||||
}: DealTicketPriceTakeProfitStopLossProps) => {
|
||||
const t = useT();
|
||||
const validateAmount = useValidateAmount();
|
||||
const priceStep = toDecimal(market?.decimalPlaces);
|
||||
|
||||
const renderTakeProfitError = () => {
|
||||
if (takeProfitError) {
|
||||
return (
|
||||
<TradingInputError testId="deal-ticket-take-profit-error-message">
|
||||
{takeProfitError}
|
||||
</TradingInputError>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderStopLossError = () => {
|
||||
if (stopLossError) {
|
||||
return (
|
||||
<TradingInputError testId="deal-stop-loss-error-message">
|
||||
{stopLossError}
|
||||
</TradingInputError>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex-1">
|
||||
<TradingFormGroup
|
||||
label={
|
||||
<Tooltip
|
||||
description={<div>{t('The price for take profit.')}</div>}
|
||||
>
|
||||
<span className="text-xs">{t('Take profit')}</span>
|
||||
</Tooltip>
|
||||
}
|
||||
labelFor="input-order-take-profit"
|
||||
className="!mb-1"
|
||||
>
|
||||
<Controller
|
||||
name="takeProfit"
|
||||
control={control}
|
||||
rules={{
|
||||
min: {
|
||||
value: priceStep,
|
||||
message: t(
|
||||
'Take profit price cannot be lower than {{priceStep}}',
|
||||
{
|
||||
priceStep,
|
||||
}
|
||||
),
|
||||
},
|
||||
validate: validateAmount(priceStep, 'takeProfit'),
|
||||
}}
|
||||
render={({ field, fieldState }) => (
|
||||
<div className="mb-2">
|
||||
<FormGroup
|
||||
labelFor="input-price-take-profit"
|
||||
label={''}
|
||||
compact
|
||||
>
|
||||
<Input
|
||||
id="input-price-take-profit"
|
||||
appendElement={<Pill size="xs">{quoteName}</Pill>}
|
||||
className="w-full"
|
||||
type="number"
|
||||
step={priceStep}
|
||||
data-testid="order-price-take-profit"
|
||||
onWheel={(e) => e.currentTarget.blur()}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
{fieldState.error && (
|
||||
<InputError testId="deal-ticket-error-message-price-take-profit">
|
||||
{fieldState.error.message}
|
||||
</InputError>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</TradingFormGroup>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<TradingFormGroup
|
||||
label={
|
||||
<Tooltip description={<div>{t('The price for stop loss.')}</div>}>
|
||||
<span className="text-xs">{t('Stop loss')}</span>
|
||||
</Tooltip>
|
||||
}
|
||||
labelFor="input-order-stop-loss"
|
||||
className="!mb-1"
|
||||
>
|
||||
<Controller
|
||||
name="stopLoss"
|
||||
control={control}
|
||||
rules={{
|
||||
min: {
|
||||
value: priceStep,
|
||||
message: t('Price cannot be lower than {{priceStep}}', {
|
||||
priceStep,
|
||||
}),
|
||||
},
|
||||
validate: validateAmount(priceStep, 'stopLoss'),
|
||||
}}
|
||||
render={({ field, fieldState }) => (
|
||||
<div className="mb-2">
|
||||
<FormGroup
|
||||
labelFor="input-price-stop-loss"
|
||||
label={''}
|
||||
compact
|
||||
>
|
||||
<Input
|
||||
id="input-price-stop-loss"
|
||||
appendElement={<Pill size="xs">{quoteName}</Pill>}
|
||||
className="w-full"
|
||||
type="number"
|
||||
step={priceStep}
|
||||
data-testid="order-price-stop-loss"
|
||||
onWheel={(e) => e.currentTarget.blur()}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
{fieldState.error && (
|
||||
<InputError testId="deal-ticket-error-message-price-stop-loss">
|
||||
{fieldState.error.message}
|
||||
</InputError>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</TradingFormGroup>
|
||||
</div>
|
||||
</div>
|
||||
{renderTakeProfitError()}
|
||||
{renderStopLossError()}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1003,7 +1003,7 @@ export const StopOrder = ({ market, marketPrice, submit }: StopOrderProps) => {
|
||||
name="oco"
|
||||
label={
|
||||
<Tooltip
|
||||
description={<span>{t('One cancels another')}</span>}
|
||||
description={<span>{t('One cancels the other')}</span>}
|
||||
>
|
||||
<>{t('OCO')}</>
|
||||
</Tooltip>
|
||||
|
||||
@@ -8,9 +8,12 @@ import { ExpirySelector } from './expiry-selector';
|
||||
import { SideSelector } from './side-selector';
|
||||
import { TimeInForceSelector } from './time-in-force-selector';
|
||||
import { TypeSelector } from './type-selector';
|
||||
import { type OrderSubmission } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet-react';
|
||||
import { mapFormValuesToOrderSubmission } from '../../utils/map-form-values-to-submission';
|
||||
import { type Transaction } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
mapFormValuesToOrderSubmission,
|
||||
mapFormValuesToTakeProfitAndStopLoss,
|
||||
} from '../../utils/map-form-values-to-submission';
|
||||
import {
|
||||
TradingInput as Input,
|
||||
TradingCheckbox as Checkbox,
|
||||
@@ -77,6 +80,8 @@ import { isNonPersistentOrder } from '../../utils/time-in-force-persistence';
|
||||
import { KeyValue } from './key-value';
|
||||
import { DocsLinks } from '@vegaprotocol/environment';
|
||||
import { useT } from '../../use-t';
|
||||
import { DealTicketPriceTakeProfitStopLoss } from './deal-ticket-price-tp-sl';
|
||||
import uniqueId from 'lodash/uniqueId';
|
||||
|
||||
export const REDUCE_ONLY_TOOLTIP =
|
||||
'"Reduce only" will ensure that this order will not increase the size of an open position. When the order is matched, it will only trade enough volume to bring your open volume towards 0 but never change the direction of your position. If applied to a limit order that is not instantly filled, the order will be stopped.';
|
||||
@@ -86,7 +91,7 @@ export interface DealTicketProps {
|
||||
marketData: StaticMarketData;
|
||||
marketPrice?: string | null;
|
||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||
submit: (order: OrderSubmission) => void;
|
||||
submit: (order: Transaction) => void;
|
||||
onDeposit: (assetId: string) => void;
|
||||
}
|
||||
|
||||
@@ -184,6 +189,7 @@ export const DealTicket = ({
|
||||
const rawSize = watch('size');
|
||||
const rawPrice = watch('price');
|
||||
const iceberg = watch('iceberg');
|
||||
const tpSl = watch('tpSl');
|
||||
const peakSize = watch('peakSize');
|
||||
const expiresAt = watch('expiresAt');
|
||||
const postOnly = watch('postOnly');
|
||||
@@ -382,17 +388,28 @@ export const DealTicket = ({
|
||||
if (lastSubmitTime.current && now - lastSubmitTime.current < 1000) {
|
||||
return;
|
||||
}
|
||||
submit(
|
||||
mapFormValuesToOrderSubmission(
|
||||
if (formValues.tpSl) {
|
||||
const reference = `${pubKey}-${now}-${uniqueId()}`;
|
||||
const batchMarketInstructions = mapFormValuesToTakeProfitAndStopLoss(
|
||||
formValues,
|
||||
market,
|
||||
reference
|
||||
);
|
||||
submit({
|
||||
batchMarketInstructions,
|
||||
});
|
||||
} else {
|
||||
const orderSubmission = mapFormValuesToOrderSubmission(
|
||||
formValues,
|
||||
market.id,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces
|
||||
)
|
||||
);
|
||||
);
|
||||
submit({ orderSubmission });
|
||||
}
|
||||
lastSubmitTime.current = now;
|
||||
},
|
||||
[submit, market.decimalPlaces, market.positionDecimalPlaces, market.id]
|
||||
[market, pubKey, submit]
|
||||
);
|
||||
useController({
|
||||
name: 'type',
|
||||
@@ -674,40 +691,63 @@ export const DealTicket = ({
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{isLimitType && (
|
||||
{
|
||||
<>
|
||||
<div className="flex justify-between gap-2 pb-2">
|
||||
{isLimitType && (
|
||||
<Controller
|
||||
name="iceberg"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Tooltip
|
||||
description={
|
||||
<p>
|
||||
{t(
|
||||
'ICEBERG_TOOLTIP',
|
||||
'Trade only a fraction of the order size at once. After the peak size of the order has traded, the size is reset. This is repeated until the order is cancelled, expires, or its full volume trades away. For example, an iceberg order with a size of 1000 and a peak size of 100 will effectively be split into 10 orders with a size of 100 each. Note that the full volume of the order is not hidden and is still reflected in the order book.'
|
||||
)}{' '}
|
||||
<ExternalLink href={DocsLinks?.ICEBERG_ORDERS}>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>{' '}
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="iceberg"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={disableIcebergCheckbox}
|
||||
label={t('Iceberg')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<Controller
|
||||
name="iceberg"
|
||||
name="tpSl"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Tooltip
|
||||
description={
|
||||
<p>
|
||||
{t(
|
||||
'ICEBERG_TOOLTIP',
|
||||
'Trade only a fraction of the order size at once. After the peak size of the order has traded, the size is reset. This is repeated until the order is cancelled, expires, or its full volume trades away. For example, an iceberg order with a size of 1000 and a peak size of 100 will effectively be split into 10 orders with a size of 100 each. Note that the full volume of the order is not hidden and is still reflected in the order book.'
|
||||
)}{' '}
|
||||
<ExternalLink href={DocsLinks?.ICEBERG_ORDERS}>
|
||||
{t('Find out more')}
|
||||
</ExternalLink>{' '}
|
||||
</p>
|
||||
<p>{t('TP_SL_TOOLTIP', 'Take profit / Stop loss')}</p>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<Checkbox
|
||||
name="iceberg"
|
||||
name="tpSl"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={disableIcebergCheckbox}
|
||||
label={t('Iceberg')}
|
||||
disabled={false}
|
||||
label={t('TP / SL')}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{iceberg && (
|
||||
{isLimitType && iceberg && (
|
||||
<DealTicketSizeIceberg
|
||||
market={market}
|
||||
peakSizeError={errors.peakSize?.message}
|
||||
@@ -717,8 +757,18 @@ export const DealTicket = ({
|
||||
peakSize={peakSize}
|
||||
/>
|
||||
)}
|
||||
{tpSl && (
|
||||
<DealTicketPriceTakeProfitStopLoss
|
||||
market={market}
|
||||
takeProfitError={errors.takeProfit?.message}
|
||||
stopLossError={errors.stopLoss?.message}
|
||||
control={control}
|
||||
quoteName={quoteName}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
}
|
||||
|
||||
<SummaryMessage
|
||||
error={summaryError}
|
||||
asset={asset}
|
||||
|
||||
@@ -53,6 +53,9 @@ export type OrderFormValues = {
|
||||
iceberg?: boolean;
|
||||
peakSize?: string;
|
||||
minimumVisibleSize?: string;
|
||||
tpSl?: boolean;
|
||||
takeProfit?: string;
|
||||
stopLoss?: string;
|
||||
};
|
||||
|
||||
type UpdateOrder = (marketId: string, values: Partial<OrderFormValues>) => void;
|
||||
|
||||
@@ -10,13 +10,16 @@ import type {
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { removeDecimal, toNanoSeconds } from '@vegaprotocol/utils';
|
||||
import { isPersistentOrder } from './time-in-force-persistence';
|
||||
import { type MarketFieldsFragment } from '@vegaprotocol/markets';
|
||||
|
||||
export const mapFormValuesToOrderSubmission = (
|
||||
order: OrderFormValues,
|
||||
marketId: string,
|
||||
decimalPlaces: number,
|
||||
positionDecimalPlaces: number
|
||||
positionDecimalPlaces: number,
|
||||
reference?: string
|
||||
): OrderSubmission => ({
|
||||
reference,
|
||||
marketId: marketId,
|
||||
type: order.type,
|
||||
side: order.side,
|
||||
@@ -81,7 +84,8 @@ export const mapFormValuesToStopOrdersSubmission = (
|
||||
data: StopOrderFormValues,
|
||||
marketId: string,
|
||||
decimalPlaces: number,
|
||||
positionDecimalPlaces: number
|
||||
positionDecimalPlaces: number,
|
||||
reference?: string
|
||||
): StopOrdersSubmission => {
|
||||
const submission: StopOrdersSubmission = {};
|
||||
const stopOrderSetup: StopOrderSetup = {
|
||||
@@ -96,7 +100,8 @@ export const mapFormValuesToStopOrdersSubmission = (
|
||||
},
|
||||
marketId,
|
||||
decimalPlaces,
|
||||
positionDecimalPlaces
|
||||
positionDecimalPlaces,
|
||||
reference
|
||||
),
|
||||
};
|
||||
setTrigger(
|
||||
@@ -120,7 +125,8 @@ export const mapFormValuesToStopOrdersSubmission = (
|
||||
},
|
||||
marketId,
|
||||
decimalPlaces,
|
||||
positionDecimalPlaces
|
||||
positionDecimalPlaces,
|
||||
reference
|
||||
),
|
||||
};
|
||||
setTrigger(
|
||||
@@ -159,3 +165,125 @@ export const mapFormValuesToStopOrdersSubmission = (
|
||||
|
||||
return submission;
|
||||
};
|
||||
|
||||
export const mapFormValuesToTakeProfitAndStopLoss = (
|
||||
formValues: OrderFormValues,
|
||||
market: MarketFieldsFragment,
|
||||
reference: string
|
||||
) => {
|
||||
const orderSubmission = mapFormValuesToOrderSubmission(
|
||||
formValues,
|
||||
market.id,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces,
|
||||
reference
|
||||
);
|
||||
|
||||
const oppositeSide =
|
||||
formValues.side === Schema.Side.SIDE_BUY
|
||||
? Schema.Side.SIDE_SELL
|
||||
: Schema.Side.SIDE_BUY;
|
||||
// For direction it needs to be implied
|
||||
// If position is LONG (BUY)
|
||||
// TP is SHORT and trigger is RISES ABOVE
|
||||
// If position is SHORT
|
||||
// TP is LONG and trigger is FALLS BELOW
|
||||
const takeProfitTriggerDirection =
|
||||
formValues.side === Schema.Side.SIDE_BUY
|
||||
? Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_RISES_ABOVE
|
||||
: Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW;
|
||||
// For direction it needs to be implied
|
||||
// If position is LONG (BUY)
|
||||
// SL is SHORT and trigger is FALLS BELOW
|
||||
// If position is SHORT
|
||||
// SL is LONG and trigger is RISES ABOVE
|
||||
const stopLossTriggerDirection =
|
||||
formValues.side === Schema.Side.SIDE_BUY
|
||||
? Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||
: Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_RISES_ABOVE;
|
||||
|
||||
const stopOrdersSubmission = [];
|
||||
|
||||
// if there are both take profit and stop loss then the stop order needs to be OCO
|
||||
if (formValues.takeProfit && formValues.stopLoss) {
|
||||
const ocoStopOrderSubmission = mapFormValuesToStopOrdersSubmission(
|
||||
{
|
||||
...formValues,
|
||||
triggerPrice: formValues.stopLoss,
|
||||
ocoTriggerPrice: formValues.takeProfit,
|
||||
price: formValues.stopLoss,
|
||||
triggerDirection: stopLossTriggerDirection,
|
||||
triggerType: 'price',
|
||||
side: oppositeSide,
|
||||
expire: false,
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
oco: true,
|
||||
ocoPrice: formValues.takeProfit,
|
||||
ocoTriggerType: 'price',
|
||||
ocoType: Schema.OrderType.TYPE_MARKET,
|
||||
ocoSize: formValues.size,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
ocoTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
},
|
||||
market.id,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces,
|
||||
reference
|
||||
);
|
||||
stopOrdersSubmission.push(ocoStopOrderSubmission);
|
||||
} else if (formValues.takeProfit) {
|
||||
const takeProfitStopOrderSubmission = mapFormValuesToStopOrdersSubmission(
|
||||
{
|
||||
...formValues,
|
||||
price: formValues.takeProfit,
|
||||
triggerDirection: takeProfitTriggerDirection,
|
||||
triggerType: 'price',
|
||||
triggerPrice: formValues.takeProfit,
|
||||
side: oppositeSide,
|
||||
expire: false,
|
||||
ocoTriggerType: 'price',
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
oco: false,
|
||||
ocoType: Schema.OrderType.TYPE_MARKET,
|
||||
ocoSize: formValues.size,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
ocoTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
},
|
||||
market.id,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces,
|
||||
reference
|
||||
);
|
||||
stopOrdersSubmission.push(takeProfitStopOrderSubmission);
|
||||
} else if (formValues.stopLoss) {
|
||||
const stopLossStopOrderSubmission = mapFormValuesToStopOrdersSubmission(
|
||||
{
|
||||
...formValues,
|
||||
triggerPrice: formValues.stopLoss,
|
||||
price: formValues.stopLoss,
|
||||
triggerDirection: stopLossTriggerDirection,
|
||||
triggerType: 'price',
|
||||
side: oppositeSide,
|
||||
expire: false,
|
||||
type: Schema.OrderType.TYPE_MARKET,
|
||||
oco: false,
|
||||
ocoTriggerType: 'price',
|
||||
ocoType: Schema.OrderType.TYPE_MARKET,
|
||||
ocoSize: formValues.size,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
ocoTimeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
},
|
||||
market.id,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces,
|
||||
reference
|
||||
);
|
||||
stopOrdersSubmission.push(stopLossStopOrderSubmission);
|
||||
}
|
||||
|
||||
const batchMarketInstructions = {
|
||||
submissions: [orderSubmission],
|
||||
stopOrdersSubmission,
|
||||
};
|
||||
return batchMarketInstructions;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||
import { mapFormValuesToOrderSubmission } from './map-form-values-to-submission';
|
||||
import type {
|
||||
OrderSubmissionBody,
|
||||
StopOrdersSubmission,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import {
|
||||
mapFormValuesToOrderSubmission,
|
||||
mapFormValuesToTakeProfitAndStopLoss,
|
||||
} from './map-form-values-to-submission';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { OrderTimeInForce, OrderType } from '@vegaprotocol/types';
|
||||
import type { OrderFormValues } from '../hooks';
|
||||
import { type MarketFieldsFragment } from '@vegaprotocol/markets';
|
||||
|
||||
describe('mapFormValuesToOrderSubmission', () => {
|
||||
it('sets and formats price only for limit orders', () => {
|
||||
@@ -186,3 +193,232 @@ describe('mapFormValuesToOrderSubmission', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const mockMarket: MarketFieldsFragment = {
|
||||
__typename: 'Market',
|
||||
id: 'marketId',
|
||||
decimalPlaces: 1,
|
||||
positionDecimalPlaces: 4,
|
||||
state: Schema.MarketState.STATE_ACTIVE,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
} as MarketFieldsFragment;
|
||||
|
||||
const orderFormValues: OrderFormValues = {
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
size: '1',
|
||||
price: '66300',
|
||||
postOnly: false,
|
||||
reduceOnly: false,
|
||||
tpSl: true,
|
||||
takeProfit: '70000',
|
||||
stopLoss: '60000',
|
||||
};
|
||||
|
||||
describe('mapFormValuesToTakeProfitAndStopLoss', () => {
|
||||
it('creates batch market instructions for a normal order created with TP and SL', () => {
|
||||
const result = mapFormValuesToTakeProfitAndStopLoss(
|
||||
orderFormValues,
|
||||
mockMarket,
|
||||
'reference'
|
||||
);
|
||||
|
||||
const expected: {
|
||||
submissions: Schema.OrderSubmission[];
|
||||
stopOrdersSubmission: StopOrdersSubmission[];
|
||||
} = {
|
||||
stopOrdersSubmission: [
|
||||
{
|
||||
fallsBelow: {
|
||||
orderSubmission: {
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: undefined,
|
||||
reduceOnly: true,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
type: OrderType.TYPE_MARKET,
|
||||
},
|
||||
price: '600000',
|
||||
},
|
||||
risesAbove: {
|
||||
orderSubmission: {
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: undefined,
|
||||
reduceOnly: true,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
type: OrderType.TYPE_MARKET,
|
||||
},
|
||||
price: '700000',
|
||||
},
|
||||
},
|
||||
],
|
||||
submissions: [
|
||||
{
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: '663000',
|
||||
reduceOnly: false,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('creates batch market instructions for a normal order created without TP and SL', () => {
|
||||
// Create order form values without TP and SL
|
||||
const orderFormValuesWithoutTPSL = { ...orderFormValues };
|
||||
delete orderFormValuesWithoutTPSL.takeProfit;
|
||||
delete orderFormValuesWithoutTPSL.stopLoss;
|
||||
|
||||
const result = mapFormValuesToTakeProfitAndStopLoss(
|
||||
orderFormValuesWithoutTPSL,
|
||||
mockMarket,
|
||||
'reference'
|
||||
);
|
||||
|
||||
// Expected result when TP and SL are not provided
|
||||
const expected: {
|
||||
submissions: Schema.OrderSubmission[];
|
||||
stopOrdersSubmission: StopOrdersSubmission[];
|
||||
} = {
|
||||
stopOrdersSubmission: [],
|
||||
submissions: [
|
||||
{
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: '663000',
|
||||
reduceOnly: false,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('creates batch market instructions for a normal order created with TP only', () => {
|
||||
// Create order form values with TP only
|
||||
const orderFormValuesWithTP = { ...orderFormValues };
|
||||
orderFormValuesWithTP.stopLoss = undefined;
|
||||
|
||||
const result = mapFormValuesToTakeProfitAndStopLoss(
|
||||
orderFormValuesWithTP,
|
||||
mockMarket,
|
||||
'reference'
|
||||
);
|
||||
|
||||
// Expected result when only TP is provided
|
||||
const expected: {
|
||||
submissions: Schema.OrderSubmission[];
|
||||
stopOrdersSubmission: StopOrdersSubmission[];
|
||||
} = {
|
||||
stopOrdersSubmission: [
|
||||
{
|
||||
risesAbove: {
|
||||
orderSubmission: {
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: undefined,
|
||||
reduceOnly: true,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
type: OrderType.TYPE_MARKET,
|
||||
},
|
||||
price: '700000',
|
||||
},
|
||||
},
|
||||
],
|
||||
submissions: [
|
||||
{
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: '663000',
|
||||
reduceOnly: false,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('creates batch market instructions for a normal order created with SL only', () => {
|
||||
// Create order form values with SL only
|
||||
const orderFormValuesWithSL = { ...orderFormValues };
|
||||
orderFormValuesWithSL.takeProfit = undefined;
|
||||
|
||||
const result = mapFormValuesToTakeProfitAndStopLoss(
|
||||
orderFormValuesWithSL,
|
||||
mockMarket,
|
||||
'reference'
|
||||
);
|
||||
|
||||
// Expected result when only SL is provided
|
||||
const expected: {
|
||||
submissions: Schema.OrderSubmission[];
|
||||
stopOrdersSubmission: StopOrdersSubmission[];
|
||||
} = {
|
||||
stopOrdersSubmission: [
|
||||
{
|
||||
fallsBelow: {
|
||||
orderSubmission: {
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: undefined,
|
||||
reduceOnly: true,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_SELL,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
type: OrderType.TYPE_MARKET,
|
||||
},
|
||||
price: '600000',
|
||||
},
|
||||
},
|
||||
],
|
||||
submissions: [
|
||||
{
|
||||
expiresAt: undefined,
|
||||
marketId: 'marketId',
|
||||
postOnly: false,
|
||||
price: '663000',
|
||||
reduceOnly: false,
|
||||
reference: 'reference',
|
||||
side: Schema.Side.SIDE_BUY,
|
||||
size: '10000',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
type: OrderType.TYPE_LIMIT,
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"Notional": "Notional",
|
||||
"NOTIONAL_SIZE_TOOLTIP_TEXT": "The notional size represents the position size in the settlement asset {{quoteName}} of the futures contract. This is calculated by multiplying the number of contracts by the prices of the contract. For example 10 contracts traded at a price of $50 has a notional size of $500.",
|
||||
"OCO": "OCO",
|
||||
"One cancels another": "One cancels another",
|
||||
"One cancels the other": "One cancels the other",
|
||||
"Only limit orders are permitted when market is in auction": "Only limit orders are permitted when market is in auction",
|
||||
"Only your allocated margin will be used to fund this position, and if the maintenance margin is breached you will be closed out.": "Only your allocated margin will be used to fund this position, and if the maintenance margin is breached you will be closed out.",
|
||||
"You have an existing position on this market.": "You have an existing position on this market.",
|
||||
@@ -135,6 +135,12 @@
|
||||
"Total margin available": "Total margin available",
|
||||
"TOTAL_MARGIN_AVAILABLE": "Total margin available = general {{assetSymbol}} balance ({{generalAccountBalance}} {{assetSymbol}}) + margin balance ({{marginAccountBalance}} {{assetSymbol}}) + order margin balance ({{orderMarginAccountBalance}} {{assetSymbol}}) - maintenance level ({{marginMaintenance}} {{assetSymbol}}).",
|
||||
"No trading": "No trading",
|
||||
"TP / SL": "TP / SL",
|
||||
"TP_SL_TOOLTIP": "Take profit / Stop loss",
|
||||
"Take profit": "Take profit",
|
||||
"Stop loss": "Stop loss",
|
||||
"The price for take profit.": "The price for take profit.",
|
||||
"The price for stop loss.": "The price for stop loss.",
|
||||
"Trailing percent offset cannot be higher than 99.9": "Trailing percent offset cannot be higher than 99.9",
|
||||
"Trailing percent offset cannot be lower than {{trailingPercentOffsetStep}}": "Trailing percent offset cannot be lower than {{trailingPercentOffsetStep}}",
|
||||
"Trailing percentage offset": "Trailing percentage offset",
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
"Docs": "Docs",
|
||||
"Earn commission & stake rewards": "Earn commission & stake rewards",
|
||||
"Earned by me": "Earned by me",
|
||||
"Edit alias": "Edit alias",
|
||||
"Eligible teams": "Eligible teams",
|
||||
"Enactment date reached and usual auction exit checks pass": "Enactment date reached and usual auction exit checks pass",
|
||||
"[empty]": "[empty]",
|
||||
@@ -142,12 +143,17 @@
|
||||
"Hoarder reward multiplier": "Hoarder reward multiplier",
|
||||
"How it works": "How it works",
|
||||
"I want a code": "I want a code",
|
||||
"INTERVAL_I12H": "12H",
|
||||
"INTERVAL_I15M": "15m",
|
||||
"INTERVAL_I1D": "1D",
|
||||
"INTERVAL_I1H": "1H",
|
||||
"INTERVAL_I1D": "D",
|
||||
"INTERVAL_I1H": "1h",
|
||||
"INTERVAL_I1M": "1m",
|
||||
"INTERVAL_I30M": "30m",
|
||||
"INTERVAL_I4H": "4H",
|
||||
"INTERVAL_I5M": "5m",
|
||||
"INTERVAL_I6H": "6H",
|
||||
"INTERVAL_I6H": "6h",
|
||||
"INTERVAL_I8H": "8h",
|
||||
"INTERVAL_I7D": "W",
|
||||
"Improve vega console": "Improve vega console",
|
||||
"Inactive": "Inactive",
|
||||
"Index Price": "Index Price",
|
||||
@@ -162,6 +168,7 @@
|
||||
"Joined": "Joined",
|
||||
"Joined at": "Joined at",
|
||||
"Joined epoch": "Joined epoch",
|
||||
"Key name": "Key name",
|
||||
"gameCount_one": "Last game result",
|
||||
"gameCount_other": "Last {{count}} game results",
|
||||
"Learn about providing liquidity": "Learn about providing liquidity",
|
||||
@@ -194,6 +201,7 @@
|
||||
"My liquidity provision": "My liquidity provision",
|
||||
"My trading fees": "My trading fees",
|
||||
"Name": "Name",
|
||||
"No alias": "No alias",
|
||||
"No closed orders": "No closed orders",
|
||||
"No data": "No data",
|
||||
"No deposits": "No deposits",
|
||||
@@ -227,6 +235,7 @@
|
||||
"Not connected": "Not connected",
|
||||
"Number of epochs after distribution to delay vesting of rewards by": "Number of epochs after distribution to delay vesting of rewards by",
|
||||
"Number of traders": "Number of traders",
|
||||
"On-change alias": "On-change alias",
|
||||
"Open": "Open",
|
||||
"Open a position": "Open a position",
|
||||
"Open markets": "Open markets",
|
||||
@@ -249,6 +258,7 @@
|
||||
"Portfolio": "Portfolio",
|
||||
"Positions": "Positions",
|
||||
"Price": "Price",
|
||||
"Profile updated": "Profile updated",
|
||||
"Program ends:": "Program ends:",
|
||||
"Propose a new market": "Propose a new market",
|
||||
"Proposed final price is {{price}} {{assetSymbol}}.": "Proposed final price is {{price}} {{assetSymbol}}.",
|
||||
@@ -289,6 +299,7 @@
|
||||
"Search": "Search",
|
||||
"See all markets": "See all markets",
|
||||
"Select market": "Select market",
|
||||
"Set party alias": "Set party alias",
|
||||
"Settings": "Settings",
|
||||
"Settlement asset": "Settlement asset",
|
||||
"Settlement date": "Settlement date",
|
||||
@@ -311,6 +322,7 @@
|
||||
"Stop": "Stop",
|
||||
"Stop orders": "Stop orders",
|
||||
"Streak reward multiplier": "Streak reward multiplier",
|
||||
"Submit": "Submit",
|
||||
"Successor of a market": "Successor of a market",
|
||||
"Successors to this market have been proposed": "Successors to this market have been proposed",
|
||||
"Supplied stake": "Supplied stake",
|
||||
@@ -371,6 +383,7 @@
|
||||
"Staking rewards": "Staking rewards",
|
||||
"Unknown": "Unknown",
|
||||
"Unknown settlement date": "Unknown settlement date",
|
||||
"Unnamed key": "Unnamed key",
|
||||
"Update team": "Update team",
|
||||
"URL": "URL",
|
||||
"Use a comma separated list to allow only specific public keys to join the team": "Use a comma separated list to allow only specific public keys to join the team",
|
||||
@@ -407,8 +420,10 @@
|
||||
"You will no longer be able to hold a position on this market when it closes in {{duration}}.": "You will no longer be able to hold a position on this market when it closes in {{duration}}.",
|
||||
"Your code has been rejected": "Your code has been rejected",
|
||||
"Your identity is always anonymous on Vega": "Your identity is always anonymous on Vega",
|
||||
"Your key's private name, can be changed in your wallet": "Your key's private name, can be changed in your wallet",
|
||||
"Your referral code": "Your referral code",
|
||||
"Your tier": "Your tier",
|
||||
"Your public alias, stored on chain": "Your public alias, stored on chain",
|
||||
"checkOutProposalsAndVote": "Check out the terms of the proposals and vote:",
|
||||
"checkOutProposalsAndVote_one": "Check out the terms of the proposal and vote:",
|
||||
"checkOutProposalsAndVote_other": "Check out the terms of the proposals and vote:",
|
||||
|
||||
@@ -15,9 +15,14 @@ export const TRADINGVIEW_INTERVAL_MAP = {
|
||||
[Interval.INTERVAL_I1M]: '1',
|
||||
[Interval.INTERVAL_I5M]: '5',
|
||||
[Interval.INTERVAL_I15M]: '15',
|
||||
[Interval.INTERVAL_I30M]: '30',
|
||||
[Interval.INTERVAL_I1H]: '60',
|
||||
[Interval.INTERVAL_I4H]: '240',
|
||||
[Interval.INTERVAL_I6H]: '360',
|
||||
[Interval.INTERVAL_I8H]: '480',
|
||||
[Interval.INTERVAL_I12H]: '720',
|
||||
[Interval.INTERVAL_I1D]: '1D',
|
||||
[Interval.INTERVAL_I7D]: '1W',
|
||||
} as const;
|
||||
|
||||
export type ResolutionRecord = typeof TRADINGVIEW_INTERVAL_MAP;
|
||||
|
||||
@@ -32,9 +32,14 @@ const resolutionMap: Record<string, Interval> = {
|
||||
'1': Interval.INTERVAL_I1M,
|
||||
'5': Interval.INTERVAL_I5M,
|
||||
'15': Interval.INTERVAL_I15M,
|
||||
'30': Interval.INTERVAL_I30M,
|
||||
'60': Interval.INTERVAL_I1H,
|
||||
'240': Interval.INTERVAL_I4H,
|
||||
'360': Interval.INTERVAL_I6H,
|
||||
'480': Interval.INTERVAL_I8H,
|
||||
'720': Interval.INTERVAL_I12H,
|
||||
'1D': Interval.INTERVAL_I1D,
|
||||
'1W': Interval.INTERVAL_I7D,
|
||||
} as const;
|
||||
|
||||
const supportedResolutions = Object.keys(resolutionMap);
|
||||
|
||||
Generated
+12
@@ -936,6 +936,8 @@ export enum DispatchMetric {
|
||||
/** Dispatch strategy for a recurring transfer */
|
||||
export type DispatchStrategy = {
|
||||
__typename?: 'DispatchStrategy';
|
||||
/** Optional multiplier on taker fees used to cap the rewards a party may receive in an epoch */
|
||||
capRewardFeeMultiple?: Maybe<Scalars['String']>;
|
||||
/** Defines the data that will be used to compare markets so as to distribute rewards appropriately */
|
||||
dispatchMetric: DispatchMetric;
|
||||
/** The asset to use for measuring contribution to the metric */
|
||||
@@ -2391,6 +2393,8 @@ export type Market = {
|
||||
state: MarketState;
|
||||
/** Optional: Market ID of the successor to this market if one exists */
|
||||
successorMarketID?: Maybe<Scalars['ID']>;
|
||||
/** The market minimum tick size */
|
||||
tickSize: Scalars['String'];
|
||||
/** An instance of, or reference to, a tradable instrument. */
|
||||
tradableInstrument: TradableInstrument;
|
||||
/** @deprecated Simplify and consolidate trades query and remove nesting. Use trades query instead */
|
||||
@@ -2816,6 +2820,8 @@ export type NewMarket = {
|
||||
riskParameters: RiskModel;
|
||||
/** Successor market configuration. If this proposed market is meant to succeed a given market, then this needs to be set. */
|
||||
successorConfiguration?: Maybe<SuccessorConfiguration>;
|
||||
/** The market minimum tick size */
|
||||
tickSize: Scalars['String'];
|
||||
};
|
||||
|
||||
/** Configuration for a new spot market on Vega */
|
||||
@@ -2839,6 +2845,8 @@ export type NewSpotMarket = {
|
||||
riskParameters?: Maybe<RiskModel>;
|
||||
/** Specifies parameters related to liquidity target stake calculation */
|
||||
targetStakeParameters: TargetStakeParameters;
|
||||
/** The market minimum tick size */
|
||||
tickSize: Scalars['String'];
|
||||
};
|
||||
|
||||
export type NewTransfer = {
|
||||
@@ -7074,6 +7082,8 @@ export type UpdateMarketConfiguration = {
|
||||
quadraticSlippageFactor: Scalars['String'];
|
||||
/** Updated futures market risk model parameters. */
|
||||
riskParameters: UpdateMarketRiskParameters;
|
||||
/** The market minimum tick size */
|
||||
tickSize: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateMarketLogNormalRiskModel = {
|
||||
@@ -7171,6 +7181,8 @@ export type UpdateSpotMarketConfiguration = {
|
||||
riskParameters: RiskModel;
|
||||
/** Specifies parameters related to target stake calculation */
|
||||
targetStakeParameters: TargetStakeParameters;
|
||||
/** The market minimum tick size */
|
||||
tickSize: Scalars['String'];
|
||||
};
|
||||
|
||||
export type UpdateVolumeDiscountProgram = {
|
||||
|
||||
@@ -33,6 +33,12 @@ export const useSimpleTransaction = (opts?: Options) => {
|
||||
const [result, setResult] = useState<Result>();
|
||||
const [error, setError] = useState<string>();
|
||||
|
||||
const reset = () => {
|
||||
setStatus('idle');
|
||||
setResult(undefined);
|
||||
setError(undefined);
|
||||
};
|
||||
|
||||
const send = async (tx: Transaction) => {
|
||||
if (!pubKey) {
|
||||
throw new Error('no pubKey');
|
||||
@@ -114,5 +120,6 @@ export const useSimpleTransaction = (opts?: Options) => {
|
||||
error,
|
||||
status,
|
||||
send,
|
||||
reset,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -403,6 +403,9 @@ export interface BatchMarketInstructionSubmissionBody {
|
||||
// Note: If multiple orders are submitted the first order ID is determined by hashing the signature of the transaction
|
||||
// (see determineId function). For each subsequent order's ID, a hash of the previous orders ID is used
|
||||
submissions?: OrderSubmission[];
|
||||
stopOrdersSubmission?: StopOrdersSubmission[];
|
||||
stopOrdersCancellation?: StopOrdersCancellation[];
|
||||
updateMarginMode?: UpdateMarginMode[];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -492,6 +495,14 @@ export interface UpdateMarginMode {
|
||||
export interface UpdateMarginModeBody {
|
||||
updateMarginMode: UpdateMarginMode;
|
||||
}
|
||||
|
||||
export interface UpdatePartyProfile {
|
||||
updatePartyProfile: {
|
||||
alias: string;
|
||||
metadata: Array<{ key: string; value: string }>;
|
||||
};
|
||||
}
|
||||
|
||||
export type Transaction =
|
||||
| UpdateMarginModeBody
|
||||
| StopOrdersSubmissionBody
|
||||
@@ -510,7 +521,8 @@ export type Transaction =
|
||||
| ApplyReferralCode
|
||||
| JoinTeam
|
||||
| CreateReferralSet
|
||||
| UpdateReferralSet;
|
||||
| UpdateReferralSet
|
||||
| UpdatePartyProfile;
|
||||
|
||||
export interface TransactionResponse {
|
||||
transactionHash: string;
|
||||
|
||||
+1
-2
@@ -11,7 +11,6 @@
|
||||
"build:all": "nx run-many --all --target=build",
|
||||
"build-spec:all": "nx run-many --all --target=build-spec",
|
||||
"lint:all": "nx run-many --all --target=lint",
|
||||
"e2e:all": "nx run-many --all --target=e2e",
|
||||
"vegacapsule": "vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl",
|
||||
"release": "git checkout develop ; git pull ; node scripts/make-release.js",
|
||||
"trading:test": "cd apps/trading/e2e && poetry run pytest -k",
|
||||
@@ -77,7 +76,7 @@
|
||||
"jsondiffpatch": "^0.4.1",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "13.3.0",
|
||||
"pennant": "^1.15.0",
|
||||
"pennant": "^1.16.2",
|
||||
"react": "18.2.0",
|
||||
"react-copy-to-clipboard": "5.1.0",
|
||||
"react-dom": "18.2.0",
|
||||
|
||||
+43
-37
@@ -7,18 +7,18 @@ projects = []
|
||||
projects_e2e = []
|
||||
|
||||
previews = {
|
||||
'governance': 'not deployed',
|
||||
'explorer': 'not deployed',
|
||||
'trading': 'not deployed',
|
||||
'tools': 'not deployed',
|
||||
'governance': 'not deployed',
|
||||
'explorer': 'not deployed',
|
||||
'trading': 'not deployed',
|
||||
'tools': 'not deployed',
|
||||
}
|
||||
|
||||
main_apps = ['governance', 'explorer', 'trading']
|
||||
|
||||
preview_governance="not deployed"
|
||||
preview_trading="not deployed"
|
||||
preview_explorer="not deployed"
|
||||
preview_tools="not deployed"
|
||||
preview_governance = "not deployed"
|
||||
preview_trading = "not deployed"
|
||||
preview_explorer = "not deployed"
|
||||
preview_tools = "not deployed"
|
||||
|
||||
# take input from the pipeline
|
||||
parser = ArgumentParser()
|
||||
@@ -30,7 +30,8 @@ parser.add_argument('--event-name', help='name of event in CI')
|
||||
args = parser.parse_args()
|
||||
|
||||
# run yarn affected command
|
||||
affected=check_output(f'yarn nx print-affected --base={environ["NX_BASE"]} --head={environ["NX_HEAD"]} --select=projects'.split()).decode('utf-8')
|
||||
affected = check_output(
|
||||
f'yarn nx print-affected --base={environ["NX_BASE"]} --head={environ["NX_HEAD"]} --select=projects'.split()).decode('utf-8')
|
||||
|
||||
|
||||
# print useful information
|
||||
@@ -44,49 +45,54 @@ print(affected)
|
||||
print(">>>> eof debug")
|
||||
|
||||
# define affection actions -> add to projects arrays and generate preview link
|
||||
|
||||
|
||||
def affect_app(app, preview_name=None):
|
||||
print(f"{app} is affected")
|
||||
projects.append(app)
|
||||
if not preview_name:
|
||||
preview_name=app
|
||||
previews[app] = f'https://{preview_name}.{args.branch_slug}.vega.rocks'
|
||||
print(f"{app} is affected")
|
||||
projects.append(app)
|
||||
if not preview_name:
|
||||
preview_name = app
|
||||
previews[app] = f'https://{preview_name}.{args.branch_slug}.vega.rocks'
|
||||
|
||||
|
||||
# check appearance in the affected string for main apps
|
||||
for app in main_apps:
|
||||
if app in affected:
|
||||
affect_app(app)
|
||||
if app in affected:
|
||||
affect_app(app)
|
||||
|
||||
# if non of main apps is affected - test all of them
|
||||
if not projects:
|
||||
for app in main_apps:
|
||||
affect_app(app)
|
||||
for app in main_apps:
|
||||
affect_app(app)
|
||||
|
||||
# generate e2e targets
|
||||
projects_e2e = [f'{app}-e2e' for app in projects]
|
||||
|
||||
# remove trading-e2e because it doesn't exists any more (new target is: console-e2e)
|
||||
if "trading-e2e" in projects_e2e:
|
||||
projects_e2e.remove("trading-e2e")
|
||||
|
||||
# check affection for multisig-signer which is deployed only from develop and pull requests
|
||||
if args.event_name == 'pull_request' or 'develop' in args.github_ref:
|
||||
if 'multisig-signer' in affected:
|
||||
affect_app('multisig-signer', 'tools')
|
||||
if 'multisig-signer' in affected:
|
||||
affect_app('multisig-signer', 'tools')
|
||||
|
||||
# now parse apps that are deployed from develop but don't have previews
|
||||
if 'develop' in args.github_ref:
|
||||
for app in ['static', 'ui-toolkit']:
|
||||
if app in affected:
|
||||
projects.append(app)
|
||||
for app in ['static', 'ui-toolkit']:
|
||||
if app in affected:
|
||||
projects.append(app)
|
||||
|
||||
# if ref is in format release/{env}-{app} then only {app} is deployed
|
||||
if 'release' in args.github_ref:
|
||||
for app in main_apps:
|
||||
if f'{args.github_ref}'.endswith(app):
|
||||
projects = [app]
|
||||
projects_e2e = [f'{app}-e2e']
|
||||
for app in main_apps:
|
||||
if f'{args.github_ref}'.endswith(app):
|
||||
projects = [app]
|
||||
projects_e2e = [f'{app}-e2e']
|
||||
|
||||
|
||||
projects = json.dumps(projects)
|
||||
|
||||
# The trading project does not use the deafult NX e2e setup (cypress)
|
||||
projects_e2e.remove('trading-e2e')
|
||||
projects_e2e = json.dumps(projects_e2e)
|
||||
|
||||
print(f'Projects: {projects}')
|
||||
@@ -94,20 +100,20 @@ print(f'Projects E2E: {projects_e2e}')
|
||||
|
||||
print('>> Previews')
|
||||
for preview, preview_value in previews.items():
|
||||
print(f'{preview}: {preview_value}')
|
||||
print(f'{preview}: {preview_value}')
|
||||
print('>> EOF Previews')
|
||||
|
||||
|
||||
lines_to_write = [
|
||||
f'PREVIEW_GOVERNANCE={previews["governance"]}',
|
||||
f'PREVIEW_EXPLORER={previews["explorer"]}',
|
||||
f'PREVIEW_TRADING={previews["trading"]}',
|
||||
f'PREVIEW_TOOLS={previews["tools"]}',
|
||||
f'PROJECTS={projects}',
|
||||
f'PROJECTS_E2E={projects_e2e}',
|
||||
f'PREVIEW_GOVERNANCE={previews["governance"]}',
|
||||
f'PREVIEW_EXPLORER={previews["explorer"]}',
|
||||
f'PREVIEW_TRADING={previews["trading"]}',
|
||||
f'PREVIEW_TOOLS={previews["tools"]}',
|
||||
f'PROJECTS={projects}',
|
||||
f'PROJECTS_E2E={projects_e2e}',
|
||||
]
|
||||
env_file = environ['GITHUB_ENV']
|
||||
print(f'Line to add to GITHUB_ENV file: {env_file}')
|
||||
print(lines_to_write)
|
||||
with open(env_file, 'a') as _f:
|
||||
_f.write('\n'.join(lines_to_write))
|
||||
_f.write('\n'.join(lines_to_write))
|
||||
|
||||
@@ -1460,13 +1460,20 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
|
||||
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.7", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
version "7.23.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
|
||||
integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.13.10", "@babel/runtime@^7.21.0":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e"
|
||||
integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.22.5":
|
||||
version "7.23.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e"
|
||||
@@ -2438,14 +2445,22 @@
|
||||
resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4"
|
||||
integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==
|
||||
|
||||
"@floating-ui/core@^1.4.2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c"
|
||||
integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==
|
||||
"@floating-ui/core@^1.0.0", "@floating-ui/core@^1.4.2":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
||||
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.1.3"
|
||||
"@floating-ui/utils" "^0.2.1"
|
||||
|
||||
"@floating-ui/dom@^1.2.1", "@floating-ui/dom@^1.5.1":
|
||||
"@floating-ui/dom@^1.2.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
||||
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.0.0"
|
||||
"@floating-ui/utils" "^0.2.0"
|
||||
|
||||
"@floating-ui/dom@^1.5.1":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa"
|
||||
integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
|
||||
@@ -2472,6 +2487,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
|
||||
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
|
||||
|
||||
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
||||
integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==
|
||||
|
||||
"@graphql-codegen/add@^3.2.1":
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/add/-/add-3.2.3.tgz#f1ecee085987e7c21841edc4b1fd48877c663e1a"
|
||||
@@ -7024,9 +7044,9 @@
|
||||
integrity sha512-5a21DF7avVPmiUau8KTsv5r76yGqbMgq4QtByoCBPXUrVFWFkd3Ob4OOhmePNRbQqfUCNFjgB4sO7sUURnKcBg==
|
||||
|
||||
"@types/d3-shape@^2.0.0":
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.1.6.tgz#38b161512d303c69e709df573db203f199343324"
|
||||
integrity sha512-UvUXi3uJk7i9gstNlyh/+lidKy96AVp6lG6it586lYVIHjS2oRKkOSfaWdON6+Ziu+EqB8kbN3onxk+eP2wSmw==
|
||||
version "2.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.1.7.tgz#7c3bd6a9c758b54ba495cab0575cb18359251123"
|
||||
integrity sha512-HedHlfGHdwzKqX9+PiQVXZrdmGlwo7naoefJP7kCNk4Y7qcpQt1tUaoRa6qn0kbTdlaIHGO7111qLtb/6J8uuw==
|
||||
dependencies:
|
||||
"@types/d3-path" "^2"
|
||||
|
||||
@@ -7300,11 +7320,16 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/lodash@^4.14.167", "@types/lodash@^4.14.168", "@types/lodash@^4.14.171":
|
||||
"@types/lodash@^4.14.167", "@types/lodash@^4.14.171":
|
||||
version "4.14.201"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.201.tgz#76f47cb63124e806824b6c18463daf3e1d480239"
|
||||
integrity sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==
|
||||
|
||||
"@types/lodash@^4.14.168":
|
||||
version "4.14.202"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8"
|
||||
integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==
|
||||
|
||||
"@types/mdast@^3.0.0":
|
||||
version "3.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
|
||||
@@ -7391,7 +7416,14 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.61.tgz#5ea47e3018348bf3bbbe646b396ba5e720310be1"
|
||||
integrity sha512-k0N7BqGhJoJzdh6MuQg1V1ragJiXTh8VUBAZTWjJ9cUq23SG0F0xavOwZbhiP4J3y20xd6jxKx+xNUhkMAi76Q==
|
||||
|
||||
"@types/node@^18.0.0", "@types/node@^18.17.5":
|
||||
"@types/node@^18.0.0":
|
||||
version "18.19.21"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.21.tgz#f4ca1ac8ffb05ee4b89163c2d6fac9a1a59ee149"
|
||||
integrity sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@types/node@^18.17.5":
|
||||
version "18.18.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.9.tgz#5527ea1832db3bba8eb8023ce8497b7d3f299592"
|
||||
integrity sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==
|
||||
@@ -7425,7 +7457,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.3.tgz#47fe8e784c2dee24fe636cab82e090d3da9b7dec"
|
||||
integrity sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==
|
||||
|
||||
"@types/prop-types@*", "@types/prop-types@^15.0.0":
|
||||
"@types/prop-types@*":
|
||||
version "15.7.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
|
||||
integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==
|
||||
|
||||
"@types/prop-types@^15.0.0":
|
||||
version "15.7.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.10.tgz#892afc9332c4d62a5ea7e897fe48ed2085bbb08a"
|
||||
integrity sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==
|
||||
@@ -7454,13 +7491,20 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.5":
|
||||
"@types/react-dom@^18.0.0":
|
||||
version "18.2.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.15.tgz#921af67f9ee023ac37ea84b1bc0cc40b898ea522"
|
||||
integrity sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^18.0.5":
|
||||
version "18.2.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.20.tgz#cbdf7abb3cc2377980bb1294bc51375016a8320f"
|
||||
integrity sha512-HXN/biJY8nv20Cn9ZbCFq3liERd4CozVZmKbaiZ9KiKTrWqsP7eoGDO6OOGvJQwoVFuiXaiJ7nBBjiFFbRmQMQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@^5.3.3":
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
|
||||
@@ -7485,7 +7529,14 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-virtualized-auto-sizer@^1.0.0", "@types/react-virtualized-auto-sizer@^1.0.1":
|
||||
"@types/react-virtualized-auto-sizer@^1.0.0":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.4.tgz#42044ef75ac2d2667893a5943e54a9f037f985a3"
|
||||
integrity sha512-nhYwlFiYa8M3S+O2T9QO/e1FQUYMr/wJENUdf/O0dhRi1RS/93rjrYQFYdbUqtdFySuhrtnEDX29P6eKOttY+A==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-virtualized-auto-sizer@^1.0.1":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.3.tgz#13f4387c1b0b635b89d403970863b1ff464cd91e"
|
||||
integrity sha512-xRsQJiM8BuwGiDl77yyFZqq32lLvI4msFtw7nVbw9qh9c2LvchDXezwjEWmysJkXnLZWjHJX9lT8MCPkFy5BfQ==
|
||||
@@ -7507,10 +7558,10 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@>=16", "@types/react@^18.0.14":
|
||||
version "18.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.37.tgz#0f03af69e463c0f19a356c2660dbca5d19c44cae"
|
||||
integrity sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==
|
||||
"@types/react@*", "@types/react@^18.0.14":
|
||||
version "18.2.63"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.63.tgz#4637c56146ad90f96d0583171edab953f7e6fe57"
|
||||
integrity sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
@@ -7525,6 +7576,15 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@>=16":
|
||||
version "18.2.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.37.tgz#0f03af69e463c0f19a356c2660dbca5d19c44cae"
|
||||
integrity sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/resolve@1.17.1":
|
||||
version "1.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
|
||||
@@ -7545,9 +7605,9 @@
|
||||
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.6.tgz#eb26db6780c513de59bee0b869ef289ad3068711"
|
||||
integrity sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==
|
||||
version "0.16.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
|
||||
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
|
||||
|
||||
"@types/semver@^7.3.12", "@types/semver@^7.3.4", "@types/semver@^7.5.0":
|
||||
version "7.5.5"
|
||||
@@ -9999,7 +10059,22 @@ check-more-types@^2.24.0:
|
||||
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
|
||||
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2, chokidar@^3.5.3:
|
||||
"chokidar@>=3.0.0 <4.0.0":
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
||||
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
chokidar@^3.5.2, chokidar@^3.5.3:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
@@ -10051,11 +10126,16 @@ cjs-module-lexer@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107"
|
||||
integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==
|
||||
|
||||
classnames@*, classnames@^2.2, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.0, classnames@^2.3.1:
|
||||
classnames@*, classnames@^2.2, classnames@^2.2.5, classnames@^2.3.1:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
|
||||
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
|
||||
|
||||
classnames@^2.2.6, classnames@^2.3.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
|
||||
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
|
||||
|
||||
clean-css@^5.2.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224"
|
||||
@@ -10890,9 +10970,9 @@ cssstyle@^2.3.0:
|
||||
cssom "~0.3.6"
|
||||
|
||||
csstype@^3.0.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
|
||||
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||
|
||||
cypress-mochawesome-reporter@^3.3.0:
|
||||
version "3.6.1"
|
||||
@@ -11400,11 +11480,11 @@ del@^6.0.0:
|
||||
slash "^3.0.0"
|
||||
|
||||
delaunator@5:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b"
|
||||
integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278"
|
||||
integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==
|
||||
dependencies:
|
||||
robust-predicates "^3.0.0"
|
||||
robust-predicates "^3.0.2"
|
||||
|
||||
delay@^5.0.0:
|
||||
version "5.0.0"
|
||||
@@ -14314,9 +14394,9 @@ immer@^9.0.12:
|
||||
integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
|
||||
|
||||
immutable@^4.0.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
|
||||
integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
|
||||
version "4.3.5"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0"
|
||||
integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==
|
||||
|
||||
immutable@~3.7.6:
|
||||
version "3.7.6"
|
||||
@@ -17903,10 +17983,10 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
pennant@^1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-1.15.0.tgz#21854cf78466cbd27eda8143c21abcde070d4d76"
|
||||
integrity sha512-p3H4vu6BP7nUqn7s2pjyTl0FMJUT2U5lq5UKuxy55F2E66sJnvp5XFvNjRZvi42vyzsxG8WURgwQDQKNqQgWAw==
|
||||
pennant@^1.16.2:
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-1.16.2.tgz#5c6a63a2beda07ff86f7e33400d8570c171ac479"
|
||||
integrity sha512-/n1GzSWZFlgYCfSZubmZA2eiIoOvZPJJP9RKc/u2pOIPlp5Bn2Lq5uKyAT9bvjh/YDQtMhBKf92Q6DxJEDnJNw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@d3fc/d3fc-technical-indicator" "^8.0.1"
|
||||
@@ -19219,7 +19299,12 @@ react-use-websocket@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-3.0.0.tgz#754cb8eea76f55d31c5676d4abe3e573bc2cea04"
|
||||
integrity sha512-BInlbhXYrODBPKIplDAmI0J1VPM+1KhCLN09o+dzgQ8qMyrYs4t5kEYmCrTqyRuMTmpahylHFZWQXpfYyDkqOw==
|
||||
|
||||
react-virtualized-auto-sizer@^1.0.4, react-virtualized-auto-sizer@^1.0.6:
|
||||
react-virtualized-auto-sizer@^1.0.4:
|
||||
version "1.0.23"
|
||||
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.23.tgz#ddb18f775a00f672577f1ec01306a94ca26161b8"
|
||||
integrity sha512-5id3UTx+fG7b7SIOKL9/7aR1vP8+MtIT84cJCf09F6pYalB/nvHlx5EQvsSk27SwHUKjgPamG/nS8ynI0uSfKA==
|
||||
|
||||
react-virtualized-auto-sizer@^1.0.6:
|
||||
version "1.0.20"
|
||||
resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.20.tgz#d9a907253a7c221c52fa57dc775a6ef40c182645"
|
||||
integrity sha512-OdIyHwj4S4wyhbKHOKM1wLSj/UDXm839Z3Cvfg2a9j+He6yDa6i5p0qQvEiCnyQlGO/HyfSnigQwuxvYalaAXA==
|
||||
@@ -19430,9 +19515,9 @@ regenerator-runtime@^0.13.7:
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
|
||||
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||
|
||||
regenerator-transform@^0.15.2:
|
||||
version "0.15.2"
|
||||
@@ -19727,7 +19812,7 @@ rimraf@~2.6.2:
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
robust-predicates@^3.0.0:
|
||||
robust-predicates@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771"
|
||||
integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==
|
||||
@@ -19916,7 +20001,7 @@ sass@1.55.0:
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sass@^1.42.1, sass@^1.49.9:
|
||||
sass@^1.42.1:
|
||||
version "1.69.5"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde"
|
||||
integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==
|
||||
@@ -19925,6 +20010,15 @@ sass@^1.42.1, sass@^1.49.9:
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sass@^1.49.9:
|
||||
version "1.71.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.71.1.tgz#dfb09c63ce63f89353777bbd4a88c0a38386ee54"
|
||||
integrity sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sax@^1.2.4:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
|
||||
|
||||
Reference in New Issue
Block a user