@scallop-io/sui-scallop-sdk 0.45.0 → 0.46.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 (43) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +1 -1
  2. package/dist/builders/referralBuilder.d.ts +12 -0
  3. package/dist/constants/common.d.ts +1 -1
  4. package/dist/index.js +533 -279
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +587 -329
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/models/scallopCache.d.ts +6 -2
  9. package/dist/models/scallopQuery.d.ts +26 -28
  10. package/dist/queries/coreQuery.d.ts +3 -29
  11. package/dist/queries/index.d.ts +1 -0
  12. package/dist/queries/priceQuery.d.ts +3 -1
  13. package/dist/queries/referralQuery.d.ts +7 -0
  14. package/dist/queries/vescaQuery.d.ts +6 -2
  15. package/dist/types/address.d.ts +15 -0
  16. package/dist/types/builder/core.d.ts +2 -0
  17. package/dist/types/builder/index.d.ts +2 -1
  18. package/dist/types/builder/referral.d.ts +30 -0
  19. package/dist/types/builder/vesca.d.ts +1 -0
  20. package/package.json +7 -6
  21. package/src/builders/borrowIncentiveBuilder.ts +10 -19
  22. package/src/builders/coreBuilder.ts +54 -0
  23. package/src/builders/index.ts +5 -2
  24. package/src/builders/referralBuilder.ts +178 -0
  25. package/src/builders/vescaBuilder.ts +8 -6
  26. package/src/constants/common.ts +9 -2
  27. package/src/constants/vesca.ts +1 -3
  28. package/src/models/scallopAddress.ts +63 -19
  29. package/src/models/scallopCache.ts +42 -2
  30. package/src/models/scallopQuery.ts +40 -0
  31. package/src/models/scallopUtils.ts +35 -35
  32. package/src/queries/borrowIncentiveQuery.ts +2 -5
  33. package/src/queries/coreQuery.ts +33 -197
  34. package/src/queries/index.ts +1 -0
  35. package/src/queries/priceQuery.ts +48 -7
  36. package/src/queries/referralQuery.ts +27 -0
  37. package/src/queries/spoolQuery.ts +8 -12
  38. package/src/queries/vescaQuery.ts +94 -15
  39. package/src/types/address.ts +15 -0
  40. package/src/types/builder/core.ts +14 -0
  41. package/src/types/builder/index.ts +2 -0
  42. package/src/types/builder/referral.ts +51 -0
  43. package/src/types/builder/vesca.ts +1 -0
