@scallop-io/sui-scallop-sdk 1.5.3 → 2.0.0-alpha.10

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 (66) hide show
  1. package/dist/index.d.mts +509 -602
  2. package/dist/index.d.ts +509 -602
  3. package/dist/index.js +28 -59
  4. package/dist/index.mjs +7 -7
  5. package/package.json +1 -1
  6. package/src/builders/coreBuilder.ts +33 -33
  7. package/src/builders/loyaltyProgramBuilder.ts +5 -3
  8. package/src/builders/{oracle.ts → oracles/index.ts} +48 -60
  9. package/src/builders/oracles/pyth.ts +44 -0
  10. package/src/builders/oracles/switchboard.ts +270 -0
  11. package/src/builders/referralBuilder.ts +5 -9
  12. package/src/builders/sCoinBuilder.ts +9 -8
  13. package/src/builders/spoolBuilder.ts +4 -6
  14. package/src/constants/common.ts +114 -126
  15. package/src/constants/index.ts +0 -5
  16. package/src/constants/pyth.ts +25 -34
  17. package/src/constants/queryKeys.ts +2 -0
  18. package/src/constants/testAddress.ts +36 -487
  19. package/src/models/index.ts +1 -0
  20. package/src/models/scallop.ts +23 -19
  21. package/src/models/scallopAddress.ts +17 -5
  22. package/src/models/scallopBuilder.ts +36 -41
  23. package/src/models/scallopCache.ts +3 -3
  24. package/src/models/scallopClient.ts +93 -98
  25. package/src/models/scallopConstants.ts +399 -0
  26. package/src/models/scallopIndexer.ts +11 -24
  27. package/src/models/scallopQuery.ts +76 -79
  28. package/src/models/scallopUtils.ts +126 -250
  29. package/src/queries/borrowIncentiveQuery.ts +25 -58
  30. package/src/queries/borrowLimitQuery.ts +3 -6
  31. package/src/queries/coreQuery.ts +98 -114
  32. package/src/queries/flashloanFeeQuery.ts +86 -0
  33. package/src/queries/index.ts +1 -0
  34. package/src/queries/isolatedAssetQuery.ts +12 -11
  35. package/src/queries/poolAddressesQuery.ts +211 -117
  36. package/src/queries/portfolioQuery.ts +60 -70
  37. package/src/queries/priceQuery.ts +16 -22
  38. package/src/queries/sCoinQuery.ts +15 -16
  39. package/src/queries/spoolQuery.ts +49 -59
  40. package/src/queries/supplyLimitQuery.ts +2 -6
  41. package/src/queries/switchboardQuery.ts +64 -0
  42. package/src/queries/xOracleQuery.ts +29 -32
  43. package/src/types/address.ts +21 -19
  44. package/src/types/builder/borrowIncentive.ts +2 -3
  45. package/src/types/builder/core.ts +20 -27
  46. package/src/types/builder/index.ts +1 -2
  47. package/src/types/builder/referral.ts +4 -8
  48. package/src/types/builder/sCoin.ts +4 -8
  49. package/src/types/builder/spool.ts +7 -10
  50. package/src/types/constant/common.ts +44 -49
  51. package/src/types/constant/enum.ts +15 -27
  52. package/src/types/constant/xOracle.ts +3 -2
  53. package/src/types/model.ts +49 -28
  54. package/src/types/query/borrowIncentive.ts +7 -24
  55. package/src/types/query/core.ts +8 -18
  56. package/src/types/query/portfolio.ts +9 -17
  57. package/src/types/query/spool.ts +5 -11
  58. package/src/types/utils.ts +1 -21
  59. package/src/utils/core.ts +1 -1
  60. package/src/utils/query.ts +15 -23
  61. package/src/utils/util.ts +6 -84
  62. package/src/constants/coinGecko.ts +0 -34
  63. package/src/constants/enum.ts +0 -268
  64. package/src/constants/flashloan.ts +0 -18
  65. package/src/constants/poolAddress.ts +0 -898
  66. package/src/models/scallopPrice.ts +0 -0
@@ -1,8 +1,4 @@
1
1
  import { normalizeStructTag } from '@mysten/sui/utils';
