@scallop-io/sui-scallop-sdk 0.44.17 → 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 +878 -255
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +867 -248
  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 +227 -131
  56. package/src/utils/util.ts +28 -0
package/dist/index.mjs CHANGED
@@ -1,9 +1,12 @@
1
1
  // src/constants/common.ts
2
2
  var API_BASE_URL = "https://sui.api.scallop.io";
3
3
  var SDK_API_BASE_URL = "https://sdk.api.scallop.io";
4
- var ADDRESSES_ID = "6462a088a7ace142bb6d7e9b";
5
- var PROTOCOL_OBJECT_ID = "0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf";
6
- var BORROW_FEE_PROTOCOL_ID = "0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da";
4
+ var IS_VE_SCA_TEST = false;
5
+ var ADDRESSES_ID = IS_VE_SCA_TEST ? "65fb07c39c845425d71d7b18" : "6601955b8b0024600a917079";
6
+ var PROTOCOL_OBJECT_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf";
7
+ var BORROW_FEE_PROTOCOL_ID = IS_VE_SCA_TEST ? "0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778" : "0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da";
8
+ var SCA_COIN_TYPE = IS_VE_SCA_TEST ? `0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524::sca::SCA` : "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA";
9
+ var OLD_BORROW_INCENTIVE_PROTOCOL_ID = "0xc63072e7f5f4983a2efaf5bdba1480d5e7d74d57948e1c7cc436f8e22cbeb410";
7
10
  var SUPPORT_POOLS = [
8
11
  "eth",
9
12
  "btc",
@@ -42,7 +45,7 @@ var SUPPORT_SPOOLS = [
42
45
  ];
43
46
  var SUPPORT_SPOOLS_REWARDS = ["sui"];
44
47
  var SUPPORT_BORROW_INCENTIVE_POOLS = ["sui", "usdc", "usdt"];
45
- var SUPPORT_BORROW_INCENTIVE_REWARDS = ["sui"];
48
+ var SUPPORT_BORROW_INCENTIVE_REWARDS = ["sui", "sca"];
46
49
  var SUPPORT_ORACLES = ["supra", "switchboard", "pyth"];
47
50
  var SUPPORT_PACKAGES = [
48
51
  "coinDecimalsRegistry",
@@ -82,7 +85,8 @@ var coinDecimals = {
82
85
  scetus: 9,
83
86
  safsui: 9,
84
87
  shasui: 9,
85
- svsui: 9
88
+ svsui: 9,
89
+ sca: 9
86
90
  };
87
91
  var assetCoins = {
88
92
  eth: "eth",
@@ -95,7 +99,8 @@ var assetCoins = {
95
99
  cetus: "cetus",
96
100
  afsui: "afsui",
97
101
  hasui: "hasui",
98
- vsui: "vsui"
102
+ vsui: "vsui",
103
+ sca: "sca"
99
104
  };
100
105
  var marketCoins = {
101
106
  seth: "seth",
@@ -131,9 +136,9 @@ var spoolRewardCoins = {
131
136
  svsui: "sui"
132
137
  };
133
138
  var borrowIncentiveRewardCoins = {
134
- sui: "sui",
135
- usdc: "sui",
136
- usdt: "sui"
139
+ sui: ["sui", "sca"],
140
+ usdc: ["sui", "sca"],
141
+ usdt: ["sui", "sca"]
137
142
  };
138
143
  var coinIds = {
139
144
  sui: "0x0000000000000000000000000000000000000000000000000000000000000002",
@@ -146,7 +151,8 @@ var coinIds = {
146
151
  cetus: "0x06864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b",
147
152
  afsui: "0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc",
148
153
  hasui: "0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d",
149
- vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55"
154
+ vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55",
155
+ sca: IS_VE_SCA_TEST ? "0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524" : "0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6"
150
156
  };
151
157
  var wormholeCoinIds = {
152
158
  eth: "0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5",
@@ -160,6 +166,13 @@ var voloCoinIds = {
160
166
  vsui: "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55"
161
167
  };
162
168
 
169
+ // src/constants/vesca.ts
170
+ var UNLOCK_ROUND_DURATION = 60 * 60 * 24;
171
+ var MAX_LOCK_ROUNDS = 1460;
172
+ var MAX_LOCK_DURATION = MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION;
173
+ var MIN_INITIAL_LOCK_AMOUNT = 1e10;
174
+ var MIN_TOP_UP_AMOUNT = 1e9;
175
+
163
176
  // src/models/scallop.ts
164
177
  import { SuiKit as SuiKit5 } from "@scallop-io/sui-kit";
165
178
 
@@ -388,8 +401,17 @@ var EMPTY_ADDRESSES = {
388
401
  adminCap: "",
389
402
  object: "",
390
403
  query: "",
404
+ config: "",
391
405
  incentivePools: "",
392
406
  incentiveAccounts: ""
407
+ },
408
+ vesca: {
409
+ id: "",
410
+ adminCap: "",
411
+ tableId: "",
412
+ table: "",
413
+ treasury: "",
414
+ config: ""
393
415
  }
394
416
  };
395
417
  var ScallopAddress = class {
@@ -717,10 +739,96 @@ var requireSender = (txBlock) => {
717
739
  }
718
740
  return sender;
719
741
  };
742
+ var checkLockSca = (scaAmountOrCoin, lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInSecondTimestamp) => {
743
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
744
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
745
+ if (isInitialLock || isLockExpired) {
746
+ if (scaAmountOrCoin !== void 0 && lockPeriodInDays !== void 0) {
747
+ if (lockPeriodInDays <= 0) {
748
+ throw new Error("Lock period must be greater than 0");
749
+ }
750
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_INITIAL_LOCK_AMOUNT) {
751
+ throw new Error(
752
+ `Minimum lock amount for ${isLockExpired ? "renewing expired veSca" : "initial lock"} is 10 SCA`
753
+ );
754
+ }
755
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
756
+ if (extendLockPeriodInSecond > MAX_LOCK_DURATION) {
757
+ throw new Error(
758
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS} days)`
759
+ );
760
+ }
761
+ } else {
762
+ throw new Error(
763
+ `SCA amount and lock period is required for ${isLockExpired ? "renewing expired veSca" : "initial lock"}`
764
+ );
765
+ }
766
+ } else {
767
+ checkVesca(prevUnlockAtInSecondTimestamp);
768
+ if (typeof scaAmountOrCoin === "number" && scaAmountOrCoin < MIN_TOP_UP_AMOUNT) {
769
+ throw new Error("Minimum top up amount is 1 SCA");
770
+ }
771
+ if (!!newUnlockAtInSecondTimestamp && !!prevUnlockAtInSecondTimestamp) {
772
+ const totalLockDuration = newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp;
773
+ if (totalLockDuration > MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
774
+ throw new Error(
775
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
776
+ );
777
+ }
778
+ }
779
+ }
780
+ };
781
+ var checkExtendLockPeriod = (lockPeriodInDays, newUnlockAtInSecondTimestamp, prevUnlockAtInSecondTimestamp) => {
782
+ checkVesca(prevUnlockAtInSecondTimestamp);
783
+ if (lockPeriodInDays <= 0) {
784
+ throw new Error("Lock period must be greater than 0");
785
+ }
786
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
787
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
788
+ if (isLockExpired) {
789
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
790
+ }
791
+ if (prevUnlockAtInSecondTimestamp) {
792
+ const totalLockDuration = newUnlockAtInSecondTimestamp - prevUnlockAtInSecondTimestamp;
793
+ if (totalLockDuration > MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
794
+ throw new Error(
795
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
796
+ );
797
+ }
798
+ }
799
+ };
800
+ var checkExtendLockAmount = (scaAmount, prevUnlockAtInSecondTimestamp) => {
801
+ checkVesca(prevUnlockAtInSecondTimestamp);
802
+ if (scaAmount < MIN_TOP_UP_AMOUNT) {
803
+ throw new Error("Minimum top up amount is 1 SCA");
804
+ }
805
+ const isInitialLock = !prevUnlockAtInSecondTimestamp;
806
+ const isLockExpired = !isInitialLock && prevUnlockAtInSecondTimestamp * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
807
+ if (isLockExpired) {
808
+ throw new Error("veSca is expired, use renewExpiredVeScaQuick instead");
809
+ }
810
+ };
811
+ var checkRenewExpiredVeSca = (scaAmount, lockPeriodInDays, prevUnlockAtInSecondTimestamp) => {
812
+ checkVesca(prevUnlockAtInSecondTimestamp);
813
+ if (scaAmount < MIN_INITIAL_LOCK_AMOUNT) {
814
+ throw new Error("Minimum lock amount for renewing expired vesca 10 SCA");
815
+ }
816
+ const extendLockPeriodInSecond = lockPeriodInDays * UNLOCK_ROUND_DURATION;
817
+ if (extendLockPeriodInSecond >= MAX_LOCK_DURATION - UNLOCK_ROUND_DURATION) {
818
+ throw new Error(
819
+ `Maximum lock period is ~4 years (${MAX_LOCK_ROUNDS - 1} days)`
820
+ );
821
+ }
822
+ };
823
+ var checkVesca = (prevUnlockAtInSecondTimestamp) => {
824
+ if (prevUnlockAtInSecondTimestamp === void 0) {
825
+ throw new Error("veSca not found");
826
+ }
827
+ };
720
828
 
721
829
  // src/utils/query.ts
722
830
  import BigNumber from "bignumber.js";
723
- import { normalizeStructTag } from "@mysten/sui.js/utils";
831
+ import { normalizeStructTag, parseStructTag } from "@mysten/sui.js/utils";
724
832
  var parseOriginMarketPoolData = (originMarketPoolData) => {
725
833
  return {
726
834
  coinType: normalizeStructTag(originMarketPoolData.type.name),
@@ -936,7 +1044,10 @@ var calculateSpoolRewardPoolData = (parsedSpoolData, parsedSpoolRewardPoolData,
936
1044
  );
937
1045
  const claimedRewardValue = claimedRewardCoin.multipliedBy(rewardCoinPrice);
938
1046
  const rewardValueForYear = BigNumber(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
939
- const rewardRate = rewardValueForYear.dividedBy(calculatedSpoolData.stakedValue).isFinite() ? rewardValueForYear.dividedBy(calculatedSpoolData.stakedValue).toNumber() : Infinity;
1047
+ let rewardRate = rewardValueForYear.dividedBy(calculatedSpoolData.stakedValue).isFinite() ? rewardValueForYear.dividedBy(calculatedSpoolData.stakedValue).toNumber() : Infinity;
1048
+ if (parsedSpoolData.maxPoint === parsedSpoolData.distributedPoint) {
1049
+ rewardRate = Infinity;
1050
+ }
940
1051
  return {
941
1052
  rewardApr: rewardRate,
942
1053
  totalRewardAmount: totalRewardAmount.toNumber(),
@@ -951,119 +1062,112 @@ var calculateSpoolRewardPoolData = (parsedSpoolData, parsedSpoolRewardPoolData,
951
1062
  rewardPerSec: rewardPerSec.toNumber()
952
1063
  };
953
1064
  };
1065
+ var parseOriginBorrowIncentivesPoolPointData = (originBorrowIncentivePoolPointData) => {
1066
+ return {
1067
+ pointType: normalizeStructTag(
1068
+ originBorrowIncentivePoolPointData.point_type.name
1069
+ ),
1070
+ distributedPointPerPeriod: Number(
1071
+ originBorrowIncentivePoolPointData.distributed_point_per_period
1072
+ ),
1073
+ period: Number(originBorrowIncentivePoolPointData.point_distribution_time),
1074
+ distributedPoint: Number(
1075
+ originBorrowIncentivePoolPointData.distributed_point
1076
+ ),
1077
+ points: Number(originBorrowIncentivePoolPointData.points),
1078
+ index: Number(originBorrowIncentivePoolPointData.index),
1079
+ baseWeight: Number(originBorrowIncentivePoolPointData.base_weight),
1080
+ weightedAmount: Number(originBorrowIncentivePoolPointData.weighted_amount),
1081
+ lastUpdate: Number(originBorrowIncentivePoolPointData.last_update)
1082
+ };
1083
+ };
954
1084
  var parseOriginBorrowIncentivePoolData = (originBorrowIncentivePoolData) => {
955
1085
  return {
956
1086
  poolType: normalizeStructTag(originBorrowIncentivePoolData.pool_type.name),
957
- maxPoint: Number(originBorrowIncentivePoolData.max_distributed_point),
958
- distributedPoint: Number(originBorrowIncentivePoolData.distributed_point),
959
- pointPerPeriod: Number(
960
- originBorrowIncentivePoolData.distributed_point_per_period
961
- ),
962
- period: Number(originBorrowIncentivePoolData.point_distribution_time),
963
- maxStake: Number(originBorrowIncentivePoolData.max_stakes),
1087
+ minStakes: Number(originBorrowIncentivePoolData.min_stakes),
1088
+ maxStakes: Number(originBorrowIncentivePoolData.max_stakes),
964
1089
  staked: Number(originBorrowIncentivePoolData.stakes),
965
- index: Number(originBorrowIncentivePoolData.index),
966
1090
  createdAt: Number(originBorrowIncentivePoolData.created_at),
967
- lastUpdate: Number(originBorrowIncentivePoolData.last_update)
1091
+ poolPoints: originBorrowIncentivePoolData.points.reduce(
1092
+ (acc, point) => {
1093
+ const parsed = parseOriginBorrowIncentivesPoolPointData(point);
1094
+ const name = parseStructTag(
1095
+ parsed.pointType
1096
+ ).name.toLowerCase();
1097
+ acc[name] = parsed;
1098
+ return acc;
1099
+ },
1100
+ {}
1101
+ )
968
1102
  };
969
1103
  };
970
- var calculateBorrowIncentivePoolData = (parsedBorrowIncentivePoolData, borrowIncentiveCoinPrice, borrowIncentiveCoinDecimal) => {
1104
+ var calculateBorrowIncentivePoolPointData = (pasredBorrowIncentinvePoolData, parsedBorrowIncentivePoolPointData, rewardCoinPrice, rewardCoinDecimal, poolCoinPrice, poolCoinDecimal) => {
971
1105
  const baseIndexRate = 1e9;
972
1106
  const distributedPointPerSec = BigNumber(
973
- parsedBorrowIncentivePoolData.pointPerPeriod
974
- ).dividedBy(parsedBorrowIncentivePoolData.period);
975
- const pointPerSec = BigNumber(
976
- parsedBorrowIncentivePoolData.pointPerPeriod
977
- ).dividedBy(parsedBorrowIncentivePoolData.period);
978
- const remainingPeriod = BigNumber(parsedBorrowIncentivePoolData.maxPoint).minus(parsedBorrowIncentivePoolData.distributedPoint).dividedBy(pointPerSec);
979
- const startDate = parsedBorrowIncentivePoolData.createdAt;
980
- const endDate = remainingPeriod.plus(parsedBorrowIncentivePoolData.lastUpdate).integerValue().toNumber();
1107
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
1108
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period);
981
1109
  const timeDelta = BigNumber(
982
- Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolData.lastUpdate
983
- ).dividedBy(parsedBorrowIncentivePoolData.period).toFixed(0);
984
- const remainingPoints = BigNumber(
985
- parsedBorrowIncentivePoolData.maxPoint
986
- ).minus(parsedBorrowIncentivePoolData.distributedPoint);
1110
+ Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolPointData.lastUpdate
1111
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period).toFixed(0);
987
1112
  const accumulatedPoints = BigNumber.minimum(
988
1113
  BigNumber(timeDelta).multipliedBy(
989
- parsedBorrowIncentivePoolData.pointPerPeriod
1114
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
990
1115
  ),
991
- remainingPoints
1116
+ BigNumber(parsedBorrowIncentivePoolPointData.points)
992
1117
  );
993
- const currentPointIndex = BigNumber(parsedBorrowIncentivePoolData.index).plus(
994
- accumulatedPoints.dividedBy(parsedBorrowIncentivePoolData.staked).isFinite() ? BigNumber(baseIndexRate).multipliedBy(accumulatedPoints).dividedBy(parsedBorrowIncentivePoolData.staked) : 0
1118
+ const currentPointIndex = BigNumber(
1119
+ parsedBorrowIncentivePoolPointData.index
1120
+ ).plus(
1121
+ accumulatedPoints.dividedBy(parsedBorrowIncentivePoolPointData.weightedAmount).isFinite() ? BigNumber(baseIndexRate).multipliedBy(accumulatedPoints).dividedBy(parsedBorrowIncentivePoolPointData.weightedAmount) : 0
995
1122
  );
996
1123
  const currentTotalDistributedPoint = BigNumber(
997
- parsedBorrowIncentivePoolData.distributedPoint
1124
+ parsedBorrowIncentivePoolPointData.distributedPoint
998
1125
  ).plus(accumulatedPoints);
999
- const stakedAmount = BigNumber(parsedBorrowIncentivePoolData.staked);
1000
- const stakedCoin = stakedAmount.shiftedBy(-1 * borrowIncentiveCoinDecimal);
1001
- const stakedValue = stakedCoin.multipliedBy(borrowIncentiveCoinPrice);
1126
+ const stakedAmount = BigNumber(pasredBorrowIncentinvePoolData.staked);
1127
+ const stakedCoin = stakedAmount.shiftedBy(-1 * poolCoinDecimal);
1128
+ const stakedValue = stakedCoin.multipliedBy(poolCoinPrice);
1129
+ const baseWeight = BigNumber(parsedBorrowIncentivePoolPointData.baseWeight);
1130
+ const weightedStakedAmount = BigNumber(
1131
+ parsedBorrowIncentivePoolPointData.weightedAmount
1132
+ );
1133
+ const weightedStakedCoin = weightedStakedAmount.shiftedBy(
1134
+ -1 * poolCoinDecimal
1135
+ );
1136
+ const weightedStakedValue = weightedStakedCoin.multipliedBy(poolCoinPrice);
1137
+ const rateYearFactor = 365 * 24 * 60 * 60;
1138
+ const rewardPerSec = BigNumber(distributedPointPerSec).dividedBy(
1139
+ parsedBorrowIncentivePoolPointData.period
1140
+ );
1141
+ const rewardValueForYear = BigNumber(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
1142
+ const weightScale = BigNumber("1000000000000");
1143
+ const rewardRate = rewardValueForYear.dividedBy(weightedStakedValue).multipliedBy(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(weightScale).isFinite() ? rewardValueForYear.dividedBy(weightedStakedValue).multipliedBy(parsedBorrowIncentivePoolPointData.baseWeight).dividedBy(weightScale).toNumber() : Infinity;
1002
1144
  return {
1003
1145
  distributedPointPerSec: distributedPointPerSec.toNumber(),
1004
1146
  accumulatedPoints: accumulatedPoints.toNumber(),
1005
1147
  currentPointIndex: currentPointIndex.toNumber(),
1006
1148
  currentTotalDistributedPoint: currentTotalDistributedPoint.toNumber(),
1007
- startDate: new Date(startDate * 1e3),
1008
- endDate: new Date(endDate * 1e3),
1009
1149
  stakedAmount: stakedAmount.toNumber(),
1010
1150
  stakedCoin: stakedCoin.toNumber(),
1011
- stakedValue: stakedValue.toNumber()
1151
+ stakedValue: stakedValue.toNumber(),
1152
+ baseWeight: baseWeight.toNumber(),
1153
+ weightedStakedAmount: weightedStakedAmount.toNumber(),
1154
+ weightedStakedCoin: weightedStakedCoin.toNumber(),
1155
+ weightedStakedValue: weightedStakedValue.toNumber(),
1156
+ rewardApr: rewardRate,
1157
+ rewardPerSec: rewardPerSec.toNumber()
1012
1158
  };
1013
1159
  };
1014
- var parseOriginBorrowIncentiveRewardPoolData = (originBorrowIncentiveRewardPoolData) => {
1160
+ var parseOriginBorrowIncentiveAccountPoolPointData = (originBorrowIncentiveAccountPoolPointData) => {
1015
1161
  return {
1016
- rewardType: normalizeStructTag(
1017
- originBorrowIncentiveRewardPoolData.reward_type.name
1162
+ pointType: normalizeStructTag(
1163
+ originBorrowIncentiveAccountPoolPointData.point_type.name
1018
1164
  ),
1019
- claimedRewards: Number(originBorrowIncentiveRewardPoolData.claimed_rewards),
1020
- exchangeRateNumerator: Number(
1021
- originBorrowIncentiveRewardPoolData.exchange_rate_numerator
1022
- ),
1023
- exchangeRateDenominator: Number(
1024
- originBorrowIncentiveRewardPoolData.exchange_rate_denominator
1165
+ weightedAmount: Number(
1166
+ originBorrowIncentiveAccountPoolPointData.weighted_amount
1025
1167
  ),
1026
- remainingRewards: Number(
1027
- originBorrowIncentiveRewardPoolData.remaining_reward
1028
- )
1029
- };
1030
- };
1031
- var calculateBorrowIncentiveRewardPoolData = (parsedBorrowIncentivePoolData, parsedBorrowIncentiveRewardPoolData, calculatedBorrowIncentivePoolData, rewardCoinPrice, rewardCoinDecimal) => {
1032
- const rateYearFactor = 365 * 24 * 60 * 60;
1033
- const rewardPerSec = BigNumber(
1034
- calculatedBorrowIncentivePoolData.distributedPointPerSec
1035
- ).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1036
- const totalRewardAmount = BigNumber(parsedBorrowIncentivePoolData.maxPoint).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1037
- const totalRewardCoin = totalRewardAmount.shiftedBy(-1 * rewardCoinDecimal);
1038
- const totalRewardValue = totalRewardCoin.multipliedBy(rewardCoinPrice);
1039
- const remaindRewardAmount = BigNumber(
1040
- parsedBorrowIncentiveRewardPoolData.remainingRewards
1041
- );
1042
- const remaindRewardCoin = remaindRewardAmount.shiftedBy(
1043
- -1 * rewardCoinDecimal
1044
- );
1045
- const remaindRewardValue = remaindRewardCoin.multipliedBy(rewardCoinPrice);
1046
- const claimedRewardAmount = BigNumber(
1047
- parsedBorrowIncentiveRewardPoolData.claimedRewards
1048
- );
1049
- const claimedRewardCoin = claimedRewardAmount.shiftedBy(
1050
- -1 * rewardCoinDecimal
1051
- );
1052
- const claimedRewardValue = claimedRewardCoin.multipliedBy(rewardCoinPrice);
1053
- const rewardValueForYear = BigNumber(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
1054
- const rewardRate = rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).isFinite() ? rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).toNumber() : Infinity;
1055
- return {
1056
- rewardApr: rewardRate,
1057
- totalRewardAmount: totalRewardAmount.toNumber(),
1058
- totalRewardCoin: totalRewardCoin.toNumber(),
1059
- totalRewardValue: totalRewardValue.toNumber(),
1060
- remaindRewardAmount: remaindRewardAmount.toNumber(),
1061
- remaindRewardCoin: remaindRewardCoin.toNumber(),
1062
- remaindRewardValue: remaindRewardValue.toNumber(),
1063
- claimedRewardAmount: claimedRewardAmount.toNumber(),
1064
- claimedRewardCoin: claimedRewardCoin.toNumber(),
1065
- claimedRewardValue: claimedRewardValue.toNumber(),
1066
- rewardPerSec: rewardPerSec.toNumber()
1168
+ points: Number(originBorrowIncentiveAccountPoolPointData.points),
1169
+ totalPoints: Number(originBorrowIncentiveAccountPoolPointData.total_points),
1170
+ index: Number(originBorrowIncentiveAccountPoolPointData.index)
1067
1171
  };
1068
1172
  };
1069
1173
  var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) => {
@@ -1071,10 +1175,18 @@ var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) =
1071
1175
  poolType: normalizeStructTag(
1072
1176
  originBorrowIncentiveAccountData.pool_type.name
1073
1177
  ),
1074
- amount: Number(originBorrowIncentiveAccountData.amount),
1075
- index: Number(originBorrowIncentiveAccountData.index),
1076
- points: Number(originBorrowIncentiveAccountData.points),
1077
- totalPoints: Number(originBorrowIncentiveAccountData.total_points)
1178
+ debtAmount: Number(originBorrowIncentiveAccountData.debt_amount),
1179
+ pointList: originBorrowIncentiveAccountData.points_list.reduce(
1180
+ (acc, point) => {
1181
+ const parsed = parseOriginBorrowIncentiveAccountPoolPointData(point);
1182
+ const name = parseStructTag(
1183
+ parsed.pointType
1184
+ ).name.toLowerCase();
1185
+ acc[name] = parsed;
1186
+ return acc;
1187
+ },
1188
+ {}
1189
+ )
1078
1190
  };
1079
1191
  };
1080
1192
  var minBigNumber = (...args) => {
@@ -1102,7 +1214,8 @@ var isMarketCoin = (coinName) => {
1102
1214
  .../* @__PURE__ */ new Set([
1103
1215
  ...SUPPORT_POOLS,
1104
1216
  ...SUPPORT_COLLATERALS,
1105
- ...SUPPORT_SPOOLS_REWARDS
1217
+ ...SUPPORT_SPOOLS_REWARDS,
1218
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
1106
1219
  ])
1107
1220
  ].includes(assetCoinName);
1108
1221
  };
@@ -1136,6 +1249,19 @@ var parseDataFromPythPriceFeed = (feed, address) => {
1136
1249
  throw new Error("Invalid feed id");
1137
1250
  }
1138
1251
  };
1252
+ var findClosestUnlockRound = (unlockAtInSecondTimestamp) => {
1253
+ const unlockDate = new Date(unlockAtInSecondTimestamp * 1e3);
1254
+ const closestTwelveAM = new Date(unlockAtInSecondTimestamp * 1e3);
1255
+ closestTwelveAM.setUTCHours(0, 0, 0, 0);
1256
+ if (unlockDate.getUTCHours() >= 0) {
1257
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() + 1);
1258
+ }
1259
+ const now = (/* @__PURE__ */ new Date()).getTime();
1260
+ if (closestTwelveAM.getTime() - now > MAX_LOCK_DURATION * 1e3) {
1261
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() - 1);
1262
+ }
1263
+ return Math.floor(closestTwelveAM.getTime() / 1e3);
1264
+ };
1139
1265
 
1140
1266
  // src/queries/coreQuery.ts
1141
1267
  var queryMarket = async (query, indexer = false) => {
@@ -1324,7 +1450,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1324
1450
  const fields = marketObject.content.fields;
1325
1451
  const coinType = query.utils.parseCoinType(poolCoinName);
1326
1452
  const balanceSheetParentId = fields.vault.fields.balance_sheets.fields.table.fields.id.id;
1327
- const balanceSheetDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1453
+ const balanceSheetDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1328
1454
  parentId: balanceSheetParentId,
1329
1455
  name: {
1330
1456
  type: "0x1::type_name::TypeName",
@@ -1333,9 +1459,9 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1333
1459
  }
1334
1460
  }
1335
1461
  });
1336
- const balanceSheetDdynamicFieldObject = balanceSheetDdynamicFieldObjectResponse.data;
1337
- if (balanceSheetDdynamicFieldObject && balanceSheetDdynamicFieldObject.content && "fields" in balanceSheetDdynamicFieldObject.content) {
1338
- const dynamicFields = balanceSheetDdynamicFieldObject.content.fields;
1462
+ const balanceSheetDynamicFieldObject = balanceSheetDynamicFieldObjectResponse.data;
1463
+ if (balanceSheetDynamicFieldObject && balanceSheetDynamicFieldObject.content && "fields" in balanceSheetDynamicFieldObject.content) {
1464
+ const dynamicFields = balanceSheetDynamicFieldObject.content.fields;
1339
1465
  balanceSheet = dynamicFields.value.fields;
1340
1466
  }
1341
1467
  const borrowIndexParentId = fields.borrow_dynamics.fields.table.fields.id.id;
@@ -1495,7 +1621,7 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1495
1621
  const fields = marketObject.content.fields;
1496
1622
  const coinType = query.utils.parseCoinType(collateralCoinName);
1497
1623
  const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
1498
- const riskModelDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1624
+ const riskModelDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1499
1625
  parentId: riskModelParentId,
1500
1626
  name: {
1501
1627
  type: "0x1::type_name::TypeName",
@@ -1504,9 +1630,9 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1504
1630
  }
1505
1631
  }
1506
1632
  });
1507
- const riskModelDdynamicFieldObject = riskModelDdynamicFieldObjectResponse.data;
1508
- if (riskModelDdynamicFieldObject && riskModelDdynamicFieldObject.content && "fields" in riskModelDdynamicFieldObject.content) {
1509
- const dynamicFields = riskModelDdynamicFieldObject.content.fields;
1633
+ const riskModelDynamicFieldObject = riskModelDynamicFieldObjectResponse.data;
1634
+ if (riskModelDynamicFieldObject && riskModelDynamicFieldObject.content && "fields" in riskModelDynamicFieldObject.content) {
1635
+ const dynamicFields = riskModelDynamicFieldObject.content.fields;
1510
1636
  riskModel = dynamicFields.value.fields;
1511
1637
  }
1512
1638
  const collateralStatParentId = fields.collateral_stats.fields.table.fields.id.id;
@@ -2176,71 +2302,70 @@ var queryBorrowIncentivePools = async (query, borrowIncentiveCoinNames, indexer
2176
2302
  const incentivePoolsId = query.address.get("borrowIncentive.incentivePools");
2177
2303
  const txBlock = new SuiKitTxBlock2();
2178
2304
  const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
2179
- txBlock.moveCall(queryTarget, [incentivePoolsId], ["0x2::sui::SUI"]);
2305
+ txBlock.moveCall(queryTarget, [incentivePoolsId]);
2180
2306
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2181
2307
  const borrowIncentivePoolsQueryData = queryResult.events[0].parsedJson;
2182
- const parsedBorrowIncentiveRewardPoolData = parseOriginBorrowIncentiveRewardPoolData(
2183
- borrowIncentivePoolsQueryData.reward_pool
2184
- );
2185
- const rewardCoinType = parsedBorrowIncentiveRewardPoolData.rewardType;
2186
- const rewardCoinName = query.utils.parseCoinNameFromType(rewardCoinType);
2187
- const coinPrices = await query.utils.getCoinPrices(
2188
- [.../* @__PURE__ */ new Set([...borrowIncentiveCoinNames, rewardCoinName])]
2189
- );
2190
2308
  const borrowIncentivePools = {};
2191
2309
  if (indexer) {
2192
- const borrowIncentivePoolsIndexer = await query.indexer.getBorrowIncentivePools();
2193
- for (const borrowIncentivePool of Object.values(
2194
- borrowIncentivePoolsIndexer
2195
- )) {
2196
- if (!borrowIncentiveCoinNames.includes(borrowIncentivePool.coinName))
2197
- continue;
2198
- borrowIncentivePool.coinPrice = coinPrices[borrowIncentivePool.coinName] || borrowIncentivePool.coinPrice;
2199
- borrowIncentivePool.rewardCoinPrice = coinPrices[rewardCoinName] || borrowIncentivePool.rewardCoinPrice;
2200
- borrowIncentivePools[borrowIncentivePool.coinName] = borrowIncentivePool;
2201
- }
2202
- return borrowIncentivePools;
2203
2310
  }
2204
2311
  for (const pool of borrowIncentivePoolsQueryData.incentive_pools) {
2205
- const coinType = normalizeStructTag4(pool.pool_type.name);
2206
- const coinName = query.utils.parseCoinNameFromType(coinType);
2207
- const rewardCoinName2 = query.utils.parseCoinNameFromType(rewardCoinType);
2208
- if (!borrowIncentiveCoinNames.includes(coinName)) {
2209
- continue;
2210
- }
2312
+ const borrowIncentivePoolPoints = {};
2211
2313
  const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(pool);
2212
- const coinPrice = coinPrices?.[coinName] ?? 0;
2213
- const coinDecimal = query.utils.getCoinDecimal(coinName);
2214
- const calculatedBorrowIncentivePoolData = calculateBorrowIncentivePoolData(
2215
- parsedBorrowIncentivePoolData,
2216
- coinPrice,
2217
- coinDecimal
2314
+ const coinPrices = await query.utils.getCoinPrices(
2315
+ [
2316
+ .../* @__PURE__ */ new Set([
2317
+ ...borrowIncentiveCoinNames,
2318
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
2319
+ ])
2320
+ ]
2218
2321
  );
2219
- const rewardCoinPrice = coinPrices?.[rewardCoinName2] ?? 0;
2220
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName2);
2221
- const calculatedBorrowIncentiveRewardPoolData = calculateBorrowIncentiveRewardPoolData(
2222
- parsedBorrowIncentivePoolData,
2223
- parsedBorrowIncentiveRewardPoolData,
2224
- calculatedBorrowIncentivePoolData,
2225
- rewardCoinPrice,
2226
- rewardCoinDecimal
2322
+ const poolCoinType = normalizeStructTag4(pool.pool_type.name);
2323
+ const poolCoinName = query.utils.parseCoinNameFromType(
2324
+ poolCoinType
2227
2325
  );
2228
- borrowIncentivePools[coinName] = {
2229
- coinName,
2230
- symbol: query.utils.parseSymbol(coinName),
2231
- coinType,
2232
- rewardCoinType,
2233
- coinDecimal,
2234
- rewardCoinDecimal,
2235
- coinPrice,
2236
- rewardCoinPrice,
2237
- maxPoint: parsedBorrowIncentivePoolData.maxPoint,
2238
- distributedPoint: parsedBorrowIncentivePoolData.distributedPoint,
2239
- maxStake: parsedBorrowIncentivePoolData.maxStake,
2240
- ...calculatedBorrowIncentivePoolData,
2241
- exchangeRateNumerator: parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator,
2242
- exchangeRateDenominator: parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator,
2243
- ...calculatedBorrowIncentiveRewardPoolData
2326
+ const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
2327
+ const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
2328
+ if (!borrowIncentiveCoinNames.includes(poolCoinName)) {
2329
+ continue;
2330
+ }
2331
+ for (const [coinName, poolPoint] of Object.entries(
2332
+ parsedBorrowIncentivePoolData.poolPoints
2333
+ )) {
2334
+ const rewardCoinType = normalizeStructTag4(poolPoint.pointType);
2335
+ const rewardCoinName = query.utils.parseCoinNameFromType(
2336
+ rewardCoinType
2337
+ );
2338
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
2339
+ const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2340
+ const symbol = query.utils.parseSymbol(rewardCoinName);
2341
+ const coinDecimal = query.utils.getCoinDecimal(rewardCoinName);
2342
+ const calculatedPoolPoint = calculateBorrowIncentivePoolPointData(
2343
+ parsedBorrowIncentivePoolData,
2344
+ poolPoint,
2345
+ rewardCoinPrice,
2346
+ rewardCoinDecimal,
2347
+ poolCoinPrice,
2348
+ poolCoinDecimal
2349
+ );
2350
+ borrowIncentivePoolPoints[coinName] = {
2351
+ symbol,
2352
+ coinName: rewardCoinName,
2353
+ coinType: rewardCoinType,
2354
+ coinDecimal,
2355
+ coinPrice: rewardCoinPrice,
2356
+ points: poolPoint.points,
2357
+ distributedPoint: poolPoint.distributedPoint,
2358
+ weightedAmount: poolPoint.weightedAmount,
2359
+ ...calculatedPoolPoint
2360
+ };
2361
+ }
2362
+ borrowIncentivePools[poolCoinName] = {
2363
+ coinName: poolCoinName,
2364
+ symbol: query.utils.parseSymbol(poolCoinName),
2365
+ coinType: poolCoinType,
2366
+ coinDecimal: poolCoinDecimal,
2367
+ coinPrice: poolCoinPrice,
2368
+ points: borrowIncentivePoolPoints
2244
2369
  };
2245
2370
  }
2246
2371
  return borrowIncentivePools;
@@ -2259,19 +2384,13 @@ var queryBorrowIncentiveAccounts = async (query, obligationId, borrowIncentiveCo
2259
2384
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2260
2385
  const borrowIncentiveAccountsQueryData = queryResult.events[0].parsedJson;
2261
2386
  const borrowIncentiveAccounts = Object.values(
2262
- borrowIncentiveAccountsQueryData.incentive_states
2387
+ borrowIncentiveAccountsQueryData.pool_records
2263
2388
  ).reduce((accounts, accountData) => {
2264
2389
  const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(accountData);
2265
2390
  const poolType = parsedBorrowIncentiveAccount.poolType;
2266
2391
  const coinName = query.utils.parseCoinNameFromType(poolType);
2267
2392
  if (borrowIncentiveCoinNames && borrowIncentiveCoinNames.includes(coinName)) {
2268
- accounts[coinName] = {
2269
- poolType,
2270
- amount: parsedBorrowIncentiveAccount.amount,
2271
- points: parsedBorrowIncentiveAccount.points,
2272
- totalPoints: parsedBorrowIncentiveAccount.totalPoints,
2273
- index: parsedBorrowIncentiveAccount.index
2274
- };
2393
+ accounts[coinName] = parsedBorrowIncentiveAccount;
2275
2394
  }
2276
2395
  return accounts;
2277
2396
  }, {});
@@ -2491,9 +2610,8 @@ var getObligationAccounts = async (query, ownerAddress, indexer = false) => {
2491
2610
  };
2492
2611
  var getObligationAccount = async (query, obligationId, ownerAddress, indexer = false, market, coinPrices, coinAmounts) => {
2493
2612
  market = market || await query.queryMarket(indexer);
2494
- const assetCoinNames = [
2613
+ const collateralAssetCoinNames = [
2495
2614
  .../* @__PURE__ */ new Set([
2496
- ...Object.values(market.pools).map((pool) => pool.coinName),
2497
2615
  ...Object.values(market.collaterals).map(
2498
2616
  (collateral) => collateral.coinName
2499
2617
  )
@@ -2505,8 +2623,8 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2505
2623
  indexer
2506
2624
  );
2507
2625
  const borrowIncentiveAccounts = await query.getBorrowIncentiveAccounts(obligationId);
2508
- coinPrices = coinPrices || await query.utils.getCoinPrices(assetCoinNames);
2509
- coinAmounts = coinAmounts || await query.getCoinAmounts(assetCoinNames, ownerAddress);
2626
+ coinPrices = coinPrices || await query.utils.getCoinPrices(collateralAssetCoinNames);
2627
+ coinAmounts = coinAmounts || await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress);
2510
2628
  const collaterals = {};
2511
2629
  const debts = {};
2512
2630
  const borrowIncentives = {};
@@ -2517,7 +2635,7 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2517
2635
  let totalBorrowedPools = 0;
2518
2636
  let totalBorrowedValue = BigNumber3(0);
2519
2637
  let totalBorrowedValueWithWeight = BigNumber3(0);
2520
- for (const assetCoinName of assetCoinNames) {
2638
+ for (const assetCoinName of collateralAssetCoinNames) {
2521
2639
  const collateral = obligationQuery.collaterals.find((collateral2) => {
2522
2640
  const collateralCoinName = query.utils.parseCoinNameFromType(
2523
2641
  collateral2.type.name
@@ -2574,7 +2692,10 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2574
2692
  };
2575
2693
  }
2576
2694
  }
2577
- for (const assetCoinName of assetCoinNames) {
2695
+ const borrowAssetCoinNames = [
2696
+ .../* @__PURE__ */ new Set([...Object.values(market.pools).map((pool) => pool.coinName)])
2697
+ ];
2698
+ for (const assetCoinName of borrowAssetCoinNames) {
2578
2699
  const debt = obligationQuery.debts.find((debt2) => {
2579
2700
  const poolCoinName = query.utils.parseCoinNameFromType(
2580
2701
  debt2.type.name
@@ -2633,34 +2754,51 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2633
2754
  )) {
2634
2755
  const coinName = poolCoinName;
2635
2756
  const borrowIncentivePool = borrowIncentivePools[coinName];
2636
- let availableClaimAmount = BigNumber3(0);
2637
- let availableClaimCoin = BigNumber3(0);
2638
2757
  if (borrowIncentivePool) {
2639
- const accountBorrowedAmount = BigNumber3(borrowIncentiveAccount.amount);
2640
- const baseIndexRate = 1e9;
2641
- const increasedPointRate = borrowIncentivePool.currentPointIndex ? BigNumber3(
2642
- borrowIncentivePool.currentPointIndex - borrowIncentiveAccount.index
2643
- ).dividedBy(baseIndexRate) : 1;
2644
- availableClaimAmount = availableClaimAmount.plus(
2645
- accountBorrowedAmount.multipliedBy(increasedPointRate).plus(borrowIncentiveAccount.points).multipliedBy(borrowIncentivePool.exchangeRateNumerator).dividedBy(borrowIncentivePool.exchangeRateDenominator)
2646
- );
2647
- availableClaimCoin = availableClaimAmount.shiftedBy(
2648
- -1 * borrowIncentivePool.rewardCoinDecimal
2649
- );
2650
- if (availableClaimAmount.isGreaterThan(0)) {
2651
- borrowIncentives[coinName] = {
2652
- coinName: borrowIncentivePool.coinName,
2653
- coinType: borrowIncentivePool.coinType,
2654
- rewardCoinType: borrowIncentivePool.rewardCoinType,
2655
- symbol: borrowIncentivePool.symbol,
2656
- coinDecimal: borrowIncentivePool.coinDecimal,
2657
- rewardCoinDecimal: borrowIncentivePool.rewardCoinDecimal,
2658
- coinPrice: borrowIncentivePool.coinPrice,
2659
- rewardCoinPrice: borrowIncentivePool.rewardCoinPrice,
2660
- availableClaimAmount: availableClaimAmount.toNumber(),
2661
- availableClaimCoin: availableClaimCoin.toNumber()
2662
- };
2758
+ const rewards = [];
2759
+ for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
2760
+ const accountPoint = borrowIncentiveAccount.pointList[rewardCoinName];
2761
+ const poolPoint = borrowIncentivePool.points[rewardCoinName];
2762
+ if (accountPoint && poolPoint) {
2763
+ let availableClaimAmount = BigNumber3(0);
2764
+ let availableClaimCoin = BigNumber3(0);
2765
+ const accountBorrowedAmount = BigNumber3(accountPoint.weightedAmount);
2766
+ const baseIndexRate = 1e9;
2767
+ const increasedPointRate = poolPoint.currentPointIndex ? BigNumber3(
2768
+ poolPoint.currentPointIndex - accountPoint.index
2769
+ ).dividedBy(baseIndexRate) : 1;
2770
+ availableClaimAmount = availableClaimAmount.plus(
2771
+ accountBorrowedAmount.multipliedBy(increasedPointRate).plus(accountPoint.points)
2772
+ );
2773
+ availableClaimCoin = availableClaimAmount.shiftedBy(
2774
+ -1 * poolPoint.coinDecimal
2775
+ );
2776
+ const weightScale = BigNumber3("1000000000000");
2777
+ const boostValue = BigNumber3(accountPoint.weightedAmount).div(
2778
+ BigNumber3(borrowIncentiveAccount.debtAmount).multipliedBy(poolPoint.baseWeight).dividedBy(weightScale)
2779
+ ).toNumber();
2780
+ if (availableClaimAmount.isGreaterThan(0)) {
2781
+ rewards.push({
2782
+ coinName: poolPoint.coinName,
2783
+ coinType: poolPoint.coinType,
2784
+ symbol: poolPoint.symbol,
2785
+ coinDecimal: poolPoint.coinDecimal,
2786
+ coinPrice: poolPoint.coinPrice,
2787
+ availableClaimAmount: availableClaimAmount.toNumber(),
2788
+ availableClaimCoin: availableClaimCoin.toNumber(),
2789
+ boostValue
2790
+ });
2791
+ }
2792
+ }
2663
2793
  }
2794
+ borrowIncentives[coinName] = {
2795
+ coinName: borrowIncentivePool.coinName,
2796
+ coinType: borrowIncentivePool.coinType,
2797
+ symbol: borrowIncentivePool.symbol,
2798
+ coinDecimal: borrowIncentivePool.coinDecimal,
2799
+ coinPrice: borrowIncentivePool.coinPrice,
2800
+ rewards
2801
+ };
2664
2802
  }
2665
2803
  }
2666
2804
  let riskLevel = totalRequiredCollateralValue.isZero() ? BigNumber3(0) : totalBorrowedValueWithWeight.dividedBy(totalRequiredCollateralValue);
@@ -2788,6 +2926,70 @@ var getTotalValueLocked = async (query, indexer = false) => {
2788
2926
  return tvl;
2789
2927
  };
2790
2928
 
2929
+ // src/queries/vescaQuery.ts
2930
+ import BigNumber4 from "bignumber.js";
2931
+ var getVescaKeys = async (query, ownerAddress) => {
2932
+ const owner = ownerAddress || query.suiKit.currentAddress();
2933
+ const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : query.address.get("vesca.id");
2934
+ const veScaKeyType = `${veScaPkgId}::ve_sca::VeScaKey`;
2935
+ const keyObjectsResponse = [];
2936
+ let hasNextPage = false;
2937
+ let nextCursor = null;
2938
+ do {
2939
+ const paginatedKeyObjectsResponse = await query.suiKit.client().getOwnedObjects({
2940
+ owner,
2941
+ filter: {
2942
+ StructType: veScaKeyType
2943
+ },
2944
+ cursor: nextCursor
2945
+ });
2946
+ keyObjectsResponse.push(...paginatedKeyObjectsResponse.data);
2947
+ if (paginatedKeyObjectsResponse.hasNextPage && paginatedKeyObjectsResponse.nextCursor) {
2948
+ hasNextPage = true;
2949
+ nextCursor = paginatedKeyObjectsResponse.nextCursor;
2950
+ } else {
2951
+ hasNextPage = false;
2952
+ }
2953
+ } while (hasNextPage);
2954
+ const keyObjectDatas = keyObjectsResponse.map((objResponse) => objResponse.data).filter((data) => !!data);
2955
+ return keyObjectDatas;
2956
+ };
2957
+ var getVeScas = async (query, ownerAddress) => {
2958
+ const keyObjectDatas = await getVescaKeys(query, ownerAddress);
2959
+ const keyObjectId = keyObjectDatas.map((data) => data.objectId);
2960
+ const veScas = [];
2961
+ for (const keyId of keyObjectId) {
2962
+ const veSca = await getVeSca(query, keyId);
2963
+ if (veSca)
2964
+ veScas.push(veSca);
2965
+ }
2966
+ return veScas;
2967
+ };
2968
+ var getVeSca = async (query, veScaKeyId, ownerAddress) => {
2969
+ const tableId = IS_VE_SCA_TEST ? "0xc607241e4a679fe376d1170b2fbe07b64917bfe69100d4825241cda20039d4bd" : query.address.get(`vesca.tableId`);
2970
+ veScaKeyId = veScaKeyId || (await getVescaKeys(query, ownerAddress))[0].objectId;
2971
+ let vesca = void 0;
2972
+ const veScaDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
2973
+ parentId: tableId,
2974
+ name: {
2975
+ type: "0x2::object::ID",
2976
+ value: veScaKeyId
2977
+ }
2978
+ });
2979
+ const veScaDynamicFieldObject = veScaDynamicFieldObjectResponse.data;
2980
+ if (veScaDynamicFieldObject && veScaDynamicFieldObject.content && veScaDynamicFieldObject.content.dataType === "moveObject" && "fields" in veScaDynamicFieldObject.content) {
2981
+ const dynamicFields = veScaDynamicFieldObject.content.fields.value.fields;
2982
+ vesca = {
2983
+ id: veScaDynamicFieldObject.objectId,
2984
+ keyId: veScaKeyId,
2985
+ lockedScaAmount: BigNumber4(dynamicFields.locked_sca_amount).toNumber(),
2986
+ lockedScaCoin: BigNumber4(dynamicFields.locked_sca_amount).shiftedBy(-9).toNumber(),
2987
+ unlockAt: BigNumber4(dynamicFields.unlock_at).toNumber()
2988
+ };
2989
+ }
2990
+ return vesca;
2991
+ };
2992
+
2791
2993
  // src/models/scallopIndexer.ts
2792
2994
  import axios2 from "axios";
2793
2995
  var ScallopIndexer = class {
@@ -3630,6 +3832,38 @@ var ScallopUtils = class {
3630
3832
  parseApyToApr(apy, compoundFrequency = 365) {
3631
3833
  return ((1 + apy) ** (1 / compoundFrequency) - 1) * compoundFrequency;
3632
3834
  }
3835
+ /**
3836
+ * Give extend lock period to get unlock at in seconds timestamp.
3837
+ *
3838
+ * @description
3839
+ * - When the user without remaining unlock period, If the extended unlock day is not specified,
3840
+ * the unlock period will be increased by one day by default.
3841
+ * - When the given extended day plus the user's remaining unlock period exceeds the maximum
3842
+ * unlock period, the maximum unlock period is used as unlock period.
3843
+ *
3844
+ * @param extendLockPeriodInDay The extend lock period in day.
3845
+ * @param unlockAtInSecondTimestamp The unlock timestamp from veSca object.
3846
+ * @return New unlock at in seconds timestamp.
3847
+ */
3848
+ getUnlockAt(extendLockPeriodInDay, unlockAtInSecondTimestamp) {
3849
+ const now = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
3850
+ const remainingLockPeriod = unlockAtInSecondTimestamp ? Math.max(unlockAtInSecondTimestamp - now, 0) : 0;
3851
+ let newUnlockAtInSecondTimestamp = 0;
3852
+ if (remainingLockPeriod === 0) {
3853
+ const lockPeriod = (extendLockPeriodInDay ?? 1) * UNLOCK_ROUND_DURATION;
3854
+ newUnlockAtInSecondTimestamp = Math.min(
3855
+ now + lockPeriod,
3856
+ now + MAX_LOCK_DURATION
3857
+ );
3858
+ } else {
3859
+ const lockPeriod = Math.min(
3860
+ extendLockPeriodInDay ? extendLockPeriodInDay * UNLOCK_ROUND_DURATION + remainingLockPeriod : remainingLockPeriod,
3861
+ MAX_LOCK_DURATION
3862
+ );
3863
+ newUnlockAtInSecondTimestamp = now + lockPeriod;
3864
+ }
3865
+ return findClosestUnlockRound(newUnlockAtInSecondTimestamp);
3866
+ }
3633
3867
  };
3634
3868
 
3635
3869
  // src/models/scallopBuilder.ts
@@ -4290,9 +4524,282 @@ var newSpoolTxBlock = (builder, initTxBlock) => {
4290
4524
  };
4291
4525
 
4292
4526
  // src/builders/borrowIncentiveBuilder.ts
4293
- import { TransactionBlock as TransactionBlock3 } from "@mysten/sui.js/transactions";
4294
- import { SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID4 } from "@mysten/sui.js/utils";
4295
- import { SuiTxBlock as SuiKitTxBlock5 } from "@scallop-io/sui-kit";
4527
+ import { TransactionBlock as TransactionBlock4 } from "@mysten/sui.js/transactions";
4528
+ import { SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID5 } from "@mysten/sui.js/utils";
4529
+ import { SuiTxBlock as SuiKitTxBlock6 } from "@scallop-io/sui-kit";
4530
+
4531
+ // src/builders/vescaBuilder.ts
4532
+ import {
4533
+ SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID4,
4534
+ TransactionBlock as TransactionBlock3,
4535
+ SuiTxBlock as SuiKitTxBlock5
4536
+ } from "@scallop-io/sui-kit";
4537
+ var requireVeSca = async (...params) => {
4538
+ const [builder, txBlock, veScaKey] = params;
4539
+ if (params.length === 3 && veScaKey && typeof veScaKey === "string") {
4540
+ const veSca = await getVeSca(builder.query, veScaKey);
4541
+ if (!veSca) {
4542
+ return void 0;
4543
+ }
4544
+ return veSca;
4545
+ }
4546
+ const sender = requireSender(txBlock);
4547
+ const veScas = await getVeScas(builder.query, sender);
4548
+ if (veScas.length === 0) {
4549
+ return void 0;
4550
+ }
4551
+ return veScas[0];
4552
+ };
4553
+ var generateNormalVeScaMethod = ({
4554
+ builder,
4555
+ txBlock
4556
+ }) => {
4557
+ const veScaIds = {
4558
+ pkgId: builder.address.get("vesca.id"),
4559
+ table: builder.address.get("vesca.table"),
4560
+ treasury: builder.address.get("vesca.treasury"),
4561
+ config: builder.address.get("vesca.config")
4562
+ };
4563
+ return {
4564
+ lockSca: (scaCoin, unlockAtInSecondTimestamp) => {
4565
+ return txBlock.moveCall(
4566
+ `${veScaIds.pkgId}::ve_sca::mint_ve_sca_key`,
4567
+ [
4568
+ veScaIds.config,
4569
+ veScaIds.table,
4570
+ veScaIds.treasury,
4571
+ scaCoin,
4572
+ unlockAtInSecondTimestamp,
4573
+ SUI_CLOCK_OBJECT_ID4
4574
+ ],
4575
+ []
4576
+ );
4577
+ },
4578
+ extendLockPeriod: (veScaKey, newUnlockAtInSecondTimestamp) => {
4579
+ txBlock.moveCall(
4580
+ `${veScaIds.pkgId}::ve_sca::extend_lock_period`,
4581
+ [
4582
+ veScaIds.config,
4583
+ veScaKey,
4584
+ veScaIds.table,
4585
+ veScaIds.treasury,
4586
+ newUnlockAtInSecondTimestamp,
4587
+ SUI_CLOCK_OBJECT_ID4
4588
+ ],
4589
+ []
4590
+ );
4591
+ },
4592
+ extendLockAmount: (veScaKey, scaCoin) => {
4593
+ txBlock.moveCall(
4594
+ `${veScaIds.pkgId}::ve_sca::lock_more_sca`,
4595
+ [
4596
+ veScaIds.config,
4597
+ veScaKey,
4598
+ veScaIds.table,
4599
+ veScaIds.treasury,
4600
+ scaCoin,
4601
+ SUI_CLOCK_OBJECT_ID4
4602
+ ],
4603
+ []
4604
+ );
4605
+ },
4606
+ renewExpiredVeSca: (veScaKey, scaCoin, newUnlockAtInSecondTimestamp) => {
4607
+ txBlock.moveCall(
4608
+ `${veScaIds.pkgId}::ve_sca::renew_expired_ve_sca`,
4609
+ [
4610
+ veScaIds.config,
4611
+ veScaKey,
4612
+ veScaIds.table,
4613
+ veScaIds.treasury,
4614
+ scaCoin,
4615
+ newUnlockAtInSecondTimestamp,
4616
+ SUI_CLOCK_OBJECT_ID4
4617
+ ],
4618
+ []
4619
+ );
4620
+ },
4621
+ redeemSca: (veScaKey) => {
4622
+ return txBlock.moveCall(
4623
+ `${veScaIds.pkgId}::ve_sca::redeem`,
4624
+ [
4625
+ veScaIds.config,
4626
+ veScaKey,
4627
+ veScaIds.table,
4628
+ veScaIds.treasury,
4629
+ SUI_CLOCK_OBJECT_ID4
4630
+ ],
4631
+ []
4632
+ );
4633
+ }
4634
+ };
4635
+ };
4636
+ var generateQuickVeScaMethod = ({
4637
+ builder,
4638
+ txBlock
4639
+ }) => {
4640
+ return {
4641
+ lockScaQuick: async (amountOrCoin, lockPeriodInDays, autoCheck = true) => {
4642
+ const sender = requireSender(txBlock);
4643
+ const veSca = await requireVeSca(builder, txBlock);
4644
+ let scaCoin = void 0;
4645
+ const transferObjects = [];
4646
+ if (amountOrCoin !== void 0 && typeof amountOrCoin === "number") {
4647
+ const coins = await builder.utils.selectCoinIds(
4648
+ amountOrCoin,
4649
+ SCA_COIN_TYPE,
4650
+ sender
4651
+ );
4652
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4653
+ coins,
4654
+ amountOrCoin
4655
+ );
4656
+ scaCoin = takeCoin;
4657
+ transferObjects.push(leftCoin);
4658
+ } else {
4659
+ scaCoin = amountOrCoin;
4660
+ }
4661
+ const newUnlockAt = builder.utils.getUnlockAt(
4662
+ lockPeriodInDays,
4663
+ veSca?.unlockAt
4664
+ );
4665
+ if (autoCheck)
4666
+ checkLockSca(
4667
+ amountOrCoin,
4668
+ lockPeriodInDays,
4669
+ newUnlockAt,
4670
+ veSca?.unlockAt
4671
+ );
4672
+ console.log(
4673
+ new Date(newUnlockAt * 1e3).toLocaleString("en-CA", {
4674
+ hour12: true
4675
+ })
4676
+ );
4677
+ const isInitialLock = !veSca?.unlockAt;
4678
+ const isLockExpired = !isInitialLock && veSca.unlockAt * 1e3 <= (/* @__PURE__ */ new Date()).getTime();
4679
+ if (isInitialLock || isLockExpired) {
4680
+ if (scaCoin) {
4681
+ if (isInitialLock) {
4682
+ const veScaKey = txBlock.lockSca(scaCoin, newUnlockAt);
4683
+ transferObjects.push(veScaKey);
4684
+ } else {
4685
+ if (veSca.lockedScaAmount !== 0) {
4686
+ const unlockedSca = txBlock.redeemSca(veSca.keyId);
4687
+ transferObjects.push(unlockedSca);
4688
+ }
4689
+ txBlock.renewExpiredVeSca(veSca.keyId, scaCoin, newUnlockAt);
4690
+ }
4691
+ }
4692
+ } else {
4693
+ if (!!scaCoin && !!lockPeriodInDays) {
4694
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4695
+ txBlock.extendLockAmount(veSca.keyId, scaCoin);
4696
+ } else if (lockPeriodInDays) {
4697
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4698
+ } else if (scaCoin) {
4699
+ txBlock.extendLockAmount(veSca.keyId, scaCoin);
4700
+ }
4701
+ }
4702
+ if (transferObjects.length > 0) {
4703
+ txBlock.transferObjects(transferObjects, sender);
4704
+ }
4705
+ },
4706
+ extendLockPeriodQuick: async (lockPeriodInDays, veScaKey, autoCheck = true) => {
4707
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4708
+ const newUnlockAt = builder.utils.getUnlockAt(lockPeriodInDays);
4709
+ if (autoCheck)
4710
+ checkExtendLockPeriod(lockPeriodInDays, newUnlockAt, veSca?.unlockAt);
4711
+ if (veSca) {
4712
+ txBlock.extendLockPeriod(veSca.keyId, newUnlockAt);
4713
+ }
4714
+ },
4715
+ extendLockAmountQuick: async (scaAmount, veScaKey, autoCheck = true) => {
4716
+ const sender = requireSender(txBlock);
4717
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4718
+ if (autoCheck)
4719
+ checkExtendLockAmount(scaAmount, veSca?.unlockAt);
4720
+ if (veSca) {
4721
+ const scaCoins = await builder.utils.selectCoinIds(
4722
+ scaAmount,
4723
+ SCA_COIN_TYPE,
4724
+ sender
4725
+ );
4726
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4727
+ scaCoins,
4728
+ scaAmount
4729
+ );
4730
+ txBlock.extendLockAmount(veSca.keyId, takeCoin);
4731
+ txBlock.transferObjects([leftCoin], sender);
4732
+ }
4733
+ },
4734
+ renewExpiredVeScaQuick: async (scaAmount, lockPeriodInDays, veScaKey, autoCheck = true) => {
4735
+ const sender = requireSender(txBlock);
4736
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4737
+ const newUnlockAt = builder.utils.getUnlockAt(
4738
+ lockPeriodInDays,
4739
+ veSca?.unlockAt
4740
+ );
4741
+ if (autoCheck)
4742
+ checkRenewExpiredVeSca(scaAmount, lockPeriodInDays, veSca?.unlockAt);
4743
+ if (veSca) {
4744
+ const transferObjects = [];
4745
+ if (veSca.lockedScaAmount !== 0) {
4746
+ const unlockedSca = txBlock.redeemSca(veSca.keyId);
4747
+ transferObjects.push(unlockedSca);
4748
+ }
4749
+ const scaCoins = await builder.utils.selectCoinIds(
4750
+ scaAmount,
4751
+ SCA_COIN_TYPE,
4752
+ sender
4753
+ );
4754
+ const [takeCoin, leftCoin] = txBlock.takeAmountFromCoins(
4755
+ scaCoins,
4756
+ scaAmount
4757
+ );
4758
+ transferObjects.push(leftCoin);
4759
+ txBlock.renewExpiredVeSca(veSca.keyId, takeCoin, newUnlockAt);
4760
+ txBlock.transferObjects(transferObjects, sender);
4761
+ }
4762
+ },
4763
+ redeemScaQuick: async (veScaKey) => {
4764
+ const sender = requireSender(txBlock);
4765
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4766
+ checkVesca(veSca?.unlockAt);
4767
+ if (veSca) {
4768
+ const sca = txBlock.redeemSca(veSca.keyId);
4769
+ txBlock.transferObjects([sca], sender);
4770
+ }
4771
+ }
4772
+ };
4773
+ };
4774
+ var newVeScaTxBlock = (builder, initTxBlock) => {
4775
+ const txBlock = initTxBlock instanceof TransactionBlock3 ? new SuiKitTxBlock5(initTxBlock) : initTxBlock ? initTxBlock : new SuiKitTxBlock5();
4776
+ const normalMethod = generateNormalVeScaMethod({
4777
+ builder,
4778
+ txBlock
4779
+ });
4780
+ const normalTxBlock = new Proxy(txBlock, {
4781
+ get: (target, prop) => {
4782
+ if (prop in normalMethod) {
4783
+ return Reflect.get(normalMethod, prop);
4784
+ }
4785
+ return Reflect.get(target, prop);
4786
+ }
4787
+ });
4788
+ const quickMethod = generateQuickVeScaMethod({
4789
+ builder,
4790
+ txBlock: normalTxBlock
4791
+ });
4792
+ return new Proxy(normalTxBlock, {
4793
+ get: (target, prop) => {
4794
+ if (prop in quickMethod) {
4795
+ return Reflect.get(quickMethod, prop);
4796
+ }
4797
+ return Reflect.get(target, prop);
4798
+ }
4799
+ });
4800
+ };
4801
+
4802
+ // src/builders/borrowIncentiveBuilder.ts
4296
4803
  var requireObligationInfo2 = async (...params) => {
4297
4804
  const [builder, txBlock, obligationId, obligationKey] = params;
4298
4805
  if (params.length === 4 && obligationId && obligationKey && typeof obligationId === "string") {
@@ -4313,59 +4820,115 @@ var requireObligationInfo2 = async (...params) => {
4313
4820
  obligationLocked: obligations[0].locked
4314
4821
  };
4315
4822
  };
4823
+ var getBindedObligationId = async (builder, veScaKey) => {
4824
+ const borrowIncentivePkgId = builder.address.get("borrowIncentive.id");
4825
+ const incentivePoolsId = builder.address.get(
4826
+ "borrowIncentive.incentivePools"
4827
+ );
4828
+ const veScaPkgId = IS_VE_SCA_TEST ? "0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8" : builder.address.get("vesca.id");
4829
+ const client = builder.suiKit.client();
4830
+ const incentivePoolsResponse = await client.getObject({
4831
+ id: incentivePoolsId,
4832
+ options: {
4833
+ showContent: true
4834
+ }
4835
+ });
4836
+ if (incentivePoolsResponse.data?.content?.dataType !== "moveObject")
4837
+ return false;
4838
+ const incentivePoolFields = incentivePoolsResponse.data.content.fields;
4839
+ const veScaBindTableId = incentivePoolFields.ve_sca_bind.fields.id.id;
4840
+ const keyType = `${borrowIncentivePkgId}::typed_id::TypedID<${veScaPkgId}::ve_sca::VeScaKey>`;
4841
+ const veScaBindTableResponse = await client.getDynamicFieldObject({
4842
+ parentId: veScaBindTableId,
4843
+ name: {
4844
+ type: keyType,
4845
+ value: veScaKey
4846
+ }
4847
+ });
4848
+ if (veScaBindTableResponse.data?.content?.dataType !== "moveObject")
4849
+ return false;
4850
+ const veScaBindTableFields = veScaBindTableResponse.data.content.fields;
4851
+ const obligationId = veScaBindTableFields.value.fields.id;
4852
+ return obligationId;
4853
+ };
4316
4854
  var generateBorrowIncentiveNormalMethod = ({ builder, txBlock }) => {
4317
4855
  const borrowIncentiveIds = {
4318
- borrowIncentivePkg: builder.address.get("borrowIncentive.id"),
4856
+ borrowIncentivePkg: IS_VE_SCA_TEST ? "0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246" : builder.address.get("borrowIncentive.id"),
4319
4857
  query: builder.address.get("borrowIncentive.query"),
4858
+ config: builder.address.get("borrowIncentive.config"),
4320
4859
  incentivePools: builder.address.get("borrowIncentive.incentivePools"),
4321
4860
  incentiveAccounts: builder.address.get(
4322
4861
  "borrowIncentive.incentiveAccounts"
4323
4862
  ),
4324
4863
  obligationAccessStore: builder.address.get("core.obligationAccessStore")
4325
4864
  };
4865
+ const veScaIds = {
4866
+ table: builder.address.get("vesca.table"),
4867
+ treasury: builder.address.get("vesca.treasury"),
4868
+ config: builder.address.get("vesca.config")
4869
+ };
4326
4870
  return {
4327
- stakeObligation: (obligationId, obligaionKey) => {
4328
- const rewardCoinName = "sui";
4329
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4871
+ stakeObligation: (obligationId, obligationKey) => {
4330
4872
  txBlock.moveCall(
4331
4873
  `${borrowIncentiveIds.borrowIncentivePkg}::user::stake`,
4332
4874
  [
4875
+ borrowIncentiveIds.config,
4333
4876
  borrowIncentiveIds.incentivePools,
4334
4877
  borrowIncentiveIds.incentiveAccounts,
4335
- obligaionKey,
4878
+ obligationKey,
4336
4879
  obligationId,
4337
4880
  borrowIncentiveIds.obligationAccessStore,
4338
- SUI_CLOCK_OBJECT_ID4
4881
+ SUI_CLOCK_OBJECT_ID5
4882
+ ]
4883
+ );
4884
+ },
4885
+ stakeObligationWithVesca: (obligationId, obligationKey, veScaKey) => {
4886
+ txBlock.moveCall(
4887
+ `${borrowIncentiveIds.borrowIncentivePkg}::user::stake_with_ve_sca`,
4888
+ [
4889
+ borrowIncentiveIds.config,
4890
+ borrowIncentiveIds.incentivePools,
4891
+ borrowIncentiveIds.incentiveAccounts,
4892
+ obligationKey,
4893
+ obligationId,
4894
+ borrowIncentiveIds.obligationAccessStore,
4895
+ veScaIds.config,
4896
+ veScaIds.treasury,
4897
+ veScaIds.table,
4898
+ veScaKey,
4899
+ SUI_CLOCK_OBJECT_ID5
4339
4900
  ],
4340
- [rewardType]
4901
+ []
4341
4902
  );
4342
4903
  },
4343
- unstakeObligation: (obligationId, obligaionKey) => {
4344
- const rewardCoinName = "sui";
4345
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4904
+ unstakeObligation: (obligationId, obligationKey) => {
4346
4905
  txBlock.moveCall(
4347
4906
  `${borrowIncentiveIds.borrowIncentivePkg}::user::unstake`,
4348
4907
  [
4908
+ borrowIncentiveIds.config,
4349
4909
  borrowIncentiveIds.incentivePools,
4350
4910
  borrowIncentiveIds.incentiveAccounts,
4351
- obligaionKey,
4911
+ obligationKey,
4352
4912
  obligationId,
4353
- SUI_CLOCK_OBJECT_ID4
4354
- ],
4355
- [rewardType]
4913
+ SUI_CLOCK_OBJECT_ID5
4914
+ ]
4356
4915
  );
4357
4916
  },
4358
- claimBorrowIncentive: (obligationId, obligaionKey, coinName) => {
4359
- const rewardCoinName = borrowIncentiveRewardCoins[coinName];
4917
+ claimBorrowIncentive: (obligationId, obligationKey, coinName, rewardCoinName) => {
4918
+ const rewardCoinNames = borrowIncentiveRewardCoins[coinName];
4919
+ if (rewardCoinNames.includes(rewardCoinName) === false) {
4920
+ throw new Error(`Invalid reward coin name ${rewardCoinName}`);
4921
+ }
4360
4922
  const rewardType = builder.utils.parseCoinType(rewardCoinName);
4361
4923
  return txBlock.moveCall(
4362
4924
  `${borrowIncentiveIds.borrowIncentivePkg}::user::redeem_rewards`,
4363
4925
  [
4926
+ borrowIncentiveIds.config,
4364
4927
  borrowIncentiveIds.incentivePools,
4365
4928
  borrowIncentiveIds.incentiveAccounts,
4366
- obligaionKey,
4929
+ obligationKey,
4367
4930
  obligationId,
4368
- SUI_CLOCK_OBJECT_ID4
4931
+ SUI_CLOCK_OBJECT_ID5
4369
4932
  ],
4370
4933
  [rewardType]
4371
4934
  );
@@ -4386,12 +4949,51 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4386
4949
  obligationKey
4387
4950
  );
4388
4951
  const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
4389
- (txn) => txn.kind === "MoveCall" && txn.target === `${builder.address.get("borrowIncentive.id")}::user::unstake`
4952
+ (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(
4953
+ "borrowIncentive.id"
4954
+ )}::user::unstake`))
4390
4955
  );
4391
4956
  if (!obligationLocked || unstakeObligationBeforeStake) {
4392
4957
  txBlock.stakeObligation(obligationArg, obligationtKeyArg);
4393
4958
  }
4394
4959
  },
4960
+ stakeObligationWithVeScaQuick: async (obligation, obligationKey, veScaKey) => {
4961
+ const {
4962
+ obligationId: obligationArg,
4963
+ obligationKey: obligationtKeyArg,
4964
+ obligationLocked
4965
+ } = await requireObligationInfo2(
4966
+ builder,
4967
+ txBlock,
4968
+ obligation,
4969
+ obligationKey
4970
+ );
4971
+ const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
4972
+ (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(
4973
+ "borrowIncentive.id"
4974
+ )}::user::unstake`))
4975
+ );
4976
+ if (!obligationLocked || unstakeObligationBeforeStake) {
4977
+ const veSca = await requireVeSca(builder, txBlock, veScaKey);
4978
+ if (veSca) {
4979
+ const bindedObligationId = await getBindedObligationId(
4980
+ builder,
4981
+ veSca.keyId
4982
+ );
4983
+ if (!bindedObligationId || bindedObligationId === obligationArg) {
4984
+ txBlock.stakeObligationWithVesca(
4985
+ obligationArg,
4986
+ obligationtKeyArg,
4987
+ veSca.keyId
4988
+ );
4989
+ } else {
4990
+ txBlock.stakeObligation(obligationArg, obligationtKeyArg);
4991
+ }
4992
+ } else {
4993
+ txBlock.stakeObligation(obligationArg, obligationtKeyArg);
4994
+ }
4995
+ }
4996
+ },
4395
4997
  unstakeObligationQuick: async (obligation, obligationKey) => {
4396
4998
  const {
4397
4999
  obligationId: obligationArg,
@@ -4407,7 +5009,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4407
5009
  txBlock.unstakeObligation(obligationArg, obligationtKeyArg);
4408
5010
  }
4409
5011
  },
4410
- claimBorrowIncentiveQuick: async (coinName, obligation, obligationKey) => {
5012
+ claimBorrowIncentiveQuick: async (coinName, rewardCoinName, obligation, obligationKey) => {
4411
5013
  const {
4412
5014
  obligationId: obligationArg,
4413
5015
  obligationKey: obligationtKeyArg
@@ -4420,13 +5022,14 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4420
5022
  return txBlock.claimBorrowIncentive(
4421
5023
  obligationArg,
4422
5024
  obligationtKeyArg,
4423
- coinName
5025
+ coinName,
5026
+ rewardCoinName
4424
5027
  );
4425
5028
  }
4426
5029
  };
4427
5030
  };
4428
5031
  var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4429
- const txBlock = initTxBlock instanceof TransactionBlock3 ? new SuiKitTxBlock5(initTxBlock) : initTxBlock ? initTxBlock : new SuiKitTxBlock5();
5032
+ const txBlock = initTxBlock instanceof TransactionBlock4 ? new SuiKitTxBlock6(initTxBlock) : initTxBlock ? initTxBlock : new SuiKitTxBlock6();
4430
5033
  const normalMethod = generateBorrowIncentiveNormalMethod({
4431
5034
  builder,
4432
5035
  txBlock
@@ -4455,15 +5058,18 @@ var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4455
5058
 
4456
5059
  // src/builders/index.ts
4457
5060
  var newScallopTxBlock = (builder, initTxBlock) => {
5061
+ const vescaTxBlock = newVeScaTxBlock(builder, initTxBlock);
4458
5062
  const borrowIncentiveTxBlock = newBorrowIncentiveTxBlock(
4459
5063
  builder,
4460
- initTxBlock
5064
+ vescaTxBlock
4461
5065
  );
4462
5066
  const spoolTxBlock = newSpoolTxBlock(builder, borrowIncentiveTxBlock);
4463
5067
  const coreTxBlock = newCoreTxBlock(builder, spoolTxBlock);
4464
5068
  return new Proxy(coreTxBlock, {
4465
5069
  get: (target, prop) => {
4466
- if (prop in borrowIncentiveTxBlock) {
5070
+ if (prop in vescaTxBlock) {
5071
+ return Reflect.get(vescaTxBlock, prop);
5072
+ } else if (prop in borrowIncentiveTxBlock) {
4467
5073
  return Reflect.get(borrowIncentiveTxBlock, prop);
4468
5074
  } else if (prop in spoolTxBlock) {
4469
5075
  return Reflect.get(spoolTxBlock, prop);
@@ -4963,7 +5569,7 @@ var ScallopClient = class {
4963
5569
  const coins = [];
4964
5570
  for (const stakeMarketCoin of stakeMarketCoins2) {
4965
5571
  const stakeCoinName = this.utils.parseCoinName(stakeMarketCoinName);
4966
- const coin = await txBlock.withdraw(stakeMarketCoin, stakeCoinName);
5572
+ const coin = txBlock.withdraw(stakeMarketCoin, stakeCoinName);
4967
5573
  coins.push(coin);
4968
5574
  }
4969
5575
  txBlock.transferObjects(coins, sender);
@@ -4996,17 +5602,17 @@ var ScallopClient = class {
4996
5602
  /**
4997
5603
  * stake obligaion.
4998
5604
  *
4999
- * @param obligaionId - The obligation account object.
5000
- * @param obligaionKeyId - The obligation key account object.
5605
+ * @param obligationId - The obligation account object.
5606
+ * @param obligationKeyId - The obligation key account object.
5001
5607
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5002
5608
  * @param walletAddress - The wallet address of the owner.
5003
5609
  * @return Transaction block response or transaction block
5004
5610
  */
5005
- async stakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5611
+ async stakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5006
5612
  const txBlock = this.builder.createTxBlock();
5007
5613
  const sender = walletAddress || this.walletAddress;
5008
5614
  txBlock.setSender(sender);
5009
- await txBlock.stakeObligationQuick(obligaionId, obligaionKeyId);
5615
+ await txBlock.stakeObligationQuick(obligationId, obligationKeyId);
5010
5616
  if (sign) {
5011
5617
  return await this.suiKit.signAndSendTxn(
5012
5618
  txBlock
@@ -5018,17 +5624,17 @@ var ScallopClient = class {
5018
5624
  /**
5019
5625
  * unstake obligaion.
5020
5626
  *
5021
- * @param obligaionId - The obligation account object.
5022
- * @param obligaionKeyId - The obligation key account object.
5627
+ * @param obligationId - The obligation account object.
5628
+ * @param obligationKeyId - The obligation key account object.
5023
5629
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5024
5630
  * @param walletAddress - The wallet address of the owner.
5025
5631
  * @return Transaction block response or transaction block
5026
5632
  */
5027
- async unstakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5633
+ async unstakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5028
5634
  const txBlock = this.builder.createTxBlock();
5029
5635
  const sender = walletAddress || this.walletAddress;
5030
5636
  txBlock.setSender(sender);
5031
- await txBlock.unstakeObligationQuick(obligaionId, obligaionKeyId);
5637
+ await txBlock.unstakeObligationQuick(obligationId, obligationKeyId);
5032
5638
  if (sign) {
5033
5639
  return await this.suiKit.signAndSendTxn(
5034
5640
  txBlock
@@ -5047,16 +5653,21 @@ var ScallopClient = class {
5047
5653
  * @param walletAddress - The wallet address of the owner.
5048
5654
  * @return Transaction block response or transaction block
5049
5655
  */
5050
- async claimBorrowIncentive(coinName, obligaionId, obligaionKeyId, sign = true, walletAddress) {
5656
+ async claimBorrowIncentive(coinName, obligationId, obligationKeyId, sign = true, walletAddress) {
5051
5657
  const txBlock = this.builder.createTxBlock();
5052
5658
  const sender = walletAddress || this.walletAddress;
5053
5659
  txBlock.setSender(sender);
5054
- const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
5055
- coinName,
5056
- obligaionId,
5057
- obligaionKeyId
5058
- );
5059
- txBlock.transferObjects([rewardCoin], sender);
5660
+ const rewardCoins = [];
5661
+ for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
5662
+ const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
5663
+ coinName,
5664
+ rewardCoinName,
5665
+ obligationId,
5666
+ obligationKeyId
5667
+ );
5668
+ rewardCoins.push(rewardCoin);
5669
+ }
5670
+ txBlock.transferObjects(rewardCoins, sender);
5060
5671
  if (sign) {
5061
5672
  return await this.suiKit.signAndSendTxn(
5062
5673
  txBlock
@@ -5178,7 +5789,14 @@ export {
5178
5789
  ADDRESSES_ID,
5179
5790
  API_BASE_URL,
5180
5791
  BORROW_FEE_PROTOCOL_ID,
5792
+ IS_VE_SCA_TEST,
5793
+ MAX_LOCK_DURATION,
5794
+ MAX_LOCK_ROUNDS,
5795
+ MIN_INITIAL_LOCK_AMOUNT,
5796
+ MIN_TOP_UP_AMOUNT,
5797
+ OLD_BORROW_INCENTIVE_PROTOCOL_ID,
5181
5798
  PROTOCOL_OBJECT_ID,
5799
+ SCA_COIN_TYPE,
5182
5800
  SDK_API_BASE_URL,
5183
5801
  SUPPORT_BORROW_INCENTIVE_POOLS,
5184
5802
  SUPPORT_BORROW_INCENTIVE_REWARDS,
@@ -5195,6 +5813,7 @@ export {
5195
5813
  ScallopIndexer,
5196
5814
  ScallopQuery,
5197
5815
  ScallopUtils,
5816
+ UNLOCK_ROUND_DURATION,
5198
5817
  assetCoins,
5199
5818
  borrowIncentiveRewardCoins,
5200
5819
  coinDecimals,