zo-sdk 0.1.42 → 0.1.44

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 (33) 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/implementations/SLPDataAPI.cjs +80 -62
  4. package/dist/implementations/SLPDataAPI.cjs.map +1 -1
  5. package/dist/implementations/SLPDataAPI.d.cts +8 -2
  6. package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
  7. package/dist/implementations/SLPDataAPI.d.mts +8 -2
  8. package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
  9. package/dist/implementations/SLPDataAPI.mjs +81 -63
  10. package/dist/implementations/SLPDataAPI.mjs.map +1 -1
  11. package/dist/implementations/USDZDataAPI.cjs +83 -16
  12. package/dist/implementations/USDZDataAPI.cjs.map +1 -1
  13. package/dist/implementations/USDZDataAPI.d.cts +7 -1
  14. package/dist/implementations/USDZDataAPI.d.cts.map +1 -1
  15. package/dist/implementations/USDZDataAPI.d.mts +7 -1
  16. package/dist/implementations/USDZDataAPI.d.mts.map +1 -1
  17. package/dist/implementations/USDZDataAPI.mjs +83 -16
  18. package/dist/implementations/USDZDataAPI.mjs.map +1 -1
  19. package/dist/interfaces/slp.d.cts +12 -0
  20. package/dist/interfaces/slp.d.cts.map +1 -1
  21. package/dist/interfaces/slp.d.mts +12 -0
  22. package/dist/interfaces/slp.d.mts.map +1 -1
  23. package/dist/interfaces/usdz.d.cts +12 -0
  24. package/dist/interfaces/usdz.d.cts.map +1 -1
  25. package/dist/interfaces/usdz.d.mts +12 -0
  26. package/dist/interfaces/usdz.d.mts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/consts/deployments-slp-mainnet.json +1 -1
  29. package/src/consts/deployments-usdz-mainnet.json +1 -1
  30. package/src/implementations/SLPDataAPI.ts +128 -65
  31. package/src/implementations/USDZDataAPI.ts +165 -18
  32. package/src/interfaces/slp.ts +14 -0
  33. package/src/interfaces/usdz.ts +13 -0
