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