@@ -0,0 +1,178 @@
1
+ import { ScallopBuilder } from 'src/models';
2
+ import { ScallopTxBlock, SupportCoins, SupportPoolCoins } from 'src/types';
3
+ import {
4
+ SUI_CLOCK_OBJECT_ID,
5
+ SuiTxBlock as SuiKitTxBlock,
6
+ SuiObjectArg,
7
+ TransactionBlock,
8
+ } from '@scallop-io/sui-kit';
9
+ import {
10
+ GenerateReferralNormalMethod,
11
+ GenerateReferralQuickMethod,
12
+ ReferralIds,
13
+ ReferralTxBlock,
14
+ SuiTxBlockWithReferralNormalMethods,
15
+ } from 'src/types/builder/referral';
16
+ import { SUPPORT_POOLS } from 'src/constants';
17
+ import { requireSender } from 'src/utils';
18
+
19
+ const generateReferralNormalMethod: GenerateReferralNormalMethod = ({
20
+ builder,
21
+ txBlock,
22
+ }) => {
23
+ const referralIds: ReferralIds = {
24
+ referralPgkId: builder.address.get('referral.id'),
25
+ referralBindings: builder.address.get('referral.referralBindings'),
26
+ referralRevenuePool: builder.address.get('referral.referralRevenuePool'),
27
+ authorizedWitnessList: builder.address.get(
28
+ 'referral.authorizedWitnessList'
29
+ ),
30
+ referralTiers: builder.address.get('referral.referralTiers'),
31
+ version: builder.address.get('referral.version'),
32
+ };
33
+
34
+ const veScaTable = builder.address.get('vesca.table');
35
+
36
+ return {
37
+ bindToReferral: (veScaKeyId: string) => {
38
+ return txBlock.moveCall(
39
+ `${referralIds.referralPgkId}::referral_bindings::bind_ve_sca_referrer`,
40
+ [
41
+ referralIds.referralBindings,
42
+ txBlock.pure(veScaKeyId),
43
+ veScaTable,
44
+ SUI_CLOCK_OBJECT_ID,
45
+ ],
46
+ []
47
+ );
48
+ },
49
+ claimReferralTicket: (poolCoinName: SupportCoins) => {
50
+ const coinType = builder.utils.parseCoinType(poolCoinName);
51
+ return txBlock.moveCall(
52
+ `${referralIds.referralPgkId}::scallop_referral_program::claim_ve_sca_referral_ticket`,
53
+ [
54
+ referralIds.version,
55
+ veScaTable,
56
+ referralIds.referralBindings,
57
+ referralIds.authorizedWitnessList,
58
+ referralIds.referralTiers,
59
+ SUI_CLOCK_OBJECT_ID,
60
+ ],
61
+ [coinType]
62
+ );
63
+ },
64
+ burnReferralTicket: (ticket: SuiObjectArg, poolCoinName: SupportCoins) => {
65
+ const coinType = builder.utils.parseCoinType(poolCoinName);
66
+ return txBlock.moveCall(
67
+ `${referralIds.referralPgkId}::scallop_referral_program::burn_ve_sca_referral_ticket`,
68
+ [
69
+ referralIds.version,
70
+ ticket,
71
+ referralIds.referralRevenuePool,
72
+ SUI_CLOCK_OBJECT_ID,
73
+ ],
74
+ [coinType]
75
+ );
76
+ },
77
+ claimReferralRevenue: (
78
+ veScaKey: SuiObjectArg,
79
+ poolCoinName: SupportCoins
80
+ ) => {
81
+ const coinType = builder.utils.parseCoinType(poolCoinName);
82
+ return txBlock.moveCall(
83
+ `${referralIds.referralPgkId}::referral_revenue_pool::claim_revenue_with_ve_sca_key`,
84
+ [
85
+ referralIds.version,
86
+ referralIds.referralRevenuePool,
87
+ veScaKey,
88
+ SUI_CLOCK_OBJECT_ID,
89
+ ],
90
+ [coinType]
91
+ );
92
+ },
93
+ };
94
+ };
95
+
96
+ const generateReferralQuickMethod: GenerateReferralQuickMethod = ({
97
+ builder,
98
+ txBlock,
99
+ }) => {
100
+ return {
101
+ claimReferralRevenueQuick: async (
102
+ veScaKey: SuiObjectArg,
103
+ coinNames: SupportPoolCoins[] = [...SUPPORT_POOLS]
104
+ ) => {
105
+ const sender = requireSender(txBlock);
106
+ const objToTransfer: SuiObjectArg[] = [];
107
+ for (const coinName of coinNames) {
108
+ if (coinName === 'sui') {
109
+ const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
110
+ objToTransfer.push(rewardCoin);
111
+ } else {
112
+ // get the matching user coin if exists
113
+ const coins = await builder.suiKit.suiInteractor.selectCoins(
114
+ sender,
115
+ Infinity,
116
+ builder.utils.parseCoinType(coinName)
117
+ );
118
+
119
+ const rewardCoin = txBlock.claimReferralRevenue(veScaKey, coinName);
120
+ if (coins.length > 0) {
121
+ txBlock.mergeCoins(rewardCoin, coins);
122
+ }
123
+ objToTransfer.push(rewardCoin);
124
+ }
125
+ }
126
+ if (objToTransfer.length > 0) {
127
+ txBlock.transferObjects(objToTransfer, sender);
128
+ }
129
+ },
130
+ };
131
+ };
132
+
133
+ /**
134
+ * Create an enhanced transaction block instance for interaction with borrow incentive modules of the Scallop contract.
135
+ *
136
+ * @param builder - Scallop builder instance.
137
+ * @param initTxBlock - Scallop txBlock, txBlock created by SuiKit, or original transaction block.
138
+ * @return Scallop borrow incentive txBlock.
139
+ */
140
+ export const newReferralTxBlock = (
141
+ builder: ScallopBuilder,
142
+ initTxBlock?: ScallopTxBlock | SuiKitTxBlock | TransactionBlock
143
+ ) => {
144
+ const txBlock =
145
+ initTxBlock instanceof TransactionBlock
146
+ ? new SuiKitTxBlock(initTxBlock)
147
+ : initTxBlock
148
+ ? initTxBlock
149
+ : new SuiKitTxBlock();
150
+
151
+ const normalMethod = generateReferralNormalMethod({
152
+ builder,
153
+ txBlock,
154
+ });
155
+
156
+ const normalTxBlock = new Proxy(txBlock, {
157
+ get: (target, prop) => {
158
+ if (prop in normalMethod) {
159
+ return Reflect.get(normalMethod, prop);
160
+ }
161
+ return Reflect.get(target, prop);
162
+ },
163
+ }) as SuiTxBlockWithReferralNormalMethods;
164
+
165
+ const quickMethod = generateReferralQuickMethod({
166
+ builder,
167
+ txBlock: normalTxBlock,
168
+ });
169
+
170
+ return new Proxy(normalTxBlock, {
171
+ get: (target, prop) => {
172
+ if (prop in quickMethod) {
173
+ return Reflect.get(quickMethod, prop);
174
+ }
175
+ return Reflect.get(target, prop);
176
+ },
177
+ }) as ReferralTxBlock;
178
+ };
@@ -65,11 +65,7 @@ export const requireVeSca = async (
65
65
  return undefined;
66
66
  }