@@ -19,6 +19,8 @@ import type {
19
19
  IUSDZFundingFeeModel,
20
20
  IUSDZMarketInfo,
21
21
  IUSDZMarketValuationInfo,
22
+ IUSDZOiFundingModel,
23
+ IUSDZOiFundingState,
22
24
  IUSDZOrderCapInfo,
23
25
  IUSDZOrderInfo,
24
26
  IUSDZPositionCapInfo,
@@ -203,8 +205,25 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
203
205
  const symbolPromises = Object.keys(this.consts.zoCore.symbols).map(async (symbol) => {
204
206
  const [direction, tokenId] = parseSymbolKey(symbol)
205
207
  const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long')
206
- const deltaSize = USDZDataAPI.calcDeltaSize(symbolInfo, (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked())
207
- const fundingFeeDelta = USDZDataAPI.calculateSymbolFundingFee(symbolInfo, symbolInfo.fundingFeeModel, (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked(), marketInfo.lpSupplyWithDecimals, Date.now() / 1000)
208
+ const deltaSize = USDZDataAPI.calcDeltaSize(
209
+ symbolInfo,
210
+ (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked(),
211
+ )
212
+
213
+ // OI context for funding fee delta
214
+ const oiState = await this.getSymbolOiFundingState(tokenId)
215
+ const pairedSymbol = await this.getSymbolInfo(tokenId, !(direction === 'long'))
216
+
217
+ const fundingFeeDelta = USDZDataAPI.calculateSymbolFundingFee(
218
+ symbolInfo,
219
+ symbolInfo.fundingFeeModel,
220
+ (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked(),
221
+ marketInfo.lpSupplyWithDecimals,
222
+ Date.now() / 1000,
223
+ oiState && oiState.enabled ? oiState.model : undefined,
224
+ pairedSymbol.openingSize,
225
+ )
226
+
208
227
  return fundingFeeDelta + deltaSize
209
228
  })
210
229
 
@@ -315,6 +334,27 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
315
334
  }
316
335
  }
317
336
 
337
+ /**
338
+ * Gets USDZ symbol OI funding state (global per symbol)
339
+ */
340
+ public async getSymbolOiFundingState(indexToken: string): Promise<IUSDZOiFundingState | null> {
341
+ this.validateCache()
342
+ try {
343
+ const rawData = await this.provider.getDynamicFieldObject({
344
+ parentId: this.consts.zoCore.market,
345
+ name: {
346
+ type: `${this.consts.zoCore.upgradedPackage}::funding::FundingStateKey<${this.consts.coins[indexToken].module}>`,
347
+ value: { dummy_field: false },
348
+ },
349
+ })
350
+ return USDZDataAPI.parseOiFundingState(rawData)
351
+ }
352
+ catch (e: any) {
353
+ console.error('Error Fetching USDZ Symbol OI Funding State:', e)
354
+ return null
355
+ }
356
+ }
357
+
318
358
  public async getPositionCapInfoList(owner: string): Promise<IUSDZPositionCapInfo[]> {
319
359
  const positionCapInfoList: IUSDZPositionCapInfo[] = []
320
360
  let cursor: string | undefined | null
@@ -539,18 +579,37 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
539
579
  }
540
580
 
541
581
  public async fundingFeeRate(indexToken: string, long: boolean): Promise<number> {
542
- const symbol = await this.getSymbolInfo(indexToken, long)
543
- if (symbol.lastUpdate <= 0) {
582
+ const oiState = await this.getSymbolOiFundingState(indexToken)
583
+
584
+ if (!oiState || !oiState.enabled) {
585
+ const symbol = await this.getSymbolInfo(indexToken, long)
586
+ if (symbol.lastUpdate <= 0) {
587
+ return 0
588
+ }
589
+ const price = (await this.getOraclePrice(indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked()
590
+ const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals
591
+ const model = symbol.fundingFeeModel
592
+ const elapsed = SECONDS_PER_EIGHT_HOUR
593
+
594
+ const deltaSize = USDZDataAPI.calcDeltaSize(symbol, price)
595
+ const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount
596
+ return USDZDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed)
597
+ }
598
+
599
+ // OI model enabled: rate based on long/short imbalance
600
+ const longSymbol = await this.getSymbolInfo(indexToken, true)
601
+ const shortSymbol = await this.getSymbolInfo(indexToken, false)
602
+
603
+ if (longSymbol.lastUpdate <= 0 && shortSymbol.lastUpdate <= 0) {
544
604
  return 0
545
605
  }
546
- const price = (await this.getOraclePrice(indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked()
547
- const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals
548
- const model = symbol.fundingFeeModel
606
+
549
607
  const elapsed = SECONDS_PER_EIGHT_HOUR
608
+ const longSize = longSymbol.openingSize
609
+ const shortSize = shortSymbol.openingSize
550
610
 
551
- const deltaSize = USDZDataAPI.calcDeltaSize(symbol, price)
552
- const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount
553
- return USDZDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed)
611
+ const deltaRate = USDZDataAPI.calcOiFundingFeeRate(oiState.model, longSize, shortSize, elapsed)
612
+ return long ? deltaRate : -deltaRate
554
613
  }
555
614
 
556
615
  public async rebaseFeeRate(collateralToken: string, increase: boolean, amount: number): Promise<number> {
@@ -636,10 +695,32 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
636
695
  return pnlPerRate >= 0 ? -secondsRate : secondsRate
637
696
  }
638
697
 
639
- private static calcAccFundingFeeRate(symbol: IUSDZSymbolInfo, model: IUSDZFundingFeeModel, price: number, lpSupplyAmount: number, timestamp: number): number {
698
+ private static calcOiFundingFeeRate(model: IUSDZOiFundingModel, longSize: number, shortSize: number, elapsed: number): number {
699
+ const imbalance = Math.abs(longSize - shortSize)
700
+ const total = longSize + shortSize > 0 ? longSize + shortSize : 1
701
+ const dailyRate = Math.min((model.multiplier * (imbalance ** model.exponent)) / total, model.max)
702
+ const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR
703
+ return longSize >= shortSize ? secondsRate : -secondsRate
704
+ }
705
+
706
+ private static calcAccFundingFeeRate(
707
+ symbol: IUSDZSymbolInfo,
708
+ model: IUSDZFundingFeeModel,
709
+ price: number,
710
+ lpSupplyAmount: number,
711
+ timestamp: number,
712
+ oiModel?: IUSDZOiFundingModel,
713
+ pairedOpeningSize?: number,
714
+ ): number {
640
715
  if (symbol.lastUpdate > 0) {
641
716
  const elapsed = timestamp - symbol.lastUpdate
642
717
  if (elapsed > 0) {
718
+ if (oiModel && typeof pairedOpeningSize === 'number') {
719
+ const longSize = symbol.long ? symbol.openingSize : pairedOpeningSize
720
+ const shortSize = symbol.long ? pairedOpeningSize : symbol.openingSize
721
+ const deltaRate = USDZDataAPI.calcOiFundingFeeRate(oiModel, longSize, shortSize, elapsed)
722
+ return symbol.accFundingRate + deltaRate
723
+ }
643
724
  const deltaSize = USDZDataAPI.calcDeltaSize(symbol, price)
644
725
  const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount
645
726
  return symbol.accFundingRate + USDZDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed)
@@ -648,8 +729,24 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
648
729
  return symbol.accFundingRate
649
730
  }
650
731
 
651
- private static calculateSymbolFundingFee(symbol: IUSDZSymbolInfo, model: IUSDZFundingFeeModel, price: number, lpSupplyAmount: number, timestamp: number): number {
652
- const accFundingRate = USDZDataAPI.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp)
732
+ private static calculateSymbolFundingFee(
733
+ symbol: IUSDZSymbolInfo,
734
+ model: IUSDZFundingFeeModel,
735
+ price: number,
736
+ lpSupplyAmount: number,
737
+ timestamp: number,
738
+ oiModel?: IUSDZOiFundingModel,
739
+ pairedOpeningSize?: number,
740
+ ): number {
741
+ const accFundingRate = USDZDataAPI.calcAccFundingFeeRate(
742
+ symbol,
743
+ model,
744
+ price,
745
+ lpSupplyAmount,
746
+ timestamp,
747
+ oiModel,
748
+ pairedOpeningSize,
749
+ )
653
750
  return symbol.unrealisedFundingFeeValue + (accFundingRate - symbol.accFundingRate) * symbol.openingSize
654
751
  }
655
752
 
@@ -836,15 +933,50 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
836
933
  openTimestamp: parseValue(positionFields.open_timestamp),
837
934
  }
838
935
 
839
- positionInfo.reservingFeeAmount = USDZDataAPI.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000)
840
- positionInfo.fundingFeeValue = USDZDataAPI.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)
936
+ positionInfo.reservingFeeAmount = USDZDataAPI.calculatePositionReserveFee(
937
+ positionInfo,
938
+ await this.getVaultInfo(positionInfo.collateralToken),
939
+ (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel,
940
+ Date.now() / 1000,
941
+ )
942
+
943
+ // OI context for funding: fetch state and paired side size when enabled
944
+ const oiState = await this.getSymbolOiFundingState(positionInfo.indexToken)
945
+ const pairedSymbol = await this.getSymbolInfo(positionInfo.indexToken, !positionInfo.long)
946
+ positionInfo.fundingFeeValue = USDZDataAPI.calculatePositionFundingFee(
947
+ positionInfo,
948
+ await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long),
949
+ (await this.getSymbolInfo(positionInfo.indexToken, positionInfo.long)).fundingFeeModel,
950
+ (await this.getOraclePrice(positionInfo.indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked(),
951
+ (await this.getMarketInfo()).lpSupplyWithDecimals,
952
+ Date.now() / 1000,
953
+ oiState && oiState.enabled ? oiState.model : undefined,
954
+ pairedSymbol.openingSize,
955
+ )
841
956
 
842
957
  return positionInfo
843
958
  }
844
959
 
845
- private static calculatePositionFundingFee(position: IUSDZPositionInfo, symbol: IUSDZSymbolInfo, model: IUSDZFundingFeeModel, price: number, lpSupplyAmount: number, timestamp: number): number {
846
- const accFundingRate = USDZDataAPI.calcAccFundingFeeRate(symbol, model, price, lpSupplyAmount, timestamp)
847
- return position.fundingFeeValue + (accFundingRate - symbol.accFundingRate) * position.positionSize
960
+ private static calculatePositionFundingFee(
961
+ position: IUSDZPositionInfo,
962
+ symbol: IUSDZSymbolInfo,
963
+ model: IUSDZFundingFeeModel,
964
+ price: number,
965
+ lpSupplyAmount: number,
966
+ timestamp: number,
967
+ oiModel?: IUSDZOiFundingModel,
968
+ pairedOpeningSize?: number,
969
+ ): number {
970
+ const accFundingRate = USDZDataAPI.calcAccFundingFeeRate(
971
+ symbol,
972
+ model,
973
+ price,
974
+ lpSupplyAmount,
975
+ timestamp,
976
+ oiModel,
977
+ pairedOpeningSize,
978
+ )
979
+ return position.fundingFeeValue + (accFundingRate - position.lastFundingRate) * position.positionSize
848
980
  }
849
981
 
850
982
  private static parseRebaseFeeModel(raw: any): { base: number, multiplier: number } {
@@ -871,6 +1003,21 @@ export class USDZDataAPI extends BaseDataAPI implements IUSDZDataAPI {
871
1003
  }
872
1004
  }
873
1005
 
1006
+ private static parseOiFundingState(raw: any): IUSDZOiFundingState {
1007
+ const content = raw.data.content.fields
1008
+ return {
1009
+ id: content.id.id,
1010
+ enabled: content.enabled,
1011
+ last_update: parseValue(content.last_update),
1012
+ model: {
1013
+ id: content.model.fields.id.id,
1014
+ multiplier: parseValue(content.model.fields.multiplier),
1015
+ exponent: parseValue(content.model.fields.exponent),
1016
+ max: parseValue(content.model.fields.max),
1017
+ },
1018
+ }
1019
+ }
1020
+
874
1021
  private parseOrderInfo(raw: any, capId: string): IUSDZOrderInfo {
875
1022
  const { content } = raw.data
876
1023
  const { fields } = content.fields.value
@@ -87,6 +87,20 @@ export interface ISLPSymbolConfig {
87
87
  instant_exit_fee_config: ISLPPositionInstantExitFeeConfig
88
88
  }
89
89
 
90
+ export interface ISLPOiFundingModel {
91
+ id: string
92
+ multiplier: number
93
+ exponent: number
94
+ max: number
95
+ }
96
+
97
+ export interface ISLPOiFundingState {
98
+ id: string
99
+ enabled: boolean
100
+ last_update: number
101
+ model: ISLPOiFundingModel
102
+ }
103
+
90
104
  // Sudo SDK specific data structures
91
105
  export interface ISudoMarket {
92
106
  lpSupply: bigint
@@ -89,6 +89,19 @@ export interface IUSDZSymbolConfig {
89
89
  instant_exit_fee_config: IUSDZPositionInstantExitFeeConfig
90
90
  }
91
91
 
92
+ export interface IUSDZOiFundingModel {
93
+ id: string
94
+ multiplier: number
95
+ exponent: number
96
+ max: number
97
+ }
98
+ export interface IUSDZOiFundingState {
99
+ id: string
100
+ enabled: boolean
101
+ last_update: number
102
+ model: IUSDZOiFundingModel
103
+ }
104
+
92
105
  // USDZ-specific data API interface
93
106
  export interface IUSDZDataAPI extends IBaseDataAPI {
94
107
  getSymbolConfig: (indexToken: string, long: boolean) => Promise<IUSDZSymbolConfig | null>