@zofai/zo-sdk 0.1.93 → 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.
- 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/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/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/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 +6 -1
- package/dist/interfaces/slp.d.cts.map +1 -1
- package/dist/interfaces/slp.d.mts +6 -1
- package/dist/interfaces/slp.d.mts.map +1 -1
- package/dist/interfaces/usdz.d.cts +6 -1
- package/dist/interfaces/usdz.d.cts.map +1 -1
- package/dist/interfaces/usdz.d.mts +6 -1
- package/dist/interfaces/usdz.d.mts.map +1 -1
- package/dist/interfaces/zlp.d.cts +6 -1
- package/dist/interfaces/zlp.d.cts.map +1 -1
- package/dist/interfaces/zlp.d.mts +6 -1
- package/dist/interfaces/zlp.d.mts.map +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/SLPDataAPI.ts +235 -19
- package/src/implementations/USDZDataAPI.ts +221 -16
- package/src/implementations/ZLPDataAPI.ts +222 -17
- package/src/interfaces/base.ts +26 -0
- package/src/interfaces/slp.ts +6 -0
- package/src/interfaces/usdz.ts +6 -0
- package/src/interfaces/zlp.ts +6 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sudo_core": {
|
|
3
3
|
"package": "0xc44d97a4bc4e5a33ca847b72b123172c88a6328196b71414f32c3070233604b2",
|
|
4
|
-
"upgraded_package": "
|
|
4
|
+
"upgraded_package": "0x133f18548e87ae085905f3dd4c9d5be9b9ceb9a9bd2d55f34a0804eb249db1ae",
|
|
5
5
|
"upgrade_cap": "0x2092387c072fe18f91b57b9dde362f758259ee88d993a5faf569b4f2eb288b12",
|
|
6
6
|
"admin_cap": "0x0b4183c84de542c6f9623acd521294ea7e8205a2a7a23f4fac97e964fe4da30e",
|
|
7
7
|
"market": "0x4d753c2c69109cbeb806393956cfeba28d832354a37d59d9a019ee580f82893d",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"zo_core": {
|
|
3
3
|
"package": "0x7fd8aba1652c58b6397c799fd375e748e5053145cb7e126d303e0a1545fd1fec",
|
|
4
|
-
"upgraded_package": "
|
|
4
|
+
"upgraded_package": "0x43779d65ae051458c5021f6bfe891a117c49b091132c6f3be2c714b02a4bcb25",
|
|
5
5
|
"upgrade_cap": "0x2f67d379d3b9e256a9c4079de50f4bd336dcbda1bd90d1fcd61a9cc1dc369d69",
|
|
6
6
|
"admin_cap": "0x63af8e78701327be98e0c44967389148c374f4ea7c7cf8acf64957b705ffd02d",
|
|
7
7
|
"market": "0x3310c794d0bbc4b0421d2fedc74fbd5a028b09fe4d396cd5458786f4c52fa636",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"zo_core": {
|
|
3
3
|
"package": "0xf7fade57462e56e2eff1d7adef32e4fd285b21fd81f983f407bb7110ca766cda",
|
|
4
|
-
"upgraded_package": "
|
|
4
|
+
"upgraded_package": "0x420dbbc3b14a2e1645a38b111dc1c381cae43f349ddf800540f8991efbce563d",
|
|
5
5
|
"upgrade_cap": "0xcc96f78abe0b868afaab05954ccc6357afb5d379a21389d6eb88dda8b1f60052",
|
|
6
6
|
"admin_cap": "0xbc10f6481f2b5d6185c73ee680aa90a60fe3854d9f638e00f7e00d3b6a88e2b8",
|
|
7
7
|
"market": "0x35c667bd8c401036103992791a924f31df0d104256a9e2313acee5b1bcf05b7e",
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
* SLP DataAPI implementation
|
|
7
7
|
* Implements SLP-specific data access methods for Sudo SDK
|
|
8
8
|
*/
|
|
9
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
10
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
11
|
+
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");
|
|
12
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
13
|
+
};
|
|
14
|
+
var _SLPDataAPI_instances, _a, _SLPDataAPI_getTotalVaultsValueUsd, _SLPDataAPI_getSwapImpactConfig, _SLPDataAPI_getEmaVolatilityFeeConfig, _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix, _SLPDataAPI_parseSwapImpactConfig, _SLPDataAPI_parseEmaVolatilityFeeConfig, _SLPDataAPI_computeSwapImpactFeeValue, _SLPDataAPI_computeEmaVolatilityFeeValue, _SLPDataAPI_maxEmaDivergenceRate, _SLPDataAPI_emaDivergenceRate;
|
|
9
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
16
|
exports.SLPDataAPI = void 0;
|
|
11
17
|
const transactions_1 = require("@mysten/sui/transactions");
|
|
@@ -19,6 +25,7 @@ const SECONDS_PER_EIGHT_HOUR = 8 * 60 * 60; // 28800 seconds
|
|
|
19
25
|
class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
20
26
|
constructor(network, provider, apiEndpoint, connectionURL) {
|
|
21
27
|
super(network, provider, apiEndpoint, connectionURL, consts_1.LPToken.SLP);
|
|
28
|
+
_SLPDataAPI_instances.add(this);
|
|
22
29
|
}
|
|
23
30
|
static calculateVaultReservingFee(vaultInfo, reservingFeeModel, currentTime) {
|
|
24
31
|
const timeDelta = currentTime - vaultInfo.lastUpdate;
|
|
@@ -26,8 +33,8 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
26
33
|
return vaultInfo.unrealisedReservingFeeAmount
|
|
27
34
|
+ (vaultInfo.reservedAmount * reservingFeeModel.multiplier * periods) / 1e18;
|
|
28
35
|
}
|
|
29
|
-
static calculateSymbolFundingFee(symbol, model, price, lpSupplyAmount, timestamp,
|
|
30
|
-
const accFundingRate =
|
|
36
|
+
static calculateSymbolFundingFee(symbol, model, price, lpSupplyAmount, timestamp, oiState, pairedOpeningSize) {
|
|
37
|
+
const accFundingRate = _a.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, symbol.long, oiState, pairedOpeningSize);
|
|
31
38
|
return symbol.unrealisedFundingFeeValue + (accFundingRate - symbol.accFundingRate) * symbol.openingSize;
|
|
32
39
|
}
|
|
33
40
|
async getRebaseFeeModel() {
|
|
@@ -41,8 +48,8 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
41
48
|
showContent: true,
|
|
42
49
|
},
|
|
43
50
|
});
|
|
44
|
-
const model =
|
|
45
|
-
const exponent = await
|
|
51
|
+
const model = _a.parseRebaseFeeModel(rawData);
|
|
52
|
+
const exponent = await _a.getRebaseFeeExponent(this.provider, this.consts.sudoCore.rebaseFeeModel, this.consts.sudoCore.upgradedPackage);
|
|
46
53
|
return { ...model, exponent };
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
@@ -131,7 +138,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
131
138
|
const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
|
|
132
139
|
const vaultData = await Promise.all(vaultKeys.map(async (vault) => {
|
|
133
140
|
const vaultInfo = await this.getVaultInfo(vault);
|
|
134
|
-
const reservingFeeDelta =
|
|
141
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
|
|
135
142
|
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
136
143
|
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
137
144
|
const { decimals } = this.consts.coins[vault];
|
|
@@ -144,10 +151,10 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
144
151
|
const [direction, tokenId] = (0, utils_2.parseSymbolKey)(symbol);
|
|
145
152
|
const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long');
|
|
146
153
|
const price = (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
147
|
-
const deltaSize =
|
|
154
|
+
const deltaSize = _a.calcDeltaSize(symbolInfo, price, direction === 'long');
|
|
148
155
|
const oiState = await this.getSymbolOiFundingState(tokenId);
|
|
149
156
|
const pairedInfo = await this.getSymbolInfo(tokenId, direction !== 'long');
|
|
150
|
-
const fundingFeeDelta =
|
|
157
|
+
const fundingFeeDelta = _a.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, price, marketInfo.lpSupplyWithDecimals, Date.now() / 1000, oiState && oiState.enabled ? oiState : undefined, pairedInfo.openingSize);
|
|
151
158
|
const symbolValue = fundingFeeDelta + deltaSize;
|
|
152
159
|
return symbolValue;
|
|
153
160
|
});
|
|
@@ -238,7 +245,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
238
245
|
});
|
|
239
246
|
const apr = await this.getCumulativeApr();
|
|
240
247
|
return {
|
|
241
|
-
...
|
|
248
|
+
..._a.parseMarketInfo(rawData),
|
|
242
249
|
apr,
|
|
243
250
|
};
|
|
244
251
|
}
|
|
@@ -290,7 +297,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
290
297
|
value: { dummy_field: false },
|
|
291
298
|
},
|
|
292
299
|
});
|
|
293
|
-
return
|
|
300
|
+
return _a.parseSymbolConfig(rawData);
|
|
294
301
|
}
|
|
295
302
|
catch {
|
|
296
303
|
// If the dynamic field doesn't exist, return null
|
|
@@ -312,7 +319,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
312
319
|
value: { dummy_field: false },
|
|
313
320
|
},
|
|
314
321
|
});
|
|
315
|
-
return
|
|
322
|
+
return _a.parsePriceImpactConfig(rawData);
|
|
316
323
|
}
|
|
317
324
|
catch (e) {
|
|
318
325
|
// If the dynamic field doesn't exist, return null (price impact not configured for this symbol)
|
|
@@ -333,7 +340,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
333
340
|
value: { dummy_field: false },
|
|
334
341
|
},
|
|
335
342
|
});
|
|
336
|
-
return
|
|
343
|
+
return _a.parseOiFundingState(rawData);
|
|
337
344
|
}
|
|
338
345
|
catch (e) {
|
|
339
346
|
// If the dynamic field doesn't exist, return null
|
|
@@ -341,6 +348,52 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
341
348
|
return null;
|
|
342
349
|
}
|
|
343
350
|
}
|
|
351
|
+
async calculateSwapFeeBreakdown(fromToken, toToken, fromAmount) {
|
|
352
|
+
if (!this.consts.sudoCore) {
|
|
353
|
+
throw new Error('Sudo Core configuration not found. Make sure you are using LPToken.SLP');
|
|
354
|
+
}
|
|
355
|
+
const timestamp = Date.now() / 1000;
|
|
356
|
+
const fromDecimals = this.consts.coins[fromToken]?.decimals;
|
|
357
|
+
const toDecimals = this.consts.coins[toToken]?.decimals;
|
|
358
|
+
if (fromDecimals === undefined || toDecimals === undefined) {
|
|
359
|
+
throw new Error(`Unknown token decimals for swap: ${fromToken} -> ${toToken}`);
|
|
360
|
+
}
|
|
361
|
+
const fromFeed = await this.getOraclePrice(fromToken);
|
|
362
|
+
const toFeed = await this.getOraclePrice(toToken);
|
|
363
|
+
const fromPrice = fromFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
364
|
+
const toPrice = toFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
365
|
+
const swapValue = (fromAmount * fromPrice) / (10 ** fromDecimals);
|
|
366
|
+
const totalVaultsValue = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getTotalVaultsValueUsd).call(this, timestamp);
|
|
367
|
+
const rebaseFeeInRate = await this.rebaseFeeRate(fromToken, true, fromAmount);
|
|
368
|
+
const rebaseFeeInValue = swapValue * rebaseFeeInRate;
|
|
369
|
+
const estimatedToAmount = toPrice !== 0
|
|
370
|
+
? (swapValue * (10 ** toDecimals)) / toPrice
|
|
371
|
+
: 0;
|
|
372
|
+
const rebaseFeeOutRate = await this.rebaseFeeRate(toToken, false, estimatedToAmount);
|
|
373
|
+
const rebaseFeeOutValue = swapValue * rebaseFeeOutRate;
|
|
374
|
+
const swapImpactCfg = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getSwapImpactConfig).call(this);
|
|
375
|
+
const swapImpactFeeValue = swapImpactCfg?.enabled
|
|
376
|
+
? __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_computeSwapImpactFeeValue).call(_a, swapValue, totalVaultsValue, swapImpactCfg.impactMultiplier, swapImpactCfg.maxImpactRate)
|
|
377
|
+
: 0;
|
|
378
|
+
const emaCfg = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getEmaVolatilityFeeConfig).call(this);
|
|
379
|
+
const emaVolatilityFeeValue = emaCfg?.enabled
|
|
380
|
+
? __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_computeEmaVolatilityFeeValue).call(_a, swapValue, __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_maxEmaDivergenceRate).call(_a, fromFeed, toFeed), emaCfg.multiplier, emaCfg.maxFeeRate)
|
|
381
|
+
: 0;
|
|
382
|
+
const totalFeeValue = rebaseFeeInValue + rebaseFeeOutValue + swapImpactFeeValue + emaVolatilityFeeValue;
|
|
383
|
+
const totalFeeRate = swapValue !== 0 ? totalFeeValue / swapValue : 0;
|
|
384
|
+
return {
|
|
385
|
+
swapValue,
|
|
386
|
+
totalVaultsValue,
|
|
387
|
+
rebaseFeeInRate,
|
|
388
|
+
rebaseFeeOutRate,
|
|
389
|
+
rebaseFeeInValue,
|
|
390
|
+
rebaseFeeOutValue,
|
|
391
|
+
swapImpactFeeValue,
|
|
392
|
+
emaVolatilityFeeValue,
|
|
393
|
+
totalFeeValue,
|
|
394
|
+
totalFeeRate,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
344
397
|
async getPositionInfoList(positionCapInfoList, owner, batchSize = 10) {
|
|
345
398
|
const positionInfoList = [];
|
|
346
399
|
// Process in batches of 10
|
|
@@ -432,7 +485,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
432
485
|
rawCredentialsData = [...rawCredentialsData, ...data];
|
|
433
486
|
}
|
|
434
487
|
const pool = await this.getStakePool();
|
|
435
|
-
const credentials = rawCredentialsData.map((item) =>
|
|
488
|
+
const credentials = rawCredentialsData.map((item) => _a.parseCredential(item, pool));
|
|
436
489
|
return {
|
|
437
490
|
credentials,
|
|
438
491
|
amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
|
|
@@ -449,7 +502,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
449
502
|
showContent: true,
|
|
450
503
|
},
|
|
451
504
|
});
|
|
452
|
-
return
|
|
505
|
+
return _a.parseStakePool(raw);
|
|
453
506
|
}
|
|
454
507
|
async getStakePoolV2() {
|
|
455
508
|
const poolId = this.sharedConfig.zoStaking.pools.slp;
|
|
@@ -459,7 +512,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
459
512
|
showContent: true,
|
|
460
513
|
},
|
|
461
514
|
});
|
|
462
|
-
return
|
|
515
|
+
return _a.parseStakePool(raw);
|
|
463
516
|
}
|
|
464
517
|
async getStakedV2(owner) {
|
|
465
518
|
let rawCredentialsData = [];
|
|
@@ -492,7 +545,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
492
545
|
const credentials = rawCredentialsData
|
|
493
546
|
.filter((item) => item.data.type
|
|
494
547
|
=== `${this.sharedConfig.zoStaking.package}::pool::Credential<${this.consts.sudoCore.package}::slp::SLP, ${this.consts.sudoCore.package}::slp::SLP>`)
|
|
495
|
-
.map((item) =>
|
|
548
|
+
.map((item) => _a.parseCredential(item, pool));
|
|
496
549
|
return {
|
|
497
550
|
credentials,
|
|
498
551
|
amount: credentials.reduce((acc, cur) => acc + cur.amount, BigInt(0)),
|
|
@@ -508,7 +561,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
508
561
|
return 0;
|
|
509
562
|
}
|
|
510
563
|
const elapsed = SECONDS_PER_EIGHT_HOUR;
|
|
511
|
-
const deltaRate =
|
|
564
|
+
const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSymbol.openingSize, shortSymbol.openingSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
|
|
512
565
|
return long ? deltaRate : -deltaRate;
|
|
513
566
|
}
|
|
514
567
|
const symbol = await this.getSymbolInfo(indexToken, long);
|
|
@@ -519,9 +572,9 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
519
572
|
const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals;
|
|
520
573
|
const model = symbol.fundingFeeModel;
|
|
521
574
|
const elapsed = SECONDS_PER_EIGHT_HOUR;
|
|
522
|
-
const deltaSize =
|
|
575
|
+
const deltaSize = _a.calcDeltaSize(symbol, price, symbol.long);
|
|
523
576
|
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
|
|
524
|
-
return
|
|
577
|
+
return _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
|
|
525
578
|
}
|
|
526
579
|
async rebaseFeeRate(collateralToken, increase, amount, _sender) {
|
|
527
580
|
let vaultValue = 0;
|
|
@@ -531,7 +584,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
531
584
|
const value = amount * (await this.getOraclePrice(collateralToken)).getPriceUnchecked().getPriceAsNumberUnchecked() / (10 ** this.consts.coins[collateralToken].decimals);
|
|
532
585
|
const vaultPromises = Object.keys(this.consts.sudoCore.vaults).map(async (vault) => {
|
|
533
586
|
const vaultInfo = await this.getVaultInfo(vault);
|
|
534
|
-
const reservingFeeDelta =
|
|
587
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, Date.now() / 1000);
|
|
535
588
|
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
536
589
|
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
537
590
|
const res = totalVaultAmount * oraclePrice / (10 ** this.consts.coins[vault].decimals);
|
|
@@ -545,7 +598,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
545
598
|
const targetRatio = Number.parseInt(this.consts.sudoCore.vaults[collateralToken].weight, 10) / Object.values(this.consts.sudoCore.vaults)
|
|
546
599
|
.map(e => Number.parseInt(e.weight, 10))
|
|
547
600
|
.reduce((acc, curr) => acc + curr, 0);
|
|
548
|
-
return
|
|
601
|
+
return _a.calcRebaseFeeRate(await this.getRebaseFeeModel(), increase, (vaultValue + value) / (totalVaultValue + value), targetRatio);
|
|
549
602
|
}
|
|
550
603
|
async reservingFeeRate(collateralToken, amount, sender) {
|
|
551
604
|
if (!sender) {
|
|
@@ -587,7 +640,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
587
640
|
showContent: true,
|
|
588
641
|
},
|
|
589
642
|
});
|
|
590
|
-
return
|
|
643
|
+
return _a.parsePositionConfig(rawData);
|
|
591
644
|
}
|
|
592
645
|
async getOpenPositions(batchSize = 50, symbol = 'sui') {
|
|
593
646
|
let positionDynamicFields = [];
|
|
@@ -805,26 +858,26 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
805
858
|
return aprResponse.apr;
|
|
806
859
|
}
|
|
807
860
|
// Private helper methods
|
|
808
|
-
static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp,
|
|
809
|
-
const accFundingRate = this.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, position.long,
|
|
861
|
+
static calculatePositionFundingFee(position, symbol, model, price, lpSupplyAmount, timestamp, oiState, pairedOpeningSize) {
|
|
862
|
+
const accFundingRate = this.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, position.long, oiState, pairedOpeningSize);
|
|
810
863
|
return position.fundingFeeValue + (accFundingRate - position.lastFundingRate) * position.positionSize;
|
|
811
864
|
}
|
|
812
|
-
static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong,
|
|
865
|
+
static calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp, isLong, oiState, pairedOpeningSize) {
|
|
813
866
|
if (symbol.lastUpdate > 0) {
|
|
814
867
|
const elapsed = timestamp - symbol.lastUpdate;
|
|
815
868
|
if (elapsed > 0) {
|
|
816
|
-
// Prefer OI-based delta when OI
|
|
817
|
-
if (
|
|
869
|
+
// Prefer OI-based delta when OI state and paired side are available
|
|
870
|
+
if (oiState?.enabled && oiState.model && typeof pairedOpeningSize === 'number') {
|
|
818
871
|
const longSize = isLong ? symbol.openingSize : pairedOpeningSize;
|
|
819
872
|
const shortSize = isLong ? pairedOpeningSize : symbol.openingSize;
|
|
820
|
-
const deltaRate =
|
|
873
|
+
const deltaRate = _a.calcOiFundingFeeRate(oiState.model, longSize, shortSize, elapsed, oiState.maxOiLong, oiState.maxOiShort);
|
|
821
874
|
const appliedRate = isLong ? deltaRate : -deltaRate;
|
|
822
875
|
return symbol.accFundingRate + appliedRate;
|
|
823
876
|
}
|
|
824
877
|
// Fallback to PnL-based funding delta
|
|
825
878
|
const deltaSize = this.calcDeltaSize(symbol, price, isLong);
|
|
826
879
|
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount;
|
|
827
|
-
return symbol.accFundingRate +
|
|
880
|
+
return symbol.accFundingRate + _a.calcFundingFeeRate(model, pnlPerLp, elapsed);
|
|
828
881
|
}
|
|
829
882
|
}
|
|
830
883
|
return symbol.accFundingRate;
|
|
@@ -838,23 +891,44 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
838
891
|
const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR;
|
|
839
892
|
return pnlPerRate >= 0 ? -secondsRate : secondsRate;
|
|
840
893
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
894
|
+
/**
|
|
895
|
+
* OI funding rate matching Move compute_oi_funding_rate_capped.
|
|
896
|
+
* When both maxOiLong and maxOiShort are set and > 0, uses normalized skew (oi/cap);
|
|
897
|
+
* otherwise falls back to (long - short) / total.
|
|
898
|
+
*/
|
|
899
|
+
static calcOiFundingFeeRate(model, oiLong, oiShort, elapsed, maxOiLong, maxOiShort) {
|
|
900
|
+
let skew;
|
|
901
|
+
if (maxOiLong && maxOiShort && maxOiLong > 0 && maxOiShort > 0) {
|
|
902
|
+
const normLong = Math.min(oiLong / maxOiLong, 1);
|
|
903
|
+
const normShort = Math.min(oiShort / maxOiShort, 1);
|
|
904
|
+
skew = normLong - normShort;
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
const total = oiLong + oiShort;
|
|
908
|
+
if (total === 0)
|
|
909
|
+
return 0;
|
|
910
|
+
skew = (oiLong - oiShort) / total;
|
|
911
|
+
}
|
|
912
|
+
if (skew === 0)
|
|
913
|
+
return 0;
|
|
914
|
+
const skewIsPositive = skew > 0;
|
|
915
|
+
const skewAbs = Math.abs(skew);
|
|
916
|
+
const exponentInt = Math.floor(model.exponent);
|
|
917
|
+
const skewPow = skewAbs ** exponentInt;
|
|
918
|
+
const dailyRate = Math.min(model.multiplier * skewPow, model.max);
|
|
919
|
+
const secondsRate = (dailyRate * elapsed) / SECONDS_PER_EIGHT_HOUR;
|
|
920
|
+
return skewIsPositive ? secondsRate : -secondsRate;
|
|
847
921
|
}
|
|
848
922
|
static calculatePositionReserveFee(position, vault, model, timestamp) {
|
|
849
|
-
const accReservingRate =
|
|
923
|
+
const accReservingRate = _a.calcAccReservingFeeRate(vault, model, timestamp);
|
|
850
924
|
return position.reservingFeeAmount + (accReservingRate - position.lastReservingRate) * position.reservedAmount;
|
|
851
925
|
}
|
|
852
926
|
static calcAccReservingFeeRate(vault, model, timestamp) {
|
|
853
927
|
if (vault.lastUpdate > 0) {
|
|
854
928
|
const elapsed = timestamp - vault.lastUpdate;
|
|
855
929
|
if (elapsed > 0) {
|
|
856
|
-
const utilization =
|
|
857
|
-
return vault.accReservingRate +
|
|
930
|
+
const utilization = _a.vaultUtilization(vault);
|
|
931
|
+
return vault.accReservingRate + _a.calcReservingFeeRate(model, utilization, elapsed);
|
|
858
932
|
}
|
|
859
933
|
}
|
|
860
934
|
return vault.accReservingRate;
|
|
@@ -1039,8 +1113,8 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1039
1113
|
else if (endSkew > 1) {
|
|
1040
1114
|
endSkew = 1;
|
|
1041
1115
|
}
|
|
1042
|
-
const avgDynamicRate =
|
|
1043
|
-
const sizeFactor =
|
|
1116
|
+
const avgDynamicRate = _a.computeIntegralAverage(config.maxDynamicSpreadRate, startSkew, endSkew, config.impactExponent);
|
|
1117
|
+
const sizeFactor = _a.computeSizeFactor(newPositionSize, config.referenceSize);
|
|
1044
1118
|
const scaledDynamicRate = avgDynamicRate * sizeFactor;
|
|
1045
1119
|
let totalSpread = config.baseSpreadRate + scaledDynamicRate;
|
|
1046
1120
|
if (totalSpread > config.maxTotalSpreadRate) {
|
|
@@ -1079,8 +1153,8 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1079
1153
|
const currentOiOpposite = isLong ? shortSymbol.openingSize : longSymbol.openingSize;
|
|
1080
1154
|
const maxOiThisSide = isLong ? config.maxOiLong : config.maxOiShort;
|
|
1081
1155
|
const maxOiOpposite = isLong ? config.maxOiShort : config.maxOiLong;
|
|
1082
|
-
const spreadRate =
|
|
1083
|
-
const adjustedPrice =
|
|
1156
|
+
const spreadRate = _a.computeAverageSpreadRate(config, currentOiThisSide, positionSizeValue, currentOiOpposite, maxOiThisSide, maxOiOpposite);
|
|
1157
|
+
const adjustedPrice = _a.applyPriceImpact(oraclePrice, spreadRate, isLong, isOpening);
|
|
1084
1158
|
return {
|
|
1085
1159
|
spreadRate,
|
|
1086
1160
|
originalPrice: oraclePrice,
|
|
@@ -1106,6 +1180,8 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1106
1180
|
exponent: (0, utils_2.parseValue)(content.model.fields.exponent),
|
|
1107
1181
|
max: (0, utils_2.parseValue)(content.model.fields.max),
|
|
1108
1182
|
},
|
|
1183
|
+
maxOiLong: content.max_oi_long !== null && content.max_oi_long !== undefined ? (0, utils_2.parseValue)(content.max_oi_long) : undefined,
|
|
1184
|
+
maxOiShort: content.max_oi_short !== null && content.max_oi_short !== undefined ? (0, utils_2.parseValue)(content.max_oi_short) : undefined,
|
|
1109
1185
|
};
|
|
1110
1186
|
}
|
|
1111
1187
|
static parsePriceImpactConfig(raw) {
|
|
@@ -1141,7 +1217,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1141
1217
|
showContent: true,
|
|
1142
1218
|
},
|
|
1143
1219
|
});
|
|
1144
|
-
const reservingFeeModel =
|
|
1220
|
+
const reservingFeeModel = _a.parseReservingFeeModel(reservingFeeModelRaw);
|
|
1145
1221
|
return {
|
|
1146
1222
|
liquidity: (0, utils_2.parseValue)(vaultFields.liquidity),
|
|
1147
1223
|
reservedAmount: (0, utils_2.parseValue)(vaultFields.reserved_amount),
|
|
@@ -1175,7 +1251,7 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1175
1251
|
showContent: true,
|
|
1176
1252
|
},
|
|
1177
1253
|
});
|
|
1178
|
-
const fundingFeeModel =
|
|
1254
|
+
const fundingFeeModel = _a.parseFundingFeeModel(fundingFeeModelRaw);
|
|
1179
1255
|
return {
|
|
1180
1256
|
objectId,
|
|
1181
1257
|
openingSize: (0, utils_2.parseValue)(fields.opening_size),
|
|
@@ -1223,11 +1299,11 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1223
1299
|
};
|
|
1224
1300
|
if (!positionFields.closed) {
|
|
1225
1301
|
try {
|
|
1226
|
-
positionInfo.reservingFeeAmount =
|
|
1302
|
+
positionInfo.reservingFeeAmount = _a.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000);
|
|
1227
1303
|
// OI context for funding: fetch state and paired side size when enabled
|
|
1228
1304
|
const oiState = await this.getSymbolOiFundingState(positionInfo.indexToken);
|
|
1229
1305
|
const pairedSymbol = await this.getSymbolInfo(positionInfo.indexToken, !positionInfo.long);
|
|
1230
|
-
positionInfo.fundingFeeValue =
|
|
1306
|
+
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);
|
|
1231
1307
|
}
|
|
1232
1308
|
catch (e) {
|
|
1233
1309
|
console.error(e);
|
|
@@ -1350,10 +1426,10 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1350
1426
|
};
|
|
1351
1427
|
// Use appropriate refresh method based on version
|
|
1352
1428
|
if (isNewVersion) {
|
|
1353
|
-
|
|
1429
|
+
_a.refreshPoolV2(pool, Math.floor(Date.now() / 1000));
|
|
1354
1430
|
}
|
|
1355
1431
|
else {
|
|
1356
|
-
|
|
1432
|
+
_a.refreshPool(pool, Math.floor(Date.now() / 1000));
|
|
1357
1433
|
}
|
|
1358
1434
|
return pool;
|
|
1359
1435
|
}
|
|
@@ -1392,4 +1468,93 @@ class SLPDataAPI extends abstract_1.BaseDataAPI {
|
|
|
1392
1468
|
}
|
|
1393
1469
|
}
|
|
1394
1470
|
exports.SLPDataAPI = SLPDataAPI;
|
|
1471
|
+
_a = SLPDataAPI, _SLPDataAPI_instances = new WeakSet(), _SLPDataAPI_getTotalVaultsValueUsd = async function _SLPDataAPI_getTotalVaultsValueUsd(timestamp) {
|
|
1472
|
+
if (!this.consts.sudoCore) {
|
|
1473
|
+
return 0;
|
|
1474
|
+
}
|
|
1475
|
+
const vaultKeys = Object.keys(this.consts.sudoCore.vaults);
|
|
1476
|
+
const vaultValues = await Promise.all(vaultKeys.map(async (vault) => {
|
|
1477
|
+
const vaultInfo = await this.getVaultInfo(vault);
|
|
1478
|
+
const reservingFeeDelta = _a.calculateVaultReservingFee(vaultInfo, vaultInfo.reservingFeeModel, timestamp);
|
|
1479
|
+
const totalVaultAmount = reservingFeeDelta + vaultInfo.liquidity + vaultInfo.reservedAmount;
|
|
1480
|
+
const oraclePrice = (await this.getOraclePrice(vault)).getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1481
|
+
const { decimals } = this.consts.coins[vault];
|
|
1482
|
+
return totalVaultAmount * oraclePrice / (10 ** decimals);
|
|
1483
|
+
}));
|
|
1484
|
+
return vaultValues.reduce((acc, curr) => acc + curr, 0);
|
|
1485
|
+
}, _SLPDataAPI_getSwapImpactConfig = async function _SLPDataAPI_getSwapImpactConfig() {
|
|
1486
|
+
if (!this.consts.sudoCore) {
|
|
1487
|
+
return null;
|
|
1488
|
+
}
|
|
1489
|
+
const raw = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix).call(this, this.consts.sudoCore.market, 'SwapImpactConfigKey');
|
|
1490
|
+
if (!raw)
|
|
1491
|
+
return null;
|
|
1492
|
+
return __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_parseSwapImpactConfig).call(_a, raw);
|
|
1493
|
+
}, _SLPDataAPI_getEmaVolatilityFeeConfig = async function _SLPDataAPI_getEmaVolatilityFeeConfig() {
|
|
1494
|
+
if (!this.consts.sudoCore) {
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
const raw = await __classPrivateFieldGet(this, _SLPDataAPI_instances, "m", _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix).call(this, this.consts.sudoCore.market, 'EmaVolatilityFeeConfigKey');
|
|
1498
|
+
if (!raw)
|
|
1499
|
+
return null;
|
|
1500
|
+
return __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_parseEmaVolatilityFeeConfig).call(_a, raw);
|
|
1501
|
+
}, _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix = async function _SLPDataAPI_getMarketDynamicFieldObjectByKeySuffix(parentId, keyTypeSuffix) {
|
|
1502
|
+
let cursor;
|
|
1503
|
+
let hasNextPage = true;
|
|
1504
|
+
while (hasNextPage) {
|
|
1505
|
+
const page = await this.provider.getDynamicFields({ parentId, cursor });
|
|
1506
|
+
for (const field of page.data) {
|
|
1507
|
+
const type = field.name?.type;
|
|
1508
|
+
if (typeof type === 'string' && type.endsWith(`::${keyTypeSuffix}`)) {
|
|
1509
|
+
return await this.provider.getDynamicFieldObject({
|
|
1510
|
+
parentId,
|
|
1511
|
+
name: field.name,
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
hasNextPage = page.hasNextPage;
|
|
1516
|
+
cursor = page.nextCursor;
|
|
1517
|
+
}
|
|
1518
|
+
return null;
|
|
1519
|
+
}, _SLPDataAPI_parseSwapImpactConfig = function _SLPDataAPI_parseSwapImpactConfig(raw) {
|
|
1520
|
+
const { fields } = raw.data.content;
|
|
1521
|
+
return {
|
|
1522
|
+
id: fields.id.id,
|
|
1523
|
+
enabled: fields.enabled,
|
|
1524
|
+
impactMultiplier: (0, utils_2.parseValue)(fields.impact_multiplier),
|
|
1525
|
+
maxImpactRate: (0, utils_2.parseValue)(fields.max_impact_rate),
|
|
1526
|
+
};
|
|
1527
|
+
}, _SLPDataAPI_parseEmaVolatilityFeeConfig = function _SLPDataAPI_parseEmaVolatilityFeeConfig(raw) {
|
|
1528
|
+
const { fields } = raw.data.content;
|
|
1529
|
+
return {
|
|
1530
|
+
id: fields.id.id,
|
|
1531
|
+
enabled: fields.enabled,
|
|
1532
|
+
multiplier: (0, utils_2.parseValue)(fields.multiplier),
|
|
1533
|
+
maxFeeRate: (0, utils_2.parseValue)(fields.max_fee_rate),
|
|
1534
|
+
};
|
|
1535
|
+
}, _SLPDataAPI_computeSwapImpactFeeValue = function _SLPDataAPI_computeSwapImpactFeeValue(swapValue, totalVaultsValue, impactMultiplier, maxImpactRate) {
|
|
1536
|
+
if (swapValue <= 0 || totalVaultsValue <= 0)
|
|
1537
|
+
return 0;
|
|
1538
|
+
const utilization = swapValue / totalVaultsValue;
|
|
1539
|
+
const rawImpactRate = impactMultiplier * utilization;
|
|
1540
|
+
const impactRate = Math.min(rawImpactRate, maxImpactRate);
|
|
1541
|
+
return swapValue * impactRate;
|
|
1542
|
+
}, _SLPDataAPI_computeEmaVolatilityFeeValue = function _SLPDataAPI_computeEmaVolatilityFeeValue(swapValue, maxDiv, multiplier, maxFeeRate) {
|
|
1543
|
+
if (swapValue <= 0 || maxDiv <= 0)
|
|
1544
|
+
return 0;
|
|
1545
|
+
const rawFeeRate = multiplier * maxDiv;
|
|
1546
|
+
const feeRate = Math.min(rawFeeRate, maxFeeRate);
|
|
1547
|
+
return swapValue * feeRate;
|
|
1548
|
+
}, _SLPDataAPI_maxEmaDivergenceRate = function _SLPDataAPI_maxEmaDivergenceRate(sourceFeed, destFeed) {
|
|
1549
|
+
const sourceDiv = __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_emaDivergenceRate).call(_a, sourceFeed);
|
|
1550
|
+
const destDiv = __classPrivateFieldGet(_a, _a, "m", _SLPDataAPI_emaDivergenceRate).call(_a, destFeed);
|
|
1551
|
+
return Math.max(sourceDiv, destDiv);
|
|
1552
|
+
}, _SLPDataAPI_emaDivergenceRate = function _SLPDataAPI_emaDivergenceRate(priceFeed) {
|
|
1553
|
+
const price = priceFeed.getPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1554
|
+
const ema = priceFeed.getEmaPriceUnchecked().getPriceAsNumberUnchecked();
|
|
1555
|
+
const denom = Math.abs(price);
|
|
1556
|
+
if (denom === 0)
|
|
1557
|
+
return 0;
|
|
1558
|
+
return Math.abs(price - ema) / denom;
|
|
1559
|
+
};
|
|
1395
1560
|
//# sourceMappingURL=SLPDataAPI.cjs.map
|