zo-sdk 0.1.39 → 0.1.41
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-zlp-mainnet.json +28 -2
- package/dist/consts/deployments-zlp-testnet.json +18 -52
- package/dist/consts/price_id_to_object_id.mainnet.json +2 -1
- package/dist/implementations/ZLPDataAPI.cjs +91 -18
- package/dist/implementations/ZLPDataAPI.cjs.map +1 -1
- package/dist/implementations/ZLPDataAPI.d.cts +7 -1
- package/dist/implementations/ZLPDataAPI.d.cts.map +1 -1
- package/dist/implementations/ZLPDataAPI.d.mts +7 -1
- package/dist/implementations/ZLPDataAPI.d.mts.map +1 -1
- package/dist/implementations/ZLPDataAPI.mjs +91 -18
- package/dist/implementations/ZLPDataAPI.mjs.map +1 -1
- package/dist/interfaces/zlp.d.cts +12 -0
- package/dist/interfaces/zlp.d.cts.map +1 -1
- package/dist/interfaces/zlp.d.mts +12 -0
- package/dist/interfaces/zlp.d.mts.map +1 -1
- package/package.json +1 -1
- package/src/consts/deployments-zlp-mainnet.json +28 -2
- package/src/consts/deployments-zlp-testnet.json +19 -53
- package/src/consts/price_id_to_object_id.mainnet.json +2 -1
- package/src/implementations/ZLPDataAPI.ts +154 -18
- package/src/interfaces/zlp.ts +13 -0
|
@@ -19,6 +19,8 @@ import type {
|
|
|
19
19
|
IZLPFundingFeeModel,
|
|
20
20
|
IZLPMarketInfo,
|
|
21
21
|
IZLPMarketValuationInfo,
|
|
22
|
+
IZLPOiFundingModel,
|
|
23
|
+
IZLPOiFundingState,
|
|
22
24
|
IZLPOrderCapInfo,
|
|
23
25
|
IZLPOrderInfo,
|
|
24
26
|
IZLPPositionCapInfo,
|
|
@@ -204,8 +206,20 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
204
206
|
const symbolPromises = Object.keys(this.consts.zoCore.symbols).map(async (symbol) => {
|
|
205
207
|
const [direction, tokenId] = parseSymbolKey(symbol)
|
|
206
208
|
const symbolInfo = await this.getSymbolInfo(tokenId, direction === 'long')
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
+
const price = (await this.getOraclePrice(tokenId)).getPriceUnchecked().getPriceAsNumberUnchecked()
|
|
210
|
+
const deltaSize = ZLPDataAPI.calcDeltaSize(symbolInfo, price)
|
|
211
|
+
|
|
212
|
+
const oiState = await this.getSymbolOiFundingState(tokenId)
|
|
213
|
+
const pairedInfo = await this.getSymbolInfo(tokenId, direction !== 'long')
|
|
214
|
+
const fundingFeeDelta = ZLPDataAPI.calculateSymbolFundingFee(
|
|
215
|
+
symbolInfo,
|
|
216
|
+
symbolInfo.fundingFeeModel,
|
|
217
|
+
price,
|
|
218
|
+
marketInfo.lpSupplyWithDecimals,
|
|
219
|
+
Date.now() / 1000,
|
|
220
|
+
oiState && oiState.enabled ? oiState.model : undefined,
|
|
221
|
+
pairedInfo.openingSize,
|
|
222
|
+
)
|
|
209
223
|
return fundingFeeDelta + deltaSize
|
|
210
224
|
})
|
|
211
225
|
|
|
@@ -309,9 +323,31 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
309
323
|
})
|
|
310
324
|
return ZLPDataAPI.parseSymbolConfig(rawData)
|
|
311
325
|
}
|
|
312
|
-
catch {
|
|
326
|
+
catch (e: any) {
|
|
327
|
+
// If the dynamic field doesn't exist, return null
|
|
328
|
+
console.error('Error Fetching Symbol Config:', e)
|
|
329
|
+
return null
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Gets ZLP symbol OI funding model
|
|
335
|
+
*/
|
|
336
|
+
public async getSymbolOiFundingState(indexToken: string): Promise<IZLPOiFundingState | null> {
|
|
337
|
+
this.validateCache()
|
|
338
|
+
try {
|
|
339
|
+
const rawData = await this.provider.getDynamicFieldObject({
|
|
340
|
+
parentId: this.consts.zoCore.market,
|
|
341
|
+
name: {
|
|
342
|
+
type: `${this.consts.zoCore.upgradedPackage}::funding::FundingStateKey<${this.consts.coins[indexToken].module}>`,
|
|
343
|
+
value: { dummy_field: false },
|
|
344
|
+
},
|
|
345
|
+
})
|
|
346
|
+
return ZLPDataAPI.parseOiFundingState(rawData)
|
|
347
|
+
}
|
|
348
|
+
catch (e: any) {
|
|
313
349
|
// If the dynamic field doesn't exist, return null
|
|
314
|
-
console.error('Symbol
|
|
350
|
+
console.error('Error Fetching Symbol OI Funding State:', e)
|
|
315
351
|
return null
|
|
316
352
|
}
|
|
317
353
|
}
|
|
@@ -570,18 +606,38 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
570
606
|
}
|
|
571
607
|
|
|
572
608
|
public async fundingFeeRate(indexToken: string, long: boolean): Promise<number> {
|
|
573
|
-
const
|
|
574
|
-
|
|
609
|
+
const oiState = await this.getSymbolOiFundingState(indexToken)
|
|
610
|
+
|
|
611
|
+
if (!oiState || !oiState.enabled) {
|
|
612
|
+
const symbol = await this.getSymbolInfo(indexToken, long)
|
|
613
|
+
if (symbol.lastUpdate <= 0) {
|
|
614
|
+
return 0
|
|
615
|
+
}
|
|
616
|
+
const price = (await this.getOraclePrice(indexToken)).getPriceUnchecked().getPriceAsNumberUnchecked()
|
|
617
|
+
const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals
|
|
618
|
+
const model = symbol.fundingFeeModel
|
|
619
|
+
const elapsed = SECONDS_PER_EIGHT_HOUR
|
|
620
|
+
|
|
621
|
+
const deltaSize = ZLPDataAPI.calcDeltaSize(symbol, price)
|
|
622
|
+
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount
|
|
623
|
+
return ZLPDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed)
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const longSymbol = await this.getSymbolInfo(indexToken, true)
|
|
627
|
+
const shortSymbol = await this.getSymbolInfo(indexToken, false)
|
|
628
|
+
|
|
629
|
+
if (longSymbol.lastUpdate <= 0 && shortSymbol.lastUpdate <= 0) {
|
|
575
630
|
return 0
|
|
576
631
|
}
|
|
577
|
-
|
|
578
|
-
const lpSupplyAmount = (await this.getMarketInfo()).lpSupplyWithDecimals
|
|
579
|
-
const model = symbol.fundingFeeModel
|
|
632
|
+
|
|
580
633
|
const elapsed = SECONDS_PER_EIGHT_HOUR
|
|
581
634
|
|
|
582
|
-
const
|
|
583
|
-
const
|
|
584
|
-
|
|
635
|
+
const longSize = longSymbol.openingSize
|
|
636
|
+
const shortSize = shortSymbol.openingSize
|
|
637
|
+
|
|
638
|
+
const deltaRate = ZLPDataAPI.calcOiFundingFeeRate(oiState.model, longSize, shortSize, elapsed)
|
|
639
|
+
console.log('deltaRate is:', deltaRate)
|
|
640
|
+
return long ? deltaRate : -deltaRate
|
|
585
641
|
}
|
|
586
642
|
|
|
587
643
|
public async rebaseFeeRate(collateralToken: string, increase: boolean, amount: number): Promise<number> {
|
|
@@ -667,10 +723,37 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
667
723
|
return pnlPerRate >= 0 ? -secondsRate : secondsRate
|
|
668
724
|
}
|
|
669
725
|
|
|
670
|
-
private static
|
|
726
|
+
private static calcOiFundingFeeRate(model: IZLPOiFundingModel, longSize: number, shortSize: number, elapsed: number): number {
|
|
727
|
+
const imbalance = Math.abs(longSize - shortSize)
|
|
728
|
+
|
|
729
|
+
// multiplier = 0.1%, exponent = 1
|
|
730
|
+
const dailyRate = Math.min(model.multiplier * (imbalance ** model.exponent) / (longSize + shortSize > 0 ? longSize + shortSize : 1), model.max)
|
|
731
|
+
const secondsRate = dailyRate * elapsed / SECONDS_PER_EIGHT_HOUR
|
|
732
|
+
return longSize >= shortSize ? secondsRate : -secondsRate
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
private static calcAccFundingFeeRate(
|
|
736
|
+
symbol: IZLPSymbolInfo,
|
|
737
|
+
model: IZLPFundingFeeModel,
|
|
738
|
+
price: number,
|
|
739
|
+
lpSupplyAmount: number,
|
|
740
|
+
timestamp: number,
|
|
741
|
+
oiModel?: IZLPOiFundingModel,
|
|
742
|
+
pairedOpeningSize?: number,
|
|
743
|
+
): number {
|
|
671
744
|
if (symbol.lastUpdate > 0) {
|
|
672
745
|
const elapsed = timestamp - symbol.lastUpdate
|
|
673
746
|
if (elapsed > 0) {
|
|
747
|
+
// Prefer OI-based delta when model and paired side are available
|
|
748
|
+
if (oiModel && typeof pairedOpeningSize === 'number') {
|
|
749
|
+
const longSize = symbol.long ? symbol.openingSize : pairedOpeningSize
|
|
750
|
+
const shortSize = symbol.long ? pairedOpeningSize : symbol.openingSize
|
|
751
|
+
const deltaRate = ZLPDataAPI.calcOiFundingFeeRate(oiModel, longSize, shortSize, elapsed)
|
|
752
|
+
const appliedRate = symbol.long ? deltaRate : -deltaRate
|
|
753
|
+
return symbol.accFundingRate + appliedRate
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Fallback to PnL-based funding delta
|
|
674
757
|
const deltaSize = ZLPDataAPI.calcDeltaSize(symbol, price)
|
|
675
758
|
const pnlPerLp = (symbol.realisedPnl + symbol.unrealisedFundingFeeValue + deltaSize) / lpSupplyAmount
|
|
676
759
|
return symbol.accFundingRate + ZLPDataAPI.calcFundingFeeRate(model, pnlPerLp, elapsed)
|
|
@@ -679,8 +762,24 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
679
762
|
return symbol.accFundingRate
|
|
680
763
|
}
|
|
681
764
|
|
|
682
|
-
private static calculateSymbolFundingFee(
|
|
683
|
-
|
|
765
|
+
private static calculateSymbolFundingFee(
|
|
766
|
+
symbol: IZLPSymbolInfo,
|
|
767
|
+
model: IZLPFundingFeeModel,
|
|
768
|
+
price: number,
|
|
769
|
+
lpSupplyAmount: number,
|
|
770
|
+
timestamp: number,
|
|
771
|
+
oiModel?: IZLPOiFundingModel,
|
|
772
|
+
pairedOpeningSize?: number,
|
|
773
|
+
): number {
|
|
774
|
+
const accFundingRate = ZLPDataAPI.calcAccFundingFeeRate(
|
|
775
|
+
symbol,
|
|
776
|
+
model,
|
|
777
|
+
price,
|
|
778
|
+
lpSupplyAmount,
|
|
779
|
+
timestamp,
|
|
780
|
+
oiModel,
|
|
781
|
+
pairedOpeningSize,
|
|
782
|
+
)
|
|
684
783
|
return symbol.unrealisedFundingFeeValue + (accFundingRate - symbol.accFundingRate) * symbol.openingSize
|
|
685
784
|
}
|
|
686
785
|
|
|
@@ -868,13 +967,33 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
868
967
|
}
|
|
869
968
|
|
|
870
969
|
positionInfo.reservingFeeAmount = ZLPDataAPI.calculatePositionReserveFee(positionInfo, await this.getVaultInfo(positionInfo.collateralToken), (await this.getVaultInfo(positionInfo.collateralToken)).reservingFeeModel, Date.now() / 1000)
|
|
871
|
-
|
|
970
|
+
// OI context for funding: fetch state and paired side size when enabled
|
|
971
|
+
const oiState = await this.getSymbolOiFundingState(positionInfo.indexToken)
|
|
972
|
+
const pairedSymbol = await this.getSymbolInfo(positionInfo.indexToken, !positionInfo.long)
|
|
973
|
+
positionInfo.fundingFeeValue = ZLPDataAPI.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)
|
|
872
974
|
|
|
873
975
|
return positionInfo
|
|
874
976
|
}
|
|
875
977
|
|
|
876
|
-
private static calculatePositionFundingFee(
|
|
877
|
-
|
|
978
|
+
private static calculatePositionFundingFee(
|
|
979
|
+
position: IZLPPositionInfo,
|
|
980
|
+
symbol: IZLPSymbolInfo,
|
|
981
|
+
model: IZLPFundingFeeModel,
|
|
982
|
+
price: number,
|
|
983
|
+
lpSupplyAmount: number,
|
|
984
|
+
timestamp: number,
|
|
985
|
+
oiModel?: IZLPOiFundingModel,
|
|
986
|
+
pairedOpeningSize?: number,
|
|
987
|
+
): number {
|
|
988
|
+
const accFundingRate = ZLPDataAPI.calcAccFundingFeeRate(
|
|
989
|
+
symbol,
|
|
990
|
+
model,
|
|
991
|
+
price,
|
|
992
|
+
lpSupplyAmount,
|
|
993
|
+
timestamp,
|
|
994
|
+
oiModel,
|
|
995
|
+
pairedOpeningSize,
|
|
996
|
+
)
|
|
878
997
|
return position.fundingFeeValue + (accFundingRate - position.lastFundingRate) * position.positionSize
|
|
879
998
|
}
|
|
880
999
|
|
|
@@ -902,6 +1021,23 @@ export class ZLPDataAPI extends BaseDataAPI implements IZLPDataAPI {
|
|
|
902
1021
|
}
|
|
903
1022
|
}
|
|
904
1023
|
|
|
1024
|
+
private static parseOiFundingState(raw: any): IZLPOiFundingState {
|
|
1025
|
+
console.log('checking oi funding state raw:', raw)
|
|
1026
|
+
const content = raw.data.content.fields
|
|
1027
|
+
console.log('oi funding state raw:', content)
|
|
1028
|
+
return {
|
|
1029
|
+
id: content.id.id,
|
|
1030
|
+
enabled: content.enabled,
|
|
1031
|
+
last_update: parseValue(content.last_update),
|
|
1032
|
+
model: {
|
|
1033
|
+
id: content.model.fields.id.id,
|
|
1034
|
+
multiplier: parseValue(content.model.fields.multiplier),
|
|
1035
|
+
exponent: parseValue(content.model.fields.exponent),
|
|
1036
|
+
max: parseValue(content.model.fields.max),
|
|
1037
|
+
},
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
|
|
905
1041
|
private parseOrderInfo(raw: any, capId: string): IZLPOrderInfo {
|
|
906
1042
|
const { content } = raw.data
|
|
907
1043
|
const { fields } = content.fields.value
|
package/src/interfaces/zlp.ts
CHANGED
|
@@ -89,6 +89,19 @@ export interface IZLPSymbolConfig {
|
|
|
89
89
|
instant_exit_fee_config: IZLPPositionInstantExitFeeConfig
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
export interface IZLPOiFundingModel {
|
|
93
|
+
id: string
|
|
94
|
+
multiplier: number
|
|
95
|
+
exponent: number
|
|
96
|
+
max: number
|
|
97
|
+
}
|
|
98
|
+
export interface IZLPOiFundingState {
|
|
99
|
+
id: string
|
|
100
|
+
enabled: boolean
|
|
101
|
+
last_update: number
|
|
102
|
+
model: IZLPOiFundingModel
|
|
103
|
+
}
|
|
104
|
+
|
|
92
105
|
// ZLP-specific data API interface
|
|
93
106
|
export interface IZLPDataAPI extends IBaseDataAPI {
|
|
94
107
|
getSymbolConfig: (indexToken: string, long: boolean) => Promise<IZLPSymbolConfig | null>
|