@lifi/perps-types 0.1.1-alpha.21 → 0.1.1-alpha.23

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 (83) hide show
  1. package/package.json +18 -4
  2. package/providers/lighter/package.json +5 -0
  3. package/src/_cjs/enums.js +19 -1
  4. package/src/_cjs/enums.js.map +1 -1
  5. package/src/_cjs/providers/hyperliquid/mappers/fill.js +2 -0
  6. package/src/_cjs/providers/hyperliquid/mappers/fill.js.map +1 -1
  7. package/src/_cjs/providers/hyperliquid/types.js +8 -1
  8. package/src/_cjs/providers/hyperliquid/types.js.map +1 -1
  9. package/src/_cjs/providers/lighter/apiTypes.js +3 -0
  10. package/src/_cjs/providers/lighter/apiTypes.js.map +1 -0
  11. package/src/_cjs/providers/lighter/index.js +20 -0
  12. package/src/_cjs/providers/lighter/index.js.map +1 -0
  13. package/src/_cjs/providers/lighter/mappers/fill.js +30 -0
  14. package/src/_cjs/providers/lighter/mappers/fill.js.map +1 -0
  15. package/src/_cjs/providers/lighter/mappers/index.js +11 -0
  16. package/src/_cjs/providers/lighter/mappers/index.js.map +1 -0
  17. package/src/_cjs/providers/lighter/mappers/order.js +84 -0
  18. package/src/_cjs/providers/lighter/mappers/order.js.map +1 -0
  19. package/src/_cjs/providers/lighter/mappers/position.js +33 -0
  20. package/src/_cjs/providers/lighter/mappers/position.js.map +1 -0
  21. package/src/_cjs/providers/lighter/types.js +23 -0
  22. package/src/_cjs/providers/lighter/types.js.map +1 -0
  23. package/src/_esm/enums.js +18 -0
  24. package/src/_esm/enums.js.map +1 -1
  25. package/src/_esm/providers/hyperliquid/mappers/fill.js +3 -1
  26. package/src/_esm/providers/hyperliquid/mappers/fill.js.map +1 -1
  27. package/src/_esm/providers/hyperliquid/types.js +10 -0
  28. package/src/_esm/providers/hyperliquid/types.js.map +1 -1
  29. package/src/_esm/providers/lighter/apiTypes.js +5 -0
  30. package/src/_esm/providers/lighter/apiTypes.js.map +1 -0
  31. package/src/_esm/providers/lighter/index.js +4 -0
  32. package/src/_esm/providers/lighter/index.js.map +1 -0
  33. package/src/_esm/providers/lighter/mappers/fill.js +32 -0
  34. package/src/_esm/providers/lighter/mappers/fill.js.map +1 -0
  35. package/src/_esm/providers/lighter/mappers/index.js +4 -0
  36. package/src/_esm/providers/lighter/mappers/index.js.map +1 -0
  37. package/src/_esm/providers/lighter/mappers/order.js +91 -0
  38. package/src/_esm/providers/lighter/mappers/order.js.map +1 -0
  39. package/src/_esm/providers/lighter/mappers/position.js +34 -0
  40. package/src/_esm/providers/lighter/mappers/position.js.map +1 -0
  41. package/src/_esm/providers/lighter/types.js +30 -0
  42. package/src/_esm/providers/lighter/types.js.map +1 -0
  43. package/src/_types/account.d.ts +17 -2
  44. package/src/_types/account.d.ts.map +1 -1
  45. package/src/_types/action.d.ts +61 -3
  46. package/src/_types/action.d.ts.map +1 -1
  47. package/src/_types/enums.d.ts +19 -3
  48. package/src/_types/enums.d.ts.map +1 -1
  49. package/src/_types/providers/hyperliquid/mappers/fill.d.ts.map +1 -1
  50. package/src/_types/providers/hyperliquid/types.d.ts +10 -0
  51. package/src/_types/providers/hyperliquid/types.d.ts.map +1 -1
  52. package/src/_types/providers/lighter/apiTypes.d.ts +74 -0
  53. package/src/_types/providers/lighter/apiTypes.d.ts.map +1 -0
  54. package/src/_types/providers/lighter/index.d.ts +4 -0
  55. package/src/_types/providers/lighter/index.d.ts.map +1 -0
  56. package/src/_types/providers/lighter/mappers/fill.d.ts +10 -0
  57. package/src/_types/providers/lighter/mappers/fill.d.ts.map +1 -0
  58. package/src/_types/providers/lighter/mappers/index.d.ts +4 -0
  59. package/src/_types/providers/lighter/mappers/index.d.ts.map +1 -0
  60. package/src/_types/providers/lighter/mappers/order.d.ts +15 -0
  61. package/src/_types/providers/lighter/mappers/order.d.ts.map +1 -0
  62. package/src/_types/providers/lighter/mappers/position.d.ts +9 -0
  63. package/src/_types/providers/lighter/mappers/position.d.ts.map +1 -0
  64. package/src/_types/providers/lighter/types.d.ts +90 -0
  65. package/src/_types/providers/lighter/types.d.ts.map +1 -0
  66. package/src/_types/providers.d.ts +40 -2
  67. package/src/_types/providers.d.ts.map +1 -1
  68. package/src/_types/typedData.d.ts +13 -5
  69. package/src/_types/typedData.d.ts.map +1 -1
  70. package/src/account.ts +18 -0
  71. package/src/action.ts +80 -3
  72. package/src/enums.ts +18 -0
  73. package/src/providers/hyperliquid/mappers/fill.ts +3 -0
  74. package/src/providers/hyperliquid/types.ts +29 -0
  75. package/src/providers/lighter/apiTypes.ts +84 -0
  76. package/src/providers/lighter/index.ts +3 -0
  77. package/src/providers/lighter/mappers/fill.ts +48 -0
  78. package/src/providers/lighter/mappers/index.ts +3 -0
  79. package/src/providers/lighter/mappers/order.ts +105 -0
  80. package/src/providers/lighter/mappers/position.ts +43 -0
  81. package/src/providers/lighter/types.ts +115 -0
  82. package/src/providers.ts +41 -2
  83. package/src/typedData.ts +15 -5
