@zofai/zo-sdk 0.1.93 → 0.1.95
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 +4 -3
- package/dist/consts/deployments-slp-mainnet.json +1 -1
- package/dist/consts/deployments-usdz-mainnet.json +1 -1
- package/dist/consts/deployments-zlp-mainnet.json +1 -1
- package/dist/implementations/SLPAPI.cjs +34 -0
- package/dist/implementations/SLPAPI.cjs.map +1 -1
- package/dist/implementations/SLPAPI.d.cts +6 -0
- package/dist/implementations/SLPAPI.d.cts.map +1 -1
- package/dist/implementations/SLPAPI.d.mts +6 -0
- package/dist/implementations/SLPAPI.d.mts.map +1 -1
- package/dist/implementations/SLPAPI.mjs +34 -0
- package/dist/implementations/SLPAPI.mjs.map +1 -1
- package/dist/implementations/SLPDataAPI.cjs +212 -47
- package/dist/implementations/SLPDataAPI.cjs.map +1 -1
- package/dist/implementations/SLPDataAPI.d.cts +8 -1
- package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
- package/dist/implementations/SLPDataAPI.d.mts +8 -1
- package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
- package/dist/implementations/SLPDataAPI.mjs +212 -47
- package/dist/implementations/SLPDataAPI.mjs.map +1 -1
- package/dist/implementations/USDZAPI.cjs +32 -0
- package/dist/implementations/USDZAPI.cjs.map +1 -1
- package/dist/implementations/USDZAPI.d.cts +6 -0
- package/dist/implementations/USDZAPI.d.cts.map +1 -1
- package/dist/implementations/USDZAPI.d.mts +6 -0
- package/dist/implementations/USDZAPI.d.mts.map +1 -1
- package/dist/implementations/USDZAPI.mjs +32 -0
- package/dist/implementations/USDZAPI.mjs.map +1 -1
- package/dist/implementations/USDZDataAPI.cjs +197 -44
- package/dist/implementations/USDZDataAPI.cjs.map +1 -1
- package/dist/implementations/USDZDataAPI.d.cts +8 -1
- package/dist/implementations/USDZDataAPI.d.cts.map +1 -1
- package/dist/implementations/USDZDataAPI.d.mts +8 -1
- package/dist/implementations/USDZDataAPI.d.mts.map +1 -1
- package/dist/implementations/USDZDataAPI.mjs +197 -44
- package/dist/implementations/USDZDataAPI.mjs.map +1 -1
- package/dist/implementations/ZLPAPI.cjs +34 -0
- package/dist/implementations/ZLPAPI.cjs.map +1 -1
- package/dist/implementations/ZLPAPI.d.cts +6 -0
- package/dist/implementations/ZLPAPI.d.cts.map +1 -1
- package/dist/implementations/ZLPAPI.d.mts +6 -0
- package/dist/implementations/ZLPAPI.d.mts.map +1 -1
- package/dist/implementations/ZLPAPI.mjs +34 -0
- package/dist/implementations/ZLPAPI.mjs.map +1 -1
- package/dist/implementations/ZLPDataAPI.cjs +200 -46
- package/dist/implementations/ZLPDataAPI.cjs.map +1 -1
- package/dist/implementations/ZLPDataAPI.d.cts +8 -1
- package/dist/implementations/ZLPDataAPI.d.cts.map +1 -1
- package/dist/implementations/ZLPDataAPI.d.mts +8 -1
- package/dist/implementations/ZLPDataAPI.d.mts.map +1 -1
- package/dist/implementations/ZLPDataAPI.mjs +200 -46
- package/dist/implementations/ZLPDataAPI.mjs.map +1 -1
- package/dist/interfaces/base.d.cts +22 -0
- package/dist/interfaces/base.d.cts.map +1 -1
- package/dist/interfaces/base.d.mts +22 -0
- package/dist/interfaces/base.d.mts.map +1 -1
- package/dist/interfaces/slp.d.cts +11 -1
- package/dist/interfaces/slp.d.cts.map +1 -1
- package/dist/interfaces/slp.d.mts +11 -1
- package/dist/interfaces/slp.d.mts.map +1 -1
- package/dist/interfaces/usdz.d.cts +11 -1
- package/dist/interfaces/usdz.d.cts.map +1 -1
- package/dist/interfaces/usdz.d.mts +11 -1
- package/dist/interfaces/usdz.d.mts.map +1 -1
- package/dist/interfaces/zlp.d.cts +11 -1
- package/dist/interfaces/zlp.d.cts.map +1 -1
- package/dist/interfaces/zlp.d.mts +11 -1
- package/dist/interfaces/zlp.d.mts.map +1 -1
- package/docs/SUMMARY.md +1 -0
- package/docs/getting-started.md +4 -4
- package/docs/introduction.md +3 -3
- package/docs/swap-integration.md +183 -0
- package/docs/type-safety.md +1 -1
- package/package.json +1 -1
- package/src/consts/deployments-slp-mainnet.json +1 -1
- package/src/consts/deployments-usdz-mainnet.json +1 -1
- package/src/consts/deployments-zlp-mainnet.json +1 -1
- package/src/implementations/SLPAPI.ts +46 -0
- package/src/implementations/SLPDataAPI.ts +235 -19
- package/src/implementations/USDZAPI.ts +41 -0
- package/src/implementations/USDZDataAPI.ts +221 -16
- package/src/implementations/ZLPAPI.ts +43 -0
- package/src/implementations/ZLPDataAPI.ts +222 -17
- package/src/interfaces/base.ts +26 -0
- package/src/interfaces/slp.ts +19 -0
- package/src/interfaces/usdz.ts +19 -0
- package/src/interfaces/zlp.ts +19 -0
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* SLP DataAPI implementation
|
|
6
6
|
* Implements SLP-specific data access methods for Sudo SDK
|
|
7
7
|
*/
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _SLPDataAPI_instances, _a, _SLPDataAPI_getTotalVaultsValueUsd, _SLPDataAPI_getSwapImpactConfig, _SLPDataAPI_getEmaVolatilityFeeConfig, _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix, _SLPDataAPI_parseSwapImpactConfig, _SLPDataAPI_parseEmaVolatilityFeeConfig, _SLPDataAPI_computeSwapImpactFeeValue, _SLPDataAPI_computeEmaVolatilityFeeValue, _SLPDataAPI_maxEmaDivergenceRate, _SLPDataAPI_emaDivergenceRate;
|
|
8
14
|
import { Transaction } from "@mysten/sui/transactions";
|
|
9
15
|
import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
|
|
10
16
|
import { BaseDataAPI } from "../abstract/index.mjs";
|
|
@@ -16,6 +22,7 @@ const SECONDS_PER_EIGHT_HOUR = 8 * 60 * 60; // 28800 seconds
|
|
|
16
22
|
export class SLPDataAPI extends BaseDataAPI {
|
|
17
23
|
constructor(network, provider, apiEndpoint, connectionURL) {
|
|
18
24
|
super(network, provider, apiEndpoint, connectionURL, LPToken.SLP);
|
|
25
|
+
_SLPDataAPI_instances.add(this);
|
|
19
26
|
}
|
|
20
27
|
static calculateVaultReservingFee(vaultInfo, reservingFeeModel, currentTime) {
|
|
21
28
|
const timeDelta = currentTime - vaultInfo.lastUpdate;
|
|
@@ -23,8 +30,8 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
23
30
|
return vaultInfo.unrealisedReservingFeeAmount
|
|
24
31
|
+ (vaultInfo.reservedAmount * reservingFeeModel.multiplier * periods) / 1e18;
|
|
25
32
|
}
|
|
26
|
-
static calculateSymbolFundingFee(symbol, model, price, lpSupplyAmount, timestamp,
|
|
27
|
-
const accFundingRate =
|
|
33
|
+
static calculateSymbolFundingFee(symbol, model, price, lpSupplyAmount, timestamp, oiState, pairedOpeningSize) {
|
|
34
|
+
const accFundingRate = _a.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, symbol.long, oiState, pairedOpeningSize);
|
|
28
35
|
return symbol.unrealisedFundingFeeValue + (accFundingRate - symbol.accFundingRate) * symbol.openingSize;
|
|
29
36
|
}
|
|
30
37
|
async getRebaseFeeModel() {
|
|
@@ -38,8 +45,8 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
38
45
|
showContent: true,
|
|
39
46
|
},
|
|
40
47
|
});
|
|
41
|
-
const model =
|
|
42
|
-
const exponent = await
|
|
48
|
+
const model = _a.parseRebaseFeeModel(rawData);
|
|
49
|
+
const exponent = await _a.getRebaseFeeExponent(this.provider, this.consts.sudoCore.rebaseFeeModel, this.consts.sudoCore.upgradedPackage);
|
|
43
50
|
return { ...model, exponent };
|
|
44
51
|
}
|
|
45
52
|
/**
|
|
@@ -128,7 +135,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
128
135
|
const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
|
|
129
136
|
const vaultData = await Promise.all(vaultKeys.map(async (vault) => {
|
|
130
137
|
const vaultInfo = await this.getVaultInfo(vault);
|
|
131
|
-
const reservingFeeDelta =
|
|
138
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
|
|
132
139
|
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
133
140
|
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
134
141
|
const { decimals } = this.consts.coins[vault];
|
|
@@ -141,10 +148,10 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
141
148
|
const [direction, tokenId] = parseSymbolKey(symbol);
|
|
142
149
|
const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long');
|
|
143
150
|
const price = (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
144
|
-
const deltaSize =
|
|
151
|
+
const deltaSize = _a.calcDeltaSize(symbolInfo, price, direction === 'long');
|
|
145
152
|
const oiState = await this.getSymbolOiFundingState(tokenId);
|
|
146
153
|
const pairedInfo = await this.getSymbolInfo(tokenId, direction !== 'long');
|
|
147
|
-
const fundingFeeDelta =
|
|
154
|
+
const fundingFeeDelta = _a.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, price, marketInfo.lpSupplyWithDecimals, Date.now() / 1000, oiState && oiState.enabled ? oiState : undefined, pairedInfo.openingSize);
|
|
148
155
|
const symbolValue = fundingFeeDelta + deltaSize;
|
|
149
156
|
return symbolValue;
|
|
150
157
|
});
|
|
@@ -235,7 +242,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
235
242
|
});
|
|
236
243
|
const apr = await this.getCumulativeApr();
|
|
237
244
|
return {
|
|
238
|
-
...
|
|
245
|
+
..._a.parseMarketInfo(rawData),
|
|
239
246
|
apr,
|
|
240
247
|
};
|
|
241
248
|
}
|
|
@@ -287,7 +294,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
287
294
|
value: { dummy_field: false },
|
|
288
295
|
},
|
|
289
296
|
});
|
|
290
|
-
return
|
|
297
|
+
return _a.parseSymbolConfig(rawData);
|
|
291
298
|
}
|
|
292
299
|
catch {
|
|
293
300
|
// If the dynamic field doesn't exist, return null
|
|
@@ -309,7 +316,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
309
316
|
value: { dummy_field: false },
|
|
310
317
|
},
|
|
311
318
|
});
|
|
312
|
-
return
|
|
319
|
+
return _a.parsePriceImpactConfig(rawData);
|
|
313
320
|
}
|
|
314
321
|
catch (e) {
|
|
315
322
|
// If the dynamic field doesn't exist, return null (price impact not configured for this symbol)
|
|
@@ -330,7 +337,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
330
337
|
value: { dummy_field: false },
|
|
331
338
|
},
|
|
332
339
|
});
|
|
333
|
-
return
|
|
340
|
+
return _a.parseOiFundingState(rawData);
|
|
334
341
|
}
|
|
335
342
|
catch (e) {
|
|
336
343
|
// If the dynamic field doesn't exist, return null
|
|
@@ -338,6 +345,52 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
338
345
|
return null;
|
|
339
346
|
}
|
|
340
347
|
}
|
|
348
|
+
async calculateSwapFeeBreakdown(fromToken, toToken, fromAmount) {
|
|
349
|
+
if (!this.consts.sudoCore) {
|
|
350
|
+
throw new Error('Sudo Core configuration not found. Make sure you are using LPToken.SLP');
|
|
351
|
+
}
|
|
352
|
+
const timestamp = Date.now() / 1000;
|
|
353
|
+
const fromDecimals = this.consts.coins[fromToken]?.decimals;
|
|
354
|
+
const toDecimals = this.consts.coins[toToken]?.decimals;
|
|
355
|
+
if (fromDecimals === undefined || toDecimals === undefined) {
|
|
356
|
+
throw new Error(`Unknown token decimals for swap: ${fromToken} -> ${toToken}`);
|
|
357
|
+
}
|
|
358
|
+
const fromFeed = await this.getOraclePrice(fromToken);
|
|
359
|
+
const toFeed = await this.getOraclePrice(toToken);
|
|
360
|
+
const fromPrice = fromFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
361
|
+
const toPrice = toFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
362
|
+
const swapValue = (fromAmount * fromPrice) / (10 ** fromDecimals);
|
|
363
|
+
const totalVaultsValue = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getTotalVaultsValueUsd).call(this, timestamp);
|
|
364
|
+
const rebaseFeeInRate = await this.rebaseFeeRate(fromToken, true, fromAmount);
|
|
365
|
+
const rebaseFeeInValue = swapValue * rebaseFeeInRate;
|
|
366
|
+
const estimatedToAmount = toPrice !== 0
|
|
367
|
+
? (swapValue * (10 ** toDecimals)) / toPrice
|
|
368
|
+
: 0;
|
|
369
|
+
const rebaseFeeOutRate = await this.rebaseFeeRate(toToken, false, estimatedToAmount);
|
|
370
|
+
const rebaseFeeOutValue = swapValue * rebaseFeeOutRate;
|
|
371
|
+
const swapImpactCfg = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getSwapImpactConfig).call(this);
|
|
372
|
+
const swapImpactFeeValue = swapImpactCfg?.enabled
|
|
373
|
+
? __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_computeSwapImpactFeeValue).call(_a, swapValue, totalVaultsValue, swapImpactCfg.impactMultiplier, swapImpactCfg.maxImpactRate)
|
|
374
|
+
: 0;
|
|
375
|
+
const emaCfg = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getEmaVolatilityFeeConfig).call(this);
|
|
376
|
+
const emaVolatilityFeeValue = emaCfg?.enabled
|
|
377
|
+
? __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_computeEmaVolatilityFeeValue).call(_a, swapValue, __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_maxEmaDivergenceRate).call(_a, fromFeed, toFeed), emaCfg.multiplier, emaCfg.maxFeeRate)
|
|
378
|
+
: 0;
|
|
379
|
+
const totalFeeValue = rebaseFeeInValue + rebaseFeeOutValue + swapImpactFeeValue + emaVolatilityFeeValue;
|
|
380
|
+
const totalFeeRate = swapValue !== 0 ? totalFeeValue / swapValue : 0;
|
|
381
|
+
return {
|
|
382
|
+
swapValue,
|
|
383
|
+
totalVaultsValue,
|
|
384
|
+
rebaseFeeInRate,
|
|
385
|
+
rebaseFeeOutRate,
|
|
386
|
+
rebaseFeeInValue,
|
|
387
|
+
rebaseFeeOutValue,
|
|
388
|
+
swapImpactFeeValue,
|
|
389
|
+
emaVolatilityFeeValue,
|
|
390
|
+
totalFeeValue,
|
|
391
|
+
totalFeeRate,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
341
394
|
async getPositionInfoList(positionCapInfoList, owner, batchSize = 10) {
|
|
342
395
|
const positionInfoList = [];
|
|
343
396
|
// Process in batches of 10
|
|
@@ -429,7 +482,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
429
482
|
rawCredentialsData = [...rawCredentialsData, ...data];
|
|
430
483
|
}
|
|
431
484
|
const pool = await this.getStakePool();
|
|
432
|
-
const credentials = rawCredentialsData.map((item) =>
|
|
485
|
+
const credentials = rawCredentialsData.map((item) => _a.parseCredential(item, pool));
|
|
433
486
|
return {
|
|
434
487
|
credentials,
|
|
435
488
|
amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
|
|
@@ -446,7 +499,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
446
499
|
showContent: true,
|
|
447
500
|
},
|
|
448
501
|
});
|
|
449
|
-
return
|
|
502
|
+
return _a.parseStakePool(raw);
|
|
450
503
|
}
|
|
451
504
|
async getStakePoolV2() {
|
|
452
505
|
const poolId = this.sharedConfig.zoStaking.pools.slp;
|
|
@@ -456,7 +509,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
456
509
|
showContent: true,
|
|
457
510
|
},
|
|
458
511
|
});
|
|
459
|
-
return
|
|
512
|
+
return _a.parseStakePool(raw);
|
|
460
513
|
}
|
|
461
514
|
async getStakedV2(owner) {
|
|
462
515
|
let rawCredentialsData = [];
|
|
@@ -489,7 +542,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
489
542
|
const credentials = rawCredentialsData
|
|
490
543
|
.filter((item) => item.data.type
|
|
491
544
|
=== `${this.sharedConfig.zoStaking.package}::pool::Credential<${this.consts.sudoCore.package}::slp::SLP, ${this.consts.sudoCore.package}::slp::SLP>`)
|
|
492
|
-
.map((item) =>
|
|
545
|
+
.map((item) => _a.parseCredential(item, pool));
|
|
493
546
|
return {
|
|
494
547
|
credentials,
|
|
495
548
|
amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
|
|
@@ -505,7 +558,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
505
558
|
return 0;
|
|
506
559
|
}
|
|
507
560
|
const elapsed = SECONDS_PER_EIGHT_HOUR;
|
|
508
|
-
const deltaRate =
|
|
561
|
+
const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSymbol.openingSize, shortSymbol.openingSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
|
|
509
562
|
return long ? deltaRate : -deltaRate;
|
|
510
563
|
}
|
|
511
564
|
const symbol = await this.getSymbolInfo(indexToken, long);
|
|
@@ -516,9 +569,9 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
516
569
|
const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals;
|
|
517
570
|
const model = symbol.fundingFeeModel;
|
|
518
571
|
const elapsed = SECONDS_PER_EIGHT_HOUR;
|
|
519
|
-
const deltaSize =
|
|
572
|
+
const deltaSize = _a.calcDeltaSize(symbol, price, symbol.long);
|
|
520
573
|
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
|
|
521
|
-
return
|
|
574
|
+
return _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
|
|
522
575
|
}
|
|
523
576
|
async rebaseFeeRate(collateralToken, increase, amount, _sender) {
|
|
524
577
|
let vaultValue = 0;
|
|
@@ -528,7 +581,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
528
581
|
const value = amount * (await this.getOraclePrice(collateralToken)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[collateralToken].decimals);
|
|
529
582
|
const vaultPromises = Object.keys(this.consts.sudoCore.vaults).map(async (vault) => {
|
|
530
583
|
const vaultInfo = await this.getVaultInfo(vault);
|
|
531
|
-
const reservingFeeDelta =
|
|
584
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
|
|
532
585
|
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
533
586
|
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
534
587
|
const res = totalVaultAmount * oraclePrice / (10 ** this.consts.coins[vault].decimals);
|
|
@@ -542,7 +595,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
542
595
|
const targetRatio = Number.parseInt(this.consts.sudoCore.vaults[collateralToken].weight, 10) / Object.values(this.consts.sudoCore.vaults)
|
|
543
596
|
.map(e => Number.parseInt(e.weight, 10))
|
|
544
597
|
.reduce((acc, curr) => acc + curr, 0);
|
|
545
|
-
return
|
|
598
|
+
return _a.calcRebaseFeeRate(await this.getRebaseFeeModel(), increase, (vaultValue + value) / (totalVaultValue + value), targetRatio);
|
|
546
599
|
}
|
|
547
600
|
async reservingFeeRate(collateralToken, amount, sender) {
|
|
548
601
|
if (!sender) {
|
|
@@ -584,7 +637,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
584
637
|
showContent: true,
|
|
585
638
|
},
|
|
586
639
|
});
|
|
587
|
-
return
|
|
640
|
+
return _a.parsePositionConfig(rawData);
|
|
588
641
|
}
|
|
589
642
|
async getOpenPositions(batchSize = 50, symbol = 'sui') {
|
|
590
643
|
let positionDynamicFields = [];
|
|
@@ -802,26 +855,26 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
802
855
|
return aprResponse.apr;
|
|
803
856
|
}
|
|
804
857
|
// Private helper methods
|
|
805
|
-
static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp,
|
|
806
|
-
const accFundingRate = this.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, position.long,
|
|
858
|
+
static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp, oiState, pairedOpeningSize) {
|
|
859
|
+
const accFundingRate = this.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, position.long, oiState, pairedOpeningSize);
|
|
807
860
|
return position.fundingFeeValue + (accFundingRate - position.lastFundingRate) * position.positionSize;
|
|
808
861
|
}
|
|
809
|
-
static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong,
|
|
862
|
+
static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong, oiState, pairedOpeningSize) {
|
|
810
863
|
if (symbol.lastUpdate > 0) {
|
|
811
864
|
const elapsed = timestamp - symbol.lastUpdate;
|
|
812
865
|
if (elapsed > 0) {
|
|
813
|
-
// Prefer OI-based delta when OI
|
|
814
|
-
if (
|
|
866
|
+
// Prefer OI-based delta when OI state and paired side are available
|
|
867
|
+
if (oiState?.enabled && oiState.model && typeof pairedOpeningSize === 'number') {
|
|
815
868
|
const longSize = isLong ? symbol.openingSize : pairedOpeningSize;
|
|
816
869
|
const shortSize = isLong ? pairedOpeningSize : symbol.openingSize;
|
|
817
|
-
const deltaRate =
|
|
870
|
+
const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSize, shortSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
|
|
818
871
|
const appliedRate = isLong ? deltaRate : -deltaRate;
|
|
819
872
|
return symbol.accFundingRate + appliedRate;
|
|
820
873
|
}
|
|
821
874
|
// Fallback to PnL-based funding delta
|
|
822
875
|
const deltaSize = this.calcDeltaSize(symbol, price, isLong);
|
|
823
876
|
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
|
|
824
|
-
return symbol.accFundingRate +
|
|
877
|
+
return symbol.accFundingRate + _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
|
|
825
878
|
}
|
|
826
879
|
}
|
|
827
880
|
return symbol.accFundingRate;
|
|
@@ -835,23 +888,44 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
835
888
|
const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR;
|
|
836
889
|
return pnlPerRate >= 0 ? -secondsRate : secondsRate;
|
|
837
890
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
891
|
+
/**
|
|
892
|
+
* OI funding rate matching Move compute_oi_funding_rate_capped.
|
|
893
|
+
* When both maxOiLong and maxOiShort are set and > 0, uses normalized skew (oi/cap);
|
|
894
|
+
* otherwise falls back to (long - short) / total.
|
|
895
|
+
*/
|
|
896
|
+
static calcOiFundingFeeRate(model, oiLong, oiShort, elapsed, maxOiLong, maxOiShort) {
|
|
897
|
+
let skew;
|
|
898
|
+
if (maxOiLong && maxOiShort && maxOiLong > 0 && maxOiShort > 0) {
|
|
899
|
+
const normLong = Math.min(oiLong / maxOiLong, 1);
|
|
900
|
+
const normShort = Math.min(oiShort / maxOiShort, 1);
|
|
901
|
+
skew = normLong - normShort;
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
const total = oiLong + oiShort;
|
|
905
|
+
if (total === 0)
|
|
906
|
+
return 0;
|
|
907
|
+
skew = (oiLong - oiShort) / total;
|
|
908
|
+
}
|
|
909
|
+
if (skew === 0)
|
|
910
|
+
return 0;
|
|
911
|
+
const skewIsPositive = skew > 0;
|
|
912
|
+
const skewAbs = Math.abs(skew);
|
|
913
|
+
const exponentInt = Math.floor(model.exponent);
|
|
914
|
+
const skewPow = skewAbs ** exponentInt;
|
|
915
|
+
const dailyRate = Math.min(model.multiplier * skewPow, model.max);
|
|
916
|
+
const secondsRate = (dailyRate * elapsed) / SECONDS_PER_EIGHT_HOUR;
|
|
917
|
+
return skewIsPositive ? secondsRate : -secondsRate;
|
|
844
918
|
}
|
|
845
919
|
static calculatePositionReserveFee(position, vault, model, timestamp) {
|
|
846
|
-
const accReservingRate =
|
|
920
|
+
const accReservingRate = _a.calcAccReservingFeeRate(vault, model, timestamp);
|
|
847
921
|
return position.reservingFeeAmount + (accReservingRate - position.lastReservingRate) * position.reservedAmount;
|
|
848
922
|
}
|
|
849
923
|
static calcAccReservingFeeRate(vault, model, timestamp) {
|
|
850
924
|
if (vault.lastUpdate > 0) {
|
|
851
925
|
const elapsed = timestamp - vault.lastUpdate;
|
|
852
926
|
if (elapsed > 0) {
|
|
853
|
-
const utilization =
|
|
854
|
-
return vault.accReservingRate +
|
|
927
|
+
const utilization = _a.vaultUtilization(vault);
|
|
928
|
+
return vault.accReservingRate + _a.calcReservingFeeRate(model, utilization, elapsed);
|
|
855
929
|
}
|
|
856
930
|
}
|
|
857
931
|
return vault.accReservingRate;
|
|
@@ -1036,8 +1110,8 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1036
1110
|
else if (endSkew > 1) {
|
|
1037
1111
|
endSkew = 1;
|
|
1038
1112
|
}
|
|
1039
|
-
const avgDynamicRate =
|
|
1040
|
-
const sizeFactor =
|
|
1113
|
+
const avgDynamicRate = _a.computeIntegralAverage(config.maxDynamicSpreadRate, startSkew, endSkew, config.impactExponent);
|
|
1114
|
+
const sizeFactor = _a.computeSizeFactor(newPositionSize, config.referenceSize);
|
|
1041
1115
|
const scaledDynamicRate = avgDynamicRate * sizeFactor;
|
|
1042
1116
|
let totalSpread = config.baseSpreadRate + scaledDynamicRate;
|
|
1043
1117
|
if (totalSpread > config.maxTotalSpreadRate) {
|
|
@@ -1076,8 +1150,8 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1076
1150
|
const currentOiOpposite = isLong ? shortSymbol.openingSize : longSymbol.openingSize;
|
|
1077
1151
|
const maxOiThisSide = isLong ? config.maxOiLong : config.maxOiShort;
|
|
1078
1152
|
const maxOiOpposite = isLong ? config.maxOiShort : config.maxOiLong;
|
|
1079
|
-
const spreadRate =
|
|
1080
|
-
const adjustedPrice =
|
|
1153
|
+
const spreadRate = _a.computeAverageSpreadRate(config, currentOiThisSide, positionSizeValue, currentOiOpposite, maxOiThisSide, maxOiOpposite);
|
|
1154
|
+
const adjustedPrice = _a.applyPriceImpact(oraclePrice, spreadRate, isLong, isOpening);
|
|
1081
1155
|
return {
|
|
1082
1156
|
spreadRate,
|
|
1083
1157
|
originalPrice: oraclePrice,
|
|
@@ -1103,6 +1177,8 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1103
1177
|
exponent: parseValue(content.model.fields.exponent),
|
|
1104
1178
|
max: parseValue(content.model.fields.max),
|
|
1105
1179
|
},
|
|
1180
|
+
maxOiLong: content.max_oi_long !== null && content.max_oi_long !== undefined ? parseValue(content.max_oi_long) : undefined,
|
|
1181
|
+
maxOiShort: content.max_oi_short !== null && content.max_oi_short !== undefined ? parseValue(content.max_oi_short) : undefined,
|
|
1106
1182
|
};
|
|
1107
1183
|
}
|
|
1108
1184
|
static parsePriceImpactConfig(raw) {
|
|
@@ -1138,7 +1214,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1138
1214
|
showContent: true,
|
|
1139
1215
|
},
|
|
1140
1216
|
});
|
|
1141
|
-
const reservingFeeModel =
|
|
1217
|
+
const reservingFeeModel = _a.parseReservingFeeModel(reservingFeeModelRaw);
|
|
1142
1218
|
return {
|
|
1143
1219
|
liquidity: parseValue(vaultFields.liquidity),
|
|
1144
1220
|
reservedAmount: parseValue(vaultFields.reserved_amount),
|
|
@@ -1172,7 +1248,7 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1172
1248
|
showContent: true,
|
|
1173
1249
|
},
|
|
1174
1250
|
});
|
|
1175
|
-
const fundingFeeModel =
|
|
1251
|
+
const fundingFeeModel = _a.parseFundingFeeModel(fundingFeeModelRaw);
|
|
1176
1252
|
return {
|
|
1177
1253
|
objectId,
|
|
1178
1254
|
openingSize: parseValue(fields.opening_size),
|
|
@@ -1220,11 +1296,11 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1220
1296
|
};
|
|
1221
1297
|
if (!positionFields.closed) {
|
|
1222
1298
|
try {
|
|
1223
|
-
positionInfo.reservingFeeAmount =
|
|
1299
|
+
positionInfo.reservingFeeAmount = _a.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000);
|
|
1224
1300
|
// OI context for funding: fetch state and paired side size when enabled
|
|
1225
1301
|
const oiState = await this.getSymbolOiFundingState(positionInfo.indexToken);
|
|
1226
1302
|
const pairedSymbol = await this.getSymbolInfo(positionInfo.indexToken, !positionInfo.long);
|
|
1227
|
-
positionInfo.fundingFeeValue =
|
|
1303
|
+
positionInfo.fundingFeeValue = _a.calculatePositionFundingFee(positionInfo, await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long), (await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long)).fundingFeeModel, (await this.getOraclePrice(positionInfo.indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked(), (await this.getMarketInfo()).lpSupplyWithDecimals, Date.now() / 1000, oiState && oiState.enabled ? oiState : undefined, pairedSymbol.openingSize);
|
|
1228
1304
|
}
|
|
1229
1305
|
catch (e) {
|
|
1230
1306
|
console.error(e);
|
|
@@ -1347,10 +1423,10 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1347
1423
|
};
|
|
1348
1424
|
// Use appropriate refresh method based on version
|
|
1349
1425
|
if (isNewVersion) {
|
|
1350
|
-
|
|
1426
|
+
_a.refreshPoolV2(pool, Math.floor(Date.now() / 1000));
|
|
1351
1427
|
}
|
|
1352
1428
|
else {
|
|
1353
|
-
|
|
1429
|
+
_a.refreshPool(pool, Math.floor(Date.now() / 1000));
|
|
1354
1430
|
}
|
|
1355
1431
|
return pool;
|
|
1356
1432
|
}
|
|
@@ -1388,4 +1464,93 @@ export class SLPDataAPI extends BaseDataAPI {
|
|
|
1388
1464
|
pool.lastUpdatedTime = calculationEndTime;
|
|
1389
1465
|
}
|
|
1390
1466
|
}
|
|
1467
|
+
_a = SLPDataAPI, _SLPDataAPI_instances = new WeakSet(), _SLPDataAPI_getTotalVaultsValueUsd = async function _SLPDataAPI_getTotalVaultsValueUsd(timestamp) {
|
|
1468
|
+
if (!this.consts.sudoCore) {
|
|
1469
|
+
return 0;
|
|
1470
|
+
}
|
|
1471
|
+
const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
|
|
1472
|
+
const vaultValues = await Promise.all(vaultKeys.map(async (vault) => {
|
|
1473
|
+
const vaultInfo = await this.getVaultInfo(vault);
|
|
1474
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, timestamp);
|
|
1475
|
+
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
1476
|
+
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1477
|
+
const { decimals } = this.consts.coins[vault];
|
|
1478
|
+
return totalVaultAmount * oraclePrice / (10 ** decimals);
|
|
1479
|
+
}));
|
|
1480
|
+
return vaultValues.reduce((acc, curr) => acc + curr, 0);
|
|
1481
|
+
}, _SLPDataAPI_getSwapImpactConfig = async function _SLPDataAPI_getSwapImpactConfig() {
|
|
1482
|
+
if (!this.consts.sudoCore) {
|
|
1483
|
+
return null;
|
|
1484
|
+
}
|
|
1485
|
+
const raw = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix).call(this, this.consts.sudoCore.market, 'SwapImpactConfigKey');
|
|
1486
|
+
if (!raw)
|
|
1487
|
+
return null;
|
|
1488
|
+
return __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_parseSwapImpactConfig).call(_a, raw);
|
|
1489
|
+
}, _SLPDataAPI_getEmaVolatilityFeeConfig = async function _SLPDataAPI_getEmaVolatilityFeeConfig() {
|
|
1490
|
+
if (!this.consts.sudoCore) {
|
|
1491
|
+
return null;
|
|
1492
|
+
}
|
|
1493
|
+
const raw = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix).call(this, this.consts.sudoCore.market, 'EmaVolatilityFeeConfigKey');
|
|
1494
|
+
if (!raw)
|
|
1495
|
+
return null;
|
|
1496
|
+
return __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_parseEmaVolatilityFeeConfig).call(_a, raw);
|
|
1497
|
+
}, _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix = async function _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix(parentId, keyTypeSuffix) {
|
|
1498
|
+
let cursor;
|
|
1499
|
+
let hasNextPage = true;
|
|
1500
|
+
while (hasNextPage) {
|
|
1501
|
+
const page = await this.provider.getDynamicFields({ parentId, cursor });
|
|
1502
|
+
for (const field of page.data) {
|
|
1503
|
+
const type = field.name?.type;
|
|
1504
|
+
if (typeof type === 'string' && type.endsWith(`::${keyTypeSuffix}`)) {
|
|
1505
|
+
return await this.provider.getDynamicFieldObject({
|
|
1506
|
+
parentId,
|
|
1507
|
+
name: field.name,
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
hasNextPage = page.hasNextPage;
|
|
1512
|
+
cursor = page.nextCursor;
|
|
1513
|
+
}
|
|
1514
|
+
return null;
|
|
1515
|
+
}, _SLPDataAPI_parseSwapImpactConfig = function _SLPDataAPI_parseSwapImpactConfig(raw) {
|
|
1516
|
+
const { fields } = raw.data.content;
|
|
1517
|
+
return {
|
|
1518
|
+
id: fields.id.id,
|
|
1519
|
+
enabled: fields.enabled,
|
|
1520
|
+
impactMultiplier: parseValue(fields.impact_multiplier),
|
|
1521
|
+
maxImpactRate: parseValue(fields.max_impact_rate),
|
|
1522
|
+
};
|
|
1523
|
+
}, _SLPDataAPI_parseEmaVolatilityFeeConfig = function _SLPDataAPI_parseEmaVolatilityFeeConfig(raw) {
|
|
1524
|
+
const { fields } = raw.data.content;
|
|
1525
|
+
return {
|
|
1526
|
+
id: fields.id.id,
|
|
1527
|
+
enabled: fields.enabled,
|
|
1528
|
+
multiplier: parseValue(fields.multiplier),
|
|
1529
|
+
maxFeeRate: parseValue(fields.max_fee_rate),
|
|
1530
|
+
};
|
|
1531
|
+
}, _SLPDataAPI_computeSwapImpactFeeValue = function _SLPDataAPI_computeSwapImpactFeeValue(swapValue, totalVaultsValue, impactMultiplier, maxImpactRate) {
|
|
1532
|
+
if (swapValue <= 0 || totalVaultsValue <= 0)
|
|
1533
|
+
return 0;
|
|
1534
|
+
const utilization = swapValue / totalVaultsValue;
|
|
1535
|
+
const rawImpactRate = impactMultiplier * utilization;
|
|
1536
|
+
const impactRate = Math.min(rawImpactRate, maxImpactRate);
|
|
1537
|
+
return swapValue * impactRate;
|
|
1538
|
+
}, _SLPDataAPI_computeEmaVolatilityFeeValue = function _SLPDataAPI_computeEmaVolatilityFeeValue(swapValue, maxDiv, multiplier, maxFeeRate) {
|
|
1539
|
+
if (swapValue <= 0 || maxDiv <= 0)
|
|
1540
|
+
return 0;
|
|
1541
|
+
const rawFeeRate = multiplier * maxDiv;
|
|
1542
|
+
const feeRate = Math.min(rawFeeRate, maxFeeRate);
|
|
1543
|
+
return swapValue * feeRate;
|
|
1544
|
+
}, _SLPDataAPI_maxEmaDivergenceRate = function _SLPDataAPI_maxEmaDivergenceRate(sourceFeed, destFeed) {
|
|
1545
|
+
const sourceDiv = __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_emaDivergenceRate).call(_a, sourceFeed);
|
|
1546
|
+
const destDiv = __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_emaDivergenceRate).call(_a, destFeed);
|
|
1547
|
+
return Math.max(sourceDiv, destDiv);
|
|
1548
|
+
}, _SLPDataAPI_emaDivergenceRate = function _SLPDataAPI_emaDivergenceRate(priceFeed) {
|
|
1549
|
+
const price = priceFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1550
|
+
const ema = priceFeed.getEmaPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1551
|
+
const denom = Math.abs(price);
|
|
1552
|
+
if (denom === 0)
|
|
1553
|
+
return 0;
|
|
1554
|
+
return Math.abs(price - ema) / denom;
|
|
1555
|
+
};
|
|
1391
1556
|
//# sourceMappingURL=SLPDataAPI.mjs.map
|