@scallop-io/sui-scallop-sdk 0.45.0 → 0.46.1

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 (43) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +1 -1
  2. package/dist/builders/referralBuilder.d.ts +12 -0
  3. package/dist/constants/common.d.ts +1 -1
  4. package/dist/index.js +533 -279
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +587 -329
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/models/scallopCache.d.ts +6 -2
  9. package/dist/models/scallopQuery.d.ts +26 -28
  10. package/dist/queries/coreQuery.d.ts +3 -29
  11. package/dist/queries/index.d.ts +1 -0
  12. package/dist/queries/priceQuery.d.ts +3 -1
  13. package/dist/queries/referralQuery.d.ts +7 -0
  14. package/dist/queries/vescaQuery.d.ts +6 -2
  15. package/dist/types/address.d.ts +15 -0
  16. package/dist/types/builder/core.d.ts +2 -0
  17. package/dist/types/builder/index.d.ts +2 -1
  18. package/dist/types/builder/referral.d.ts +30 -0
  19. package/dist/types/builder/vesca.d.ts +1 -0
  20. package/package.json +7 -6
  21. package/src/builders/borrowIncentiveBuilder.ts +10 -19
  22. package/src/builders/coreBuilder.ts +54 -0
  23. package/src/builders/index.ts +5 -2
  24. package/src/builders/referralBuilder.ts +178 -0
  25. package/src/builders/vescaBuilder.ts +8 -6
  26. package/src/constants/common.ts +9 -2
  27. package/src/constants/vesca.ts +1 -3
  28. package/src/models/scallopAddress.ts +63 -19
  29. package/src/models/scallopCache.ts +42 -2
  30. package/src/models/scallopQuery.ts +40 -0
  31. package/src/models/scallopUtils.ts +35 -35
  32. package/src/queries/borrowIncentiveQuery.ts +2 -5
  33. package/src/queries/coreQuery.ts +33 -197
  34. package/src/queries/index.ts +1 -0
  35. package/src/queries/priceQuery.ts +48 -7
  36. package/src/queries/referralQuery.ts +27 -0
  37. package/src/queries/spoolQuery.ts +8 -12
  38. package/src/queries/vescaQuery.ts +94 -15
  39. package/src/types/address.ts +15 -0
  40. package/src/types/builder/core.ts +14 -0
  41. package/src/types/builder/index.ts +2 -0
  42. package/src/types/builder/referral.ts +51 -0
  43. package/src/types/builder/vesca.ts +1 -0
package/dist/index.js CHANGED
@@ -75,7 +75,10 @@ module.exports = __toCommonJS(src_exports);
75
75
  var API_BASE_URL = "https://sui.api.scallop.io";
76
76
  var SDK_API_BASE_URL = "https://sdk.api.scallop.io";
77
77
  var IS_VE_SCA_TEST = false;
78
- var ADDRESSES_ID = IS_VE_SCA_TEST ? "65fb07c39c845425d71d7b18" : "6601955b8b0024600a917079";
78
+ var ADDRESSES_ID = IS_VE_SCA_TEST ? (
79
+ // ? ('65fb07c39c845425d71d7b18' as const)
80
+ "65fb07c39c845425d71d7b18"
81
+ ) : "664dfe22898c36c159e28bc8";
79
82
  var PROTOCOL_OBJECT_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf";
80
83
  var BORROW_FEE_PROTOCOL_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da";
81
84
  var SCA_COIN_TYPE = IS_VE_SCA_TEST ? `0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524::sca::SCA` : "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA";
@@ -259,13 +262,13 @@ var voloCoinIds = {
259
262
 
260
263
  // src/constants/vesca.ts
261
264
  var UNLOCK_ROUND_DURATION = 60 * 60 * 24;
262
- var MAX_LOCK_ROUNDS = IS_VE_SCA_TEST ? 9 : 1460;
265
+ var MAX_LOCK_ROUNDS = 1460;
263
266
  var MAX_LOCK_DURATION = MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION;
264
267
  var MIN_INITIAL_LOCK_AMOUNT = 1e10;
265
268
  var MIN_TOP_UP_AMOUNT = 1e9;
266
269
 
267
270
  // src/models/scallop.ts
268
- var import_sui_kit10 = require("@scallop-io/sui-kit");
271
+ var import_sui_kit12 = require("@scallop-io/sui-kit");
269
272
 
270
273
  // src/models/scallopCache.ts
271
274
  var import_query_core = require("@tanstack/query-core");
@@ -456,6 +459,35 @@ var ScallopCache = class {
456
459
  }
457
460
  });
458
461
  }
462
+ async queryGetAllCoinBalances(owner) {
463
+ const queryKey = ["getAllCoinBalances", owner];
464
+ return this.queryClient.fetchQuery({
465
+ queryKey,
466
+ queryFn: async () => {
467
+ const allBalances = await this.suiKit.client().getAllBalances({ owner });
468
+ return allBalances.reduce(
469
+ (acc, coinBalance) => {
470
+ if (coinBalance.totalBalance !== "0") {
471
+ acc[(0, import_sui_kit.normalizeStructTag)(coinBalance.coinType)] = coinBalance.totalBalance;
472
+ }
473
+ return acc;
474
+ },
475
+ {}
476
+ );
477
+ }
478
+ });
479
+ }
480
+ async queryGetCoinBalance(input) {
481
+ const queryKey = ["getCoinBalance", input.owner, input.coinType];
482
+ return this.queryClient.fetchQuery({
483
+ queryKey,
484
+ queryFn: async () => {
485
+ if (!input.coinType)
486
+ return "0";
487
+ return (await this.queryGetAllCoinBalances(input.owner))[(0, import_sui_kit.normalizeStructTag)(input.coinType)] ?? "0";
488
+ }
489
+ });
490
+ }
459
491
  };
460
492
 
461
493
  // src/models/scallopAddress.ts
