@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.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),
@@ -954,119 +1062,112 @@ var calculateSpoolRewardPoolData = (parsedSpoolData, parsedSpoolRewardPoolData,
954
1062
  rewardPerSec: rewardPerSec.toNumber()
955
1063
  };
956
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
+ };
957
1084
  var parseOriginBorrowIncentivePoolData = (originBorrowIncentivePoolData) => {
958
1085
  return {
959
1086
  poolType: normalizeStructTag(originBorrowIncentivePoolData.pool_type.name),
960
- maxPoint: Number(originBorrowIncentivePoolData.max_distributed_point),
961
- distributedPoint: Number(originBorrowIncentivePoolData.distributed_point),
962
- pointPerPeriod: Number(
963
- originBorrowIncentivePoolData.distributed_point_per_period
964
- ),
965
- period: Number(originBorrowIncentivePoolData.point_distribution_time),
966
- maxStake: Number(originBorrowIncentivePoolData.max_stakes),
1087
+ minStakes: Number(originBorrowIncentivePoolData.min_stakes),
1088
+ maxStakes: Number(originBorrowIncentivePoolData.max_stakes),
967
1089
  staked: Number(originBorrowIncentivePoolData.stakes),
968
- index: Number(originBorrowIncentivePoolData.index),
969
1090
  createdAt: Number(originBorrowIncentivePoolData.created_at),
970
- 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
+ )
971
1102
  };
972
1103
  };
973
- var calculateBorrowIncentivePoolData = (parsedBorrowIncentivePoolData, borrowIncentiveCoinPrice, borrowIncentiveCoinDecimal) => {
1104
+ var calculateBorrowIncentivePoolPointData = (pasredBorrowIncentinvePoolData, parsedBorrowIncentivePoolPointData, rewardCoinPrice, rewardCoinDecimal, poolCoinPrice, poolCoinDecimal) => {
974
1105
  const baseIndexRate = 1e9;
975
1106
  const distributedPointPerSec = BigNumber(
976
- parsedBorrowIncentivePoolData.pointPerPeriod
977
- ).dividedBy(parsedBorrowIncentivePoolData.period);
978
- const pointPerSec = BigNumber(
979
- parsedBorrowIncentivePoolData.pointPerPeriod
980
- ).dividedBy(parsedBorrowIncentivePoolData.period);
981
- const remainingPeriod = BigNumber(parsedBorrowIncentivePoolData.maxPoint).minus(parsedBorrowIncentivePoolData.distributedPoint).dividedBy(pointPerSec);
982
- const startDate = parsedBorrowIncentivePoolData.createdAt;
983
- const endDate = remainingPeriod.plus(parsedBorrowIncentivePoolData.lastUpdate).integerValue().toNumber();
1107
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
1108
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period);
984
1109
  const timeDelta = BigNumber(
985
- Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolData.lastUpdate
986
- ).dividedBy(parsedBorrowIncentivePoolData.period).toFixed(0);
987
- const remainingPoints = BigNumber(
988
- parsedBorrowIncentivePoolData.maxPoint
989
- ).minus(parsedBorrowIncentivePoolData.distributedPoint);
1110
+ Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - parsedBorrowIncentivePoolPointData.lastUpdate
1111
+ ).dividedBy(parsedBorrowIncentivePoolPointData.period).toFixed(0);
990
1112
  const accumulatedPoints = BigNumber.minimum(
991
1113
  BigNumber(timeDelta).multipliedBy(
992
- parsedBorrowIncentivePoolData.pointPerPeriod
1114
+ parsedBorrowIncentivePoolPointData.distributedPointPerPeriod
993
1115
  ),
994
- remainingPoints
1116
+ BigNumber(parsedBorrowIncentivePoolPointData.points)
995
1117
  );
996
- const currentPointIndex = BigNumber(parsedBorrowIncentivePoolData.index).plus(
997
- 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
998
1122
  );
999
1123
  const currentTotalDistributedPoint = BigNumber(
1000
- parsedBorrowIncentivePoolData.distributedPoint
1124
+ parsedBorrowIncentivePoolPointData.distributedPoint
1001
1125
  ).plus(accumulatedPoints);
1002
- const stakedAmount = BigNumber(parsedBorrowIncentivePoolData.staked);
1003
- const stakedCoin = stakedAmount.shiftedBy(-1 * borrowIncentiveCoinDecimal);
1004
- 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;
1005
1144
  return {
1006
1145
  distributedPointPerSec: distributedPointPerSec.toNumber(),
1007
1146
  accumulatedPoints: accumulatedPoints.toNumber(),
1008
1147
  currentPointIndex: currentPointIndex.toNumber(),
1009
1148
  currentTotalDistributedPoint: currentTotalDistributedPoint.toNumber(),
1010
- startDate: new Date(startDate * 1e3),
1011
- endDate: new Date(endDate * 1e3),
1012
1149
  stakedAmount: stakedAmount.toNumber(),
1013
1150
  stakedCoin: stakedCoin.toNumber(),
1014
- 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()
1015
1158
  };
