@zofai/zo-sdk 0.2.28 → 0.2.30

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 (41) hide show
  1. package/dist/consts/deployments-zlp-mainnet.json +1 -1
  2. package/dist/consts/deployments-zo-oracle-mainnet.json +19 -2
  3. package/dist/implementations/ZLPAPI.cjs +456 -123
  4. package/dist/implementations/ZLPAPI.cjs.map +1 -1
  5. package/dist/implementations/ZLPAPI.d.cts +46 -1
  6. package/dist/implementations/ZLPAPI.d.cts.map +1 -1
  7. package/dist/implementations/ZLPAPI.d.mts +46 -1
  8. package/dist/implementations/ZLPAPI.d.mts.map +1 -1
  9. package/dist/implementations/ZLPAPI.mjs +457 -124
  10. package/dist/implementations/ZLPAPI.mjs.map +1 -1
  11. package/dist/implementations/ZLPDataAPI.cjs +38 -0
  12. package/dist/implementations/ZLPDataAPI.cjs.map +1 -1
  13. package/dist/implementations/ZLPDataAPI.d.cts +16 -0
  14. package/dist/implementations/ZLPDataAPI.d.cts.map +1 -1
  15. package/dist/implementations/ZLPDataAPI.d.mts +16 -0
  16. package/dist/implementations/ZLPDataAPI.d.mts.map +1 -1
  17. package/dist/implementations/ZLPDataAPI.mjs +38 -0
  18. package/dist/implementations/ZLPDataAPI.mjs.map +1 -1
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +1 -0
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.mts +1 -0
  23. package/dist/index.d.mts.map +1 -1
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/interfaces/zlp.d.cts +19 -0
  26. package/dist/interfaces/zlp.d.cts.map +1 -1
  27. package/dist/interfaces/zlp.d.mts +19 -0
  28. package/dist/interfaces/zlp.d.mts.map +1 -1
  29. package/docs/api-reference.md +45 -0
  30. package/docs/architecture.md +21 -3
  31. package/docs/common-operations.md +56 -8
  32. package/docs/getting-started.md +8 -3
  33. package/docs/lp-specific-features.md +89 -12
  34. package/docs/swap-integration.md +52 -20
  35. package/package.json +1 -1
  36. package/src/consts/deployments-zlp-mainnet.json +1 -1
  37. package/src/consts/deployments-zo-oracle-mainnet.json +19 -2
  38. package/src/implementations/ZLPAPI.ts +760 -151
  39. package/src/implementations/ZLPDataAPI.ts +42 -0
  40. package/src/index.ts +1 -0
  41. package/src/interfaces/zlp.ts +170 -0
@@ -6,14 +6,69 @@ import { KioskTransaction } from "@mysten/kiosk";
6
6
  import { Transaction } from "@mysten/sui/transactions";
7
7
  import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
8
8
  import { BaseAPI } from "../abstract/index.mjs";
9
+ import { resolveSpendableSuiCoin } from "../coins.mjs";
9
10
  import { ALLOW_TRADE_CAN_TRADE, ALLOW_TRADE_MUST_TRADE, ALLOW_TRADE_NO_TRADE, LPToken } from "../consts/index.mjs";
10
- import { joinSymbol } from "../utils.mjs";
11
+ import { oracleArgsStandard } from "../oraclePro.mjs";
12
+ import { joinSymbol, parseSymbolKey } from "../utils.mjs";
11
13
  import { ZLPDataAPI } from "./ZLPDataAPI.mjs";
