@zofai/zo-sdk 0.2.29 → 0.2.31

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 (103) hide show
  1. package/dist/abstract/BaseAPI.cjs +3 -0
  2. package/dist/abstract/BaseAPI.cjs.map +1 -1
  3. package/dist/abstract/BaseAPI.d.cts +3 -2
  4. package/dist/abstract/BaseAPI.d.cts.map +1 -1
  5. package/dist/abstract/BaseAPI.d.mts +3 -2
  6. package/dist/abstract/BaseAPI.d.mts.map +1 -1
  7. package/dist/abstract/BaseAPI.mjs +3 -0
  8. package/dist/abstract/BaseAPI.mjs.map +1 -1
  9. package/dist/abstract/BaseDataAPI.cjs +48 -2
  10. package/dist/abstract/BaseDataAPI.cjs.map +1 -1
  11. package/dist/abstract/BaseDataAPI.d.cts +15 -2
  12. package/dist/abstract/BaseDataAPI.d.cts.map +1 -1
  13. package/dist/abstract/BaseDataAPI.d.mts +15 -2
  14. package/dist/abstract/BaseDataAPI.d.mts.map +1 -1
  15. package/dist/abstract/BaseDataAPI.mjs +48 -2
  16. package/dist/abstract/BaseDataAPI.mjs.map +1 -1
  17. package/dist/consts/deployments-zlp-mainnet.json +1 -1
  18. package/dist/consts/deployments-zo-oracle-mainnet.json +18 -1
  19. package/dist/data.cjs +19 -7
  20. package/dist/data.cjs.map +1 -1
  21. package/dist/data.d.cts.map +1 -1
  22. package/dist/data.d.mts.map +1 -1
  23. package/dist/data.mjs +19 -7
  24. package/dist/data.mjs.map +1 -1
  25. package/dist/implementations/SLPDataAPI.cjs +26 -8
  26. package/dist/implementations/SLPDataAPI.cjs.map +1 -1
  27. package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
  28. package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
  29. package/dist/implementations/SLPDataAPI.mjs +26 -8
  30. package/dist/implementations/SLPDataAPI.mjs.map +1 -1
  31. package/dist/implementations/USDZDataAPI.cjs +26 -8
  32. package/dist/implementations/USDZDataAPI.cjs.map +1 -1
  33. package/dist/implementations/USDZDataAPI.d.cts.map +1 -1
  34. package/dist/implementations/USDZDataAPI.d.mts.map +1 -1
  35. package/dist/implementations/USDZDataAPI.mjs +26 -8
  36. package/dist/implementations/USDZDataAPI.mjs.map +1 -1
  37. package/dist/implementations/ZBTCVCDataAPI.cjs +19 -7
  38. package/dist/implementations/ZBTCVCDataAPI.cjs.map +1 -1
  39. package/dist/implementations/ZBTCVCDataAPI.d.cts.map +1 -1
  40. package/dist/implementations/ZBTCVCDataAPI.d.mts.map +1 -1
  41. package/dist/implementations/ZBTCVCDataAPI.mjs +19 -7
  42. package/dist/implementations/ZBTCVCDataAPI.mjs.map +1 -1
  43. package/dist/implementations/ZLPAPI.cjs +456 -123
  44. package/dist/implementations/ZLPAPI.cjs.map +1 -1
  45. package/dist/implementations/ZLPAPI.d.cts +46 -1
  46. package/dist/implementations/ZLPAPI.d.cts.map +1 -1
  47. package/dist/implementations/ZLPAPI.d.mts +46 -1
  48. package/dist/implementations/ZLPAPI.d.mts.map +1 -1
  49. package/dist/implementations/ZLPAPI.mjs +457 -124
  50. package/dist/implementations/ZLPAPI.mjs.map +1 -1
  51. package/dist/implementations/ZLPDataAPI.cjs +64 -8
  52. package/dist/implementations/ZLPDataAPI.cjs.map +1 -1
  53. package/dist/implementations/ZLPDataAPI.d.cts +16 -0
  54. package/dist/implementations/ZLPDataAPI.d.cts.map +1 -1
  55. package/dist/implementations/ZLPDataAPI.d.mts +16 -0
  56. package/dist/implementations/ZLPDataAPI.d.mts.map +1 -1
  57. package/dist/implementations/ZLPDataAPI.mjs +64 -8
  58. package/dist/implementations/ZLPDataAPI.mjs.map +1 -1
  59. package/dist/index.cjs +1 -0
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +2 -0
  62. package/dist/index.d.cts.map +1 -1
  63. package/dist/index.d.mts +2 -0
  64. package/dist/index.d.mts.map +1 -1
  65. package/dist/index.mjs +1 -0
  66. package/dist/index.mjs.map +1 -1
  67. package/dist/interfaces/base.d.cts +14 -1
  68. package/dist/interfaces/base.d.cts.map +1 -1
  69. package/dist/interfaces/base.d.mts +14 -1
  70. package/dist/interfaces/base.d.mts.map +1 -1
  71. package/dist/interfaces/zlp.d.cts +19 -0
  72. package/dist/interfaces/zlp.d.cts.map +1 -1
  73. package/dist/interfaces/zlp.d.mts +19 -0
  74. package/dist/interfaces/zlp.d.mts.map +1 -1
  75. package/dist/traderPositions.cjs +130 -0
  76. package/dist/traderPositions.cjs.map +1 -0
  77. package/dist/traderPositions.d.cts +72 -0
  78. package/dist/traderPositions.d.cts.map +1 -0
  79. package/dist/traderPositions.d.mts +72 -0
  80. package/dist/traderPositions.d.mts.map +1 -0
  81. package/dist/traderPositions.mjs +124 -0
  82. package/dist/traderPositions.mjs.map +1 -0
  83. package/docs/api-reference.md +45 -0
  84. package/docs/architecture.md +21 -3
  85. package/docs/common-operations.md +56 -8
  86. package/docs/getting-started.md +8 -3
  87. package/docs/lp-specific-features.md +89 -12
  88. package/docs/swap-integration.md +52 -20
  89. package/package.json +1 -1
  90. package/src/abstract/BaseAPI.ts +6 -2
  91. package/src/abstract/BaseDataAPI.ts +67 -3
  92. package/src/consts/deployments-zlp-mainnet.json +1 -1
  93. package/src/consts/deployments-zo-oracle-mainnet.json +18 -1
  94. package/src/data.ts +19 -7
  95. package/src/implementations/SLPDataAPI.ts +34 -16
  96. package/src/implementations/USDZDataAPI.ts +32 -14
  97. package/src/implementations/ZBTCVCDataAPI.ts +23 -11
  98. package/src/implementations/ZLPAPI.ts +760 -151
  99. package/src/implementations/ZLPDataAPI.ts +79 -14
  100. package/src/index.ts +2 -0
  101. package/src/interfaces/base.ts +15 -1
  102. package/src/interfaces/zlp.ts +170 -0
  103. package/src/traderPositions.ts +218 -0
