fix(#623): order fixes

* feat: format size and volume with positionDecimalPlaces

* fix: pass in calculated step so client side validation works

* fix: add requested state to order dialog, handle user rejected error

* feat: add test case for user rejecting tx

* feat: add test case for order list fractional sizes

* feat: add test case for fractional volume in positions table

* fix: deal ticket tests imports

* feat: add test case for trades fractional size

* fix: props for orderbook tests

* fix: add missing positionDecimalPlaces fields to mock functions

* fix: improve error handling of service error with type guard
This commit is contained in:
Matthew Russell 2022-06-23 15:00:58 -07:00 committed by GitHub
parent a9df2f425d
commit d5727baffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 275 additions and 185 deletions

View File

@ -12,6 +12,7 @@ export const generateOrderBook = (
const marketDepth: MarketDepth_market = { const marketDepth: MarketDepth_market = {
id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e', id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
data: { data: {
staticMidPrice: '826337', staticMidPrice: '826337',
marketTradingMode: MarketTradingMode.Continuous, marketTradingMode: MarketTradingMode.Continuous,

View File

@ -18,6 +18,7 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d', id: 'c9f5acd348796011c075077e4d58d9b7f1689b7c1c8e030a5e886b83aa96923d',
name: 'AAVEDAI Monthly (30 Jun 2022)', name: 'AAVEDAI Monthly (30 Jun 2022)',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
tradableInstrument: { tradableInstrument: {
__typename: 'TradableInstrument', __typename: 'TradableInstrument',
instrument: { instrument: {
@ -46,6 +47,7 @@ export const generateOrders = (override?: PartialDeep<Orders>): Orders => {
id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376', id: '5a4b0b9e9c0629f0315ec56fcb7bd444b0c6e4da5ec7677719d502626658a376',
name: 'Tesla Quarterly (30 Jun 2022)', name: 'Tesla Quarterly (30 Jun 2022)',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
tradableInstrument: { tradableInstrument: {
__typename: 'TradableInstrument', __typename: 'TradableInstrument',
instrument: { instrument: {

View File

@ -25,6 +25,7 @@ export const generatePositions = (
market: { __typename: 'Market', id: '123' }, market: { __typename: 'Market', id: '123' },
}, },
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
tradableInstrument: { tradableInstrument: {
instrument: { instrument: {
id: '', id: '',
@ -78,6 +79,7 @@ export const generatePositions = (
}, },
}, },
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
tradableInstrument: { tradableInstrument: {
instrument: { instrument: {
id: '', id: '',

View File

@ -12,6 +12,7 @@ export const generateTrades = (override?: PartialDeep<Trades>): Trades => {
market: { market: {
id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff', id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
__typename: 'Market', __typename: 'Market',
}, },
__typename: 'Trade', __typename: 'Trade',
@ -24,6 +25,7 @@ export const generateTrades = (override?: PartialDeep<Trades>): Trades => {
market: { market: {
id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff', id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
__typename: 'Market', __typename: 'Market',
}, },
__typename: 'Trade', __typename: 'Trade',
@ -36,6 +38,7 @@ export const generateTrades = (override?: PartialDeep<Trades>): Trades => {
market: { market: {
id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff', id: '0c3c1490db767f926d24fb674b4235a9aa339614915a4ab96cbfc0e1ad83c0ff',
decimalPlaces: 5, decimalPlaces: 5,
positionDecimalPlaces: 0,
__typename: 'Market', __typename: 'Market',
}, },
__typename: 'Trade', __typename: 'Trade',

View File

@ -109,7 +109,7 @@ interface TradeGridProps {
export const TradeGrid = ({ market }: TradeGridProps) => { export const TradeGrid = ({ market }: TradeGridProps) => {
const wrapperClasses = classNames( const wrapperClasses = classNames(
'h-full max-h-full', 'h-full max-h-full',
'grid gap-4 grid-cols-[1fr_375px_460px] grid-rows-[min-content_1fr_200px]', 'grid gap-4 grid-cols-[1fr_375px_460px] grid-rows-[min-content_1fr_300px]',
'bg-black-10 dark:bg-white-10', 'bg-black-10 dark:bg-white-10',
'text-ui' 'text-ui'
); );

View File

@ -1,108 +0,0 @@
/* tslint:disable */
/* eslint-disable */
// @generated
// This file was automatically generated and should not be edited.
import { BusEventType, OrderType, OrderStatus, OrderRejectionReason } from "@vegaprotocol/types";
// ====================================================
// GraphQL subscription operation: OrderEvent
// ====================================================
export interface OrderEvent_busEvents_event_TimeUpdate {
__typename: "TimeUpdate" | "MarketEvent" | "TransferResponses" | "PositionResolution" | "Trade" | "Account" | "Party" | "MarginLevels" | "Proposal" | "Vote" | "MarketData" | "NodeSignature" | "LossSocialization" | "SettlePosition" | "Market" | "Asset" | "MarketTick" | "SettleDistressed" | "AuctionEvent" | "RiskFactor" | "Deposit" | "Withdrawal" | "OracleSpec" | "LiquidityProvision";
}
export interface OrderEvent_busEvents_event_Order_market {
__typename: "Market";
/**
* Market full name
*/
name: string;
/**
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
* number denominated in the currency of the Market. (uint64)
*
* Examples:
* Currency Balance decimalPlaces Real Balance
* GBP 100 0 GBP 100
* GBP 100 2 GBP 1.00
* GBP 100 4 GBP 0.01
* GBP 1 4 GBP 0.0001 ( 0.01p )
*
* GBX (pence) 100 0 GBP 1.00 (100p )
* GBX (pence) 100 2 GBP 0.01 ( 1p )
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/
decimalPlaces: number;
}
export interface OrderEvent_busEvents_event_Order {
__typename: "Order";
/**
* Type the order type (defaults to PARTY)
*/
type: OrderType | null;
/**
* Hash of the order data
*/
id: string;
/**
* The status of an order, for example 'Active'
*/
status: OrderStatus;
/**
* Reason for the order to be rejected
*/
rejectionReason: OrderRejectionReason | null;
/**
* RFC3339Nano formatted date and time for when the order was created (timestamp)
*/
createdAt: string;
/**
* Total number of contracts that may be bought or sold (immutable) (uint64)
*/
size: string;
/**
* The worst price the order will trade at (e.g. buy for price or less, sell for price or more) (uint64)
*/
price: string;
/**
* The market the order is trading on (probably stored internally as a hash of the market details)
*/
market: OrderEvent_busEvents_event_Order_market | null;
}
export type OrderEvent_busEvents_event = OrderEvent_busEvents_event_TimeUpdate | OrderEvent_busEvents_event_Order;
export interface OrderEvent_busEvents {
__typename: "BusEvent";
/**
* the id for this event
*/
eventId: string;
/**
* the block hash
*/
block: string;
/**
* the type of event we're dealing with
*/
type: BusEventType;
/**
* the payload - the wrapped event
*/
event: OrderEvent_busEvents_event;
}
export interface OrderEvent {
/**
* Subscribe to event data from the event bus
*/
busEvents: OrderEvent_busEvents[] | null;
}
export interface OrderEventVariables {
partyId: string;
}

View File

@ -1,3 +1,2 @@
export * from './DealTicketQuery'; export * from './DealTicketQuery';
export * from './MarketInfoQuery'; export * from './MarketInfoQuery';
export * from './OrderEvent';

View File

@ -12,22 +12,17 @@ export interface DealTicketAmountProps {
price?: string; price?: string;
} }
const getAmountComponent = (type: OrderType) => { export const DealTicketAmount = ({
switch (type) { orderType,
...props
}: DealTicketAmountProps) => {
switch (orderType) {
case OrderType.Market: case OrderType.Market:
return DealTicketMarketAmount; return <DealTicketMarketAmount {...props} />;
case OrderType.Limit: case OrderType.Limit:
return DealTicketLimitAmount; return <DealTicketLimitAmount {...props} />;
default: { default: {
throw new Error('Invalid ticket type'); throw new Error('Invalid ticket type');
} }
} }
}; };
export const DealTicketAmount = ({
orderType,
...props
}: DealTicketAmountProps) => {
const AmountComponent = getAmountComponent(orderType);
return <AmountComponent {...props} />;
};

View File

@ -37,6 +37,10 @@ export const DealTicketManager = ({
return Intent.Danger; return Intent.Danger;
} }
if (status === VegaTxStatus.Requested) {
return Intent.Warning;
}
if (status === VegaTxStatus.Error) { if (status === VegaTxStatus.Error) {
return Intent.Danger; return Intent.Danger;
} }
@ -47,6 +51,8 @@ export const DealTicketManager = ({
useEffect(() => { useEffect(() => {
if (transaction.status !== VegaTxStatus.Default) { if (transaction.status !== VegaTxStatus.Default) {
setOrderDialogOpen(true); setOrderDialogOpen(true);
} else {
setOrderDialogOpen(false);
} }
}, [transaction.status]); }, [transaction.status]);

View File

@ -6,13 +6,14 @@ import {
import { addDecimal } from '@vegaprotocol/react-helpers'; import { addDecimal } from '@vegaprotocol/react-helpers';
import { fireEvent, render, screen, act } from '@testing-library/react'; import { fireEvent, render, screen, act } from '@testing-library/react';
import { DealTicket } from './deal-ticket'; import { DealTicket } from './deal-ticket';
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery'; import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
import type { Order } from '../utils/get-default-order'; import type { Order } from '../utils/get-default-order';
import { MarketState, MarketTradingMode } from '@vegaprotocol/types'; import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
const market: DealTicketQuery_market = { const market: DealTicketQuery_market = {
__typename: 'Market', __typename: 'Market',
id: 'market-id', id: 'market-id',
name: 'market-name',
decimalPlaces: 2, decimalPlaces: 2,
positionDecimalPlaces: 1, positionDecimalPlaces: 1,
tradingMode: MarketTradingMode.Continuous, tradingMode: MarketTradingMode.Continuous,
@ -24,6 +25,12 @@ const market: DealTicketQuery_market = {
product: { product: {
__typename: 'Future', __typename: 'Future',
quoteName: 'quote-name', quoteName: 'quote-name',
settlementAsset: {
__typename: 'Asset',
id: 'asset-id',
name: 'asset-name',
symbol: 'asset-symbol',
},
}, },
}, },
}, },

View File

@ -77,7 +77,7 @@ export const DealTicket = ({
/> />
<DealTicketAmount <DealTicketAmount
orderType={orderType} orderType={orderType}
step={0.02} step={step}
register={register} register={register}
price={ price={
market.depth.lastTrade market.depth.lastTrade

View File

@ -1,9 +1,13 @@
import { Icon, Loader } from '@vegaprotocol/ui-toolkit'; import { Icon, Loader } from '@vegaprotocol/ui-toolkit';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import type { OrderEvent_busEvents_event_Order } from './__generated__/OrderEvent'; import {
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers'; addDecimal,
addDecimalsFormatNumber,
t,
} from '@vegaprotocol/react-helpers';
import type { VegaTxState } from '@vegaprotocol/wallet'; import type { VegaTxState } from '@vegaprotocol/wallet';
import { VegaTxStatus } from '@vegaprotocol/wallet'; import { VegaTxStatus } from '@vegaprotocol/wallet';
import type { OrderEvent_busEvents_event_Order } from '../hooks/__generated__/OrderEvent';
interface OrderDialogProps { interface OrderDialogProps {
transaction: VegaTxState; transaction: VegaTxState;
@ -14,9 +18,22 @@ export const OrderDialog = ({
transaction, transaction,
finalizedOrder, finalizedOrder,
}: OrderDialogProps) => { }: OrderDialogProps) => {
// TODO: When wallets support confirming transactions return UI for 'awaiting confirmation' step
// Rejected by wallet // Rejected by wallet
if (transaction.status === VegaTxStatus.Requested) {
return (
<OrderDialogWrapper
title="Confirm transaction in wallet"
icon={<Icon name="hand-up" size={20} />}
>
<p>
Please open your wallet application and confirm or reject the
transaction
</p>
</OrderDialogWrapper>
);
}
// Transaction error
if (transaction.status === VegaTxStatus.Error) { if (transaction.status === VegaTxStatus.Error) {
return ( return (
<OrderDialogWrapper <OrderDialogWrapper
@ -72,7 +89,14 @@ export const OrderDialog = ({
<p>{t(`Market: ${finalizedOrder.market.name}`)}</p> <p>{t(`Market: ${finalizedOrder.market.name}`)}</p>
)} )}
<p>{t(`Type: ${finalizedOrder.type}`)}</p> <p>{t(`Type: ${finalizedOrder.type}`)}</p>
<p>{t(`Amount: ${finalizedOrder.size}`)}</p> <p>
{t(
`Amount: ${addDecimal(
finalizedOrder.size,
finalizedOrder.market?.positionDecimalPlaces || 0
)}`
)}
</p>
{finalizedOrder.type === 'Limit' && finalizedOrder.market && ( {finalizedOrder.type === 'Limit' && finalizedOrder.market && (
<p> <p>
{t( {t(

View File

@ -36,6 +36,12 @@ export interface OrderEvent_busEvents_event_Order_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
} }
export interface OrderEvent_busEvents_event_Order { export interface OrderEvent_busEvents_event_Order {

View File

@ -4,12 +4,12 @@ import type { Order } from '../utils/get-default-order';
import { OrderType, useVegaWallet } from '@vegaprotocol/wallet'; import { OrderType, useVegaWallet } from '@vegaprotocol/wallet';
import { determineId, removeDecimal } from '@vegaprotocol/react-helpers'; import { determineId, removeDecimal } from '@vegaprotocol/react-helpers';
import { useVegaTransaction } from '@vegaprotocol/wallet'; import { useVegaTransaction } from '@vegaprotocol/wallet';
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
import type { import type {
OrderEvent, OrderEvent,
OrderEventVariables, OrderEventVariables,
OrderEvent_busEvents_event_Order, OrderEvent_busEvents_event_Order,
} from '../components/__generated__/OrderEvent'; } from './__generated__/OrderEvent';
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
const ORDER_EVENT_SUB = gql` const ORDER_EVENT_SUB = gql`
subscription OrderEvent($partyId: ID!) { subscription OrderEvent($partyId: ID!) {
@ -29,6 +29,7 @@ const ORDER_EVENT_SUB = gql`
market { market {
name name
decimalPlaces decimalPlaces
positionDecimalPlaces
} }
} }
} }

View File

@ -132,6 +132,12 @@ export interface MarketDepth_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* marketData for the given market * marketData for the given market
*/ */

View File

@ -55,6 +55,12 @@ export interface MarketDepthSubscription_marketDepthUpdate_market {
* Market ID * Market ID
*/ */
id: string; id: string;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* marketData for the given market * marketData for the given market
*/ */

View File

@ -16,6 +16,7 @@ const MARKET_DEPTH_QUERY = gql`
market(id: $marketId) { market(id: $marketId) {
id id
decimalPlaces decimalPlaces
positionDecimalPlaces
data { data {
staticMidPrice staticMidPrice
marketTradingMode marketTradingMode
@ -52,6 +53,7 @@ export const MARKET_DEPTH_SUBSCRIPTION_QUERY = gql`
marketDepthUpdate(marketId: $marketId) { marketDepthUpdate(marketId: $marketId) {
market { market {
id id
positionDecimalPlaces
data { data {
staticMidPrice staticMidPrice
marketTradingMode marketTradingMode

View File

@ -82,6 +82,7 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
<Orderbook <Orderbook
{...orderbookData} {...orderbookData}
decimalPlaces={data?.decimalPlaces ?? 0} decimalPlaces={data?.decimalPlaces ?? 0}
positionDecimalPlaces={data?.positionDecimalPlaces ?? 0}
resolution={resolution} resolution={resolution}
onResolutionChange={(resolution: number) => setResolution(resolution)} onResolutionChange={(resolution: number) => setResolution(resolution)}
/> />

View File

@ -5,6 +5,7 @@ import {
CumulativeVol, CumulativeVol,
addDecimalsFormatNumber, addDecimalsFormatNumber,
VolumeType, VolumeType,
addDecimal,
} from '@vegaprotocol/react-helpers'; } from '@vegaprotocol/react-helpers';
interface OrderbookRowProps { interface OrderbookRowProps {
@ -15,6 +16,7 @@ interface OrderbookRowProps {
cumulativeRelativeAsk?: number; cumulativeRelativeAsk?: number;
cumulativeRelativeBid?: number; cumulativeRelativeBid?: number;
decimalPlaces: number; decimalPlaces: number;
positionDecimalPlaces: number;
indicativeVolume?: string; indicativeVolume?: string;
price: string; price: string;
relativeAsk?: number; relativeAsk?: number;
@ -30,6 +32,7 @@ export const OrderbookRow = React.memo(
cumulativeRelativeAsk, cumulativeRelativeAsk,
cumulativeRelativeBid, cumulativeRelativeBid,
decimalPlaces, decimalPlaces,
positionDecimalPlaces,
indicativeVolume, indicativeVolume,
price, price,
relativeAsk, relativeAsk,
@ -40,6 +43,7 @@ export const OrderbookRow = React.memo(
<Vol <Vol
testId={`bid-vol-${price}`} testId={`bid-vol-${price}`}
value={bid} value={bid}
valueFormatted={addDecimal(bid, positionDecimalPlaces)}
relativeValue={relativeBid} relativeValue={relativeBid}
type={VolumeType.bid} type={VolumeType.bid}
/> />
@ -51,6 +55,7 @@ export const OrderbookRow = React.memo(
<Vol <Vol
testId={`ask-vol-${price}`} testId={`ask-vol-${price}`}
value={ask} value={ask}
valueFormatted={addDecimal(ask, positionDecimalPlaces)}
relativeValue={relativeAsk} relativeValue={relativeAsk}
type={VolumeType.ask} type={VolumeType.ask}
/> />

View File

@ -22,6 +22,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -35,6 +36,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -44,6 +46,7 @@ describe('Orderbook', () => {
result.rerender( result.rerender(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData({ {...generateMockData({
...params, ...params,
numberOfSellRows: params.numberOfSellRows - 1, numberOfSellRows: params.numberOfSellRows - 1,
@ -60,6 +63,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -69,6 +73,7 @@ describe('Orderbook', () => {
result.rerender( result.rerender(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData({ {...generateMockData({
...params, ...params,
bestStaticBidPrice: params.bestStaticBidPrice + 1, bestStaticBidPrice: params.bestStaticBidPrice + 1,
@ -86,6 +91,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -98,6 +104,7 @@ describe('Orderbook', () => {
result.rerender( result.rerender(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData({ {...generateMockData({
...params, ...params,
numberOfSellRows: params.numberOfSellRows - 1, numberOfSellRows: params.numberOfSellRows - 1,
@ -114,6 +121,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -134,6 +142,7 @@ describe('Orderbook', () => {
const result = render( const result = render(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData(params)} {...generateMockData(params)}
onResolutionChange={onResolutionChange} onResolutionChange={onResolutionChange}
/> />
@ -153,6 +162,7 @@ describe('Orderbook', () => {
result.rerender( result.rerender(
<Orderbook <Orderbook
decimalPlaces={decimalPlaces} decimalPlaces={decimalPlaces}
positionDecimalPlaces={0}
{...generateMockData({ {...generateMockData({
...params, ...params,
resolution: 10, resolution: 10,

View File

@ -19,6 +19,7 @@ import { Icon, Splash } from '@vegaprotocol/ui-toolkit';
import type { OrderbookData, OrderbookRowData } from './orderbook-data'; import type { OrderbookData, OrderbookRowData } from './orderbook-data';
interface OrderbookProps extends OrderbookData { interface OrderbookProps extends OrderbookData {
decimalPlaces: number; decimalPlaces: number;
positionDecimalPlaces: number;
resolution: number; resolution: number;
onResolutionChange: (resolution: number) => void; onResolutionChange: (resolution: number) => void;
} }
@ -100,6 +101,7 @@ export const Orderbook = ({
indicativeVolume, indicativeVolume,
indicativePrice, indicativePrice,
decimalPlaces, decimalPlaces,
positionDecimalPlaces,
resolution, resolution,
onResolutionChange, onResolutionChange,
}: OrderbookProps) => { }: OrderbookProps) => {
@ -298,6 +300,7 @@ export const Orderbook = ({
<OrderbookRow <OrderbookRow
price={(BigInt(data.price) / BigInt(resolution)).toString()} price={(BigInt(data.price) / BigInt(resolution)).toString()}
decimalPlaces={decimalPlaces - Math.log10(resolution)} decimalPlaces={decimalPlaces - Math.log10(resolution)}
positionDecimalPlaces={positionDecimalPlaces}
bid={data.bid} bid={data.bid}
relativeBid={data.relativeBid} relativeBid={data.relativeBid}
cumulativeBid={data.cumulativeVol.bid} cumulativeBid={data.cumulativeVol.bid}

View File

@ -52,6 +52,12 @@ export interface OrderFields_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -52,6 +52,12 @@ export interface OrderSub_orders_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -52,6 +52,12 @@ export interface Orders_party_orders_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -25,6 +25,7 @@ const marketOrder: Orders_party_orders = {
id: 'market-id', id: 'market-id',
name: 'market-name', name: 'market-name',
decimalPlaces: 2, decimalPlaces: 2,
positionDecimalPlaces: 0,
tradableInstrument: { tradableInstrument: {
__typename: 'TradableInstrument', __typename: 'TradableInstrument',
instrument: { instrument: {
@ -54,6 +55,7 @@ const limitOrder: Orders_party_orders = {
id: 'market-id', id: 'market-id',
name: 'market-name', name: 'market-name',
decimalPlaces: 2, decimalPlaces: 2,
positionDecimalPlaces: 2,
tradableInstrument: { tradableInstrument: {
__typename: 'TradableInstrument', __typename: 'TradableInstrument',
instrument: { instrument: {
@ -62,11 +64,11 @@ const limitOrder: Orders_party_orders = {
}, },
}, },
}, },
size: '10', size: '1000',
type: OrderType.Limit, type: OrderType.Limit,
status: OrderStatus.Active, status: OrderStatus.Active,
side: Side.Sell, side: Side.Sell,
remaining: '5', remaining: '500',
price: '12345', price: '12345',
timeInForce: OrderTimeInForce.GTT, timeInForce: OrderTimeInForce.GTT,
createdAt: new Date('2022-3-3').toISOString(), createdAt: new Date('2022-3-3').toISOString(),
@ -122,10 +124,10 @@ it('Correct formatting applied for GTT limit order', async () => {
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
const expectedValues = [ const expectedValues = [
limitOrder.market?.tradableInstrument.instrument.code, limitOrder.market?.tradableInstrument.instrument.code,
'-10', '-10.00',
limitOrder.type, limitOrder.type,
limitOrder.status, limitOrder.status,
'5', '5.00',
formatNumber(limitOrder.price, limitOrder.market?.decimalPlaces ?? 0), formatNumber(limitOrder.price, limitOrder.market?.decimalPlaces ?? 0),
`${limitOrder.timeInForce}: ${getDateTimeFormat().format( `${limitOrder.timeInForce}: ${getDateTimeFormat().format(
new Date(limitOrder.expiresAt ?? '') new Date(limitOrder.expiresAt ?? '')

View File

@ -1,11 +1,17 @@
import { OrderTimeInForce, OrderStatus, Side } from '@vegaprotocol/types'; import { OrderTimeInForce, OrderStatus, Side } from '@vegaprotocol/types';
import type { Orders_party_orders } from './__generated__/Orders'; import type { Orders_party_orders } from './__generated__/Orders';
import { formatNumber, getDateTimeFormat } from '@vegaprotocol/react-helpers'; import {
addDecimal,
formatNumber,
getDateTimeFormat,
t,
} from '@vegaprotocol/react-helpers';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit'; import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import type { ValueFormatterParams } from 'ag-grid-community'; import type { ValueFormatterParams } from 'ag-grid-community';
import type { AgGridReact } from 'ag-grid-react'; import type { AgGridReact } from 'ag-grid-react';
import { AgGridColumn } from 'ag-grid-react'; import { AgGridColumn } from 'ag-grid-react';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import BigNumber from 'bignumber.js';
interface OrderListProps { interface OrderListProps {
data: Orders_party_orders[] | null; data: Orders_party_orders[] | null;
@ -23,16 +29,18 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
getRowId={({ data }) => data.id} getRowId={({ data }) => data.id}
> >
<AgGridColumn <AgGridColumn
headerName="Market" headerName={t('Market')}
field="market.tradableInstrument.instrument.code" field="market.tradableInstrument.instrument.code"
/> />
<AgGridColumn <AgGridColumn
headerName="Amount" headerName={t('Amount')}
field="size" field="size"
cellClass="font-mono" cellClass="font-mono"
valueFormatter={({ value, data }: ValueFormatterParams) => { valueFormatter={({ value, data }: ValueFormatterParams) => {
const prefix = data.side === Side.Buy ? '+' : '-'; const prefix = data.side === Side.Buy ? '+' : '-';
return prefix + value; return (
prefix + addDecimal(value, data.market.positionDecimalPlaces)
);
}} }}
/> />
<AgGridColumn field="type" /> <AgGridColumn field="type" />
@ -47,11 +55,18 @@ export const OrderList = forwardRef<AgGridReact, OrderListProps>(
}} }}
/> />
<AgGridColumn <AgGridColumn
headerName="Filled" headerName={t('Filled')}
field="remaining" field="remaining"
cellClass="font-mono" cellClass="font-mono"
valueFormatter={({ data }: ValueFormatterParams) => { valueFormatter={({ data }: ValueFormatterParams) => {
return `${Number(data.size) - Number(data.remaining)}/${data.size}`; const dps = data.market.positionDecimalPlaces;
const size = new BigNumber(data.size);
const remaining = new BigNumber(data.remaining);
const fills = size.minus(remaining);
return `${addDecimal(fills.toString(), dps)}/${addDecimal(
size.toString(),
dps
)}`;
}} }}
/> />
<AgGridColumn <AgGridColumn

View File

@ -13,6 +13,7 @@ const ORDER_FRAGMENT = gql`
id id
name name
decimalPlaces decimalPlaces
positionDecimalPlaces
tradableInstrument { tradableInstrument {
instrument { instrument {
code code

View File

@ -136,6 +136,12 @@ export interface PositionDetails_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -136,6 +136,12 @@ export interface PositionSubscribe_positions_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -136,6 +136,12 @@ export interface Positions_party_positions_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
/** /**
* An instance of or reference to a tradable instrument. * An instance of or reference to a tradable instrument.
*/ */

View File

@ -27,6 +27,7 @@ const POSITIONS_FRAGMENT = gql`
} }
} }
decimalPlaces decimalPlaces
positionDecimalPlaces
tradableInstrument { tradableInstrument {
instrument { instrument {
id id

View File

@ -5,7 +5,7 @@ import { MarketTradingMode } from '@vegaprotocol/types';
const singleRow: Positions_party_positions = { const singleRow: Positions_party_positions = {
realisedPNL: '520000000', realisedPNL: '520000000',
openVolume: '100', openVolume: '10000',
unrealisedPNL: '895000', unrealisedPNL: '895000',
averageEntryPrice: '1129935', averageEntryPrice: '1129935',
market: { market: {
@ -17,6 +17,7 @@ const singleRow: Positions_party_positions = {
__typename: 'MarketData', __typename: 'MarketData',
market: { __typename: 'Market', id: '123' }, market: { __typename: 'Market', id: '123' },
}, },
positionDecimalPlaces: 2,
decimalPlaces: 5, decimalPlaces: 5,
tradableInstrument: { tradableInstrument: {
instrument: { instrument: {
@ -90,7 +91,7 @@ it('Correct formatting applied', async () => {
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
const expectedValues = [ const expectedValues = [
singleRow.market.tradableInstrument.instrument.code, singleRow.market.tradableInstrument.instrument.code,
'+100', '+100.00',
'11.29935', '11.29935',
'11.38885', '11.38885',
'+5,200.000', '+5,200.000',

View File

@ -88,8 +88,11 @@ export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
<AgGridColumn <AgGridColumn
headerName={t('Amount')} headerName={t('Amount')}
field="openVolume" field="openVolume"
valueFormatter={({ value }: PositionsTableValueFormatterParams) => valueFormatter={({
volumePrefix(value) value,
data,
}: PositionsTableValueFormatterParams) =>
volumePrefix(addDecimal(value, data.market.positionDecimalPlaces))
} }
/> />
<AgGridColumn <AgGridColumn

View File

@ -1,19 +1,6 @@
import once from 'lodash/once'; import once from 'lodash/once';
import { getUserLocale } from './utils'; import { getUserLocale } from './utils';
/**
* Returns a number prefixed with either a '-' or a '+'. The open volume field
* already comes with a '-' if negative so we only need to actually prefix if
* its a positive value
*/
export function volumePrefix(value: string): string {
if (value === '0' || value.startsWith('-')) {
return value;
}
return '+' + value;
}
export const getTimeFormat = once( export const getTimeFormat = once(
() => () =>
new Intl.DateTimeFormat(getUserLocale(), { new Intl.DateTimeFormat(getUserLocale(), {

View File

@ -1,4 +1,5 @@
export * from './date'; export * from './date';
export * from './number'; export * from './number';
export * from './truncate'; export * from './truncate';
export * from './size';
export * from './utils'; export * from './utils';

View File

@ -0,0 +1,12 @@
/**
* Returns a number prefixed with either a '-' or a '+'. The open volume field
* already comes with a '-' if negative so we only need to actually prefix if
* its a positive value
*/
export function volumePrefix(value: string): string {
if (value === '0' || value.startsWith('-')) {
return value;
}
return '+' + value;
}

View File

@ -9,6 +9,7 @@ export enum VolumeType {
} }
export interface VolProps { export interface VolProps {
value: number | bigint | null | undefined; value: number | bigint | null | undefined;
valueFormatted: string;
relativeValue?: number; relativeValue?: number;
type: VolumeType; type: VolumeType;
testId?: string; testId?: string;
@ -22,7 +23,7 @@ export const BID_COLOR = 'darkgreen';
export const ASK_COLOR = 'maroon'; export const ASK_COLOR = 'maroon';
export const Vol = React.memo( export const Vol = React.memo(
({ value, relativeValue, type, testId }: VolProps) => { ({ value, valueFormatted, relativeValue, type, testId }: VolProps) => {
if ((!value && value !== 0) || isNaN(Number(value))) { if ((!value && value !== 0) || isNaN(Number(value))) {
return <div data-testid="vol">-</div>; return <div data-testid="vol">-</div>;
} }
@ -38,7 +39,7 @@ export const Vol = React.memo(
backgroundColor: type === VolumeType.bid ? BID_COLOR : ASK_COLOR, backgroundColor: type === VolumeType.bid ? BID_COLOR : ASK_COLOR,
}} }}
></div> ></div>
<PriceCell value={value} valueFormatted={value.toString()} /> <PriceCell value={value} valueFormatted={valueFormatted} />
</div> </div>
); );
} }

View File

@ -30,6 +30,12 @@ export interface TradeFields_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
} }
export interface TradeFields { export interface TradeFields {

View File

@ -30,6 +30,12 @@ export interface Trades_market_trades_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
} }
export interface Trades_market_trades { export interface Trades_market_trades {

View File

@ -30,6 +30,12 @@ export interface TradesSub_trades_market {
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p) * GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
*/ */
decimalPlaces: number; decimalPlaces: number;
/**
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
*/
positionDecimalPlaces: number;
} }
export interface TradesSub_trades { export interface TradesSub_trades {

View File

@ -16,6 +16,7 @@ const TRADES_FRAGMENT = gql`
market { market {
id id
decimalPlaces decimalPlaces
positionDecimalPlaces
} }
} }
`; `;

View File

@ -7,12 +7,13 @@ const trade: TradeFields = {
__typename: 'Trade', __typename: 'Trade',
id: 'trade-id', id: 'trade-id',
price: '111122200', price: '111122200',
size: '20', size: '2000',
createdAt: new Date('2022-04-06T19:00:00').toISOString(), createdAt: new Date('2022-04-06T19:00:00').toISOString(),
market: { market: {
__typename: 'Market', __typename: 'Market',
id: 'market-id', id: 'market-id',
decimalPlaces: 2, decimalPlaces: 2,
positionDecimalPlaces: 2,
}, },
}; };
@ -34,7 +35,7 @@ it('Number and data columns are formatted', async () => {
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
const expectedValues = [ const expectedValues = [
'1,111,222.00', '1,111,222.00',
'20', '20.00',
getDateTimeFormat().format(new Date(trade.createdAt)), getDateTimeFormat().format(new Date(trade.createdAt)),
]; ];
cells.forEach((cell, i) => { cells.forEach((cell, i) => {

View File

@ -4,6 +4,7 @@ import { forwardRef, useMemo } from 'react';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit'; import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import type { TradeFields } from './__generated__/TradeFields'; import type { TradeFields } from './__generated__/TradeFields';
import { import {
addDecimal,
addDecimalsFormatNumber, addDecimalsFormatNumber,
getDateTimeFormat, getDateTimeFormat,
t, t,
@ -73,6 +74,9 @@ export const TradesTable = forwardRef<AgGridReact, TradesTableProps>(
<AgGridColumn <AgGridColumn
headerName={t('Size')} headerName={t('Size')}
field="size" field="size"
valueFormatter={({ value, data }: ValueFormatterParams) => {
return addDecimal(value, data.market.positionDecimalPlaces);
}}
cellClass={changeCellClass('size')} cellClass={changeCellClass('size')}
/> />
<AgGridColumn <AgGridColumn

View File

@ -87,27 +87,28 @@ export class RestConnector implements VegaConnector {
async sendTx(body: TransactionSubmission) { async sendTx(body: TransactionSubmission) {
try { try {
return await this.service.commandSyncPost(body); const res = await this.service.commandSyncPost(body);
return res;
} catch (err) { } catch (err) {
return this.handleSendTxError(err); return this.handleSendTxError(err);
} }
} }
private handleSendTxError(err: unknown) { private handleSendTxError(err: unknown) {
if (typeof err === 'object' && err && 'body' in err) { const unpexpectedError = { error: 'Something went wrong' };
if (isServiceError(err)) {
if (err.code === 401) {
return { error: 'User rejected' };
}
try { try {
// @ts-ignore Not sure why TS can't infer that 'body' does indeed exist on object return JSON.parse(err.body ?? '');
return JSON.parse(err.body);
} catch { } catch {
// Unexpected response return unpexpectedError;
return {
error: 'Something went wrong',
};
} }
} else { } else {
return { return unpexpectedError;
error: 'Something went wrong',
};
} }
} }
@ -132,3 +133,17 @@ export class RestConnector implements VegaConnector {
LocalStorage.removeItem(this.configKey); LocalStorage.removeItem(this.configKey);
} }
} }
interface ServiceError {
code: number;
body: string | undefined;
headers: object;
}
export const isServiceError = (err: unknown): err is ServiceError => {
// Some responses don't contain body object
if (typeof err === 'object' && err !== null && 'code' in err) {
return true;
}
return false;
};

View File

@ -2,7 +2,11 @@ import { act, renderHook } from '@testing-library/react-hooks';
import type { VegaWalletContextShape } from './context'; import type { VegaWalletContextShape } from './context';
import { VegaWalletContext } from './context'; import { VegaWalletContext } from './context';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { useVegaTransaction, VegaTxStatus } from './use-vega-transaction'; import {
initialState,
useVegaTransaction,
VegaTxStatus,
} from './use-vega-transaction';
import type { OrderSubmission } from './types'; import type { OrderSubmission } from './types';
const defaultWalletContext = { const defaultWalletContext = {
@ -94,3 +98,14 @@ it('Returns the signature if successful', async () => {
successObj.tx.signature.value successObj.tx.signature.value
); );
}); });
it('Resets transaction state if user rejects', async () => {
const mockSendTx = jest
.fn()
.mockReturnValue(Promise.resolve({ error: 'User rejected' }));
const { result } = setup({ sendTx: mockSendTx });
await act(async () => {
result.current.send({} as OrderSubmission);
});
expect(result.current.transaction).toEqual(initialState);
});

View File

@ -44,6 +44,10 @@ export const useVegaTransaction = () => {
[setTransaction] [setTransaction]
); );
const reset = useCallback(() => {
setTransaction(initialState);
}, [setTransaction]);
const send = useCallback( const send = useCallback(
async (tx: TransactionSubmission) => { async (tx: TransactionSubmission) => {
setTransaction({ setTransaction({
@ -61,7 +65,12 @@ export const useVegaTransaction = () => {
} }
if ('error' in res) { if ('error' in res) {
handleError(res); // Close dialog if user rejects the transaction
if (res.error === 'User rejected') {
reset();
} else {
handleError(res);
}
return null; return null;
} else if ('errors' in res) { } else if ('errors' in res) {
handleError(res); handleError(res);
@ -79,12 +88,8 @@ export const useVegaTransaction = () => {
return null; return null;
}, },
[sendTx, handleError, setTransaction] [sendTx, handleError, setTransaction, reset]
); );
const reset = useCallback(() => {
setTransaction(initialState);
}, [setTransaction]);
return { send, transaction, reset }; return { send, transaction, reset };
}; };

View File

@ -29,7 +29,7 @@
"@sentry/nextjs": "^6.19.3", "@sentry/nextjs": "^6.19.3",
"@sentry/react": "^6.19.2", "@sentry/react": "^6.19.2",
"@sentry/tracing": "^6.19.2", "@sentry/tracing": "^6.19.2",
"@vegaprotocol/vegawallet-service-api-client": "^0.4.12", "@vegaprotocol/vegawallet-service-api-client": "^0.4.13",
"@walletconnect/ethereum-provider": "^1.7.5", "@walletconnect/ethereum-provider": "^1.7.5",
"@web3-react/core": "8.0.20-beta.0", "@web3-react/core": "8.0.20-beta.0",
"@web3-react/metamask": "8.0.16-beta.0", "@web3-react/metamask": "8.0.16-beta.0",

View File

@ -6750,10 +6750,10 @@
"@typescript-eslint/types" "5.22.0" "@typescript-eslint/types" "5.22.0"
eslint-visitor-keys "^3.0.0" eslint-visitor-keys "^3.0.0"
"@vegaprotocol/vegawallet-service-api-client@^0.4.12": "@vegaprotocol/vegawallet-service-api-client@^0.4.13":
version "0.4.12" version "0.4.13"
resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.12.tgz#65551b9a4d2e00b2c2e9ca9619d95453954a0dbf" resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.13.tgz#fb98ec0179ea6cc27e991ef3d3338327eca4f3c4"
integrity sha512-Z680W8rsjz2U8R/gss7+hI0eik0euDJLlh7LzWGXUJxUC3XWO9rwJmzlqN/ZlEB4L9OzSLTSZsvlBAGwiHzUSQ== integrity sha512-YK6DsDKgvb+n9QwvKYSBQ51TDon0lGpLsNdNUa4oywIjubzWGVE4g98GrEmcP+UB/AfZzLA6A9ul7F/+TSep5Q==
dependencies: dependencies:
es6-promise "^4.2.4" es6-promise "^4.2.4"
url-parse "^1.4.3" url-parse "^1.4.3"