12
14
  export class ZLPAPI extends BaseAPI {
13
15
  constructor(network, provider, apiEndpoint, connectionURL) {
14
16
  super(network, provider, apiEndpoint, connectionURL, LPToken.ZLP);
15
17
  this.dataAPI = new ZLPDataAPI(network, provider, apiEndpoint, connectionURL);
16
18
  }
19
+ zlpLpType() {
20
+ return `${this.consts.zoCore.package}::zlp::ZLP`;
21
+ }
22
+ positionTypeArgs(collateralToken, indexToken, long) {
23
+ return [
24
+ this.zlpLpType(),
25
+ this.consts.coins[collateralToken].module,
26
+ this.consts.coins[indexToken].module,
27
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
28
+ this.consts.coins[collateralToken].module,
29
+ ];
30
+ }
31
+ redeemTypeArgs(collateralToken, indexToken, long) {
32
+ return [
33
+ this.zlpLpType(),
34
+ this.consts.coins[collateralToken].module,
35
+ this.consts.coins[indexToken].module,
36
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
37
+ ];
38
+ }
39
+ async initV3OracleForTokens(tokens, tx, pythProUpdateBytes, includeEmaPrice, options) {
40
+ const result = await this.initV3OracleTxb(tokens, tx, {
41
+ rawUpdateBytes: pythProUpdateBytes,
42
+ includeEmaPrice,
43
+ ...options,
44
+ });
45
+ return { tx: result.tx, oracle: result.oracle };
46
+ }
47
+ /** Vault + symbol index tokens required for valuate_vault_v2 / valuate_symbol_v2. */
48
+ getValuationOracleTokens() {
49
+ const tokens = new Set(Object.keys(this.consts.zoCore.vaults));
50
+ for (const key of Object.keys(this.consts.zoCore.symbols)) {
51
+ const [, token] = parseSymbolKey(key);
52
+ tokens.add(token);
53
+ }
54
+ return [...tokens];
55
+ }
56
+ /** Pyth Pro oracle init for deposit / withdraw market valuation. */
57
+ async initValuationOracle(tx) {
58
+ const tokens = this.getValuationOracleTokens();
59
+ const pythProUpdateBytes = await this.fetchPythProUpdateBytesForTokens(tokens);
60
+ return this.initV3OracleForTokens(tokens, tx, pythProUpdateBytes);
61
+ }
62
+ async resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender) {
63
+ if (!sponsoredTx) {
64
+ return undefined;
65
+ }
66
+ const additional = collateralToken === 'sui' ? relayerFee : 0n;
67
+ if (additional === 0n) {
68
+ return undefined;
69
+ }
70
+ return resolveSpendableSuiCoin(tx, this.provider, this.requireSenderForSponsored(sender), additional);
71
+ }
17
72
  calcPositionReserveFeeAmount(_position) {
18
73
  throw new Error(`Method not implemented in ${this.constructor.name}.`);
19
74
  }
@@ -29,35 +84,10 @@ export class ZLPAPI extends BaseAPI {
29
84
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
30
85
  tx = await this.addReferral(referralAddress, tx);
31
86
  }
