@lifi/perps-sdk 16.0.0 → 17.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.
Files changed (55) hide show
  1. package/README.md +16 -3
  2. package/dist/cjs/client/PerpsClient.d.ts +2 -2
  3. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  4. package/dist/cjs/client/PerpsClient.js +24 -3
  5. package/dist/cjs/client/PerpsClient.js.map +1 -1
  6. package/dist/cjs/index.d.ts +0 -2
  7. package/dist/cjs/index.d.ts.map +1 -1
  8. package/dist/cjs/index.js +1 -3
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/types/provider.d.ts +2 -2
  11. package/dist/cjs/types/provider.d.ts.map +1 -1
  12. package/dist/cjs/types/withdrawal.d.ts +2 -0
  13. package/dist/cjs/types/withdrawal.d.ts.map +1 -1
  14. package/dist/cjs/version.d.ts +1 -1
  15. package/dist/cjs/version.js +1 -1
  16. package/dist/esm/client/PerpsClient.d.ts +10 -6
  17. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  18. package/dist/esm/client/PerpsClient.js +32 -7
  19. package/dist/esm/client/PerpsClient.js.map +1 -1
  20. package/dist/esm/index.d.ts +0 -2
  21. package/dist/esm/index.d.ts.map +1 -1
  22. package/dist/esm/index.js +0 -1
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/types/provider.d.ts +14 -11
  25. package/dist/esm/types/provider.d.ts.map +1 -1
  26. package/dist/esm/types/withdrawal.d.ts +12 -0
  27. package/dist/esm/types/withdrawal.d.ts.map +1 -1
  28. package/dist/esm/version.d.ts +1 -1
  29. package/dist/esm/version.js +1 -1
  30. package/dist/types/client/PerpsClient.d.ts +10 -6
  31. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  32. package/dist/types/index.d.ts +0 -2
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/dist/types/types/provider.d.ts +14 -11
  35. package/dist/types/types/provider.d.ts.map +1 -1
  36. package/dist/types/types/withdrawal.d.ts +12 -0
  37. package/dist/types/types/withdrawal.d.ts.map +1 -1
  38. package/dist/types/version.d.ts +1 -1
  39. package/package.json +2 -2
  40. package/src/client/PerpsClient.ts +35 -10
  41. package/src/index.ts +0 -2
  42. package/src/types/provider.ts +13 -13
  43. package/src/types/withdrawal.ts +12 -0
  44. package/src/version.ts +1 -1
  45. package/dist/cjs/utils/transferMargin.d.ts +0 -7
  46. package/dist/cjs/utils/transferMargin.d.ts.map +0 -1
  47. package/dist/cjs/utils/transferMargin.js +0 -50
  48. package/dist/cjs/utils/transferMargin.js.map +0 -1
  49. package/dist/esm/utils/transferMargin.d.ts +0 -24
  50. package/dist/esm/utils/transferMargin.d.ts.map +0 -1
  51. package/dist/esm/utils/transferMargin.js +0 -56
  52. package/dist/esm/utils/transferMargin.js.map +0 -1
  53. package/dist/types/utils/transferMargin.d.ts +0 -24
  54. package/dist/types/utils/transferMargin.d.ts.map +0 -1
  55. package/src/utils/transferMargin.ts +0 -98
