@lifi/perps-sdk-provider-lighter 41.0.1 → 42.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.
Files changed (61) hide show
  1. package/README.md +37 -1
  2. package/dist/cjs/depositFlow.d.ts.map +1 -1
  3. package/dist/cjs/depositFlow.js +9 -10
  4. package/dist/cjs/depositFlow.js.map +1 -1
  5. package/dist/cjs/signers/generated/wasmExecRuntime.d.ts +1 -0
  6. package/dist/cjs/signers/generated/wasmExecRuntime.d.ts.map +1 -1
  7. package/dist/cjs/signers/generated/wasmExecRuntime.js +38 -0
  8. package/dist/cjs/signers/generated/wasmExecRuntime.js.map +1 -1
  9. package/dist/cjs/signers/wasmLoader.d.ts.map +1 -1
  10. package/dist/cjs/signers/wasmLoader.js +2 -14
  11. package/dist/cjs/signers/wasmLoader.js.map +1 -1
  12. package/dist/cjs/utils/mapFill.d.ts.map +1 -1
  13. package/dist/cjs/utils/mapFill.js +19 -2
  14. package/dist/cjs/utils/mapFill.js.map +1 -1
  15. package/dist/cjs/utils/mapOrder.d.ts.map +1 -1
  16. package/dist/cjs/utils/mapOrder.js +1 -0
  17. package/dist/cjs/utils/mapOrder.js.map +1 -1
  18. package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
  19. package/dist/cjs/utils/mapPosition.js +5 -1
  20. package/dist/cjs/utils/mapPosition.js.map +1 -1
  21. package/dist/esm/depositFlow.d.ts +3 -3
  22. package/dist/esm/depositFlow.d.ts.map +1 -1
  23. package/dist/esm/depositFlow.js +12 -13
  24. package/dist/esm/depositFlow.js.map +1 -1
  25. package/dist/esm/signers/generated/wasmExecRuntime.d.ts +1 -0
  26. package/dist/esm/signers/generated/wasmExecRuntime.d.ts.map +1 -1
  27. package/dist/esm/signers/generated/wasmExecRuntime.js +37 -0
  28. package/dist/esm/signers/generated/wasmExecRuntime.js.map +1 -1
  29. package/dist/esm/signers/wasmLoader.d.ts.map +1 -1
  30. package/dist/esm/signers/wasmLoader.js +4 -17
  31. package/dist/esm/signers/wasmLoader.js.map +1 -1
  32. package/dist/esm/utils/mapFill.d.ts +2 -1
  33. package/dist/esm/utils/mapFill.d.ts.map +1 -1
  34. package/dist/esm/utils/mapFill.js +27 -5
  35. package/dist/esm/utils/mapFill.js.map +1 -1
  36. package/dist/esm/utils/mapOrder.d.ts.map +1 -1
  37. package/dist/esm/utils/mapOrder.js +1 -0
  38. package/dist/esm/utils/mapOrder.js.map +1 -1
  39. package/dist/esm/utils/mapPosition.d.ts +3 -1
  40. package/dist/esm/utils/mapPosition.d.ts.map +1 -1
  41. package/dist/esm/utils/mapPosition.js +8 -2
  42. package/dist/esm/utils/mapPosition.js.map +1 -1
  43. package/dist/types/depositFlow.d.ts +3 -3
  44. package/dist/types/depositFlow.d.ts.map +1 -1
  45. package/dist/types/signers/generated/wasmExecRuntime.d.ts +1 -0
  46. package/dist/types/signers/generated/wasmExecRuntime.d.ts.map +1 -1
  47. package/dist/types/signers/wasmLoader.d.ts.map +1 -1
  48. package/dist/types/utils/mapFill.d.ts +2 -1
  49. package/dist/types/utils/mapFill.d.ts.map +1 -1
  50. package/dist/types/utils/mapOrder.d.ts.map +1 -1
  51. package/dist/types/utils/mapPosition.d.ts +3 -1
  52. package/dist/types/utils/mapPosition.d.ts.map +1 -1
  53. package/dist/wasm/lighter-signer.manifest.json +46 -0
  54. package/dist/wasm/lighter-signer.wasm +0 -0
  55. package/package.json +3 -3
  56. package/src/depositFlow.ts +20 -18
  57. package/src/signers/generated/wasmExecRuntime.ts +38 -0
  58. package/src/signers/wasmLoader.ts +7 -18
  59. package/src/utils/mapFill.ts +33 -5
  60. package/src/utils/mapOrder.ts +1 -0
  61. package/src/utils/mapPosition.ts +8 -2
