@lifi/perps-sdk 1.6.0 → 2.1.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 (70) hide show
  1. package/dist/cjs/client/PerpsClient.d.ts +9 -4
  2. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  3. package/dist/cjs/client/PerpsClient.js +36 -4
  4. package/dist/cjs/client/PerpsClient.js.map +1 -1
  5. package/dist/cjs/index.d.ts +2 -2
  6. package/dist/cjs/index.d.ts.map +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/types/api.d.ts +11 -1
  9. package/dist/cjs/types/api.d.ts.map +1 -1
  10. package/dist/cjs/types/config.d.ts +1 -0
  11. package/dist/cjs/types/config.d.ts.map +1 -1
  12. package/dist/cjs/types/provider.d.ts +1 -0
  13. package/dist/cjs/types/provider.d.ts.map +1 -1
  14. package/dist/cjs/utils/accountSummary.d.ts +1 -1
  15. package/dist/cjs/utils/accountSummary.d.ts.map +1 -1
  16. package/dist/cjs/utils/accountSummary.js +6 -2
  17. package/dist/cjs/utils/accountSummary.js.map +1 -1
  18. package/dist/cjs/utils/switchChain.d.ts +5 -0
  19. package/dist/cjs/utils/switchChain.d.ts.map +1 -0
  20. package/dist/cjs/utils/switchChain.js +39 -0
  21. package/dist/cjs/utils/switchChain.js.map +1 -0
  22. package/dist/cjs/version.d.ts +1 -1
  23. package/dist/cjs/version.js +1 -1
  24. package/dist/esm/client/PerpsClient.d.ts +42 -7
  25. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  26. package/dist/esm/client/PerpsClient.js +69 -7
  27. package/dist/esm/client/PerpsClient.js.map +1 -1
  28. package/dist/esm/index.d.ts +2 -2
  29. package/dist/esm/index.d.ts.map +1 -1
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/types/api.d.ts +28 -7
  32. package/dist/esm/types/api.d.ts.map +1 -1
  33. package/dist/esm/types/config.d.ts +11 -0
  34. package/dist/esm/types/config.d.ts.map +1 -1
  35. package/dist/esm/types/provider.d.ts +11 -0
  36. package/dist/esm/types/provider.d.ts.map +1 -1
  37. package/dist/esm/utils/accountSummary.d.ts +4 -1
  38. package/dist/esm/utils/accountSummary.d.ts.map +1 -1
  39. package/dist/esm/utils/accountSummary.js +6 -2
  40. package/dist/esm/utils/accountSummary.js.map +1 -1
  41. package/dist/esm/utils/switchChain.d.ts +21 -0
  42. package/dist/esm/utils/switchChain.d.ts.map +1 -0
  43. package/dist/esm/utils/switchChain.js +51 -0
  44. package/dist/esm/utils/switchChain.js.map +1 -0
  45. package/dist/esm/version.d.ts +1 -1
  46. package/dist/esm/version.js +1 -1
  47. package/dist/types/client/PerpsClient.d.ts +42 -7
  48. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  49. package/dist/types/index.d.ts +2 -2
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/types/types/api.d.ts +28 -7
  52. package/dist/types/types/api.d.ts.map +1 -1
  53. package/dist/types/types/config.d.ts +11 -0
  54. package/dist/types/types/config.d.ts.map +1 -1
  55. package/dist/types/types/provider.d.ts +11 -0
  56. package/dist/types/types/provider.d.ts.map +1 -1
  57. package/dist/types/utils/accountSummary.d.ts +4 -1
  58. package/dist/types/utils/accountSummary.d.ts.map +1 -1
  59. package/dist/types/utils/switchChain.d.ts +21 -0
  60. package/dist/types/utils/switchChain.d.ts.map +1 -0
  61. package/dist/types/version.d.ts +1 -1
  62. package/package.json +2 -2
  63. package/src/client/PerpsClient.ts +86 -9
  64. package/src/index.ts +3 -2
  65. package/src/types/api.ts +33 -7
  66. package/src/types/config.ts +14 -0
  67. package/src/types/provider.ts +11 -0
  68. package/src/utils/accountSummary.ts +10 -3
  69. package/src/utils/switchChain.ts +73 -0
  70. package/src/version.ts +1 -1
package/src/types/api.ts CHANGED
@@ -14,7 +14,11 @@ import type {
14
14
  } from '@lifi/perps-types'
15
15
  import type { Account, Address, WalletClient } from 'viem'
16
16
  import type { RetryConfig } from '../transport/retryPolicy.js'
17
- import type { ProviderConfigs, RequestInterceptor } from './config.js'
17
+ import type {
18
+ ProviderConfigs,
19
+ RequestInterceptor,
20
+ SwitchChainHook,
21
+ } from './config.js'
18
22
  import type { PerpsProviderPlugin } from './provider.js'
19
23
 
20
24
  /**
@@ -85,6 +89,12 @@ export interface PerpsClientOptions {
85
89
  * a keyed `ProviderConfigs` map.
86
90
  */
