@lifi/perps-sdk-provider-ondo 0.0.0-preview-7ff840c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +38 -0
- package/dist/cjs/OndoProvider.d.ts +8 -0
- package/dist/cjs/OndoProvider.d.ts.map +1 -0
- package/dist/cjs/OndoProvider.js +338 -0
- package/dist/cjs/OndoProvider.js.map +1 -0
- package/dist/cjs/accountConfig.d.ts +3 -0
- package/dist/cjs/accountConfig.d.ts.map +1 -0
- package/dist/cjs/accountConfig.js +59 -0
- package/dist/cjs/accountConfig.js.map +1 -0
- package/dist/cjs/accountSummary.d.ts +3 -0
- package/dist/cjs/accountSummary.d.ts.map +1 -0
- package/dist/cjs/accountSummary.js +8 -0
- package/dist/cjs/accountSummary.js.map +1 -0
- package/dist/cjs/auth/OndoTokenStore.d.ts +13 -0
- package/dist/cjs/auth/OndoTokenStore.d.ts.map +1 -0
- package/dist/cjs/auth/OndoTokenStore.js +53 -0
- package/dist/cjs/auth/OndoTokenStore.js.map +1 -0
- package/dist/cjs/auth/completeSiweLogin.d.ts +13 -0
- package/dist/cjs/auth/completeSiweLogin.d.ts.map +1 -0
- package/dist/cjs/auth/completeSiweLogin.js +15 -0
- package/dist/cjs/auth/completeSiweLogin.js.map +1 -0
- package/dist/cjs/auth/index.d.ts +4 -0
- package/dist/cjs/auth/index.d.ts.map +1 -0
- package/dist/cjs/auth/index.js +11 -0
- package/dist/cjs/auth/index.js.map +1 -0
- package/dist/cjs/auth/signActions.d.ts +13 -0
- package/dist/cjs/auth/signActions.d.ts.map +1 -0
- package/dist/cjs/auth/signActions.js +86 -0
- package/dist/cjs/auth/signActions.js.map +1 -0
- package/dist/cjs/constants.d.ts +9 -0
- package/dist/cjs/constants.d.ts.map +1 -0
- package/dist/cjs/constants.js +12 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/auth.d.ts +16 -0
- package/dist/cjs/types/auth.d.ts.map +1 -0
- package/dist/cjs/types/auth.js +3 -0
- package/dist/cjs/types/auth.js.map +1 -0
- package/dist/cjs/types/index.d.ts +4 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +3 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/wire.d.ts +154 -0
- package/dist/cjs/types/wire.d.ts.map +1 -0
- package/dist/cjs/types/wire.js +3 -0
- package/dist/cjs/types/wire.js.map +1 -0
- package/dist/cjs/types/ws.d.ts +92 -0
- package/dist/cjs/types/ws.d.ts.map +1 -0
- package/dist/cjs/types/ws.js +3 -0
- package/dist/cjs/types/ws.js.map +1 -0
- package/dist/cjs/utils/activityCursor.d.ts +9 -0
- package/dist/cjs/utils/activityCursor.d.ts.map +1 -0
- package/dist/cjs/utils/activityCursor.js +79 -0
- package/dist/cjs/utils/activityCursor.js.map +1 -0
- package/dist/cjs/utils/apiClient.d.ts +43 -0
- package/dist/cjs/utils/apiClient.d.ts.map +1 -0
- package/dist/cjs/utils/apiClient.js +134 -0
- package/dist/cjs/utils/apiClient.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +11 -0
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/cjs/utils/index.js +39 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/liquidation.d.ts +4 -0
- package/dist/cjs/utils/liquidation.d.ts.map +1 -0
- package/dist/cjs/utils/liquidation.js +16 -0
- package/dist/cjs/utils/liquidation.js.map +1 -0
- package/dist/cjs/utils/mapActivity.d.ts +5 -0
- package/dist/cjs/utils/mapActivity.d.ts.map +1 -0
- package/dist/cjs/utils/mapActivity.js +34 -0
- package/dist/cjs/utils/mapActivity.js.map +1 -0
- package/dist/cjs/utils/mapFill.d.ts +4 -0
- package/dist/cjs/utils/mapFill.d.ts.map +1 -0
- package/dist/cjs/utils/mapFill.js +36 -0
- package/dist/cjs/utils/mapFill.js.map +1 -0
- package/dist/cjs/utils/mapOrder.d.ts +16 -0
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -0
- package/dist/cjs/utils/mapOrder.js +135 -0
- package/dist/cjs/utils/mapOrder.js.map +1 -0
- package/dist/cjs/utils/mapPosition.d.ts +5 -0
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -0
- package/dist/cjs/utils/mapPosition.js +26 -0
- package/dist/cjs/utils/mapPosition.js.map +1 -0
- package/dist/cjs/utils/ohlcvInterval.d.ts +4 -0
- package/dist/cjs/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/cjs/utils/ohlcvInterval.js +49 -0
- package/dist/cjs/utils/ohlcvInterval.js.map +1 -0
- package/dist/cjs/utils/ondoAsset.d.ts +3 -0
- package/dist/cjs/utils/ondoAsset.d.ts.map +1 -0
- package/dist/cjs/utils/ondoAsset.js +12 -0
- package/dist/cjs/utils/ondoAsset.js.map +1 -0
- package/dist/cjs/utils/orderFormatting.d.ts +4 -0
- package/dist/cjs/utils/orderFormatting.d.ts.map +1 -0
- package/dist/cjs/utils/orderFormatting.js +40 -0
- package/dist/cjs/utils/orderFormatting.js.map +1 -0
- package/dist/cjs/websocket/OndoWsProvider.d.ts +56 -0
- package/dist/cjs/websocket/OndoWsProvider.d.ts.map +1 -0
- package/dist/cjs/websocket/OndoWsProvider.js +515 -0
- package/dist/cjs/websocket/OndoWsProvider.js.map +1 -0
- package/dist/esm/OndoProvider.d.ts +39 -0
- package/dist/esm/OndoProvider.d.ts.map +1 -0
- package/dist/esm/OndoProvider.js +366 -0
- package/dist/esm/OndoProvider.js.map +1 -0
- package/dist/esm/accountConfig.d.ts +13 -0
- package/dist/esm/accountConfig.d.ts.map +1 -0
- package/dist/esm/accountConfig.js +77 -0
- package/dist/esm/accountConfig.js.map +1 -0
- package/dist/esm/accountSummary.d.ts +12 -0
- package/dist/esm/accountSummary.d.ts.map +1 -0
- package/dist/esm/accountSummary.js +14 -0
- package/dist/esm/accountSummary.js.map +1 -0
- package/dist/esm/auth/OndoTokenStore.d.ts +20 -0
- package/dist/esm/auth/OndoTokenStore.d.ts.map +1 -0
- package/dist/esm/auth/OndoTokenStore.js +61 -0
- package/dist/esm/auth/OndoTokenStore.js.map +1 -0
- package/dist/esm/auth/completeSiweLogin.d.ts +28 -0
- package/dist/esm/auth/completeSiweLogin.d.ts.map +1 -0
- package/dist/esm/auth/completeSiweLogin.js +21 -0
- package/dist/esm/auth/completeSiweLogin.js.map +1 -0
- package/dist/esm/auth/index.d.ts +4 -0
- package/dist/esm/auth/index.d.ts.map +1 -0
- package/dist/esm/auth/index.js +5 -0
- package/dist/esm/auth/index.js.map +1 -0
- package/dist/esm/auth/signActions.d.ts +35 -0
- package/dist/esm/auth/signActions.d.ts.map +1 -0
- package/dist/esm/auth/signActions.js +103 -0
- package/dist/esm/auth/signActions.js.map +1 -0
- package/dist/esm/constants.d.ts +35 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +35 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +21 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types/auth.d.ts +32 -0
- package/dist/esm/types/auth.d.ts.map +1 -0
- package/dist/esm/types/auth.js +2 -0
- package/dist/esm/types/auth.js.map +1 -0
- package/dist/esm/types/index.d.ts +4 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +3 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/wire.d.ts +195 -0
- package/dist/esm/types/wire.d.ts.map +1 -0
- package/dist/esm/types/wire.js +7 -0
- package/dist/esm/types/wire.js.map +1 -0
- package/dist/esm/types/ws.d.ts +108 -0
- package/dist/esm/types/ws.d.ts.map +1 -0
- package/dist/esm/types/ws.js +7 -0
- package/dist/esm/types/ws.js.map +1 -0
- package/dist/esm/utils/activityCursor.d.ts +47 -0
- package/dist/esm/utils/activityCursor.d.ts.map +1 -0
- package/dist/esm/utils/activityCursor.js +93 -0
- package/dist/esm/utils/activityCursor.js.map +1 -0
- package/dist/esm/utils/apiClient.d.ts +90 -0
- package/dist/esm/utils/apiClient.d.ts.map +1 -0
- package/dist/esm/utils/apiClient.js +169 -0
- package/dist/esm/utils/apiClient.js.map +1 -0
- package/dist/esm/utils/index.d.ts +11 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +12 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/liquidation.d.ts +20 -0
- package/dist/esm/utils/liquidation.d.ts.map +1 -0
- package/dist/esm/utils/liquidation.js +29 -0
- package/dist/esm/utils/liquidation.js.map +1 -0
- package/dist/esm/utils/mapActivity.d.ts +21 -0
- package/dist/esm/utils/mapActivity.d.ts.map +1 -0
- package/dist/esm/utils/mapActivity.js +45 -0
- package/dist/esm/utils/mapActivity.js.map +1 -0
- package/dist/esm/utils/mapFill.d.ts +12 -0
- package/dist/esm/utils/mapFill.d.ts.map +1 -0
- package/dist/esm/utils/mapFill.js +37 -0
- package/dist/esm/utils/mapFill.js.map +1 -0
- package/dist/esm/utils/mapOrder.d.ts +50 -0
- package/dist/esm/utils/mapOrder.d.ts.map +1 -0
- package/dist/esm/utils/mapOrder.js +155 -0
- package/dist/esm/utils/mapOrder.js.map +1 -0
- package/dist/esm/utils/mapPosition.d.ts +19 -0
- package/dist/esm/utils/mapPosition.d.ts.map +1 -0
- package/dist/esm/utils/mapPosition.js +32 -0
- package/dist/esm/utils/mapPosition.js.map +1 -0
- package/dist/esm/utils/ohlcvInterval.d.ts +11 -0
- package/dist/esm/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/esm/utils/ohlcvInterval.js +59 -0
- package/dist/esm/utils/ohlcvInterval.js.map +1 -0
- package/dist/esm/utils/ondoAsset.d.ts +4 -0
- package/dist/esm/utils/ondoAsset.d.ts.map +1 -0
- package/dist/esm/utils/ondoAsset.js +9 -0
- package/dist/esm/utils/ondoAsset.js.map +1 -0
- package/dist/esm/utils/orderFormatting.d.ts +33 -0
- package/dist/esm/utils/orderFormatting.d.ts.map +1 -0
- package/dist/esm/utils/orderFormatting.js +62 -0
- package/dist/esm/utils/orderFormatting.js.map +1 -0
- package/dist/esm/websocket/OndoWsProvider.d.ts +122 -0
- package/dist/esm/websocket/OndoWsProvider.d.ts.map +1 -0
- package/dist/esm/websocket/OndoWsProvider.js +591 -0
- package/dist/esm/websocket/OndoWsProvider.js.map +1 -0
- package/dist/types/OndoProvider.d.ts +39 -0
- package/dist/types/OndoProvider.d.ts.map +1 -0
- package/dist/types/accountConfig.d.ts +13 -0
- package/dist/types/accountConfig.d.ts.map +1 -0
- package/dist/types/accountSummary.d.ts +12 -0
- package/dist/types/accountSummary.d.ts.map +1 -0
- package/dist/types/auth/OndoTokenStore.d.ts +20 -0
- package/dist/types/auth/OndoTokenStore.d.ts.map +1 -0
- package/dist/types/auth/completeSiweLogin.d.ts +28 -0
- package/dist/types/auth/completeSiweLogin.d.ts.map +1 -0
- package/dist/types/auth/index.d.ts +4 -0
- package/dist/types/auth/index.d.ts.map +1 -0
- package/dist/types/auth/signActions.d.ts +35 -0
- package/dist/types/auth/signActions.d.ts.map +1 -0
- package/dist/types/constants.d.ts +35 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types/auth.d.ts +32 -0
- package/dist/types/types/auth.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +4 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/wire.d.ts +195 -0
- package/dist/types/types/wire.d.ts.map +1 -0
- package/dist/types/types/ws.d.ts +108 -0
- package/dist/types/types/ws.d.ts.map +1 -0
- package/dist/types/utils/activityCursor.d.ts +47 -0
- package/dist/types/utils/activityCursor.d.ts.map +1 -0
- package/dist/types/utils/apiClient.d.ts +90 -0
- package/dist/types/utils/apiClient.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +11 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/liquidation.d.ts +20 -0
- package/dist/types/utils/liquidation.d.ts.map +1 -0
- package/dist/types/utils/mapActivity.d.ts +21 -0
- package/dist/types/utils/mapActivity.d.ts.map +1 -0
- package/dist/types/utils/mapFill.d.ts +12 -0
- package/dist/types/utils/mapFill.d.ts.map +1 -0
- package/dist/types/utils/mapOrder.d.ts +50 -0
- package/dist/types/utils/mapOrder.d.ts.map +1 -0
- package/dist/types/utils/mapPosition.d.ts +19 -0
- package/dist/types/utils/mapPosition.d.ts.map +1 -0
- package/dist/types/utils/ohlcvInterval.d.ts +11 -0
- package/dist/types/utils/ohlcvInterval.d.ts.map +1 -0
- package/dist/types/utils/ondoAsset.d.ts +4 -0
- package/dist/types/utils/ondoAsset.d.ts.map +1 -0
- package/dist/types/utils/orderFormatting.d.ts +33 -0
- package/dist/types/utils/orderFormatting.d.ts.map +1 -0
- package/dist/types/websocket/OndoWsProvider.d.ts +122 -0
- package/dist/types/websocket/OndoWsProvider.d.ts.map +1 -0
- package/package.json +64 -0
- package/src/OndoProvider.ts +635 -0
- package/src/accountConfig.ts +105 -0
- package/src/accountSummary.ts +22 -0
- package/src/auth/OndoTokenStore.ts +83 -0
- package/src/auth/completeSiweLogin.ts +43 -0
- package/src/auth/index.ts +12 -0
- package/src/auth/signActions.ts +160 -0
- package/src/constants.ts +38 -0
- package/src/index.ts +36 -0
- package/src/types/auth.ts +32 -0
- package/src/types/index.ts +5 -0
- package/src/types/wire.ts +228 -0
- package/src/types/ws.ts +79 -0
- package/src/utils/activityCursor.ts +140 -0
- package/src/utils/apiClient.ts +257 -0
- package/src/utils/index.ts +35 -0
- package/src/utils/liquidation.ts +37 -0
- package/src/utils/mapActivity.ts +61 -0
- package/src/utils/mapFill.ts +47 -0
- package/src/utils/mapOrder.ts +201 -0
- package/src/utils/mapPosition.ts +44 -0
- package/src/utils/ohlcvInterval.ts +69 -0
- package/src/utils/ondoAsset.ts +10 -0
- package/src/utils/orderFormatting.ts +70 -0
- package/src/websocket/OndoWsProvider.ts +752 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// biome-ignore-all lint/performance/noBarrelFile: module public entry point.
|
|
2
|
+
|
|
3
|
+
export {
|
|
4
|
+
decodeActivityCursor,
|
|
5
|
+
encodeActivityCursor,
|
|
6
|
+
type OndoActivityCursor,
|
|
7
|
+
} from './activityCursor.js'
|
|
8
|
+
export {
|
|
9
|
+
type ApiParams,
|
|
10
|
+
ONDO_RETRY_DEFAULTS,
|
|
11
|
+
OndoApiClient,
|
|
12
|
+
type OndoApiClientOptions,
|
|
13
|
+
OndoApiError,
|
|
14
|
+
type OndoHttpMethod,
|
|
15
|
+
type OndoPage,
|
|
16
|
+
type OndoRequestOptions,
|
|
17
|
+
OndoSessionExpiredError,
|
|
18
|
+
} from './apiClient.js'
|
|
19
|
+
export { estimateLiquidationPrice } from './liquidation.js'
|
|
20
|
+
export { mapFundingActivity, mapLiquidationActivity } from './mapActivity.js'
|
|
21
|
+
export { mapFill } from './mapFill.js'
|
|
22
|
+
export {
|
|
23
|
+
classifyAndMapOrders,
|
|
24
|
+
isTriggerOrder,
|
|
25
|
+
mapOrder,
|
|
26
|
+
mapOrderDetail,
|
|
27
|
+
mapOrderStatus,
|
|
28
|
+
mapOrderType,
|
|
29
|
+
mapStatusReason,
|
|
30
|
+
mapTriggerOrder,
|
|
31
|
+
} from './mapOrder.js'
|
|
32
|
+
export { mapOpenPositions, mapPosition } from './mapPosition.js'
|
|
33
|
+
export { intervalFromBarSpan, mapInterval } from './ohlcvInterval.js'
|
|
34
|
+
export { ondoAsset } from './ondoAsset.js'
|
|
35
|
+
export { formatOrderPrice, formatOrderSize } from './orderFormatting.js'
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ondo liquidation price estimation.
|
|
3
|
+
*
|
|
4
|
+
* The LI.FI backend surfaces Ondo's per-market maintenance margin rate on the
|
|
5
|
+
* generic {@link PerpsMarket} as `maintenanceMarginRate`. The estimate is the
|
|
6
|
+
* standard isolated-margin model parameterised by that rate.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
estimateIsolatedLiquidationPrice,
|
|
11
|
+
type LiquidationEstimateParams,
|
|
12
|
+
} from '@lifi/perps-sdk'
|
|
13
|
+
import type { PerpsMarket } from '@lifi/perps-types'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Estimate the liquidation price of a new position on an Ondo market.
|
|
17
|
+
*
|
|
18
|
+
* @returns The estimated liquidation price, or `undefined` when
|
|
19
|
+
* `market.maintenanceMarginRate` is absent (the model cannot be evaluated
|
|
20
|
+
* without the venue's maintenance margin rate) or the inputs are
|
|
21
|
+
* degenerate.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export function estimateLiquidationPrice(
|
|
25
|
+
market: PerpsMarket,
|
|
26
|
+
params: LiquidationEstimateParams
|
|
27
|
+
): number | undefined {
|
|
28
|
+
if (market.maintenanceMarginRate === undefined) {
|
|
29
|
+
return undefined
|
|
30
|
+
}
|
|
31
|
+
return estimateIsolatedLiquidationPrice({
|
|
32
|
+
entryPrice: params.entryPrice,
|
|
33
|
+
leverage: params.leverage,
|
|
34
|
+
isLong: params.isLong,
|
|
35
|
+
maintenanceMarginRate: market.maintenanceMarginRate,
|
|
36
|
+
})
|
|
37
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
FundingActivity,
|
|
3
|
+
LiquidationActivity,
|
|
4
|
+
MarketDisplay,
|
|
5
|
+
} from '@lifi/perps-types'
|
|
6
|
+
import { ActivityType } from '@lifi/perps-types'
|
|
7
|
+
import { ONDO_PROVIDER_KEY } from '../constants.js'
|
|
8
|
+
import type {
|
|
9
|
+
OndoFundingFeeTransfer,
|
|
10
|
+
OndoLiquidationEvent,
|
|
11
|
+
} from '../types/wire.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Map an Ondo funding-fee transfer to a {@link FundingActivity}. Ondo carries
|
|
15
|
+
* no transfer id on the wire, so a deterministic `funding:<market>:<ISO time>`
|
|
16
|
+
* id is synthesized — funding settles at most once per market per interval,
|
|
17
|
+
* so the pair is unique.
|
|
18
|
+
*
|
|
19
|
+
* @param market - Backend-resolved market identity for `transfer.market`.
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export const mapFundingActivity = (
|
|
23
|
+
transfer: OndoFundingFeeTransfer,
|
|
24
|
+
market: MarketDisplay
|
|
25
|
+
): FundingActivity => {
|
|
26
|
+
const timestamp = new Date(transfer.time).toISOString()
|
|
27
|
+
return {
|
|
28
|
+
id: `funding:${transfer.market}:${timestamp}`,
|
|
29
|
+
provider: ONDO_PROVIDER_KEY,
|
|
30
|
+
timestamp,
|
|
31
|
+
type: ActivityType.FUNDING,
|
|
32
|
+
market,
|
|
33
|
+
amount: transfer.amount,
|
|
34
|
+
positionSize: transfer.positionSize,
|
|
35
|
+
fundingRate: transfer.rate,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Map an Ondo liquidation event to a {@link LiquidationActivity}. Ondo does
|
|
41
|
+
* not report the account value at liquidation time, and its margin accounts
|
|
42
|
+
* are cross-only, so `accountValue` is `'0'` and `leverageType` is `'cross'`.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export const mapLiquidationActivity = (
|
|
47
|
+
event: OndoLiquidationEvent,
|
|
48
|
+
resolveMarket: (market: string) => MarketDisplay
|
|
49
|
+
): LiquidationActivity => ({
|
|
50
|
+
id: event.id,
|
|
51
|
+
provider: ONDO_PROVIDER_KEY,
|
|
52
|
+
timestamp: new Date(event.time).toISOString(),
|
|
53
|
+
type: ActivityType.LIQUIDATION,
|
|
54
|
+
liquidatedNotionalPosition: event.filledQuoteSize ?? '0',
|
|
55
|
+
accountValue: '0',
|
|
56
|
+
leverageType: 'cross',
|
|
57
|
+
liquidatedPositions: (event.triggeringPositions ?? []).map((p) => ({
|
|
58
|
+
market: resolveMarket(p.market),
|
|
59
|
+
size: p.netQuantity,
|
|
60
|
+
})),
|
|
61
|
+
})
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Fill, MarketDisplay } from '@lifi/perps-types'
|
|
2
|
+
import {
|
|
3
|
+
FillClassification,
|
|
4
|
+
FillStatus,
|
|
5
|
+
LiquidityRole,
|
|
6
|
+
OrderSide,
|
|
7
|
+
} from '@lifi/perps-types'
|
|
8
|
+
import Big from 'big.js'
|
|
9
|
+
import type { OndoFill, OndoFillDirection } from '../types/wire.js'
|
|
10
|
+
|
|
11
|
+
const DIRECTION_CLASSIFICATIONS: Record<OndoFillDirection, FillClassification> =
|
|
12
|
+
{
|
|
13
|
+
openLong: FillClassification.OPENED_LONG,
|
|
14
|
+
openShort: FillClassification.OPENED_SHORT,
|
|
15
|
+
closeLong: FillClassification.CLOSED_LONG,
|
|
16
|
+
closeShort: FillClassification.CLOSED_SHORT,
|
|
17
|
+
flipLongToShort: FillClassification.SWITCHED_SHORT,
|
|
18
|
+
flipShortToLong: FillClassification.SWITCHED_LONG,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Map a raw Ondo fill to the generic {@link Fill}. The fee is netted against
|
|
23
|
+
* Ondo's `feeRebate`; when the wire `direction` is absent the classification
|
|
24
|
+
* falls back to the fill side.
|
|
25
|
+
*
|
|
26
|
+
* @param market - Backend-resolved market identity for `fill.market`.
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export const mapFill = (fill: OndoFill, market: MarketDisplay): Fill => ({
|
|
30
|
+
id: fill.id,
|
|
31
|
+
orderId: fill.orderId,
|
|
32
|
+
market,
|
|
33
|
+
side: fill.side === 'buy' ? OrderSide.BUY : OrderSide.SELL,
|
|
34
|
+
size: fill.size,
|
|
35
|
+
price: fill.price,
|
|
36
|
+
status: FillStatus.FILLED,
|
|
37
|
+
liquidity: fill.isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
|
|
38
|
+
fee: new Big(fill.fee).minus(fill.feeRebate ?? '0').toFixed(),
|
|
39
|
+
realizedPnl: fill.pnl,
|
|
40
|
+
classification:
|
|
41
|
+
fill.direction !== undefined
|
|
42
|
+
? DIRECTION_CLASSIFICATIONS[fill.direction]
|
|
43
|
+
: fill.side === 'buy'
|
|
44
|
+
? FillClassification.OPENED_LONG
|
|
45
|
+
: FillClassification.OPENED_SHORT,
|
|
46
|
+
createdAt: new Date(fill.time).toISOString(),
|
|
47
|
+
})
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MarketDisplay,
|
|
3
|
+
OpenOrder,
|
|
4
|
+
Order,
|
|
5
|
+
TriggerOrder,
|
|
6
|
+
} from '@lifi/perps-types'
|
|
7
|
+
import {
|
|
8
|
+
OrderSide,
|
|
9
|
+
OrderStatus,
|
|
10
|
+
OrderType,
|
|
11
|
+
TimeInForce,
|
|
12
|
+
} from '@lifi/perps-types'
|
|
13
|
+
import Big from 'big.js'
|
|
14
|
+
import type {
|
|
15
|
+
OndoOrder,
|
|
16
|
+
OndoOrderStatus,
|
|
17
|
+
OndoOrderType,
|
|
18
|
+
} from '../types/wire.js'
|
|
19
|
+
|
|
20
|
+
const toIso = (time: string): string => new Date(time).toISOString()
|
|
21
|
+
|
|
22
|
+
const mapSide = (side: OndoOrder['side']): OrderSide =>
|
|
23
|
+
side === 'buy' ? OrderSide.BUY : OrderSide.SELL
|
|
24
|
+
|
|
25
|
+
/** @public */
|
|
26
|
+
export const mapOrderType = (type: OndoOrderType): OrderType => {
|
|
27
|
+
switch (type) {
|
|
28
|
+
case 'limit':
|
|
29
|
+
return OrderType.LIMIT
|
|
30
|
+
case 'market':
|
|
31
|
+
return OrderType.MARKET
|
|
32
|
+
case 'stopMarket':
|
|
33
|
+
return OrderType.STOP_MARKET
|
|
34
|
+
case 'takeProfitMarket':
|
|
35
|
+
return OrderType.TAKE_PROFIT_MARKET
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Map Ondo's order status onto the generic enum. `untriggered` stop orders
|
|
41
|
+
* are active resting orders from the trader's point of view, so they map to
|
|
42
|
+
* OPEN.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export const mapOrderStatus = (status: OndoOrderStatus): OrderStatus => {
|
|
46
|
+
switch (status) {
|
|
47
|
+
case 'open':
|
|
48
|
+
case 'untriggered':
|
|
49
|
+
return OrderStatus.OPEN
|
|
50
|
+
case 'pending':
|
|
51
|
+
return OrderStatus.PENDING
|
|
52
|
+
case 'fullyfilled':
|
|
53
|
+
return OrderStatus.FILLED
|
|
54
|
+
case 'canceled':
|
|
55
|
+
return OrderStatus.CANCELLED
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const CANCEL_REASON_SENTENCES: Record<string, string> = {
|
|
60
|
+
liquidation: 'Order cancelled: position was liquidated.',
|
|
61
|
+
selfMatchPrevention:
|
|
62
|
+
'Order cancelled: would self-match against your own resting order.',
|
|
63
|
+
immediateOrCancel: 'Order cancelled: immediate-or-cancel remainder.',
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Plain-English `statusReason` for a cancelled order; `undefined` for every
|
|
68
|
+
* other status. Unknown wire reasons fall back to the generic sentence rather
|
|
69
|
+
* than leaking raw enum values into the UI.
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
export const mapStatusReason = (order: OndoOrder): string | undefined => {
|
|
73
|
+
if (order.status !== 'canceled') {
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
return CANCEL_REASON_SENTENCES[order.cancelReason ?? ''] ?? 'Order cancelled.'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Whether an order rests on a trigger. Checks `stopOrderType` and
|
|
81
|
+
* `triggerPrice` besides the type so a lagging `type` field cannot
|
|
82
|
+
* misclassify a trigger as a plain order.
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
export const isTriggerOrder = (order: OndoOrder): boolean =>
|
|
86
|
+
order.type === 'stopMarket' ||
|
|
87
|
+
order.type === 'takeProfitMarket' ||
|
|
88
|
+
order.stopOrderType !== undefined ||
|
|
89
|
+
order.triggerPrice !== undefined
|
|
90
|
+
|
|
91
|
+
/** Map an active non-trigger Ondo order to an {@link OpenOrder}. @public */
|
|
92
|
+
export const mapOrder = (
|
|
93
|
+
order: OndoOrder,
|
|
94
|
+
market: MarketDisplay
|
|
95
|
+
): OpenOrder => ({
|
|
96
|
+
orderId: order.orderId,
|
|
97
|
+
market,
|
|
98
|
+
side: mapSide(order.side),
|
|
99
|
+
type: mapOrderType(order.type),
|
|
100
|
+
size: order.size,
|
|
101
|
+
price: order.price,
|
|
102
|
+
filledSize: order.filledSize,
|
|
103
|
+
reduceOnly: order.reduceOnly ?? false,
|
|
104
|
+
createdAt: toIso(order.createdAt),
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
/** Map an active trigger Ondo order to a {@link TriggerOrder}. @public */
|
|
108
|
+
export const mapTriggerOrder = (
|
|
109
|
+
order: OndoOrder,
|
|
110
|
+
market: MarketDisplay
|
|
111
|
+
): TriggerOrder => ({
|
|
112
|
+
orderId: order.orderId,
|
|
113
|
+
market,
|
|
114
|
+
type: mapOrderType(order.type),
|
|
115
|
+
size: order.size,
|
|
116
|
+
triggerPrice: order.triggerPrice ?? '0',
|
|
117
|
+
createdAt: toIso(order.createdAt),
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const TERMINAL_STATUSES: ReadonlySet<OndoOrderStatus> = new Set([
|
|
121
|
+
'canceled',
|
|
122
|
+
'fullyfilled',
|
|
123
|
+
])
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Bucket a venue order list into active open/trigger orders (mapped) and
|
|
127
|
+
* terminal order ids. Orders whose market the resolver does not know are
|
|
128
|
+
* skipped.
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export const classifyAndMapOrders = (
|
|
132
|
+
orders: OndoOrder[],
|
|
133
|
+
resolveMarket: (market: string) => MarketDisplay | undefined
|
|
134
|
+
): {
|
|
135
|
+
openOrders: OpenOrder[]
|
|
136
|
+
triggerOrders: TriggerOrder[]
|
|
137
|
+
terminated: string[]
|
|
138
|
+
} => {
|
|
139
|
+
const openOrders: OpenOrder[] = []
|
|
140
|
+
const triggerOrders: TriggerOrder[] = []
|
|
141
|
+
const terminated: string[] = []
|
|
142
|
+
for (const order of orders) {
|
|
143
|
+
if (TERMINAL_STATUSES.has(order.status)) {
|
|
144
|
+
terminated.push(order.orderId)
|
|
145
|
+
continue
|
|
146
|
+
}
|
|
147
|
+
const market = resolveMarket(order.market)
|
|
148
|
+
if (market === undefined) {
|
|
149
|
+
continue
|
|
150
|
+
}
|
|
151
|
+
if (isTriggerOrder(order)) {
|
|
152
|
+
triggerOrders.push(mapTriggerOrder(order, market))
|
|
153
|
+
} else {
|
|
154
|
+
openOrders.push(mapOrder(order, market))
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return { openOrders, triggerOrders, terminated }
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Map a single venue order onto the rich {@link Order} detail shape.
|
|
162
|
+
* `remainingSize` and `averagePrice` are derived (`size − filledSize`,
|
|
163
|
+
* `filledCost ÷ filledSize`); `updatedAt` is the latest transition timestamp
|
|
164
|
+
* Ondo exposes, falling back to `createdAt`.
|
|
165
|
+
* @public
|
|
166
|
+
*/
|
|
167
|
+
export const mapOrderDetail = (
|
|
168
|
+
order: OndoOrder,
|
|
169
|
+
market: MarketDisplay
|
|
170
|
+
): Order => {
|
|
171
|
+
const filled = new Big(order.filledSize)
|
|
172
|
+
const trigger = isTriggerOrder(order)
|
|
173
|
+
return {
|
|
174
|
+
orderId: order.orderId,
|
|
175
|
+
market,
|
|
176
|
+
side: mapSide(order.side),
|
|
177
|
+
type: mapOrderType(order.type),
|
|
178
|
+
price: order.price,
|
|
179
|
+
originalSize: order.size,
|
|
180
|
+
remainingSize: new Big(order.size).minus(filled).toFixed(),
|
|
181
|
+
filledSize: order.filledSize,
|
|
182
|
+
timeInForce:
|
|
183
|
+
order.timeInForce === undefined
|
|
184
|
+
? undefined
|
|
185
|
+
: TimeInForce[order.timeInForce],
|
|
186
|
+
reduceOnly: order.reduceOnly ?? false,
|
|
187
|
+
isTrigger: trigger,
|
|
188
|
+
...(trigger && order.triggerPrice !== undefined
|
|
189
|
+
? { triggerPrice: order.triggerPrice }
|
|
190
|
+
: {}),
|
|
191
|
+
status: mapOrderStatus(order.status),
|
|
192
|
+
...(mapStatusReason(order) !== undefined
|
|
193
|
+
? { statusReason: mapStatusReason(order) }
|
|
194
|
+
: {}),
|
|
195
|
+
...(filled.gt(0)
|
|
196
|
+
? { averagePrice: new Big(order.filledCost).div(filled).toFixed() }
|
|
197
|
+
: {}),
|
|
198
|
+
createdAt: toIso(order.createdAt),
|
|
199
|
+
updatedAt: toIso(order.canceledAt ?? order.filledAt ?? order.createdAt),
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { MarketDisplay, Position } from '@lifi/perps-types'
|
|
2
|
+
import { MarginMode, PositionSide } from '@lifi/perps-types'
|
|
3
|
+
import Big from 'big.js'
|
|
4
|
+
import type { OndoPosition } from '../types/wire.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Map a raw Ondo position to the generic Position type. Ondo margin accounts
|
|
8
|
+
* are cross-margined only.
|
|
9
|
+
*
|
|
10
|
+
* @param market - Backend-resolved market identity for `pos.market`.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export const mapPosition = (
|
|
14
|
+
pos: OndoPosition,
|
|
15
|
+
market: MarketDisplay
|
|
16
|
+
): Position => ({
|
|
17
|
+
market,
|
|
18
|
+
side: pos.direction === 'short' ? PositionSide.SHORT : PositionSide.LONG,
|
|
19
|
+
size: new Big(pos.netQuantity).abs().toFixed(),
|
|
20
|
+
entryPrice: pos.averageEntryPrice,
|
|
21
|
+
markPrice: pos.markPrice,
|
|
22
|
+
liquidationPrice: pos.liquidationPrice,
|
|
23
|
+
unrealizedPnl: pos.unrealizedPnl,
|
|
24
|
+
leverage: Number.parseFloat(pos.leverage),
|
|
25
|
+
marginUsed: pos.usedMargin,
|
|
26
|
+
marginMode: MarginMode.CROSS,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Map raw Ondo positions to open {@link Position}s, dropping neutral and
|
|
31
|
+
* zero-quantity rows. Only valid for payloads carrying the full position
|
|
32
|
+
* set — dropping zeros from a partial frame would make closes unobservable.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export const mapOpenPositions = (
|
|
37
|
+
positions: OndoPosition[],
|
|
38
|
+
resolveMarket: (market: string) => MarketDisplay
|
|
39
|
+
): Position[] =>
|
|
40
|
+
positions
|
|
41
|
+
.filter(
|
|
42
|
+
(p) => p.direction !== 'neutral' && Number.parseFloat(p.netQuantity) !== 0
|
|
43
|
+
)
|
|
44
|
+
.map((p) => mapPosition(p, resolveMarket(p.market)))
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
2
|
+
import type { OhlcvInterval } from '@lifi/perps-types'
|
|
3
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Map our `OhlcvInterval` literal to Ondo's kline `resolution` enum.
|
|
7
|
+
*
|
|
8
|
+
* Ondo exposes only the timeframes listed below. SDK intervals without a
|
|
9
|
+
* direct match (3m, 2h, 8h, 12h, 3d) raise a validation error rather than
|
|
10
|
+
* silently rounding — the caller picks a supported timeframe.
|
|
11
|
+
*/
|
|
12
|
+
const ONDO_SUPPORTED_INTERVALS: Record<string, string> = {
|
|
13
|
+
'1m': '1',
|
|
14
|
+
'5m': '5',
|
|
15
|
+
'15m': '15',
|
|
16
|
+
'30m': '30',
|
|
17
|
+
'1h': '1H',
|
|
18
|
+
'4h': '4H',
|
|
19
|
+
'1d': '1D',
|
|
20
|
+
'1w': '1W',
|
|
21
|
+
'1M': '1M',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const INTERVAL_SECONDS: Record<string, OhlcvInterval> = {
|
|
25
|
+
60: '1m',
|
|
26
|
+
300: '5m',
|
|
27
|
+
900: '15m',
|
|
28
|
+
1800: '30m',
|
|
29
|
+
3600: '1h',
|
|
30
|
+
14400: '4h',
|
|
31
|
+
86400: '1d',
|
|
32
|
+
604800: '1w',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const MONTH_MIN_SECS = 28 * 86400
|
|
36
|
+
const MONTH_MAX_SECS = 31 * 86400
|
|
37
|
+
|
|
38
|
+
/** @public */
|
|
39
|
+
export const mapInterval = (interval: string): string => {
|
|
40
|
+
const resolution = ONDO_SUPPORTED_INTERVALS[interval]
|
|
41
|
+
if (!resolution) {
|
|
42
|
+
throw new PerpsError(
|
|
43
|
+
PerpsErrorCode.ValidationError,
|
|
44
|
+
`Ondo does not support OHLCV interval '${interval}'. ` +
|
|
45
|
+
`Supported: ${Object.keys(ONDO_SUPPORTED_INTERVALS).join(', ')}.`
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
return resolution
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Recover the SDK interval from a kline frame's bar span in seconds. Ondo's
|
|
53
|
+
* kline updates carry no resolution field — only the interval start/end —
|
|
54
|
+
* so the span is the only way to route a frame to its subscription.
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export const intervalFromBarSpan = (
|
|
58
|
+
spanSecs: number
|
|
59
|
+
): OhlcvInterval | undefined => {
|
|
60
|
+
const fixed = INTERVAL_SECONDS[spanSecs]
|
|
61
|
+
if (fixed !== undefined) {
|
|
62
|
+
return fixed
|
|
63
|
+
}
|
|
64
|
+
// Monthly bars span a calendar month, so their second-count varies by month.
|
|
65
|
+
if (spanSecs >= MONTH_MIN_SECS && spanSecs <= MONTH_MAX_SECS) {
|
|
66
|
+
return '1M'
|
|
67
|
+
}
|
|
68
|
+
return undefined
|
|
69
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Asset } from '@lifi/perps-types'
|
|
2
|
+
import { ONDO_PROVIDER_KEY } from '../constants.js'
|
|
3
|
+
|
|
4
|
+
/** @public */
|
|
5
|
+
export const ondoAsset = (id: string, displaySymbol: string): Asset => ({
|
|
6
|
+
providerId: ONDO_PROVIDER_KEY,
|
|
7
|
+
id,
|
|
8
|
+
displaySymbol,
|
|
9
|
+
logoURI: '',
|
|
10
|
+
})
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ondo order size and price formatting for exchange submission.
|
|
3
|
+
*
|
|
4
|
+
* Ondo's tick and lot grids are exact contract increments (`quoteIncrement` /
|
|
5
|
+
* `baseIncrement`) that need not be powers of ten. When the generic
|
|
6
|
+
* {@link Market} carries the raw increment (`priceIncrement` / `sizeIncrement`)
|
|
7
|
+
* these helpers snap onto that grid; otherwise they fall back to the
|
|
8
|
+
* power-of-ten grid implied by `priceDecimals` / `szDecimals`. Prices round
|
|
9
|
+
* half-up to the nearest tick; sizes truncate toward zero to the lot.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { PerpsError } from '@lifi/perps-sdk'
|
|
13
|
+
import { type Market, PerpsErrorCode } from '@lifi/perps-types'
|
|
14
|
+
import Big from 'big.js'
|
|
15
|
+
|
|
16
|
+
const powerOfTenIncrement = (decimals: number): Big => new Big(`1e-${decimals}`)
|
|
17
|
+
|
|
18
|
+
const priceGrid = (market: Market): Big => {
|
|
19
|
+
if (market.priceIncrement !== undefined) {
|
|
20
|
+
return new Big(market.priceIncrement)
|
|
21
|
+
}
|
|
22
|
+
if (market.priceDecimals !== undefined) {
|
|
23
|
+
return powerOfTenIncrement(market.priceDecimals)
|
|
24
|
+
}
|
|
25
|
+
throw new PerpsError(
|
|
26
|
+
PerpsErrorCode.ValidationError,
|
|
27
|
+
`Market '${market.id}' carries no price grid; Ondo order prices cannot ` +
|
|
28
|
+
`be formatted without the market's tick increment.`
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Format a price onto an Ondo market's tick grid: snapped half-up to the
|
|
34
|
+
* nearest `priceIncrement` (or the grid implied by `priceDecimals`), trailing
|
|
35
|
+
* zeros stripped.
|
|
36
|
+
*
|
|
37
|
+
* @throws {PerpsError} `ValidationError` when the market carries neither
|
|
38
|
+
* `priceIncrement` nor `priceDecimals` — without the venue's tick grid no
|
|
39
|
+
* correct price can be produced.
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
export function formatOrderPrice(market: Market, price: number): string {
|
|
43
|
+
const increment = priceGrid(market)
|
|
44
|
+
const snapped = new Big(price)
|
|
45
|
+
.div(increment)
|
|
46
|
+
.round(0, Big.roundHalfUp)
|
|
47
|
+
.times(increment)
|
|
48
|
+
return snapped.eq(0) ? '0' : snapped.toFixed()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Format a size onto an Ondo market's lot grid: truncated toward zero (never
|
|
53
|
+
* rounded up, so the size cannot exceed the user's balance) to the market's
|
|
54
|
+
* `sizeIncrement` (or the grid implied by `szDecimals`), trailing zeros
|
|
55
|
+
* stripped.
|
|
56
|
+
*
|
|
57
|
+
* @param size - Size in base-asset units as a non-negative magnitude.
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export function formatOrderSize(market: Market, size: number): string {
|
|
61
|
+
const increment =
|
|
62
|
+
market.sizeIncrement !== undefined
|
|
63
|
+
? new Big(market.sizeIncrement)
|
|
64
|
+
: powerOfTenIncrement(market.szDecimals)
|
|
65
|
+
const snapped = new Big(size)
|
|
66
|
+
.div(increment)
|
|
67
|
+
.round(0, Big.roundDown)
|
|
68
|
+
.times(increment)
|
|
69
|
+
return snapped.eq(0) ? '0' : snapped.toFixed()
|
|
70
|
+
}
|