@@ -0,0 +1,48 @@
1
+ import {
2
+ FillClassification,
3
+ FillStatus,
4
+ LiquidityRole,
5
+ OrderSide,
6
+ OrderType,
7
+ } from '../../../enums.js'
8
+ import type { Fill } from '../../../account.js'
9
+ import type { LtTrade } from '../apiTypes.js'
10
+
11
+ const classifyFill = (isBuy: boolean): FillClassification =>
12
+ isBuy ? FillClassification.OPENED_LONG : FillClassification.OPENED_SHORT
13
+
14
+ /**
15
+ * Map a raw Lighter trade to the generic Fill type.
16
+ * @param trade - Raw trade from REST or WS
17
+ * @param accountIndex - The viewer's Lighter account index (to determine buy/sell side)
18
+ * @param symbol - Resolved symbol (market_id → symbol lookup)
19
+ */
20
+ export const mapFill = (
21
+ trade: LtTrade,
22
+ accountIndex: number,
23
+ symbol: string
24
+ ): Fill => {
25
+ const isBuyer = trade.bid_account_id === accountIndex
26
+ const isMaker =
27
+ (trade.is_maker_ask && !isBuyer) || (!trade.is_maker_ask && isBuyer)
28
+
29
+ return {
30
+ id: trade.trade_id.toString(),
31
+ orderId: String(isBuyer ? trade.bid_id : trade.ask_id),
32
+ asset: {
33
+ assetId: symbol,
34
+ market: 'lighter',
35
+ displaySymbol: symbol,
36
+ displayQuote: 'USDC',
37
+ },
38
+ side: isBuyer ? OrderSide.BUY : OrderSide.SELL,
39
+ type: OrderType.LIMIT,
40
+ size: trade.size,
41
+ price: trade.price,
42
+ status: FillStatus.FILLED,
43
+ liquidity: isMaker ? LiquidityRole.MAKER : LiquidityRole.TAKER,
44
+ fee: isMaker ? trade.maker_fee?.toString() : trade.taker_fee?.toString(),
45
+ classification: classifyFill(isBuyer),
46
+ createdAt: new Date(trade.timestamp).toISOString(),
47
+ }
48
+ }
@@ -0,0 +1,3 @@
1
+ export { mapPosition } from './position.js'
2
+ export { mapFill } from './fill.js'
3
+ export { mapOrder, mapOrderDetail } from './order.js'
@@ -0,0 +1,105 @@
1
+ import {
2
+ OrderSide,
3
+ OrderStatus,
4
+ OrderType,
5
+ TimeInForce,
6
+ } from '../../../enums.js'
7
+ import type { OpenOrder } from '../../../account.js'
8
+ import type { Order } from '../../../action.js'
9
+ import type { LtOrder } from '../apiTypes.js'
10
+
11
+ // Lighter's `type` enum uses hyphens in the OpenAPI spec but earlier API
12
+ // versions emitted underscores. Tolerate both so we don't silently fall
13
+ // through to LIMIT for stop/take-profit orders.
14
+ const mapOrderType = (ltType: string): OrderType => {
15
+ const normalized = ltType.replace(/-/g, '_')
16
+ const map: Record<string, OrderType> = {
17
+ limit: OrderType.LIMIT,
18
+ market: OrderType.MARKET,
19
+ stop_loss: OrderType.STOP_MARKET,
20
+ stop_loss_limit: OrderType.STOP_LIMIT,
21
+ take_profit: OrderType.TAKE_PROFIT_MARKET,
22
+ take_profit_limit: OrderType.TAKE_PROFIT_LIMIT,
23
+ }
24
+ return map[normalized] ?? OrderType.LIMIT
25
+ }
26
+
27
+ const mapTimeInForce = (tif: string): TimeInForce | undefined => {
28
+ switch (tif.replace(/-/g, '_')) {
29
+ case 'good_till_time':
30
+ return TimeInForce.GTT
31
+ case 'immediate_or_cancel':
32
+ return TimeInForce.IOC
33
+ case 'post_only':
34
+ return TimeInForce.POST_ONLY
35
+ default:
36
+ return undefined
37
+ }
38
+ }
39
+
40
+ const mapOrderStatus = (status: string): OrderStatus => {
41
+ if (
42
+ status === 'open' ||
43
+ status === 'in-progress' ||
44
+ status === 'in_progress'
45
+ ) {
46
+ return OrderStatus.OPEN
47
+ }
48
+ if (status === 'pending') {
49
+ return OrderStatus.PENDING
50
+ }
51
+ if (status === 'filled') {
52
+ return OrderStatus.FILLED
53
+ }
54
+ if (status.startsWith('canceled')) {
55
+ return OrderStatus.CANCELLED
56
+ }
57
+ return OrderStatus.OPEN
58
+ }
59
+
60
+ /**
61
+ * Map a raw Lighter order to the generic OpenOrder type.
62
+ * @param order - Raw order from REST or WS
63
+ * @param symbol - Resolved symbol (market_index → symbol lookup)
64
+ */
65
+ export const mapOrder = (order: LtOrder, symbol: string): OpenOrder => ({
66
+ id: order.order_id,
67
+ asset: {
68
+ assetId: symbol,
69
+ market: 'lighter',
70
+ displaySymbol: symbol,
71
+ displayQuote: 'USDC',
72
+ },
73
+ side: order.is_ask ? OrderSide.SELL : OrderSide.BUY,
74
+ type: mapOrderType(order.type),
75
+ size: order.initial_base_amount,
76
+ price: order.price,
77
+ filledSize: order.filled_base_amount,
78
+ reduceOnly: order.reduce_only,
79
+ createdAt: new Date(order.created_at * 1000).toISOString(),
80
+ })
81
+
82
+ /**
83
+ * Map a raw Lighter order to the rich Order type used by getOrder.
84
+ * Includes status, time-in-force, and remaining/filled sizes.
85
+ */
86
+ export const mapOrderDetail = (order: LtOrder, symbol: string): Order => ({
87
+ orderId: order.order_id,
88
+ asset: {
89
+ assetId: symbol,
90
+ market: 'lighter',
91
+ displaySymbol: symbol,
92
+ displayQuote: 'USDC',
93
+ },
94
+ side: order.is_ask ? OrderSide.SELL : OrderSide.BUY,
95
+ type: mapOrderType(order.type),
96
+ price: order.price,
97
+ originalSize: order.initial_base_amount,
98
+ remainingSize: order.remaining_base_amount,
99
+ filledSize: order.filled_base_amount,
100
+ timeInForce: mapTimeInForce(order.time_in_force),
101
+ reduceOnly: order.reduce_only,
102
+ status: mapOrderStatus(order.status),
103
+ createdAt: new Date(order.created_at * 1000).toISOString(),
104
+ updatedAt: new Date(order.updated_at * 1000).toISOString(),
105
+ })
@@ -0,0 +1,43 @@
1
+ import { MarginMode, PositionSide } from '../../../enums.js'
2
+ import type { Position } from '../../../account.js'
3
+ import type { LtAccountPosition } from '../apiTypes.js'
4
+ import { LT_MARGIN_MODE_ISOLATED } from '../types.js'
5
+
6
+ /**
7
+ * Map a raw Lighter account position to the generic Position type.
8
+ * @param pos - Raw position from REST or WS
9
+ * @param symbol - Resolved symbol (market_id → symbol lookup, or pos.symbol)
10
+ */
11
+ export const mapPosition = (
12
+ pos: LtAccountPosition,
13
+ symbol: string
14
+ ): Position => {
15
+ const size = parseFloat(pos.position)
16
+
17
+ return {
18
+ asset: {
19
+ assetId: symbol,
20
+ market: 'lighter',
21
+ displaySymbol: symbol,
22
+ displayQuote: 'USDC',
23
+ },
24
+ side: pos.sign >= 0 ? PositionSide.LONG : PositionSide.SHORT,
25
+ size: Math.abs(size).toString(),
26
+ entryPrice: pos.avg_entry_price,
27
+ markPrice:
28
+ pos.position_value === '0' || size === 0
29
+ ? '0'
30
+ : (parseFloat(pos.position_value) / Math.abs(size)).toString(),
31
+ liquidationPrice: pos.liquidation_price,
32
+ unrealizedPnl: pos.unrealized_pnl,
33
+ leverage:
34
+ parseFloat(pos.initial_margin_fraction) > 0
35
+ ? Math.round(100 / parseFloat(pos.initial_margin_fraction))
36
+ : 1,
37
+ marginUsed: pos.allocated_margin,
38
+ marginMode:
39
+ pos.margin_mode === LT_MARGIN_MODE_ISOLATED
40
+ ? MarginMode.ISOLATED
41
+ : MarginMode.CROSS,
42
+ }
43
+ }
@@ -0,0 +1,115 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Lighter WASM signer parameter types
3
+ //
4
+ // These define the exact shapes that `wasmSignParams` takes for each Lighter
5
+ // action type. The backend populates these; the SDK passes them to the WASM
6
+ // signer along with SDK-managed fields (nonce, account_index, api_key_index).
7
+ // ---------------------------------------------------------------------------
8
+
9
+ /** Backend-provided params for SignCreateOrder. */
10
+ export type LtCreateOrderWasmParams = {
11
+ market_index: number
12
+ client_order_index: number
13
+ base_amount: number
14
+ price: number
15
+ is_ask: number
16
+ order_type: number
17
+ time_in_force: number
18
+ reduce_only: boolean
19
+ trigger_price: number
20
+ order_expiry: number
21
+ integrator_account_index: number
22
+ integrator_taker_fee: number
23
+ integrator_maker_fee: number
24
+ }
25
+
26
+ /** Backend-provided params for SignCancelOrder. */
27
+ export type LtCancelOrderWasmParams = {
28
+ market_index: number
29
+ order_index: number
30
+ }
31
+
32
+ /** Backend-provided params for SignModifyOrder. */
33
+ export type LtModifyOrderWasmParams = {
34
+ market_index: number
35
+ order_index: number
36
+ base_amount: number
37
+ price: number
38
+ trigger_price: number
39
+ integrator_account_index: number
40
+ integrator_taker_fee: number
41
+ integrator_maker_fee: number
42
+ }
43
+
44
+ /** Backend-provided params for SignUpdateLeverage. */
45
+ export type LtUpdateLeverageWasmParams = {
46
+ market_index: number
47
+ fraction: number
48
+ margin_mode: number
49
+ }
50
+
51
+ /** Backend-provided params for SignUpdateMargin. */
52
+ export type LtUpdateMarginWasmParams = {
53
+ market_index: number
54
+ usdc_amount: number
55
+ direction: number
56
+ }
57
+
58
+ /** Backend-provided params for SignWithdraw. */
59
+ export type LtWithdrawWasmParams = {
60
+ asset_index: number
61
+ route_type: number
62
+ amount: number
63
+ }
64
+
65
+ /** Backend-provided params for SignCancelAllOrders. */
66
+ export type LtCancelAllOrdersWasmParams = {
67
+ /** 0=immediate (cancel GTC), 1=scheduled, 2=abort scheduled */
68
+ time_in_force: number
69
+ /** Unix timestamp in milliseconds. Use Date.now() for immediate cancels. */
70
+ timestamp_ms: number
71
+ }
72
+
73
+ /**
74
+ * Backend-provided params for SignChangePubKey (REGISTER_API_KEY).
75
+ *
76
+ * NOTE: `new_public_key` is a placeholder here — the SDK generates the actual
77
+ * keypair via the WASM signer and fills this in before calling SignChangePubKey.
78
+ * This action also requires an L1 Ethereum signature (the user's wallet signs
79
+ * the ChangePubKey message), so it is a hybrid: WASM blob + EIP-191 eth_sign.
80
+ */
81
+ export type LtChangePubKeyWasmParams = {
82
+ /** API key slot index to register (0-255). SDK fills in the generated public key. */
83
+ api_key_index: number
84
+ nonce: number
85
+ }
86
+
87
+ // ---------------------------------------------------------------------------
88
+ // Lighter WASM signer constants
89
+ // ---------------------------------------------------------------------------
90
+
91
+ export const LT_ORDER_TYPE_LIMIT = 0
92
+ export const LT_ORDER_TYPE_MARKET = 1
93
+ export const LT_ORDER_TYPE_STOP_LOSS = 2
94
+ export const LT_ORDER_TYPE_STOP_LOSS_LIMIT = 3
95
+ export const LT_ORDER_TYPE_TAKE_PROFIT = 4
96
+ export const LT_ORDER_TYPE_TAKE_PROFIT_LIMIT = 5
97
+ export const LT_ORDER_TYPE_TWAP = 6
98
+
99
+ export const LT_TIME_IN_FORCE_IOC = 0
100
+ export const LT_TIME_IN_FORCE_GTC = 1
101
+ export const LT_TIME_IN_FORCE_POST_ONLY = 2
102
+
103
+ export const LT_MARGIN_MODE_CROSS = 0
104
+ export const LT_MARGIN_MODE_ISOLATED = 1
105
+
106
+ export const LT_MARGIN_DIRECTION_REMOVE = 0
107
+ export const LT_MARGIN_DIRECTION_ADD = 1
108
+
109
+ export const LT_ROUTE_PERP = 0
110
+ export const LT_ROUTE_SPOT = 1
111
+
112
+ export const LT_ASSET_ID_USDC = 3
113
+
114
+ export const LT_NIL_TRIGGER_PRICE = 0
115
+ export const LT_DEFAULT_ORDER_EXPIRY = -1
package/src/providers.ts CHANGED
@@ -1,8 +1,40 @@
1
- import type { ActionType, PerpsSigner } from './enums.js'
1
+ import type { ActionType, PerpsSigner, SigningMethod } from './enums.js'
2
2
 