@@ -14,7 +14,6 @@ import type {
14
14
  OrdersResponse,
15
15
  PortfolioHistoryResponse,
16
16
  Position,
17
- PositionMarginConstraints,
18
17
  Provider,
19
18
  ProviderAction,
20
19
  SignedActionStep,
@@ -89,6 +88,14 @@ import {
89
88
  import { createPerpsClient } from './createPerpsClient.js'
90
89
  import { requireProvider as resolveProvider } from './requireProvider.js'
91
90
 
91
+ function isNonNegativeDecimal(value: string): boolean {
92
+ try {
93
+ return new Big(value).gte(0)
94
+ } catch {
95
+ return false
96
+ }
97
+ }
98
+
92
99
  /**
93
100
  * Look up an action's descriptor in the provider's metadata. Throws if the
94
101
  * action isn't declared — defensive: better to fail loudly than to mis-sign.
@@ -592,17 +599,18 @@ export class PerpsClient {
592
599
  }
593
600
 
594
601
  /**
595
- * Resolve the exact venue-owned margin requirements for `position`.
596
- * Returns `undefined` when the position has no individual margin adjustment.
602
+ * Resolve the margin that can be removed from `position`, from the owning
603
+ * provider's venue margin rules. Returns `undefined` when the position has
604
+ * no individual margin adjustment and `'0'` when it accepts no removal.
597
605
  *
606
+ * @throws {PerpsError} `ValidationError` when a `Position` decimal that the
607
+ * venue formula reads is malformed.
598
608
  * @public
599
609
  */
600
- getPositionMarginConstraints(
601
- position: Position
602
- ): PositionMarginConstraints | undefined {
610
+ getPositionRemovableMargin(position: Position): string | undefined {
603
611
  return this.requireProvider(
604
612
  position.market.providerId
605
- ).positionMarginConstraints(position)
613
+ ).positionRemovableMargin(position)
606
614
  }
607
615
 
608
616
  /**
@@ -663,8 +671,9 @@ export class PerpsClient {
663
671
  *
664
672
  * @returns `undefined` when the registered plugin declares no withdrawable
665
673
  * read.
666
- * @throws {PerpsError} When the provider plugin is not registered, or either
667
- * the plugin read or the asset sync fails.
674
+ * @throws {PerpsError} When the provider plugin is not registered, when
675
+ * either the plugin read or the asset sync fails, or when a row's
676
+ * `withdrawalFee` is not a non-negative decimal.
668
677
  * @public
669
678
  */
670
679
  async getWithdrawableBalances(
@@ -700,7 +709,23 @@ export class PerpsClient {
700
709
  return []
701
710
  }
702
711
  }
703
- return [{ asset, route: row.route, available: row.available }]
712
+ if (row.withdrawalFee === undefined) {
713
+ return [{ asset, route: row.route, available: row.available }]
714
+ }
715
+ if (!isNonNegativeDecimal(row.withdrawalFee)) {
716
+ throw new PerpsError(
717
+ PerpsErrorCode.SDKError,
718
+ `Provider '${params.provider}' row for asset '${asset.id}' has a \`withdrawalFee\` that is not a non-negative decimal: '${row.withdrawalFee}'.`
719
+ )
720
+ }
721
+ return [
722
+ {
723
+ asset,
724
+ route: row.route,
725
+ available: row.available,
726
+ withdrawalFee: row.withdrawalFee,
727
+ },
728
+ ]
704
729
  })
705
730
  }
706
731
 
package/src/index.ts CHANGED
@@ -252,8 +252,6 @@ export {
252
252
  signTypedData,
253
253
  signTypedDataWithSigner,
254
254
  } from './utils/signTypedData.js'
255
- export type { RemovableIsolatedMarginParams } from './utils/transferMargin.js'
256
- export { removableIsolatedMargin } from './utils/transferMargin.js'
257
255
  export { fromBaseUnits, fromBaseUnitsNumber } from './utils/units.js'
258
256
  export { validateMargin } from './utils/validation.js'
259
257
  export { createWarnOnce } from './utils/warnOnce.js'