67
67
 
68
- return veScas.reduce(
69
- (prev, acc) =>
70
- acc.currentVeScaBalance > prev.currentVeScaBalance ? acc : prev,
71
- veScas[0]
72
- ); // return veSCA with highest veSCA balance
68
+ return veScas[0]; // return veSCA with highest veSCA balance
73
69
  };
74
70
 
75
71
  /**
@@ -161,6 +157,13 @@ const generateNormalVeScaMethod: GenerateVeScaNormalMethod = ({
161
157
  []
162
158
  );
163
159
  },
160
+ mintEmptyVeSca: () => {
161
+ return txBlock.moveCall(
162
+ `${veScaIds.pkgId}::ve_sca::mint_ve_sca_placeholder_key`,
163
+ [veScaIds.config, veScaIds.table],
164
+ []
165
+ );
166
+ },
164
167
  };
165
168
  };
166
169
 
@@ -378,7 +381,6 @@ export const newVeScaTxBlock = (
378
381
  },
379
382
  }) as SuiTxBlockWithVeScaNormalMethods;
380
383
 
381
- // TODO: Add quickMethod for veSCA
382
384
  const quickMethod = generateQuickVeScaMethod({
383
385
  builder,
384
386
  txBlock: normalTxBlock,
@@ -3,18 +3,25 @@ export const SDK_API_BASE_URL = 'https://sdk.api.scallop.io';
3
3
 
4
4
  export const IS_VE_SCA_TEST = false;
5
5
 
6
+ // export const ADDRESSES_ID = '';
6
7
  export const ADDRESSES_ID = IS_VE_SCA_TEST
7
- ? ('65fb07c39c845425d71d7b18' as const)
8
- : ('6601955b8b0024600a917079' as const);
8
+ ? // ? ('65fb07c39c845425d71d7b18' as const)
9
+ ('65fb07c39c845425d71d7b18' as const)
10
+ : ('664dfe22898c36c159e28bc8' as const);
11
+ // : ('6601955b8b0024600a917079' as const);
9
12
  // : ('6462a088a7ace142bb6d7e9b' as const);
10
13
 
11
14
  export const PROTOCOL_OBJECT_ID = IS_VE_SCA_TEST
12
15
  ? ('0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778' as const)
13
16
  : ('0xefe8b36d5b2e43728cc323298626b83177803521d195cfb11e15b910e892fddf' as const);
17
+ // export const PROTOCOL_OBJECT_ID =
18
+ // '0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1' as const;
14
19
 
15
20
  export const BORROW_FEE_PROTOCOL_ID = IS_VE_SCA_TEST
16
21
  ? ('0xc9f859f98ca352a11b97a038c4b4162bee437b8df8caa047990fe9cb03d4f778' as const)
17
22
  : ('0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da' as const); // test environment
23
+ // export const BORROW_FEE_PROTOCOL_ID =
24
+ // '0x87ddec2984645dbbe2403a509cc6edf393a43acdba9b77d45da2bcbefcf733c1' as const;
18
25
 
19
26
  export const SCA_COIN_TYPE = IS_VE_SCA_TEST
20
27
  ? (`0x6cd813061a3adf3602b76545f076205f0c8e7ec1d3b1eab9a1da7992c18c0524::sca::SCA` as const)
@@ -1,7 +1,5 @@
1
- import { IS_VE_SCA_TEST } from './common';
2
-
3
1
  export const UNLOCK_ROUND_DURATION = 60 * 60 * 24; // 1 days in seconds
4
- export const MAX_LOCK_ROUNDS: number = IS_VE_SCA_TEST ? 9 : 1460; // 4 years in days (or 9 days for testing)
2
+ export const MAX_LOCK_ROUNDS: number = 1460; // 4 years in days (or 9 days for testing)
5
3
  export const MAX_LOCK_DURATION: number =
6
4
  MAX_LOCK_ROUNDS * UNLOCK_ROUND_DURATION; // 4 years in seconds
7
5
 
@@ -19,6 +19,45 @@ const EMPTY_ADDRESSES: AddressesInterface = {
19
19
  coinDecimalsRegistry: '',
20
20
  obligationAccessStore: '',
21
21
  coins: {
22
+ cetus: {
23
+ id: '',
24
+ metaData: '',
25
+ treasury: '',
26
+ oracle: {
27
+ supra: '',
28
+ switchboard: '',
29
+ pyth: {
30
+ feed: '',
31
+ feedObject: '',
32
+ },
33
+ },
34
+ },
35
+ apt: {
36
+ id: '',
37
+ metaData: '',
38
+ treasury: '',
39
+ oracle: {
40
+ supra: '',
41
+ switchboard: '',
42
+ pyth: {
43
+ feed: '',
44
+ feedObject: '',
45
+ },
46
+ },
47
+ },
48
+ sol: {
49
+ id: '',
50
+ metaData: '',
51
+ treasury: '',
52
+ oracle: {
53
+ supra: '',
54
+ switchboard: '',
55
+ pyth: {
56
+ feed: '',
57
+ feedObject: '',
58
+ },
59
+ },
60
+ },
22
61
  btc: {
23
62
  id: '',
24
63
  metaData: '',
@@ -140,15 +179,8 @@ const EMPTY_ADDRESSES: AddressesInterface = {
140
179
  oracles: {
141
180
  xOracle: '',
142
181
  xOracleCap: '',
143
- supra: {
144
- registry: '',
145
- registryCap: '',
146
- holder: '',
147
- },
148
- switchboard: {
149
- registry: '',
150
- registryCap: '',
151
- },
182
+ supra: { registry: '', registryCap: '', holder: '' },
183
+ switchboard: { registry: '', registryCap: '' },
152
184
  pyth: {
153
185
  registry: '',
154
186
  registryCap: '',
@@ -178,27 +210,25 @@ const EMPTY_ADDRESSES: AddressesInterface = {
178
210
  id: '',
179
211
  upgradeCap: '',
180
212
  },
181
- query: {
213
+ protocolWhitelist: {
182
214
  id: '',
183
215
  upgradeCap: '',
184
216
  },
185
- pyth: {
217
+ query: {
186
218
  id: '',
187
219
  upgradeCap: '',
188
220
  },
189
- switchboard: {
221
+ supra: { id: '', upgradeCap: '' },
222
+ pyth: {
190
223
  id: '',
191
224
  upgradeCap: '',
192
225
  },
226
+ switchboard: { id: '', upgradeCap: '' },
193
227
  xOracle: {
194
228
  id: '',
195
229
  upgradeCap: '',
196
230
  },
197
- // Deploy for faucet on testnet.
198
- testCoin: {
199
- id: '',
200
- upgradeCap: '',
201
- },
231
+ testCoin: { id: '', upgradeCap: '' },
202
232
  },
203
233
  },
204
234
  spool: {
@@ -239,26 +269,40 @@ const EMPTY_ADDRESSES: AddressesInterface = {
239
269
  rewardPoolId: '',
240
270
  },
241
271
  },
272
+ config: '',
242
273
  },
243
274
  borrowIncentive: {
244
275
  id: '',
245
276
  adminCap: '',
246
277
  object: '',
247
278
  query: '',
248
- config: '',
249
279
  incentivePools: '',
250
280
  incentiveAccounts: '',
281
+ config: '',
251
282
  },
252
283
  vesca: {
253
284
  id: '',
285
+ object: '',
254
286
  adminCap: '',
255
287
  tableId: '',
256
288
  table: '',
257
289
  treasury: '',
258
290
  config: '',
259
291
  },
292
+ referral: {
293
+ id: '',
294
+ version: '',
295
+ object: '',
296
+ adminCap: '',
297
+ referralBindings: '',
298
+ bindingTableId: '',
299
+ referralRevenuePool: '',
300
+ revenueTableId: '',
301
+ referralTiers: '',
302
+ tiersTableId: '',
303
+ authorizedWitnessList: '',
304
+ },
260
305
  };
261
-
262
306
  /**
263
307
  * @description
264
308
  * It provides methods for managing addresses.
@@ -1,5 +1,5 @@
1
1
  import { QueryClient, QueryClientConfig } from '@tanstack/query-core';
2
- import { SuiTxArg, SuiTxBlock } from '@scallop-io/sui-kit';
2
+ import { SuiTxArg, SuiTxBlock, normalizeStructTag } from '@scallop-io/sui-kit';
3
3
  import { SuiKit } from '@scallop-io/sui-kit';
4
4
  import type {
5
5
  SuiObjectResponse,
@@ -11,6 +11,7 @@ import type {
11
11
  GetDynamicFieldsParams,
12
12
  DynamicFieldPage,
13
13
  GetDynamicFieldObjectParams,
14
+ GetBalanceParams,
14
15
  } from '@mysten/sui.js/client';
15
16
  import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
16
17
 
@@ -70,7 +71,7 @@ export class ScallopCache {
70
71
  * @description Cache protocol config call for 60 seconds.
71
72
  * @returns Promise<ProtocolConfig>
72
73
  */
