@zofai/zo-sdk 0.1.92 → 0.1.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/consts/deployments-slp-mainnet.json +1 -1
  2. package/dist/consts/deployments-usdz-mainnet.json +1 -1
  3. package/dist/consts/deployments-zlp-mainnet.json +1 -1
  4. package/dist/implementations/SLPDataAPI.cjs +227 -51
  5. package/dist/implementations/SLPDataAPI.cjs.map +1 -1
  6. package/dist/implementations/SLPDataAPI.d.cts +8 -1
  7. package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
  8. package/dist/implementations/SLPDataAPI.d.mts +8 -1
  9. package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
  10. package/dist/implementations/SLPDataAPI.mjs +227 -51
  11. package/dist/implementations/SLPDataAPI.mjs.map +1 -1
  12. package/dist/implementations/USDZDataAPI.cjs +208 -48
  13. package/dist/implementations/USDZDataAPI.cjs.map +1 -1
  14. package/dist/implementations/USDZDataAPI.d.cts +8 -1
  15. package/dist/implementations/USDZDataAPI.d.cts.map +1 -1
  16. package/dist/implementations/USDZDataAPI.d.mts +8 -1
  17. package/dist/implementations/USDZDataAPI.d.mts.map +1 -1
  18. package/dist/implementations/USDZDataAPI.mjs +208 -48
  19. package/dist/implementations/USDZDataAPI.mjs.map +1 -1
  20. package/dist/implementations/ZLPDataAPI.cjs +211 -50
  21. package/dist/implementations/ZLPDataAPI.cjs.map +1 -1
  22. package/dist/implementations/ZLPDataAPI.d.cts +8 -1
  23. package/dist/implementations/ZLPDataAPI.d.cts.map +1 -1
  24. package/dist/implementations/ZLPDataAPI.d.mts +8 -1
  25. package/dist/implementations/ZLPDataAPI.d.mts.map +1 -1
  26. package/dist/implementations/ZLPDataAPI.mjs +211 -50
  27. package/dist/implementations/ZLPDataAPI.mjs.map +1 -1
  28. package/dist/interfaces/base.d.cts +22 -0
  29. package/dist/interfaces/base.d.cts.map +1 -1
  30. package/dist/interfaces/base.d.mts +22 -0
  31. package/dist/interfaces/base.d.mts.map +1 -1
  32. package/dist/interfaces/slp.d.cts +8 -1
  33. package/dist/interfaces/slp.d.cts.map +1 -1
  34. package/dist/interfaces/slp.d.mts +8 -1
  35. package/dist/interfaces/slp.d.mts.map +1 -1
  36. package/dist/interfaces/usdz.d.cts +8 -1
  37. package/dist/interfaces/usdz.d.cts.map +1 -1
  38. package/dist/interfaces/usdz.d.mts +8 -1
  39. package/dist/interfaces/usdz.d.mts.map +1 -1
  40. package/dist/interfaces/zlp.d.cts +8 -1
  41. package/dist/interfaces/zlp.d.cts.map +1 -1
  42. package/dist/interfaces/zlp.d.mts +8 -1
  43. package/dist/interfaces/zlp.d.mts.map +1 -1
  44. package/package.json +4 -1
  45. package/src/consts/deployments-slp-mainnet.json +1 -1
  46. package/src/consts/deployments-usdz-mainnet.json +1 -1
  47. package/src/consts/deployments-zlp-mainnet.json +1 -1
  48. package/src/implementations/SLPDataAPI.ts +253 -23
  49. package/src/implementations/USDZDataAPI.ts +232 -20
  50. package/src/implementations/ZLPDataAPI.ts +233 -21
  51. package/src/interfaces/base.ts +26 -0
  52. package/src/interfaces/slp.ts +10 -1
  53. package/src/interfaces/usdz.ts +10 -1
  54. package/src/interfaces/zlp.ts +10 -1