@@ -10,6 +10,7 @@ import { Transaction } from '@mysten/sui/transactions'
10
10
  import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils'
11
11
 
12
12
  import { BaseAPI } from '../abstract'
13
+ import { resolveSpendableSuiCoin } from '../coins'
13
14
  import type { Network } from '../consts'
14
15
  import { ALLOW_TRADE_CAN_TRADE, ALLOW_TRADE_MUST_TRADE, ALLOW_TRADE_NO_TRADE, LPToken } from '../consts'
15
16
  import type {
@@ -17,8 +18,11 @@ import type {
17
18
  IZLPAPI,
18
19
  IZLPCredential,
19
20
  } from '../interfaces'
21
+ import type { IInitPythProOracleOptions } from '../oracle'
22
+ import type { OracleInputs } from '../oraclePro'
23
+ import { oracleArgsStandard } from '../oraclePro'
20
24
  import type { SuiClient } from '../suiClient'
21
- import { joinSymbol } from '../utils'
25
+ import { joinSymbol, parseSymbolKey } from '../utils'
22
26
  import { ZLPDataAPI } from './ZLPDataAPI'
23
27
 
24
28
  export class ZLPAPI extends BaseAPI implements IZLPAPI {
@@ -34,6 +38,85 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
34
38
  this.dataAPI = new ZLPDataAPI(network, provider, apiEndpoint, connectionURL)
35
39
  }
36
40
 
41
+ private zlpLpType(): string {
42
+ return `${this.consts.zoCore.package}::zlp::ZLP`
43
+ }
44
+
45
+ private positionTypeArgs(collateralToken: string, indexToken: string, long: boolean): string[] {
46
+ return [
47
+ this.zlpLpType(),
48
+ this.consts.coins[collateralToken].module,
49
+ this.consts.coins[indexToken].module,
50
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
51
+ this.consts.coins[collateralToken].module,
52
+ ]
53
+ }
54
+
55
+ private redeemTypeArgs(collateralToken: string, indexToken: string, long: boolean): string[] {
56
+ return [
57
+ this.zlpLpType(),
58
+ this.consts.coins[collateralToken].module,
59
+ this.consts.coins[indexToken].module,
60
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
61
+ ]
62
+ }
63
+
64
+ private async initV3OracleForTokens(
65
+ tokens: string[],
66
+ tx: Transaction,
67
+ pythProUpdateBytes: Uint8Array | number[],
68
+ includeEmaPrice?: boolean,
69
+ options?: Pick<IInitPythProOracleOptions, 'storkUpdateData' | 'skipStork' | 'storkFeeSource' | 'kronosUrl'>,
70
+ ): Promise<{ tx: Transaction, oracle: OracleInputs }> {
71
+ const result = await this.initV3OracleTxb(tokens, tx, {
72
+ rawUpdateBytes: pythProUpdateBytes,
73
+ includeEmaPrice,
74
+ ...options,
75
+ })
76
+ return { tx: result.tx, oracle: result.oracle }
77
+ }
78
+
79
+ /** Vault + symbol index tokens required for valuate_vault_v2 / valuate_symbol_v2. */
80
+ private getValuationOracleTokens(): string[] {
81
+ const tokens = new Set(Object.keys(this.consts.zoCore.vaults))
82
+ for (const key of Object.keys(this.consts.zoCore.symbols)) {
83
+ const [, token] = parseSymbolKey(key)
84
+ tokens.add(token)
85
+ }
86
+ return [...tokens]
87
+ }
88
+
89
+ /** Pyth Pro oracle init for deposit / withdraw market valuation. */
90
+ private async initValuationOracle(
91
+ tx: Transaction,
92
+ ): Promise<{ tx: Transaction, oracle: OracleInputs }> {
93
+ const tokens = this.getValuationOracleTokens()
94
+ const pythProUpdateBytes = await this.fetchPythProUpdateBytesForTokens(tokens)
95
+ return this.initV3OracleForTokens(tokens, tx, pythProUpdateBytes)
96
+ }
97
+
98
+ private async resolveSponsoredSui(
99
+ tx: Transaction,
100
+ collateralToken: string,
101
+ relayerFee: bigint,
102
+ sponsoredTx?: boolean,
103
+ sender?: string,
104
+ ): Promise<TransactionObjectArgument | undefined> {
105
+ if (!sponsoredTx) {
106
+ return undefined
107
+ }
108
+ const additional = collateralToken === 'sui' ? relayerFee : 0n
109
+ if (additional === 0n) {
110
+ return undefined
111
+ }
112
+ return resolveSpendableSuiCoin(
113
+ tx,
114
+ this.provider,
115
+ this.requireSenderForSponsored(sender),
116
+ additional,
117
+ )
118
+ }
119
+
37
120
  public calcPositionReserveFeeAmount(_position: IBasePositionInfo): Promise<number> {
38
121
  throw new Error(`Method not implemented in ${this.constructor.name}.`)
39
122
  }
@@ -61,53 +144,18 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
61
144
  tx = await this.addReferral(referralAddress, tx)
62
145
  }
