zo-sdk 0.0.50 → 0.1.0

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 (206) hide show
  1. package/README.md +272 -20
  2. package/dist/abstract/BaseAPI.cjs +117 -0
  3. package/dist/abstract/BaseAPI.cjs.map +1 -0
  4. package/dist/abstract/BaseAPI.d.cts +131 -0
  5. package/dist/abstract/BaseAPI.d.cts.map +1 -0
  6. package/dist/abstract/BaseAPI.d.mts +131 -0
  7. package/dist/abstract/BaseAPI.d.mts.map +1 -0
  8. package/dist/abstract/BaseAPI.mjs +113 -0
  9. package/dist/abstract/BaseAPI.mjs.map +1 -0
  10. package/dist/abstract/BaseDataAPI.cjs +139 -0
  11. package/dist/abstract/BaseDataAPI.cjs.map +1 -0
  12. package/dist/abstract/BaseDataAPI.d.cts +89 -0
  13. package/dist/abstract/BaseDataAPI.d.cts.map +1 -0
  14. package/dist/abstract/BaseDataAPI.d.mts +89 -0
  15. package/dist/abstract/BaseDataAPI.d.mts.map +1 -0
  16. package/dist/abstract/BaseDataAPI.mjs +135 -0
  17. package/dist/abstract/BaseDataAPI.mjs.map +1 -0
  18. package/dist/abstract/index.cjs +12 -0
  19. package/dist/abstract/index.cjs.map +1 -0
  20. package/dist/abstract/index.d.cts +7 -0
  21. package/dist/abstract/index.d.cts.map +1 -0
  22. package/dist/abstract/index.d.mts +7 -0
  23. package/dist/abstract/index.d.mts.map +1 -0
  24. package/dist/abstract/index.mjs +7 -0
  25. package/dist/abstract/index.mjs.map +1 -0
  26. package/dist/bcs.cjs +42 -0
  27. package/dist/bcs.cjs.map +1 -0
  28. package/dist/bcs.d.cts +91 -0
  29. package/dist/bcs.d.cts.map +1 -0
  30. package/dist/bcs.d.mts +91 -0
  31. package/dist/bcs.d.mts.map +1 -0
  32. package/dist/bcs.mjs +39 -0
  33. package/dist/bcs.mjs.map +1 -0
  34. package/dist/consts/deployments-slp-mainnet.json +710 -0
  35. package/dist/consts/deployments-slp-testnet.json +109 -0
  36. package/dist/consts/deployments-usdz-mainnet.json +180 -0
  37. package/dist/consts/deployments-usdz-testnet.json +98 -0
  38. package/dist/consts/{deployments-mainnet.json → deployments-zlp-mainnet.json} +278 -42
  39. package/dist/consts/index.cjs +40 -8
  40. package/dist/consts/index.cjs.map +1 -1
  41. package/dist/consts/index.d.cts +81 -11
  42. package/dist/consts/index.d.cts.map +1 -1
  43. package/dist/consts/index.d.mts +81 -11
  44. package/dist/consts/index.d.mts.map +1 -1
  45. package/dist/consts/index.mjs +39 -7
  46. package/dist/consts/index.mjs.map +1 -1
  47. package/dist/consts/price_id_to_object_id.mainnet.json +9 -1
  48. package/dist/data.cjs +2 -2
  49. package/dist/data.cjs.map +1 -1
  50. package/dist/data.mjs +2 -2
  51. package/dist/data.mjs.map +1 -1
  52. package/dist/factory/SDKFactory.cjs +185 -0
  53. package/dist/factory/SDKFactory.cjs.map +1 -0
  54. package/dist/factory/SDKFactory.d.cts +74 -0
  55. package/dist/factory/SDKFactory.d.cts.map +1 -0
  56. package/dist/factory/SDKFactory.d.mts +74 -0
  57. package/dist/factory/SDKFactory.d.mts.map +1 -0
  58. package/dist/factory/SDKFactory.mjs +179 -0
  59. package/dist/factory/SDKFactory.mjs.map +1 -0
  60. package/dist/implementations/SLPAPI.cjs +829 -0
  61. package/dist/implementations/SLPAPI.cjs.map +1 -0
  62. package/dist/implementations/SLPAPI.d.cts +120 -0
  63. package/dist/implementations/SLPAPI.d.cts.map +1 -0
  64. package/dist/implementations/SLPAPI.d.mts +120 -0
  65. package/dist/implementations/SLPAPI.d.mts.map +1 -0
  66. package/dist/implementations/SLPAPI.mjs +825 -0
  67. package/dist/implementations/SLPAPI.mjs.map +1 -0
  68. package/dist/implementations/SLPDataAPI.cjs +916 -0
  69. package/dist/implementations/SLPDataAPI.cjs.map +1 -0
  70. package/dist/implementations/SLPDataAPI.d.cts +102 -0
  71. package/dist/implementations/SLPDataAPI.d.cts.map +1 -0
  72. package/dist/implementations/SLPDataAPI.d.mts +102 -0
  73. package/dist/implementations/SLPDataAPI.d.mts.map +1 -0
  74. package/dist/implementations/SLPDataAPI.mjs +912 -0
  75. package/dist/implementations/SLPDataAPI.mjs.map +1 -0
  76. package/dist/implementations/USDZAPI.cjs +522 -0
  77. package/dist/implementations/USDZAPI.cjs.map +1 -0
  78. package/dist/implementations/USDZAPI.d.cts +118 -0
  79. package/dist/implementations/USDZAPI.d.cts.map +1 -0
  80. package/dist/implementations/USDZAPI.d.mts +118 -0
  81. package/dist/implementations/USDZAPI.d.mts.map +1 -0
  82. package/dist/implementations/USDZAPI.mjs +518 -0
  83. package/dist/implementations/USDZAPI.mjs.map +1 -0
  84. package/dist/implementations/USDZDataAPI.cjs +697 -0
  85. package/dist/implementations/USDZDataAPI.cjs.map +1 -0
  86. package/dist/implementations/USDZDataAPI.d.cts +86 -0
  87. package/dist/implementations/USDZDataAPI.d.cts.map +1 -0
  88. package/dist/implementations/USDZDataAPI.d.mts +86 -0
  89. package/dist/implementations/USDZDataAPI.d.mts.map +1 -0
  90. package/dist/implementations/USDZDataAPI.mjs +693 -0
  91. package/dist/implementations/USDZDataAPI.mjs.map +1 -0
  92. package/dist/implementations/ZLPAPI.cjs +809 -0
  93. package/dist/implementations/ZLPAPI.cjs.map +1 -0
  94. package/dist/implementations/ZLPAPI.d.cts +121 -0
  95. package/dist/implementations/ZLPAPI.d.cts.map +1 -0
  96. package/dist/implementations/ZLPAPI.d.mts +121 -0
  97. package/dist/implementations/ZLPAPI.d.mts.map +1 -0
  98. package/dist/implementations/ZLPAPI.mjs +805 -0
  99. package/dist/implementations/ZLPAPI.mjs.map +1 -0
  100. package/dist/implementations/ZLPDataAPI.cjs +724 -0
  101. package/dist/implementations/ZLPDataAPI.cjs.map +1 -0
  102. package/dist/implementations/ZLPDataAPI.d.cts +83 -0
  103. package/dist/implementations/ZLPDataAPI.d.cts.map +1 -0
  104. package/dist/implementations/ZLPDataAPI.d.mts +83 -0
  105. package/dist/implementations/ZLPDataAPI.d.mts.map +1 -0
  106. package/dist/implementations/ZLPDataAPI.mjs +720 -0
  107. package/dist/implementations/ZLPDataAPI.mjs.map +1 -0
  108. package/dist/implementations/index.cjs +22 -0
  109. package/dist/implementations/index.cjs.map +1 -0
  110. package/dist/implementations/index.d.cts +11 -0
  111. package/dist/implementations/index.d.cts.map +1 -0
  112. package/dist/implementations/index.d.mts +11 -0
  113. package/dist/implementations/index.d.mts.map +1 -0
  114. package/dist/implementations/index.mjs +13 -0
  115. package/dist/implementations/index.mjs.map +1 -0
  116. package/dist/index.cjs +47 -0
  117. package/dist/index.cjs.map +1 -1
  118. package/dist/index.d.cts +45 -0
  119. package/dist/index.d.cts.map +1 -1
  120. package/dist/index.d.mts +45 -0
  121. package/dist/index.d.mts.map +1 -1
  122. package/dist/index.mjs +45 -0
  123. package/dist/index.mjs.map +1 -1
  124. package/dist/interfaces/base.cjs +8 -0
  125. package/dist/interfaces/base.cjs.map +1 -0
  126. package/dist/interfaces/base.d.cts +293 -0
  127. package/dist/interfaces/base.d.cts.map +1 -0
  128. package/dist/interfaces/base.d.mts +293 -0
  129. package/dist/interfaces/base.d.mts.map +1 -0
  130. package/dist/interfaces/base.mjs +6 -0
  131. package/dist/interfaces/base.mjs.map +1 -0
  132. package/dist/interfaces/index.cjs +29 -0
  133. package/dist/interfaces/index.cjs.map +1 -0
  134. package/dist/interfaces/index.d.cts +13 -0
  135. package/dist/interfaces/index.d.cts.map +1 -0
  136. package/dist/interfaces/index.d.mts +13 -0
  137. package/dist/interfaces/index.d.mts.map +1 -0
  138. package/dist/interfaces/index.mjs +13 -0
  139. package/dist/interfaces/index.mjs.map +1 -0
  140. package/dist/interfaces/slp.cjs +9 -0
  141. package/dist/interfaces/slp.cjs.map +1 -0
  142. package/dist/interfaces/slp.d.cts +115 -0
  143. package/dist/interfaces/slp.d.cts.map +1 -0
  144. package/dist/interfaces/slp.d.mts +115 -0
  145. package/dist/interfaces/slp.d.mts.map +1 -0
  146. package/dist/interfaces/slp.mjs +7 -0
  147. package/dist/interfaces/slp.mjs.map +1 -0
  148. package/dist/interfaces/usdz.cjs +7 -0
  149. package/dist/interfaces/usdz.cjs.map +1 -0
  150. package/dist/interfaces/usdz.d.cts +40 -0
  151. package/dist/interfaces/usdz.d.cts.map +1 -0
  152. package/dist/interfaces/usdz.d.mts +40 -0
  153. package/dist/interfaces/usdz.d.mts.map +1 -0
  154. package/dist/interfaces/usdz.mjs +6 -0
  155. package/dist/interfaces/usdz.mjs.map +1 -0
  156. package/dist/interfaces/zlp.cjs +7 -0
  157. package/dist/interfaces/zlp.cjs.map +1 -0
  158. package/dist/interfaces/zlp.d.cts +45 -0
  159. package/dist/interfaces/zlp.d.cts.map +1 -0
  160. package/dist/interfaces/zlp.d.mts +45 -0
  161. package/dist/interfaces/zlp.d.mts.map +1 -0
  162. package/dist/interfaces/zlp.mjs +6 -0
  163. package/dist/interfaces/zlp.mjs.map +1 -0
  164. package/dist/oracle.cjs +7 -35
  165. package/dist/oracle.cjs.map +1 -1
  166. package/dist/oracle.d.cts +3 -4
  167. package/dist/oracle.d.cts.map +1 -1
  168. package/dist/oracle.d.mts +3 -4
  169. package/dist/oracle.d.mts.map +1 -1
  170. package/dist/oracle.mjs +8 -32
  171. package/dist/oracle.mjs.map +1 -1
  172. package/package.json +1 -1
  173. package/src/abstract/BaseAPI.ts +429 -0
  174. package/src/abstract/BaseDataAPI.ts +204 -0
  175. package/src/abstract/index.ts +7 -0
  176. package/src/bcs.ts +45 -0
  177. package/src/consts/deployments-slp-mainnet.json +710 -0
  178. package/src/consts/deployments-slp-testnet.json +109 -0
  179. package/src/consts/deployments-usdz-mainnet.json +180 -0
  180. package/src/consts/deployments-usdz-testnet.json +98 -0
  181. package/src/consts/{deployments-mainnet.json → deployments-zlp-mainnet.json} +279 -43
  182. package/src/consts/index.ts +134 -39
  183. package/src/consts/price_id_to_object_id.mainnet.json +10 -2
  184. package/src/data.ts +2 -2
  185. package/src/factory/SDKFactory.ts +282 -0
  186. package/src/implementations/SLPAPI.ts +1207 -0
  187. package/src/implementations/SLPDataAPI.ts +1188 -0
  188. package/src/implementations/USDZAPI.ts +715 -0
  189. package/src/implementations/USDZDataAPI.ts +826 -0
  190. package/src/implementations/ZLPAPI.ts +1130 -0
  191. package/src/implementations/ZLPDataAPI.ts +856 -0
  192. package/src/implementations/index.ts +14 -0
  193. package/src/index.ts +53 -0
  194. package/src/interfaces/base.ts +556 -0
  195. package/src/interfaces/index.ts +45 -0
  196. package/src/interfaces/slp.ts +156 -0
  197. package/src/interfaces/usdz.ts +71 -0
  198. package/src/interfaces/zlp.ts +96 -0
  199. package/src/oracle.ts +12 -42
  200. package/tsconfig.json +4 -2
  201. package/dist/consts/staking/deployments-mainnet.json +0 -12
  202. package/dist/consts/staking/deployments-testnet.json +0 -11
  203. package/src/consts/staking/deployments-mainnet.json +0 -12
  204. package/src/consts/staking/deployments-testnet.json +0 -11
  205. /package/dist/consts/{deployments-testnet.json → deployments-zlp-testnet.json} +0 -0
  206. /package/src/consts/{deployments-testnet.json → deployments-zlp-testnet.json} +0 -0