@@ -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, oiModel, pairedOpeningSize) {
27
- const accFundingRate = SLPDataAPI.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, symbol.long, oiModel, pairedOpeningSize);
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 = SLPDataAPI.parseRebaseFeeModel(rawData);
42
- const exponent = await SLPDataAPI.getRebaseFeeExponent(this.provider, this.consts.sudoCore.rebaseFeeModel, this.consts.sudoCore.upgradedPackage);
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
  /**
@@ -125,27 +132,30 @@ export class SLPDataAPI extends BaseDataAPI {
125
132
  const marketInfo = await this.getMarketInfo();
126
133
  let slpPrice = 0;
127
134
  let value = 0;
128
- const vaultPromises = Object.keys(this.consts.sudoCore.vaults).map(async (vault) => {
135
+ const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
136
+ const vaultData = await Promise.all(vaultKeys.map(async (vault) => {
129
137
  const vaultInfo = await this.getVaultInfo(vault);
130
- const reservingFeeDelta = SLPDataAPI.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
138
+ const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
131
139
  const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
132
140
  const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
133
141
  const { decimals } = this.consts.coins[vault];
134
142
  const vaultValue = totalVaultAmount * oraclePrice / (10 ** decimals);
135
- return vaultValue;
136
- });
143
+ return { vault, oraclePrice, vaultValue };
144
+ }));
145
+ const vaultPrices = Object.fromEntries(vaultData.map(d => [d.vault, d.oraclePrice]));
146
+ const vaultValues = vaultData.map(d => d.vaultValue);
137
147
  const symbolPromises = Object.keys(this.consts.sudoCore.symbols).map(async (symbol) => {
138
148
  const [direction, tokenId] = parseSymbolKey(symbol);
139
149
  const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long');
140
150
  const price = (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked();
141
- const deltaSize = SLPDataAPI.calcDeltaSize(symbolInfo, price, direction === 'long');
151
+ const deltaSize = _a.calcDeltaSize(symbolInfo, price, direction === 'long');
142
152
  const oiState = await this.getSymbolOiFundingState(tokenId);
143
153
  const pairedInfo = await this.getSymbolInfo(tokenId, direction !== 'long');
144
- const fundingFeeDelta = SLPDataAPI.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, price, marketInfo.lpSupplyWithDecimals, Date.now() / 1000, oiState && oiState.enabled ? oiState.model : undefined, pairedInfo.openingSize);
154
+ const fundingFeeDelta = _a.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, price, marketInfo.lpSupplyWithDecimals, Date.now() / 1000, oiState && oiState.enabled ? oiState : undefined, pairedInfo.openingSize);
145
155
  const symbolValue = fundingFeeDelta + deltaSize;
146
156
  return symbolValue;
147
157
  });
148
- const [vaultValues, symbolValues] = await Promise.all([Promise.all(vaultPromises), Promise.all(symbolPromises)]);
158
+ const symbolValues = await Promise.all(symbolPromises);
149
159
  const totalVaultValue = vaultValues.reduce((acc, curr) => acc + curr, 0);
150
160
  const totalSymbolValue = symbolValues.reduce((acc, curr) => acc + curr, 0);
151
161
  value = totalVaultValue + totalSymbolValue;
@@ -155,6 +165,7 @@ export class SLPDataAPI extends BaseDataAPI {
155
165
  price: slpPrice,
156
166
  supply: marketInfo.lpSupplyWithDecimals,
157
167
  apr: Number(marketInfo.apr),
168
+ vaultPrices,
158
169
  };
159
170
  }
160
171
  /**
@@ -201,11 +212,18 @@ export class SLPDataAPI extends BaseDataAPI {
201
212
  const marketInfo = await this.getMarketInfo();
202
213
  const value = await this.simValuateVaults(this.consts.sudoCore.adminCap);
203
214
  const slpPrice = value / marketInfo.lpSupplyWithDecimals;
215
+ const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
216
+ const vaultPricesEntries = await Promise.all(vaultKeys.map(async (vault) => {
217
+ const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
218
+ return [vault, oraclePrice];
219
+ }));
220
+ const vaultPrices = Object.fromEntries(vaultPricesEntries);
204
221
  return {
205
222
  marketCap: value,
206
223
  price: slpPrice,
207
224
  supply: marketInfo.lpSupplyWithDecimals,
208
225
  apr: Number(marketInfo.apr),
226
+ vaultPrices,
209
227
  };
210
228
  }
211
229
  /**
@@ -224,7 +242,7 @@ export class SLPDataAPI extends BaseDataAPI {
224
242
  });
225
243
  const apr = await this.getCumulativeApr();
226
244
  return {
227
- ...SLPDataAPI.parseMarketInfo(rawData),
245
+ ..._a.parseMarketInfo(rawData),
228
246
  apr,
229
247
  };
230
248
  }
@@ -276,7 +294,7 @@ export class SLPDataAPI extends BaseDataAPI {
276
294
  value: { dummy_field: false },
277
295
  },
278
296
  });
279
- return SLPDataAPI.parseSymbolConfig(rawData);
297
+ return _a.parseSymbolConfig(rawData);
280
298
  }
281
299
  catch {
282
300
  // If the dynamic field doesn't exist, return null
@@ -298,7 +316,7 @@ export class SLPDataAPI extends BaseDataAPI {
298
316
  value: { dummy_field: false },
299
317
  },
300
318
  });
301
- return SLPDataAPI.parsePriceImpactConfig(rawData);
319
+ return _a.parsePriceImpactConfig(rawData);
302
320
  }
303
321
  catch (e) {
304
322
  // If the dynamic field doesn't exist, return null (price impact not configured for this symbol)
@@ -319,7 +337,7 @@ export class SLPDataAPI extends BaseDataAPI {
319
337
  value: { dummy_field: false },
320
338
  },
321
339
  });
322
- return SLPDataAPI.parseOiFundingState(rawData);
340
+ return _a.parseOiFundingState(rawData);
323
341
  }
324
342
  catch (e) {
325
343
  // If the dynamic field doesn't exist, return null
@@ -327,6 +345,52 @@ export class SLPDataAPI extends BaseDataAPI {
327
345
  return null;
328
346
  }
329
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
+ }
330
394
  async getPositionInfoList(positionCapInfoList, owner, batchSize = 10) {
331
395
  const positionInfoList = [];
332
396
  // Process in batches of 10
@@ -418,7 +482,7 @@ export class SLPDataAPI extends BaseDataAPI {
418
482
  rawCredentialsData = [...rawCredentialsData, ...data];
419
483
  }
420
484
  const pool = await this.getStakePool();
421
- const credentials = rawCredentialsData.map((item) => SLPDataAPI.parseCredential(item, pool));
485
+ const credentials = rawCredentialsData.map((item) => _a.parseCredential(item, pool));
422
486
  return {
423
487
  credentials,
424
488
  amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
@@ -435,7 +499,7 @@ export class SLPDataAPI extends BaseDataAPI {
435
499
  showContent: true,
436
500
  },
437
501
  });
438
- return SLPDataAPI.parseStakePool(raw);
502
+ return _a.parseStakePool(raw);
439
503
  }
440
504
  async getStakePoolV2() {
441
505
  const poolId = this.sharedConfig.zoStaking.pools.slp;
@@ -445,7 +509,7 @@ export class SLPDataAPI extends BaseDataAPI {
445
509
  showContent: true,
446
510
  },
447
511
  });
448
- return SLPDataAPI.parseStakePool(raw);
512
+ return _a.parseStakePool(raw);
449
513
  }
450
514
  async getStakedV2(owner) {
451
515
  let rawCredentialsData = [];
@@ -478,7 +542,7 @@ export class SLPDataAPI extends BaseDataAPI {
478
542
  const credentials = rawCredentialsData
479
543
  .filter((item) => item.data.type
480
544
  === `${this.sharedConfig.zoStaking.package}::pool::Credential<${this.consts.sudoCore.package}::slp::SLP, ${this.consts.sudoCore.package}::slp::SLP>`)
481
- .map((item) => SLPDataAPI.parseCredential(item, pool));
545
+ .map((item) => _a.parseCredential(item, pool));
482
546
  return {
483
547
  credentials,
484
548
  amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
@@ -494,7 +558,7 @@ export class SLPDataAPI extends BaseDataAPI {
494
558
  return 0;
495
559
  }
496
560
  const elapsed = SECONDS_PER_EIGHT_HOUR;
497
- const deltaRate = SLPDataAPI.calcOiFundingFeeRate(oiState.model, longSymbol.openingSize, shortSymbol.openingSize, elapsed);
561
+ const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSymbol.openingSize, shortSymbol.openingSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
498
562
  return long ? deltaRate : -deltaRate;
499
563
  }
500
564
  const symbol = await this.getSymbolInfo(indexToken, long);
@@ -505,9 +569,9 @@ export class SLPDataAPI extends BaseDataAPI {
505
569
  const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals;
506
570
  const model = symbol.fundingFeeModel;
507
571
  const elapsed = SECONDS_PER_EIGHT_HOUR;
508
- const deltaSize = SLPDataAPI.calcDeltaSize(symbol, price, symbol.long);
572
+ const deltaSize = _a.calcDeltaSize(symbol, price, symbol.long);
509
573
  const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
510
- return SLPDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed);
574
+ return _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
511
575
  }
512
576
  async rebaseFeeRate(collateralToken, increase, amount, _sender) {
513
577
  let vaultValue = 0;
@@ -517,7 +581,7 @@ export class SLPDataAPI extends BaseDataAPI {
517
581
  const value = amount * (await this.getOraclePrice(collateralToken)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[collateralToken].decimals);
518
582
  const vaultPromises = Object.keys(this.consts.sudoCore.vaults).map(async (vault) => {
519
583
  const vaultInfo = await this.getVaultInfo(vault);
520
- const reservingFeeDelta = SLPDataAPI.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
584
+ const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
521
585
  const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
522
586
  const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
523
587
  const res = totalVaultAmount * oraclePrice / (10 ** this.consts.coins[vault].decimals);
@@ -531,7 +595,7 @@ export class SLPDataAPI extends BaseDataAPI {
531
595
  const targetRatio = Number.parseInt(this.consts.sudoCore.vaults[collateralToken].weight, 10) / Object.values(this.consts.sudoCore.vaults)
532
596
  .map(e => Number.parseInt(e.weight, 10))
533
597
  .reduce((acc, curr) => acc + curr, 0);
534
- return SLPDataAPI.calcRebaseFeeRate(await this.getRebaseFeeModel(), increase, (vaultValue + value) / (totalVaultValue + value), targetRatio);
598
+ return _a.calcRebaseFeeRate(await this.getRebaseFeeModel(), increase, (vaultValue + value) / (totalVaultValue + value), targetRatio);
535
599
  }
536
600
  async reservingFeeRate(collateralToken, amount, sender) {
537
601
  if (!sender) {
@@ -573,7 +637,7 @@ export class SLPDataAPI extends BaseDataAPI {
573
637
  showContent: true,
574
638
  },
575
639
  });
576
- return SLPDataAPI.parsePositionConfig(rawData);
640
+ return _a.parsePositionConfig(rawData);
577
641
  }
578
642
  async getOpenPositions(batchSize = 50, symbol = 'sui') {
579
643
  let positionDynamicFields = [];
@@ -791,26 +855,26 @@ export class SLPDataAPI extends BaseDataAPI {
791
855
  return aprResponse.apr;
792
856
  }
793
857
  // Private helper methods
794
- static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp, oiModel, pairedOpeningSize) {
795
- const accFundingRate = this.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, position.long, oiModel, pairedOpeningSize);
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);
796
860
  return position.fundingFeeValue + (accFundingRate - position.lastFundingRate) * position.positionSize;
797
861
  }
798
- static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong, oiModel, pairedOpeningSize) {
862
+ static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong, oiState, pairedOpeningSize) {
799
863
  if (symbol.lastUpdate > 0) {
800
864
  const elapsed = timestamp - symbol.lastUpdate;
801
865
  if (elapsed > 0) {
802
- // Prefer OI-based delta when OI model and paired side are available
803
- if (oiModel && typeof pairedOpeningSize === 'number') {
866
+ // Prefer OI-based delta when OI state and paired side are available
867
+ if (oiState?.enabled && oiState.model && typeof pairedOpeningSize === 'number') {
804
868
  const longSize = isLong ? symbol.openingSize : pairedOpeningSize;
805
869
  const shortSize = isLong ? pairedOpeningSize : symbol.openingSize;
806
- const deltaRate = SLPDataAPI.calcOiFundingFeeRate(oiModel, longSize, shortSize, elapsed);
870
+ const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSize, shortSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
807
871
  const appliedRate = isLong ? deltaRate : -deltaRate;
808
872
  return symbol.accFundingRate + appliedRate;
809
873
  }
810
874
  // Fallback to PnL-based funding delta
811
875
  const deltaSize = this.calcDeltaSize(symbol, price, isLong);
812
876
  const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
813
- return symbol.accFundingRate + SLPDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed);
877
+ return symbol.accFundingRate + _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
814
878
  }
815
879
  }
816
880
  return symbol.accFundingRate;
@@ -824,23 +888,44 @@ export class SLPDataAPI extends BaseDataAPI {
824
888
  const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR;
825
889
  return pnlPerRate >= 0 ? -secondsRate : secondsRate;
826
890
  }
827
- static calcOiFundingFeeRate(model, longSize, shortSize, elapsed) {
828
- const imbalance = Math.abs(longSize - shortSize);
829
- const denom = longSize + shortSize > 0 ? longSize + shortSize : 1;
830
- const dailyRate = Math.min((model.multiplier * (imbalance ** model.exponent)) / denom, model.max);
831
- const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR;
832
- return longSize >= shortSize ? secondsRate : -secondsRate;
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;
833
918
  }
834
919
  static calculatePositionReserveFee(position, vault, model, timestamp) {
835
- const accReservingRate = SLPDataAPI.calcAccReservingFeeRate(vault, model, timestamp);
920
+ const accReservingRate = _a.calcAccReservingFeeRate(vault, model, timestamp);
836
921
  return position.reservingFeeAmount + (accReservingRate - position.lastReservingRate) * position.reservedAmount;
837
922
  }
838
923
  static calcAccReservingFeeRate(vault, model, timestamp) {
839
924
  if (vault.lastUpdate > 0) {
840
925
  const elapsed = timestamp - vault.lastUpdate;
841
926
  if (elapsed > 0) {
842
- const utilization = SLPDataAPI.vaultUtilization(vault);
843
- return vault.accReservingRate + SLPDataAPI.calcReservingFeeRate(model, utilization, elapsed);
927
+ const utilization = _a.vaultUtilization(vault);
928
+ return vault.accReservingRate + _a.calcReservingFeeRate(model, utilization, elapsed);
844
929
  }
845
930
  }
846
931
  return vault.accReservingRate;
@@ -1025,8 +1110,8 @@ export class SLPDataAPI extends BaseDataAPI {
1025
1110
  else if (endSkew > 1) {
1026
1111
  endSkew = 1;
1027
1112
  }
1028
- const avgDynamicRate = SLPDataAPI.computeIntegralAverage(config.maxDynamicSpreadRate, startSkew, endSkew, config.impactExponent);
1029
- const sizeFactor = SLPDataAPI.computeSizeFactor(newPositionSize, config.referenceSize);
1113
+ const avgDynamicRate = _a.computeIntegralAverage(config.maxDynamicSpreadRate, startSkew, endSkew, config.impactExponent);
1114
+ const sizeFactor = _a.computeSizeFactor(newPositionSize, config.referenceSize);
1030
1115
  const scaledDynamicRate = avgDynamicRate * sizeFactor;
1031
1116
  let totalSpread = config.baseSpreadRate + scaledDynamicRate;
1032
1117
  if (totalSpread > config.maxTotalSpreadRate) {
@@ -1065,8 +1150,8 @@ export class SLPDataAPI extends BaseDataAPI {
1065
1150
  const currentOiOpposite = isLong ? shortSymbol.openingSize : longSymbol.openingSize;
1066
1151
  const maxOiThisSide = isLong ? config.maxOiLong : config.maxOiShort;
1067
1152
  const maxOiOpposite = isLong ? config.maxOiShort : config.maxOiLong;
1068
- const spreadRate = SLPDataAPI.computeAverageSpreadRate(config, currentOiThisSide, positionSizeValue, currentOiOpposite, maxOiThisSide, maxOiOpposite);
1069
- const adjustedPrice = SLPDataAPI.applyPriceImpact(oraclePrice, spreadRate, isLong, isOpening);
1153
+ const spreadRate = _a.computeAverageSpreadRate(config, currentOiThisSide, positionSizeValue, currentOiOpposite, maxOiThisSide, maxOiOpposite);
1154
+ const adjustedPrice = _a.applyPriceImpact(oraclePrice, spreadRate, isLong, isOpening);
1070
1155
  return {
1071
1156
  spreadRate,
1072
1157
  originalPrice: oraclePrice,
@@ -1092,6 +1177,8 @@ export class SLPDataAPI extends BaseDataAPI {
1092
1177
  exponent: parseValue(content.model.fields.exponent),
1093
1178
  max: parseValue(content.model.fields.max),
1094
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,
1095
1182
  };
1096
1183
  }
1097
1184
  static parsePriceImpactConfig(raw) {
@@ -1127,7 +1214,7 @@ export class SLPDataAPI extends BaseDataAPI {
1127
1214
  showContent: true,
1128
1215
  },
1129
1216
  });
1130
- const reservingFeeModel = SLPDataAPI.parseReservingFeeModel(reservingFeeModelRaw);
1217
+ const reservingFeeModel = _a.parseReservingFeeModel(reservingFeeModelRaw);
1131
1218
  return {
1132
1219
  liquidity: parseValue(vaultFields.liquidity),
1133
1220
  reservedAmount: parseValue(vaultFields.reserved_amount),
@@ -1161,7 +1248,7 @@ export class SLPDataAPI extends BaseDataAPI {
1161
1248
  showContent: true,
1162
1249
  },
1163
1250
  });
1164
- const fundingFeeModel = SLPDataAPI.parseFundingFeeModel(fundingFeeModelRaw);
1251
+ const fundingFeeModel = _a.parseFundingFeeModel(fundingFeeModelRaw);
1165
1252
  return {
1166
1253
  objectId,
1167
1254
  openingSize: parseValue(fields.opening_size),
@@ -1209,11 +1296,11 @@ export class SLPDataAPI extends BaseDataAPI {
1209
1296
  };
1210
1297
  if (!positionFields.closed) {
1211
1298
  try {
1212
- positionInfo.reservingFeeAmount = SLPDataAPI.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000);
1299
+ positionInfo.reservingFeeAmount = _a.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000);
1213
1300
  // OI context for funding: fetch state and paired side size when enabled
1214
1301
  const oiState = await this.getSymbolOiFundingState(positionInfo.indexToken);
1215
1302
  const pairedSymbol = await this.getSymbolInfo(positionInfo.indexToken, !positionInfo.long);
1216
- positionInfo.fundingFeeValue = SLPDataAPI.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.model : undefined, pairedSymbol.openingSize);
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);
1217
1304
  }
1218
1305
  catch (e) {
1219
1306
  console.error(e);
@@ -1336,10 +1423,10 @@ export class SLPDataAPI extends BaseDataAPI {
1336
1423
  };
1337
1424
  // Use appropriate refresh method based on version
1338
1425
  if (isNewVersion) {
1339
- SLPDataAPI.refreshPoolV2(pool, Math.floor(Date.now() / 1000));
1426
+ _a.refreshPoolV2(pool, Math.floor(Date.now() / 1000));
1340
1427
  }
1341
1428
  else {
1342
- SLPDataAPI.refreshPool(pool, Math.floor(Date.now() / 1000));
1429
+ _a.refreshPool(pool, Math.floor(Date.now() / 1000));
1343
1430
  }
1344
1431
  return pool;
1345
1432
  }
@@ -1377,4 +1464,93 @@ export class SLPDataAPI extends BaseDataAPI {
1377
1464
  pool.lastUpdatedTime = calculationEndTime;
1378
1465
  }
1379
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
+ };
1380
1556
  //# sourceMappingURL=SLPDataAPI.mjs.map