@@ -470,6 +502,45 @@ var EMPTY_ADDRESSES = {
470
502
  coinDecimalsRegistry: "",
471
503
  obligationAccessStore: "",
472
504
  coins: {
505
+ cetus: {
506
+ id: "",
507
+ metaData: "",
508
+ treasury: "",
509
+ oracle: {
510
+ supra: "",
511
+ switchboard: "",
512
+ pyth: {
513
+ feed: "",
514
+ feedObject: ""
515
+ }
516
+ }
517
+ },
518
+ apt: {
519
+ id: "",
520
+ metaData: "",
521
+ treasury: "",
522
+ oracle: {
523
+ supra: "",
524
+ switchboard: "",
525
+ pyth: {
526
+ feed: "",
527
+ feedObject: ""
528
+ }
529
+ }
530
+ },
531
+ sol: {
532
+ id: "",
533
+ metaData: "",
534
+ treasury: "",
535
+ oracle: {
536
+ supra: "",
537
+ switchboard: "",
538
+ pyth: {
539
+ feed: "",
540
+ feedObject: ""
541
+ }
542
+ }
543
+ },
473
544
  btc: {
474
545
  id: "",
475
546
  metaData: "",
@@ -591,15 +662,8 @@ var EMPTY_ADDRESSES = {
591
662
  oracles: {
592
663
  xOracle: "",
593
664
  xOracleCap: "",
594
- supra: {
595
- registry: "",
596
- registryCap: "",
597
- holder: ""
598
- },
599
- switchboard: {
600
- registry: "",
601
- registryCap: ""
602
- },
665
+ supra: { registry: "", registryCap: "", holder: "" },
666
+ switchboard: { registry: "", registryCap: "" },
603
667
  pyth: {
604
668
  registry: "",
605
669
  registryCap: "",
@@ -629,27 +693,25 @@ var EMPTY_ADDRESSES = {
629
693
  id: "",
630
694
  upgradeCap: ""
631
695
  },
632
- query: {
696
+ protocolWhitelist: {
633
697
  id: "",
634
698
  upgradeCap: ""
635
699
  },
636
- pyth: {
700
+ query: {
637
701
  id: "",
638
702
  upgradeCap: ""
639
703
  },
640
- switchboard: {
704
+ supra: { id: "", upgradeCap: "" },
705
+ pyth: {
641
706
  id: "",
642
707
  upgradeCap: ""
643
708
  },
709
+ switchboard: { id: "", upgradeCap: "" },
644
710
  xOracle: {
645
711
  id: "",
646
712
  upgradeCap: ""
647
713
  },
648
- // Deploy for faucet on testnet.
649
- testCoin: {
650
- id: "",
651
- upgradeCap: ""
652
- }
714
+ testCoin: { id: "", upgradeCap: "" }
653
715
  }
654
716
  },
655
717
  spool: {
@@ -689,24 +751,39 @@ var EMPTY_ADDRESSES = {
689
751
  id: "",
690
752
  rewardPoolId: ""
691
753
  }
692
- }
754
+ },
755
+ config: ""
693
756
  },
694
757
  borrowIncentive: {
695
758
  id: "",
696
759
  adminCap: "",
697
760
  object: "",
698
761
  query: "",
699
- config: "",
700
762
  incentivePools: "",
701
- incentiveAccounts: ""
763
+ incentiveAccounts: "",
764
+ config: ""
702
765
  },
703
766
  vesca: {
704
767
  id: "",
768
+ object: "",
705
769
  adminCap: "",
706
770
  tableId: "",
707
771
  table: "",
708
772
  treasury: "",
709
773
  config: ""
774
+ },
775
+ referral: {
776
+ id: "",
777
+ version: "",
778
+ object: "",
779
+ adminCap: "",
780
+ referralBindings: "",
781
+ bindingTableId: "",
782
+ referralRevenuePool: "",
783
+ revenueTableId: "",
784
+ referralTiers: "",
785
+ tiersTableId: "",
786
+ authorizedWitnessList: ""
710
787
  }
711
788
  };
712
789
  var ScallopAddress = class {
@@ -1013,20 +1090,19 @@ var ScallopAddress = class {
1013
1090
  };
1014
1091
 
1015
1092
  // src/models/scallopClient.ts
1016
- var import_utils20 = require("@mysten/sui.js/utils");
1017
- var import_sui_kit9 = require("@scallop-io/sui-kit");
1093
+ var import_utils21 = require("@mysten/sui.js/utils");
1094
+ var import_sui_kit11 = require("@scallop-io/sui-kit");
1018
1095
 
1019
1096
  // src/models/scallopUtils.ts
1020
1097
  var import_utils9 = require("@mysten/sui.js/utils");
1021
- var import_sui_kit3 = require("@scallop-io/sui-kit");
1098
+ var import_sui_kit4 = require("@scallop-io/sui-kit");
1022
1099
  var import_pyth_sui_js = require("@pythnetwork/pyth-sui-js");
1023
1100
 
1024
1101
  // src/models/scallopQuery.ts
1025
- var import_sui_kit2 = require("@scallop-io/sui-kit");
1102
+ var import_sui_kit3 = require("@scallop-io/sui-kit");
1026
1103
 
1027
1104
  // src/queries/coreQuery.ts
1028
1105
  var import_utils2 = require("@mysten/sui.js/utils");
1029
- var import_bignumber2 = __toESM(require("bignumber.js"));
1030
1106
 
1031
1107
  // src/utils/builder.ts
1032
1108
  var requireSender = (txBlock) => {
@@ -1574,6 +1650,7 @@ var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
1574
1650
  };
1575
1651
 
1576
1652
  // src/queries/coreQuery.ts
1653
+ var import_bignumber2 = __toESM(require("bignumber.js"));
1577
1654
  var queryMarket = async (query, indexer = false) => {
1578
1655
  const packageId = query.address.get("core.packages.query.id");
1579
1656
  const marketId = query.address.get("core.market");
@@ -2047,178 +2124,50 @@ var queryObligation = async (query, obligationId) => {
2047
2124
  var getCoinAmounts = async (query, assetCoinNames, ownerAddress) => {
2048
2125
  assetCoinNames = assetCoinNames || [...SUPPORT_POOLS];
2049
2126
  const owner = ownerAddress || query.suiKit.currentAddress();
2050
- const coinObjectsResponse = [];
2051
- let hasNextPage = false;
2052
- let nextCursor = null;
2053
- do {
2054
- const paginatedCoinObjectsResponse = await query.cache.queryGetOwnedObjects(
2055
- {
2056
- owner,
2057
- filter: {
2058
- MatchAny: assetCoinNames.map((assetCoinName) => {
2059
- const coinType = query.utils.parseCoinType(assetCoinName);
2060
- return { StructType: `0x2::coin::Coin<${coinType}>` };
2061
- })
2062
- },
2063
- options: {
2064
- showType: true,
2065
- showContent: true
2066
- },
2067
- cursor: nextCursor
2068
- }
2069
- );
2070
- coinObjectsResponse.push(...paginatedCoinObjectsResponse.data);
2071
- if (paginatedCoinObjectsResponse.hasNextPage && paginatedCoinObjectsResponse.nextCursor) {
2072
- hasNextPage = true;
2073
- nextCursor = paginatedCoinObjectsResponse.nextCursor;
2074
- } else {
2075
- hasNextPage = false;
2076
- }
2077
- } while (hasNextPage);
2078
- const coinAmounts = {};
2079
- const coinObjects = coinObjectsResponse.map((response) => {
2080
- return response.data;
2081
- }).filter(
2082
- (object) => object !== void 0 && object !== null
2127
+ const assetCoins2 = {};
2128
+ await Promise.allSettled(
2129
+ assetCoinNames.map(async (assetCoinName) => {
2130
+ const marketCoin = await getCoinAmount(query, assetCoinName, owner);
2131
+ assetCoins2[assetCoinName] = marketCoin;
2132
+ })
2083
2133
  );
2084
- for (const coinObject of coinObjects) {
2085
- const type = coinObject.type;
2086
- if (coinObject.content && "fields" in coinObject.content) {
2087
- const fields = coinObject.content.fields;
2088
- const poolCoinName = query.utils.parseCoinNameFromType(type);
2089
- if (poolCoinName) {
2090
- coinAmounts[poolCoinName] = (0, import_bignumber2.default)(coinAmounts[poolCoinName] ?? 0).plus(fields.balance).toNumber();
2091
- }
2092
- }
2093
- }
2094
- return coinAmounts;
2134
+ return assetCoins2;
2095
2135
  };
2096
2136
  var getCoinAmount = async (query, assetCoinName, ownerAddress) => {
2097
2137
  const owner = ownerAddress || query.suiKit.currentAddress();
2098
2138
  const coinType = query.utils.parseCoinType(assetCoinName);
2099
- const coinObjectsResponse = [];
2100
- let hasNextPage = false;
2101
- let nextCursor = null;
2102
- do {
2103
- const paginatedCoinObjectsResponse = await query.cache.queryGetOwnedObjects(
2104
- {
2105
- owner,
2106
- filter: { StructType: `0x2::coin::Coin<${coinType}>` },
2107
- options: {
2108
- showContent: true
2109
- },
2110
- cursor: nextCursor
2111
- }
2112
- );
2113
- coinObjectsResponse.push(...paginatedCoinObjectsResponse.data);
2114
- if (paginatedCoinObjectsResponse.hasNextPage && paginatedCoinObjectsResponse.nextCursor) {
2115
- hasNextPage = true;
2116
- nextCursor = paginatedCoinObjectsResponse.nextCursor;
2117
- } else {
2118
- hasNextPage = false;
2119
- }
2120
- } while (hasNextPage);
2121
- let coinAmount = 0;
2122
- const coinObjects = coinObjectsResponse.map((response) => {
2123
- return response.data;
2124
- }).filter(
2125
- (object) => object !== void 0 && object !== null
2126
- );
2127
- for (const coinObject of coinObjects) {
2128
- if (coinObject.content && "fields" in coinObject.content) {
2129
- const fields = coinObject.content.fields;
2130
- coinAmount = (0, import_bignumber2.default)(coinAmount).plus(fields.balance).toNumber();
2131
- }
2132
- }
2133
- return coinAmount;
2139
+ const amount = await query.cache.queryGetCoinBalance({
2140
+ owner,
2141
+ coinType
2142
+ });
2143
+ return (0, import_bignumber2.default)(amount).toNumber();
2134
2144
  };
2135
2145
  var getMarketCoinAmounts = async (query, marketCoinNames, ownerAddress) => {
2136
2146
  marketCoinNames = marketCoinNames || [...SUPPORT_POOLS].map(
2137
2147
  (poolCoinName) => query.utils.parseMarketCoinName(poolCoinName)
2138
2148
  );
2139
2149
  const owner = ownerAddress || query.suiKit.currentAddress();
2140
- const marketCoinObjectsResponse = [];
2141
- let hasNextPage = false;
2142
- let nextCursor = null;
2143
- do {
2144
- const paginatedMarketCoinObjectsResponse = await query.cache.queryGetOwnedObjects({
2145
- owner,
2146
- filter: {
2147
- MatchAny: marketCoinNames.map((marketCoinName) => {
2148
- const marketCoinType = query.utils.parseMarketCoinType(marketCoinName);
2149
- return { StructType: `0x2::coin::Coin<${marketCoinType}>` };
2150
- })
2151
- },
2152
- options: {
2153
- showType: true,
2154
- showContent: true
2155
- },
2156
- cursor: nextCursor
2157
- });
2158
- marketCoinObjectsResponse.push(...paginatedMarketCoinObjectsResponse.data);
2159
- if (paginatedMarketCoinObjectsResponse.hasNextPage && paginatedMarketCoinObjectsResponse.nextCursor) {
2160
- hasNextPage = true;
2161
- nextCursor = paginatedMarketCoinObjectsResponse.nextCursor;
2162
- } else {
2163
- hasNextPage = false;
2164
- }
2165
- } while (hasNextPage);
2166
- const marketCoinAmounts = {};
2167
- const marketCoinObjects = marketCoinObjectsResponse.map((response) => {
2168
- return response.data;
2169
- }).filter(
2170
- (object) => object !== void 0 && object !== null
2150
+ const marketCoins2 = {};
2151
+ Promise.allSettled(
2152
+ marketCoinNames.map(async (marketCoinName) => {
2153
+ const marketCoin = await getMarketCoinAmount(
2154
+ query,
2155
+ marketCoinName,
2156
+ owner
2157
+ );
2158
+ marketCoins2[marketCoinName] = marketCoin;
2159
+ })
2171
2160
  );
2172
- for (const marketCoinObject of marketCoinObjects) {
2173
- const marketCoinType = marketCoinObject.type;
2174
- if (marketCoinObject.content && "fields" in marketCoinObject.content) {
2175
- const fields = marketCoinObject.content.fields;
2176
- const marketCoinName = query.utils.parseCoinNameFromType(marketCoinType);
2177
- if (marketCoinName) {
2178
- marketCoinAmounts[marketCoinName] = (0, import_bignumber2.default)(
2179
- marketCoinAmounts[marketCoinName] ?? 0
2180
- ).plus(fields.balance).toNumber();
2181
- }
2182
- }
2183
- }
2184
- return marketCoinAmounts;
2161
+ return marketCoins2;
2185
2162
  };
2186
2163
  var getMarketCoinAmount = async (query, marketCoinName, ownerAddress) => {
2187
2164
  const owner = ownerAddress || query.suiKit.currentAddress();
2188
2165
  const marketCoinType = query.utils.parseMarketCoinType(marketCoinName);
2189
- const marketCoinObjectsResponse = [];
2190
- let hasNextPage = false;
2191
- let nextCursor = null;
2192
- do {
2193
- const paginatedMarketCoinObjectsResponse = await query.cache.queryGetOwnedObjects({
2194
- owner,
2195
- filter: { StructType: `0x2::coin::Coin<${marketCoinType}>` },
2196
- options: {
2197
- showContent: true
2198
- },
2199
- cursor: nextCursor
2200
- });
2201
- marketCoinObjectsResponse.push(...paginatedMarketCoinObjectsResponse.data);
2202
- if (paginatedMarketCoinObjectsResponse.hasNextPage && paginatedMarketCoinObjectsResponse.nextCursor) {
2203
- hasNextPage = true;
2204
- nextCursor = paginatedMarketCoinObjectsResponse.nextCursor;
2205
- } else {
2206
- hasNextPage = false;
2207
- }
2208
- } while (hasNextPage);
2209
- let marketCoinAmount = 0;
2210
- const marketCoinObjects = marketCoinObjectsResponse.map((response) => {
2211
- return response.data;
2212
- }).filter(
2213
- (object) => object !== void 0 && object !== null
2214
- );
2215
- for (const marketCoinObject of marketCoinObjects) {
2216
- if (marketCoinObject.content && "fields" in marketCoinObject.content) {
2217
- const fields = marketCoinObject.content.fields;
2218
- marketCoinAmount = (0, import_bignumber2.default)(marketCoinAmount).plus(fields.balance).toNumber();
2219
- }
2220
- }
2221
- return marketCoinAmount;
2166
+ const amount = await query.cache.queryGetCoinBalance({
2167
+ owner,
2168
+ coinType: marketCoinType
2169
+ });
2170
+ return (0, import_bignumber2.default)(amount).toNumber();
2222
2171
  };
2223
2172
 
2224
2173
  // src/queries/spoolQuery.ts
@@ -2288,17 +2237,17 @@ var getSpool = async (query, marketCoinName, indexer = false, marketPool, coinPr
2288
2237
  spoolIndexer.rewardCoinPrice = coinPrices?.[rewardCoinName] || spoolIndexer.rewardCoinPrice;
2289
2238
  return spoolIndexer;
2290
2239
  }
2291
- const spoolObjectResponse = await query.suiKit.client().multiGetObjects({
2292
- ids: [poolId, rewardPoolId],
2293
- options: {
2240
+ const spoolObjectResponse = await query.cache.queryGetObjects(
2241
+ [poolId, rewardPoolId],
2242
+ {
2294
2243
  showContent: true
2295
2244
  }
2296
- });
2297
- if (marketPool && spoolObjectResponse[0].data && spoolObjectResponse[1].data) {
2245
+ );
2246
+ if (marketPool && spoolObjectResponse[0] && spoolObjectResponse[1]) {
2298
2247
  const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
2299
2248
  coinPrices = coinPrices || await query.utils.getCoinPrices([coinName, rewardCoinName]);
2300
- const spoolObject = spoolObjectResponse[0].data;
2301
- const rewardPoolObject = spoolObjectResponse[1].data;
2249
+ const spoolObject = spoolObjectResponse[0];
2250
+ const rewardPoolObject = spoolObjectResponse[1];
2302
2251
  if (spoolObject.content && "fields" in spoolObject.content) {
2303
2252
  const spoolFields = spoolObject.content.fields;
2304
2253
  const parsedSpoolData = parseOriginSpoolData({
@@ -2699,7 +2648,7 @@ var queryBorrowIncentiveAccounts = async (query, obligationId, borrowIncentiveCo
2699
2648
  var getBindedObligationId = async (query, veScaKeyId) => {
2700
2649
  const borrowIncentiveObjectId = query.address.get("borrowIncentive.object");
2701
2650
  const incentivePoolsId = query.address.get("borrowIncentive.incentivePools");
2702
- const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : query.address.get("vesca.id");
2651
+ const veScaObjId = query.address.get("vesca.object");
2703
2652
  const client = query.suiKit.client();
2704
2653
  const incentivePoolsResponse = await client.getObject({
2705
2654
  id: incentivePoolsId,
@@ -2711,7 +2660,7 @@ var getBindedObligationId = async (query, veScaKeyId) => {
2711
2660
  return null;
2712
2661
  const incentivePoolFields = incentivePoolsResponse.data.content.fields;
2713
2662
  const veScaBindTableId = incentivePoolFields.ve_sca_bind.fields.id.id;
2714
- const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaPkgId}::ve_sca::VeScaKey>`;
2663
+ const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
2715
2664
  const veScaBindTableResponse = await client.getDynamicFieldObject({
2716
2665
  parentId: veScaBindTableId,
2717
2666
  name: {
@@ -2755,16 +2704,13 @@ var getBindedVeScaKey = async (query, obliationId) => {
2755
2704
  };
2756
2705
 
2757
2706
  // src/queries/priceQuery.ts
2758
- var getPythPrice = async (query, assetCoinName) => {
2707
+ var getPythPrice = async (query, assetCoinName, priceFeedObject) => {
2759
2708
  const pythFeedObjectId = query.address.get(
2760
2709
  `core.coins.${assetCoinName}.oracle.pyth.feedObject`
2761
2710
  );
2762
- const priceFeedObjectResponse = await query.cache.queryGetObject(
2763
- pythFeedObjectId,
2764
- { showContent: true }
2765
- );
2766
- if (priceFeedObjectResponse.data) {
2767
- const priceFeedPoolObject = priceFeedObjectResponse.data;
2711
+ priceFeedObject = priceFeedObject || (await query.cache.queryGetObject(pythFeedObjectId, { showContent: true })).data;
2712
+ if (priceFeedObject) {
2713
+ const priceFeedPoolObject = priceFeedObject;
2768
2714
  if (priceFeedPoolObject.content && "fields" in priceFeedPoolObject.content) {
2769
2715
  const fields = priceFeedPoolObject.content.fields;
2770
2716
  const expoMagnitude = Number(
@@ -2784,6 +2730,36 @@ var getPythPrice = async (query, assetCoinName) => {
2784
2730
  }
2785
2731
  return 0;
2786
2732
  };
2733
+ var getPythPrices = async (query, assetCoinNames) => {
2734
+ const seen = {};
2735
+ const pythFeedObjectIds = assetCoinNames.map((assetCoinName) => {
2736
+ const pythFeedObjectId = query.address.get(
2737
+ `core.coins.${assetCoinName}.oracle.pyth.feedObject`
2738
+ );
2739
+ if (seen[pythFeedObjectId])
2740
+ return null;
2741
+ seen[pythFeedObjectId] = true;
2742
+ return pythFeedObjectId;
2743
+ }).filter((item) => !!item);
2744
+ const priceFeedObjects = await query.cache.queryGetObjects(
2745
+ pythFeedObjectIds,
2746
+ {
2747
+ showContent: true
2748
+ }
2749
+ );
2750
+ return (await Promise.all(
2751
+ priceFeedObjects.map(async (priceFeedObject, idx) => ({
2752
+ coinName: assetCoinNames[idx],
2753
+ price: await getPythPrice(query, assetCoinNames[idx], priceFeedObject)
2754
+ }))
2755
+ )).reduce(
2756
+ (prev, curr) => {
2757
+ prev[curr.coinName] = curr.price;
2758
+ return prev;
2759
+ },
2760
+ {}
2761
+ );
2762
+ };
2787
2763
 
2788
2764
  // src/queries/portfolioQuery.ts
2789
2765
  var import_bignumber3 = __toESM(require("bignumber.js"));
@@ -3285,10 +3261,12 @@ var getTotalValueLocked = async (query, indexer = false) => {
3285
3261
 
3286
3262
  // src/queries/vescaQuery.ts
3287
3263
  var import_bignumber4 = __toESM(require("bignumber.js"));
3264
+ var import_sui_kit2 = require("@scallop-io/sui-kit");
3265
+ var import_bcs = require("@mysten/sui.js/bcs");
3288
3266
  var getVescaKeys = async (query, ownerAddress) => {
3289
3267
  const owner = ownerAddress || query.suiKit.currentAddress();
3290
- const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : query.address.get("vesca.id");
3291
- const veScaKeyType = `${veScaPkgId}::ve_sca::VeScaKey`;
3268
+ const veScaObjId = query.address.get("vesca.object");
3269
+ const veScaKeyType = `${veScaObjId}::ve_sca::VeScaKey`;
3292
3270
  const keyObjectsResponse = [];
3293
3271
  let hasNextPage = false;
3294
3272
  let nextCursor = null;
@@ -3314,16 +3292,18 @@ var getVescaKeys = async (query, ownerAddress) => {
3314
3292
  var getVeScas = async (query, ownerAddress) => {
3315
3293
  const keyObjectDatas = await getVescaKeys(query, ownerAddress);
3316
3294
  const keyObjectId = keyObjectDatas.map((data) => data.objectId);
3317
- const veScas = [];
3318
- for (const keyId of keyObjectId) {
3295
+ const veScas = Array(keyObjectId.length).fill(null);
3296
+ const tasks = keyObjectId.map(async (keyId, idx) => {
3319
3297
  const veSca = await getVeSca(query, keyId);
3320
- if (veSca)
3321
- veScas.push(veSca);
3322
- }
3323
- return veScas;
3298
+ if (veSca) {
3299
+ veScas[idx] = veSca;
3300
+ }
3301
+ });
3302
+ await Promise.allSettled(tasks);
3303
+ return veScas.filter(Boolean).sort((a, b) => a.currentVeScaBalance - b.currentVeScaBalance);
3324
3304
  };
3325
3305
  var getVeSca = async (query, veScaKeyId, ownerAddress) => {
3326
- const tableId = IS_VE_SCA_TEST ? "0xc607241e4a679fe376d1170b2fbe07b64917bfe69100d4825241cda20039d4bd" : query.address.get(`vesca.tableId`);
3306
+ const tableId = query.address.get(`vesca.tableId`);
3327
3307
  veScaKeyId = veScaKeyId || (await getVescaKeys(query, ownerAddress))[0].objectId;
3328
3308
  let vesca = void 0;
3329
3309
  const veScaDynamicFieldObjectResponse = await query.cache.queryGetDynamicFieldObject({
@@ -3349,11 +3329,77 @@ var getVeSca = async (query, veScaKeyId, ownerAddress) => {
3349
3329
  lockedScaAmount,
3350
3330
  lockedScaCoin,
3351
3331
  currentVeScaBalance,
3352
- unlockAt: (0, import_bignumber4.default)(dynamicFields.unlock_at).toNumber()
3332
+ unlockAt: (0, import_bignumber4.default)(dynamicFields.unlock_at * 1e3).toNumber()
3353
3333
  };
3354
3334
  }
3355
3335
  return vesca;
3356
3336
  };
3337
+ var getTotalVeScaTreasuryAmount = async (query) => {
3338
+ const veScaPkgId = query.address.get("vesca.id");
3339
+ const veScaConfig = query.address.get("vesca.config");
3340
+ const veScaTreasury = query.address.get("vesca.treasury");
3341
+ const refreshQueryTarget = `${veScaPkgId}::treasury::refresh`;
3342
+ const refreshArgs = [veScaConfig, veScaTreasury, import_sui_kit2.SUI_CLOCK_OBJECT_ID];
3343
+ const veScaAmountQueryTarget = `${veScaPkgId}::treasury::total_ve_sca_amount`;
3344
+ const veScaAmountArgs = [veScaTreasury, import_sui_kit2.SUI_CLOCK_OBJECT_ID];
3345
+ const resolvedRefreshArgs = await Promise.all(
3346
+ refreshArgs.map(async (arg) => {
3347
+ if (typeof arg === "string") {
3348
+ return (await query.cache.queryGetObject(arg, { showContent: true })).data;
3349
+ }
3350
+ return arg;
3351
+ })
3352
+ );
3353
+ const resolvedVeScaAmountArgs = await Promise.all(
3354
+ veScaAmountArgs.map(async (arg) => {
3355
+ if (typeof arg === "string") {
3356
+ return (await query.cache.queryGetObject(arg, { showContent: true })).data;
3357
+ }
3358
+ return arg;
3359
+ })
3360
+ );
3361
+ const txb = new import_sui_kit2.SuiTxBlock();
3362
+ txb.moveCall(refreshQueryTarget, resolvedRefreshArgs);
3363
+ txb.moveCall(veScaAmountQueryTarget, resolvedVeScaAmountArgs);
3364
+ const txBytes = await txb.txBlock.build({
3365
+ client: query.suiKit.client(),
3366
+ onlyTransactionKind: true,
3367
+ protocolConfig: await query.cache.getProtocolConfig()
3368
+ });
3369
+ const res = await query.cache.queryClient.fetchQuery({
3370
+ queryKey: [
3371
+ "getTotalVeScaTreasuryAmount",
3372
+ JSON.stringify([...refreshArgs, ...veScaAmountArgs])
3373
+ ],
3374
+ queryFn: async () => {
3375
+ return await query.suiKit.inspectTxn(txBytes);
3376
+ },
3377
+ staleTime: 8e3
3378
+ });
3379
+ const results = res.results;
3380
+ if (results && results[1].returnValues) {
3381
+ const value = Uint8Array.from(results[1].returnValues[0][0]);
3382
+ const type = results[1].returnValues[0][1];
3383
+ return import_bcs.bcs.de(type, value);
3384
+ }
3385
+ return "0";
3386
+ };
3387
+
3388
+ // src/queries/referralQuery.ts
3389
+ var queryVeScaKeyIdFromReferralBindings = async (query, refereeAddress) => {
3390
+ const referralBindingTableId = query.address.get("referral.bindingTableId");
3391
+ const referralBindResponse = await query.cache.queryGetDynamicFieldObject({
3392
+ parentId: referralBindingTableId,
3393
+ name: {
3394
+ type: "address",
3395
+ value: refereeAddress
3396
+ }
3397
+ });
3398
+ if (referralBindResponse.data?.content?.dataType !== "moveObject")
3399
+ return null;
3400
+ const fields = referralBindResponse.data.content.fields;
3401
+ return fields.value;
3402
+ };
3357
3403
 
3358
3404
  // src/models/scallopIndexer.ts
3359
3405
  var import_axios2 = __toESM(require("axios"));
@@ -3518,7 +3564,7 @@ var ScallopIndexer = class {
3518
3564
  var ScallopQuery = class {
3519
3565
  constructor(params, instance) {
3520
3566
  this.params = params;
3521
- this.suiKit = instance?.suiKit ?? new import_sui_kit2.SuiKit(params);
3567
+ this.suiKit = instance?.suiKit ?? new import_sui_kit3.SuiKit(params);
3522
3568
  this.cache = instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
3523
3569
  this.address = instance?.address ?? new ScallopAddress(
3524
3570
  {
@@ -3673,6 +3719,15 @@ var ScallopQuery = class {
3673
3719
  async getPriceFromPyth(assetCoinName) {
3674
3720
  return await getPythPrice(this, assetCoinName);
3675
3721
  }
3722
+ /**
3723
+ * Get prices from pyth fee object.
3724
+ *
3725
+ * @param assetCoinNames - Array of supported asset coin names.
3726
+ * @return Array of asset coin prices.
3727
+ */
3728
+ async getPricesFromPyth(assetCoinNames) {
3729
+ return await getPythPrices(this, assetCoinNames);
3730
+ }
3676
3731
  /* ==================== Spool Query Methods ==================== */
3677
3732
  /**
3678
3733
  * Get spools data.
@@ -3871,6 +3926,29 @@ var ScallopQuery = class {
3871
3926
  async getTvl(indexer = false) {
3872
3927
  return await getTotalValueLocked(this, indexer);
3873
3928
  }
3929
+ /**
3930
+ * Get all veSca from walletAdddress
3931
+ * @param walletAddress
3932
+ * @returns array of veSca
3933
+ */
3934
+ async getVeScas(walletAddress) {
3935
+ return await getVeScas(this, walletAddress);
3936
+ }
3937
+ /**
3938
+ * Get total vesca treasury with movecall
3939
+ * @returns Promise<string | undefined>
3940
+ */
3941
+ async getTotalVeScaTreasuryAmount() {
3942
+ return await getTotalVeScaTreasuryAmount(this);
3943
+ }
3944
+ /**
3945
+ * Return binded veScaKeyId of walletAddress if exist
3946
+ * @param walletAddress
3947
+ * @returns veScaKeyId
3948
+ */
3949
+ async getVeScaKeyIdFromReferralBindings(walletAddress) {
3950
+ return await queryVeScaKeyIdFromReferralBindings(this, walletAddress);
3951
+ }
3874
3952
  /**
3875
3953
  * Get binded obligationId from a veScaKey if it exists.
3876
3954
  * @param veScaKey
@@ -3918,7 +3996,7 @@ var ScallopUtils = class {
3918
3996
  return borrowIncentiveRewardCoins[borrowIncentiveCoinName];
3919
3997
  };
3920
3998
  this.params = params;
3921
- this._suiKit = instance?.suiKit ?? new import_sui_kit3.SuiKit(params);
3999
+ this._suiKit = instance?.suiKit ?? new import_sui_kit4.SuiKit(params);
3922
4000
  this._cache = instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this._suiKit);
3923
4001
  this._address = instance?.address ?? new ScallopAddress(
3924
4002
  {
@@ -4151,8 +4229,6 @@ var ScallopUtils = class {
4151
4229
  lackPricesCoinNames
4152
4230
  );
4153
4231
  for (const endpoint of endpoints) {
4154
- let hasFailRequest = false;
4155
- const pythConnection = new import_pyth_sui_js.SuiPriceServiceConnection(endpoint);
4156
4232
  const priceIds = Array.from(failedRequests.values()).reduce(
4157
4233
  (acc, coinName) => {
4158
4234
  const priceId = this._address.get(
@@ -4163,43 +4239,46 @@ var ScallopUtils = class {
4163
4239
  },
4164
4240
  {}
4165
4241
  );
4166
- for (const [coinName, priceId] of Object.entries(priceIds)) {
4167
- try {
4168
- const feed = await this._cache.queryClient.fetchQuery({
4169
- queryKey: [priceId],
4170
- queryFn: async () => {
4171
- return await pythConnection.getLatestPriceFeeds([priceId]);
4172
- }
4173
- // staleTime: 15000,
4174
- });
4175
- if (feed) {
4176
- const data = parseDataFromPythPriceFeed(feed[0], this._address);
4177
- this._priceMap.set(coinName, {
4178
- price: data.price,
4179
- publishTime: data.publishTime
4242
+ await Promise.allSettled(
4243
+ Object.entries(priceIds).map(async ([coinName, priceId]) => {
4244
+ const pythConnection = new import_pyth_sui_js.SuiPriceServiceConnection(endpoint);
4245
+ try {
4246
+ const feed = await this._cache.queryClient.fetchQuery({
4247
+ queryKey: [priceId],
4248
+ queryFn: async () => {
4249
+ return await pythConnection.getLatestPriceFeeds([priceId]);
4250
+ }
4180
4251
  });
4181
- coinPrices[coinName] = data.price;
4252
+ if (feed) {
4253
+ const data = parseDataFromPythPriceFeed(feed[0], this._address);
4254
+ this._priceMap.set(coinName, {
4255
+ price: data.price,
4256
+ publishTime: data.publishTime
4257
+ });
4258
+ coinPrices[coinName] = data.price;
4259
+ }
4260
+ failedRequests.delete(coinName);
4261
+ } catch (e) {
4262
+ console.warn(
4263
+ `Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
4264
+ );
4182
4265
  }
4183
- failedRequests.delete(coinName);
4184
- } catch (e) {
4185
- console.warn(
4186
- `Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
4187
- );
4188
- hasFailRequest = true;
4189
- }
4190
- }
4191
- if (!hasFailRequest)
4266
+ })
4267
+ );
4268
+ if (failedRequests.size === 0)
4192
4269
  break;
4193
4270
  }
4194
4271
  if (failedRequests.size > 0) {
4195
- for (const coinName of failedRequests.values()) {
4196
- const price = await this._query.getPriceFromPyth(coinName);
4197
- this._priceMap.set(coinName, {
4198
- price,
4199
- publishTime: Date.now()
4200
- });
4201
- coinPrices[coinName] = price;
4202
- }
4272
+ await Promise.allSettled(
4273
+ Array.from(failedRequests.values()).map(async (coinName) => {
4274
+ const price = await this._query.getPriceFromPyth(coinName);
4275
+ this._priceMap.set(coinName, {
4276
+ price,
4277
+ publishTime: Date.now()
4278
+ });
4279
+ coinPrices[coinName] = price;
4280
+ })
4281
+ );
4203
4282
  }
4204
4283
  }
4205
4284
  return coinPrices;
@@ -4259,13 +4338,13 @@ var ScallopUtils = class {
4259
4338
  };
4260
4339
 
4261
4340
  // src/models/scallopBuilder.ts
4262
- var import_utils19 = require("@mysten/sui.js/utils");
4263
- var import_sui_kit8 = require("@scallop-io/sui-kit");
4341
+ var import_utils20 = require("@mysten/sui.js/utils");
4342
+ var import_sui_kit10 = require("@scallop-io/sui-kit");
4264
4343
 
4265
4344
  // src/builders/coreBuilder.ts
4266
4345
  var import_transactions = require("@mysten/sui.js/transactions");
4267
4346
  var import_utils12 = require("@mysten/sui.js/utils");
4268
- var import_sui_kit4 = require("@scallop-io/sui-kit");
4347
+ var import_sui_kit5 = require("@scallop-io/sui-kit");
4269
4348
 
4270
4349
  // src/builders/oracle.ts
4271
4350
  var import_utils11 = require("@mysten/sui.js/utils");
@@ -4435,6 +4514,8 @@ var generateCoreNormalMethod = ({
4435
4514
  coinDecimalsRegistry: builder.address.get("core.coinDecimalsRegistry"),
4436
4515
  xOracle: builder.address.get("core.oracles.xOracle")
4437
4516
  };
4517
+ const referralPkgId = builder.address.get("referral.id");
4518
+ const referralWitnessType = `${referralPkgId}::scallop_referral_program::REFERRAL_WITNESS`;
4438
4519
  return {
4439
4520
  openObligation: () => txBlock.moveCall(
4440
4521
  `${coreIds.protocolPkg}::open_obligation::open_obligation`,
@@ -4522,6 +4603,24 @@ var generateCoreNormalMethod = ({
4522
4603
  [coinType]
4523
4604
  );
4524
4605
  },
4606
+ borrowWithReferral: (obligation, obligationKey, borrowReferral, amount, poolCoinName) => {
4607
+ const coinType = builder.utils.parseCoinType(poolCoinName);
4608
+ return txBlock.moveCall(
4609
+ `${coreIds.protocolPkg}::borrow::borrow_with_referral`,
4610
+ [
4611
+ coreIds.version,
4612
+ obligation,
4613
+ obligationKey,
4614
+ coreIds.market,
4615
+ coreIds.coinDecimalsRegistry,
4616
+ borrowReferral,
4617
+ amount,
4618
+ coreIds.xOracle,
4619
+ import_utils12.SUI_CLOCK_OBJECT_ID
4620
+ ],
4621
+ [coinType, referralWitnessType]
4622
+ );
4623
+ },
4525
4624
  borrowEntry: (obligation, obligationKey, amount, poolCoinName) => {
4526
4625
  const coinType = builder.utils.parseCoinType(poolCoinName);
4527
4626
  return txBlock.moveCall(
@@ -4662,6 +4761,26 @@ var generateCoreQuickMethod = ({
4662
4761
  poolCoinName
4663
4762
  );
4664
4763
  },
4764
+ borrowWithReferralQuick: async (amount, poolCoinName, borrowReferral, obligationId, obligationKey) => {
4765
+ const obligationInfo = await requireObligationInfo(
4766
+ builder,
4767
+ txBlock,
4768
+ obligationId,
4769
+ obligationKey
4770
+ );
4771
+ const obligationCoinNames = await builder.utils.getObligationCoinNames(
4772
+ obligationInfo.obligationId
4773
+ );
4774
+ const updateCoinNames = [...obligationCoinNames, poolCoinName];
4775
+ await updateOracles(builder, txBlock, updateCoinNames);
4776
+ return txBlock.borrowWithReferral(
4777
+ obligationInfo.obligationId,
4778
+ obligationInfo.obligationKey,
4779
+ borrowReferral,
4780
+ amount,
4781
+ poolCoinName
4782
+ );
4783
+ },
4665
4784
  repayQuick: async (amount, poolCoinName, obligationId) => {
4666
4785
  const sender = requireSender(txBlock);
4667
4786
  const obligationInfo = await requireObligationInfo(
@@ -4697,7 +4816,7 @@ var generateCoreQuickMethod = ({
4697
4816
  };
4698
4817
  };
4699
4818
  var newCoreTxBlock = (builder, initTxBlock) => {
4700
- const txBlock = initTxBlock instanceof import_transactions.TransactionBlock ? new import_sui_kit4.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit4.SuiTxBlock();
4819
+ const txBlock = initTxBlock instanceof import_transactions.TransactionBlock ? new import_sui_kit5.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit5.SuiTxBlock();
4701
4820
  const normalMethod = generateCoreNormalMethod({
4702
4821
  builder,
4703
4822
  txBlock
@@ -4727,7 +4846,7 @@ var newCoreTxBlock = (builder, initTxBlock) => {
4727
4846
  // src/builders/spoolBuilder.ts
4728
4847
  var import_transactions2 = require("@mysten/sui.js/transactions");
4729
4848
  var import_utils14 = require("@mysten/sui.js/utils");
4730
- var import_sui_kit5 = require("@scallop-io/sui-kit");
4849
+ var import_sui_kit6 = require("@scallop-io/sui-kit");
4731
4850
  var requireStakeAccountIds = async (...params) => {
4732
4851
  const [builder, txBlock, stakeMarketCoinName, stakeAccountId] = params;
4733
4852
  if (params.length === 4 && stakeAccountId)
@@ -4885,7 +5004,7 @@ var generateSpoolQuickMethod = ({
4885
5004
  };
4886
5005
  };
4887
5006
  var newSpoolTxBlock = (builder, initTxBlock) => {
4888
- const txBlock = initTxBlock instanceof import_transactions2.TransactionBlock ? new import_sui_kit5.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit5.SuiTxBlock();
5007
+ const txBlock = initTxBlock instanceof import_transactions2.TransactionBlock ? new import_sui_kit6.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit6.SuiTxBlock();
4889
5008
  const normalMethod = generateSpoolNormalMethod({
4890
5009
  builder,
4891
5010
  txBlock
@@ -4915,10 +5034,10 @@ var newSpoolTxBlock = (builder, initTxBlock) => {
4915
5034
  // src/builders/borrowIncentiveBuilder.ts
4916
5035
  var import_transactions3 = require("@mysten/sui.js/transactions");
4917
5036
  var import_utils17 = require("@mysten/sui.js/utils");
4918
- var import_sui_kit7 = require("@scallop-io/sui-kit");
5037
+ var import_sui_kit8 = require("@scallop-io/sui-kit");
4919
5038
 
4920
5039
  // src/builders/vescaBuilder.ts
4921
- var import_sui_kit6 = require("@scallop-io/sui-kit");
5040
+ var import_sui_kit7 = require("@scallop-io/sui-kit");
4922
5041
  var requireVeSca = async (...params) => {
4923
5042
  const [builder, txBlock, veScaKey] = params;
4924
5043
  if (params.length === 3 && veScaKey && typeof veScaKey === "string") {
@@ -4933,10 +5052,7 @@ var requireVeSca = async (...params) => {
4933
5052
  if (veScas.length === 0) {
4934
5053
  return void 0;
4935
5054
  }
4936
- return veScas.reduce(
4937
- (prev, acc) => acc.currentVeScaBalance > prev.currentVeScaBalance ? acc : prev,
4938
- veScas[0]
4939
- );
5055
+ return veScas[0];
4940
5056
  };
4941
5057
  var generateNormalVeScaMethod = ({
4942
5058
  builder,
@@ -4958,7 +5074,7 @@ var generateNormalVeScaMethod = ({
4958
5074
  veScaIds.treasury,
4959
5075
  scaCoin,
4960
5076
  unlockAtInSecondTimestamp,
4961
- import_sui_kit6.SUI_CLOCK_OBJECT_ID
5077
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4962
5078
  ],
4963
5079
  []
4964
5080
  );
@@ -4972,7 +5088,7 @@ var generateNormalVeScaMethod = ({
4972
5088
  veScaIds.table,
4973
5089
  veScaIds.treasury,
4974
5090
  newUnlockAtInSecondTimestamp,
4975
- import_sui_kit6.SUI_CLOCK_OBJECT_ID
5091
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4976
5092
  ],
4977
5093
  []
4978
5094
  );
@@ -4986,7 +5102,7 @@ var generateNormalVeScaMethod = ({
4986
5102
  veScaIds.table,
4987
5103
  veScaIds.treasury,
4988
5104
  scaCoin,
4989
- import_sui_kit6.SUI_CLOCK_OBJECT_ID
5105
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4990
5106
  ],
4991
5107
  []
4992
5108
  );
@@ -5001,7 +5117,7 @@ var generateNormalVeScaMethod = ({
5001
5117
  veScaIds.treasury,
5002
5118
  scaCoin,
5003
5119
  newUnlockAtInSecondTimestamp,
5004
- import_sui_kit6.SUI_CLOCK_OBJECT_ID
5120
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
5005
5121
  ],
5006
5122
  []
5007
5123
  );
@@ -5014,10 +5130,17 @@ var generateNormalVeScaMethod = ({
5014
5130
  veScaKey,
5015
5131
  veScaIds.table,
5016
5132
  veScaIds.treasury,
5017
- import_sui_kit6.SUI_CLOCK_OBJECT_ID
5133
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
5018
5134
  ],
5019
5135
  []
5020
5136
  );
5137
+ },
5138
+ mintEmptyVeSca: () => {
5139
+ return txBlock.moveCall(
5140
+ `${veScaIds.pkgId}::ve_sca::mint_ve_sca_placeholder_key`,
5141
+ [veScaIds.config, veScaIds.table],
5142
+ []
5143
+ );
5021
5144
  }
5022
5145
  };
5023
5146
  };
@@ -5160,7 +5283,7 @@ var generateQuickVeScaMethod = ({
5160
5283
  };
5161
5284
  };
5162
5285
  var newVeScaTxBlock = (builder, initTxBlock) => {
5163
- const txBlock = initTxBlock instanceof import_sui_kit6.TransactionBlock ? new import_sui_kit6.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit6.SuiTxBlock();
5286
+ const txBlock = initTxBlock instanceof import_sui_kit7.TransactionBlock ? new import_sui_kit7.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit7.SuiTxBlock();
5164
5287
  const normalMethod = generateNormalVeScaMethod({
5165
5288
  builder,
5166
5289
  txBlock
@@ -5213,7 +5336,7 @@ var requireObligationInfo2 = async (...params) => {
5213
5336
  };
5214
5337
  var generateBorrowIncentiveNormalMethod = ({ builder, txBlock }) => {
5215
5338
  const borrowIncentiveIds = {
5216
- borrowIncentivePkg: IS_VE_SCA_TEST ? "0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246" : builder.address.get("borrowIncentive.id"),
5339
+ borrowIncentivePkg: builder.address.get("borrowIncentive.id"),
5217
5340
  query: builder.address.get("borrowIncentive.query"),
5218
5341
  config: builder.address.get("borrowIncentive.config"),
5219
5342
  incentivePools: builder.address.get("borrowIncentive.incentivePools"),
@@ -5322,9 +5445,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
5322
5445
  obligationKey
5323
5446
  );
5324
5447
  const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
5325
- (txn) => txn.kind === "MoveCall" && (txn.target === `${OLD_BORROW_INCENTIVE_PROTOCOL_ID}::user::unstake` || txn.target === (IS_VE_SCA_TEST ? `${"0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246"}::user::unstake` : `${builder.address.get(
5326
- "borrowIncentive.id"
5327
- )}::user::unstake`))
5448
+ (txn) => txn.kind === "MoveCall" && (txn.target === `${OLD_BORROW_INCENTIVE_PROTOCOL_ID}::user::unstake` || txn.target === `${builder.address.get("borrowIncentive.id")}::user::unstake`)
5328
5449
  );
5329
5450
  if (!obligationLocked || unstakeObligationBeforeStake) {
5330
5451
  txBlock.stakeObligation(obligationArg, obligationtKeyArg);
@@ -5342,9 +5463,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
5342
5463
  obligationKey
5343
5464
  );
5344
5465
  const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
5345
- (txn) => txn.kind === "MoveCall" && (txn.target === `${OLD_BORROW_INCENTIVE_PROTOCOL_ID}::user::unstake` || txn.target === (IS_VE_SCA_TEST ? `${"0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246"}::user::unstake` : `${builder.address.get(
5346
- "borrowIncentive.id"
5347
- )}::user::unstake`))
5466
+ (txn) => txn.kind === "MoveCall" && (txn.target === `${OLD_BORROW_INCENTIVE_PROTOCOL_ID}::user::unstake` || txn.target === `${builder.address.get("borrowIncentive.id")}::user::unstake`)
5348
5467
  );
5349
5468
  if (!obligationLocked || unstakeObligationBeforeStake) {
5350
5469
  const veSca = await requireVeSca(builder, txBlock, veScaKey);
@@ -5353,7 +5472,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
5353
5472
  builder.query,
5354
5473
  veSca.keyId
5355
5474
  );
5356
- if (!bindedObligationId || bindedObligationId === obligationArg) {
5475
+ if ((!bindedObligationId || bindedObligationId === obligationArg) && veSca.currentVeScaBalance > 0) {
5357
5476
  txBlock.stakeObligationWithVesca(
5358
5477
  obligationArg,
5359
5478
  obligationtKeyArg,
@@ -5402,7 +5521,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
5402
5521
  };
5403
5522
  };
5404
5523
  var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
5405
- const txBlock = initTxBlock instanceof import_transactions3.TransactionBlock ? new import_sui_kit7.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit7.SuiTxBlock();
5524
+ const txBlock = initTxBlock instanceof import_transactions3.TransactionBlock ? new import_sui_kit8.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit8.SuiTxBlock();
5406
5525
  const normalMethod = generateBorrowIncentiveNormalMethod({
5407
5526
  builder,
5408
5527
  txBlock
@@ -5429,6 +5548,138 @@ var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
5429
5548
  });
5430
5549
  };
5431
5550
 
5551
+ // src/builders/referralBuilder.ts
5552
+ var import_sui_kit9 = require("@scallop-io/sui-kit");
5553
+ var generateReferralNormalMethod = ({
5554
+ builder,
5555
+ txBlock
5556
+ }) => {
5557
+ const referralIds = {
5558
+ referralPgkId: builder.address.get("referral.id"),
5559
+ referralBindings: builder.address.get("referral.referralBindings"),
5560
+ referralRevenuePool: builder.address.get("referral.referralRevenuePool"),
5561
+ authorizedWitnessList: builder.address.get(
5562
+ "referral.authorizedWitnessList"
5563
+ ),
5564
+ referralTiers: builder.address.get("referral.referralTiers"),
5565
+ version: builder.address.get("referral.version")
5566
+ };
5567
+ const veScaTable = builder.address.get("vesca.table");
5568
+ return {
5569
+ bindToReferral: (veScaKeyId) => {
5570
+ return txBlock.moveCall(
5571
+ `${referralIds.referralPgkId}::referral_bindings::bind_ve_sca_referrer`,
5572
+ [
5573
+ referralIds.referralBindings,
5574
+ txBlock.pure(veScaKeyId),
5575
+ veScaTable,
5576
+ import_sui_kit9.SUI_CLOCK_OBJECT_ID
5577
+ ],
5578
+ []
5579
+ );
5580
+ },
5581
+ claimReferralTicket: (poolCoinName) => {
5582
+ const coinType = builder.utils.parseCoinType(poolCoinName);
5583
+ return txBlock.moveCall(
5584
+ `${referralIds.referralPgkId}::scallop_referral_program::claim_ve_sca_referral_ticket`,
5585
+ [
5586
+ referralIds.version,
5587
+ veScaTable,
5588
+ referralIds.referralBindings,
5589
+ referralIds.authorizedWitnessList,
5590
+ referralIds.referralTiers,
5591
+ import_sui_kit9.SUI_CLOCK_OBJECT_ID
5592
+ ],
5593
+ [coinType]
5594
+ );
5595
+ },
5596
+ burnReferralTicket: (ticket, poolCoinName) => {
5597
+ const coinType = builder.utils.parseCoinType(poolCoinName);
5598
+ return txBlock.moveCall(
5599
+ `${referralIds.referralPgkId}::scallop_referral_program::burn_ve_sca_referral_ticket`,
5600
+ [
5601
+ referralIds.version,
5602
+ ticket,
5603
+ referralIds.referralRevenuePool,
5604
+ import_sui_kit9.SUI_CLOCK_OBJECT_ID
5605
+ ],
5606
+ [coinType]
5607
+ );
5608
+ },
5609
+ claimReferralRevenue: (veScaKey, poolCoinName) => {
5610
+ const coinType = builder.utils.parseCoinType(poolCoinName);
5611
+ return txBlock.moveCall(
5612
+ `${referralIds.referralPgkId}::referral_revenue_pool::claim_revenue_with_ve_sca_key`,
5613
+ [
5614
+ referralIds.version,
5615
+ referralIds.referralRevenuePool,
5616
+ veScaKey,
5617
+ import_sui_kit9.SUI_CLOCK_OBJECT_ID
5618
+ ],
5619
+ [coinType]
5620
+ );
5621
+ }
5622
+ };
5623
+ };
5624
+ var generateReferralQuickMethod = ({
5625
+ builder,
5626
+ txBlock
5627
+ }) => {
5628
+ return {
5629
+ claimReferralRevenueQuick: async (veScaKey, coinNames = [...SUPPORT_POOLS]) => {
5630
+ const sender = requireSender(txBlock);
5631
+ const objToTransfer = [];
5632
+ for (const coinName of coinNames) {
5633
+ if (coinName === "sui") {
5634
+ const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
5635
+ objToTransfer.push(rewardCoin);
5636
+ } else {
5637
+ const coins = await builder.suiKit.suiInteractor.selectCoins(
5638
+ sender,
5639
+ Infinity,
5640
+ builder.utils.parseCoinType(coinName)
5641
+ );
5642
+ const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
5643
+ if (coins.length > 0) {
5644
+ txBlock.mergeCoins(rewardCoin, coins);
5645
+ }
5646
+ objToTransfer.push(rewardCoin);
5647
+ }
5648
+ }
5649
+ if (objToTransfer.length > 0) {
5650
+ txBlock.transferObjects(objToTransfer, sender);
5651
+ }
5652
+ }
5653
+ };
5654
+ };
5655
+ var newReferralTxBlock = (builder, initTxBlock) => {
5656
+ const txBlock = initTxBlock instanceof import_sui_kit9.TransactionBlock ? new import_sui_kit9.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit9.SuiTxBlock();
5657
+ const normalMethod = generateReferralNormalMethod({
5658
+ builder,
5659
+ txBlock
5660
+ });
5661
+ const normalTxBlock = new Proxy(txBlock, {
5662
+ get: (target, prop) => {
5663
+ if (prop in normalMethod) {
5664
+ return Reflect.get(normalMethod, prop);
5665
+ }
5666
+ return Reflect.get(target, prop);
5667
+ }
5668
+ });
5669
+ const quickMethod = generateReferralQuickMethod({
5670
+ builder,
5671
+ txBlock: normalTxBlock
5672
+ });
5673
+ return new Proxy(normalTxBlock, {
5674
+ get: (target, prop) => {
5675
+ if (prop in quickMethod) {
5676
+ return Reflect.get(quickMethod, prop);
5677
+ }
5678
+ return Reflect.get(target, prop);
5679
+ }
5680
+ });
5681
+ };
5682
+
5432
5683
  // src/builders/index.ts
5433
5684
  var newScallopTxBlock = (builder, initTxBlock) => {
5434
5685
  const vescaTxBlock = newVeScaTxBlock(builder, initTxBlock);
@@ -5436,7 +5687,8 @@ var newScallopTxBlock = (builder, initTxBlock) => {
5436
5687
  builder,
5437
5688
  vescaTxBlock
5438
5689
  );
5439
- const spoolTxBlock = newSpoolTxBlock(builder, borrowIncentiveTxBlock);
5690
+ const referralTxBlock = newReferralTxBlock(builder, borrowIncentiveTxBlock);
5691
+ const spoolTxBlock = newSpoolTxBlock(builder, referralTxBlock);
5440
5692
  const coreTxBlock = newCoreTxBlock(builder, spoolTxBlock);
5441
5693
  return new Proxy(coreTxBlock, {
5442
5694
  get: (target, prop) => {
@@ -5444,6 +5696,8 @@ var newScallopTxBlock = (builder, initTxBlock) => {
5444
5696
  return Reflect.get(vescaTxBlock, prop);
5445
5697
  } else if (prop in borrowIncentiveTxBlock) {
5446
5698
  return Reflect.get(borrowIncentiveTxBlock, prop);
5699
+ } else if (prop in referralTxBlock) {
5700
+ return Reflect.get(referralTxBlock, prop);
5447
5701
  } else if (prop in spoolTxBlock) {
5448
5702
  return Reflect.get(spoolTxBlock, prop);
5449
5703
  }
@@ -5456,7 +5710,7 @@ var newScallopTxBlock = (builder, initTxBlock) => {
5456
5710
  var ScallopBuilder = class {
5457
5711
  constructor(params, instance) {
5458
5712
  this.params = params;
5459
- this.suiKit = instance?.suiKit ?? new import_sui_kit8.SuiKit(params);
5713
+ this.suiKit = instance?.suiKit ?? new import_sui_kit10.SuiKit(params);
5460
5714
  this.cache = instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
5461
5715
  this.address = instance?.address ?? new ScallopAddress(
5462
5716
  {
@@ -5476,7 +5730,7 @@ var ScallopBuilder = class {
5476
5730
  query: this.query,
5477
5731
  cache: this.cache
5478
5732
  });
5479
- this.walletAddress = (0, import_utils19.normalizeSuiAddress)(
5733
+ this.walletAddress = (0, import_utils20.normalizeSuiAddress)(
5480
5734
  params?.walletAddress || this.suiKit.currentAddress()
5481
5735
  );
5482
5736
  this.isTestnet = params.networkType ? params.networkType === "testnet" : false;
@@ -5555,7 +5809,7 @@ var ScallopBuilder = class {
5555
5809
  var ScallopClient = class {
5556
5810
  constructor(params, instance) {
5557
5811
  this.params = params;
5558
- this.suiKit = instance?.suiKit ?? new import_sui_kit9.SuiKit(params);
5812
+ this.suiKit = instance?.suiKit ?? new import_sui_kit11.SuiKit(params);
5559
5813
  this.cache = instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
5560
5814
  this.address = instance?.address ?? new ScallopAddress(
5561
5815
  {
@@ -5582,7 +5836,7 @@ var ScallopClient = class {
5582
5836
  utils: this.utils,
5583
5837
  cache: this.cache
5584
5838
  });
5585
- this.walletAddress = (0, import_utils20.normalizeSuiAddress)(
5839
+ this.walletAddress = (0, import_utils21.normalizeSuiAddress)(
5586
5840
  params?.walletAddress || this.suiKit.currentAddress()
5587
5841
  );
5588
5842
  }
@@ -6088,7 +6342,7 @@ var ScallopClient = class {
6088
6342
  var Scallop = class {
6089
6343
  constructor(params, cacheOptions) {
6090
6344
  this.params = params;
6091
- this.suiKit = new import_sui_kit10.SuiKit(params);
6345
+ this.suiKit = new import_sui_kit12.SuiKit(params);
6092
6346
  this.cache = new ScallopCache(
6093
6347
  cacheOptions ?? DEFAULT_CACHE_OPTIONS,
6094
6348
  this.suiKit