Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into tu/migrate-positions
Browse files Browse the repository at this point in the history
  • Loading branch information
tyleroooo committed Dec 19, 2024
2 parents 8c4e1b0 + 963cb30 commit 281d112
Show file tree
Hide file tree
Showing 33 changed files with 978 additions and 98 deletions.
42 changes: 41 additions & 1 deletion public/configs/v1/env.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,47 @@
"iconUrl": "/logos/dydx-x.png"
},
"v2": {
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e"
"projectId": "47559b2ec96c09aed9ff2cb54a31ab0e",
"wallets": {
"ios": [
"c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96",
"4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0",
"971e689d0a5be527bac79629b4ee9b925e82208e5168b733496a09c0faed0709",
"c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a",
"1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
"ecc4036f814562b41a5268adc86270fba1365471402006302e70169465b7ac18",
"c286eebc742a537cd1d6818363e9dc53b21759a1e8e5d9b263d0c03ec7703576",
"ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef",
"38f5d18bd8522c244bdd70cb4a68e0e718865155811c043f052fb9f1c51de662",
"0b415a746fb9ee99cce155c2ceca0c6f6061b1dbca2d722b3ba16381d0562150",
"15c8b91ade1a4e58f3ce4e7a0dd7f42b47db0c8df7e0d84f63eb39bcb96c4e0f",
"19177a98252e07ddfc9af2083ba8e07ef627cb6103467ffebb3f8f4205fd7927",
"344d0e58b139eb1b6da0c29ea71d52a8eace8b57897c6098cb9b46012665c193",
"225affb176778569276e484e1b92637ad061b01e13a048b35a9d280c3b58970f",
"f2436c67184f158d1beda5df53298ee84abfc367581e4505134b5bcf5f46697d",
"18450873727504ae9315a084fa7624b5297d2fe5880f0982979c17345a138277",
"541d5dcd4ede02f3afaf75bf8e3e4c4f1fb09edb5fa6c4377ebf31c2785d9adf"
],
"android": [
"c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96",
"4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0",
"971e689d0a5be527bac79629b4ee9b925e82208e5168b733496a09c0faed0709",
"c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a",
"1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369",
"ecc4036f814562b41a5268adc86270fba1365471402006302e70169465b7ac18",
"c286eebc742a537cd1d6818363e9dc53b21759a1e8e5d9b263d0c03ec7703576",
"ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef",
"38f5d18bd8522c244bdd70cb4a68e0e718865155811c043f052fb9f1c51de662",
"0b415a746fb9ee99cce155c2ceca0c6f6061b1dbca2d722b3ba16381d0562150",
"15c8b91ade1a4e58f3ce4e7a0dd7f42b47db0c8df7e0d84f63eb39bcb96c4e0f",
"19177a98252e07ddfc9af2083ba8e07ef627cb6103467ffebb3f8f4205fd7927",
"344d0e58b139eb1b6da0c29ea71d52a8eace8b57897c6098cb9b46012665c193",
"225affb176778569276e484e1b92637ad061b01e13a048b35a9d280c3b58970f",
"f2436c67184f158d1beda5df53298ee84abfc367581e4505134b5bcf5f46697d",
"18450873727504ae9315a084fa7624b5297d2fe5880f0982979c17345a138277",
"541d5dcd4ede02f3afaf75bf8e3e4c4f1fb09edb5fa6c4377ebf31c2785d9adf"
]
}
}
},
"walletSegue": {
Expand Down
25 changes: 25 additions & 0 deletions src/abacus-ts/calculators/markets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { IndexerPerpetualMarketResponseObject } from '@/types/indexer/indexerApiGen';
import { mapValues } from 'lodash';
import { weakMapMemoize } from 'reselect';

import { TOKEN_DECIMALS, USD_DECIMALS } from '@/constants/numbers';

import { MaybeBigNumber } from '@/lib/numbers';

import { MarketsData } from '../rawTypes';
import { MarketInfo, MarketsInfo } from '../summaryTypes';

export function calculateAllMarkets(markets: MarketsData | undefined): MarketsInfo | undefined {
if (markets == null) {
return markets;
}
return mapValues(markets, calculateMarket);
}

const calculateMarket = weakMapMemoize(
(market: IndexerPerpetualMarketResponseObject): MarketInfo => ({
...market,
stepSizeDecimals: MaybeBigNumber(market.stepSize)?.decimalPlaces() ?? TOKEN_DECIMALS,
tickSizeDecimals: MaybeBigNumber(market.tickSize)?.decimalPlaces() ?? USD_DECIMALS,
})
);
24 changes: 11 additions & 13 deletions src/abacus-ts/calculators/orders.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IndexerBestEffortOpenedStatus, IndexerOrderStatus } from '@/types/indexer/indexerApiGen';
import { IndexerCompositeOrderObject } from '@/types/indexer/indexerManual';
import { HeightResponse } from '@dydxprotocol/v4-client-js';
import { mapValues, maxBy, pickBy } from 'lodash';
import { mapValues, maxBy, orderBy } from 'lodash';

