@zofai/zo-sdk 0.2.26 → 0.2.27

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 (37) hide show
  1. package/dist/consts/deployments-slp-mainnet.json +1 -1
  2. package/dist/consts/deployments-zo-oracle-mainnet.json +9 -0
  3. package/dist/implementations/SLPAPI.cjs +424 -209
  4. package/dist/implementations/SLPAPI.cjs.map +1 -1
  5. package/dist/implementations/SLPAPI.d.cts +19 -2
  6. package/dist/implementations/SLPAPI.d.cts.map +1 -1
  7. package/dist/implementations/SLPAPI.d.mts +19 -2
  8. package/dist/implementations/SLPAPI.d.mts.map +1 -1
  9. package/dist/implementations/SLPAPI.mjs +425 -210
  10. package/dist/implementations/SLPAPI.mjs.map +1 -1
  11. package/dist/implementations/SLPDataAPI.cjs +38 -0
  12. package/dist/implementations/SLPDataAPI.cjs.map +1 -1
  13. package/dist/implementations/SLPDataAPI.d.cts +10 -0
  14. package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
  15. package/dist/implementations/SLPDataAPI.d.mts +10 -0
  16. package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
  17. package/dist/implementations/SLPDataAPI.mjs +38 -0
  18. package/dist/implementations/SLPDataAPI.mjs.map +1 -1
  19. package/dist/interfaces/slp.d.cts +16 -0
  20. package/dist/interfaces/slp.d.cts.map +1 -1
  21. package/dist/interfaces/slp.d.mts +16 -0
  22. package/dist/interfaces/slp.d.mts.map +1 -1
  23. package/dist/oraclePro.cjs +93 -8
  24. package/dist/oraclePro.cjs.map +1 -1
  25. package/dist/oraclePro.d.cts +38 -0
  26. package/dist/oraclePro.d.cts.map +1 -1
  27. package/dist/oraclePro.d.mts +38 -0
  28. package/dist/oraclePro.d.mts.map +1 -1
  29. package/dist/oraclePro.mjs +89 -8
  30. package/dist/oraclePro.mjs.map +1 -1
  31. package/package.json +1 -1
  32. package/src/consts/deployments-slp-mainnet.json +1 -1
  33. package/src/consts/deployments-zo-oracle-mainnet.json +9 -0
  34. package/src/implementations/SLPAPI.ts +723 -239
  35. package/src/implementations/SLPDataAPI.ts +42 -0
  36. package/src/interfaces/slp.ts +170 -0
  37. package/src/oraclePro.ts +147 -9
@@ -38,7 +38,9 @@ import type {
38
38
  ISLPVaultInfo,
39
39
  ISwapFeeBreakdown,
40
40
  } from '../interfaces'
41
+ import type { OracleInputs } from '../oraclePro'
41
42
  import type { DynamicFieldInfo, SuiClient } from '../suiClient'
43
+ import { valuateSymbolsV3, valuateVaultsV3 } from '../oraclePro'
42
44
  import { joinSymbol, parseSymbolKey, parseValue, suiSymbolToSymbol } from '../utils'
43
45
 