63
146
 
64
- // Initialize oracle transaction
65
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
66
-
67
- // Handle sponsored transaction case
68
- if (sponsoredTx) {
69
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
70
- sender: this.requireSenderForSponsored(sender),
71
- additionalSuiAmount: coin === 'sui' ? BigInt(amount) : 0n,
72
- })
73
- tx = oracle.tx
74
-
75
- const depositObject = await this.resolveSplitCoinObject(
76
- tx,
77
- coin,
78
- BigInt(amount),
79
- coinObjects,
80
- { sponsoredTx: true, suiCoinObject: oracle.suiCoinObject, sender },
81
- )
82
-
83
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
84
-
85
- tx.moveCall({
86
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
87
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
88
- arguments: [
89
- tx.object(this.consts.zoCore.market),
90
- tx.object(this.consts.zoCore.rebaseFeeModel),
91
- depositObject,
92
- tx.pure.u64(minAmountOut),
93
- vaultsValuation,
94
- symbolsValuation,
95
- ],
96
- })
97
- return tx
98
- }
147
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
148
+ tx = txWithOracle
99
149
 
100
- // Handle non-sponsored transaction case
101
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
102
150
  const depositObject = await this.resolveSplitCoinObject(
103
151
  tx,
104
152
  coin,
105
153
  BigInt(amount),
106
154
  coinObjects,
107
- { sender },
155
+ { sponsoredTx, sender },
108
156
  )
109
157
 
110
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
158
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
111
159
 
112
160
  tx.moveCall({
113
161
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
@@ -149,53 +197,18 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
149
197
  tx = await this.addReferral(referralAddress, tx)
150
198
  }
151
199
 
152
- // Initialize oracle transaction
153
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
154
-
155
- // Handle sponsored transaction case
156
- if (sponsoredTx) {
157
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
158
- sender: this.requireSenderForSponsored(sender),
159
- additionalSuiAmount: coin === 'sui' ? BigInt(amount) : 0n,
160
- })
161
- tx = oracle.tx
162
-
163
- const depositObject = await this.resolveSplitCoinObject(
164
- tx,
165
- coin,
166
- BigInt(amount),
167
- coinObjects,
168
- { sponsoredTx: true, suiCoinObject: oracle.suiCoinObject, sender },
169
- )
170
-
171
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
172
-
173
- const [mintedCoin] = tx.moveCall({
174
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
175
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
176
- arguments: [
177
- tx.object(this.consts.zoCore.market),
178
- tx.object(this.consts.zoCore.rebaseFeeModel),
179
- depositObject,
180
- tx.pure.u64(minAmountOut),
181
- vaultsValuation,
182
- symbolsValuation,
183
- ],
184
- })
185
- return mintedCoin
186
- }
200
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
201
+ tx = txWithOracle
187
202
 
188
- // Handle non-sponsored transaction case
189
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
190
203
  const depositObject = await this.resolveSplitCoinObject(
191
204
  tx,
192
205
  coin,
193
206
  BigInt(amount),
194
207
  coinObjects,
195
- { sender },
208
+ { sponsoredTx, sender },
196
209
  )
197
210
 
198
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
211
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
199
212
 
