@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
@@ -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
  ISLPAPI,
18
19
  ISLPCredential,
19
20
  } from '../interfaces'
21
+ import type { IInitPythProOracleOptions } from '../oracle'
22
+ import type { OracleInputs } from '../oraclePro'
23
+ import { buildOracleInputsAlt, oracleArgsAlt, oracleArgsRegistryFirst } from '../oraclePro'
20
24
  import type { SuiClient } from '../suiClient'
21
- import { joinSymbol } from '../utils'
25
+ import { joinSymbol, parseSymbolKey } from '../utils'
22
26
  import { SLPDataAPI } from './SLPDataAPI'
23
27
 
24
28
  export class SLPAPI extends BaseAPI implements ISLPAPI {
@@ -34,6 +38,98 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
34
38
  this.dataAPI = new SLPDataAPI(network, provider, apiEndpoint, connectionURL)
35
39
  }
36
40
 
41
+ private slpLpType(): string {
42
+ return `${this.consts.sudoCore.package}::slp::SLP`
43
+ }
44
+
45
+ private positionTypeArgs(collateralToken: string, indexToken: string, long: boolean): string[] {
46
+ return [
47
+ this.slpLpType(),
48
+ this.consts.coins[collateralToken].module,
49
+ this.consts.coins[indexToken].module,
50
+ `${this.consts.sudoCore.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.slpLpType(),
58
+ this.consts.coins[collateralToken].module,
59
+ this.consts.coins[indexToken].module,
60
+ `${this.consts.sudoCore.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
+ private getValuationOracleTokens(): string[] {
80
+ const tokens = new Set(Object.keys(this.consts.sudoCore.vaults))
81
+ for (const key of Object.keys(this.consts.sudoCore.symbols)) {
82
+ const [, token] = parseSymbolKey(key)
83
+ tokens.add(token)
84
+ }
85
+ return [...tokens]
86
+ }
87
+
88
+ private async initValuationOracle(
89
+ tx: Transaction,
90
+ ): Promise<{ tx: Transaction, oracle: OracleInputs }> {
91
+ const tokens = this.getValuationOracleTokens()
92
+ const pythProUpdateBytes = await this.fetchPythProUpdateBytesForTokens(tokens)
93
+ return this.initV3OracleForTokens(tokens, tx, pythProUpdateBytes)
94
+ }
95
+
96
+ private async resolveSponsoredSui(
97
+ tx: Transaction,
98
+ collateralToken: string,
99
+ relayerFee: bigint,
100
+ sponsoredTx?: boolean,
101
+ sender?: string,
102
+ ): Promise<TransactionObjectArgument | undefined> {
103
+ if (!sponsoredTx) {
104
+ return undefined
105
+ }
106
+ const additional = collateralToken === 'sui' ? relayerFee : 0n
107
+ if (additional === 0n) {
108
+ return undefined
109
+ }
110
+ return resolveSpendableSuiCoin(
111
+ tx,
112
+ this.provider,
113
+ this.requireSenderForSponsored(sender),
114
+ additional,
115
+ )
116
+ }
117
+
118
+ private positionFeeOracleArgs(
119
+ tx: Transaction,
120
+ collateralToken: string,
121
+ indexToken: string,
122
+ long: boolean,
123
+ oracle: OracleInputs,
124
+ ): TransactionObjectArgument[] {
125
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
126
+ return [
127
+ tx.object(this.consts.sudoCore.vaults[collateralToken].reservingFeeModel),
128
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
129
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
130
+ ]
131
+ }
132
+
37
133
  public calcPositionReserveFeeAmount(_position: IBasePositionInfo): Promise<number> {
38
134
  throw new Error(`Method not implemented in ${this.constructor.name}.`)
39
135
  }
@@ -56,68 +152,26 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
56
152
  ): Promise<Transaction> {
57
153
  let tx = new Transaction()
58
154
 
59
- // Add referral if needed
60
155
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
61
156
  tx = await this.addReferral(referralAddress, tx)
62
157
  }
63
158
 
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.sudoCore.upgradedPackage}::market::deposit`,
87
- typeArguments: [
88
- `${this.consts.sudoCore.package}::slp::SLP`,
89
- this.consts.coins[coin].module,
90
- ],
91
- arguments: [
92
- tx.object(this.consts.sudoCore.market),
93
- tx.object(this.consts.sudoCore.rebaseFeeModel),
94
- depositObject,
95
- tx.pure.u64(minAmountOut),
96
- vaultsValuation,
97
- symbolsValuation,
98
- ],
99
- })
100
- return tx
101
- }
159
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
160
+ tx = txWithOracle
102
161
 
103
- // Handle non-sponsored transaction case
104
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
105
162
  const depositObject = await this.resolveSplitCoinObject(
106
163
  tx,
107
164
  coin,
108
165
  BigInt(amount),
109
166
  coinObjects,
110
- { sender },
167
+ { sponsoredTx, sender },
111
168
  )
112
169
 
113
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
170
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
114
171
 
115
172
  tx.moveCall({
116
173
  target: `${this.consts.sudoCore.upgradedPackage}::market::deposit`,
117
- typeArguments: [
118
- `${this.consts.sudoCore.package}::slp::SLP`,
119
- this.consts.coins[coin].module,
120
- ],
174
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
121
175
  arguments: [
122
176
  tx.object(this.consts.sudoCore.market),
123
177
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -147,65 +201,26 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
147
201
  tx = new Transaction()
148
202
  }
149
203
 
150
- // Add referral if needed
151
204
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
152
205
  tx = await this.addReferral(referralAddress, tx)
153
206
  }
154
207
 
155
- // Initialize oracle transaction
156
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
157
-
158
- // Handle sponsored transaction case
159
- if (sponsoredTx) {
160
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
161
- sender: this.requireSenderForSponsored(sender),
162
- additionalSuiAmount: coin === 'sui' ? BigInt(amount) : 0n,
163
- })
164
- tx = oracle.tx
165
-
166
- const depositObject = await this.resolveSplitCoinObject(
167
- tx,
168
- coin,
169
- BigInt(amount),
170
- coinObjects,
171
- { sponsoredTx: true, suiCoinObject: oracle.suiCoinObject, sender },
172
- )
173
-
174
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
175
-
176
- const [mintedCoin] = tx.moveCall({
177
- target: `${this.consts.sudoCore.upgradedPackage}::market::deposit_ptb`,
178
- typeArguments: [`${this.consts.sudoCore.package}::slp::SLP`, this.consts.coins[coin].module],
179
- arguments: [
180
- tx.object(this.consts.sudoCore.market),
181
- tx.object(this.consts.sudoCore.rebaseFeeModel),
182
- depositObject,
183
- tx.pure.u64(minAmountOut),
184
- vaultsValuation,
185
- symbolsValuation,
186
- ],
187
- })
188
- return mintedCoin
189
- }
208
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
209
+ tx = txWithOracle
190
210
 
191
- // Handle non-sponsored transaction case
192
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
193
211
  const depositObject = await this.resolveSplitCoinObject(
194
212
  tx,
195
213
  coin,
196
214
  BigInt(amount),
197
215
  coinObjects,
198
- { sender },
216
+ { sponsoredTx, sender },
199
217
  )
200
218
 
201
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
219
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
202
220
 
203
221
  const [mintedCoin] = tx.moveCall({
204
222
  target: `${this.consts.sudoCore.upgradedPackage}::market::deposit_ptb`,
205
- typeArguments: [
206
- `${this.consts.sudoCore.package}::slp::SLP`,
207
- this.consts.coins[coin].module,
208
- ],
223
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
209
224
  arguments: [
210
225
  tx.object(this.consts.sudoCore.market),
211
226
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -215,7 +230,6 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
215
230
  symbolsValuation,
216
231
  ],
217
232
  })
218
-
219
233
  return mintedCoin
220
234
  }
221
235
 
@@ -235,54 +249,18 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
235
249
  tx = new Transaction()
236
250
  }
237
251
 
238
- // Add referral if needed
239
252
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
240
253
  tx = await this.addReferral(referralAddress, tx)
241
254
  }
242
255
 
243
- // Initialize oracle transaction
244
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
245
-
246
- // Handle sponsored transaction case
247
- if (sponsoredTx) {
248
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
249
- sender: this.requireSenderForSponsored(sender),
250
- additionalSuiAmount: 0n,
251
- })
252
- tx = oracle.tx
253
- const { suiCoinObject } = oracle
254
-
255
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
256
-
257
- tx.moveCall({
258
- target: `${this.consts.sudoCore.upgradedPackage}::market::deposit`,
259
- typeArguments: [
260
- `${this.consts.sudoCore.package}::slp::SLP`,
261
- this.consts.coins[coin].module,
262
- ],
263
- arguments: [
264
- tx.object(this.consts.sudoCore.market),
265
- tx.object(this.consts.sudoCore.rebaseFeeModel),
266
- depositObject,
267
- tx.pure.u64(minAmountOut),
268
- vaultsValuation,
269
- symbolsValuation,
270
- ],
271
- })
272
- return tx
273
- }
274
-
275
- // Handle non-sponsored transaction case
276
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
256
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
257
+ tx = txWithOracle
277
258
 
278
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
259
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
279
260
 
280
261
  tx.moveCall({
281
262
  target: `${this.consts.sudoCore.upgradedPackage}::market::deposit`,
282
- typeArguments: [
283
- `${this.consts.sudoCore.package}::slp::SLP`,
284
- this.consts.coins[coin].module,
285
- ],
263
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
286
264
  arguments: [
287
265
  tx.object(this.consts.sudoCore.market),
288
266
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -312,37 +290,21 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
312
290
 
313
291
  let tx = new Transaction()
314
292
 
315
- // Initialize oracle transaction
316
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
317
-
318
- let suiCoinObject
319
- if (sponsoredTx) {
320
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
321
- sender: this.requireSenderForSponsored(sender),
322
- additionalSuiAmount: 0n,
323
- })
324
- tx = oracle.tx
325
- suiCoinObject = oracle.suiCoinObject
326
- }
327
- else {
328
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
329
- }
293
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
294
+ tx = txWithOracle
330
295
 
331
296
  const withdrawObject = await this.resolveSplitCoinObject(
332
297
  tx,
333
298
  'slp',
334
299
  BigInt(amount),
335
300
  lpCoinObjects,
336
- { sponsoredTx, suiCoinObject, sender },
301
+ { sponsoredTx, sender },
337
302
  )
338
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
303
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
339
304
 
340
305
  tx.moveCall({
341
306
  target: `${this.consts.sudoCore.upgradedPackage}::market::withdraw`,
342
- typeArguments: [
343
- `${this.consts.sudoCore.package}::slp::SLP`,
344
- this.consts.coins[coin].module,
345
- ],
307
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
346
308
  arguments: [
347
309
  tx.object(this.consts.sudoCore.market),
348
310
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -368,18 +330,13 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
368
330
  tx = new Transaction()
369
331
  }
370
332
 
371
- // Initialize oracle transaction
372
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
373
-
374
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
375
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
333
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
334
+ tx = txWithOracle
335
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
376
336
 
377
337
  tx.moveCall({
378
338
  target: `${this.consts.sudoCore.upgradedPackage}::market::withdraw`,
379
- typeArguments: [
380
- `${this.consts.sudoCore.package}::slp::SLP`,
381
- this.consts.coins[coin].module,
382
- ],
339
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
383
340
  arguments: [
384
341
  tx.object(this.consts.sudoCore.market),
385
342
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -409,37 +366,21 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
409
366
  tx = new Transaction()
410
367
  }
411
368
 
412
- // Initialize oracle transaction
413
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
414
-
415
- let suiCoinObject
416
- if (sponsoredTx) {
417
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
418
- sender: this.requireSenderForSponsored(sender),
419
- additionalSuiAmount: 0n,
420
- })
421
- tx = oracle.tx
422
- suiCoinObject = oracle.suiCoinObject
423
- }
424
- else {
425
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx
426
- }
369
+ const { tx: txWithOracle, oracle } = await this.initValuationOracle(tx)
370
+ tx = txWithOracle
427
371
 
428
372
  const withdrawObject = await this.resolveSplitCoinObject(
429
373
  tx,
430
374
  'slp',
431
375
  BigInt(amount),
432
376
  lpCoinObjects,
433
- { sponsoredTx, suiCoinObject, sender },
377
+ { sponsoredTx, sender },
434
378
  )
435
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
379
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV3(tx, oracle)
436
380
 
437
381
  const [withdrawCoin] = tx.moveCall({
438
382
  target: `${this.consts.sudoCore.upgradedPackage}::market::withdraw_ptb`,
439
- typeArguments: [
440
- `${this.consts.sudoCore.package}::slp::SLP`,
441
- this.consts.coins[coin].module,
442
- ],
383
+ typeArguments: [this.slpLpType(), this.consts.coins[coin].module],
443
384
  arguments: [
444
385
  tx.object(this.consts.sudoCore.market),
445
386
  tx.object(this.consts.sudoCore.rebaseFeeModel),
@@ -1486,45 +1427,25 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1486
1427
  sponsoredTx?: boolean,
1487
1428
  sender?: string,
1488
1429
  ): Promise<Transaction> {
1489
- let tx = new Transaction()
1490
-
1491
- // Handle oracle initialization and coin processing
1492
- let suiCoinObject
1493
- if (sponsoredTx) {
1494
- const oracle = await this.initOracleTxb([collateralToken, indexToken], tx, true, {
1495
- sender: this.requireSenderForSponsored(sender),
1496
- additionalSuiAmount: collateralToken === 'sui' ? BigInt(amount) : 0n,
1497
- })
1498
- tx = oracle.tx
1499
- suiCoinObject = oracle.suiCoinObject
1500
- }
1501
- else {
1502
- tx = (await this.initOracleTxb([collateralToken, indexToken], tx)).tx
1503
- }
1430
+ const tx = new Transaction()
1504
1431
 
1505
1432
  const depositObject = await this.resolveSplitCoinObject(
1506
1433
  tx,
1507
1434
  collateralToken,
1508
1435
  BigInt(amount),
1509
1436
  coinObjects,
1510
- { sponsoredTx, suiCoinObject, sender },
1437
+ { sponsoredTx, sender },
1511
1438
  )
1512
1439
 
1513
1440
  tx.moveCall({
1514
1441
  target: `${this.consts.sudoCore.upgradedPackage}::market::pledge_in_position`,
1515
- typeArguments: [
1516
- `${this.consts.sudoCore.package}::slp::SLP`,
1517
- this.consts.coins[collateralToken].module,
1518
- this.consts.coins[indexToken].module,
1519
- `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1520
- ],
1442
+ typeArguments: this.redeemTypeArgs(collateralToken, indexToken, long),
1521
1443
  arguments: [
1522
1444
  tx.object(this.consts.sudoCore.market),
1523
1445
  tx.object(pcpId),
1524
1446
  depositObject,
1525
1447
  ],