@@ -0,0 +1,46 @@
1
+ {
2
+ "protocol": 2,
3
+ "sourceCommit": "b1edafa9cefc356be10e6b257d7097390a2e2d9f",
4
+ "sourceTreeSha256": "eec666104c587023f670ffaee6522a5371f5c1f11b0a93017ba243971066a7e1",
5
+ "goVersion": "go1.26.8",
6
+ "sha256": "2ebb649ab539784f69b7fbbfa04eebaf8728284aa269f84bfb327d2bed911a83",
7
+ "exports": [
8
+ "_lighterTest",
9
+ "_createClient",
10
+ "_createClientByPrv",
11
+ "_signChangePubKey",
12
+ "_signRevokePubKey",
13
+ "_signCreateSubAccount",
14
+ "_signCreatePublicPool",
15
+ "_signUpdatePublicPool",
16
+ "_signCreateOrder",
17
+ "_signCancelOrder",
18
+ "_signWithdraw",
19
+ "_signCancelAllOrders",
20
+ "_signModifyOrder",
21
+ "_signTransfer",
22
+ "_signMintShares",
23
+ "_signBurnShares",
24
+ "_signUpdateLeverage",
25
+ "_signUpdateMargin",
26
+ "_signUpdateAccountConfig",
27
+ "_signUpdateAccountAssetConfig",
28
+ "_signCreateGroupedOrders",
29
+ "_signApproveIntegrator",
30
+ "_getApproveIntegratorTransaction",
31
+ "_getChangePubKeyTransaction",
32
+ "_getRevokePubKeyTransaction",
33
+ "_getTransferTransaction",
34
+ "_getAirdropAllocationMessage",
35
+ "_createAuthToken",
36
+ "_signStakeAssets",
37
+ "_signUnstakeAssets",
38
+ "_signBinaryOptionsOperatorCreateMarket",
39
+ "_signBinaryOptionsOperatorUpdateMarket",
40
+ "_signBinaryOptionsOperatorSettleMarket",
41
+ "_resetClients",
42
+ "_selectClient"
43
+ ],
44
+ "runtimeSha256": "0c949f4996f9a89698e4b5c586de32249c3b69b7baadb64d220073cc04acba14",
45
+ "htmlSha256": "12efc5f5d57374c95f45ba061d6e1554de4221935bc2f3474c88367afa4677e5"
46
+ }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/perps-sdk-provider-lighter",
3
- "version": "41.0.1",
3
+ "version": "42.0.0",
4
4
  "description": "Lighter provider plugin for @lifi/perps-sdk",
5
5
  "homepage": "https://github.com/lifinance/perps-sdk",
