@scallop-io/sui-scallop-sdk 0.44.18 → 0.44.19

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 (56) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +7 -0
  2. package/dist/builders/vescaBuilder.d.ts +24 -0
  3. package/dist/constants/common.d.ts +7 -4
  4. package/dist/constants/index.d.ts +1 -0
  5. package/dist/constants/vesca.d.ts +5 -0
  6. package/dist/index.js +874 -254
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +863 -247
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/models/scallopClient.d.ts +7 -7
  11. package/dist/models/scallopUtils.d.ts +16 -14
  12. package/dist/queries/index.d.ts +1 -0
  13. package/dist/queries/vescaQuery.d.ts +28 -0
  14. package/dist/types/address.d.ts +9 -0
  15. package/dist/types/builder/borrowIncentive.d.ts +9 -6
  16. package/dist/types/builder/index.d.ts +3 -1
  17. package/dist/types/builder/vesca.d.ts +33 -0
  18. package/dist/types/constant/enum.d.ts +1 -1
  19. package/dist/types/query/borrowIncentive.d.ts +65 -60
  20. package/dist/types/query/index.d.ts +1 -0
  21. package/dist/types/query/portfolio.d.ts +12 -6
  22. package/dist/types/query/vesca.d.ts +7 -0
  23. package/dist/types/utils.d.ts +1 -2
  24. package/dist/utils/builder.d.ts +6 -0
  25. package/dist/utils/query.d.ts +4 -10
  26. package/dist/utils/util.d.ts +7 -0
  27. package/package.json +1 -1
  28. package/src/builders/borrowIncentiveBuilder.ts +174 -25
  29. package/src/builders/index.ts +6 -2
  30. package/src/builders/vescaBuilder.ts +392 -0
  31. package/src/constants/common.ts +19 -6
  32. package/src/constants/enum.ts +9 -3
  33. package/src/constants/index.ts +1 -0
  34. package/src/constants/vesca.ts +7 -0
  35. package/src/models/scallopAddress.ts +9 -1
  36. package/src/models/scallopClient.ts +29 -20
  37. package/src/models/scallopUtils.ts +45 -0
  38. package/src/queries/borrowIncentiveQuery.ts +93 -83
  39. package/src/queries/coreQuery.ts +19 -20
  40. package/src/queries/index.ts +1 -0
  41. package/src/queries/portfolioQuery.ts +79 -41
  42. package/src/queries/spoolQuery.ts +1 -1
  43. package/src/queries/vescaQuery.ts +124 -0
  44. package/src/types/address.ts +9 -0
  45. package/src/types/builder/borrowIncentive.ts +22 -5
  46. package/src/types/builder/index.ts +4 -1
  47. package/src/types/builder/vesca.ts +73 -0
  48. package/src/types/constant/enum.ts +1 -1
  49. package/src/types/query/borrowIncentive.ts +195 -74
  50. package/src/types/query/index.ts +1 -0
  51. package/src/types/query/portfolio.ts +17 -6
  52. package/src/types/query/vesca.ts +7 -0
  53. package/src/types/utils.ts +1 -1
  54. package/src/utils/builder.ts +141 -0
  55. package/src/utils/query.ts +221 -130
  56. package/src/utils/util.ts +28 -0