73
- private async getProtocolConfig() {
74
+ public async getProtocolConfig() {
74
75
  return await this.queryClient.fetchQuery({
75
76
  queryKey: ['getProtocolConfig'],
76
77
  queryFn: async () => {
@@ -242,4 +243,43 @@ export class ScallopCache {
242
243
  },
243
244
  });
244
245
  }
246
+
247
+ public async queryGetAllCoinBalances(
248
+ owner: string
249
+ ): Promise<{ [k: string]: string }> {
250
+ const queryKey = ['getAllCoinBalances', owner];
251
+ return this.queryClient.fetchQuery({
252
+ queryKey,
253
+ queryFn: async () => {
254
+ const allBalances = await this.suiKit
255
+ .client()
256
+ .getAllBalances({ owner });
257
+ return allBalances.reduce(
258
+ (acc, coinBalance) => {
259
+ if (coinBalance.totalBalance !== '0') {
260
+ acc[normalizeStructTag(coinBalance.coinType)] =
261
+ coinBalance.totalBalance;
262
+ }
263
+ return acc;
264
+ },
265
+ {} as { [k: string]: string }
266
+ );
267
+ },
268
+ });
269
+ }
270
+
271
+ public async queryGetCoinBalance(input: GetBalanceParams): Promise<string> {
272
+ const queryKey = ['getCoinBalance', input.owner, input.coinType];
273
+ return this.queryClient.fetchQuery({
274
+ queryKey,
275
+ queryFn: async () => {
276
+ if (!input.coinType) return '0';
277
+ return (
278
+ (await this.queryGetAllCoinBalances(input.owner))[
279
+ normalizeStructTag(input.coinType)
280
+ ] ?? '0'
281
+ );
282
+ },
283
+ });
284
+ }
245
285
  }
@@ -25,8 +25,12 @@ import {
25
25
  getObligationAccounts,
26
26
  getObligationAccount,
27
27
  getTotalValueLocked,
28
+ queryVeScaKeyIdFromReferralBindings,
28
29
  getBindedObligationId,
29
30
  getBindedVeScaKey,
31
+ getVeScas,
32
+ getPythPrices,
33
+ getTotalVeScaTreasuryAmount,
30
34
  } from '../queries';
31
35
  import {
32
36
  ScallopQueryParams,
@@ -272,6 +276,16 @@ export class ScallopQuery {
272
276
  return await getPythPrice(this, assetCoinName);
273
277
  }
274
278
 
279
+ /**
280
+ * Get prices from pyth fee object.
281
+ *
282
+ * @param assetCoinNames - Array of supported asset coin names.
283
+ * @return Array of asset coin prices.
284
+ */
285
+ public async getPricesFromPyth(assetCoinNames: SupportAssetCoins[]) {
286
+ return await getPythPrices(this, assetCoinNames);
287
+ }
288
+
275
289
  /* ==================== Spool Query Methods ==================== */
276
290
 
277
291
  /**
@@ -524,6 +538,32 @@ export class ScallopQuery {
524
538
  return await getTotalValueLocked(this, indexer);
525
539
  }
526
540
 
541
+ /**
542
+ * Get all veSca from walletAdddress
543
+ * @param walletAddress
544
+ * @returns array of veSca
545
+ */
546
+ public async getVeScas(walletAddress: string) {
547
+ return await getVeScas(this, walletAddress);
548
+ }
549
+
550
+ /**
551
+ * Get total vesca treasury with movecall
552
+ * @returns Promise<string | undefined>
553
+ */
554
+ public async getTotalVeScaTreasuryAmount() {
555
+ return await getTotalVeScaTreasuryAmount(this);
556
+ }
557
+
558
+ /**
559
+ * Return binded veScaKeyId of walletAddress if exist
560
+ * @param walletAddress
561
+ * @returns veScaKeyId
562
+ */
563
+ public async getVeScaKeyIdFromReferralBindings(walletAddress: string) {
564
+ return await queryVeScaKeyIdFromReferralBindings(this, walletAddress);
565
+ }
566
+
527
567
  /**
528
568
  * Get binded obligationId from a veScaKey if it exists.
529
569
  * @param veScaKey
@@ -419,9 +419,6 @@ export class ScallopUtils {
419
419
  );
420
420
 
421
421
  for (const endpoint of endpoints) {
422
- let hasFailRequest = false;
423
- const pythConnection = new SuiPriceServiceConnection(endpoint);
424
-
425
422
  const priceIds = Array.from(failedRequests.values()).reduce(
426
423
  (acc, coinName) => {
427
424
  const priceId = this._address.get(
@@ -433,43 +430,46 @@ export class ScallopUtils {
433
430
  {} as Record<SupportAssetCoins, string>
434
431
  );
435
432
 
436
- for (const [coinName, priceId] of Object.entries(priceIds)) {
437
- try {
438
- const feed = await this._cache.queryClient.fetchQuery({
439
- queryKey: [priceId],
440
- queryFn: async () => {
441
- return await pythConnection.getLatestPriceFeeds([priceId]);
442
- },
443
- // staleTime: 15000,
444
- });
445
- if (feed) {
446
- const data = parseDataFromPythPriceFeed(feed[0], this._address);
447
- this._priceMap.set(coinName as SupportAssetCoins, {
448
- price: data.price,
449
- publishTime: data.publishTime,
433
+ await Promise.allSettled(
434
+ Object.entries(priceIds).map(async ([coinName, priceId]) => {
435
+ const pythConnection = new SuiPriceServiceConnection(endpoint);
436
+ try {
437
+ const feed = await this._cache.queryClient.fetchQuery({
438
+ queryKey: [priceId],
439
+ queryFn: async () => {
440
+ return await pythConnection.getLatestPriceFeeds([priceId]);
441
+ },
450
442
  });
451
- coinPrices[coinName as SupportAssetCoins] = data.price;
443
+ if (feed) {
444
+ const data = parseDataFromPythPriceFeed(feed[0], this._address);
445
+ this._priceMap.set(coinName as SupportAssetCoins, {
446
+ price: data.price,
447
+ publishTime: data.publishTime,
448
+ });
449
+ coinPrices[coinName as SupportAssetCoins] = data.price;
450
+ }
451
+ failedRequests.delete(coinName as SupportAssetCoins); // remove success price feed to prevent duplicate request on the next endpoint
452
+ } catch (e) {
453
+ console.warn(
454
+ `Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
455
+ );
452
456
  }
453
- failedRequests.delete(coinName as SupportAssetCoins); // remove success price feed to prevent duplicate request on the next endpoint
454
- } catch (e) {
455
- console.warn(
456
- `Failed to get price ${coinName} feeds with endpoint ${endpoint}: ${e}`
457
- );
458
- hasFailRequest = true;
459
- }
460
- }
461
- if (!hasFailRequest) break;
457
+ })
458
+ );
459
+ if (failedRequests.size === 0) break;
462
460
  }
463
461
 
464
462
  if (failedRequests.size > 0) {
465
- for (const coinName of failedRequests.values()) {
466
- const price = await this._query.getPriceFromPyth(coinName);
467
- this._priceMap.set(coinName, {
468
- price: price,
469
- publishTime: Date.now(),
470
- });
471
- coinPrices[coinName] = price;
472
- }
463
+ await Promise.allSettled(
464
+ Array.from(failedRequests.values()).map(async (coinName) => {
465
+ const price = await this._query.getPriceFromPyth(coinName);
466
+ this._priceMap.set(coinName, {
467
+ price: price,
468
+ publishTime: Date.now(),
469
+ });
470
+ coinPrices[coinName] = price;
471
+ })
472
+ );
473
473
  }
474
474
  }
475
475
 
@@ -1,6 +1,5 @@
1
1
  import { normalizeStructTag } from '@mysten/sui.js/utils';
2
2
  import {
3
- IS_VE_SCA_TEST,
4
3
  SUPPORT_BORROW_INCENTIVE_POOLS,
5
4
  SUPPORT_BORROW_INCENTIVE_REWARDS,
6
5
  } from '../constants';
@@ -208,9 +207,7 @@ export const getBindedObligationId = async (
208
207
  ): Promise<string | null> => {
209
208
  const borrowIncentiveObjectId = query.address.get('borrowIncentive.object');
210
209
  const incentivePoolsId = query.address.get('borrowIncentive.incentivePools');
211
- const veScaPkgId = IS_VE_SCA_TEST
212
- ? '0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8'
213
- : query.address.get('vesca.id');
210
+ const veScaObjId = query.address.get('vesca.object');
214
211
 
215
212
  const client = query.suiKit.client();
216
213
 
@@ -229,7 +226,7 @@ export const getBindedObligationId = async (
229
226
  .id as string;
230
227
 
231
228
  // check if veSca is inside the bind table
232
- const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaPkgId}::ve_sca::VeScaKey>`;
229
+ const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
233
230
  const veScaBindTableResponse = await client.getDynamicFieldObject({
234
231
  parentId: veScaBindTableId,
235
232
  name: {