@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.
- package/README.md +16 -3
- package/dist/cjs/client/PerpsClient.d.ts +2 -2
- package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
- package/dist/cjs/client/PerpsClient.js +24 -3
- package/dist/cjs/client/PerpsClient.js.map +1 -1
- package/dist/cjs/index.d.ts +0 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/provider.d.ts +2 -2
- package/dist/cjs/types/provider.d.ts.map +1 -1
- package/dist/cjs/types/withdrawal.d.ts +2 -0
- package/dist/cjs/types/withdrawal.d.ts.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client/PerpsClient.d.ts +10 -6
- package/dist/esm/client/PerpsClient.d.ts.map +1 -1
- package/dist/esm/client/PerpsClient.js +32 -7
- package/dist/esm/client/PerpsClient.js.map +1 -1
- package/dist/esm/index.d.ts +0 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/provider.d.ts +14 -11
- package/dist/esm/types/provider.d.ts.map +1 -1
- package/dist/esm/types/withdrawal.d.ts +12 -0
- package/dist/esm/types/withdrawal.d.ts.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/types/client/PerpsClient.d.ts +10 -6
- package/dist/types/client/PerpsClient.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/provider.d.ts +14 -11
- package/dist/types/types/provider.d.ts.map +1 -1
- package/dist/types/types/withdrawal.d.ts +12 -0
- package/dist/types/types/withdrawal.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/client/PerpsClient.ts +35 -10
- package/src/index.ts +0 -2
- package/src/types/provider.ts +13 -13
- package/src/types/withdrawal.ts +12 -0
- package/src/version.ts +1 -1
- package/dist/cjs/utils/transferMargin.d.ts +0 -7
- package/dist/cjs/utils/transferMargin.d.ts.map +0 -1
- package/dist/cjs/utils/transferMargin.js +0 -50
- package/dist/cjs/utils/transferMargin.js.map +0 -1
- package/dist/esm/utils/transferMargin.d.ts +0 -24
- package/dist/esm/utils/transferMargin.d.ts.map +0 -1
- package/dist/esm/utils/transferMargin.js +0 -56
- package/dist/esm/utils/transferMargin.js.map +0 -1
- package/dist/types/utils/transferMargin.d.ts +0 -24
- package/dist/types/utils/transferMargin.d.ts.map +0 -1
- 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
|
|
596
|
-
* Returns `undefined` when the position has
|
|
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
|
-
|
|
601
|
-
position: Position
|
|
602
|
-
): PositionMarginConstraints | undefined {
|
|
610
|
+
getPositionRemovableMargin(position: Position): string | undefined {
|
|
603
611
|
return this.requireProvider(
|
|
604
612
|
position.market.providerId
|
|
605
|
-
).
|
|
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,
|
|
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
|
-
|
|
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'
|
package/src/types/provider.ts
CHANGED
|
@@ -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
|
|
461
|
-
* only an account-scoped figure. `undefined`
|
|
462
|
-
* to read for this market, and the caller falls
|
|
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
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
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
|
|
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
|
-
|
|
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`
|
package/src/types/withdrawal.ts
CHANGED
|
@@ -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
|
@@ -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
|
-
}
|