1526
1448
  })
1527
- this.returnUnusedSuiCoin(tx, suiCoinObject, sender)
1528
1449
  return tx
1529
1450
  }
1530
1451
 
@@ -1595,7 +1516,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1595
1516
  break
1596
1517
  }
1597
1518
  case 'OPEN_MARKET': {
1598
- functionName = 'clear_open_market_order'
1519
+ functionName = 'clear_open_position_order_unified'
1599
1520
  break
1600
1521
  }
1601
1522
  case 'DECREASE_POSITION': {
@@ -1603,7 +1524,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1603
1524
  break
1604
1525
  }
1605
1526
  case 'DECREASE_MARKET': {
1606
- functionName = 'clear_decrease_market_order'
1527
+ functionName = 'clear_decrease_position_order_unified'
1607
1528
  break
1608
1529
  }
1609
1530
  default: {
@@ -1651,7 +1572,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1651
1572
  break
1652
1573
  }
1653
1574
  case 'OPEN_MARKET': {
1654
- functionName = 'clear_open_market_order'
1575
+ functionName = 'clear_open_position_order_unified'
1655
1576
  break
1656
1577
  }
1657
1578
  case 'DECREASE_POSITION': {
@@ -1659,7 +1580,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1659
1580
  break
1660
1581
  }
