@scallop-io/sui-scallop-sdk 0.37.3
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/LICENSE +202 -0
- package/README.md +276 -0
- package/dist/constants/common.d.ts +7 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1487 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1444 -0
- package/dist/index.mjs.map +1 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/scallop.d.ts +46 -0
- package/dist/models/scallopAddress.d.ts +107 -0
- package/dist/models/scallopClient.d.ts +151 -0
- package/dist/models/scallopUtils.d.ts +56 -0
- package/dist/queries/index.d.ts +2 -0
- package/dist/queries/market.d.ts +4 -0
- package/dist/queries/obligation.d.ts +8 -0
- package/dist/txBuilders/coin.d.ts +67 -0
- package/dist/txBuilders/index.d.ts +1 -0
- package/dist/txBuilders/normalMethods.d.ts +3 -0
- package/dist/txBuilders/oracle.d.ts +7 -0
- package/dist/txBuilders/quickMethods.d.ts +7 -0
- package/dist/types/data.d.ts +127 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/model.d.ts +9 -0
- package/dist/types/txBuilder.d.ts +66 -0
- package/package.json +147 -0
- package/src/constants/common.ts +36 -0
- package/src/constants/index.ts +1 -0
- package/src/index.ts +3 -0
- package/src/models/index.ts +4 -0
- package/src/models/scallop.ts +76 -0
- package/src/models/scallopAddress.ts +460 -0
- package/src/models/scallopClient.ts +461 -0
- package/src/models/scallopUtils.ts +133 -0
- package/src/queries/index.ts +2 -0
- package/src/queries/market.ts +16 -0
- package/src/queries/obligation.ts +44 -0
- package/src/txBuilders/coin.ts +38 -0
- package/src/txBuilders/index.ts +1 -0
- package/src/txBuilders/normalMethods.ts +216 -0
- package/src/txBuilders/oracle.ts +376 -0
- package/src/txBuilders/quickMethods.ts +231 -0
- package/src/types/data.ts +170 -0
- package/src/types/index.ts +3 -0
- package/src/types/model.ts +15 -0
- package/src/types/txBuilder.ts +136 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { normalizeSuiAddress } from '@mysten/sui.js';
|
|
2
|
+
import { SuiKit } from '@scallop-io/sui-kit';
|
|
3
|
+
import { ScallopAddress } from './scallopAddress';
|
|
4
|
+
import { ScallopUtils } from './scallopUtils';
|
|
5
|
+
import { newScallopTxBlock } from '../txBuilders';
|
|
6
|
+
import { queryObligation, queryMarket, getObligations } from '../queries';
|
|
7
|
+
import type {
|
|
8
|
+
TransactionArgument,
|
|
9
|
+
SuiTransactionBlockResponse,
|
|
10
|
+
} from '@mysten/sui.js';
|
|
11
|
+
import type { SuiTxArg } from '@scallop-io/sui-kit';
|
|
12
|
+
import type {
|
|
13
|
+
ScallopClientFnReturnType,
|
|
14
|
+
ScallopParams,
|
|
15
|
+
SupportAssetCoins,
|
|
16
|
+
SupportCollateralCoins,
|
|
17
|
+
SupportCoins,
|
|
18
|
+
ScallopTxBlock,
|
|
19
|
+
} from '../types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* ### Scallop Client
|
|
23
|
+
*
|
|
24
|
+
* it provides contract interaction operations for general users.
|
|
25
|
+
*
|
|
26
|
+
* #### Usage
|
|
27
|
+
*
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const client = new Scallop(<parameters>);
|
|
30
|
+
* client.<interact functions>();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class ScallopClient {
|
|
34
|
+
public suiKit: SuiKit;
|
|
35
|
+
public address: ScallopAddress;
|
|
36
|
+
public walletAddress: string;
|
|
37
|
+
|
|
38
|
+
private readonly _utils: ScallopUtils;
|
|
39
|
+
private readonly _isTestnet: boolean;
|
|
40
|
+
|
|
41
|
+
public constructor(
|
|
42
|
+
params: ScallopParams,
|
|
43
|
+
address: ScallopAddress,
|
|
44
|
+
walletAddress?: string,
|
|
45
|
+
isTestnet?: boolean
|
|
46
|
+
) {
|
|
47
|
+
this.suiKit = new SuiKit(params);
|
|
48
|
+
this.address = address;
|
|
49
|
+
this.walletAddress = normalizeSuiAddress(
|
|
50
|
+
walletAddress || this.suiKit.currentAddress()
|
|
51
|
+
);
|
|
52
|
+
this._utils = new ScallopUtils(params);
|
|
53
|
+
this._isTestnet =
|
|
54
|
+
isTestnet ||
|
|
55
|
+
(params.networkType ? params.networkType === 'testnet' : false);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
createTxBlock() {
|
|
59
|
+
return newScallopTxBlock(
|
|
60
|
+
this.suiKit,
|
|
61
|
+
this.address,
|
|
62
|
+
this._utils,
|
|
63
|
+
this._isTestnet
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Query market data.
|
|
69
|
+
*
|
|
70
|
+
* @return Market data
|
|
71
|
+
*/
|
|
72
|
+
public async queryMarket() {
|
|
73
|
+
return queryMarket(this.address, this.suiKit);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Query obligations data.
|
|
78
|
+
*
|
|
79
|
+
* @param ownerAddress - The owner address.
|
|
80
|
+
* @return Obligations data
|
|
81
|
+
*/
|
|
82
|
+
async getObligations(ownerAddress?: string) {
|
|
83
|
+
const owner = ownerAddress || this.walletAddress;
|
|
84
|
+
return getObligations(owner, this.address, this.suiKit);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Query obligation data.
|
|
89
|
+
*
|
|
90
|
+
* @param obligationId - The obligation id from protocol package.
|
|
91
|
+
* @return Obligation data
|
|
92
|
+
*/
|
|
93
|
+
public async queryObligation(obligationId: string) {
|
|
94
|
+
return queryObligation(obligationId, this.address, this.suiKit);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Open obligation.
|
|
99
|
+
*
|
|
100
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
101
|
+
* @return Transaction block response or transaction block
|
|
102
|
+
*/
|
|
103
|
+
public async openObligation(): Promise<SuiTransactionBlockResponse>;
|
|
104
|
+
public async openObligation<S extends boolean>(
|
|
105
|
+
sign?: S
|
|
106
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
107
|
+
public async openObligation<S extends boolean>(
|
|
108
|
+
sign: S = true as S
|
|
109
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
110
|
+
const txBlock = this.createTxBlock();
|
|
111
|
+
txBlock.openObligationEntry();
|
|
112
|
+
if (sign) {
|
|
113
|
+
return (await this.suiKit.signAndSendTxn(
|
|
114
|
+
txBlock
|
|
115
|
+
)) as ScallopClientFnReturnType<S>;
|
|
116
|
+
} else {
|
|
117
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Deposit collateral into the specific pool.
|
|
123
|
+
*
|
|
124
|
+
* @param coinName - Types of collateral coin.
|
|
125
|
+
* @param amount - The amount of coins would deposit.
|
|
126
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
127
|
+
* @param obligationId - The obligation object.
|
|
128
|
+
* @param walletAddress - The wallet address of the owner.
|
|
129
|
+
* @return Transaction block response or transaction block
|
|
130
|
+
*/
|
|
131
|
+
public async depositCollateral(
|
|
132
|
+
coinName: SupportCollateralCoins,
|
|
133
|
+
amount: number
|
|
134
|
+
): Promise<SuiTransactionBlockResponse>;
|
|
135
|
+
public async depositCollateral<S extends boolean>(
|
|
136
|
+
coinName: SupportCollateralCoins,
|
|
137
|
+
amount: number,
|
|
138
|
+
sign?: S,
|
|
139
|
+
obligationId?: SuiTxArg,
|
|
140
|
+
walletAddress?: string
|
|
141
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
142
|
+
public async depositCollateral<S extends boolean>(
|
|
143
|
+
coinName: SupportCollateralCoins,
|
|
144
|
+
amount: number,
|
|
145
|
+
sign: S = true as S,
|
|
146
|
+
obligationId?: SuiTxArg,
|
|
147
|
+
walletAddress?: string
|
|
148
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
149
|
+
const txBlock = this.createTxBlock();
|
|
150
|
+
const sender = walletAddress || this.walletAddress;
|
|
151
|
+
txBlock.setSender(sender);
|
|
152
|
+
|
|
153
|
+
if (obligationId) {
|
|
154
|
+
await txBlock.addCollateralQuick(amount, coinName, obligationId);
|
|
155
|
+
} else {
|
|
156
|
+
const [obligation, obligationKey, hotPotato] = txBlock.openObligation();
|
|
157
|
+
await txBlock.addCollateralQuick(amount, coinName, obligation);
|
|
158
|
+
txBlock.returnObligation(obligation, hotPotato);
|
|
159
|
+
txBlock.transferObjects([obligationKey], sender);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (sign) {
|
|
163
|
+
return (await this.suiKit.signAndSendTxn(
|
|
164
|
+
txBlock
|
|
165
|
+
)) as ScallopClientFnReturnType<S>;
|
|
166
|
+
} else {
|
|
167
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Withdraw collateral from the specific pool.
|
|
173
|
+
*
|
|
174
|
+
* @param coinName - Types of collateral coin.
|
|
175
|
+
* @param amount - The amount of coins would deposit.
|
|
176
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
177
|
+
* @param obligationId - The obligation object.
|
|
178
|
+
* @param obligationKey - The obligation key object to verifying obligation authority.
|
|
179
|
+
* @param walletAddress - The wallet address of the owner.
|
|
180
|
+
* @return Transaction block response or transaction block
|
|
181
|
+
*/
|
|
182
|
+
public async withdrawCollateral<S extends boolean>(
|
|
183
|
+
coinName: SupportCollateralCoins,
|
|
184
|
+
amount: number,
|
|
185
|
+
sign: S = true as S,
|
|
186
|
+
obligationId: string,
|
|
187
|
+
obligationKey: string,
|
|
188
|
+
walletAddress?: string
|
|
189
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
190
|
+
const txBlock = this.createTxBlock();
|
|
191
|
+
const sender = walletAddress || this.walletAddress;
|
|
192
|
+
txBlock.setSender(sender);
|
|
193
|
+
|
|
194
|
+
const collateralCoin = await txBlock.takeCollateralQuick(
|
|
195
|
+
amount,
|
|
196
|
+
coinName,
|
|
197
|
+
obligationId,
|
|
198
|
+
obligationKey
|
|
199
|
+
);
|
|
200
|
+
txBlock.transferObjects([collateralCoin], sender);
|
|
201
|
+
|
|
202
|
+
if (sign) {
|
|
203
|
+
return (await this.suiKit.signAndSendTxn(
|
|
204
|
+
txBlock
|
|
205
|
+
)) as ScallopClientFnReturnType<S>;
|
|
206
|
+
} else {
|
|
207
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Deposit asset into the specific pool.
|
|
213
|
+
*
|
|
214
|
+
* @param coinName - Types of asset coin.
|
|
215
|
+
* @param amount - The amount of coins would deposit.
|
|
216
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
217
|
+
* @param walletAddress - The wallet address of the owner.
|
|
218
|
+
* @return Transaction block response or transaction block
|
|
219
|
+
*/
|
|
220
|
+
public async deposit(
|
|
221
|
+
coinName: SupportAssetCoins,
|
|
222
|
+
amount: number
|
|
223
|
+
): Promise<SuiTransactionBlockResponse>;
|
|
224
|
+
public async deposit<S extends boolean>(
|
|
225
|
+
coinName: SupportAssetCoins,
|
|
226
|
+
amount: number,
|
|
227
|
+
sign?: S,
|
|
228
|
+
walletAddress?: string
|
|
229
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
230
|
+
public async deposit<S extends boolean>(
|
|
231
|
+
coinName: SupportAssetCoins,
|
|
232
|
+
amount: number,
|
|
233
|
+
sign: S = true as S,
|
|
234
|
+
walletAddress?: string
|
|
235
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
236
|
+
const txBlock = this.createTxBlock();
|
|
237
|
+
const sender = walletAddress || this.walletAddress;
|
|
238
|
+
txBlock.setSender(sender);
|
|
239
|
+
|
|
240
|
+
const marketCoin = await txBlock.depositQuick(amount, coinName);
|
|
241
|
+
txBlock.transferObjects([marketCoin], sender);
|
|
242
|
+
|
|
243
|
+
if (sign) {
|
|
244
|
+
return (await this.suiKit.signAndSendTxn(
|
|
245
|
+
txBlock
|
|
246
|
+
)) as ScallopClientFnReturnType<S>;
|
|
247
|
+
} else {
|
|
248
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Withdraw asset from the specific pool, must return market coin.
|
|
254
|
+
*
|
|
255
|
+
* @param coinName - Types of asset coin.
|
|
256
|
+
* @param amount - The amount of coins would withdraw.
|
|
257
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
258
|
+
* @param walletAddress - The wallet address of the owner.
|
|
259
|
+
* @return Transaction block response or transaction block
|
|
260
|
+
*/
|
|
261
|
+
public async withdraw(
|
|
262
|
+
coinName: SupportAssetCoins,
|
|
263
|
+
amount: number
|
|
264
|
+
): Promise<SuiTransactionBlockResponse>;
|
|
265
|
+
public async withdraw<S extends boolean>(
|
|
266
|
+
coinName: SupportAssetCoins,
|
|
267
|
+
amount: number,
|
|
268
|
+
sign?: S,
|
|
269
|
+
walletAddress?: string
|
|
270
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
271
|
+
public async withdraw<S extends boolean>(
|
|
272
|
+
coinName: SupportAssetCoins,
|
|
273
|
+
amount: number,
|
|
274
|
+
sign: S = true as S,
|
|
275
|
+
walletAddress?: string
|
|
276
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
277
|
+
const txBlock = this.createTxBlock();
|
|
278
|
+
const sender = walletAddress || this.walletAddress;
|
|
279
|
+
txBlock.setSender(sender);
|
|
280
|
+
|
|
281
|
+
const coin = await txBlock.withdrawQuick(amount, coinName);
|
|
282
|
+
txBlock.transferObjects([coin], sender);
|
|
283
|
+
|
|
284
|
+
if (sign) {
|
|
285
|
+
return (await this.suiKit.signAndSendTxn(
|
|
286
|
+
txBlock
|
|
287
|
+
)) as ScallopClientFnReturnType<S>;
|
|
288
|
+
} else {
|
|
289
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* borrow asset from the specific pool.
|
|
295
|
+
*
|
|
296
|
+
* @param coinName - Types of asset coin.
|
|
297
|
+
* @param amount - The amount of coins would borrow.
|
|
298
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
299
|
+
* @param obligationId - The obligation object.
|
|
300
|
+
* @param obligationKey - The obligation key object to verifying obligation authority.
|
|
301
|
+
* @param walletAddress - The wallet address of the owner.
|
|
302
|
+
* @return Transaction block response or transaction block
|
|
303
|
+
*/
|
|
304
|
+
public async borrow<S extends boolean>(
|
|
305
|
+
coinName: SupportAssetCoins,
|
|
306
|
+
amount: number,
|
|
307
|
+
sign: S = true as S,
|
|
308
|
+
obligationId: string,
|
|
309
|
+
obligationKey: string,
|
|
310
|
+
walletAddress?: string
|
|
311
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
312
|
+
const txBlock = this.createTxBlock();
|
|
313
|
+
const sender = walletAddress || this.walletAddress;
|
|
314
|
+
txBlock.setSender(sender);
|
|
315
|
+
|
|
316
|
+
const coin = await txBlock.borrowQuick(
|
|
317
|
+
amount,
|
|
318
|
+
coinName,
|
|
319
|
+
obligationId,
|
|
320
|
+
obligationKey
|
|
321
|
+
);
|
|
322
|
+
txBlock.transferObjects([coin], sender);
|
|
323
|
+
|
|
324
|
+
if (sign) {
|
|
325
|
+
return (await this.suiKit.signAndSendTxn(
|
|
326
|
+
txBlock
|
|
327
|
+
)) as ScallopClientFnReturnType<S>;
|
|
328
|
+
} else {
|
|
329
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Repay asset into the specific pool.
|
|
335
|
+
*
|
|
336
|
+
* @param coinName - Types of asset coin.
|
|
337
|
+
* @param amount - The amount of coins would repay.
|
|
338
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
339
|
+
* @param obligationId - The obligation object.
|
|
340
|
+
* @param walletAddress - The wallet address of the owner.
|
|
341
|
+
* @return Transaction block response or transaction block
|
|
342
|
+
*/
|
|
343
|
+
public async repay<S extends boolean>(
|
|
344
|
+
coinName: SupportAssetCoins,
|
|
345
|
+
amount: number,
|
|
346
|
+
sign: S = true as S,
|
|
347
|
+
obligationId: string,
|
|
348
|
+
walletAddress?: string
|
|
349
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
350
|
+
const txBlock = this.createTxBlock();
|
|
351
|
+
const sender = walletAddress || this.walletAddress;
|
|
352
|
+
txBlock.setSender(sender);
|
|
353
|
+
|
|
354
|
+
await txBlock.repayQuick(amount, coinName, obligationId);
|
|
355
|
+
|
|
356
|
+
if (sign) {
|
|
357
|
+
return (await this.suiKit.signAndSendTxn(
|
|
358
|
+
txBlock
|
|
359
|
+
)) as ScallopClientFnReturnType<S>;
|
|
360
|
+
} else {
|
|
361
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* FlashLoan asset from the specific pool.
|
|
367
|
+
*
|
|
368
|
+
* @param coinName - Types of asset coin.
|
|
369
|
+
* @param amount - The amount of coins would repay.
|
|
370
|
+
* @param callback - The callback function to build transaction block and return coin argument.
|
|
371
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
372
|
+
* @return Transaction block response or transaction block
|
|
373
|
+
*/
|
|
374
|
+
public async flashLoan(
|
|
375
|
+
coinName: SupportAssetCoins,
|
|
376
|
+
amount: number,
|
|
377
|
+
callback: (
|
|
378
|
+
txBlock: ScallopTxBlock,
|
|
379
|
+
coin: TransactionArgument
|
|
380
|
+
) => TransactionArgument
|
|
381
|
+
): Promise<SuiTransactionBlockResponse>;
|
|
382
|
+
public async flashLoan<S extends boolean>(
|
|
383
|
+
coinName: SupportAssetCoins,
|
|
384
|
+
amount: number,
|
|
385
|
+
callback: (
|
|
386
|
+
txBlock: ScallopTxBlock,
|
|
387
|
+
coin: TransactionArgument
|
|
388
|
+
) => TransactionArgument,
|
|
389
|
+
sign?: S
|
|
390
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
391
|
+
public async flashLoan<S extends boolean>(
|
|
392
|
+
coinName: SupportAssetCoins,
|
|
393
|
+
amount: number,
|
|
394
|
+
callback: (
|
|
395
|
+
txBlock: ScallopTxBlock,
|
|
396
|
+
coin: TransactionArgument
|
|
397
|
+
) => TransactionArgument,
|
|
398
|
+
sign: S = true as S
|
|
399
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
400
|
+
const txBlock = this.createTxBlock();
|
|
401
|
+
const [coin, loan] = txBlock.borrowFlashLoan(amount, coinName);
|
|
402
|
+
txBlock.repayFlashLoan(callback(txBlock, coin), loan, coinName);
|
|
403
|
+
|
|
404
|
+
if (sign) {
|
|
405
|
+
return (await this.suiKit.signAndSendTxn(
|
|
406
|
+
txBlock
|
|
407
|
+
)) as ScallopClientFnReturnType<S>;
|
|
408
|
+
} else {
|
|
409
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Mint and get test coin.
|
|
415
|
+
*
|
|
416
|
+
* @remarks
|
|
417
|
+
* Only be used on the test network.
|
|
418
|
+
*
|
|
419
|
+
* @param coinName - Types of coins supported on the test network.
|
|
420
|
+
* @param amount - The amount of coins minted and received.
|
|
421
|
+
* @param receiveAddress - The wallet address that receives the coins.
|
|
422
|
+
* @param sign - Decide to directly sign the transaction or return the transaction block.
|
|
423
|
+
* @return Transaction block response or transaction block
|
|
424
|
+
*/
|
|
425
|
+
public async mintTestCoin(
|
|
426
|
+
coinName: Exclude<SupportCoins, 'sui'>,
|
|
427
|
+
amount: number
|
|
428
|
+
): Promise<SuiTransactionBlockResponse>;
|
|
429
|
+
public async mintTestCoin<S extends boolean>(
|
|
430
|
+
coinName: Exclude<SupportCoins, 'sui'>,
|
|
431
|
+
amount: number,
|
|
432
|
+
sign?: S,
|
|
433
|
+
receiveAddress?: string
|
|
434
|
+
): Promise<ScallopClientFnReturnType<S>>;
|
|
435
|
+
public async mintTestCoin<S extends boolean>(
|
|
436
|
+
coinName: Exclude<SupportCoins, 'sui'>,
|
|
437
|
+
amount: number,
|
|
438
|
+
sign: S = true as S,
|
|
439
|
+
receiveAddress?: string
|
|
440
|
+
): Promise<ScallopClientFnReturnType<S>> {
|
|
441
|
+
if (!this._isTestnet) {
|
|
442
|
+
throw new Error('Only be used on the test network.');
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const txBlock = this.createTxBlock();
|
|
446
|
+
const recipient = receiveAddress || this.walletAddress;
|
|
447
|
+
const packageId = this.address.get('core.packages.testCoin.id');
|
|
448
|
+
const treasuryId = this.address.get(`core.coins.${coinName}.treasury`);
|
|
449
|
+
const target = `${packageId}::${coinName}::mint`;
|
|
450
|
+
const coin = txBlock.moveCall(target, [treasuryId, amount]);
|
|
451
|
+
txBlock.transferObjects([coin], recipient);
|
|
452
|
+
|
|
453
|
+
if (sign) {
|
|
454
|
+
return (await this.suiKit.signAndSendTxn(
|
|
455
|
+
txBlock
|
|
456
|
+
)) as ScallopClientFnReturnType<S>;
|
|
457
|
+
} else {
|
|
458
|
+
return txBlock.txBlock as ScallopClientFnReturnType<S>;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SUI_FRAMEWORK_ADDRESS,
|
|
3
|
+
SUI_TYPE_ARG,
|
|
4
|
+
normalizeStructTag,
|
|
5
|
+
} from '@mysten/sui.js';
|
|
6
|
+
import { SuiKit } from '@scallop-io/sui-kit';
|
|
7
|
+
import { PriceServiceConnection } from '@pythnetwork/price-service-client';
|
|
8
|
+
import type { ScallopParams, SupportCoins } from '../types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* ### Scallop Utils
|
|
12
|
+
*
|
|
13
|
+
* Integrates some helper functions frequently used in interactions with the Scallop contract.
|
|
14
|
+
*
|
|
15
|
+
* #### Usage
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const utils = new ScallopUtils(<parameters>);
|
|
19
|
+
* utils.<help functions>();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export class ScallopUtils {
|
|
23
|
+
private _suiKit: SuiKit;
|
|
24
|
+
|
|
25
|
+
public constructor(params: ScallopParams) {
|
|
26
|
+
this._suiKit = new SuiKit(params);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @description Select coin id that add up to the given amount as transaction arguments.
|
|
31
|
+
* @param owner The address of the owner.
|
|
32
|
+
* @param amount The amount that is needed for the coin.
|
|
33
|
+
* @param coinType The coin type, default is 0x2::SUI::SUI.
|
|
34
|
+
* @return The selected transaction coin arguments.
|
|
35
|
+
*/
|
|
36
|
+
public async selectCoins(
|
|
37
|
+
owner: string,
|
|
38
|
+
amount: number,
|
|
39
|
+
coinType: string = SUI_TYPE_ARG
|
|
40
|
+
) {
|
|
41
|
+
const coins = await this._suiKit.rpcProvider.selectCoins(
|
|
42
|
+
owner,
|
|
43
|
+
amount,
|
|
44
|
+
coinType
|
|
45
|
+
);
|
|
46
|
+
return coins.map((c) => c.objectId);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @description Fetch price feed VAAs of interest from the Pyth.
|
|
51
|
+
* @param priceIds Array of hex-encoded price ids.
|
|
52
|
+
* @param isTestnet Specify whether it is a test network.
|
|
53
|
+
* @return Array of base64 encoded VAAs.
|
|
54
|
+
*/
|
|
55
|
+
public async getVaas(priceIds: string[], isTestnet?: boolean) {
|
|
56
|
+
const connection = new PriceServiceConnection(
|
|
57
|
+
isTestnet
|
|
58
|
+
? 'https://xc-testnet.pyth.network'
|
|
59
|
+
: 'https://xc-mainnet.pyth.network',
|
|
60
|
+
{
|
|
61
|
+
priceFeedRequestConfig: {
|
|
62
|
+
binary: true,
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
return await connection.getLatestVaas(priceIds);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @description Handle non-standard coins.
|
|
71
|
+
* @param coinPackageId Package id of coin.
|
|
72
|
+
* @param coinName specific support coin name.
|
|
73
|
+
* @return coinType.
|
|
74
|
+
*/
|
|
75
|
+
public parseCoinType(coinPackageId: string, coinName: string) {
|
|
76
|
+
if (coinName === 'sui') return normalizeStructTag(SUI_TYPE_ARG);
|
|
77
|
+
const wormHoleCoins = [
|
|
78
|
+
// USDC
|
|
79
|
+
'0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf',
|
|
80
|
+
// USDT
|
|
81
|
+
'0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c',
|
|
82
|
+
];
|
|
83
|
+
if (wormHoleCoins.includes(coinPackageId)) {
|
|
84
|
+
return `${coinPackageId}::coin::COIN`;
|
|
85
|
+
} else {
|
|
86
|
+
return `${coinPackageId}::${coinName}::${coinName.toUpperCase()}`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @description Handle non-standard coin names.
|
|
92
|
+
* @param coinPackageId Package id of coin.
|
|
93
|
+
* @param coinName specific support coin name.
|
|
94
|
+
* @return coinType.
|
|
95
|
+
*/
|
|
96
|
+
public getCoinNameFromCoinType(coinType: string) {
|
|
97
|
+
const wormHoleCoinTypes = [
|
|
98
|
+
// USDC
|
|
99
|
+
'0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN',
|
|
100
|
+
// USDT
|
|
101
|
+
'0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN',
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
if (coinType === wormHoleCoinTypes[0]) {
|
|
105
|
+
return 'usdc';
|
|
106
|
+
} else if (coinType === wormHoleCoinTypes[1]) {
|
|
107
|
+
return 'usdt';
|
|
108
|
+
} else {
|
|
109
|
+
return coinType.split('::')[2].toLowerCase() as SupportCoins;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @description Handle market coin types.
|
|
115
|
+
*
|
|
116
|
+
* @param coinPackageId Package id of coin.
|
|
117
|
+
* @param protocolPkgId Package id of protocol.
|
|
118
|
+
* @param coinName specific support coin name.
|
|
119
|
+
*
|
|
120
|
+
* @return marketCoinType.
|
|
121
|
+
*/
|
|
122
|
+
public parseMarketCoinType(
|
|
123
|
+
coinPackageId: string,
|
|
124
|
+
protocolPkgId: string,
|
|
125
|
+
coinName: string
|
|
126
|
+
) {
|
|
127
|
+
const coinType = this.parseCoinType(
|
|
128
|
+
coinName === 'sui' ? SUI_FRAMEWORK_ADDRESS : coinPackageId,
|
|
129
|
+
coinName
|
|
130
|
+
);
|
|
131
|
+
return `${protocolPkgId}::reserve::MarketCoin<${coinType}>`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SuiKit, SuiTxBlock } from '@scallop-io/sui-kit';
|
|
2
|
+
import { ScallopAddress } from '../models';
|
|
3
|
+
import { MarketInterface } from '../types';
|
|
4
|
+
|
|
5
|
+
export const queryMarket = async (
|
|
6
|
+
scallopAddress: ScallopAddress,
|
|
7
|
+
suiKit: SuiKit
|
|
8
|
+
) => {
|
|
9
|
+
const packageId = scallopAddress.get('core.packages.query.id');
|
|
10
|
+
const marketId = scallopAddress.get('core.market');
|
|
11
|
+
const txBlock = new SuiTxBlock();
|
|
12
|
+
const queryTarget = `${packageId}::market_query::market_data`;
|
|
13
|
+
txBlock.moveCall(queryTarget, [marketId]);
|
|
14
|
+
const queryResult = await suiKit.inspectTxn(txBlock);
|
|
15
|
+
return queryResult.events[0].parsedJson as MarketInterface;
|
|
16
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SuiKit, SuiTxBlock } from '@scallop-io/sui-kit';
|
|
2
|
+
import { ScallopAddress } from '../models';
|
|
3
|
+
import { ObligationInterface } from '../types';
|
|
4
|
+
|
|
5
|
+
export const queryObligation = async (
|
|
6
|
+
obligationId: string,
|
|
7
|
+
scallopAddress: ScallopAddress,
|
|
8
|
+
suiKit: SuiKit
|
|
9
|
+
) => {
|
|
10
|
+
const packageId = scallopAddress.get('core.packages.query.id');
|
|
11
|
+
const queryTarget = `${packageId}::obligation_query::obligation_data`;
|
|
12
|
+
const txBlock = new SuiTxBlock();
|
|
13
|
+
txBlock.moveCall(queryTarget, [obligationId]);
|
|
14
|
+
const queryResult = await suiKit.inspectTxn(txBlock);
|
|
15
|
+
return queryResult.events[0].parsedJson as ObligationInterface;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getObligations = async (
|
|
19
|
+
ownerAddress: string,
|
|
20
|
+
scallopAddress: ScallopAddress,
|
|
21
|
+
suiKit: SuiKit
|
|
22
|
+
) => {
|
|
23
|
+
const owner = ownerAddress || suiKit.currentAddress();
|
|
24
|
+
const keyObjectRefs = await suiKit.provider().getOwnedObjects({
|
|
25
|
+
owner,
|
|
26
|
+
filter: {
|
|
27
|
+
StructType: `${scallopAddress.get(
|
|
28
|
+
'core.packages.protocol.id'
|
|
29
|
+
)}::obligation::ObligationKey`,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
const keyIds = keyObjectRefs.data
|
|
33
|
+
.map((ref: any) => ref?.data?.objectId)
|
|
34
|
+
.filter((id: any) => id !== undefined) as string[];
|
|
35
|
+
const keyObjects = await suiKit.getObjects(keyIds);
|
|
36
|
+
const obligations: { id: string; keyId: string }[] = [];
|
|
37
|
+
for (const keyObject of keyObjects) {
|
|
38
|
+
const keyId = keyObject.objectId;
|
|
39
|
+
const fields = keyObject.objectFields as any;
|
|
40
|
+
const obligationId = fields['ownership']['fields']['of'];
|
|
41
|
+
obligations.push({ id: obligationId, keyId });
|
|
42
|
+
}
|
|
43
|
+
return obligations;
|
|
44
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { SuiTxBlock } from '@scallop-io/sui-kit';
|
|
2
|
+
import { ScallopAddress, ScallopUtils } from '../models';
|
|
3
|
+
import { SupportCoins } from '../types';
|
|
4
|
+
|
|
5
|
+
export const selectCoin = async (
|
|
6
|
+
txBlock: SuiTxBlock,
|
|
7
|
+
scallopAddress: ScallopAddress,
|
|
8
|
+
scallopUtils: ScallopUtils,
|
|
9
|
+
coinName: SupportCoins,
|
|
10
|
+
amount: number,
|
|
11
|
+
sender: string
|
|
12
|
+
) => {
|
|
13
|
+
const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
|
|
14
|
+
const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
|
|
15
|
+
const coins = await scallopUtils.selectCoins(sender, amount, coinType);
|
|
16
|
+
const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(coins, amount);
|
|
17
|
+
return { takeCoin, leftCoin };
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const selectMarketCoin = async (
|
|
21
|
+
txBlock: SuiTxBlock,
|
|
22
|
+
scallopAddress: ScallopAddress,
|
|
23
|
+
scallopUtils: ScallopUtils,
|
|
24
|
+
coinName: SupportCoins,
|
|
25
|
+
amount: number,
|
|
26
|
+
sender: string
|
|
27
|
+
) => {
|
|
28
|
+
const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
|
|
29
|
+
const protocolPackageId = scallopAddress.get('core.packages.protocol.id');
|
|
30
|
+
const coinType = scallopUtils.parseMarketCoinType(
|
|
31
|
+
coinPackageId,
|
|
32
|
+
protocolPackageId,
|
|
33
|
+
coinName
|
|
34
|
+
);
|
|
35
|
+
const coins = await scallopUtils.selectCoins(sender, amount, coinType);
|
|
36
|
+
const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(coins, amount);
|
|
37
|
+
return { takeCoin, leftCoin };
|
|
38
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { newScallopTxBlock } from './quickMethods';
|