44
46
  export interface GetCumulativeAprResponse {
@@ -210,6 +212,46 @@ export class SLPDataAPI extends BaseDataAPI implements ISLPDataAPI {
210
212
  return { vaultsValuation, symbolsValuation }
211
213
  }
212
214
 
215
+ /** Creates vaults valuation using valuate_vault_v3 (Pyth Pro + Stork, sudo-core). */
216
+ public valuateVaultsV3(tx: Transaction, oracle: OracleInputs) {
217
+ if (!this.consts.sudoCore) {
218
+ throw new Error('Sudo Core configuration not found. Make sure you are using LPToken.SLP')
219
+ }
220
+ return valuateVaultsV3({
221
+ tx,
222
+ upgradedPackage: this.consts.sudoCore.upgradedPackage,
223
+ lpType: `${this.consts.sudoCore.package}::slp::SLP`,
224
+ market: this.consts.sudoCore.market,
225
+ vaults: this.consts.sudoCore.vaults,
226
+ coinModules: this.consts.coins,
227
+ oracle,
228
+ })
229
+ }
230
+
231
+ /** Creates symbols valuation using valuate_symbol_v3 (Pyth Pro + Stork, sudo-core). */
232
+ public valuateSymbolsV3(tx: Transaction, oracle: OracleInputs) {
233
+ if (!this.consts.sudoCore) {
234
+ throw new Error('Sudo Core configuration not found. Make sure you are using LPToken.SLP')
235
+ }
236
+ return valuateSymbolsV3({
237
+ tx,
238
+ upgradedPackage: this.consts.sudoCore.upgradedPackage,
239
+ marketPackage: this.consts.sudoCore.package,
240
+ lpType: `${this.consts.sudoCore.package}::slp::SLP`,
241
+ market: this.consts.sudoCore.market,
242
+ symbols: this.consts.sudoCore.symbols,
243
+ coinModules: this.consts.coins,
244
+ oracle,
245
+ })
246
+ }
247
+
248
+ /** Creates both vaults and symbols valuation (Pyth Pro + Stork, sudo-core). */
249
+ public valuateV3(tx: Transaction, oracle: OracleInputs) {
250
+ const vaultsValuation = this.valuateVaultsV3(tx, oracle)
251
+ const symbolsValuation = this.valuateSymbolsV3(tx, oracle)
252
+ return { vaultsValuation, symbolsValuation }
253
+ }
254
+
213
255
  /**
214
256
  * Valuates the SLP market using Sudo SDK's approach
215
257
  */
@@ -6,6 +6,7 @@
6
6
  import type { KioskClient, KioskOwnerCap } from '@mysten/kiosk'
7
7
  import type { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions'
8
8
 
9
+ import type { OracleInputs } from '../oraclePro'
9
10
  import type {
10
11
  IBaseAPI,
11
12
  IBaseCredential,
@@ -217,6 +218,12 @@ export interface ISLPDataAPI extends IBaseDataAPI {
217
218
  getSymbolConfig: (indexToken: string, long: boolean) => Promise<ISLPSymbolConfig | null>
218
219
  getPriceImpactConfig: (indexToken: string) => Promise<ISLPPriceImpactConfig | null>
219
220
  calculateSwapFeeBreakdown: (fromToken: string, toToken: string, fromAmount: number) => Promise<ISwapFeeBreakdown>
221
+ valuateVaultsV3: (tx: Transaction, oracle: OracleInputs) => TransactionObjectArgument
222
+ valuateSymbolsV3: (tx: Transaction, oracle: OracleInputs) => TransactionObjectArgument
223
+ valuateV3: (tx: Transaction, oracle: OracleInputs) => {
224
+ vaultsValuation: TransactionObjectArgument
225
+ symbolsValuation: TransactionObjectArgument
226
+ }
220
227
  }
221
228
 
222
229
  // SLP-specific API interface
@@ -286,4 +293,167 @@ export interface ISLPAPI extends IBaseAPI {
286
293
  minAmountOut?: number,
287
294
  tx?: Transaction,
288
295
  ) => Promise<TransactionObjectArgument>
296
+
297
+ swapV4: (
298
+ fromToken: string,
299
+ toToken: string,
300
+ fromAmount: bigint,
301
+ fromCoinObjects: string[],
302
+ pythProUpdateBytes: Uint8Array | number[],
303
+ minAmountOut?: number,
304
+ tx?: Transaction,
305
+ ) => Promise<Transaction>
306
+
307
+ swapV4Ptb: (
308
+ fromToken: string,
309
+ toToken: string,
310
+ fromAmount: bigint,
311
+ fromCoinObjects: string[],
312
+ pythProUpdateBytes: Uint8Array | number[],
313
+ minAmountOut?: number,
314
+ tx?: Transaction,
315
+ ) => Promise<TransactionObjectArgument>
316
+
317
+ openPositionV3: (
318
+ collateralToken: string,
319
+ indexToken: string,
320
+ size: bigint,
321
+ collateralAmount: bigint,
322
+ coinObjects: string[],
323
+ long: boolean,
324
+ reserveAmount: bigint,
325
+ indexPrice: number,
326
+ collateralPrice: number,
327
+ pythProUpdateBytes: Uint8Array | number[],
328
+ isLimitOrder?: boolean,
329
+ isIocOrder?: boolean,
330
+ pricesSlippage?: number,
331
+ collateralSlippage?: number,
332
+ relayerFee?: bigint,
333
+ referralAddress?: string,
334
+ sender?: string,
335
+ sponsoredTx?: boolean,
336
+ ) => Promise<Transaction>
337
+
338
+ openPositionWithSCardV3: (
339
+ collateralToken: string,
340
+ indexToken: string,
341
+ size: bigint,
342
+ collateralAmount: bigint,
343
+ coinObjects: string[],
344
+ long: boolean,
345
+ reserveAmount: bigint,
346
+ indexPrice: number,
347
+ collateralPrice: number,
348
+ kioskClient: KioskClient,
349
+ kioskCap: KioskOwnerCap,
350
+ scard: string,
351
+ pythProUpdateBytes: Uint8Array | number[],
352
+ isLimitOrder?: boolean,
353
+ isIocOrder?: boolean,
354
+ pricesSlippage?: number,
355
+ collateralSlippage?: number,
356
+ relayerFee?: bigint,
357
+ referralAddress?: string,
358
+ sender?: string,
359
+ sponsoredTx?: boolean,
360
+ ) => Promise<Transaction>
361
+
362
+ openPositionWithCoinV3: (
363
+ collateralToken: string,
364
+ indexToken: string,
365
+ size: bigint,
366
+ coinObj: TransactionObjectArgument,
367
+ long: boolean,
368
+ reserveAmount: bigint,
369
+ indexPrice: number,
370
+ collateralPrice: number,
371
+ pythProUpdateBytes: Uint8Array | number[],
372
+ isLimitOrder?: boolean,
373
+ isIocOrder?: boolean,
374
+ pricesSlippage?: number,
375
+ collateralSlippage?: number,
376
+ relayerFee?: bigint,
377
+ referralAddress?: string,
378
+ sender?: string,
379
+ tx?: Transaction,
380
+ sponsoredTx?: boolean,
381
+ ) => Promise<Transaction>
382
+
383
+ openPositionWithCoinAndSCardV3: (
384
+ collateralToken: string,
385
+ indexToken: string,
386
+ size: bigint,
387
+ coinObj: TransactionObjectArgument,
388
+ long: boolean,
389
+ reserveAmount: bigint,
390
+ indexPrice: number,
391
+ collateralPrice: number,
392
+ kioskClient: KioskClient,
393
+ kioskCap: KioskOwnerCap,
394
+ scard: string,
395
+ pythProUpdateBytes: Uint8Array | number[],
396
+ isLimitOrder?: boolean,
397
+ isIocOrder?: boolean,
398
+ pricesSlippage?: number,
399
+ collateralSlippage?: number,
400
+ relayerFee?: bigint,
401
+ referralAddress?: string,
402
+ sender?: string,
403
+ tx?: Transaction,
404
+ sponsoredTx?: boolean,
405
+ ) => Promise<Transaction>
406
+
407
+ decreasePositionV3: (
408
+ pcpId: string,
409
+ collateralToken: string,
410
+ indexToken: string,
411
+ amount: bigint,
412
+ long: boolean,
413
+ indexPrice: number,
414
+ collateralPrice: number,
415
+ pythProUpdateBytes: Uint8Array | number[],
416
+ isTriggerOrder?: boolean,
417
+ isTakeProfitOrder?: boolean,
418
+ isIocOrder?: boolean,
419
+ pricesSlippage?: number,
420
+ collateralSlippage?: number,
421
+ relayerFee?: bigint,
422
+ coinObjects?: string[],
423
+ sponsoredTx?: boolean,
424
+ sender?: string,
425
+ ) => Promise<Transaction>
426
+
427
+ decreasePositionWithSCardV3: (
428
+ pcpId: string,
429
+ collateralToken: string,
430
+ indexToken: string,
431
+ amount: bigint,
432
+ long: boolean,
433
+ indexPrice: number,
434
+ collateralPrice: number,
435
+ kioskClient: KioskClient,
436
+ kioskCap: KioskOwnerCap,
437
+ scard: string,
438
+ pythProUpdateBytes: Uint8Array | number[],
439
+ isTriggerOrder?: boolean,
440
+ isTakeProfitOrder?: boolean,
441
+ isIocOrder?: boolean,
442
+ pricesSlippage?: number,
443
+ collateralSlippage?: number,
444
+ relayerFee?: bigint,
445
+ coinObjects?: string[],
446
+ sponsoredTx?: boolean,
447
+ sender?: string,
448
+ ) => Promise<Transaction>
449
+
450
+ redeemFromPositionV3: (
451
+ pcpId: string,
452
+ collateralToken: string,
453
+ indexToken: string,
454
+ amount: number,
455
+ long: boolean,
456
+ pythProUpdateBytes: Uint8Array | number[],
457
+ tx?: Transaction,
458
+ ) => Promise<Transaction>
289
459
  }
package/src/oraclePro.ts CHANGED
@@ -60,6 +60,44 @@ export function requireOracleProConfig(network: Network): IOracleProConfig {
60
60
  return buildOracleProConfig(getZoOracleConfig(network))
61
61
  }
62
62
 
63
+ /**
64
+ * LST SUI vault tokens priced on-chain via Pyth Lazer RR feed × SUI/USD.
65
+ * Numeric ids are Pyth Lazer `priceFeedIds` (not Hermes price ids).
66
+ */
67
+ export const LST_SUI_PYTH_LAZER_RR_FEED_IDS: Record<string, number> = {
68
+ afSui: 3245,
69
+ stSui: 736,
70
+ vSui: 2349,
71
+ haSui: 3244,
72
+ }
73
+
74
+ const LST_SUI_TOKENS = new Set(Object.keys(LST_SUI_PYTH_LAZER_RR_FEED_IDS))
75
+
76
+ function lookupLazerFeedIdForToken(
77
+ token: string,
78
+ zoOracle: IZoOracleConfig,
79
+ coins: Record<string, { module: string }>,
80
+ network: Network,
81
+ coinModuleMap: Map<string, number>,
82
+ legacyFeeders?: Record<string, string>,
83
+ ): number | undefined {
84
+ const module = coins[token]?.module
85
+ if (!module) {
86
+ return undefined
87
+ }
88
+
89
+ let lazerId = coinModuleMap.get(normalizeCoinType(module))
90
+
91
+ if (lazerId === undefined && legacyFeeders?.[token]) {
92
+ const priceId = getPythFeederToPriceId(network)[legacyFeeders[token]]
93
+ if (priceId) {
94
+ lazerId = zoOracle.pythLazer.feedIds[priceId]
95
+ }
96
+ }
97
+
98
+ return lazerId
99
+ }
100
+
63
101
  /**
64
102
  * Build coin module -> Lazer feed id using zo_oracle symbol configs + Hermes price id map.
65
103
  */
@@ -93,9 +131,7 @@ export function resolveLazerFeedIds(
93
131
  network: Network,
94
132
  legacyFeeders?: Record<string, string>,
95
133
  ): number[] {
96
- const { pythLazer } = zoOracle
97
- const coinModuleMap = buildCoinModuleToLazerFeedId(pythLazer, zoOracle, network)
98
- const feederToPriceId = getPythFeederToPriceId(network)
134
+ const coinModuleMap = buildCoinModuleToLazerFeedId(zoOracle.pythLazer, zoOracle, network)
99
135
 
100
136
  const ids = new Set<number>()
101
137
  for (const token of tokens) {
@@ -104,15 +140,32 @@ export function resolveLazerFeedIds(
104
140
  throw new Error(`Unknown token: ${token}`)
105
141
  }
106
142
 
107
- let lazerId = coinModuleMap.get(normalizeCoinType(module))
108
-
109
- if (lazerId === undefined && legacyFeeders?.[token]) {
110
- const priceId = feederToPriceId[legacyFeeders[token]]
111
- if (priceId) {
112
- lazerId = pythLazer.feedIds[priceId]
143
+ if (LST_SUI_TOKENS.has(token)) {
144
+ ids.add(LST_SUI_PYTH_LAZER_RR_FEED_IDS[token])
145
+ const suiLazerId = lookupLazerFeedIdForToken(
146
+ 'sui',
147
+ zoOracle,
148
+ coins,
149
+ network,
150
+ coinModuleMap,
151
+ legacyFeeders,
152
+ )
153
+ if (suiLazerId === undefined) {
154
+ throw new Error(`No Pyth Lazer feed id for SUI (required for LST token "${token}")`)
113
155
  }
156
+ ids.add(suiLazerId)
157
+ continue
114
158
  }
115
159
 
160
+ const lazerId = lookupLazerFeedIdForToken(
161
+ token,
162
+ zoOracle,
163
+ coins,
164
+ network,
165
+ coinModuleMap,
166
+ legacyFeeders,
167
+ )
168
+
116
169
  if (lazerId === undefined) {
117
170
  throw new Error(`No Pyth Lazer feed id for token "${token}" (${module})`)
118
171
  }
@@ -212,6 +265,11 @@ export function oracleArgsAlt(oracle: OracleInputsAlt): TransactionObjectArgumen
212
265
  return [oracle.oracleRegistry, oracle.storkState, oracle.pythProUpdate]
213
266
  }
214
267
 
268
+ /** Sudo-core valuation/swap order: `[oracleRegistry, pythProUpdate, storkState, clock]`. */
269
+ export function oracleArgsRegistryFirst(oracle: OracleInputs): TransactionObjectArgument[] {
270
+ return [oracle.oracleRegistry, oracle.pythProUpdate, oracle.storkState, oracle.clock]
271
+ }
272
+
215
273
  export function buildOracleInputsAlt(oracle: OracleInputs): OracleInputsAlt {
216
274
  return {
217
275
  oracleRegistry: oracle.oracleRegistry,
@@ -312,3 +370,83 @@ export function valuateSymbolsV2(params: IValuateSymbolsV2Params): TransactionOb
312
370
 
313
371
  return symbolsValuation
314
372
  }
373
+
374
+ export interface IValuateVaultsV3Params {
375
+ tx: Transaction
376
+ upgradedPackage: string
377
+ lpType: string
378
+ market: string
379
+ vaults: Record<string, { reservingFeeModel: string }>
380
+ coinModules: Record<string, { module: string }>
381
+ oracle: OracleInputs
382
+ }
383
+
384
+ /** create_vaults_valuation + valuate_vault_v3 for each vault (sudo-core). */
385
+ export function valuateVaultsV3(params: IValuateVaultsV3Params): TransactionObjectArgument {
386
+ const { tx, upgradedPackage, lpType, market, vaults, coinModules, oracle } = params
387
+
388
+ const vaultsValuation = tx.moveCall({
389
+ target: `${upgradedPackage}::market::create_vaults_valuation`,
390
+ typeArguments: [lpType],
391
+ arguments: [oracle.clock, tx.object(market)],
392
+ })
393
+
394
+ for (const key of Object.keys(vaults)) {
395
+ const vault = vaults[key]
396
+ tx.moveCall({
397
+ target: `${upgradedPackage}::market::valuate_vault_v3`,
398
+ typeArguments: [lpType, coinModules[key].module],
399
+ arguments: [
400
+ tx.object(market),
401
+ tx.object(vault.reservingFeeModel),
402
+ ...oracleArgsRegistryFirst(oracle),
403
+ vaultsValuation,
404
+ ],
405
+ })
406
+ }
407
+
408
+ return vaultsValuation
409
+ }
410
+
411
+ export interface IValuateSymbolsV3Params {
412
+ tx: Transaction
413
+ upgradedPackage: string
414
+ marketPackage: string
415
+ lpType: string
416
+ market: string
417
+ symbols: Record<string, { fundingFeeModel: string }>
418
+ coinModules: Record<string, { module: string }>
419
+ oracle: OracleInputs
420
+ }
421
+
422
+ /** create_symbols_valuation + valuate_symbol_v3 for each symbol (sudo-core). */
423
+ export function valuateSymbolsV3(params: IValuateSymbolsV3Params): TransactionObjectArgument {
424
+ const { tx, upgradedPackage, marketPackage, lpType, market, symbols, coinModules, oracle } = params
425
+
426
+ const symbolsValuation = tx.moveCall({
427
+ target: `${upgradedPackage}::market::create_symbols_valuation`,
428
+ typeArguments: [lpType],
429
+ arguments: [oracle.clock, tx.object(market)],
430
+ })
431
+
432
+ for (const key of Object.keys(symbols)) {
433
+ const [direction, token] = parseSymbolKey(key)
434
+ const symbol = symbols[key]
435
+ tx.moveCall({
436
+ target: `${upgradedPackage}::market::valuate_symbol_v3`,
437
+ typeArguments: [
438
+ lpType,
439
+ coinModules[token].module,
440
+ `${marketPackage}::market::${direction.toUpperCase()}`,
441
+ ],
442
+ arguments: [
443
+ tx.object(market),
444
+ tx.object(symbol.fundingFeeModel),
445
+ ...oracleArgsRegistryFirst(oracle),
446
+ symbolsValuation,
447
+ ],
448
+ })
449
+ }
450
+
451
+ return symbolsValuation
452
+ }