@zofai/zo-sdk 0.1.92

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 (275) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.gitattributes +4 -0
  3. package/.prettierrc.js +9 -0
  4. package/README.md +28 -0
  5. package/dist/abstract/BaseAPI.cjs +206 -0
  6. package/dist/abstract/BaseAPI.cjs.map +1 -0
  7. package/dist/abstract/BaseAPI.d.cts +172 -0
  8. package/dist/abstract/BaseAPI.d.cts.map +1 -0
  9. package/dist/abstract/BaseAPI.d.mts +172 -0
  10. package/dist/abstract/BaseAPI.d.mts.map +1 -0
  11. package/dist/abstract/BaseAPI.mjs +202 -0
  12. package/dist/abstract/BaseAPI.mjs.map +1 -0
  13. package/dist/abstract/BaseDataAPI.cjs +140 -0
  14. package/dist/abstract/BaseDataAPI.cjs.map +1 -0
  15. package/dist/abstract/BaseDataAPI.d.cts +89 -0
  16. package/dist/abstract/BaseDataAPI.d.cts.map +1 -0
  17. package/dist/abstract/BaseDataAPI.d.mts +89 -0
  18. package/dist/abstract/BaseDataAPI.d.mts.map +1 -0
  19. package/dist/abstract/BaseDataAPI.mjs +136 -0
  20. package/dist/abstract/BaseDataAPI.mjs.map +1 -0
  21. package/dist/abstract/index.cjs +12 -0
  22. package/dist/abstract/index.cjs.map +1 -0
  23. package/dist/abstract/index.d.cts +7 -0
  24. package/dist/abstract/index.d.cts.map +1 -0
  25. package/dist/abstract/index.d.mts +7 -0
  26. package/dist/abstract/index.d.mts.map +1 -0
  27. package/dist/abstract/index.mjs +7 -0
  28. package/dist/abstract/index.mjs.map +1 -0
  29. package/dist/api.cjs +779 -0
  30. package/dist/api.cjs.map +1 -0
  31. package/dist/api.d.cts +75 -0
  32. package/dist/api.d.cts.map +1 -0
  33. package/dist/api.d.mts +75 -0
  34. package/dist/api.d.mts.map +1 -0
  35. package/dist/api.mjs +775 -0
  36. package/dist/api.mjs.map +1 -0
  37. package/dist/bcs.cjs +42 -0
  38. package/dist/bcs.cjs.map +1 -0
  39. package/dist/bcs.d.cts +91 -0
  40. package/dist/bcs.d.cts.map +1 -0
  41. package/dist/bcs.d.mts +91 -0
  42. package/dist/bcs.d.mts.map +1 -0
  43. package/dist/bcs.mjs +39 -0
  44. package/dist/bcs.mjs.map +1 -0
  45. package/dist/consts/deployments-shared-mainnet.json +50 -0
  46. package/dist/consts/deployments-shared-testnet.json +45 -0
  47. package/dist/consts/deployments-slp-mainnet.json +600 -0
  48. package/dist/consts/deployments-slp-testnet.json +87 -0
  49. package/dist/consts/deployments-usdz-mainnet.json +494 -0
  50. package/dist/consts/deployments-usdz-testnet.json +98 -0
  51. package/dist/consts/deployments-zbtcvc-mainnet.json +180 -0
  52. package/dist/consts/deployments-zlp-mainnet.json +791 -0
  53. package/dist/consts/deployments-zlp-testnet.json +76 -0
  54. package/dist/consts/index.cjs +200 -0
  55. package/dist/consts/index.cjs.map +1 -0
  56. package/dist/consts/index.d.cts +157 -0
  57. package/dist/consts/index.d.cts.map +1 -0
  58. package/dist/consts/index.d.mts +157 -0
  59. package/dist/consts/index.d.mts.map +1 -0
  60. package/dist/consts/index.mjs +189 -0
  61. package/dist/consts/index.mjs.map +1 -0
  62. package/dist/consts/price_id_to_object_id.mainnet.json +56 -0
  63. package/dist/consts/price_id_to_object_id.testnet.json +17 -0
  64. package/dist/data.cjs +919 -0
  65. package/dist/data.cjs.map +1 -0
  66. package/dist/data.d.cts +235 -0
  67. package/dist/data.d.cts.map +1 -0
  68. package/dist/data.d.mts +235 -0
  69. package/dist/data.d.mts.map +1 -0
  70. package/dist/data.mjs +915 -0
  71. package/dist/data.mjs.map +1 -0
  72. package/dist/factory/SDKFactory.cjs +228 -0
  73. package/dist/factory/SDKFactory.cjs.map +1 -0
  74. package/dist/factory/SDKFactory.d.cts +84 -0
  75. package/dist/factory/SDKFactory.d.cts.map +1 -0
  76. package/dist/factory/SDKFactory.d.mts +84 -0
  77. package/dist/factory/SDKFactory.d.mts.map +1 -0
  78. package/dist/factory/SDKFactory.mjs +222 -0
  79. package/dist/factory/SDKFactory.mjs.map +1 -0
  80. package/dist/implementations/SLPAPI.cjs +1794 -0
  81. package/dist/implementations/SLPAPI.cjs.map +1 -0
  82. package/dist/implementations/SLPAPI.d.cts +183 -0
  83. package/dist/implementations/SLPAPI.d.cts.map +1 -0
  84. package/dist/implementations/SLPAPI.d.mts +183 -0
  85. package/dist/implementations/SLPAPI.d.mts.map +1 -0
  86. package/dist/implementations/SLPAPI.mjs +1790 -0
  87. package/dist/implementations/SLPAPI.mjs.map +1 -0
  88. package/dist/implementations/SLPDataAPI.cjs +1384 -0
  89. package/dist/implementations/SLPDataAPI.cjs.map +1 -0
  90. package/dist/implementations/SLPDataAPI.d.cts +158 -0
  91. package/dist/implementations/SLPDataAPI.d.cts.map +1 -0
  92. package/dist/implementations/SLPDataAPI.d.mts +158 -0
  93. package/dist/implementations/SLPDataAPI.d.mts.map +1 -0
  94. package/dist/implementations/SLPDataAPI.mjs +1380 -0
  95. package/dist/implementations/SLPDataAPI.mjs.map +1 -0
  96. package/dist/implementations/USDZAPI.cjs +1676 -0
  97. package/dist/implementations/USDZAPI.cjs.map +1 -0
  98. package/dist/implementations/USDZAPI.d.cts +180 -0
  99. package/dist/implementations/USDZAPI.d.cts.map +1 -0
  100. package/dist/implementations/USDZAPI.d.mts +180 -0
  101. package/dist/implementations/USDZAPI.d.mts.map +1 -0
  102. package/dist/implementations/USDZAPI.mjs +1672 -0
  103. package/dist/implementations/USDZAPI.mjs.map +1 -0
  104. package/dist/implementations/USDZDataAPI.cjs +1209 -0
  105. package/dist/implementations/USDZDataAPI.cjs.map +1 -0
  106. package/dist/implementations/USDZDataAPI.d.cts +191 -0
  107. package/dist/implementations/USDZDataAPI.d.cts.map +1 -0
  108. package/dist/implementations/USDZDataAPI.d.mts +191 -0
  109. package/dist/implementations/USDZDataAPI.d.mts.map +1 -0
  110. package/dist/implementations/USDZDataAPI.mjs +1205 -0
  111. package/dist/implementations/USDZDataAPI.mjs.map +1 -0
  112. package/dist/implementations/ZBTCVCAPI.cjs +906 -0
  113. package/dist/implementations/ZBTCVCAPI.cjs.map +1 -0
  114. package/dist/implementations/ZBTCVCAPI.d.cts +107 -0
  115. package/dist/implementations/ZBTCVCAPI.d.cts.map +1 -0
  116. package/dist/implementations/ZBTCVCAPI.d.mts +107 -0
  117. package/dist/implementations/ZBTCVCAPI.d.mts.map +1 -0
  118. package/dist/implementations/ZBTCVCAPI.mjs +902 -0
  119. package/dist/implementations/ZBTCVCAPI.mjs.map +1 -0
  120. package/dist/implementations/ZBTCVCDataAPI.cjs +829 -0
  121. package/dist/implementations/ZBTCVCDataAPI.cjs.map +1 -0
  122. package/dist/implementations/ZBTCVCDataAPI.d.cts +94 -0
  123. package/dist/implementations/ZBTCVCDataAPI.d.cts.map +1 -0
  124. package/dist/implementations/ZBTCVCDataAPI.d.mts +94 -0
  125. package/dist/implementations/ZBTCVCDataAPI.d.mts.map +1 -0
  126. package/dist/implementations/ZBTCVCDataAPI.mjs +825 -0
  127. package/dist/implementations/ZBTCVCDataAPI.mjs.map +1 -0
  128. package/dist/implementations/ZLPAPI.cjs +1948 -0
  129. package/dist/implementations/ZLPAPI.cjs.map +1 -0
  130. package/dist/implementations/ZLPAPI.d.cts +192 -0
  131. package/dist/implementations/ZLPAPI.d.cts.map +1 -0
  132. package/dist/implementations/ZLPAPI.d.mts +192 -0
  133. package/dist/implementations/ZLPAPI.d.mts.map +1 -0
  134. package/dist/implementations/ZLPAPI.mjs +1944 -0
  135. package/dist/implementations/ZLPAPI.mjs.map +1 -0
  136. package/dist/implementations/ZLPDataAPI.cjs +1267 -0
  137. package/dist/implementations/ZLPDataAPI.cjs.map +1 -0
  138. package/dist/implementations/ZLPDataAPI.d.cts +193 -0
  139. package/dist/implementations/ZLPDataAPI.d.cts.map +1 -0
  140. package/dist/implementations/ZLPDataAPI.d.mts +193 -0
  141. package/dist/implementations/ZLPDataAPI.d.mts.map +1 -0
  142. package/dist/implementations/ZLPDataAPI.mjs +1263 -0
  143. package/dist/implementations/ZLPDataAPI.mjs.map +1 -0
  144. package/dist/implementations/index.cjs +26 -0
  145. package/dist/implementations/index.cjs.map +1 -0
  146. package/dist/implementations/index.d.cts +13 -0
  147. package/dist/implementations/index.d.cts.map +1 -0
  148. package/dist/implementations/index.d.mts +13 -0
  149. package/dist/implementations/index.d.mts.map +1 -0
  150. package/dist/implementations/index.mjs +15 -0
  151. package/dist/implementations/index.mjs.map +1 -0
  152. package/dist/index.cjs +69 -0
  153. package/dist/index.cjs.map +1 -0
  154. package/dist/index.d.cts +51 -0
  155. package/dist/index.d.cts.map +1 -0
  156. package/dist/index.d.mts +51 -0
  157. package/dist/index.d.mts.map +1 -0
  158. package/dist/index.mjs +51 -0
  159. package/dist/index.mjs.map +1 -0
  160. package/dist/interfaces/base.cjs +7 -0
  161. package/dist/interfaces/base.cjs.map +1 -0
  162. package/dist/interfaces/base.d.cts +346 -0
  163. package/dist/interfaces/base.d.cts.map +1 -0
  164. package/dist/interfaces/base.d.mts +346 -0
  165. package/dist/interfaces/base.d.mts.map +1 -0
  166. package/dist/interfaces/base.mjs +6 -0
  167. package/dist/interfaces/base.mjs.map +1 -0
  168. package/dist/interfaces/index.cjs +31 -0
  169. package/dist/interfaces/index.cjs.map +1 -0
  170. package/dist/interfaces/index.d.cts +15 -0
  171. package/dist/interfaces/index.d.cts.map +1 -0
  172. package/dist/interfaces/index.d.mts +15 -0
  173. package/dist/interfaces/index.d.mts.map +1 -0
  174. package/dist/interfaces/index.mjs +15 -0
  175. package/dist/interfaces/index.mjs.map +1 -0
  176. package/dist/interfaces/slp.cjs +7 -0
  177. package/dist/interfaces/slp.cjs.map +1 -0
  178. package/dist/interfaces/slp.d.cts +179 -0
  179. package/dist/interfaces/slp.d.cts.map +1 -0
  180. package/dist/interfaces/slp.d.mts +179 -0
  181. package/dist/interfaces/slp.d.mts.map +1 -0
  182. package/dist/interfaces/slp.mjs +6 -0
  183. package/dist/interfaces/slp.mjs.map +1 -0
  184. package/dist/interfaces/usdz.cjs +7 -0
  185. package/dist/interfaces/usdz.cjs.map +1 -0
  186. package/dist/interfaces/usdz.d.cts +104 -0
  187. package/dist/interfaces/usdz.d.cts.map +1 -0
  188. package/dist/interfaces/usdz.d.mts +104 -0
  189. package/dist/interfaces/usdz.d.mts.map +1 -0
  190. package/dist/interfaces/usdz.mjs +6 -0
  191. package/dist/interfaces/usdz.mjs.map +1 -0
  192. package/dist/interfaces/zbtcvc.cjs +7 -0
  193. package/dist/interfaces/zbtcvc.cjs.map +1 -0
  194. package/dist/interfaces/zbtcvc.d.cts +64 -0
  195. package/dist/interfaces/zbtcvc.d.cts.map +1 -0
  196. package/dist/interfaces/zbtcvc.d.mts +64 -0
  197. package/dist/interfaces/zbtcvc.d.mts.map +1 -0
  198. package/dist/interfaces/zbtcvc.mjs +6 -0
  199. package/dist/interfaces/zbtcvc.mjs.map +1 -0
  200. package/dist/interfaces/zlp.cjs +7 -0
  201. package/dist/interfaces/zlp.cjs.map +1 -0
  202. package/dist/interfaces/zlp.d.cts +114 -0
  203. package/dist/interfaces/zlp.d.cts.map +1 -0
  204. package/dist/interfaces/zlp.d.mts +114 -0
  205. package/dist/interfaces/zlp.d.mts.map +1 -0
  206. package/dist/interfaces/zlp.mjs +6 -0
  207. package/dist/interfaces/zlp.mjs.map +1 -0
  208. package/dist/oracle.cjs +118 -0
  209. package/dist/oracle.cjs.map +1 -0
  210. package/dist/oracle.d.cts +25 -0
  211. package/dist/oracle.d.cts.map +1 -0
  212. package/dist/oracle.d.mts +25 -0
  213. package/dist/oracle.d.mts.map +1 -0
  214. package/dist/oracle.mjs +114 -0
  215. package/dist/oracle.mjs.map +1 -0
  216. package/dist/utils.cjs +129 -0
  217. package/dist/utils.cjs.map +1 -0
  218. package/dist/utils.d.cts +44 -0
  219. package/dist/utils.d.cts.map +1 -0
  220. package/dist/utils.d.mts +44 -0
  221. package/dist/utils.d.mts.map +1 -0
  222. package/dist/utils.mjs +115 -0
  223. package/dist/utils.mjs.map +1 -0
  224. package/docs/SUMMARY.md +10 -0
  225. package/docs/api-reference.md +32 -0
  226. package/docs/architecture.md +14 -0
  227. package/docs/common-operations.md +52 -0
  228. package/docs/error-handling.md +17 -0
  229. package/docs/getting-started.md +60 -0
  230. package/docs/introduction.md +15 -0
  231. package/docs/lp-specific-features.md +96 -0
  232. package/docs/type-safety.md +29 -0
  233. package/eslint.config.mjs +18 -0
  234. package/package.json +42 -0
  235. package/src/abstract/BaseAPI.ts +575 -0
  236. package/src/abstract/BaseDataAPI.ts +207 -0
  237. package/src/abstract/index.ts +7 -0
  238. package/src/api.ts +1100 -0
  239. package/src/bcs.ts +45 -0
  240. package/src/consts/deployments-shared-mainnet.json +50 -0
  241. package/src/consts/deployments-shared-testnet.json +45 -0
  242. package/src/consts/deployments-slp-mainnet.json +600 -0
  243. package/src/consts/deployments-slp-testnet.json +87 -0
  244. package/src/consts/deployments-usdz-mainnet.json +494 -0
  245. package/src/consts/deployments-usdz-testnet.json +98 -0
  246. package/src/consts/deployments-zbtcvc-mainnet.json +180 -0
  247. package/src/consts/deployments-zlp-mainnet.json +791 -0
  248. package/src/consts/deployments-zlp-testnet.json +76 -0
  249. package/src/consts/index.ts +345 -0
  250. package/src/consts/price_id_to_object_id.mainnet.json +56 -0
  251. package/src/consts/price_id_to_object_id.testnet.json +17 -0
  252. package/src/data.ts +1279 -0
  253. package/src/factory/SDKFactory.ts +340 -0
  254. package/src/implementations/SLPAPI.ts +2722 -0
  255. package/src/implementations/SLPDataAPI.ts +1839 -0
  256. package/src/implementations/USDZAPI.ts +2488 -0
  257. package/src/implementations/USDZDataAPI.ts +1548 -0
  258. package/src/implementations/ZBTCVCAPI.ts +1337 -0
  259. package/src/implementations/ZBTCVCDataAPI.ts +993 -0
  260. package/src/implementations/ZLPAPI.ts +2888 -0
  261. package/src/implementations/ZLPDataAPI.ts +1603 -0
  262. package/src/implementations/index.ts +16 -0
  263. package/src/index.ts +58 -0
  264. package/src/interfaces/base.ts +838 -0
  265. package/src/interfaces/index.ts +50 -0
  266. package/src/interfaces/slp.ts +268 -0
  267. package/src/interfaces/usdz.ts +181 -0
  268. package/src/interfaces/zbtcvc.ts +116 -0
  269. package/src/interfaces/zlp.ts +244 -0
  270. package/src/oracle.ts +153 -0
  271. package/src/utils.ts +168 -0
  272. package/tests/api.test.ts +219 -0
  273. package/tests/data.test.ts +156 -0
  274. package/tests/oracle.test.ts +33 -0
  275. package/tsconfig.json +22 -0
