@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,55 +1,32 @@
1
- import { SUI_TYPE_ARG, normalizeStructTag } from '@mysten/sui/utils';
1
+ import {
2
+ SUI_TYPE_ARG,
3
+ normalizeStructTag,
4
+ parseStructTag,
5
+ } from '@mysten/sui/utils';
2
6
  import { SuiKit } from '@scallop-io/sui-kit';
3
7
  import { SuiPriceServiceConnection } from '@pythnetwork/pyth-sui-js';
4
8
  import { ScallopAddress } from './scallopAddress';
5
- import {
6
- ADDRESS_ID,
7
- PROTOCOL_OBJECT_ID,
8
- SUPPORT_POOLS,
9
- SUPPORT_COLLATERALS,
10
- spoolRewardCoins,
11
- coinDecimals,
12
- wormholeCoinIds,
13
- voloCoinIds,
14
- coinIds,
15
- UNLOCK_ROUND_DURATION,
16
- MAX_LOCK_DURATION,
17
- SUPPORT_SCOIN,
18
- sCoinIds,
19
- suiBridgeCoins,
20
- COIN_GECKGO_IDS,
21
- POOL_ADDRESSES,
22
- sCoinTypeToName,
23
- sCoinRawNameToName,
24
- } from '../constants';
9
+ import { UNLOCK_ROUND_DURATION, MAX_LOCK_DURATION } from '../constants';
25
10
  import { getPythPrices, queryObligation } from '../queries';
26
- import {
27
- parseDataFromPythPriceFeed,
28
- isMarketCoin,
29
- parseAssetSymbol,
30
- findClosestUnlockRound,
31
- isSuiBridgeAsset,
32
- isWormholeAsset,
33
- } from '../utils';
34
- import { PYTH_ENDPOINTS, PYTH_FEED_IDS } from 'src/constants/pyth';
11
+ import { parseDataFromPythPriceFeed, findClosestUnlockRound } from '../utils';
35
12
  import { ScallopCache } from './scallopCache';
36
13
  import type {
37
14
  ScallopUtilsParams,
38
- SupportCoins,
39
- SupportAssetCoins,
40
- SupportMarketCoins,
41
- SupportStakeMarketCoins,
42
15
  CoinPrices,
43
16
  CoinWrappedType,
44
- SupportSCoin,
45
17
  ScallopUtilsInstanceParams,
46
- SupportSuiBridgeCoins,
47
- SupportWormholeCoins,
48
- PoolAddressInfo,
18
+ PoolAddress,
49
19
  } from '../types';
50
20
  import { queryKeys } from 'src/constants';
51
21
  import type { SuiObjectArg, SuiTxBlock } from '@scallop-io/sui-kit';
52
22
  import { newSuiKit } from './suiKit';
23
+ import { ScallopConstants } from './scallopConstants';
24
+
25
+ const PYTH_ENDPOINTS: {
26
+ [k in 'mainnet']: string[];
27
+ } = {
28
+ mainnet: ['https://hermes.pyth.network', 'https://scallop.rpc.p2p.world'],
29
+ };
53
30
 
54
31
  /**
55
32
  * @description
@@ -65,11 +42,11 @@ import { newSuiKit } from './suiKit';
65
42
  */
