@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.
Files changed (47) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +276 -0
  3. package/dist/constants/common.d.ts +7 -0
  4. package/dist/constants/index.d.ts +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +1487 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.mjs +1444 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/models/index.d.ts +4 -0
  11. package/dist/models/scallop.d.ts +46 -0
  12. package/dist/models/scallopAddress.d.ts +107 -0
  13. package/dist/models/scallopClient.d.ts +151 -0
  14. package/dist/models/scallopUtils.d.ts +56 -0
  15. package/dist/queries/index.d.ts +2 -0
  16. package/dist/queries/market.d.ts +4 -0
  17. package/dist/queries/obligation.d.ts +8 -0
  18. package/dist/txBuilders/coin.d.ts +67 -0
  19. package/dist/txBuilders/index.d.ts +1 -0
  20. package/dist/txBuilders/normalMethods.d.ts +3 -0
  21. package/dist/txBuilders/oracle.d.ts +7 -0
  22. package/dist/txBuilders/quickMethods.d.ts +7 -0
  23. package/dist/types/data.d.ts +127 -0
  24. package/dist/types/index.d.ts +3 -0
  25. package/dist/types/model.d.ts +9 -0
  26. package/dist/types/txBuilder.d.ts +66 -0
  27. package/package.json +147 -0
  28. package/src/constants/common.ts +36 -0
  29. package/src/constants/index.ts +1 -0
  30. package/src/index.ts +3 -0
  31. package/src/models/index.ts +4 -0
  32. package/src/models/scallop.ts +76 -0
  33. package/src/models/scallopAddress.ts +460 -0
  34. package/src/models/scallopClient.ts +461 -0
  35. package/src/models/scallopUtils.ts +133 -0
  36. package/src/queries/index.ts +2 -0
  37. package/src/queries/market.ts +16 -0
  38. package/src/queries/obligation.ts +44 -0
  39. package/src/txBuilders/coin.ts +38 -0
  40. package/src/txBuilders/index.ts +1 -0
  41. package/src/txBuilders/normalMethods.ts +216 -0
  42. package/src/txBuilders/oracle.ts +376 -0
  43. package/src/txBuilders/quickMethods.ts +231 -0
  44. package/src/types/data.ts +170 -0
  45. package/src/types/index.ts +3 -0
  46. package/src/types/model.ts +15 -0
  47. package/src/types/txBuilder.ts +136 -0