32
- // Initialize oracle transaction
33
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
34
- // Handle sponsored transaction case
35
- if (sponsoredTx) {
36
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
37
- sender: this.requireSenderForSponsored(sender),
38
- additionalSuiAmount: coin === 'sui' ? BigInt(amount) : 0n,
39
- });
40
- tx = oracle.tx;
41
- const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sponsoredTx: true, suiCoinObject: oracle.suiCoinObject, sender });
42
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
43
- tx.moveCall({
44
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
45
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
46
- arguments: [
47
- tx.object(this.consts.zoCore.market),
48
- tx.object(this.consts.zoCore.rebaseFeeModel),
49
- depositObject,
50
- tx.pure.u64(minAmountOut),
51
- vaultsValuation,
52
- symbolsValuation,
53
- ],
54
- });
55
- return tx;
56
- }
57
- // Handle non-sponsored transaction case
58
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
59
- const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sender });
60
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
87
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
88
+ tx = txWithOracle;
89
+ const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sponsoredTx, sender });
90
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
61
91
  tx.moveCall({
62
92
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
63
93
  typeArguments: [
@@ -86,35 +116,10 @@ export class ZLPAPI extends BaseAPI {
86
116
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
87
117
  tx = await this.addReferral(referralAddress, tx);
88
118
  }
89
- // Initialize oracle transaction
90
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
91
- // Handle sponsored transaction case
92
- if (sponsoredTx) {
93
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
94
- sender: this.requireSenderForSponsored(sender),
95
- additionalSuiAmount: coin === 'sui' ? BigInt(amount) : 0n,
96
- });
97
- tx = oracle.tx;
98
- const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sponsoredTx: true, suiCoinObject: oracle.suiCoinObject, sender });
99
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
100
- const [mintedCoin] = tx.moveCall({
101
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
102
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
103
- arguments: [
104
- tx.object(this.consts.zoCore.market),
105
- tx.object(this.consts.zoCore.rebaseFeeModel),
106
- depositObject,
107
- tx.pure.u64(minAmountOut),
108
- vaultsValuation,
109
- symbolsValuation,
110
- ],
111
- });
112
- return mintedCoin;
113
- }
114
- // Handle non-sponsored transaction case
115
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
116
- const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sender });
117
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
119
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
120
+ tx = txWithOracle;
121
+ const depositObject = await this.resolveSplitCoinObject(tx, coin, BigInt(amount), coinObjects, { sponsoredTx, sender });
122
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
118
123
  const [mintedCoin] = tx.moveCall({
119
124
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
120
125
  typeArguments: [
@@ -132,7 +137,7 @@ export class ZLPAPI extends BaseAPI {
132
137
  });
133
138
  return mintedCoin;
134
139
  }
135
- async depositWithPtb(coin, depositObject, minAmountOut = 0, referralAddress, sender, tx, sponsoredTx) {
140
+ async depositWithPtb(coin, depositObject, minAmountOut = 0, referralAddress, sender, tx, _sponsoredTx) {
136
141
  if (!tx) {
137
142
  tx = new Transaction();
138
143
  }
@@ -140,34 +145,9 @@ export class ZLPAPI extends BaseAPI {
140
145
  if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
141
146
  tx = await this.addReferral(referralAddress, tx);
142
147
  }
143
- // Initialize oracle transaction
144
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
145
- // Handle sponsored transaction case
146
- if (sponsoredTx) {
147
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
148
- sender: this.requireSenderForSponsored(sender),
149
- additionalSuiAmount: 0n,
150
- });
151
- tx = oracle.tx;
152
- const { suiCoinObject } = oracle;
153
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
154
- tx.moveCall({
155
- target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
156
- typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
157
- arguments: [
158
- tx.object(this.consts.zoCore.market),
159
- tx.object(this.consts.zoCore.rebaseFeeModel),
160
- depositObject,
161
- tx.pure.u64(minAmountOut),
162
- vaultsValuation,
163
- symbolsValuation,
164
- ],
165
- });
166
- return tx;
167
- }
168
- // Handle non-sponsored transaction case
169
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
170
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
148
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
149
+ tx = txWithOracle;
150
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
171
151
  tx.moveCall({
172
152
  target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
173
153
  typeArguments: [
@@ -193,22 +173,10 @@ export class ZLPAPI extends BaseAPI {
193
173
  throw new Error(`${this.constructor.name}: lpCoinObjects or sender is required`);
194
174
  }
195
175
  let tx = new Transaction();
196
- // Initialize oracle transaction
197
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
198
- let suiCoinObject;
199
- if (sponsoredTx) {
200
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
201
- sender: this.requireSenderForSponsored(sender),
202
- additionalSuiAmount: 0n,
203
- });
204
- tx = oracle.tx;
205
- suiCoinObject = oracle.suiCoinObject;
206
- }
207
- else {
208
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
209
- }
210
- const withdrawObject = await this.resolveSplitCoinObject(tx, 'zlp', BigInt(amount), lpCoinObjects, { sponsoredTx, suiCoinObject, sender });
211
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
176
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
177
+ tx = txWithOracle;
178
+ const withdrawObject = await this.resolveSplitCoinObject(tx, 'zlp', BigInt(amount), lpCoinObjects, { sponsoredTx, sender });
179
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
212
180
  tx.moveCall({
213
181
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
214
182
  typeArguments: [
@@ -233,10 +201,9 @@ export class ZLPAPI extends BaseAPI {
233
201
  if (!tx) {
234
202
  tx = new Transaction();
235
203
  }
236
- // Initialize oracle transaction
237
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
238
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
239
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
204
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
205
+ tx = txWithOracle;
206
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
240
207
  tx.moveCall({
241
208
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
242
209
  typeArguments: [
@@ -261,22 +228,10 @@ export class ZLPAPI extends BaseAPI {
261
228
  if (!tx) {
262
229
  tx = new Transaction();
263
230
  }
264
- // Initialize oracle transaction
265
- const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder);
266
- let suiCoinObject;
267
- if (sponsoredTx) {
268
- const oracle = await this.initOracleTxb(pythFeederKeys, tx, true, {
269
- sender: this.requireSenderForSponsored(sender),
270
- additionalSuiAmount: 0n,
271
- });
272
- tx = oracle.tx;
273
- suiCoinObject = oracle.suiCoinObject;
274
- }
275
- else {
276
- tx = (await this.initOracleTxb(pythFeederKeys, tx)).tx;
277
- }
278
- const withdrawObject = await this.resolveSplitCoinObject(tx, 'zlp', BigInt(amount), lpCoinObjects, { sponsoredTx, suiCoinObject, sender });
279
- const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx);
231
+ const { tx: txWithOracle, oracle: oracleBundle } = await this.initValuationOracle(tx);
232
+ tx = txWithOracle;
233
+ const withdrawObject = await this.resolveSplitCoinObject(tx, 'zlp', BigInt(amount), lpCoinObjects, { sponsoredTx, sender });
234
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuateV2(tx, oracleBundle);
280
235
  const [withdrawCoin] = tx.moveCall({
281
236
  target: `${this.consts.zoCore.upgradedPackage}::market::withdraw_ptb`,
282
237
  typeArguments: [
@@ -2063,5 +2018,383 @@ export class ZLPAPI extends BaseAPI {
2063
2018
  });
2064
2019
  return tx;
2065
2020
  }
2021
+ // --- Pyth Pro + Stork (v3) ---
2022
+ /**
2023
+ * Swaps tokens using swap_v3 (Pyth Pro + Stork). Transfers output to sender.
2024
+ */
2025
+ async swapV3(fromToken, toToken, fromAmount, fromCoinObjects, pythProUpdateBytes, minAmountOut, tx) {
2026
+ if (!tx) {
2027
+ tx = new Transaction();
2028
+ }
2029
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(Object.keys(this.consts.zoCore.vaults), tx, pythProUpdateBytes, true);
2030
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects);
2031
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)]);
2032
+ const vaultsValuation = this.dataAPI.valuateVaultsV2(tx_, oracle);
2033
+ tx_.moveCall({
2034
+ target: `${this.consts.zoCore.upgradedPackage}::market::swap_v3`,
2035
+ typeArguments: [
2036
+ this.zlpLpType(),
2037
+ this.consts.coins[fromToken].module,
2038
+ this.consts.coins[toToken].module,
2039
+ ],
2040
+ arguments: [
2041
+ tx_.object(this.consts.zoCore.market),
2042
+ tx_.object(this.consts.zoCore.rebaseFeeModel),
2043
+ fromDepositObject,
2044
+ tx_.pure.u64(minAmountOut || 0),
2045
+ vaultsValuation,
2046
+ ...oracleArgsStandard(oracle),
2047
+ ],
2048
+ });
2049
+ return tx_;
2050
+ }
2051
+ /**
2052
+ * Swaps tokens and returns the output coin (swap_v3_ptb).
2053
+ */
2054
+ async swapV3Ptb(fromToken, toToken, fromAmount, fromCoinObjects, pythProUpdateBytes, minAmountOut, tx) {
2055
+ if (!tx) {
2056
+ tx = new Transaction();
2057
+ }
2058
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens(Object.keys(this.consts.zoCore.vaults), tx, pythProUpdateBytes, true);
2059
+ const fromCoinObject = this.processCoins(tx_, fromToken, fromCoinObjects);
2060
+ const [fromDepositObject] = tx_.splitCoins(fromCoinObject, [tx_.pure.u64(fromAmount)]);
2061
+ const vaultsValuation = this.dataAPI.valuateVaultsV2(tx_, oracle);
2062
+ const [outputCoin] = tx_.moveCall({
2063
+ target: `${this.consts.zoCore.upgradedPackage}::market::swap_v3_ptb`,
2064
+ typeArguments: [
2065
+ this.zlpLpType(),
2066
+ this.consts.coins[fromToken].module,
2067
+ this.consts.coins[toToken].module,
2068
+ ],
2069
+ arguments: [
2070
+ tx_.object(this.consts.zoCore.market),
2071
+ tx_.object(this.consts.zoCore.rebaseFeeModel),
2072
+ fromDepositObject,
2073
+ tx_.pure.u64(minAmountOut || 0),
2074
+ vaultsValuation,
2075
+ ...oracleArgsStandard(oracle),
2076
+ ],
2077
+ });
2078
+ return outputCoin;
2079
+ }
2080
+ /**
2081
+ * Opens a position using open_position_v3 (Pyth Pro + Stork).
2082
+ */
2083
+ async openPositionV3(collateralToken, indexToken, size, collateralAmount, coinObjects, long, reserveAmount, indexPrice, collateralPrice, pythProUpdateBytes, isLimitOrder, isIocOrder, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), referralAddress, sender, sponsoredTx) {
2084
+ let tx = new Transaction();
2085
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2086
+ tx = await this.addReferral(referralAddress, tx);
2087
+ }
2088
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken);
2089
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage);
2090
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2091
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2092
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2093
+ if (isLimitOrder) {
2094
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2095
+ }
2096
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2097
+ tx = tx_;
2098
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender);
2099
+ const [depositObject, feeObject] = this.processCoinSplitting(tx, collateralToken, coinObjects, [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)], sponsoredTx, suiCoinObject);
2100
+ tx.moveCall({
2101
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v3`,
2102
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2103
+ arguments: [
2104
+ tx.object(SUI_CLOCK_OBJECT_ID),
2105
+ tx.object(this.consts.zoCore.market),
2106
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
2107
+ ...oracleArgsStandard(oracle),
2108
+ depositObject,
2109
+ feeObject,
2110
+ tx.pure.u8(allowTrade),
2111
+ tx.pure.u64(size),
2112
+ tx.pure.u64(reserveAmount),
2113
+ tx.pure.u256(adjustCollateralPrice),
2114
+ tx.pure.u256(adjustPrice),
2115
+ tx.pure.u256(indexPriceThreshold),
2116
+ ],
2117
+ });
2118
+ return tx;
2119
+ }
2120
+ /**
2121
+ * Opens a position with S Card using open_position_with_scard_v3.
2122
+ */
2123
+ async openPositionWithSCardV3(collateralToken, indexToken, size, collateralAmount, coinObjects, long, reserveAmount, indexPrice, collateralPrice, kioskClient, kioskCap, scard, pythProUpdateBytes, isLimitOrder, isIocOrder, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), referralAddress, sender, sponsoredTx) {
2124
+ let tx = new Transaction();
2125
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2126
+ tx = await this.addReferral(referralAddress, tx);
2127
+ }
2128
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken);
2129
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage);
2130
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2131
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2132
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2133
+ if (isLimitOrder) {
2134
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2135
+ }
2136
+ const kioskTx = new KioskTransaction({
2137
+ transaction: tx,
2138
+ kioskClient,
2139
+ cap: kioskCap,
2140
+ });
2141
+ const [sudoCard, promise] = kioskTx.borrow({
2142
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2143
+ itemId: scard,
2144
+ });
2145
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2146
+ tx = tx_;
2147
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender);
2148
+ const [depositObject, feeObject] = this.processCoinSplitting(tx, collateralToken, coinObjects, [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)], sponsoredTx, suiCoinObject);
2149
+ tx.moveCall({
2150
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v3`,
2151
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2152
+ arguments: [
2153
+ tx.object(SUI_CLOCK_OBJECT_ID),
2154
+ tx.object(this.consts.zoCore.market),
2155
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
2156
+ ...oracleArgsStandard(oracle),
2157
+ depositObject,
2158
+ feeObject,
2159
+ tx.pure.u8(allowTrade),
2160
+ tx.pure.u64(size),
2161
+ tx.pure.u64(reserveAmount),
2162
+ tx.pure.u256(adjustCollateralPrice),
2163
+ tx.pure.u256(adjustPrice),
2164
+ tx.pure.u256(indexPriceThreshold),
2165
+ sudoCard,
2166
+ ],
2167
+ });
2168
+ kioskTx
2169
+ .return({
2170
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2171
+ item: sudoCard,
2172
+ promise,
2173
+ })
2174
+ .finalize();
2175
+ return tx;
2176
+ }
2177
+ /**
2178
+ * Opens a position with a pre-composed collateral coin using open_position_v3 (Pyth Pro + Stork).
2179
+ */
2180
+ async openPositionWithCoinV3(collateralToken, indexToken, size, coinObj, long, reserveAmount, indexPrice, collateralPrice, pythProUpdateBytes, isLimitOrder, isIocOrder, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), referralAddress, sender, tx, sponsoredTx) {
2181
+ if (!tx) {
2182
+ tx = new Transaction();
2183
+ }
2184
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2185
+ tx = await this.addReferral(referralAddress, tx);
2186
+ }
2187
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken);
2188
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage);
2189
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2190
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2191
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2192
+ if (isLimitOrder) {
2193
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2194
+ }
2195
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2196
+ tx = tx_;
2197
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)]);
2198
+ tx.moveCall({
2199
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v3`,
2200
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2201
+ arguments: [
2202
+ tx.object(SUI_CLOCK_OBJECT_ID),
2203
+ tx.object(this.consts.zoCore.market),
2204
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
2205
+ ...oracleArgsStandard(oracle),
2206
+ coinObj,
2207
+ feeObject,
2208
+ tx.pure.u8(allowTrade),
2209
+ tx.pure.u64(size),
2210
+ tx.pure.u64(reserveAmount),
2211
+ tx.pure.u256(adjustCollateralPrice),
2212
+ tx.pure.u256(adjustPrice),
2213
+ tx.pure.u256(indexPriceThreshold),
2214
+ ],
2215
+ });
2216
+ return tx;
2217
+ }
2218
+ /**
2219
+ * Opens a position with a pre-composed collateral coin and S Card using open_position_with_scard_v3.
2220
+ */
2221
+ async openPositionWithCoinAndSCardV3(collateralToken, indexToken, size, coinObj, long, reserveAmount, indexPrice, collateralPrice, kioskClient, kioskCap, scard, pythProUpdateBytes, isLimitOrder, isIocOrder, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), referralAddress, sender, tx, sponsoredTx) {
2222
+ if (!tx) {
2223
+ tx = new Transaction();
2224
+ }
2225
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
2226
+ tx = await this.addReferral(referralAddress, tx);
2227
+ }
2228
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken);
2229
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage);
2230
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2231
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2232
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2233
+ if (isLimitOrder) {
2234
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2235
+ }
2236
+ const kioskTx = new KioskTransaction({
2237
+ transaction: tx,
2238
+ kioskClient,
2239
+ cap: kioskCap,
2240
+ });
2241
+ const [sudoCard, promise] = kioskTx.borrow({
2242
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2243
+ itemId: scard,
2244
+ });
2245
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2246
+ tx = tx_;
2247
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)]);
2248
+ tx.moveCall({
2249
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v3`,
2250
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2251
+ arguments: [
2252
+ tx.object(SUI_CLOCK_OBJECT_ID),
2253
+ tx.object(this.consts.zoCore.market),
2254
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
2255
+ ...oracleArgsStandard(oracle),
2256
+ coinObj,
2257
+ feeObject,
2258
+ tx.pure.u8(allowTrade),
2259
+ tx.pure.u64(size),
2260
+ tx.pure.u64(reserveAmount),
2261
+ tx.pure.u256(adjustCollateralPrice),
2262
+ tx.pure.u256(adjustPrice),
2263
+ tx.pure.u256(indexPriceThreshold),
2264
+ sudoCard,
2265
+ ],
2266
+ });
2267
+ kioskTx
2268
+ .return({
2269
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2270
+ item: sudoCard,
2271
+ promise,
2272
+ })
2273
+ .finalize();
2274
+ return tx;
2275
+ }
2276
+ /**
2277
+ * Decreases a position using decrease_position_v3.
2278
+ */
2279
+ async decreasePositionV3(pcpId, collateralToken, indexToken, amount, long, indexPrice, collateralPrice, pythProUpdateBytes, isTriggerOrder = false, isTakeProfitOrder = true, isIocOrder = false, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), coinObjects, sponsoredTx, sender) {
2280
+ if (!coinObjects?.length && !sender) {
2281
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`);
2282
+ }
2283
+ let tx = new Transaction();
2284
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage);
2285
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2286
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2287
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2288
+ if (isTriggerOrder) {
2289
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2290
+ }
2291
+ else {
2292
+ isTakeProfitOrder = true;
2293
+ }
2294
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2295
+ tx = tx_;
2296
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender);
2297
+ const feeObject = await this.resolveRelayerFeeObject(tx, collateralToken, coinObjects ?? [], relayerFee, sponsoredTx, suiCoinObject, sender);
2298
+ tx.moveCall({
2299
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_v3`,
2300
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2301
+ arguments: [
2302
+ tx.object(SUI_CLOCK_OBJECT_ID),
2303
+ tx.object(this.consts.zoCore.market),
2304
+ tx.object(pcpId),
2305
+ ...oracleArgsStandard(oracle),
2306
+ feeObject,
2307
+ tx.pure.u8(allowTrade),
2308
+ tx.pure.bool(isTakeProfitOrder),
2309
+ tx.pure.u64(amount),
2310
+ tx.pure.u256(adjustCollateralPrice),
2311
+ tx.pure.u256(adjustPrice),
2312
+ tx.pure.u256(indexPriceThreshold),
2313
+ ],
2314
+ });
2315
+ return tx;
2316
+ }
2317
+ /**
2318
+ * Decreases a position with S Card using decrease_position_with_scard_v3.
2319
+ */
2320
+ async decreasePositionWithSCardV3(pcpId, collateralToken, indexToken, amount, long, indexPrice, collateralPrice, kioskClient, kioskCap, scard, pythProUpdateBytes, isTriggerOrder = false, isTakeProfitOrder = true, isIocOrder = false, pricesSlippage = 0.003, collateralSlippage = 0.5, relayerFee = BigInt(0.5), coinObjects, sponsoredTx, sender) {
2321
+ if (!coinObjects?.length && !sender) {
2322
+ throw new Error(`${this.constructor.name}: coinObjects or sender is required`);
2323
+ }
2324
+ let tx = new Transaction();
2325
+ const kioskTx = new KioskTransaction({
2326
+ transaction: tx,
2327
+ kioskClient,
2328
+ cap: kioskCap,
2329
+ });
2330
+ const [sudoCard, promise] = kioskTx.borrow({
2331
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2332
+ itemId: scard,
2333
+ });
2334
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage);
2335
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage);
2336
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage);
2337
+ let allowTrade = ALLOW_TRADE_MUST_TRADE;
2338
+ if (isTriggerOrder) {
2339
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE;
2340
+ }
2341
+ else {
2342
+ isTakeProfitOrder = true;
2343
+ }
2344
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2345
+ tx = tx_;
2346
+ const suiCoinObject = await this.resolveSponsoredSui(tx, collateralToken, relayerFee, sponsoredTx, sender);
2347
+ const feeObject = await this.resolveRelayerFeeObject(tx, collateralToken, coinObjects ?? [], relayerFee, sponsoredTx, suiCoinObject, sender);
2348
+ tx.moveCall({
2349
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard_v3`,
2350
+ typeArguments: this.positionTypeArgs(collateralToken, indexToken, long),
2351
+ arguments: [
2352
+ tx.object(SUI_CLOCK_OBJECT_ID),
2353
+ tx.object(this.consts.zoCore.market),
2354
+ tx.object(pcpId),
2355
+ ...oracleArgsStandard(oracle),
2356
+ feeObject,
2357
+ tx.pure.u8(allowTrade),
2358
+ tx.pure.bool(isTakeProfitOrder),
2359
+ tx.pure.u64(amount),
2360
+ tx.pure.u256(adjustCollateralPrice),
2361
+ tx.pure.u256(adjustPrice),
2362
+ tx.pure.u256(indexPriceThreshold),
2363
+ sudoCard,
2364
+ ],
2365
+ });
2366
+ kioskTx
2367
+ .return({
2368
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2369
+ item: sudoCard,
2370
+ promise,
2371
+ })
2372
+ .finalize();
2373
+ return tx;
2374
+ }
2375
+ /**
2376
+ * Redeems collateral from a position via redeem_from_position_v2 (Pyth Pro path).
2377
+ */
2378
+ async redeemFromPositionV2(pcpId, collateralToken, indexToken, amount, long, pythProUpdateBytes, tx) {
2379
+ if (!tx) {
2380
+ tx = new Transaction();
2381
+ }
2382
+ const { tx: tx_, oracle } = await this.initV3OracleForTokens([collateralToken, indexToken], tx, pythProUpdateBytes);
2383
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken);
2384
+ tx_.moveCall({
2385
+ target: `${this.consts.zoCore.upgradedPackage}::market::redeem_from_position_v2`,
2386
+ typeArguments: this.redeemTypeArgs(collateralToken, indexToken, long),
2387
+ arguments: [
2388
+ tx_.object(SUI_CLOCK_OBJECT_ID),
2389
+ tx_.object(this.consts.zoCore.market),
2390
+ tx_.object(pcpId),
2391
+ tx_.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
2392
+ tx_.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
2393
+ ...oracleArgsStandard(oracle),
2394
+ tx_.pure.u64(amount),
2395
+ ],
2396
+ });
2397
+ return tx_;
2398
+ }
2066
2399
  }
2067
2400
  //# sourceMappingURL=ZLPAPI.mjs.map