import { NUM_PARENT_SUBACCOUNTS } from '@/constants/account';

Expand All @@ -12,30 +12,28 @@ import { MaybeBigNumber, MustBigNumber } from '@/lib/numbers';

import { mergeObjects } from '../lib/mergeObjects';
import { OrdersData } from '../rawTypes';
import { OrderStatus, SubaccountOrder, SubaccountOrdersData } from '../summaryTypes';
import { OrderStatus, SubaccountOrder } from '../summaryTypes';

export function calculateOpenOrders(orders: SubaccountOrdersData) {
return pickBy(
orders,
(order) => getSimpleOrderStatus(order.status ?? OrderStatus.Open) === OrderStatus.Open
export function calculateOpenOrders(orders: SubaccountOrder[]) {
return orders.filter(
(order) => order.status == null || getSimpleOrderStatus(order.status) === OrderStatus.Open
);
}

export function calculateOrderHistory(orders: SubaccountOrdersData) {
return pickBy(
orders,
(order) => getSimpleOrderStatus(order.status ?? OrderStatus.Open) !== OrderStatus.Open
export function calculateOrderHistory(orders: SubaccountOrder[]) {
return orders.filter(
(order) => order.status != null && getSimpleOrderStatus(order.status) !== OrderStatus.Open
);
}

export function calculateAllOrders(
liveOrders: OrdersData | undefined,
restOrders: OrdersData | undefined,
height: HeightResponse
): SubaccountOrdersData {
): SubaccountOrder[] {
const actuallyMerged = calculateMergedOrders(liveOrders ?? {}, restOrders ?? {});
const mapped = mapValues(actuallyMerged, (order) => calculateSubaccountOrder(order, height));
return mapped;
return orderBy(Object.values(mapped), [(o) => o.updatedAtHeight], ['desc']);
}

function calculateSubaccountOrder(
Expand Down Expand Up @@ -74,7 +72,7 @@ function calculateSubaccountOrder(
return order;
}

function getSimpleOrderStatus(status: OrderStatus) {
export function getSimpleOrderStatus(status: OrderStatus) {
switch (status) {
case OrderStatus.Open:
case OrderStatus.Pending:
Expand Down
8 changes: 3 additions & 5 deletions src/abacus-ts/calculators/subaccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from '../summaryTypes';

export function calculateParentSubaccountPositions(
parent: Omit<ParentSubaccountData, 'ephemeral'>,
parent: Omit<ParentSubaccountData, 'live'>,
markets: MarketsData
): SubaccountPosition[] {
return Object.values(parent.childSubaccounts)
Expand All @@ -46,7 +46,7 @@ export function calculateParentSubaccountPositions(
}

export function calculateParentSubaccountSummary(
parent: Omit<ParentSubaccountData, 'ephemeral'>,
parent: Omit<ParentSubaccountData, 'live'>,
markets: MarketsData
): GroupedSubaccountSummary {
const summaries = mapValues(parent.childSubaccounts, (subaccount) =>
Expand All @@ -67,9 +67,7 @@ export function calculateParentSubaccountSummary(
};
}

export function calculateMarketsNeededForSubaccount(
parent: Omit<ParentSubaccountData, 'ephemeral'>
) {
export function calculateMarketsNeededForSubaccount(parent: Omit<ParentSubaccountData, 'live'>) {
return Object.values(parent.childSubaccounts).flatMap((o) =>
Object.values(o?.openPerpetualPositions ?? {}).map((p) => p.market)
);
Expand Down
4 changes: 3 additions & 1 deletion src/abacus-ts/lib/createStoreEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export function createStoreEffect<T>(
const removeStoreListener = store.subscribe(() => {
const thisValue = selector(store.getState());
if (thisValue !== lastValue) {
lastCleanup?.();
lastValue = thisValue;
// NOTE: some cleanups dispatch actions which cause this to happen recursively.
// we must ensure that those actions don't change the state they subscribe to or this will go infinitely
lastCleanup?.();
lastCleanup = handleChange(thisValue);
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/abacus-ts/rawTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface ParentSubaccountData {

// this data is lost on websocket reconnect, should never be trusted as the ONLY source for this information
// it should be used to trigger a rest call refresh (debounced) and merged with the rest call result until the refresh completes
ephemeral: {
live: {
tradingRewards?: IndexerHistoricalBlockTradingReward[];
fills?: IndexerCompositeFillObject[];
orders?: OrdersData;
Expand Down
17 changes: 15 additions & 2 deletions src/abacus-ts/selectors/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
selectRawValidatorHeightData,
} from './base';

const BACKUP_BLOCK_HEIGHT = { height: 0, time: '1971-01-01T00:00:00Z' };

const selectRelevantMarketsList = createAppSelector(
[selectRawParentSubaccountData],
(parentSubaccount) => {
Expand Down Expand Up @@ -98,7 +100,6 @@ export const selectParentSubaccountOpenPositions = createAppSelector(
);
export const selectParentSubaccountOpenPositionsLoading = selectParentSubaccountSummaryLoading;

const baseTime = { height: 0, time: '1971-01-01T00:00:00Z' };
export const selectAccountOrders = createAppSelector(
[
selectRawOrdersRestData,
Expand All @@ -107,7 +108,7 @@ export const selectAccountOrders = createAppSelector(
selectRawIndexerHeightData,
],
(rest, live, indexerHeight, validatorHeight) => {
return calculateAllOrders(rest, live, validatorHeight ?? indexerHeight ?? baseTime);
return calculateAllOrders(rest, live, validatorHeight ?? indexerHeight ?? BACKUP_BLOCK_HEIGHT);
}
);

Expand All @@ -119,6 +120,18 @@ export const selectOrderHistory = createAppSelector([selectAccountOrders], (orde
return calculateOrderHistory(orders);
});

export const selectCurrentMarketOpenOrders = createAppSelector(
[getCurrentMarketId, selectOpenOrders],
(currentMarketId, orders) =>
!currentMarketId ? EMPTY_ARR : orders.filter((o) => o.marketId === currentMarketId)
);

export const selectCurrentMarketOrderHistory = createAppSelector(
[getCurrentMarketId, selectOrderHistory],
(currentMarketId, orders) =>
!currentMarketId ? EMPTY_ARR : orders.filter((o) => o.marketId === currentMarketId)
);

export const selectAccountOrdersLoading = createAppSelector(
[
selectRawOrdersRest,
Expand Down
8 changes: 4 additions & 4 deletions src/abacus-ts/selectors/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export const selectRawBlockTradingRewardsRestData = (state: RootState) =>
state.raw.account.blockTradingRewards.data;

export const selectRawFillsLiveData = (state: RootState) =>
state.raw.account.parentSubaccount.data?.ephemeral.fills;
state.raw.account.parentSubaccount.data?.live.fills;
export const selectRawOrdersLiveData = (state: RootState) =>
state.raw.account.parentSubaccount.data?.ephemeral.orders;
state.raw.account.parentSubaccount.data?.live.orders;
export const selectRawTransfersLiveData = (state: RootState) =>
state.raw.account.parentSubaccount.data?.ephemeral.transfers;
state.raw.account.parentSubaccount.data?.live.transfers;
export const selectRawBlockTradingRewardsLiveData = (state: RootState) =>
state.raw.account.parentSubaccount.data?.ephemeral.tradingRewards;
state.raw.account.parentSubaccount.data?.live.tradingRewards;

export const selectRawIndexerHeightData = (state: RootState) =>
state.raw.heights.indexerHeight.data;
Expand Down
8 changes: 8 additions & 0 deletions src/abacus-ts/selectors/markets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createAppSelector } from '@/state/appTypes';

import { calculateAllMarkets } from '../calculators/markets';
import { selectRawMarketsData } from './base';

export const selectAllMarketsInfo = createAppSelector([selectRawMarketsData], (markets) =>
calculateAllMarkets(markets)
);
10 changes: 8 additions & 2 deletions src/abacus-ts/summaryTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
IndexerAPITimeInForce,
IndexerOrderSide,
IndexerOrderType,
IndexerPerpetualMarketResponseObject,
IndexerPerpetualPositionResponseObject,
} from '@/types/indexer/indexerApiGen';
import { type BigNumber } from 'bignumber.js';
Expand All @@ -19,6 +20,12 @@ type ConvertStringToBigNumber<T, K extends SelectStringProperties<T>> = {
[P in keyof T]: P extends K ? ReplaceBigNumberInUnion<T[P]> : T[P];
};

export type MarketInfo = IndexerPerpetualMarketResponseObject & {
stepSizeDecimals: number;
tickSizeDecimals: number;
};
export type MarketsInfo = { [marketId: string]: MarketInfo };

export type SubaccountSummaryCore = {
quoteBalance: BigNumber;
valueTotal: BigNumber;
Expand Down Expand Up @@ -87,7 +94,7 @@ export type SubaccountPositionDerivedExtra = {
updatedUnrealizedPnlPercent: BigNumber | null;
};

export type SubaccountPosition = SubaccountPositionBase &
export type SubaccountPosition = Omit<SubaccountPositionBase, 'size'> &
SubaccountPositionDerivedCore &
SubaccountPositionDerivedExtra;

Expand Down Expand Up @@ -130,4 +137,3 @@ export type SubaccountOrder = {
removalReason: string | undefined;
marginMode: MarginMode | undefined;
};
export type SubaccountOrdersData = { [orderId: string]: SubaccountOrder };
5 changes: 3 additions & 2 deletions src/abacus-ts/websocket/lib/indexerWebsocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class IndexerWebsocket {
const message = isWsMessage(messagePre);
if (message.type === 'error') {
logAbacusTsError('IndexerWebsocket', 'encountered server side error:', message.message);
} else if (message.type === 'connected') {
} else if (message.type === 'connected' || message.type === 'unsubscribed') {
// do nothing
} else if (
message.type === 'subscribed' ||
Expand Down Expand Up @@ -200,6 +200,7 @@ type IndexerWebsocketMessageType =
subaccountNumber?: number;
contents: any;
}
| { type: 'subscribed'; channel: string; id: string | undefined; contents: any };
| { type: 'subscribed'; channel: string; id: string | undefined; contents: any }
| { type: 'unsubscribed'; channel: string; id: string | undefined; contents: any };

export const isWsMessage = typia.createAssert<IndexerWebsocketMessageType>();
25 changes: 11 additions & 14 deletions src/abacus-ts/websocket/parentSubaccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function accountWebsocketValue(
.map(convertToStoredChildSubaccount),
(c) => c.subaccountNumber
),
ephemeral: {
live: {
orders: keyBy(message.orders, (o) => o.id),
},
});
Expand Down Expand Up @@ -150,16 +150,16 @@ function accountWebsocketValue(
});
}
if (update.tradingReward != null) {
returnValue.ephemeral.tradingRewards ??= [];
returnValue.ephemeral.tradingRewards = [
...returnValue.ephemeral.tradingRewards,
returnValue.live.tradingRewards ??= [];
returnValue.live.tradingRewards = [
...returnValue.live.tradingRewards,
update.tradingReward,
];
}
if (update.fills != null) {
returnValue.ephemeral.fills ??= [];
returnValue.ephemeral.fills = [
...returnValue.ephemeral.fills,
returnValue.live.fills ??= [];
returnValue.live.fills = [
...returnValue.live.fills,
...update.fills.map((f) => ({
...f,
subaccountNumber,
Expand All @@ -169,8 +169,8 @@ function accountWebsocketValue(
];
}
if (update.orders != null) {
returnValue.ephemeral.orders = { ...(returnValue.ephemeral.orders ?? {}) };
const allOrders = returnValue.ephemeral.orders;
returnValue.live.orders = { ...(returnValue.live.orders ?? {}) };
const allOrders = returnValue.live.orders;
update.orders.forEach((o) => {
const previousOrder = allOrders[o.id];
if (previousOrder == null) {
Expand All @@ -188,11 +188,8 @@ function accountWebsocketValue(
});
}
if (update.transfers != null) {
returnValue.ephemeral.transfers ??= [];
returnValue.ephemeral.transfers = [
...returnValue.ephemeral.transfers,
update.transfers,
];
returnValue.live.transfers ??= [];
returnValue.live.transfers = [...returnValue.live.transfers, update.transfers];
}
});
});
Expand Down
Loading

0 comments on commit 281d112

Please sign in to comment.