200
213
  const [mintedCoin] = tx.moveCall({
201
214
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
@@ -223,7 +236,7 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
223
236
  referralAddress?: string,
224
237
  sender?: string,
225
238
  tx?: Transaction,
226
- sponsoredTx?: boolean,
239
+ _sponsoredTx?: boolean,
227
240
  ): Promise<Transaction> {
228
241
  if (!tx) {
229
242
  tx = new Transaction()
@@ -234,39 +247,10 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
234
247
  tx = await this.addReferral(referralAddress, tx)
235
248
  }
236
249
 
237
- // Initialize oracle transaction
238
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
239
-
240
- // Handle sponsored transaction case
241
- if (sponsoredTx) {
242
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
243
- sender: this.requireSenderForSponsored(sender),
244
- additionalSuiAmount: 0n,
245
- })
246
- tx = oracle.tx
247
- const { suiCoinObject } = oracle
248
-
249
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
250
-
251
- tx.moveCall({
252
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
253
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
254
- arguments: [
255
- tx.object(this.consts.zoCore.market),
256
- tx.object(this.consts.zoCore.rebaseFeeModel),
257
- depositObject,
258
- tx.pure.u64(minAmountOut),
259
- vaultsValuation,
260
- symbolsValuation,
261
- ],
262
- })
263
- return tx
264
- }
265
-
266
- // Handle non-sponsored transaction case
267
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
250
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
251
+ tx = txWithOracle
268
252
 
269
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
253
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
270
254
 
271
255
  tx.moveCall({
272
256
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
@@ -303,30 +287,17 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
303
287
 
304
288
  let tx = new Transaction()
305
289
 
306
- // Initialize oracle transaction
307
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
308
-
309
- let suiCoinObject
310
- if (sponsoredTx) {
311
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
312
- sender: this.requireSenderForSponsored(sender),
313
- additionalSuiAmount: 0n,
314
- })
315
- tx = oracle.tx
316
- suiCoinObject = oracle.suiCoinObject
317
- }
318
- else {
319
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
320
- }
290
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
291
+ tx = txWithOracle
321
292
 
322
293
  const withdrawObject = await this.resolveSplitCoinObject(
323
294
  tx,
324
295
  'zlp',
325
296
  BigInt(amount),
326
297
  lpCoinObjects,
327
- { sponsoredTx, suiCoinObject, sender },
298
+ { sponsoredTx, sender },
328
299
  )
329
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
300
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
330
301
 
331
302
  tx.moveCall({
332
303
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
@@ -358,11 +329,9 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
358
329
  if (!tx) {
359
330
  tx = new Transaction()
360
331
  }
361
- // Initialize oracle transaction
362
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
363
-
364
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
365
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
332
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
333
+ tx = txWithOracle
334
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
366
335
 
367
336
  tx.moveCall({
368
337
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
@@ -399,30 +368,17 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
399
368
  tx = new Transaction()
400
369
  }
401
370
 
402
- // Initialize oracle transaction
403
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
404
-
405
- let suiCoinObject
406
- if (sponsoredTx) {
407
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
408
- sender: this.requireSenderForSponsored(sender),
409
- additionalSuiAmount: 0n,
410
- })
411
- tx = oracle.tx
412
- suiCoinObject = oracle.suiCoinObject
413
- }
414
- else {
415
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
416
- }
371
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx)
372
+ tx = txWithOracle
417
373
 
418
374
  const withdrawObject = await this.resolveSplitCoinObject(
419
375
  tx,
420
376
  'zlp',
421
377
  BigInt(amount),
422
378
  lpCoinObjects,
423
- { sponsoredTx, suiCoinObject, sender },
379
+ { sponsoredTx, sender },
424
380
  )
425
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
381
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle)
426
382
 