87
91
  providers?: PerpsProviderPlugin[] | ProviderConfigs
92
+ /**
93
+ * Hook invoked before a USER-signed EIP-712 action is signed, to switch the
94
+ * user's wallet to the action's target chain. Also settable at runtime via
95
+ * `setSwitchChain`.
96
+ */
97
+ switchChain?: SwitchChainHook
88
98
  }
89
99
 
90
100
  /**
@@ -145,6 +155,22 @@ export interface WithdrawParams {
145
155
  withdrawal: WithdrawalParams
146
156
  }
147
157
 
158
+ /**
159
+ * Parameters for {@link PerpsClient.sendAsset}. The send-asset fields are held
160
+ * flat (not nested) to avoid colliding with `@lifi/perps-types`'
161
+ * `SendAssetParams`, which types the underlying action payload.
162
+ *
163
+ * @public
164
+ */
165
+ export interface SendAssetActionParams {
166
+ provider: string
167
+ address: Address
168
+ collateral: string
169
+ sourceDex: string
170
+ destinationDex: string
171
+ amount: string
172
+ }
173
+
148
174
  /**
149
175
  * Parameters for canceling orders.
150
176
  *
@@ -153,7 +179,11 @@ export interface WithdrawParams {
153
179
  export interface CancelOrdersParams {
154
180
  provider: string
155
181
  address: Address
182
+ /** Venue order ids. Venues whose ids are scoped per market (e.g. Lighter's
183
+ * `order_index`) also accept the composite `"<market_id>:<order_id>"`. */
156
184
  ids: string[]
185
+ /** Market context for per-market order ids; the order's `market.id`. */
186
+ assetId?: string
157
187
  }
158
188
 
159
189
  /**
@@ -205,9 +235,7 @@ export interface ProviderSetup {
205
235
  }
206
236
 
207
237
  /**
208
- * Parameters for {@link PerpsClient.executeProviderSetup}.
209
- *
210
- * @public
238
+ * Parameters for the internal `PerpsClient.executeProviderSetup` batch submit.
211
239
  */