1661
1582
  case 'DECREASE_MARKET': {
1662
- functionName = 'clear_decrease_market_order'
1583
+ functionName = 'clear_decrease_position_order_unified'
1663
1584
  break
1664
1585
  }
1665
1586
  default: {
@@ -1707,7 +1628,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1707
1628
  indexToken: string,
1708
1629
  long: boolean,
1709
1630
  tx: Transaction,
1710
- isV11Order = true,
1631
+ isV11Order = false,
1711
1632
  ): void {
1712
1633
  tx.moveCall({
1713
1634
  target: `${this.consts.sudoCore.upgradedPackage}::market::clear_open_position_order_unified`,
@@ -1731,7 +1652,7 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1731
1652
  indexToken: string,
1732
1653
  long: boolean,
1733
1654
  tx: Transaction,
1734
- isV11Order = true,
1655
+ isV11Order = false,
1735
1656
  ): void {
1736
1657
  tx.moveCall({
1737
1658
  target: `${this.consts.sudoCore.upgradedPackage}::market::clear_decrease_position_order_unified`,
@@ -1755,20 +1676,9 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1755
1676
  indexToken: string,
1756
1677
  long: boolean,
1757
1678
  tx: Transaction,
1758
- _isV11Order?: boolean,
1679
+ isV11Order = false,
1759
1680
  ): void {
1760
- const funcName = 'clear_open_market_order'
1761
- tx.moveCall({
1762
- target: `${this.consts.sudoCore.upgradedPackage}::market::${funcName}`,
1763
- typeArguments: [
1764
- `${this.consts.sudoCore.package}::slp::SLP`,
1765
- this.consts.coins[collateralToken].module,
1766
- this.consts.coins[indexToken].module,
1767
- `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1768
- this.consts.coins[collateralToken].module,
1769
- ],
1770
- arguments: [tx.object(this.consts.sudoCore.market), tx.object(orderCapId)],
1771
- })
1681
+ this.clearOpenPositionOrder(orderCapId, collateralToken, indexToken, long, tx, isV11Order)
1772
1682
  }
1773
1683
 
1774
1684
  public clearDecreaseMarketOrder(
@@ -1777,20 +1687,9 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
1777
1687
  indexToken: string,
1778
1688
  long: boolean,
1779
1689
  tx: Transaction,
1780
- _isV11Order?: boolean,
1690
+ isV11Order = false,
1781
1691
  ): void {
1782
- const funcName = 'clear_decrease_market_order'
1783
- tx.moveCall({
1784
- target: `${this.consts.sudoCore.upgradedPackage}::market::${funcName}`,
1785
- typeArguments: [
1786
- `${this.consts.sudoCore.package}::slp::SLP`,
1787
- this.consts.coins[collateralToken].module,
1788
- this.consts.coins[indexToken].module,
1789
- `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1790
- this.consts.coins[collateralToken].module,
1791
- ],
1792
- arguments: [tx.object(this.consts.sudoCore.market), tx.object(orderCapId)],
1793
- })
1692
+ this.clearDecreasePositionOrder(orderCapId, collateralToken, indexToken, long, tx, isV11Order)
1794
1693
  }
1795
1694
 
1796
1695
  public async openPositionWithSCard(
@@ -2841,6 +2740,591 @@ export class SLPAPI extends BaseAPI implements ISLPAPI {
2841
2740
  })
2842
2741
  }
2843
2742
 
2743
+ // --- Pyth Pro + Stork (v3_1 / swap_v4) ---
2744
+
2745
+ public async swapV4(
2746
+ fromToken: string,
2747
+ toToken: string,
2748
+ fromAmount: bigint,
2749
+ fromCoinObjects: string[],
2750
+ pythProUpdateBytes: Uint8Array | number[],
2751
+ minAmountOut?: number,
2752
+ tx?: Transaction,
2753
+ ): Promise<Transaction> {
2754
+ if (!tx) {
2755
+ tx = new Transaction()
2756
+ }
2757
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
2758
+ Object.keys(this.consts.sudoCore.vaults),
2759
+ tx,
2760
+ pythProUpdateBytes,
2761
+ true,
2762
+ )
2763
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects)
2764
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)])
2765
+ const vaultsValuation = this.dataAPI.valuateVaultsV3(tx_, oracle)
2766
+
2767
+ tx_.moveCall({
2768
+ target: `${this.consts.sudoCore.upgradedPackage}::market::swap_v4`,
2769
+ typeArguments: [this.slpLpType(), this.consts.coins[fromToken].module, this.consts.coins[toToken].module],
2770
+ arguments: [
2771
+ tx_.object(this.consts.sudoCore.market),
2772
+ tx_.object(this.consts.sudoCore.rebaseFeeModel),
2773
+ fromDepositObject,
2774
+ tx_.pure.u64(minAmountOut || 0),
2775
+ vaultsValuation,
2776
+ ...oracleArgsRegistryFirst(oracle),
2777
+ ],
2778
+ })
2779
+ return tx_
2780
+ }
2781
+
2782
+ public async swapV4Ptb(
2783
+ fromToken: string,
2784
+ toToken: string,
2785
+ fromAmount: bigint,
2786
+ fromCoinObjects: string[],
2787
+ pythProUpdateBytes: Uint8Array | number[],
2788
+ minAmountOut?: number,
2789
+ tx?: Transaction,
2790
+ ): Promise<TransactionObjectArgument> {
2791
+ if (!tx) {
2792
+ tx = new Transaction()
2793
+ }
2794
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
2795
+ Object.keys(this.consts.sudoCore.vaults),
2796
+ tx,
2797
+ pythProUpdateBytes,
2798
+ true,
2799
+ )
2800
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects)
2801
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)])
2802
+ const vaultsValuation = this.dataAPI.valuateVaultsV3(tx_, oracle)
2803
+
2804
+ const [outputCoin] = tx_.moveCall({
2805
+ target: `${this.consts.sudoCore.upgradedPackage}::market::swap_v4_ptb`,
2806
+ typeArguments: [this.slpLpType(), this.consts.coins[fromToken].module, this.consts.coins[toToken].module],
2807
+ arguments: [
2808
+ tx_.object(this.consts.sudoCore.market),
2809
+ tx_.object(this.consts.sudoCore.rebaseFeeModel),
2810
+ fromDepositObject,
2811
+ tx_.pure.u64(minAmountOut || 0),
2812
+ vaultsValuation,
2813
+ ...oracleArgsRegistryFirst(oracle),
2814
+ ],
2815
+ })
2816
+ return outputCoin
2817
+ }
2818
+
2819
+ public async openPositionV3(
2820
+ collateralToken: string,
2821
+ indexToken: string,
2822
+ size: bigint,
2823
+ collateralAmount: bigint,
2824
+ coinObjects: string[],
2825
+ long: boolean,
2826
+ reserveAmount: bigint,
2827
+ indexPrice: number,
2828
+ collateralPrice: number,
2829
+ pythProUpdateBytes: Uint8Array | number[],
2830
+ isLimitOrder?: boolean,
2831
+ isIocOrder?: boolean,
2832
+ pricesSlippage = 0.003,
2833
+ collateralSlippage = 0.5,
2834
+ relayerFee = BigInt(0.5),
2835
+ referralAddress?: string,
2836
+ sender?: string,
2837
+ sponsoredTx?: boolean,
2838
+ ): Promise<Transaction> {
2839
+ let tx = new Transaction()
2840
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2841
+ tx = await this.addReferral(referralAddress, tx)
2842
+ }
2843
+
2844
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
2845
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
2846
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
2847
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
2848
+
2849
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
2850
+ if (isLimitOrder) {
2851
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
2852
+ }
2853
+
2854
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
2855
+ [collateralToken, indexToken],
2856
+ tx,
2857
+ pythProUpdateBytes,
2858
+ )
2859
+ tx = tx_
2860
+
2861
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
2862
+ const [depositObject, feeObject] = this.processCoinSplitting(
2863
+ tx,
2864
+ collateralToken,
2865
+ coinObjects,
2866
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
2867
+ sponsoredTx,
2868
+ suiCoinObject,
2869
+ )
2870
+
2871
+ tx.moveCall({
2872
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_v3_1`,
2873
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2874
+ arguments: [
2875
+ tx.object(SUI_CLOCK_OBJECT_ID),
2876
+ tx.object(this.consts.sudoCore.market),
2877
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
2878
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
2879
+ depositObject,
2880
+ feeObject,
2881
+ tx.pure.u8(allowTrade),
2882
+ tx.pure.u64(size),
2883
+ tx.pure.u64(reserveAmount),
2884
+ tx.pure.u256(adjustCollateralPrice),
2885
+ tx.pure.u256(adjustPrice),
2886
+ tx.pure.u256(indexPriceThreshold),
2887
+ ],
2888
+ })
2889
+ return tx
2890
+ }
2891
+
2892
+ public async openPositionWithSCardV3(
2893
+ collateralToken: string,
2894
+ indexToken: string,
2895
+ size: bigint,
2896
+ collateralAmount: bigint,
2897
+ coinObjects: string[],
2898
+ long: boolean,
2899
+ reserveAmount: bigint,
2900
+ indexPrice: number,
2901
+ collateralPrice: number,
2902
+ kioskClient: KioskClient,
2903
+ kioskCap: KioskOwnerCap,
2904
+ scard: string,
2905
+ pythProUpdateBytes: Uint8Array | number[],
2906
+ isLimitOrder?: boolean,
2907
+ isIocOrder?: boolean,
2908
+ pricesSlippage = 0.003,
2909
+ collateralSlippage = 0.5,
2910
+ relayerFee = BigInt(0.5),
2911
+ referralAddress?: string,
2912
+ sender?: string,
2913
+ sponsoredTx?: boolean,
2914
+ ): Promise<Transaction> {
2915
+ let tx = new Transaction()
2916
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2917
+ tx = await this.addReferral(referralAddress, tx)
2918
+ }
2919
+
2920
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
2921
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
2922
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
2923
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
2924
+
2925
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
2926
+ if (isLimitOrder) {
2927
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
2928
+ }
2929
+
2930
+ const kioskTx = new KioskTransaction({ transaction: tx, kioskClient, cap: kioskCap })
2931
+ const [sudoCard, promise] = kioskTx.borrow({
2932
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
2933
+ itemId: scard,
2934
+ })
2935
+
2936
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
2937
+ [collateralToken, indexToken],
2938
+ tx,
2939
+ pythProUpdateBytes,
2940
+ )
2941
+ tx = tx_
2942
+
2943
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
2944
+ const [depositObject, feeObject] = this.processCoinSplitting(
2945
+ tx,
2946
+ collateralToken,
2947
+ coinObjects,
2948
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
2949
+ sponsoredTx,
2950
+ suiCoinObject,
2951
+ )
2952
+
2953
+ tx.moveCall({
2954
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_with_scard_v3_1`,
2955
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2956
+ arguments: [
2957
+ tx.object(SUI_CLOCK_OBJECT_ID),
2958
+ tx.object(this.consts.sudoCore.market),
2959
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
2960
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
2961
+ depositObject,
2962
+ feeObject,
2963
+ tx.pure.u8(allowTrade),
2964
+ tx.pure.u64(size),
2965
+ tx.pure.u64(reserveAmount),
2966
+ tx.pure.u256(adjustCollateralPrice),
2967
+ tx.pure.u256(adjustPrice),
2968
+ tx.pure.u256(indexPriceThreshold),
2969
+ sudoCard,
2970
+ ],
2971
+ })
2972
+
2973
+ kioskTx.return({
2974
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
2975
+ item: sudoCard,
2976
+ promise,
2977
+ }).finalize()
2978
+ return tx
2979
+ }
2980
+
2981
+ public async openPositionWithCoinV3(
2982
+ collateralToken: string,
2983
+ indexToken: string,
2984
+ size: bigint,
2985
+ coinObj: TransactionObjectArgument,
2986
+ long: boolean,
2987
+ reserveAmount: bigint,
2988
+ indexPrice: number,
2989
+ collateralPrice: number,
2990
+ pythProUpdateBytes: Uint8Array | number[],
2991
+ isLimitOrder?: boolean,
2992
+ isIocOrder?: boolean,
2993
+ pricesSlippage = 0.003,
2994
+ collateralSlippage = 0.5,
2995
+ relayerFee = BigInt(0.5),
2996
+ referralAddress?: string,
2997
+ sender?: string,
2998
+ tx?: Transaction,
2999
+ sponsoredTx?: boolean,
3000
+ ): Promise<Transaction> {
3001
+ if (!tx) {
3002
+ tx = new Transaction()
3003
+ }
3004
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3005
+ tx = await this.addReferral(referralAddress, tx)
3006
+ }
3007
+
3008
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3009
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3010
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3011
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3012
+
3013
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3014
+ if (isLimitOrder) {
3015
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3016
+ }
3017
+
3018
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3019
+ [collateralToken, indexToken],
3020
+ tx,
3021
+ pythProUpdateBytes,
3022
+ )
3023
+ tx = tx_
3024
+
3025
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
3026
+
3027
+ tx.moveCall({
3028
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_v3_1`,
3029
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3030
+ arguments: [
3031
+ tx.object(SUI_CLOCK_OBJECT_ID),
3032
+ tx.object(this.consts.sudoCore.market),
3033
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
3034
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
3035
+ coinObj,
3036
+ feeObject,
3037
+ tx.pure.u8(allowTrade),
3038
+ tx.pure.u64(size),
3039
+ tx.pure.u64(reserveAmount),
3040
+ tx.pure.u256(adjustCollateralPrice),
3041
+ tx.pure.u256(adjustPrice),
3042
+ tx.pure.u256(indexPriceThreshold),
3043
+ ],
3044
+ })
3045
+ return tx
3046
+ }
3047
+
3048
+ public async openPositionWithCoinAndSCardV3(
3049
+ collateralToken: string,
3050
+ indexToken: string,
3051
+ size: bigint,
3052
+ coinObj: TransactionObjectArgument,
3053
+ long: boolean,
3054
+ reserveAmount: bigint,
3055
+ indexPrice: number,
3056
+ collateralPrice: number,
3057
+ kioskClient: KioskClient,
3058
+ kioskCap: KioskOwnerCap,
3059
+ scard: string,
3060
+ pythProUpdateBytes: Uint8Array | number[],
3061
+ isLimitOrder?: boolean,
3062
+ isIocOrder?: boolean,
3063
+ pricesSlippage = 0.003,
3064
+ collateralSlippage = 0.5,
3065
+ relayerFee = BigInt(0.5),
3066
+ referralAddress?: string,
3067
+ sender?: string,
3068
+ tx?: Transaction,
3069
+ sponsoredTx?: boolean,
3070
+ ): Promise<Transaction> {
3071
+ if (!tx) {
3072
+ tx = new Transaction()
3073
+ }
3074
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
3075
+ tx = await this.addReferral(referralAddress, tx)
3076
+ }
3077
+
3078
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
3079
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
3080
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3081
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3082
+
3083
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3084
+ if (isLimitOrder) {
3085
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3086
+ }
3087
+
3088
+ const kioskTx = new KioskTransaction({ transaction: tx, kioskClient, cap: kioskCap })
3089
+ const [sudoCard, promise] = kioskTx.borrow({
3090
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
3091
+ itemId: scard,
3092
+ })
3093
+
3094
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3095
+ [collateralToken, indexToken],
3096
+ tx,
3097
+ pythProUpdateBytes,
3098
+ )
3099
+ tx = tx_
3100
+
3101
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
3102
+
3103
+ tx.moveCall({
3104
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_with_scard_v3_1`,
3105
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3106
+ arguments: [
3107
+ tx.object(SUI_CLOCK_OBJECT_ID),
3108
+ tx.object(this.consts.sudoCore.market),
3109
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
3110
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
3111
+ coinObj,
3112
+ feeObject,
3113
+ tx.pure.u8(allowTrade),
3114
+ tx.pure.u64(size),
3115
+ tx.pure.u64(reserveAmount),
3116
+ tx.pure.u256(adjustCollateralPrice),
3117
+ tx.pure.u256(adjustPrice),
3118
+ tx.pure.u256(indexPriceThreshold),
3119
+ sudoCard,
3120
+ ],
3121
+ })
3122
+
3123
+ kioskTx.return({
3124
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
3125
+ item: sudoCard,
3126
+ promise,
3127
+ }).finalize()
3128
+ return tx
3129
+ }
3130
+
3131
+ public async decreasePositionV3(
3132
+ pcpId: string,
3133
+ collateralToken: string,
3134
+ indexToken: string,
3135
+ amount: bigint,
3136
+ long: boolean,
3137
+ indexPrice: number,
3138
+ collateralPrice: number,
3139
+ pythProUpdateBytes: Uint8Array | number[],
3140
+ isTriggerOrder = false,
3141
+ isTakeProfitOrder = true,
3142
+ isIocOrder = false,
3143
+ pricesSlippage = 0.003,
3144
+ collateralSlippage = 0.5,
3145
+ relayerFee = BigInt(0.5),
3146
+ coinObjects?: string[],
3147
+ sponsoredTx?: boolean,
3148
+ sender?: string,
3149
+ ): Promise<Transaction> {
3150
+ if (!coinObjects?.length && !sender) {
3151
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`)
3152
+ }
3153
+
3154
+ let tx = new Transaction()
3155
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
3156
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3157
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3158
+
3159
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3160
+ if (isTriggerOrder) {
3161
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3162
+ }
3163
+ else {
3164
+ isTakeProfitOrder = true
3165
+ }
3166
+
3167
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3168
+ [collateralToken, indexToken],
3169
+ tx,
3170
+ pythProUpdateBytes,
3171
+ )
3172
+ tx = tx_
3173
+
3174
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3175
+ const feeObject = await this.resolveRelayerFeeObject(
3176
+ tx,
3177
+ collateralToken,
3178
+ coinObjects ?? [],
3179
+ relayerFee,
3180
+ sponsoredTx,
3181
+ suiCoinObject,
3182
+ sender,
3183
+ )
3184
+
3185
+ tx.moveCall({
3186
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_v3_1`,
3187
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3188
+ arguments: [
3189
+ tx.object(SUI_CLOCK_OBJECT_ID),
3190
+ tx.object(this.consts.sudoCore.market),
3191
+ tx.object(pcpId),
3192
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
3193
+ feeObject,
3194
+ tx.pure.u8(allowTrade),
3195
+ tx.pure.bool(isTakeProfitOrder),
3196
+ tx.pure.u64(amount),
3197
+ tx.pure.u256(adjustCollateralPrice),
3198
+ tx.pure.u256(adjustPrice),
3199
+ tx.pure.u256(indexPriceThreshold),
3200
+ ],
3201
+ })
3202
+ return tx
3203
+ }
3204
+
3205
+ public async decreasePositionWithSCardV3(
3206
+ pcpId: string,
3207
+ collateralToken: string,
3208
+ indexToken: string,
3209
+ amount: bigint,
3210
+ long: boolean,
3211
+ indexPrice: number,
3212
+ collateralPrice: number,
3213
+ kioskClient: KioskClient,
3214
+ kioskCap: KioskOwnerCap,
3215
+ scard: string,
3216
+ pythProUpdateBytes: Uint8Array | number[],
3217
+ isTriggerOrder = false,
3218
+ isTakeProfitOrder = true,
3219
+ isIocOrder = false,
3220
+ pricesSlippage = 0.003,
3221
+ collateralSlippage = 0.5,
3222
+ relayerFee = BigInt(0.5),
3223
+ coinObjects?: string[],
3224
+ sponsoredTx?: boolean,
3225
+ sender?: string,
3226
+ ): Promise<Transaction> {
3227
+ if (!coinObjects?.length && !sender) {
3228
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`)
3229
+ }
3230
+
3231
+ let tx = new Transaction()
3232
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
3233
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
3234
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
3235
+
3236
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
3237
+ if (isTriggerOrder) {
3238
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
3239
+ }
3240
+ else {
3241
+ isTakeProfitOrder = true
3242
+ }
3243
+
3244
+ const kioskTx = new KioskTransaction({ transaction: tx, kioskClient, cap: kioskCap })
3245
+ const [sudoCard, promise] = kioskTx.borrow({
3246
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
3247
+ itemId: scard,
3248
+ })
3249
+
3250
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3251
+ [collateralToken, indexToken],
3252
+ tx,
3253
+ pythProUpdateBytes,
3254
+ )
3255
+ tx = tx_
3256
+
3257
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender)
3258
+ const feeObject = await this.resolveRelayerFeeObject(
3259
+ tx,
3260
+ collateralToken,
3261
+ coinObjects ?? [],
3262
+ relayerFee,
3263
+ sponsoredTx,
3264
+ suiCoinObject,
3265
+ sender,
3266
+ )
3267
+
3268
+ tx.moveCall({
3269
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_with_scard_v3_1`,
3270
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
3271
+ arguments: [
3272
+ tx.object(SUI_CLOCK_OBJECT_ID),
3273
+ tx.object(this.consts.sudoCore.market),
3274
+ tx.object(pcpId),
3275
+ ...oracleArgsAlt(buildOracleInputsAlt(oracle)),
3276
+ feeObject,
3277
+ tx.pure.u8(allowTrade),
3278
+ tx.pure.bool(isTakeProfitOrder),
3279
+ tx.pure.u64(amount),
3280
+ tx.pure.u256(adjustCollateralPrice),
3281
+ tx.pure.u256(adjustPrice),
3282
+ tx.pure.u256(indexPriceThreshold),
3283
+ sudoCard,
3284
+ ],
3285
+ })
3286
+
3287
+ kioskTx.return({
3288
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
3289
+ item: sudoCard,
3290
+ promise,
3291
+ }).finalize()
3292
+ return tx
3293
+ }
3294
+
3295
+ public async redeemFromPositionV3(
3296
+ pcpId: string,
3297
+ collateralToken: string,
3298
+ indexToken: string,
3299
+ amount: number,
3300
+ long: boolean,
3301
+ pythProUpdateBytes: Uint8Array | number[],
3302
+ tx?: Transaction,
3303
+ ): Promise<Transaction> {
3304
+ if (!tx) {
3305
+ tx = new Transaction()
3306
+ }
3307
+
3308
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(
3309
+ [collateralToken, indexToken],
3310
+ tx,
3311
+ pythProUpdateBytes,
3312
+ )
3313
+
3314
+ tx_.moveCall({
3315
+ target: `${this.consts.sudoCore.upgradedPackage}::market::redeem_from_position_v3_1`,
3316
+ typeArguments: this.redeemTypeArgs(collateralToken, indexToken, long),
3317
+ arguments: [
3318
+ tx_.object(SUI_CLOCK_OBJECT_ID),
3319
+ tx_.object(this.consts.sudoCore.market),
3320
+ tx_.object(pcpId),
3321
+ ...this.positionFeeOracleArgs(tx_, collateralToken, indexToken, long, oracle),
3322
+ tx_.pure.u64(amount),
3323
+ ],
3324
+ })
3325
+ return tx_
3326
+ }
3327
+
2844
3328
  // SLP Specific APIs
2845
3329
  public claimTokenFromSCard(
2846
3330
  token: string,