3
3
  export interface ActionDescriptor {
4
4
  type: ActionType
5
5
  signers: PerpsSigner[]
6
+ /**
7
+ * How the SDK must sign this specific action. Most actions match the
8
+ * provider's dominant pattern (Hyperliquid: EIP712, Lighter: WASM_BLOB),
9
+ * but on-chain bridge actions like DEPOSIT are EVM_TX regardless of
10
+ * provider — the SDK dispatches by this field rather than by
11
+ * `Provider.signingMethod`.
12
+ */
13
+ signingMethod: SigningMethod
14
+ }
15
+
16
+ /**
17
+ * Self-documenting account-setup step the user must (or may) fulfill before
18
+ * trading with a given provider. Mirrors a single entry of the `config`
19
+ * object returned by `GET /perps/account` — that endpoint reports the
20
+ * *state* of these items, while `Provider.accountConfiguration` declares
21
+ * what items exist and how to fulfill them.
22
+ *
23
+ * Extends `ActionDescriptor` because each item resolves to exactly one
24
+ * action the SDK dispatches when the user proceeds; the additional fields
25
+ * are the presentation and gating metadata the widget needs to render the
26
+ * onboarding overlay without hardcoded labels.
27
+ *
28
+ * `optional: false` means the item must be fulfilled before the user can
29
+ * proceed; `optional: true` means the user may skip it.
30
+ */
31
+ export interface AccountConfigurationItem extends ActionDescriptor {
32
+ /** User-facing row title rendered in the onboarding overlay. */
33
+ title: string
34
+ /** User-facing description rendered in the onboarding overlay. */
35
+ description: string
36
+ /** When true the user may skip the item; when false it gates the trade flow. */
37
+ optional: boolean
6
38
  }