@@ -0,0 +1,1207 @@
1
+ /**
2
+ * SLP API implementation
3
+ * Implements SLP-specific trading and transaction methods for Sudo SDK
4
+ */
5
+
6
+ import type { SuiClient } from '@mysten/sui/client'
7
+ import { Transaction } from '@mysten/sui/transactions'
8
+ import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils'
9
+ import type { Network } from '../consts'
10
+ import { ALLOW_TRADE_CAN_TRADE, ALLOW_TRADE_MUST_TRADE, ALLOW_TRADE_NO_TRADE, LPToken } from '../consts'
11
+ import type {
12
+ ISLPAPI,
13
+ ISLPCredential,
14
+ IBaseOrderCapInfo,
15
+ IBaseOrderInfo,
16
+ IBasePositionCapInfo,
17
+ IBasePositionConfig,
18
+ IBasePositionInfo,
19
+ IBaseStaked,
20
+ IBaseHistoryResponse,
21
+ IBaseMarketInfo,
22
+ IBaseMarketValuationInfo,
23
+ IBaseSymbolInfo,
24
+ IBaseVaultInfo,
25
+ IBaseRebaseFeeModel,
26
+ IBaseStakePool
27
+ } from '../interfaces'
28
+ import { BaseAPI } from '../abstract'
29
+ import { SLPDataAPI } from './SLPDataAPI'
30
+ import { joinSymbol } from '../utils'
31
+ import { KioskClient, KioskOwnerCap, KioskTransaction } from '@mysten/kiosk'
32
+
33
+ export class SLPAPI extends BaseAPI implements ISLPAPI {
34
+ public dataAPI: SLPDataAPI
35
+
36
+ constructor(
37
+ network: Network,
38
+ provider: SuiClient,
39
+ apiEndpoint: string,
40
+ connectionURL: string
41
+ ) {
42
+ super(network, provider, apiEndpoint, connectionURL, LPToken.SLP)
43
+ this.dataAPI = new SLPDataAPI(network, provider, apiEndpoint, connectionURL)
44
+ }
45
+
46
+ public valuateVaults(tx: Transaction) {
47
+ throw new Error('Method not implemented.')
48
+ }
49
+ public valuateSymbols(tx: Transaction) {
50
+ throw new Error('Method not implemented.')
51
+ }
52
+ public valuate(tx: Transaction): { vaultsValuation: any; symbolsValuation: any } {
53
+ throw new Error('Method not implemented.')
54
+ }
55
+ public valuateMarket(): Promise<IBaseMarketValuationInfo> {
56
+ throw new Error('Method not implemented.')
57
+ }
58
+ public fundingFeeRate(indexToken: string, long: boolean, sender?: string): Promise<number> {
59
+ throw new Error('Method not implemented.')
60
+ }
61
+ public rebaseFeeRate(collateralToken: string, increase: boolean, amount: number, sender?: string): Promise<number> {
62
+ throw new Error('Method not implemented.')
63
+ }
64
+ public reservingFeeRate(collateralToken: string, amount: number, sender?: string): Promise<number> {
65
+ throw new Error('Method not implemented.')
66
+ }
67
+ public calcPositionReserveFeeAmount(position: IBasePositionInfo): Promise<number> {
68
+ throw new Error('Method not implemented.')
69
+ }
70
+ public calcPositionFundingFeeValue(position: IBasePositionInfo): Promise<number> {
71
+ throw new Error('Method not implemented.')
72
+ }
73
+ public getMarketInfo(): Promise<IBaseMarketInfo> {
74
+ throw new Error('Method not implemented.')
75
+ }
76
+ public getVaultInfo(vault: string): Promise<IBaseVaultInfo> {
77
+ throw new Error('Method not implemented.')
78
+ }
79
+ public getSymbolInfo(tokenId: string, long: boolean): Promise<IBaseSymbolInfo> {
80
+ throw new Error('Method not implemented.')
81
+ }
82
+ public getPositionConfig(indexToken: string, long: boolean): Promise<IBasePositionConfig> {
83
+ throw new Error('Method not implemented.')
84
+ }
85
+ public getRebaseFeeModel(): Promise<IBaseRebaseFeeModel> {
86
+ throw new Error('Method not implemented.')
87
+ }
88
+ public getOpenPositions(): Promise<IBasePositionInfo[]> {
89
+ throw new Error('Method not implemented.')
90
+ }
91
+ public getPositionCapInfoList(owner: string): Promise<IBasePositionCapInfo[]> {
92
+ throw new Error('Method not implemented.')
93
+ }
94
+ public getPositionInfoList(positionCapInfoList: IBasePositionCapInfo[], owner: string): Promise<IBasePositionInfo[]> {
95
+ throw new Error('Method not implemented.')
96
+ }
97
+ public getOrderCapInfoList(owner: string): Promise<IBaseOrderCapInfo[]> {
98
+ throw new Error('Method not implemented.')
99
+ }
100
+ public getOrderInfoList(orderCapInfoList: IBaseOrderCapInfo[], owner: string): Promise<IBaseOrderInfo[]> {
101
+ throw new Error('Method not implemented.')
102
+ }
103
+ public getHistory(trader: string, page: number, limit: number, orderType?: string, symbol?: string): Promise<IBaseHistoryResponse> {
104
+ throw new Error('Method not implemented.')
105
+ }
106
+ public getStaked(owner: string): Promise<IBaseStaked> {
107
+ throw new Error('Method not implemented.')
108
+ }
109
+ public getStakePool(): Promise<IBaseStakePool> {
110
+ throw new Error('Method not implemented.')
111
+ }
112
+ public hasReferral(referree: string): Promise<boolean> {
113
+ throw new Error('Method not implemented.')
114
+ }
115
+ public getReferralData(referree: string): Promise<any> {
116
+ throw new Error('Method not implemented.')
117
+ }
118
+
119
+ /**
120
+ * Deposits collateral into SLP vault using Sudo SDK approach
121
+ */
122
+ public async deposit(
123
+ coin: string,
124
+ coinObjects: string[],
125
+ amount: number,
126
+ minAmountOut?: number,
127
+ referralAddress?: string,
128
+ sender?: string
129
+ ): Promise<Transaction> {
130
+ let tx = new Transaction()
131
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
132
+ tx = await this.addReferral(referralAddress, tx)
133
+ }
134
+ tx = await this.initOracleTxb(
135
+ Object.keys(this.consts.pythFeeder.feeder),
136
+ )
137
+ const coinObject = this.processCoins(tx, coin, coinObjects)
138
+ const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
139
+
140
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
141
+
142
+ tx.moveCall({
143
+ target: `${this.consts.sudoCore.upgradedPackage}::market::deposit`,
144
+ typeArguments: [
145
+ `${this.consts.sudoCore.package}::slp::SLP`,
146
+ this.consts.coins[coin].module,
147
+ ],
148
+ arguments: [
149
+ tx.object(this.consts.sudoCore.market),
150
+ tx.object(this.consts.sudoCore.rebaseFeeModel),
151
+ depositObject,
152
+ tx.pure.u64(minAmountOut || 0),
153
+ vaultsValuation,
154
+ symbolsValuation,
155
+ ],
156
+ })
157
+ return tx
158
+ }
159
+
160
+ /**
161
+ * Withdraws collateral from SLP vault using Sudo SDK approach
162
+ */
163
+ public async withdraw(
164
+ coin: string,
165
+ lpCoinObjects: string[],
166
+ amount: number,
167
+ minAmountOut?: number
168
+ ): Promise<Transaction> {
169
+ const tx = await this.initOracleTxb(
170
+ Object.keys(this.consts.pythFeeder.feeder),
171
+ )
172
+ const lpCoinObject = this.processCoins(tx, `${this.consts.sudoCore.package}::slp::SLP`, lpCoinObjects)
173
+ const [withdrawObject] = tx.splitCoins(lpCoinObject, [tx.pure.u64(amount)])
174
+ const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
175
+
176
+ tx.moveCall({
177
+ target: `${this.consts.sudoCore.upgradedPackage}::market::withdraw`,
178
+ typeArguments: [
179
+ `${this.consts.sudoCore.package}::slp::SLP`,
180
+ this.consts.coins[coin].module,
181
+ ],
182
+ arguments: [
183
+ tx.object(this.consts.sudoCore.market),
184
+ tx.object(this.consts.sudoCore.rebaseFeeModel),
185
+ withdrawObject,
186
+ tx.pure.u64(minAmountOut || 0),
187
+ vaultsValuation,
188
+ symbolsValuation,
189
+ ],
190
+ })
191
+ return tx
192
+ }
193
+
194
+ public async swap(
195
+ fromToken: string,
196
+ toToken: string,
197
+ fromAmount: bigint,
198
+ fromCoinObjects: string[],
199
+ minAmountOut?: number
200
+ ): Promise<Transaction> {
201
+ const tx = await this.initOracleTxb(
202
+ Object.keys(this.consts.sudoCore.vaults)
203
+ )
204
+ const fromCoinObject = this.processCoins(tx, fromToken, fromCoinObjects)
205
+ const [fromDepositObject] = tx.splitCoins(fromCoinObject, [
206
+ tx.pure.u64(fromAmount),
207
+ ])
208
+ const vaultsValuation = this.dataAPI.valuateVaults(tx)
209
+
210
+ tx.moveCall({
211
+ target: `${this.consts.sudoCore.upgradedPackage}::market::swap`,
212
+ typeArguments: [
213
+ `${this.consts.sudoCore.package}::slp::SLP`,
214
+ this.consts.coins[fromToken].module,
215
+ this.consts.coins[toToken].module,
216
+ ],
217
+ arguments: [
218
+ tx.object(this.consts.sudoCore.market),
219
+ tx.object(this.consts.sudoCore.rebaseFeeModel),
220
+ fromDepositObject,
221
+ tx.pure.u64(minAmountOut || 0),
222
+ vaultsValuation,
223
+ ],
224
+ })
225
+ return tx
226
+ }
227
+
228
+ /**
229
+ * Stakes SLP tokens in Sudo staking pools
230
+ */
231
+ public async stake(
232
+ lpCoinObjects: string[],
233
+ amount: bigint,
234
+ pool: string
235
+ ): Promise<Transaction> {
236
+ if (!this.consts.sudoStaking) {
237
+ throw new Error('Sudo staking configuration not found')
238
+ }
239
+
240
+ const tx = new Transaction()
241
+ const coinObject = this.processCoins(tx, 'slp', lpCoinObjects)
242
+ const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
243
+
244
+ tx.moveCall({
245
+ target: `${this.consts.sudoStaking.package}::pool::deposit`,
246
+ typeArguments: [
247
+ `${this.consts.sudoCore.package}::slp::SLP`,
248
+ `${this.consts.sudoCore.package}::slp::SLP`,
249
+ ],
250
+ arguments: [
251
+ tx.object(pool),
252
+ tx.object(SUI_CLOCK_OBJECT_ID),
253
+ depositObject,
254
+ ],
255
+ })
256
+ return tx
257
+ }
258
+
259
+ /**
260
+ * Unstakes SLP tokens from Sudo staking pools
261
+ */
262
+ public async unstake(
263
+ credentials: ISLPCredential[],
264
+ amount: bigint,
265
+ pool: string
266
+ ): Promise<Transaction> {
267
+ if (!this.consts.sudoStaking) {
268
+ throw new Error('Sudo staking configuration not found')
269
+ }
270
+
271
+ const tx = new Transaction()
272
+
273
+ for (const credential of credentials) {
274
+ // eslint-disable-next-line unicorn/prefer-math-min-max
275
+ const withdrawAmount =
276
+ amount < credential.amount ? amount : credential.amount
277
+ amount -= withdrawAmount
278
+ tx.moveCall({
279
+ target: `${this.consts.sudoStaking.package}::pool::withdraw`,
280
+ typeArguments: [
281
+ `${this.consts.sudoCore.package}::slp::SLP`,
282
+ `${this.consts.sudoCore.package}::slp::SLP`,
283
+ ],
284
+ arguments: [
285
+ tx.object(pool),
286
+ tx.object(SUI_CLOCK_OBJECT_ID),
287
+ tx.object(credential.id),
288
+ tx.pure.u64(withdrawAmount),
289
+ ],
290
+ })
291
+ if (credential.amount === BigInt(0)) {
292
+ tx.moveCall({
293
+ target: `${this.consts.sudoStaking.package}::pool::clear_empty_credential`,
294
+ typeArguments: [
295
+ `${this.consts.sudoCore.package}::slp::SLP`,
296
+ `${this.consts.sudoCore.package}::slp::SLP`,
297
+ ],
298
+ arguments: [tx.object(credential.id)],
299
+ })
300
+ }
301
+ }
302
+ return tx
303
+ }
304
+
305
+ /**
306
+ * Opens a position using Sudo SDK approach
307
+ */
308
+ public async openPosition(
309
+ collateralToken: string,
310
+ indexToken: string,
311
+ size: bigint,
312
+ collateralAmount: bigint,
313
+ coinObjects: string[],
314
+ long: boolean,
315
+ reserveAmount: bigint,
316
+ indexPrice: number,
317
+ collateralPrice: number,
318
+ isLimitOrder = false,
319
+ isIocOrder = false,
320
+ pricesSlippage: number = 0.003,
321
+ collateralSlippage: number = 0.5,
322
+ relayerFee = BigInt(0.5),
323
+ referralAddress?: string,
324
+ sender?: string
325
+ ): Promise<Transaction> {
326
+ let tx = new Transaction()
327
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
328
+ tx = await this.addReferral(referralAddress, tx)
329
+ }
330
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
331
+ const coinObject = this.processCoins(tx, collateralToken, coinObjects)
332
+ const [depositObject] = tx.splitCoins(coinObject, [
333
+ tx.pure.u64(collateralAmount),
334
+ ])
335
+ const feeObject = tx.splitCoins(tx.gas, [tx.pure.u64(relayerFee || BigInt(0.5))]) // Sudo contract requires SUI as fee
336
+
337
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
338
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage || 0.003)
339
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage || 0.5)
340
+
341
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
342
+ if (isLimitOrder) {
343
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
344
+ }
345
+
346
+ tx.moveCall({
347
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_v1_2`,
348
+ typeArguments: [
349
+ `${this.consts.sudoCore.package}::slp::SLP`,
350
+ this.consts.coins[collateralToken].module,
351
+ this.consts.coins[indexToken].module,
352
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
353
+ this.consts.coins['sui'].module,
354
+ ],
355
+ arguments: [
356
+ tx.object(SUI_CLOCK_OBJECT_ID),
357
+ tx.object(this.consts.sudoCore.market),
358
+ tx.object(
359
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
360
+ ),
361
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
362
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
363
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
364
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
365
+ depositObject,
366
+ feeObject,
367
+ tx.pure.u8(allowTrade),
368
+ tx.pure.u64(size),
369
+ tx.pure.u64(reserveAmount),
370
+ tx.pure.u256(adjustCollateralPrice),
371
+ tx.pure.u256(adjustPrice),
372
+ tx.pure.bool(isLimitOrder),
373
+ ],
374
+ })
375
+ return tx
376
+ }
377
+
378
+ /**
379
+ * Decreases an existing position in SLP using Sudo SDK approach
380
+ */
381
+ public async decreasePosition(
382
+ pcpId: string,
383
+ collateralToken: string,
384
+ indexToken: string,
385
+ amount: bigint,
386
+ long: boolean,
387
+ indexPrice: number,
388
+ collateralPrice: number,
389
+ isTriggerOrder = false,
390
+ isTakeProfitOrder = true,
391
+ isIocOrder = false,
392
+ pricesSlippage: number = 0.003,
393
+ collateralSlippage: number = 0.5,
394
+ relayerFee = BigInt(0.5),
395
+ coinObjects?: string[]
396
+ ): Promise<Transaction> {
397
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
398
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
399
+ const feeObject = tx.splitCoins(tx.gas, [tx.pure.u64(relayerFee)]) // Sudo contract requires SUI as fee
400
+
401
+ const adjustPrice = this.processSlippage(
402
+ indexPrice,
403
+ !long,
404
+ isTriggerOrder ? 0 : pricesSlippage
405
+ )
406
+ const adjustCollateralPrice = this.processSlippage(
407
+ collateralPrice,
408
+ false,
409
+ collateralSlippage
410
+ )
411
+
412
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
413
+ if (isTriggerOrder) {
414
+ if (isIocOrder || !isTakeProfitOrder) {
415
+ allowTrade = ALLOW_TRADE_NO_TRADE
416
+ } else {
417
+ allowTrade = ALLOW_TRADE_CAN_TRADE
418
+ }
419
+ } else {
420
+ isTakeProfitOrder = true
421
+ }
422
+
423
+ tx.moveCall({
424
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_v1_2`,
425
+ typeArguments: [
426
+ `${this.consts.sudoCore.package}::slp::SLP`,
427
+ this.consts.coins[collateralToken].module,
428
+ this.consts.coins[indexToken].module,
429
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
430
+ this.consts.coins['sui'].module,
431
+ ],
432
+ arguments: [
433
+ tx.object(SUI_CLOCK_OBJECT_ID),
434
+ tx.object(this.consts.sudoCore.market),
435
+ tx.object(pcpId),
436
+ tx.object(
437
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
438
+ ),
439
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
440
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
441
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
442
+ feeObject,
443
+ tx.pure.u8(allowTrade),
444
+ tx.pure.bool(isTakeProfitOrder),
445
+ tx.pure.u64(amount),
446
+ tx.pure.u256(adjustCollateralPrice),
447
+ tx.pure.u256(adjustPrice),
448
+ tx.pure.bool(isTriggerOrder),
449
+ ],
450
+ })
451
+
452
+ return tx
453
+ }
454
+
455
+ public async decreaseMultiPositions(
456
+ positions: Array<{
457
+ pcpId: string,
458
+ collateralToken: string,
459
+ coinObjects: string[],
460
+ indexToken: string,
461
+ amount: bigint,
462
+ long: boolean,
463
+ indexPrice: number,
464
+ collateralPrice: number,
465
+ isTriggerOrder: boolean,
466
+ isTakeProfitOrder: boolean,
467
+ isIocOrder: boolean,
468
+ slippage: number,
469
+ relayerFee: bigint,
470
+ }>, tx?: Transaction
471
+ ): Promise<Transaction> {
472
+ if (!tx) {
473
+ tx = new Transaction()
474
+ }
475
+ tx = await this.initOracleTxb(positions.map(position => [position.collateralToken, position.indexToken]).flat(), tx)
476
+
477
+ for (const position of positions) {
478
+ const {
479
+ pcpId,
480
+ collateralToken,
481
+ coinObjects, indexToken, amount, long, indexPrice, collateralPrice, isTriggerOrder, isTakeProfitOrder, isIocOrder, slippage, relayerFee
482
+ } = position
483
+ let innerIsTakeProfitOrder = isTakeProfitOrder
484
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
485
+ const coinObject = this.processCoins(tx, collateralToken, coinObjects)
486
+ const feeObject = tx.splitCoins(coinObject, [tx.pure.u64(relayerFee)])
487
+
488
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : slippage)
489
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, 0.5)
490
+
491
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
492
+ if (isTriggerOrder) {
493
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
494
+ } else {
495
+ innerIsTakeProfitOrder = true
496
+ }
497
+
498
+ tx.moveCall({
499
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_v1_2`,
500
+ typeArguments: [
501
+ `${this.consts.sudoCore.package}::slp::SLP`,
502
+ this.consts.coins[collateralToken].module,
503
+ this.consts.coins[indexToken].module,
504
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
505
+ this.consts.coins['sui'].module,
506
+ ],
507
+ arguments: [
508
+ tx.object(SUI_CLOCK_OBJECT_ID),
509
+ tx.object(this.consts.sudoCore.market),
510
+ tx.object(pcpId),
511
+ tx.object(
512
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
513
+ ),
514
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
515
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
516
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
517
+ feeObject,
518
+ tx.pure.u8(allowTrade),
519
+ tx.pure.bool(isTakeProfitOrder),
520
+ tx.pure.u64(amount),
521
+ tx.pure.u256(adjustCollateralPrice),
522
+ tx.pure.u256(adjustPrice),
523
+ tx.pure.bool(isTriggerOrder),
524
+ ],
525
+ })
526
+ }
527
+ return tx
528
+ }
529
+
530
+ public async pledgeInPosition(
531
+ pcpId: string,
532
+ collateralToken: string,
533
+ indexToken: string,
534
+ amount: number,
535
+ coinObjects: string[],
536
+ long: boolean
537
+ ): Promise<Transaction> {
538
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
539
+ const coinObject = this.processCoins(tx, collateralToken, coinObjects)
540
+ const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
541
+
542
+ tx.moveCall({
543
+ target: `${this.consts.sudoCore.upgradedPackage}::market::pledge_in_position`,
544
+ typeArguments: [
545
+ `${this.consts.sudoCore.package}::slp::SLP`,
546
+ this.consts.coins[collateralToken].module,
547
+ this.consts.coins[indexToken].module,
548
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
549
+ ],
550
+ arguments: [
551
+ tx.object(this.consts.sudoCore.market),
552
+ tx.object(pcpId),
553
+ depositObject,
554
+ ],
555
+ })
556
+ return tx
557
+ }
558
+
559
+ public async redeemFromPosition(
560
+ pcpId: string,
561
+ collateralToken: string,
562
+ indexToken: string,
563
+ amount: number,
564
+ long: boolean
565
+ ): Promise<Transaction> {
566
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
567
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
568
+
569
+ tx.moveCall({
570
+ target: `${this.consts.sudoCore.upgradedPackage}::market::redeem_from_position_v1_1`,
571
+ typeArguments: [
572
+ `${this.consts.sudoCore.package}::slp::SLP`,
573
+ this.consts.coins[collateralToken].module,
574
+ this.consts.coins[indexToken].module,
575
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
576
+ ],
577
+ arguments: [
578
+ tx.object(SUI_CLOCK_OBJECT_ID),
579
+ tx.object(this.consts.sudoCore.market),
580
+ tx.object(pcpId),
581
+ tx.object(
582
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
583
+ ),
584
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
585
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
586
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
587
+ tx.pure.u64(amount),
588
+ ],
589
+ })
590
+
591
+ return tx
592
+ }
593
+
594
+ public async cancelOrder(
595
+ orderCapId: string,
596
+ collateralToken: string,
597
+ indexToken: string,
598
+ long: boolean,
599
+ type: string,
600
+ isV11Order?: boolean
601
+ ): Promise<Transaction> {
602
+ const tx = new Transaction()
603
+ let functionName = ''
604
+ switch (type) {
605
+ case 'OPEN_POSITION':
606
+ functionName = 'clear_open_position_order_v1_1'
607
+ break
608
+ case 'DECREASE_POSITION':
609
+ functionName = 'clear_decrease_position_order_v1_1'
610
+ break
611
+ default:
612
+ throw new Error('invalid order type')
613
+ }
614
+ tx.moveCall({
615
+ target: `${this.consts.sudoCore.upgradedPackage}::market::${functionName}`,
616
+ typeArguments: [
617
+ `${this.consts.sudoCore.package}::slp::SLP`,
618
+ this.consts.coins[collateralToken].module,
619
+ this.consts.coins[indexToken].module,
620
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
621
+ this.consts.coins['sui'].module,
622
+ ],
623
+ arguments: [
624
+ tx.object(this.consts.sudoCore.market),
625
+ tx.object(orderCapId),
626
+ ],
627
+ })
628
+ return tx
629
+ }
630
+
631
+ public async cancelMultiOrders(
632
+ orders: Array<{
633
+ orderCapId: string,
634
+ collateralToken: string,
635
+ indexToken: string,
636
+ long: boolean,
637
+ type: string,
638
+ isV11Order?: boolean
639
+ }>, tx?: Transaction
640
+ ): Promise<Transaction> {
641
+ if (!tx) {
642
+ tx = new Transaction()
643
+ }
644
+
645
+ for (const order of orders) {
646
+ const { orderCapId, collateralToken, indexToken, long, type, isV11Order } = order
647
+ let functionName = ''
648
+ switch (type) {
649
+ case 'OPEN_POSITION': {
650
+ functionName = isV11Order ? 'clear_open_position_order_v1_1' : 'clear_open_position_order_v1_1'
651
+ break
652
+ }
653
+ case 'DECREASE_POSITION': {
654
+ functionName = isV11Order
655
+ ? 'clear_decrease_position_order_v1_1'
656
+ : 'clear_decrease_position_order_v1_1'
657
+ break
658
+ }
659
+ default: {
660
+ throw new Error('invalid order type')
661
+ }
662
+ }
663
+
664
+ tx.moveCall({
665
+ target: `${this.consts.sudoCore.upgradedPackage}::market::${functionName}`,
666
+ typeArguments: [
667
+ `${this.consts.sudoCore.package}::slp::SLP`,
668
+ this.consts.coins[collateralToken].module,
669
+ this.consts.coins[indexToken].module,
670
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
671
+ this.consts.coins[collateralToken].module,
672
+ ],
673
+ arguments: [tx.object(this.consts.sudoCore.market), tx.object(orderCapId)],
674
+ })
675
+ }
676
+ return tx
677
+ }
678
+
679
+ public clearClosedPosition(
680
+ pcpId: string,
681
+ collateralToken: string,
682
+ indexToken: string,
683
+ long: boolean,
684
+ tx: Transaction,
685
+ ): void {
686
+ tx.moveCall({
687
+ target: `${this.consts.sudoCore.upgradedPackage}::market::clear_closed_position`,
688
+ typeArguments: [
689
+ `${this.consts.sudoCore.package}::slp::SLP`,
690
+ this.consts.coins[collateralToken].module,
691
+ this.consts.coins[indexToken].module,
692
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
693
+ ],
694
+ arguments: [tx.object(this.consts.sudoCore.market), tx.object(pcpId)],
695
+ })
696
+ }
697
+
698
+ public clearOpenPositionOrder(
699
+ orderCapId: string,
700
+ collateralToken: string,
701
+ indexToken: string,
702
+ long: boolean,
703
+ tx: Transaction,
704
+ isV11Order?: boolean
705
+ ): void {
706
+ tx.moveCall({
707
+ target: `${this.consts.sudoCore.upgradedPackage}::market::clear_open_position_order_v1_1`,
708
+ typeArguments: [
709
+ `${this.consts.sudoCore.package}::slp::SLP`,
710
+ this.consts.coins[collateralToken].module,
711
+ this.consts.coins[indexToken].module,
712
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
713
+ this.consts.coins['sui'].module,
714
+ ],
715
+ arguments: [
716
+ tx.object(this.consts.sudoCore.market),
717
+ tx.object(orderCapId),
718
+ ],
719
+ })
720
+ }
721
+
722
+ public clearDecreasePositionOrder(
723
+ orderCapId: string,
724
+ collateralToken: string,
725
+ indexToken: string,
726
+ long: boolean,
727
+ tx: Transaction
728
+ ): void {
729
+ tx.moveCall({
730
+ target: `${this.consts.sudoCore.upgradedPackage}::market::clear_decrease_position_order_v1_1`,
731
+ typeArguments: [
732
+ `${this.consts.sudoCore.package}::slp::SLP`,
733
+ this.consts.coins[collateralToken].module,
734
+ this.consts.coins[indexToken].module,
735
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
736
+ this.consts.coins['sui'].module,
737
+ ],
738
+ arguments: [
739
+ tx.object(this.consts.sudoCore.market),
740
+ tx.object(orderCapId),
741
+ ],
742
+ })
743
+ }
744
+
745
+ public async openPositionWithSCard(
746
+ collateralToken: string,
747
+ indexToken: string,
748
+ size: bigint,
749
+ collateralAmount: bigint,
750
+ coinObjects: string[],
751
+ long: boolean,
752
+ reserveAmount: bigint,
753
+ indexPrice: number,
754
+ collateralPrice: number,
755
+ kioskClient: KioskClient,
756
+ kioskCap: KioskOwnerCap,
757
+ scard: string,
758
+ isLimitOrder = false,
759
+ isIocOrder = false,
760
+ pricesSlippage?: number,
761
+ collateralSlippage?: number,
762
+ relayerFee?: bigint,
763
+ referralAddress?: string,
764
+ sender?: string,
765
+ ): Promise<Transaction> {
766
+ let tx = new Transaction()
767
+ if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
768
+ tx = await this.addReferral(referralAddress, tx)
769
+ }
770
+ tx = await this.initOracleTxb([collateralToken, indexToken], tx)
771
+ const coinObject = this.processCoins(tx, collateralToken, coinObjects)
772
+ const [depositObject] = tx.splitCoins(coinObject, [
773
+ tx.pure.u64(collateralAmount),
774
+ ])
775
+ const feeObject = tx.splitCoins(tx.gas, [tx.pure.u64(relayerFee || BigInt(0.5))]) // Sudo contract requires SUI as fee
776
+
777
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
778
+ const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage || 0.003)
779
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage || 0.5)
780
+
781
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
782
+ if (isLimitOrder) {
783
+ allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
784
+ }
785
+
786
+ const kioskTx = new KioskTransaction({
787
+ transaction: tx,
788
+ kioskClient,
789
+ cap: kioskCap,
790
+ })
791
+
792
+ const [sudoCard, promise] = kioskTx.borrow({
793
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
794
+ itemId: scard,
795
+ })
796
+
797
+ tx.moveCall({
798
+ target: `${this.consts.sudoCore.upgradedPackage}::market::open_position_v1_3`,
799
+ typeArguments: [
800
+ `${this.consts.sudoCore.package}::slp::SLP`,
801
+ this.consts.coins[collateralToken].module,
802
+ this.consts.coins[indexToken].module,
803
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
804
+ this.consts.coins['sui'].module,
805
+ ],
806
+ arguments: [
807
+ tx.object(SUI_CLOCK_OBJECT_ID),
808
+ tx.object(this.consts.sudoCore.market),
809
+ tx.object(
810
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
811
+ ),
812
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
813
+ tx.object(this.consts.sudoCore.symbols[symbol].positionConfig),
814
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
815
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
816
+ depositObject,
817
+ feeObject,
818
+ tx.pure.u8(allowTrade),
819
+ tx.pure.u64(size),
820
+ tx.pure.u64(reserveAmount),
821
+ tx.pure.u256(adjustCollateralPrice),
822
+ tx.pure.u256(adjustPrice),
823
+ tx.pure.bool(isLimitOrder),
824
+ sudoCard,
825
+ ],
826
+ })
827
+
828
+ kioskTx
829
+ .return({
830
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
831
+ item: sudoCard,
832
+ promise: promise,
833
+ })
834
+ .finalize()
835
+ return tx
836
+ }
837
+
838
+ public async decreasePositionWithSCard(
839
+ pcpId: string,
840
+ collateralToken: string,
841
+ indexToken: string,
842
+ amount: bigint,
843
+ long: boolean,
844
+ indexPrice: number,
845
+ collateralPrice: number,
846
+ kioskClient: KioskClient,
847
+ kioskCap: KioskOwnerCap,
848
+ scard: string,
849
+ isTriggerOrder = false,
850
+ isTakeProfitOrder = true,
851
+ isIocOrder = false,
852
+ pricesSlippage: number = 0.003,
853
+ collateralSlippage: number = 0.5,
854
+ relayerFee = BigInt(0.5),
855
+ coinObjects?: string[]
856
+ ): Promise<Transaction> {
857
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
858
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
859
+ const feeObject = tx.splitCoins(tx.gas, [tx.pure.u64(relayerFee)]) // Sudo contract requires SUI as fee
860
+
861
+ const adjustPrice = this.processSlippage(
862
+ indexPrice,
863
+ !long,
864
+ isTriggerOrder ? 0 : pricesSlippage
865
+ )
866
+ const adjustCollateralPrice = this.processSlippage(
867
+ collateralPrice,
868
+ false,
869
+ collateralSlippage
870
+ )
871
+
872
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
873
+ if (isTriggerOrder) {
874
+ if (isIocOrder || !isTakeProfitOrder) {
875
+ allowTrade = ALLOW_TRADE_NO_TRADE
876
+ } else {
877
+ allowTrade = ALLOW_TRADE_CAN_TRADE
878
+ }
879
+ } else {
880
+ isTakeProfitOrder = true
881
+ }
882
+
883
+ const kioskTx = new KioskTransaction({
884
+ transaction: tx,
885
+ kioskClient,
886
+ cap: kioskCap,
887
+ })
888
+
889
+ const [sudoCard, promise] = kioskTx.borrow({
890
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
891
+ itemId: scard,
892
+ })
893
+
894
+ tx.moveCall({
895
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_v1_3`,
896
+ typeArguments: [
897
+ `${this.consts.sudoCore.package}::slp::SLP`,
898
+ this.consts.coins[collateralToken].module,
899
+ this.consts.coins[indexToken].module,
900
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
901
+ this.consts.coins['sui'].module,
902
+ ],
903
+ arguments: [
904
+ tx.object(SUI_CLOCK_OBJECT_ID),
905
+ tx.object(this.consts.sudoCore.market),
906
+ tx.object(pcpId),
907
+ tx.object(
908
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
909
+ ),
910
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
911
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
912
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
913
+ feeObject,
914
+ tx.pure.u8(allowTrade),
915
+ tx.pure.bool(isTakeProfitOrder),
916
+ tx.pure.u64(amount),
917
+ tx.pure.u256(adjustCollateralPrice),
918
+ tx.pure.u256(adjustPrice),
919
+ tx.pure.bool(isTriggerOrder),
920
+ sudoCard,
921
+ ],
922
+ })
923
+
924
+ kioskTx
925
+ .return({
926
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
927
+ item: sudoCard,
928
+ promise: promise,
929
+ })
930
+ .finalize()
931
+ return tx
932
+ }
933
+
934
+ public async decreaseMultiPositionsWithSCard(
935
+ positions: Array<{
936
+ pcpId: string,
937
+ collateralToken: string,
938
+ indexToken: string,
939
+ amount: bigint,
940
+ long: boolean,
941
+ indexPrice: number,
942
+ collateralPrice: number,
943
+ isTriggerOrder: boolean,
944
+ isTakeProfitOrder: boolean,
945
+ isIocOrder: boolean,
946
+ slippage: number,
947
+ relayerFee: bigint,
948
+ coinObjects: string[]
949
+ }>,
950
+ kioskClient: KioskClient,
951
+ kioskCap: KioskOwnerCap,
952
+ scard: string,
953
+ tx?: Transaction
954
+ ): Promise<Transaction> {
955
+ if (!tx) {
956
+ tx = new Transaction()
957
+ }
958
+ tx = await this.initOracleTxb(positions.map(position => [position.collateralToken, position.indexToken]).flat(), tx)
959
+
960
+ const kioskTx = new KioskTransaction({
961
+ transaction: tx,
962
+ kioskClient,
963
+ cap: kioskCap,
964
+ })
965
+
966
+ const [sudoCard, promise] = kioskTx.borrow({
967
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
968
+ itemId: scard,
969
+ })
970
+
971
+ for (const position of positions) {
972
+ const {
973
+ pcpId,
974
+ collateralToken,
975
+ indexToken,
976
+ amount,
977
+ long,
978
+ indexPrice,
979
+ collateralPrice,
980
+ isTriggerOrder,
981
+ isTakeProfitOrder,
982
+ isIocOrder,
983
+ slippage,
984
+ relayerFee,
985
+ coinObjects,
986
+ } = position
987
+ let innerIsTakeProfitOrder = isTakeProfitOrder
988
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
989
+ const coinObject = this.processCoins(tx, collateralToken, coinObjects)
990
+ const feeObject = tx.splitCoins(coinObject, [tx.pure.u64(relayerFee)])
991
+
992
+ const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : slippage)
993
+ const adjustCollateralPrice = this.processSlippage(collateralPrice, false, 0.5)
994
+
995
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
996
+ if (isTriggerOrder) {
997
+ allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
998
+ } else {
999
+ innerIsTakeProfitOrder = true
1000
+ }
1001
+
1002
+ tx.moveCall({
1003
+ target: `${this.consts.sudoCore.upgradedPackage}::market::decrease_position_v1_3`,
1004
+ typeArguments: [
1005
+ `${this.consts.sudoCore.package}::slp::SLP`,
1006
+ this.consts.coins[collateralToken].module,
1007
+ this.consts.coins[indexToken].module,
1008
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1009
+ this.consts.coins['sui'].module,
1010
+ ],
1011
+ arguments: [
1012
+ tx.object(SUI_CLOCK_OBJECT_ID),
1013
+ tx.object(this.consts.sudoCore.market),
1014
+ tx.object(pcpId),
1015
+ tx.object(
1016
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel
1017
+ ),
1018
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
1019
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1020
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1021
+ feeObject,
1022
+ tx.pure.u8(allowTrade),
1023
+ tx.pure.bool(isTakeProfitOrder),
1024
+ tx.pure.u64(amount),
1025
+ tx.pure.u256(adjustCollateralPrice),
1026
+ tx.pure.u256(adjustPrice),
1027
+ tx.pure.bool(isTriggerOrder),
1028
+ sudoCard,
1029
+ ],
1030
+ })
1031
+ }
1032
+
1033
+ kioskTx
1034
+ .return({
1035
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
1036
+ item: sudoCard,
1037
+ promise: promise,
1038
+ })
1039
+ .finalize()
1040
+ return tx
1041
+ }
1042
+
1043
+ public addReferral(
1044
+ referrer: string,
1045
+ tx?: Transaction
1046
+ ): Transaction {
1047
+ if (!tx) {
1048
+ tx = new Transaction()
1049
+ }
1050
+ tx.moveCall({
1051
+ target: `${this.consts.sudoCore.upgradedPackage}::market::add_new_referral`,
1052
+ typeArguments: [`${this.consts.sudoCore.package}::slp::SLP`],
1053
+ arguments: [tx.object(this.consts.sudoCore.market), tx.object(referrer)],
1054
+ })
1055
+
1056
+ return tx
1057
+ }
1058
+
1059
+ public async adminUpdatePriceFeed(
1060
+ collateralToken: string,
1061
+ indexToken: string
1062
+ ): Promise<Transaction> {
1063
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
1064
+ return tx
1065
+ }
1066
+
1067
+ public async adminSettlePosition(
1068
+ positionId: string,
1069
+ owner: string,
1070
+ collateralToken: string,
1071
+ indexToken: string,
1072
+ long: boolean
1073
+ ): Promise<Transaction> {
1074
+ // SLP does not support this operation
1075
+ throw new Error('Method not implemented.')
1076
+ }
1077
+
1078
+ public async adminDecreasePosition(
1079
+ positionId: string,
1080
+ owner: string,
1081
+ collateralToken: string,
1082
+ indexToken: string,
1083
+ positionAmount: number,
1084
+ amount: bigint,
1085
+ long: boolean,
1086
+ collateralPrice?: number,
1087
+ collateralSlippage?: number,
1088
+ relayerFee?: bigint
1089
+ ): Promise<Transaction> {
1090
+ const tx = await this.initOracleTxb([collateralToken, indexToken])
1091
+ const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
1092
+ const feeObject = tx.splitCoins(tx.gas, [tx.pure.u64(relayerFee || BigInt(1))])
1093
+
1094
+ const adjustCollateralPrice = this.processSlippage(
1095
+ collateralPrice || 0,
1096
+ false,
1097
+ collateralSlippage || 0.5,
1098
+ )
1099
+
1100
+ let allowTrade = ALLOW_TRADE_MUST_TRADE
1101
+
1102
+ tx.moveCall({
1103
+ target: `${this.consts.sudoCore.upgradedPackage}::market::admin_decrease_position_v1_3`,
1104
+ typeArguments: [
1105
+ `${this.consts.sudoCore.package}::slp::SLP`,
1106
+ this.consts.coins[collateralToken].module,
1107
+ this.consts.coins[indexToken].module,
1108
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1109
+ this.consts.coins['sui'].module,
1110
+ ],
1111
+ arguments: [
1112
+ tx.object(this.consts.sudoCore.adminCap),
1113
+ tx.object(SUI_CLOCK_OBJECT_ID),
1114
+ tx.object(this.consts.sudoCore.market),
1115
+ tx.object(positionId),
1116
+ tx.object(
1117
+ this.consts.sudoCore.vaults[collateralToken].reservingFeeModel,
1118
+ ),
1119
+ tx.object(this.consts.sudoCore.symbols[symbol].fundingFeeModel),
1120
+ tx.object(this.consts.pythFeeder.feeder[collateralToken]),
1121
+ tx.object(this.consts.pythFeeder.feeder[indexToken]),
1122
+ feeObject,
1123
+ tx.pure.u8(allowTrade),
1124
+ tx.pure.u64(amount),
1125
+ tx.pure.u256(adjustCollateralPrice),
1126
+ tx.object(owner),
1127
+ ],
1128
+ })
1129
+
1130
+ if (amount === BigInt(positionAmount)) {
1131
+ this.adminClearClosedPosition(
1132
+ positionId,
1133
+ owner,
1134
+ collateralToken,
1135
+ indexToken,
1136
+ long,
1137
+ tx,
1138
+ )
1139
+ }
1140
+
1141
+ return tx
1142
+ }
1143
+
1144
+ public async adminClearClosedPosition(
1145
+ positionId: string,
1146
+ owner: string,
1147
+ collateralToken: string,
1148
+ indexToken: string,
1149
+ long: boolean,
1150
+ tx: Transaction
1151
+ ): Promise<void> {
1152
+ tx.moveCall({
1153
+ target: `${this.consts.sudoCore.upgradedPackage}::market::admin_clear_closed_position_v1_1`,
1154
+ typeArguments: [
1155
+ `${this.consts.sudoCore.package}::slp::SLP`,
1156
+ this.consts.coins[collateralToken].module,
1157
+ this.consts.coins[indexToken].module,
1158
+ `${this.consts.sudoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
1159
+ ],
1160
+ arguments: [
1161
+ tx.object(this.consts.sudoCore.adminCap),
1162
+ tx.object(owner),
1163
+ tx.object(this.consts.sudoCore.market),
1164
+ tx.object(positionId),
1165
+ ],
1166
+ })
1167
+ }
1168
+
1169
+ // SLP Specific APIs
1170
+ public async claimTokenFromSCard(
1171
+ token: string,
1172
+ coinObjects: string[],
1173
+ kioskClient: KioskClient,
1174
+ kioskCap: KioskOwnerCap,
1175
+ scard: string
1176
+ ): Promise<Transaction> {
1177
+ const tx = new Transaction()
1178
+ const kioskTx = new KioskTransaction({
1179
+ transaction: tx,
1180
+ kioskClient,
1181
+ cap: kioskCap,
1182
+ })
1183
+
1184
+ const [sudoCard, promise] = kioskTx.borrow({
1185
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
1186
+ itemId: scard,
1187
+ })
1188
+
1189
+ // claim tokens
1190
+ coinObjects.forEach(coinObject => {
1191
+ return tx.moveCall({
1192
+ target: `${this.consts.sudoNft.upgradedPackage}::card::claim_token`,
1193
+ typeArguments: [`${this.consts.coins[token].module}`],
1194
+ arguments: [sudoCard, tx.object(coinObject)],
1195
+ })
1196
+ })
1197
+
1198
+ kioskTx
1199
+ .return({
1200
+ itemType: `${this.consts.sudoNft.package}::card::SudoCard`,
1201
+ item: sudoCard,
1202
+ promise: promise,
1203
+ })
1204
+ .finalize()
1205
+ return tx
1206
+ }
1207
+ }