1016
1159
  };
1017
- var parseOriginBorrowIncentiveRewardPoolData = (originBorrowIncentiveRewardPoolData) => {
1160
+ var parseOriginBorrowIncentiveAccountPoolPointData = (originBorrowIncentiveAccountPoolPointData) => {
1018
1161
  return {
1019
- rewardType: normalizeStructTag(
1020
- originBorrowIncentiveRewardPoolData.reward_type.name
1162
+ pointType: normalizeStructTag(
1163
+ originBorrowIncentiveAccountPoolPointData.point_type.name
1021
1164
  ),
1022
- claimedRewards: Number(originBorrowIncentiveRewardPoolData.claimed_rewards),
1023
- exchangeRateNumerator: Number(
1024
- originBorrowIncentiveRewardPoolData.exchange_rate_numerator
1165
+ weightedAmount: Number(
1166
+ originBorrowIncentiveAccountPoolPointData.weighted_amount
1025
1167
  ),
1026
- exchangeRateDenominator: Number(
1027
- originBorrowIncentiveRewardPoolData.exchange_rate_denominator
1028
- ),
1029
- remainingRewards: Number(
1030
- originBorrowIncentiveRewardPoolData.remaining_reward
1031
- )
1032
- };
1033
- };
1034
- var calculateBorrowIncentiveRewardPoolData = (parsedBorrowIncentivePoolData, parsedBorrowIncentiveRewardPoolData, calculatedBorrowIncentivePoolData, rewardCoinPrice, rewardCoinDecimal) => {
1035
- const rateYearFactor = 365 * 24 * 60 * 60;
1036
- const rewardPerSec = BigNumber(
1037
- calculatedBorrowIncentivePoolData.distributedPointPerSec
1038
- ).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1039
- const totalRewardAmount = BigNumber(parsedBorrowIncentivePoolData.maxPoint).multipliedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator).dividedBy(parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator);
1040
- const totalRewardCoin = totalRewardAmount.shiftedBy(-1 * rewardCoinDecimal);
1041
- const totalRewardValue = totalRewardCoin.multipliedBy(rewardCoinPrice);
1042
- const remaindRewardAmount = BigNumber(
1043
- parsedBorrowIncentiveRewardPoolData.remainingRewards
1044
- );
1045
- const remaindRewardCoin = remaindRewardAmount.shiftedBy(
1046
- -1 * rewardCoinDecimal
1047
- );
1048
- const remaindRewardValue = remaindRewardCoin.multipliedBy(rewardCoinPrice);
1049
- const claimedRewardAmount = BigNumber(
1050
- parsedBorrowIncentiveRewardPoolData.claimedRewards
1051
- );
1052
- const claimedRewardCoin = claimedRewardAmount.shiftedBy(
1053
- -1 * rewardCoinDecimal
1054
- );
1055
- const claimedRewardValue = claimedRewardCoin.multipliedBy(rewardCoinPrice);
1056
- const rewardValueForYear = BigNumber(rewardPerSec).shiftedBy(-1 * rewardCoinDecimal).multipliedBy(rateYearFactor).multipliedBy(rewardCoinPrice);
1057
- const rewardRate = rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).isFinite() ? rewardValueForYear.dividedBy(calculatedBorrowIncentivePoolData.stakedValue).toNumber() : Infinity;
1058
- return {
1059
- rewardApr: rewardRate,
1060
- totalRewardAmount: totalRewardAmount.toNumber(),
1061
- totalRewardCoin: totalRewardCoin.toNumber(),
1062
- totalRewardValue: totalRewardValue.toNumber(),
1063
- remaindRewardAmount: remaindRewardAmount.toNumber(),
1064
- remaindRewardCoin: remaindRewardCoin.toNumber(),
1065
- remaindRewardValue: remaindRewardValue.toNumber(),
1066
- claimedRewardAmount: claimedRewardAmount.toNumber(),
1067
- claimedRewardCoin: claimedRewardCoin.toNumber(),
1068
- claimedRewardValue: claimedRewardValue.toNumber(),
1069
- rewardPerSec: rewardPerSec.toNumber()
1168
+ points: Number(originBorrowIncentiveAccountPoolPointData.points),
1169
+ totalPoints: Number(originBorrowIncentiveAccountPoolPointData.total_points),
1170
+ index: Number(originBorrowIncentiveAccountPoolPointData.index)
1070
1171
  };
1071
1172
  };
1072
1173
  var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) => {
@@ -1074,10 +1175,18 @@ var parseOriginBorrowIncentiveAccountData = (originBorrowIncentiveAccountData) =
1074
1175
  poolType: normalizeStructTag(
1075
1176
  originBorrowIncentiveAccountData.pool_type.name
1076
1177
  ),
1077
- amount: Number(originBorrowIncentiveAccountData.amount),
1078
- index: Number(originBorrowIncentiveAccountData.index),
1079
- points: Number(originBorrowIncentiveAccountData.points),
1080
- 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
+ )
1081
1190
  };