2
- import {
3
- SUPPORT_BORROW_INCENTIVE_POOLS,
4
- SUPPORT_BORROW_INCENTIVE_REWARDS,
5
- } from '../constants';
6
2
  import {
7
3
  parseOriginBorrowIncentivePoolData,
8
4
  parseOriginBorrowIncentiveAccountData,
@@ -14,11 +10,8 @@ import type {
14
10
  BorrowIncentivePools,
15
11
  BorrowIncentiveAccountsQueryInterface,
16
12
  BorrowIncentiveAccounts,
17
- SupportBorrowIncentiveCoins,
18
- SupportBorrowIncentiveRewardCoins,
19
13
  BorrowIncentivePoolPoints,
20
14
  OptionalKeys,
21
- BorrowIncentivePool,
22
15
  CoinPrices,
23
16
  MarketPools,
24
17
  } from '../types';
@@ -56,9 +49,7 @@ export const queryBorrowIncentivePools = async (address: ScallopAddress) => {
56
49
  */
57
50
  export const getBorrowIncentivePools = async (
58
51
  query: ScallopQuery,
59
- borrowIncentiveCoinNames: SupportBorrowIncentiveCoins[] = [
60
- ...SUPPORT_BORROW_INCENTIVE_POOLS,
61
- ],
52
+ borrowIncentiveCoinNames: string[] = [...query.constants.whitelist.lending],
62
53
  indexer: boolean = false,
63
54
  marketPools?: MarketPools,
64
55
  coinPrices?: CoinPrices
@@ -69,36 +60,13 @@ export const getBorrowIncentivePools = async (
69
60
  (await query.getMarketPools(undefined, { coinPrices, indexer })).pools;
70
61
  coinPrices = coinPrices ?? (await query.getAllCoinPrices({ marketPools }));
71
62
 
72
- if (indexer) {
73
- const borrowIncentivePoolsIndexer =
74
- await query.indexer.getBorrowIncentivePools();
75
-
76
- const updateBorrowIncentivePool = (pool: BorrowIncentivePool) => {
77
- if (!borrowIncentiveCoinNames.includes(pool.coinName)) return;
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
- }
85
- borrowIncentivePools[pool.coinName] = pool;
86
- };
87
-
88
- Object.values(borrowIncentivePoolsIndexer).forEach(
89
- updateBorrowIncentivePool
90
- );
91
-
92
- return borrowIncentivePools;
93
- }
94
-
95
63
  const borrowIncentivePoolsQueryData = await queryBorrowIncentivePools(
96
64
  query.address
97
65
  );
98
66
 
99
67
  for (const pool of borrowIncentivePoolsQueryData?.incentive_pools ?? []) {
100
68
  const borrowIncentivePoolPoints: OptionalKeys<
101
- Record<SupportBorrowIncentiveRewardCoins, BorrowIncentivePoolPoints>
69
+ Record<string, BorrowIncentivePoolPoints>
102
70
  > = {};
103
71
  const parsedBorrowIncentivePoolData = parseOriginBorrowIncentivePoolData(
104
72
  query.utils,
@@ -106,10 +74,7 @@ export const getBorrowIncentivePools = async (
106
74
  );
107
75
 
108
76
  const poolCoinType = normalizeStructTag(pool.pool_type.name);
109
- const poolCoinName =
110
- query.utils.parseCoinNameFromType<SupportBorrowIncentiveCoins>(
111
- poolCoinType
112
- );
77
+ const poolCoinName = query.utils.parseCoinNameFromType(poolCoinType);
113
78
  const poolCoinPrice = coinPrices?.[poolCoinName] ?? 0;
114
79
  const poolCoinDecimal = query.utils.getCoinDecimal(poolCoinName);
115
80
 
@@ -122,12 +87,16 @@ export const getBorrowIncentivePools = async (
122
87
  for (const [coinName, poolPoint] of Object.entries(
123
88
  parsedBorrowIncentivePoolData.poolPoints
124
89
  )) {
90
+ if (!poolPoint) continue;
125
91
  const rewardCoinType = poolPoint.pointType;
126
92
  const rewardCoinName = query.utils.parseCoinNameFromType(
127
93
  rewardCoinType
128
- ) as SupportBorrowIncentiveRewardCoins;
94
+ ) as string;
129
95
  // handle for scoin name
130
96
  const rewardCoinDecimal = query.utils.getCoinDecimal(rewardCoinName);
97
+ if (rewardCoinDecimal === undefined)
98
+ throw new Error(`Coin decimal not found for ${rewardCoinName}`);
99
+
131
100
  const rewardCoinPrice = coinPrices?.[rewardCoinName] ?? 0;
132
101
 
133
102
  const symbol = query.utils.parseSymbol(rewardCoinName);
@@ -142,18 +111,17 @@ export const getBorrowIncentivePools = async (
142
111
  poolCoinDecimal
143
112
  );
144
113
 
145
- borrowIncentivePoolPoints[coinName as SupportBorrowIncentiveRewardCoins] =
146
- {
147
- symbol,
148
- coinName: rewardCoinName,
149
- coinType: rewardCoinType,
150
- coinDecimal,
151
- coinPrice: rewardCoinPrice,
152
- points: poolPoint.points,
153
- distributedPoint: poolPoint.distributedPoint,
154
- weightedAmount: poolPoint.weightedAmount,
155
- ...calculatedPoolPoint,
156
- };
114
+ borrowIncentivePoolPoints[coinName as string] = {
115
+ symbol,
116
+ coinName: rewardCoinName,
117
+ coinType: rewardCoinType,
118
+ coinDecimal,
119
+ coinPrice: rewardCoinPrice,
120
+ points: poolPoint.points,
121
+ distributedPoint: poolPoint.distributedPoint,
122
+ weightedAmount: poolPoint.weightedAmount,
123
+ ...calculatedPoolPoint,
124
+ };
157
125
  }
158
126
 
159
127
  const stakedAmount = BigNumber(parsedBorrowIncentivePoolData.staked);
@@ -190,9 +158,7 @@ export const queryBorrowIncentiveAccounts = async (
190
158
  utils: ScallopUtils;
191
159
  },
192
160
  obligationId: string | SuiObjectRef,
193
- borrowIncentiveCoinNames: SupportBorrowIncentiveCoins[] = [
194
- ...SUPPORT_BORROW_INCENTIVE_POOLS,
195
- ]
161
+ borrowIncentiveCoinNames: string[] = [...utils.constants.whitelist.lending]
196
162
  ) => {
197
163
  const queryPkgId = utils.address.get('borrowIncentive.query');
198
164
  const incentiveAccountsId = utils.address.get(
@@ -208,11 +174,12 @@ export const queryBorrowIncentiveAccounts = async (
208
174
  const borrowIncentiveAccounts: BorrowIncentiveAccounts = Object.values(
209
175
  borrowIncentiveAccountsQueryData?.pool_records ?? []
210
176
  ).reduce((accounts, accountData) => {
211
- const parsedBorrowIncentiveAccount =
212
- parseOriginBorrowIncentiveAccountData(accountData);
177
+ const parsedBorrowIncentiveAccount = parseOriginBorrowIncentiveAccountData(
178
+ utils,
179
+ accountData
180
+ );
213
181
  const poolType = parsedBorrowIncentiveAccount.poolType;
214
- const coinName =
215
- utils.parseCoinNameFromType<SupportBorrowIncentiveCoins>(poolType);
182
+ const coinName = utils.parseCoinNameFromType(poolType);
216
183
 
217
184
  if (
218
185
  borrowIncentiveCoinNames &&
@@ -1,5 +1,4 @@
1
1
  import { ScallopUtils } from 'src/models';
2
- import { SupportPoolCoins } from 'src/types';
3
2
  import { z as zod } from 'zod';
4
3
 
5
4
  const borrowLimitZod = zod.object({
@@ -26,10 +25,7 @@ const borrowLimitKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c
26
25
  * @param poolName
27
26
  * @returns supply limit (decimals included)
28
27
  */
29
- export const getBorrowLimit = async (
30
- utils: ScallopUtils,
31
- poolName: SupportPoolCoins
32
- ) => {
28
+ export const getBorrowLimit = async (utils: ScallopUtils, poolName: string) => {
33
29
  try {
34
30
  const poolCoinType = utils.parseCoinType(poolName).slice(2);
35
31
  const marketObject = utils.address.get('core.market');
@@ -44,7 +40,8 @@ export const getBorrowLimit = async (
44
40
  });
45
41
 
46
42
  const parsedData = borrowLimitZod.safeParse(object?.data?.content);
47
- if (!parsedData.success) return null;
43
+ if (!parsedData.success) return '0';
44
+
48
45
  return parsedData.data.fields.value;
49
46
  } catch (e: any) {
50
47
  console.error(`Error in getBorrowLimit for ${poolName}: ${e.message}`);
@@ -1,11 +1,4 @@
1
1
  import { normalizeStructTag, SUI_CLOCK_OBJECT_ID } from '@mysten/sui/utils';
2
- import {
3
- SUPPORT_POOLS,
4
- PROTOCOL_OBJECT_ID,
5
- SUPPORT_COLLATERALS,
6
- FlashLoanFeeObjectMap,
7
- POOL_ADDRESSES,
8
- } from '../constants';
9
2
  import {
10
3
  parseOriginMarketPoolData,
11
4
  calculateMarketPoolData,
@@ -27,16 +20,12 @@ import {
27
20
  MarketCollaterals,
28
21
  MarketCollateral,
29
22
  MarketQueryInterface,
30
- SupportAssetCoins,
31
- SupportPoolCoins,
32
- SupportCollateralCoins,
33
23
  ObligationQueryInterface,
34
24
  Obligation,
35
25
  InterestModel,
36
26
  BalanceSheet,
37
27
  RiskModel,
38
28
  CollateralStat,
39
- SupportMarketCoins,
40
29
  OptionalKeys,
41
30
  CoinPrices,
42
31
  OriginMarketPoolData,
@@ -49,6 +38,8 @@ import { getSupplyLimit } from './supplyLimitQuery';
49
38
  import { isIsolatedAsset } from './isolatedAssetQuery';
50
39
  import { getBorrowLimit } from './borrowLimitQuery';
51
40
  import { queryMultipleObjects } from './objectsQuery';
41
+ import { ScallopConstants } from 'src/models/scallopConstants';
42
+ import { queryFlashLoanFees } from './flashloanFeeQuery';
52
43
 
53
44
  /**
54
45
  * Query market data.
@@ -87,8 +78,12 @@ export const queryMarket = async (
87
78
  collaterals[item.coinName] = item;
88
79
  };
89
80
 
90
- Object.values(marketIndexer.pools).forEach(updatePools);
91
- Object.values(marketIndexer.collaterals).forEach(updateCollaterals);
81
+ Object.values(marketIndexer.pools)
82
+ .filter((t) => !!t)
83
+ .forEach(updatePools);
84
+ Object.values(marketIndexer.collaterals)
85
+ .filter((t) => !!t)
86
+ .forEach(updateCollaterals);
92
87
 
93
88
  return {
94
89
  pools,
@@ -108,12 +103,11 @@ export const queryMarket = async (
108
103
 
109
104
  for (const pool of marketData?.pools ?? []) {
110
105
  const coinType = normalizeStructTag(pool.type.name);
111
- const poolCoinName =
112
- query.utils.parseCoinNameFromType<SupportPoolCoins>(coinType);
106
+ const poolCoinName = query.utils.parseCoinNameFromType(coinType);
113
107
  const coinPrice = coinPrices[poolCoinName] ?? 0;
114
108
 
115
109
  // Filter pools not yet supported by the SDK.
116
- if (!SUPPORT_POOLS.includes(poolCoinName)) {
110
+ if (!query.constants.whitelist.lending.has(poolCoinName)) {
117
111
  continue;
118
112
  }
119
113
 
@@ -152,9 +146,10 @@ export const queryMarket = async (
152
146
  symbol: query.utils.parseSymbol(poolCoinName),
153
147
  coinType: coinType,
154
148
  marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
155
- sCoinType: query.utils.parseSCoinType(
156
- query.utils.parseMarketCoinName(poolCoinName)
157
- ),
149
+ sCoinType:
150
+ query.utils.parseSCoinType(
151
+ query.utils.parseMarketCoinName(poolCoinName)
152
+ ) ?? '',
158
153
  coinWrappedType: query.utils.getCoinWrappedType(poolCoinName),
159
154
  coinPrice: coinPrice,
160
155
  highKink: parsedMarketPoolData.highKink,
@@ -170,12 +165,11 @@ export const queryMarket = async (
170
165
 
171
166
  for (const collateral of marketData?.collaterals ?? []) {
172
167
  const coinType = normalizeStructTag(collateral.type.name);
173
- const collateralCoinName =
174
- query.utils.parseCoinNameFromType<SupportCollateralCoins>(coinType);
168
+ const collateralCoinName = query.utils.parseCoinNameFromType(coinType);
175
169
  const coinPrice = coinPrices[collateralCoinName] ?? 0;
176
170
 
177
171
  // Filter collaterals not yet supported by the SDK.
178
- if (!SUPPORT_COLLATERALS.includes(collateralCoinName)) {
172
+ if (!query.constants.whitelist.collateral.has(collateralCoinName)) {
179
173
  continue;
180
174
  }
181
175
 
@@ -223,20 +217,20 @@ export const queryMarket = async (
223
217
 
224
218
  const queryRequiredMarketObjects = async (
225
219
  query: ScallopQuery,
226
- poolCoinNames: SupportPoolCoins[]
220
+ poolCoinNames: string[]
227
221
  ) => {
228
222
  // Prepare all tasks for querying each object type
229
223
  const tasks = poolCoinNames.map((t) => ({
230
224
  poolCoinName: t,
231
- balanceSheet: POOL_ADDRESSES[t]?.lendingPoolAddress,
232
- collateralStat: POOL_ADDRESSES[t]?.collateralPoolAddress,
233
- borrowDynamic: POOL_ADDRESSES[t]?.borrowDynamic,
234
- interestModel: POOL_ADDRESSES[t]?.interestModel,
235
- riskModel: POOL_ADDRESSES[t]?.riskModel,
236
- borrowFeeKey: POOL_ADDRESSES[t]?.borrowFeeKey,
237
- supplyLimitKey: POOL_ADDRESSES[t]?.supplyLimitKey,
238
- borrowLimitKey: POOL_ADDRESSES[t]?.borrowLimitKey,
239
- isolatedAssetKey: POOL_ADDRESSES[t]?.isolatedAssetKey,
225
+ balanceSheet: query.constants.poolAddresses[t]?.lendingPoolAddress,
226
+ collateralStat: query.constants.poolAddresses[t]?.collateralPoolAddress,
227
+ borrowDynamic: query.constants.poolAddresses[t]?.borrowDynamic,
228
+ interestModel: query.constants.poolAddresses[t]?.interestModel,
229
+ riskModel: query.constants.poolAddresses[t]?.riskModel,
230
+ borrowFeeKey: query.constants.poolAddresses[t]?.borrowFeeKey,
231
+ supplyLimitKey: query.constants.poolAddresses[t]?.supplyLimitKey,
232
+ borrowLimitKey: query.constants.poolAddresses[t]?.borrowLimitKey,
233
+ isolatedAssetKey: query.constants.poolAddresses[t]?.isolatedAssetKey,
240
234
  }));
241
235
 
242
236
  // Query all objects for each key in parallel
@@ -366,7 +360,7 @@ const queryRequiredMarketObjects = async (
366
360
  return acc;
367
361
  },
368
362
  {} as Record<
369
- SupportPoolCoins,
363
+ string,
370
364
  {
371
365
  balanceSheet: SuiObjectData;
372
366
  collateralStat?: SuiObjectData;
@@ -398,7 +392,7 @@ const queryRequiredMarketObjects = async (
398
392
  */
399
393
  export const getMarketPools = async (
400
394
  query: ScallopQuery,
401
- poolCoinNames: SupportPoolCoins[],
395
+ poolCoinNames: string[],
402
396
  indexer: boolean = false,
403
397
  coinPrices?: CoinPrices
404
398
  ): Promise<{
@@ -440,8 +434,12 @@ export const getMarketPools = async (
440
434
  collaterals[item.coinName] = item;
441
435
  };
442
436
 
443
- Object.values(marketIndexer.pools).forEach(updatePools);
444
- Object.values(marketIndexer.collaterals).forEach(updateCollaterals);
437
+ Object.values(marketIndexer.pools)
438
+ .filter((t) => !!t)
439
+ .forEach(updatePools);
440
+ Object.values(marketIndexer.collaterals)
441
+ .filter((t) => !!t)
442
+ .forEach(updateCollaterals);
445
443
 
446
444
  return {
447
445
  pools,
@@ -468,8 +466,7 @@ export const getMarketPools = async (
468
466
  pools[poolCoinName] = result?.marketPool;
469
467
  }
470
468
  if (result?.collateral) {
471
- collaterals[poolCoinName as SupportCollateralCoins] =
472
- result.collateral;
469
+ collaterals[poolCoinName as string] = result.collateral;
473
470
  }
474
471
  } catch (e) {
475
472
  console.error(e);
@@ -499,7 +496,7 @@ const parseMarketPoolObjects = ({
499
496
  collateralStat?: SuiObjectData;
500
497
  interestModel: SuiObjectData;
501
498
  riskModel?: SuiObjectData;
502
- borrowFeeKey: SuiObjectData;
499
+ borrowFeeKey?: SuiObjectData;
503
500
  supplyLimitKey?: SuiObjectData;
504
501
  borrowLimitKey?: SuiObjectData;
505
502
  isolatedAssetKey: SuiObjectData;
@@ -509,7 +506,9 @@ const parseMarketPoolObjects = ({
509
506
  const _balanceSheet = parseObjectAs<BalanceSheet>(balanceSheet);
510
507
  const _interestModel = parseObjectAs<InterestModel>(interestModel);
511
508
  const _borrowDynamic = parseObjectAs<BorrowDynamic>(borrowDynamic);
512
- const _borrowFee = parseObjectAs<BorrowFee>(borrowFeeKey);
509
+ const _borrowFee = borrowFeeKey
510
+ ? parseObjectAs<BorrowFee>(borrowFeeKey)
511
+ : { value: '0' };
513
512
  const _supplyLimit = supplyLimitKey
514
513
  ? parseObjectAs<string>(supplyLimitKey)
515
514
  : '0';
@@ -578,7 +577,7 @@ const parseMarketPoolObjects = ({
578
577
  */
579
578
  export const getMarketPool = async (
580
579
  query: ScallopQuery,
581
- poolCoinName: SupportPoolCoins,
580
+ poolCoinName: string,
582
581
  indexer: boolean = false,
583
582
  coinPrice: number,
584
583
  requiredObjects?: {
@@ -606,9 +605,9 @@ export const getMarketPool = async (
606
605
  );
607
606
 
608
607
  let marketCollateralIndexer: MarketCollateral | undefined = undefined;
609
- if (SUPPORT_COLLATERALS.includes(poolCoinName as SupportCollateralCoins)) {
608
+ if (query.constants.whitelist.collateral.has(poolCoinName as string)) {
610
609
  marketCollateralIndexer = await query.indexer.getMarketCollateral(
611
- poolCoinName as SupportCollateralCoins
610
+ poolCoinName as string
612
611
  );
613
612
  marketCollateralIndexer.coinPrice =
614
613
  coinPrice ?? marketCollateralIndexer.coinPrice;
@@ -642,7 +641,7 @@ export const getMarketPool = async (
642
641
  )
643
642
  : undefined;
644
643
 
645
- const basePoolData = <T extends SupportPoolCoins = SupportPoolCoins>() => ({
644
+ const basePoolData = <T extends string = string>() => ({
646
645
  coinName: poolCoinName as T,
647
646
  symbol: query.utils.parseSymbol(poolCoinName),
648
647
  marketCoinType: query.utils.parseMarketCoinType(poolCoinName),
@@ -651,9 +650,10 @@ export const getMarketPool = async (
651
650
  return {
652
651
  marketPool: {
653
652
  ...basePoolData(),
654
- sCoinType: query.utils.parseSCoinType(
655
- query.utils.parseMarketCoinName(poolCoinName)
656
- ),
653
+ sCoinType:
654
+ query.utils.parseSCoinType(
655
+ query.utils.parseMarketCoinName(poolCoinName)
656
+ ) ?? '',
657
657
  coinWrappedType: query.utils.getCoinWrappedType(poolCoinName),
658
658
  coinPrice: coinPrice ?? 0,
659
659
  highKink: parsedMarketPoolData.highKink,
@@ -667,7 +667,7 @@ export const getMarketPool = async (
667
667
  },
668
668
  collateral: parsedMarketCollateralData
669
669
  ? {
670
- ...basePoolData<SupportCollateralCoins>(),
670
+ ...basePoolData<string>(),
671
671
  coinWrappedType: query.utils.getCoinWrappedType(poolCoinName),
672
672
  coinPrice: coinPrice,
673
673
  collateralFactor: parsedMarketCollateralData.collateralFactor,
@@ -699,7 +699,7 @@ export const getMarketPool = async (
699
699
  */
700
700
  export const getMarketCollaterals = async (
701
701
  query: ScallopQuery,
702
- collateralCoinNames: SupportCollateralCoins[] = [...SUPPORT_COLLATERALS],
702
+ collateralCoinNames: string[] = [...query.constants.whitelist.collateral],
703
703
  indexer: boolean = false
704
704
  ) => {
705
705
  const marketId = query.address.get('core.market');
@@ -717,7 +717,9 @@ export const getMarketCollaterals = async (
717
717
  );
718
718
  marketCollaterals[marketCollateral.coinName] = marketCollateral;
719
719
  };
720
- Object.values(marketCollateralsIndexer).forEach(updateMarketCollateral);
720
+ Object.values(marketCollateralsIndexer)
721
+ .filter((t) => !!t)
722
+ .forEach(updateMarketCollateral);
721
723
  return marketCollaterals;
722
724
  }
723
725
 
@@ -753,7 +755,7 @@ export const getMarketCollaterals = async (
753
755
  */
754
756
  export const getMarketCollateral = async (
755
757
  query: ScallopQuery,
756
- collateralCoinName: SupportCollateralCoins,
758
+ collateralCoinName: string,
757
759
  indexer: boolean = false,
758
760
  marketObject?: SuiObjectData | null,
759
761
  coinPrice?: number
@@ -891,20 +893,20 @@ export const getMarketCollateral = async (
891
893
  */
892
894
  export const getObligations = async (
893
895
  {
894
- address,
896
+ constants,
895
897
  }: {
896
- address: ScallopAddress;
898
+ constants: ScallopConstants;
897
899
  },
898
900
  ownerAddress: string
899
901
  ) => {
900
902
  const owner = ownerAddress;
901
- const protocolObjectId = address.get('core.object') || PROTOCOL_OBJECT_ID;
903
+ const protocolObjectId = constants.protocolObjectId;
902
904
  const keyObjectsResponse: SuiObjectResponse[] = [];
903
905
  let hasNextPage = false;
904
906
  let nextCursor: string | null | undefined = null;
905
907
  do {
906
908
  const paginatedKeyObjectsResponse =
907
- await address.cache.queryGetOwnedObjects({
909
+ await constants.cache.queryGetOwnedObjects({
908
910
  owner,
909
911
  filter: {
910
912
  StructType: `${protocolObjectId}::obligation::ObligationKey`,
@@ -935,7 +937,7 @@ export const getObligations = async (
935
937
  const obligations: Obligation[] = [];
936
938
  // fetch all obligations with multi get objects
937
939
  const obligationsObjects = await queryMultipleObjects(
938
- address.cache,
940
+ constants.cache,
939
941
  keyObjects
940
942
  .map((ref) => ref.data?.content)
941
943
  .filter(
@@ -953,7 +955,7 @@ export const getObligations = async (
953
955
  const fields = content.fields as any;
954
956
  const obligationId = String(fields.ownership.fields.of);
955
957
  const locked = await getObligationLocked(
956
- address.cache,
958
+ constants.cache,
957
959
  obligationsObjects[idx]
958
960
  );
959
961
  obligations.push({ id: obligationId, keyId, locked });
@@ -1044,11 +1046,11 @@ export const queryObligation = async (
1044
1046
  */
1045
1047
  export const getCoinAmounts = async (
1046
1048
  query: ScallopQuery,
1047
- assetCoinNames: SupportAssetCoins[] = [...SUPPORT_POOLS],
1049
+ assetCoinNames: string[] = [...query.constants.whitelist.lending],
1048
1050
  ownerAddress?: string
1049
1051
  ) => {
1050
1052
  const owner = ownerAddress ?? query.suiKit.currentAddress();
1051
- const assetCoins = {} as OptionalKeys<Record<SupportAssetCoins, number>>;
1053
+ const assetCoins = {} as OptionalKeys<Record<string, number>>;
1052
1054
 
1053
1055
  await Promise.allSettled(
1054
1056
  assetCoinNames.map(async (assetCoinName) => {
@@ -1070,7 +1072,7 @@ export const getCoinAmounts = async (
1070
1072
  */
1071
1073
  export const getCoinAmount = async (
1072
1074
  query: ScallopQuery,
1073
- assetCoinName: SupportAssetCoins,
1075
+ assetCoinName: string,
1074
1076
  ownerAddress?: string
1075
1077
  ) => {
1076
1078
  const owner = ownerAddress ?? query.suiKit.currentAddress();
@@ -1092,16 +1094,16 @@ export const getCoinAmount = async (
1092
1094
  */
1093
1095
  export const getMarketCoinAmounts = async (
1094
1096
  query: ScallopQuery,
1095
- marketCoinNames?: SupportMarketCoins[],
1097
+ marketCoinNames?: string[],
1096
1098
  ownerAddress?: string
1097
1099
  ) => {
1098
1100
  marketCoinNames =
1099
1101
  marketCoinNames ||
1100
- [...SUPPORT_POOLS].map((poolCoinName) =>
1102
+ [...query.constants.whitelist.lending].map((poolCoinName) =>
1101
1103
  query.utils.parseMarketCoinName(poolCoinName)
1102
1104
  );
1103
1105
  const owner = ownerAddress ?? query.suiKit.currentAddress();
1104
- const marketCoins = {} as OptionalKeys<Record<SupportMarketCoins, number>>;
1106
+ const marketCoins = {} as OptionalKeys<Record<string, number>>;
1105
1107
 
1106
1108
  await Promise.allSettled(
1107
1109
  marketCoinNames.map(async (marketCoinName) => {
@@ -1127,7 +1129,7 @@ export const getMarketCoinAmounts = async (
1127
1129
  */
1128
1130
  export const getMarketCoinAmount = async (
1129
1131
  query: ScallopQuery,
1130
- marketCoinName: SupportMarketCoins,
1132
+ marketCoinName: string,
1131
1133
  ownerAddress?: string
1132
1134
  ) => {
1133
1135
  const owner = ownerAddress ?? query.suiKit.currentAddress();
@@ -1148,10 +1150,11 @@ export const getMarketCoinAmount = async (
1148
1150
 
1149
1151
  export const getFlashLoanFees = async (
1150
1152
  query: ScallopQuery,
1151
- assetNames: SupportPoolCoins[]
1152
- ): Promise<Record<SupportPoolCoins, number>> => {
1153
- const FEE_RATE = 1e4;
1154
- const missingAssets: SupportPoolCoins[] = [];
1153
+ assetNames: string[],
1154
+ feeRate = 1e4
1155
+ ): Promise<Record<string, number>> => {
1156
+ const missingAssets: string[] = [];
1157
+ let results: Record<string, number> = {};
1155
1158
 
1156
1159
  // create mapping from asset type to asset name
1157
1160
  const assetTypeMap = assetNames.reduce(
@@ -1160,67 +1163,48 @@ export const getFlashLoanFees = async (
1160
1163
  prev[assetType] = curr;
1161
1164
  return prev;
1162
1165
  },
1163
- {} as Record<string, SupportPoolCoins>
1166
+ {} as Record<string, string>
1164
1167
  );
1165
1168
 
1166
1169
  // use the mapped object first
1167
1170
  const objIds = assetNames
1168
1171
  .map((assetName) => {
1169
- if (!FlashLoanFeeObjectMap[assetName]) {
1172
+ const mappedFlashloanFeeObject =
1173
+ query.constants.poolAddresses[assetName]?.flashloanFeeObject;
1174
+ if (!mappedFlashloanFeeObject) {
1170
1175
  missingAssets.push(assetName);
1171
1176
  return null;
1172
1177
  } else {
1173
- return FlashLoanFeeObjectMap[assetName];
1178
+ return mappedFlashloanFeeObject;
1174
1179
  }
1175
1180
  })
1176
1181
  .filter((t) => !!t) as string[];
1177
1182
 
1178
- const flashloanFeeObjects = await query.cache.queryGetObjects(objIds);
1183
+ const flashloanFeeObjects = await queryMultipleObjects(query.cache, objIds);
1179
1184
 
1180
1185
  if (missingAssets.length > 0) {
1181
- // get market object
1182
- const marketObjectId = query.address.get('core.market');
1183
- const marketObjectRes = await query.cache.queryGetObject(marketObjectId);
1184
- if (marketObjectRes?.data?.content?.dataType !== 'moveObject')
1185
- throw new Error('Failed to get market object');
1186
-
1187
- // get vault
1188
- const vault = (marketObjectRes.data.content.fields as any).vault;
1189
-
1190
- // get vault balance sheet object id
1191
- const flashloanFeesTableId = vault.fields.flash_loan_fees.fields.table
1192
- .fields.id.id as string;
1193
-
1194
- // the balance sheet is a VecSet<0x1::type_name::TypeName
1195
- const balanceSheetDynamicFields = await query.cache.queryGetDynamicFields({
1196
- parentId: flashloanFeesTableId,
1197
- limit: 10,
1198
- });
1199
-
1200
- // get the dynamic object ids
1201
- const dynamicFieldObjectIds =
1202
- balanceSheetDynamicFields?.data
1203
- .filter((field) => {
1204
- const assetType = (field.name.value as any).name as string;
1205
- return !!assetTypeMap[assetType];
1206
- })
1207
- .map((field) => field.objectId) ?? [];
1208
-
1209
- flashloanFeeObjects.push(
1210
- ...(await query.cache.queryGetObjects(dynamicFieldObjectIds))
1186
+ const missingDatas = await queryFlashLoanFees(
1187
+ query.utils,
1188
+ missingAssets,
1189
+ feeRate
1211
1190
  );
1191
+ results = { ...results, ...missingDatas };
1212
1192
  }
1213
1193
 
1214
- return flashloanFeeObjects.reduce(
1215
- (prev, curr) => {
1216
- if (curr.content?.dataType === 'moveObject') {
1217
- const objectFields = curr.content.fields as any;
1218
- const assetType = (curr.content.fields as any).name.fields.name;
1219
- const feeNumerator = +objectFields.value;
1220
- prev[assetTypeMap[assetType]] = feeNumerator / FEE_RATE;
1221
- }
1222
- return prev;
1223
- },
1224
- {} as Record<SupportPoolCoins, number>
1225
- );
1194
+ results = {
1195
+ ...results,
1196
+ ...flashloanFeeObjects.reduce(
1197
+ (prev, curr) => {
1198
+ if (curr.content?.dataType === 'moveObject') {
1199
+ const objectFields = curr.content.fields as any;
1200
+ const assetType = (curr.content.fields as any).name.fields.name;
1201
+ const feeNumerator = +objectFields.value;
1202
+ prev[assetTypeMap[assetType]] = feeNumerator / feeRate;
1203
+ }
1204
+ return prev;
1205
+ },
1206
+ {} as Record<string, number>
1207
+ ),
1208
+ };
1209
+ return results;
1226
1210
  };