@lifi/perps-sdk 25.0.2 → 27.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 (99) hide show
  1. package/README.md +66 -1
  2. package/dist/cjs/client/PerpsClient.d.ts +5 -5
  3. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  4. package/dist/cjs/client/PerpsClient.js +73 -75
  5. package/dist/cjs/client/PerpsClient.js.map +1 -1
  6. package/dist/cjs/errors/PerpsExecutionError.d.ts +9 -0
  7. package/dist/cjs/errors/PerpsExecutionError.d.ts.map +1 -0
  8. package/dist/cjs/errors/PerpsExecutionError.js +29 -0
  9. package/dist/cjs/errors/PerpsExecutionError.js.map +1 -0
  10. package/dist/cjs/index.d.ts +6 -4
  11. package/dist/cjs/index.d.ts.map +1 -1
  12. package/dist/cjs/index.js +16 -12
  13. package/dist/cjs/index.js.map +1 -1
  14. package/dist/cjs/math/fills.d.ts +0 -1
  15. package/dist/cjs/math/fills.d.ts.map +1 -1
  16. package/dist/cjs/math/fills.js +0 -18
  17. package/dist/cjs/math/fills.js.map +1 -1
  18. package/dist/cjs/math/order.d.ts +5 -5
  19. package/dist/cjs/math/order.d.ts.map +1 -1
  20. package/dist/cjs/math/order.js +10 -10
  21. package/dist/cjs/math/order.js.map +1 -1
  22. package/dist/cjs/math/position.d.ts +2 -2
  23. package/dist/cjs/math/position.d.ts.map +1 -1
  24. package/dist/cjs/math/position.js +5 -5
  25. package/dist/cjs/math/position.js.map +1 -1
  26. package/dist/cjs/types/api.d.ts +1 -10
  27. package/dist/cjs/types/api.d.ts.map +1 -1
  28. package/dist/cjs/types/provider.d.ts +5 -1
  29. package/dist/cjs/types/provider.d.ts.map +1 -1
  30. package/dist/cjs/utils/actionResult.d.ts +3 -0
  31. package/dist/cjs/utils/actionResult.d.ts.map +1 -0
  32. package/dist/cjs/utils/actionResult.js +9 -0
  33. package/dist/cjs/utils/actionResult.js.map +1 -0
  34. package/dist/cjs/version.d.ts +1 -1
  35. package/dist/cjs/version.js +1 -1
  36. package/dist/esm/client/PerpsClient.d.ts +64 -47
  37. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  38. package/dist/esm/client/PerpsClient.js +134 -128
  39. package/dist/esm/client/PerpsClient.js.map +1 -1
  40. package/dist/esm/errors/PerpsExecutionError.d.ts +24 -0
  41. package/dist/esm/errors/PerpsExecutionError.d.ts.map +1 -0
  42. package/dist/esm/errors/PerpsExecutionError.js +39 -0
  43. package/dist/esm/errors/PerpsExecutionError.js.map +1 -0
  44. package/dist/esm/index.d.ts +6 -4
  45. package/dist/esm/index.d.ts.map +1 -1
  46. package/dist/esm/index.js +5 -3
  47. package/dist/esm/index.js.map +1 -1
  48. package/dist/esm/math/fills.d.ts +0 -9
  49. package/dist/esm/math/fills.d.ts.map +1 -1
  50. package/dist/esm/math/fills.js +0 -25
  51. package/dist/esm/math/fills.js.map +1 -1
  52. package/dist/esm/math/order.d.ts +6 -6
  53. package/dist/esm/math/order.d.ts.map +1 -1
  54. package/dist/esm/math/order.js +6 -6
  55. package/dist/esm/math/order.js.map +1 -1
  56. package/dist/esm/math/position.d.ts +2 -2
  57. package/dist/esm/math/position.d.ts.map +1 -1
  58. package/dist/esm/math/position.js +3 -3
  59. package/dist/esm/math/position.js.map +1 -1
  60. package/dist/esm/types/api.d.ts +1 -18
  61. package/dist/esm/types/api.d.ts.map +1 -1
  62. package/dist/esm/types/provider.d.ts +21 -4
  63. package/dist/esm/types/provider.d.ts.map +1 -1
  64. package/dist/esm/utils/actionResult.d.ts +4 -0
  65. package/dist/esm/utils/actionResult.d.ts.map +1 -0
  66. package/dist/esm/utils/actionResult.js +7 -0
  67. package/dist/esm/utils/actionResult.js.map +1 -0
  68. package/dist/esm/version.d.ts +1 -1
  69. package/dist/esm/version.js +1 -1
  70. package/dist/types/client/PerpsClient.d.ts +64 -47
  71. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  72. package/dist/types/errors/PerpsExecutionError.d.ts +24 -0
  73. package/dist/types/errors/PerpsExecutionError.d.ts.map +1 -0
  74. package/dist/types/index.d.ts +6 -4
  75. package/dist/types/index.d.ts.map +1 -1
  76. package/dist/types/math/fills.d.ts +0 -9
  77. package/dist/types/math/fills.d.ts.map +1 -1
  78. package/dist/types/math/order.d.ts +6 -6
  79. package/dist/types/math/order.d.ts.map +1 -1
  80. package/dist/types/math/position.d.ts +2 -2
  81. package/dist/types/math/position.d.ts.map +1 -1
  82. package/dist/types/types/api.d.ts +1 -18
  83. package/dist/types/types/api.d.ts.map +1 -1
  84. package/dist/types/types/provider.d.ts +21 -4
  85. package/dist/types/types/provider.d.ts.map +1 -1
  86. package/dist/types/utils/actionResult.d.ts +4 -0
  87. package/dist/types/utils/actionResult.d.ts.map +1 -0
  88. package/dist/types/version.d.ts +1 -1
  89. package/package.json +2 -2
  90. package/src/client/PerpsClient.ts +165 -166
  91. package/src/errors/PerpsExecutionError.ts +54 -0
  92. package/src/index.ts +13 -8
  93. package/src/math/fills.ts +0 -29
  94. package/src/math/order.ts +11 -11
  95. package/src/math/position.ts +3 -3
  96. package/src/types/api.ts +0 -21
  97. package/src/types/provider.ts +22 -4
  98. package/src/utils/actionResult.ts +10 -0
  99. package/src/version.ts +1 -1
