zo-sdk 0.1.21 → 0.1.23
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.
- package/dist/abstract/BaseDataAPI.d.cts +2 -2
- package/dist/abstract/BaseDataAPI.d.cts.map +1 -1
- package/dist/abstract/BaseDataAPI.d.mts +2 -2
- package/dist/abstract/BaseDataAPI.d.mts.map +1 -1
- package/dist/consts/deployments-zbtcvc-mainnet.json +180 -0
- package/dist/consts/index.cjs +27 -20
- package/dist/consts/index.cjs.map +1 -1
- package/dist/consts/index.d.cts +5 -17
- package/dist/consts/index.d.cts.map +1 -1
- package/dist/consts/index.d.mts +5 -17
- package/dist/consts/index.d.mts.map +1 -1
- package/dist/consts/index.mjs +26 -19
- package/dist/consts/index.mjs.map +1 -1
- package/dist/factory/SDKFactory.cjs +36 -0
- package/dist/factory/SDKFactory.cjs.map +1 -1
- package/dist/factory/SDKFactory.d.cts +11 -1
- package/dist/factory/SDKFactory.d.cts.map +1 -1
- package/dist/factory/SDKFactory.d.mts +11 -1
- package/dist/factory/SDKFactory.d.mts.map +1 -1
- package/dist/factory/SDKFactory.mjs +36 -0
- package/dist/factory/SDKFactory.mjs.map +1 -1
- package/dist/implementations/SLPDataAPI.cjs +54 -32
- package/dist/implementations/SLPDataAPI.cjs.map +1 -1
- package/dist/implementations/SLPDataAPI.d.cts +2 -2
- package/dist/implementations/SLPDataAPI.d.cts.map +1 -1
- package/dist/implementations/SLPDataAPI.d.mts +2 -2
- package/dist/implementations/SLPDataAPI.d.mts.map +1 -1
- package/dist/implementations/SLPDataAPI.mjs +54 -32
- package/dist/implementations/SLPDataAPI.mjs.map +1 -1
- package/dist/implementations/USDZAPI.cjs +1 -1
- package/dist/implementations/USDZAPI.cjs.map +1 -1
- package/dist/implementations/USDZAPI.d.cts +1 -1
- package/dist/implementations/USDZAPI.d.cts.map +1 -1
- package/dist/implementations/USDZAPI.d.mts +1 -1
- package/dist/implementations/USDZAPI.d.mts.map +1 -1
- package/dist/implementations/USDZAPI.mjs +1 -1
- package/dist/implementations/USDZAPI.mjs.map +1 -1
- package/dist/implementations/ZBTCVCAPI.cjs +984 -0
- package/dist/implementations/ZBTCVCAPI.cjs.map +1 -0
- package/dist/implementations/ZBTCVCAPI.d.cts +133 -0
- package/dist/implementations/ZBTCVCAPI.d.cts.map +1 -0
- package/dist/implementations/ZBTCVCAPI.d.mts +133 -0
- package/dist/implementations/ZBTCVCAPI.d.mts.map +1 -0
- package/dist/implementations/ZBTCVCAPI.mjs +980 -0
- package/dist/implementations/ZBTCVCAPI.mjs.map +1 -0
- package/dist/implementations/ZBTCVCDataAPI.cjs +824 -0
- package/dist/implementations/ZBTCVCDataAPI.cjs.map +1 -0
- package/dist/implementations/ZBTCVCDataAPI.d.cts +94 -0
- package/dist/implementations/ZBTCVCDataAPI.d.cts.map +1 -0
- package/dist/implementations/ZBTCVCDataAPI.d.mts +94 -0
- package/dist/implementations/ZBTCVCDataAPI.d.mts.map +1 -0
- package/dist/implementations/ZBTCVCDataAPI.mjs +820 -0
- package/dist/implementations/ZBTCVCDataAPI.mjs.map +1 -0
- package/dist/implementations/index.cjs +5 -1
- package/dist/implementations/index.cjs.map +1 -1
- package/dist/implementations/index.d.cts +2 -0
- package/dist/implementations/index.d.cts.map +1 -1
- package/dist/implementations/index.d.mts +2 -0
- package/dist/implementations/index.d.mts.map +1 -1
- package/dist/implementations/index.mjs +2 -0
- package/dist/implementations/index.mjs.map +1 -1
- package/dist/interfaces/base.d.cts +2 -2
- package/dist/interfaces/base.d.cts.map +1 -1
- package/dist/interfaces/base.d.mts +2 -2
- package/dist/interfaces/base.d.mts.map +1 -1
- package/dist/interfaces/index.cjs +2 -0
- package/dist/interfaces/index.cjs.map +1 -1
- package/dist/interfaces/index.d.cts +2 -0
- package/dist/interfaces/index.d.cts.map +1 -1
- package/dist/interfaces/index.d.mts +2 -0
- package/dist/interfaces/index.d.mts.map +1 -1
- package/dist/interfaces/index.mjs +2 -0
- package/dist/interfaces/index.mjs.map +1 -1
- package/dist/interfaces/zbtcvc.cjs +7 -0
- package/dist/interfaces/zbtcvc.cjs.map +1 -0
- package/dist/interfaces/zbtcvc.d.cts +64 -0
- package/dist/interfaces/zbtcvc.d.cts.map +1 -0
- package/dist/interfaces/zbtcvc.d.mts +64 -0
- package/dist/interfaces/zbtcvc.d.mts.map +1 -0
- package/dist/interfaces/zbtcvc.mjs +6 -0
- package/dist/interfaces/zbtcvc.mjs.map +1 -0
- package/package.json +8 -8
- package/src/abstract/BaseDataAPI.ts +2 -2
- package/src/consts/deployments-zbtcvc-mainnet.json +180 -0
- package/src/consts/index.ts +28 -35
- package/src/factory/SDKFactory.ts +50 -0
- package/src/implementations/SLPDataAPI.ts +71 -41
- package/src/implementations/USDZAPI.ts +1 -1
- package/src/implementations/ZBTCVCAPI.ts +1453 -0
- package/src/implementations/ZBTCVCDataAPI.ts +985 -0
- package/src/implementations/index.ts +2 -0
- package/src/interfaces/base.ts +2 -2
- package/src/interfaces/index.ts +8 -0
- package/src/interfaces/zbtcvc.ts +115 -0
|
@@ -0,0 +1,1453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZBTCVC API implementation
|
|
3
|
+
* Implements ZBTCVC-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 { Transaction } from '@mysten/sui/transactions'
|
|
10
|
+
import { SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils'
|
|
11
|
+
|
|
12
|
+
import { BaseAPI } from '../abstract'
|
|
13
|
+
import type { Network } from '../consts'
|
|
14
|
+
import { ALLOW_TRADE_CAN_TRADE, ALLOW_TRADE_MUST_TRADE, ALLOW_TRADE_NO_TRADE, LPToken } from '../consts'
|
|
15
|
+
import type {
|
|
16
|
+
IBaseHistoryResponse,
|
|
17
|
+
IBaseMarketInfo,
|
|
18
|
+
IBaseMarketValuationInfo,
|
|
19
|
+
IBaseOrderCapInfo,
|
|
20
|
+
IBaseOrderInfo,
|
|
21
|
+
IBasePositionCapInfo,
|
|
22
|
+
IBasePositionConfig,
|
|
23
|
+
IBasePositionInfo,
|
|
24
|
+
IBaseRebaseFeeModel,
|
|
25
|
+
IBaseStaked,
|
|
26
|
+
IBaseStakePool,
|
|
27
|
+
IBaseSymbolInfo,
|
|
28
|
+
IBaseVaultInfo,
|
|
29
|
+
IZBTCVCAPI,
|
|
30
|
+
IZBTCVCCredential,
|
|
31
|
+
} from '../interfaces'
|
|
32
|
+
import { joinSymbol } from '../utils'
|
|
33
|
+
import { ZBTCVCDataAPI } from './ZBTCVCDataAPI'
|
|
34
|
+
|
|
35
|
+
export class ZBTCVCAPI extends BaseAPI implements IZBTCVCAPI {
|
|
36
|
+
public dataAPI: ZBTCVCDataAPI
|
|
37
|
+
|
|
38
|
+
constructor(
|
|
39
|
+
network: Network,
|
|
40
|
+
provider: SuiClient,
|
|
41
|
+
apiEndpoint: string,
|
|
42
|
+
connectionURL: string,
|
|
43
|
+
) {
|
|
44
|
+
super(network, provider, apiEndpoint, connectionURL, LPToken.ZBTCVC)
|
|
45
|
+
this.dataAPI = new ZBTCVCDataAPI(network, provider, apiEndpoint, connectionURL)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public claimTokenFromSCard(_token: string, _coinObjects: string[], _kioskClient: KioskClient, _kioskCap: KioskOwnerCap, _scard: string): Transaction {
|
|
49
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public valuateVaults(_tx: Transaction) {
|
|
53
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public valuateSymbols(_tx: Transaction) {
|
|
57
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public valuate(_tx: Transaction): { vaultsValuation: any, symbolsValuation: any } {
|
|
61
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public valuateMarket(): Promise<IBaseMarketValuationInfo> {
|
|
65
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public fundingFeeRate(_indexToken: string, _long: boolean): Promise<number> {
|
|
69
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public rebaseFeeRate(_collateralToken: string, _increase: boolean, _amount: number): Promise<number> {
|
|
73
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public reservingFeeRate(_collateralToken: string, _amount: number): Promise<number> {
|
|
77
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public calcPositionReserveFeeAmount(_position: IBasePositionInfo): Promise<number> {
|
|
81
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public calcPositionFundingFeeValue(_position: IBasePositionInfo): Promise<number> {
|
|
85
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public getMarketInfo(): Promise<IBaseMarketInfo> {
|
|
89
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public getVaultInfo(_vault: string): Promise<IBaseVaultInfo> {
|
|
93
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public getSymbolInfo(_tokenId: string, _long: boolean): Promise<IBaseSymbolInfo> {
|
|
97
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public getPositionConfig(_indexToken: string, _long: boolean): Promise<IBasePositionConfig> {
|
|
101
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public getRebaseFeeModel(): Promise<IBaseRebaseFeeModel> {
|
|
105
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public getOpenPositions(): Promise<IBasePositionInfo[]> {
|
|
109
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public getPositionCapInfoList(_owner: string): Promise<IBasePositionCapInfo[]> {
|
|
113
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public getPositionInfoList(_positionCapInfoList: IBasePositionCapInfo[], _owner: string, _batchSize?: number): Promise<IBasePositionInfo[]> {
|
|
117
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public getOrderCapInfoList(_owner: string): Promise<IBaseOrderCapInfo[]> {
|
|
121
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public getOrderInfoList(_orderCapInfoList: IBaseOrderCapInfo[], _owner: string): Promise<IBaseOrderInfo[]> {
|
|
125
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public getHistory(_trader: string, _page: number, _limit: number, _orderType?: string, _symbol?: string): Promise<IBaseHistoryResponse> {
|
|
129
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public getStaked(_owner: string): Promise<IBaseStaked> {
|
|
133
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public getStakePool(): Promise<IBaseStakePool> {
|
|
137
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public hasReferral(_referree: string): Promise<boolean> {
|
|
141
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public getReferralData(_referree: string): Promise<any> {
|
|
145
|
+
throw new Error(`Method not implemented in ${this.constructor.name}.`)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public clearClosedPosition(pcpId: string, collateralToken: string, indexToken: string, long: boolean, tx: Transaction): void {
|
|
149
|
+
tx.moveCall({
|
|
150
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::clear_closed_position`,
|
|
151
|
+
typeArguments: [
|
|
152
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
153
|
+
this.consts.coins[collateralToken].module,
|
|
154
|
+
this.consts.coins[indexToken].module,
|
|
155
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
156
|
+
],
|
|
157
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(pcpId)],
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public clearOpenPositionOrder(orderCapId: string, collateralToken: string, indexToken: string, long: boolean, tx: Transaction, isV11Order?: boolean): void {
|
|
162
|
+
const funcName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
|
|
163
|
+
tx.moveCall({
|
|
164
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
|
|
165
|
+
typeArguments: [
|
|
166
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
167
|
+
this.consts.coins[collateralToken].module,
|
|
168
|
+
this.consts.coins[indexToken].module,
|
|
169
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
170
|
+
this.consts.coins[collateralToken].module,
|
|
171
|
+
],
|
|
172
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public clearDecreasePositionOrder(orderCapId: string, collateralToken: string, indexToken: string, long: boolean, tx: Transaction, isV11Order?: boolean): void {
|
|
177
|
+
const funcName = isV11Order ? 'clear_decrease_position_order' : 'clear_decrease_position_order'
|
|
178
|
+
tx.moveCall({
|
|
179
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::${funcName}`,
|
|
180
|
+
typeArguments: [
|
|
181
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
182
|
+
this.consts.coins[collateralToken].module,
|
|
183
|
+
this.consts.coins[indexToken].module,
|
|
184
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
185
|
+
this.consts.coins[collateralToken].module,
|
|
186
|
+
],
|
|
187
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public async openPositionWithSCard(
|
|
192
|
+
collateralToken: string,
|
|
193
|
+
indexToken: string,
|
|
194
|
+
size: bigint,
|
|
195
|
+
collateralAmount: bigint,
|
|
196
|
+
coinObjects: string[],
|
|
197
|
+
long: boolean,
|
|
198
|
+
reserveAmount: bigint,
|
|
199
|
+
indexPrice: number,
|
|
200
|
+
collateralPrice: number,
|
|
201
|
+
kioskClient: KioskClient,
|
|
202
|
+
kioskCap: KioskOwnerCap,
|
|
203
|
+
scard: string,
|
|
204
|
+
isLimitOrder?: boolean,
|
|
205
|
+
isIocOrder?: boolean,
|
|
206
|
+
pricesSlippage = 0.003,
|
|
207
|
+
collateralSlippage = 0.5,
|
|
208
|
+
relayerFee = BigInt(0.5),
|
|
209
|
+
referralAddress?: string,
|
|
210
|
+
sender?: string,
|
|
211
|
+
sponsoredTx?: boolean,
|
|
212
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
213
|
+
): Promise<Transaction> {
|
|
214
|
+
let tx = new Transaction()
|
|
215
|
+
if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
|
|
216
|
+
tx = await this.addReferral(referralAddress, tx)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
220
|
+
const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
|
|
221
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
222
|
+
|
|
223
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
224
|
+
if (isLimitOrder) {
|
|
225
|
+
allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const kioskTx = new KioskTransaction({
|
|
229
|
+
transaction: tx,
|
|
230
|
+
kioskClient,
|
|
231
|
+
cap: kioskCap,
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
const [sudoCard, promise] = kioskTx.borrow({
|
|
235
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
236
|
+
itemId: scard,
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
// Handle oracle initialization and coin processing
|
|
240
|
+
let suiCoinObject
|
|
241
|
+
if (sponsoredTx) {
|
|
242
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
243
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Process coin splitting
|
|
250
|
+
const [depositObject, feeObject] = this.processCoinSplitting(
|
|
251
|
+
tx,
|
|
252
|
+
collateralToken,
|
|
253
|
+
coinObjects,
|
|
254
|
+
[tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
|
|
255
|
+
sponsoredTx,
|
|
256
|
+
suiCoinObject,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
tx.moveCall({
|
|
260
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::open_position_with_scard`,
|
|
261
|
+
typeArguments: [
|
|
262
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
263
|
+
this.consts.coins[collateralToken].module,
|
|
264
|
+
this.consts.coins[indexToken].module,
|
|
265
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
266
|
+
this.consts.coins[collateralToken].module,
|
|
267
|
+
],
|
|
268
|
+
arguments: [
|
|
269
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
270
|
+
tx.object(this.consts.zoCore.market),
|
|
271
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
272
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
273
|
+
tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
|
|
274
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
275
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
276
|
+
depositObject,
|
|
277
|
+
feeObject,
|
|
278
|
+
tx.pure.u8(allowTrade),
|
|
279
|
+
tx.pure.u64(size),
|
|
280
|
+
tx.pure.u64(reserveAmount),
|
|
281
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
282
|
+
tx.pure.u256(adjustPrice),
|
|
283
|
+
sudoCard,
|
|
284
|
+
],
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
kioskTx
|
|
288
|
+
.return({
|
|
289
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
290
|
+
item: sudoCard,
|
|
291
|
+
promise,
|
|
292
|
+
})
|
|
293
|
+
.finalize()
|
|
294
|
+
return tx
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
public async decreasePositionWithSCard(
|
|
298
|
+
pcpId: string,
|
|
299
|
+
collateralToken: string,
|
|
300
|
+
indexToken: string,
|
|
301
|
+
amount: bigint,
|
|
302
|
+
long: boolean,
|
|
303
|
+
indexPrice: number,
|
|
304
|
+
collateralPrice: number,
|
|
305
|
+
kioskClient: KioskClient,
|
|
306
|
+
kioskCap: KioskOwnerCap,
|
|
307
|
+
scard: string,
|
|
308
|
+
isTriggerOrder = false,
|
|
309
|
+
isTakeProfitOrder = true,
|
|
310
|
+
isIocOrder = false,
|
|
311
|
+
pricesSlippage = 0.003,
|
|
312
|
+
collateralSlippage = 0.5,
|
|
313
|
+
relayerFee = BigInt(0.5),
|
|
314
|
+
coinObjects?: string[],
|
|
315
|
+
sponsoredTx?: boolean,
|
|
316
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
317
|
+
): Promise<Transaction> {
|
|
318
|
+
if (!coinObjects) {
|
|
319
|
+
throw new Error(`${this.constructor.name}: coinObjects is required`)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
let tx = new Transaction()
|
|
323
|
+
|
|
324
|
+
const kioskTx = new KioskTransaction({
|
|
325
|
+
transaction: tx,
|
|
326
|
+
kioskClient,
|
|
327
|
+
cap: kioskCap,
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
const [sudoCard, promise] = kioskTx.borrow({
|
|
331
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
332
|
+
itemId: scard,
|
|
333
|
+
})
|
|
334
|
+
|
|
335
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
336
|
+
|
|
337
|
+
const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
|
|
338
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
339
|
+
|
|
340
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
341
|
+
if (isTriggerOrder) {
|
|
342
|
+
allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
isTakeProfitOrder = true
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Handle oracle initialization and coin processing
|
|
349
|
+
let suiCoinObject
|
|
350
|
+
if (sponsoredTx) {
|
|
351
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
352
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Process coin splitting
|
|
359
|
+
const [feeObject] = this.processCoinSplitting(
|
|
360
|
+
tx,
|
|
361
|
+
collateralToken,
|
|
362
|
+
coinObjects,
|
|
363
|
+
[tx.pure.u64(relayerFee)],
|
|
364
|
+
sponsoredTx,
|
|
365
|
+
suiCoinObject,
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
tx.moveCall({
|
|
369
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard`,
|
|
370
|
+
typeArguments: [
|
|
371
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
372
|
+
this.consts.coins[collateralToken].module,
|
|
373
|
+
this.consts.coins[indexToken].module,
|
|
374
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
375
|
+
this.consts.coins[collateralToken].module,
|
|
376
|
+
],
|
|
377
|
+
arguments: [
|
|
378
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
379
|
+
tx.object(this.consts.zoCore.market),
|
|
380
|
+
tx.object(pcpId),
|
|
381
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
382
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
383
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
384
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
385
|
+
feeObject,
|
|
386
|
+
tx.pure.u8(allowTrade),
|
|
387
|
+
tx.pure.bool(isTakeProfitOrder),
|
|
388
|
+
tx.pure.u64(amount),
|
|
389
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
390
|
+
tx.pure.u256(adjustPrice),
|
|
391
|
+
sudoCard,
|
|
392
|
+
],
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
kioskTx
|
|
396
|
+
.return({
|
|
397
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
398
|
+
item: sudoCard,
|
|
399
|
+
promise,
|
|
400
|
+
})
|
|
401
|
+
.finalize()
|
|
402
|
+
return tx
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
public async decreaseMultiPositionsWithSCard(
|
|
406
|
+
positions: Array<{
|
|
407
|
+
pcpId: string
|
|
408
|
+
collateralToken: string
|
|
409
|
+
indexToken: string
|
|
410
|
+
amount: bigint
|
|
411
|
+
long: boolean
|
|
412
|
+
indexPrice: number
|
|
413
|
+
collateralPrice: number
|
|
414
|
+
isTriggerOrder?: boolean
|
|
415
|
+
isTakeProfitOrder?: boolean
|
|
416
|
+
isIocOrder?: boolean
|
|
417
|
+
pricesSlippage?: number
|
|
418
|
+
collateralSlippage?: number
|
|
419
|
+
relayerFee?: bigint
|
|
420
|
+
coinObjects?: string[]
|
|
421
|
+
}>,
|
|
422
|
+
kioskClient: KioskClient,
|
|
423
|
+
kioskCap: KioskOwnerCap,
|
|
424
|
+
scard: string,
|
|
425
|
+
tx?: Transaction,
|
|
426
|
+
sponsoredTx?: boolean,
|
|
427
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
428
|
+
): Promise<Transaction> {
|
|
429
|
+
if (!tx) {
|
|
430
|
+
tx = new Transaction()
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Handle oracle initialization and coin processing
|
|
434
|
+
let suiCoinObject
|
|
435
|
+
if (sponsoredTx) {
|
|
436
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
437
|
+
tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx, true, suiCoinObject)
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx)
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const kioskTx = new KioskTransaction({
|
|
444
|
+
transaction: tx,
|
|
445
|
+
kioskClient,
|
|
446
|
+
cap: kioskCap,
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
const [sudoCard, promise] = kioskTx.borrow({
|
|
450
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
451
|
+
itemId: scard,
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
for (const position of positions) {
|
|
455
|
+
const {
|
|
456
|
+
pcpId,
|
|
457
|
+
collateralToken,
|
|
458
|
+
coinObjects = [],
|
|
459
|
+
indexToken,
|
|
460
|
+
amount,
|
|
461
|
+
long,
|
|
462
|
+
indexPrice,
|
|
463
|
+
collateralPrice,
|
|
464
|
+
isTriggerOrder = false,
|
|
465
|
+
isTakeProfitOrder = true,
|
|
466
|
+
isIocOrder = false,
|
|
467
|
+
pricesSlippage = 0.003,
|
|
468
|
+
collateralSlippage = 0.5,
|
|
469
|
+
relayerFee = BigInt(0.5),
|
|
470
|
+
} = position
|
|
471
|
+
let innerIsTakeProfitOrder = isTakeProfitOrder
|
|
472
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
473
|
+
|
|
474
|
+
const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
|
|
475
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
476
|
+
|
|
477
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
478
|
+
if (isTriggerOrder) {
|
|
479
|
+
allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
innerIsTakeProfitOrder = true
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Process coin splitting
|
|
486
|
+
const [feeObject] = this.processCoinSplitting(
|
|
487
|
+
tx,
|
|
488
|
+
collateralToken,
|
|
489
|
+
coinObjects,
|
|
490
|
+
[tx.pure.u64(relayerFee)],
|
|
491
|
+
sponsoredTx,
|
|
492
|
+
suiCoinObject,
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
tx.moveCall({
|
|
496
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position_with_scard`,
|
|
497
|
+
typeArguments: [
|
|
498
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
499
|
+
this.consts.coins[collateralToken].module,
|
|
500
|
+
this.consts.coins[indexToken].module,
|
|
501
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
502
|
+
this.consts.coins[collateralToken].module,
|
|
503
|
+
],
|
|
504
|
+
arguments: [
|
|
505
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
506
|
+
tx.object(this.consts.zoCore.market),
|
|
507
|
+
tx.object(pcpId),
|
|
508
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
509
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
510
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
511
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
512
|
+
feeObject,
|
|
513
|
+
tx.pure.u8(allowTrade),
|
|
514
|
+
tx.pure.bool(innerIsTakeProfitOrder),
|
|
515
|
+
tx.pure.u64(amount),
|
|
516
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
517
|
+
tx.pure.u256(adjustPrice),
|
|
518
|
+
sudoCard,
|
|
519
|
+
],
|
|
520
|
+
})
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
kioskTx
|
|
524
|
+
.return({
|
|
525
|
+
itemType: `0xe7e651e4974fe367aa2837712d68081efb299c470242a15e2b9c26ea326159ec::card::SudoCard`,
|
|
526
|
+
item: sudoCard,
|
|
527
|
+
promise,
|
|
528
|
+
})
|
|
529
|
+
.finalize()
|
|
530
|
+
return tx
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Deposits collateral into ZBTCVC vault
|
|
535
|
+
*/
|
|
536
|
+
public async deposit(
|
|
537
|
+
coin: string,
|
|
538
|
+
coinObjects: string[],
|
|
539
|
+
amount: number,
|
|
540
|
+
minAmountOut = 0,
|
|
541
|
+
referralAddress?: string,
|
|
542
|
+
sender?: string,
|
|
543
|
+
sponsoredTx?: boolean,
|
|
544
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
545
|
+
): Promise<Transaction> {
|
|
546
|
+
let tx = new Transaction()
|
|
547
|
+
|
|
548
|
+
// Add referral if needed
|
|
549
|
+
if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
|
|
550
|
+
tx = await this.addReferral(referralAddress, tx)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Initialize oracle transaction
|
|
554
|
+
const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
|
|
555
|
+
|
|
556
|
+
// Handle sponsored transaction case
|
|
557
|
+
if (sponsoredTx) {
|
|
558
|
+
const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
559
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
|
|
560
|
+
|
|
561
|
+
// Process deposit coins
|
|
562
|
+
const depositObject = coin === 'sui'
|
|
563
|
+
? tx.splitCoins(suiCoinObject, [tx.pure.u64(amount)])[0]
|
|
564
|
+
: tx.splitCoins(this.processCoins(tx, coin, coinObjects, true), [tx.pure.u64(amount)])[0]
|
|
565
|
+
|
|
566
|
+
const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
|
|
567
|
+
|
|
568
|
+
tx.moveCall({
|
|
569
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
|
|
570
|
+
typeArguments: [`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`, this.consts.coins[coin].module],
|
|
571
|
+
arguments: [
|
|
572
|
+
tx.object(this.consts.zoCore.market),
|
|
573
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
574
|
+
depositObject,
|
|
575
|
+
tx.pure.u64(minAmountOut),
|
|
576
|
+
vaultsValuation,
|
|
577
|
+
symbolsValuation,
|
|
578
|
+
],
|
|
579
|
+
})
|
|
580
|
+
return tx
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Handle non-sponsored transaction case
|
|
584
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx)
|
|
585
|
+
const depositObject = tx.splitCoins(
|
|
586
|
+
this.processCoins(tx, coin, coinObjects, false),
|
|
587
|
+
[tx.pure.u64(amount)],
|
|
588
|
+
)[0]
|
|
589
|
+
|
|
590
|
+
const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
|
|
591
|
+
|
|
592
|
+
tx.moveCall({
|
|
593
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::deposit`,
|
|
594
|
+
typeArguments: [
|
|
595
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
596
|
+
this.consts.coins[coin].module,
|
|
597
|
+
],
|
|
598
|
+
arguments: [
|
|
599
|
+
tx.object(this.consts.zoCore.market),
|
|
600
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
601
|
+
depositObject,
|
|
602
|
+
tx.pure.u64(minAmountOut),
|
|
603
|
+
vaultsValuation,
|
|
604
|
+
symbolsValuation,
|
|
605
|
+
],
|
|
606
|
+
})
|
|
607
|
+
return tx
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Deposits collateral into ZBTCVC vault
|
|
612
|
+
*/
|
|
613
|
+
public async depositPtb(
|
|
614
|
+
coin: string,
|
|
615
|
+
coinObjects: string[],
|
|
616
|
+
amount: number,
|
|
617
|
+
minAmountOut = 0,
|
|
618
|
+
referralAddress?: string,
|
|
619
|
+
sender?: string,
|
|
620
|
+
tx?: Transaction,
|
|
621
|
+
sponsoredTx?: boolean,
|
|
622
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
623
|
+
): Promise<any> {
|
|
624
|
+
if (!tx) {
|
|
625
|
+
tx = new Transaction()
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Add referral if needed
|
|
629
|
+
if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
|
|
630
|
+
tx = await this.addReferral(referralAddress, tx)
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Initialize oracle transaction
|
|
634
|
+
const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
|
|
635
|
+
|
|
636
|
+
// Handle sponsored transaction case
|
|
637
|
+
if (sponsoredTx) {
|
|
638
|
+
const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
639
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
|
|
640
|
+
|
|
641
|
+
// Process deposit coins
|
|
642
|
+
const depositObject = coin === 'sui'
|
|
643
|
+
? tx.splitCoins(suiCoinObject, [tx.pure.u64(amount)])[0]
|
|
644
|
+
: tx.splitCoins(this.processCoins(tx, coin, coinObjects, true), [tx.pure.u64(amount)])[0]
|
|
645
|
+
|
|
646
|
+
const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
|
|
647
|
+
|
|
648
|
+
const [mintedCoin] = tx.moveCall({
|
|
649
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
|
|
650
|
+
typeArguments: [`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`, this.consts.coins[coin].module],
|
|
651
|
+
arguments: [
|
|
652
|
+
tx.object(this.consts.zoCore.market),
|
|
653
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
654
|
+
depositObject,
|
|
655
|
+
tx.pure.u64(minAmountOut),
|
|
656
|
+
vaultsValuation,
|
|
657
|
+
symbolsValuation,
|
|
658
|
+
],
|
|
659
|
+
})
|
|
660
|
+
return mintedCoin
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Handle non-sponsored transaction case
|
|
664
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx)
|
|
665
|
+
const depositObject = tx.splitCoins(
|
|
666
|
+
this.processCoins(tx, coin, coinObjects, false),
|
|
667
|
+
[tx.pure.u64(amount)],
|
|
668
|
+
)[0]
|
|
669
|
+
|
|
670
|
+
const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
|
|
671
|
+
|
|
672
|
+
const [mintedCoin] = tx.moveCall({
|
|
673
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::deposit_ptb`,
|
|
674
|
+
typeArguments: [
|
|
675
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
676
|
+
this.consts.coins[coin].module,
|
|
677
|
+
],
|
|
678
|
+
arguments: [
|
|
679
|
+
tx.object(this.consts.zoCore.market),
|
|
680
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
681
|
+
depositObject,
|
|
682
|
+
tx.pure.u64(minAmountOut),
|
|
683
|
+
vaultsValuation,
|
|
684
|
+
symbolsValuation,
|
|
685
|
+
],
|
|
686
|
+
})
|
|
687
|
+
|
|
688
|
+
return mintedCoin
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Withdraws collateral from ZBTCVC vault
|
|
693
|
+
*/
|
|
694
|
+
public async withdraw(
|
|
695
|
+
coin: string,
|
|
696
|
+
lpCoinObjects: string[],
|
|
697
|
+
amount: number,
|
|
698
|
+
minAmountOut = 0,
|
|
699
|
+
sponsoredTx?: boolean,
|
|
700
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
701
|
+
): Promise<Transaction> {
|
|
702
|
+
let tx = new Transaction()
|
|
703
|
+
|
|
704
|
+
// Initialize oracle transaction
|
|
705
|
+
const pythFeederKeys = Object.keys(this.consts.pythFeeder.feeder)
|
|
706
|
+
|
|
707
|
+
if (sponsoredTx) {
|
|
708
|
+
const suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
709
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx, true, suiCoinObject)
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
tx = await this.initOracleTxb(pythFeederKeys, tx)
|
|
713
|
+
}
|
|
714
|
+
const zbtcvcCoinObject = this.processCoins(tx, 'zbtcvc', lpCoinObjects, false)
|
|
715
|
+
const [withdrawObject] = tx.splitCoins(zbtcvcCoinObject, [tx.pure.u64(amount)])
|
|
716
|
+
const { vaultsValuation, symbolsValuation } = this.dataAPI.valuate(tx)
|
|
717
|
+
|
|
718
|
+
tx.moveCall({
|
|
719
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::withdraw`,
|
|
720
|
+
typeArguments: [
|
|
721
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
722
|
+
this.consts.coins[coin].module,
|
|
723
|
+
],
|
|
724
|
+
arguments: [
|
|
725
|
+
tx.object(this.consts.zoCore.market),
|
|
726
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
727
|
+
withdrawObject,
|
|
728
|
+
tx.pure.u64(minAmountOut),
|
|
729
|
+
vaultsValuation,
|
|
730
|
+
symbolsValuation,
|
|
731
|
+
],
|
|
732
|
+
})
|
|
733
|
+
return tx
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Stakes ZBTCVC tokens in ZO staking pools
|
|
738
|
+
*/
|
|
739
|
+
public stake(
|
|
740
|
+
lpCoinObjects: string[],
|
|
741
|
+
amount: bigint,
|
|
742
|
+
pool: string,
|
|
743
|
+
tx?: Transaction,
|
|
744
|
+
): Transaction {
|
|
745
|
+
if (!this.consts.zoStaking) {
|
|
746
|
+
throw new Error('ZO staking configuration not found')
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (!tx) {
|
|
750
|
+
tx = new Transaction()
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const coinObject = this.processCoins(tx, 'zbtcvc', lpCoinObjects)
|
|
754
|
+
const [depositObject] = tx.splitCoins(coinObject, [tx.pure.u64(amount)])
|
|
755
|
+
|
|
756
|
+
tx.moveCall({
|
|
757
|
+
target: `${this.consts.zoStaking.package}::pool::deposit`,
|
|
758
|
+
typeArguments: [
|
|
759
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
760
|
+
`${this.consts.coins.sui.module}`,
|
|
761
|
+
],
|
|
762
|
+
arguments: [
|
|
763
|
+
tx.object(pool),
|
|
764
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
765
|
+
depositObject,
|
|
766
|
+
],
|
|
767
|
+
})
|
|
768
|
+
return tx
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Stakes ZBTCVC tokens using coin object only (PTB)
|
|
773
|
+
*/
|
|
774
|
+
public stakeCoinObject(
|
|
775
|
+
coinObject: any,
|
|
776
|
+
pool: string,
|
|
777
|
+
tx?: Transaction,
|
|
778
|
+
): Transaction {
|
|
779
|
+
if (!this.consts.zoStaking) {
|
|
780
|
+
throw new Error('ZO staking configuration not found')
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (!tx) {
|
|
784
|
+
tx = new Transaction()
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
tx.moveCall({
|
|
788
|
+
target: `${this.consts.zoStaking.package}::pool::deposit`,
|
|
789
|
+
typeArguments: [
|
|
790
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
791
|
+
`${this.consts.coins.sui.module}`,
|
|
792
|
+
],
|
|
793
|
+
arguments: [
|
|
794
|
+
tx.object(pool),
|
|
795
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
796
|
+
coinObject,
|
|
797
|
+
],
|
|
798
|
+
})
|
|
799
|
+
return tx
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Unstakes ZBTCVC tokens from ZO staking pools
|
|
804
|
+
*/
|
|
805
|
+
public unstake(
|
|
806
|
+
credentials: IZBTCVCCredential[],
|
|
807
|
+
amount: bigint,
|
|
808
|
+
pool: string,
|
|
809
|
+
tx?: Transaction,
|
|
810
|
+
): Transaction {
|
|
811
|
+
if (!this.consts.zoStaking) {
|
|
812
|
+
throw new Error('ZO staking configuration not found')
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
let unstakeAmount = amount
|
|
816
|
+
if (!tx) {
|
|
817
|
+
tx = new Transaction()
|
|
818
|
+
}
|
|
819
|
+
for (const credential of credentials) {
|
|
820
|
+
const withdrawAmount = (() => {
|
|
821
|
+
const min = (a: bigint, b: bigint) => a < b ? a : b
|
|
822
|
+
return min(unstakeAmount, credential.amount)
|
|
823
|
+
})()
|
|
824
|
+
unstakeAmount -= withdrawAmount
|
|
825
|
+
tx.moveCall({
|
|
826
|
+
target: `${this.consts.zoStaking.package}::pool::withdraw`,
|
|
827
|
+
typeArguments: [
|
|
828
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
829
|
+
`${this.consts.coins.sui.module}`,
|
|
830
|
+
],
|
|
831
|
+
arguments: [
|
|
832
|
+
tx.object(pool),
|
|
833
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
834
|
+
tx.object(credential.id),
|
|
835
|
+
tx.pure.u64(withdrawAmount),
|
|
836
|
+
],
|
|
837
|
+
})
|
|
838
|
+
if (credential.amount === BigInt(0)) {
|
|
839
|
+
tx.moveCall({
|
|
840
|
+
target: `${this.consts.zoStaking.package}::pool::clear_empty_credential`,
|
|
841
|
+
typeArguments: [
|
|
842
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
843
|
+
`${this.consts.coins.sui.module}`,
|
|
844
|
+
],
|
|
845
|
+
arguments: [tx.object(credential.id)],
|
|
846
|
+
})
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return tx
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
public async swap(
|
|
853
|
+
fromToken: string,
|
|
854
|
+
toToken: string,
|
|
855
|
+
fromAmount: bigint,
|
|
856
|
+
fromCoinObjects: string[],
|
|
857
|
+
minAmountOut?: number,
|
|
858
|
+
): Promise<Transaction> {
|
|
859
|
+
const tx = await this.initOracleTxb(Object.keys(this.consts.zoCore.vaults))
|
|
860
|
+
const fromCoinObject = this.processCoins(tx, fromToken, fromCoinObjects)
|
|
861
|
+
const [fromDepositObject] = tx.splitCoins(fromCoinObject, [tx.pure.u64(fromAmount)])
|
|
862
|
+
const vaultsValuation = this.dataAPI.valuateVaults(tx)
|
|
863
|
+
|
|
864
|
+
tx.moveCall({
|
|
865
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::swap`,
|
|
866
|
+
typeArguments: [
|
|
867
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
868
|
+
this.consts.coins[fromToken].module,
|
|
869
|
+
this.consts.coins[toToken].module,
|
|
870
|
+
],
|
|
871
|
+
arguments: [
|
|
872
|
+
tx.object(this.consts.zoCore.market),
|
|
873
|
+
tx.object(this.consts.zoCore.rebaseFeeModel),
|
|
874
|
+
fromDepositObject,
|
|
875
|
+
tx.pure.u64(minAmountOut || 0),
|
|
876
|
+
vaultsValuation,
|
|
877
|
+
],
|
|
878
|
+
})
|
|
879
|
+
return tx
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Opens a new position in ZBTCVC
|
|
884
|
+
*/
|
|
885
|
+
public async openPosition(
|
|
886
|
+
collateralToken: string,
|
|
887
|
+
indexToken: string,
|
|
888
|
+
size: bigint,
|
|
889
|
+
collateralAmount: bigint,
|
|
890
|
+
coinObjects: string[],
|
|
891
|
+
long: boolean,
|
|
892
|
+
reserveAmount: bigint,
|
|
893
|
+
indexPrice: number,
|
|
894
|
+
collateralPrice: number,
|
|
895
|
+
isLimitOrder?: boolean,
|
|
896
|
+
isIocOrder?: boolean,
|
|
897
|
+
pricesSlippage = 0.003,
|
|
898
|
+
collateralSlippage = 0.5,
|
|
899
|
+
relayerFee = BigInt(0.5),
|
|
900
|
+
referralAddress?: string,
|
|
901
|
+
sender?: string,
|
|
902
|
+
sponsoredTx?: boolean,
|
|
903
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
904
|
+
): Promise<Transaction> {
|
|
905
|
+
let tx = new Transaction()
|
|
906
|
+
if (referralAddress && !(await this.dataAPI.hasReferral(sender || ''))) {
|
|
907
|
+
tx = await this.addReferral(referralAddress, tx)
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
911
|
+
const adjustPrice = this.processSlippage(indexPrice, long, isLimitOrder ? 0 : pricesSlippage)
|
|
912
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
913
|
+
|
|
914
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
915
|
+
if (isLimitOrder) {
|
|
916
|
+
allowTrade = isIocOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// Handle oracle initialization and coin processing
|
|
920
|
+
let suiCoinObject
|
|
921
|
+
if (sponsoredTx) {
|
|
922
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
923
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
924
|
+
}
|
|
925
|
+
else {
|
|
926
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
// Process coin splitting
|
|
930
|
+
const [depositObject, feeObject] = this.processCoinSplitting(
|
|
931
|
+
tx,
|
|
932
|
+
collateralToken,
|
|
933
|
+
coinObjects,
|
|
934
|
+
[tx.pure.u64(collateralAmount), tx.pure.u64(relayerFee)],
|
|
935
|
+
sponsoredTx,
|
|
936
|
+
suiCoinObject,
|
|
937
|
+
)
|
|
938
|
+
|
|
939
|
+
tx.moveCall({
|
|
940
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::open_position`,
|
|
941
|
+
typeArguments: [
|
|
942
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
943
|
+
this.consts.coins[collateralToken].module,
|
|
944
|
+
this.consts.coins[indexToken].module,
|
|
945
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
946
|
+
this.consts.coins[collateralToken].module,
|
|
947
|
+
],
|
|
948
|
+
arguments: [
|
|
949
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
950
|
+
tx.object(this.consts.zoCore.market),
|
|
951
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
952
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
953
|
+
tx.object(this.consts.zoCore.symbols[symbol].positionConfig),
|
|
954
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
955
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
956
|
+
depositObject,
|
|
957
|
+
feeObject,
|
|
958
|
+
tx.pure.u8(allowTrade),
|
|
959
|
+
tx.pure.u64(size),
|
|
960
|
+
tx.pure.u64(reserveAmount),
|
|
961
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
962
|
+
tx.pure.u256(adjustPrice),
|
|
963
|
+
],
|
|
964
|
+
})
|
|
965
|
+
return tx
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Decreases an existing position in ZBTCVC
|
|
970
|
+
*/
|
|
971
|
+
public async decreasePosition(
|
|
972
|
+
pcpId: string,
|
|
973
|
+
collateralToken: string,
|
|
974
|
+
indexToken: string,
|
|
975
|
+
amount: bigint,
|
|
976
|
+
long: boolean,
|
|
977
|
+
indexPrice: number,
|
|
978
|
+
collateralPrice: number,
|
|
979
|
+
isTriggerOrder = false,
|
|
980
|
+
isTakeProfitOrder = true,
|
|
981
|
+
isIocOrder = false,
|
|
982
|
+
pricesSlippage = 0.003,
|
|
983
|
+
collateralSlippage = 0.5,
|
|
984
|
+
relayerFee = BigInt(0.5),
|
|
985
|
+
coinObjects?: string[],
|
|
986
|
+
sponsoredTx?: boolean,
|
|
987
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
988
|
+
): Promise<Transaction> {
|
|
989
|
+
if (!coinObjects) {
|
|
990
|
+
throw new Error(`${this.constructor.name}: coinObjects is required`)
|
|
991
|
+
}
|
|
992
|
+
let tx = new Transaction()
|
|
993
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
994
|
+
|
|
995
|
+
const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
|
|
996
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
997
|
+
|
|
998
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
999
|
+
if (isTriggerOrder) {
|
|
1000
|
+
allowTrade = isIocOrder || !isTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
isTakeProfitOrder = true
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// Handle oracle initialization and coin processing
|
|
1007
|
+
let suiCoinObject
|
|
1008
|
+
if (sponsoredTx) {
|
|
1009
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
1010
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// Process coin splitting
|
|
1017
|
+
const [feeObject] = this.processCoinSplitting(
|
|
1018
|
+
tx,
|
|
1019
|
+
collateralToken,
|
|
1020
|
+
coinObjects,
|
|
1021
|
+
[tx.pure.u64(relayerFee)],
|
|
1022
|
+
sponsoredTx,
|
|
1023
|
+
suiCoinObject,
|
|
1024
|
+
)
|
|
1025
|
+
|
|
1026
|
+
tx.moveCall({
|
|
1027
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position`,
|
|
1028
|
+
typeArguments: [
|
|
1029
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1030
|
+
this.consts.coins[collateralToken].module,
|
|
1031
|
+
this.consts.coins[indexToken].module,
|
|
1032
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1033
|
+
this.consts.coins[collateralToken].module,
|
|
1034
|
+
],
|
|
1035
|
+
arguments: [
|
|
1036
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
1037
|
+
tx.object(this.consts.zoCore.market),
|
|
1038
|
+
tx.object(pcpId),
|
|
1039
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
1040
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
1041
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
1042
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
1043
|
+
feeObject,
|
|
1044
|
+
tx.pure.u8(allowTrade),
|
|
1045
|
+
tx.pure.bool(isTakeProfitOrder),
|
|
1046
|
+
tx.pure.u64(amount),
|
|
1047
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
1048
|
+
tx.pure.u256(adjustPrice),
|
|
1049
|
+
],
|
|
1050
|
+
})
|
|
1051
|
+
|
|
1052
|
+
return tx
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
public async decreaseMultiPositions(positions: Array<{
|
|
1056
|
+
pcpId: string
|
|
1057
|
+
collateralToken: string
|
|
1058
|
+
indexToken: string
|
|
1059
|
+
amount: bigint
|
|
1060
|
+
long: boolean
|
|
1061
|
+
indexPrice: number
|
|
1062
|
+
collateralPrice: number
|
|
1063
|
+
isTriggerOrder?: boolean
|
|
1064
|
+
isTakeProfitOrder?: boolean
|
|
1065
|
+
isIocOrder?: boolean
|
|
1066
|
+
pricesSlippage?: number
|
|
1067
|
+
collateralSlippage?: number
|
|
1068
|
+
relayerFee?: bigint
|
|
1069
|
+
coinObjects?: string[]
|
|
1070
|
+
}>, tx?: Transaction, sponsoredTx?: boolean, suiCoinObjectsForPythUpdate?: string[]): Promise<Transaction> {
|
|
1071
|
+
if (!tx) {
|
|
1072
|
+
tx = new Transaction()
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// Handle oracle initialization and coin processing
|
|
1076
|
+
let suiCoinObject
|
|
1077
|
+
if (sponsoredTx) {
|
|
1078
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
1079
|
+
tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx, true, suiCoinObject)
|
|
1080
|
+
}
|
|
1081
|
+
else {
|
|
1082
|
+
tx = await this.initOracleTxb(positions.flatMap(position => [position.collateralToken, position.indexToken]), tx)
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
for (const position of positions) {
|
|
1086
|
+
const {
|
|
1087
|
+
pcpId,
|
|
1088
|
+
collateralToken,
|
|
1089
|
+
coinObjects = [],
|
|
1090
|
+
indexToken,
|
|
1091
|
+
amount,
|
|
1092
|
+
long,
|
|
1093
|
+
indexPrice,
|
|
1094
|
+
collateralPrice,
|
|
1095
|
+
isTriggerOrder = false,
|
|
1096
|
+
isTakeProfitOrder = true,
|
|
1097
|
+
isIocOrder = false,
|
|
1098
|
+
pricesSlippage = 0.003,
|
|
1099
|
+
collateralSlippage = 0.5,
|
|
1100
|
+
relayerFee = BigInt(0.5),
|
|
1101
|
+
} = position
|
|
1102
|
+
let innerIsTakeProfitOrder = isTakeProfitOrder
|
|
1103
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
1104
|
+
|
|
1105
|
+
const adjustPrice = this.processSlippage(indexPrice, !long, isTriggerOrder ? 0 : pricesSlippage)
|
|
1106
|
+
const adjustCollateralPrice = this.processSlippage(collateralPrice, false, collateralSlippage)
|
|
1107
|
+
|
|
1108
|
+
let allowTrade = ALLOW_TRADE_MUST_TRADE
|
|
1109
|
+
if (isTriggerOrder) {
|
|
1110
|
+
allowTrade = isIocOrder || !innerIsTakeProfitOrder ? ALLOW_TRADE_NO_TRADE : ALLOW_TRADE_CAN_TRADE
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
innerIsTakeProfitOrder = true
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// Process coin splitting
|
|
1117
|
+
const [feeObject] = this.processCoinSplitting(
|
|
1118
|
+
tx,
|
|
1119
|
+
collateralToken,
|
|
1120
|
+
coinObjects,
|
|
1121
|
+
[tx.pure.u64(relayerFee)],
|
|
1122
|
+
sponsoredTx,
|
|
1123
|
+
suiCoinObject,
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1126
|
+
tx.moveCall({
|
|
1127
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::decrease_position`,
|
|
1128
|
+
typeArguments: [
|
|
1129
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1130
|
+
this.consts.coins[collateralToken].module,
|
|
1131
|
+
this.consts.coins[indexToken].module,
|
|
1132
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1133
|
+
this.consts.coins[collateralToken].module,
|
|
1134
|
+
],
|
|
1135
|
+
arguments: [
|
|
1136
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
1137
|
+
tx.object(this.consts.zoCore.market),
|
|
1138
|
+
tx.object(pcpId),
|
|
1139
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
1140
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
1141
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
1142
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
1143
|
+
feeObject,
|
|
1144
|
+
tx.pure.u8(allowTrade),
|
|
1145
|
+
tx.pure.bool(innerIsTakeProfitOrder),
|
|
1146
|
+
tx.pure.u64(amount),
|
|
1147
|
+
tx.pure.u256(adjustCollateralPrice),
|
|
1148
|
+
tx.pure.u256(adjustPrice),
|
|
1149
|
+
],
|
|
1150
|
+
})
|
|
1151
|
+
}
|
|
1152
|
+
return tx
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Pledges in position (ZBTCVC-specific functionality)
|
|
1157
|
+
*/
|
|
1158
|
+
public async pledgeInPosition(
|
|
1159
|
+
pcpId: string,
|
|
1160
|
+
collateralToken: string,
|
|
1161
|
+
indexToken: string,
|
|
1162
|
+
amount: number,
|
|
1163
|
+
coinObjects: string[],
|
|
1164
|
+
long: boolean,
|
|
1165
|
+
sponsoredTx?: boolean,
|
|
1166
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
1167
|
+
): Promise<Transaction> {
|
|
1168
|
+
let tx = new Transaction()
|
|
1169
|
+
// Handle oracle initialization and coin processing
|
|
1170
|
+
let suiCoinObject
|
|
1171
|
+
if (sponsoredTx) {
|
|
1172
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
1173
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// Process coin splitting
|
|
1180
|
+
const [depositObject] = this.processCoinSplitting(
|
|
1181
|
+
tx,
|
|
1182
|
+
collateralToken,
|
|
1183
|
+
coinObjects,
|
|
1184
|
+
[tx.pure.u64(amount)],
|
|
1185
|
+
sponsoredTx,
|
|
1186
|
+
suiCoinObject,
|
|
1187
|
+
)
|
|
1188
|
+
|
|
1189
|
+
tx.moveCall({
|
|
1190
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::pledge_in_position`,
|
|
1191
|
+
typeArguments: [
|
|
1192
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1193
|
+
this.consts.coins[collateralToken].module,
|
|
1194
|
+
this.consts.coins[indexToken].module,
|
|
1195
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1196
|
+
],
|
|
1197
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(pcpId), depositObject],
|
|
1198
|
+
})
|
|
1199
|
+
return tx
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
public async redeemFromPosition(
|
|
1203
|
+
pcpId: string,
|
|
1204
|
+
collateralToken: string,
|
|
1205
|
+
indexToken: string,
|
|
1206
|
+
amount: number,
|
|
1207
|
+
long: boolean,
|
|
1208
|
+
sponsoredTx?: boolean,
|
|
1209
|
+
suiCoinObjectsForPythUpdate?: string[],
|
|
1210
|
+
): Promise<Transaction> {
|
|
1211
|
+
let tx = new Transaction()
|
|
1212
|
+
// Handle oracle initialization and coin processing
|
|
1213
|
+
let suiCoinObject
|
|
1214
|
+
if (sponsoredTx) {
|
|
1215
|
+
suiCoinObject = this.processCoins(tx, 'sui', suiCoinObjectsForPythUpdate || [], true)
|
|
1216
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx, true, suiCoinObject)
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
tx = await this.initOracleTxb([collateralToken, indexToken], tx)
|
|
1220
|
+
}
|
|
1221
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
1222
|
+
|
|
1223
|
+
tx.moveCall({
|
|
1224
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::redeem_from_position`,
|
|
1225
|
+
typeArguments: [
|
|
1226
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1227
|
+
this.consts.coins[collateralToken].module,
|
|
1228
|
+
this.consts.coins[indexToken].module,
|
|
1229
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1230
|
+
],
|
|
1231
|
+
arguments: [
|
|
1232
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
1233
|
+
tx.object(this.consts.zoCore.market),
|
|
1234
|
+
tx.object(pcpId),
|
|
1235
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
1236
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
1237
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
1238
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
1239
|
+
tx.pure.u64(amount),
|
|
1240
|
+
],
|
|
1241
|
+
})
|
|
1242
|
+
|
|
1243
|
+
return tx
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
public cancelOrder(
|
|
1247
|
+
orderCapId: string,
|
|
1248
|
+
collateralToken: string,
|
|
1249
|
+
indexToken: string,
|
|
1250
|
+
long: boolean,
|
|
1251
|
+
type: string,
|
|
1252
|
+
isV11Order?: boolean,
|
|
1253
|
+
): Transaction {
|
|
1254
|
+
const tx = new Transaction()
|
|
1255
|
+
let functionName = ''
|
|
1256
|
+
switch (type) {
|
|
1257
|
+
case 'OPEN_POSITION': {
|
|
1258
|
+
functionName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
|
|
1259
|
+
break
|
|
1260
|
+
}
|
|
1261
|
+
case 'DECREASE_POSITION': {
|
|
1262
|
+
functionName = isV11Order
|
|
1263
|
+
? 'clear_decrease_position_order'
|
|
1264
|
+
: 'clear_decrease_position_order'
|
|
1265
|
+
break
|
|
1266
|
+
}
|
|
1267
|
+
default: {
|
|
1268
|
+
throw new Error('invalid order type')
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
tx.moveCall({
|
|
1272
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::${functionName}`,
|
|
1273
|
+
typeArguments: [
|
|
1274
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1275
|
+
this.consts.coins[collateralToken].module,
|
|
1276
|
+
this.consts.coins[indexToken].module,
|
|
1277
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1278
|
+
this.consts.coins[collateralToken].module,
|
|
1279
|
+
],
|
|
1280
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
|
|
1281
|
+
})
|
|
1282
|
+
return tx
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
public cancelMultiOrders(
|
|
1286
|
+
orders: Array<{
|
|
1287
|
+
orderCapId: string
|
|
1288
|
+
collateralToken: string
|
|
1289
|
+
indexToken: string
|
|
1290
|
+
long: boolean
|
|
1291
|
+
type: string
|
|
1292
|
+
isV11Order?: boolean
|
|
1293
|
+
}>,
|
|
1294
|
+
tx?: Transaction,
|
|
1295
|
+
): Transaction {
|
|
1296
|
+
if (!tx) {
|
|
1297
|
+
tx = new Transaction()
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
for (const order of orders) {
|
|
1301
|
+
const { orderCapId, collateralToken, indexToken, long, type, isV11Order } = order
|
|
1302
|
+
let functionName = ''
|
|
1303
|
+
switch (type) {
|
|
1304
|
+
case 'OPEN_POSITION': {
|
|
1305
|
+
functionName = isV11Order ? 'clear_open_position_order' : 'clear_open_position_order'
|
|
1306
|
+
break
|
|
1307
|
+
}
|
|
1308
|
+
case 'DECREASE_POSITION': {
|
|
1309
|
+
functionName = isV11Order
|
|
1310
|
+
? 'clear_decrease_position_order'
|
|
1311
|
+
: 'clear_decrease_position_order'
|
|
1312
|
+
break
|
|
1313
|
+
}
|
|
1314
|
+
default: {
|
|
1315
|
+
throw new Error('invalid order type')
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
tx.moveCall({
|
|
1320
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::${functionName}`,
|
|
1321
|
+
typeArguments: [
|
|
1322
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1323
|
+
this.consts.coins[collateralToken].module,
|
|
1324
|
+
this.consts.coins[indexToken].module,
|
|
1325
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1326
|
+
this.consts.coins[collateralToken].module,
|
|
1327
|
+
],
|
|
1328
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(orderCapId)],
|
|
1329
|
+
})
|
|
1330
|
+
}
|
|
1331
|
+
return tx
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
public addReferral(
|
|
1335
|
+
referralAddress: string,
|
|
1336
|
+
tx?: Transaction,
|
|
1337
|
+
): Transaction {
|
|
1338
|
+
if (!tx) {
|
|
1339
|
+
tx = new Transaction()
|
|
1340
|
+
}
|
|
1341
|
+
tx.moveCall({
|
|
1342
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::add_new_referral`,
|
|
1343
|
+
typeArguments: [`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`],
|
|
1344
|
+
arguments: [tx.object(this.consts.zoCore.market), tx.object(referralAddress)],
|
|
1345
|
+
})
|
|
1346
|
+
|
|
1347
|
+
return tx
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
public async adminUpdatePriceFeed(
|
|
1351
|
+
collateralToken: string,
|
|
1352
|
+
indexToken: string,
|
|
1353
|
+
): Promise<Transaction> {
|
|
1354
|
+
const tx = await this.initOracleTxb([collateralToken, indexToken])
|
|
1355
|
+
return tx
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
public adminSettlePosition(
|
|
1359
|
+
positionId: string,
|
|
1360
|
+
owner: string,
|
|
1361
|
+
collateralToken: string,
|
|
1362
|
+
indexToken: string,
|
|
1363
|
+
long: boolean,
|
|
1364
|
+
): Transaction {
|
|
1365
|
+
const tx = new Transaction()
|
|
1366
|
+
|
|
1367
|
+
tx.moveCall({
|
|
1368
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::force_settle_position`,
|
|
1369
|
+
typeArguments: [
|
|
1370
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1371
|
+
this.consts.coins[collateralToken].module,
|
|
1372
|
+
this.consts.coins[indexToken].module,
|
|
1373
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1374
|
+
],
|
|
1375
|
+
arguments: [
|
|
1376
|
+
tx.object(this.consts.zoCore.adminCap),
|
|
1377
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
1378
|
+
tx.object(this.consts.zoCore.market),
|
|
1379
|
+
tx.object(owner),
|
|
1380
|
+
tx.object(positionId),
|
|
1381
|
+
],
|
|
1382
|
+
})
|
|
1383
|
+
|
|
1384
|
+
this.adminClearClosedPosition(positionId, owner, collateralToken, indexToken, long, tx)
|
|
1385
|
+
|
|
1386
|
+
return tx
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
public adminDecreasePosition(
|
|
1390
|
+
positionId: string,
|
|
1391
|
+
owner: string,
|
|
1392
|
+
collateralToken: string,
|
|
1393
|
+
indexToken: string,
|
|
1394
|
+
positionAmount: number,
|
|
1395
|
+
amount: bigint,
|
|
1396
|
+
long: boolean,
|
|
1397
|
+
): Transaction {
|
|
1398
|
+
const tx = new Transaction()
|
|
1399
|
+
const symbol = joinSymbol(long ? 'long' : 'short', indexToken)
|
|
1400
|
+
|
|
1401
|
+
tx.moveCall({
|
|
1402
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::force_close_position`,
|
|
1403
|
+
typeArguments: [
|
|
1404
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1405
|
+
this.consts.coins[collateralToken].module,
|
|
1406
|
+
this.consts.coins[indexToken].module,
|
|
1407
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1408
|
+
],
|
|
1409
|
+
arguments: [
|
|
1410
|
+
tx.object(this.consts.zoCore.adminCap),
|
|
1411
|
+
tx.object(SUI_CLOCK_OBJECT_ID),
|
|
1412
|
+
tx.object(this.consts.zoCore.market),
|
|
1413
|
+
tx.object(this.consts.zoCore.vaults[collateralToken].reservingFeeModel),
|
|
1414
|
+
tx.object(this.consts.zoCore.symbols[symbol].fundingFeeModel),
|
|
1415
|
+
tx.object(this.consts.pythFeeder.feeder[collateralToken]),
|
|
1416
|
+
tx.object(this.consts.pythFeeder.feeder[indexToken]),
|
|
1417
|
+
tx.object(owner),
|
|
1418
|
+
tx.object(positionId),
|
|
1419
|
+
],
|
|
1420
|
+
})
|
|
1421
|
+
|
|
1422
|
+
if (amount === BigInt(positionAmount)) {
|
|
1423
|
+
this.adminClearClosedPosition(positionId, owner, collateralToken, indexToken, long, tx)
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
return tx
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
public adminClearClosedPosition(
|
|
1430
|
+
positionId: string,
|
|
1431
|
+
owner: string,
|
|
1432
|
+
collateralToken: string,
|
|
1433
|
+
indexToken: string,
|
|
1434
|
+
long: boolean,
|
|
1435
|
+
tx: Transaction,
|
|
1436
|
+
): void {
|
|
1437
|
+
tx.moveCall({
|
|
1438
|
+
target: `${this.consts.zoCore.upgradedPackage}::market::force_clear_closed_position`,
|
|
1439
|
+
typeArguments: [
|
|
1440
|
+
`${this.consts.zoCore.package}::zbtcvc::ZBTCVC`,
|
|
1441
|
+
this.consts.coins[collateralToken].module,
|
|
1442
|
+
this.consts.coins[indexToken].module,
|
|
1443
|
+
`${this.consts.zoCore.package}::market::${long ? 'LONG' : 'SHORT'}`,
|
|
1444
|
+
],
|
|
1445
|
+
arguments: [
|
|
1446
|
+
tx.object(this.consts.zoCore.adminCap),
|
|
1447
|
+
tx.object(this.consts.zoCore.market),
|
|
1448
|
+
tx.object(positionId),
|
|
1449
|
+
tx.object(owner),
|
|
1450
|
+
],
|
|
1451
|
+
})
|
|
1452
|
+
}
|
|
1453
|
+
}
|