package/dist/index.js CHANGED
@@ -33,7 +33,14 @@ __export(src_exports, {
33
33
  ADDRESSES_ID: () => ADDRESSES_ID,
34
34
  API_BASE_URL: () => API_BASE_URL,
35
35
  BORROW_FEE_PROTOCOL_ID: () => BORROW_FEE_PROTOCOL_ID,
36
+ IS_VE_SCA_TEST: () => IS_VE_SCA_TEST,
37
+ MAX_LOCK_DURATION: () => MAX_LOCK_DURATION,
38
+ MAX_LOCK_ROUNDS: () => MAX_LOCK_ROUNDS,
39
+ MIN_INITIAL_LOCK_AMOUNT: () => MIN_INITIAL_LOCK_AMOUNT,
40
+ MIN_TOP_UP_AMOUNT: () => MIN_TOP_UP_AMOUNT,
41
+ OLD_BORROW_INCENTIVE_PROTOCOL_ID: () => OLD_BORROW_INCENTIVE_PROTOCOL_ID,
36
42
  PROTOCOL_OBJECT_ID: () => PROTOCOL_OBJECT_ID,
43
+ SCA_COIN_TYPE: () => SCA_COIN_TYPE,
37
44
  SDK_API_BASE_URL: () => SDK_API_BASE_URL,
38
45
  SUPPORT_BORROW_INCENTIVE_POOLS: () => SUPPORT_BORROW_INCENTIVE_POOLS,
39
46
  SUPPORT_BORROW_INCENTIVE_REWARDS: () => SUPPORT_BORROW_INCENTIVE_REWARDS,
@@ -50,6 +57,7 @@ __export(src_exports, {
50
57
  ScallopIndexer: () => ScallopIndexer,
51
58
  ScallopQuery: () => ScallopQuery,
52
59
  ScallopUtils: () => ScallopUtils,
60
+ UNLOCK_ROUND_DURATION: () => UNLOCK_ROUND_DURATION,
53
61
  assetCoins: () => assetCoins,
54
62
  borrowIncentiveRewardCoins: () => borrowIncentiveRewardCoins,
55
63
  coinDecimals: () => coinDecimals,
@@ -65,9 +73,12 @@ module.exports = __toCommonJS(src_exports);
65
73
  // src/constants/common.ts
66
74
  var API_BASE_URL = "https://sui.api.scallop.io";
67
75
  var SDK_API_BASE_URL = "https://sdk.api.scallop.io";
68
- var ADDRESSES_ID = "6462a088a7ace142bb6d7e9b";
69
- var PROTOCOL_OBJECT_ID = "0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf";
70
- var BORROW_FEE_PROTOCOL_ID = "0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da";
76
+ var IS_VE_SCA_TEST = false;
77
+ var ADDRESSES_ID = IS_VE_SCA_TEST ? "65fb07c39c845425d71d7b18" : "6601955b8b0024600a917079";
78
+ var PROTOCOL_OBJECT_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf";
79
+ var BORROW_FEE_PROTOCOL_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da";
80
+ var SCA_COIN_TYPE = IS_VE_SCA_TEST ? `0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524::sca::SCA` : "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA";
81
+ var OLD_BORROW_INCENTIVE_PROTOCOL_ID = "0xc63072e7f5f4983a2efaf5bdba1480d5e7d74d57948e1c7cc436f8e22cbeb410";
71
82
  var SUPPORT_POOLS = [
72
83
  "eth",
73
84
  "btc",
@@ -106,7 +117,7 @@ var SUPPORT_SPOOLS = [
106
117
  ];
107
118
  var SUPPORT_SPOOLS_REWARDS = ["sui"];
108
119
  var SUPPORT_BORROW_INCENTIVE_POOLS = ["sui", "usdc", "usdt"];
109
- var SUPPORT_BORROW_INCENTIVE_REWARDS = ["sui"];
120
+ var SUPPORT_BORROW_INCENTIVE_REWARDS = ["sui", "sca"];
110
121
  var SUPPORT_ORACLES = ["supra", "switchboard", "pyth"];
111
122
  var SUPPORT_PACKAGES = [
112
123
  "coinDecimalsRegistry",
@@ -146,7 +157,8 @@ var coinDecimals = {
146
157
  scetus: 9,
147
158
  safsui: 9,
148
159
  shasui: 9,
149
- svsui: 9
160
+ svsui: 9,
161
+ sca: 9
150
162
  };
151
163
  var assetCoins = {
152
164
  eth: "eth",
@@ -159,7 +171,8 @@ var assetCoins = {
159
171
  cetus: "cetus",
160
172
  afsui: "afsui",
161
173
  hasui: "hasui",
162
- vsui: "vsui"
174
+ vsui: "vsui",
175
+ sca: "sca"
163
176
  };
164
177
  var marketCoins = {
165
178
  seth: "seth",
@@ -195,9 +208,9 @@ var spoolRewardCoins = {
195
208
  svsui: "sui"
196
209
  };
197
210
  var borrowIncentiveRewardCoins = {
198
- sui: "sui",
199
- usdc: "sui",
200
- usdt: "sui"
211
+ sui: ["sui", "sca"],
212
+ usdc: ["sui", "sca"],
213
+ usdt: ["sui", "sca"]
201
214
  };
202
215
  var coinIds = {
203
216
  sui: "0x0000000000000000000000000000000000000000000000000000000000000002",
@@ -210,7 +223,8 @@ var coinIds = {
210
223
  cetus: "0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b",
211
224
  afsui: "0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc",
212
225
  hasui: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d",
213
- vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55"
226
+ vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55",
227
+ sca: IS_VE_SCA_TEST ? "0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524" : "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6"
214
228
  };
215
229
  var wormholeCoinIds = {
216
230
  eth: "0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5",
@@ -224,8 +238,15 @@ var voloCoinIds = {
224
238
  vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55"
225
239
  };
226
240
 
241
+ // src/constants/vesca.ts
242
+ var UNLOCK_ROUND_DURATION = 60 * 60 * 24;
243
+ var MAX_LOCK_ROUNDS = 1460;
244
+ var MAX_LOCK_DURATION = MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION;
245
+ var MIN_INITIAL_LOCK_AMOUNT = 1e10;
246
+ var MIN_TOP_UP_AMOUNT = 1e9;
247
+
227
248
  // src/models/scallop.ts
228
- var import_sui_kit10 = require("@scallop-io/sui-kit");
249
+ var import_sui_kit11 = require("@scallop-io/sui-kit");
229
250
 
230
251
  // src/models/scallopAddress.ts
231
252
  var import_axios = __toESM(require("axios"));
@@ -452,8 +473,17 @@ var EMPTY_ADDRESSES = {
452
473
  adminCap: "",
453
474
  object: "",
454
475
  query: "",
476
+ config: "",
455
477
  incentivePools: "",
456
478
  incentiveAccounts: ""
479
+ },
480
+ vesca: {
481
+ id: "",
482
+ adminCap: "",
483
+ tableId: "",
484
+ table: "",
485
+ treasury: "",
486
+ config: ""
457
487
  }
458
488
  };
459
489
  var ScallopAddress = class {
@@ -757,8 +787,8 @@ var ScallopAddress = class {
757
787
  };
758
788
 
759
789
  // src/models/scallopClient.ts
760
- var import_utils19 = require("@mysten/sui.js/utils");
761
- var import_sui_kit9 = require("@scallop-io/sui-kit");
790
+ var import_utils20 = require("@mysten/sui.js/utils");
791
+ var import_sui_kit10 = require("@scallop-io/sui-kit");
762
792
 
763
793
  // src/models/scallopUtils.ts
764
794
  var import_utils9 = require("@mysten/sui.js/utils");
@@ -781,6 +811,92 @@ var requireSender = (txBlock) => {
781
811
  }
782
812
  return sender;
783
813
  };
814
+ var checkLockSca = (scaAmountOrCoin, lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInSecondTimestamp) => {
815
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
816
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
817
+ if (isInitialLock || isLockExpired) {
818
+ if (scaAmountOrCoin !== void 0 && lockPeriodInDays !== void 0) {
819
+ if (lockPeriodInDays <= 0) {
820
+ throw new Error("Lock period must be greater than 0");
821
+ }
822
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_INITIAL_LOCK_AMOUNT) {
823
+ throw new Error(
824
+ `Minimum lock amount for ${isLockExpired ? "renewing expired veSca" : "initial lock"} is 10 SCA`
825
+ );
826
+ }
827
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
828
+ if (extendLockPeriodInSecond > MAX_LOCK_DURATION) {
829
+ throw new Error(
830
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days)`
831
+ );
832
+ }
833
+ } else {
834
+ throw new Error(
835
+ `SCA amount and lock period is required for ${isLockExpired ? "renewing expired veSca" : "initial lock"}`
836
+ );
837
+ }
838
+ } else {
839
+ checkVesca(prevUnlockAtInSecondTimestamp);
840
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_TOP_UP_AMOUNT) {
841
+ throw new Error("Minimum top up amount is 1 SCA");
842
+ }
843
+ if (!!newUnlockAtInSecondTimestamp && !!prevUnlockAtInSecondTimestamp) {
844
+ const totalLockDuration = newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp;
845
+ if (totalLockDuration > MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
846
+ throw new Error(
847
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
848
+ );
849
+ }
850
+ }
851
+ }
852
+ };
853
+ var checkExtendLockPeriod = (lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInSecondTimestamp) => {
854
+ checkVesca(prevUnlockAtInSecondTimestamp);
855
+ if (lockPeriodInDays <= 0) {
856
+ throw new Error("Lock period must be greater than 0");
857
+ }
858
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
859
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
860
+ if (isLockExpired) {
861
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
862
+ }
863
+ if (prevUnlockAtInSecondTimestamp) {
864
+ const totalLockDuration = newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp;
865
+ if (totalLockDuration > MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
866
+ throw new Error(
867
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
868
+ );
869
+ }
870
+ }
871
+ };
872
+ var checkExtendLockAmount = (scaAmount, prevUnlockAtInSecondTimestamp) => {
873
+ checkVesca(prevUnlockAtInSecondTimestamp);
874
+ if (scaAmount < MIN_TOP_UP_AMOUNT) {
875
+ throw new Error("Minimum top up amount is 1 SCA");
876
+ }
877
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
878
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
879
+ if (isLockExpired) {
880
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
881
+ }
882
+ };
883
+ var checkRenewExpiredVeSca = (scaAmount, lockPeriodInDays, prevUnlockAtInSecondTimestamp) => {
884
+ checkVesca(prevUnlockAtInSecondTimestamp);
885
+ if (scaAmount < MIN_INITIAL_LOCK_AMOUNT) {
886
+ throw new Error("Minimum lock amount for renewing expired vesca 10 SCA");
887
+ }
888
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
889
+ if (extendLockPeriodInSecond >= MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
890
+ throw new Error(
891
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
892
+ );
893
+ }
894
+ };
895
+ var checkVesca = (prevUnlockAtInSecondTimestamp) => {
896
+ if (prevUnlockAtInSecondTimestamp === void 0) {
897
+ throw new Error("veSca not found");
898
+ }
899
+ };
784
900
 
785
901
  // src/utils/query.ts
786
902
  var import_bignumber = __toESM(require("bignumber.js"));
@@ -1018,119 +1134,112 @@ var calculateSpoolRewardPoolData = (parsedSpoolData, parsedSpoolRewardPoolData,
1018
1134
  rewardPerSec: rewardPerSec.toNumber()
1019
1135
  };
1020
1136
  };
1137
+ var parseOriginBorrowIncentivesPoolPointData = (originBorrowIncentivePoolPointData) => {
1138
+ return {
1139
+ pointType: (0, import_utils.normalizeStructTag)(
1140
+ originBorrowIncentivePoolPointData.point_type.name
1141
+ ),
1142
+ distributedPointPerPeriod: Number(
1143
+ originBorrowIncentivePoolPointData.distributed_point_per_period
1144
+ ),
1145
+ period: Number(originBorrowIncentivePoolPointData.point_distribution_time),
1146
+ distributedPoint: Number(
1147
+ originBorrowIncentivePoolPointData.distributed_point
1148
+ ),
1149
+ points: Number(originBorrowIncentivePoolPointData.points),
1150
+ index: Number(originBorrowIncentivePoolPointData.index),
1151
+ baseWeight: Number(originBorrowIncentivePoolPointData.base_weight),
1152
+ weightedAmount: Number(originBorrowIncentivePoolPointData.weighted_amount),
1153
+ lastUpdate: Number(originBorrowIncentivePoolPointData.last_update)
1154
+ };
1155
+ };
1021
1156
  var parseOriginBorrowIncentivePoolData = (originBorrowIncentivePoolData) => {
1022
1157
  return {
1023
1158
  poolType: (0, import_utils.normalizeStructTag)(originBorrowIncentivePoolData.pool_type.name),
1024
- maxPoint: Number(originBorrowIncentivePoolData.max_distributed_point),
1025
- distributedPoint: Number(originBorrowIncentivePoolData.distributed_point),
1026
- pointPerPeriod: Number(
1027
- originBorrowIncentivePoolData.distributed_point_per_period
1028
- ),
1029
- period: Number(originBorrowIncentivePoolData.point_distribution_time),
1030
- maxStake: Number(originBorrowIncentivePoolData.max_stakes),
1159
+ minStakes: Number(originBorrowIncentivePoolData.min_stakes),
1160
+ maxStakes: Number(originBorrowIncentivePoolData.max_stakes),
1031
1161
  staked: Number(originBorrowIncentivePoolData.stakes),
1032
- index: Number(originBorrowIncentivePoolData.index),
1033
1162
  createdAt: Number(originBorrowIncentivePoolData.created_at),
1034
- lastUpdate: Number(originBorrowIncentivePoolData.last_update)
1163
+ poolPoints: originBorrowIncentivePoolData.points.reduce(
1164
+ (acc, point) => {
1165
+ const parsed = parseOriginBorrowIncentivesPoolPointData(point);
1166
+ const name = (0, import_utils.parseStructTag)(
1167
+ parsed.pointType
1168
+ ).name.toLowerCase();
1169
+ acc[name] = parsed;
1170
+ return acc;
1171
+ },
1172
+ {}
1173
+ )
1035
1174
  };
1036
1175
  };
1037
- var calculateBorrowIncentivePoolData = (parsedBorrowIncentivePoolData, borrowIncentiveCoinPrice, borrowIncentiveCoinDecimal) => {
1176
+ var calculateBorrowIncentivePoolPointData = (pasredBorrowIncentinvePoolData, parsedBorrowIncentivePoolPointData, rewardCoinPrice, rewardCoinDecimal, poolCoinPrice, poolCoinDecimal) => {
1038
1177
  const baseIndexRate = 1e9;
1039
1178
  const distributedPointPerSec = (0, import_bignumber.default)(
1040
- parsedBorrowIncentivePoolData.pointPerPeriod
1041
- ).dividedBy(parsedBorrowIncentivePoolData.period);
1042
- const pointPerSec = (0, import_bignumber.default)(
1043
- parsedBorrowIncentivePoolData.pointPerPeriod
1044
- ).dividedBy(parsedBorrowIncentivePoolData.period);
1045
- const remainingPeriod = (0, import_bignumber.default)(parsedBorrowIncentivePoolData.maxPoint).minus(parsedBorrowIncentivePoolData.distributedPoint).dividedBy(pointPerSec);
1046
- const startDate = parsedBorrowIncentivePoolData.createdAt;
1047
- const endDate = remainingPeriod.plus(parsedBorrowIncentivePoolData.lastUpdate).integerValue().toNumber();
1179
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
1180
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period);
1048
1181
  const timeDelta = (0, import_bignumber.default)(
1049
- Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolData.lastUpdate
1050
- ).dividedBy(parsedBorrowIncentivePoolData.period).toFixed(0);
1051
- const remainingPoints = (0, import_bignumber.default)(
1052
- parsedBorrowIncentivePoolData.maxPoint
1053
- ).minus(parsedBorrowIncentivePoolData.distributedPoint);
1182
+ Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolPointData.lastUpdate
1183
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period).toFixed(0);
1054
1184
  const accumulatedPoints = import_bignumber.default.minimum(
1055
1185
  (0, import_bignumber.default)(timeDelta).multipliedBy(
1056
- parsedBorrowIncentivePoolData.pointPerPeriod
1186
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
1057
1187
  ),
1058
- remainingPoints
1188
+ (0, import_bignumber.default)(parsedBorrowIncentivePoolPointData.points)
1059
1189
  );
1060
- const currentPointIndex = (0, import_bignumber.default)(parsedBorrowIncentivePoolData.index).plus(
1061
- accumulatedPoints.dividedBy(parsedBorrowIncentivePoolData.staked).isFinite() ? (0, import_bignumber.default)(baseIndexRate).multipliedBy(accumulatedPoints).dividedBy(parsedBorrowIncentivePoolData.staked) : 0
1190
+ const currentPointIndex = (0, import_bignumber.default)(
1191
+ parsedBorrowIncentivePoolPointData.index
1192
+ ).plus(
1193
+ accumulatedPoints.dividedBy(parsedBorrowIncentivePoolPointData.weightedAmount).isFinite() ? (0, import_bignumber.default)(baseIndexRate).multipliedBy(accumulatedPoints).dividedBy(parsedBorrowIncentivePoolPointData.weightedAmount) : 0
1062
1194
  );
1063
1195
  const currentTotalDistributedPoint = (0, import_bignumber.default)(
1064
- parsedBorrowIncentivePoolData.distributedPoint
1196
+ parsedBorrowIncentivePoolPointData.distributedPoint
1065
1197
  ).plus(accumulatedPoints);
1066
- const stakedAmount = (0, import_bignumber.default)(parsedBorrowIncentivePoolData.staked);
1067
- const stakedCoin = stakedAmount.shiftedBy(-1 * borrowIncentiveCoinDecimal);
1068
- const stakedValue = stakedCoin.multipliedBy(borrowIncentiveCoinPrice);
1198
+ const stakedAmount = (0, import_bignumber.default)(pasredBorrowIncentinvePoolData.staked);
1199
+ const stakedCoin = stakedAmount.shiftedBy(-1 * poolCoinDecimal);
1200
+ const stakedValue = stakedCoin.multipliedBy(poolCoinPrice);
1201
+ const baseWeight = (0, import_bignumber.default)(parsedBorrowIncentivePoolPointData.baseWeight);
1202
+ const weightedStakedAmount = (0, import_bignumber.default)(
1203
+ parsedBorrowIncentivePoolPointData.weightedAmount
1204
+ );
1205
+ const weightedStakedCoin = weightedStakedAmount.shiftedBy(
1206
+ -1 * poolCoinDecimal
1207
+ );
1208
+ const weightedStakedValue = weightedStakedCoin.multipliedBy(poolCoinPrice);
1209
+ const rateYearFactor = 365 * 24 * 60 * 60;
1210
+ const rewardPerSec = (0, import_bignumber.default)(distributedPointPerSec).dividedBy(
1211
+ parsedBorrowIncentivePoolPointData.period
1212
+ );
1213
+ const rewardValueForYear = (0, import_bignumber.default)(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
1214
+ const weightScale = (0, import_bignumber.default)("1000000000000");
1215
+ const rewardRate = rewardValueForYear.dividedBy(weightedStakedValue).multipliedBy(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(weightScale).isFinite() ? rewardValueForYear.dividedBy(weightedStakedValue).multipliedBy(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(weightScale).toNumber() : Infinity;
1069
1216
  return {
1070
1217
  distributedPointPerSec: distributedPointPerSec.toNumber(),
1071
1218
  accumulatedPoints: accumulatedPoints.toNumber(),
1072
1219
  currentPointIndex: currentPointIndex.toNumber(),
1073
1220
  currentTotalDistributedPoint: currentTotalDistributedPoint.toNumber(),
1074
- startDate: new Date(startDate * 1e3),
1075
- endDate: new Date(endDate * 1e3),
1076
1221
  stakedAmount: stakedAmount.toNumber(),
1077
1222
  stakedCoin: stakedCoin.toNumber(),
1078
- stakedValue: stakedValue.toNumber()
1223
+ stakedValue: stakedValue.toNumber(),
1224
+ baseWeight: baseWeight.toNumber(),
1225
+ weightedStakedAmount: weightedStakedAmount.toNumber(),
1226
+ weightedStakedCoin: weightedStakedCoin.toNumber(),
1227
+ weightedStakedValue: weightedStakedValue.toNumber(),
1228
+ rewardApr: rewardRate,
1229
+ rewardPerSec: rewardPerSec.toNumber()
1079
1230
  };
1080
1231
  };
1081
- var parseOriginBorrowIncentiveRewardPoolData = (originBorrowIncentiveRewardPoolData) => {
1232
+ var parseOriginBorrowIncentiveAccountPoolPointData = (originBorrowIncentiveAccountPoolPointData) => {
1082
1233
  return {
1083
- rewardType: (0, import_utils.normalizeStructTag)(
1084
- originBorrowIncentiveRewardPoolData.reward_type.name
1234
+ pointType: (0, import_utils.normalizeStructTag)(
1235
+ originBorrowIncentiveAccountPoolPointData.point_type.name
1085
1236
  ),
1086
- claimedRewards: Number(originBorrowIncentiveRewardPoolData.claimed_rewards),
1087
- exchangeRateNumerator: Number(
1088
- originBorrowIncentiveRewardPoolData.exchange_rate_numerator
1089
- ),
1090
- exchangeRateDenominator: Number(
1091
- originBorrowIncentiveRewardPoolData.exchange_rate_denominator
1237
+ weightedAmount: Number(
1238
+ originBorrowIncentiveAccountPoolPointData.weighted_amount
1092
1239
  ),
1093
- remainingRewards: Number(
1094
- originBorrowIncentiveRewardPoolData.remaining_reward
1095
- )
1096
- };
1097
- };
1098
- var calculateBorrowIncentiveRewardPoolData = (parsedBorrowIncentivePoolData, parsedBorrowIncentiveRewardPoolData, calculatedBorrowIncentivePoolData, rewardCoinPrice, rewardCoinDecimal) => {
1099
- const rateYearFactor = 365 * 24 * 60 * 60;
1100
- const rewardPerSec = (0, import_bignumber.default)(
1101
- calculatedBorrowIncentivePoolData.distributedPointPerSec
1102
- ).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1103
- const totalRewardAmount = (0, import_bignumber.default)(parsedBorrowIncentivePoolData.maxPoint).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1104
- const totalRewardCoin = totalRewardAmount.shiftedBy(-1 * rewardCoinDecimal);
1105
- const totalRewardValue = totalRewardCoin.multipliedBy(rewardCoinPrice);
1106
- const remaindRewardAmount = (0, import_bignumber.default)(
1107
- parsedBorrowIncentiveRewardPoolData.remainingRewards
1108
- );
1109
- const remaindRewardCoin = remaindRewardAmount.shiftedBy(
1110
- -1 * rewardCoinDecimal
1111
- );
1112
- const remaindRewardValue = remaindRewardCoin.multipliedBy(rewardCoinPrice);
1113
- const claimedRewardAmount = (0, import_bignumber.default)(
1114
- parsedBorrowIncentiveRewardPoolData.claimedRewards
1115
- );
1116
- const claimedRewardCoin = claimedRewardAmount.shiftedBy(
1117
- -1 * rewardCoinDecimal
1118
- );
1119
- const claimedRewardValue = claimedRewardCoin.multipliedBy(rewardCoinPrice);
1120
- const rewardValueForYear = (0, import_bignumber.default)(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
1121
- const rewardRate = rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).isFinite() ? rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).toNumber() : Infinity;
1122
- return {
1123
- rewardApr: rewardRate,
1124
- totalRewardAmount: totalRewardAmount.toNumber(),
1125
- totalRewardCoin: totalRewardCoin.toNumber(),
1126
- totalRewardValue: totalRewardValue.toNumber(),
1127
- remaindRewardAmount: remaindRewardAmount.toNumber(),
1128
- remaindRewardCoin: remaindRewardCoin.toNumber(),
1129
- remaindRewardValue: remaindRewardValue.toNumber(),
1130
- claimedRewardAmount: claimedRewardAmount.toNumber(),
1131
- claimedRewardCoin: claimedRewardCoin.toNumber(),
1132
- claimedRewardValue: claimedRewardValue.toNumber(),
1133
- rewardPerSec: rewardPerSec.toNumber()
1240
+ points: Number(originBorrowIncentiveAccountPoolPointData.points),
1241
+ totalPoints: Number(originBorrowIncentiveAccountPoolPointData.total_points),
1242
+ index: Number(originBorrowIncentiveAccountPoolPointData.index)
1134
1243
  };
1135
1244
  };
1136
1245
  var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) => {
@@ -1138,10 +1247,18 @@ var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) =
1138
1247
  poolType: (0, import_utils.normalizeStructTag)(
1139
1248
  originBorrowIncentiveAccountData.pool_type.name
1140
1249
  ),
1141
- amount: Number(originBorrowIncentiveAccountData.amount),
1142
- index: Number(originBorrowIncentiveAccountData.index),
1143
- points: Number(originBorrowIncentiveAccountData.points),
1144
- totalPoints: Number(originBorrowIncentiveAccountData.total_points)
1250
+ debtAmount: Number(originBorrowIncentiveAccountData.debt_amount),
1251
+ pointList: originBorrowIncentiveAccountData.points_list.reduce(
1252
+ (acc, point) => {
1253
+ const parsed = parseOriginBorrowIncentiveAccountPoolPointData(point);
1254
+ const name = (0, import_utils.parseStructTag)(
1255
+ parsed.pointType
1256
+ ).name.toLowerCase();
1257
+ acc[name] = parsed;
1258
+ return acc;
1259
+ },
1260
+ {}
1261
+ )
1145
1262
  };
1146
1263
  };
1147
1264
  var minBigNumber = (...args) => {
@@ -1169,7 +1286,8 @@ var isMarketCoin = (coinName) => {
1169
1286
  .../* @__PURE__ */ new Set([
1170
1287
  ...SUPPORT_POOLS,
1171
1288
  ...SUPPORT_COLLATERALS,
1172
- ...SUPPORT_SPOOLS_REWARDS
1289
+ ...SUPPORT_SPOOLS_REWARDS,
1290
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
1173
1291
  ])
1174
1292
  ].includes(assetCoinName);
1175
1293
  };
@@ -1203,6 +1321,19 @@ var parseDataFromPythPriceFeed = (feed, address) => {
1203
1321
  throw new Error("Invalid feed id");
1204
1322
  }
1205
1323
  };
1324
+ var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
1325
+ const unlockDate = new Date(unlockAtInSecondTimestamp * 1e3);
1326
+ const closestTwelveAM = new Date(unlockAtInSecondTimestamp * 1e3);
1327
+ closestTwelveAM.setUTCHours(0, 0, 0, 0);
1328
+ if (unlockDate.getUTCHours() >= 0) {
1329
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() + 1);
1330
+ }
1331
+ const now = (/* @__PURE__ */ new Date()).getTime();
1332
+ if (closestTwelveAM.getTime() - now > MAX_LOCK_DURATION * 1e3) {
1333
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() - 1);
1334
+ }
1335
+ return Math.floor(closestTwelveAM.getTime() / 1e3);
1336
+ };
1206
1337
 
1207
1338
  // src/queries/coreQuery.ts
1208
1339
  var queryMarket = async (query, indexer = false) => {
@@ -1391,7 +1522,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1391
1522
  const fields = marketObject.content.fields;
1392
1523
  const coinType = query.utils.parseCoinType(poolCoinName);
1393
1524
  const balanceSheetParentId = fields.vault.fields.balance_sheets.fields.table.fields.id.id;
1394
- const balanceSheetDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1525
+ const balanceSheetDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1395
1526
  parentId: balanceSheetParentId,
1396
1527
  name: {
1397
1528
  type: "0x1::type_name::TypeName",
@@ -1400,9 +1531,9 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1400
1531
  }
1401
1532
  }
1402
1533
  });
1403
- const balanceSheetDdynamicFieldObject = balanceSheetDdynamicFieldObjectResponse.data;
1404
- if (balanceSheetDdynamicFieldObject && balanceSheetDdynamicFieldObject.content && "fields" in balanceSheetDdynamicFieldObject.content) {
1405
- const dynamicFields = balanceSheetDdynamicFieldObject.content.fields;
1534
+ const balanceSheetDynamicFieldObject = balanceSheetDynamicFieldObjectResponse.data;
1535
+ if (balanceSheetDynamicFieldObject && balanceSheetDynamicFieldObject.content && "fields" in balanceSheetDynamicFieldObject.content) {
1536
+ const dynamicFields = balanceSheetDynamicFieldObject.content.fields;
1406
1537
  balanceSheet = dynamicFields.value.fields;
1407
1538
  }
1408
1539
  const borrowIndexParentId = fields.borrow_dynamics.fields.table.fields.id.id;
@@ -1562,7 +1693,7 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1562
1693
  const fields = marketObject.content.fields;
1563
1694
  const coinType = query.utils.parseCoinType(collateralCoinName);
1564
1695
  const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
1565
- const riskModelDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1696
+ const riskModelDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1566
1697
  parentId: riskModelParentId,
1567
1698
  name: {
1568
1699
  type: "0x1::type_name::TypeName",
@@ -1571,9 +1702,9 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1571
1702
  }
1572
1703
  }
1573
1704
  });
1574
- const riskModelDdynamicFieldObject = riskModelDdynamicFieldObjectResponse.data;
1575
- if (riskModelDdynamicFieldObject && riskModelDdynamicFieldObject.content && "fields" in riskModelDdynamicFieldObject.content) {
1576
- const dynamicFields = riskModelDdynamicFieldObject.content.fields;
1705
+ const riskModelDynamicFieldObject = riskModelDynamicFieldObjectResponse.data;
1706
+ if (riskModelDynamicFieldObject && riskModelDynamicFieldObject.content && "fields" in riskModelDynamicFieldObject.content) {
1707
+ const dynamicFields = riskModelDynamicFieldObject.content.fields;
1577
1708
  riskModel = dynamicFields.value.fields;
1578
1709
  }
1579
1710
  const collateralStatParentId = fields.collateral_stats.fields.table.fields.id.id;
@@ -2243,71 +2374,70 @@ var queryBorrowIncentivePools = async (query, borrowIncentiveCoinNames, indexer
2243
2374
  const incentivePoolsId = query.address.get("borrowIncentive.incentivePools");
2244
2375
  const txBlock = new import_sui_kit2.SuiTxBlock();
2245
2376
  const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
2246
- txBlock.moveCall(queryTarget, [incentivePoolsId], ["0x2::sui::SUI"]);
2377
+ txBlock.moveCall(queryTarget, [incentivePoolsId]);
2247
2378
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2248
2379
  const borrowIncentivePoolsQueryData = queryResult.events[0].parsedJson;
2249
- const parsedBorrowIncentiveRewardPoolData = parseOriginBorrowIncentiveRewardPoolData(
2250
- borrowIncentivePoolsQueryData.reward_pool
2251
- );
2252
- const rewardCoinType = parsedBorrowIncentiveRewardPoolData.rewardType;
2253
- const rewardCoinName = query.utils.parseCoinNameFromType(rewardCoinType);
2254
- const coinPrices = await query.utils.getCoinPrices(
2255
- [.../* @__PURE__ */ new Set([...borrowIncentiveCoinNames, rewardCoinName])]
2256
- );
2257
2380
  const borrowIncentivePools = {};
2258
2381
  if (indexer) {
2259
- const borrowIncentivePoolsIndexer = await query.indexer.getBorrowIncentivePools();
2260
- for (const borrowIncentivePool of Object.values(
2261
- borrowIncentivePoolsIndexer
2262
- )) {
2263
- if (!borrowIncentiveCoinNames.includes(borrowIncentivePool.coinName))
2264
- continue;
2265
- borrowIncentivePool.coinPrice = coinPrices[borrowIncentivePool.coinName] || borrowIncentivePool.coinPrice;
2266
- borrowIncentivePool.rewardCoinPrice = coinPrices[rewardCoinName] || borrowIncentivePool.rewardCoinPrice;
2267
- borrowIncentivePools[borrowIncentivePool.coinName] = borrowIncentivePool;
2268
- }
2269
- return borrowIncentivePools;
2270
2382
  }
2271
2383
  for (const pool of borrowIncentivePoolsQueryData.incentive_pools) {
2272
- const coinType = (0, import_utils6.normalizeStructTag)(pool.pool_type.name);
2273
- const coinName = query.utils.parseCoinNameFromType(coinType);
2274
- const rewardCoinName2 = query.utils.parseCoinNameFromType(rewardCoinType);
2275
- if (!borrowIncentiveCoinNames.includes(coinName)) {
2276
- continue;
2277
- }
2384
+ const borrowIncentivePoolPoints = {};
2278
2385
  const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(pool);
2279
- const coinPrice = coinPrices?.[coinName] ?? 0;
2280
- const coinDecimal = query.utils.getCoinDecimal(coinName);
2281
- const calculatedBorrowIncentivePoolData = calculateBorrowIncentivePoolData(
2282
- parsedBorrowIncentivePoolData,
2283
- coinPrice,
2284
- coinDecimal
2386
+ const coinPrices = await query.utils.getCoinPrices(
2387
+ [
2388
+ .../* @__PURE__ */ new Set([
2389
+ ...borrowIncentiveCoinNames,
2390
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
2391
+ ])
2392
+ ]
2285
2393
  );
2286
- const rewardCoinPrice = coinPrices?.[rewardCoinName2] ?? 0;
2287
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName2);
2288
- const calculatedBorrowIncentiveRewardPoolData = calculateBorrowIncentiveRewardPoolData(
2289
- parsedBorrowIncentivePoolData,
2290
- parsedBorrowIncentiveRewardPoolData,
2291
- calculatedBorrowIncentivePoolData,
2292
- rewardCoinPrice,
2293
- rewardCoinDecimal
2394
+ const poolCoinType = (0, import_utils6.normalizeStructTag)(pool.pool_type.name);
2395
+ const poolCoinName = query.utils.parseCoinNameFromType(
2396
+ poolCoinType
2294
2397
  );
2295
- borrowIncentivePools[coinName] = {
2296
- coinName,
2297
- symbol: query.utils.parseSymbol(coinName),
2298
- coinType,
2299
- rewardCoinType,
2300
- coinDecimal,
2301
- rewardCoinDecimal,
2302
- coinPrice,
2303
- rewardCoinPrice,
2304
- maxPoint: parsedBorrowIncentivePoolData.maxPoint,
2305
- distributedPoint: parsedBorrowIncentivePoolData.distributedPoint,
2306
- maxStake: parsedBorrowIncentivePoolData.maxStake,
2307
- ...calculatedBorrowIncentivePoolData,
2308
- exchangeRateNumerator: parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator,
2309
- exchangeRateDenominator: parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator,
2310
- ...calculatedBorrowIncentiveRewardPoolData
2398
+ const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
2399
+ const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
2400
+ if (!borrowIncentiveCoinNames.includes(poolCoinName)) {
2401
+ continue;
2402
+ }
2403
+ for (const [coinName, poolPoint] of Object.entries(
2404
+ parsedBorrowIncentivePoolData.poolPoints
2405
+ )) {
2406
+ const rewardCoinType = (0, import_utils6.normalizeStructTag)(poolPoint.pointType);
2407
+ const rewardCoinName = query.utils.parseCoinNameFromType(
2408
+ rewardCoinType
2409
+ );
2410
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
2411
+ const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2412
+ const symbol = query.utils.parseSymbol(rewardCoinName);
2413
+ const coinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2414
+ const calculatedPoolPoint = calculateBorrowIncentivePoolPointData(
2415
+ parsedBorrowIncentivePoolData,
2416
+ poolPoint,
2417
+ rewardCoinPrice,
2418
+ rewardCoinDecimal,
2419
+ poolCoinPrice,
2420
+ poolCoinDecimal
2421
+ );
2422
+ borrowIncentivePoolPoints[coinName] = {
2423
+ symbol,
2424
+ coinName: rewardCoinName,
2425
+ coinType: rewardCoinType,
2426
+ coinDecimal,
2427
+ coinPrice: rewardCoinPrice,
2428
+ points: poolPoint.points,
2429
+ distributedPoint: poolPoint.distributedPoint,
2430
+ weightedAmount: poolPoint.weightedAmount,
2431
+ ...calculatedPoolPoint
2432
+ };
2433
+ }
2434
+ borrowIncentivePools[poolCoinName] = {
2435
+ coinName: poolCoinName,
2436
+ symbol: query.utils.parseSymbol(poolCoinName),
2437
+ coinType: poolCoinType,
2438
+ coinDecimal: poolCoinDecimal,
2439
+ coinPrice: poolCoinPrice,
2440
+ points: borrowIncentivePoolPoints
2311
2441
  };
2312
2442
  }
2313
2443
  return borrowIncentivePools;
@@ -2326,19 +2456,13 @@ var queryBorrowIncentiveAccounts = async (query, obligationId, borrowIncentiveCo
2326
2456
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2327
2457
  const borrowIncentiveAccountsQueryData = queryResult.events[0].parsedJson;
2328
2458
  const borrowIncentiveAccounts = Object.values(
2329
- borrowIncentiveAccountsQueryData.incentive_states
2459
+ borrowIncentiveAccountsQueryData.pool_records
2330
2460
  ).reduce((accounts, accountData) => {
2331
2461
  const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(accountData);
2332
2462
  const poolType = parsedBorrowIncentiveAccount.poolType;
2333
2463
  const coinName = query.utils.parseCoinNameFromType(poolType);
2334
2464
  if (borrowIncentiveCoinNames && borrowIncentiveCoinNames.includes(coinName)) {
2335
- accounts[coinName] = {
2336
- poolType,
2337
- amount: parsedBorrowIncentiveAccount.amount,
2338
- points: parsedBorrowIncentiveAccount.points,
2339
- totalPoints: parsedBorrowIncentiveAccount.totalPoints,
2340
- index: parsedBorrowIncentiveAccount.index
2341
- };
2465
+ accounts[coinName] = parsedBorrowIncentiveAccount;
2342
2466
  }
2343
2467
  return accounts;
2344
2468
  }, {});
@@ -2558,9 +2682,8 @@ var getObligationAccounts = async (query, ownerAddress, indexer = false) => {
2558
2682
  };
2559
2683
  var getObligationAccount = async (query, obligationId, ownerAddress, indexer = false, market, coinPrices, coinAmounts) => {
2560
2684
  market = market || await query.queryMarket(indexer);
2561
- const assetCoinNames = [
2685
+ const collateralAssetCoinNames = [
2562
2686
  .../* @__PURE__ */ new Set([
2563
- ...Object.values(market.pools).map((pool) => pool.coinName),
2564
2687
  ...Object.values(market.collaterals).map(
2565
2688
  (collateral) => collateral.coinName
2566
2689
  )
@@ -2572,8 +2695,8 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2572
2695
  indexer
2573
2696
  );
2574
2697
  const borrowIncentiveAccounts = await query.getBorrowIncentiveAccounts(obligationId);
2575
- coinPrices = coinPrices || await query.utils.getCoinPrices(assetCoinNames);
2576
- coinAmounts = coinAmounts || await query.getCoinAmounts(assetCoinNames, ownerAddress);
2698
+ coinPrices = coinPrices || await query.utils.getCoinPrices(collateralAssetCoinNames);
2699
+ coinAmounts = coinAmounts || await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress);
2577
2700
  const collaterals = {};
2578
2701
  const debts = {};
2579
2702
  const borrowIncentives = {};
@@ -2584,7 +2707,7 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2584
2707
  let totalBorrowedPools = 0;
2585
2708
  let totalBorrowedValue = (0, import_bignumber3.default)(0);
2586
2709
  let totalBorrowedValueWithWeight = (0, import_bignumber3.default)(0);
2587
- for (const assetCoinName of assetCoinNames) {
2710
+ for (const assetCoinName of collateralAssetCoinNames) {
2588
2711
  const collateral = obligationQuery.collaterals.find((collateral2) => {
2589
2712
  const collateralCoinName = query.utils.parseCoinNameFromType(
2590
2713
  collateral2.type.name
@@ -2641,7 +2764,10 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2641
2764
  };
2642
2765
  }
2643
2766
  }
2644
- for (const assetCoinName of assetCoinNames) {
2767
+ const borrowAssetCoinNames = [
2768
+ .../* @__PURE__ */ new Set([...Object.values(market.pools).map((pool) => pool.coinName)])
2769
+ ];
2770
+ for (const assetCoinName of borrowAssetCoinNames) {
2645
2771
  const debt = obligationQuery.debts.find((debt2) => {
2646
2772
  const poolCoinName = query.utils.parseCoinNameFromType(
2647
2773
  debt2.type.name
@@ -2700,34 +2826,51 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2700
2826
  )) {
2701
2827
  const coinName = poolCoinName;
2702
2828
  const borrowIncentivePool = borrowIncentivePools[coinName];
2703
- let availableClaimAmount = (0, import_bignumber3.default)(0);
2704
- let availableClaimCoin = (0, import_bignumber3.default)(0);
2705
2829
  if (borrowIncentivePool) {
2706
- const accountBorrowedAmount = (0, import_bignumber3.default)(borrowIncentiveAccount.amount);
2707
- const baseIndexRate = 1e9;
2708
- const increasedPointRate = borrowIncentivePool.currentPointIndex ? (0, import_bignumber3.default)(
2709
- borrowIncentivePool.currentPointIndex - borrowIncentiveAccount.index
2710
- ).dividedBy(baseIndexRate) : 1;
2711
- availableClaimAmount = availableClaimAmount.plus(
2712
- accountBorrowedAmount.multipliedBy(increasedPointRate).plus(borrowIncentiveAccount.points).multipliedBy(borrowIncentivePool.exchangeRateNumerator).dividedBy(borrowIncentivePool.exchangeRateDenominator)
2713
- );
2714
- availableClaimCoin = availableClaimAmount.shiftedBy(
2715
- -1 * borrowIncentivePool.rewardCoinDecimal
2716
- );
2717
- if (availableClaimAmount.isGreaterThan(0)) {
2718
- borrowIncentives[coinName] = {
2719
- coinName: borrowIncentivePool.coinName,
2720
- coinType: borrowIncentivePool.coinType,
2721
- rewardCoinType: borrowIncentivePool.rewardCoinType,
2722
- symbol: borrowIncentivePool.symbol,
2723
- coinDecimal: borrowIncentivePool.coinDecimal,
2724
- rewardCoinDecimal: borrowIncentivePool.rewardCoinDecimal,
2725
- coinPrice: borrowIncentivePool.coinPrice,
2726
- rewardCoinPrice: borrowIncentivePool.rewardCoinPrice,
2727
- availableClaimAmount: availableClaimAmount.toNumber(),
2728
- availableClaimCoin: availableClaimCoin.toNumber()
2729
- };
2830
+ const rewards = [];
2831
+ for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
2832
+ const accountPoint = borrowIncentiveAccount.pointList[rewardCoinName];
2833
+ const poolPoint = borrowIncentivePool.points[rewardCoinName];
2834
+ if (accountPoint && poolPoint) {
2835
+ let availableClaimAmount = (0, import_bignumber3.default)(0);
2836
+ let availableClaimCoin = (0, import_bignumber3.default)(0);
2837
+ const accountBorrowedAmount = (0, import_bignumber3.default)(accountPoint.weightedAmount);
2838
+ const baseIndexRate = 1e9;
2839
+ const increasedPointRate = poolPoint.currentPointIndex ? (0, import_bignumber3.default)(
2840
+ poolPoint.currentPointIndex - accountPoint.index
2841
+ ).dividedBy(baseIndexRate) : 1;
2842
+ availableClaimAmount = availableClaimAmount.plus(
2843
+ accountBorrowedAmount.multipliedBy(increasedPointRate).plus(accountPoint.points)
2844
+ );
2845
+ availableClaimCoin = availableClaimAmount.shiftedBy(
2846
+ -1 * poolPoint.coinDecimal
2847
+ );
2848
+ const weightScale = (0, import_bignumber3.default)("1000000000000");
2849
+ const boostValue = (0, import_bignumber3.default)(accountPoint.weightedAmount).div(
2850
+ (0, import_bignumber3.default)(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
2851
+ ).toNumber();
2852
+ if (availableClaimAmount.isGreaterThan(0)) {
2853
+ rewards.push({
2854
+ coinName: poolPoint.coinName,
2855
+ coinType: poolPoint.coinType,
2856
+ symbol: poolPoint.symbol,
2857
+ coinDecimal: poolPoint.coinDecimal,
2858
+ coinPrice: poolPoint.coinPrice,
2859
+ availableClaimAmount: availableClaimAmount.toNumber(),
2860
+ availableClaimCoin: availableClaimCoin.toNumber(),
2861
+ boostValue
2862
+ });
2863
+ }
2864
+ }
2730
2865
  }
2866
+ borrowIncentives[coinName] = {
2867
+ coinName: borrowIncentivePool.coinName,
2868
+ coinType: borrowIncentivePool.coinType,
2869
+ symbol: borrowIncentivePool.symbol,
2870
+ coinDecimal: borrowIncentivePool.coinDecimal,
2871
+ coinPrice: borrowIncentivePool.coinPrice,
2872
+ rewards
2873
+ };
2731
2874
  }
2732
2875
  }
2733
2876
  let riskLevel = totalRequiredCollateralValue.isZero() ? (0, import_bignumber3.default)(0) : totalBorrowedValueWithWeight.dividedBy(totalRequiredCollateralValue);
@@ -2855,6 +2998,70 @@ var getTotalValueLocked = async (query, indexer = false) => {
2855
2998
  return tvl;
2856
2999
  };
2857
3000
 
3001
+ // src/queries/vescaQuery.ts
3002
+ var import_bignumber4 = __toESM(require("bignumber.js"));
3003
+ var getVescaKeys = async (query, ownerAddress) => {
3004
+ const owner = ownerAddress || query.suiKit.currentAddress();
3005
+ const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : query.address.get("vesca.id");
3006
+ const veScaKeyType = `${veScaPkgId}::ve_sca::VeScaKey`;
3007
+ const keyObjectsResponse = [];
3008
+ let hasNextPage = false;
3009
+ let nextCursor = null;
3010
+ do {
3011
+ const paginatedKeyObjectsResponse = await query.suiKit.client().getOwnedObjects({
3012
+ owner,
3013
+ filter: {
3014
+ StructType: veScaKeyType
3015
+ },
3016
+ cursor: nextCursor
3017
+ });
3018
+ keyObjectsResponse.push(...paginatedKeyObjectsResponse.data);
3019
+ if (paginatedKeyObjectsResponse.hasNextPage && paginatedKeyObjectsResponse.nextCursor) {
3020
+ hasNextPage = true;
3021
+ nextCursor = paginatedKeyObjectsResponse.nextCursor;
3022
+ } else {
3023
+ hasNextPage = false;
3024
+ }
3025
+ } while (hasNextPage);
3026
+ const keyObjectDatas = keyObjectsResponse.map((objResponse) => objResponse.data).filter((data) => !!data);
3027
+ return keyObjectDatas;
3028
+ };
3029
+ var getVeScas = async (query, ownerAddress) => {
3030
+ const keyObjectDatas = await getVescaKeys(query, ownerAddress);
3031
+ const keyObjectId = keyObjectDatas.map((data) => data.objectId);
3032
+ const veScas = [];
3033
+ for (const keyId of keyObjectId) {
3034
+ const veSca = await getVeSca(query, keyId);
3035
+ if (veSca)
3036
+ veScas.push(veSca);
3037
+ }
3038
+ return veScas;
3039
+ };
3040
+ var getVeSca = async (query, veScaKeyId, ownerAddress) => {
3041
+ const tableId = IS_VE_SCA_TEST ? "0xc607241e4a679fe376d1170b2fbe07b64917bfe69100d4825241cda20039d4bd" : query.address.get(`vesca.tableId`);
3042
+ veScaKeyId = veScaKeyId || (await getVescaKeys(query, ownerAddress))[0].objectId;
3043
+ let vesca = void 0;
3044
+ const veScaDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
3045
+ parentId: tableId,
3046
+ name: {
3047
+ type: "0x2::object::ID",
3048
+ value: veScaKeyId
3049
+ }
3050
+ });
3051
+ const veScaDynamicFieldObject = veScaDynamicFieldObjectResponse.data;
3052
+ if (veScaDynamicFieldObject && veScaDynamicFieldObject.content && veScaDynamicFieldObject.content.dataType === "moveObject" && "fields" in veScaDynamicFieldObject.content) {
3053
+ const dynamicFields = veScaDynamicFieldObject.content.fields.value.fields;
3054
+ vesca = {
3055
+ id: veScaDynamicFieldObject.objectId,
3056
+ keyId: veScaKeyId,
3057
+ lockedScaAmount: (0, import_bignumber4.default)(dynamicFields.locked_sca_amount).toNumber(),
3058
+ lockedScaCoin: (0, import_bignumber4.default)(dynamicFields.locked_sca_amount).shiftedBy(-9).toNumber(),
3059
+ unlockAt: (0, import_bignumber4.default)(dynamicFields.unlock_at).toNumber()
3060
+ };
3061
+ }
3062
+ return vesca;
3063
+ };
3064
+
2858
3065
  // src/models/scallopIndexer.ts
2859
3066
  var import_axios2 = __toESM(require("axios"));
2860
3067
  var ScallopIndexer = class {
@@ -3697,11 +3904,43 @@ var ScallopUtils = class {
3697
3904
  parseApyToApr(apy, compoundFrequency = 365) {
3698
3905
  return ((1 + apy) ** (1 / compoundFrequency) - 1) * compoundFrequency;
3699
3906
  }
3907
+ /**
3908
+ * Give extend lock period to get unlock at in seconds timestamp.
3909
+ *
3910
+ * @description
3911
+ * - When the user without remaining unlock period, If the extended unlock day is not specified,
3912
+ * the unlock period will be increased by one day by default.
3913
+ * - When the given extended day plus the user's remaining unlock period exceeds the maximum
3914
+ * unlock period, the maximum unlock period is used as unlock period.
3915
+ *
3916
+ * @param extendLockPeriodInDay The extend lock period in day.
3917
+ * @param unlockAtInSecondTimestamp The unlock timestamp from veSca object.
3918
+ * @return New unlock at in seconds timestamp.
3919
+ */
3920
+ getUnlockAt(extendLockPeriodInDay, unlockAtInSecondTimestamp) {
3921
+ const now = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
3922
+ const remainingLockPeriod = unlockAtInSecondTimestamp ? Math.max(unlockAtInSecondTimestamp - now, 0) : 0;
3923
+ let newUnlockAtInSecondTimestamp = 0;
3924
+ if (remainingLockPeriod === 0) {
3925
+ const lockPeriod = (extendLockPeriodInDay ?? 1) * UNLOCK_ROUND_DURATION;
3926
+ newUnlockAtInSecondTimestamp = Math.min(
3927
+ now + lockPeriod,
3928
+ now + MAX_LOCK_DURATION
3929
+ );
3930
+ } else {
3931
+ const lockPeriod = Math.min(
3932
+ extendLockPeriodInDay ? extendLockPeriodInDay * UNLOCK_ROUND_DURATION + remainingLockPeriod : remainingLockPeriod,
3933
+ MAX_LOCK_DURATION
3934
+ );
3935
+ newUnlockAtInSecondTimestamp = now + lockPeriod;
3936
+ }
3937
+ return findClosestUnlockRound(newUnlockAtInSecondTimestamp);
3938
+ }
3700
3939
  };
3701
3940
 
3702
3941
  // src/models/scallopBuilder.ts
3703
- var import_utils18 = require("@mysten/sui.js/utils");
3704
- var import_sui_kit8 = require("@scallop-io/sui-kit");
3942
+ var import_utils19 = require("@mysten/sui.js/utils");
3943
+ var import_sui_kit9 = require("@scallop-io/sui-kit");
3705
3944
 
3706
3945
  // src/builders/coreBuilder.ts
3707
3946
  var import_transactions = require("@mysten/sui.js/transactions");
@@ -4355,8 +4594,277 @@ var newSpoolTxBlock = (builder, initTxBlock) => {
4355
4594
 
4356
4595
  // src/builders/borrowIncentiveBuilder.ts
4357
4596
  var import_transactions3 = require("@mysten/sui.js/transactions");
4358
- var import_utils16 = require("@mysten/sui.js/utils");
4597
+ var import_utils17 = require("@mysten/sui.js/utils");
4598
+ var import_sui_kit8 = require("@scallop-io/sui-kit");
4599
+
4600
+ // src/builders/vescaBuilder.ts
4359
4601
  var import_sui_kit7 = require("@scallop-io/sui-kit");
4602
+ var requireVeSca = async (...params) => {
4603
+ const [builder, txBlock, veScaKey] = params;
4604
+ if (params.length === 3 && veScaKey && typeof veScaKey === "string") {
4605
+ const veSca = await getVeSca(builder.query, veScaKey);
4606
+ if (!veSca) {
4607
+ return void 0;
4608
+ }
4609
+ return veSca;
4610
+ }
4611
+ const sender = requireSender(txBlock);
4612
+ const veScas = await getVeScas(builder.query, sender);
4613
+ if (veScas.length === 0) {
4614
+ return void 0;
4615
+ }
4616
+ return veScas[0];
4617
+ };
4618
+ var generateNormalVeScaMethod = ({
4619
+ builder,
4620
+ txBlock
4621
+ }) => {
4622
+ const veScaIds = {
4623
+ pkgId: builder.address.get("vesca.id"),
4624
+ table: builder.address.get("vesca.table"),
4625
+ treasury: builder.address.get("vesca.treasury"),
4626
+ config: builder.address.get("vesca.config")
4627
+ };
4628
+ return {
4629
+ lockSca: (scaCoin, unlockAtInSecondTimestamp) => {
4630
+ return txBlock.moveCall(
4631
+ `${veScaIds.pkgId}::ve_sca::mint_ve_sca_key`,
4632
+ [
4633
+ veScaIds.config,
4634
+ veScaIds.table,
4635
+ veScaIds.treasury,
4636
+ scaCoin,
4637
+ unlockAtInSecondTimestamp,
4638
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4639
+ ],
4640
+ []
4641
+ );
4642
+ },
4643
+ extendLockPeriod: (veScaKey, newUnlockAtInSecondTimestamp) => {
4644
+ txBlock.moveCall(
4645
+ `${veScaIds.pkgId}::ve_sca::extend_lock_period`,
4646
+ [
4647
+ veScaIds.config,
4648
+ veScaKey,
4649
+ veScaIds.table,
4650
+ veScaIds.treasury,
4651
+ newUnlockAtInSecondTimestamp,
4652
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4653
+ ],
4654
+ []
4655
+ );
4656
+ },
4657
+ extendLockAmount: (veScaKey, scaCoin) => {
4658
+ txBlock.moveCall(
4659
+ `${veScaIds.pkgId}::ve_sca::lock_more_sca`,
4660
+ [
4661
+ veScaIds.config,
4662
+ veScaKey,
4663
+ veScaIds.table,
4664
+ veScaIds.treasury,
4665
+ scaCoin,
4666
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4667
+ ],
4668
+ []
4669
+ );
4670
+ },
4671
+ renewExpiredVeSca: (veScaKey, scaCoin, newUnlockAtInSecondTimestamp) => {
4672
+ txBlock.moveCall(
4673
+ `${veScaIds.pkgId}::ve_sca::renew_expired_ve_sca`,
4674
+ [
4675
+ veScaIds.config,
4676
+ veScaKey,
4677
+ veScaIds.table,
4678
+ veScaIds.treasury,
4679
+ scaCoin,
4680
+ newUnlockAtInSecondTimestamp,
4681
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4682
+ ],
4683
+ []
4684
+ );
4685
+ },
4686
+ redeemSca: (veScaKey) => {
4687
+ return txBlock.moveCall(
4688
+ `${veScaIds.pkgId}::ve_sca::redeem`,
4689
+ [
4690
+ veScaIds.config,
4691
+ veScaKey,
4692
+ veScaIds.table,
4693
+ veScaIds.treasury,
4694
+ import_sui_kit7.SUI_CLOCK_OBJECT_ID
4695
+ ],
4696
+ []
4697
+ );
4698
+ }
4699
+ };
4700
+ };
4701
+ var generateQuickVeScaMethod = ({
4702
+ builder,
4703
+ txBlock
4704
+ }) => {
4705
+ return {
4706
+ lockScaQuick: async (amountOrCoin, lockPeriodInDays, autoCheck = true) => {
4707
+ const sender = requireSender(txBlock);
4708
+ const veSca = await requireVeSca(builder, txBlock);
4709
+ let scaCoin = void 0;
4710
+ const transferObjects = [];
4711
+ if (amountOrCoin !== void 0 && typeof amountOrCoin === "number") {
4712
+ const coins = await builder.utils.selectCoinIds(
4713
+ amountOrCoin,
4714
+ SCA_COIN_TYPE,
4715
+ sender
4716
+ );
4717
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4718
+ coins,
4719
+ amountOrCoin
4720
+ );
4721
+ scaCoin = takeCoin;
4722
+ transferObjects.push(leftCoin);
4723
+ } else {
4724
+ scaCoin = amountOrCoin;
4725
+ }
4726
+ const newUnlockAt = builder.utils.getUnlockAt(
4727
+ lockPeriodInDays,
4728
+ veSca?.unlockAt
4729
+ );
4730
+ if (autoCheck)
4731
+ checkLockSca(
4732
+ amountOrCoin,
4733
+ lockPeriodInDays,
4734
+ newUnlockAt,
4735
+ veSca?.unlockAt
4736
+ );
4737
+ console.log(
4738
+ new Date(newUnlockAt * 1e3).toLocaleString("en-CA", {
4739
+ hour12: true
4740
+ })
4741
+ );
4742
+ const isInitialLock = !veSca?.unlockAt;
4743
+ const isLockExpired = !isInitialLock && veSca.unlockAt * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
4744
+ if (isInitialLock || isLockExpired) {
4745
+ if (scaCoin) {
4746
+ if (isInitialLock) {
4747
+ const veScaKey = txBlock.lockSca(scaCoin, newUnlockAt);
4748
+ transferObjects.push(veScaKey);
4749
+ } else {
4750
+ if (veSca.lockedScaAmount !== 0) {
4751
+ const unlockedSca = txBlock.redeemSca(veSca.keyId);
4752
+ transferObjects.push(unlockedSca);
4753
+ }
4754
+ txBlock.renewExpiredVeSca(veSca.keyId, scaCoin, newUnlockAt);
4755
+ }
4756
+ }
4757
+ } else {
4758
+ if (!!scaCoin && !!lockPeriodInDays) {
4759
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4760
+ txBlock.extendLockAmount(veSca.keyId, scaCoin);
4761
+ } else if (lockPeriodInDays) {
4762
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4763
+ } else if (scaCoin) {
4764
+ txBlock.extendLockAmount(veSca.keyId, scaCoin);
4765
+ }
4766
+ }
4767
+ if (transferObjects.length > 0) {
4768
+ txBlock.transferObjects(transferObjects, sender);
4769
+ }
4770
+ },
4771
+ extendLockPeriodQuick: async (lockPeriodInDays, veScaKey, autoCheck = true) => {
4772
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4773
+ const newUnlockAt = builder.utils.getUnlockAt(lockPeriodInDays);
4774
+ if (autoCheck)
4775
+ checkExtendLockPeriod(lockPeriodInDays, newUnlockAt, veSca?.unlockAt);
4776
+ if (veSca) {
4777
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4778
+ }
4779
+ },
4780
+ extendLockAmountQuick: async (scaAmount, veScaKey, autoCheck = true) => {
4781
+ const sender = requireSender(txBlock);
4782
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4783
+ if (autoCheck)
4784
+ checkExtendLockAmount(scaAmount, veSca?.unlockAt);
4785
+ if (veSca) {
4786
+ const scaCoins = await builder.utils.selectCoinIds(
4787
+ scaAmount,
4788
+ SCA_COIN_TYPE,
4789
+ sender
4790
+ );
4791
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4792
+ scaCoins,
4793
+ scaAmount
4794
+ );
4795
+ txBlock.extendLockAmount(veSca.keyId, takeCoin);
4796
+ txBlock.transferObjects([leftCoin], sender);
4797
+ }
4798
+ },
4799
+ renewExpiredVeScaQuick: async (scaAmount, lockPeriodInDays, veScaKey, autoCheck = true) => {
4800
+ const sender = requireSender(txBlock);
4801
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4802
+ const newUnlockAt = builder.utils.getUnlockAt(
4803
+ lockPeriodInDays,
4804
+ veSca?.unlockAt
4805
+ );
4806
+ if (autoCheck)
4807
+ checkRenewExpiredVeSca(scaAmount, lockPeriodInDays, veSca?.unlockAt);
4808
+ if (veSca) {
4809
+ const transferObjects = [];
4810
+ if (veSca.lockedScaAmount !== 0) {
4811
+ const unlockedSca = txBlock.redeemSca(veSca.keyId);
4812
+ transferObjects.push(unlockedSca);
4813
+ }
4814
+ const scaCoins = await builder.utils.selectCoinIds(
4815
+ scaAmount,
4816
+ SCA_COIN_TYPE,
4817
+ sender
4818
+ );
4819
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4820
+ scaCoins,
4821
+ scaAmount
4822
+ );
4823
+ transferObjects.push(leftCoin);
4824
+ txBlock.renewExpiredVeSca(veSca.keyId, takeCoin, newUnlockAt);
4825
+ txBlock.transferObjects(transferObjects, sender);
4826
+ }
4827
+ },
4828
+ redeemScaQuick: async (veScaKey) => {
4829
+ const sender = requireSender(txBlock);
4830
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4831
+ checkVesca(veSca?.unlockAt);
4832
+ if (veSca) {
4833
+ const sca = txBlock.redeemSca(veSca.keyId);
4834
+ txBlock.transferObjects([sca], sender);
4835
+ }
4836
+ }
4837
+ };
4838
+ };
4839
+ var newVeScaTxBlock = (builder, initTxBlock) => {
4840
+ const txBlock = initTxBlock instanceof import_sui_kit7.TransactionBlock ? new import_sui_kit7.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit7.SuiTxBlock();
4841
+ const normalMethod = generateNormalVeScaMethod({
4842
+ builder,
4843
+ txBlock
4844
+ });
4845
+ const normalTxBlock = new Proxy(txBlock, {
4846
+ get: (target, prop) => {
4847
+ if (prop in normalMethod) {
4848
+ return Reflect.get(normalMethod, prop);
4849
+ }
4850
+ return Reflect.get(target, prop);
4851
+ }
4852
+ });
4853
+ const quickMethod = generateQuickVeScaMethod({
4854
+ builder,
4855
+ txBlock: normalTxBlock
4856
+ });
4857
+ return new Proxy(normalTxBlock, {
4858
+ get: (target, prop) => {
4859
+ if (prop in quickMethod) {
4860
+ return Reflect.get(quickMethod, prop);
4861
+ }
4862
+ return Reflect.get(target, prop);
4863
+ }
4864
+ });
4865
+ };
4866
+
4867
+ // src/builders/borrowIncentiveBuilder.ts
4360
4868
  var requireObligationInfo2 = async (...params) => {
4361
4869
  const [builder, txBlock, obligationId, obligationKey] = params;
4362
4870
  if (params.length === 4 && obligationId && obligationKey && typeof obligationId === "string") {
@@ -4377,59 +4885,115 @@ var requireObligationInfo2 = async (...params) => {
4377
4885
  obligationLocked: obligations[0].locked
4378
4886
  };
4379
4887
  };
4888
+ var getBindedObligationId = async (builder, veScaKey) => {
4889
+ const borrowIncentivePkgId = builder.address.get("borrowIncentive.id");
4890
+ const incentivePoolsId = builder.address.get(
4891
+ "borrowIncentive.incentivePools"
4892
+ );
4893
+ const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : builder.address.get("vesca.id");
4894
+ const client = builder.suiKit.client();
4895
+ const incentivePoolsResponse = await client.getObject({
4896
+ id: incentivePoolsId,
4897
+ options: {
4898
+ showContent: true
4899
+ }
4900
+ });
4901
+ if (incentivePoolsResponse.data?.content?.dataType !== "moveObject")
4902
+ return false;
4903
+ const incentivePoolFields = incentivePoolsResponse.data.content.fields;
4904
+ const veScaBindTableId = incentivePoolFields.ve_sca_bind.fields.id.id;
4905
+ const keyType = `${borrowIncentivePkgId}::typed_id::TypedID<${veScaPkgId}::ve_sca::VeScaKey>`;
4906
+ const veScaBindTableResponse = await client.getDynamicFieldObject({
4907
+ parentId: veScaBindTableId,
4908
+ name: {
4909
+ type: keyType,
4910
+ value: veScaKey
4911
+ }
4912
+ });
4913
+ if (veScaBindTableResponse.data?.content?.dataType !== "moveObject")
4914
+ return false;
4915
+ const veScaBindTableFields = veScaBindTableResponse.data.content.fields;
4916
+ const obligationId = veScaBindTableFields.value.fields.id;
4917
+ return obligationId;
4918
+ };
4380
4919
  var generateBorrowIncentiveNormalMethod = ({ builder, txBlock }) => {
4381
4920
  const borrowIncentiveIds = {
4382
- borrowIncentivePkg: builder.address.get("borrowIncentive.id"),
4921
+ borrowIncentivePkg: IS_VE_SCA_TEST ? "0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246" : builder.address.get("borrowIncentive.id"),
4383
4922
  query: builder.address.get("borrowIncentive.query"),
4923
+ config: builder.address.get("borrowIncentive.config"),
4384
4924
  incentivePools: builder.address.get("borrowIncentive.incentivePools"),
4385
4925
  incentiveAccounts: builder.address.get(
4386
4926
  "borrowIncentive.incentiveAccounts"
4387
4927
  ),
4388
4928
  obligationAccessStore: builder.address.get("core.obligationAccessStore")
4389
4929
  };
4930
+ const veScaIds = {
4931
+ table: builder.address.get("vesca.table"),
4932
+ treasury: builder.address.get("vesca.treasury"),
4933
+ config: builder.address.get("vesca.config")
4934
+ };
4390
4935
  return {
4391
- stakeObligation: (obligationId, obligaionKey) => {
4392
- const rewardCoinName = "sui";
4393
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4936
+ stakeObligation: (obligationId, obligationKey) => {
4394
4937
  txBlock.moveCall(
4395
4938
  `${borrowIncentiveIds.borrowIncentivePkg}::user::stake`,
4396
4939
  [
4940
+ borrowIncentiveIds.config,
4941
+ borrowIncentiveIds.incentivePools,
4942
+ borrowIncentiveIds.incentiveAccounts,
4943
+ obligationKey,
4944
+ obligationId,
4945
+ borrowIncentiveIds.obligationAccessStore,
4946
+ import_utils17.SUI_CLOCK_OBJECT_ID
4947
+ ]
4948
+ );
4949
+ },
4950
+ stakeObligationWithVesca: (obligationId, obligationKey, veScaKey) => {
4951
+ txBlock.moveCall(
4952
+ `${borrowIncentiveIds.borrowIncentivePkg}::user::stake_with_ve_sca`,
4953
+ [
4954
+ borrowIncentiveIds.config,
4397
4955
  borrowIncentiveIds.incentivePools,
4398
4956
  borrowIncentiveIds.incentiveAccounts,
4399
- obligaionKey,
4957
+ obligationKey,
4400
4958
  obligationId,
4401
4959
  borrowIncentiveIds.obligationAccessStore,
4402
- import_utils16.SUI_CLOCK_OBJECT_ID
4960
+ veScaIds.config,
4961
+ veScaIds.treasury,
4962
+ veScaIds.table,
4963
+ veScaKey,
4964
+ import_utils17.SUI_CLOCK_OBJECT_ID
4403
4965
  ],
4404
- [rewardType]
4966
+ []
4405
4967
  );
4406
4968
  },
4407
- unstakeObligation: (obligationId, obligaionKey) => {
4408
- const rewardCoinName = "sui";
4409
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4969
+ unstakeObligation: (obligationId, obligationKey) => {
4410
4970
  txBlock.moveCall(
4411
4971
  `${borrowIncentiveIds.borrowIncentivePkg}::user::unstake`,
4412
4972
  [
4973
+ borrowIncentiveIds.config,
4413
4974
  borrowIncentiveIds.incentivePools,
4414
4975
  borrowIncentiveIds.incentiveAccounts,
4415
- obligaionKey,
4976
+ obligationKey,
4416
4977
  obligationId,
4417
- import_utils16.SUI_CLOCK_OBJECT_ID
4418
- ],
4419
- [rewardType]
4978
+ import_utils17.SUI_CLOCK_OBJECT_ID
4979
+ ]
4420
4980
  );
4421
4981
  },
4422
- claimBorrowIncentive: (obligationId, obligaionKey, coinName) => {
4423
- const rewardCoinName = borrowIncentiveRewardCoins[coinName];
4982
+ claimBorrowIncentive: (obligationId, obligationKey, coinName, rewardCoinName) => {
4983
+ const rewardCoinNames = borrowIncentiveRewardCoins[coinName];
4984
+ if (rewardCoinNames.includes(rewardCoinName) === false) {
4985
+ throw new Error(`Invalid reward coin name ${rewardCoinName}`);
4986
+ }
4424
4987
  const rewardType = builder.utils.parseCoinType(rewardCoinName);
4425
4988
  return txBlock.moveCall(
4426
4989
  `${borrowIncentiveIds.borrowIncentivePkg}::user::redeem_rewards`,
4427
4990
  [
4991
+ borrowIncentiveIds.config,
4428
4992
  borrowIncentiveIds.incentivePools,
4429
4993
  borrowIncentiveIds.incentiveAccounts,
4430
- obligaionKey,
4994
+ obligationKey,
4431
4995
  obligationId,
4432
- import_utils16.SUI_CLOCK_OBJECT_ID
4996
+ import_utils17.SUI_CLOCK_OBJECT_ID
4433
4997
  ],
4434
4998
  [rewardType]
4435
4999
  );
@@ -4450,12 +5014,51 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4450
5014
  obligationKey
4451
5015
  );
4452
5016
  const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
4453
- (txn) => txn.kind === "MoveCall" && txn.target === `${builder.address.get("borrowIncentive.id")}::user::unstake`
5017
+ (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(
5018
+ "borrowIncentive.id"
5019
+ )}::user::unstake`))
4454
5020
  );
4455
5021
  if (!obligationLocked || unstakeObligationBeforeStake) {
4456
5022
  txBlock.stakeObligation(obligationArg, obligationtKeyArg);
4457
5023
  }
4458
5024
  },
5025
+ stakeObligationWithVeScaQuick: async (obligation, obligationKey, veScaKey) => {
5026
+ const {
5027
+ obligationId: obligationArg,
5028
+ obligationKey: obligationtKeyArg,
5029
+ obligationLocked
5030
+ } = await requireObligationInfo2(
5031
+ builder,
5032
+ txBlock,
5033
+ obligation,
5034
+ obligationKey
5035
+ );
5036
+ const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
5037
+ (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(
5038
+ "borrowIncentive.id"
5039
+ )}::user::unstake`))
5040
+ );
5041
+ if (!obligationLocked || unstakeObligationBeforeStake) {
5042
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
5043
+ if (veSca) {
5044
+ const bindedObligationId = await getBindedObligationId(
5045
+ builder,
5046
+ veSca.keyId
5047
+ );
5048
+ if (!bindedObligationId || bindedObligationId === obligationArg) {
5049
+ txBlock.stakeObligationWithVesca(
5050
+ obligationArg,
5051
+ obligationtKeyArg,
5052
+ veSca.keyId
5053
+ );
5054
+ } else {
5055
+ txBlock.stakeObligation(obligationArg, obligationtKeyArg);
5056
+ }
5057
+ } else {
5058
+ txBlock.stakeObligation(obligationArg, obligationtKeyArg);
5059
+ }
5060
+ }
5061
+ },
4459
5062
  unstakeObligationQuick: async (obligation, obligationKey) => {
4460
5063
  const {
4461
5064
  obligationId: obligationArg,
@@ -4471,7 +5074,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4471
5074
  txBlock.unstakeObligation(obligationArg, obligationtKeyArg);
4472
5075
  }
4473
5076
  },
4474
- claimBorrowIncentiveQuick: async (coinName, obligation, obligationKey) => {
5077
+ claimBorrowIncentiveQuick: async (coinName, rewardCoinName, obligation, obligationKey) => {
4475
5078
  const {
4476
5079
  obligationId: obligationArg,
4477
5080
  obligationKey: obligationtKeyArg
@@ -4484,13 +5087,14 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4484
5087
  return txBlock.claimBorrowIncentive(
4485
5088
  obligationArg,
4486
5089
  obligationtKeyArg,
4487
- coinName
5090
+ coinName,
5091
+ rewardCoinName
4488
5092
  );
4489
5093
  }
4490
5094
  };
4491
5095
  };
4492
5096
  var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4493
- const txBlock = initTxBlock instanceof import_transactions3.TransactionBlock ? new import_sui_kit7.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit7.SuiTxBlock();
5097
+ const txBlock = initTxBlock instanceof import_transactions3.TransactionBlock ? new import_sui_kit8.SuiTxBlock(initTxBlock) : initTxBlock ? initTxBlock : new import_sui_kit8.SuiTxBlock();
4494
5098
  const normalMethod = generateBorrowIncentiveNormalMethod({
4495
5099
  builder,
4496
5100
  txBlock
@@ -4519,15 +5123,18 @@ var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4519
5123
 
4520
5124
  // src/builders/index.ts
4521
5125
  var newScallopTxBlock = (builder, initTxBlock) => {
5126
+ const vescaTxBlock = newVeScaTxBlock(builder, initTxBlock);
4522
5127
  const borrowIncentiveTxBlock = newBorrowIncentiveTxBlock(
4523
5128
  builder,
4524
- initTxBlock
5129
+ vescaTxBlock
4525
5130
  );
4526
5131
  const spoolTxBlock = newSpoolTxBlock(builder, borrowIncentiveTxBlock);
4527
5132
  const coreTxBlock = newCoreTxBlock(builder, spoolTxBlock);
4528
5133
  return new Proxy(coreTxBlock, {
4529
5134
  get: (target, prop) => {
4530
- if (prop in borrowIncentiveTxBlock) {
5135
+ if (prop in vescaTxBlock) {
5136
+ return Reflect.get(vescaTxBlock, prop);
5137
+ } else if (prop in borrowIncentiveTxBlock) {
4531
5138
  return Reflect.get(borrowIncentiveTxBlock, prop);
4532
5139
  } else if (prop in spoolTxBlock) {
4533
5140
  return Reflect.get(spoolTxBlock, prop);
@@ -4541,7 +5148,7 @@ var newScallopTxBlock = (builder, initTxBlock) => {
4541
5148
  var ScallopBuilder = class {
4542
5149
  constructor(params, instance) {
4543
5150
  this.params = params;
4544
- this.suiKit = instance?.suiKit ?? new import_sui_kit8.SuiKit(params);
5151
+ this.suiKit = instance?.suiKit ?? new import_sui_kit9.SuiKit(params);
4545
5152
  this.address = instance?.address ?? new ScallopAddress({
4546
5153
  id: params?.addressesId || ADDRESSES_ID,
4547
5154
  network: params?.networkType
@@ -4555,7 +5162,7 @@ var ScallopBuilder = class {
4555
5162
  address: this.address,
4556
5163
  query: this.query
4557
5164
  });
4558
- this.walletAddress = (0, import_utils18.normalizeSuiAddress)(
5165
+ this.walletAddress = (0, import_utils19.normalizeSuiAddress)(
4559
5166
  params?.walletAddress || this.suiKit.currentAddress()
4560
5167
  );
4561
5168
  this.isTestnet = params.networkType ? params.networkType === "testnet" : false;
@@ -4634,7 +5241,7 @@ var ScallopBuilder = class {
4634
5241
  var ScallopClient = class {
4635
5242
  constructor(params, instance) {
4636
5243
  this.params = params;
4637
- this.suiKit = instance?.suiKit ?? new import_sui_kit9.SuiKit(params);
5244
+ this.suiKit = instance?.suiKit ?? new import_sui_kit10.SuiKit(params);
4638
5245
  this.address = instance?.address ?? new ScallopAddress({
4639
5246
  id: params?.addressesId || ADDRESSES_ID,
4640
5247
  network: params?.networkType
@@ -4654,7 +5261,7 @@ var ScallopClient = class {
4654
5261
  query: this.query,
4655
5262
  utils: this.utils
4656
5263
  });
4657
- this.walletAddress = (0, import_utils19.normalizeSuiAddress)(
5264
+ this.walletAddress = (0, import_utils20.normalizeSuiAddress)(
4658
5265
  params?.walletAddress || this.suiKit.currentAddress()
4659
5266
  );
4660
5267
  }
@@ -5027,7 +5634,7 @@ var ScallopClient = class {
5027
5634
  const coins = [];
5028
5635
  for (const stakeMarketCoin of stakeMarketCoins2) {
5029
5636
  const stakeCoinName = this.utils.parseCoinName(stakeMarketCoinName);
5030
- const coin = await txBlock.withdraw(stakeMarketCoin, stakeCoinName);
5637
+ const coin = txBlock.withdraw(stakeMarketCoin, stakeCoinName);
5031
5638
  coins.push(coin);
5032
5639
  }
5033
5640
  txBlock.transferObjects(coins, sender);
@@ -5060,17 +5667,17 @@ var ScallopClient = class {
5060
5667
  /**
5061
5668
  * stake obligaion.
5062
5669
  *
5063
- * @param obligaionId - The obligation account object.
5064
- * @param obligaionKeyId - The obligation key account object.
5670
+ * @param obligationId - The obligation account object.
5671
+ * @param obligationKeyId - The obligation key account object.
5065
5672
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5066
5673
  * @param walletAddress - The wallet address of the owner.
5067
5674
  * @return Transaction block response or transaction block
5068
5675
  */
5069
- async stakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5676
+ async stakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5070
5677
  const txBlock = this.builder.createTxBlock();
5071
5678
  const sender = walletAddress || this.walletAddress;
5072
5679
  txBlock.setSender(sender);
5073
- await txBlock.stakeObligationQuick(obligaionId, obligaionKeyId);
5680
+ await txBlock.stakeObligationQuick(obligationId, obligationKeyId);
5074
5681
  if (sign) {
5075
5682
  return await this.suiKit.signAndSendTxn(
5076
5683
  txBlock
@@ -5082,17 +5689,17 @@ var ScallopClient = class {
5082
5689
  /**
5083
5690
  * unstake obligaion.
5084
5691
  *
5085
- * @param obligaionId - The obligation account object.
5086
- * @param obligaionKeyId - The obligation key account object.
5692
+ * @param obligationId - The obligation account object.
5693
+ * @param obligationKeyId - The obligation key account object.
5087
5694
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5088
5695
  * @param walletAddress - The wallet address of the owner.
5089
5696
  * @return Transaction block response or transaction block
5090
5697
  */
5091
- async unstakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5698
+ async unstakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5092
5699
  const txBlock = this.builder.createTxBlock();
5093
5700
  const sender = walletAddress || this.walletAddress;
5094
5701
  txBlock.setSender(sender);
5095
- await txBlock.unstakeObligationQuick(obligaionId, obligaionKeyId);
5702
+ await txBlock.unstakeObligationQuick(obligationId, obligationKeyId);
5096
5703
  if (sign) {
5097
5704
  return await this.suiKit.signAndSendTxn(
5098
5705
  txBlock
@@ -5111,16 +5718,21 @@ var ScallopClient = class {
5111
5718
  * @param walletAddress - The wallet address of the owner.
5112
5719
  * @return Transaction block response or transaction block
5113
5720
  */
5114
- async claimBorrowIncentive(coinName, obligaionId, obligaionKeyId, sign = true, walletAddress) {
5721
+ async claimBorrowIncentive(coinName, obligationId, obligationKeyId, sign = true, walletAddress) {
5115
5722
  const txBlock = this.builder.createTxBlock();
5116
5723
  const sender = walletAddress || this.walletAddress;
5117
5724
  txBlock.setSender(sender);
5118
- const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
5119
- coinName,
5120
- obligaionId,
5121
- obligaionKeyId
5122
- );
5123
- txBlock.transferObjects([rewardCoin], sender);
5725
+ const rewardCoins = [];
5726
+ for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
5727
+ const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
5728
+ coinName,
5729
+ rewardCoinName,
5730
+ obligationId,
5731
+ obligationKeyId
5732
+ );
5733
+ rewardCoins.push(rewardCoin);
5734
+ }
5735
+ txBlock.transferObjects(rewardCoins, sender);
5124
5736
  if (sign) {
5125
5737
  return await this.suiKit.signAndSendTxn(
5126
5738
  txBlock
@@ -5155,7 +5767,7 @@ var ScallopClient = class {
5155
5767
  var Scallop = class {
5156
5768
  constructor(params) {
5157
5769
  this.params = params;
5158
- this.suiKit = new import_sui_kit10.SuiKit(params);
5770
+ this.suiKit = new import_sui_kit11.SuiKit(params);
5159
5771
  this._address = new ScallopAddress({
5160
5772
  id: params?.addressesId || ADDRESSES_ID,
5161
5773
  network: params?.networkType
@@ -5243,7 +5855,14 @@ var Scallop = class {
5243
5855
  ADDRESSES_ID,
5244
5856
  API_BASE_URL,
5245
5857
  BORROW_FEE_PROTOCOL_ID,
5858
+ IS_VE_SCA_TEST,
5859
+ MAX_LOCK_DURATION,
5860
+ MAX_LOCK_ROUNDS,
5861
+ MIN_INITIAL_LOCK_AMOUNT,
5862
+ MIN_TOP_UP_AMOUNT,
5863
+ OLD_BORROW_INCENTIVE_PROTOCOL_ID,
5246
5864
  PROTOCOL_OBJECT_ID,
5865
+ SCA_COIN_TYPE,
5247
5866
  SDK_API_BASE_URL,
5248
5867
  SUPPORT_BORROW_INCENTIVE_POOLS,
5249
5868
  SUPPORT_BORROW_INCENTIVE_REWARDS,
@@ -5260,6 +5879,7 @@ var Scallop = class {
5260
5879
  ScallopIndexer,
5261
5880
  ScallopQuery,
5262
5881
  ScallopUtils,
5882
+ UNLOCK_ROUND_DURATION,
5263
5883
  assetCoins,
5264
5884
  borrowIncentiveRewardCoins,
5265
5885
  coinDecimals,