chore(wallet): remove dependency on apollo from wallet lib (#4814)

This commit is contained in:
Bartłomiej Głownia 2023-10-05 11:25:54 +02:00 committed by GitHub
parent f4abd7cef5
commit 6dbde76c84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 632 additions and 933 deletions

View File

@ -11,7 +11,6 @@ import {
waitForBeginningOfEpoch,
} from '../../support/staking.functions';
import { previousEpochData } from '../../fixtures/mocks/previous-epoch';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
const guideLink = 'staking-guide-link';
const validatorTitle = 'validator-node-title';
@ -38,17 +37,11 @@ const txTimeout = Cypress.env('txTimeout');
context('Validators Page - verify elements on page', function () {
before('navigate to validators page', () => {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
cy.visit('/validators');
});
beforeEach(() => {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
});
describe('with wallets disconnected', { tags: '@smoke' }, function () {
@ -189,10 +182,7 @@ context('Validators Page - verify elements on page', function () {
{ tags: '@smoke' },
function () {
before('connect wallets and click on validator', function () {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
cy.visit('/validators');
cy.connectVegaWallet();
clickOnValidatorFromList(0);

View File

@ -4,8 +4,6 @@ import {
vegaWalletFaucetAssetsWithoutCheck,
vegaWalletTeardown,
} from '../../support/wallet-functions';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
const walletContainer = 'aside [data-testid="vega-wallet"]';
const walletHeader = '[data-testid="wallet-header"] h1';
@ -88,10 +86,7 @@ context(
describe('when vega wallet connected', function () {
before('connect vega wallet', function () {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
cy.visit('/');
cy.wait('@ChainId');
cy.connectVegaWallet();
@ -276,10 +271,7 @@ context(
];
before('faucet assets to connected vega wallet', function () {
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
for (const { id, amount } of assets) {
vegaWalletFaucetAssetsWithoutCheck(id, amount, vegaWalletPublicKey);
}

View File

@ -9,8 +9,6 @@ import './wallet-functions.ts';
import './proposal.functions.ts';
import 'cypress-mochawesome-reporter/register';
import registerCypressGrep from '@cypress/grep';
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
import { turnTelemetryOff } from './common.functions.ts';
registerCypressGrep();
@ -29,10 +27,7 @@ before(() => {
// // Ensuring the telemetry modal doesn't disrupt the tests
turnTelemetryOff();
// Mock chainId fetch which happens on every page for wallet connection
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
});
cy.mockChainId();
// Self stake validators so they are displayed
cy.validatorsSelfDelegate();
});

View File

@ -26,11 +26,11 @@ import {
} from '@vegaprotocol/web3';
import { Web3Provider } from '@vegaprotocol/web3';
import { VegaWalletDialogs } from './components/vega-wallet-dialogs';
import { VegaWalletProvider } from '@vegaprotocol/wallet';
import {
useVegaTransactionManager,
useVegaTransactionUpdater,
VegaWalletProvider,
} from '@vegaprotocol/wallet';
} from '@vegaprotocol/web3';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { useEthereumConfig } from '@vegaprotocol/web3';
import {

View File

@ -4,7 +4,7 @@ import {
getProposalDialogTitle,
} from '@vegaprotocol/proposals';
import type { ProposalEventFieldsFragment } from '@vegaprotocol/proposals';
import type { DialogProps } from '@vegaprotocol/wallet';
import type { DialogProps } from '@vegaprotocol/proposals';
interface ProposalFormTransactionDialogProps {
finalizedProposal: ProposalEventFieldsFragment | null;

View File

@ -6,7 +6,7 @@ import { ConnectToVega } from '../../../../components/connect-to-vega';
import { VoteButtonsContainer } from './vote-buttons';
import { SubHeading } from '../../../../components/heading';
import type { VoteValue } from '@vegaprotocol/types';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { VoteState } from './use-user-vote';

View File

@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/react';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { VoteState } from './use-user-vote';
import { VegaTxStatus } from '@vegaprotocol/wallet';
import { VegaTxStatus } from '@vegaprotocol/proposals';
describe('VoteTransactionDialog', () => {
const mockTransactionDialog = jest.fn(({ title, content }) => (

View File

@ -17,7 +17,7 @@ import { VoteState } from './use-user-vote';
import { ProposalMinRequirements, ProposalUserAction } from '../shared';
import { VoteTransactionDialog } from './vote-transaction-dialog';
import { useVoteButtonsQuery } from './__generated__/Stake';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
interface VoteButtonsContainerProps {
voteState: VoteState | null;

View File

@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
import { VoteState } from './use-user-vote';
import type { DialogProps, VegaTxState } from '@vegaprotocol/wallet';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals';
interface VoteTransactionDialogProps {
voteState: VoteState;

View File

@ -7,7 +7,6 @@ import {
assetQuery,
assetsQuery,
candlesQuery,
chainIdQuery,
chartQuery,
depositsQuery,
estimateFeesQuery,
@ -25,7 +24,6 @@ import {
estimatePositionQuery,
positionsQuery,
proposalListQuery,
statisticsQuery,
tradesQuery,
withdrawalsQuery,
protocolUpgradeProposalsQuery,
@ -91,8 +89,6 @@ const mockTradingPage = (
tradingMode?: Schema.MarketTradingMode,
trigger?: Schema.AuctionTrigger
) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'NodeCheck', statisticsQuery());
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
aliasGQLQuery(
req,
@ -218,6 +214,7 @@ export const addMockTradingPage = () => {
trigger,
oracleStatus
) => {
cy.mockChainId();
cy.mockGQL((req) => {
mockTradingPage(req, state, tradingMode, trigger);
});

View File

@ -10,12 +10,10 @@ import classNames from 'classnames';
import { Navigate, useSearchParams } from 'react-router-dom';
import { useEffect, useRef, useState } from 'react';
import { Button } from './buttons';
import {
useTransactionEventSubscription,
useVegaWallet,
} from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useReferral } from './hooks/use-referral';
import { Routes } from '../../lib/links';
import { useTransactionEventSubscription } from '@vegaprotocol/web3';
export const ApplyCodeForm = () => {
const [status, setStatus] = useState<

View File

@ -1,6 +1,6 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { WithdrawFormContainer } from '@vegaprotocol/withdraws';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
export const WithdrawContainer = ({ assetId }: { assetId?: string }) => {
const { pubKey } = useVegaWallet();

View File

@ -4,10 +4,12 @@ import type { AppProps } from 'next/app';
import { t } from '@vegaprotocol/i18n';
import {
useEagerConnect as useVegaEagerConnect,
useVegaTransactionManager,
useVegaTransactionUpdater,
useVegaWallet,
} from '@vegaprotocol/wallet';
import {
useVegaTransactionManager,
useVegaTransactionUpdater,
} from '@vegaprotocol/web3';
import {
useEagerConnect as useEthereumEagerConnect,
useEthTransactionManager,

View File

@ -7,7 +7,8 @@ import {
} from '@vegaprotocol/network-parameters';
import { useDataProvider } from '@vegaprotocol/data-provider';
import type { Transfer } from '@vegaprotocol/wallet';
import { useVegaTransactionStore, useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useCallback, useMemo } from 'react';
import { accountsDataProvider } from './accounts-data-provider';
import { TransferForm } from './transfer-form';

View File

@ -22,7 +22,6 @@ export * from '../markets/src/lib/oracle-spec-data-connection.mock';
export * from '../orders/src/lib/components/order-data-provider/orders.mock';
export * from '../positions/src/lib/positions.mock';
export * from '../network-parameters/src/network-params.mock';
export * from '../wallet/src/connect-dialog/chain-id.mock';
export * from '../positions/src/lib/estimate-position.mock';
export * from '../trades/src/lib/trades.mock';
export * from '../withdraws/src/lib/withdrawal.mock';

View File

@ -1,5 +1,5 @@
import { addGetTestIdcommand } from './lib/commands/get-by-test-id';
import { addMockGQLCommand } from './lib/mock-gql';
import { addMockGQLCommand, addMockStatistics } from './lib/mock-gql';
import { addMockSubscription } from './lib/mock-ws';
import { addMockWalletCommand } from './lib/mock-rest';
import { addMockWeb3ProviderCommand } from './lib/commands/mock-web3-provider';
@ -28,6 +28,7 @@ import { addMockChainId } from './lib/commands/mock-chain-id';
addGetTestIdcommand();
addMockGQLCommand();
addMockStatistics();
addMockSubscription();
addMockWalletCommand();
addMockWeb3ProviderCommand();

View File

@ -1,6 +1,6 @@
import { aliasGQLQuery } from '../mock-gql';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
import { statisticsQuery } from '@vegaprotocol/mock';
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
@ -12,11 +12,26 @@ declare global {
}
}
const chainId = 'test-id';
export function addMockChainId() {
Cypress.Commands.add('mockChainId', () => {
const result = {
statistics: {
chainId,
},
};
cy.mockGQL((req) => {
aliasGQLQuery(req, 'ChainId', chainIdQuery());
aliasGQLQuery(req, 'Statistics', statisticsQuery());
aliasGQLQuery(req, 'NodeCheck', statisticsQuery(result));
});
cy.mockStatistics((req) => {
req.reply({
statusCode: 200,
body: result,
headers: {
'Content-Type': 'application/json',
},
});
});
});
}

View File

@ -8,6 +8,7 @@ declare global {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
mockGQL(handler: RouteHandler): void;
mockStatistics(handler: RouteHandler): void;
}
}
}
@ -40,6 +41,16 @@ const extractVariables = (req: CyHttpMessages.IncomingHttpRequest): object => {
);
};
export function addMockStatistics() {
Cypress.Commands.add('mockStatistics', (handler: RouteHandler) => {
cy.intercept(
'GET',
Cypress.env('VEGA_URL').replace('graphql', 'statistics'),
handler
).as('ChainId');
});
}
export function addMockGQLCommand() {
Cypress.Commands.add('mockGQL', (handler: RouteHandler) => {
cy.intercept('POST', Cypress.env('VEGA_URL'), handler).as('GQL');

View File

@ -1,4 +1,4 @@
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
import {
isStopOrderType,
useDealTicketFormValues,

View File

@ -1,6 +1,7 @@
import { t } from '@vegaprotocol/i18n';
import { TradingButton } from '@vegaprotocol/ui-toolkit';
import { useVegaTransactionStore, useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
import { useHasAmendableOrder } from '../../order-hooks';
export const OpenOrdersMenu = ({ marketId }: { marketId: string }) => {

View File

@ -32,12 +32,6 @@ fragment OrderFields on Order {
}
}
query OrderById($orderId: ID!) {
orderByID(id: $orderId) {
...OrderFields
}
}
query Orders(
$partyId: ID!
$marketIds: [ID!]
@ -153,9 +147,3 @@ query StopOrders($filter: StopOrderFilter) {
}
}
}
query StopOrderById($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
...StopOrderFields
}
}

View File

@ -5,13 +5,6 @@ import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type OrderFieldsFragment = { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null };
export type OrderByIdQueryVariables = Types.Exact<{
orderId: Types.Scalars['ID'];
}>;
export type OrderByIdQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } };
export type OrdersQueryVariables = Types.Exact<{
partyId: Types.Scalars['ID'];
marketIds?: Types.InputMaybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>;
@ -43,13 +36,6 @@ export type StopOrdersQueryVariables = Types.Exact<{
export type StopOrdersQuery = { __typename?: 'Query', stopOrders?: { __typename?: 'StopOrderConnection', edges?: Array<{ __typename?: 'StopOrderEdge', node?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, order?: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } | null, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null }> | null } | null };
export type StopOrderByIdQueryVariables = Types.Exact<{
stopOrderId: Types.Scalars['ID'];
}>;
export type StopOrderByIdQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, order?: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } | null, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null };
export const OrderUpdateFieldsFragmentDoc = gql`
fragment OrderUpdateFields on OrderUpdate {
id
@ -161,41 +147,6 @@ export const StopOrderFieldsFragmentDoc = gql`
}
${OrderFieldsFragmentDoc}
${OrderSubmissionFieldsFragmentDoc}`;
export const OrderByIdDocument = gql`
query OrderById($orderId: ID!) {
orderByID(id: $orderId) {
...OrderFields
}
}
${OrderFieldsFragmentDoc}`;
/**
* __useOrderByIdQuery__
*
* To run a query within a React component, call `useOrderByIdQuery` and pass it any options that fit your needs.
* When your component renders, `useOrderByIdQuery` 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 } = useOrderByIdQuery({
* variables: {
* orderId: // value for 'orderId'
* },
* });
*/
export function useOrderByIdQuery(baseOptions: Apollo.QueryHookOptions<OrderByIdQuery, OrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<OrderByIdQuery, OrderByIdQueryVariables>(OrderByIdDocument, options);
}
export function useOrderByIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<OrderByIdQuery, OrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<OrderByIdQuery, OrderByIdQueryVariables>(OrderByIdDocument, options);
}
export type OrderByIdQueryHookResult = ReturnType<typeof useOrderByIdQuery>;
export type OrderByIdLazyQueryHookResult = ReturnType<typeof useOrderByIdLazyQuery>;
export type OrderByIdQueryResult = Apollo.QueryResult<OrderByIdQuery, OrderByIdQueryVariables>;
export const OrdersDocument = gql`
query Orders($partyId: ID!, $marketIds: [ID!], $pagination: Pagination, $filter: OrderFilter) {
party(id: $partyId) {
@ -320,39 +271,4 @@ export function useStopOrdersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions
}
export type StopOrdersQueryHookResult = ReturnType<typeof useStopOrdersQuery>;
export type StopOrdersLazyQueryHookResult = ReturnType<typeof useStopOrdersLazyQuery>;
export type StopOrdersQueryResult = Apollo.QueryResult<StopOrdersQuery, StopOrdersQueryVariables>;
export const StopOrderByIdDocument = gql`
query StopOrderById($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
...StopOrderFields
}
}
${StopOrderFieldsFragmentDoc}`;
/**
* __useStopOrderByIdQuery__
*
* To run a query within a React component, call `useStopOrderByIdQuery` and pass it any options that fit your needs.
* When your component renders, `useStopOrderByIdQuery` 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 } = useStopOrderByIdQuery({
* variables: {
* stopOrderId: // value for 'stopOrderId'
* },
* });
*/
export function useStopOrderByIdQuery(baseOptions: Apollo.QueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
}
export function useStopOrderByIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
}
export type StopOrderByIdQueryHookResult = ReturnType<typeof useStopOrderByIdQuery>;
export type StopOrderByIdLazyQueryHookResult = ReturnType<typeof useStopOrderByIdLazyQuery>;
export type StopOrderByIdQueryResult = Apollo.QueryResult<StopOrderByIdQuery, StopOrderByIdQueryVariables>;
export type StopOrdersQueryResult = Apollo.QueryResult<StopOrdersQuery, StopOrdersQueryVariables>;

View File

@ -5,11 +5,9 @@ import { OrderListTable } from '../order-list/order-list';
import type { useDataGridEvents } from '@vegaprotocol/datagrid';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { ordersWithMarketProvider } from '../order-data-provider/order-data-provider';
import {
normalizeOrderAmendment,
useVegaTransactionStore,
} from '@vegaprotocol/wallet';
import type { OrderTxUpdateFieldsFragment } from '@vegaprotocol/wallet';
import { normalizeOrderAmendment } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
import type { OrderTxUpdateFieldsFragment } from '@vegaprotocol/web3';
import { OrderEditDialog } from '../order-list/order-edit-dialog';
import type { Order } from '../order-data-provider';
import { OrderViewDialog } from '../order-list/order-view-dialog';

View File

@ -1,8 +1,6 @@
import type { Story, Meta } from '@storybook/react';
import { OrderListTable } from './order-list';
import { useState } from 'react';
import type { VegaTxState } from '@vegaprotocol/wallet';
import { VegaTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
import { generateOrdersArray } from '../mocks';
import { OrderEditDialog } from './order-edit-dialog';
import type { Order } from '../order-data-provider';
@ -32,25 +30,15 @@ const Template: Story = (args) => {
};
const Template2: Story = (args) => {
const [open, setOpen] = useState(false);
const [editOrder, setEditOrder] = useState<Order>();
const cancel = () => {
setOpen(!open);
return Promise.resolve();
};
const transaction: VegaTxState = {
status: VegaTxStatus.Requested,
error: null,
txHash: null,
signature: null,
dialogOpen: false,
};
return (
<>
<div style={{ height: 1000 }}>
<OrderListTable
rowData={args.data}
onCancel={cancel}
onCancel={() => {
return;
}}
onEdit={setEditOrder}
onView={() => {
return;
@ -58,11 +46,6 @@ const Template2: Story = (args) => {
isReadOnly={false}
/>
</div>
<VegaTransactionDialog
isOpen={open}
onChange={setOpen}
transaction={transaction}
/>
{editOrder && (
<OrderEditDialog
isOpen={Boolean(editOrder)}

View File

@ -2,12 +2,12 @@ import { t } from '@vegaprotocol/i18n';
import { useCallback, useEffect, useState } from 'react';
import { StopOrdersTable } from '../stop-orders-table/stop-orders-table';
import type { useDataGridEvents } from '@vegaprotocol/datagrid';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import type { StopOrder } from '../order-data-provider/stop-orders-data-provider';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { stopOrdersWithMarketProvider } from '../order-data-provider/stop-orders-data-provider';
import { OrderViewDialog } from '../order-list/order-view-dialog';
import type { Order, StopOrdersQueryVariables } from '../order-data-provider';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
export interface StopOrdersManagerProps {
partyId: string;

View File

@ -1,3 +1,2 @@
export * from './__generated__/OrdersSubscription';
export * from './use-has-amendable-order';
export * from './use-order-update';

View File

@ -1,60 +0,0 @@
import { useApolloClient } from '@apollo/client';
import { useCallback, useEffect, useRef } from 'react';
import { OrderSubDocument } from './__generated__/OrdersSubscription';
import type {
OrderSubSubscription,
OrderSubSubscriptionVariables,
OrderSubFieldsFragment,
} from './__generated__/OrdersSubscription';
import type { Subscription } from 'zen-observable-ts';
import type { VegaTxState } from '@vegaprotocol/wallet';
type WaitFunc = (
orderId: string,
partyId: string
) => Promise<OrderSubFieldsFragment>;
export const useOrderUpdate = (transaction: VegaTxState) => {
const client = useApolloClient();
const subRef = useRef<Subscription | null>(null);
const waitForOrderUpdate = useCallback<WaitFunc>(
(id: string, partyId: string) => {
return new Promise((resolve) => {
subRef.current = client
.subscribe<OrderSubSubscription, OrderSubSubscriptionVariables>({
query: OrderSubDocument,
variables: { partyId },
})
.subscribe(({ data }) => {
if (!data?.orders?.length) {
return;
}
// No types available for the subscription result
const matchingOrder = data.orders.find((order) => {
return order.id === id;
});
if (matchingOrder) {
resolve(matchingOrder);
subRef.current?.unsubscribe();
}
});
});
},
[client]
);
useEffect(() => {
if (!transaction.dialogOpen) {
subRef.current?.unsubscribe();
}
return () => {
subRef.current?.unsubscribe();
};
}, [transaction.dialogOpen]);
return waitForOrderUpdate;
};

View File

@ -1,110 +1,7 @@
import { Intent } from '@vegaprotocol/ui-toolkit';
import {
getOrderToastIntent,
getOrderToastTitle,
getRejectionReason,
timeInForceLabel,
} from './utils';
import { timeInForceLabel } from './utils';
import * as Types from '@vegaprotocol/types';
describe('WithdrawalsTable', () => {
describe('getOrderToastTitle', () => {
it('should return the correct title', () => {
expect(getOrderToastTitle(Types.OrderStatus.STATUS_ACTIVE)).toBe(
'Order submitted'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_FILLED)).toBe(
'Order filled'
);
expect(
getOrderToastTitle(Types.OrderStatus.STATUS_PARTIALLY_FILLED)
).toBe('Order partially filled');
expect(getOrderToastTitle(Types.OrderStatus.STATUS_PARKED)).toBe(
'Order parked'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_STOPPED)).toBe(
'Order stopped'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_CANCELLED)).toBe(
'Order cancelled'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_EXPIRED)).toBe(
'Order expired'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_REJECTED)).toBe(
'Order rejected'
);
expect(getOrderToastTitle(undefined)).toBe(undefined);
});
});
describe('getOrderToastIntent', () => {
it('should return the correct intent', () => {
expect(getOrderToastIntent(Types.OrderStatus.STATUS_PARKED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_EXPIRED)).toBe(
Intent.Warning
);
expect(
getOrderToastIntent(Types.OrderStatus.STATUS_PARTIALLY_FILLED)
).toBe(Intent.Warning);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_REJECTED)).toBe(
Intent.Danger
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_STOPPED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_FILLED)).toBe(
Intent.Success
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_ACTIVE)).toBe(
Intent.Success
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_CANCELLED)).toBe(
Intent.Success
);
expect(getOrderToastIntent(undefined)).toBe(undefined);
});
});
describe('getRejectionReason', () => {
it('should return the correct rejection reason for insufficient asset balance', () => {
expect(
getRejectionReason({
rejectionReason:
Types.OrderRejectionReason.ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE,
status: Types.OrderStatus.STATUS_REJECTED,
id: '',
createdAt: undefined,
size: '',
price: '',
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
side: Types.Side.SIDE_BUY,
marketId: '',
})
).toBe('Insufficient asset balance');
});
it('should return the correct rejection reason when order is stopped', () => {
expect(
getRejectionReason({
rejectionReason: null,
status: Types.OrderStatus.STATUS_STOPPED,
id: '',
createdAt: undefined,
size: '',
price: '',
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
side: Types.Side.SIDE_BUY,
marketId: '',
})
).toBe(
'Your Fill or Kill (FOK) order was not filled and it has been stopped'
);
});
});
describe('utils', () => {
describe('timeInForceLabel', () => {
it('should return the correct label for time in force', () => {
expect(timeInForceLabel(Types.OrderTimeInForce.TIME_IN_FORCE_FOK)).toBe(

View File

@ -1,7 +1,5 @@
import { t } from '@vegaprotocol/i18n';
import * as Schema from '@vegaprotocol/types';
import type { OrderSubFieldsFragment } from './order-hooks';
import { Intent } from '@vegaprotocol/ui-toolkit';
// More detail in https://docs.vega.xyz/mainnet/graphql/enums/order-time-in-force
export const timeInForceLabel = (tif: string) => {
@ -22,72 +20,3 @@ export const timeInForceLabel = (tif: string) => {
return t(tif);
}
};
export const getRejectionReason = (
order: OrderSubFieldsFragment
): string | null => {
switch (order.status) {
case Schema.OrderStatus.STATUS_STOPPED:
return t(
`Your ${
Schema.OrderTimeInForceMapping[order.timeInForce]
} order was not filled and it has been stopped`
);
default:
return order.rejectionReason
? t(Schema.OrderRejectionReasonMapping[order.rejectionReason])
: '';
}
};
export const getOrderToastTitle = (
status?: Schema.OrderStatus
): string | undefined => {
if (!status) {
return;
}
switch (status) {
case Schema.OrderStatus.STATUS_ACTIVE:
return t('Order submitted');
case Schema.OrderStatus.STATUS_FILLED:
return t('Order filled');
case Schema.OrderStatus.STATUS_PARTIALLY_FILLED:
return t('Order partially filled');
case Schema.OrderStatus.STATUS_PARKED:
return t('Order parked');
case Schema.OrderStatus.STATUS_STOPPED:
return t('Order stopped');
case Schema.OrderStatus.STATUS_CANCELLED:
return t('Order cancelled');
case Schema.OrderStatus.STATUS_EXPIRED:
return t('Order expired');
case Schema.OrderStatus.STATUS_REJECTED:
return t('Order rejected');
default:
return t('Submission failed');
}
};
export const getOrderToastIntent = (
status?: Schema.OrderStatus
): Intent | undefined => {
if (!status) {
return;
}
switch (status) {
case Schema.OrderStatus.STATUS_PARKED:
case Schema.OrderStatus.STATUS_EXPIRED:
case Schema.OrderStatus.STATUS_PARTIALLY_FILLED:
case Schema.OrderStatus.STATUS_STOPPED:
return Intent.Warning;
case Schema.OrderStatus.STATUS_REJECTED:
return Intent.Danger;
case Schema.OrderStatus.STATUS_FILLED:
case Schema.OrderStatus.STATUS_ACTIVE:
case Schema.OrderStatus.STATUS_CANCELLED:
return Intent.Success;
default:
return;
}
};

View File

@ -9,6 +9,9 @@ const mockCreate = jest.fn();
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
useVegaWallet: jest.fn(() => ({ pubKey: 'partyId' })),
}));
jest.mock('@vegaprotocol/web3', () => ({
...jest.requireActual('@vegaprotocol/web3'),
useVegaTransactionStore: jest.fn(() => mockCreate),
}));
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@ -1,7 +1,8 @@
import { useCallback } from 'react';
import { PositionsTable } from './positions-table';
import * as Schema from '@vegaprotocol/types';
import { useVegaTransactionStore, useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { t } from '@vegaprotocol/i18n';
import { useDataProvider } from '@vegaprotocol/data-provider';
import {

View File

@ -5,3 +5,4 @@ export * from './protocol-upgrade-countdown';
export * from './protocol-upgrade-in-progress-notification';
export * from './protocol-upgrade-proposal-notification';
export * from './voting-progress';
export * from './vega-transaction-dialog';

View File

@ -1,8 +1,8 @@
import { render, screen } from '@testing-library/react';
import { WalletError } from '../connectors';
import type { VegaWalletContextShape } from '../context';
import { VegaWalletContext } from '../context';
import { VegaTxStatus } from '../types';
import { WalletError } from '@vegaprotocol/wallet';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { VegaTxStatus } from '../../lib/proposals-hooks/use-vega-transaction';
import type { VegaTransactionDialogProps } from './vega-transaction-dialog';
import { VegaTransactionDialog } from './vega-transaction-dialog';

View File

@ -2,9 +2,9 @@ import type { ReactNode } from 'react';
import { t } from '@vegaprotocol/i18n';
import { Dialog, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
import { WalletClientError } from '@vegaprotocol/wallet-client';
import type { VegaTxState } from '../types';
import { VegaTxStatus } from '../types';
import { useVegaWallet } from '../use-vega-wallet';
import type { VegaTxState } from '../../lib/proposals-hooks/use-vega-transaction';
import { VegaTxStatus } from '../../lib/proposals-hooks/use-vega-transaction';
import { useVegaWallet } from '@vegaprotocol/wallet';
export type VegaTransactionContentMap = {
[C in VegaTxStatus]?: JSX.Element;

View File

@ -1,5 +1,6 @@
export * from './__generated__/Proposal';
export * from './use-proposal-event';
export * from './use-vega-transaction';
export * from './use-proposal-submit';
export * from './use-update-proposal';
export * from './use-update-network-paramaters-toasts';

View File

@ -7,7 +7,7 @@ import type {
ProposalEventFieldsFragment,
} from './__generated__/Proposal';
import type { Subscription } from 'zen-observable-ts';
import type { VegaTxState } from '@vegaprotocol/wallet';
import type { VegaTxState } from '../proposals-hooks/use-vega-transaction';
export const useProposalEvent = (transaction: VegaTxState) => {
const client = useApolloClient();

View File

@ -1,10 +1,7 @@
import { useCallback, useState } from 'react';
import * as Sentry from '@sentry/react';
import {
useVegaWallet,
useVegaTransaction,
determineId,
} from '@vegaprotocol/wallet';
import { useVegaWallet, determineId } from '@vegaprotocol/wallet';
import { useVegaTransaction } from './use-vega-transaction';
import { useProposalEvent } from './use-proposal-event';
import type { ProposalSubmission } from '@vegaprotocol/wallet';
import type { ProposalEventFieldsFragment } from './__generated__/Proposal';

View File

@ -1,11 +1,12 @@
import { act, renderHook } from '@testing-library/react';
import type { VegaWalletContextShape } from './context';
import { VegaWalletContext } from './context';
import type { VegaWalletContextShape, Transaction } from '@vegaprotocol/wallet';
import { VegaWalletContext, WalletError } from '@vegaprotocol/wallet';
import type { ReactNode } from 'react';
import { initialState, useVegaTransaction } from './use-vega-transaction';
import type { Transaction } from './connectors';
import { WalletError } from './connectors';
import { VegaTxStatus } from './types';
import {
initialState,
useVegaTransaction,
VegaTxStatus,
} from './use-vega-transaction';
const mockPubKey = '0x123';

View File

@ -4,15 +4,27 @@ import {
WalletClientError,
WalletHttpError,
} from '@vegaprotocol/wallet-client';
import { useVegaWallet } from './use-vega-wallet';
import type { VegaTransactionContentMap } from './vega-transaction-dialog';
import { VegaTransactionDialog } from './vega-transaction-dialog';
import { useVegaWallet, WalletError, ClientErrors } from '@vegaprotocol/wallet';
import type { Transaction } from '@vegaprotocol/wallet';
import type { VegaTransactionContentMap } from '../../components/vega-transaction-dialog';
import { VegaTransactionDialog } from '../../components/vega-transaction-dialog';
import type { Intent } from '@vegaprotocol/ui-toolkit';
import type { Transaction } from './connectors';
import { WalletError } from './connectors';
import { ClientErrors } from './connectors';
import type { VegaTxState } from './types';
import { VegaTxStatus } from './types';
export enum VegaTxStatus {
Default = 'Default',
Requested = 'Requested',
Pending = 'Pending',
Error = 'Error',
Complete = 'Complete',
}
export interface VegaTxState {
status: VegaTxStatus;
error: Error | null;
txHash: string | null;
signature: string | null;
dialogOpen: boolean;
}
export interface DialogProps {
intent?: Intent;

View File

@ -2,7 +2,7 @@ import { useApolloClient } from '@apollo/client';
import { useCallback, useEffect, useRef } from 'react';
import { VoteEventDocument } from './__generated__/VoteSubsciption';
import type { Subscription } from 'zen-observable-ts';
import type { VegaTxState } from '@vegaprotocol/wallet';
import type { VegaTxState } from '../proposals-hooks/use-vega-transaction';
import type {
VoteEventFieldsFragment,
VoteEventSubscription,

View File

@ -1,6 +1,7 @@
import { useCallback, useState } from 'react';
import * as Sentry from '@sentry/react';
import { useVegaTransaction, useVegaWallet } from '@vegaprotocol/wallet';
import { useVegaTransaction } from '../proposals-hooks/use-vega-transaction';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useVoteEvent } from './use-vote-event';
import type { VoteValue } from '@vegaprotocol/types';
import type { VoteEventFieldsFragment } from './__generated__/VoteSubsciption';

View File

@ -1,5 +0,0 @@
query ChainId {
statistics {
chainId
}
}

View File

@ -1,45 +0,0 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ChainIdQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ChainIdQuery = { __typename?: 'Query', statistics: { __typename?: 'Statistics', chainId: string } };
export const ChainIdDocument = gql`
query ChainId {
statistics {
chainId
}
}
`;
/**
* __useChainIdQuery__
*
* To run a query within a React component, call `useChainIdQuery` and pass it any options that fit your needs.
* When your component renders, `useChainIdQuery` 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 } = useChainIdQuery({
* variables: {
* },
* });
*/
export function useChainIdQuery(baseOptions?: Apollo.QueryHookOptions<ChainIdQuery, ChainIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<ChainIdQuery, ChainIdQueryVariables>(ChainIdDocument, options);
}
export function useChainIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ChainIdQuery, ChainIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<ChainIdQuery, ChainIdQueryVariables>(ChainIdDocument, options);
}
export type ChainIdQueryHookResult = ReturnType<typeof useChainIdQuery>;
export type ChainIdLazyQueryHookResult = ReturnType<typeof useChainIdLazyQuery>;
export type ChainIdQueryResult = Apollo.QueryResult<ChainIdQuery, ChainIdQueryVariables>;

View File

@ -1,16 +0,0 @@
import type { ChainIdQuery } from './__generated__/ChainId';
import merge from 'lodash/merge';
import type { PartialDeep } from 'type-fest';
export const chainIdQuery = (
override?: PartialDeep<ChainIdQuery>
): ChainIdQuery => {
const defaultResult = {
statistics: {
__typename: 'Statistics',
chainId: 'test-id',
},
};
return merge(defaultResult, override);
};

View File

@ -1,6 +1,4 @@
import { act, fireEvent, render, screen } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import type { VegaWalletConfig } from '../provider';
import { VegaWalletProvider } from '../provider';
import { VegaConnectDialog, CLOSE_DELAY } from './connect-dialog';
@ -13,8 +11,6 @@ import {
ViewConnector,
WalletError,
} from '../connectors';
import type { ChainIdQuery } from './__generated__/ChainId';
import { ChainIdDocument } from './__generated__/ChainId';
import {
mockBrowserWallet,
clearBrowserWallet,
@ -26,6 +22,7 @@ const mockUpdateDialogOpen = jest.fn();
const mockCloseVegaDialog = jest.fn();
let mockIsDesktopRunning = true;
const mockChainId = 'chain-id';
jest.mock('../use-is-wallet-service-running', () => ({
useIsWalletServiceRunning: jest
@ -33,6 +30,10 @@ jest.mock('../use-is-wallet-service-running', () => ({
.mockImplementation(() => mockIsDesktopRunning),
}));
jest.mock('./use-chain-id', () => ({
useChainId: jest.fn().mockImplementation(() => mockChainId),
}));
let defaultProps: VegaConnectDialogProps;
const INITIAL_KEY = 'some-key';
@ -60,8 +61,6 @@ beforeEach(() => {
});
});
const mockChainId = 'chain-id';
const defaultConfig: VegaWalletConfig = {
network: 'TESTNET',
vegaUrl: 'https://vega.xyz',
@ -78,24 +77,10 @@ function generateJSX(
props?: Partial<VegaConnectDialogProps>,
config?: Partial<VegaWalletConfig>
) {
const chainIdMock: MockedResponse<ChainIdQuery> = {
request: {
query: ChainIdDocument,
},
result: {
data: {
statistics: {
chainId: mockChainId,
},
},
},
};
return (
<MockedProvider mocks={[chainIdMock]}>
<VegaWalletProvider config={{ ...defaultConfig, ...config }}>
<VegaConnectDialog {...defaultProps} {...props} />
</VegaWalletProvider>
</MockedProvider>
<VegaWalletProvider config={{ ...defaultConfig, ...config }}>
<VegaConnectDialog {...defaultProps} {...props} />
</VegaWalletProvider>
);
}

View File

@ -35,13 +35,13 @@ import type { Status as JsonRpcStatus } from '../use-json-rpc-connect';
import { useJsonRpcConnect } from '../use-json-rpc-connect';
import type { Status as InjectedStatus } from '../use-injected-connector';
import { useInjectedConnector } from '../use-injected-connector';
import { useChainIdQuery } from './__generated__/ChainId';
import { useVegaWallet } from '../use-vega-wallet';
import { InjectedConnectorForm } from './injected-connector-form';
import { isBrowserWalletInstalled } from '../utils';
import { useIsWalletServiceRunning } from '../use-is-wallet-service-running';
import { SnapStatus, useSnapStatus } from '../use-snap-status';
import { useVegaWalletDialogStore } from './vega-wallet-dialog-store';
import { useChainId } from './use-chain-id';
export const CLOSE_DELAY = 1700;
@ -82,12 +82,12 @@ export const VegaConnectDialog = ({
// Ensure we have a chain Id so we can compare with wallet chain id.
// This value will already be in the cache, if it failed the app wont render
const { data } = useChainIdQuery();
const chainId = useChainId();
const content = data && (
const content = chainId && (
<ConnectDialogContainer
connectors={connectors}
appChainId={data.statistics.chainId}
appChainId={chainId}
riskMessage={riskMessage}
onClose={onClose}
/>

View File

@ -0,0 +1,37 @@
import { useEffect, useState } from 'react';
import { useVegaWallet } from '../use-vega-wallet';
const cache: Record<string, string> = {};
export const useChainId = () => {
const { vegaUrl } = useVegaWallet();
const [chainId, setChainId] = useState<undefined | string>(cache[vegaUrl]);
const [fetchAttempt, setFetchAttempt] = useState(1);
useEffect(() => {
let isCancelled = false;
if (cache[vegaUrl]) {
setChainId(cache[vegaUrl]);
return;
}
fetch(vegaUrl.replace('graphql', 'statistics'))
.then((response) => response.json())
.then((response) => {
if (isCancelled) {
return;
}
if (!response?.statistics?.chainId) {
throw new Error('statistics.chainId not present in fetched response');
}
setChainId(response?.statistics?.chainId);
})
.catch(() => {
if (fetchAttempt < 3) {
setFetchAttempt((value) => (value += 1));
}
});
return () => {
isCancelled = true;
};
}, [fetchAttempt, vegaUrl]);
return chainId;
};

View File

@ -1,18 +1,9 @@
export * from './connectors';
export * from './context';
export * from './use-vega-transaction';
export * from './use-vega-wallet';
export * from './use-vega-transaction-manager';
export * from './use-vega-transaction-store';
export * from './use-vega-transaction-updater';
export * from './use-transaction-result';
export * from './use-eager-connect';
export * from './manage-dialog';
export * from './provider';
export * from './connect-dialog';
export * from './utils';
export * from './storage';
export * from './types';
export * from './vega-transaction-dialog';
export * from './__generated__/TransactionResult';
export * from './__generated__/WithdrawalApproval';

View File

@ -28,3 +28,10 @@ export * from './lib/web3-provider';
export * from './lib/withdrawal-approval-dialog';
export * from './lib/withdrawal-approval-status';
export * from './lib/default-web3-provider';
export * from './lib/use-vega-transaction-manager';
export * from './lib/use-vega-transaction-store';
export * from './lib/use-vega-transaction-updater';
export * from './lib/use-transaction-result';
export * from './lib/types';
export * from './lib/__generated__/TransactionResult';
export * from './lib/__generated__/WithdrawalApproval';

View File

@ -0,0 +1,74 @@
query OrderById($orderId: ID!) {
orderByID(id: $orderId) {
id
market {
id
}
type
side
size
status
rejectionReason
price
timeInForce
remaining
expiresAt
createdAt
updatedAt
postOnly
reduceOnly
liquidityProvision {
__typename
}
peggedOrder {
__typename
reference
offset
}
icebergOrder {
__typename
peakSize
minimumVisibleSize
reservedRemaining
}
}
}
query StopOrderById($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
id
ocoLinkId
expiresAt
expiryStrategy
triggerDirection
status
createdAt
updatedAt
partyId
marketId
trigger {
... on StopOrderPrice {
price
}
... on StopOrderTrailingPercentOffset {
trailingPercentOffset
}
}
submission {
marketId
price
size
side
timeInForce
expiresAt
type
reference
peggedOrder {
reference
offset
}
postOnly
reduceOnly
}
}
}

153
libs/web3/src/lib/__generated__/Orders.ts generated Normal file
View File

@ -0,0 +1,153 @@
import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type OrderByIdQueryVariables = Types.Exact<{
orderId: Types.Scalars['ID'];
}>;
export type OrderByIdQuery = { __typename?: 'Query', orderByID: { __typename?: 'Order', id: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, postOnly?: boolean | null, reduceOnly?: boolean | null, market: { __typename?: 'Market', id: string }, liquidityProvision?: { __typename: 'LiquidityProvision' } | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null } };
export type StopOrderByIdQueryVariables = Types.Exact<{
stopOrderId: Types.Scalars['ID'];
}>;
export type StopOrderByIdQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string }, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null };
export const OrderByIdDocument = gql`
query OrderById($orderId: ID!) {
orderByID(id: $orderId) {
id
market {
id
}
type
side
size
status
rejectionReason
price
timeInForce
remaining
expiresAt
createdAt
updatedAt
postOnly
reduceOnly
liquidityProvision {
__typename
}
peggedOrder {
__typename
reference
offset
}
icebergOrder {
__typename
peakSize
minimumVisibleSize
reservedRemaining
}
}
}
`;
/**
* __useOrderByIdQuery__
*
* To run a query within a React component, call `useOrderByIdQuery` and pass it any options that fit your needs.
* When your component renders, `useOrderByIdQuery` 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 } = useOrderByIdQuery({
* variables: {
* orderId: // value for 'orderId'
* },
* });
*/
export function useOrderByIdQuery(baseOptions: Apollo.QueryHookOptions<OrderByIdQuery, OrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<OrderByIdQuery, OrderByIdQueryVariables>(OrderByIdDocument, options);
}
export function useOrderByIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<OrderByIdQuery, OrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<OrderByIdQuery, OrderByIdQueryVariables>(OrderByIdDocument, options);
}
export type OrderByIdQueryHookResult = ReturnType<typeof useOrderByIdQuery>;
export type OrderByIdLazyQueryHookResult = ReturnType<typeof useOrderByIdLazyQuery>;
export type OrderByIdQueryResult = Apollo.QueryResult<OrderByIdQuery, OrderByIdQueryVariables>;
export const StopOrderByIdDocument = gql`
query StopOrderById($stopOrderId: ID!) {
stopOrder(id: $stopOrderId) {
id
ocoLinkId
expiresAt
expiryStrategy
triggerDirection
status
createdAt
updatedAt
partyId
marketId
trigger {
... on StopOrderPrice {
price
}
... on StopOrderTrailingPercentOffset {
trailingPercentOffset
}
}
submission {
marketId
price
size
side
timeInForce
expiresAt
type
reference
peggedOrder {
reference
offset
}
postOnly
reduceOnly
}
}
}
`;
/**
* __useStopOrderByIdQuery__
*
* To run a query within a React component, call `useStopOrderByIdQuery` and pass it any options that fit your needs.
* When your component renders, `useStopOrderByIdQuery` 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 } = useStopOrderByIdQuery({
* variables: {
* stopOrderId: // value for 'stopOrderId'
* },
* });
*/
export function useStopOrderByIdQuery(baseOptions: Apollo.QueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
}
export function useStopOrderByIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
}
export type StopOrderByIdQueryHookResult = ReturnType<typeof useStopOrderByIdQuery>;
export type StopOrderByIdLazyQueryHookResult = ReturnType<typeof useStopOrderByIdLazyQuery>;
export type StopOrderByIdQueryResult = Apollo.QueryResult<StopOrderByIdQuery, StopOrderByIdQueryVariables>;

View File

@ -0,0 +1,4 @@
import '@testing-library/jest-dom';
import ResizeObserver from 'resize-observer-polyfill';
global.ResizeObserver = ResizeObserver;

View File

@ -7,7 +7,7 @@ import type { Token } from '@vegaprotocol/smart-contracts';
import type {
DepositBusEventFieldsFragment,
WithdrawalBusEventFieldsFragment,
} from '@vegaprotocol/wallet';
} from './__generated__/TransactionResult';
import type { EthTxState } from './use-ethereum-transaction';
import { EthTxStatus } from './use-ethereum-transaction';

View File

@ -3,15 +3,13 @@ import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import type { ReactNode } from 'react';
import { useEthTransactionUpdater } from './use-ethereum-transaction-updater';
import {
DepositBusEventDocument,
VegaWalletContext,
} from '@vegaprotocol/wallet';
import { DepositBusEventDocument } from './__generated__/TransactionResult';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import type {
DepositBusEventSubscription,
DepositBusEventFieldsFragment,
VegaWalletContextShape,
} from '@vegaprotocol/wallet';
} from './__generated__/TransactionResult';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import type { EthTransactionStore } from './use-ethereum-transaction-store';
import { DepositStatus } from '@vegaprotocol/types';

View File

@ -1,8 +1,6 @@
import { DepositStatus } from '@vegaprotocol/types';
import {
useDepositBusEventSubscription,
useVegaWallet,
} from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useDepositBusEventSubscription } from './__generated__/TransactionResult';
import { useEthTransactionStore } from './use-ethereum-transaction-store';
export const useEthTransactionUpdater = () => {

View File

@ -16,8 +16,8 @@ import type {
} from './use-ethereum-withdraw-approvals-store';
import type { EthTransactionStore } from './use-ethereum-transaction-store';
import { WithdrawalApprovalDocument } from '@vegaprotocol/wallet';
import type { WithdrawalApprovalQuery } from '@vegaprotocol/wallet';
import { WithdrawalApprovalDocument } from './__generated__/WithdrawalApproval';
import type { WithdrawalApprovalQuery } from './__generated__/WithdrawalApproval';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';

View File

@ -15,9 +15,9 @@ import { useWeb3React } from '@web3-react/core';
import type {
WithdrawalApprovalQuery,
WithdrawalApprovalQueryVariables,
} from '@vegaprotocol/wallet';
} from './__generated__/WithdrawalApproval';
import { WithdrawalApprovalDocument } from '@vegaprotocol/wallet';
import { WithdrawalApprovalDocument } from './__generated__/WithdrawalApproval';
import { useEthTransactionStore } from './use-ethereum-transaction-store';
import {

View File

@ -1,12 +1,12 @@
import { useEthWithdrawApprovalsStore } from './use-ethereum-withdraw-approvals-store';
import type { VegaStoredTxState } from '@vegaprotocol/wallet';
import type { VegaStoredTxState } from './use-vega-transaction-store';
import { ApprovalStatus } from './use-ethereum-withdraw-approvals-store';
import type { EthWithdrawalApprovalState } from './use-ethereum-withdraw-approvals-store';
const mockFindVegaTransaction = jest.fn<VegaStoredTxState, []>();
const mockDismissVegaTransaction = jest.fn();
jest.mock('@vegaprotocol/wallet', () => ({
jest.mock('./use-vega-transaction-store', () => ({
useVegaTransactionStore: {
getState: () => ({
transactions: {

View File

@ -1,10 +1,10 @@
import { create } from 'zustand';
import produce from 'immer';
import type BigNumber from 'bignumber.js';
import type { WithdrawalBusEventFieldsFragment } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import type { WithdrawalBusEventFieldsFragment } from './__generated__/TransactionResult';
import { useVegaTransactionStore } from './use-vega-transaction-store';
import type { WithdrawalApprovalQuery } from '@vegaprotocol/wallet';
import type { WithdrawalApprovalQuery } from './__generated__/WithdrawalApproval';
import { subscribeWithSelector } from 'zustand/middleware';
export enum ApprovalStatus {

View File

@ -2,7 +2,7 @@ import { useCallback } from 'react';
import { useBridgeContract } from './use-bridge-contract';
import BigNumber from 'bignumber.js';
import { addDecimal } from '@vegaprotocol/utils';
import type { WithdrawalBusEventFieldsFragment } from '@vegaprotocol/wallet';
import type { WithdrawalBusEventFieldsFragment } from './__generated__/TransactionResult';
import { localLoggerFactory } from '@vegaprotocol/logger';
type Asset = Pick<

View File

@ -1,19 +1,20 @@
import { useVegaTransactionManager } from './use-vega-transaction-manager';
import { renderHook } from '@testing-library/react';
import waitForNextTick from 'flush-promises';
import type { TransactionResponse } from './connectors/vega-connector';
import type { TransactionResponse } from '@vegaprotocol/wallet';
import { VegaTxStatus } from './types';
import type {
VegaTransactionStore,
VegaStoredTxState,
} from './use-vega-transaction-store';
const mockSendTx = jest.fn<Promise<Partial<TransactionResponse> | null>, []>();
const mockSendTx = jest.fn();
const pubKey = 'pubKey';
const mockDisconnect = jest.fn();
jest.mock('./use-vega-wallet', () => ({
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
useVegaWallet: () => ({
sendTx: mockSendTx,
pubKey,

View File

@ -1,7 +1,5 @@
import { useVegaWallet } from './use-vega-wallet';
import { useVegaWallet, WalletError, ClientErrors } from '@vegaprotocol/wallet';
import { useEffect, useRef } from 'react';
import { WalletError } from './connectors';
import { ClientErrors } from './connectors';
import { useVegaTransactionStore } from './use-vega-transaction-store';
import {
WalletClientError,

View File

@ -4,7 +4,7 @@ import type {
OrderAmendmentBody,
OrderCancellationBody,
WithdrawSubmissionBody,
} from './connectors/vega-connector';
} from '@vegaprotocol/wallet';
import {
OrderStatus,
OrderTimeInForce,
@ -13,8 +13,8 @@ import {
} from '@vegaprotocol/types';
import { VegaTxStatus } from './types';
jest.mock('./utils', () => ({
...jest.requireActual('./utils'),
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
determineId: jest.fn((v) => v),
}));

View File

@ -1,5 +1,5 @@
import produce from 'immer';
import type { Transaction } from './connectors';
import type { Transaction } from '@vegaprotocol/wallet';
import {
isWithdrawTransaction,
isOrderSubmissionTransaction,
@ -9,8 +9,8 @@ import {
isTransferTransaction,
isStopOrdersSubmissionTransaction,
isStopOrdersCancellationTransaction,
} from './connectors';
import { determineId } from './utils';
determineId,
} from '@vegaprotocol/wallet';
import { create } from 'zustand';
import type {

View File

@ -1,18 +1,26 @@
import { render } from '@testing-library/react';
import * as Types from '@vegaprotocol/types';
import {
OrderStatus,
OrderTimeInForce,
OrderType,
Side,
} from '@vegaprotocol/types';
import type { VegaStoredTxState } from '@vegaprotocol/wallet';
import { VegaTxStatus } from '@vegaprotocol/wallet';
import {
VegaTransactionDetails,
getVegaTransactionContentIntent,
getOrderToastIntent,
getOrderToastTitle,
getRejectionReason,
} from './use-vega-transaction-toasts';
import { Intent } from '@vegaprotocol/ui-toolkit';
import type { OrderByIdQuery, StopOrderByIdQuery } from '@vegaprotocol/orders';
import type {
OrderByIdQuery,
StopOrderByIdQuery,
} from './__generated__/Orders';
import type { VegaStoredTxState } from './use-vega-transaction-store';
import { VegaTxStatus } from './types';
jest.mock('@vegaprotocol/assets', () => {
const A1 = {
@ -56,9 +64,8 @@ jest.mock('@vegaprotocol/markets', () => {
};
});
jest.mock('@vegaprotocol/orders', () => {
jest.mock('./__generated__/Orders', () => {
return {
...jest.requireActual('@vegaprotocol/orders'),
useOrderByIdQuery: jest.fn(({ variables: { orderId } }) => {
if (orderId === '0') {
const data: OrderByIdQuery = {
@ -408,3 +415,99 @@ describe('getVegaTransactionContentIntent', () => {
expect(getVegaTransactionContentIntent(batch).intent).toBe(Intent.Primary);
});
});
describe('getOrderToastTitle', () => {
it('should return the correct title', () => {
expect(getOrderToastTitle(Types.OrderStatus.STATUS_ACTIVE)).toBe(
'Order submitted'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_FILLED)).toBe(
'Order filled'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_PARTIALLY_FILLED)).toBe(
'Order partially filled'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_PARKED)).toBe(
'Order parked'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_STOPPED)).toBe(
'Order stopped'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_CANCELLED)).toBe(
'Order cancelled'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_EXPIRED)).toBe(
'Order expired'
);
expect(getOrderToastTitle(Types.OrderStatus.STATUS_REJECTED)).toBe(
'Order rejected'
);
expect(getOrderToastTitle(undefined)).toBe(undefined);
});
});
describe('getOrderToastIntent', () => {
it('should return the correct intent', () => {
expect(getOrderToastIntent(Types.OrderStatus.STATUS_PARKED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_EXPIRED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_PARTIALLY_FILLED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_REJECTED)).toBe(
Intent.Danger
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_STOPPED)).toBe(
Intent.Warning
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_FILLED)).toBe(
Intent.Success
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_ACTIVE)).toBe(
Intent.Success
);
expect(getOrderToastIntent(Types.OrderStatus.STATUS_CANCELLED)).toBe(
Intent.Success
);
expect(getOrderToastIntent(undefined)).toBe(undefined);
});
});
describe('getRejectionReason', () => {
it('should return the correct rejection reason for insufficient asset balance', () => {
expect(
getRejectionReason({
rejectionReason:
Types.OrderRejectionReason.ORDER_ERROR_INSUFFICIENT_ASSET_BALANCE,
status: Types.OrderStatus.STATUS_REJECTED,
id: '',
createdAt: undefined,
size: '',
price: '',
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
side: Types.Side.SIDE_BUY,
marketId: '',
})
).toBe('Insufficient asset balance');
});
it('should return the correct rejection reason when order is stopped', () => {
expect(
getRejectionReason({
rejectionReason: null,
status: Types.OrderStatus.STATUS_STOPPED,
id: '',
createdAt: undefined,
size: '',
price: '',
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
side: Types.Side.SIDE_BUY,
marketId: '',
})
).toBe(
'Your Fill or Kill (FOK) order was not filled and it has been stopped'
);
});
});

View File

@ -4,13 +4,15 @@ import compact from 'lodash/compact';
import type {
BatchMarketInstructionSubmissionBody,
OrderAmendment,
OrderTxUpdateFieldsFragment,
OrderSubmission,
VegaStoredTxState,
WithdrawalBusEventFieldsFragment,
StopOrdersSubmission,
StopOrderSetup,
} from '@vegaprotocol/wallet';
import type {
OrderTxUpdateFieldsFragment,
WithdrawalBusEventFieldsFragment,
} from './__generated__/TransactionResult';
import type { VegaStoredTxState } from './use-vega-transaction-store';
import {
isTransferTransaction,
isBatchMarketInstructionsTransaction,
@ -21,12 +23,12 @@ import {
isOrderCancellationTransaction,
isOrderSubmissionTransaction,
isWithdrawTransaction,
useVegaTransactionStore,
VegaTxStatus,
isStopOrdersSubmissionTransaction,
isStopOrdersCancellationTransaction,
isReferralRelatedTransaction,
} from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from './use-vega-transaction-store';
import { VegaTxStatus } from './types';
import type { Toast, ToastContent } from '@vegaprotocol/ui-toolkit';
import { ToastHeading } from '@vegaprotocol/ui-toolkit';
import { Panel } from '@vegaprotocol/ui-toolkit';
@ -45,12 +47,9 @@ import { useAssetsMapProvider } from '@vegaprotocol/assets';
import { useEthWithdrawApprovalsStore } from './use-ethereum-withdraw-approvals-store';
import { DApp, EXPLORER_TX, useLinks } from '@vegaprotocol/environment';
import {
getOrderToastIntent,
getOrderToastTitle,
getRejectionReason,
useOrderByIdQuery,
useStopOrderByIdQuery,
} from '@vegaprotocol/orders';
} from './__generated__/Orders';
import { getAsset, useMarketsMapProvider } from '@vegaprotocol/markets';
import type { Market } from '@vegaprotocol/markets';
import type { Side } from '@vegaprotocol/types';
@ -59,6 +58,75 @@ import { Size } from '@vegaprotocol/datagrid';
import { useWithdrawalApprovalDialog } from './withdrawal-approval-dialog';
import * as Schema from '@vegaprotocol/types';
export const getRejectionReason = (
order: OrderTxUpdateFieldsFragment
): string | null => {
switch (order.status) {
case Schema.OrderStatus.STATUS_STOPPED:
return t(
`Your ${
Schema.OrderTimeInForceMapping[order.timeInForce]
} order was not filled and it has been stopped`
);
default:
return order.rejectionReason
? t(Schema.OrderRejectionReasonMapping[order.rejectionReason])
: '';
}
};
export const getOrderToastTitle = (
status?: Schema.OrderStatus
): string | undefined => {
if (!status) {
return;
}
switch (status) {
case Schema.OrderStatus.STATUS_ACTIVE:
return t('Order submitted');
case Schema.OrderStatus.STATUS_FILLED:
return t('Order filled');
case Schema.OrderStatus.STATUS_PARTIALLY_FILLED:
return t('Order partially filled');
case Schema.OrderStatus.STATUS_PARKED:
return t('Order parked');
case Schema.OrderStatus.STATUS_STOPPED:
return t('Order stopped');
case Schema.OrderStatus.STATUS_CANCELLED:
return t('Order cancelled');
case Schema.OrderStatus.STATUS_EXPIRED:
return t('Order expired');
case Schema.OrderStatus.STATUS_REJECTED:
return t('Order rejected');
default:
return t('Submission failed');
}
};
export const getOrderToastIntent = (
status?: Schema.OrderStatus
): Intent | undefined => {
if (!status) {
return;
}
switch (status) {
case Schema.OrderStatus.STATUS_PARKED:
case Schema.OrderStatus.STATUS_EXPIRED:
case Schema.OrderStatus.STATUS_PARTIALLY_FILLED:
case Schema.OrderStatus.STATUS_STOPPED:
return Intent.Warning;
case Schema.OrderStatus.STATUS_REJECTED:
return Intent.Danger;
case Schema.OrderStatus.STATUS_FILLED:
case Schema.OrderStatus.STATUS_ACTIVE:
case Schema.OrderStatus.STATUS_CANCELLED:
return Intent.Success;
default:
return;
}
};
const intentMap: { [s in VegaTxStatus]: Intent } = {
Default: Intent.Primary,
Requested: Intent.Warning,

View File

@ -38,7 +38,7 @@ const render = (mocks?: MockedResponse[]) => {
const pubKey = 'pubKey';
jest.mock('./use-vega-wallet', () => ({
jest.mock('@vegaprotocol/wallet', () => ({
useVegaWallet: () => ({
pubKey,
}),

View File

@ -1,5 +1,5 @@
import { useApolloClient } from '@apollo/client';
import { useVegaWallet } from './use-vega-wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import {
useOrderTxUpdateSubscription,
useWithdrawalBusEventSubscription,

View File

@ -10,7 +10,7 @@ import {
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { useWithdrawalApprovalQuery } from '@vegaprotocol/wallet';
import { useWithdrawalApprovalQuery } from './__generated__/WithdrawalApproval';
import omit from 'lodash/omit';
import { create } from 'zustand';

View File

@ -1,8 +1,6 @@
export * from './lib/__generated__/Erc20Approval';
export * from './lib/__generated__/Withdrawal';
export * from './lib/create-withdrawal-dialog';
export * from './lib/use-complete-withdraw';
export * from './lib/use-create-withdraw';
export * from './lib/use-verify-withdrawal';
export * from './lib/withdraw-form-container';
export * from './lib/withdraw-form';

View File

@ -4,7 +4,7 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
import { WithdrawFormContainer } from './withdraw-form-container';
import { useWeb3ConnectStore } from '@vegaprotocol/web3';
import { useWithdrawalDialog } from './withdrawal-dialog';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import { useVegaTransactionStore } from '@vegaprotocol/web3';
export const CreateWithdrawalDialog = () => {
const { assetId, isOpen, open, close } = useWithdrawalDialog();

View File

@ -1,192 +0,0 @@
import { act, renderHook } from '@testing-library/react';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import type { ReactNode } from 'react';
import type { WithdrawalArgs } from './use-create-withdraw';
import { useCreateWithdraw } from './use-create-withdraw';
import { Erc20ApprovalDocument } from './__generated__/Erc20Approval';
import type { Erc20ApprovalQuery } from './__generated__/Erc20Approval';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import {
initialState,
VegaTxStatus,
VegaWalletContext,
determineId,
} from '@vegaprotocol/wallet';
import { waitFor } from '@testing-library/react';
import type {
WithdrawalEventSubscription,
WithdrawalFieldsFragment,
} from './__generated__/Withdrawal';
import { WithdrawalEventDocument } from './__generated__/Withdrawal';
import * as Schema from '@vegaprotocol/types';
function setup(
vegaWalletContext: Partial<VegaWalletContextShape>,
mocks?: MockedResponse[]
) {
const wrapper = ({ children }: { children: ReactNode }) => (
<MockedProvider mocks={mocks}>
<VegaWalletContext.Provider
value={vegaWalletContext as VegaWalletContextShape}
>
{children}
</VegaWalletContext.Provider>
</MockedProvider>
);
return renderHook(() => useCreateWithdraw(), { wrapper });
}
const txHash = 'tx-hash';
const signature =
'cfe592d169f87d0671dd447751036d0dddc165b9c4b65e5a5060e2bbadd1aa726d4cbe9d3c3b327bcb0bff4f83999592619a2493f9bbd251fae99ce7ce766909';
const derivedWithdrawalId = determineId(signature);
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
const pubKey = '0x123';
let mockSend: jest.Mock;
let withdrawalInput: WithdrawalArgs;
let withdrawalEvent: WithdrawalFieldsFragment;
let mockERC20Approval: MockedResponse<Erc20ApprovalQuery>;
let mockWithdrawalEvent: MockedResponse<WithdrawalEventSubscription>;
beforeEach(() => {
mockSend = jest
.fn()
.mockReturnValue(Promise.resolve({ transactionHash: txHash, signature }));
withdrawalEvent = {
id: '2fca514cebf9f465ae31ecb4c5721e3a6f5f260425ded887ca50ba15b81a5d50',
status: Schema.WithdrawalStatus.STATUS_OPEN,
amount: '100',
asset: {
__typename: 'Asset',
id: 'asset-id',
name: 'asset-name',
symbol: 'asset-symbol',
decimals: 2,
status: Schema.AssetStatus.STATUS_ENABLED,
source: {
__typename: 'ERC20',
contractAddress: '0x123',
},
},
createdTimestamp: '2022-07-05T14:25:47.815283706Z',
withdrawnTimestamp: '2022-07-05T14:25:47.815283706Z',
txHash: '0x123',
details: {
__typename: 'Erc20WithdrawalDetails',
receiverAddress: '0x123',
},
pendingOnForeignChain: false,
__typename: 'Withdrawal',
};
withdrawalInput = {
amount: '100',
asset: 'asset-id',
receiverAddress: 'receiver-address',
availableTimestamp: null,
};
mockERC20Approval = {
request: {
query: Erc20ApprovalDocument,
variables: { withdrawalId: derivedWithdrawalId },
},
result: {
data: {
erc20WithdrawalApproval: {
__typename: 'Erc20WithdrawalApproval',
assetSource: 'asset-source',
amount: '100',
nonce: '1',
signatures: 'signatures',
targetAddress: 'targetAddress',
creation: '1',
},
},
},
delay: 2000,
};
mockWithdrawalEvent = {
request: {
query: WithdrawalEventDocument,
variables: { partyId: pubKey },
},
result: {
data: {
busEvents: [
{
event: withdrawalEvent,
__typename: 'BusEvent',
},
],
},
},
delay: 1000,
};
});
it('creates withdrawal and waits for approval creation', async () => {
const { result } = setup({ sendTx: mockSend, pubKey }, [
mockWithdrawalEvent,
mockERC20Approval,
]);
expect(result.current.transaction).toEqual(initialState);
expect(result.current.submit).toEqual(expect.any(Function));
expect(result.current.reset).toEqual(expect.any(Function));
expect(result.current.approval).toEqual(null);
act(() => {
result.current.submit(withdrawalInput);
});
expect(mockSend).toHaveBeenCalledWith(pubKey, {
withdrawSubmission: {
amount: withdrawalInput.amount,
asset: withdrawalInput.asset,
ext: {
erc20: {
receiverAddress: withdrawalInput.receiverAddress,
},
},
},
});
expect(result.current.transaction.status).toEqual(VegaTxStatus.Requested);
await waitFor(() => {
expect(result.current.transaction.status).toEqual(VegaTxStatus.Pending);
expect(result.current.transaction.dialogOpen).toBe(true);
// Withdrawal event should not be found yet
expect(result.current.withdrawal).toEqual(null);
// Poll for erc20Approval should not be complete yet
expect(result.current.approval).toEqual(null);
});
await act(async () => {
// Advance time by delay plus interval length to ensure mock result is triggered
// eslint-disable-next-line
jest.advanceTimersByTime(mockWithdrawalEvent.delay! + 1000);
});
expect(result.current.withdrawal).toEqual(withdrawalEvent);
await act(async () => {
// Advance time by delay plus interval length to ensure mock result is triggered
// eslint-disable-next-line
jest.advanceTimersByTime(mockERC20Approval.delay! + 1000);
});
expect(result.current.transaction.status).toEqual(VegaTxStatus.Complete);
expect(result.current.approval).toEqual(
// @ts-ignore MockedRespones types inteferring
mockERC20Approval.result.data.erc20WithdrawalApproval
);
});

View File

@ -1,79 +0,0 @@
import {
useVegaTransaction,
useVegaWallet,
determineId,
} from '@vegaprotocol/wallet';
import { useCallback, useState } from 'react';
import { useWithdrawalApproval } from './use-withdrawal-approval';
import { useWithdrawalEvent } from './use-withdrawal-event';
import type { Erc20ApprovalQuery } from './__generated__/Erc20Approval';
import type { WithdrawalFieldsFragment } from './__generated__/Withdrawal';
export interface WithdrawalArgs {
amount: string;
asset: string;
receiverAddress: string;
availableTimestamp: number | null;
}
export const useCreateWithdraw = () => {
const waitForWithdrawalApproval = useWithdrawalApproval();
const [approval, setApproval] = useState<
Erc20ApprovalQuery['erc20WithdrawalApproval'] | null
>(null);
const [withdrawal, setWithdrawal] = useState<WithdrawalFieldsFragment | null>(
null
);
const [availableTimestamp, setAvailableTimestamp] = useState<number | null>(
null
);
const { pubKey } = useVegaWallet();
const { transaction, send, setComplete, reset, Dialog } =
useVegaTransaction();
const waitForWithdrawal = useWithdrawalEvent(transaction);
const submit = useCallback(
async (withdrawal: WithdrawalArgs) => {
if (!pubKey) {
return;
}
setAvailableTimestamp(withdrawal.availableTimestamp);
const res = await send(pubKey, {
withdrawSubmission: {
amount: withdrawal.amount,
asset: withdrawal.asset,
ext: {
erc20: {
receiverAddress: withdrawal.receiverAddress,
},
},
},
});
if (res) {
const withdrawalId = determineId(res.signature);
const withdrawal = await waitForWithdrawal(withdrawalId, pubKey);
setWithdrawal(withdrawal);
const approval = await waitForWithdrawalApproval(withdrawal.id);
setApproval(approval);
setComplete();
}
},
[pubKey, send, waitForWithdrawal, waitForWithdrawalApproval, setComplete]
);
return {
transaction,
submit,
reset,
approval,
withdrawal,
availableTimestamp,
Dialog,
};
};

View File

@ -1,8 +1,5 @@
import { useDataProvider } from '@vegaprotocol/data-provider';
import {
useVegaWallet,
useWithdrawalApprovalQuery,
} from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import BigNumber from 'bignumber.js';
import type { Toast } from '@vegaprotocol/ui-toolkit';
import { Button, Intent, Panel, ToastHeading } from '@vegaprotocol/ui-toolkit';
@ -15,6 +12,7 @@ import {
useEthWithdrawApprovalsStore,
useGetWithdrawDelay,
useGetWithdrawThreshold,
useWithdrawalApprovalQuery,
} from '@vegaprotocol/web3';
import { withdrawalProvider } from './withdrawals-provider';
import type { WithdrawalFieldsFragment } from './__generated__/Withdrawal';

View File

@ -1,5 +1,5 @@
import { useApolloClient } from '@apollo/client';
import type { VegaTxState } from '@vegaprotocol/wallet';
import type { VegaTxState } from '@vegaprotocol/web3';
import { useCallback, useEffect, useRef } from 'react';
import type { Subscription } from 'zen-observable-ts';
import { WithdrawalEventDocument } from './__generated__/Withdrawal';

View File

@ -4,9 +4,10 @@ import { t } from '@vegaprotocol/i18n';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { AsyncRendererInline } from '@vegaprotocol/ui-toolkit';
import { accountsDataProvider } from '@vegaprotocol/accounts';
import type { WithdrawalArgs } from './use-create-withdraw';
import { WithdrawManager } from './withdraw-manager';
import * as Types from '@vegaprotocol/types';
import type { WithdrawalArgs } from './withdraw-form';
interface WithdrawFormContainerProps {
partyId?: string;

View File

@ -26,7 +26,6 @@ import { useEffect, type ButtonHTMLAttributes } from 'react';
import type { ControllerRenderProps } from 'react-hook-form';
import { formatDistanceToNow } from 'date-fns';
import { useForm, Controller, useWatch } from 'react-hook-form';
import type { WithdrawalArgs } from './use-create-withdraw';
import { WithdrawLimits } from './withdraw-limits';
import {
ETHEREUM_EAGER_CONNECT,
@ -36,6 +35,13 @@ import {
import { AssetBalance } from './asset-balance';
import { DocsLinks } from '@vegaprotocol/environment';
export interface WithdrawalArgs {
amount: string;
asset: string;
receiverAddress: string;
availableTimestamp: number | null;
}
interface FormFields {
asset: string;
to: string;

View File

@ -1,6 +1,6 @@
import sortBy from 'lodash/sortBy';
import type { WithdrawalArgs } from './withdraw-form';
import { WithdrawForm } from './withdraw-form';
import type { WithdrawalArgs } from './use-create-withdraw';
import type { Asset } from '@vegaprotocol/assets';
import type { AccountFieldsFragment } from '@vegaprotocol/accounts';
import { useWithdrawAsset } from './use-withdraw-asset';

View File

@ -1,12 +1,4 @@
import { create } from 'zustand';
import { t } from '@vegaprotocol/i18n';
import { Dialog } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useCompleteWithdraw } from './use-complete-withdraw';
import { useCreateWithdraw } from './use-create-withdraw';
import { WithdrawFormContainer } from './withdraw-form-container';
import { WithdrawalFeedback } from './withdrawal-feedback';
import { useWeb3ConnectStore } from '@vegaprotocol/web3';
interface State {
isOpen: boolean;
assetId?: string;
@ -23,48 +15,3 @@ export const useWithdrawalDialog = create<State & Actions>()((set) => ({
open: (assetId) => set(() => ({ assetId, isOpen: true })),
close: () => set(() => ({ assetId: undefined, isOpen: false })),
}));
export const WithdrawalDialog = () => {
const { assetId, isOpen, open, close } = useWithdrawalDialog();
const { pubKey } = useVegaWallet();
const createWithdraw = useCreateWithdraw();
const completeWithdraw = useCompleteWithdraw();
const connectWalletDialogIsOpen = useWeb3ConnectStore(
(state) => state.isOpen
);
return (
<>
<Dialog
title={t('Withdraw')}
open={isOpen && !connectWalletDialogIsOpen}
onChange={(isOpen) => (isOpen ? open() : close())}
size="small"
>
<WithdrawFormContainer
assetId={assetId}
partyId={pubKey ? pubKey : undefined}
submit={(args) => {
close();
createWithdraw.submit(args);
}}
/>
</Dialog>
<createWithdraw.Dialog
content={{
Complete: (
<WithdrawalFeedback
withdrawal={createWithdraw.withdrawal}
transaction={createWithdraw.transaction}
availableTimestamp={createWithdraw.availableTimestamp}
submitWithdraw={(id) => {
createWithdraw.reset();
completeWithdraw.submit(id);
}}
/>
),
}}
/>
<completeWithdraw.Dialog />
</>
);
};

View File

@ -6,7 +6,7 @@ import {
KeyValueTable,
KeyValueTableRow,
} from '@vegaprotocol/ui-toolkit';
import type { VegaTxState } from '@vegaprotocol/wallet';
import type { VegaTxState } from '@vegaprotocol/web3';
import { getChainName, useWeb3ConnectStore } from '@vegaprotocol/web3';
import { useWeb3React } from '@web3-react/core';
import { formatDistanceToNow } from 'date-fns';