1082
1191
  };
1083
1192
  var minBigNumber = (...args) => {
@@ -1105,7 +1214,8 @@ var isMarketCoin = (coinName) => {
1105
1214
  .../* @__PURE__ */ new Set([
1106
1215
  ...SUPPORT_POOLS,
1107
1216
  ...SUPPORT_COLLATERALS,
1108
- ...SUPPORT_SPOOLS_REWARDS
1217
+ ...SUPPORT_SPOOLS_REWARDS,
1218
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
1109
1219
  ])
1110
1220
  ].includes(assetCoinName);
1111
1221
  };
@@ -1139,6 +1249,19 @@ var parseDataFromPythPriceFeed = (feed, address) => {
1139
1249
  throw new Error("Invalid feed id");
1140
1250
  }
1141
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
+ };
1142
1265
 
1143
1266
  // src/queries/coreQuery.ts
1144
1267
  var queryMarket = async (query, indexer = false) => {
@@ -1327,7 +1450,7 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1327
1450
  const fields = marketObject.content.fields;
1328
1451
  const coinType = query.utils.parseCoinType(poolCoinName);
1329
1452
  const balanceSheetParentId = fields.vault.fields.balance_sheets.fields.table.fields.id.id;
1330
- const balanceSheetDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1453
+ const balanceSheetDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1331
1454
  parentId: balanceSheetParentId,
1332
1455
  name: {
1333
1456
  type: "0x1::type_name::TypeName",
@@ -1336,9 +1459,9 @@ var getMarketPool = async (query, poolCoinName, indexer = false, marketObject, c
1336
1459
  }
1337
1460
  }
1338
1461
  });
1339
- const balanceSheetDdynamicFieldObject = balanceSheetDdynamicFieldObjectResponse.data;
1340
- if (balanceSheetDdynamicFieldObject && balanceSheetDdynamicFieldObject.content && "fields" in balanceSheetDdynamicFieldObject.content) {
1341
- 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;
1342
1465
  balanceSheet = dynamicFields.value.fields;
1343
1466
  }
1344
1467
  const borrowIndexParentId = fields.borrow_dynamics.fields.table.fields.id.id;
@@ -1498,7 +1621,7 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1498
1621
  const fields = marketObject.content.fields;
1499
1622
  const coinType = query.utils.parseCoinType(collateralCoinName);
1500
1623
  const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
1501
- const riskModelDdynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1624
+ const riskModelDynamicFieldObjectResponse = await query.suiKit.client().getDynamicFieldObject({
1502
1625
  parentId: riskModelParentId,
1503
1626
  name: {
1504
1627
  type: "0x1::type_name::TypeName",
@@ -1507,9 +1630,9 @@ var getMarketCollateral = async (query, collateralCoinName, indexer = false, mar
1507
1630
  }
1508
1631
  }
1509
1632
  });
1510
- const riskModelDdynamicFieldObject = riskModelDdynamicFieldObjectResponse.data;
1511
- if (riskModelDdynamicFieldObject && riskModelDdynamicFieldObject.content && "fields" in riskModelDdynamicFieldObject.content) {
1512
- 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;
1513
1636
  riskModel = dynamicFields.value.fields;
1514
1637
  }
1515
1638
  const collateralStatParentId = fields.collateral_stats.fields.table.fields.id.id;