212
240
  export interface ExecuteProviderSetupParams {
213
241
  /** Provider to satisfy setup for */
@@ -221,9 +249,7 @@ export interface ExecuteProviderSetupParams {
221
249
  }
222
250
 
223
251
  /**
224
- * Result from {@link PerpsClient.executeProviderSetup}.
225
- *
226
- * @public
252
+ * Result from the internal `PerpsClient.executeProviderSetup` batch submit.
227
253
  */
228
254
  export interface ExecuteProviderSetupResult {
229
255
  results: ExecuteActionResponse
@@ -9,6 +9,20 @@ import type { RetryConfig } from '../transport/retryPolicy.js'
9
9
  */
10
10
  export type PerpsClientSigner = WalletClient<any, any, Account>
11
11
 
12
+ /**
13
+ * Consumer-supplied hook invoked at the SDK's signing choke point to switch the
14
+ * user's wallet to a USER-signed EIP-712 action's target chain. Modelled on
15
+ * `@lifi/sdk`'s switch-chain contract: a json-rpc wallet switches in place and
16
+ * resolves to the re-fetched client; a local/private-key signer resolves to a
17
+ * chain-bound client (or signs offline). Resolve to `undefined` to signal the
18
+ * switch could not be performed.
19
+ *
20
+ * @public
21
+ */
22
+ export type SwitchChainHook = (
23
+ chainId: number
24
+ ) => Promise<PerpsClientSigner | undefined>
25
+
12
26
  /**
13
27
  * Per-provider config — restricts which `markets` the WS client subscribes
14
28
  * to. Indexed by provider key.
@@ -63,6 +63,17 @@ export interface SignActionsContext {
63
63
  * forwards the descriptor's `signers` as data; it does not branch on them.
64
64
  */
65
65
  signers?: PerpsSigner[]
66
+ /**
67
+ * Switch `userWallet` to `chainId` and resolve the client to broadcast with.
68
+ * Bound by core to the consumer's `switchChain` hook and the resolved
69
+ * `userWallet`: a no-op returning the same client when already on `chainId`,
70
+ * else it switches and re-verifies, rejecting with `PerpsErrorCode.SDKError`
71
+ * when the switch cannot be completed. Present only when a `switchChain` hook
72
+ * is configured; a plugin whose legs broadcast on-chain (Lighter's `EVM_TX`)
73
+ * calls it per leg, and falls back to a fail-loud wrong-chain guard when it is
74
+ * absent (local/private-key signer, or no hook).
75
+ */
76
+ switchToChain?: (chainId: number) => Promise<PerpsClientSigner>
66
77
  }
67
78
 
68
79
  /**
@@ -15,6 +15,9 @@ const sumValueUsd = (balances: AccountResponse['balances']): number =>
15
15
  * - `'free'` — free collateral only; locked margin and unrealized PnL are
16
16
  * both carried by the positions. Available margin is the free collateral
17
17
  * as-is; unrealized PnL is not counted toward it.
18
+ * - `'net'` — free collateral with unrealized PnL already marked in; only
19
+ * the locked margin is carried by the positions (e.g. a venue-reported
20
+ * available balance).
18
21
  * - `'gross'` — locked margin included, unrealized PnL carried by the
19
22
  * positions (e.g. spot holdings backing a unified account). The venue
20
23
  * counts unrealized PnL toward buying power, so it is added to available
@@ -25,7 +28,7 @@ const sumValueUsd = (balances: AccountResponse['balances']): number =>
25
28
  *
26
29
  * @public
27
30
  */
28
- export type CollateralSemantics = 'free' | 'gross' | 'equity'
31
+ export type CollateralSemantics = 'free' | 'net' | 'gross' | 'equity'
29
32
 
30
33
  /**
31
34
  * Roll an {@link AccountResponse} and its open positions up into an
@@ -51,9 +54,13 @@ export function summarizeAccount(
51
54
  const balances = sumValueUsd(account.balances)
52
55
 
53
56
  const grossCollateral =
54
- semantics === 'free' ? collateral + marginUsed : collateral
57
+ semantics === 'free' || semantics === 'net'
58
+ ? collateral + marginUsed
59
+ : collateral
55
60
  const equity =
56
- semantics === 'equity' ? grossCollateral : grossCollateral + unrealizedPnl
61
+ semantics === 'equity' || semantics === 'net'
62
+ ? grossCollateral
63
+ : grossCollateral + unrealizedPnl
57
64
 
58
65
  // Buying power is equity net of locked margin, so unrealized PnL counts
59
66
  // toward it. The `'free'` rows exclude uPnL from available margin, holding
@@ -0,0 +1,73 @@
1
+ import type {
2
+ ActionStep,
3
+ Eip712ActionStep,
4
+ ProviderAction,
5
+ } from '@lifi/perps-types'
6
+ import { PerpsErrorCode, PerpsSigner, SigningMethod } from '@lifi/perps-types'
7
+ import { getChainId } from 'viem/actions'
8
+ import { PerpsError } from '../errors/PerpsError.js'
9
+ import type { PerpsClientSigner, SwitchChainHook } from '../types/config.js'
10
+
11
+ /**
12
+ * The chain a batch of `actions` must be signed on, or `undefined` when no
13
+ * wallet chain switch applies. Only USER-signed EIP-712 batches carry a target
14
+ * (agent-signed batches sign with a chain-bound keypair; other schemes are not
15
+ * EIP-712). Reads the first numeric `typedData.domain.chainId`; a batch whose
16
+ * steps omit `chainId` yields `undefined`.
17
+ */
18
+ export function userEip712TargetChainId(
19
+ descriptor: ProviderAction,
20
+ actions: ActionStep[]
21
+ ): number | undefined {
22
+ if (
23
+ descriptor.signingMethod !== SigningMethod.EIP712 ||
24
+ !descriptor.signers.includes(PerpsSigner.USER)
25
+ ) {
26
+ return undefined
27
+ }
28
+ for (const step of actions) {
29
+ const chainId = (step as Eip712ActionStep).typedData?.domain?.chainId
30
+ if (typeof chainId === 'number') {
31
+ return chainId
32
+ }
33
+ }
34
+ return undefined
35
+ }
36
+
37
+ /**
38
+ * Ensure `wallet` is on `targetChainId` before signing, returning the wallet to
39
+ * sign with. Without a `switchChain` hook the wallet is returned unchanged (no
40
+ * throw, no RPC) — a local/private-key signer signs EIP-712 offline regardless
41
+ * of its transport chain. With a hook: probe the current chain via viem
42
+ * `getChainId`, return the wallet untouched when already on target, else invoke
43
+ * the hook and re-verify. Throws `PerpsErrorCode.SDKError` when the hook yields
44
+ * no client or a client still on the wrong chain.
45
+ */
46
+ export async function switchSigningChain(
47
+ wallet: PerpsClientSigner,
48
+ targetChainId: number,
49
+ switchChain?: SwitchChainHook
50
+ ): Promise<PerpsClientSigner> {
51
+ if (!switchChain) {
52
+ return wallet
53
+ }
54
+ const currentChainId = await getChainId(wallet)
55
+ if (currentChainId === targetChainId) {
56
+ return wallet
57
+ }
58
+ const switched = await switchChain(targetChainId)
59
+ if (!switched) {
60
+ throw new PerpsError(
61
+ PerpsErrorCode.SDKError,
62
+ `Wallet chain switch to ${targetChainId} was not completed.`
63
+ )
64
+ }
65
+ const switchedChainId = await getChainId(switched)
66
+ if (switchedChainId !== targetChainId) {
67
+ throw new PerpsError(
68
+ PerpsErrorCode.SDKError,
69
+ `Wallet is on chain ${switchedChainId} but chain ${targetChainId} is required to sign.`
70
+ )
71
+ }
72
+ return switched
73
+ }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/perps-sdk'
2
- export const version = '1.6.0'
2
+ export const version = '2.1.0'