@scallop-io/sui-scallop-sdk 1.4.0 → 1.4.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/constants/common.d.ts +3 -3
  2. package/dist/constants/enum.d.ts +2 -2
  3. package/dist/index.js +220 -150
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +219 -149
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/models/scallopClient.d.ts +4 -4
  8. package/dist/models/scallopQuery.d.ts +40 -6
  9. package/dist/models/scallopUtils.d.ts +11 -11
  10. package/dist/queries/borrowIncentiveQuery.d.ts +2 -2
  11. package/dist/queries/coreQuery.d.ts +0 -2
  12. package/dist/queries/portfolioQuery.d.ts +0 -2
  13. package/dist/queries/priceQuery.d.ts +32 -2
  14. package/dist/queries/sCoinQuery.d.ts +1 -1
  15. package/dist/test.d.ts +0 -0
  16. package/dist/types/builder/borrowIncentive.d.ts +6 -6
  17. package/dist/types/constant/common.d.ts +1 -1
  18. package/dist/types/utils.d.ts +2 -6
  19. package/package.json +1 -1
  20. package/src/builders/borrowIncentiveBuilder.ts +2 -13
  21. package/src/constants/coinGecko.ts +3 -2
  22. package/src/constants/common.ts +10 -5
  23. package/src/constants/enum.ts +44 -34
  24. package/src/constants/poolAddress.ts +9 -8
  25. package/src/constants/pyth.ts +3 -2
  26. package/src/models/scallopClient.ts +27 -10
  27. package/src/models/scallopQuery.ts +18 -1
  28. package/src/models/scallopUtils.ts +23 -18
  29. package/src/queries/borrowIncentiveQuery.ts +29 -12
  30. package/src/queries/borrowLimitQuery.ts +3 -2
  31. package/src/queries/coreQuery.ts +4 -10
  32. package/src/queries/isolatedAssetQuery.ts +3 -2
  33. package/src/queries/portfolioQuery.ts +65 -62
  34. package/src/queries/priceQuery.ts +35 -2
  35. package/src/queries/sCoinQuery.ts +1 -1
  36. package/src/queries/spoolQuery.ts +2 -4
  37. package/src/queries/supplyLimitQuery.ts +3 -2
  38. package/src/test.ts +20 -0
  39. package/src/types/builder/borrowIncentive.ts +10 -15
  40. package/src/types/constant/common.ts +1 -2
  41. package/src/types/utils.ts +2 -10
  42. package/src/utils/query.ts +0 -87
@@ -4,7 +4,6 @@ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
4
4
  import {
5
5
  ADDRESSES_ID,
6
6
  SUPPORT_BORROW_INCENTIVE_POOLS,
7
- SUPPORT_BORROW_INCENTIVE_REWARDS,
8
7
  SUPPORT_SCOIN,
9
8
  SUPPORT_SPOOLS,
10
9
  } from '../constants';