@@ -2179,71 +2302,70 @@ var queryBorrowIncentivePools = async (query, borrowIncentiveCoinNames, indexer
2179
2302
  const incentivePoolsId = query.address.get("borrowIncentive.incentivePools");
2180
2303
  const txBlock = new SuiKitTxBlock2();
2181
2304
  const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
2182
- txBlock.moveCall(queryTarget, [incentivePoolsId], ["0x2::sui::SUI"]);
2305
+ txBlock.moveCall(queryTarget, [incentivePoolsId]);
2183
2306
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2184
2307
  const borrowIncentivePoolsQueryData = queryResult.events[0].parsedJson;
2185
- const parsedBorrowIncentiveRewardPoolData = parseOriginBorrowIncentiveRewardPoolData(
2186
- borrowIncentivePoolsQueryData.reward_pool
2187
- );
2188
- const rewardCoinType = parsedBorrowIncentiveRewardPoolData.rewardType;
2189
- const rewardCoinName = query.utils.parseCoinNameFromType(rewardCoinType);
2190
- const coinPrices = await query.utils.getCoinPrices(
2191
- [.../* @__PURE__ */ new Set([...borrowIncentiveCoinNames, rewardCoinName])]
2192
- );
2193
2308
  const borrowIncentivePools = {};
2194
2309
  if (indexer) {
2195
- const borrowIncentivePoolsIndexer = await query.indexer.getBorrowIncentivePools();
2196
- for (const borrowIncentivePool of Object.values(
2197
- borrowIncentivePoolsIndexer
2198
- )) {
2199
- if (!borrowIncentiveCoinNames.includes(borrowIncentivePool.coinName))
2200
- continue;
2201
- borrowIncentivePool.coinPrice = coinPrices[borrowIncentivePool.coinName] || borrowIncentivePool.coinPrice;
2202
- borrowIncentivePool.rewardCoinPrice = coinPrices[rewardCoinName] || borrowIncentivePool.rewardCoinPrice;
2203
- borrowIncentivePools[borrowIncentivePool.coinName] = borrowIncentivePool;
2204
- }
2205
- return borrowIncentivePools;
2206
2310
  }
2207
2311
  for (const pool of borrowIncentivePoolsQueryData.incentive_pools) {
2208
- const coinType = normalizeStructTag4(pool.pool_type.name);
2209
- const coinName = query.utils.parseCoinNameFromType(coinType);
2210
- const rewardCoinName2 = query.utils.parseCoinNameFromType(rewardCoinType);
2211
- if (!borrowIncentiveCoinNames.includes(coinName)) {
2212
- continue;
2213
- }
2312
+ const borrowIncentivePoolPoints = {};
2214
2313
  const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(pool);
2215
- const coinPrice = coinPrices?.[coinName] ?? 0;
2216
- const coinDecimal = query.utils.getCoinDecimal(coinName);
2217
- const calculatedBorrowIncentivePoolData = calculateBorrowIncentivePoolData(
2218
- parsedBorrowIncentivePoolData,
2219
- coinPrice,
2220
- coinDecimal
2314
+ const coinPrices = await query.utils.getCoinPrices(
2315
+ [
2316
+ .../* @__PURE__ */ new Set([
2317
+ ...borrowIncentiveCoinNames,
2318
+ ...SUPPORT_BORROW_INCENTIVE_REWARDS
2319
+ ])
2320
+ ]
2221
2321
  );
2222
- const rewardCoinPrice = coinPrices?.[rewardCoinName2] ?? 0;
2223
- const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName2);
2224
- const calculatedBorrowIncentiveRewardPoolData = calculateBorrowIncentiveRewardPoolData(
2225
- parsedBorrowIncentivePoolData,
2226
- parsedBorrowIncentiveRewardPoolData,
2227
- calculatedBorrowIncentivePoolData,
2228
- rewardCoinPrice,
2229
- rewardCoinDecimal
2322
+ const poolCoinType = normalizeStructTag4(pool.pool_type.name);
2323
+ const poolCoinName = query.utils.parseCoinNameFromType(
2324
+ poolCoinType
2230
2325
  );
2231
- borrowIncentivePools[coinName] = {
2232
- coinName,
2233
- symbol: query.utils.parseSymbol(coinName),
2234
- coinType,
2235
- rewardCoinType,
2236
- coinDecimal,
2237
- rewardCoinDecimal,
2238
- coinPrice,
2239
- rewardCoinPrice,
2240
- maxPoint: parsedBorrowIncentivePoolData.maxPoint,
2241
- distributedPoint: parsedBorrowIncentivePoolData.distributedPoint,
2242
- maxStake: parsedBorrowIncentivePoolData.maxStake,
2243
- ...calculatedBorrowIncentivePoolData,
2244
- exchangeRateNumerator: parsedBorrowIncentiveRewardPoolData.exchangeRateNumerator,
2245
- exchangeRateDenominator: parsedBorrowIncentiveRewardPoolData.exchangeRateDenominator,
2246
- ...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
2247
2369
  };
2248
2370
  }
2249
2371
  return borrowIncentivePools;
@@ -2262,19 +2384,13 @@ var queryBorrowIncentiveAccounts = async (query, obligationId, borrowIncentiveCo
2262
2384
  const queryResult = await query.suiKit.inspectTxn(txBlock);
2263
2385
  const borrowIncentiveAccountsQueryData = queryResult.events[0].parsedJson;
2264
2386
  const borrowIncentiveAccounts = Object.values(
2265
- borrowIncentiveAccountsQueryData.incentive_states
2387
+ borrowIncentiveAccountsQueryData.pool_records
2266
2388
  ).reduce((accounts, accountData) => {
2267
2389
  const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(accountData);
2268
2390
  const poolType = parsedBorrowIncentiveAccount.poolType;
2269
2391
  const coinName = query.utils.parseCoinNameFromType(poolType);
2270
2392
  if (borrowIncentiveCoinNames && borrowIncentiveCoinNames.includes(coinName)) {
2271
- accounts[coinName] = {
2272
- poolType,
2273
- amount: parsedBorrowIncentiveAccount.amount,
2274
- points: parsedBorrowIncentiveAccount.points,
2275
- totalPoints: parsedBorrowIncentiveAccount.totalPoints,
2276
- index: parsedBorrowIncentiveAccount.index
2277
- };
2393
+ accounts[coinName] = parsedBorrowIncentiveAccount;
2278
2394
  }
2279
2395
  return accounts;
2280
2396
  }, {});
@@ -2494,9 +2610,8 @@ var getObligationAccounts = async (query, ownerAddress, indexer = false) => {
2494
2610
  };
2495
2611
  var getObligationAccount = async (query, obligationId, ownerAddress, indexer = false, market, coinPrices, coinAmounts) => {
2496
2612
  market = market || await query.queryMarket(indexer);
2497
- const assetCoinNames = [
2613
+ const collateralAssetCoinNames = [
2498
2614
  .../* @__PURE__ */ new Set([
2499
- ...Object.values(market.pools).map((pool) => pool.coinName),
2500
2615
  ...Object.values(market.collaterals).map(
2501
2616
  (collateral) => collateral.coinName
2502
2617
  )
@@ -2508,8 +2623,8 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2508
2623
  indexer
2509
2624
  );
2510
2625
  const borrowIncentiveAccounts = await query.getBorrowIncentiveAccounts(obligationId);
2511
- coinPrices = coinPrices || await query.utils.getCoinPrices(assetCoinNames);
2512
- coinAmounts = coinAmounts || await query.getCoinAmounts(assetCoinNames, ownerAddress);
2626
+ coinPrices = coinPrices || await query.utils.getCoinPrices(collateralAssetCoinNames);
2627
+ coinAmounts = coinAmounts || await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress);
2513
2628
  const collaterals = {};
2514
2629
  const debts = {};
2515
2630
  const borrowIncentives = {};
@@ -2520,7 +2635,7 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2520
2635
  let totalBorrowedPools = 0;
2521
2636
  let totalBorrowedValue = BigNumber3(0);
2522
2637
  let totalBorrowedValueWithWeight = BigNumber3(0);
2523
- for (const assetCoinName of assetCoinNames) {
2638
+ for (const assetCoinName of collateralAssetCoinNames) {
2524
2639
  const collateral = obligationQuery.collaterals.find((collateral2) => {
2525
2640
  const collateralCoinName = query.utils.parseCoinNameFromType(
2526
2641
  collateral2.type.name
@@ -2577,7 +2692,10 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2577
2692
  };
2578
2693
  }
2579
2694
  }
2580
- 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) {
2581
2699
  const debt = obligationQuery.debts.find((debt2) => {
2582
2700
  const poolCoinName = query.utils.parseCoinNameFromType(
2583
2701
  debt2.type.name
@@ -2636,34 +2754,51 @@ var getObligationAccount = async (query, obligationId, ownerAddress, indexer = f
2636
2754
  )) {
2637
2755
  const coinName = poolCoinName;
2638
2756
  const borrowIncentivePool = borrowIncentivePools[coinName];
2639
- let availableClaimAmount = BigNumber3(0);
2640
- let availableClaimCoin = BigNumber3(0);
2641
2757
  if (borrowIncentivePool) {
2642
- const accountBorrowedAmount = BigNumber3(borrowIncentiveAccount.amount);
2643
- const baseIndexRate = 1e9;
2644
- const increasedPointRate = borrowIncentivePool.currentPointIndex ? BigNumber3(
2645
- borrowIncentivePool.currentPointIndex - borrowIncentiveAccount.index
2646
- ).dividedBy(baseIndexRate) : 1;
2647
- availableClaimAmount = availableClaimAmount.plus(
2648
- accountBorrowedAmount.multipliedBy(increasedPointRate).plus(borrowIncentiveAccount.points).multipliedBy(borrowIncentivePool.exchangeRateNumerator).dividedBy(borrowIncentivePool.exchangeRateDenominator)
2649
- );
2650
- availableClaimCoin = availableClaimAmount.shiftedBy(
2651
- -1 * borrowIncentivePool.rewardCoinDecimal
2652
- );
2653
- if (availableClaimAmount.isGreaterThan(0)) {
2654
- borrowIncentives[coinName] = {
2655
- coinName: borrowIncentivePool.coinName,
2656
- coinType: borrowIncentivePool.coinType,
2657
- rewardCoinType: borrowIncentivePool.rewardCoinType,
2658
- symbol: borrowIncentivePool.symbol,
2659
- coinDecimal: borrowIncentivePool.coinDecimal,
2660
- rewardCoinDecimal: borrowIncentivePool.rewardCoinDecimal,
2661
- coinPrice: borrowIncentivePool.coinPrice,
2662
- rewardCoinPrice: borrowIncentivePool.rewardCoinPrice,
2663
- availableClaimAmount: availableClaimAmount.toNumber(),
2664
- availableClaimCoin: availableClaimCoin.toNumber()
2665
- };
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
+ }
2666
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
+ };
2667
2802
  }
2668
2803
  }
2669
2804
  let riskLevel = totalRequiredCollateralValue.isZero() ? BigNumber3(0) : totalBorrowedValueWithWeight.dividedBy(totalRequiredCollateralValue);
@@ -2791,6 +2926,70 @@ var getTotalValueLocked = async (query, indexer = false) => {
2791
2926
  return tvl;
2792
2927
  };
2793
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
+
2794
2993
  // src/models/scallopIndexer.ts
2795
2994
  import axios2 from "axios";
2796
2995
  var ScallopIndexer = class {
@@ -3633,6 +3832,38 @@ var ScallopUtils = class {
3633
3832
  parseApyToApr(apy, compoundFrequency = 365) {
3634
3833
  return ((1 + apy) ** (1 / compoundFrequency) - 1) * compoundFrequency;
3635
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
+ }
3636
3867
  };
3637
3868
 
3638
3869
  // src/models/scallopBuilder.ts
@@ -4293,9 +4524,282 @@ var newSpoolTxBlock = (builder, initTxBlock) => {
4293
4524
  };
4294
4525
 
4295
4526
  // src/builders/borrowIncentiveBuilder.ts
4296
- import { TransactionBlock as TransactionBlock3 } from "@mysten/sui.js/transactions";
4297
- import { SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID4 } from "@mysten/sui.js/utils";
4298
- 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
4299
4803
  var requireObligationInfo2 = async (...params) => {
4300
4804
  const [builder, txBlock, obligationId, obligationKey] = params;
4301
4805
  if (params.length === 4 && obligationId && obligationKey && typeof obligationId === "string") {
@@ -4316,59 +4820,115 @@ var requireObligationInfo2 = async (...params) => {
4316
4820
  obligationLocked: obligations[0].locked
4317
4821
  };
4318
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
+ };
4319
4854
  var generateBorrowIncentiveNormalMethod = ({ builder, txBlock }) => {
4320
4855
  const borrowIncentiveIds = {
4321
- borrowIncentivePkg: builder.address.get("borrowIncentive.id"),
4856
+ borrowIncentivePkg: IS_VE_SCA_TEST ? "0x4d5a7cefa4147b4ace0ca845b20437d6ac0d32e5f2f855171f745472c2576246" : builder.address.get("borrowIncentive.id"),
4322
4857
  query: builder.address.get("borrowIncentive.query"),
4858
+ config: builder.address.get("borrowIncentive.config"),
4323
4859
  incentivePools: builder.address.get("borrowIncentive.incentivePools"),
4324
4860
  incentiveAccounts: builder.address.get(
4325
4861
  "borrowIncentive.incentiveAccounts"
4326
4862
  ),
4327
4863
  obligationAccessStore: builder.address.get("core.obligationAccessStore")
4328
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
+ };
4329
4870
  return {
4330
- stakeObligation: (obligationId, obligaionKey) => {
4331
- const rewardCoinName = "sui";
4332
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4871
+ stakeObligation: (obligationId, obligationKey) => {
4333
4872
  txBlock.moveCall(
4334
4873
  `${borrowIncentiveIds.borrowIncentivePkg}::user::stake`,
4335
4874
  [
4875
+ borrowIncentiveIds.config,
4336
4876
  borrowIncentiveIds.incentivePools,
4337
4877
  borrowIncentiveIds.incentiveAccounts,
4338
- obligaionKey,
4878
+ obligationKey,
4339
4879
  obligationId,
4340
4880
  borrowIncentiveIds.obligationAccessStore,
4341
- 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
4342
4900
  ],
4343
- [rewardType]
4901
+ []
4344
4902
  );
4345
4903
  },
4346
- unstakeObligation: (obligationId, obligaionKey) => {
4347
- const rewardCoinName = "sui";
4348
- const rewardType = builder.utils.parseCoinType(rewardCoinName);
4904
+ unstakeObligation: (obligationId, obligationKey) => {
4349
4905
  txBlock.moveCall(
4350
4906
  `${borrowIncentiveIds.borrowIncentivePkg}::user::unstake`,
4351
4907
  [
4908
+ borrowIncentiveIds.config,
4352
4909
  borrowIncentiveIds.incentivePools,
4353
4910
  borrowIncentiveIds.incentiveAccounts,
4354
- obligaionKey,
4911
+ obligationKey,
4355
4912
  obligationId,
4356
- SUI_CLOCK_OBJECT_ID4
4357
- ],
4358
- [rewardType]
4913
+ SUI_CLOCK_OBJECT_ID5
4914
+ ]
4359
4915
  );
4360
4916
  },
4361
- claimBorrowIncentive: (obligationId, obligaionKey, coinName) => {
4362
- 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
+ }
4363
4922
  const rewardType = builder.utils.parseCoinType(rewardCoinName);
4364
4923
  return txBlock.moveCall(
4365
4924
  `${borrowIncentiveIds.borrowIncentivePkg}::user::redeem_rewards`,
4366
4925
  [
4926
+ borrowIncentiveIds.config,
4367
4927
  borrowIncentiveIds.incentivePools,
4368
4928
  borrowIncentiveIds.incentiveAccounts,
4369
- obligaionKey,
4929
+ obligationKey,
4370
4930
  obligationId,
4371
- SUI_CLOCK_OBJECT_ID4
4931
+ SUI_CLOCK_OBJECT_ID5
4372
4932
  ],
4373
4933
  [rewardType]
4374
4934
  );
@@ -4389,12 +4949,51 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4389
4949
  obligationKey
4390
4950
  );
4391
4951
  const unstakeObligationBeforeStake = !!txBlock.txBlock.blockData.transactions.find(
4392
- (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`))
4393
4955
  );
4394
4956
  if (!obligationLocked || unstakeObligationBeforeStake) {
4395
4957
  txBlock.stakeObligation(obligationArg, obligationtKeyArg);
4396
4958
  }
4397
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
+ },
4398
4997
  unstakeObligationQuick: async (obligation, obligationKey) => {
4399
4998
  const {
4400
4999
  obligationId: obligationArg,
@@ -4410,7 +5009,7 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4410
5009
  txBlock.unstakeObligation(obligationArg, obligationtKeyArg);
4411
5010
  }
4412
5011
  },
4413
- claimBorrowIncentiveQuick: async (coinName, obligation, obligationKey) => {
5012
+ claimBorrowIncentiveQuick: async (coinName, rewardCoinName, obligation, obligationKey) => {
4414
5013
  const {
4415
5014
  obligationId: obligationArg,
4416
5015
  obligationKey: obligationtKeyArg
@@ -4423,13 +5022,14 @@ var generateBorrowIncentiveQuickMethod = ({ builder, txBlock }) => {
4423
5022
  return txBlock.claimBorrowIncentive(
4424
5023
  obligationArg,
4425
5024
  obligationtKeyArg,
4426
- coinName
5025
+ coinName,
5026
+ rewardCoinName
4427
5027
  );
4428
5028
  }
4429
5029
  };
4430
5030
  };
4431
5031
  var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4432
- 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();
4433
5033
  const normalMethod = generateBorrowIncentiveNormalMethod({
4434
5034
  builder,
4435
5035
  txBlock
@@ -4458,15 +5058,18 @@ var newBorrowIncentiveTxBlock = (builder, initTxBlock) => {
4458
5058
 
4459
5059
  // src/builders/index.ts
4460
5060
  var newScallopTxBlock = (builder, initTxBlock) => {
5061
+ const vescaTxBlock = newVeScaTxBlock(builder, initTxBlock);
4461
5062
  const borrowIncentiveTxBlock = newBorrowIncentiveTxBlock(
4462
5063
  builder,
4463
- initTxBlock
5064
+ vescaTxBlock
4464
5065
  );
4465
5066
  const spoolTxBlock = newSpoolTxBlock(builder, borrowIncentiveTxBlock);
4466
5067
  const coreTxBlock = newCoreTxBlock(builder, spoolTxBlock);
4467
5068
  return new Proxy(coreTxBlock, {
4468
5069
  get: (target, prop) => {
4469
- if (prop in borrowIncentiveTxBlock) {
5070
+ if (prop in vescaTxBlock) {
5071
+ return Reflect.get(vescaTxBlock, prop);
5072
+ } else if (prop in borrowIncentiveTxBlock) {
4470
5073
  return Reflect.get(borrowIncentiveTxBlock, prop);
4471
5074
  } else if (prop in spoolTxBlock) {
4472
5075
  return Reflect.get(spoolTxBlock, prop);
@@ -4966,7 +5569,7 @@ var ScallopClient = class {
4966
5569
  const coins = [];
4967
5570
  for (const stakeMarketCoin of stakeMarketCoins2) {
4968
5571
  const stakeCoinName = this.utils.parseCoinName(stakeMarketCoinName);
4969
- const coin = await txBlock.withdraw(stakeMarketCoin, stakeCoinName);
5572
+ const coin = txBlock.withdraw(stakeMarketCoin, stakeCoinName);
4970
5573
  coins.push(coin);
4971
5574
  }
4972
5575
  txBlock.transferObjects(coins, sender);
@@ -4999,17 +5602,17 @@ var ScallopClient = class {
4999
5602
  /**
5000
5603
  * stake obligaion.
5001
5604
  *
5002
- * @param obligaionId - The obligation account object.
5003
- * @param obligaionKeyId - The obligation key account object.
5605
+ * @param obligationId - The obligation account object.
5606
+ * @param obligationKeyId - The obligation key account object.
5004
5607
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5005
5608
  * @param walletAddress - The wallet address of the owner.
5006
5609
  * @return Transaction block response or transaction block
5007
5610
  */
5008
- async stakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5611
+ async stakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5009
5612
  const txBlock = this.builder.createTxBlock();
5010
5613
  const sender = walletAddress || this.walletAddress;
5011
5614
  txBlock.setSender(sender);
5012
- await txBlock.stakeObligationQuick(obligaionId, obligaionKeyId);
5615
+ await txBlock.stakeObligationQuick(obligationId, obligationKeyId);
5013
5616
  if (sign) {
5014
5617
  return await this.suiKit.signAndSendTxn(
5015
5618
  txBlock
@@ -5021,17 +5624,17 @@ var ScallopClient = class {
5021
5624
  /**
5022
5625
  * unstake obligaion.
5023
5626
  *
5024
- * @param obligaionId - The obligation account object.
5025
- * @param obligaionKeyId - The obligation key account object.
5627
+ * @param obligationId - The obligation account object.
5628
+ * @param obligationKeyId - The obligation key account object.
5026
5629
  * @param sign - Decide to directly sign the transaction or return the transaction block.
5027
5630
  * @param walletAddress - The wallet address of the owner.
5028
5631
  * @return Transaction block response or transaction block
5029
5632
  */
5030
- async unstakeObligation(obligaionId, obligaionKeyId, sign = true, walletAddress) {
5633
+ async unstakeObligation(obligationId, obligationKeyId, sign = true, walletAddress) {
5031
5634
  const txBlock = this.builder.createTxBlock();
5032
5635
  const sender = walletAddress || this.walletAddress;
5033
5636
  txBlock.setSender(sender);
5034
- await txBlock.unstakeObligationQuick(obligaionId, obligaionKeyId);
5637
+ await txBlock.unstakeObligationQuick(obligationId, obligationKeyId);
5035
5638
  if (sign) {
5036
5639
  return await this.suiKit.signAndSendTxn(
5037
5640
  txBlock
@@ -5050,16 +5653,21 @@ var ScallopClient = class {
5050
5653
  * @param walletAddress - The wallet address of the owner.
5051
5654
  * @return Transaction block response or transaction block
5052
5655
  */
5053
- async claimBorrowIncentive(coinName, obligaionId, obligaionKeyId, sign = true, walletAddress) {
5656
+ async claimBorrowIncentive(coinName, obligationId, obligationKeyId, sign = true, walletAddress) {
5054
5657
  const txBlock = this.builder.createTxBlock();
5055
5658
  const sender = walletAddress || this.walletAddress;
5056
5659
  txBlock.setSender(sender);
5057
- const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
5058
- coinName,
5059
- obligaionId,
5060
- obligaionKeyId
5061
- );
5062
- 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);
5063
5671
  if (sign) {
5064
5672
  return await this.suiKit.signAndSendTxn(
5065
5673
  txBlock
@@ -5181,7 +5789,14 @@ export {
5181
5789
  ADDRESSES_ID,
5182
5790
  API_BASE_URL,
5183
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,
5184
5798
  PROTOCOL_OBJECT_ID,
5799
+ SCA_COIN_TYPE,
5185
5800
  SDK_API_BASE_URL,
5186
5801
  SUPPORT_BORROW_INCENTIVE_POOLS,
5187
5802
  SUPPORT_BORROW_INCENTIVE_REWARDS,
@@ -5198,6 +5813,7 @@ export {
5198
5813
  ScallopIndexer,
5199
5814
  ScallopQuery,
5200
5815
  ScallopUtils,
5816
+ UNLOCK_ROUND_DURATION,
5201
5817
  assetCoins,
5202
5818
  borrowIncentiveRewardCoins,
5203
5819
  coinDecimals,