66
43
  export class ScallopUtils {
67
44
  public readonly params: ScallopUtilsParams;
68
- public readonly isTestnet: boolean;
69
45
 
70
46
  public suiKit: SuiKit;
71
47
  public address: ScallopAddress;
72
48
  public cache: ScallopCache;
49
+ public constants: ScallopConstants;
73
50
  public walletAddress: string;
74
51
 
75
52
  public constructor(
@@ -82,40 +59,51 @@ export class ScallopUtils {
82
59
  };
83
60
  this.walletAddress =
84
61
  params.walletAddress ?? instance?.suiKit?.currentAddress() ?? '';
85
- this.suiKit =
86
- instance?.suiKit ?? instance?.address?.cache.suiKit ?? newSuiKit(params);
87
62
 
88
- if (instance?.address) {
89
- this.address = instance.address;
90
- this.cache = this.address.cache;
91
- } else {
92
- this.cache = new ScallopCache(this.params, {
63
+ this.suiKit =
64
+ instance?.suiKit ??
65
+ instance?.constants?.cache.suiKit ??
66
+ newSuiKit(params);
67
+
68
+ this.cache =
69
+ instance?.constants?.cache ??
70
+ instance?.cache ??
71
+ new ScallopCache(this.params, {
93
72
  suiKit: this.suiKit,
94
73
  });
95
- this.address =
96
- instance?.address ??
97
- new ScallopAddress(
98
- {
99
- id: params?.addressId ?? ADDRESS_ID,
100
- network: params?.networkType,
101
- forceInterface: params?.forceAddressesInterface,
102
- },
103
- {
104
- cache: this.cache,
105
- }
106
- );
107
- }
108
- this.isTestnet = params.networkType
109
- ? params.networkType === 'testnet'
110
- : false;
74
+
75
+ this.address =
76
+ instance?.constants?.address ??
77
+ new ScallopAddress(this.params, {
78
+ cache: this.cache,
79
+ });
80
+
81
+ this.constants =
82
+ instance?.constants ??
83
+ new ScallopConstants(this.params, {
84
+ address: this.address,
85
+ });
111
86
  }
87
+
88
+ get whitelist() {
89
+ return this.constants.whitelist;
90
+ }
91
+
112
92
  // -------------- TYPE GUARDS --------------
113
- public isSuiBridgeAsset(coinName: any): coinName is SupportSuiBridgeCoins {
114
- return isSuiBridgeAsset(coinName);
93
+ public isSuiBridgeAsset(coinName: any) {
94
+ return this.constants.whitelist.suiBridge.has(coinName);
115
95
  }
116
96
 
117
- public isWormholeAsset(coinName: any): coinName is SupportWormholeCoins {
118
- return isWormholeAsset(coinName);
97
+ public isWormholeAsset(coinName: any) {
98
+ return this.constants.whitelist.wormhole.has(coinName);
99
+ }
100
+
101
+ public isMarketCoin(coinName: string) {
102
+ const assetCoinName = coinName.slice(1).toLowerCase() as string;
103
+ return (
104
+ coinName.charAt(0).toLowerCase() === 's' &&
105
+ this.whitelist.lending.has(assetCoinName)
106
+ );
119
107
  }
120
108
 
121
109
  /**
@@ -124,10 +112,9 @@ export class ScallopUtils {
124
112
  * @param force - Whether to force initialization.
125
113
  * @param address - ScallopAddress instance.
126
114
  */
127
- public async init(force: boolean = false, address?: ScallopAddress) {
128
- if (address && !this.address) this.address = address;
129
- if (force || !this.address.getAddresses()) {
130
- await this.address.read();
115
+ public async init(force: boolean = false) {
116
+ if (force || !this.constants.isInitialized) {
117
+ await this.constants.init();
131
118
  }
132
119
  }
133
120
 
@@ -137,8 +124,11 @@ export class ScallopUtils {
137
124
  * @param coinName - Specific support coin name.
138
125
  * @return Symbol string.
139
126
  */
140
- public parseSymbol(coinName: SupportCoins) {
141
- return parseAssetSymbol(coinName);
127
+ public parseSymbol(coinName: string) {
128
+ return this.isMarketCoin(coinName)
129
+ ? (this.constants.poolAddresses[this.parseCoinName(coinName)]
130
+ ?.sCoinSymbol ?? '')
131
+ : (this.constants.poolAddresses[coinName]?.symbol ?? '');
142
132
  }
143
133
 
144
134
  /**
@@ -152,60 +142,11 @@ export class ScallopUtils {
152
142
  * @param coinName - Specific support coin name.
153
143
  * @return Coin type.
154
144
  */
155
- public parseCoinType(
156
- coinName: SupportCoins,
157
- useOldMarketCoin: boolean = false
158
- ) {
159
- // try parse scoin first
160
- if (sCoinIds[coinName as SupportSCoin] && !useOldMarketCoin) {
161
- return sCoinIds[coinName as SupportSCoin];
162
- }
163
- coinName = isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName;
164
- const coinPackageId =
165
- this.address.get(`core.coins.${coinName}.id`) ||
166
- coinIds[coinName] ||
167
- undefined;
168
- if (!coinPackageId) {
169
- throw Error(`Coin ${coinName} is not supported`);
170
- }
171
- if (coinName === 'sui')
172
- return normalizeStructTag(`${coinPackageId}::sui::SUI`);
173
- if (coinName === 'blub')
174
- return normalizeStructTag(`${coinPackageId}::BLUB::BLUB`);
175
- if (coinName === 'sbwbtc')
176
- return normalizeStructTag(`${coinPackageId}::btc::BTC`);
177
-
178
- const wormHolePackageIds = [
179
- this.address.get('core.coins.wusdc.id') ?? wormholeCoinIds.wusdc,
180
- this.address.get('core.coins.wusdt.id') ?? wormholeCoinIds.wusdt,
181
- this.address.get('core.coins.weth.id') ?? wormholeCoinIds.weth,
182
- this.address.get('core.coins.wbtc.id') ?? wormholeCoinIds.wbtc,
183
- this.address.get('core.coins.wsol.id') ?? wormholeCoinIds.wsol,
184
- this.address.get('core.coins.wapt.id') ?? wormholeCoinIds.wapt,
185
- ];
186
- const voloPackageIds = [
187
- this.address.get('core.coins.vsui.id') ?? voloCoinIds.vsui,
188
- ];
189
-
190
- const suiBridgePackageIds = Object.values<SupportSuiBridgeCoins>(
191
- suiBridgeCoins
192
- ).reduce((curr, coinName) => {
193
- curr.push(
194
- this.address.get(`core.coins.${coinName}.id`) ?? coinIds[coinName]
195
- );
196
- return curr;
197
- }, [] as string[]);
198
- if (wormHolePackageIds.includes(coinPackageId)) {
199
- return `${coinPackageId}::coin::COIN`;
200
- } else if (voloPackageIds.includes(coinPackageId)) {
201
- return `${coinPackageId}::cert::CERT`;
202
- } else if (suiBridgePackageIds.includes(coinPackageId)) {
203
- // handle sui bridge assets
204
- const typeCoinName = coinName.slice(2);
205
- return `${coinPackageId}::${typeCoinName}::${typeCoinName.toUpperCase()}`;
206
- } else {
207
- return `${coinPackageId}::${coinName}::${coinName.toUpperCase()}`;
145
+ public parseCoinType(coinName: string, useOldMarketCoin: boolean = false) {
146
+ if (useOldMarketCoin) {
147
+ return this.constants.coinNameToOldMarketCoinTypeMap[coinName] ?? '';
208
148
  }
149
+ return this.constants.coinTypes[coinName] ?? '';
209
150
  }
210
151
 
211
152
  /**
@@ -214,18 +155,13 @@ export class ScallopUtils {
214
155
  * @param coinName - Specific support coin name.
215
156
  * @return sCoin name.
216
157
  */
217
- public parseSCoinName<T extends SupportSCoin>(
218
- coinName: SupportCoins | SupportMarketCoins
219
- ) {
158
+ public parseSCoinName<T extends string>(coinName: string) {
220
159
  // need more check because swapt has no sCoin type
221
- if (
222
- isMarketCoin(coinName) &&
223
- SUPPORT_SCOIN.includes(coinName as SupportSCoin)
224
- ) {
160
+ if (this.isMarketCoin(coinName) && this.whitelist.scoin.has(coinName)) {
225
161
  return coinName as T;
226
162
  } else {
227
163
  const marketCoinName = `s${coinName}`;
228
- if (SUPPORT_SCOIN.includes(marketCoinName as SupportSCoin)) {
164
+ if (this.whitelist.scoin.has(marketCoinName)) {
229
165
  return marketCoinName as T;
230
166
  }
231
167
  return undefined;
@@ -240,7 +176,7 @@ export class ScallopUtils {
240
176
  * @return sCoin name
241
177
  */
242
178
  public parseSCoinTypeNameToMarketCoinName(coinName: string) {
243
- return sCoinRawNameToName[coinName] ?? coinName;
179
+ return this.constants.sCoinRawNameToScoinNameMap[coinName] ?? coinName;
244
180
  }
245
181
 
246
182
  /**
@@ -248,8 +184,8 @@ export class ScallopUtils {
248
184
  * @param sCoinName
249
185
  * @returns sCoin type
250
186
  */
251
- public parseSCoinType(sCoinName: SupportSCoin) {
252
- return sCoinIds[sCoinName];
187
+ public parseSCoinType(sCoinName: string) {
188
+ return this.constants.sCoinTypes[sCoinName] ?? '';
253
189
  }
254
190
 
255
191
  /**
@@ -258,7 +194,7 @@ export class ScallopUtils {
258
194
  * @returns sCoin name
259
195
  */
260
196
  public parseSCoinNameFromType(sCoinType: string) {
261
- return sCoinTypeToName[sCoinType];
197
+ return this.constants.sCoinTypeToSCoinNameMap[sCoinType];
262
198
  }
263
199
 
264
200
  /**
@@ -266,7 +202,7 @@ export class ScallopUtils {
266
202
  * @param sCoinName
267
203
  * @returns coin type
268
204
  */
269
- public parseUnderlyingSCoinType(sCoinName: SupportSCoin) {
205
+ public parseUnderlyingSCoinType(sCoinName: string) {
270
206
  const coinName = this.parseCoinName(sCoinName);
271
207
  return this.parseCoinType(coinName);
272
208
  }
@@ -276,7 +212,7 @@ export class ScallopUtils {
276
212
  * @param sCoinName
277
213
  * @returns sCoin treasury id
278
214
  */
279
- public getSCoinTreasury(sCoinName: SupportSCoin) {
215
+ public getSCoinTreasury(sCoinName: string) {
280
216
  return this.address.get(`scoin.coins.${sCoinName}.treasury`);
281
217
  }
282
218
 
@@ -287,11 +223,12 @@ export class ScallopUtils {
287
223
  * @param coinName - Specific support coin name.
288
224
  * @return Market coin type.
289
225
  */
290
- public parseMarketCoinType(coinName: SupportCoins) {
291
- const protocolObjectId =
292
- this.address.get('core.object') || PROTOCOL_OBJECT_ID;
293
- const coinType = this.parseCoinType(coinName, true);
294
- return `${protocolObjectId}::reserve::MarketCoin<${coinType}>`;
226
+ public parseMarketCoinType(coinName: string) {
227
+ const coinType = this.parseCoinType(
228
+ this.isMarketCoin(coinName) ? this.parseCoinName(coinName) : coinName,
229
+ true
230
+ );
231
+ return coinType;
295
232
  }
296
233
 
297
234
  /**
@@ -304,74 +241,28 @@ export class ScallopUtils {
304
241
  * @param coinType - Specific support coin type.
305
242
  * @return Coin Name.
306
243
  */
307
- public parseCoinNameFromType<T extends SupportAssetCoins>(
308
- coinType: string
309
- ): T extends SupportAssetCoins ? T : SupportAssetCoins;
310
- public parseCoinNameFromType<T extends SupportMarketCoins>(
311
- coinType: string
312
- ): T extends SupportMarketCoins ? T : SupportMarketCoins;
313
- public parseCoinNameFromType<T extends SupportCoins>(
314
- coinType: string
315
- ): T extends SupportCoins ? T : SupportCoins;
316
- public parseCoinNameFromType<T extends SupportSCoin>(
317
- coinType: string
318
- ): T extends SupportSCoin ? T : SupportSCoin;
319
244
  public parseCoinNameFromType(coinType: string) {
320
245
  coinType = normalizeStructTag(coinType);
321
- if (sCoinTypeToName[coinType]) {
322
- return sCoinTypeToName[coinType] as SupportSCoin;
246
+ const { address, module, name, typeParams } = parseStructTag(coinType);
247
+ const isMarketCoinType =
248
+ address === this.constants.protocolObjectId &&
249
+ module === 'reserve' &&
250
+ name === 'MarketCoin';
251
+
252
+ if (isMarketCoinType) {
253
+ return this.parseMarketCoinName(
254
+ (typeof typeParams[0] === 'string'
255
+ ? parseStructTag(typeParams[0])
256
+ : typeParams[0]
257
+ ).name.toLowerCase()
258
+ );
323
259
  }
324
-
325
- const coinTypeRegex = new RegExp(`((0x[^:]+::[^:]+::[^<>]+))(?![^<>]*<)`);
326
- const coinTypeMatch = coinType.match(coinTypeRegex);
327
- const isMarketCoinType = coinType.includes('reserve::MarketCoin');
328
- coinType = coinTypeMatch?.[1] ?? coinType;
329
-
330
- const wormholeCoinTypeMap: Record<string, SupportAssetCoins> = {
331
- [`${
332
- this.address.get('core.coins.wusdc.id') ?? wormholeCoinIds.wusdc
333
- }::coin::COIN`]: 'wusdc',
334
- [`${
335
- this.address.get('core.coins.wusdt.id') ?? wormholeCoinIds.wusdt
336
- }::coin::COIN`]: 'wusdt',
337
- [`${
338
- this.address.get('core.coins.weth.id') ?? wormholeCoinIds.weth
339
- }::coin::COIN`]: 'weth',
340
- [`${
341
- this.address.get('core.coins.wbtc.id') ?? wormholeCoinIds.wbtc
342
- }::coin::COIN`]: 'wbtc',
343
- [`${
344
- this.address.get('core.coins.wsol.id') ?? wormholeCoinIds.wsol
345
- }::coin::COIN`]: 'wsol',
346
- [`${
347
- this.address.get('core.coins.wapt.id') ?? wormholeCoinIds.wapt
348
- }::coin::COIN`]: 'wapt',
349
- };
350
- const voloCoinTypeMap: Record<string, SupportAssetCoins> = {
351
- [`${
352
- this.address.get('core.coins.vsui.id') ?? voloCoinIds.vsui
353
- }::cert::CERT`]: 'vsui',
354
- };
355
-
356
- const suiBridgeTypeMap = Object.values<SupportSuiBridgeCoins>(
357
- suiBridgeCoins
358
- ).reduce(
359
- (curr, coinName) => {
360
- curr[this.parseCoinType(coinName)] = coinName;
361
- return curr;
362
- },
363
- {} as Record<string, SupportSuiBridgeCoins>
364
- );
365
-
366
260
  const assetCoinName =
367
- wormholeCoinTypeMap[coinType] ||
368
- voloCoinTypeMap[coinType] ||
369
- suiBridgeTypeMap[coinType] ||
370
- (coinType.split('::')[2].toLowerCase() as SupportAssetCoins);
371
-
372
- return isMarketCoinType
373
- ? this.parseMarketCoinName(assetCoinName)
374
- : assetCoinName;
261
+ this.constants.coinTypeToCoinNameMap[coinType] ||
262
+ this.constants.sCoinTypeToSCoinNameMap[coinType] ||
263
+ parseStructTag(coinType).name.toLowerCase();
264
+
265
+ return assetCoinName;
375
266
  }
376
267
 
377
268
  /**
@@ -380,7 +271,7 @@ export class ScallopUtils {
380
271
  * @param marketCoinName - Specific support market coin name.
381
272
  * @return Coin Name.
382
273
  */
383
- public parseCoinName<T extends SupportAssetCoins>(marketCoinName: string) {
274
+ public parseCoinName<T extends string>(marketCoinName: string) {
384
275
  return marketCoinName.slice(1) as T;
385
276
  }
386
277
 
@@ -390,9 +281,7 @@ export class ScallopUtils {
390
281
  * @param coinName - Specific support coin name.
391
282
  * @return Market coin name.
392
283
  */
393
- public parseMarketCoinName<T extends SupportMarketCoins>(
394
- coinName: SupportCoins
395
- ) {
284
+ public parseMarketCoinName<T extends string>(coinName: string) {
396
285
  return `s${coinName}` as T;
397
286
  }
398
287
 
@@ -402,10 +291,8 @@ export class ScallopUtils {
402
291
  * @param stakeMarketCoinName - Support stake market coin.
403
292
  * @return Spool reward coin name.
404
293
  */
405
- public getSpoolRewardCoinName = (
406
- stakeMarketCoinName: SupportStakeMarketCoins
407
- ) => {
408
- return spoolRewardCoins[stakeMarketCoinName];
294
+ public getSpoolRewardCoinName = () => {
295
+ return 'sui'; // No further plan to incentivize other spools
409
296
  };
410
297
 
411
298
  /**
@@ -413,8 +300,8 @@ export class ScallopUtils {
413
300
  *
414
301
  * return Coin decimal.
415
302
  */
416
- public getCoinDecimal(coinName: SupportCoins) {
417
- return coinDecimals[coinName];
303
+ public getCoinDecimal(coinName: string) {
304
+ return this.constants.coinDecimals[coinName] ?? 0;
418
305
  }
419
306
 
420
307
  /**
@@ -422,7 +309,7 @@ export class ScallopUtils {
422
309
  *
423
310
  * return Coin wrapped type.
424
311
  */
425
- public getCoinWrappedType(assetCoinName: SupportAssetCoins): CoinWrappedType {
312
+ public getCoinWrappedType(assetCoinName: string): CoinWrappedType {
426
313
  if (this.isSuiBridgeAsset(assetCoinName)) {
427
314
  return {
428
315
  from: 'Sui Bridge',
@@ -531,35 +418,33 @@ export class ScallopUtils {
531
418
  * @return Asset coin price.
532
419
  */
533
420
  public async getCoinPrices(
534
- _: SupportAssetCoins[] = [
535
- ...new Set([...SUPPORT_POOLS, ...SUPPORT_COLLATERALS]),
536
- ] as SupportAssetCoins[]
421
+ coinNames: string[] = [
422
+ ...new Set([
423
+ ...this.constants.whitelist.lending,
424
+ ...this.constants.whitelist.collateral,
425
+ ]),
426
+ ] as string[]
537
427
  ) {
538
428
  let coinPrices: CoinPrices = {};
539
429
 
540
- const endpoints =
541
- this.params.pythEndpoints ??
542
- PYTH_ENDPOINTS[this.isTestnet ? 'testnet' : 'mainnet'];
430
+ const endpoints = this.params.pythEndpoints ?? PYTH_ENDPOINTS['mainnet'];
543
431
 
544
- const failedRequests: Set<SupportAssetCoins> = new Set([
545
- ...SUPPORT_POOLS,
546
- ...SUPPORT_COLLATERALS,
547
- ]);
432
+ const failedRequests: Set<string> = new Set(coinNames);
548
433
 
549
434
  for (const endpoint of endpoints) {
550
435
  const priceIdPairs = Array.from(failedRequests.values()).reduce(
551
436
  (acc, coinName) => {
552
437
  const priceId =
553
438
  this.address.get(`core.coins.${coinName}.oracle.pyth.feed`) ??
554
- PYTH_FEED_IDS[coinName];
439
+ this.constants.poolAddresses[coinName]?.pythFeed;
555
440
  acc.push([coinName, priceId]);
556
441
  return acc;
557
442
  },
558
443
  [] as [string, string][]
559
444
  );
445
+ if (priceIdPairs.length === 0) break;
560
446
 
561
447
  const priceIds = priceIdPairs.map(([_, priceId]) => priceId);
562
-
563
448
  const pythConnection = new SuiPriceServiceConnection(endpoint, {
564
449
  timeout: 4000,
565
450
  });
@@ -575,10 +460,10 @@ export class ScallopUtils {
575
460
  });
576
461
  if (feeds) {
577
462
  feeds.forEach((feed, idx) => {
578
- const coinName = priceIdPairs[idx][0] as SupportAssetCoins;
579
- const data = parseDataFromPythPriceFeed(feed, this.address);
580
- coinPrices[coinName as SupportAssetCoins] = data.price;
581
- failedRequests.delete(coinName as SupportAssetCoins); // remove success price feed to prevent duplicate request on the next endpoint
463
+ const coinName = priceIdPairs[idx][0] as string;
464
+ const data = parseDataFromPythPriceFeed(feed, this.constants);
465
+ coinPrices[coinName as string] = data.price;
466
+ failedRequests.delete(coinName as string); // remove success price feed to prevent duplicate request on the next endpoint
582
467
  });
583
468
  }
584
469
  } catch (e: any) {
@@ -666,20 +551,11 @@ export class ScallopUtils {
666
551
  * Get detailed contract address and price id information for supported pool in Scallop
667
552
  * @returns Supported pool informations
668
553
  */
669
- public getSupportedPoolAddresses(): PoolAddressInfo[] {
670
- return SUPPORT_POOLS.map((poolName) => {
671
- const sCoinName = this.parseSCoinName(poolName)!;
672
- return {
673
- name: this.parseSymbol(poolName),
674
- coingeckoId: COIN_GECKGO_IDS[poolName],
675
- decimal: coinDecimals[poolName],
676
- pythFeedId: PYTH_FEED_IDS[poolName],
677
- ...POOL_ADDRESSES[poolName],
678
- sCoinAddress: sCoinIds[sCoinName],
679
- marketCoinAddress: this.parseMarketCoinType(poolName),
680
- coinAddress: this.parseCoinType(poolName),
681
- sCoinName: sCoinName ? this.parseSymbol(sCoinName) : undefined,
682
- };
683
- });
554
+ public getSupportedPoolAddresses(): PoolAddress[] {
555
+ return this.constants.poolAddresses
556
+ ? Object.values(this.constants.poolAddresses).filter(
557
+ (address): address is PoolAddress => address !== undefined
558
+ )
559
+ : [];
684
560
  }
685
561
  }