Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfe083cbee |
@@ -3,6 +3,9 @@ fragment MarginFields on MarginLevels {
|
||||
searchLevel
|
||||
initialLevel
|
||||
collateralReleaseLevel
|
||||
marginFactor
|
||||
marginMode
|
||||
orderMarginLevel
|
||||
asset {
|
||||
id
|
||||
}
|
||||
@@ -33,6 +36,9 @@ subscription MarginsSubscription($partyId: ID!) {
|
||||
searchLevel
|
||||
initialLevel
|
||||
collateralReleaseLevel
|
||||
marginFactor
|
||||
marginMode
|
||||
orderMarginLevel
|
||||
timestamp
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -3,21 +3,21 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type MarginFieldsFragment = { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, asset: { __typename?: 'Asset', id: string }, market: { __typename?: 'Market', id: string } };
|
||||
export type MarginFieldsFragment = { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, marginFactor: string, marginMode: Types.MarginMode, orderMarginLevel: string, asset: { __typename?: 'Asset', id: string }, market: { __typename?: 'Market', id: string } };
|
||||
|
||||
export type MarginsQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarginsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, marginsConnection?: { __typename?: 'MarginConnection', edges?: Array<{ __typename?: 'MarginEdge', node: { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, asset: { __typename?: 'Asset', id: string }, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
export type MarginsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, marginsConnection?: { __typename?: 'MarginConnection', edges?: Array<{ __typename?: 'MarginEdge', node: { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, marginFactor: string, marginMode: Types.MarginMode, orderMarginLevel: string, asset: { __typename?: 'Asset', id: string }, market: { __typename?: 'Market', id: string } } }> | null } | null } | null };
|
||||
|
||||
export type MarginsSubscriptionSubscriptionVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarginsSubscriptionSubscription = { __typename?: 'Subscription', margins: { __typename?: 'MarginLevelsUpdate', marketId: string, asset: string, partyId: string, maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, timestamp: any } };
|
||||
export type MarginsSubscriptionSubscription = { __typename?: 'Subscription', margins: { __typename?: 'MarginLevelsUpdate', marketId: string, asset: string, partyId: string, maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string, marginFactor: string, marginMode: Types.MarginMode, orderMarginLevel: string, timestamp: any } };
|
||||
|
||||
export const MarginFieldsFragmentDoc = gql`
|
||||
fragment MarginFields on MarginLevels {
|
||||
@@ -25,6 +25,9 @@ export const MarginFieldsFragmentDoc = gql`
|
||||
searchLevel
|
||||
initialLevel
|
||||
collateralReleaseLevel
|
||||
marginFactor
|
||||
marginMode
|
||||
orderMarginLevel
|
||||
asset {
|
||||
id
|
||||
}
|
||||
@@ -85,6 +88,9 @@ export const MarginsSubscriptionDocument = gql`
|
||||
searchLevel
|
||||
initialLevel
|
||||
collateralReleaseLevel
|
||||
marginFactor
|
||||
marginMode
|
||||
orderMarginLevel
|
||||
timestamp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ const update = (
|
||||
searchLevel: delta.searchLevel,
|
||||
initialLevel: delta.initialLevel,
|
||||
collateralReleaseLevel: delta.collateralReleaseLevel,
|
||||
marginFactor: delta.marginFactor,
|
||||
marginMode: delta.marginMode,
|
||||
orderMarginLevel: delta.orderMarginLevel,
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: delta.asset,
|
||||
|
||||
@@ -13,6 +13,7 @@ import { AsyncRendererInline } from '@vegaprotocol/ui-toolkit';
|
||||
import { DealTicket } from './deal-ticket';
|
||||
import { useFeatureFlags } from '@vegaprotocol/environment';
|
||||
import { useT } from '../../use-t';
|
||||
import { MarginModeSelector } from './margin-mode-selector';
|
||||
|
||||
interface DealTicketContainerProps {
|
||||
marketId: string;
|
||||
@@ -51,21 +52,26 @@ export const DealTicketContainer = ({
|
||||
reload={reload}
|
||||
>
|
||||
{market && marketData ? (
|
||||
featureFlags.STOP_ORDERS && showStopOrder ? (
|
||||
<StopOrder
|
||||
market={market}
|
||||
marketPrice={marketPrice}
|
||||
submit={(stopOrdersSubmission) => create({ stopOrdersSubmission })}
|
||||
/>
|
||||
) : (
|
||||
<DealTicket
|
||||
{...props}
|
||||
market={market}
|
||||
marketPrice={marketPrice}
|
||||
marketData={marketData}
|
||||
submit={(orderSubmission) => create({ orderSubmission })}
|
||||
/>
|
||||
)
|
||||
<>
|
||||
<MarginModeSelector marketId={marketId} />
|
||||
{featureFlags.STOP_ORDERS && showStopOrder ? (
|
||||
<StopOrder
|
||||
market={market}
|
||||
marketPrice={marketPrice}
|
||||
submit={(stopOrdersSubmission) =>
|
||||
create({ stopOrdersSubmission })
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<DealTicket
|
||||
{...props}
|
||||
market={market}
|
||||
marketPrice={marketPrice}
|
||||
marketData={marketData}
|
||||
submit={(orderSubmission) => create({ orderSubmission })}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<p>{t('Could not load market')}</p>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||
import { Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { marginModeDataProvider } from '@vegaprotocol/positions';
|
||||
import { MarginMode, useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import * as Types from '@vegaprotocol/types';
|
||||
import { useVegaTransactionStore } from '@vegaprotocol/web3';
|
||||
|
||||
export const MarginModeSelector = ({ marketId }: { marketId: string }) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data: marginMode } = useDataProvider({
|
||||
dataProvider: marginModeDataProvider,
|
||||
variables: {
|
||||
partyId: pubKey || '',
|
||||
marketId,
|
||||
},
|
||||
skip: !pubKey,
|
||||
});
|
||||
const create = useVegaTransactionStore((state) => state.create);
|
||||
const disabled = isReadOnly;
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-2 mb-2">
|
||||
<TradingButton
|
||||
disabled={disabled}
|
||||
size="extra-small"
|
||||
onClick={() =>
|
||||
create({
|
||||
updateMarginMode: {
|
||||
market_id: marketId,
|
||||
mode: MarginMode.MARGIN_MODE_CROSS_MARGIN,
|
||||
},
|
||||
})
|
||||
}
|
||||
intent={
|
||||
!marginMode ||
|
||||
marginMode.marginMode === Types.MarginMode.MARGIN_MODE_CROSS_MARGIN
|
||||
? Intent.Primary
|
||||
: Intent.None
|
||||
}
|
||||
>
|
||||
Cross
|
||||
</TradingButton>
|
||||
<TradingButton
|
||||
disabled={disabled}
|
||||
size="extra-small"
|
||||
onClick={() =>
|
||||
create({
|
||||
updateMarginMode: {
|
||||
market_id: marketId,
|
||||
mode: MarginMode.MARGIN_MODE_ISOLATED_MARGIN,
|
||||
marginFactor: '0.1',
|
||||
},
|
||||
})
|
||||
}
|
||||
intent={
|
||||
marginMode?.marginMode ===
|
||||
Types.MarginMode.MARGIN_MODE_ISOLATED_MARGIN
|
||||
? Intent.Primary
|
||||
: Intent.None
|
||||
}
|
||||
>
|
||||
Isolated {marginMode?.margin_factor || '10'}x
|
||||
</TradingButton>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './lib/__generated__/Positions';
|
||||
export * from './lib/margin-modes-provider';
|
||||
export * from './lib/positions-data-providers';
|
||||
export * from './lib/positions-table';
|
||||
export * from './lib/positions-manager';
|
||||
|
||||
@@ -83,3 +83,23 @@ query EstimatePosition(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment MarginMode on PartyMarginMode {
|
||||
marketId
|
||||
partyId
|
||||
marginMode
|
||||
margin_factor
|
||||
min_theoretical_margin_factor
|
||||
max_theoretical_leverage
|
||||
atEpoch
|
||||
}
|
||||
|
||||
query MarginModes($partyId: ID!) {
|
||||
partyMarginModes(partyId: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
...MarginMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-1
@@ -29,6 +29,15 @@ export type EstimatePositionQueryVariables = Types.Exact<{
|
||||
|
||||
export type EstimatePositionQuery = { __typename?: 'Query', estimatePosition?: { __typename?: 'PositionEstimate', margin: { __typename?: 'MarginEstimate', worstCase: { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string }, bestCase: { __typename?: 'MarginLevels', maintenanceLevel: string, searchLevel: string, initialLevel: string, collateralReleaseLevel: string } }, liquidation?: { __typename?: 'LiquidationEstimate', worstCase: { __typename?: 'LiquidationPrice', open_volume_only: string, including_buy_orders: string, including_sell_orders: string }, bestCase: { __typename?: 'LiquidationPrice', open_volume_only: string, including_buy_orders: string, including_sell_orders: string } } | null } | null };
|
||||
|
||||
export type MarginModeFragment = { __typename?: 'PartyMarginMode', marketId: string, partyId: string, marginMode: Types.MarginMode, margin_factor?: string | null, min_theoretical_margin_factor?: string | null, max_theoretical_leverage?: string | null, atEpoch: number };
|
||||
|
||||
export type MarginModesQueryVariables = Types.Exact<{
|
||||
partyId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type MarginModesQuery = { __typename?: 'Query', partyMarginModes?: { __typename?: 'PartyMarginModesConnection', edges?: Array<{ __typename?: 'PartyMarginModeEdge', node: { __typename?: 'PartyMarginMode', marketId: string, partyId: string, marginMode: Types.MarginMode, margin_factor?: string | null, min_theoretical_margin_factor?: string | null, max_theoretical_leverage?: string | null, atEpoch: number } } | null> | null } | null };
|
||||
|
||||
export const PositionFieldsFragmentDoc = gql`
|
||||
fragment PositionFields on Position {
|
||||
realisedPNL
|
||||
@@ -46,6 +55,17 @@ export const PositionFieldsFragmentDoc = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const MarginModeFragmentDoc = gql`
|
||||
fragment MarginMode on PartyMarginMode {
|
||||
marketId
|
||||
partyId
|
||||
marginMode
|
||||
margin_factor
|
||||
min_theoretical_margin_factor
|
||||
max_theoretical_leverage
|
||||
atEpoch
|
||||
}
|
||||
`;
|
||||
export const PositionsDocument = gql`
|
||||
query Positions($partyIds: [ID!]!) {
|
||||
positions(filter: {partyIds: $partyIds}) {
|
||||
@@ -191,4 +211,43 @@ export function useEstimatePositionLazyQuery(baseOptions?: Apollo.LazyQueryHookO
|
||||
}
|
||||
export type EstimatePositionQueryHookResult = ReturnType<typeof useEstimatePositionQuery>;
|
||||
export type EstimatePositionLazyQueryHookResult = ReturnType<typeof useEstimatePositionLazyQuery>;
|
||||
export type EstimatePositionQueryResult = Apollo.QueryResult<EstimatePositionQuery, EstimatePositionQueryVariables>;
|
||||
export type EstimatePositionQueryResult = Apollo.QueryResult<EstimatePositionQuery, EstimatePositionQueryVariables>;
|
||||
export const MarginModesDocument = gql`
|
||||
query MarginModes($partyId: ID!) {
|
||||
partyMarginModes(partyId: $partyId) {
|
||||
edges {
|
||||
node {
|
||||
...MarginMode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${MarginModeFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useMarginModesQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useMarginModesQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMarginModesQuery` 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 } = useMarginModesQuery({
|
||||
* variables: {
|
||||
* partyId: // value for 'partyId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useMarginModesQuery(baseOptions: Apollo.QueryHookOptions<MarginModesQuery, MarginModesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<MarginModesQuery, MarginModesQueryVariables>(MarginModesDocument, options);
|
||||
}
|
||||
export function useMarginModesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarginModesQuery, MarginModesQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<MarginModesQuery, MarginModesQueryVariables>(MarginModesDocument, options);
|
||||
}
|
||||
export type MarginModesQueryHookResult = ReturnType<typeof useMarginModesQuery>;
|
||||
export type MarginModesLazyQueryHookResult = ReturnType<typeof useMarginModesLazyQuery>;
|
||||
export type MarginModesQueryResult = Apollo.QueryResult<MarginModesQuery, MarginModesQueryVariables>;
|
||||
@@ -0,0 +1,38 @@
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import {
|
||||
makeDataProvider,
|
||||
makeDerivedDataProvider,
|
||||
} from '@vegaprotocol/data-provider';
|
||||
import {
|
||||
MarginModesDocument,
|
||||
type MarginModesQueryVariables,
|
||||
MarginModesQuery,
|
||||
MarginModeFragment,
|
||||
} from './__generated__/Positions';
|
||||
|
||||
export const marginModesDataProvider = makeDataProvider<
|
||||
MarginModesQuery,
|
||||
MarginModeFragment[],
|
||||
never,
|
||||
never,
|
||||
MarginModesQueryVariables
|
||||
>({
|
||||
query: MarginModesDocument,
|
||||
getData: (responseData: MarginModesQuery | null) =>
|
||||
removePaginationWrapper(responseData?.partyMarginModes?.edges) || [],
|
||||
});
|
||||
|
||||
export const marginModeDataProvider = makeDerivedDataProvider<
|
||||
MarginModeFragment | undefined,
|
||||
never,
|
||||
MarginModesQueryVariables & { marketId: string }
|
||||
>(
|
||||
[
|
||||
(callback, client, variables) =>
|
||||
marginModesDataProvider(callback, client, { partyId: variables.partyId }),
|
||||
],
|
||||
(data, variables) =>
|
||||
(data as MarginModeFragment[]).find(
|
||||
(marginMode) => marginMode.marketId === variables.marketId
|
||||
)
|
||||
);
|
||||
Generated
+70
@@ -1986,8 +1986,14 @@ export type MarginLevels = {
|
||||
initialLevel: Scalars['String'];
|
||||
/** Minimal margin for the position to be maintained in the network (unsigned integer) */
|
||||
maintenanceLevel: Scalars['String'];
|
||||
/** Margin factor, only relevant for isolated margin mode, else 0 */
|
||||
marginFactor: Scalars['String'];
|
||||
/** Margin mode of the party, cross margin or isolated margin */
|
||||
marginMode: MarginMode;
|
||||
/** Market in which the margin is required for this party */
|
||||
market: Market;
|
||||
/** When in isolated margin, the required order margin level, otherwise, 0 */
|
||||
orderMarginLevel: Scalars['String'];
|
||||
/** The party for this margin */
|
||||
party: Party;
|
||||
/** If the margin is between maintenance and search, the network will initiate a collateral search, expressed as unsigned integer */
|
||||
@@ -2010,8 +2016,14 @@ export type MarginLevelsUpdate = {
|
||||
initialLevel: Scalars['String'];
|
||||
/** Minimal margin for the position to be maintained in the network (unsigned integer) */
|
||||
maintenanceLevel: Scalars['String'];
|
||||
/** Margin factor, only relevant for isolated margin mode, else 0 */
|
||||
marginFactor: Scalars['String'];
|
||||
/** Margin mode of the party, cross margin or isolated margin */
|
||||
marginMode: MarginMode;
|
||||
/** Market in which the margin is required for this party */
|
||||
marketId: Scalars['ID'];
|
||||
/** When in isolated margin, the required order margin level, otherwise, 0 */
|
||||
orderMarginLevel: Scalars['String'];
|
||||
/** The party for this margin */
|
||||
partyId: Scalars['ID'];
|
||||
/** If the margin is between maintenance and search, the network will initiate a collateral search (unsigned integer) */
|
||||
@@ -2020,6 +2032,13 @@ export type MarginLevelsUpdate = {
|
||||
timestamp: Scalars['Timestamp'];
|
||||
};
|
||||
|
||||
export enum MarginMode {
|
||||
/** Party is in cross margin mode */
|
||||
MARGIN_MODE_CROSS_MARGIN = 'MARGIN_MODE_CROSS_MARGIN',
|
||||
/** Party is in isolated margin mode */
|
||||
MARGIN_MODE_ISOLATED_MARGIN = 'MARGIN_MODE_ISOLATED_MARGIN'
|
||||
}
|
||||
|
||||
/** Represents a product & associated parameters that can be traded on Vega, has an associated OrderBook and Trade history */
|
||||
export type Market = {
|
||||
__typename?: 'Market';
|
||||
@@ -3118,6 +3137,8 @@ export enum OrderRejectionReason {
|
||||
ORDER_ERROR_INVALID_TIME_IN_FORCE = 'ORDER_ERROR_INVALID_TIME_IN_FORCE',
|
||||
/** Invalid type */
|
||||
ORDER_ERROR_INVALID_TYPE = 'ORDER_ERROR_INVALID_TYPE',
|
||||
/** Party has insufficient funds to cover for the order margin for the new or amended order */
|
||||
ORDER_ERROR_ISOLATED_MARGIN_CHECK_FAILED = 'ORDER_ERROR_ISOLATED_MARGIN_CHECK_FAILED',
|
||||
/** Margin check failed - not enough available margin */
|
||||
ORDER_ERROR_MARGIN_CHECK_FAILED = 'ORDER_ERROR_MARGIN_CHECK_FAILED',
|
||||
/** Market is closed */
|
||||
@@ -3138,6 +3159,8 @@ export enum OrderRejectionReason {
|
||||
ORDER_ERROR_OFFSET_MUST_BE_GREATER_THAN_ZERO = 'ORDER_ERROR_OFFSET_MUST_BE_GREATER_THAN_ZERO',
|
||||
/** Order is out of sequence */
|
||||
ORDER_ERROR_OUT_OF_SEQUENCE = 'ORDER_ERROR_OUT_OF_SEQUENCE',
|
||||
/** Pegged orders are not allowed for a party in isolated margin mode */
|
||||
ORDER_ERROR_PEGGED_ORDERS_NOT_ALLOWED_IN_ISOLATED_MARGIN_MODE = 'ORDER_ERROR_PEGGED_ORDERS_NOT_ALLOWED_IN_ISOLATED_MARGIN_MODE',
|
||||
/** A post-only order would produce an aggressive trade and thus it has been rejected */
|
||||
ORDER_ERROR_POST_ONLY_ORDER_WOULD_TRADE = 'ORDER_ERROR_POST_ONLY_ORDER_WOULD_TRADE',
|
||||
/** A reduce-ony order would not reduce the party's position and thus it has been rejected */
|
||||
@@ -3586,6 +3609,41 @@ export type PartyLockedBalance = {
|
||||
untilEpoch: Scalars['Int'];
|
||||
};
|
||||
|
||||
/** Margin mode selected for the given party and market. */
|
||||
export type PartyMarginMode = {
|
||||
__typename?: 'PartyMarginMode';
|
||||
/** Epoch at which the update happened. */
|
||||
atEpoch: Scalars['Int'];
|
||||
/** Selected margin mode. */
|
||||
marginMode: MarginMode;
|
||||
/** Margin factor for the market. Isolated mode only. */
|
||||
margin_factor?: Maybe<Scalars['String']>;
|
||||
/** Unique ID of the market. */
|
||||
marketId: Scalars['ID'];
|
||||
/** Maximum theoretical leverage for the market. Isolated mode only. */
|
||||
max_theoretical_leverage?: Maybe<Scalars['String']>;
|
||||
/** Minimum theoretical margin factor for the market. Isolated mode only. */
|
||||
min_theoretical_margin_factor?: Maybe<Scalars['String']>;
|
||||
/** Unique ID of the party. */
|
||||
partyId: Scalars['ID'];
|
||||
};
|
||||
|
||||
/** Edge type containing the deposit and cursor information returned by a PartyMarginModeConnection */
|
||||
export type PartyMarginModeEdge = {
|
||||
__typename?: 'PartyMarginModeEdge';
|
||||
cursor: Scalars['String'];
|
||||
node: PartyMarginMode;
|
||||
};
|
||||
|
||||
/** Connection type for retrieving cursor-based paginated party margin modes information */
|
||||
export type PartyMarginModesConnection = {
|
||||
__typename?: 'PartyMarginModesConnection';
|
||||
/** The party margin modes */
|
||||
edges?: Maybe<Array<Maybe<PartyMarginModeEdge>>>;
|
||||
/** The pagination information */
|
||||
pageInfo?: Maybe<PageInfo>;
|
||||
};
|
||||
|
||||
/**
|
||||
* All staking information related to a Party.
|
||||
* Contains the current recognised balance by the network and
|
||||
@@ -4438,6 +4496,12 @@ export type Query = {
|
||||
partiesConnection?: Maybe<PartyConnection>;
|
||||
/** An entity that is trading on the Vega network */
|
||||
party?: Maybe<Party>;
|
||||
/**
|
||||
* List margin modes per party per market
|
||||
*
|
||||
* Get a list of all margin modes, or for a specific market ID, or party ID.
|
||||
*/
|
||||
partyMarginModes?: Maybe<PartyMarginModesConnection>;
|
||||
/** Fetch all positions */
|
||||
positions?: Maybe<PositionConnection>;
|
||||
/** A governance proposal located by either its ID or reference. If both are set, ID is used. */
|
||||
@@ -6211,6 +6275,8 @@ export enum TransferType {
|
||||
TRANSFER_TYPE_INFRASTRUCTURE_FEE_DISTRIBUTE = 'TRANSFER_TYPE_INFRASTRUCTURE_FEE_DISTRIBUTE',
|
||||
/** Infrastructure fee paid from general account */
|
||||
TRANSFER_TYPE_INFRASTRUCTURE_FEE_PAY = 'TRANSFER_TYPE_INFRASTRUCTURE_FEE_PAY',
|
||||
/** Funds moved from order margin account to margin account. */
|
||||
TRANSFER_TYPE_ISOLATED_MARGIN_LOW = 'TRANSFER_TYPE_ISOLATED_MARGIN_LOW',
|
||||
/** Allocates liquidity fee earnings to each liquidity provider's network controlled liquidity fee account. */
|
||||
TRANSFER_TYPE_LIQUIDITY_FEE_ALLOCATE = 'TRANSFER_TYPE_LIQUIDITY_FEE_ALLOCATE',
|
||||
/** Liquidity fee received into general account */
|
||||
@@ -6237,6 +6303,10 @@ export enum TransferType {
|
||||
TRANSFER_TYPE_MTM_LOSS = 'TRANSFER_TYPE_MTM_LOSS',
|
||||
/** Funds added to margin account after mark to market gain */
|
||||
TRANSFER_TYPE_MTM_WIN = 'TRANSFER_TYPE_MTM_WIN',
|
||||
/** Funds released from order margin account to general. */
|
||||
TRANSFER_TYPE_ORDER_MARGIN_HIGH = 'TRANSFER_TYPE_ORDER_MARGIN_HIGH',
|
||||
/** Funds moved from general account to order margin account. */
|
||||
TRANSFER_TYPE_ORDER_MARGIN_LOW = 'TRANSFER_TYPE_ORDER_MARGIN_LOW',
|
||||
/** Funds deducted from margin account after a perpetuals funding loss. */
|
||||
TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS = 'TRANSFER_TYPE_PERPETUALS_FUNDING_LOSS',
|
||||
/** Funds added to margin account after a perpetuals funding gain. */
|
||||
|
||||
@@ -448,7 +448,24 @@ export type CreateReferralSet = {
|
||||
};
|
||||
};
|
||||
|
||||
export enum MarginMode {
|
||||
/** Party is in cross margin mode */
|
||||
MARGIN_MODE_CROSS_MARGIN = 1,
|
||||
/** Party is in isolated margin mode */
|
||||
MARGIN_MODE_ISOLATED_MARGIN = 'MARGIN_MODE_ISOLATED_MARGIN',
|
||||
}
|
||||
export interface UpdateMarginMode {
|
||||
market_id: string;
|
||||
mode: MarginMode;
|
||||
marginFactor?: string;
|
||||
}
|
||||
|
||||
export interface UpdateMarginModeBody {
|
||||
updateMarginMode: UpdateMarginMode;
|
||||
}
|
||||
|
||||
export type Transaction =
|
||||
| UpdateMarginModeBody
|
||||
| StopOrdersSubmissionBody
|
||||
| StopOrdersCancellationBody
|
||||
| OrderSubmissionBody
|
||||
@@ -465,6 +482,10 @@ export type Transaction =
|
||||
| ApplyReferralCode
|
||||
| CreateReferralSet;
|
||||
|
||||
export const isMarginModeUpdateTransaction = (
|
||||
transaction: Transaction
|
||||
): transaction is UpdateMarginModeBody => 'updateMarginMode' in transaction;
|
||||
|
||||
export const isWithdrawTransaction = (
|
||||
transaction: Transaction
|
||||
): transaction is WithdrawSubmissionBody => 'withdrawSubmission' in transaction;
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
isStopOrdersSubmissionTransaction,
|
||||
isStopOrdersCancellationTransaction,
|
||||
determineId,
|
||||
isMarginModeUpdateTransaction,
|
||||
} from '@vegaprotocol/wallet';
|
||||
|
||||
import { create } from 'zustand';
|
||||
@@ -58,7 +59,7 @@ export interface VegaTransactionStore {
|
||||
|
||||
export const useVegaTransactionStore = create<VegaTransactionStore>()(
|
||||
subscribeWithSelector((set, get) => ({
|
||||
transactions: [] as VegaStoredTxState[],
|
||||
transactions: [] as (VegaStoredTxState | undefined)[],
|
||||
create: (body: Transaction, order?: OrderTxUpdateFieldsFragment) => {
|
||||
const transactions = get().transactions;
|
||||
const now = new Date();
|
||||
@@ -205,16 +206,23 @@ export const useVegaTransactionStore = create<VegaTransactionStore>()(
|
||||
isStopOrdersCancellationTransaction(transaction.body);
|
||||
const isConfirmedStopOrderSubmission =
|
||||
isStopOrdersSubmissionTransaction(transaction.body);
|
||||
const isConfirmedMarginModeTransaction =
|
||||
isMarginModeUpdateTransaction(transaction.body);
|
||||
|
||||
if (
|
||||
(isConfirmedOrderCancellation ||
|
||||
isConfirmedTransfer ||
|
||||
isConfirmedStopOrderCancellation ||
|
||||
isConfirmedStopOrderSubmission) &&
|
||||
!transactionResult.error &&
|
||||
transactionResult.status
|
||||
isConfirmedOrderCancellation ||
|
||||
isConfirmedTransfer ||
|
||||
isConfirmedStopOrderCancellation ||
|
||||
isConfirmedStopOrderSubmission ||
|
||||
isConfirmedMarginModeTransaction
|
||||
//transactionResult.status
|
||||
) {
|
||||
transaction.status = VegaTxStatus.Complete;
|
||||
if (transactionResult.error) {
|
||||
transaction.status = VegaTxStatus.Error;
|
||||
transaction.error = new Error(transactionResult.error);
|
||||
} else {
|
||||
transaction.status = VegaTxStatus.Complete;
|
||||
}
|
||||
}
|
||||
transaction.dialogOpen = true;
|
||||
transaction.updatedAt = new Date();
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
OrderSubmission,
|
||||
StopOrdersSubmission,
|
||||
StopOrderSetup,
|
||||
UpdateMarginMode,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import type {
|
||||
OrderTxUpdateFieldsFragment,
|
||||
@@ -26,6 +27,8 @@ import {
|
||||
isStopOrdersSubmissionTransaction,
|
||||
isStopOrdersCancellationTransaction,
|
||||
isReferralRelatedTransaction,
|
||||
isMarginModeUpdateTransaction,
|
||||
MarginMode,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { useVegaTransactionStore } from './use-vega-transaction-store';
|
||||
import { VegaTxStatus } from './types';
|
||||
@@ -163,6 +166,7 @@ const isClosePositionTransaction = (tx: VegaStoredTxState) => {
|
||||
};
|
||||
|
||||
const isTransactionTypeSupported = (tx: VegaStoredTxState) => {
|
||||
const marginModeUpdate = isMarginModeUpdateTransaction(tx.body);
|
||||
const withdraw = isWithdrawTransaction(tx.body);
|
||||
const submitOrder = isOrderSubmissionTransaction(tx.body);
|
||||
const cancelOrder = isOrderCancellationTransaction(tx.body);
|
||||
@@ -173,6 +177,7 @@ const isTransactionTypeSupported = (tx: VegaStoredTxState) => {
|
||||
const transfer = isTransferTransaction(tx.body);
|
||||
const referral = isReferralRelatedTransaction(tx.body);
|
||||
return (
|
||||
marginModeUpdate ||
|
||||
withdraw ||
|
||||
submitOrder ||
|
||||
cancelOrder ||
|
||||
@@ -445,6 +450,27 @@ const CancelOrderDetails = ({
|
||||
);
|
||||
};
|
||||
|
||||
const MarginModeDetails = ({ data }: { data: UpdateMarginMode }) => {
|
||||
const t = useT();
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const marketId = data.market_id;
|
||||
const market = marketId && markets?.[marketId];
|
||||
if (!market) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Panel>
|
||||
<h4>{t('Update margin mode')}</h4>
|
||||
<p>{market?.tradableInstrument.instrument.code}</p>
|
||||
{data.mode === MarginMode.MARGIN_MODE_CROSS_MARGIN
|
||||
? t('Cross margin mode')
|
||||
: t('Isolated margin mode {{leverage}}x', {
|
||||
leverage: 1 / Number(data.marginFactor),
|
||||
})}
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
|
||||
const CancelStopOrderDetails = ({ stopOrderId }: { stopOrderId: string }) => {
|
||||
const t = useT();
|
||||
const formatTrigger = useFormatTrigger();
|
||||
@@ -598,6 +624,10 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isMarginModeUpdateTransaction(tx.body)) {
|
||||
return <MarginModeDetails data={tx.body.updateMarginMode} />;
|
||||
}
|
||||
|
||||
if (isClosePositionTransaction(tx)) {
|
||||
const transaction = tx.body as BatchMarketInstructionSubmissionBody;
|
||||
const marketId = first(
|
||||
|
||||
Reference in New Issue
Block a user