@lifi/perps-sdk 15.0.0 → 17.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 (88) hide show
  1. package/README.md +38 -0
  2. package/dist/cjs/client/PerpsClient.d.ts +7 -2
  3. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  4. package/dist/cjs/client/PerpsClient.js +67 -11
  5. package/dist/cjs/client/PerpsClient.js.map +1 -1
  6. package/dist/cjs/index.d.ts +4 -5
  7. package/dist/cjs/index.d.ts.map +1 -1
  8. package/dist/cjs/index.js +6 -7
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/registry/assetRegistry.d.ts +2 -1
  11. package/dist/cjs/registry/assetRegistry.d.ts.map +1 -1
  12. package/dist/cjs/registry/assetRegistry.js +11 -1
  13. package/dist/cjs/registry/assetRegistry.js.map +1 -1
  14. package/dist/cjs/types/provider.d.ts +7 -2
  15. package/dist/cjs/types/provider.d.ts.map +1 -1
  16. package/dist/cjs/types/withdrawal.d.ts +2 -0
  17. package/dist/cjs/types/withdrawal.d.ts.map +1 -1
  18. package/dist/cjs/version.d.ts +1 -1
  19. package/dist/cjs/version.js +1 -1
  20. package/dist/cjs/websocket/decodeChain.d.ts +11 -0
  21. package/dist/cjs/websocket/decodeChain.d.ts.map +1 -0
  22. package/dist/cjs/websocket/decodeChain.js +37 -0
  23. package/dist/cjs/websocket/decodeChain.js.map +1 -0
  24. package/dist/esm/client/PerpsClient.d.ts +39 -10
  25. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  26. package/dist/esm/client/PerpsClient.js +109 -20
  27. package/dist/esm/client/PerpsClient.js.map +1 -1
  28. package/dist/esm/index.d.ts +4 -5
  29. package/dist/esm/index.d.ts.map +1 -1
  30. package/dist/esm/index.js +2 -3
  31. package/dist/esm/index.js.map +1 -1
  32. package/dist/esm/registry/assetRegistry.d.ts +7 -1
  33. package/dist/esm/registry/assetRegistry.d.ts.map +1 -1
  34. package/dist/esm/registry/assetRegistry.js +14 -0
  35. package/dist/esm/registry/assetRegistry.js.map +1 -1
  36. package/dist/esm/types/provider.d.ts +29 -7
  37. package/dist/esm/types/provider.d.ts.map +1 -1
  38. package/dist/esm/types/withdrawal.d.ts +12 -0
  39. package/dist/esm/types/withdrawal.d.ts.map +1 -1
  40. package/dist/esm/version.d.ts +1 -1
  41. package/dist/esm/version.js +1 -1
  42. package/dist/esm/websocket/decodeChain.d.ts +30 -0
  43. package/dist/esm/websocket/decodeChain.d.ts.map +1 -0
  44. package/dist/esm/websocket/decodeChain.js +44 -0
  45. package/dist/esm/websocket/decodeChain.js.map +1 -0
  46. package/dist/types/client/PerpsClient.d.ts +39 -10
  47. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  48. package/dist/types/index.d.ts +4 -5
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/types/registry/assetRegistry.d.ts +7 -1
  51. package/dist/types/registry/assetRegistry.d.ts.map +1 -1
  52. package/dist/types/types/provider.d.ts +29 -7
  53. package/dist/types/types/provider.d.ts.map +1 -1
  54. package/dist/types/types/withdrawal.d.ts +12 -0
  55. package/dist/types/types/withdrawal.d.ts.map +1 -1
  56. package/dist/types/version.d.ts +1 -1
  57. package/dist/types/websocket/decodeChain.d.ts +30 -0
  58. package/dist/types/websocket/decodeChain.d.ts.map +1 -0
  59. package/package.json +2 -2
  60. package/src/client/PerpsClient.ts +146 -28
  61. package/src/index.ts +8 -7
  62. package/src/registry/assetRegistry.ts +16 -1
  63. package/src/types/provider.ts +34 -9
  64. package/src/types/withdrawal.ts +12 -0
  65. package/src/version.ts +1 -1
  66. package/src/websocket/decodeChain.ts +54 -0
  67. package/dist/cjs/utils/accountSummary.d.ts +0 -4
  68. package/dist/cjs/utils/accountSummary.d.ts.map +0 -1
  69. package/dist/cjs/utils/accountSummary.js +0 -35
  70. package/dist/cjs/utils/accountSummary.js.map +0 -1
  71. package/dist/cjs/utils/transferMargin.d.ts +0 -7
  72. package/dist/cjs/utils/transferMargin.d.ts.map +0 -1
  73. package/dist/cjs/utils/transferMargin.js +0 -50
  74. package/dist/cjs/utils/transferMargin.js.map +0 -1
  75. package/dist/esm/utils/accountSummary.d.ts +0 -32
  76. package/dist/esm/utils/accountSummary.d.ts.map +0 -1
  77. package/dist/esm/utils/accountSummary.js +0 -46
  78. package/dist/esm/utils/accountSummary.js.map +0 -1
  79. package/dist/esm/utils/transferMargin.d.ts +0 -24
  80. package/dist/esm/utils/transferMargin.d.ts.map +0 -1
  81. package/dist/esm/utils/transferMargin.js +0 -56
  82. package/dist/esm/utils/transferMargin.js.map +0 -1
  83. package/dist/types/utils/accountSummary.d.ts +0 -32
  84. package/dist/types/utils/accountSummary.d.ts.map +0 -1
  85. package/dist/types/utils/transferMargin.d.ts +0 -24
  86. package/dist/types/utils/transferMargin.d.ts.map +0 -1
  87. package/src/utils/accountSummary.ts +0 -90
  88. package/src/utils/transferMargin.ts +0 -98
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.summarizeAccount = summarizeAccount;
4
- const parse_js_1 = require("./parse.js");
5
- const sumValueUsd = (balances) => balances.reduce((sum, b) => sum + (0, parse_js_1.stringToFloat)(b.valueUsd), 0);
6
- const sumMarginUsd = (balances) => balances.reduce((sum, b) => sum + (0, parse_js_1.stringToFloat)(b.valueUsd) * (b.collateralWeight ?? 1), 0);
7
- function summarizeAccount(account, positions, semantics) {
8
- let marginUsed = 0;
9
- let unrealizedPnl = 0;
10
- for (const p of positions) {
11
- marginUsed += (0, parse_js_1.stringToFloat)(p.marginUsed);
12
- unrealizedPnl += (0, parse_js_1.stringToFloat)(p.unrealizedPnl);
13
- }
14
- const collateral = sumValueUsd(account.collateralBalances);
15
- const marginCollateral = sumMarginUsd(account.collateralBalances);
16
- const balances = sumValueUsd(account.balances);
17
- const withLocked = semantics === 'free' || semantics === 'net';
18
- const grossCollateral = withLocked ? collateral + marginUsed : collateral;
19
- const grossMarginCollateral = withLocked
20
- ? marginCollateral + marginUsed
21
- : marginCollateral;
22
- const equity = semantics === 'equity' || semantics === 'net'
23
- ? grossCollateral
24
- : grossCollateral + unrealizedPnl;
25
- const availableMargin = grossMarginCollateral +
26
- (semantics === 'gross' ? unrealizedPnl : 0) -
27
- marginUsed;
28
- return {
29
- portfolioValue: (balances + equity).toString(),
30
- availableMargin: availableMargin.toString(),
31
- marginUsed: marginUsed.toString(),
32
- unrealizedPnl: unrealizedPnl.toString(),
33
- };
34
- }
35
- //# sourceMappingURL=accountSummary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accountSummary.js","sourceRoot":"","sources":["../../../src/utils/accountSummary.ts"],"names":[],"mappings":";;AA8CA,4CA2CC;AApFD,yCAA0C;AAE1C,MAAM,WAAW,GAAG,CAAC,QAAqC,EAAU,EAAE,CACpE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAA,wBAAa,EAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;AAEjE,MAAM,YAAY,GAAG,CAAC,QAAqC,EAAU,EAAE,CACrE,QAAQ,CAAC,MAAM,CACb,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAA,wBAAa,EAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EACvE,CAAC,CACF,CAAA;AAgCH,SAAgB,gBAAgB,CAC9B,OAAwB,EACxB,SAAqB,EACrB,SAA8B;IAE9B,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,UAAU,IAAI,IAAA,wBAAa,EAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QACzC,aAAa,IAAI,IAAA,wBAAa,EAAC,CAAC,CAAC,aAAa,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAI1D,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9C,MAAM,UAAU,GAAG,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAA;IAC9D,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IACzE,MAAM,qBAAqB,GAAG,UAAU;QACtC,CAAC,CAAC,gBAAgB,GAAG,UAAU;QAC/B,CAAC,CAAC,gBAAgB,CAAA;IACpB,MAAM,MAAM,GACV,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,KAAK;QAC3C,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,eAAe,GAAG,aAAa,CAAA;IAKrC,MAAM,eAAe,GACnB,qBAAqB;QACrB,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,UAAU,CAAA;IAEZ,OAAO;QACL,cAAc,EAAE,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,QAAQ,EAAE;QAC9C,eAAe,EAAE,eAAe,CAAC,QAAQ,EAAE;QAC3C,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;QACjC,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE;KACxC,CAAA;AACH,CAAC"}
@@ -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,32 +0,0 @@
1
- import type { AccountResponse, AccountSummary, Position } from '@lifi/perps-types';
2
- /**
3
- * What the summed `collateralBalances` rows already contain, relative to the
4
- * positions' locked margin and unrealized PnL:
5
- *
6
- * - `'free'` — free collateral only; locked margin and unrealized PnL are
7
- * both carried by the positions. Available margin is the free collateral
8
- * as-is; unrealized PnL is not counted toward it.
9
- * - `'net'` — free collateral with unrealized PnL already marked in; only
10
- * the locked margin is carried by the positions (e.g. a venue-reported
11
- * available balance).
12
- * - `'gross'` — locked margin included, unrealized PnL carried by the
13
- * positions (e.g. spot holdings backing a unified account). The venue
14
- * counts unrealized PnL toward buying power, so it is added to available
15
- * margin on top of the gross collateral.
16
- * - `'equity'` — total equity: locked margin AND unrealized PnL included
17
- * (e.g. a venue-reported account value). Unrealized PnL is thus already
18
- * counted toward available margin.
19
- *
20
- * @public
21
- */
22
- export type CollateralSemantics = 'free' | 'net' | 'gross' | 'equity';
23
- /**
24
- * Roll an {@link AccountResponse} and its open positions up into an
25
- * {@link AccountSummary}.
26
- *
27
- * @param semantics - How the collateral rows relate to the positions'
28
- * locked margin and unrealized PnL; see {@link CollateralSemantics}.
29
- * @public
30
- */
31
- export declare function summarizeAccount(account: AccountResponse, positions: Position[], semantics: CollateralSemantics): AccountSummary;
32
- //# sourceMappingURL=accountSummary.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accountSummary.d.ts","sourceRoot":"","sources":["../../../src/utils/accountSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,QAAQ,EACT,MAAM,mBAAmB,CAAA;AAY1B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,mBAAmB,GAC7B,cAAc,CAuChB"}
@@ -1,46 +0,0 @@
1
- import { stringToFloat } from './parse.js';
2
- const sumValueUsd = (balances) => balances.reduce((sum, b) => sum + stringToFloat(b.valueUsd), 0);
3
- const sumMarginUsd = (balances) => balances.reduce((sum, b) => sum + stringToFloat(b.valueUsd) * (b.collateralWeight ?? 1), 0);
4
- /**
5
- * Roll an {@link AccountResponse} and its open positions up into an
6
- * {@link AccountSummary}.
7
- *
8
- * @param semantics - How the collateral rows relate to the positions'
9
- * locked margin and unrealized PnL; see {@link CollateralSemantics}.
10
- * @public
11
- */
12
- export function summarizeAccount(account, positions, semantics) {
13
- let marginUsed = 0;
14
- let unrealizedPnl = 0;
15
- for (const p of positions) {
16
- marginUsed += stringToFloat(p.marginUsed);
17
- unrealizedPnl += stringToFloat(p.unrealizedPnl);
18
- }
19
- const collateral = sumValueUsd(account.collateralBalances);
20
- // Margin-eligible collateral: each row's value scaled by its loan-to-value
21
- // weight (1 when unset), so a haircut asset backs buying power at less than
22
- // face while `portfolioValue` still reflects its full value.
23
- const marginCollateral = sumMarginUsd(account.collateralBalances);
24
- const balances = sumValueUsd(account.balances);
25
- const withLocked = semantics === 'free' || semantics === 'net';
26
- const grossCollateral = withLocked ? collateral + marginUsed : collateral;
27
- const grossMarginCollateral = withLocked
28
- ? marginCollateral + marginUsed
29
- : marginCollateral;
30
- const equity = semantics === 'equity' || semantics === 'net'
31
- ? grossCollateral
32
- : grossCollateral + unrealizedPnl;
33
- // Buying power is equity net of locked margin, so unrealized PnL counts
34
- // toward it. The `'free'` rows exclude uPnL from available margin, holding
35
- // it purely as free collateral.
36
- const availableMargin = grossMarginCollateral +
37
- (semantics === 'gross' ? unrealizedPnl : 0) -
38
- marginUsed;
39
- return {
40
- portfolioValue: (balances + equity).toString(),
41
- availableMargin: availableMargin.toString(),
42
- marginUsed: marginUsed.toString(),
43
- unrealizedPnl: unrealizedPnl.toString(),
44
- };
45
- }
46
- //# sourceMappingURL=accountSummary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accountSummary.js","sourceRoot":"","sources":["../../../src/utils/accountSummary.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,MAAM,WAAW,GAAG,CAAC,QAAqC,EAAU,EAAE,CACpE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;AAEjE,MAAM,YAAY,GAAG,CAAC,QAAqC,EAAU,EAAE,CACrE,QAAQ,CAAC,MAAM,CACb,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EACvE,CAAC,CACF,CAAA;AAwBH;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,SAAqB,EACrB,SAA8B;IAE9B,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,UAAU,IAAI,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;QACzC,aAAa,IAAI,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC1D,2EAA2E;IAC3E,4EAA4E;IAC5E,6DAA6D;IAC7D,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9C,MAAM,UAAU,GAAG,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAA;IAC9D,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAA;IACzE,MAAM,qBAAqB,GAAG,UAAU;QACtC,CAAC,CAAC,gBAAgB,GAAG,UAAU;QAC/B,CAAC,CAAC,gBAAgB,CAAA;IACpB,MAAM,MAAM,GACV,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,KAAK;QAC3C,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,eAAe,GAAG,aAAa,CAAA;IAErC,wEAAwE;IACxE,2EAA2E;IAC3E,gCAAgC;IAChC,MAAM,eAAe,GACnB,qBAAqB;QACrB,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,UAAU,CAAA;IAEZ,OAAO;QACL,cAAc,EAAE,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,QAAQ,EAAE;QAC9C,eAAe,EAAE,eAAe,CAAC,QAAQ,EAAE;QAC3C,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;QACjC,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE;KACxC,CAAA;AACH,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,32 +0,0 @@
1
- import type { AccountResponse, AccountSummary, Position } from '@lifi/perps-types';
2
- /**
3
- * What the summed `collateralBalances` rows already contain, relative to the
4
- * positions' locked margin and unrealized PnL:
5
- *
6
- * - `'free'` — free collateral only; locked margin and unrealized PnL are
7
- * both carried by the positions. Available margin is the free collateral
8
- * as-is; unrealized PnL is not counted toward it.
9
- * - `'net'` — free collateral with unrealized PnL already marked in; only
10
- * the locked margin is carried by the positions (e.g. a venue-reported
11
- * available balance).
12
- * - `'gross'` — locked margin included, unrealized PnL carried by the
13
- * positions (e.g. spot holdings backing a unified account). The venue
14
- * counts unrealized PnL toward buying power, so it is added to available
15
- * margin on top of the gross collateral.
16
- * - `'equity'` — total equity: locked margin AND unrealized PnL included
17
- * (e.g. a venue-reported account value). Unrealized PnL is thus already
18
- * counted toward available margin.
19
- *
20
- * @public
21
- */
22
- export type CollateralSemantics = 'free' | 'net' | 'gross' | 'equity';
23
- /**
24
- * Roll an {@link AccountResponse} and its open positions up into an
25
- * {@link AccountSummary}.
26
- *
27
- * @param semantics - How the collateral rows relate to the positions'
28
- * locked margin and unrealized PnL; see {@link CollateralSemantics}.
29
- * @public
30
- */
31
- export declare function summarizeAccount(account: AccountResponse, positions: Position[], semantics: CollateralSemantics): AccountSummary;
32
- //# sourceMappingURL=accountSummary.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"accountSummary.d.ts","sourceRoot":"","sources":["../../../src/utils/accountSummary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,QAAQ,EACT,MAAM,mBAAmB,CAAA;AAY1B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,mBAAmB,GAC7B,cAAc,CAuChB"}
@@ -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,90 +0,0 @@
1
- import type {
2
- AccountResponse,
3
- AccountSummary,
4
- Position,
5
- } from '@lifi/perps-types'
6
- import { stringToFloat } from './parse.js'
7
-
8
- const sumValueUsd = (balances: AccountResponse['balances']): number =>
9
- balances.reduce((sum, b) => sum + stringToFloat(b.valueUsd), 0)
10
-
11
- const sumMarginUsd = (balances: AccountResponse['balances']): number =>
12
- balances.reduce(
13
- (sum, b) => sum + stringToFloat(b.valueUsd) * (b.collateralWeight ?? 1),
14
- 0
15
- )
16
-
17
- /**
18
- * What the summed `collateralBalances` rows already contain, relative to the
19
- * positions' locked margin and unrealized PnL:
20
- *
21
- * - `'free'` — free collateral only; locked margin and unrealized PnL are
22
- * both carried by the positions. Available margin is the free collateral
23
- * as-is; unrealized PnL is not counted toward it.
24
- * - `'net'` — free collateral with unrealized PnL already marked in; only
25
- * the locked margin is carried by the positions (e.g. a venue-reported
26
- * available balance).
27
- * - `'gross'` — locked margin included, unrealized PnL carried by the
28
- * positions (e.g. spot holdings backing a unified account). The venue
29
- * counts unrealized PnL toward buying power, so it is added to available
30
- * margin on top of the gross collateral.
31
- * - `'equity'` — total equity: locked margin AND unrealized PnL included
32
- * (e.g. a venue-reported account value). Unrealized PnL is thus already
33
- * counted toward available margin.
34
- *
35
- * @public
36
- */
37
- export type CollateralSemantics = 'free' | 'net' | 'gross' | 'equity'
38
-
39
- /**
40
- * Roll an {@link AccountResponse} and its open positions up into an
41
- * {@link AccountSummary}.
42
- *
43
- * @param semantics - How the collateral rows relate to the positions'
44
- * locked margin and unrealized PnL; see {@link CollateralSemantics}.
45
- * @public
46
- */
47
- export function summarizeAccount(
48
- account: AccountResponse,
49
- positions: Position[],
50
- semantics: CollateralSemantics
51
- ): AccountSummary {
52
- let marginUsed = 0
53
- let unrealizedPnl = 0
54
- for (const p of positions) {
55
- marginUsed += stringToFloat(p.marginUsed)
56
- unrealizedPnl += stringToFloat(p.unrealizedPnl)
57
- }
58
-
59
- const collateral = sumValueUsd(account.collateralBalances)
60
- // Margin-eligible collateral: each row's value scaled by its loan-to-value
61
- // weight (1 when unset), so a haircut asset backs buying power at less than
62
- // face while `portfolioValue` still reflects its full value.
63
- const marginCollateral = sumMarginUsd(account.collateralBalances)
64
- const balances = sumValueUsd(account.balances)
65
-
66
- const withLocked = semantics === 'free' || semantics === 'net'
67
- const grossCollateral = withLocked ? collateral + marginUsed : collateral
68
- const grossMarginCollateral = withLocked
69
- ? marginCollateral + marginUsed
70
- : marginCollateral
71
- const equity =
72
- semantics === 'equity' || semantics === 'net'
73
- ? grossCollateral
74
- : grossCollateral + unrealizedPnl
75
-
76
- // Buying power is equity net of locked margin, so unrealized PnL counts
77
- // toward it. The `'free'` rows exclude uPnL from available margin, holding
78
- // it purely as free collateral.
79
- const availableMargin =
80
- grossMarginCollateral +
81
- (semantics === 'gross' ? unrealizedPnl : 0) -
82
- marginUsed
83
-
84
- return {
85
- portfolioValue: (balances + equity).toString(),
86
- availableMargin: availableMargin.toString(),
87
- marginUsed: marginUsed.toString(),
88
- unrealizedPnl: unrealizedPnl.toString(),
89
- }
90
- }
@@ -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
- }