@@ -28,7 +27,6 @@ import type {
28
27
  SupportAssetCoins,
29
28
  SupportStakeCoins,
30
29
  SupportStakeMarketCoins,
31
- SupportBorrowIncentiveCoins,
32
30
  ScallopTxBlock,
33
31
  SupportSCoin,
34
32
  ScallopClientVeScaReturnType,
@@ -945,9 +943,9 @@ export class ScallopClient {
945
943
  }
946
944
 
947
945
  /**
948
- * unstake market coin from the specific spool.
946
+ * Claim borrow incentive reward.
949
947
  *
950
- * @param marketCoinName - Types of mak coin.
948
+ * @param poolName
951
949
  * @param amount - The amount of coins would deposit.
952
950
  * @param sign - Decide to directly sign the transaction or return the transaction block.
953
951
  * @param accountId - The stake account object.
@@ -955,7 +953,6 @@ export class ScallopClient {
955
953
  * @return Transaction block response or transaction block
956
954
  */
957
955
  public async claimBorrowIncentive<S extends boolean>(
958
- coinName: SupportBorrowIncentiveCoins,
959
956
  obligationId: string,
960
957
  obligationKeyId: string,
961
958
  sign: S = true as S,
@@ -965,17 +962,37 @@ export class ScallopClient {
965
962
  const sender = walletAddress ?? this.walletAddress;
966
963
  txBlock.setSender(sender);
967
964
 
968
- const rewardCoins = [];
969
- for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
965
+ const rewardCoinsCollection: Record<string, TransactionResult[]> = {};
966
+ const obligationAccount =
967
+ await this.query.getObligationAccount(obligationId);
968
+ const rewardCoinNames = Object.values(obligationAccount.borrowIncentives)
969
+ .flatMap(({ rewards }) =>
970
+ rewards.filter(({ availableClaimAmount }) => availableClaimAmount > 0)
971
+ )
972
+ .flatMap(({ coinName }) => coinName);
973
+ for (const rewardCoinName of rewardCoinNames) {
970
974
  const rewardCoin = await txBlock.claimBorrowIncentiveQuick(
971
- coinName,
972
975
  rewardCoinName,
973
976
  obligationId,
974
977
  obligationKeyId
975
978
  );
976
- rewardCoins.push(rewardCoin);
979
+ if (!rewardCoinsCollection[rewardCoinName]) {
980
+ rewardCoinsCollection[rewardCoinName] = [rewardCoin];
981
+ } else {
982
+ rewardCoinsCollection[rewardCoinName].push(rewardCoin);
983
+ }
977
984
  }
978
- txBlock.transferObjects(rewardCoins, sender);
985
+
986
+ txBlock.transferObjects(
987
+ Object.values(rewardCoinsCollection).map((rewardCoins) => {
988
+ const mergeDest = rewardCoins[0];
989
+ if (rewardCoins.length > 1) {
990
+ txBlock.mergeCoins(mergeDest, rewardCoins.slice(1));
991
+ }
992
+ return mergeDest;
993
+ }),
994
+ sender
995
+ );
979
996
 
980
997
  if (sign) {
981
998
  return (await this.suiKit.signAndSendTxn(
@@ -47,6 +47,7 @@ import {
47
47
  getSCoinAmounts,
48
48
  getSCoinSwapRate,
49
49
  getSCoinTotalSupply,
50
+ getAllCoinPrices,
50
51
  } from '../queries';
51
52
  import {
52
53
  ScallopQueryParams,
@@ -544,12 +545,17 @@ export class ScallopQuery {
544
545
  */
545
546
  public async getBorrowIncentivePools(
546
547
  coinNames?: SupportBorrowIncentiveCoins[],
547
- args?: { coinPrices: CoinPrices; indexer?: boolean }
548
+ args?: {
549
+ coinPrices: CoinPrices;
550
+ indexer?: boolean;
551
+ marketPools?: MarketPools;
552
+ }
548
553
  ) {
549
554
  return await getBorrowIncentivePools(
550
555
  this,
551
556
  coinNames,
552
557
  args?.indexer,
558
+ args?.marketPools,
553
559
  args?.coinPrices
554
560
  );
555
561
  }
@@ -824,4 +830,15 @@ export class ScallopQuery {
824
830
  public async getCoinPriceByIndexer(poolName: SupportPoolCoins) {
825
831
  return this.indexer.getCoinPrice(poolName);
826
832
  }
833
+
834
+ /**
835
+ * Get all coin prices, including sCoin
836
+ * @returns prices data
837
+ */
838
+ public async getAllCoinPrices(args?: {
839
+ marketPools?: MarketPools;
840
+ coinPrices?: CoinPrices;
841
+ }) {
842
+ return getAllCoinPrices(this, args?.marketPools, args?.coinPrices);
843
+ }
827
844
  }
@@ -8,7 +8,6 @@ import {
8
8
  SUPPORT_POOLS,
9
9
  SUPPORT_COLLATERALS,
10
10
  spoolRewardCoins,
11
- borrowIncentiveRewardCoins,
12
11
  coinDecimals,
13
12
  wormholeCoinIds,
14
13
  voloCoinIds,
@@ -21,6 +20,7 @@ import {
21
20
  COIN_GECKGO_IDS,
22
21
  POOL_ADDRESSES,
23
22
  sCoinTypeToName,
23
+ sCoinRawNameToName,
24
24
  } from '../constants';
25
25
  import { getPythPrices, queryObligation } from '../queries';
26
26
  import {
@@ -40,7 +40,6 @@ import type {
40
40
  SupportAssetCoins,
41
41
  SupportMarketCoins,
42
42
  SupportStakeMarketCoins,
43
- SupportBorrowIncentiveCoins,
44
43
  CoinPrices,
45
44
  CoinWrappedType,
46
45
  SupportSCoin,
@@ -157,7 +156,14 @@ export class ScallopUtils {
157
156
  * @param coinName - Specific support coin name.
158
157
  * @return Coin type.
159
158
  */
160
- public parseCoinType(coinName: SupportCoins) {
159
+ public parseCoinType(
160
+ coinName: SupportCoins,
161
+ useOldMarketCoin: boolean = false
162
+ ) {
163
+ // try parse scoin first
164
+ if (sCoinIds[coinName as SupportSCoin] && !useOldMarketCoin) {
165
+ return sCoinIds[coinName as SupportSCoin];
166
+ }
161
167
  coinName = isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName;
162
168
  const coinPackageId =
163
169
  this.address.get(`core.coins.${coinName}.id`) ||
@@ -225,6 +231,16 @@ export class ScallopUtils {
225
231
  }
226
232
  }
227
233
 
234
+ /**
235
+ * Convert sCoin name to coin name.
236
+ * This function will parse new sCoin name `scallop_...` to its old market coin name which is shorter
237
+ * e.g: `scallop_sui -> ssui
238
+ * @return sCoin name
239
+ */
240
+ public parseCoinNameFromSCoinName(coinName: string) {
241
+ return sCoinRawNameToName[coinName];
242
+ }
243
+
228
244
  /**
229
245
  * Convert sCoin name into sCoin type
230
246
  * @param sCoinName
@@ -272,7 +288,7 @@ export class ScallopUtils {
272
288
  public parseMarketCoinType(coinName: SupportCoins) {
273
289
  const protocolObjectId =
274
290
  this.address.get('core.object') ?? PROTOCOL_OBJECT_ID;
275
- const coinType = this.parseCoinType(coinName);
291
+ const coinType = this.parseCoinType(coinName, true);
276
292
  return `${protocolObjectId}::reserve::MarketCoin<${coinType}>`;
277
293
  }
278
294
 
@@ -297,12 +313,13 @@ export class ScallopUtils {
297
313
  ): T extends SupportCoins ? T : SupportCoins;
298
314
  public parseCoinNameFromType(coinType: string) {
299
315
  coinType = normalizeStructTag(coinType);
316
+
300
317
  const coinTypeRegex = new RegExp(`((0x[^:]+::[^:]+::[^<>]+))(?![^<>]*<)`);
301
318
  const coinTypeMatch = coinType.match(coinTypeRegex);
302
319
  const isMarketCoinType = coinType.includes('reserve::MarketCoin');
303
320
  coinType = coinTypeMatch?.[1] ?? coinType;
304
321
 
305
- const wormHoleCoinTypeMap: Record<string, SupportAssetCoins> = {
322
+ const wormholeCoinTypeMap: Record<string, SupportAssetCoins> = {
306
323
  [`${
307
324
  this.address.get('core.coins.wusdc.id') ?? wormholeCoinIds.wusdc
308
325
  }::coin::COIN`]: 'wusdc',
@@ -339,7 +356,7 @@ export class ScallopUtils {
339
356
  );
340
357
 
341
358
  const assetCoinName =
342
- wormHoleCoinTypeMap[coinType] ||
359
+ wormholeCoinTypeMap[coinType] ||
343
360
  voloCoinTypeMap[coinType] ||
344
361
  suiBridgeTypeMap[coinType] ||
345
362
  (coinType.split('::')[2].toLowerCase() as SupportAssetCoins);
@@ -383,18 +400,6 @@ export class ScallopUtils {
383
400
  return spoolRewardCoins[stakeMarketCoinName];
384
401
  };
385
402
 
386
- /**
387
- * Get reward type of borrow incentive pool.
388
- *
389
- * @param borrowIncentiveCoinName - Support borrow incentive coin.
390
- * @return Borrow incentive reward coin name.
391
- */
392
- public getBorrowIncentiveRewardCoinName = (
393
- borrowIncentiveCoinName: SupportBorrowIncentiveCoins
394
- ) => {
395
- return borrowIncentiveRewardCoins[borrowIncentiveCoinName];
396
- };
397
-
398
403
  /**
399
404
  * Get coin decimal.
400
405
  *
@@ -1,5 +1,9 @@
1
1
  import { normalizeStructTag } from '@mysten/sui/utils';
2
- import { SUPPORT_BORROW_INCENTIVE_POOLS } from '../constants';
2
+ import {
3
+ sCoinRawNameToName,
4
+ SUPPORT_BORROW_INCENTIVE_POOLS,
5
+ SUPPORT_BORROW_INCENTIVE_REWARDS,
6
+ } from '../constants';
3
7
  import {
4
8
  parseOriginBorrowIncentivePoolData,
5
9
  parseOriginBorrowIncentiveAccountData,
@@ -17,6 +21,7 @@ import type {
17
21
  OptionalKeys,
18
22
  BorrowIncentivePool,
19
23
  CoinPrices,
24
+ MarketPools,
20
25
  } from '../types';
21
26
  import BigNumber from 'bignumber.js';
22
27
 
@@ -55,11 +60,14 @@ export const getBorrowIncentivePools = async (
55
60
  ...SUPPORT_BORROW_INCENTIVE_POOLS,
56
61
  ],
57
62
  indexer: boolean = false,
63
+ marketPools?: MarketPools,
58
64
  coinPrices?: CoinPrices
59
65
  ) => {
60
66
  const borrowIncentivePools: BorrowIncentivePools = {};
61
-
62
- coinPrices = coinPrices ?? (await query.utils.getCoinPrices()) ?? {};
67
+ marketPools =
68
+ marketPools ??
69
+ (await query.getMarketPools(undefined, { indexer, coinPrices }));
70
+ coinPrices = coinPrices ?? (await query.getAllCoinPrices({ marketPools }));
63
71
 
64
72
  if (indexer) {
65
73
  const borrowIncentivePoolsIndexer =
@@ -67,7 +75,13 @@ export const getBorrowIncentivePools = async (
67
75
 
68
76
  const updateBorrowIncentivePool = (pool: BorrowIncentivePool) => {
69
77
  if (!borrowIncentiveCoinNames.includes(pool.coinName)) return;
70
- pool.coinPrice = coinPrices[pool.coinName] ?? pool.coinPrice;
78
+ pool.coinPrice = coinPrices[pool.coinName] || pool.coinPrice;
79
+ for (const sCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
80
+ if (pool.points[sCoinName]) {
81
+ pool.points[sCoinName].coinPrice =
82
+ coinPrices[sCoinName] ?? pool.points[sCoinName].coinPrice;
83
+ }
84
+ }
71
85
  borrowIncentivePools[pool.coinName] = pool;
72
86
  };
73
87
 
@@ -94,7 +108,6 @@ export const getBorrowIncentivePools = async (
94
108
  query.utils.parseCoinNameFromType<SupportBorrowIncentiveCoins>(
95
109
  poolCoinType
96
110
  );
97
-
98
111
  const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
99
112
  const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
100
113
 
@@ -102,17 +115,21 @@ export const getBorrowIncentivePools = async (
102
115
  if (!borrowIncentiveCoinNames.includes(poolCoinName)) {
103
116
  continue;
104
117
  }
105
- // pool points for borrow incentive reward ('sui' and 'sca')
118
+
119
+ // pool points for borrow incentive reward
106
120
  for (const [coinName, poolPoint] of Object.entries(
107
121
  parsedBorrowIncentivePoolData.poolPoints
108
122
  )) {
109
- const rewardCoinType = normalizeStructTag(poolPoint.pointType);
110
- const rewardCoinName =
111
- query.utils.parseCoinNameFromType<SupportBorrowIncentiveRewardCoins>(
112
- rewardCoinType
113
- );
114
- const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
123
+ const rewardCoinType = poolPoint.pointType;
124
+ let rewardCoinName = query.utils.parseCoinNameFromType(
125
+ rewardCoinType
126
+ ) as SupportBorrowIncentiveRewardCoins;
127
+ // handle for scoin name
128
+ if (sCoinRawNameToName[rewardCoinName]) {
129
+ rewardCoinName = sCoinRawNameToName[rewardCoinName];
130
+ }
115
131
  const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
132
+ const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
116
133
 
117
134
  const symbol = query.utils.parseSymbol(rewardCoinName);
118
135
  const coinDecimal = query.utils.getCoinDecimal(rewardCoinName);
@@ -17,8 +17,9 @@ const borrowLimitZod = zod.object({
17
17
  }),
18
18
  });
19
19
 
20
- const borrowLimitKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::BorrowLimitKey`; // prod
21
- // const borrowLimitKeyType = `0xb784ea287d944e478a3ceaa071f8885072cce6b7224cf245914dc2f9963f460e::market_dynamic_keys::BorrowLimitKey`;
20
+ // TODO: enable for production
21
+ // const borrowLimitKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::BorrowLimitKey`; // prod
22
+ const borrowLimitKeyType = `0xb784ea287d944e478a3ceaa071f8885072cce6b7224cf245914dc2f9963f460e::market_dynamic_keys::BorrowLimitKey`;
22
23
  /**
23
24
  * Return supply limit of a pool (including the decimals)
24
25
  * @param utils
@@ -247,7 +247,7 @@ export const getMarketPools = async (
247
247
  const marketObjectResponse = await query.cache.queryGetObject(marketId, {
248
248
  showContent: true,
249
249
  });
250
- coinPrices = (await query.utils.getCoinPrices(poolCoinNames)) ?? {};
250
+ coinPrices = coinPrices ?? (await query.utils.getCoinPrices());
251
251
 
252
252
  const marketPools: MarketPools = {};
253
253
 
@@ -305,9 +305,7 @@ export const getMarketPool = async (
305
305
  marketObject?: SuiObjectData | null,
306
306
  coinPrice?: number
307
307
  ): Promise<MarketPool | undefined> => {
308
- coinPrice =
309
- coinPrice ||
310
- (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName];
308
+ coinPrice = coinPrice ?? (await query.utils.getCoinPrices())?.[poolCoinName];
311
309
 
312
310
  if (indexer) {
313
311
  const marketPoolIndexer = await query.indexer.getMarketPool(poolCoinName);
@@ -536,8 +534,7 @@ export const getMarketCollaterals = async (
536
534
  indexer: boolean = false
537
535
  ) => {
538
536
  const marketId = query.address.get('core.market');
539
- const coinPrices =
540
- (await query.utils.getCoinPrices(collateralCoinNames)) ?? {};
537
+ const coinPrices = (await query.utils.getCoinPrices()) ?? {};
541
538
  const marketCollaterals: MarketCollaterals = {};
542
539
 
543
540
  if (indexer) {
@@ -595,10 +592,7 @@ export const getMarketCollateral = async (
595
592
  coinPrice?: number
596
593
  ): Promise<MarketCollateral | undefined> => {
597
594
  coinPrice =
598
- coinPrice ||
599
- (await query.utils.getCoinPrices([collateralCoinName]))?.[
600
- collateralCoinName
601
- ];
595
+ coinPrice ?? (await query.utils.getCoinPrices())?.[collateralCoinName];
602
596
 
603
597
  if (indexer) {
604
598
  const marketCollateralIndexer =
@@ -18,8 +18,9 @@ const isolatedAssetZod = zod.object({
18
18
  }),
19
19
  });
20
20
 
21
- const isolatedAssetKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::IsolatedAssetKey`; // prod
22
- // const isolatedAssetKeyType = `0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d::market_dynamic_keys::IsolatedAssetKey`;
21
+ // TODO: enable for production
22
+ // const isolatedAssetKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::IsolatedAssetKey`; // prod
23
+ const isolatedAssetKeyType = `0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d::market_dynamic_keys::IsolatedAssetKey`;
23
24
 
24
25
  /**
25
26
  * Return list of isolated assets coin types
@@ -1,6 +1,5 @@
1
1
  import BigNumber from 'bignumber.js';
2
2
  import {
3
- SUPPORT_BORROW_INCENTIVE_REWARDS,
4
3
  SUPPORT_COLLATERALS,
5
4
  SUPPORT_POOLS,
6
5
  SUPPORT_SPOOLS,
@@ -50,7 +49,7 @@ export const getLendings = async (
50
49
  (SUPPORT_SPOOLS as readonly SupportMarketCoins[]).includes(marketCoinName)
51
50
  ) as SupportStakeMarketCoins[];
52
51
 
53
- const coinPrices = await query.utils.getCoinPrices(poolCoinNames);
52
+ const coinPrices = await query.utils.getCoinPrices();
54
53
  const marketPools = await query.getMarketPools(poolCoinNames, {
55
54
  indexer,
56
55
  coinPrices,
@@ -124,9 +123,7 @@ export const getLending = async (
124
123
  ) => {
125
124
  const marketCoinName = query.utils.parseMarketCoinName(poolCoinName);
126
125
  coinPrice =
127
- coinPrice ??
128
- (await query.utils.getCoinPrices([poolCoinName]))?.[poolCoinName] ??
129
- 0;
126
+ coinPrice ?? (await query.utils.getCoinPrices())?.[poolCoinName] ?? 0;
130
127
 
131
128
  marketPool =
132
129
  marketPool ??
@@ -355,9 +352,9 @@ export const getObligationAccount = async (
355
352
  const collateralAssetCoinNames: SupportCollateralCoins[] = [
356
353
  ...SUPPORT_COLLATERALS,
357
354
  ];
355
+ market = market ?? (await query.queryMarket({ indexer }));
358
356
  coinPrices =
359
- coinPrices ?? (await query.utils.getCoinPrices(collateralAssetCoinNames));
360
- market = market ?? (await query.queryMarket({ indexer, coinPrices }));
357
+ coinPrices ?? (await query.getAllCoinPrices({ marketPools: market.pools }));
361
358
  coinAmounts =
362
359
  coinAmounts ||
363
360
  (await query.getCoinAmounts(collateralAssetCoinNames, ownerAddress));
@@ -526,64 +523,70 @@ export const getObligationAccount = async (
526
523
  const borrowIncentivePool = borrowIncentivePools[coinName];
527
524
  if (borrowIncentivePool) {
528
525
  const rewards: ObligationBorrowIcentiveReward[] = [];
529
- for (const rewardCoinName of SUPPORT_BORROW_INCENTIVE_REWARDS) {
530
- const accountPoint = borrowIncentiveAccount.pointList[rewardCoinName];
531
- const poolPoint = borrowIncentivePool.points[rewardCoinName];
532
-
533
- if (accountPoint && poolPoint) {
534
- let availableClaimAmount = BigNumber(0);
535
- let availableClaimCoin = BigNumber(0);
536
- const accountBorrowedAmount = BigNumber(accountPoint.weightedAmount);
537
- const baseIndexRate = 1_000_000_000;
538
- const increasedPointRate = poolPoint.currentPointIndex
539
- ? Math.max(
540
- BigNumber(poolPoint.currentPointIndex - accountPoint.index)
541
- .dividedBy(baseIndexRate)
542
- .toNumber(),
543
- 0
544
- )
545
- : 1;
546
- availableClaimAmount = availableClaimAmount.plus(
547
- accountBorrowedAmount
548
- .multipliedBy(increasedPointRate)
549
- .plus(accountPoint.points)
550
- );
551
- availableClaimCoin = availableClaimAmount.shiftedBy(
552
- -1 * poolPoint.coinDecimal
553
- );
554
-
555
- // for veSCA
556
- const weightScale = BigNumber(1_000_000_000_000);
557
- const boostValue = BigNumber(accountPoint.weightedAmount)
558
- .div(
559
- BigNumber(borrowIncentiveAccount.debtAmount)
560
- .multipliedBy(poolPoint.baseWeight)
561
- .dividedBy(weightScale)
562
- )
563
- .isFinite()
564
- ? BigNumber(accountPoint.weightedAmount)
565
- .div(
566
- BigNumber(borrowIncentiveAccount.debtAmount)
567
- .multipliedBy(poolPoint.baseWeight)
568
- .dividedBy(weightScale)
526
+ Object.entries(borrowIncentiveAccount.pointList).forEach(
527
+ ([key, accountPoint]) => {
528
+ const poolPoint =
529
+ borrowIncentivePool.points[
530
+ key as SupportBorrowIncentiveRewardCoins
531
+ ];
532
+
533
+ if (accountPoint && poolPoint) {
534
+ let availableClaimAmount = BigNumber(0);
535
+ let availableClaimCoin = BigNumber(0);
536
+ const accountBorrowedAmount = BigNumber(
537
+ accountPoint.weightedAmount
538
+ );
539
+ const baseIndexRate = 1_000_000_000;
540
+ const increasedPointRate = poolPoint.currentPointIndex
541
+ ? Math.max(
542
+ BigNumber(poolPoint.currentPointIndex - accountPoint.index)
543
+ .dividedBy(baseIndexRate)
544
+ .toNumber(),
545
+ 0
569
546
  )
570
- .toNumber()
571
- : 1;
572
-
573
- if (availableClaimAmount.isGreaterThanOrEqualTo(0)) {
574
- rewards.push({
575
- coinName: poolPoint.coinName,
576
- coinType: poolPoint.coinType,
577
- symbol: poolPoint.symbol,
578
- coinDecimal: poolPoint.coinDecimal,
579
- coinPrice: poolPoint.coinPrice,
580
- availableClaimAmount: availableClaimAmount.toNumber(),
581
- availableClaimCoin: availableClaimCoin.toNumber(),
582
- boostValue,
583
- });
547
+ : 1;
548
+ availableClaimAmount = availableClaimAmount.plus(
549
+ accountBorrowedAmount
550
+ .multipliedBy(increasedPointRate)
551
+ .plus(accountPoint.points)
552
+ );
553
+ availableClaimCoin = availableClaimAmount.shiftedBy(
554
+ -1 * poolPoint.coinDecimal
555
+ );
556
+
557
+ // for veSCA
558
+ const weightScale = BigNumber(1_000_000_000_000);
559
+ const boostValue = BigNumber(accountPoint.weightedAmount)
560
+ .div(
561
+ BigNumber(borrowIncentiveAccount.debtAmount)
562
+ .multipliedBy(poolPoint.baseWeight)
563
+ .dividedBy(weightScale)
564
+ )
565
+ .isFinite()
566
+ ? BigNumber(accountPoint.weightedAmount)
567
+ .div(
568
+ BigNumber(borrowIncentiveAccount.debtAmount)
569
+ .multipliedBy(poolPoint.baseWeight)
570
+ .dividedBy(weightScale)
571
+ )
572
+ .toNumber()
573
+ : 1;
574
+
575
+ if (availableClaimAmount.isGreaterThanOrEqualTo(0)) {
576
+ rewards.push({
577
+ coinName: poolPoint.coinName,
578
+ coinType: poolPoint.coinType,
579
+ symbol: poolPoint.symbol,
580
+ coinDecimal: poolPoint.coinDecimal,
581
+ coinPrice: poolPoint.coinPrice,
582
+ availableClaimAmount: availableClaimAmount.toNumber(),
583
+ availableClaimCoin: availableClaimCoin.toNumber(),
584
+ boostValue,
585
+ });
586
+ }
584
587
  }
585
588
  }
586
- }
589
+ );
587
590
 
588
591
  if (
589
592
  Object.keys(borrowIncentivePool.points).some((coinName: any) => {
@@ -1,6 +1,14 @@
1
1
  import { SuiObjectData } from '@mysten/sui/client';
2
- import type { ScallopAddress } from '../models';
3
- import type { SupportAssetCoins } from '../types';
2
+ import type { ScallopAddress, ScallopQuery } from '../models';
3
+ import type {
4
+ CoinPrices,
5
+ MarketPools,
6
+ OptionalKeys,
7
+ SupportAssetCoins,
8
+ SupportSCoin,
9
+ } from '../types';
10
+ import { SUPPORT_SCOIN } from 'src/constants/common';
11
+ import BigNumber from 'bignumber.js';
4
12
 
5
13
  /**
6
14
  * Get price from pyth fee object.
@@ -126,3 +134,28 @@ export const getPythPrices = async (
126
134
  {} as Record<SupportAssetCoins, number>
127
135
  );
128
136
  };
137
+
138
+ export const getAllCoinPrices = async (
139
+ query: ScallopQuery,
140
+ marketPools?: MarketPools,
141
+ coinPrices?: CoinPrices
142
+ ) => {
143
+ coinPrices = coinPrices ?? (await query.utils.getCoinPrices());
144
+ marketPools =
145
+ marketPools ?? (await query.getMarketPools(undefined, { coinPrices }));
146
+ if (!marketPools) {
147
+ throw new Error(`Failed to fetch market pool for getAllCoinPrices`);
148
+ }
149
+ const sCoinPrices: OptionalKeys<Record<SupportSCoin, number>> = {};
150
+ SUPPORT_SCOIN.forEach((sCoinName) => {
151
+ const coinName = query.utils.parseCoinName(sCoinName);
152
+ sCoinPrices[sCoinName] = BigNumber(coinPrices[coinName] ?? 0)
153
+ .multipliedBy(marketPools[coinName]?.conversionRate ?? 1)
154
+ .toNumber();
155
+ });
156
+
157
+ return {
158
+ ...coinPrices,
159
+ ...sCoinPrices,
160
+ };
161
+ };
@@ -153,7 +153,7 @@ export const getSCoinSwapRate = async (
153
153
  const BtoSCoinBRate = 1 / marketPools[1]!.conversionRate;
154
154
 
155
155
  const calcAtoBRate = async () => {
156
- const prices = await query.utils.getCoinPrices([fromCoinName, toCoinName]);
156
+ const prices = await query.utils.getCoinPrices();
157
157
  if (!prices[fromCoinName] || !prices[toCoinName]) {
158
158
  throw new Error('Failed to fetch the coin prices');
159
159
  }
@@ -71,7 +71,6 @@ export const getSpools = async (
71
71
  };
72
72
  Object.values(spoolsIndexer).forEach(updateSpools);
73
73
 
74
- // console.log(spools);
75
74
  return spools;
76
75
  }
77
76
 
@@ -122,7 +121,7 @@ export const getSpool = async (
122
121
  `spool.pools.${marketCoinName}.rewardPoolId`
123
122
  );
124
123
  let spool: Spool | undefined = undefined;
125
- coinPrices = coinPrices || (await query.utils.getCoinPrices([coinName]));
124
+ coinPrices = coinPrices || (await query.utils.getCoinPrices());
126
125
 
127
126
  if (indexer) {
128
127
  const spoolIndexer = await query.indexer.getSpool(marketCoinName);
@@ -152,8 +151,7 @@ export const getSpool = async (
152
151
  }
153
152
 
154
153
  const rewardCoinName = query.utils.getSpoolRewardCoinName(marketCoinName);
155
- coinPrices =
156
- coinPrices || (await query.utils.getCoinPrices([coinName, rewardCoinName]));
154
+ coinPrices = coinPrices || (await query.utils.getCoinPrices());
157
155
 
158
156
  const spoolObject = spoolObjectResponse[0];
159
157
  const rewardPoolObject = spoolObjectResponse[1];
@@ -17,8 +17,9 @@ const supplyLimitZod = zod.object({
17
17
  }),
18
18
  });
19
19
 
20
- const supplyLimitKeyType = `0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey`; // prod
21
- // const supplyLimitKeyType = `0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d::market_dynamic_keys::SupplyLimitKey`;
20
+ // TODO: enable for production
21
+ // const supplyLimitKeyType = `0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey`; // prod
22
+ const supplyLimitKeyType = `0x6c23585e940a989588432509107e98bae06dbca4e333f26d0635d401b3c7c76d::market_dynamic_keys::SupplyLimitKey`;
22
23
  /**
23
24
  * Return supply limit of a pool (including the decimals)
24
25
  * @param utils
package/src/test.ts ADDED
@@ -0,0 +1,20 @@
1
+ // import { ScallopQuery } from './models';
2
+
3
+ // const main = async () => {
4
+ // try {
5
+ // const query = new ScallopQuery({
6
+ // walletAddress:
7
+ // '0x61819c99588108d9f7710047e6ad8f2da598de8e98a26ea62bd7ad9847f5329c',
8
+ // });
9
+ // await query.init();
10
+
11
+ // const res = await query.getAllCoinPrices();
12
+ // console.dir(res, { depth: null });
13
+ // } catch (e) {
14
+ // console.error(e);
15
+ // } finally {
16
+ // process.exit(0);
17
+ // }
18
+ // };
19
+
20
+ // main();