@@ -0,0 +1,54 @@
1
+ import {
2
+ type ActionResult,
3
+ type ExecuteActionResponse,
4
+ PerpsErrorCode,
5
+ } from '@lifi/perps-types'
6
+ import { PerpsError } from './PerpsError.js'
7
+
8
+ /**
9
+ * Error thrown when an execution stage fails after part of the execution
10
+ * report is known. `response` holds every result known at the failure, and
11
+ * `cause` holds the original error. Its `code` is the cause's code when the
12
+ * cause is a {@link PerpsError}, else `SDKError`.
13
+ *
14
+ * @public
15
+ */
16
+ export class PerpsExecutionError extends PerpsError {
17
+ override name = 'PerpsExecutionError'
18
+ readonly response: ExecuteActionResponse
19
+
20
+ constructor(response: ExecuteActionResponse, cause: unknown) {
21
+ super(
22
+ cause instanceof PerpsError ? cause.code : PerpsErrorCode.SDKError,
23
+ cause instanceof Error ? cause.message : String(cause)
24
+ )
25
+ this.response = response
26
+ this.cause = cause
27
+ if (cause instanceof PerpsError && cause.tool !== undefined) {
28
+ this.tool = cause.tool
29
+ }
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Rethrow `error` unchanged when `known` is empty. Otherwise throw a
35
+ * {@link PerpsExecutionError} whose report holds `known`, then any results
36
+ * `error` already carries.
37
+ *
38
+ * @public
39
+ */
40
+ export function rethrowWithKnownResults(
41
+ known: ActionResult[],
42
+ error: unknown
43
+ ): never {
44
+ if (known.length === 0) {
45
+ throw error
46
+ }
47
+ if (error instanceof PerpsExecutionError) {
48
+ throw new PerpsExecutionError(
49
+ { results: [...known, ...error.response.results] },
50
+ error.cause
51
+ )
52
+ }
53
+ throw new PerpsExecutionError({ results: known }, error)
54
+ }
package/src/index.ts CHANGED
@@ -71,35 +71,38 @@ export {
71
71
  export { PerpsErrorMessage } from './errors/constants.js'
72
72
  export { PerpsError } from './errors/PerpsError.js'
73
73
  export {
74
- classifyFill,
74
+ PerpsExecutionError,
75
+ rethrowWithKnownResults,
76
+ } from './errors/PerpsExecutionError.js'
77
+ export {
75
78
  classifyFillFromPosition,
76
79
  FillClassification,
77
80
  } from './math/fills.js'
78
81
  export type { ExpectedPnl } from './math/order.js'
79
82
  export {
80
- applySlippageToPrice,
81
83
  buildQuote,
82
84
  calculateExpectedPnl,
85
+ calculateOrderbookWalk,
83
86
  calculateRealizedPnlPercent,
84
87
  calculateSize,
88
+ calculateSlippagePrice,
85
89
  calculateTriggerPercent,
86
90
  calculateTriggerPrice,
87
91
  estimateFees,
88
92
  estimateRealizedPnl,
89
- findMatchingPosition,
90
93
  resolveCloseSize,
91
- safeApplySlippageToPrice,
94
+ resolveMatchingPosition,
92
95
  safeBuildQuote,
93
96
  safeCalculateExpectedPnl,
97
+ safeCalculateOrderbookWalk,
94
98
  safeCalculateRealizedPnlPercent,
95
99
  safeCalculateSize,
100
+ safeCalculateSlippagePrice,
96
101
  safeCalculateTriggerPercent,
97
102
  safeCalculateTriggerPrice,
98
103
  safeEstimateFees,
99
104
  safeEstimateRealizedPnl,
100
105
  safeResolveCloseSize,
101
- safeWalkOrderbook,
102
- walkOrderbook,
103
106
  } from './math/order.js'
104
107
  export {
105
108
  calculateEffectiveLeverage,
@@ -114,8 +117,8 @@ export {
114
117
  estimateLiquidationPriceAtMarketRate,
115
118
  estimateNewLeverage,
116
119
  estimateUnrealizedPnl,
117
- positionSupportsMarginAdjustment,
118
- positionSupportsMarginRemoval,
120
+ isPositionMarginAdjustable,
121
+ isPositionMarginRemovable,
119
122
  safeCalculateEffectiveLeverage,
120
123
  safeCalculateLiquidationDistance,
121
124
  safeCalculateNotionalValue,
@@ -283,6 +286,7 @@ export type {
283
286
  QuoteListener,
284
287
  SignActionProgress,
285
288
  SignActionsContext,
289
+ SignActionsResult,
286
290
  } from './types/provider.js'
287
291
  export type {
288
292
  ProviderWithdrawableBalance,
@@ -293,6 +297,7 @@ export type {
293
297
  WithdrawFlowReady,
294
298
  WithdrawFlowSetupRequired,
295
299
  } from './types/withdrawal.js'
300
+ export { isSubmittedOrAccepted } from './utils/actionResult.js'
296
301
  export { paginateActivity } from './utils/activityPaging.js'
297
302
  export { createSafeFunction } from './utils/createSafeFunction.js'
298
303
  export {
package/src/math/fills.ts CHANGED
@@ -4,7 +4,6 @@ import {
4
4
  OrderSide,
5
5
  } from '@lifi/perps-types'
6
6
  import Big from 'big.js'
7
- import { isDecimalStringZero } from '../decimal/compare.js'
8
7
  import { isDecimalString } from '../decimal/parse.js'
9
8
 
10
9
  /**
@@ -69,31 +68,3 @@ export function classifyFillFromPosition(
69
68
  }
70
69
  return FillClassification.REDUCED_SHORT
71
70
  }
72
-
73
- /**
74
- * Classify a fill as open or close based on realizedPnl.
75
- * @deprecated Use `Fill.classification` instead — it uses startPosition
76
- * for accurate open/increase/reduce/close/reverse classification.
77
- * @returns `BUY` or `SELL` when `realizedPnl` is a string that does not match the
78
- * decimal pattern.
79
- * @public
80
- */
81
- export function classifyFill(
82
- side: OrderSide,
83
- realizedPnl: DecimalString | null | undefined
84
- ): FillClassification {
85
- if (realizedPnl != null && !isDecimalString(realizedPnl)) {
86
- return side === OrderSide.BUY
87
- ? FillClassification.BUY
88
- : FillClassification.SELL
89
- }
90
- const isClose = realizedPnl != null && !isDecimalStringZero(realizedPnl)
91
- if (side === OrderSide.BUY) {
92
- return isClose
93
- ? FillClassification.CLOSED_SHORT
94
- : FillClassification.OPENED_LONG
95
- }
96
- return isClose
97
- ? FillClassification.CLOSED_LONG
98
- : FillClassification.OPENED_SHORT
99
- }
package/src/math/order.ts CHANGED
@@ -96,7 +96,7 @@ export const safeEstimateFees = createSafeFunction('estimateFees', estimateFees)
96
96
  * decimal pattern, or `slippagePercent` is -100 or less.
97
97
  * @public
98
98
  */
99
- export function applySlippageToPrice(
99
+ export function calculateSlippagePrice(
100
100
  price: string,
101
101
  slippagePercent: string,
102
102
  isBuy: boolean
@@ -116,9 +116,9 @@ export function applySlippageToPrice(
116
116
  }
117
117
 
118
118
  /** @public */
119
- export const safeApplySlippageToPrice = createSafeFunction(
120
- 'applySlippageToPrice',
121
- applySlippageToPrice
119
+ export const safeCalculateSlippagePrice = createSafeFunction(
120
+ 'calculateSlippagePrice',
121
+ calculateSlippagePrice
122
122
  )
123
123
 
124
124
  /**
@@ -277,7 +277,7 @@ export const safeCalculateRealizedPnlPercent = createSafeFunction(
277
277
  calculateRealizedPnlPercent
278
278
  )
279
279
 
280
- /** Result of {@link walkOrderbook} — the fill obtained for a USD-notional walk. */
280
+ /** Result of {@link calculateOrderbookWalk} — the fill obtained for a USD-notional walk. */
281
281
  interface BookWalk {
282
282
  /** Base amount filled. */
283
283
  baseSize: string
@@ -301,7 +301,7 @@ interface BookWalk {
301
301
  * or `size` does not match the decimal pattern.
302
302
  * @public
303
303
  */
304
- export function walkOrderbook(
304
+ export function calculateOrderbookWalk(
305
305
  levels: OrderbookLevel[],
306
306
  sizeUsd: string
307
307
  ): BookWalk {
@@ -333,9 +333,9 @@ export function walkOrderbook(
333
333
  }
334
334
 
335
335
  /** @public */
336
- export const safeWalkOrderbook = createSafeFunction(
337
- 'walkOrderbook',
338
- walkOrderbook
336
+ export const safeCalculateOrderbookWalk = createSafeFunction(
337
+ 'calculateOrderbookWalk',
338
+ calculateOrderbookWalk
339
339
  )
340
340
 
341
341
  /** Inputs to {@link buildQuote} — the resolved market, its live price, its book, and the trade ask. */
@@ -369,7 +369,7 @@ export function buildQuote(input: BuildQuoteInput): Quote {
369
369
  const { market, price, side, sizeUsd, feeTier } = input
370
370
  const markPrice = decimalStringToDivBig(price.markPrice)
371
371
  const levels = side === 'buy' ? input.asks : input.bids
372
- const walk = walkOrderbook(levels, sizeUsd)
372
+ const walk = calculateOrderbookWalk(levels, sizeUsd)
373
373
  const vwap = decimalStringToBig(walk.vwap)
374
374
  const priceImpactBps =
375
375
  markPrice.eq(0) || vwap.eq(0)
@@ -407,7 +407,7 @@ export const safeBuildQuote = createSafeFunction('buildQuote', buildQuote)
407
407
  * @param positions - Open positions list (any market).
408
408
  * @public
409
409
  */
410
- export function findMatchingPosition(
410
+ export function resolveMatchingPosition(
411
411
  marketId: string,
412
412
  positions: readonly Position[]
413
413
  ): Position | undefined {
@@ -417,7 +417,7 @@ export const safeCalculateRealizedPnl = createSafeFunction(
417
417
  *
418
418
  * @public
419
419
  */
420
- export function positionSupportsMarginAdjustment(position: Position): boolean {
420
+ export function isPositionMarginAdjustable(position: Position): boolean {
421
421
  return (
422
422
  position.marginMode === MarginMode.ISOLATED &&
423
423
  position.market.positionMarginAdjustment !== PositionMarginAdjustment.NONE
@@ -430,9 +430,9 @@ export function positionSupportsMarginAdjustment(position: Position): boolean {
430
430
  *
431
431
  * @public
432
432
  */
433
- export function positionSupportsMarginRemoval(position: Position): boolean {
433
+ export function isPositionMarginRemovable(position: Position): boolean {
434
434
  return (
435
- positionSupportsMarginAdjustment(position) &&
435
+ isPositionMarginAdjustable(position) &&
436
436
  position.market.positionMarginAdjustment ===
437
437
  PositionMarginAdjustment.ADD_AND_REMOVE
438
438
  )
package/src/types/api.ts CHANGED
@@ -7,7 +7,6 @@ import type {
7
7
  PlaceTwapOrderParams as ActionPlaceTwapOrderParams,
8
8
  ActionStep,
9
9
  DecimalString,
10
- ExecuteActionResponse,
11
10
  MarginMode,
12
11
  MarketRef,
13
12
  MetaActionType,
@@ -18,7 +17,6 @@ import type {
18
17
  PortfolioHistoryRange,
19
18
  SetupAction,
20
19
  SetupOption,
21
- SignedActionStep,
22
20
  TimeInForce,
23
21
  TriggerOrderInput,
24
22
  WithdrawalParams,
@@ -380,25 +378,6 @@ export interface ProviderSetup {
380
378
  checklist: SetupChecklistItem[]
381
379
  }
382
380
 
383
- /**
384
- * Parameters for the internal `PerpsClient.executeProviderSetup` batch submit.
385
- */
386
- export interface ExecuteProviderSetupParams {
387
- provider: string
388
- address: Address
389
- /** The unsatisfied setup steps from checkSetup() */
390
- setup: ActionStep[]
391
- /** Signed counterparts of `setup`, in the same order */
392
- signedActions: SignedActionStep[]
393
- }
394
-
395
- /**
396
- * Result from the internal `PerpsClient.executeProviderSetup` batch submit.
397
- */
398
- export interface ExecuteProviderSetupResult {
399
- results: ExecuteActionResponse
400
- }
401
-
402
381
  /**
403
382
  * Result envelope returned by {@link PerpsClient.getAccount} — wraps the
404
383
  * backend's `AccountResponse` with a single SDK-projected `settings` array.
@@ -79,6 +79,23 @@ export interface SignActionProgress {
79
79
  txHash: string
80
80
  }
81
81
 
82
+ /**
83
+ * Output of {@link PerpsProviderPlugin.signActions}, in batch order.
84
+ *
85
+ * A plugin that executes a step itself while signing (a venue REST mutation,
86
+ * a reverted on-chain leg) puts that step's real result in `executed` and
87
+ * leaves it out of `signed`. The plugin stops at the first `executed` result
88
+ * that is not `Submitted` or `Accepted`. Core submits `signed` to
89
+ * `/executeAction` only when every `executed` result is `Submitted` or
90
+ * `Accepted`, and reports `executed` before the `/executeAction` results.
91
+ *
92
+ * @public
93
+ */
94
+ export interface SignActionsResult {
95
+ signed: SignedActionStep[]
96
+ executed: ActionResult[]
97
+ }
98
+
82
99
  /**
83
100
  * Per-call context passed by `PerpsClient` to a provider's
84
101
  * {@link PerpsProviderPlugin.signActions} implementation. Carries the
@@ -699,12 +716,13 @@ export interface PerpsProviderPlugin {
699
716
  steps: ActionStep[],
700
717
  address: Address,
701
718
  ctx?: SignActionsContext
702
- ): Promise<SignedActionStep[]>
719
+ ): Promise<SignActionsResult>
703
720
 
704
721
  /**
705
- * Observe the per-step results of an `/executeAction` round trip before the
706
- * core surfaces failures. Lets a provider react to structured failure codes
707
- * — e.g. evicting a locally stored credential the venue no longer accepts.
722
+ * Observe the execution report of each `execute` call: the results of the
723
+ * steps the plugin executed while signing, then the `/executeAction`
724
+ * results. Lets a provider react to structured statuses — e.g. evicting a
725
+ * locally stored credential the venue refused.
708
726
  */
709
727
  onExecuteResults?(address: Address, results: ActionResult[]): Promise<void>
710
728
 
@@ -0,0 +1,10 @@
1
+ import type { ActionResult } from '@lifi/perps-types'
2
+ import { UserActionStatus } from '@lifi/perps-types'
3
+
4
+ /** Whether the action took effect: its status is `Submitted` or `Accepted`. */
5
+ export function isSubmittedOrAccepted(result: ActionResult): boolean {
6
+ return (
7
+ result.status === UserActionStatus.Submitted ||
8
+ result.status === UserActionStatus.Accepted
9
+ )
10
+ }
package/src/version.ts CHANGED
@@ -10,4 +10,4 @@ export const name = '@lifi/perps-sdk'
10
10
  *
11
11
  * @public
12
12
  */
13
- export const version = '25.0.2'
13
+ export const version = '27.0.0'