@lifi/perps-sdk-provider-lighter 41.0.2 → 42.0.1
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/README.md +34 -0
- package/dist/cjs/depositFlow.d.ts.map +1 -1
- package/dist/cjs/depositFlow.js +9 -10
- package/dist/cjs/depositFlow.js.map +1 -1
- package/dist/cjs/types/ws.d.ts +2 -0
- package/dist/cjs/types/ws.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.js +18 -2
- package/dist/cjs/utils/mapFill.js.map +1 -1
- package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
- package/dist/cjs/utils/mapOrder.js +1 -0
- package/dist/cjs/utils/mapOrder.js.map +1 -1
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
- package/dist/cjs/utils/mapPosition.js +5 -1
- package/dist/cjs/utils/mapPosition.js.map +1 -1
- package/dist/cjs/utils/tradePrice.d.ts +3 -0
- package/dist/cjs/utils/tradePrice.d.ts.map +1 -0
- package/dist/cjs/utils/tradePrice.js +9 -0
- package/dist/cjs/utils/tradePrice.js.map +1 -0
- package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.js +2 -1
- package/dist/cjs/websocket/LighterWsProvider.js.map +1 -1
- package/dist/esm/depositFlow.d.ts +3 -3
- package/dist/esm/depositFlow.d.ts.map +1 -1
- package/dist/esm/depositFlow.js +12 -13
- package/dist/esm/depositFlow.js.map +1 -1
- package/dist/esm/types/ws.d.ts +2 -0
- package/dist/esm/types/ws.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.d.ts +2 -1
- package/dist/esm/utils/mapFill.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.js +23 -4
- package/dist/esm/utils/mapFill.js.map +1 -1
- package/dist/esm/utils/mapOrder.d.ts.map +1 -1
- package/dist/esm/utils/mapOrder.js +1 -0
- package/dist/esm/utils/mapOrder.js.map +1 -1
- package/dist/esm/utils/mapPosition.d.ts +3 -1
- package/dist/esm/utils/mapPosition.d.ts.map +1 -1
- package/dist/esm/utils/mapPosition.js +8 -2
- package/dist/esm/utils/mapPosition.js.map +1 -1
- package/dist/esm/utils/tradePrice.d.ts +11 -0
- package/dist/esm/utils/tradePrice.d.ts.map +1 -0
- package/dist/esm/utils/tradePrice.js +13 -0
- package/dist/esm/utils/tradePrice.js.map +1 -0
- package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.js +2 -1
- package/dist/esm/websocket/LighterWsProvider.js.map +1 -1
- package/dist/types/depositFlow.d.ts +3 -3
- package/dist/types/depositFlow.d.ts.map +1 -1
- package/dist/types/types/ws.d.ts +2 -0
- package/dist/types/types/ws.d.ts.map +1 -1
- package/dist/types/utils/mapFill.d.ts +2 -1
- package/dist/types/utils/mapFill.d.ts.map +1 -1
- package/dist/types/utils/mapOrder.d.ts.map +1 -1
- package/dist/types/utils/mapPosition.d.ts +3 -1
- package/dist/types/utils/mapPosition.d.ts.map +1 -1
- package/dist/types/utils/tradePrice.d.ts +11 -0
- package/dist/types/utils/tradePrice.d.ts.map +1 -0
- package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/depositFlow.ts +20 -18
- package/src/types/ws.ts +2 -0
- package/src/utils/mapFill.ts +28 -5
- package/src/utils/mapOrder.ts +1 -0
- package/src/utils/mapPosition.ts +8 -2
- package/src/utils/tradePrice.ts +20 -0
- package/src/websocket/LighterWsProvider.ts +2 -1
package/src/depositFlow.ts
CHANGED
|
@@ -11,31 +11,33 @@ import { ActionType, type LighterProviderKey } from '@lifi/perps-types'
|
|
|
11
11
|
import { LIGHTER_PROVIDER_KEY, LIGHTER_RH_PROVIDER_KEY } from './constants.js'
|
|
12
12
|
|
|
13
13
|
interface LighterDepositAssets {
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Collateral token on the venue chain that a LI.FI route credits to an
|
|
16
|
+
* account that exists. Absent when only the venue deposit credits an account.
|
|
17
|
+
*/
|
|
18
|
+
venueCollateral?: DeclaredDepositAsset
|
|
19
|
+
/** Collateral the venue deposit is made in, on the chain that deposit runs on. */
|
|
20
|
+
venueDepositCollateral: DeclaredDepositAsset
|
|
21
|
+
venueDepositGas: DeclaredDepositAsset
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
const DEPOSIT_ASSETS: Record<LighterProviderKey, LighterDepositAssets> = {
|
|
22
25
|
[LIGHTER_PROVIDER_KEY]: {
|
|
23
26
|
venueCollateral: LIGHTER_USDC,
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
venueDepositCollateral: ETHEREUM_USDC,
|
|
28
|
+
venueDepositGas: ETHEREUM_NATIVE_GAS,
|
|
26
29
|
},
|
|
27
30
|
[LIGHTER_RH_PROVIDER_KEY]: {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
firstDepositGas: ROBINHOOD_NATIVE_GAS,
|
|
31
|
+
venueDepositCollateral: ROBINHOOD_USDG,
|
|
32
|
+
venueDepositGas: ROBINHOOD_NATIVE_GAS,
|
|
31
33
|
},
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* Resolve one Lighter instance's deposit flow from whether the account already
|
|
36
|
-
* exists: an existing account takes a swap into the instance's venue collateral
|
|
37
|
-
*
|
|
38
|
-
* that instance's collateral is deposited from.
|
|
38
|
+
* exists: an existing account takes a swap into the instance's venue collateral
|
|
39
|
+
* when a LI.FI route credits it there. Every other case runs the venue deposit
|
|
40
|
+
* on the chain that instance's collateral is deposited from.
|
|
39
41
|
*
|
|
40
42
|
* @public
|
|
41
43
|
*/
|
|
@@ -45,15 +47,15 @@ export function lighterDepositFlow(
|
|
|
45
47
|
): DepositFlow {
|
|
46
48
|
const assets = DEPOSIT_ASSETS[providerKey]
|
|
47
49
|
|
|
48
|
-
if (accountExists) {
|
|
50
|
+
if (accountExists && assets.venueCollateral) {
|
|
49
51
|
return { kind: 'lifiSwap', destination: assets.venueCollateral }
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
return {
|
|
53
|
-
kind: '
|
|
54
|
-
chainId: assets.
|
|
55
|
-
gasAsset: assets.
|
|
56
|
-
collateral: assets.
|
|
55
|
+
kind: 'venueDepositPipeline',
|
|
56
|
+
chainId: assets.venueDepositCollateral.chainId,
|
|
57
|
+
gasAsset: assets.venueDepositGas,
|
|
58
|
+
collateral: assets.venueDepositCollateral,
|
|
57
59
|
bridgeAction: ActionType.DEPOSIT,
|
|
58
60
|
}
|
|
59
61
|
}
|
package/src/types/ws.ts
CHANGED
package/src/utils/mapFill.ts
CHANGED
|
@@ -13,12 +13,13 @@ import {
|
|
|
13
13
|
safeMultiplyDecimalString,
|
|
14
14
|
warnSkippedVenueRow,
|
|
15
15
|
} from '@lifi/perps-sdk'
|
|
16
|
-
import type { Fill, MarketDisplay } from '@lifi/perps-types'
|
|
17
|
-
import { LiquidityRole, OrderSide
|
|
16
|
+
import type { Fill, FillLiquidation, MarketDisplay } from '@lifi/perps-types'
|
|
17
|
+
import { LiquidationMethod, LiquidityRole, OrderSide } from '@lifi/perps-types'
|
|
18
18
|
import { LIGHTER_FEE_TICK_SCALE, LIGHTER_PROVIDER_KEY } from '../constants.js'
|
|
19
19
|
import type { LtTrade } from '../types/index.js'
|
|
20
20
|
import { leverageFromScaledImf } from './mapPosition.js'
|
|
21
21
|
import { rowTimestampToIsoStringOrUndefined } from './rowTimestamp.js'
|
|
22
|
+
import { resolveTradePrice } from './tradePrice.js'
|
|
22
23
|
import { isPlaceholderTxHash } from './txHash.js'
|
|
23
24
|
|
|
24
25
|
/**
|
|
@@ -111,8 +112,28 @@ const deriveRealizedPnl = (
|
|
|
111
112
|
return isDecimalStringZero(pnl) ? null : pnl
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
// The liquidation engine trades as the taker for the liquidated account; the
|
|
116
|
+
// maker of a forced trade is its counterparty.
|
|
117
|
+
const mapFillLiquidation = (
|
|
118
|
+
type: string,
|
|
119
|
+
isMaker: boolean
|
|
120
|
+
): FillLiquidation | undefined => {
|
|
121
|
+
if (isMaker) {
|
|
122
|
+
return undefined
|
|
123
|
+
}
|
|
124
|
+
switch (type) {
|
|
125
|
+
case 'liquidation':
|
|
126
|
+
return { method: LiquidationMethod.MARKET }
|
|
127
|
+
case 'deleverage':
|
|
128
|
+
return { method: LiquidationMethod.DELEVERAGE }
|
|
129
|
+
default:
|
|
130
|
+
return undefined
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
114
134
|
/**
|
|
115
|
-
* Map a raw Lighter trade to the generic Fill type.
|
|
135
|
+
* Map a raw Lighter trade to the generic Fill type. Leaves `type` absent: a
|
|
136
|
+
* trade row does not name the originating order type.
|
|
116
137
|
* @param accountIndex - The viewer's Lighter account index (selects buy/sell side and maker/taker role).
|
|
117
138
|
* @param market - Backend-resolved market identity for `trade.market_id`.
|
|
118
139
|
* @public
|
|
@@ -122,7 +143,8 @@ export const mapFill = (
|
|
|
122
143
|
accountIndex: number,
|
|
123
144
|
market: MarketDisplay
|
|
124
145
|
): Fill | undefined => {
|
|
125
|
-
const { size
|
|
146
|
+
const { size } = trade
|
|
147
|
+
const price = resolveTradePrice(trade)
|
|
126
148
|
const createdAt = rowTimestampToIsoStringOrUndefined(trade.timestamp)
|
|
127
149
|
if (createdAt === undefined) {
|
|
128
150
|
warnSkippedVenueRow(
|
|
@@ -159,13 +181,13 @@ export const mapFill = (
|
|
|
159
181
|
feeTick === undefined
|
|
160
182
|
? undefined
|
|
161
183
|
: tickToFeeAmount(trade.usd_amount, feeTick, integratorFeeTick)
|
|
184
|
+
const liquidation = mapFillLiquidation(trade.type, isMaker)
|
|
162
185
|
|
|
163
186
|
return {
|
|
164
187
|
id: trade.trade_id_str,
|
|
165
188
|
orderId: isBuyer ? trade.bid_id_str : trade.ask_id_str,
|
|
166
189
|
market,
|
|
167
190
|
side: isBuyer ? OrderSide.BUY : OrderSide.SELL,
|
|
168
|
-
type: OrderType.LIMIT,
|
|
169
191
|
size,
|
|
170
192
|
price,
|
|
171
193
|
liquidity: isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
|
|
@@ -192,5 +214,6 @@ export const mapFill = (
|
|
|
192
214
|
explorerLink: isPlaceholderTxHash(trade.tx_hash)
|
|
193
215
|
? undefined
|
|
194
216
|
: explorerTxUrl(ExplorerChainId.LIGHTER, trade.tx_hash),
|
|
217
|
+
...(liquidation === undefined ? {} : { liquidation }),
|
|
195
218
|
}
|
|
196
219
|
}
|
package/src/utils/mapOrder.ts
CHANGED
package/src/utils/mapPosition.ts
CHANGED
|
@@ -79,7 +79,9 @@ const warnUnreadableField = (field: string, value: unknown): void => {
|
|
|
79
79
|
* an invalid size gives `undefined`. An invalid position value or a
|
|
80
80
|
* non-positive initial margin fraction keeps the row, leaves `leverage` and
|
|
81
81
|
* `initialMarginRequirement` absent, sets a cross `marginUsed` to `'0'` and
|
|
82
|
-
* warns once. Prices, PnL, funding and isolated margin pass through raw.
|
|
82
|
+
* warns once. Prices, PnL, funding and isolated margin pass through raw. A
|
|
83
|
+
* zero or empty `liquidation_price`, which Lighter sends for a position that
|
|
84
|
+
* no price liquidates, leaves `liquidationPrice` absent.
|
|
83
85
|
* @param market - Backend-resolved market identity for `pos.market_id`.
|
|
84
86
|
* @public
|
|
85
87
|
*/
|
|
@@ -107,6 +109,10 @@ export const mapPosition = (
|
|
|
107
109
|
positionValue === undefined || leverage === undefined
|
|
108
110
|
? undefined
|
|
109
111
|
: divideDecimalString(multiplyDecimalString(positionValue, imf), '100')
|
|
112
|
+
const liquidationPrice = pos.liquidation_price
|
|
113
|
+
const hasLiquidationPrice = isDecimalString(liquidationPrice)
|
|
114
|
+
? !isDecimalStringZero(liquidationPrice)
|
|
115
|
+
: liquidationPrice !== ''
|
|
110
116
|
|
|
111
117
|
return {
|
|
112
118
|
market,
|
|
@@ -121,7 +127,7 @@ export const mapPosition = (
|
|
|
121
127
|
? '0'
|
|
122
128
|
: divideDecimalString(positionValue, size),
|
|
123
129
|
}),
|
|
124
|
-
liquidationPrice:
|
|
130
|
+
...(hasLiquidationPrice ? { liquidationPrice } : {}),
|
|
125
131
|
unrealizedPnl: pos.unrealized_pnl,
|
|
126
132
|
accruedFunding: pos.total_funding_paid_out ?? '0',
|
|
127
133
|
...(leverage === undefined ? {} : { leverage }),
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safeDivideDecimalString,
|
|
3
|
+
safeIsDecimalStringZero,
|
|
4
|
+
} from '@lifi/perps-sdk'
|
|
5
|
+
import type { LtTrade } from '../types/index.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Execution price of a Lighter trade row. Lighter reports a zero `price` on a
|
|
9
|
+
* `deleverage` row, but `usd_amount` still carries the execution notional, so
|
|
10
|
+
* that row resolves to `usd_amount / size`. Every other row, and a row whose
|
|
11
|
+
* division fails, keeps the venue `price`.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export const resolveTradePrice = (
|
|
16
|
+
trade: Pick<LtTrade, 'type' | 'price' | 'size' | 'usd_amount'>
|
|
17
|
+
): string =>
|
|
18
|
+
trade.type === 'deleverage' && safeIsDecimalStringZero(trade.price) === true
|
|
19
|
+
? (safeDivideDecimalString(trade.usd_amount, trade.size) ?? trade.price)
|
|
20
|
+
: trade.price
|
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
mapPosition,
|
|
74
74
|
} from '../utils/index.js'
|
|
75
75
|
import { spotPriceByAssetId, spotValuation } from '../utils/spotPrice.js'
|
|
76
|
+
import { resolveTradePrice } from '../utils/tradePrice.js'
|
|
76
77
|
import { askOrder, bidOrder, OrderBookSide } from './orderBookSide.js'
|
|
77
78
|
|
|
78
79
|
// Public channels: `marketsContext` (market_stats/all + spot_market_stats/all),
|
|
@@ -1097,7 +1098,7 @@ export class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
1097
1098
|
data: trades.map((t) => ({
|
|
1098
1099
|
provider: this.providerKey,
|
|
1099
1100
|
marketId: assetId,
|
|
1100
|
-
price: t
|
|
1101
|
+
price: resolveTradePrice(t),
|
|
1101
1102
|
size: t.size,
|
|
1102
1103
|
timestamp: t.timestamp,
|
|
1103
1104
|
side: t.is_maker_ask ? 'buy' : 'sell',
|