@@ -21,7 +21,6 @@ import type {
21
21
  PortfolioHistoryRange,
22
22
  PortfolioHistoryResponse,
23
23
  Position,
24
- PositionMarginConstraints,
25
24
  PositionsResponse,
26
25
  ProviderAction,
27
26
  Quote,
@@ -457,10 +456,10 @@ export interface PerpsProviderPlugin {
457
456
  /**
458
457
  * The amounts the account can still buy and sell on one market, in that
459
458
  * market's margin asset. Optional because venues expose this unevenly:
460
- * Hyperliquid reads it directly (`activeAssetData`), other venues publish
461
- * only an account-scoped figure. `undefined` means the venue has nothing
462
- * to read for this market, and the caller falls back to the account
463
- * summary.
459
+ * Hyperliquid (`activeAssetData`) and Ondo (`max_order_size`) read it
460
+ * directly, other venues publish only an account-scoped figure. `undefined`
461
+ * means the venue has nothing to read for this market, and the caller falls
462
+ * back to the account summary.
464
463
  */
465
464
  getAvailableToTrade?(
466
465
  params: ProviderGetAvailableToTradeParams,
@@ -563,16 +562,17 @@ export interface PerpsProviderPlugin {
563
562
  ): number | undefined
564
563
 
565
564
  /**
566
- * Exact venue-owned constraints for changing `position`'s dedicated margin.
567
- * Pure — providers normalize raw venue quantities onto the position before
568
- * returning these inputs.
565
+ * Margin that can be removed from `position` under the venue margin rules,
566
+ * as an exact decimal string rounded down to the venue amount increment.
567
+ * Pure — each provider reads its own venue meaning of `Position.marginUsed`.
569
568
  *
570
- * @returns `undefined` when this position has no individual margin
571
- * adjustment (for example a cross position or a cross-only venue).
569
+ * @returns `undefined` when the position has no individual margin
570
+ * adjustment (for example a cross position or a cross-only venue), and
571
+ * `'0'` when the venue accepts no margin removal for it.
572
+ * @throws {PerpsError} `ValidationError` when a `Position` decimal that the
573
+ * venue formula reads is malformed.
572
574
  */
573
- positionMarginConstraints(
574
- position: Position
575
- ): PositionMarginConstraints | undefined
575
+ positionRemovableMargin(position: Position): string | undefined
576
576
 
577
577
  /**
578
578
  * Project a typed {@link AccountConfig} against the provider's `setup`
@@ -22,6 +22,12 @@ export interface ProviderWithdrawableBalance {
22
22
  route: WithdrawalRoute
23
23
  /** Withdrawable amount in the asset's own units. Always greater than zero. */
24
24
  available: string
25
+ /**
26
+ * Flat venue fee on a withdrawal from this row, in the asset's own units.
27
+ * Absent when the venue publishes no fee for the asset. The client rejects a
28
+ * value that is not a non-negative decimal.
29
+ */
30
+ withdrawalFee?: string
25
31
  }
26
32
 
27
33
  /**
@@ -36,4 +42,10 @@ export interface WithdrawableBalance {
36
42
  route: WithdrawalRoute
37
43
  /** Withdrawable amount in the asset's own units. */
38
44
  available: string
45
+ /**
46
+ * Flat venue fee on a withdrawal from this row, in the asset's own units. An
47
+ * amount at or below it delivers nothing. Absent when the venue publishes no
48
+ * fee for the asset.
49
+ */
50
+ withdrawalFee?: string
39
51
  }
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 = '16.0.0'
13
+ export const version = '17.0.1'
@@ -1,7 +0,0 @@
1
- import { type Position, type PositionMarginConstraints } from '@lifi/perps-types';
2
- export interface RemovableIsolatedMarginParams {
3
- position: Position;
4
- constraints: PositionMarginConstraints;
5
- }
6
- export declare function removableIsolatedMargin({ position, constraints, }: RemovableIsolatedMarginParams): string;
7
- //# sourceMappingURL=transferMargin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transferMargin.d.ts","sourceRoot":"","sources":["../../../src/utils/transferMargin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,yBAAyB,EAE/B,MAAM,mBAAmB,CAAA;AAyC1B,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,EAAE,yBAAyB,CAAA;CACvC;AAcD,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,GACZ,EAAE,6BAA6B,GAAG,MAAM,CA+BxC"}
@@ -1,50 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.removableIsolatedMargin = removableIsolatedMargin;
7
- const perps_types_1 = require("@lifi/perps-types");
8
- const big_js_1 = __importDefault(require("big.js"));
9
- const PerpsError_js_1 = require("../errors/PerpsError.js");
10
- function positionAmount(value, field) {
11
- try {
12
- return new big_js_1.default(value);
13
- }
14
- catch {
15
- throw new PerpsError_js_1.PerpsError(perps_types_1.PerpsErrorCode.ValidationError, `Invalid decimal string on Position.${field}: '${value}'`);
16
- }
17
- }
18
- function constraintAmount(value, field) {
19
- try {
20
- return new big_js_1.default(value);
21
- }
22
- catch {
23
- throw new PerpsError_js_1.PerpsError(perps_types_1.PerpsErrorCode.ValidationError, `Invalid decimal string on PositionMarginConstraints.${field}: '${value}'`);
24
- }
25
- }
26
- function requirePositive(value, field) {
27
- if (value.lte(0)) {
28
- throw new PerpsError_js_1.PerpsError(perps_types_1.PerpsErrorCode.ValidationError, `${field} must be greater than zero.`);
29
- }
30
- return value;
31
- }
32
- function removableIsolatedMargin({ position, constraints, }) {
33
- if (!(0, perps_types_1.positionSupportsMarginRemoval)(position)) {
34
- return '0';
35
- }
36
- const marginUsed = requirePositive(positionAmount(position.marginUsed, 'marginUsed'), 'Position.marginUsed');
37
- const unrealizedPnl = positionAmount(position.unrealizedPnl, 'unrealizedPnl');
38
- const minimumMargin = requirePositive(constraintAmount(constraints.minimumMarginRequirement, 'minimumMarginRequirement'), 'PositionMarginConstraints.minimumMarginRequirement');
39
- const amountIncrement = requirePositive(constraintAmount(constraints.amountIncrement, 'amountIncrement'), 'PositionMarginConstraints.amountIncrement');
40
- const removable = marginUsed.plus(unrealizedPnl).minus(minimumMargin);
41
- if (removable.lte(0)) {
42
- return '0';
43
- }
44
- return removable
45
- .div(amountIncrement)
46
- .round(0, big_js_1.default.roundDown)
47
- .times(amountIncrement)
48
- .toFixed();
49
- }
50
- //# sourceMappingURL=transferMargin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transferMargin.js","sourceRoot":"","sources":["../../../src/utils/transferMargin.ts"],"names":[],"mappings":";;;;;AA+DA,0DAkCC;AAjGD,mDAK0B;AAC1B,oDAAwB;AACxB,2DAAoD;AAEpD,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,CAAC;QACH,OAAO,IAAI,gBAAG,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,0BAAU,CAClB,4BAAc,CAAC,eAAe,EAC9B,sCAAsC,KAAK,MAAM,KAAK,GAAG,CAC1D,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACpD,IAAI,CAAC;QACH,OAAO,IAAI,gBAAG,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,0BAAU,CAClB,4BAAc,CAAC,eAAe,EAC9B,uDAAuD,KAAK,MAAM,KAAK,GAAG,CAC3E,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAU,EAAE,KAAa;IAChD,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,0BAAU,CAClB,4BAAc,CAAC,eAAe,EAC9B,GAAG,KAAK,6BAA6B,CACtC,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAwBD,SAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,GACmB;IAC9B,IAAI,CAAC,IAAA,2CAA6B,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAChC,cAAc,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,EACjD,qBAAqB,CACtB,CAAA;IACD,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;IAC7E,MAAM,aAAa,GAAG,eAAe,CACnC,gBAAgB,CACd,WAAW,CAAC,wBAAwB,EACpC,0BAA0B,CAC3B,EACD,oDAAoD,CACrD,CAAA;IACD,MAAM,eAAe,GAAG,eAAe,CACrC,gBAAgB,CAAC,WAAW,CAAC,eAAe,EAAE,iBAAiB,CAAC,EAChE,2CAA2C,CAC5C,CAAA;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IACrE,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,OAAO,SAAS;SACb,GAAG,CAAC,eAAe,CAAC;SACpB,KAAK,CAAC,CAAC,EAAE,gBAAG,CAAC,SAAS,CAAC;SACvB,KAAK,CAAC,eAAe,CAAC;SACtB,OAAO,EAAE,CAAA;AACd,CAAC"}
@@ -1,24 +0,0 @@
1
- import { type Position, type PositionMarginConstraints } from '@lifi/perps-types';
2
- /**
3
- * Exact inputs for {@link removableIsolatedMargin}.
4
- *
5
- * @public
6
- */
7
- export interface RemovableIsolatedMarginParams {
8
- position: Position;
9
- constraints: PositionMarginConstraints;
10
- }
11
- /**
12
- * Calculate margin that can be removed from an isolated position using the
13
- * provider's exact retained-margin requirement. Position equity is allocated
14
- * margin plus unrealized PnL.
15
- *
16
- * The result snaps down to the provider's accepted amount increment. Markets
17
- * that are add-only and cross-margined positions return `'0'`.
18
- *
19
- * @throws {PerpsError} `ValidationError` for malformed, non-positive, or
20
- * inconsistent risk inputs.
21
- * @public
22
- */
23
- export declare function removableIsolatedMargin({ position, constraints, }: RemovableIsolatedMarginParams): string;
24
- //# sourceMappingURL=transferMargin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transferMargin.d.ts","sourceRoot":"","sources":["../../../src/utils/transferMargin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,yBAAyB,EAE/B,MAAM,mBAAmB,CAAA;AAoC1B;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,EAAE,yBAAyB,CAAA;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,GACZ,EAAE,6BAA6B,GAAG,MAAM,CA+BxC"}
@@ -1,56 +0,0 @@
1
- import { PerpsErrorCode, positionSupportsMarginRemoval, } from '@lifi/perps-types';
2
- import Big from 'big.js';
3
- import { PerpsError } from '../errors/PerpsError.js';
4
- function positionAmount(value, field) {
5
- try {
6
- return new Big(value);
7
- }
8
- catch {
9
- throw new PerpsError(PerpsErrorCode.ValidationError, `Invalid decimal string on Position.${field}: '${value}'`);
10
- }
11
- }
12
- function constraintAmount(value, field) {
13
- try {
14
- return new Big(value);
15
- }
16
- catch {
17
- throw new PerpsError(PerpsErrorCode.ValidationError, `Invalid decimal string on PositionMarginConstraints.${field}: '${value}'`);
18
- }
19
- }
20
- function requirePositive(value, field) {
21
- if (value.lte(0)) {
22
- throw new PerpsError(PerpsErrorCode.ValidationError, `${field} must be greater than zero.`);
23
- }
24
- return value;
25
- }
26
- /**
27
- * Calculate margin that can be removed from an isolated position using the
28
- * provider's exact retained-margin requirement. Position equity is allocated
29
- * margin plus unrealized PnL.
30
- *
31
- * The result snaps down to the provider's accepted amount increment. Markets
32
- * that are add-only and cross-margined positions return `'0'`.
33
- *
34
- * @throws {PerpsError} `ValidationError` for malformed, non-positive, or
35
- * inconsistent risk inputs.
36
- * @public
37
- */
38
- export function removableIsolatedMargin({ position, constraints, }) {
39
- if (!positionSupportsMarginRemoval(position)) {
40
- return '0';
41
- }
42
- const marginUsed = requirePositive(positionAmount(position.marginUsed, 'marginUsed'), 'Position.marginUsed');
43
- const unrealizedPnl = positionAmount(position.unrealizedPnl, 'unrealizedPnl');
44
- const minimumMargin = requirePositive(constraintAmount(constraints.minimumMarginRequirement, 'minimumMarginRequirement'), 'PositionMarginConstraints.minimumMarginRequirement');
45
- const amountIncrement = requirePositive(constraintAmount(constraints.amountIncrement, 'amountIncrement'), 'PositionMarginConstraints.amountIncrement');
46
- const removable = marginUsed.plus(unrealizedPnl).minus(minimumMargin);
47
- if (removable.lte(0)) {
48
- return '0';
49
- }
50
- return removable
51
- .div(amountIncrement)
52
- .round(0, Big.roundDown)
53
- .times(amountIncrement)
54
- .toFixed();
55
- }
56
- //# sourceMappingURL=transferMargin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transferMargin.js","sourceRoot":"","sources":["../../../src/utils/transferMargin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAGd,6BAA6B,GAC9B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,GAAG,MAAM,QAAQ,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAEpD,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,eAAe,EAC9B,sCAAsC,KAAK,MAAM,KAAK,GAAG,CAC1D,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,KAAa;IACpD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,eAAe,EAC9B,uDAAuD,KAAK,MAAM,KAAK,GAAG,CAC3E,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAU,EAAE,KAAa;IAChD,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAClB,cAAc,CAAC,eAAe,EAC9B,GAAG,KAAK,6BAA6B,CACtC,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAYD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,GACmB;IAC9B,IAAI,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAChC,cAAc,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,EACjD,qBAAqB,CACtB,CAAA;IACD,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;IAC7E,MAAM,aAAa,GAAG,eAAe,CACnC,gBAAgB,CACd,WAAW,CAAC,wBAAwB,EACpC,0BAA0B,CAC3B,EACD,oDAAoD,CACrD,CAAA;IACD,MAAM,eAAe,GAAG,eAAe,CACrC,gBAAgB,CAAC,WAAW,CAAC,eAAe,EAAE,iBAAiB,CAAC,EAChE,2CAA2C,CAC5C,CAAA;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IACrE,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,OAAO,SAAS;SACb,GAAG,CAAC,eAAe,CAAC;SACpB,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC;SACvB,KAAK,CAAC,eAAe,CAAC;SACtB,OAAO,EAAE,CAAA;AACd,CAAC"}
@@ -1,24 +0,0 @@
1
- import { type Position, type PositionMarginConstraints } from '@lifi/perps-types';
2
- /**
3
- * Exact inputs for {@link removableIsolatedMargin}.
4
- *
5
- * @public
6
- */
7
- export interface RemovableIsolatedMarginParams {
8
- position: Position;
9
- constraints: PositionMarginConstraints;
10
- }
11
- /**
12
- * Calculate margin that can be removed from an isolated position using the
13
- * provider's exact retained-margin requirement. Position equity is allocated
14
- * margin plus unrealized PnL.
15
- *
16
- * The result snaps down to the provider's accepted amount increment. Markets
17
- * that are add-only and cross-margined positions return `'0'`.
18
- *
19
- * @throws {PerpsError} `ValidationError` for malformed, non-positive, or
20
- * inconsistent risk inputs.
21
- * @public
22
- */
23
- export declare function removableIsolatedMargin({ position, constraints, }: RemovableIsolatedMarginParams): string;
24
- //# sourceMappingURL=transferMargin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transferMargin.d.ts","sourceRoot":"","sources":["../../../src/utils/transferMargin.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,yBAAyB,EAE/B,MAAM,mBAAmB,CAAA;AAoC1B;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,QAAQ,CAAA;IAClB,WAAW,EAAE,yBAAyB,CAAA;CACvC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,WAAW,GACZ,EAAE,6BAA6B,GAAG,MAAM,CA+BxC"}
@@ -1,98 +0,0 @@
1
- import {
2
- PerpsErrorCode,
3
- type Position,
4
- type PositionMarginConstraints,
5
- positionSupportsMarginRemoval,
6
- } from '@lifi/perps-types'
7
- import Big from 'big.js'
8
- import { PerpsError } from '../errors/PerpsError.js'
9
-
10
- function positionAmount(value: string, field: string): Big {
11
- try {
12
- return new Big(value)
13
- } catch {
14
- throw new PerpsError(
15
- PerpsErrorCode.ValidationError,
16
- `Invalid decimal string on Position.${field}: '${value}'`
17
- )
18
- }
19
- }
20
-
21
- function constraintAmount(value: string, field: string): Big {
22
- try {
23
- return new Big(value)
24
- } catch {
25
- throw new PerpsError(
26
- PerpsErrorCode.ValidationError,
27
- `Invalid decimal string on PositionMarginConstraints.${field}: '${value}'`
28
- )
29
- }
30
- }
31
-
32
- function requirePositive(value: Big, field: string): Big {
33
- if (value.lte(0)) {
34
- throw new PerpsError(
35
- PerpsErrorCode.ValidationError,
36
- `${field} must be greater than zero.`
37
- )
38
- }
39
- return value
40
- }
41
-
42
- /**
43
- * Exact inputs for {@link removableIsolatedMargin}.
44
- *
45
- * @public
46
- */
47
- export interface RemovableIsolatedMarginParams {
48
- position: Position
49
- constraints: PositionMarginConstraints
50
- }
51
-
52
- /**
53
- * Calculate margin that can be removed from an isolated position using the
54
- * provider's exact retained-margin requirement. Position equity is allocated
55
- * margin plus unrealized PnL.
56
- *
57
- * The result snaps down to the provider's accepted amount increment. Markets
58
- * that are add-only and cross-margined positions return `'0'`.
59
- *
60
- * @throws {PerpsError} `ValidationError` for malformed, non-positive, or
61
- * inconsistent risk inputs.
62
- * @public
63
- */
64
- export function removableIsolatedMargin({
65
- position,
66
- constraints,
67
- }: RemovableIsolatedMarginParams): string {
68
- if (!positionSupportsMarginRemoval(position)) {
69
- return '0'
70
- }
71
-
72
- const marginUsed = requirePositive(
73
- positionAmount(position.marginUsed, 'marginUsed'),
74
- 'Position.marginUsed'
75
- )
76
- const unrealizedPnl = positionAmount(position.unrealizedPnl, 'unrealizedPnl')
77
- const minimumMargin = requirePositive(
78
- constraintAmount(
79
- constraints.minimumMarginRequirement,
80
- 'minimumMarginRequirement'
81
- ),
82
- 'PositionMarginConstraints.minimumMarginRequirement'
83
- )
84
- const amountIncrement = requirePositive(
85
- constraintAmount(constraints.amountIncrement, 'amountIncrement'),
86
- 'PositionMarginConstraints.amountIncrement'
87
- )
88
-
89
- const removable = marginUsed.plus(unrealizedPnl).minus(minimumMargin)
90
- if (removable.lte(0)) {
91
- return '0'
92
- }
93
- return removable
94
- .div(amountIncrement)
95
- .round(0, Big.roundDown)
96
- .times(amountIncrement)
97
- .toFixed()
98
- }