package/dist/index.js ADDED
@@ -0,0 +1,1487 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ ADDRESSES_ID: () => ADDRESSES_ID,
34
+ API_BASE_URL: () => API_BASE_URL,
35
+ SUI_COIN_TYPE_ARG_REGEX: () => SUI_COIN_TYPE_ARG_REGEX,
36
+ SUPPORT_ASSET_COINS: () => SUPPORT_ASSET_COINS,
37
+ SUPPORT_COLLATERAL_COINS: () => SUPPORT_COLLATERAL_COINS,
38
+ SUPPORT_ORACLES: () => SUPPORT_ORACLES,
39
+ SUPPORT_PACKAGES: () => SUPPORT_PACKAGES,
40
+ Scallop: () => Scallop,
41
+ ScallopAddress: () => ScallopAddress,
42
+ ScallopClient: () => ScallopClient,
43
+ ScallopUtils: () => ScallopUtils
44
+ });
45
+ module.exports = __toCommonJS(src_exports);
46
+
47
+ // src/constants/common.ts
48
+ var API_BASE_URL = "https://sui.api.scallop.io";
49
+ var ADDRESSES_ID = "6462a088a7ace142bb6d7e9b";
50
+ var SUPPORT_ASSET_COINS = [
51
+ "eth",
52
+ "btc",
53
+ "usdc",
54
+ "usdt",
55
+ "sui"
56
+ ];
57
+ var SUPPORT_COLLATERAL_COINS = [
58
+ "eth",
59
+ "btc",
60
+ "usdc",
61
+ "usdt",
62
+ "sui"
63
+ ];
64
+ var SUPPORT_ORACLES = ["supra", "switchboard", "pyth"];
65
+ var SUPPORT_PACKAGES = [
66
+ "coinDecimalsRegistry",
67
+ "math",
68
+ "whitelist",
69
+ "x",
70
+ "protocol",
71
+ "query",
72
+ "supra",
73
+ "pyth",
74
+ "switchboard",
75
+ "xOracle",
76
+ "testCoin"
77
+ ];
78
+ var SUI_COIN_TYPE_ARG_REGEX = /^0x(0*)2::sui::SUI$/;
79
+
80
+ // src/models/scallop.ts
81
+ var import_sui_kit6 = require("@scallop-io/sui-kit");
82
+
83
+ // src/models/scallopAddress.ts
84
+ var import_axios = __toESM(require("axios"));
85
+ var ScallopAddress = class {
86
+ constructor(params) {
87
+ const { id, auth, network } = params;
88
+ if (auth)
89
+ this._auth = auth;
90
+ this._id = id;
91
+ this._network = network || "mainnet";
92
+ this._addressesMap = /* @__PURE__ */ new Map();
93
+ this._apiClient = import_axios.default.create({
94
+ baseURL: API_BASE_URL,
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ Accept: "application/json"
98
+ },
99
+ timeout: 3e4
100
+ });
101
+ }
102
+ /**
103
+ * Get addresses API id.
104
+ *
105
+ * @returns The addresses API id.
106
+ */
107
+ getId() {
108
+ return this._id;
109
+ }
110
+ /**
111
+ * Get the address at the provided path.
112
+ *
113
+ * @param path - The path of the address to get.
114
+ * @returns The address at the provided path.
115
+ */
116
+ get(path) {
117
+ if (this._addresses) {
118
+ const value = path.split(".").reduce(
119
+ (nestedAddressObj, key) => typeof nestedAddressObj === "object" ? nestedAddressObj[key] : nestedAddressObj,
120
+ this._addresses
121
+ );
122
+ return value || void 0;
123
+ } else {
124
+ return void 0;
125
+ }
126
+ }
127
+ /**
128
+ * Set the address at the provided path.
129
+ *
130
+ * @param path - The path of the address to set.
131
+ * @param address - The address be setted to the tartget path.
132
+ * @returns The addresses.
133
+ */
134
+ set(path, address) {
135
+ if (this._addresses) {
136
+ const keys = path.split(".");
137
+ keys.reduce((nestedAddressObj, key, index) => {
138
+ if (index === keys.length - 1) {
139
+ nestedAddressObj[key] = address;
140
+ } else {
141
+ return nestedAddressObj[key];
142
+ }
143
+ }, this._addresses);
144
+ }
145
+ return this._addresses;
146
+ }
147
+ /**
148
+ * Get the addresses.
149
+ *
150
+ * @param network - Specifies which network's addresses you want to get.
151
+ * @returns The addresses.
152
+ */
153
+ getAddresses(network) {
154
+ if (network) {
155
+ return this._addressesMap.get(network);
156
+ } else {
157
+ return this._addresses;
158
+ }
159
+ }
160
+ /**
161
+ * Set the addresses into addresses map.
162
+ *
163
+ * @param network - Specifies which network's addresses you want to set.
164
+ * @param addresses - The addresses be setted to the tartget network.
165
+ * @returns The addresses.
166
+ */
167
+ setAddresses(network, addresses) {
168
+ const targetNetwork = network || this._network;
169
+ const targetAddresses = addresses || this._addresses || void 0;
170
+ if (targetAddresses) {
171
+ this._addressesMap.set(targetNetwork, targetAddresses);
172
+ } else {
173
+ this._addressesMap.set(targetNetwork, {
174
+ core: {
175
+ version: "",
176
+ versionCap: "",
177
+ market: "",
178
+ adminCap: "",
179
+ coinDecimalsRegistry: "",
180
+ coins: {
181
+ btc: {
182
+ id: "",
183
+ metaData: "",
184
+ treasury: "",
185
+ oracle: {
186
+ supra: "",
187
+ switchboard: "",
188
+ pyth: {
189
+ feed: "",
190
+ feedObject: ""
191
+ }
192
+ }
193
+ },
194
+ eth: {
195
+ id: "",
196
+ metaData: "",
197
+ treasury: "",
198
+ oracle: {
199
+ supra: "",
200
+ switchboard: "",
201
+ pyth: {
202
+ feed: "",
203
+ feedObject: ""
204
+ }
205
+ }
206
+ },
207
+ usdc: {
208
+ id: "",
209
+ metaData: "",
210
+ treasury: "",
211
+ oracle: {
212
+ supra: "",
213
+ switchboard: "",
214
+ pyth: {
215
+ feed: "",
216
+ feedObject: ""
217
+ }
218
+ }
219
+ },
220
+ usdt: {
221
+ id: "",
222
+ metaData: "",
223
+ treasury: "",
224
+ oracle: {
225
+ supra: "",
226
+ switchboard: "",
227
+ pyth: {
228
+ feed: "",
229
+ feedObject: ""
230
+ }
231
+ }
232
+ },
233
+ sui: {
234
+ id: "",
235
+ metaData: "",
236
+ treasury: "",
237
+ oracle: {
238
+ supra: "",
239
+ switchboard: "",
240
+ pyth: {
241
+ feed: "",
242
+ feedObject: ""
243
+ }
244
+ }
245
+ }
246
+ },
247
+ oracles: {
248
+ xOracle: "",
249
+ xOracleCap: "",
250
+ supra: {
251
+ registry: "",
252
+ registryCap: "",
253
+ holder: ""
254
+ },
255
+ switchboard: {
256
+ registry: "",
257
+ registryCap: ""
258
+ },
259
+ pyth: {
260
+ registry: "",
261
+ registryCap: "",
262
+ state: "",
263
+ wormhole: "",
264
+ wormholeState: ""
265
+ }
266
+ },
267
+ packages: {
268
+ coinDecimalsRegistry: {
269
+ id: "",
270
+ upgradeCap: ""
271
+ },
272
+ math: {
273
+ id: "",
274
+ upgradeCap: ""
275
+ },
276
+ whitelist: {
277
+ id: "",
278
+ upgradeCap: ""
279
+ },
280
+ x: {
281
+ id: "",
282
+ upgradeCap: ""
283
+ },
284
+ protocol: {
285
+ id: "",
286
+ upgradeCap: ""
287
+ },
288
+ query: {
289
+ id: "",
290
+ upgradeCap: ""
291
+ },
292
+ // Deploy by pyth on testnet
293
+ pyth: {
294
+ id: "",
295
+ upgradeCap: ""
296
+ },
297
+ // Deploy by ourself on testnet
298
+ switchboard: {
299
+ id: "",
300
+ upgradeCap: ""
301
+ },
302
+ xOracle: {
303
+ id: "",
304
+ upgradeCap: ""
305
+ },
306
+ // Deploy for faucet on testnet
307
+ testCoin: {
308
+ id: "",
309
+ upgradeCap: ""
310
+ }
311
+ }
312
+ }
313
+ });
314
+ }
315
+ }
316
+ /**
317
+ * Get all addresses.
318
+ *
319
+ * @returns All addresses.
320
+ */
321
+ getAllAddresses() {
322
+ return Object.fromEntries(this._addressesMap);
323
+ }
324
+ /**
325
+ * Create a new address through the API and synchronize it back to the
326
+ * instance. If the `network` is not specified, the mainnet is used by default.
327
+ * If no `addresses` is provided, an addresses with all empty strings is created
328
+ * by default.
329
+ *
330
+ * This function only allows for one addresses to be input into a specific network
331
+ * at a time, and does not provide an addresses map for setting addresses
332
+ * across all networks at once.
333
+ *
334
+ * @param network - Specifies which network's addresses you want to set.
335
+ * @param addresses - The addresses be setted to the tartget network.
336
+ * @param auth - The authentication API key.
337
+ * @returns The addresses.
338
+ */
339
+ async create(network, addresses, auth) {
340
+ const apiKey = auth || this._auth || void 0;
341
+ const targetNetwork = network || this._network;
342
+ const targetAddresses = addresses || this._addresses || void 0;
343
+ if (apiKey !== void 0) {
344
+ this._addressesMap.clear();
345
+ this.setAddresses(targetNetwork, targetAddresses);
346
+ const response = await this._apiClient.post(
347
+ `${API_BASE_URL}/addresses`,
348
+ JSON.stringify(Object.fromEntries(this._addressesMap)),
349
+ {
350
+ headers: {
351
+ "Content-Type": "application/json",
352
+ "api-key": auth || this._auth
353
+ }
354
+ }
355
+ );
356
+ if (response.status === 201) {
357
+ for (const [network2, addresses2] of Object.entries(
358
+ response.data
359
+ )) {
360
+ if (["localnet", "devnet", "testnet", "mainnet"].includes(network2)) {
361
+ if (network2 === this._network)
362
+ this._addresses = addresses2;
363
+ this._addressesMap.set(network2, addresses2);
364
+ }
365
+ }
366
+ this._id = response.data.id;
367
+ return this._addresses;
368
+ } else {
369
+ throw Error("Failed to create addresses.");
370
+ }
371
+ } else {
372
+ throw Error("You don't have permission to access this request.");
373
+ }
374
+ }
375
+ /**
376
+ * It doesn't read the data stored in the address instance, but reads and
377
+ * synchronizes the data from the API into instance.
378
+ *
379
+ * @param id - The id of the addresses to get.
380
+ * @returns The addresses.
381
+ */
382
+ async read(id) {
383
+ const addressesId = id || this._id || void 0;
384
+ if (addressesId !== void 0) {
385
+ const response = await this._apiClient.get(
386
+ `${API_BASE_URL}/addresses/${addressesId}`,
387
+ {
388
+ headers: {
389
+ "Content-Type": "application/json"
390
+ }
391
+ }
392
+ );
393
+ if (response.status === 200) {
394
+ for (const [network, addresses] of Object.entries(
395
+ response.data
396
+ )) {
397
+ if (["localnet", "devnet", "testnet", "mainnet"].includes(network)) {
398
+ if (network === this._network)
399
+ this._addresses = addresses;
400
+ this._addressesMap.set(network, addresses);
401
+ }
402
+ }
403
+ this._id = response.data.id;
404
+ return this._addresses;
405
+ } else {
406
+ throw Error("Failed to create addresses.");
407
+ }
408
+ }
409
+ }
410
+ /**
411
+ * Update the address through the API and synchronize it back to the
412
+ * instance. If the `network` is not specified, the mainnet is used by default.
413
+ * If no `addresses` is provided, an addresses with all empty strings is created
414
+ * by default.
415
+ *
416
+ * This function only allows for one addresses to be input into a specific network
417
+ * at a time, and does not provide an addresses map for setting addresses
418
+ * across all networks at once.
419
+ *
420
+ * @param id - The id of the addresses to update.
421
+ * @param network - Specifies which network's addresses you want to set.
422
+ * @param addresses - The addresses be setted to the tartget network.
423
+ * @param auth - The authentication api key.
424
+ * @returns The addresses.
425
+ */
426
+ async update(id, network, addresses, auth) {
427
+ const apiKey = auth || this._auth || void 0;
428
+ const targetId = id || this._id || void 0;
429
+ const targetNetwork = network || this._network;
430
+ const targetAddresses = addresses || this._addresses || void 0;
431
+ if (targetId === void 0)
432
+ throw Error("Require addresses id.");
433
+ if (apiKey !== void 0) {
434
+ if (id !== this._id) {
435
+ this._addressesMap.clear();
436
+ }
437
+ this.setAddresses(targetNetwork, targetAddresses);
438
+ const response = await this._apiClient.put(
439
+ `${API_BASE_URL}/addresses/${targetId}`,
440
+ JSON.stringify(Object.fromEntries(this._addressesMap)),
441
+ {
442
+ headers: {
443
+ "Content-Type": "application/json",
444
+ "api-key": auth || this._auth
445
+ }
446
+ }
447
+ );
448
+ if (response.status === 200) {
449
+ for (const [network2, addresses2] of Object.entries(
450
+ response.data
451
+ )) {
452
+ if (["localnet", "devnet", "testnet", "mainnet"].includes(network2)) {
453
+ if (network2 === this._network)
454
+ this._addresses = addresses2;
455
+ this._addressesMap.set(network2, addresses2);
456
+ }
457
+ }
458
+ this._id = response.data.id;
459
+ return this._addresses;
460
+ } else {
461
+ throw Error("Failed to update addresses.");
462
+ }
463
+ } else {
464
+ throw Error("You don't have permission to access this request.");
465
+ }
466
+ }
467
+ /**
468
+ * Deletes all addresses of a specified id through the API and synchronizes
469
+ * them back to the instance.
470
+ *
471
+ * @param id - The id of the addresses to delete.
472
+ * @param auth - The authentication API key.
473
+ */
474
+ async delete(id, auth) {
475
+ const apiKey = auth || this._auth || void 0;
476
+ const targetId = id || this._id || void 0;
477
+ if (targetId === void 0)
478
+ throw Error("Require addresses id.");
479
+ if (apiKey !== void 0) {
480
+ const response = await this._apiClient.delete(
481
+ `${API_BASE_URL}/addresses/${targetId}`,
482
+ {
483
+ headers: {
484
+ "Content-Type": "application/json",
485
+ "api-key": auth || this._auth
486
+ }
487
+ }
488
+ );
489
+ if (response.status === 200) {
490
+ this._id = void 0;
491
+ this._addresses = void 0;
492
+ this._addressesMap.clear();
493
+ } else {
494
+ throw Error("Failed to delete addresses.");
495
+ }
496
+ } else {
497
+ throw Error("You don't have permission to access this request.");
498
+ }
499
+ }
500
+ };
501
+
502
+ // src/models/scallopClient.ts
503
+ var import_sui4 = require("@mysten/sui.js");
504
+ var import_sui_kit5 = require("@scallop-io/sui-kit");
505
+
506
+ // src/models/scallopUtils.ts
507
+ var import_sui = require("@mysten/sui.js");
508
+ var import_sui_kit = require("@scallop-io/sui-kit");
509
+ var import_price_service_client = require("@pythnetwork/price-service-client");
510
+ var ScallopUtils = class {
511
+ constructor(params) {
512
+ this._suiKit = new import_sui_kit.SuiKit(params);
513
+ }
514
+ /**
515
+ * @description Select coin id that add up to the given amount as transaction arguments.
516
+ * @param owner The address of the owner.
517
+ * @param amount The amount that is needed for the coin.
518
+ * @param coinType The coin type, default is 0x2::SUI::SUI.
519
+ * @return The selected transaction coin arguments.
520
+ */
521
+ async selectCoins(owner, amount, coinType = import_sui.SUI_TYPE_ARG) {
522
+ const coins = await this._suiKit.rpcProvider.selectCoins(
523
+ owner,
524
+ amount,
525
+ coinType
526
+ );
527
+ return coins.map((c) => c.objectId);
528
+ }
529
+ /**
530
+ * @description Fetch price feed VAAs of interest from the Pyth.
531
+ * @param priceIds Array of hex-encoded price ids.
532
+ * @param isTestnet Specify whether it is a test network.
533
+ * @return Array of base64 encoded VAAs.
534
+ */
535
+ async getVaas(priceIds, isTestnet) {
536
+ const connection = new import_price_service_client.PriceServiceConnection(
537
+ isTestnet ? "https://xc-testnet.pyth.network" : "https://xc-mainnet.pyth.network",
538
+ {
539
+ priceFeedRequestConfig: {
540
+ binary: true
541
+ }
542
+ }
543
+ );
544
+ return await connection.getLatestVaas(priceIds);
545
+ }
546
+ /**
547
+ * @description Handle non-standard coins.
548
+ * @param coinPackageId Package id of coin.
549
+ * @param coinName specific support coin name.
550
+ * @return coinType.
551
+ */
552
+ parseCoinType(coinPackageId, coinName) {
553
+ if (coinName === "sui")
554
+ return (0, import_sui.normalizeStructTag)(import_sui.SUI_TYPE_ARG);
555
+ const wormHoleCoins = [
556
+ // USDC
557
+ "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf",
558
+ // USDT
559
+ "0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c"
560
+ ];
561
+ if (wormHoleCoins.includes(coinPackageId)) {
562
+ return `${coinPackageId}::coin::COIN`;
563
+ } else {
564
+ return `${coinPackageId}::${coinName}::${coinName.toUpperCase()}`;
565
+ }
566
+ }
567
+ /**
568
+ * @description Handle non-standard coin names.
569
+ * @param coinPackageId Package id of coin.
570
+ * @param coinName specific support coin name.
571
+ * @return coinType.
572
+ */
573
+ getCoinNameFromCoinType(coinType) {
574
+ const wormHoleCoinTypes = [
575
+ // USDC
576
+ "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN",
577
+ // USDT
578
+ "0xc060006111016b8a020ad5b33834984a437aaa7d3c74c18e09a95d48aceab08c::coin::COIN"
579
+ ];
580
+ if (coinType === wormHoleCoinTypes[0]) {
581
+ return "usdc";
582
+ } else if (coinType === wormHoleCoinTypes[1]) {
583
+ return "usdt";
584
+ } else {
585
+ return coinType.split("::")[2].toLowerCase();
586
+ }
587
+ }
588
+ /**
589
+ * @description Handle market coin types.
590
+ *
591
+ * @param coinPackageId Package id of coin.
592
+ * @param protocolPkgId Package id of protocol.
593
+ * @param coinName specific support coin name.
594
+ *
595
+ * @return marketCoinType.
596
+ */
597
+ parseMarketCoinType(coinPackageId, protocolPkgId, coinName) {
598
+ const coinType = this.parseCoinType(
599
+ coinName === "sui" ? import_sui.SUI_FRAMEWORK_ADDRESS : coinPackageId,
600
+ coinName
601
+ );
602
+ return `${protocolPkgId}::reserve::MarketCoin<${coinType}>`;
603
+ }
604
+ };
605
+
606
+ // src/queries/market.ts
607
+ var import_sui_kit2 = require("@scallop-io/sui-kit");
608
+ var queryMarket = async (scallopAddress, suiKit) => {
609
+ const packageId = scallopAddress.get("core.packages.query.id");
610
+ const marketId = scallopAddress.get("core.market");
611
+ const txBlock = new import_sui_kit2.SuiTxBlock();
612
+ const queryTarget = `${packageId}::market_query::market_data`;
613
+ txBlock.moveCall(queryTarget, [marketId]);
614
+ const queryResult = await suiKit.inspectTxn(txBlock);
615
+ return queryResult.events[0].parsedJson;
616
+ };
617
+
618
+ // src/queries/obligation.ts
619
+ var import_sui_kit3 = require("@scallop-io/sui-kit");
620
+ var queryObligation = async (obligationId, scallopAddress, suiKit) => {
621
+ const packageId = scallopAddress.get("core.packages.query.id");
622
+ const queryTarget = `${packageId}::obligation_query::obligation_data`;
623
+ const txBlock = new import_sui_kit3.SuiTxBlock();
624
+ txBlock.moveCall(queryTarget, [obligationId]);
625
+ const queryResult = await suiKit.inspectTxn(txBlock);
626
+ return queryResult.events[0].parsedJson;
627
+ };
628
+ var getObligations = async (ownerAddress, scallopAddress, suiKit) => {
629
+ const owner = ownerAddress || suiKit.currentAddress();
630
+ const keyObjectRefs = await suiKit.provider().getOwnedObjects({
631
+ owner,
632
+ filter: {
633
+ StructType: `${scallopAddress.get(
634
+ "core.packages.protocol.id"
635
+ )}::obligation::ObligationKey`
636
+ }
637
+ });
638
+ const keyIds = keyObjectRefs.data.map((ref) => ref?.data?.objectId).filter((id) => id !== void 0);
639
+ const keyObjects = await suiKit.getObjects(keyIds);
640
+ const obligations = [];
641
+ for (const keyObject of keyObjects) {
642
+ const keyId = keyObject.objectId;
643
+ const fields = keyObject.objectFields;
644
+ const obligationId = fields["ownership"]["fields"]["of"];
645
+ obligations.push({ id: obligationId, keyId });
646
+ }
647
+ return obligations;
648
+ };
649
+
650
+ // src/txBuilders/normalMethods.ts
651
+ var import_sui2 = require("@mysten/sui.js");
652
+ var import_sui_kit4 = require("@scallop-io/sui-kit");
653
+ var scallopNormalMethodsHandler = {
654
+ openObligation: ({ txBlock, coreIds }) => () => txBlock.moveCall(
655
+ `${coreIds.protocolPkg}::open_obligation::open_obligation`,
656
+ [coreIds.version]
657
+ ),
658
+ returnObligation: ({ txBlock, coreIds }) => (obligation, obligationHotPotato) => txBlock.moveCall(
659
+ `${coreIds.protocolPkg}::open_obligation::return_obligation`,
660
+ [coreIds.version, obligation, obligationHotPotato]
661
+ ),
662
+ openObligationEntry: ({ txBlock, coreIds }) => () => txBlock.moveCall(
663
+ `${coreIds.protocolPkg}::open_obligation::open_obligation_entry`,
664
+ [coreIds.version]
665
+ ),
666
+ addCollateral: ({ txBlock, coreIds, scallopUtils, scallopAddress }) => (obligation, coin, coinName) => {
667
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
668
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
669
+ return txBlock.moveCall(
670
+ `${coreIds.protocolPkg}::deposit_collateral::deposit_collateral`,
671
+ [coreIds.version, obligation, coreIds.market, coin],
672
+ [coinType]
673
+ );
674
+ },
675
+ takeCollateral: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (obligation, obligationKey, amount, coinName) => {
676
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
677
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
678
+ return txBlock.moveCall(
679
+ `${coreIds.protocolPkg}::withdraw_collateral::withdraw_collateral`,
680
+ [
681
+ coreIds.version,
682
+ obligation,
683
+ obligationKey,
684
+ coreIds.market,
685
+ coreIds.dmlR,
686
+ amount,
687
+ coreIds.oracle,
688
+ import_sui2.SUI_CLOCK_OBJECT_ID
689
+ ],
690
+ [coinType]
691
+ );
692
+ },
693
+ deposit: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (coin, coinName) => {
694
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
695
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
696
+ return txBlock.moveCall(
697
+ `${coreIds.protocolPkg}::mint::mint`,
698
+ [coreIds.version, coreIds.market, coin, import_sui2.SUI_CLOCK_OBJECT_ID],
699
+ [coinType]
700
+ );
701
+ },
702
+ depositEntry: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (coin, coinName) => {
703
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
704
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
705
+ return txBlock.moveCall(
706
+ `${coreIds.protocolPkg}::mint::mint_entry`,
707
+ [coreIds.version, coreIds.market, coin, import_sui2.SUI_CLOCK_OBJECT_ID],
708
+ [coinType]
709
+ );
710
+ },
711
+ withdraw: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (marketCoin, coinName) => {
712
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
713
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
714
+ return txBlock.moveCall(
715
+ `${coreIds.protocolPkg}::redeem::redeem`,
716
+ [coreIds.version, coreIds.market, marketCoin, import_sui2.SUI_CLOCK_OBJECT_ID],
717
+ [coinType]
718
+ );
719
+ },
720
+ withdrawEntry: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (marketCoin, coinName) => {
721
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
722
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
723
+ return txBlock.moveCall(
724
+ `${coreIds.protocolPkg}::redeem::redeem_entry`,
725
+ [coreIds.version, coreIds.market, marketCoin, import_sui2.SUI_CLOCK_OBJECT_ID],
726
+ [coinType]
727
+ );
728
+ },
729
+ borrow: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (obligation, obligationKey, amount, coinName) => {
730
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
731
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
732
+ return txBlock.moveCall(
733
+ `${coreIds.protocolPkg}::borrow::borrow`,
734
+ [
735
+ coreIds.version,
736
+ obligation,
737
+ obligationKey,
738
+ coreIds.market,
739
+ coreIds.dmlR,
740
+ amount,
741
+ coreIds.oracle,
742
+ import_sui2.SUI_CLOCK_OBJECT_ID
743
+ ],
744
+ [coinType]
745
+ );
746
+ },
747
+ borrowEntry: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (obligation, obligationKey, amount, coinName) => {
748
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
749
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
750
+ return txBlock.moveCall(
751
+ `${coreIds.protocolPkg}::borrow::borrow_entry`,
752
+ [
753
+ coreIds.version,
754
+ obligation,
755
+ obligationKey,
756
+ coreIds.market,
757
+ coreIds.dmlR,
758
+ amount,
759
+ coreIds.oracle,
760
+ import_sui2.SUI_CLOCK_OBJECT_ID
761
+ ],
762
+ [coinType]
763
+ );
764
+ },
765
+ repay: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (obligation, coin, coinName) => {
766
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
767
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
768
+ return txBlock.moveCall(
769
+ `${coreIds.protocolPkg}::repay::repay`,
770
+ [
771
+ coreIds.version,
772
+ obligation,
773
+ coreIds.market,
774
+ coin,
775
+ import_sui2.SUI_CLOCK_OBJECT_ID
776
+ ],
777
+ [coinType]
778
+ );
779
+ },
780
+ borrowFlashLoan: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (amount, coinName) => {
781
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
782
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
783
+ return txBlock.moveCall(
784
+ `${coreIds.protocolPkg}::flash_loan::borrow_flash_loan`,
785
+ [coreIds.version, coreIds.market, amount],
786
+ [coinType]
787
+ );
788
+ },
789
+ repayFlashLoan: ({ txBlock, coreIds, scallopAddress, scallopUtils }) => (coin, loan, coinName) => {
790
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
791
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
792
+ return txBlock.moveCall(
793
+ `${coreIds.protocolPkg}::flash_loan::repay_flash_loan`,
794
+ [coreIds.version, coreIds.market, coin, loan],
795
+ [coinType]
796
+ );
797
+ }
798
+ };
799
+ var newTxBlock = (scallopAddress, scallopUtils) => {
800
+ const coreIds = {
801
+ protocolPkg: scallopAddress.get("core.packages.protocol.id"),
802
+ market: scallopAddress.get("core.market"),
803
+ version: scallopAddress.get("core.version"),
804
+ dmlR: scallopAddress.get("core.coinDecimalsRegistry"),
805
+ oracle: scallopAddress.get("core.oracles.xOracle")
806
+ };
807
+ const txBlock = new import_sui_kit4.SuiTxBlock();
808
+ const txBlockProxy = new Proxy(txBlock, {
809
+ get: (target, prop) => {
810
+ if (prop in scallopNormalMethodsHandler) {
811
+ return scallopNormalMethodsHandler[prop]({
812
+ txBlock: target,
813
+ coreIds,
814
+ scallopAddress,
815
+ scallopUtils
816
+ });
817
+ }
818
+ return target[prop];
819
+ }
820
+ });
821
+ return txBlockProxy;
822
+ };
823
+
824
+ // src/txBuilders/oracle.ts
825
+ var import_bcs = require("@mysten/bcs");
826
+ var import_sui3 = require("@mysten/sui.js");
827
+ var updateOraclesForWithdrawCollateral = async (txBlock, address, scallopUtils, suiKit, obligationId, isTestnet) => {
828
+ const obligationCoinNames = await getObligationCoinNames(
829
+ suiKit,
830
+ obligationId,
831
+ address,
832
+ scallopUtils
833
+ );
834
+ return updateOracles(
835
+ txBlock,
836
+ address,
837
+ scallopUtils,
838
+ obligationCoinNames,
839
+ isTestnet
840
+ );
841
+ };
842
+ var updateOraclesForBorrow = async (txBlock, address, scallopUtils, suiKit, obligationId, borrowCoinName, isTestnet) => {
843
+ const obligationCoinNames = await getObligationCoinNames(
844
+ suiKit,
845
+ obligationId,
846
+ address,
847
+ scallopUtils
848
+ );
849
+ const updateCoinNames = [
850
+ .../* @__PURE__ */ new Set([...obligationCoinNames, borrowCoinName])
851
+ ];
852
+ return updateOracles(
853
+ txBlock,
854
+ address,
855
+ scallopUtils,
856
+ updateCoinNames,
857
+ isTestnet
858
+ );
859
+ };
860
+ var getObligationCoinNames = async (suiKit, obligationId, address, scallopUtils) => {
861
+ const obligation = await queryObligation(obligationId, address, suiKit);
862
+ const collateralCoinTypes = obligation.collaterals.map((collateral) => {
863
+ return `0x${collateral.type.name}`;
864
+ });
865
+ const debtCoinTypes = obligation.debts.map((debt) => {
866
+ return `0x${debt.type.name}`;
867
+ });
868
+ const obligationCoinTypes = [
869
+ .../* @__PURE__ */ new Set([...collateralCoinTypes, ...debtCoinTypes])
870
+ ];
871
+ const obligationCoinNames = obligationCoinTypes.map((coinType) => {
872
+ return scallopUtils.getCoinNameFromCoinType(coinType);
873
+ });
874
+ return obligationCoinNames;
875
+ };
876
+ var updateOracles = async (txBlock, address, scallopUtils, coinNames, isTestnet) => {
877
+ const updateCoinTypes = [...new Set(coinNames)];
878
+ for (const coinName of updateCoinTypes) {
879
+ await updateOracle(txBlock, address, scallopUtils, coinName, isTestnet);
880
+ }
881
+ };
882
+ var updateOracle = async (txBlock, address, scallopUtils, coinName, isTestnet) => {
883
+ const coinPackageId = address.get(`core.coins.${coinName}.id`);
884
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
885
+ const [vaaFromFeeId] = await scallopUtils.getVaas(
886
+ [address.get(`core.coins.${coinName}.oracle.pyth.feed`)],
887
+ isTestnet
888
+ );
889
+ updatePrice(
890
+ txBlock,
891
+ isTestnet ? ["pyth"] : ["pyth"],
892
+ address.get("core.packages.xOracle.id"),
893
+ address.get("core.oracles.xOracle"),
894
+ address.get("core.packages.pyth.id"),
895
+ address.get("core.oracles.pyth.registry"),
896
+ address.get("core.oracles.pyth.state"),
897
+ address.get("core.oracles.pyth.wormholeState"),
898
+ address.get(`core.coins.${coinName}.oracle.pyth.feedObject`),
899
+ vaaFromFeeId,
900
+ address.get("core.packages.switchboard.id"),
901
+ address.get("core.oracles.switchboard.registry"),
902
+ address.get(`core.coins.${coinName}.oracle.switchboard`),
903
+ address.get("core.packages.supra.id"),
904
+ address.get("core.oracles.supra.registry"),
905
+ address.get(`core.oracles.supra.holder`),
906
+ coinType
907
+ );
908
+ };
909
+ function updatePrice(txBlock, rules, xOraclePackageId, xOracleId, pythPackageId, pythRegistryId, pythStateId, pythWormholeStateId, pythFeedObjectId, pythVaaFromFeeId, switchboardPackageId, switchboardRegistryId, switchboardAggregatorId, supraPackageId, supraRegistryId, supraHolderId, coinType) {
910
+ const request = priceUpdateRequest(
911
+ txBlock,
912
+ xOraclePackageId,
913
+ xOracleId,
914
+ coinType
915
+ );
916
+ if (rules.includes("pyth")) {
917
+ updatePythPrice(
918
+ txBlock,
919
+ pythPackageId,
920
+ request,
921
+ pythStateId,
922
+ pythWormholeStateId,
923
+ pythFeedObjectId,
924
+ pythVaaFromFeeId,
925
+ pythRegistryId,
926
+ coinType
927
+ );
928
+ }
929
+ if (rules.includes("switchboard")) {
930
+ updateSwitchboardPrice(
931
+ txBlock,
932
+ switchboardPackageId,
933
+ request,
934
+ switchboardAggregatorId,
935
+ switchboardRegistryId,
936
+ coinType
937
+ );
938
+ }
939
+ if (rules.includes("supra")) {
940
+ updateSupraPrice(
941
+ txBlock,
942
+ supraPackageId,
943
+ request,
944
+ supraHolderId,
945
+ supraRegistryId,
946
+ coinType
947
+ );
948
+ }
949
+ confirmPriceUpdateRequest(
950
+ txBlock,
951
+ xOraclePackageId,
952
+ xOracleId,
953
+ request,
954
+ coinType
955
+ );
956
+ return txBlock;
957
+ }
958
+ function priceUpdateRequest(txBlock, packageId, xOracleId, coinType) {
959
+ const target = `${packageId}::x_oracle::price_update_request`;
960
+ const typeArgs = [coinType];
961
+ return txBlock.moveCall(target, [xOracleId], typeArgs);
962
+ }
963
+ function confirmPriceUpdateRequest(txBlock, packageId, xOracleId, request, coinType) {
964
+ const target = `${packageId}::x_oracle::confirm_price_update_request`;
965
+ const typeArgs = [coinType];
966
+ txBlock.moveCall(target, [xOracleId, request, import_sui3.SUI_CLOCK_OBJECT_ID], typeArgs);
967
+ return txBlock;
968
+ }
969
+ function updateSupraPrice(txBlock, packageId, request, holderId, registryId, coinType) {
970
+ txBlock.moveCall(
971
+ `${packageId}::rule::set_price`,
972
+ [request, holderId, registryId, import_sui3.SUI_CLOCK_OBJECT_ID],
973
+ [coinType]
974
+ );
975
+ }
976
+ function updateSwitchboardPrice(txBlock, packageId, request, aggregatorId, registryId, coinType) {
977
+ txBlock.moveCall(
978
+ `${packageId}::rule::set_price`,
979
+ [request, aggregatorId, registryId, import_sui3.SUI_CLOCK_OBJECT_ID],
980
+ [coinType]
981
+ );
982
+ }
983
+ function updatePythPrice(txBlock, packageId, request, stateId, wormholeStateId, feedObjectId, vaaFromFeeId, registryId, coinType) {
984
+ const [updateFee] = txBlock.splitSUIFromGas([1]);
985
+ txBlock.moveCall(
986
+ `${packageId}::rule::set_price`,
987
+ [
988
+ request,
989
+ wormholeStateId,
990
+ stateId,
991
+ feedObjectId,
992
+ registryId,
993
+ txBlock.pure([...(0, import_bcs.fromB64)(vaaFromFeeId)]),
994
+ updateFee,
995
+ import_sui3.SUI_CLOCK_OBJECT_ID
996
+ ],
997
+ [coinType]
998
+ );
999
+ }
1000
+
1001
+ // src/txBuilders/coin.ts
1002
+ var selectCoin = async (txBlock, scallopAddress, scallopUtils, coinName, amount, sender) => {
1003
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
1004
+ const coinType = scallopUtils.parseCoinType(coinPackageId, coinName);
1005
+ const coins = await scallopUtils.selectCoins(sender, amount, coinType);
1006
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(coins, amount);
1007
+ return { takeCoin, leftCoin };
1008
+ };
1009
+ var selectMarketCoin = async (txBlock, scallopAddress, scallopUtils, coinName, amount, sender) => {
1010
+ const coinPackageId = scallopAddress.get(`core.coins.${coinName}.id`);
1011
+ const protocolPackageId = scallopAddress.get("core.packages.protocol.id");
1012
+ const coinType = scallopUtils.parseMarketCoinType(
1013
+ coinPackageId,
1014
+ protocolPackageId,
1015
+ coinName
1016
+ );
1017
+ const coins = await scallopUtils.selectCoins(sender, amount, coinType);
1018
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(coins, amount);
1019
+ return { takeCoin, leftCoin };
1020
+ };
1021
+
1022
+ // src/txBuilders/quickMethods.ts
1023
+ var requireSender = (txBlock) => {
1024
+ const sender = txBlock.blockData.sender;
1025
+ if (!sender) {
1026
+ throw new Error("Sender is required");
1027
+ }
1028
+ return sender;
1029
+ };
1030
+ var requireObligationInfo = async (...args) => {
1031
+ const [txBlock, scallopAddress, suiKit, obligationId, obligationKey] = args;
1032
+ if (args.length === 4 && obligationId)
1033
+ return { obligationId };
1034
+ if (args.length === 5 && obligationId && obligationKey)
1035
+ return { obligationId, obligationKey };
1036
+ const sender = requireSender(txBlock);
1037
+ const obligations = await getObligations(sender, scallopAddress, suiKit);
1038
+ if (obligations.length === 0) {
1039
+ throw new Error(`No obligation found for sender ${sender}`);
1040
+ }
1041
+ return {
1042
+ obligationId: obligations[0].id,
1043
+ obligationKey: obligations[0].keyId
1044
+ };
1045
+ };
1046
+ var scallopQuickMethodsHandler = {
1047
+ addCollateralQuick: ({ txBlock, scallopAddress, scallopUtils, suiKit }) => async (amount, coinName, obligationId) => {
1048
+ const sender = requireSender(txBlock);
1049
+ const { obligationId: obligationArg } = await requireObligationInfo(
1050
+ txBlock,
1051
+ scallopAddress,
1052
+ suiKit,
1053
+ obligationId
1054
+ );
1055
+ if (coinName === "sui") {
1056
+ const [suiCoin] = txBlock.splitSUIFromGas([amount]);
1057
+ txBlock.addCollateral(obligationArg, suiCoin, coinName);
1058
+ } else {
1059
+ const { leftCoin, takeCoin } = await selectCoin(
1060
+ txBlock,
1061
+ scallopAddress,
1062
+ scallopUtils,
1063
+ coinName,
1064
+ amount,
1065
+ sender
1066
+ );
1067
+ txBlock.addCollateral(obligationArg, takeCoin, coinName);
1068
+ txBlock.transferObjects([leftCoin], sender);
1069
+ }
1070
+ },
1071
+ takeCollateralQuick: ({ txBlock, suiKit, scallopUtils, scallopAddress, isTestnet }) => async (amount, coinName, obligationId, obligationKey) => {
1072
+ const { obligationId: obligationArg, obligationKey: obligationKeyArg } = await requireObligationInfo(
1073
+ txBlock,
1074
+ scallopAddress,
1075
+ suiKit,
1076
+ obligationId,
1077
+ obligationKey
1078
+ );
1079
+ await updateOraclesForWithdrawCollateral(
1080
+ txBlock,
1081
+ scallopAddress,
1082
+ scallopUtils,
1083
+ suiKit,
1084
+ obligationArg,
1085
+ isTestnet
1086
+ );
1087
+ return txBlock.takeCollateral(
1088
+ obligationArg,
1089
+ obligationKeyArg,
1090
+ amount,
1091
+ coinName
1092
+ );
1093
+ },
1094
+ depositQuick: ({ txBlock, scallopUtils, scallopAddress }) => async (amount, coinName) => {
1095
+ const sender = requireSender(txBlock);
1096
+ if (coinName === "sui") {
1097
+ const [suiCoin] = txBlock.splitSUIFromGas([amount]);
1098
+ return txBlock.deposit(suiCoin, coinName);
1099
+ } else {
1100
+ const { leftCoin, takeCoin } = await selectCoin(
1101
+ txBlock,
1102
+ scallopAddress,
1103
+ scallopUtils,
1104
+ coinName,
1105
+ amount,
1106
+ sender
1107
+ );
1108
+ txBlock.transferObjects([leftCoin], sender);
1109
+ return txBlock.deposit(takeCoin, coinName);
1110
+ }
1111
+ },
1112
+ withdrawQuick: ({ txBlock, scallopUtils, scallopAddress }) => async (amount, coinName) => {
1113
+ const sender = requireSender(txBlock);
1114
+ const { leftCoin, takeCoin } = await selectMarketCoin(
1115
+ txBlock,
1116
+ scallopAddress,
1117
+ scallopUtils,
1118
+ coinName,
1119
+ amount,
1120
+ sender
1121
+ );
1122
+ txBlock.transferObjects([leftCoin], sender);
1123
+ return txBlock.withdraw(takeCoin, coinName);
1124
+ },
1125
+ borrowQuick: ({ txBlock, suiKit, scallopUtils, scallopAddress, isTestnet }) => async (amount, coinName, obligationId, obligationKey) => {
1126
+ const { obligationId: obligationArg, obligationKey: obligationKeyArg } = await requireObligationInfo(
1127
+ txBlock,
1128
+ scallopAddress,
1129
+ suiKit,
1130
+ obligationId,
1131
+ obligationKey
1132
+ );
1133
+ await updateOraclesForBorrow(
1134
+ txBlock,
1135
+ scallopAddress,
1136
+ scallopUtils,
1137
+ suiKit,
1138
+ obligationArg,
1139
+ coinName,
1140
+ isTestnet
1141
+ );
1142
+ return txBlock.borrow(
1143
+ obligationArg,
1144
+ obligationKeyArg,
1145
+ amount,
1146
+ coinName
1147
+ );
1148
+ },
1149
+ repayQuick: ({ txBlock, suiKit, scallopUtils, scallopAddress }) => async (amount, coinName, obligationId) => {
1150
+ const sender = requireSender(txBlock);
1151
+ const { obligationId: obligationArg } = await requireObligationInfo(
1152
+ txBlock,
1153
+ scallopAddress,
1154
+ suiKit,
1155
+ obligationId
1156
+ );
1157
+ if (coinName === "sui") {
1158
+ const [suiCoin] = txBlock.splitSUIFromGas([amount]);
1159
+ return txBlock.repay(obligationArg, suiCoin, coinName);
1160
+ } else {
1161
+ const { leftCoin, takeCoin } = await selectCoin(
1162
+ txBlock,
1163
+ scallopAddress,
1164
+ scallopUtils,
1165
+ coinName,
1166
+ amount,
1167
+ sender
1168
+ );
1169
+ txBlock.transferObjects([leftCoin], sender);
1170
+ return txBlock.repay(obligationArg, takeCoin, coinName);
1171
+ }
1172
+ },
1173
+ updateAssetPricesQuick: ({ txBlock, scallopUtils, scallopAddress, isTestnet }) => async (coinNames) => {
1174
+ return updateOracles(
1175
+ txBlock,
1176
+ scallopAddress,
1177
+ scallopUtils,
1178
+ coinNames,
1179
+ isTestnet
1180
+ );
1181
+ }
1182
+ };
1183
+ var newScallopTxBlock = (suiKit, scallopAddress, scallopUtils, isTestnet) => {
1184
+ const txBlock = newTxBlock(scallopAddress, scallopUtils);
1185
+ const txBlockProxy = new Proxy(txBlock, {
1186
+ get: (target, prop) => {
1187
+ if (prop in scallopQuickMethodsHandler) {
1188
+ return scallopQuickMethodsHandler[prop]({
1189
+ txBlock: target,
1190
+ suiKit,
1191
+ scallopAddress,
1192
+ scallopUtils,
1193
+ isTestnet
1194
+ });
1195
+ }
1196
+ return target[prop];
1197
+ }
1198
+ });
1199
+ return txBlockProxy;
1200
+ };
1201
+
1202
+ // src/models/scallopClient.ts
1203
+ var ScallopClient = class {
1204
+ constructor(params, address, walletAddress, isTestnet) {
1205
+ this.suiKit = new import_sui_kit5.SuiKit(params);
1206
+ this.address = address;
1207
+ this.walletAddress = (0, import_sui4.normalizeSuiAddress)(
1208
+ walletAddress || this.suiKit.currentAddress()
1209
+ );
1210
+ this._utils = new ScallopUtils(params);
1211
+ this._isTestnet = isTestnet || (params.networkType ? params.networkType === "testnet" : false);
1212
+ }
1213
+ createTxBlock() {
1214
+ return newScallopTxBlock(
1215
+ this.suiKit,
1216
+ this.address,
1217
+ this._utils,
1218
+ this._isTestnet
1219
+ );
1220
+ }
1221
+ /**
1222
+ * Query market data.
1223
+ *
1224
+ * @return Market data
1225
+ */
1226
+ async queryMarket() {
1227
+ return queryMarket(this.address, this.suiKit);
1228
+ }
1229
+ /**
1230
+ * Query obligations data.
1231
+ *
1232
+ * @param ownerAddress - The owner address.
1233
+ * @return Obligations data
1234
+ */
1235
+ async getObligations(ownerAddress) {
1236
+ const owner = ownerAddress || this.walletAddress;
1237
+ return getObligations(owner, this.address, this.suiKit);
1238
+ }
1239
+ /**
1240
+ * Query obligation data.
1241
+ *
1242
+ * @param obligationId - The obligation id from protocol package.
1243
+ * @return Obligation data
1244
+ */
1245
+ async queryObligation(obligationId) {
1246
+ return queryObligation(obligationId, this.address, this.suiKit);
1247
+ }
1248
+ async openObligation(sign = true) {
1249
+ const txBlock = this.createTxBlock();
1250
+ txBlock.openObligationEntry();
1251
+ if (sign) {
1252
+ return await this.suiKit.signAndSendTxn(
1253
+ txBlock
1254
+ );
1255
+ } else {
1256
+ return txBlock.txBlock;
1257
+ }
1258
+ }
1259
+ async depositCollateral(coinName, amount, sign = true, obligationId, walletAddress) {
1260
+ const txBlock = this.createTxBlock();
1261
+ const sender = walletAddress || this.walletAddress;
1262
+ txBlock.setSender(sender);
1263
+ if (obligationId) {
1264
+ await txBlock.addCollateralQuick(amount, coinName, obligationId);
1265
+ } else {
1266
+ const [obligation, obligationKey, hotPotato] = txBlock.openObligation();
1267
+ await txBlock.addCollateralQuick(amount, coinName, obligation);
1268
+ txBlock.returnObligation(obligation, hotPotato);
1269
+ txBlock.transferObjects([obligationKey], sender);
1270
+ }
1271
+ if (sign) {
1272
+ return await this.suiKit.signAndSendTxn(
1273
+ txBlock
1274
+ );
1275
+ } else {
1276
+ return txBlock.txBlock;
1277
+ }
1278
+ }
1279
+ /**
1280
+ * Withdraw collateral from the specific pool.
1281
+ *
1282
+ * @param coinName - Types of collateral coin.
1283
+ * @param amount - The amount of coins would deposit.
1284
+ * @param sign - Decide to directly sign the transaction or return the transaction block.
1285
+ * @param obligationId - The obligation object.
1286
+ * @param obligationKey - The obligation key object to verifying obligation authority.
1287
+ * @param walletAddress - The wallet address of the owner.
1288
+ * @return Transaction block response or transaction block
1289
+ */
1290
+ async withdrawCollateral(coinName, amount, sign = true, obligationId, obligationKey, walletAddress) {
1291
+ const txBlock = this.createTxBlock();
1292
+ const sender = walletAddress || this.walletAddress;
1293
+ txBlock.setSender(sender);
1294
+ const collateralCoin = await txBlock.takeCollateralQuick(
1295
+ amount,
1296
+ coinName,
1297
+ obligationId,
1298
+ obligationKey
1299
+ );
1300
+ txBlock.transferObjects([collateralCoin], sender);
1301
+ if (sign) {
1302
+ return await this.suiKit.signAndSendTxn(
1303
+ txBlock
1304
+ );
1305
+ } else {
1306
+ return txBlock.txBlock;
1307
+ }
1308
+ }
1309
+ async deposit(coinName, amount, sign = true, walletAddress) {
1310
+ const txBlock = this.createTxBlock();
1311
+ const sender = walletAddress || this.walletAddress;
1312
+ txBlock.setSender(sender);
1313
+ const marketCoin = await txBlock.depositQuick(amount, coinName);
1314
+ txBlock.transferObjects([marketCoin], sender);
1315
+ if (sign) {
1316
+ return await this.suiKit.signAndSendTxn(
1317
+ txBlock
1318
+ );
1319
+ } else {
1320
+ return txBlock.txBlock;
1321
+ }
1322
+ }
1323
+ async withdraw(coinName, amount, sign = true, walletAddress) {
1324
+ const txBlock = this.createTxBlock();
1325
+ const sender = walletAddress || this.walletAddress;
1326
+ txBlock.setSender(sender);
1327
+ const coin = await txBlock.withdrawQuick(amount, coinName);
1328
+ txBlock.transferObjects([coin], sender);
1329
+ if (sign) {
1330
+ return await this.suiKit.signAndSendTxn(
1331
+ txBlock
1332
+ );
1333
+ } else {
1334
+ return txBlock.txBlock;
1335
+ }
1336
+ }
1337
+ /**
1338
+ * borrow asset from the specific pool.
1339
+ *
1340
+ * @param coinName - Types of asset coin.
1341
+ * @param amount - The amount of coins would borrow.
1342
+ * @param sign - Decide to directly sign the transaction or return the transaction block.
1343
+ * @param obligationId - The obligation object.
1344
+ * @param obligationKey - The obligation key object to verifying obligation authority.
1345
+ * @param walletAddress - The wallet address of the owner.
1346
+ * @return Transaction block response or transaction block
1347
+ */
1348
+ async borrow(coinName, amount, sign = true, obligationId, obligationKey, walletAddress) {
1349
+ const txBlock = this.createTxBlock();
1350
+ const sender = walletAddress || this.walletAddress;
1351
+ txBlock.setSender(sender);
1352
+ const coin = await txBlock.borrowQuick(
1353
+ amount,
1354
+ coinName,
1355
+ obligationId,
1356
+ obligationKey
1357
+ );
1358
+ txBlock.transferObjects([coin], sender);
1359
+ if (sign) {
1360
+ return await this.suiKit.signAndSendTxn(
1361
+ txBlock
1362
+ );
1363
+ } else {
1364
+ return txBlock.txBlock;
1365
+ }
1366
+ }
1367
+ /**
1368
+ * Repay asset into the specific pool.
1369
+ *
1370
+ * @param coinName - Types of asset coin.
1371
+ * @param amount - The amount of coins would repay.
1372
+ * @param sign - Decide to directly sign the transaction or return the transaction block.
1373
+ * @param obligationId - The obligation object.
1374
+ * @param walletAddress - The wallet address of the owner.
1375
+ * @return Transaction block response or transaction block
1376
+ */
1377
+ async repay(coinName, amount, sign = true, obligationId, walletAddress) {
1378
+ const txBlock = this.createTxBlock();
1379
+ const sender = walletAddress || this.walletAddress;
1380
+ txBlock.setSender(sender);
1381
+ await txBlock.repayQuick(amount, coinName, obligationId);
1382
+ if (sign) {
1383
+ return await this.suiKit.signAndSendTxn(
1384
+ txBlock
1385
+ );
1386
+ } else {
1387
+ return txBlock.txBlock;
1388
+ }
1389
+ }
1390
+ async flashLoan(coinName, amount, callback, sign = true) {
1391
+ const txBlock = this.createTxBlock();
1392
+ const [coin, loan] = txBlock.borrowFlashLoan(amount, coinName);
1393
+ txBlock.repayFlashLoan(callback(txBlock, coin), loan, coinName);
1394
+ if (sign) {
1395
+ return await this.suiKit.signAndSendTxn(
1396
+ txBlock
1397
+ );
1398
+ } else {
1399
+ return txBlock.txBlock;
1400
+ }
1401
+ }
1402
+ async mintTestCoin(coinName, amount, sign = true, receiveAddress) {
1403
+ if (!this._isTestnet) {
1404
+ throw new Error("Only be used on the test network.");
1405
+ }
1406
+ const txBlock = this.createTxBlock();
1407
+ const recipient = receiveAddress || this.walletAddress;
1408
+ const packageId = this.address.get("core.packages.testCoin.id");
1409
+ const treasuryId = this.address.get(`core.coins.${coinName}.treasury`);
1410
+ const target = `${packageId}::${coinName}::mint`;
1411
+ const coin = txBlock.moveCall(target, [treasuryId, amount]);
1412
+ txBlock.transferObjects([coin], recipient);
1413
+ if (sign) {
1414
+ return await this.suiKit.signAndSendTxn(
1415
+ txBlock
1416
+ );
1417
+ } else {
1418
+ return txBlock.txBlock;
1419
+ }
1420
+ }
1421
+ };
1422
+
1423
+ // src/models/scallop.ts
1424
+ var Scallop = class {
1425
+ constructor(params) {
1426
+ this.params = params;
1427
+ this.suiKit = new import_sui_kit6.SuiKit(params);
1428
+ this.address = new ScallopAddress({
1429
+ id: ADDRESSES_ID,
1430
+ network: params?.networkType
1431
+ });
1432
+ }
1433
+ /**
1434
+ * Create an instance to operate the transaction block, making it more convenient to organize transaction combinations.
1435
+ * @return Scallop Transaction Builder
1436
+ */
1437
+ async createTxBuilder() {
1438
+ await this.address.read();
1439
+ const scallopUtils = new ScallopUtils(this.params);
1440
+ const suiKit = new import_sui_kit6.SuiKit(this.params);
1441
+ const isTestnet = this.params.networkType === "testnet";
1442
+ return {
1443
+ createTxBlock: () => {
1444
+ return newScallopTxBlock(suiKit, this.address, scallopUtils, isTestnet);
1445
+ },
1446
+ signAndSendTxBlock: (txBlock) => {
1447
+ return suiKit.signAndSendTxn(txBlock);
1448
+ }
1449
+ };
1450
+ }
1451
+ /**
1452
+ * Create an instance to collect the addresses, making it easier to get object addresses from lending contract.
1453
+ *
1454
+ * @param id - The API id of the addresses.
1455
+ * @param auth - The authentication API key.
1456
+ * @param network - Specifies which network's addresses you want to set.
1457
+ * @return Scallop Address
1458
+ */
1459
+ createAddress(id, auth, network) {
1460
+ return new ScallopAddress({ id, auth, network });
1461
+ }
1462
+ /**
1463
+ * Create an instance that provides contract interaction operations for general users.
1464
+ *
1465
+ * @param walletAddress - When user cannot provide a secret key or mnemonic, the scallop client cannot directly derive the address of the transaction the user wants to sign. This argument specifies the wallet address for signing the transaction.
1466
+ * @return Scallop Client
1467
+ */
1468
+ async createScallopClient(walletAddress) {
1469
+ await this.address.read();
1470
+ return new ScallopClient(this.params, this.address, walletAddress);
1471
+ }
1472
+ };
1473
+ // Annotate the CommonJS export names for ESM import in node:
1474
+ 0 && (module.exports = {
1475
+ ADDRESSES_ID,
1476
+ API_BASE_URL,
1477
+ SUI_COIN_TYPE_ARG_REGEX,
1478
+ SUPPORT_ASSET_COINS,
1479
+ SUPPORT_COLLATERAL_COINS,
1480
+ SUPPORT_ORACLES,
1481
+ SUPPORT_PACKAGES,
1482
+ Scallop,
1483
+ ScallopAddress,
1484
+ ScallopClient,
1485
+ ScallopUtils
1486
+ });
1487
+ //# sourceMappingURL=index.js.map