6
6
  "bugs": {
@@ -44,10 +44,10 @@
44
44
  "dependencies": {
45
45
  "big.js": "^7.0.1",
46
46
  "viem": "^2.55.18",
47
- "@lifi/perps-types": "^25.0.1"
47
+ "@lifi/perps-types": "^26.0.0"
48
48
  },
49
49
  "peerDependencies": {
50
- "@lifi/perps-sdk": "^28.0.0"
50
+ "@lifi/perps-sdk": "^29.0.0"
51
51
  },
52
52
  "publishConfig": {
53
53
  "access": "public"
@@ -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
- /** Collateral token on the venue chain, credited to an account that exists. */
15
- venueCollateral: DeclaredDepositAsset
16
- /** Collateral the account-opening deposit is made in, on the chain that deposit runs on. */
17
- firstDepositCollateral: DeclaredDepositAsset
18
- firstDepositGas: DeclaredDepositAsset
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
- firstDepositCollateral: ETHEREUM_USDC,
25
- firstDepositGas: ETHEREUM_NATIVE_GAS,
27
+ venueDepositCollateral: ETHEREUM_USDC,
28
+ venueDepositGas: ETHEREUM_NATIVE_GAS,
26
29
  },
27
30
  [LIGHTER_RH_PROVIDER_KEY]: {
28
- venueCollateral: ROBINHOOD_USDG,
29
- firstDepositCollateral: ROBINHOOD_USDG,
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
- * while an address with no account runs the account-opening deposit on the chain
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: 'firstDepositPipeline',
54
- chainId: assets.firstDepositCollateral.chainId,
55
- gasAsset: assets.firstDepositGas,
56
- collateral: assets.firstDepositCollateral,
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
  }
@@ -585,3 +585,41 @@ export function createGoRuntime(): {
585
585
 
586
586
  return new globalThis.Go()
587
587
  }
588
+
589
+ export const lighterWasmGlobalNames = [
590
+ "_lighterTest",
591
+ "_createClient",
592
+ "_createClientByPrv",
593
+ "_signChangePubKey",
594
+ "_signRevokePubKey",
595
+ "_signCreateSubAccount",
596
+ "_signCreatePublicPool",
597
+ "_signUpdatePublicPool",
598
+ "_signCreateOrder",
599
+ "_signCancelOrder",
600
+ "_signWithdraw",
601
+ "_signCancelAllOrders",
602
+ "_signModifyOrder",
603
+ "_signTransfer",
604
+ "_signMintShares",
605
+ "_signBurnShares",
606
+ "_signUpdateLeverage",
607
+ "_signUpdateMargin",
608
+ "_signUpdateAccountConfig",
609
+ "_signUpdateAccountAssetConfig",
610
+ "_signCreateGroupedOrders",
611
+ "_signApproveIntegrator",
612
+ "_getApproveIntegratorTransaction",
613
+ "_getChangePubKeyTransaction",
614
+ "_getRevokePubKeyTransaction",
615
+ "_getTransferTransaction",
616
+ "_getAirdropAllocationMessage",
617
+ "_createAuthToken",
618
+ "_signStakeAssets",
619
+ "_signUnstakeAssets",
620
+ "_signBinaryOptionsOperatorCreateMarket",
621
+ "_signBinaryOptionsOperatorUpdateMarket",
622
+ "_signBinaryOptionsOperatorSettleMarket",
623
+ "_resetClients",
624
+ "_selectClient"
625
+ ] as const
@@ -3,7 +3,10 @@
3
3
 
4
4
  import { PerpsError } from '@lifi/perps-sdk'
5
5
  import { PerpsErrorCode } from '@lifi/perps-types'
6
- import { createGoRuntime } from './generated/wasmExecRuntime.js'
6
+ import {
7
+ createGoRuntime,
8
+ lighterWasmGlobalNames,
9
+ } from './generated/wasmExecRuntime.js'
7
10
  import {
8
11
  lighterWasmBinaryUrl,
9
12
  resolveEmittedBinaryUrl,
@@ -257,22 +260,6 @@ const WASM_FUNCTION_NAMES = [
257
260
  '_signUpdateAccountAssetConfig',
258
261
  ] as const satisfies readonly (keyof LighterWasmExports)[]
259
262
 
260
- // Installed by the binary but never called. They are removed from globalThis
261
- // with the used exports, because each one signs with the account's API key.
262
- const UNUSED_WASM_FUNCTION_NAMES = [
263
- '_signRevokePubKey',
264
- '_getRevokePubKeyTransaction',
265
- '_signCreateSubAccount',
266
- '_signCreatePublicPool',
267
- '_signUpdatePublicPool',
268
- '_signMintShares',
269
- '_signBurnShares',
270
- '_signCreateGroupedOrders',
271
- '_getAirdropAllocationMessage',
272
- '_signStakeAssets',
273
- '_signUnstakeAssets',
274
- ] as const
275
-
276
263
  /**
277
264
  * Call one signer export and wait for its result. A `{error}` result becomes a
278
265
  * {@link PerpsError} with code `SignatureInvalid`.
@@ -451,9 +438,11 @@ async function loadWasmUncached(): Promise<LighterWasmExports> {
451
438
  ;(exports as Record<string, unknown>)[name] = fn
452
439
  delete globals[name]
453
440
  }
454
- for (const name of UNUSED_WASM_FUNCTION_NAMES) {
441
+ for (const name of lighterWasmGlobalNames) {
455
442
  delete globals[name]
456
443
  }
444
+ // The protocol version is metadata, not a manifest export.
445
+ delete globals._signerVersion
457
446
 
458
447
  return exports as LighterWasmExports
459
448
  }
@@ -10,11 +10,12 @@ import {
10
10
  isDecimalStringZero,
11
11
  safeAddDecimalString,
12
12
  safeDivideDecimalString,
13
+ safeIsDecimalStringZero,
13
14
  safeMultiplyDecimalString,
14
15
  warnSkippedVenueRow,
15
16
  } from '@lifi/perps-sdk'
16
- import type { Fill, MarketDisplay } from '@lifi/perps-types'
17
- import { LiquidityRole, OrderSide, OrderType } from '@lifi/perps-types'
17
+ import type { Fill, FillLiquidation, MarketDisplay } from '@lifi/perps-types'
18
+ import { LiquidationMethod, LiquidityRole, OrderSide } from '@lifi/perps-types'
18
19
  import { LIGHTER_FEE_TICK_SCALE, LIGHTER_PROVIDER_KEY } from '../constants.js'
19
20
  import type { LtTrade } from '../types/index.js'
20
21
  import { leverageFromScaledImf } from './mapPosition.js'
@@ -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,13 @@ export const mapFill = (
122
143
  accountIndex: number,
123
144
  market: MarketDisplay
124
145
  ): Fill | undefined => {
125
- const { size, price } = trade
146
+ const { size } = trade
147
+ // Lighter reports a zero `price` on a `deleverage` row, but `usd_amount`
148
+ // still carries the execution notional.
149
+ const price =
150
+ trade.type === 'deleverage' && safeIsDecimalStringZero(trade.price) === true
151
+ ? (safeDivideDecimalString(trade.usd_amount, size) ?? trade.price)
152
+ : trade.price
126
153
  const createdAt = rowTimestampToIsoStringOrUndefined(trade.timestamp)
127
154
  if (createdAt === undefined) {
128
155
  warnSkippedVenueRow(
@@ -159,13 +186,13 @@ export const mapFill = (
159
186
  feeTick === undefined
160
187
  ? undefined
161
188
  : tickToFeeAmount(trade.usd_amount, feeTick, integratorFeeTick)
189
+ const liquidation = mapFillLiquidation(trade.type, isMaker)
162
190
 
163
191
  return {
164
192
  id: trade.trade_id_str,
165
193
  orderId: isBuyer ? trade.bid_id_str : trade.ask_id_str,
166
194
  market,
167
195
  side: isBuyer ? OrderSide.BUY : OrderSide.SELL,
168
- type: OrderType.LIMIT,
169
196
  size,
170
197
  price,
171
198
  liquidity: isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
@@ -192,5 +219,6 @@ export const mapFill = (
192
219
  explorerLink: isPlaceholderTxHash(trade.tx_hash)
193
220
  ? undefined
194
221
  : explorerTxUrl(ExplorerChainId.LIGHTER, trade.tx_hash),
222
+ ...(liquidation === undefined ? {} : { liquidation }),
195
223
  }
196
224
  }
@@ -221,6 +221,7 @@ export const mapOrder = (
221
221
  price: order.price,
222
222
  timeInForce: mapTimeInForce(order.time_in_force),
223
223
  ...(expiresAt === undefined ? {} : { expiresAt }),
224
+ ...(order.type === 'liquidation' ? { isLiquidation: true } : {}),
224
225
  }
225
226
  }
226
227
  }
@@ -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: pos.liquidation_price,
130
+ ...(hasLiquidationPrice ? { liquidationPrice } : {}),
125
131
  unrealizedPnl: pos.unrealized_pnl,
126
132
  accruedFunding: pos.total_funding_paid_out ?? '0',
127
133
  ...(leverage === undefined ? {} : { leverage }),