@lifi/perps-sdk-provider-lighter 30.0.0 → 31.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.
- package/dist/cjs/LighterProvider.d.ts.map +1 -1
- package/dist/cjs/LighterProvider.js +62 -54
- package/dist/cjs/LighterProvider.js.map +1 -1
- package/dist/cjs/accountSummary.d.ts +4 -1
- package/dist/cjs/accountSummary.d.ts.map +1 -1
- package/dist/cjs/accountSummary.js +8 -7
- package/dist/cjs/accountSummary.js.map +1 -1
- package/dist/cjs/availableToTrade.d.ts +2 -0
- package/dist/cjs/availableToTrade.d.ts.map +1 -1
- package/dist/cjs/availableToTrade.js +6 -7
- package/dist/cjs/availableToTrade.js.map +1 -1
- package/dist/cjs/types/pnl.d.ts.map +1 -1
- package/dist/cjs/types/ws.d.ts +5 -0
- package/dist/cjs/types/ws.d.ts.map +1 -1
- package/dist/cjs/utils/apiClient.d.ts +3 -2
- package/dist/cjs/utils/apiClient.d.ts.map +1 -1
- package/dist/cjs/utils/apiClient.js +5 -3
- package/dist/cjs/utils/apiClient.js.map +1 -1
- package/dist/cjs/utils/fetchDetailedAccount.d.ts +1 -1
- package/dist/cjs/utils/fetchDetailedAccount.d.ts.map +1 -1
- package/dist/cjs/utils/fetchDetailedAccount.js +2 -1
- package/dist/cjs/utils/fetchDetailedAccount.js.map +1 -1
- package/dist/cjs/utils/mapFill.d.ts.map +1 -1
- package/dist/cjs/utils/mapFill.js +1 -3
- package/dist/cjs/utils/mapFill.js.map +1 -1
- package/dist/cjs/utils/mapPortfolioHistory.d.ts +1 -1
- package/dist/cjs/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/cjs/utils/mapPortfolioHistory.js +36 -21
- package/dist/cjs/utils/mapPortfolioHistory.js.map +1 -1
- package/dist/cjs/utils/mapPosition.d.ts +1 -0
- package/dist/cjs/utils/mapPosition.d.ts.map +1 -1
- package/dist/cjs/utils/mapPosition.js +13 -1
- package/dist/cjs/utils/mapPosition.js.map +1 -1
- package/dist/cjs/utils/ohlcvInterval.d.ts.map +1 -1
- package/dist/cjs/utils/ohlcvInterval.js.map +1 -1
- package/dist/cjs/utils/spotPrice.d.ts +5 -1
- package/dist/cjs/utils/spotPrice.d.ts.map +1 -1
- package/dist/cjs/utils/spotPrice.js +14 -1
- package/dist/cjs/utils/spotPrice.js.map +1 -1
- package/dist/cjs/utils/withdrawableBalances.d.ts +3 -3
- package/dist/cjs/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/cjs/utils/withdrawableBalances.js +11 -3
- package/dist/cjs/utils/withdrawableBalances.js.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.d.ts +6 -0
- package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/cjs/websocket/LighterWsProvider.js +120 -9
- package/dist/cjs/websocket/LighterWsProvider.js.map +1 -1
- package/dist/esm/LighterProvider.d.ts.map +1 -1
- package/dist/esm/LighterProvider.js +71 -61
- package/dist/esm/LighterProvider.js.map +1 -1
- package/dist/esm/accountSummary.d.ts +17 -3
- package/dist/esm/accountSummary.d.ts.map +1 -1
- package/dist/esm/accountSummary.js +18 -9
- package/dist/esm/accountSummary.js.map +1 -1
- package/dist/esm/availableToTrade.d.ts +2 -0
- package/dist/esm/availableToTrade.d.ts.map +1 -1
- package/dist/esm/availableToTrade.js +4 -6
- package/dist/esm/availableToTrade.js.map +1 -1
- package/dist/esm/types/pnl.d.ts +2 -3
- package/dist/esm/types/pnl.d.ts.map +1 -1
- package/dist/esm/types/ws.d.ts +13 -0
- package/dist/esm/types/ws.d.ts.map +1 -1
- package/dist/esm/types/ws.js +0 -11
- package/dist/esm/types/ws.js.map +1 -1
- package/dist/esm/utils/apiClient.d.ts +9 -2
- package/dist/esm/utils/apiClient.d.ts.map +1 -1
- package/dist/esm/utils/apiClient.js +9 -2
- package/dist/esm/utils/apiClient.js.map +1 -1
- package/dist/esm/utils/fetchDetailedAccount.d.ts +1 -1
- package/dist/esm/utils/fetchDetailedAccount.d.ts.map +1 -1
- package/dist/esm/utils/fetchDetailedAccount.js +2 -1
- package/dist/esm/utils/fetchDetailedAccount.js.map +1 -1
- package/dist/esm/utils/mapFill.d.ts.map +1 -1
- package/dist/esm/utils/mapFill.js +6 -10
- package/dist/esm/utils/mapFill.js.map +1 -1
- package/dist/esm/utils/mapPortfolioHistory.d.ts +3 -6
- package/dist/esm/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/esm/utils/mapPortfolioHistory.js +38 -26
- package/dist/esm/utils/mapPortfolioHistory.js.map +1 -1
- package/dist/esm/utils/mapPosition.d.ts +7 -0
- package/dist/esm/utils/mapPosition.d.ts.map +1 -1
- package/dist/esm/utils/mapPosition.js +17 -0
- package/dist/esm/utils/mapPosition.js.map +1 -1
- package/dist/esm/utils/ohlcvInterval.d.ts.map +1 -1
- package/dist/esm/utils/ohlcvInterval.js +5 -3
- package/dist/esm/utils/ohlcvInterval.js.map +1 -1
- package/dist/esm/utils/spotPrice.d.ts +10 -1
- package/dist/esm/utils/spotPrice.d.ts.map +1 -1
- package/dist/esm/utils/spotPrice.js +14 -0
- package/dist/esm/utils/spotPrice.js.map +1 -1
- package/dist/esm/utils/withdrawableBalances.d.ts +12 -5
- package/dist/esm/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/esm/utils/withdrawableBalances.js +17 -5
- package/dist/esm/utils/withdrawableBalances.js.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.d.ts +24 -0
- package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -1
- package/dist/esm/websocket/LighterWsProvider.js +153 -15
- package/dist/esm/websocket/LighterWsProvider.js.map +1 -1
- package/dist/types/LighterProvider.d.ts.map +1 -1
- package/dist/types/accountSummary.d.ts +17 -3
- package/dist/types/accountSummary.d.ts.map +1 -1
- package/dist/types/availableToTrade.d.ts +2 -0
- package/dist/types/availableToTrade.d.ts.map +1 -1
- package/dist/types/types/pnl.d.ts +2 -3
- package/dist/types/types/pnl.d.ts.map +1 -1
- package/dist/types/types/ws.d.ts +13 -0
- package/dist/types/types/ws.d.ts.map +1 -1
- package/dist/types/utils/apiClient.d.ts +9 -2
- package/dist/types/utils/apiClient.d.ts.map +1 -1
- package/dist/types/utils/fetchDetailedAccount.d.ts +1 -1
- package/dist/types/utils/fetchDetailedAccount.d.ts.map +1 -1
- package/dist/types/utils/mapFill.d.ts.map +1 -1
- package/dist/types/utils/mapPortfolioHistory.d.ts +3 -6
- package/dist/types/utils/mapPortfolioHistory.d.ts.map +1 -1
- package/dist/types/utils/mapPosition.d.ts +7 -0
- package/dist/types/utils/mapPosition.d.ts.map +1 -1
- package/dist/types/utils/ohlcvInterval.d.ts.map +1 -1
- package/dist/types/utils/spotPrice.d.ts +10 -1
- package/dist/types/utils/spotPrice.d.ts.map +1 -1
- package/dist/types/utils/withdrawableBalances.d.ts +12 -5
- package/dist/types/utils/withdrawableBalances.d.ts.map +1 -1
- package/dist/types/websocket/LighterWsProvider.d.ts +24 -0
- package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/LighterProvider.ts +119 -74
- package/src/accountSummary.ts +37 -14
- package/src/availableToTrade.ts +6 -10
- package/src/types/pnl.ts +2 -3
- package/src/types/ws.ts +23 -0
- package/src/utils/apiClient.ts +16 -7
- package/src/utils/fetchDetailedAccount.ts +2 -2
- package/src/utils/mapFill.ts +6 -13
- package/src/utils/mapPortfolioHistory.ts +42 -27
- package/src/utils/mapPosition.ts +17 -0
- package/src/utils/ohlcvInterval.ts +5 -3
- package/src/utils/spotPrice.ts +21 -1
- package/src/utils/withdrawableBalances.ts +26 -7
- package/src/websocket/LighterWsProvider.ts +222 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spotPrice.d.ts","sourceRoot":"","sources":["../../../src/utils/spotPrice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"spotPrice.d.ts","sourceRoot":"","sources":["../../../src/utils/spotPrice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,GAAG,MAAM,QAAQ,CAAA;AAGxB;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,SAAS,MAAM,EAAE,EAC1B,gBAAgB,MAAM,EACtB,UAAU,SAAS,aAAa,EAAE,EAClC,UAAU,WAAW,CAAC,MAAM,CAAC,KAC5B,GAAG,CAAC,MAAM,EAAE,GAAG,CAmBjB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,OAAO,MAAM,EACb,sBAAsB,MAAM,EAC5B,YAAY,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,KACnC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAA;CAQjC,CAAA"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type {
|
|
1
|
+
import { type ProviderWithdrawableBalance } from '@lifi/perps-sdk';
|
|
2
|
+
import type { LtAccount } from '../types/account.js';
|
|
3
3
|
/**
|
|
4
4
|
* Split each held asset into the two routes a Lighter withdrawal can name:
|
|
5
5
|
* spot draws on `balance` net of `locked_balance`, perps draws on
|
|
6
|
-
* `margin_balance`.
|
|
7
|
-
*
|
|
6
|
+
* `margin_balance`. The settlement asset's perps route is also capped by the
|
|
7
|
+
* account `available_balance`, which excludes the margin open positions use.
|
|
8
|
+
* Every other asset's perps route reports its full `margin_balance`, uncapped,
|
|
9
|
+
* although `getAccount` reports `transferable: '0'` for it: a category
|
|
10
|
+
* transfer moves only the settlement asset. Routes with nothing left to draw
|
|
11
|
+
* are dropped; the per-asset venue minimum is applied by the caller holding
|
|
12
|
+
* the asset registry.
|
|
8
13
|
*
|
|
14
|
+
* @param settlementAssetIndex - L2 asset index of the deployment's collateral
|
|
15
|
+
* asset, the only asset that `available_balance` is denominated in.
|
|
9
16
|
* @public
|
|
10
17
|
*/
|
|
11
|
-
export declare const lighterWithdrawableBalances: (assets:
|
|
18
|
+
export declare const lighterWithdrawableBalances: (account: Pick<LtAccount, "assets" | "available_balance">, settlementAssetIndex: number) => ProviderWithdrawableBalance[];
|
|
12
19
|
//# sourceMappingURL=withdrawableBalances.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withdrawableBalances.d.ts","sourceRoot":"","sources":["../../../src/utils/withdrawableBalances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"withdrawableBalances.d.ts","sourceRoot":"","sources":["../../../src/utils/withdrawableBalances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,2BAA2B,EAAE,MAAM,iBAAiB,CAAA;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAGpD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,mBAAmB,CAAC,EACxD,sBAAsB,MAAM,KAC3B,2BAA2B,EA0B7B,CAAA"}
|
|
@@ -59,6 +59,7 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
59
59
|
* is a full open-position snapshot per the `PositionsEvent` contract.
|
|
60
60
|
*/
|
|
61
61
|
private readonly positionsByAddress;
|
|
62
|
+
private readonly accountSummaryInputs;
|
|
62
63
|
private readonly registry;
|
|
63
64
|
private readonly accountIndexCache;
|
|
64
65
|
private readonly accountIndexPromises;
|
|
@@ -77,6 +78,12 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
77
78
|
*/
|
|
78
79
|
subscribeQuote(params: ProviderGetQuoteParams, onQuote: QuoteListener): Promise<() => void>;
|
|
79
80
|
protected openChannel(sub: Subscription): Promise<() => void>;
|
|
81
|
+
/**
|
|
82
|
+
* Hold a `marketsContext` subscription for the spot marks that price the
|
|
83
|
+
* account's spot balances. The ref-counted base shares the wire channels
|
|
84
|
+
* with any consumer `marketsContext` subscription.
|
|
85
|
+
*/
|
|
86
|
+
private subscribeSpotMarks;
|
|
80
87
|
protected onClose(): void;
|
|
81
88
|
protected sendSubscribe({ channel, needsAuth, address, }: SubState): Promise<void>;
|
|
82
89
|
/**
|
|
@@ -87,6 +94,8 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
87
94
|
* code, as it does for the Ondo and Lighter REST auth failures.
|
|
88
95
|
*/
|
|
89
96
|
private requireAuthToken;
|
|
97
|
+
/** Whether a token resolves for the address; a resolver that throws counts as no token. */
|
|
98
|
+
private canResolveAuthToken;
|
|
90
99
|
protected toKey(sub: Subscription): string;
|
|
91
100
|
private resolveChannel;
|
|
92
101
|
private resolveAccountIndex;
|
|
@@ -95,6 +104,21 @@ export declare class LighterWsProvider extends WsProviderBase<SubState> {
|
|
|
95
104
|
private dispatch;
|
|
96
105
|
private handleAccountOrders;
|
|
97
106
|
private handleUserStats;
|
|
107
|
+
/**
|
|
108
|
+
* Replace the spot balances on a `subscribed/` frame and upsert them on an
|
|
109
|
+
* `update/` frame. An update before the first snapshot is dropped, so the
|
|
110
|
+
* map never holds a partial set. Balances parse here, so a non-decimal
|
|
111
|
+
* balance rejects its frame and never reaches the emit path.
|
|
112
|
+
*/
|
|
113
|
+
private handleAccountAll;
|
|
114
|
+
/**
|
|
115
|
+
* Emit the account summary once both the `user_stats` figures and the spot
|
|
116
|
+
* balances are in. `portfolioValue` values the spot balances as REST
|
|
117
|
+
* `getAccount` does. `onlyOnChange` skips an emit whose `portfolioValue`
|
|
118
|
+
* equals the last one, so a mark tick on an unrelated market emits nothing.
|
|
119
|
+
*/
|
|
120
|
+
private emitAccountSummary;
|
|
121
|
+
private settlementAssetIndex;
|
|
98
122
|
private handleAccountTrades;
|
|
99
123
|
private handleAccountPositions;
|
|
100
124
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LighterWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/LighterWsProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAKlB,cAAc,EACd,KAAK,iBAAiB,EAGvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"LighterWsProvider.d.ts","sourceRoot":"","sources":["../../../src/websocket/LighterWsProvider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/perps-sdk-provider-lighter",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "31.0.0",
|
|
4
4
|
"description": "Lighter provider plugin for @lifi/perps-sdk",
|
|
5
5
|
"homepage": "https://github.com/lifinance/perps-sdk",
|
|
6
6
|
"bugs": {
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"big.js": "^7.0.1",
|
|
46
46
|
"viem": "^2.55.18",
|
|
47
|
-
"@lifi/perps-types": "^
|
|
47
|
+
"@lifi/perps-types": "^18.0.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@lifi/perps-sdk": "^
|
|
50
|
+
"@lifi/perps-sdk": "^20.0.0"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
package/src/LighterProvider.ts
CHANGED
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
getProviders,
|
|
10
10
|
isActiveOrderStatus,
|
|
11
11
|
localStorageAdapter,
|
|
12
|
+
maxOf,
|
|
13
|
+
minOf,
|
|
12
14
|
PerpsError,
|
|
13
15
|
type PerpsProviderPlugin,
|
|
14
16
|
type PerpsSDKClient,
|
|
@@ -74,7 +76,7 @@ import {
|
|
|
74
76
|
projectLighterConfigSettings,
|
|
75
77
|
resolveAccountTier,
|
|
76
78
|
} from './accountConfig.js'
|
|
77
|
-
import { getAccountSummary } from './accountSummary.js'
|
|
79
|
+
import { getAccountSummary, lighterConfig } from './accountSummary.js'
|
|
78
80
|
import { lighterAvailableToTrade } from './availableToTrade.js'
|
|
79
81
|
import {
|
|
80
82
|
DEFAULT_TRADES_LIMIT,
|
|
@@ -159,7 +161,7 @@ import {
|
|
|
159
161
|
fetchRegisteredApiKey,
|
|
160
162
|
normalizeLighterPublicKey,
|
|
161
163
|
} from './utils/registeredApiKey.js'
|
|
162
|
-
import { spotPriceByAssetId } from './utils/spotPrice.js'
|
|
164
|
+
import { spotPriceByAssetId, spotValuation } from './utils/spotPrice.js'
|
|
163
165
|
import { isPlaceholderTxHash } from './utils/txHash.js'
|
|
164
166
|
import { wireList } from './utils/wireList.js'
|
|
165
167
|
|
|
@@ -168,13 +170,6 @@ const ZERO_FEE_TIER = { maker: '0', taker: '0' }
|
|
|
168
170
|
const tickToFeeString = (tick: number): string =>
|
|
169
171
|
String(tick / LIGHTER_FEE_TICK_SCALE)
|
|
170
172
|
|
|
171
|
-
const transferableWithin = (venueFigure: Big, units: Big): string => {
|
|
172
|
-
if (venueFigure.lt(0)) {
|
|
173
|
-
return '0'
|
|
174
|
-
}
|
|
175
|
-
return (venueFigure.gt(units) ? units : venueFigure).toFixed()
|
|
176
|
-
}
|
|
177
|
-
|
|
178
173
|
const projectFeeTier = (
|
|
179
174
|
limits: LtAccountLimits
|
|
180
175
|
): { maker: string; taker: string } => ({
|
|
@@ -200,21 +195,21 @@ const CLIENT_ORDER_INDEX_PATTERN = /^\d+$/
|
|
|
200
195
|
const INACTIVE_ORDERS_LOOKUP_LIMIT = 100
|
|
201
196
|
|
|
202
197
|
interface PnlWindow {
|
|
203
|
-
resolution: '1h' | '
|
|
204
|
-
|
|
198
|
+
resolution: '1h' | '1d'
|
|
199
|
+
bucketSeconds: number
|
|
205
200
|
countBack: number
|
|
206
201
|
}
|
|
207
202
|
|
|
208
|
-
const
|
|
209
|
-
const
|
|
203
|
+
const HOUR_SECONDS = 60 * 60
|
|
204
|
+
const DAY_SECONDS = 24 * HOUR_SECONDS
|
|
210
205
|
|
|
211
206
|
// `all` has no natural bucket count; 1000 daily buckets reach back past the
|
|
212
207
|
// venue's launch for every account.
|
|
213
208
|
const PNL_WINDOWS: Record<PortfolioHistoryRange, PnlWindow> = {
|
|
214
|
-
'24h': { resolution: '1h',
|
|
215
|
-
'7d': { resolution: '
|
|
216
|
-
'30d': { resolution: '1d',
|
|
217
|
-
all: { resolution: '1d',
|
|
209
|
+
'24h': { resolution: '1h', bucketSeconds: HOUR_SECONDS, countBack: 24 },
|
|
210
|
+
'7d': { resolution: '1h', bucketSeconds: HOUR_SECONDS, countBack: 168 },
|
|
211
|
+
'30d': { resolution: '1d', bucketSeconds: DAY_SECONDS, countBack: 30 },
|
|
212
|
+
all: { resolution: '1d', bucketSeconds: DAY_SECONDS, countBack: 1000 },
|
|
218
213
|
}
|
|
219
214
|
|
|
220
215
|
/** Batches that get the pre-sign account tier check. */
|
|
@@ -789,24 +784,48 @@ export const createLighterProvider = (
|
|
|
789
784
|
}
|
|
790
785
|
}
|
|
791
786
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
787
|
+
/** The account, or `undefined` when Lighter has no account for the address. */
|
|
788
|
+
const fetchAccountIfExists = async (
|
|
789
|
+
client: LighterApiClient,
|
|
790
|
+
address: Address
|
|
791
|
+
): Promise<LtAccount | undefined> => {
|
|
796
792
|
try {
|
|
797
|
-
await fetchDetailedAccount(
|
|
798
|
-
return true
|
|
793
|
+
return await fetchDetailedAccount(client, address)
|
|
799
794
|
} catch (err) {
|
|
800
795
|
if (
|
|
801
796
|
err instanceof PerpsError &&
|
|
802
797
|
err.code === PerpsErrorCode.AccountNotFound
|
|
803
798
|
) {
|
|
804
|
-
return
|
|
799
|
+
return undefined
|
|
805
800
|
}
|
|
806
801
|
throw err
|
|
807
802
|
}
|
|
808
803
|
}
|
|
809
804
|
|
|
805
|
+
/** The venue default for a market: its backend `defaultLeverage`, with cross margin. */
|
|
806
|
+
const resolveDefaultMarketSettings = async (
|
|
807
|
+
marketId: string
|
|
808
|
+
): Promise<MarketSettings> => {
|
|
809
|
+
const registry = getMarketRegistry(requireClient(), providerKey)
|
|
810
|
+
await registry.sync()
|
|
811
|
+
const market = registry.require(marketId)
|
|
812
|
+
const leverage =
|
|
813
|
+
'maxLeverage' in market ? market.defaultLeverage : undefined
|
|
814
|
+
if (leverage === undefined || !(leverage > 0)) {
|
|
815
|
+
throw new PerpsError(
|
|
816
|
+
PerpsErrorCode.SDKError,
|
|
817
|
+
`The backend market '${marketId}' carries no positive Lighter default leverage`
|
|
818
|
+
)
|
|
819
|
+
}
|
|
820
|
+
return { marginMode: MarginMode.CROSS, leverage }
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const resolveAccountExists = async (
|
|
824
|
+
address: Address,
|
|
825
|
+
opts?: SDKRequestOptions
|
|
826
|
+
): Promise<boolean> =>
|
|
827
|
+
(await fetchAccountIfExists(apiClient(opts), address)) !== undefined
|
|
828
|
+
|
|
810
829
|
let setupPromise: Promise<SetupAction[]> | undefined
|
|
811
830
|
|
|
812
831
|
/** The venue's own `Provider.setup` descriptor for an action, if declared. */
|
|
@@ -963,9 +982,6 @@ export const createLighterProvider = (
|
|
|
963
982
|
const instanceMeta = providers.find((p) => p.key === providerKey)
|
|
964
983
|
const categories = instanceMeta?.categories ?? []
|
|
965
984
|
const perpsCategory = categories.find((c) => c.quoteAsset !== null)
|
|
966
|
-
const spotCategoryId =
|
|
967
|
-
categories.find((c) => c.quoteAsset === null)?.id ??
|
|
968
|
-
LIGHTER_SPOT_CATEGORY_ID
|
|
969
985
|
|
|
970
986
|
const availableBalance = toRequiredBig(
|
|
971
987
|
account.available_balance,
|
|
@@ -982,7 +998,7 @@ export const createLighterProvider = (
|
|
|
982
998
|
)
|
|
983
999
|
const spotPrices = spotPriceByAssetId(
|
|
984
1000
|
registry.markets,
|
|
985
|
-
|
|
1001
|
+
LIGHTER_SPOT_CATEGORY_ID,
|
|
986
1002
|
prices,
|
|
987
1003
|
new Set(
|
|
988
1004
|
[...heldAssets, ...marginAssets]
|
|
@@ -996,16 +1012,17 @@ export const createLighterProvider = (
|
|
|
996
1012
|
asset: Asset,
|
|
997
1013
|
units: string
|
|
998
1014
|
): Balance => {
|
|
999
|
-
const price =
|
|
1000
|
-
a.asset_id
|
|
1001
|
-
|
|
1002
|
-
|
|
1015
|
+
const { valueUsd, price } = spotValuation(
|
|
1016
|
+
a.asset_id,
|
|
1017
|
+
units,
|
|
1018
|
+
collateral.assetIndex,
|
|
1019
|
+
spotPrices
|
|
1020
|
+
)
|
|
1003
1021
|
return {
|
|
1004
1022
|
categoryId,
|
|
1005
1023
|
asset,
|
|
1006
1024
|
units,
|
|
1007
|
-
valueUsd
|
|
1008
|
-
price === undefined ? '0' : new Big(units).times(price).toFixed(),
|
|
1025
|
+
valueUsd,
|
|
1009
1026
|
...(price === undefined ? {} : { price: price.toFixed() }),
|
|
1010
1027
|
}
|
|
1011
1028
|
}
|
|
@@ -1033,13 +1050,31 @@ export const createLighterProvider = (
|
|
|
1033
1050
|
a.margin_balance
|
|
1034
1051
|
),
|
|
1035
1052
|
transferable: isSettlement
|
|
1036
|
-
?
|
|
1053
|
+
? minOf(
|
|
1054
|
+
maxOf(availableBalance, new Big(0)),
|
|
1055
|
+
new Big(a.margin_balance)
|
|
1056
|
+
).toFixed()
|
|
1037
1057
|
: '0',
|
|
1038
1058
|
}
|
|
1039
1059
|
})
|
|
1040
|
-
const balances: Balance[] = heldAssets.map((a) =>
|
|
1041
|
-
|
|
1042
|
-
|
|
1060
|
+
const balances: Balance[] = heldAssets.map((a) => {
|
|
1061
|
+
const balance = new Big(a.balance)
|
|
1062
|
+
return {
|
|
1063
|
+
...toBalance(
|
|
1064
|
+
a,
|
|
1065
|
+
LIGHTER_SPOT_CATEGORY_ID,
|
|
1066
|
+
registryAsset(a),
|
|
1067
|
+
a.balance
|
|
1068
|
+
),
|
|
1069
|
+
transferable: minOf(
|
|
1070
|
+
maxOf(
|
|
1071
|
+
balance.minus(toRequiredBig(a.locked_balance, 'locked_balance')),
|
|
1072
|
+
new Big(0)
|
|
1073
|
+
),
|
|
1074
|
+
balance
|
|
1075
|
+
).toFixed(),
|
|
1076
|
+
}
|
|
1077
|
+
})
|
|
1043
1078
|
|
|
1044
1079
|
const assetCollateral = account.assets.flatMap((a) =>
|
|
1045
1080
|
a.margin_mode === undefined
|
|
@@ -1059,6 +1094,8 @@ export const createLighterProvider = (
|
|
|
1059
1094
|
apiKeyRegistered,
|
|
1060
1095
|
accountType: account.account_type,
|
|
1061
1096
|
availableBalance: account.available_balance,
|
|
1097
|
+
crossAssetValue: account.cross_asset_value,
|
|
1098
|
+
crossInitialMarginRequirement: account.cross_initial_margin_requirement,
|
|
1062
1099
|
totalAssetValue: account.total_asset_value,
|
|
1063
1100
|
userTierName: limitsResult?.user_tier_name,
|
|
1064
1101
|
accountTradingMode:
|
|
@@ -1112,11 +1149,13 @@ export const createLighterProvider = (
|
|
|
1112
1149
|
params: ProviderGetWithdrawableBalancesParams,
|
|
1113
1150
|
opts?: SDKRequestOptions
|
|
1114
1151
|
): Promise<ProviderWithdrawableBalance[]> {
|
|
1115
|
-
const account = await
|
|
1152
|
+
const account = await fetchAccountIfExists(
|
|
1116
1153
|
apiClient(opts),
|
|
1117
1154
|
params.address
|
|
1118
1155
|
)
|
|
1119
|
-
return
|
|
1156
|
+
return account === undefined
|
|
1157
|
+
? []
|
|
1158
|
+
: lighterWithdrawableBalances(account, collateral.assetIndex)
|
|
1120
1159
|
},
|
|
1121
1160
|
|
|
1122
1161
|
async getPositions(
|
|
@@ -1126,9 +1165,16 @@ export const createLighterProvider = (
|
|
|
1126
1165
|
const client = apiClient(opts)
|
|
1127
1166
|
const registry = getMarketRegistry(requireClient(), providerKey)
|
|
1128
1167
|
const [account] = await Promise.all([
|
|
1129
|
-
|
|
1168
|
+
fetchAccountIfExists(client, params.address),
|
|
1130
1169
|
registry.sync(),
|
|
1131
1170
|
])
|
|
1171
|
+
if (account === undefined) {
|
|
1172
|
+
return {
|
|
1173
|
+
provider: providerKey,
|
|
1174
|
+
positions: [],
|
|
1175
|
+
pagination: { limit: params.limit ?? 0, hasMore: false },
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1132
1178
|
|
|
1133
1179
|
let positions: Position[] = mapOpenPositions(account.positions, (id) =>
|
|
1134
1180
|
toPerpsMarketDisplay(registry.require(String(id)))
|
|
@@ -1165,39 +1211,38 @@ export const createLighterProvider = (
|
|
|
1165
1211
|
},
|
|
1166
1212
|
|
|
1167
1213
|
/**
|
|
1168
|
-
* Lighter reports a market's margin mode and leverage
|
|
1169
|
-
*
|
|
1170
|
-
*
|
|
1214
|
+
* Lighter reports a market's margin mode and leverage on the account's
|
|
1215
|
+
* position row. Without a row carrying a positive IMF (or without an
|
|
1216
|
+
* account), the venue applies the market's default leverage with cross margin.
|
|
1171
1217
|
*/
|
|
1172
1218
|
async getMarketSettings(
|
|
1173
1219
|
params: ProviderGetMarketSettingsParams,
|
|
1174
1220
|
opts?: SDKRequestOptions
|
|
1175
|
-
): Promise<MarketSettings
|
|
1176
|
-
|
|
1177
|
-
if (
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
account = await fetchDetailedAccount(apiClient(opts), params.address)
|
|
1183
|
-
} catch (err) {
|
|
1184
|
-
if (
|
|
1185
|
-
err instanceof PerpsError &&
|
|
1186
|
-
err.code === PerpsErrorCode.AccountNotFound
|
|
1187
|
-
) {
|
|
1188
|
-
return undefined
|
|
1189
|
-
}
|
|
1190
|
-
throw err
|
|
1221
|
+
): Promise<MarketSettings> {
|
|
1222
|
+
const { marketId, categoryId } = params.market
|
|
1223
|
+
if (categoryId === LIGHTER_SPOT_CATEGORY_ID) {
|
|
1224
|
+
throw new PerpsError(
|
|
1225
|
+
PerpsErrorCode.ValidationError,
|
|
1226
|
+
`Lighter market '${marketId}' is a spot market and carries no leverage setting`
|
|
1227
|
+
)
|
|
1191
1228
|
}
|
|
1192
|
-
const
|
|
1193
|
-
|
|
1229
|
+
const client = apiClient(opts)
|
|
1230
|
+
const account = await fetchAccountIfExists(client, params.address)
|
|
1231
|
+
const row = account?.positions.find(
|
|
1232
|
+
(p) => String(p.market_id) === marketId
|
|
1194
1233
|
)
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1234
|
+
// An unparsable IMF throws; a non-positive one means no stored setting.
|
|
1235
|
+
const leverage =
|
|
1236
|
+
row === undefined
|
|
1237
|
+
? undefined
|
|
1238
|
+
: leverageFromImf(
|
|
1239
|
+
toRequiredBig(
|
|
1240
|
+
row.initial_margin_fraction,
|
|
1241
|
+
'initial_margin_fraction'
|
|
1242
|
+
).toFixed()
|
|
1243
|
+
)
|
|
1244
|
+
if (row === undefined || leverage === undefined) {
|
|
1245
|
+
return resolveDefaultMarketSettings(marketId)
|
|
1201
1246
|
}
|
|
1202
1247
|
return {
|
|
1203
1248
|
marginMode:
|
|
@@ -1493,18 +1538,18 @@ export const createLighterProvider = (
|
|
|
1493
1538
|
}
|
|
1494
1539
|
|
|
1495
1540
|
const client = apiClient(opts)
|
|
1496
|
-
const account = await
|
|
1541
|
+
const account = await plugin.getAccount({ address: params.address }, opts)
|
|
1497
1542
|
const window = PNL_WINDOWS[params.range]
|
|
1498
|
-
const
|
|
1543
|
+
const endTimestampSeconds = Math.floor(Date.now() / 1_000)
|
|
1499
1544
|
const queryParams: Record<string, string | number | boolean> = {
|
|
1500
1545
|
by: 'index',
|
|
1501
|
-
value: String(account.
|
|
1546
|
+
value: String(lighterConfig(account).accountIndex),
|
|
1502
1547
|
resolution: window.resolution,
|
|
1503
1548
|
start_timestamp:
|
|
1504
1549
|
params.range === 'all'
|
|
1505
1550
|
? 0
|
|
1506
|
-
:
|
|
1507
|
-
end_timestamp:
|
|
1551
|
+
: endTimestampSeconds - window.countBack * window.bucketSeconds,
|
|
1552
|
+
end_timestamp: endTimestampSeconds,
|
|
1508
1553
|
count_back: window.countBack,
|
|
1509
1554
|
ignore_transfers: false,
|
|
1510
1555
|
}
|
|
@@ -1537,7 +1582,7 @@ export const createLighterProvider = (
|
|
|
1537
1582
|
return mapPortfolioHistory(
|
|
1538
1583
|
params.range,
|
|
1539
1584
|
wireList(response.pnl),
|
|
1540
|
-
|
|
1585
|
+
new Big(getAccountSummary(account, account.positions).portfolioValue)
|
|
1541
1586
|
)
|
|
1542
1587
|
},
|
|
1543
1588
|
|
package/src/accountSummary.ts
CHANGED
|
@@ -7,10 +7,18 @@ import type {
|
|
|
7
7
|
} from '@lifi/perps-types'
|
|
8
8
|
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
9
9
|
import Big from 'big.js'
|
|
10
|
+
import { atLeastZero } from './availableToTrade.js'
|
|
10
11
|
import { LIGHTER_PROVIDER_KEY, LIGHTER_RH_PROVIDER_KEY } from './constants.js'
|
|
11
12
|
import { toRequiredBig } from './utils/decimal.js'
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The Lighter arm of `account.config`.
|
|
16
|
+
*
|
|
17
|
+
* @throws {PerpsError} `SDKError` when the account is not a Lighter one.
|
|
18
|
+
*/
|
|
19
|
+
export const lighterConfig = (
|
|
20
|
+
account: AccountResponse
|
|
21
|
+
): LighterAccountConfig => {
|
|
14
22
|
const { config } = account
|
|
15
23
|
if (
|
|
16
24
|
config.provider !== LIGHTER_PROVIDER_KEY &&
|
|
@@ -24,12 +32,27 @@ const lighterConfig = (account: AccountResponse): LighterAccountConfig => {
|
|
|
24
32
|
return config
|
|
25
33
|
}
|
|
26
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Lighter portfolio value: the perps-route equity (`total_asset_value`) plus
|
|
37
|
+
* the USD value of every spot-route holding, settlement asset included.
|
|
38
|
+
*/
|
|
39
|
+
export const lighterPortfolioValue = (
|
|
40
|
+
perpsEquity: Big,
|
|
41
|
+
spotValuesUsd: readonly string[]
|
|
42
|
+
): Big =>
|
|
43
|
+
spotValuesUsd.reduce(
|
|
44
|
+
(sum, valueUsd) => sum.plus(toRequiredBig(valueUsd, 'valueUsd')),
|
|
45
|
+
perpsEquity
|
|
46
|
+
)
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* Roll a Lighter account up into an {@link AccountSummary}. `totalAssetValue`
|
|
29
50
|
* is perps-route equity and excludes the spot route, so `portfolioValue` adds
|
|
30
51
|
* every spot `balances` row, settlement included; the `collateralBalances` rows
|
|
31
|
-
* are the perps-route holding already inside `totalAssetValue`.
|
|
32
|
-
*
|
|
52
|
+
* are the perps-route holding already inside `totalAssetValue`.
|
|
53
|
+
* `availableMargin` is the cross free collateral, floored at 0: an isolated
|
|
54
|
+
* position's equity stays with that position until the user removes it. The
|
|
55
|
+
* positions supply only the margin and PnL breakdown.
|
|
33
56
|
*
|
|
34
57
|
* @throws {PerpsError} `SDKError` when the account is not a Lighter one.
|
|
35
58
|
* @public
|
|
@@ -47,18 +70,18 @@ export function getAccountSummary(
|
|
|
47
70
|
unrealizedPnl = unrealizedPnl.plus(position.unrealizedPnl)
|
|
48
71
|
}
|
|
49
72
|
|
|
50
|
-
let portfolioValue = toRequiredBig(config.totalAssetValue, 'totalAssetValue')
|
|
51
|
-
for (const balance of account.balances) {
|
|
52
|
-
portfolioValue = portfolioValue.plus(
|
|
53
|
-
toRequiredBig(balance.valueUsd, 'valueUsd')
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
73
|
return {
|
|
58
|
-
portfolioValue:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
74
|
+
portfolioValue: lighterPortfolioValue(
|
|
75
|
+
toRequiredBig(config.totalAssetValue, 'totalAssetValue'),
|
|
76
|
+
account.balances.map((balance) => balance.valueUsd)
|
|
77
|
+
).toFixed(),
|
|
78
|
+
availableMargin: atLeastZero(
|
|
79
|
+
toRequiredBig(config.crossAssetValue, 'crossAssetValue').minus(
|
|
80
|
+
toRequiredBig(
|
|
81
|
+
config.crossInitialMarginRequirement,
|
|
82
|
+
'crossInitialMarginRequirement'
|
|
83
|
+
)
|
|
84
|
+
)
|
|
62
85
|
).toFixed(),
|
|
63
86
|
marginUsed: marginUsed.toFixed(),
|
|
64
87
|
unrealizedPnl: unrealizedPnl.toFixed(),
|
package/src/availableToTrade.ts
CHANGED
|
@@ -4,23 +4,19 @@ import { MarginMode, PositionSide } from '@lifi/perps-types'
|
|
|
4
4
|
import Big from 'big.js'
|
|
5
5
|
import { toRequiredBig } from './utils/decimal.js'
|
|
6
6
|
|
|
7
|
-
const atLeastZero = (value: Big): Big =>
|
|
7
|
+
export const atLeastZero = (value: Big): Big =>
|
|
8
|
+
value.lt(0) ? new Big(0) : value
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
//
|
|
10
|
+
// `availableMargin` is the cross free collateral and holds nothing of an
|
|
11
|
+
// isolated position, so closing one releases its whole equity.
|
|
11
12
|
const releasedOnClose = (position: Position): Big => {
|
|
12
13
|
const marginUsed = toRequiredBig(position.marginUsed, 'marginUsed')
|
|
13
14
|
if (position.marginMode !== MarginMode.ISOLATED) {
|
|
14
15
|
return marginUsed
|
|
15
16
|
}
|
|
16
|
-
|
|
17
|
-
toRequiredBig(position.unrealizedPnl, 'unrealizedPnl')
|
|
17
|
+
return atLeastZero(
|
|
18
|
+
marginUsed.plus(toRequiredBig(position.unrealizedPnl, 'unrealizedPnl'))
|
|
18
19
|
)
|
|
19
|
-
const imr = toRequiredBig(
|
|
20
|
-
position.initialMarginRequirement,
|
|
21
|
-
'initialMarginRequirement'
|
|
22
|
-
)
|
|
23
|
-
return equity.lt(imr) ? equity : imr
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
/**
|
package/src/types/pnl.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
// Lighter serializes an empty list as JSON `null`, so list members are nullable.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* One PnL
|
|
6
|
-
*
|
|
7
|
-
* value.
|
|
5
|
+
* One cumulative PnL snapshot. `timestamp` is Unix seconds; PnL, flow, and
|
|
6
|
+
* volume fields are cumulative totals as of that timestamp.
|
|
8
7
|
*
|
|
9
8
|
* @public
|
|
10
9
|
*/
|
package/src/types/ws.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { LtAccountAsset } from './account.js'
|
|
2
|
+
|
|
1
3
|
// The Lighter stream server sends JSON messages of shape:
|
|
2
4
|
// { type: 'subscribed/<channel>' | 'update/<channel>' | 'ping',
|
|
3
5
|
// channel: '<channel>/<id>',
|
|
@@ -9,6 +11,7 @@
|
|
|
9
11
|
// - spot_market_stats/all → context across all spot markets
|
|
10
12
|
// - spot_market_stats/{id} → context for one spot market
|
|
11
13
|
// - order_book/{market_id} → bids/asks per market (stateful with deltas)
|
|
14
|
+
// - account_all/{account} → per-asset spot-route balances
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* Common envelope fields on every Lighter WebSocket frame.
|
|
@@ -211,6 +214,26 @@ export type LtWsUserStatsMessage = LtWsMessage & {
|
|
|
211
214
|
}
|
|
212
215
|
}
|
|
213
216
|
|
|
217
|
+
/**
|
|
218
|
+
* `account_all/{account_index}` or `account_all_assets/{account_index}` frame,
|
|
219
|
+
* read for its `assets` map only. The `subscribed/` frame carries every asset
|
|
220
|
+
* keyed by asset index; an `update/` frame carries the changed assets, or
|
|
221
|
+
* `null` when no balance changed. `balance` is the spot-route balance in asset
|
|
222
|
+
* units.
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
export type LtWsAccountAllMessage = LtWsMessage & {
|
|
226
|
+
type:
|
|
227
|
+
| 'subscribed/account_all'
|
|
228
|
+
| 'update/account_all'
|
|
229
|
+
| 'subscribed/account_all_assets'
|
|
230
|
+
| 'update/account_all_assets'
|
|
231
|
+
assets?: Record<
|
|
232
|
+
string,
|
|
233
|
+
Pick<LtAccountAsset, 'symbol' | 'asset_id' | 'balance' | 'locked_balance'>
|
|
234
|
+
> | null
|
|
235
|
+
}
|
|
236
|
+
|
|
214
237
|
/**
|
|
215
238
|
* Authenticated account-position frame. Position and funding maps are keyed
|
|
216
239
|
* by Lighter market index; the provider normalizes the payload before emitting
|