7
39
 
8
40
  export interface ProviderMarketInfo {
@@ -14,7 +46,14 @@ export interface Provider {
14
46
  key: string
15
47
  name: string
16
48
  logoURI: string
17
- prepareAccountActions: ActionDescriptor[]
49
+ signingMethod: SigningMethod
50
+ /**
51
+ * Account-setup items required (or optional) for trading with this
52
+ * provider. Replaces the previous `prepareAccountActions: ActionDescriptor[]`:
53
+ * same operational fields, plus the user-facing metadata the widget needs.
54
+ * An empty array is valid and indicates the provider has no setup gates.
55
+ */
56
+ accountConfiguration: AccountConfigurationItem[]
18
57
  actions: ActionDescriptor[]
19
58
  markets: ProviderMarketInfo[]
20
59
  wsUrl?: string
package/src/typedData.ts CHANGED
@@ -1,12 +1,22 @@
1
- import type { TypedData, SignedTypedData } from '@lifi/types'
2
1
  import type { Address, Hex, TypedDataDomain, TypedDataParameter } from 'viem'
2
+ import type { HlPrimaryType } from './providers/hyperliquid/types.js'
3
3
 
4
- export type PerpsTypedData = Omit<TypedData, 'primaryType'> & {
5
- primaryType: string
4
+ /**
5
+ * All known EIP-712 primaryType values across supported providers.
6
+ * Extend this union when adding a new EIP-712 provider.
7
+ */
8
+ export type PerpsPrimaryType = HlPrimaryType
9
+
10
+ export type PerpsTypedData = {
11
+ domain: TypedDataDomain
12
+ types: Record<string, readonly TypedDataParameter[]>
13
+ primaryType: PerpsPrimaryType
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ message: Record<string, any>
6
16
  }
7
17
 
8
- export type PerpsSignedTypedData = Omit<SignedTypedData, 'primaryType'> & {
9
- primaryType: string
18
+ export type PerpsSignedTypedData = PerpsTypedData & {
19
+ signature: Hex
10
20
  }
11
21
 
12
22
  // Re-export viem primitives used across perps types