@@ -0,0 +1,2888 @@
1
+ /**
2
+ * ZLP API implementation
3
+ * Implements ZLP-specific trading and transaction methods
4
+ */
5
+
6
+ import type { KioskClient, KioskOwnerCap } from '@mysten/kiosk'
7
+ import { KioskTransaction } from '@mysten/kiosk'
8
+ import type { SuiClient } from '@mysten/sui/client'
9
+ import type { TransactionObjectArgument } from '@mysten/sui/transactions'
10
+ import { Transaction } from '@mysten/sui/transactions'
11
+ import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils'
12
+
13
+ import { BaseAPI } from '../abstract'
14
+ import type { Network } from '../consts'
15
+ import { ALLOW_TRADE_CAN_TRADE, ALLOW_TRADE_MUST_TRADE, ALLOW_TRADE_NO_TRADE, LPToken } from '../consts'
16
+ import type {
17
+ IBasePositionInfo,
18
+ IZLPAPI,
19
+ IZLPCredential,
20
+ } from '../interfaces'
21
+ import { joinSymbol } from '../utils'
22
+ import { ZLPDataAPI } from './ZLPDataAPI'
23
+
24
+ export class ZLPAPI extends BaseAPI implements IZLPAPI {
25
+ public dataAPI: ZLPDataAPI
26
+
27
+ constructor(
28
+ network: Network,
29
+ provider: SuiClient,
30
+ apiEndpoint: string,
31
+ connectionURL: string,
32
+ ) {
33
+ super(network, provider, apiEndpoint, connectionURL, LPToken.ZLP)
34
+ this.dataAPI = new ZLPDataAPI(network, provider, apiEndpoint, connectionURL)
35
+ }
36
+
37
+ public calcPositionReserveFeeAmount(_position: IBasePositionInfo): Promise<number> {
38
+ throw new Error(`Method not implemented in ${this.constructor.name}.`)
39
+ }
40
+
41
+ public calcPositionFundingFeeValue(_position: IBasePositionInfo): Promise<number> {
42
+ throw new Error(`Method not implemented in ${this.constructor.name}.`)
43
+ }
44
+
45
+ /**
46
+ * Deposits collateral into ZLP vault
47
+ */
48
+ public async deposit(
49
+ coin: string,
50
+ coinObjects: string[],
51
+ amount: number,
52
+ minAmountOut = 0,
53
+ referralAddress?: string,
54
+ sender?: string,
55
+ sponsoredTx?: boolean,
56
+ suiCoinObjectsForPythUpdate?: string[],
57
+ ): Promise<Transaction> {
58
+ let tx = new Transaction()
59
+
60
+ // Add referral if needed
61
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
62
+ tx = await this.addReferral(referralAddress, tx)
63
+ }
64
+
65
+ // Initialize oracle transaction
66
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
67
+
68
+ // Handle sponsored transaction case
69
+ if (sponsoredTx) {
70
+ const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
71
+ tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
72
+
73
+ // Process deposit coins
74
+ const depositObject = coin === 'sui'
75
+ ? tx.splitCoins(suiCoinObject, [tx.pure.u64(amount)])[0]
76
+ : tx.splitCoins(this.processCoins(tx, coin, coinObjects, true), [tx.pure.u64(amount)])[0]
77
+
78
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
79
+
80
+ tx.moveCall({
81
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
82
+ typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
83
+ arguments: [
84
+ tx.object(this.consts.zoCore.market),
85
+ tx.object(this.consts.zoCore.rebaseFeeModel),
86
+ depositObject,
87
+ tx.pure.u64(minAmountOut),
88
+ vaultsValuation,
89
+ symbolsValuation,
90
+ ],
91
+ })
92
+ return tx
93
+ }
94
+
95
+ // Handle non-sponsored transaction case
96
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
97
+ const depositObject = tx.splitCoins(
98
+ this.processCoins(tx, coin, coinObjects, false),
99
+ [tx.pure.u64(amount)],
100
+ )[0]
101
+
102
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
103
+
104
+ tx.moveCall({
105
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
106
+ typeArguments: [
107
+ `${this.consts.zoCore.package}::zlp::ZLP`,
108
+ this.consts.coins[coin].module,
109
+ ],
110
+ arguments: [
111
+ tx.object(this.consts.zoCore.market),
112
+ tx.object(this.consts.zoCore.rebaseFeeModel),
113
+ depositObject,
114
+ tx.pure.u64(minAmountOut),
115
+ vaultsValuation,
116
+ symbolsValuation,
117
+ ],
118
+ })
119
+ return tx
120
+ }
121
+
122
+ /**
123
+ * Deposits collateral into ZLP vault and returns a coin
124
+ */
125
+ public async depositPtb(
126
+ coin: string,
127
+ coinObjects: string[],
128
+ amount: number,
129
+ minAmountOut = 0,
130
+ referralAddress?: string,
131
+ sender?: string,
132
+ tx?: Transaction,
133
+ sponsoredTx?: boolean,
134
+ suiCoinObjectsForPythUpdate?: string[],
135
+ ): Promise<TransactionObjectArgument> {
136
+ if (!tx) {
137
+ tx = new Transaction()
138
+ }
139
+
140
+ // Add referral if needed
141
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
142
+ tx = await this.addReferral(referralAddress, tx)
143
+ }
144
+
145
+ // Initialize oracle transaction
146
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
147
+
148
+ // Handle sponsored transaction case
149
+ if (sponsoredTx) {
150
+ const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
151
+ tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
152
+
153
+ // Process deposit coins
154
+ const depositObject = coin === 'sui'
155
+ ? tx.splitCoins(suiCoinObject, [tx.pure.u64(amount)])[0]
156
+ : tx.splitCoins(this.processCoins(tx, coin, coinObjects, true), [tx.pure.u64(amount)])[0]
157
+
158
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
159
+
160
+ const [mintedCoin] = tx.moveCall({
161
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
162
+ typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
163
+ arguments: [
164
+ tx.object(this.consts.zoCore.market),
165
+ tx.object(this.consts.zoCore.rebaseFeeModel),
166
+ depositObject,
167
+ tx.pure.u64(minAmountOut),
168
+ vaultsValuation,
169
+ symbolsValuation,
170
+ ],
171
+ })
172
+ return mintedCoin
173
+ }
174
+
175
+ // Handle non-sponsored transaction case
176
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
177
+ const depositObject = tx.splitCoins(
178
+ this.processCoins(tx, coin, coinObjects, false),
179
+ [tx.pure.u64(amount)],
180
+ )[0]
181
+
182
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
183
+
184
+ const [mintedCoin] = tx.moveCall({
185
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
186
+ typeArguments: [
187
+ `${this.consts.zoCore.package}::zlp::ZLP`,
188
+ this.consts.coins[coin].module,
189
+ ],
190
+ arguments: [
191
+ tx.object(this.consts.zoCore.market),
192
+ tx.object(this.consts.zoCore.rebaseFeeModel),
193
+ depositObject,
194
+ tx.pure.u64(minAmountOut),
195
+ vaultsValuation,
196
+ symbolsValuation,
197
+ ],
198
+ })
199
+
200
+ return mintedCoin
201
+ }
202
+
203
+ public async depositWithPtb(
204
+ coin: string,
205
+ depositObject: TransactionObjectArgument,
206
+ minAmountOut = 0,
207
+ referralAddress?: string,
208
+ sender?: string,
209
+ tx?: Transaction,
210
+ sponsoredTx?: boolean,
211
+ suiCoinObjectsForPythUpdate?: string[],
212
+ ): Promise<Transaction> {
213
+ if (!tx) {
214
+ tx = new Transaction()
215
+ }
216
+
217
+ // Add referral if needed
218
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
219
+ tx = await this.addReferral(referralAddress, tx)
220
+ }
221
+
222
+ // Initialize oracle transaction
223
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
224
+
225
+ // Handle sponsored transaction case
226
+ if (sponsoredTx) {
227
+ const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
228
+ tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
229
+
230
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
231
+
232
+ tx.moveCall({
233
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
234
+ typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`, this.consts.coins[coin].module],
235
+ arguments: [
236
+ tx.object(this.consts.zoCore.market),
237
+ tx.object(this.consts.zoCore.rebaseFeeModel),
238
+ depositObject,
239
+ tx.pure.u64(minAmountOut),
240
+ vaultsValuation,
241
+ symbolsValuation,
242
+ ],
243
+ })
244
+ return tx
245
+ }
246
+
247
+ // Handle non-sponsored transaction case
248
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
249
+
250
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
251
+
252
+ tx.moveCall({
253
+ target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
254
+ typeArguments: [
255
+ `${this.consts.zoCore.package}::zlp::ZLP`,
256
+ this.consts.coins[coin].module,
257
+ ],
258
+ arguments: [
259
+ tx.object(this.consts.zoCore.market),
260
+ tx.object(this.consts.zoCore.rebaseFeeModel),
261
+ depositObject,
262
+ tx.pure.u64(minAmountOut),
263
+ vaultsValuation,
264
+ symbolsValuation,
265
+ ],
266
+ })
267
+ return tx
268
+ }
269
+
270
+ /**
271
+ * Withdraws collateral from ZLP vault
272
+ */
273
+ public async withdraw(
274
+ coin: string,
275
+ lpCoinObjects: string[],
276
+ amount: number,
277
+ minAmountOut = 0,
278
+ sponsoredTx?: boolean,
279
+ suiCoinObjectsForPythUpdate?: string[],
280
+ ): Promise<Transaction> {
281
+ let tx = new Transaction()
282
+
283
+ // Initialize oracle transaction
284
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
285
+
286
+ if (sponsoredTx) {
287
+ const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
288
+ tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
289
+ }
290
+ else {
291
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
292
+ }
293
+ const zlpCoinObject = this.processCoins(tx, 'zlp', lpCoinObjects, false)
294
+ const [withdrawObject] = tx.splitCoins(zlpCoinObject, [tx.pure.u64(amount)])
295
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
296
+
297
+ tx.moveCall({
298
+ target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
299
+ typeArguments: [
300
+ `${this.consts.zoCore.package}::zlp::ZLP`,
301
+ this.consts.coins[coin].module,
302
+ ],
303
+ arguments: [
304
+ tx.object(this.consts.zoCore.market),
305
+ tx.object(this.consts.zoCore.rebaseFeeModel),
306
+ withdrawObject,
307
+ tx.pure.u64(minAmountOut),
308
+ vaultsValuation,
309
+ symbolsValuation,
310
+ ],
311
+ })
312
+ return tx
313
+ }
314
+
315
+ /**
316
+ * Withdraws LP coin object from ZLP vault
317
+ */
318
+ public async withdrawLpCoinObject(
319
+ coin: string,
320
+ lpCoinObject: TransactionObjectArgument,
321
+ minAmountOut = 0,
322
+ tx?: Transaction,
323
+ ): Promise<Transaction> {
324
+ if (!tx) {
325
+ tx = new Transaction()
326
+ }
327
+ // Initialize oracle transaction
328
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
329
+
330
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
331
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
332
+
333
+ tx.moveCall({
334
+ target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
335
+ typeArguments: [
336
+ `${this.consts.zoCore.package}::zlp::ZLP`,
337
+ this.consts.coins[coin].module,
338
+ ],
339
+ arguments: [
340
+ tx.object(this.consts.zoCore.market),
341
+ tx.object(this.consts.zoCore.rebaseFeeModel),
342
+ lpCoinObject,
343
+ tx.pure.u64(minAmountOut),
344
+ vaultsValuation,
345
+ symbolsValuation,
346
+ ],
347
+ })
348
+ return tx
349
+ }
350
+
351
+ public async withdrawPtb(
352
+ coin: string,
353
+ lpCoinObjects: string[],
354
+ amount: number,
355
+ minAmountOut = 0,
356
+ tx?: Transaction,
357
+ sponsoredTx?: boolean,
358
+ suiCoinObjectsForPythUpdate?: string[],
359
+ ): Promise<TransactionObjectArgument> {
360
+ if (!tx) {
361
+ tx = new Transaction()
362
+ }
363
+
364
+ // Initialize oracle transaction
365
+ const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
366
+
367
+ if (sponsoredTx) {
368
+ const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
369
+ tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
370
+ }
371
+ else {
372
+ tx = await this.initOracleTxb(pythFeederKeys, tx)
373
+ }
374
+ const zlpCoinObject = this.processCoins(tx, 'zlp', lpCoinObjects, false)
375
+ const [withdrawObject] = tx.splitCoins(zlpCoinObject, [tx.pure.u64(amount)])
376
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
377
+
378
+ const [withdrawCoin] = tx.moveCall({
379
+ target: `${this.consts.zoCore.upgradedPackage}::market::withdraw_ptb`,
380
+ typeArguments: [
381
+ `${this.consts.zoCore.package}::zlp::ZLP`,
382
+ this.consts.coins[coin].module,
383
+ ],
384
+ arguments: [
385
+ tx.object(this.consts.zoCore.market),
386
+ tx.object(this.consts.zoCore.rebaseFeeModel),
387
+ withdrawObject,
388
+ tx.pure.u64(minAmountOut),
389
+ vaultsValuation,
390
+ symbolsValuation,
391
+ ],
392
+ })
393
+ return withdrawCoin
394
+ }
395
+
396
+ /**
397
+ * Stakes ZLP tokens in ZO staking pools
398
+ */
399
+ public stake(
400
+ lpCoinObjects: string[],
401
+ amount: bigint,
402
+ pool: string,
403
+ tx?: Transaction,
404
+ ): Transaction {
405
+ if (!tx) {
406
+ tx = new Transaction()
407
+ }
408
+
409
+ const coinObject = this.processCoins(tx, 'zlp', lpCoinObjects)
410
+ const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
411
+
412
+ tx.moveCall({
413
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::deposit`,
414
+ typeArguments: [
415
+ `${this.consts.zoCore.package}::zlp::ZLP`,
416
+ `${this.consts.coins.sui.module}`,
417
+ ],
418
+ arguments: [
419
+ tx.object(pool),
420
+ tx.object(SUI_CLOCK_OBJECT_ID),
421
+ depositObject,
422
+ ],
423
+ })
424
+ return tx
425
+ }
426
+
427
+ /**
428
+ * Stakes ZLP tokens using coin object only (PTB)
429
+ */
430
+ public stakeCoinObject(
431
+ coinObject: TransactionObjectArgument,
432
+ pool: string,
433
+ tx?: Transaction,
434
+ ): Transaction {
435
+ if (!tx) {
436
+ tx = new Transaction()
437
+ }
438
+
439
+ tx.moveCall({
440
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::deposit`,
441
+ typeArguments: [
442
+ `${this.consts.zoCore.package}::zlp::ZLP`,
443
+ `${this.consts.coins.sui.module}`,
444
+ ],
445
+ arguments: [
446
+ tx.object(pool),
447
+ tx.object(SUI_CLOCK_OBJECT_ID),
448
+ coinObject,
449
+ ],
450
+ })
451
+ return tx
452
+ }
453
+
454
+ /**
455
+ * Unstakes ZLP tokens from ZO staking pools
456
+ */
457
+ public unstake(
458
+ credentials: IZLPCredential[],
459
+ amount: bigint,
460
+ pool: string,
461
+ tx?: Transaction,
462
+ ): Transaction {
463
+ let unstakeAmount = amount
464
+ if (!tx) {
465
+ tx = new Transaction()
466
+ }
467
+ for (const credential of credentials) {
468
+ const withdrawAmount = (() => {
469
+ const min = (a: bigint, b: bigint) => a < b ? a : b
470
+ return min(unstakeAmount, credential.amount)
471
+ })()
472
+ unstakeAmount -= withdrawAmount
473
+ tx.moveCall({
474
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::withdraw`,
475
+ typeArguments: [
476
+ `${this.consts.zoCore.package}::zlp::ZLP`,
477
+ `${this.consts.coins.sui.module}`,
478
+ ],
479
+ arguments: [
480
+ tx.object(pool),
481
+ tx.object(SUI_CLOCK_OBJECT_ID),
482
+ tx.object(credential.id),
483
+ tx.pure.u64(withdrawAmount),
484
+ ],
485
+ })
486
+ if (credential.amount === BigInt(0)) {
487
+ tx.moveCall({
488
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::clear_empty_credential`,
489
+ typeArguments: [
490
+ `${this.consts.zoCore.package}::zlp::ZLP`,
491
+ `${this.consts.coins.sui.module}`,
492
+ ],
493
+ arguments: [tx.object(credential.id)],
494
+ })
495
+ }
496
+ }
497
+ return tx
498
+ }
499
+
500
+ /**
501
+ * Unstakes ZLP tokens from ZO staking pools and return Coins
502
+ */
503
+ public unstakeToCoins(
504
+ credentials: IZLPCredential[],
505
+ amount: bigint,
506
+ pool: string,
507
+ tx: Transaction,
508
+ ): TransactionObjectArgument[] {
509
+ let unstakeAmount = amount
510
+ const withdrawnCoinObjects = []
511
+ for (const credential of credentials) {
512
+ const withdrawAmount = (() => {
513
+ const min = (a: bigint, b: bigint) => a < b ? a : b
514
+ return min(unstakeAmount, credential.amount)
515
+ })()
516
+ unstakeAmount -= withdrawAmount
517
+ const [withdrawnCoin] = tx.moveCall({
518
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::withdraw_ptb`,
519
+ typeArguments: [
520
+ `${this.consts.zoCore.package}::zlp::ZLP`,
521
+ `${this.consts.coins.sui.module}`,
522
+ ],
523
+ arguments: [
524
+ tx.object(pool),
525
+ tx.object(SUI_CLOCK_OBJECT_ID),
526
+ tx.object(credential.id),
527
+ tx.pure.u64(withdrawAmount),
528
+ ],
529
+ })
530
+ withdrawnCoinObjects.push(withdrawnCoin)
531
+ if (credential.amount === BigInt(0)) {
532
+ tx.moveCall({
533
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::clear_empty_credential`,
534
+ typeArguments: [
535
+ `${this.consts.zoCore.package}::zlp::ZLP`,
536
+ `${this.consts.coins.sui.module}`,
537
+ ],
538
+ arguments: [tx.object(credential.id)],
539
+ })
540
+ }
541
+ }
542
+ return withdrawnCoinObjects
543
+ }
544
+
545
+ /**
546
+ * Withdraws ZLP tokens from a staking pool credential (PTB)
547
+ * Returns the withdrawn coin object for use in programmable transaction blocks
548
+ */
549
+ public withdrawFromVaultPtb(
550
+ pool: string,
551
+ credential: string,
552
+ withdrawAmount: bigint,
553
+ tx: Transaction,
554
+ ): TransactionObjectArgument {
555
+ const [withdrawnCoin] = tx.moveCall({
556
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::withdraw_ptb`,
557
+ typeArguments: [
558
+ `${this.consts.zoCore.package}::zlp::ZLP`,
559
+ `${this.consts.coins.sui.module}`,
560
+ ],
561
+ arguments: [
562
+ tx.object(pool),
563
+ tx.object(SUI_CLOCK_OBJECT_ID),
564
+ tx.object(credential),
565
+ tx.pure.u64(withdrawAmount),
566
+ ],
567
+ })
568
+ return withdrawnCoin
569
+ }
570
+
571
+ /**
572
+ * Claims rewards from a staking pool credential (PTB)
573
+ * Returns the reward coin object for use in programmable transaction blocks
574
+ */
575
+ public claimRewardsPtb(
576
+ pool: string,
577
+ credential: string,
578
+ tx: Transaction,
579
+ ): TransactionObjectArgument {
580
+ const [rewardCoin] = tx.moveCall({
581
+ target: `${this.sharedConfig.zoStaking.upgradedPackage}::pool::claim_rewards_ptb`,
582
+ typeArguments: [
583
+ `${this.consts.zoCore.package}::zlp::ZLP`,
584
+ `${this.consts.coins.sui.module}`,
585
+ ],
586
+ arguments: [
587
+ tx.object(pool),
588
+ tx.object(SUI_CLOCK_OBJECT_ID),
589
+ tx.object(credential),
590
+ ],
591
+ })
592
+ return rewardCoin
593
+ }
594
+
595
+ public async swap(
596
+ fromToken: string,
597
+ toToken: string,
598
+ fromAmount: bigint,
599
+ fromCoinObjects: string[],
600
+ minAmountOut?: number,
601
+ ): Promise<Transaction> {
602
+ const tx = await this.initOracleTxb(Object.keys(this.consts.zoCore.vaults))
603
+ const fromCoinObject = this.processCoins(tx, fromToken, fromCoinObjects)
604
+ const [fromDepositObject] = tx.splitCoins(fromCoinObject, [tx.pure.u64(fromAmount)])
605
+ const vaultsValuation = this.dataAPI.valuateVaults(tx)
606
+
607
+ tx.moveCall({
608
+ target: `${this.consts.zoCore.upgradedPackage}::market::swap_v2`,
609
+ typeArguments: [
610
+ `${this.consts.zoCore.package}::zlp::ZLP`,
611
+ this.consts.coins[fromToken].module,
612
+ this.consts.coins[toToken].module,
613
+ ],
614
+ arguments: [
615
+ tx.object(this.consts.zoCore.market),
616
+ tx.object(this.consts.zoCore.rebaseFeeModel),
617
+ fromDepositObject,
618
+ tx.pure.u64(minAmountOut || 0),
619
+ vaultsValuation,
620
+ tx.object(this.consts.pythFeeder.feeder[fromToken]),
621
+ tx.object(this.consts.pythFeeder.feeder[toToken]),
622
+ ],
623
+ })
624
+ return tx
625
+ }
626
+
627
+ /**
628
+ * Opens a new position in ZLP
629
+ */
630
+ public async openPosition(
631
+ collateralToken: string,
632
+ indexToken: string,
633
+ size: bigint,
634
+ collateralAmount: bigint,
635
+ coinObjects: string[],
636
+ long: boolean,
637
+ reserveAmount: bigint,
638
+ indexPrice: number,
639
+ collateralPrice: number,
640
+ isLimitOrder?: boolean,
641
+ isIocOrder?: boolean,
642
+ pricesSlippage = 0.003,
643
+ collateralSlippage = 0.5,
644
+ relayerFee = BigInt(0.5),
645
+ referralAddress?: string,
646
+ sender?: string,
647
+ sponsoredTx?: boolean,
648
+ suiCoinObjectsForPythUpdate?: string[],
649
+ ): Promise<Transaction> {
650
+ let tx = new Transaction()
651
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
652
+ tx = await this.addReferral(referralAddress, tx)
653
+ }
654
+
655
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
656
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
657
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
658
+
659
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
660
+ if (isLimitOrder) {
661
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
662
+ }
663
+
664
+ // Handle oracle initialization and coin processing
665
+ let suiCoinObject
666
+ if (sponsoredTx) {
667
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
668
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
669
+ }
670
+ else {
671
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
672
+ }
673
+
674
+ // Process coin splitting
675
+ const [depositObject, feeObject] = this.processCoinSplitting(
676
+ tx,
677
+ collateralToken,
678
+ coinObjects,
679
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
680
+ sponsoredTx,
681
+ suiCoinObject,
682
+ )
683
+
684
+ tx.moveCall({
685
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position`,
686
+ typeArguments: [
687
+ `${this.consts.zoCore.package}::zlp::ZLP`,
688
+ this.consts.coins[collateralToken].module,
689
+ this.consts.coins[indexToken].module,
690
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
691
+ this.consts.coins[collateralToken].module,
692
+ ],
693
+ arguments: [
694
+ tx.object(SUI_CLOCK_OBJECT_ID),
695
+ tx.object(this.consts.zoCore.market),
696
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
697
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
698
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
699
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
700
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
701
+ depositObject,
702
+ feeObject,
703
+ tx.pure.u8(allowTrade),
704
+ tx.pure.u64(size),
705
+ tx.pure.u64(reserveAmount),
706
+ tx.pure.u256(adjustCollateralPrice),
707
+ tx.pure.u256(adjustPrice),
708
+ ],
709
+ })
710
+
711
+ return tx
712
+ }
713
+
714
+ /**
715
+ * Opens a new position in ZLP
716
+ */
717
+ public async openPositionV2(
718
+ collateralToken: string,
719
+ indexToken: string,
720
+ size: bigint,
721
+ collateralAmount: bigint,
722
+ coinObjects: string[],
723
+ long: boolean,
724
+ reserveAmount: bigint,
725
+ indexPrice: number,
726
+ collateralPrice: number,
727
+ isLimitOrder?: boolean,
728
+ isIocOrder?: boolean,
729
+ pricesSlippage = 0.003,
730
+ collateralSlippage = 0.5,
731
+ relayerFee = BigInt(0.5),
732
+ referralAddress?: string,
733
+ sender?: string,
734
+ sponsoredTx?: boolean,
735
+ suiCoinObjectsForPythUpdate?: string[],
736
+ ): Promise<Transaction> {
737
+ let tx = new Transaction()
738
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
739
+ tx = await this.addReferral(referralAddress, tx)
740
+ }
741
+
742
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
743
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
744
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
745
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
746
+
747
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
748
+ if (isLimitOrder) {
749
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
750
+ }
751
+
752
+ // Handle oracle initialization and coin processing
753
+ let suiCoinObject
754
+ if (sponsoredTx) {
755
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
756
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
757
+ }
758
+ else {
759
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
760
+ }
761
+
762
+ // Process coin splitting
763
+ const [depositObject, feeObject] = this.processCoinSplitting(
764
+ tx,
765
+ collateralToken,
766
+ coinObjects,
767
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
768
+ sponsoredTx,
769
+ suiCoinObject,
770
+ )
771
+
772
+ tx.moveCall({
773
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v2`,
774
+ typeArguments: [
775
+ `${this.consts.zoCore.package}::zlp::ZLP`,
776
+ this.consts.coins[collateralToken].module,
777
+ this.consts.coins[indexToken].module,
778
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
779
+ this.consts.coins[collateralToken].module,
780
+ ],
781
+ arguments: [
782
+ tx.object(SUI_CLOCK_OBJECT_ID),
783
+ tx.object(this.consts.zoCore.market),
784
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
785
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
786
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
787
+ depositObject,
788
+ feeObject,
789
+ tx.pure.u8(allowTrade),
790
+ tx.pure.u64(size),
791
+ tx.pure.u64(reserveAmount),
792
+ tx.pure.u256(adjustCollateralPrice),
793
+ tx.pure.u256(adjustPrice),
794
+ tx.pure.u256(indexPriceThreshold),
795
+ ],
796
+ })
797
+
798
+ return tx
799
+ }
800
+
801
+ /**
802
+ * Opens a new position with Coin in ZLP
803
+ */
804
+ public async openPositionWithCoin(
805
+ collateralToken: string,
806
+ indexToken: string,
807
+ size: bigint,
808
+ coinObj: TransactionObjectArgument,
809
+ long: boolean,
810
+ reserveAmount: bigint,
811
+ indexPrice: number,
812
+ collateralPrice: number,
813
+ isLimitOrder?: boolean,
814
+ isIocOrder?: boolean,
815
+ pricesSlippage = 0.003,
816
+ collateralSlippage = 0.5,
817
+ relayerFee = BigInt(0.5),
818
+ referralAddress?: string,
819
+ sender?: string,
820
+ tx?: Transaction,
821
+ sponsoredTx?: boolean,
822
+ suiCoinObjectsForPythUpdate?: string[],
823
+ ): Promise<Transaction> {
824
+ if (!tx) {
825
+ tx = new Transaction()
826
+ }
827
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
828
+ tx = await this.addReferral(referralAddress, tx)
829
+ }
830
+
831
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
832
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
833
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
834
+
835
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
836
+ if (isLimitOrder) {
837
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
838
+ }
839
+
840
+ // Handle oracle initialization and coin processing
841
+ let suiCoinObject
842
+ if (sponsoredTx) {
843
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
844
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
845
+ }
846
+ else {
847
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
848
+ }
849
+
850
+ // Process coin splitting
851
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
852
+
853
+ tx.moveCall({
854
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position`,
855
+ typeArguments: [
856
+ `${this.consts.zoCore.package}::zlp::ZLP`,
857
+ this.consts.coins[collateralToken].module,
858
+ this.consts.coins[indexToken].module,
859
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
860
+ this.consts.coins[collateralToken].module,
861
+ ],
862
+ arguments: [
863
+ tx.object(SUI_CLOCK_OBJECT_ID),
864
+ tx.object(this.consts.zoCore.market),
865
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
866
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
867
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
868
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
869
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
870
+ coinObj,
871
+ feeObject,
872
+ tx.pure.u8(allowTrade),
873
+ tx.pure.u64(size),
874
+ tx.pure.u64(reserveAmount),
875
+ tx.pure.u256(adjustCollateralPrice),
876
+ tx.pure.u256(adjustPrice),
877
+ ],
878
+ })
879
+
880
+ return tx
881
+ }
882
+
883
+ /**
884
+ * Opens a new position with Coin in ZLP (V2)
885
+ */
886
+ public async openPositionWithCoinV2(
887
+ collateralToken: string,
888
+ indexToken: string,
889
+ size: bigint,
890
+ coinObj: TransactionObjectArgument,
891
+ long: boolean,
892
+ reserveAmount: bigint,
893
+ indexPrice: number,
894
+ collateralPrice: number,
895
+ isLimitOrder?: boolean,
896
+ isIocOrder?: boolean,
897
+ pricesSlippage = 0.003,
898
+ collateralSlippage = 0.5,
899
+ relayerFee = BigInt(0.5),
900
+ referralAddress?: string,
901
+ sender?: string,
902
+ tx?: Transaction,
903
+ sponsoredTx?: boolean,
904
+ suiCoinObjectsForPythUpdate?: string[],
905
+ ): Promise<Transaction> {
906
+ if (!tx) {
907
+ tx = new Transaction()
908
+ }
909
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
910
+ tx = await this.addReferral(referralAddress, tx)
911
+ }
912
+
913
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
914
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
915
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
916
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
917
+
918
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
919
+ if (isLimitOrder) {
920
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
921
+ }
922
+
923
+ // Handle oracle initialization and coin processing
924
+ let suiCoinObject
925
+ if (sponsoredTx) {
926
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
927
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
928
+ }
929
+ else {
930
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
931
+ }
932
+
933
+ // Process coin splitting
934
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
935
+
936
+ tx.moveCall({
937
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_v2`,
938
+ typeArguments: [
939
+ `${this.consts.zoCore.package}::zlp::ZLP`,
940
+ this.consts.coins[collateralToken].module,
941
+ this.consts.coins[indexToken].module,
942
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
943
+ this.consts.coins[collateralToken].module,
944
+ ],
945
+ arguments: [
946
+ tx.object(SUI_CLOCK_OBJECT_ID),
947
+ tx.object(this.consts.zoCore.market),
948
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
949
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
950
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
951
+ coinObj,
952
+ feeObject,
953
+ tx.pure.u8(allowTrade),
954
+ tx.pure.u64(size),
955
+ tx.pure.u64(reserveAmount),
956
+ tx.pure.u256(adjustCollateralPrice),
957
+ tx.pure.u256(adjustPrice),
958
+ tx.pure.u256(indexPriceThreshold),
959
+ ],
960
+ })
961
+
962
+ return tx
963
+ }
964
+
965
+ /**
966
+ * Decreases an existing position in ZLP
967
+ */
968
+ public async decreasePosition(
969
+ pcpId: string,
970
+ collateralToken: string,
971
+ indexToken: string,
972
+ amount: bigint,
973
+ long: boolean,
974
+ indexPrice: number,
975
+ collateralPrice: number,
976
+ isTriggerOrder = false,
977
+ isTakeProfitOrder = true,
978
+ isIocOrder = false,
979
+ pricesSlippage = 0.003,
980
+ collateralSlippage = 0.5,
981
+ relayerFee = BigInt(0.5),
982
+ coinObjects?: string[],
983
+ sponsoredTx?: boolean,
984
+ suiCoinObjectsForPythUpdate?: string[],
985
+ ): Promise<Transaction> {
986
+ if (!coinObjects) {
987
+ throw new Error(`${this.constructor.name}: coinObjects is required`)
988
+ }
989
+
990
+ let tx = new Transaction()
991
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
992
+
993
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
994
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
995
+
996
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
997
+ if (isTriggerOrder) {
998
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
999
+ }
1000
+ else {
1001
+ isTakeProfitOrder = true
1002
+ }
1003
+
1004
+ // Handle oracle initialization and coin processing
1005
+ let suiCoinObject
1006
+ if (sponsoredTx) {
1007
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1008
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1009
+ }
1010
+ else {
1011
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1012
+ }
1013
+
1014
+ // Process coin splitting
1015
+ const [feeObject] = this.processCoinSplitting(
1016
+ tx,
1017
+ collateralToken,
1018
+ coinObjects,
1019
+ [tx.pure.u64(relayerFee)],
1020
+ sponsoredTx,
1021
+ suiCoinObject,
1022
+ )
1023
+
1024
+ tx.moveCall({
1025
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position`,
1026
+ typeArguments: [
1027
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1028
+ this.consts.coins[collateralToken].module,
1029
+ this.consts.coins[indexToken].module,
1030
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1031
+ this.consts.coins[collateralToken].module,
1032
+ ],
1033
+ arguments: [
1034
+ tx.object(SUI_CLOCK_OBJECT_ID),
1035
+ tx.object(this.consts.zoCore.market),
1036
+ tx.object(pcpId),
1037
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
1038
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
1039
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1040
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1041
+ feeObject,
1042
+ tx.pure.u8(allowTrade),
1043
+ tx.pure.bool(isTakeProfitOrder),
1044
+ tx.pure.u64(amount),
1045
+ tx.pure.u256(adjustCollateralPrice),
1046
+ tx.pure.u256(adjustPrice),
1047
+ ],
1048
+ })
1049
+
1050
+ return tx
1051
+ }
1052
+
1053
+ /**
1054
+ * Decreases an existing position in ZLP
1055
+ */
1056
+ public async decreasePositionV2(
1057
+ pcpId: string,
1058
+ collateralToken: string,
1059
+ indexToken: string,
1060
+ amount: bigint,
1061
+ long: boolean,
1062
+ indexPrice: number,
1063
+ collateralPrice: number,
1064
+ isTriggerOrder = false,
1065
+ isTakeProfitOrder = true,
1066
+ isIocOrder = false,
1067
+ pricesSlippage = 0.003,
1068
+ collateralSlippage = 0.5,
1069
+ relayerFee = BigInt(0.5),
1070
+ coinObjects?: string[],
1071
+ sponsoredTx?: boolean,
1072
+ suiCoinObjectsForPythUpdate?: string[],
1073
+ ): Promise<Transaction> {
1074
+ if (!coinObjects) {
1075
+ throw new Error(`${this.constructor.name}: coinObjects is required`)
1076
+ }
1077
+
1078
+ let tx = new Transaction()
1079
+
1080
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
1081
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1082
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
1083
+
1084
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1085
+ if (isTriggerOrder) {
1086
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1087
+ }
1088
+ else {
1089
+ isTakeProfitOrder = true
1090
+ }
1091
+
1092
+ // Handle oracle initialization and coin processing
1093
+ let suiCoinObject
1094
+ if (sponsoredTx) {
1095
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1096
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1097
+ }
1098
+ else {
1099
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1100
+ }
1101
+
1102
+ // Process coin splitting
1103
+ const [feeObject] = this.processCoinSplitting(
1104
+ tx,
1105
+ collateralToken,
1106
+ coinObjects,
1107
+ [tx.pure.u64(relayerFee)],
1108
+ sponsoredTx,
1109
+ suiCoinObject,
1110
+ )
1111
+
1112
+ tx.moveCall({
1113
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_v2`,
1114
+ typeArguments: [
1115
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1116
+ this.consts.coins[collateralToken].module,
1117
+ this.consts.coins[indexToken].module,
1118
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1119
+ this.consts.coins[collateralToken].module,
1120
+ ],
1121
+ arguments: [
1122
+ tx.object(SUI_CLOCK_OBJECT_ID),
1123
+ tx.object(this.consts.zoCore.market),
1124
+ tx.object(pcpId),
1125
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1126
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1127
+ feeObject,
1128
+ tx.pure.u8(allowTrade),
1129
+ tx.pure.bool(isTakeProfitOrder),
1130
+ tx.pure.u64(amount),
1131
+ tx.pure.u256(adjustCollateralPrice),
1132
+ tx.pure.u256(adjustPrice),
1133
+ tx.pure.u256(indexPriceThreshold),
1134
+ ],
1135
+ })
1136
+
1137
+ return tx
1138
+ }
1139
+
1140
+ public async decreaseMultiPositions(positions: Array<{
1141
+ pcpId: string
1142
+ collateralToken: string
1143
+ indexToken: string
1144
+ amount: bigint
1145
+ long: boolean
1146
+ indexPrice: number
1147
+ collateralPrice: number
1148
+ isTriggerOrder?: boolean
1149
+ isTakeProfitOrder?: boolean
1150
+ isIocOrder?: boolean
1151
+ pricesSlippage?: number
1152
+ collateralSlippage?: number
1153
+ relayerFee?: bigint
1154
+ coinObjects?: string[]
1155
+ }>, tx?: Transaction, sponsoredTx?: boolean, suiCoinObjectsForPythUpdate?: string[]): Promise<Transaction> {
1156
+ if (!tx) {
1157
+ tx = new Transaction()
1158
+ }
1159
+
1160
+ // Handle oracle initialization and coin processing
1161
+ let suiCoinObject
1162
+ if (sponsoredTx) {
1163
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1164
+ tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx, true, suiCoinObject)
1165
+ }
1166
+ else {
1167
+ tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx)
1168
+ }
1169
+
1170
+ for (const position of positions) {
1171
+ const {
1172
+ pcpId,
1173
+ collateralToken,
1174
+ coinObjects = [],
1175
+ indexToken,
1176
+ amount,
1177
+ long,
1178
+ indexPrice,
1179
+ collateralPrice,
1180
+ isTriggerOrder = false,
1181
+ isTakeProfitOrder = true,
1182
+ isIocOrder = false,
1183
+ pricesSlippage = 0.003,
1184
+ collateralSlippage = 0.5,
1185
+ relayerFee = BigInt(0.5),
1186
+ } = position
1187
+ let innerIsTakeProfitOrder = isTakeProfitOrder
1188
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1189
+
1190
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
1191
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1192
+
1193
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1194
+ if (isTriggerOrder) {
1195
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1196
+ }
1197
+ else {
1198
+ innerIsTakeProfitOrder = true
1199
+ }
1200
+
1201
+ // Process coin splitting
1202
+ const [feeObject] = this.processCoinSplitting(
1203
+ tx,
1204
+ collateralToken,
1205
+ coinObjects,
1206
+ [tx.pure.u64(relayerFee)],
1207
+ sponsoredTx,
1208
+ suiCoinObject,
1209
+ )
1210
+
1211
+ tx.moveCall({
1212
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position`,
1213
+ typeArguments: [
1214
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1215
+ this.consts.coins[collateralToken].module,
1216
+ this.consts.coins[indexToken].module,
1217
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1218
+ this.consts.coins[collateralToken].module,
1219
+ ],
1220
+ arguments: [
1221
+ tx.object(SUI_CLOCK_OBJECT_ID),
1222
+ tx.object(this.consts.zoCore.market),
1223
+ tx.object(pcpId),
1224
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
1225
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
1226
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1227
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1228
+ feeObject,
1229
+ tx.pure.u8(allowTrade),
1230
+ tx.pure.bool(innerIsTakeProfitOrder),
1231
+ tx.pure.u64(amount),
1232
+ tx.pure.u256(adjustCollateralPrice),
1233
+ tx.pure.u256(adjustPrice),
1234
+ ],
1235
+ })
1236
+ }
1237
+ return tx
1238
+ }
1239
+
1240
+ public async decreaseMultiPositionsV2(positions: Array<{
1241
+ pcpId: string
1242
+ collateralToken: string
1243
+ indexToken: string
1244
+ amount: bigint
1245
+ long: boolean
1246
+ indexPrice: number
1247
+ collateralPrice: number
1248
+ isTriggerOrder?: boolean
1249
+ isTakeProfitOrder?: boolean
1250
+ isIocOrder?: boolean
1251
+ pricesSlippage?: number
1252
+ collateralSlippage?: number
1253
+ relayerFee?: bigint
1254
+ coinObjects?: string[]
1255
+ }>, tx?: Transaction, sponsoredTx?: boolean, suiCoinObjectsForPythUpdate?: string[], feeObjects?: TransactionObjectArgument[]): Promise<Transaction> {
1256
+ const transaction = tx ?? new Transaction()
1257
+
1258
+ // Handle oracle initialization and coin processing
1259
+ const tokens = positions.flatMap(position => [position.collateralToken, position.indexToken])
1260
+ const suiCoinObject = sponsoredTx
1261
+ ? this.processCoins(transaction, 'sui', suiCoinObjectsForPythUpdate || [], true)
1262
+ : undefined
1263
+ await this.initOracleTxb(tokens, transaction, !!sponsoredTx, suiCoinObject)
1264
+
1265
+ if (!feeObjects || feeObjects.length !== positions.length) {
1266
+ throw new Error('feeObjects must be provided (pre-processed via buildFeeCoinObjects) and match positions length')
1267
+ }
1268
+
1269
+ for (const [i, position] of positions.entries()) {
1270
+ const feeObject = feeObjects[i]
1271
+ const {
1272
+ pcpId,
1273
+ collateralToken,
1274
+ indexToken,
1275
+ amount,
1276
+ long,
1277
+ indexPrice,
1278
+ collateralPrice,
1279
+ isTriggerOrder = false,
1280
+ isTakeProfitOrder = true,
1281
+ isIocOrder = false,
1282
+ pricesSlippage = 0.003,
1283
+ collateralSlippage = 0.5,
1284
+ } = position
1285
+ let innerIsTakeProfitOrder = isTakeProfitOrder
1286
+
1287
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
1288
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1289
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
1290
+
1291
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1292
+ if (isTriggerOrder) {
1293
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1294
+ }
1295
+ else {
1296
+ innerIsTakeProfitOrder = true
1297
+ }
1298
+
1299
+ transaction.moveCall({
1300
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_v2`,
1301
+ typeArguments: [
1302
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1303
+ this.consts.coins[collateralToken].module,
1304
+ this.consts.coins[indexToken].module,
1305
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1306
+ this.consts.coins[collateralToken].module,
1307
+ ],
1308
+ arguments: [
1309
+ transaction.object(SUI_CLOCK_OBJECT_ID),
1310
+ transaction.object(this.consts.zoCore.market),
1311
+ transaction.object(pcpId),
1312
+ transaction.object(this.consts.pythFeeder.feeder[collateralToken]),
1313
+ transaction.object(this.consts.pythFeeder.feeder[indexToken]),
1314
+ feeObject,
1315
+ transaction.pure.u8(allowTrade),
1316
+ transaction.pure.bool(innerIsTakeProfitOrder),
1317
+ transaction.pure.u64(amount),
1318
+ transaction.pure.u256(adjustCollateralPrice),
1319
+ transaction.pure.u256(adjustPrice),
1320
+ transaction.pure.u256(indexPriceThreshold),
1321
+ ],
1322
+ })
1323
+ }
1324
+ return transaction
1325
+ }
1326
+
1327
+ public async openPositionWithSCard(
1328
+ collateralToken: string,
1329
+ indexToken: string,
1330
+ size: bigint,
1331
+ collateralAmount: bigint,
1332
+ coinObjects: string[],
1333
+ long: boolean,
1334
+ reserveAmount: bigint,
1335
+ indexPrice: number,
1336
+ collateralPrice: number,
1337
+ kioskClient: KioskClient,
1338
+ kioskCap: KioskOwnerCap,
1339
+ scard: string,
1340
+ isLimitOrder?: boolean,
1341
+ isIocOrder?: boolean,
1342
+ pricesSlippage = 0.003,
1343
+ collateralSlippage = 0.5,
1344
+ relayerFee = BigInt(0.5),
1345
+ referralAddress?: string,
1346
+ sender?: string,
1347
+ sponsoredTx?: boolean,
1348
+ suiCoinObjectsForPythUpdate?: string[],
1349
+ ): Promise<Transaction> {
1350
+ let tx = new Transaction()
1351
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
1352
+ tx = await this.addReferral(referralAddress, tx)
1353
+ }
1354
+
1355
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1356
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
1357
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1358
+
1359
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1360
+ if (isLimitOrder) {
1361
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1362
+ }
1363
+
1364
+ const kioskTx = new KioskTransaction({
1365
+ transaction: tx,
1366
+ kioskClient,
1367
+ cap: kioskCap,
1368
+ })
1369
+
1370
+ const [sudoCard, promise] = kioskTx.borrow({
1371
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1372
+ itemId: scard,
1373
+ })
1374
+
1375
+ // Handle oracle initialization and coin processing
1376
+ let suiCoinObject
1377
+ if (sponsoredTx) {
1378
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1379
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1380
+ }
1381
+ else {
1382
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1383
+ }
1384
+
1385
+ // Process coin splitting
1386
+ const [depositObject, feeObject] = this.processCoinSplitting(
1387
+ tx,
1388
+ collateralToken,
1389
+ coinObjects,
1390
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
1391
+ sponsoredTx,
1392
+ suiCoinObject,
1393
+ )
1394
+
1395
+ tx.moveCall({
1396
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard`,
1397
+ typeArguments: [
1398
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1399
+ this.consts.coins[collateralToken].module,
1400
+ this.consts.coins[indexToken].module,
1401
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1402
+ this.consts.coins[collateralToken].module,
1403
+ ],
1404
+ arguments: [
1405
+ tx.object(SUI_CLOCK_OBJECT_ID),
1406
+ tx.object(this.consts.zoCore.market),
1407
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
1408
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
1409
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
1410
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1411
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1412
+ depositObject,
1413
+ feeObject,
1414
+ tx.pure.u8(allowTrade),
1415
+ tx.pure.u64(size),
1416
+ tx.pure.u64(reserveAmount),
1417
+ tx.pure.u256(adjustCollateralPrice),
1418
+ tx.pure.u256(adjustPrice),
1419
+ sudoCard,
1420
+ ],
1421
+ })
1422
+
1423
+ kioskTx
1424
+ .return({
1425
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1426
+ item: sudoCard,
1427
+ promise,
1428
+ })
1429
+ .finalize()
1430
+
1431
+ return tx
1432
+ }
1433
+
1434
+ public async openPositionWithSCardV2(
1435
+ collateralToken: string,
1436
+ indexToken: string,
1437
+ size: bigint,
1438
+ collateralAmount: bigint,
1439
+ coinObjects: string[],
1440
+ long: boolean,
1441
+ reserveAmount: bigint,
1442
+ indexPrice: number,
1443
+ collateralPrice: number,
1444
+ kioskClient: KioskClient,
1445
+ kioskCap: KioskOwnerCap,
1446
+ scard: string,
1447
+ isLimitOrder?: boolean,
1448
+ isIocOrder?: boolean,
1449
+ pricesSlippage = 0.003,
1450
+ collateralSlippage = 0.5,
1451
+ relayerFee = BigInt(0.5),
1452
+ referralAddress?: string,
1453
+ sender?: string,
1454
+ sponsoredTx?: boolean,
1455
+ suiCoinObjectsForPythUpdate?: string[],
1456
+ ): Promise<Transaction> {
1457
+ let tx = new Transaction()
1458
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
1459
+ tx = await this.addReferral(referralAddress, tx)
1460
+ }
1461
+
1462
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1463
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
1464
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1465
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
1466
+
1467
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1468
+ if (isLimitOrder) {
1469
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1470
+ }
1471
+
1472
+ const kioskTx = new KioskTransaction({
1473
+ transaction: tx,
1474
+ kioskClient,
1475
+ cap: kioskCap,
1476
+ })
1477
+
1478
+ const [sudoCard, promise] = kioskTx.borrow({
1479
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1480
+ itemId: scard,
1481
+ })
1482
+
1483
+ // Handle oracle initialization and coin processing
1484
+ let suiCoinObject
1485
+ if (sponsoredTx) {
1486
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1487
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1488
+ }
1489
+ else {
1490
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1491
+ }
1492
+
1493
+ // Process coin splitting
1494
+ const [depositObject, feeObject] = this.processCoinSplitting(
1495
+ tx,
1496
+ collateralToken,
1497
+ coinObjects,
1498
+ [tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
1499
+ sponsoredTx,
1500
+ suiCoinObject,
1501
+ )
1502
+
1503
+ tx.moveCall({
1504
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v2`,
1505
+ typeArguments: [
1506
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1507
+ this.consts.coins[collateralToken].module,
1508
+ this.consts.coins[indexToken].module,
1509
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1510
+ this.consts.coins[collateralToken].module,
1511
+ ],
1512
+ arguments: [
1513
+ tx.object(SUI_CLOCK_OBJECT_ID),
1514
+ tx.object(this.consts.zoCore.market),
1515
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
1516
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1517
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1518
+ depositObject,
1519
+ feeObject,
1520
+ tx.pure.u8(allowTrade),
1521
+ tx.pure.u64(size),
1522
+ tx.pure.u64(reserveAmount),
1523
+ tx.pure.u256(adjustCollateralPrice),
1524
+ tx.pure.u256(adjustPrice),
1525
+ tx.pure.u256(indexPriceThreshold),
1526
+ sudoCard,
1527
+ ],
1528
+ })
1529
+
1530
+ kioskTx
1531
+ .return({
1532
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1533
+ item: sudoCard,
1534
+ promise,
1535
+ })
1536
+ .finalize()
1537
+
1538
+ return tx
1539
+ }
1540
+
1541
+ public async openPositionWithCoinAndSCard(
1542
+ collateralToken: string,
1543
+ indexToken: string,
1544
+ size: bigint,
1545
+ coinObj: TransactionObjectArgument,
1546
+ long: boolean,
1547
+ reserveAmount: bigint,
1548
+ indexPrice: number,
1549
+ collateralPrice: number,
1550
+ kioskClient: KioskClient,
1551
+ kioskCap: KioskOwnerCap,
1552
+ scard: string,
1553
+ isLimitOrder?: boolean,
1554
+ isIocOrder?: boolean,
1555
+ pricesSlippage = 0.003,
1556
+ collateralSlippage = 0.5,
1557
+ relayerFee = BigInt(0.5),
1558
+ referralAddress?: string,
1559
+ sender?: string,
1560
+ tx?: Transaction,
1561
+ sponsoredTx?: boolean,
1562
+ suiCoinObjectsForPythUpdate?: string[],
1563
+ ): Promise<Transaction> {
1564
+ if (!tx) {
1565
+ tx = new Transaction()
1566
+ }
1567
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
1568
+ tx = await this.addReferral(referralAddress, tx)
1569
+ }
1570
+
1571
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1572
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
1573
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1574
+
1575
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1576
+ if (isLimitOrder) {
1577
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1578
+ }
1579
+
1580
+ const kioskTx = new KioskTransaction({
1581
+ transaction: tx,
1582
+ kioskClient,
1583
+ cap: kioskCap,
1584
+ })
1585
+
1586
+ const [sudoCard, promise] = kioskTx.borrow({
1587
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1588
+ itemId: scard,
1589
+ })
1590
+
1591
+ // Handle oracle initialization and coin processing
1592
+ let suiCoinObject
1593
+ if (sponsoredTx) {
1594
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1595
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1596
+ }
1597
+ else {
1598
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1599
+ }
1600
+
1601
+ // Process coin splitting
1602
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
1603
+
1604
+ tx.moveCall({
1605
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard`,
1606
+ typeArguments: [
1607
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1608
+ this.consts.coins[collateralToken].module,
1609
+ this.consts.coins[indexToken].module,
1610
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1611
+ this.consts.coins[collateralToken].module,
1612
+ ],
1613
+ arguments: [
1614
+ tx.object(SUI_CLOCK_OBJECT_ID),
1615
+ tx.object(this.consts.zoCore.market),
1616
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
1617
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
1618
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
1619
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1620
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1621
+ coinObj,
1622
+ feeObject,
1623
+ tx.pure.u8(allowTrade),
1624
+ tx.pure.u64(size),
1625
+ tx.pure.u64(reserveAmount),
1626
+ tx.pure.u256(adjustCollateralPrice),
1627
+ tx.pure.u256(adjustPrice),
1628
+ sudoCard,
1629
+ ],
1630
+ })
1631
+
1632
+ kioskTx
1633
+ .return({
1634
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1635
+ item: sudoCard,
1636
+ promise,
1637
+ })
1638
+ .finalize()
1639
+
1640
+ return tx
1641
+ }
1642
+
1643
+ public async openPositionWithCoinAndSCardV2(
1644
+ collateralToken: string,
1645
+ indexToken: string,
1646
+ size: bigint,
1647
+ coinObj: TransactionObjectArgument,
1648
+ long: boolean,
1649
+ reserveAmount: bigint,
1650
+ indexPrice: number,
1651
+ collateralPrice: number,
1652
+ kioskClient: KioskClient,
1653
+ kioskCap: KioskOwnerCap,
1654
+ scard: string,
1655
+ isLimitOrder?: boolean,
1656
+ isIocOrder?: boolean,
1657
+ pricesSlippage = 0.003,
1658
+ collateralSlippage = 0.5,
1659
+ relayerFee = BigInt(0.5),
1660
+ referralAddress?: string,
1661
+ sender?: string,
1662
+ tx?: Transaction,
1663
+ sponsoredTx?: boolean,
1664
+ suiCoinObjectsForPythUpdate?: string[],
1665
+ ): Promise<Transaction> {
1666
+ if (!tx) {
1667
+ tx = new Transaction()
1668
+ }
1669
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
1670
+ tx = await this.addReferral(referralAddress, tx)
1671
+ }
1672
+
1673
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1674
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
1675
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1676
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
1677
+
1678
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1679
+ if (isLimitOrder) {
1680
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1681
+ }
1682
+
1683
+ const kioskTx = new KioskTransaction({
1684
+ transaction: tx,
1685
+ kioskClient,
1686
+ cap: kioskCap,
1687
+ })
1688
+
1689
+ const [sudoCard, promise] = kioskTx.borrow({
1690
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1691
+ itemId: scard,
1692
+ })
1693
+
1694
+ // Handle oracle initialization and coin processing
1695
+ let suiCoinObject
1696
+ if (sponsoredTx) {
1697
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1698
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1699
+ }
1700
+ else {
1701
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1702
+ }
1703
+
1704
+ // Process coin splitting
1705
+ const [feeObject] = tx.splitCoins(coinObj, [tx.pure.u64(relayerFee)])
1706
+
1707
+ tx.moveCall({
1708
+ target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard_v2`,
1709
+ typeArguments: [
1710
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1711
+ this.consts.coins[collateralToken].module,
1712
+ this.consts.coins[indexToken].module,
1713
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1714
+ this.consts.coins[collateralToken].module,
1715
+ ],
1716
+ arguments: [
1717
+ tx.object(SUI_CLOCK_OBJECT_ID),
1718
+ tx.object(this.consts.zoCore.market),
1719
+ tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
1720
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1721
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1722
+ coinObj,
1723
+ feeObject,
1724
+ tx.pure.u8(allowTrade),
1725
+ tx.pure.u64(size),
1726
+ tx.pure.u64(reserveAmount),
1727
+ tx.pure.u256(adjustCollateralPrice),
1728
+ tx.pure.u256(adjustPrice),
1729
+ tx.pure.u256(indexPriceThreshold),
1730
+ sudoCard,
1731
+ ],
1732
+ })
1733
+
1734
+ kioskTx
1735
+ .return({
1736
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1737
+ item: sudoCard,
1738
+ promise,
1739
+ })
1740
+ .finalize()
1741
+
1742
+ return tx
1743
+ }
1744
+
1745
+ public async decreasePositionWithSCard(
1746
+ pcpId: string,
1747
+ collateralToken: string,
1748
+ indexToken: string,
1749
+ amount: bigint,
1750
+ long: boolean,
1751
+ indexPrice: number,
1752
+ collateralPrice: number,
1753
+ kioskClient: KioskClient,
1754
+ kioskCap: KioskOwnerCap,
1755
+ scard: string,
1756
+ isTriggerOrder = false,
1757
+ isTakeProfitOrder = true,
1758
+ isIocOrder = false,
1759
+ pricesSlippage = 0.003,
1760
+ collateralSlippage = 0.5,
1761
+ relayerFee = BigInt(0.5),
1762
+ coinObjects?: string[],
1763
+ sponsoredTx?: boolean,
1764
+ suiCoinObjectsForPythUpdate?: string[],
1765
+ ): Promise<Transaction> {
1766
+ if (!coinObjects) {
1767
+ throw new Error(`${this.constructor.name}: coinObjects is required`)
1768
+ }
1769
+
1770
+ let tx = new Transaction()
1771
+
1772
+ const kioskTx = new KioskTransaction({
1773
+ transaction: tx,
1774
+ kioskClient,
1775
+ cap: kioskCap,
1776
+ })
1777
+
1778
+ const [sudoCard, promise] = kioskTx.borrow({
1779
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1780
+ itemId: scard,
1781
+ })
1782
+
1783
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1784
+
1785
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
1786
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1787
+
1788
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1789
+ if (isTriggerOrder) {
1790
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1791
+ }
1792
+ else {
1793
+ isTakeProfitOrder = true
1794
+ }
1795
+
1796
+ // Handle oracle initialization and coin processing
1797
+ let suiCoinObject
1798
+ if (sponsoredTx) {
1799
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1800
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1801
+ }
1802
+ else {
1803
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1804
+ }
1805
+
1806
+ // Process coin splitting
1807
+ const [feeObject] = this.processCoinSplitting(
1808
+ tx,
1809
+ collateralToken,
1810
+ coinObjects,
1811
+ [tx.pure.u64(relayerFee)],
1812
+ sponsoredTx,
1813
+ suiCoinObject,
1814
+ )
1815
+
1816
+ tx.moveCall({
1817
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard`,
1818
+ typeArguments: [
1819
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1820
+ this.consts.coins[collateralToken].module,
1821
+ this.consts.coins[indexToken].module,
1822
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1823
+ this.consts.coins[collateralToken].module,
1824
+ ],
1825
+ arguments: [
1826
+ tx.object(SUI_CLOCK_OBJECT_ID),
1827
+ tx.object(this.consts.zoCore.market),
1828
+ tx.object(pcpId),
1829
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
1830
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
1831
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1832
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1833
+ feeObject,
1834
+ tx.pure.u8(allowTrade),
1835
+ tx.pure.bool(isTakeProfitOrder),
1836
+ tx.pure.u64(amount),
1837
+ tx.pure.u256(adjustCollateralPrice),
1838
+ tx.pure.u256(adjustPrice),
1839
+ sudoCard,
1840
+ ],
1841
+ })
1842
+
1843
+ kioskTx
1844
+ .return({
1845
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1846
+ item: sudoCard,
1847
+ promise,
1848
+ })
1849
+ .finalize()
1850
+ return tx
1851
+ }
1852
+
1853
+ public async decreasePositionWithSCardV2(
1854
+ pcpId: string,
1855
+ collateralToken: string,
1856
+ indexToken: string,
1857
+ amount: bigint,
1858
+ long: boolean,
1859
+ indexPrice: number,
1860
+ collateralPrice: number,
1861
+ kioskClient: KioskClient,
1862
+ kioskCap: KioskOwnerCap,
1863
+ scard: string,
1864
+ isTriggerOrder = false,
1865
+ isTakeProfitOrder = true,
1866
+ isIocOrder = false,
1867
+ pricesSlippage = 0.003,
1868
+ collateralSlippage = 0.5,
1869
+ relayerFee = BigInt(0.5),
1870
+ coinObjects?: string[],
1871
+ sponsoredTx?: boolean,
1872
+ suiCoinObjectsForPythUpdate?: string[],
1873
+ ): Promise<Transaction> {
1874
+ if (!coinObjects) {
1875
+ throw new Error(`${this.constructor.name}: coinObjects is required`)
1876
+ }
1877
+
1878
+ let tx = new Transaction()
1879
+
1880
+ const kioskTx = new KioskTransaction({
1881
+ transaction: tx,
1882
+ kioskClient,
1883
+ cap: kioskCap,
1884
+ })
1885
+
1886
+ const [sudoCard, promise] = kioskTx.borrow({
1887
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1888
+ itemId: scard,
1889
+ })
1890
+
1891
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
1892
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
1893
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
1894
+
1895
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1896
+ if (isTriggerOrder) {
1897
+ allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
1898
+ }
1899
+ else {
1900
+ isTakeProfitOrder = true
1901
+ }
1902
+
1903
+ // Handle oracle initialization and coin processing
1904
+ let suiCoinObject
1905
+ if (sponsoredTx) {
1906
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1907
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
1908
+ }
1909
+ else {
1910
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
1911
+ }
1912
+
1913
+ // Process coin splitting
1914
+ const [feeObject] = this.processCoinSplitting(
1915
+ tx,
1916
+ collateralToken,
1917
+ coinObjects,
1918
+ [tx.pure.u64(relayerFee)],
1919
+ sponsoredTx,
1920
+ suiCoinObject,
1921
+ )
1922
+
1923
+ tx.moveCall({
1924
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard_v2`,
1925
+ typeArguments: [
1926
+ `${this.consts.zoCore.package}::zlp::ZLP`,
1927
+ this.consts.coins[collateralToken].module,
1928
+ this.consts.coins[indexToken].module,
1929
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1930
+ this.consts.coins[collateralToken].module,
1931
+ ],
1932
+ arguments: [
1933
+ tx.object(SUI_CLOCK_OBJECT_ID),
1934
+ tx.object(this.consts.zoCore.market),
1935
+ tx.object(pcpId),
1936
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1937
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1938
+ feeObject,
1939
+ tx.pure.u8(allowTrade),
1940
+ tx.pure.bool(isTakeProfitOrder),
1941
+ tx.pure.u64(amount),
1942
+ tx.pure.u256(adjustCollateralPrice),
1943
+ tx.pure.u256(adjustPrice),
1944
+ tx.pure.u256(indexPriceThreshold),
1945
+ sudoCard,
1946
+ ],
1947
+ })
1948
+
1949
+ kioskTx
1950
+ .return({
1951
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
1952
+ item: sudoCard,
1953
+ promise,
1954
+ })
1955
+ .finalize()
1956
+ return tx
1957
+ }
1958
+
1959
+ public async decreaseMultiPositionsWithSCard(
1960
+ positions: Array<{
1961
+ pcpId: string
1962
+ collateralToken: string
1963
+ indexToken: string
1964
+ amount: bigint
1965
+ long: boolean
1966
+ indexPrice: number
1967
+ collateralPrice: number
1968
+ isTriggerOrder?: boolean
1969
+ isTakeProfitOrder?: boolean
1970
+ isIocOrder?: boolean
1971
+ pricesSlippage?: number
1972
+ collateralSlippage?: number
1973
+ relayerFee?: bigint
1974
+ coinObjects?: string[]
1975
+ }>,
1976
+ kioskClient: KioskClient,
1977
+ kioskCap: KioskOwnerCap,
1978
+ scard: string,
1979
+ tx?: Transaction,
1980
+ sponsoredTx?: boolean,
1981
+ suiCoinObjectsForPythUpdate?: string[],
1982
+ ): Promise<Transaction> {
1983
+ if (!tx) {
1984
+ tx = new Transaction()
1985
+ }
1986
+
1987
+ // Handle oracle initialization and coin processing
1988
+ let suiCoinObject
1989
+ if (sponsoredTx) {
1990
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
1991
+ tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx, true, suiCoinObject)
1992
+ }
1993
+ else {
1994
+ tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx)
1995
+ }
1996
+
1997
+ const kioskTx = new KioskTransaction({
1998
+ transaction: tx,
1999
+ kioskClient,
2000
+ cap: kioskCap,
2001
+ })
2002
+
2003
+ const [sudoCard, promise] = kioskTx.borrow({
2004
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2005
+ itemId: scard,
2006
+ })
2007
+
2008
+ for (const position of positions) {
2009
+ const {
2010
+ pcpId,
2011
+ collateralToken,
2012
+ indexToken,
2013
+ amount,
2014
+ long,
2015
+ indexPrice,
2016
+ collateralPrice,
2017
+ isTriggerOrder = false,
2018
+ isTakeProfitOrder = true,
2019
+ isIocOrder = false,
2020
+ pricesSlippage = 0.003,
2021
+ collateralSlippage = 0.5,
2022
+ relayerFee = BigInt(0.5),
2023
+ coinObjects = [],
2024
+ } = position
2025
+ let innerIsTakeProfitOrder = isTakeProfitOrder
2026
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
2027
+
2028
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
2029
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
2030
+
2031
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
2032
+ if (isTriggerOrder) {
2033
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
2034
+ }
2035
+ else {
2036
+ innerIsTakeProfitOrder = true
2037
+ }
2038
+
2039
+ // Process coin splitting
2040
+ const [feeObject] = this.processCoinSplitting(
2041
+ tx,
2042
+ collateralToken,
2043
+ coinObjects,
2044
+ [tx.pure.u64(relayerFee)],
2045
+ sponsoredTx,
2046
+ suiCoinObject,
2047
+ )
2048
+
2049
+ tx.moveCall({
2050
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard`,
2051
+ typeArguments: [
2052
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2053
+ this.consts.coins[collateralToken].module,
2054
+ this.consts.coins[indexToken].module,
2055
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2056
+ this.consts.coins[collateralToken].module,
2057
+ ],
2058
+ arguments: [
2059
+ tx.object(SUI_CLOCK_OBJECT_ID),
2060
+ tx.object(this.consts.zoCore.market),
2061
+ tx.object(pcpId),
2062
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
2063
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
2064
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
2065
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
2066
+ feeObject,
2067
+ tx.pure.u8(allowTrade),
2068
+ tx.pure.bool(innerIsTakeProfitOrder),
2069
+ tx.pure.u64(amount),
2070
+ tx.pure.u256(adjustCollateralPrice),
2071
+ tx.pure.u256(adjustPrice),
2072
+ sudoCard,
2073
+ ],
2074
+ })
2075
+ }
2076
+
2077
+ kioskTx
2078
+ .return({
2079
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2080
+ item: sudoCard,
2081
+ promise,
2082
+ })
2083
+ .finalize()
2084
+ return tx
2085
+ }
2086
+
2087
+ public async decreaseMultiPositionsWithSCardV2(
2088
+ positions: Array<{
2089
+ pcpId: string
2090
+ collateralToken: string
2091
+ indexToken: string
2092
+ amount: bigint
2093
+ long: boolean
2094
+ indexPrice: number
2095
+ collateralPrice: number
2096
+ isTriggerOrder?: boolean
2097
+ isTakeProfitOrder?: boolean
2098
+ isIocOrder?: boolean
2099
+ pricesSlippage?: number
2100
+ collateralSlippage?: number
2101
+ relayerFee?: bigint
2102
+ coinObjects?: string[]
2103
+ }>,
2104
+ kioskClient: KioskClient,
2105
+ kioskCap: KioskOwnerCap,
2106
+ scard: string,
2107
+ tx?: Transaction,
2108
+ sponsoredTx?: boolean,
2109
+ suiCoinObjectsForPythUpdate?: string[],
2110
+ feeObjects?: TransactionObjectArgument[],
2111
+ ): Promise<Transaction> {
2112
+ const transaction = tx ?? new Transaction()
2113
+
2114
+ // Handle oracle initialization and coin processing
2115
+ const tokens = positions.flatMap(position => [position.collateralToken, position.indexToken])
2116
+ const suiCoinObject = sponsoredTx
2117
+ ? this.processCoins(transaction, 'sui', suiCoinObjectsForPythUpdate || [], true)
2118
+ : undefined
2119
+ await this.initOracleTxb(tokens, transaction, !!sponsoredTx, suiCoinObject)
2120
+
2121
+ if (!feeObjects || feeObjects.length !== positions.length) {
2122
+ throw new Error('feeObjects must be provided (pre-processed via buildFeeCoinObjects) and match positions length')
2123
+ }
2124
+
2125
+ const kioskTx = new KioskTransaction({
2126
+ transaction,
2127
+ kioskClient,
2128
+ cap: kioskCap,
2129
+ })
2130
+
2131
+ const [sudoCard, promise] = kioskTx.borrow({
2132
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2133
+ itemId: scard,
2134
+ })
2135
+
2136
+ for (const [i, position] of positions.entries()) {
2137
+ const feeObject = feeObjects[i]
2138
+ const {
2139
+ pcpId,
2140
+ collateralToken,
2141
+ indexToken,
2142
+ amount,
2143
+ long,
2144
+ indexPrice,
2145
+ collateralPrice,
2146
+ isTriggerOrder = false,
2147
+ isTakeProfitOrder = true,
2148
+ isIocOrder = false,
2149
+ pricesSlippage = 0.003,
2150
+ collateralSlippage = 0.5,
2151
+ } = position
2152
+ let innerIsTakeProfitOrder = isTakeProfitOrder
2153
+
2154
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
2155
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
2156
+ const indexPriceThreshold = this.processPriceThreshold(indexPrice, pricesSlippage)
2157
+
2158
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
2159
+ if (isTriggerOrder) {
2160
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
2161
+ }
2162
+ else {
2163
+ innerIsTakeProfitOrder = true
2164
+ }
2165
+
2166
+ transaction.moveCall({
2167
+ target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard_v2`,
2168
+ typeArguments: [
2169
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2170
+ this.consts.coins[collateralToken].module,
2171
+ this.consts.coins[indexToken].module,
2172
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2173
+ this.consts.coins[collateralToken].module,
2174
+ ],
2175
+ arguments: [
2176
+ transaction.object(SUI_CLOCK_OBJECT_ID),
2177
+ transaction.object(this.consts.zoCore.market),
2178
+ transaction.object(pcpId),
2179
+ transaction.object(this.consts.pythFeeder.feeder[collateralToken]),
2180
+ transaction.object(this.consts.pythFeeder.feeder[indexToken]),
2181
+ feeObject,
2182
+ transaction.pure.u8(allowTrade),
2183
+ transaction.pure.bool(innerIsTakeProfitOrder),
2184
+ transaction.pure.u64(amount),
2185
+ transaction.pure.u256(adjustCollateralPrice),
2186
+ transaction.pure.u256(adjustPrice),
2187
+ transaction.pure.u256(indexPriceThreshold),
2188
+ sudoCard,
2189
+ ],
2190
+ })
2191
+ }
2192
+
2193
+ kioskTx
2194
+ .return({
2195
+ itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
2196
+ item: sudoCard,
2197
+ promise,
2198
+ })
2199
+ .finalize()
2200
+ return transaction
2201
+ }
2202
+
2203
+ /**
2204
+ * Pledges in position (ZLP-specific functionality)
2205
+ */
2206
+ public async pledgeInPosition(
2207
+ pcpId: string,
2208
+ collateralToken: string,
2209
+ indexToken: string,
2210
+ amount: number,
2211
+ coinObjects: string[],
2212
+ long: boolean,
2213
+ sponsoredTx?: boolean,
2214
+ suiCoinObjectsForPythUpdate?: string[],
2215
+ ): Promise<Transaction> {
2216
+ let tx = new Transaction()
2217
+ // Handle oracle initialization and coin processing
2218
+ let suiCoinObject
2219
+ if (sponsoredTx) {
2220
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
2221
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
2222
+ }
2223
+ else {
2224
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
2225
+ }
2226
+
2227
+ // Process coin splitting
2228
+ const [depositObject] = this.processCoinSplitting(
2229
+ tx,
2230
+ collateralToken,
2231
+ coinObjects,
2232
+ [tx.pure.u64(amount)],
2233
+ sponsoredTx,
2234
+ suiCoinObject,
2235
+ )
2236
+
2237
+ tx.moveCall({
2238
+ target: `${this.consts.zoCore.upgradedPackage}::market::pledge_in_position`,
2239
+ typeArguments: [
2240
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2241
+ this.consts.coins[collateralToken].module,
2242
+ this.consts.coins[indexToken].module,
2243
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2244
+ ],
2245
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(pcpId), depositObject],
2246
+ })
2247
+ return tx
2248
+ }
2249
+
2250
+ public async redeemFromPosition(
2251
+ pcpId: string,
2252
+ collateralToken: string,
2253
+ indexToken: string,
2254
+ amount: number,
2255
+ long: boolean,
2256
+ sponsoredTx?: boolean,
2257
+ suiCoinObjectsForPythUpdate?: string[],
2258
+ ): Promise<Transaction> {
2259
+ let tx = new Transaction()
2260
+ // Handle oracle initialization and coin processing
2261
+ let suiCoinObject
2262
+ if (sponsoredTx) {
2263
+ suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
2264
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
2265
+ }
2266
+ else {
2267
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
2268
+ }
2269
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
2270
+
2271
+ tx.moveCall({
2272
+ target: `${this.consts.zoCore.upgradedPackage}::market::redeem_from_position`,
2273
+ typeArguments: [
2274
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2275
+ this.consts.coins[collateralToken].module,
2276
+ this.consts.coins[indexToken].module,
2277
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2278
+ ],
2279
+ arguments: [
2280
+ tx.object(SUI_CLOCK_OBJECT_ID),
2281
+ tx.object(this.consts.zoCore.market),
2282
+ tx.object(pcpId),
2283
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
2284
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
2285
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
2286
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
2287
+ tx.pure.u64(amount),
2288
+ ],
2289
+ })
2290
+
2291
+ return tx
2292
+ }
2293
+
2294
+ public cancelOrder(
2295
+ orderCapId: string,
2296
+ collateralToken: string,
2297
+ indexToken: string,
2298
+ long: boolean,
2299
+ type: string,
2300
+ isV11Order?: boolean,
2301
+ ): Transaction {
2302
+ const tx = new Transaction()
2303
+ let functionName = ''
2304
+ switch (type) {
2305
+ case 'OPEN_POSITION': {
2306
+ functionName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
2307
+ break
2308
+ }
2309
+ case 'OPEN_MARKET': {
2310
+ functionName = 'clear_open_market_order'
2311
+ break
2312
+ }
2313
+ case 'DECREASE_POSITION': {
2314
+ functionName = isV11Order
2315
+ ? 'clear_decrease_position_order'
2316
+ : 'clear_decrease_position_order'
2317
+ break
2318
+ }
2319
+ case 'DECREASE_MARKET': {
2320
+ functionName = 'clear_decrease_market_order'
2321
+ break
2322
+ }
2323
+ default: {
2324
+ throw new Error('invalid order type')
2325
+ }
2326
+ }
2327
+ tx.moveCall({
2328
+ target: `${this.consts.zoCore.upgradedPackage}::market::${functionName}`,
2329
+ typeArguments: [
2330
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2331
+ this.consts.coins[collateralToken].module,
2332
+ this.consts.coins[indexToken].module,
2333
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2334
+ this.consts.coins[collateralToken].module,
2335
+ ],
2336
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2337
+ })
2338
+ return tx
2339
+ }
2340
+
2341
+ public cancelMultiOrders(
2342
+ orders: Array<{
2343
+ orderCapId: string
2344
+ collateralToken: string
2345
+ indexToken: string
2346
+ long: boolean
2347
+ type: string
2348
+ isV11Order?: boolean
2349
+ }>,
2350
+ tx?: Transaction,
2351
+ ): Transaction {
2352
+ if (!tx) {
2353
+ tx = new Transaction()
2354
+ }
2355
+
2356
+ for (const order of orders) {
2357
+ const { orderCapId, collateralToken, indexToken, long, type, isV11Order } = order
2358
+ let functionName = ''
2359
+ switch (type) {
2360
+ case 'OPEN_POSITION': {
2361
+ functionName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
2362
+ break
2363
+ }
2364
+ case 'OPEN_MARKET': {
2365
+ functionName = 'clear_open_market_order'
2366
+ break
2367
+ }
2368
+ case 'DECREASE_POSITION': {
2369
+ functionName = isV11Order
2370
+ ? 'clear_decrease_position_order'
2371
+ : 'clear_decrease_position_order'
2372
+ break
2373
+ }
2374
+ case 'DECREASE_MARKET': {
2375
+ functionName = 'clear_decrease_market_order'
2376
+ break
2377
+ }
2378
+ default: {
2379
+ throw new Error('invalid order type')
2380
+ }
2381
+ }
2382
+
2383
+ tx.moveCall({
2384
+ target: `${this.consts.zoCore.upgradedPackage}::market::${functionName}`,
2385
+ typeArguments: [
2386
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2387
+ this.consts.coins[collateralToken].module,
2388
+ this.consts.coins[indexToken].module,
2389
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2390
+ this.consts.coins[collateralToken].module,
2391
+ ],
2392
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2393
+ })
2394
+ }
2395
+ return tx
2396
+ }
2397
+
2398
+ public clearClosedPosition(
2399
+ pcpId: string,
2400
+ collateralToken: string,
2401
+ indexToken: string,
2402
+ long: boolean,
2403
+ tx: Transaction,
2404
+ ): void {
2405
+ tx.moveCall({
2406
+ target: `${this.consts.zoCore.upgradedPackage}::market::clear_closed_position`,
2407
+ typeArguments: [
2408
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2409
+ this.consts.coins[collateralToken].module,
2410
+ this.consts.coins[indexToken].module,
2411
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2412
+ ],
2413
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(pcpId)],
2414
+ })
2415
+ }
2416
+
2417
+ public clearOpenPositionOrder(
2418
+ orderCapId: string,
2419
+ collateralToken: string,
2420
+ indexToken: string,
2421
+ long: boolean,
2422
+ tx: Transaction,
2423
+ isV11Order?: boolean,
2424
+ ): void {
2425
+ const funcName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
2426
+ tx.moveCall({
2427
+ target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
2428
+ typeArguments: [
2429
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2430
+ this.consts.coins[collateralToken].module,
2431
+ this.consts.coins[indexToken].module,
2432
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2433
+ this.consts.coins[collateralToken].module,
2434
+ ],
2435
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2436
+ })
2437
+ }
2438
+
2439
+ public clearOpenMarketOrder(
2440
+ orderCapId: string,
2441
+ collateralToken: string,
2442
+ indexToken: string,
2443
+ long: boolean,
2444
+ tx: Transaction,
2445
+ _isV11Order?: boolean,
2446
+ ): void {
2447
+ const funcName = 'clear_open_market_order'
2448
+ tx.moveCall({
2449
+ target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
2450
+ typeArguments: [
2451
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2452
+ this.consts.coins[collateralToken].module,
2453
+ this.consts.coins[indexToken].module,
2454
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2455
+ this.consts.coins[collateralToken].module,
2456
+ ],
2457
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2458
+ })
2459
+ }
2460
+
2461
+ public clearDecreasePositionOrder(
2462
+ orderCapId: string,
2463
+ collateralToken: string,
2464
+ indexToken: string,
2465
+ long: boolean,
2466
+ tx: Transaction,
2467
+ isV11Order?: boolean,
2468
+ ): void {
2469
+ const funcName = isV11Order ? 'clear_decrease_position_order' : 'clear_decrease_position_order'
2470
+ tx.moveCall({
2471
+ target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
2472
+ typeArguments: [
2473
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2474
+ this.consts.coins[collateralToken].module,
2475
+ this.consts.coins[indexToken].module,
2476
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2477
+ this.consts.coins[collateralToken].module,
2478
+ ],
2479
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2480
+ })
2481
+ }
2482
+
2483
+ public clearDecreaseMarketOrder(
2484
+ orderCapId: string,
2485
+ collateralToken: string,
2486
+ indexToken: string,
2487
+ long: boolean,
2488
+ tx: Transaction,
2489
+ _isV11Order?: boolean,
2490
+ ): void {
2491
+ const funcName = 'clear_decrease_market_order'
2492
+ tx.moveCall({
2493
+ target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
2494
+ typeArguments: [
2495
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2496
+ this.consts.coins[collateralToken].module,
2497
+ this.consts.coins[indexToken].module,
2498
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2499
+ this.consts.coins[collateralToken].module,
2500
+ ],
2501
+ arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
2502
+ })
2503
+ }
2504
+
2505
+ public addReferral(
2506
+ referralAddress: string,
2507
+ tx?: Transaction,
2508
+ ): Transaction {
2509
+ if (!tx) {
2510
+ tx = new Transaction()
2511
+ }
2512
+ tx.moveCall({
2513
+ target: `${this.consts.zoCore.upgradedPackage}::market::add_new_referral`,
2514
+ typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`],
2515
+ arguments: [tx.object(this.consts.zoCore.market), tx.pure.address(referralAddress)],
2516
+ })
2517
+
2518
+ return tx
2519
+ }
2520
+
2521
+ public async adminUpdatePriceFeed(
2522
+ collateralToken: string,
2523
+ indexToken: string,
2524
+ ): Promise<Transaction> {
2525
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
2526
+ return tx
2527
+ }
2528
+
2529
+ public adminSettlePosition(
2530
+ positionId: string,
2531
+ owner: string,
2532
+ collateralToken: string,
2533
+ indexToken: string,
2534
+ long: boolean,
2535
+ ): Transaction {
2536
+ const tx = new Transaction()
2537
+
2538
+ tx.moveCall({
2539
+ target: `${this.consts.zoCore.upgradedPackage}::market::force_settle_position`,
2540
+ typeArguments: [
2541
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2542
+ this.consts.coins[collateralToken].module,
2543
+ this.consts.coins[indexToken].module,
2544
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2545
+ ],
2546
+ arguments: [
2547
+ tx.object(this.consts.zoCore.adminCap),
2548
+ tx.object(SUI_CLOCK_OBJECT_ID),
2549
+ tx.object(this.consts.zoCore.market),
2550
+ tx.object(owner),
2551
+ tx.object(positionId),
2552
+ ],
2553
+ })
2554
+
2555
+ this.adminClearClosedPosition(positionId, owner, collateralToken, indexToken, long, tx)
2556
+
2557
+ return tx
2558
+ }
2559
+
2560
+ public adminDecreasePosition(
2561
+ positionId: string,
2562
+ owner: string,
2563
+ collateralToken: string,
2564
+ indexToken: string,
2565
+ positionAmount: number,
2566
+ amount: bigint,
2567
+ long: boolean,
2568
+ ): Transaction {
2569
+ const tx = new Transaction()
2570
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
2571
+
2572
+ tx.moveCall({
2573
+ target: `${this.consts.zoCore.upgradedPackage}::market::force_close_position`,
2574
+ typeArguments: [
2575
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2576
+ this.consts.coins[collateralToken].module,
2577
+ this.consts.coins[indexToken].module,
2578
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2579
+ ],
2580
+ arguments: [
2581
+ tx.object(this.consts.zoCore.adminCap),
2582
+ tx.object(SUI_CLOCK_OBJECT_ID),
2583
+ tx.object(this.consts.zoCore.market),
2584
+ tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
2585
+ tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
2586
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
2587
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
2588
+ tx.object(owner),
2589
+ tx.object(positionId),
2590
+ ],
2591
+ })
2592
+
2593
+ if (amount === BigInt(positionAmount)) {
2594
+ this.adminClearClosedPosition(positionId, owner, collateralToken, indexToken, long, tx)
2595
+ }
2596
+
2597
+ return tx
2598
+ }
2599
+
2600
+ public adminClearClosedPosition(
2601
+ positionId: string,
2602
+ owner: string,
2603
+ collateralToken: string,
2604
+ indexToken: string,
2605
+ long: boolean,
2606
+ tx: Transaction,
2607
+ ): void {
2608
+ tx.moveCall({
2609
+ target: `${this.consts.zoCore.upgradedPackage}::market::force_clear_closed_position`,
2610
+ typeArguments: [
2611
+ `${this.consts.zoCore.package}::zlp::ZLP`,
2612
+ this.consts.coins[collateralToken].module,
2613
+ this.consts.coins[indexToken].module,
2614
+ `${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
2615
+ ],
2616
+ arguments: [
2617
+ tx.object(this.consts.zoCore.adminCap),
2618
+ tx.object(this.consts.zoCore.market),
2619
+ tx.object(positionId),
2620
+ tx.object(owner),
2621
+ ],
2622
+ })
2623
+ }
2624
+
2625
+ public adminIssueLootbox(
2626
+ coin: string,
2627
+ tiers: number[],
2628
+ beneficiaries: string[],
2629
+ amounts: number[],
2630
+ tx: Transaction,
2631
+ ): void {
2632
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2633
+ if (coin !== 'zlp') {
2634
+ module = this.consts.coins[coin].module
2635
+ }
2636
+ for (const [i, beneficiary] of beneficiaries.entries()) {
2637
+ tx.moveCall({
2638
+ target: `${this.sharedConfig.zoLootbox.package}::lootbox::admin_issue_lootbox`,
2639
+ typeArguments: [module],
2640
+ arguments: [
2641
+ tx.object(this.sharedConfig.zoLootbox.adminCap),
2642
+ tx.pure.u8(tiers[i]),
2643
+ tx.pure.address(beneficiary),
2644
+ tx.pure.u64(amounts[i]),
2645
+ tx.pure.bool(amounts[i] > 0),
2646
+ tx.object(`${this.sharedConfig.zoLootbox.lootboxSettings}`),
2647
+ ],
2648
+ })
2649
+ }
2650
+ }
2651
+
2652
+ public depositToPrizePool(
2653
+ coin: string,
2654
+ coinObjects: string[],
2655
+ amount: number,
2656
+ ): Transaction {
2657
+ const tx = new Transaction()
2658
+ const coinObject = this.processCoins(tx, coin, coinObjects)
2659
+ const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
2660
+
2661
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2662
+ if (coin !== 'zlp') {
2663
+ module = this.consts.coins[coin].module
2664
+ }
2665
+
2666
+ tx.moveCall({
2667
+ target: `${this.sharedConfig.zoLootbox.package}::lootbox::deposit`,
2668
+ typeArguments: [module],
2669
+ arguments: [
2670
+ tx.object(this.sharedConfig.zoLootbox.adminCap),
2671
+ tx.object(this.sharedConfig.zoLootbox.lootboxTreasury),
2672
+ depositObject,
2673
+ ],
2674
+ })
2675
+ return tx
2676
+ }
2677
+
2678
+ public withdrawFromPricePool(
2679
+ coin: string,
2680
+ amount: number,
2681
+ ): Transaction {
2682
+ const tx = new Transaction()
2683
+
2684
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2685
+ let metadata = this.consts.zoCore.zlpMetadata
2686
+ if (coin !== 'zlp') {
2687
+ module = this.consts.coins[coin].module
2688
+ metadata = this.consts.coins[coin].metadata
2689
+ }
2690
+
2691
+ tx.moveCall({
2692
+ target: `${this.sharedConfig.zoLootbox.package}::lootbox::withdraw`,
2693
+ typeArguments: [module],
2694
+ arguments: [
2695
+ tx.object(this.sharedConfig.zoLootbox.adminCap),
2696
+ tx.object(this.sharedConfig.zoLootbox.lootboxTreasury),
2697
+ tx.object(metadata),
2698
+ tx.pure.u64(amount),
2699
+ ],
2700
+ })
2701
+ return tx
2702
+ }
2703
+
2704
+ public openLootbox(
2705
+ coin: string,
2706
+ lootbox: string,
2707
+ ): Transaction {
2708
+ const tx = new Transaction()
2709
+
2710
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2711
+ let metadata = this.consts.zoCore.zlpMetadata
2712
+ if (coin !== 'zlp') {
2713
+ module = this.consts.coins[coin].module
2714
+ metadata = this.consts.coins[coin].metadata
2715
+ }
2716
+
2717
+ tx.moveCall({
2718
+ target: `${this.sharedConfig.zoLootbox.upgradedPackage}::lootbox::open_lootbox`,
2719
+ typeArguments: [module],
2720
+ arguments: [
2721
+ tx.object(`${this.sharedConfig.zoLootbox.lootboxTreasury}`),
2722
+ tx.object(lootbox),
2723
+ tx.object(metadata),
2724
+ tx.object(`${this.sharedConfig.zoLootbox.lootboxSettings}`),
2725
+ ],
2726
+ })
2727
+
2728
+ return tx
2729
+ }
2730
+
2731
+ // V2 Lootbox Methods for new contract
2732
+ public adminIssueLootboxV2(
2733
+ coin: string,
2734
+ tiers: number[],
2735
+ beneficiaries: string[],
2736
+ amounts: number[],
2737
+ titles: string[],
2738
+ descriptions: string[],
2739
+ tx: Transaction,
2740
+ ): void {
2741
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2742
+ if (coin !== 'zlp') {
2743
+ module = this.consts.coins[coin].module
2744
+ }
2745
+
2746
+ for (const [i, beneficiary] of beneficiaries.entries()) {
2747
+ const moveCallArgs = {
2748
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::admin_issue_lootbox`,
2749
+ typeArguments: [module],
2750
+ arguments: [
2751
+ tx.object(this.sharedConfig.zoLootboxV2.adminCap),
2752
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxTreasury),
2753
+ tx.pure.u8(tiers[i]),
2754
+ tx.pure.address(beneficiary),
2755
+ tx.pure.u64(amounts[i]),
2756
+ tx.pure.bool(amounts[i] > 0),
2757
+ tx.pure.string(titles[i]),
2758
+ tx.pure.string(descriptions[i]),
2759
+ tx.object(`${this.sharedConfig.zoLootboxV2.lootboxSettings}`),
2760
+ ],
2761
+ }
2762
+
2763
+ tx.moveCall(moveCallArgs)
2764
+ }
2765
+ }
2766
+
2767
+ public openLootboxV2(
2768
+ coin: string,
2769
+ lootbox: string,
2770
+ ): Transaction {
2771
+ const tx = new Transaction()
2772
+
2773
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2774
+ let metadata = this.consts.zoCore.zlpMetadata
2775
+ if (coin !== 'zlp') {
2776
+ module = this.consts.coins[coin].module
2777
+ metadata = this.consts.coins[coin].metadata
2778
+ }
2779
+
2780
+ tx.moveCall({
2781
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::open_lootbox`,
2782
+ typeArguments: [module],
2783
+ arguments: [
2784
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxTreasury),
2785
+ tx.object(lootbox),
2786
+ tx.object(metadata),
2787
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxSettings),
2788
+ ],
2789
+ })
2790
+
2791
+ return tx
2792
+ }
2793
+
2794
+ // Vesting Lootbox Methods (V2)
2795
+ public adminIssueVestingLootboxV2(
2796
+ _coin: string,
2797
+ beneficiaries: string[],
2798
+ unlockedAmounts: number[],
2799
+ lockedAmounts: number[],
2800
+ lockDurationsMs: number[],
2801
+ tx: Transaction,
2802
+ ): void {
2803
+ const module = `${this.consts.zoCore.package}::zlp::ZLP`
2804
+
2805
+ for (const [i, beneficiary] of beneficiaries.entries()) {
2806
+ tx.moveCall({
2807
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::admin_issue_vesting_lootbox_precision`,
2808
+ typeArguments: [module],
2809
+ arguments: [
2810
+ tx.object(this.sharedConfig.zoLootboxV2.adminCap),
2811
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxTreasury),
2812
+ tx.object(SUI_CLOCK_OBJECT_ID),
2813
+ tx.pure.u64(unlockedAmounts[i]),
2814
+ tx.pure.u64(lockedAmounts[i]),
2815
+ tx.pure.u64(lockDurationsMs[i]),
2816
+ tx.pure.address(beneficiary),
2817
+ ],
2818
+ })
2819
+ }
2820
+ }
2821
+
2822
+ public claimUnlockedV2(
2823
+ coin: string,
2824
+ vestingLootbox: string,
2825
+ ): Transaction {
2826
+ const tx = new Transaction()
2827
+
2828
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2829
+ if (coin !== 'zlp') {
2830
+ module = this.consts.coins[coin].module
2831
+ }
2832
+
2833
+ tx.moveCall({
2834
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::claim_unlocked`,
2835
+ typeArguments: [module],
2836
+ arguments: [
2837
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxTreasury),
2838
+ tx.object(vestingLootbox),
2839
+ ],
2840
+ })
2841
+
2842
+ return tx
2843
+ }
2844
+
2845
+ public claimVestedV2(
2846
+ coin: string,
2847
+ vestingLootbox: string,
2848
+ ): Transaction {
2849
+ const tx = new Transaction()
2850
+
2851
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2852
+ if (coin !== 'zlp') {
2853
+ module = this.consts.coins[coin].module
2854
+ }
2855
+
2856
+ tx.moveCall({
2857
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::claim_vested`,
2858
+ typeArguments: [module],
2859
+ arguments: [
2860
+ tx.object(this.sharedConfig.zoLootboxV2.lootboxTreasury),
2861
+ tx.object(vestingLootbox),
2862
+ tx.object(SUI_CLOCK_OBJECT_ID),
2863
+ ],
2864
+ })
2865
+
2866
+ return tx
2867
+ }
2868
+
2869
+ public destroyVestingLootboxV2(
2870
+ coin: string,
2871
+ vestingLootbox: string,
2872
+ ): Transaction {
2873
+ const tx = new Transaction()
2874
+
2875
+ let module = `${this.consts.zoCore.package}::zlp::ZLP`
2876
+ if (coin !== 'zlp') {
2877
+ module = this.consts.coins[coin].module
2878
+ }
2879
+
2880
+ tx.moveCall({
2881
+ target: `${this.sharedConfig.zoLootboxV2.upgradedPackage}::lootbox::destroy_vesting_lootbox`,
2882
+ typeArguments: [module],
2883
+ arguments: [tx.object(vestingLootbox)],
2884
+ })
2885
+
2886
+ return tx
2887
+ }
2888
+ }