@lifi/perps-sdk-provider-lighter 35.0.0 → 36.0.0
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/dist/cjs/LighterProvider.d.ts.map +1 -1
- package/dist/cjs/LighterProvider.js +101 -58
- package/dist/cjs/LighterProvider.js.map +1 -1
- package/dist/cjs/accountSummary.d.ts +1 -2
- package/dist/cjs/accountSummary.d.ts.map +1 -1
- package/dist/cjs/accountSummary.js +9 -16
- package/dist/cjs/accountSummary.js.map +1 -1
- package/dist/cjs/availableToTrade.d.ts +1 -2
- package/dist/cjs/availableToTrade.d.ts.map +1 -1
- package/dist/cjs/availableToTrade.js +8 -12
- package/dist/cjs/availableToTrade.js.map +1 -1
- package/dist/cjs/constants.d.ts +1 -0
- package/dist/cjs/constants.d.ts.map +1 -1
- package/dist/cjs/constants.js +2 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/signers/LighterSigner.d.ts.map +1 -1
- package/dist/cjs/signers/LighterSigner.js +2 -6
- package/dist/cjs/signers/LighterSigner.js.map +1 -1
- package/dist/cjs/types/submit.d.ts +5 -0
- package/dist/cjs/types/submit.d.ts.map +1 -1
- package/dist/cjs/utils/index.d.ts +3 -3
- package/dist/cjs/utils/index.d.ts.map +1 -1
- package/dist/cjs/utils/index.js +5 -6
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/cjs/utils/mapFill.d.ts +1 -1
- package/dist/cjs/utils/mapFill.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.js +44 -31
- package/dist/cjs/utils/mapFill.js.map +1 -1
- package/dist/cjs/utils/mapOpenPositions.d.ts +3 -1
- package/dist/cjs/utils/mapOpenPositions.d.ts.map +1 -1
- package/dist/cjs/utils/mapOpenPositions.js +20 -4
- package/dist/cjs/utils/mapOpenPositions.js.map +1 -1
- package/dist/cjs/utils/mapOrder.d.ts +1 -1
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.js +64 -26
- package/dist/cjs/utils/mapOrder.js.map +1 -1
- package/dist/cjs/utils/mapPortfolioHistory.d.ts +1 -2
- package/dist/cjs/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/cjs/utils/mapPortfolioHistory.js +29 -21
- package/dist/cjs/utils/mapPortfolioHistory.js.map +1 -1
- package/dist/cjs/utils/mapPosition.d.ts +3 -3
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
- package/dist/cjs/utils/mapPosition.js +35 -35
- package/dist/cjs/utils/mapPosition.js.map +1 -1
- package/dist/cjs/utils/rowTimestamp.d.ts +2 -0
- package/dist/cjs/utils/rowTimestamp.d.ts.map +1 -0
- package/dist/cjs/utils/rowTimestamp.js +14 -0
- package/dist/cjs/utils/rowTimestamp.js.map +1 -0
- package/dist/cjs/utils/settlementPool.d.ts +2 -3
- package/dist/cjs/utils/settlementPool.d.ts.map +1 -1
- package/dist/cjs/utils/settlementPool.js +8 -7
- package/dist/cjs/utils/settlementPool.js.map +1 -1
- package/dist/cjs/utils/spotPrice.d.ts +3 -4
- package/dist/cjs/utils/spotPrice.d.ts.map +1 -1
- package/dist/cjs/utils/spotPrice.js +6 -11
- package/dist/cjs/utils/spotPrice.js.map +1 -1
- package/dist/cjs/utils/time.d.ts.map +1 -1
- package/dist/cjs/utils/time.js +3 -2
- package/dist/cjs/utils/time.js.map +1 -1
- package/dist/cjs/utils/transferMargin.d.ts.map +1 -1
- package/dist/cjs/utils/transferMargin.js +7 -15
- package/dist/cjs/utils/transferMargin.js.map +1 -1
- package/dist/cjs/utils/withdrawableBalances.d.ts +1 -1
- package/dist/cjs/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/cjs/utils/withdrawableBalances.js +12 -17
- package/dist/cjs/utils/withdrawableBalances.js.map +1 -1
- package/dist/cjs/utils/withdrawalTypes.d.ts +17 -0
- package/dist/cjs/utils/withdrawalTypes.d.ts.map +1 -0
- package/dist/cjs/utils/withdrawalTypes.js +58 -0
- package/dist/cjs/utils/withdrawalTypes.js.map +1 -0
- package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.js +46 -58
- package/dist/cjs/websocket/LighterWsProvider.js.map +1 -1
- package/dist/cjs/websocket/orderBookSide.d.ts +19 -0
- package/dist/cjs/websocket/orderBookSide.d.ts.map +1 -0
- package/dist/cjs/websocket/orderBookSide.js +71 -0
- package/dist/cjs/websocket/orderBookSide.js.map +1 -0
- package/dist/esm/LighterProvider.d.ts.map +1 -1
- package/dist/esm/LighterProvider.js +116 -62
- package/dist/esm/LighterProvider.js.map +1 -1
- package/dist/esm/accountSummary.d.ts +1 -2
- package/dist/esm/accountSummary.d.ts.map +1 -1
- package/dist/esm/accountSummary.js +10 -14
- package/dist/esm/accountSummary.js.map +1 -1
- package/dist/esm/availableToTrade.d.ts +1 -2
- package/dist/esm/availableToTrade.d.ts.map +1 -1
- package/dist/esm/availableToTrade.js +9 -10
- package/dist/esm/availableToTrade.js.map +1 -1
- package/dist/esm/constants.d.ts +8 -0
- package/dist/esm/constants.d.ts.map +1 -1
- package/dist/esm/constants.js +8 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/signers/LighterSigner.d.ts.map +1 -1
- package/dist/esm/signers/LighterSigner.js +3 -4
- package/dist/esm/signers/LighterSigner.js.map +1 -1
- package/dist/esm/types/submit.d.ts +14 -0
- package/dist/esm/types/submit.d.ts.map +1 -1
- package/dist/esm/utils/index.d.ts +3 -3
- package/dist/esm/utils/index.d.ts.map +1 -1
- package/dist/esm/utils/index.js +2 -3
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/mapFill.d.ts +1 -1
- package/dist/esm/utils/mapFill.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.js +51 -35
- package/dist/esm/utils/mapFill.js.map +1 -1
- package/dist/esm/utils/mapOpenPositions.d.ts +17 -3
- package/dist/esm/utils/mapOpenPositions.d.ts.map +1 -1
- package/dist/esm/utils/mapOpenPositions.js +31 -5
- package/dist/esm/utils/mapOpenPositions.js.map +1 -1
- package/dist/esm/utils/mapOrder.d.ts +6 -2
- package/dist/esm/utils/mapOrder.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.js +70 -25
- package/dist/esm/utils/mapOrder.js.map +1 -1
- package/dist/esm/utils/mapPortfolioHistory.d.ts +6 -3
- package/dist/esm/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/esm/utils/mapPortfolioHistory.js +34 -19
- package/dist/esm/utils/mapPortfolioHistory.js.map +1 -1
- package/dist/esm/utils/mapPosition.d.ts +12 -8
- package/dist/esm/utils/mapPosition.d.ts.map +1 -1
- package/dist/esm/utils/mapPosition.js +45 -38
- package/dist/esm/utils/mapPosition.js.map +1 -1
- package/dist/esm/utils/rowTimestamp.d.ts +6 -0
- package/dist/esm/utils/rowTimestamp.d.ts.map +1 -0
- package/dist/esm/utils/rowTimestamp.js +14 -0
- package/dist/esm/utils/rowTimestamp.js.map +1 -0
- package/dist/esm/utils/settlementPool.d.ts +2 -3
- package/dist/esm/utils/settlementPool.d.ts.map +1 -1
- package/dist/esm/utils/settlementPool.js +8 -7
- package/dist/esm/utils/settlementPool.js.map +1 -1
- package/dist/esm/utils/spotPrice.d.ts +3 -4
- package/dist/esm/utils/spotPrice.d.ts.map +1 -1
- package/dist/esm/utils/spotPrice.js +6 -8
- package/dist/esm/utils/spotPrice.js.map +1 -1
- package/dist/esm/utils/time.d.ts +10 -2
- package/dist/esm/utils/time.d.ts.map +1 -1
- package/dist/esm/utils/time.js +13 -4
- package/dist/esm/utils/time.js.map +1 -1
- package/dist/esm/utils/transferMargin.d.ts.map +1 -1
- package/dist/esm/utils/transferMargin.js +8 -13
- package/dist/esm/utils/transferMargin.js.map +1 -1
- package/dist/esm/utils/withdrawableBalances.d.ts +5 -3
- package/dist/esm/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/esm/utils/withdrawableBalances.js +17 -17
- package/dist/esm/utils/withdrawableBalances.js.map +1 -1
- package/dist/esm/utils/withdrawalTypes.d.ts +45 -0
- package/dist/esm/utils/withdrawalTypes.d.ts.map +1 -0
- package/dist/esm/utils/withdrawalTypes.js +68 -0
- package/dist/esm/utils/withdrawalTypes.js.map +1 -0
- package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.js +48 -57
- package/dist/esm/websocket/LighterWsProvider.js.map +1 -1
- package/dist/esm/websocket/orderBookSide.d.ts +33 -0
- package/dist/esm/websocket/orderBookSide.d.ts.map +1 -0
- package/dist/esm/websocket/orderBookSide.js +76 -0
- package/dist/esm/websocket/orderBookSide.js.map +1 -0
- package/dist/types/LighterProvider.d.ts.map +1 -1
- package/dist/types/accountSummary.d.ts +1 -2
- package/dist/types/accountSummary.d.ts.map +1 -1
- package/dist/types/availableToTrade.d.ts +1 -2
- package/dist/types/availableToTrade.d.ts.map +1 -1
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/signers/LighterSigner.d.ts.map +1 -1
- package/dist/types/types/submit.d.ts +14 -0
- package/dist/types/types/submit.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +3 -3
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/mapFill.d.ts +1 -1
- package/dist/types/utils/mapFill.d.ts.map +1 -1
- package/dist/types/utils/mapOpenPositions.d.ts +17 -3
- package/dist/types/utils/mapOpenPositions.d.ts.map +1 -1
- package/dist/types/utils/mapOrder.d.ts +6 -2
- package/dist/types/utils/mapOrder.d.ts.map +1 -1
- package/dist/types/utils/mapPortfolioHistory.d.ts +6 -3
- package/dist/types/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/types/utils/mapPosition.d.ts +12 -8
- package/dist/types/utils/mapPosition.d.ts.map +1 -1
- package/dist/types/utils/rowTimestamp.d.ts +6 -0
- package/dist/types/utils/rowTimestamp.d.ts.map +1 -0
- package/dist/types/utils/settlementPool.d.ts +2 -3
- package/dist/types/utils/settlementPool.d.ts.map +1 -1
- package/dist/types/utils/spotPrice.d.ts +3 -4
- package/dist/types/utils/spotPrice.d.ts.map +1 -1
- package/dist/types/utils/time.d.ts +10 -2
- package/dist/types/utils/time.d.ts.map +1 -1
- package/dist/types/utils/transferMargin.d.ts.map +1 -1
- package/dist/types/utils/withdrawableBalances.d.ts +5 -3
- package/dist/types/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/types/utils/withdrawalTypes.d.ts +45 -0
- package/dist/types/utils/withdrawalTypes.d.ts.map +1 -0
- package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/types/websocket/orderBookSide.d.ts +33 -0
- package/dist/types/websocket/orderBookSide.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/LighterProvider.ts +236 -100
- package/src/accountSummary.ts +41 -22
- package/src/availableToTrade.ts +38 -15
- package/src/constants.ts +9 -0
- package/src/index.ts +1 -0
- package/src/signers/LighterSigner.ts +11 -4
- package/src/types/submit.ts +15 -0
- package/src/utils/index.ts +9 -3
- package/src/utils/mapFill.ts +82 -43
- package/src/utils/mapOpenPositions.ts +45 -6
- package/src/utils/mapOrder.ts +99 -28
- package/src/utils/mapPortfolioHistory.ts +78 -24
- package/src/utils/mapPosition.ts +67 -44
- package/src/utils/rowTimestamp.ts +15 -0
- package/src/utils/settlementPool.ts +36 -12
- package/src/utils/spotPrice.ts +18 -12
- package/src/utils/time.ts +14 -4
- package/src/utils/transferMargin.ts +28 -17
- package/src/utils/withdrawableBalances.ts +34 -20
- package/src/utils/withdrawalTypes.ts +125 -0
- package/src/websocket/LighterWsProvider.ts +75 -92
- package/src/websocket/orderBookSide.ts +106 -0
- package/dist/cjs/utils/decimal.d.ts +0 -5
- package/dist/cjs/utils/decimal.d.ts.map +0 -1
- package/dist/cjs/utils/decimal.js +0 -38
- package/dist/cjs/utils/decimal.js.map +0 -1
- package/dist/cjs/utils/liquidation.d.ts +0 -4
- package/dist/cjs/utils/liquidation.d.ts.map +0 -1
- package/dist/cjs/utils/liquidation.js +0 -16
- package/dist/cjs/utils/liquidation.js.map +0 -1
- package/dist/esm/utils/decimal.d.ts +0 -15
- package/dist/esm/utils/decimal.d.ts.map +0 -1
- package/dist/esm/utils/decimal.js +0 -39
- package/dist/esm/utils/decimal.js.map +0 -1
- package/dist/esm/utils/liquidation.d.ts +0 -22
- package/dist/esm/utils/liquidation.d.ts.map +0 -1
- package/dist/esm/utils/liquidation.js +0 -31
- package/dist/esm/utils/liquidation.js.map +0 -1
- package/dist/types/utils/decimal.d.ts +0 -15
- package/dist/types/utils/decimal.d.ts.map +0 -1
- package/dist/types/utils/liquidation.d.ts +0 -22
- package/dist/types/utils/liquidation.d.ts.map +0 -1
- package/src/utils/decimal.ts +0 -52
- package/src/utils/liquidation.ts +0 -39
package/src/utils/mapOrder.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isActiveOrderStatus,
|
|
3
|
+
isDecimalStringGreaterThan,
|
|
3
4
|
PerpsError,
|
|
5
|
+
safeDivideDecimalString,
|
|
6
|
+
safeTimestampToIsoString,
|
|
4
7
|
triggerConditionFor,
|
|
8
|
+
unknownToDecimalString,
|
|
9
|
+
warnSkippedVenueRow,
|
|
5
10
|
} from '@lifi/perps-sdk'
|
|
6
11
|
import type { MarketDisplay, Order, OrderBase } from '@lifi/perps-types'
|
|
7
12
|
import {
|
|
@@ -11,8 +16,9 @@ import {
|
|
|
11
16
|
PerpsErrorCode,
|
|
12
17
|
TimeInForce,
|
|
13
18
|
} from '@lifi/perps-types'
|
|
14
|
-
import
|
|
19
|
+
import { LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
15
20
|
import type { LtOrder } from '../types/index.js'
|
|
21
|
+
import { rowTimestampToIsoStringOrUndefined } from './rowTimestamp.js'
|
|
16
22
|
|
|
17
23
|
const mapOrderType = (type: string): Order['type'] => {
|
|
18
24
|
switch (type.replace(/-/g, '_')) {
|
|
@@ -56,10 +62,20 @@ const mapTimeInForce = (tif: string): TimeInForce => {
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
const venueDecimal = (value: unknown, field: string): string | undefined => {
|
|
66
|
+
try {
|
|
67
|
+
return unknownToDecimalString(value, field, LIGHTER_PROVIDER_KEY)
|
|
68
|
+
} catch {
|
|
69
|
+
return undefined
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const hasFill = (order: LtOrder): boolean => {
|
|
74
|
+
const filled = venueDecimal(order.filled_base_amount, 'filled_base_amount')
|
|
75
|
+
return filled !== undefined && isDecimalStringGreaterThan(filled, '0')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const mapOrderStatus = (order: LtOrder): OrderStatus => {
|
|
63
79
|
switch (order.status) {
|
|
64
80
|
case 'in-progress':
|
|
65
81
|
return OrderStatus.ACCEPTED
|
|
@@ -69,7 +85,7 @@ const mapOrderStatus = (
|
|
|
69
85
|
if (order.trigger_status === 'parent-order') {
|
|
70
86
|
return OrderStatus.PENDING
|
|
71
87
|
}
|
|
72
|
-
return
|
|
88
|
+
return hasFill(order) ? OrderStatus.PARTIALLY_FILLED : OrderStatus.OPEN
|
|
73
89
|
case 'triggered':
|
|
74
90
|
return OrderStatus.TRIGGERED
|
|
75
91
|
case 'filled':
|
|
@@ -97,11 +113,72 @@ const mapOrderStatus = (
|
|
|
97
113
|
}
|
|
98
114
|
}
|
|
99
115
|
|
|
100
|
-
|
|
101
|
-
|
|
116
|
+
const skipOrder = (field: string, value: unknown): undefined => {
|
|
117
|
+
warnSkippedVenueRow(LIGHTER_PROVIDER_KEY, 'order', field, value)
|
|
118
|
+
return undefined
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const orderSizeOrSkip = (
|
|
122
|
+
field: 'initial_base_amount' | 'remaining_base_amount' | 'filled_base_amount',
|
|
123
|
+
value: string
|
|
124
|
+
): string | undefined =>
|
|
125
|
+
venueDecimal(value, field) === undefined ? skipOrder(field, value) : value
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Map a Lighter order with its venue identity, lifecycle, and execution fields.
|
|
129
|
+
* A row with an invalid size or time gives `undefined`. An invalid limit price or
|
|
130
|
+
* filled quote amount omits that field.
|
|
131
|
+
*/
|
|
132
|
+
export const mapOrder = (
|
|
133
|
+
order: LtOrder,
|
|
134
|
+
market: MarketDisplay
|
|
135
|
+
): Order | undefined => {
|
|
102
136
|
const type = mapOrderType(order.type)
|
|
103
|
-
const
|
|
104
|
-
|
|
137
|
+
const originalSize = orderSizeOrSkip(
|
|
138
|
+
'initial_base_amount',
|
|
139
|
+
order.initial_base_amount
|
|
140
|
+
)
|
|
141
|
+
if (originalSize === undefined) {
|
|
142
|
+
return undefined
|
|
143
|
+
}
|
|
144
|
+
const remainingSize = orderSizeOrSkip(
|
|
145
|
+
'remaining_base_amount',
|
|
146
|
+
order.remaining_base_amount
|
|
147
|
+
)
|
|
148
|
+
if (remainingSize === undefined) {
|
|
149
|
+
return undefined
|
|
150
|
+
}
|
|
151
|
+
const filledSize = orderSizeOrSkip(
|
|
152
|
+
'filled_base_amount',
|
|
153
|
+
order.filled_base_amount
|
|
154
|
+
)
|
|
155
|
+
if (filledSize === undefined) {
|
|
156
|
+
return undefined
|
|
157
|
+
}
|
|
158
|
+
const createdAt = rowTimestampToIsoStringOrUndefined(order.created_at * 1000)
|
|
159
|
+
if (createdAt === undefined) {
|
|
160
|
+
return skipOrder('created_at', order.created_at)
|
|
161
|
+
}
|
|
162
|
+
const updatedAt = rowTimestampToIsoStringOrUndefined(order.updated_at * 1000)
|
|
163
|
+
if (updatedAt === undefined) {
|
|
164
|
+
return skipOrder('updated_at', order.updated_at)
|
|
165
|
+
}
|
|
166
|
+
const filledQuote = venueDecimal(
|
|
167
|
+
order.filled_quote_amount,
|
|
168
|
+
'filled_quote_amount'
|
|
169
|
+
)
|
|
170
|
+
const filledAmount = venueDecimal(filledSize, 'filled_base_amount')
|
|
171
|
+
const averagePrice =
|
|
172
|
+
filledQuote !== undefined &&
|
|
173
|
+
filledAmount !== undefined &&
|
|
174
|
+
isDecimalStringGreaterThan(filledAmount, '0')
|
|
175
|
+
? safeDivideDecimalString(filledQuote, filledAmount)
|
|
176
|
+
: undefined
|
|
177
|
+
const expiresAt =
|
|
178
|
+
order.order_expiry > 0
|
|
179
|
+
? safeTimestampToIsoString(order.order_expiry)
|
|
180
|
+
: undefined
|
|
181
|
+
const status = mapOrderStatus(order)
|
|
105
182
|
const base: OrderBase = {
|
|
106
183
|
orderId: String(order.order_index),
|
|
107
184
|
...(order.client_order_index === 0
|
|
@@ -111,20 +188,14 @@ export const mapOrder = (order: LtOrder, market: MarketDisplay): Order => {
|
|
|
111
188
|
side: order.is_ask ? OrderSide.SELL : OrderSide.BUY,
|
|
112
189
|
status,
|
|
113
190
|
...(status === OrderStatus.CANCELLED ? { statusReason: order.status } : {}),
|
|
114
|
-
originalSize
|
|
115
|
-
remainingSize
|
|
116
|
-
filledSize
|
|
117
|
-
...(
|
|
118
|
-
? {
|
|
119
|
-
averagePrice: new Big(order.filled_quote_amount)
|
|
120
|
-
.div(filledSize)
|
|
121
|
-
.toFixed(),
|
|
122
|
-
}
|
|
123
|
-
: {}),
|
|
191
|
+
originalSize,
|
|
192
|
+
remainingSize,
|
|
193
|
+
filledSize,
|
|
194
|
+
...(averagePrice === undefined ? {} : { averagePrice }),
|
|
124
195
|
reduceOnly: order.reduce_only,
|
|
125
196
|
...(order.parent_order_id ? { parentOrderId: order.parent_order_id } : {}),
|
|
126
|
-
createdAt
|
|
127
|
-
updatedAt
|
|
197
|
+
createdAt,
|
|
198
|
+
updatedAt,
|
|
128
199
|
}
|
|
129
200
|
switch (type) {
|
|
130
201
|
case OrderType.TWAP:
|
|
@@ -137,17 +208,19 @@ export const mapOrder = (order: LtOrder, market: MarketDisplay): Order => {
|
|
|
137
208
|
case OrderType.STOP_MARKET:
|
|
138
209
|
case OrderType.STOP_LIMIT:
|
|
139
210
|
case OrderType.TAKE_PROFIT_MARKET:
|
|
140
|
-
case OrderType.TAKE_PROFIT_LIMIT:
|
|
211
|
+
case OrderType.TAKE_PROFIT_LIMIT: {
|
|
141
212
|
return {
|
|
142
213
|
...base,
|
|
143
214
|
type,
|
|
144
215
|
triggerPrice: order.trigger_price,
|
|
145
216
|
triggerCondition: triggerConditionFor(type, base.side),
|
|
146
|
-
...(type === OrderType.STOP_LIMIT ||
|
|
147
|
-
|
|
217
|
+
...((type === OrderType.STOP_LIMIT ||
|
|
218
|
+
type === OrderType.TAKE_PROFIT_LIMIT) &&
|
|
219
|
+
venueDecimal(order.price, 'price') !== undefined
|
|
148
220
|
? { limitPrice: order.price }
|
|
149
221
|
: {}),
|
|
150
222
|
}
|
|
223
|
+
}
|
|
151
224
|
case OrderType.MARKET:
|
|
152
225
|
case OrderType.LIMIT:
|
|
153
226
|
return {
|
|
@@ -155,9 +228,7 @@ export const mapOrder = (order: LtOrder, market: MarketDisplay): Order => {
|
|
|
155
228
|
type,
|
|
156
229
|
price: order.price,
|
|
157
230
|
timeInForce: mapTimeInForce(order.time_in_force),
|
|
158
|
-
...(
|
|
159
|
-
? { expiresAt: new Date(order.order_expiry).toISOString() }
|
|
160
|
-
: {}),
|
|
231
|
+
...(expiresAt === undefined ? {} : { expiresAt }),
|
|
161
232
|
}
|
|
162
233
|
}
|
|
163
234
|
}
|
|
@@ -1,33 +1,85 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addDecimalString,
|
|
3
|
+
numberToDecimalString,
|
|
4
|
+
subtractDecimalString,
|
|
5
|
+
warnSkippedVenueRow,
|
|
6
|
+
} from '@lifi/perps-sdk'
|
|
1
7
|
import type {
|
|
2
8
|
PortfolioHistoryRange,
|
|
3
9
|
PortfolioHistoryResponse,
|
|
4
10
|
} from '@lifi/perps-types'
|
|
5
|
-
import
|
|
11
|
+
import { LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
6
12
|
import type { LtPnLEntry } from '../types/pnl.js'
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
const SNAPSHOT_DECIMAL_FIELDS = [
|
|
15
|
+
'trade_pnl',
|
|
16
|
+
'trade_spot_pnl',
|
|
17
|
+
'inflow',
|
|
18
|
+
'outflow',
|
|
19
|
+
'spot_inflow',
|
|
20
|
+
'spot_outflow',
|
|
21
|
+
'volume',
|
|
22
|
+
] as const
|
|
23
|
+
|
|
24
|
+
type SnapshotDecimalField = (typeof SNAPSHOT_DECIMAL_FIELDS)[number]
|
|
25
|
+
|
|
26
|
+
const snapshotDecimal = (
|
|
27
|
+
snapshot: LtPnLEntry,
|
|
28
|
+
field: SnapshotDecimalField
|
|
29
|
+
): string => numberToDecimalString(snapshot[field])
|
|
30
|
+
|
|
31
|
+
function isValidSnapshot(snapshot: LtPnLEntry): boolean {
|
|
32
|
+
const invalid = SNAPSHOT_DECIMAL_FIELDS.find(
|
|
33
|
+
(field) => !Number.isFinite(snapshot[field])
|
|
34
|
+
)
|
|
35
|
+
if (invalid === undefined) {
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
warnSkippedVenueRow(
|
|
39
|
+
LIGHTER_PROVIDER_KEY,
|
|
40
|
+
'portfolio history',
|
|
41
|
+
invalid,
|
|
42
|
+
snapshot[invalid]
|
|
43
|
+
)
|
|
44
|
+
return false
|
|
10
45
|
}
|
|
11
46
|
|
|
12
|
-
function
|
|
13
|
-
return
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
47
|
+
function getCumulativePnl(snapshot: LtPnLEntry): string {
|
|
48
|
+
return addDecimalString(
|
|
49
|
+
snapshotDecimal(snapshot, 'trade_pnl'),
|
|
50
|
+
snapshotDecimal(snapshot, 'trade_spot_pnl')
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getCumulativeNetFlow(snapshot: LtPnLEntry): string {
|
|
55
|
+
return subtractDecimalString(
|
|
56
|
+
addDecimalString(
|
|
57
|
+
subtractDecimalString(
|
|
58
|
+
snapshotDecimal(snapshot, 'inflow'),
|
|
59
|
+
snapshotDecimal(snapshot, 'outflow')
|
|
60
|
+
),
|
|
61
|
+
snapshotDecimal(snapshot, 'spot_inflow')
|
|
62
|
+
),
|
|
63
|
+
snapshotDecimal(snapshot, 'spot_outflow')
|
|
64
|
+
)
|
|
17
65
|
}
|
|
18
66
|
|
|
19
67
|
/**
|
|
20
68
|
* Derive window-relative history from Lighter's cumulative PnL snapshots.
|
|
21
|
-
* Historical account values are anchored to the current account value.
|
|
69
|
+
* Historical account values are anchored to the current account value. A
|
|
70
|
+
* snapshot with a non-finite value is skipped.
|
|
71
|
+
*
|
|
72
|
+
* @throws {PerpsError} `ValidationError` when `currentValue` is not a decimal
|
|
73
|
+
* string.
|
|
22
74
|
*/
|
|
23
75
|
export const mapPortfolioHistory = (
|
|
24
76
|
range: PortfolioHistoryRange,
|
|
25
77
|
snapshots: LtPnLEntry[],
|
|
26
|
-
currentValue:
|
|
78
|
+
currentValue: string
|
|
27
79
|
): PortfolioHistoryResponse => {
|
|
28
|
-
const orderedSnapshots =
|
|
29
|
-
(
|
|
30
|
-
|
|
80
|
+
const orderedSnapshots = snapshots
|
|
81
|
+
.filter(isValidSnapshot)
|
|
82
|
+
.sort((a, b) => a.timestamp - b.timestamp)
|
|
31
83
|
const firstSnapshot = orderedSnapshots[0]
|
|
32
84
|
const latestSnapshot = orderedSnapshots.at(-1)
|
|
33
85
|
if (!firstSnapshot || !latestSnapshot) {
|
|
@@ -41,27 +93,29 @@ export const mapPortfolioHistory = (
|
|
|
41
93
|
|
|
42
94
|
const firstPnl = getCumulativePnl(firstSnapshot)
|
|
43
95
|
const latestPnl = getCumulativePnl(latestSnapshot)
|
|
44
|
-
const accountValueOffset =
|
|
45
|
-
|
|
46
|
-
|
|
96
|
+
const accountValueOffset = subtractDecimalString(
|
|
97
|
+
subtractDecimalString(currentValue, latestPnl),
|
|
98
|
+
getCumulativeNetFlow(latestSnapshot)
|
|
99
|
+
)
|
|
47
100
|
const points = orderedSnapshots.map((snapshot) => {
|
|
48
101
|
const pnl = getCumulativePnl(snapshot)
|
|
49
102
|
return {
|
|
50
103
|
timestamp: snapshot.timestamp * 1_000,
|
|
51
|
-
accountValue:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
pnl: pnl
|
|
104
|
+
accountValue: addDecimalString(
|
|
105
|
+
addDecimalString(accountValueOffset, pnl),
|
|
106
|
+
getCumulativeNetFlow(snapshot)
|
|
107
|
+
),
|
|
108
|
+
pnl: subtractDecimalString(pnl, firstPnl),
|
|
56
109
|
}
|
|
57
110
|
})
|
|
58
111
|
|
|
59
112
|
return {
|
|
60
113
|
range,
|
|
61
114
|
points,
|
|
62
|
-
volume:
|
|
63
|
-
|
|
64
|
-
|
|
115
|
+
volume: subtractDecimalString(
|
|
116
|
+
snapshotDecimal(latestSnapshot, 'volume'),
|
|
117
|
+
snapshotDecimal(firstSnapshot, 'volume')
|
|
118
|
+
),
|
|
65
119
|
totalPnl: points.at(-1)?.pnl,
|
|
66
120
|
}
|
|
67
121
|
}
|
package/src/utils/mapPosition.ts
CHANGED
|
@@ -1,86 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
absDecimalString,
|
|
3
|
+
divideDecimalString,
|
|
4
|
+
isDecimalString,
|
|
5
|
+
isDecimalStringZero,
|
|
6
|
+
multiplyDecimalString,
|
|
7
|
+
safeDivideDecimalString,
|
|
8
|
+
safeIsDecimalStringGreaterThan,
|
|
9
|
+
safeNumberToDecimalString,
|
|
10
|
+
safeRoundDecimalString,
|
|
11
|
+
warnSkippedVenueRow,
|
|
12
|
+
} from '@lifi/perps-sdk'
|
|
1
13
|
import type { PerpsMarketDisplay, Position } from '@lifi/perps-types'
|
|
2
14
|
import { MarginMode, PositionSide } from '@lifi/perps-types'
|
|
3
|
-
import
|
|
4
|
-
|
|
15
|
+
import {
|
|
16
|
+
LIGHTER_IMF_PERCENT_SCALE,
|
|
17
|
+
LIGHTER_LEVERAGE_PRECISION,
|
|
18
|
+
LIGHTER_PROVIDER_KEY,
|
|
19
|
+
} from '../constants.js'
|
|
5
20
|
import type { LtAccountPosition } from '../types/index.js'
|
|
6
21
|
import { LT_MARGIN_MODE_ISOLATED } from '../types/index.js'
|
|
7
|
-
import { toPositiveRequiredBig, toRequiredBig } from './decimal.js'
|
|
8
22
|
|
|
9
23
|
/**
|
|
10
24
|
* Display leverage from an IMF percent string: `100 / IMF` in exact decimal
|
|
11
|
-
* arithmetic
|
|
12
|
-
*
|
|
13
|
-
* instead. `undefined` for a non-positive or unparsable
|
|
25
|
+
* arithmetic, rounded half-up to `LIGHTER_LEVERAGE_PRECISION`, so the value a
|
|
26
|
+
* client reads is the value it saved. Provider risk calculations consume the
|
|
27
|
+
* original decimal IMF instead. `undefined` for a non-positive or unparsable
|
|
28
|
+
* IMF.
|
|
14
29
|
* @public
|
|
15
30
|
*/
|
|
16
|
-
export const leverageFromImf = (imf: string):
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
parsed = new Big(imf)
|
|
20
|
-
} catch {
|
|
31
|
+
export const leverageFromImf = (imf: string): string | undefined => {
|
|
32
|
+
if (safeIsDecimalStringGreaterThan(imf, '0') !== true) {
|
|
21
33
|
return undefined
|
|
22
34
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
const leverage = safeDivideDecimalString('100', imf)
|
|
36
|
+
return leverage === undefined
|
|
37
|
+
? undefined
|
|
38
|
+
: safeRoundDecimalString(leverage, LIGHTER_LEVERAGE_PRECISION, 'round')
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
/**
|
|
30
42
|
* Display leverage from an integer IMF on `LIGHTER_IMF_PERCENT_SCALE`, the
|
|
31
43
|
* unit of trade rows and order-book details: `500` is 5.00%, so 20x.
|
|
32
|
-
* `undefined` for a non-positive or
|
|
44
|
+
* `undefined` for a non-positive or non-finite IMF. Lighter declares the
|
|
33
45
|
* fraction a `StrictInt`, so the scale division is exact.
|
|
34
46
|
*/
|
|
35
|
-
export const leverageFromScaledImf = (imf: number):
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
export const leverageFromScaledImf = (imf: number): string | undefined => {
|
|
48
|
+
const scaled = safeNumberToDecimalString(imf)
|
|
49
|
+
const percent =
|
|
50
|
+
scaled === undefined
|
|
51
|
+
? undefined
|
|
52
|
+
: safeDivideDecimalString(scaled, String(LIGHTER_IMF_PERCENT_SCALE))
|
|
53
|
+
return percent === undefined ? undefined : leverageFromImf(percent)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const skipPosition = (field: string, value: unknown): undefined => {
|
|
57
|
+
warnSkippedVenueRow(LIGHTER_PROVIDER_KEY, 'position', field, value)
|
|
58
|
+
return undefined
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
/**
|
|
46
|
-
* Map a raw Lighter account position to the generic Position type.
|
|
62
|
+
* Map a raw Lighter account position to the generic Position type. A row with
|
|
63
|
+
* an invalid size or value, or a non-positive initial margin fraction, gives
|
|
64
|
+
* `undefined`: the mapper derives the size, mark price, margin and leverage
|
|
65
|
+
* from them. Prices, PnL, funding and isolated margin pass through raw.
|
|
47
66
|
* @param market - Backend-resolved market identity for `pos.market_id`.
|
|
48
67
|
* @public
|
|
49
68
|
*/
|
|
50
69
|
export const mapPosition = (
|
|
51
70
|
pos: LtAccountPosition,
|
|
52
71
|
market: PerpsMarketDisplay
|
|
53
|
-
): Position => {
|
|
54
|
-
|
|
72
|
+
): Position | undefined => {
|
|
73
|
+
if (!isDecimalString(pos.position)) {
|
|
74
|
+
return skipPosition('position', pos.position)
|
|
75
|
+
}
|
|
76
|
+
if (!isDecimalString(pos.position_value)) {
|
|
77
|
+
return skipPosition('position_value', pos.position_value)
|
|
78
|
+
}
|
|
79
|
+
const imf = pos.initial_margin_fraction
|
|
80
|
+
const leverage = isDecimalString(imf) ? leverageFromImf(imf) : undefined
|
|
81
|
+
if (leverage === undefined) {
|
|
82
|
+
return skipPosition('initial_margin_fraction', imf)
|
|
83
|
+
}
|
|
55
84
|
const isIsolated = pos.margin_mode === LT_MARGIN_MODE_ISOLATED
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
pos.initial_margin_fraction,
|
|
62
|
-
'initial_margin_fraction'
|
|
85
|
+
const size = absDecimalString(pos.position)
|
|
86
|
+
const positionValue = absDecimalString(pos.position_value)
|
|
87
|
+
const initialMarginRequirement = divideDecimalString(
|
|
88
|
+
multiplyDecimalString(positionValue, imf),
|
|
89
|
+
'100'
|
|
63
90
|
)
|
|
64
|
-
const initialMarginRequirement = positionValue.times(imf).div(100)
|
|
65
|
-
const marginUsed = isIsolated
|
|
66
|
-
? pos.allocated_margin
|
|
67
|
-
: initialMarginRequirement.toFixed()
|
|
68
91
|
|
|
69
92
|
return {
|
|
70
93
|
market,
|
|
71
94
|
side: pos.sign >= 0 ? PositionSide.LONG : PositionSide.SHORT,
|
|
72
|
-
size
|
|
95
|
+
size,
|
|
73
96
|
entryPrice: pos.avg_entry_price,
|
|
74
97
|
markPrice:
|
|
75
|
-
positionValue
|
|
98
|
+
isDecimalStringZero(positionValue) || isDecimalStringZero(size)
|
|
76
99
|
? '0'
|
|
77
|
-
: positionValue
|
|
100
|
+
: divideDecimalString(positionValue, size),
|
|
78
101
|
liquidationPrice: pos.liquidation_price,
|
|
79
102
|
unrealizedPnl: pos.unrealized_pnl,
|
|
80
103
|
accruedFunding: pos.total_funding_paid_out ?? '0',
|
|
81
|
-
leverage
|
|
82
|
-
marginUsed,
|
|
83
|
-
initialMarginRequirement
|
|
104
|
+
leverage,
|
|
105
|
+
marginUsed: isIsolated ? pos.allocated_margin : initialMarginRequirement,
|
|
106
|
+
initialMarginRequirement,
|
|
84
107
|
marginMode: isIsolated ? MarginMode.ISOLATED : MarginMode.CROSS,
|
|
85
108
|
}
|
|
86
109
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { timestampToIsoString } from '@lifi/perps-sdk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Read a venue row time as an ISO-8601 string, or `undefined` when the time is
|
|
5
|
+
* not valid. The caller logs the row skip, so this logs nothing.
|
|
6
|
+
*/
|
|
7
|
+
export const rowTimestampToIsoStringOrUndefined = (
|
|
8
|
+
value: string | number
|
|
9
|
+
): string | undefined => {
|
|
10
|
+
try {
|
|
11
|
+
return timestampToIsoString(value)
|
|
12
|
+
} catch {
|
|
13
|
+
return undefined
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
addDecimalString,
|
|
3
|
+
isDecimalStringGreaterThan,
|
|
4
|
+
subtractDecimalString,
|
|
5
|
+
unknownToDecimalString,
|
|
6
|
+
} from '@lifi/perps-sdk'
|
|
7
|
+
import { LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
2
8
|
import type { LtAccountAsset } from '../types/account.js'
|
|
3
|
-
import { toRequiredBig } from './decimal.js'
|
|
4
9
|
|
|
5
10
|
/** Both routes of a unified account's settlement asset, as one holding. */
|
|
6
|
-
export const pooledSettlementUnits = (asset: LtAccountAsset):
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
export const pooledSettlementUnits = (asset: LtAccountAsset): string =>
|
|
12
|
+
addDecimalString(
|
|
13
|
+
unknownToDecimalString(asset.balance, 'balance', LIGHTER_PROVIDER_KEY),
|
|
14
|
+
unknownToDecimalString(
|
|
15
|
+
asset.margin_balance,
|
|
16
|
+
'margin_balance',
|
|
17
|
+
LIGHTER_PROVIDER_KEY
|
|
18
|
+
)
|
|
9
19
|
)
|
|
10
20
|
|
|
11
21
|
/**
|
|
@@ -16,12 +26,26 @@ export const pooledSettlementUnits = (asset: LtAccountAsset): Big =>
|
|
|
16
26
|
*/
|
|
17
27
|
export const pooledSettlementSpendable = (
|
|
18
28
|
asset: LtAccountAsset,
|
|
19
|
-
availableBalance:
|
|
20
|
-
):
|
|
21
|
-
const marginBalance =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
availableBalance: string
|
|
30
|
+
): string => {
|
|
31
|
+
const marginBalance = unknownToDecimalString(
|
|
32
|
+
asset.margin_balance,
|
|
33
|
+
'margin_balance',
|
|
34
|
+
LIGHTER_PROVIDER_KEY
|
|
35
|
+
)
|
|
36
|
+
return addDecimalString(
|
|
37
|
+
subtractDecimalString(
|
|
38
|
+
unknownToDecimalString(asset.balance, 'balance', LIGHTER_PROVIDER_KEY),
|
|
39
|
+
unknownToDecimalString(
|
|
40
|
+
asset.locked_balance,
|
|
41
|
+
'locked_balance',
|
|
42
|
+
LIGHTER_PROVIDER_KEY
|
|
43
|
+
)
|
|
44
|
+
),
|
|
45
|
+
isDecimalStringGreaterThan(marginBalance, availableBalance)
|
|
46
|
+
? availableBalance
|
|
47
|
+
: marginBalance
|
|
48
|
+
)
|
|
25
49
|
}
|
|
26
50
|
|
|
27
51
|
/** Spot-route `balance` of the collateral asset; `'0'` when the account holds none. */
|
|
@@ -32,5 +56,5 @@ export const collateralSpotBalance = (
|
|
|
32
56
|
const asset = assets.find((a) => a.asset_id === settlementAssetIndex)
|
|
33
57
|
return asset === undefined
|
|
34
58
|
? '0'
|
|
35
|
-
:
|
|
59
|
+
: unknownToDecimalString(asset.balance, 'balance', LIGHTER_PROVIDER_KEY)
|
|
36
60
|
}
|
package/src/utils/spotPrice.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isDecimalStringGreaterThan,
|
|
3
|
+
multiplyDecimalString,
|
|
4
|
+
unknownToDecimalString,
|
|
5
|
+
} from '@lifi/perps-sdk'
|
|
1
6
|
import type { Market, MarketContext } from '@lifi/perps-types'
|
|
2
|
-
import
|
|
3
|
-
import { toRequiredBig } from './decimal.js'
|
|
7
|
+
import { LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Unit prices keyed by spot base `Asset.id` (the venue `asset_id`), read from
|
|
@@ -17,9 +21,9 @@ export const spotPriceByAssetId = (
|
|
|
17
21
|
spotCategoryId: string,
|
|
18
22
|
contexts: readonly MarketContext[],
|
|
19
23
|
assetIds: ReadonlySet<string>
|
|
20
|
-
): Map<string,
|
|
24
|
+
): Map<string, string> => {
|
|
21
25
|
const markByMarketId = new Map(contexts.map((c) => [c.marketId, c.markPrice]))
|
|
22
|
-
const priceByAssetId = new Map<string,
|
|
26
|
+
const priceByAssetId = new Map<string, string>()
|
|
23
27
|
for (const market of markets) {
|
|
24
28
|
const mark = markByMarketId.get(market.id)
|
|
25
29
|
if (
|
|
@@ -30,8 +34,12 @@ export const spotPriceByAssetId = (
|
|
|
30
34
|
) {
|
|
31
35
|
continue
|
|
32
36
|
}
|
|
33
|
-
const price =
|
|
34
|
-
|
|
37
|
+
const price = unknownToDecimalString(
|
|
38
|
+
mark,
|
|
39
|
+
'markPrice',
|
|
40
|
+
LIGHTER_PROVIDER_KEY
|
|
41
|
+
)
|
|
42
|
+
if (isDecimalStringGreaterThan(price, '0')) {
|
|
35
43
|
priceByAssetId.set(market.baseAsset.id, price)
|
|
36
44
|
}
|
|
37
45
|
}
|
|
@@ -47,13 +55,11 @@ export const spotValuation = (
|
|
|
47
55
|
assetId: number,
|
|
48
56
|
units: string,
|
|
49
57
|
settlementAssetIndex: number,
|
|
50
|
-
spotPrices: ReadonlyMap<string,
|
|
51
|
-
): { valueUsd: string; price?:
|
|
58
|
+
spotPrices: ReadonlyMap<string, string>
|
|
59
|
+
): { valueUsd: string; price?: string } => {
|
|
52
60
|
const price =
|
|
53
|
-
assetId === settlementAssetIndex
|
|
54
|
-
? new Big(1)
|
|
55
|
-
: spotPrices.get(String(assetId))
|
|
61
|
+
assetId === settlementAssetIndex ? '1' : spotPrices.get(String(assetId))
|
|
56
62
|
return price === undefined
|
|
57
63
|
? { valueUsd: '0' }
|
|
58
|
-
: { valueUsd:
|
|
64
|
+
: { valueUsd: multiplyDecimalString(units, price), price }
|
|
59
65
|
}
|
package/src/utils/time.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import { timestampToIsoString } from '@lifi/perps-sdk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert seconds since unix epoch to ISO-8601.
|
|
5
|
+
*
|
|
6
|
+
* @throws {PerpsError} `ValidationError` when `seconds` is not a valid time.
|
|
7
|
+
*/
|
|
2
8
|
export const toIsoFromSeconds = (seconds: number): string =>
|
|
3
|
-
|
|
9
|
+
timestampToIsoString(seconds * 1000)
|
|
4
10
|
|
|
5
|
-
/**
|
|
6
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Convert milliseconds since unix epoch to ISO-8601.
|
|
13
|
+
*
|
|
14
|
+
* @throws {PerpsError} `ValidationError` when `ms` is not a valid time.
|
|
15
|
+
*/
|
|
16
|
+
export const toIsoFromMs = (ms: number): string => timestampToIsoString(ms)
|