427
383
  const [withdrawCoin] = tx.moveCall({
428
384
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw_ptb`,
@@ -3058,4 +3014,657 @@ export class ZLPAPI extends BaseAPI implements IZLPAPI {
3058
3014
 
3059
3015
  return tx
3060
3016
  }
3017
+
3018
+ // --- Pyth Pro + Stork (v3) ---
3019
+
3020
+ /**
3021
+ * Swaps tokens using swap_v3 (Pyth Pro + Stork). Transfers output to sender.
3022
+ */
3023
+ public async swapV3(
3024
+ fromToken: string,
3025
+ toToken: string,
3026
+ fromAmount: bigint,
3027
+ fromCoinObjects: string[],
3028
+ pythProUpdateBytes: Uint8Array | number[],
3029
+ minAmountOut?: number,
3030
+ tx?: Transaction,
3031
+ ): Promise<Transaction> {
3032
+ if (!tx) {
3033
+ tx = new Transaction()
3034
+ }
3035
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3036
+ Object.keys(this.consts.zoCore.vaults),
3037
+ tx,
3038
+ pythProUpdateBytes,
3039
+ true,
3040
+ )
3041
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects)
3042
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)])
3043
+ const vaultsValuation = this.dataAPI.valuateVaultsV2(tx_, oracle)
3044
+
3045
+ tx_.moveCall({
3046
+ target: `${this.consts.zoCore.upgradedPackage}::market::swap_v3`,
3047
+ typeArguments: [
3048
+ this.zlpLpType(),
3049
+ this.consts.coins[fromToken].module,
3050
+ this.consts.coins[toToken].module,
3051
+ ],
3052
+ arguments: [
3053
+ tx_.object(this.consts.zoCore.market),
3054
+ tx_.object(this.consts.zoCore.rebaseFeeModel),
3055
+ fromDepositObject,
3056
+ tx_.pure.u64(minAmountOut || 0),
3057
+ vaultsValuation,
3058
+ ...oracleArgsStandard(oracle),
3059
+ ],
3060
+ })
3061
+ return tx_
3062
+ }
3063
+
3064
+ /**
3065
+ * Swaps tokens and returns the output coin (swap_v3_ptb).
3066
+ */
3067
+ public async swapV3Ptb(
3068
+ fromToken: string,
3069
+ toToken: string,
3070
+ fromAmount: bigint,
3071
+ fromCoinObjects: string[],
3072
+ pythProUpdateBytes: Uint8Array | number[],
3073
+ minAmountOut?: number,
3074
+ tx?: Transaction,
3075
+ ): Promise<TransactionObjectArgument> {
3076
+ if (!tx) {
3077
+ tx = new Transaction()
3078
+ }
3079
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3080
+ Object.keys(this.consts.zoCore.vaults),
3081
+ tx,
3082
+ pythProUpdateBytes,
3083
+ true,
3084
+ )
3085
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects)
3086
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)])
3087
+ const vaultsValuation = this.dataAPI.valuateVaultsV2(tx_, oracle)
3088
+
3089
+ const [outputCoin] = tx_.moveCall({
3090
+ target: `${this.consts.zoCore.upgradedPackage}::market::swap_v3_ptb`,
3091
+ typeArguments: [
3092
+ this.zlpLpType(),
3093
+ this.consts.coins[fromToken].module,
3094
+ this.consts.coins[toToken].module,
3095
+ ],
3096
+ arguments: [
3097
+ tx_.object(this.consts.zoCore.market),
3098
+ tx_.object(this.consts.zoCore.rebaseFeeModel),
3099
+ fromDepositObject,
3100
+ tx_.pure.u64(minAmountOut || 0),
3101
+ vaultsValuation,
3102
+ ...oracleArgsStandard(oracle),
3103
+ ],
3104
+ })
3105
+ return outputCoin
3106
+ }
3107
+
3108
+ /**
3109
+ * Opens a position using open_position_v3 (Pyth Pro + Stork).
3110
+ */
3111
+ public async openPositionV3(
3112
+ collateralToken: string,
3113
+ indexToken: string,
3114
+ size: bigint,
3115
+ collateralAmount: bigint,
3116
+ coinObjects: string[],
3117
+ long: boolean,
3118
+ reserveAmount: bigint,
3119
+ indexPrice: number,
3120
+ collateralPrice: number,
3121
+ pythProUpdateBytes: Uint8Array | number[],
3122
+ isLimitOrder?: boolean,
3123
+ isIocOrder?: boolean,
3124
+ pricesSlippage = 0.003,
3125
+ collateralSlippage = 0.5,
3126
+ relayerFee = BigInt(0.5),
3127
+ referralAddress?: string,
3128
+ sender?: string,
3129
+ sponsoredTx?: boolean,
3130
+ ): Promise<Transaction> {
3131
+ let tx = new Transaction()
3132
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3133
+ tx = await this.addReferral(referralAddress, tx)
3134
+ }
3135
+
3136
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3137
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3138
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3139
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3140
+
3141
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3142
+ if (isLimitOrder) {
3143
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3144
+ }
3145
+
3146
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3147
+ [collateralToken, indexToken],
3148
+ tx,
3149
+ pythProUpdateBytes,
3150
+ )
3151
+ tx = tx_
3152
+
3153
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3154
+ const [depositObject, feeObject] = this.processCoinSplitting(
3155
+ tx,
3156
+ collateralToken,
3157
+ coinObjects,
3158
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
3159
+ sponsoredTx,
3160
+ suiCoinObject,
3161
+ )
3162
+
3163
+ tx.moveCall({
3164
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v3`,
3165
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3166
+ arguments: [
3167
+ tx.object(SUI_CLOCK_OBJECT_ID),
3168
+ tx.object(this.consts.zoCore.market),
3169
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
3170
+ ...oracleArgsStandard(oracle),
3171
+ depositObject,
3172
+ feeObject,
3173
+ tx.pure.u8(allowTrade),
3174
+ tx.pure.u64(size),
3175
+ tx.pure.u64(reserveAmount),
3176
+ tx.pure.u256(adjustCollateralPrice),
3177
+ tx.pure.u256(adjustPrice),
3178
+ tx.pure.u256(indexPriceThreshold),
3179
+ ],
3180
+ })
3181
+
3182
+ return tx
3183
+ }
3184
+
3185
+ /**
3186
+ * Opens a position with S Card using open_position_with_scard_v3.
3187
+ */
3188
+ public async openPositionWithSCardV3(
3189
+ collateralToken: string,
3190
+ indexToken: string,
3191
+ size: bigint,
3192
+ collateralAmount: bigint,
3193
+ coinObjects: string[],
3194
+ long: boolean,
3195
+ reserveAmount: bigint,
3196
+ indexPrice: number,
3197
+ collateralPrice: number,
3198
+ kioskClient: KioskClient,
3199
+ kioskCap: KioskOwnerCap,
3200
+ scard: string,
3201
+ pythProUpdateBytes: Uint8Array | number[],
3202
+ isLimitOrder?: boolean,
3203
+ isIocOrder?: boolean,
3204
+ pricesSlippage = 0.003,
3205
+ collateralSlippage = 0.5,
3206
+ relayerFee = BigInt(0.5),
3207
+ referralAddress?: string,
3208
+ sender?: string,
3209
+ sponsoredTx?: boolean,
3210
+ ): Promise<Transaction> {
3211
+ let tx = new Transaction()
3212
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3213
+ tx = await this.addReferral(referralAddress, tx)
3214
+ }
3215
+
3216
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3217
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3218
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3219
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3220
+
3221
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3222
+ if (isLimitOrder) {
3223
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3224
+ }
3225
+
3226
+ const kioskTx = new KioskTransaction({
3227
+ transaction: tx,
3228
+ kioskClient,
3229
+ cap: kioskCap,
3230
+ })
3231
+
3232
+ const [sudoCard, promise] = kioskTx.borrow({
3233
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3234
+ itemId: scard,
3235
+ })
3236
+
3237
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3238
+ [collateralToken, indexToken],
3239
+ tx,
3240
+ pythProUpdateBytes,
3241
+ )
3242
+ tx = tx_
3243
+
3244
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3245
+ const [depositObject, feeObject] = this.processCoinSplitting(
3246
+ tx,
3247
+ collateralToken,
3248
+ coinObjects,
3249
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
3250
+ sponsoredTx,
3251
+ suiCoinObject,
3252
+ )
3253
+
3254
+ tx.moveCall({
3255
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v3`,
3256
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3257
+ arguments: [
3258
+ tx.object(SUI_CLOCK_OBJECT_ID),
3259
+ tx.object(this.consts.zoCore.market),
3260
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
3261
+ ...oracleArgsStandard(oracle),
3262
+ depositObject,
3263
+ feeObject,
3264
+ tx.pure.u8(allowTrade),
3265
+ tx.pure.u64(size),
3266
+ tx.pure.u64(reserveAmount),
3267
+ tx.pure.u256(adjustCollateralPrice),
3268
+ tx.pure.u256(adjustPrice),
3269
+ tx.pure.u256(indexPriceThreshold),
3270
+ sudoCard,
3271
+ ],
3272
+ })
3273
+
3274
+ kioskTx
3275
+ .return({
3276
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3277
+ item: sudoCard,
3278
+ promise,
3279
+ })
3280
+ .finalize()
3281
+
3282
+ return tx
3283
+ }
3284
+
3285
+ /**
3286
+ * Opens a position with a pre-composed collateral coin using open_position_v3 (Pyth Pro + Stork).
3287
+ */
3288
+ public async openPositionWithCoinV3(
3289
+ collateralToken: string,
3290
+ indexToken: string,
3291
+ size: bigint,
3292
+ coinObj: TransactionObjectArgument,
3293
+ long: boolean,
3294
+ reserveAmount: bigint,
3295
+ indexPrice: number,
3296
+ collateralPrice: number,
3297
+ pythProUpdateBytes: Uint8Array | number[],
3298
+ isLimitOrder?: boolean,
3299
+ isIocOrder?: boolean,
3300
+ pricesSlippage = 0.003,
3301
+ collateralSlippage = 0.5,
3302
+ relayerFee = BigInt(0.5),
3303
+ referralAddress?: string,
3304
+ sender?: string,
3305
+ tx?: Transaction,
3306
+ sponsoredTx?: boolean,
3307
+ ): Promise<Transaction> {
3308
+ if (!tx) {
3309
+ tx = new Transaction()
3310
+ }
3311
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3312
+ tx = await this.addReferral(referralAddress, tx)
3313
+ }
3314
+
3315
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3316
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3317
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3318
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3319
+
3320
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3321
+ if (isLimitOrder) {
3322
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3323
+ }
3324
+
3325
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3326
+ [collateralToken, indexToken],
3327
+ tx,
3328
+ pythProUpdateBytes,
3329
+ )
3330
+ tx = tx_
3331
+
3332
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
3333
+
3334
+ tx.moveCall({
3335
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v3`,
3336
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3337
+ arguments: [
3338
+ tx.object(SUI_CLOCK_OBJECT_ID),
3339
+ tx.object(this.consts.zoCore.market),
3340
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
3341
+ ...oracleArgsStandard(oracle),
3342
+ coinObj,
3343
+ feeObject,
3344
+ tx.pure.u8(allowTrade),
3345
+ tx.pure.u64(size),
3346
+ tx.pure.u64(reserveAmount),
3347
+ tx.pure.u256(adjustCollateralPrice),
3348
+ tx.pure.u256(adjustPrice),
3349
+ tx.pure.u256(indexPriceThreshold),
3350
+ ],
3351
+ })
3352
+
3353
+ return tx
3354
+ }
3355
+
3356
+ /**
3357
+ * Opens a position with a pre-composed collateral coin and S Card using open_position_with_scard_v3.
3358
+ */
3359
+ public async openPositionWithCoinAndSCardV3(
3360
+ collateralToken: string,
3361
+ indexToken: string,
3362
+ size: bigint,
3363
+ coinObj: TransactionObjectArgument,
3364
+ long: boolean,
3365
+ reserveAmount: bigint,
3366
+ indexPrice: number,
3367
+ collateralPrice: number,
3368
+ kioskClient: KioskClient,
3369
+ kioskCap: KioskOwnerCap,
3370
+ scard: string,
3371
+ pythProUpdateBytes: Uint8Array | number[],
3372
+ isLimitOrder?: boolean,
3373
+ isIocOrder?: boolean,
3374
+ pricesSlippage = 0.003,
3375
+ collateralSlippage = 0.5,
3376
+ relayerFee = BigInt(0.5),
3377
+ referralAddress?: string,
3378
+ sender?: string,
3379
+ tx?: Transaction,
3380
+ sponsoredTx?: boolean,
3381
+ ): Promise<Transaction> {
3382
+ if (!tx) {
3383
+ tx = new Transaction()
3384
+ }
3385
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3386
+ tx = await this.addReferral(referralAddress, tx)
3387
+ }
3388
+
3389
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3390
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3391
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3392
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3393
+
3394
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3395
+ if (isLimitOrder) {
3396
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3397
+ }
3398
+
3399
+ const kioskTx = new KioskTransaction({
3400
+ transaction: tx,
3401
+ kioskClient,
3402
+ cap: kioskCap,
3403
+ })
3404
+
3405
+ const [sudoCard, promise] = kioskTx.borrow({
3406
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3407
+ itemId: scard,
3408
+ })
3409
+
3410
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3411
+ [collateralToken, indexToken],
3412
+ tx,
3413
+ pythProUpdateBytes,
3414
+ )
3415
+ tx = tx_
3416
+
3417
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
3418
+
3419
+ tx.moveCall({
3420
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v3`,
3421
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3422
+ arguments: [
3423
+ tx.object(SUI_CLOCK_OBJECT_ID),
3424
+ tx.object(this.consts.zoCore.market),
3425
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
3426
+ ...oracleArgsStandard(oracle),
3427
+ coinObj,
3428
+ feeObject,
3429
+ tx.pure.u8(allowTrade),
3430
+ tx.pure.u64(size),
3431
+ tx.pure.u64(reserveAmount),
3432
+ tx.pure.u256(adjustCollateralPrice),
3433
+ tx.pure.u256(adjustPrice),
3434
+ tx.pure.u256(indexPriceThreshold),
3435
+ sudoCard,
3436
+ ],
3437
+ })
3438
+
3439
+ kioskTx
3440
+ .return({
3441
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3442
+ item: sudoCard,
3443
+ promise,
3444
+ })
3445
+ .finalize()
3446
+
3447
+ return tx
3448
+ }
3449
+
3450
+ /**
3451
+ * Decreases a position using decrease_position_v3.
3452
+ */
3453
+ public async decreasePositionV3(
3454
+ pcpId: string,
3455
+ collateralToken: string,
3456
+ indexToken: string,
3457
+ amount: bigint,
3458
+ long: boolean,
3459
+ indexPrice: number,
3460
+ collateralPrice: number,
3461
+ pythProUpdateBytes: Uint8Array | number[],
3462
+ isTriggerOrder = false,
3463
+ isTakeProfitOrder = true,
3464
+ isIocOrder = false,
3465
+ pricesSlippage = 0.003,
3466
+ collateralSlippage = 0.5,
3467
+ relayerFee = BigInt(0.5),
3468
+ coinObjects?: string[],
3469
+ sponsoredTx?: boolean,
3470
+ sender?: string,
3471
+ ): Promise<Transaction> {
3472
+ if (!coinObjects?.length && !sender) {
3473
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`)
3474
+ }
3475
+
3476
+ let tx = new Transaction()
3477
+
3478
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
3479
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3480
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3481
+
3482
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3483
+ if (isTriggerOrder) {
3484
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3485
+ }
3486
+ else {
3487
+ isTakeProfitOrder = true
3488
+ }
3489
+
3490
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3491
+ [collateralToken, indexToken],
3492
+ tx,
3493
+ pythProUpdateBytes,
3494
+ )
3495
+ tx = tx_
3496
+
3497
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3498
+ const feeObject = await this.resolveRelayerFeeObject(
3499
+ tx,
3500
+ collateralToken,
3501
+ coinObjects ?? [],
3502
+ relayerFee,
3503
+ sponsoredTx,
3504
+ suiCoinObject,
3505
+ sender,
3506
+ )
3507
+
3508
+ tx.moveCall({
3509
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_v3`,
3510
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3511
+ arguments: [
3512
+ tx.object(SUI_CLOCK_OBJECT_ID),
3513
+ tx.object(this.consts.zoCore.market),
3514
+ tx.object(pcpId),
3515
+ ...oracleArgsStandard(oracle),
3516
+ feeObject,
3517
+ tx.pure.u8(allowTrade),
3518
+ tx.pure.bool(isTakeProfitOrder),
3519
+ tx.pure.u64(amount),
3520
+ tx.pure.u256(adjustCollateralPrice),
3521
+ tx.pure.u256(adjustPrice),
3522
+ tx.pure.u256(indexPriceThreshold),
3523
+ ],
3524
+ })
3525
+
3526
+ return tx
3527
+ }
3528
+
3529
+ /**
3530
+ * Decreases a position with S Card using decrease_position_with_scard_v3.
3531
+ */
3532
+ public async decreasePositionWithSCardV3(
3533
+ pcpId: string,
3534
+ collateralToken: string,
3535
+ indexToken: string,
3536
+ amount: bigint,
3537
+ long: boolean,
3538
+ indexPrice: number,
3539
+ collateralPrice: number,
3540
+ kioskClient: KioskClient,
3541
+ kioskCap: KioskOwnerCap,
3542
+ scard: string,
3543
+ pythProUpdateBytes: Uint8Array | number[],
3544
+ isTriggerOrder = false,
3545
+ isTakeProfitOrder = true,
3546
+ isIocOrder = false,
3547
+ pricesSlippage = 0.003,
3548
+ collateralSlippage = 0.5,
3549
+ relayerFee = BigInt(0.5),
3550
+ coinObjects?: string[],
3551
+ sponsoredTx?: boolean,
3552
+ sender?: string,
3553
+ ): Promise<Transaction> {
3554
+ if (!coinObjects?.length && !sender) {
3555
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`)
3556
+ }
3557
+
3558
+ let tx = new Transaction()
3559
+
3560
+ const kioskTx = new KioskTransaction({
3561
+ transaction: tx,
3562
+ kioskClient,
3563
+ cap: kioskCap,
3564
+ })
3565
+
3566
+ const [sudoCard, promise] = kioskTx.borrow({
3567
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3568
+ itemId: scard,
3569
+ })
3570
+
3571
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
3572
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3573
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3574
+
3575
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3576
+ if (isTriggerOrder) {
3577
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3578
+ }
3579
+ else {
3580
+ isTakeProfitOrder = true
3581
+ }
3582
+
3583
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3584
+ [collateralToken, indexToken],
3585
+ tx,
3586
+ pythProUpdateBytes,
3587
+ )
3588
+ tx = tx_
3589
+
3590
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3591
+ const feeObject = await this.resolveRelayerFeeObject(
3592
+ tx,
3593
+ collateralToken,
3594
+ coinObjects ?? [],
3595
+ relayerFee,
3596
+ sponsoredTx,
3597
+ suiCoinObject,
3598
+ sender,
3599
+ )
3600
+
3601
+ tx.moveCall({
3602
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard_v3`,
3603
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3604
+ arguments: [
3605
+ tx.object(SUI_CLOCK_OBJECT_ID),
3606
+ tx.object(this.consts.zoCore.market),
3607
+ tx.object(pcpId),
3608
+ ...oracleArgsStandard(oracle),
3609
+ feeObject,
3610
+ tx.pure.u8(allowTrade),
3611
+ tx.pure.bool(isTakeProfitOrder),
3612
+ tx.pure.u64(amount),
3613
+ tx.pure.u256(adjustCollateralPrice),
3614
+ tx.pure.u256(adjustPrice),
3615
+ tx.pure.u256(indexPriceThreshold),
3616
+ sudoCard,
3617
+ ],
3618
+ })
3619
+
3620
+ kioskTx
3621
+ .return({
3622
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
3623
+ item: sudoCard,
3624
+ promise,
3625
+ })
3626
+ .finalize()
3627
+ return tx
3628
+ }
3629
+
3630
+ /**
3631
+ * Redeems collateral from a position via redeem_from_position_v2 (Pyth Pro path).
3632
+ */
3633
+ public async redeemFromPositionV2(
3634
+ pcpId: string,
3635
+ collateralToken: string,
3636
+ indexToken: string,
3637
+ amount: number,
3638
+ long: boolean,
3639
+ pythProUpdateBytes: Uint8Array | number[],
3640
+ tx?: Transaction,
3641
+ ): Promise<Transaction> {
3642
+ if (!tx) {
3643
+ tx = new Transaction()
3644
+ }
3645
+
3646
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3647
+ [collateralToken, indexToken],
3648
+ tx,
3649
+ pythProUpdateBytes,
3650
+ )
3651
+
3652
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3653
+
3654
+ tx_.moveCall({
3655
+ target: `${this.consts.zoCore.upgradedPackage}::market::redeem_from_position_v2`,
3656
+ typeArguments: this.redeemTypeArgs(collateralToken, indexToken, long),
3657
+ arguments: [
3658
+ tx_.object(SUI_CLOCK_OBJECT_ID),
3659
+ tx_.object(this.consts.zoCore.market),
3660
+ tx_.object(pcpId),
3661
+ tx_.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
3662
+ tx_.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
3663
+ ...oracleArgsStandard(oracle),
3664
+ tx_.pure.u64(amount),
3665
+ ],
3666
+ })
3667
+
3668
+ return tx_
3669
+ }
3061
3670
  }