@scallop-io/sui-scallop-sdk 0.44.28 → 0.46.0

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 (60) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +1 -1
  2. package/dist/builders/referralBuilder.d.ts +12 -0
  3. package/dist/constants/cache.d.ts +8 -0
  4. package/dist/constants/common.d.ts +1 -1
  5. package/dist/index.js +890 -419
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +967 -493
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/models/index.d.ts +1 -0
  10. package/dist/models/scallop.d.ts +7 -1
  11. package/dist/models/scallopAddress.d.ts +4 -2
  12. package/dist/models/scallopBuilder.d.ts +2 -0
  13. package/dist/models/scallopCache.d.ts +75 -0
  14. package/dist/models/scallopClient.d.ts +2 -0
  15. package/dist/models/scallopIndexer.d.ts +5 -3
  16. package/dist/models/scallopQuery.d.ts +28 -28
  17. package/dist/models/scallopUtils.d.ts +1 -0
  18. package/dist/queries/coreQuery.d.ts +3 -29
  19. package/dist/queries/index.d.ts +1 -0
  20. package/dist/queries/priceQuery.d.ts +3 -1
  21. package/dist/queries/referralQuery.d.ts +7 -0
  22. package/dist/queries/vescaQuery.d.ts +6 -2
  23. package/dist/types/address.d.ts +15 -0
  24. package/dist/types/builder/core.d.ts +2 -0
  25. package/dist/types/builder/index.d.ts +2 -1
  26. package/dist/types/builder/referral.d.ts +30 -0
  27. package/dist/types/builder/vesca.d.ts +1 -0
  28. package/dist/types/model.d.ts +2 -0
  29. package/package.json +8 -6
  30. package/src/builders/borrowIncentiveBuilder.ts +12 -21
  31. package/src/builders/coreBuilder.ts +54 -0
  32. package/src/builders/index.ts +5 -2
  33. package/src/builders/referralBuilder.ts +178 -0
  34. package/src/builders/vescaBuilder.ts +8 -6
  35. package/src/constants/cache.ts +15 -0
  36. package/src/constants/common.ts +9 -2
  37. package/src/constants/vesca.ts +1 -3
  38. package/src/models/index.ts +1 -0
  39. package/src/models/scallop.ts +26 -7
  40. package/src/models/scallopAddress.ts +87 -38
  41. package/src/models/scallopBuilder.ts +14 -4
  42. package/src/models/scallopCache.ts +285 -0
  43. package/src/models/scallopClient.ts +15 -4
  44. package/src/models/scallopIndexer.ts +58 -84
  45. package/src/models/scallopQuery.ts +54 -5
  46. package/src/models/scallopUtils.ts +66 -37
  47. package/src/queries/borrowIncentiveQuery.ts +6 -12
  48. package/src/queries/coreQuery.ts +83 -260
  49. package/src/queries/index.ts +1 -0
  50. package/src/queries/priceQuery.ts +48 -9
  51. package/src/queries/referralQuery.ts +27 -0
  52. package/src/queries/spoolQuery.ts +20 -27
  53. package/src/queries/vescaQuery.ts +95 -17
  54. package/src/types/address.ts +15 -0
  55. package/src/types/builder/core.ts +14 -0
  56. package/src/types/builder/index.ts +2 -0
  57. package/src/types/builder/referral.ts +51 -0
  58. package/src/types/builder/vesca.ts +1 -0
  59. package/src/types/model.ts +2 -0
  60. package/src/types/query/borrowIncentive.ts +0 -107
@@ -15,7 +15,11 @@ import type {
15
15
  SupportStakeMarketCoins,
16
16
  SupportBorrowIncentiveCoins,
17
17
  TotalValueLocked,
18
+ ScallopQueryParams,
19
+ ScallopParams,
20
+ ScallopInstanceParams,
18
21
  } from '../types';
22
+ import { ScallopCache } from './scallopCache';
19
23
 
20
24
  /**
21
25
  * @description
@@ -30,9 +34,13 @@ import type {
30
34
  * ```
31
35
  */
32
36
  export class ScallopIndexer {
33
- private _requestClient: AxiosInstance;
37
+ private readonly _cache: ScallopCache;
38
+ public readonly params: ScallopQueryParams;
39
+ private readonly _requestClient: AxiosInstance;
34
40
 
35
- public constructor() {
41
+ public constructor(params: ScallopParams, instance?: ScallopInstanceParams) {
42
+ this.params = params;
43
+ this._cache = instance?.cache ?? new ScallopCache();
36
44
  this._requestClient = axios.create({
37
45
  baseURL: SDK_API_BASE_URL,
38
46
  headers: {
@@ -49,10 +57,15 @@ export class ScallopIndexer {
49
57
  * @return Market data.
50
58
  */
51
59
  public async getMarket(): Promise<Pick<Market, 'pools' | 'collaterals'>> {
52
- const response = await this._requestClient.get<{
53
- pools: MarketPool[];
54
- collaterals: MarketCollateral[];
55
- }>(`${SDK_API_BASE_URL}/api/market`);
60
+ const response = await this._cache.queryClient.fetchQuery({
61
+ queryKey: ['market'],
62
+ queryFn: async () => {
63
+ return await this._requestClient.get<{
64
+ pools: MarketPool[];
65
+ collaterals: MarketCollateral[];
66
+ }>(`/api/market`);
67
+ },
68
+ });
56
69
 
57
70
  if (response.status === 200) {
58
71
  return {
@@ -79,18 +92,8 @@ export class ScallopIndexer {
79
92
  * @return Market pools data.
80
93
  */
81
94
  public async getMarketPools(): Promise<Required<MarketPools>> {
82
- const response = await this._requestClient.get<{
83
- pools: MarketPool[];
84
- }>(`${SDK_API_BASE_URL}/api/market/pools`);
85
-
86
- if (response.status === 200) {
87
- return response.data.pools.reduce((marketPools, marketPool) => {
88
- marketPools[marketPool.coinName] = marketPool;
89
- return marketPools;
90
- }, {} as MarketPools) as Required<MarketPools>;
91
- } else {
92
- throw Error('Failed to getMarketPools.');
93
- }
95
+ const response = (await this.getMarket()).pools;
96
+ return response as Required<MarketPools>;
94
97
  }
95
98
 
96
99
  /**
@@ -101,15 +104,7 @@ export class ScallopIndexer {
101
104
  public async getMarketPool(
102
105
  poolCoinName: SupportPoolCoins
103
106
  ): Promise<MarketPool> {
104
- const response = await this._requestClient.get<{
105
- pool: MarketPool;
106
- }>(`${SDK_API_BASE_URL}/api/market/pool/${poolCoinName}`);
107
-
108
- if (response.status === 200) {
109
- return response.data.pool;
110
- } else {
111
- throw Error('Failed to getMarketPool.');
112
- }
107
+ return (await this.getMarketPools())[poolCoinName] as MarketPool;
113
108
  }
114
109
 
115
110
  /**
@@ -118,21 +113,7 @@ export class ScallopIndexer {
118
113
  * @return Market collaterals data.
119
114
  */
120
115
  public async getMarketCollaterals(): Promise<Required<MarketCollaterals>> {
121
- const response = await this._requestClient.get<{
122
- collaterals: MarketCollateral[];
123
- }>(`${SDK_API_BASE_URL}/api/market/collaterals`);
124
-
125
- if (response.status === 200) {
126
- return response.data.collaterals.reduce(
127
- (marketCollaterals, marketCollateral) => {
128
- marketCollaterals[marketCollateral.coinName] = marketCollateral;
129
- return marketCollaterals;
130
- },
131
- {} as MarketCollaterals
132
- ) as Required<MarketCollaterals>;
133
- } else {
134
- throw Error('Failed to getMarketCollaterals.');
135
- }
116
+ return (await this.getMarket()).collaterals as Required<MarketCollaterals>;
136
117
  }
137
118
 
138
119
  /**
@@ -143,15 +124,9 @@ export class ScallopIndexer {
143
124
  public async getMarketCollateral(
144
125
  collateralCoinName: SupportCollateralCoins
145
126
  ): Promise<MarketCollateral> {
146
- const response = await this._requestClient.get<{
147
- collateral: MarketCollateral;
148
- }>(`${SDK_API_BASE_URL}/api/market/collateral/${collateralCoinName}`);
149
-
150
- if (response.status === 200) {
151
- return response.data.collateral;
152
- } else {
153
- throw Error('Failed to getMarketCollateral.');
154
- }
127
+ return (await this.getMarketCollaterals())[
128
+ collateralCoinName
129
+ ] as MarketCollateral;
155
130
  }
156
131
 
157
132
  /**
@@ -160,9 +135,14 @@ export class ScallopIndexer {
160
135
  * @return Spools data.
161
136
  */
162
137
  public async getSpools(): Promise<Required<Spools>> {
163
- const response = await this._requestClient.get<{
164
- spools: Spool[];
165
- }>(`${SDK_API_BASE_URL}/api/spools`);
138
+ const response = await this._cache.queryClient.fetchQuery({
139
+ queryKey: ['spools'],
140
+ queryFn: async () => {
141
+ return await this._requestClient.get<{
142
+ spools: Spool[];
143
+ }>(`/api/spools`);
144
+ },
145
+ });
166
146
 
167
147
  if (response.status === 200) {
168
148
  return response.data.spools.reduce((spools, spool) => {
@@ -182,15 +162,7 @@ export class ScallopIndexer {
182
162
  public async getSpool(
183
163
  marketCoinName: SupportStakeMarketCoins
184
164
  ): Promise<Spool> {
185
- const response = await this._requestClient.get<{
186
- spool: Spool;
187
- }>(`${SDK_API_BASE_URL}/api/spool/${marketCoinName}`);
188
-
189
- if (response.status === 200) {
190
- return response.data.spool;
191
- } else {
192
- throw Error('Failed to getSpool.');
193
- }
165
+ return (await this.getSpools())[marketCoinName] as Spool;
194
166
  }
195
167
 
196
168
  /**
@@ -201,9 +173,14 @@ export class ScallopIndexer {
201
173
  public async getBorrowIncentivePools(): Promise<
202
174
  Required<BorrowIncentivePools>
203
175
  > {
204
- const response = await this._requestClient.get<{
205
- borrowIncentivePools: BorrowIncentivePool[];
206
- }>(`${SDK_API_BASE_URL}/api/borrowIncentivePools`);
176
+ const response = await this._cache.queryClient.fetchQuery({
177
+ queryKey: ['borrowIncentivePools'],
178
+ queryFn: async () => {
179
+ return await this._requestClient.get<{
180
+ borrowIncentivePools: BorrowIncentivePool[];
181
+ }>(`/api/borrowIncentivePools`);
182
+ },
183
+ });
207
184
 
208
185
  if (response.status === 200) {
209
186
  return response.data.borrowIncentivePools.reduce(
@@ -227,17 +204,9 @@ export class ScallopIndexer {
227
204
  public async getBorrowIncentivePool(
228
205
  borrowIncentiveCoinName: SupportBorrowIncentiveCoins
229
206
  ): Promise<BorrowIncentivePool> {
230
- const response = await this._requestClient.get<{
231
- borrowIncentivePool: BorrowIncentivePool;
232
- }>(
233
- `${SDK_API_BASE_URL}/api/borrowIncentivePool/${borrowIncentiveCoinName}`
234
- );
235
-
236
- if (response.status === 200) {
237
- return response.data.borrowIncentivePool;
238
- } else {
239
- throw Error('Failed to getSpool.');
240
- }
207
+ return (await this.getBorrowIncentivePools())[
208
+ borrowIncentiveCoinName
209
+ ] as BorrowIncentivePool;
241
210
  }
242
211
 
243
212
  /**
@@ -252,13 +221,18 @@ export class ScallopIndexer {
252
221
  supplyValueChangeRatio: number;
253
222
  }
254
223
  > {
255
- const response = await this._requestClient.get<
256
- TotalValueLocked & {
257
- totalValueChangeRatio: number;
258
- borrowValueChangeRatio: number;
259
- supplyValueChangeRatio: number;
260
- }
261
- >(`${SDK_API_BASE_URL}/api/market/tvl`);
224
+ const response = await this._cache.queryClient.fetchQuery({
225
+ queryKey: ['totalValueLocked'],
226
+ queryFn: async () => {
227
+ return await this._requestClient.get<
228
+ TotalValueLocked & {
229
+ totalValueChangeRatio: number;
230
+ borrowValueChangeRatio: number;
231
+ supplyValueChangeRatio: number;
232
+ }
233
+ >(`/api/market/tvl`);
234
+ },
235
+ });
262
236
 
263
237
  if (response.status === 200) {
264
238
  return response.data;
@@ -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,
@@ -43,6 +47,8 @@ import {
43
47
  import { ScallopAddress } from './scallopAddress';
44
48
  import { ScallopUtils } from './scallopUtils';
45
49
  import { ScallopIndexer } from './scallopIndexer';
50
+ import { ScallopCache } from './scallopCache';
51
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
46
52
 
47
53
  /**
48
54
  * @description
@@ -63,6 +69,7 @@ export class ScallopQuery {
63
69
  public address: ScallopAddress;
64
70
  public utils: ScallopUtils;
65
71
  public indexer: ScallopIndexer;
72
+ public cache: ScallopCache;
66
73
 
67
74
  public constructor(
68
75
  params: ScallopQueryParams,
@@ -70,20 +77,26 @@ export class ScallopQuery {
70
77
  ) {
71
78
  this.params = params;
72
79
  this.suiKit = instance?.suiKit ?? new SuiKit(params);
80
+ this.cache =
81
+ instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
73
82
  this.address =
74
83
  instance?.address ??
75
- new ScallopAddress({
76
- id: params?.addressesId || ADDRESSES_ID,
77
- network: params?.networkType,
78
- });
84
+ new ScallopAddress(
85
+ {
86
+ id: params?.addressesId || ADDRESSES_ID,
87
+ network: params?.networkType,
88
+ },
89
+ this.cache
90
+ );
79
91
  this.utils =
80
92
  instance?.utils ??
81
93
  new ScallopUtils(this.params, {
82
94
  suiKit: this.suiKit,
83
95
  address: this.address,
96
+ cache: this.cache,
84
97
  query: this,
85
98
  });
86
- this.indexer = new ScallopIndexer();
99
+ this.indexer = new ScallopIndexer(this.params, { cache: this.cache });
87
100
  }
88
101
 
89
102
  /**
@@ -263,6 +276,16 @@ export class ScallopQuery {
263
276
  return await getPythPrice(this, assetCoinName);
264
277
  }
265
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
+
266
289
  /* ==================== Spool Query Methods ==================== */
267
290
 
268
291
  /**
@@ -515,6 +538,32 @@ export class ScallopQuery {
515
538
  return await getTotalValueLocked(this, indexer);
516
539
  }
517
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
+
518
567
  /**
519
568
  * Get binded obligationId from a veScaKey if it exists.
520
569
  * @param veScaKey
@@ -37,6 +37,8 @@ import type {
37
37
  CoinWrappedType,
38
38
  } from '../types';
39
39
  import { PYTH_ENDPOINTS } from 'src/constants/pyth';
40
+ import { ScallopCache } from './scallopCache';
41
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
40
42
 
41
43
  /**
42
44
  * @description
@@ -58,6 +60,7 @@ export class ScallopUtils {
58
60
  private _address: ScallopAddress;
59
61
  private _query: ScallopQuery;
60
62
  private _priceMap: PriceMap = new Map();
63
+ private _cache: ScallopCache;
61
64
 
62
65
  public constructor(
63
66
  params: ScallopUtilsParams,
@@ -65,17 +68,23 @@ export class ScallopUtils {
65
68
  ) {
66
69
  this.params = params;
67
70
  this._suiKit = instance?.suiKit ?? new SuiKit(params);
71
+ this._cache =
72
+ instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this._suiKit);
68
73
  this._address =
69
74
  instance?.address ??
70
- new ScallopAddress({
71
- id: params?.addressesId || ADDRESSES_ID,
72
- network: params?.networkType,
73
- });
75
+ new ScallopAddress(
76
+ {
77
+ id: params?.addressesId || ADDRESSES_ID,
78
+ network: params?.networkType,
79
+ },
80
+ this._cache
81
+ );
74
82
  this._query =
75
83
  instance?.query ??
76
84
  new ScallopQuery(params, {
77
85
  suiKit: this._suiKit,
78
86
  address: this._address,
87
+ cache: this._cache,
79
88
  });
80
89
  this.isTestnet = params.networkType
81
90
  ? params.networkType === 'testnet'
@@ -404,43 +413,63 @@ export class ScallopUtils {
404
413
  const endpoints =
405
414
  this.params.pythEndpoints ??
406
415
  PYTH_ENDPOINTS[this.isTestnet ? 'testnet' : 'mainnet'];
407
- try {
408
- for (const endpoint of endpoints) {
409
- try {
410
- const pythConnection = new SuiPriceServiceConnection(endpoint);
411
- const priceIds = lackPricesCoinNames.map((coinName) =>
412
- this._address.get(`core.coins.${coinName}.oracle.pyth.feed`)
416
+
417
+ const failedRequests: Set<SupportAssetCoins> = new Set(
418
+ lackPricesCoinNames
419
+ );
420
+
421
+ for (const endpoint of endpoints) {
422
+ const priceIds = Array.from(failedRequests.values()).reduce(
423
+ (acc, coinName) => {
424
+ const priceId = this._address.get(
425
+ `core.coins.${coinName}.oracle.pyth.feed`
413
426
  );
414
- const priceFeeds =
415
- (await pythConnection.getLatestPriceFeeds(priceIds)) || [];
416
- for (const [index, feed] of priceFeeds.entries()) {
417
- const data = parseDataFromPythPriceFeed(feed, this._address);
418
- const coinName = lackPricesCoinNames[index];
419
- this._priceMap.set(coinName, {
420
- price: data.price,
421
- publishTime: data.publishTime,
427
+ acc[coinName] = priceId;
428
+ return acc;
429
+ },
430
+ {} as Record<SupportAssetCoins, string>
431
+ );
432
+
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
+ },
422
442
  });
423
- coinPrices[coinName] = 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
+ );
424
456
  }
457
+ })
458
+ );
459
+ if (failedRequests.size === 0) break;
460
+ }
425
461
 
426
- break;
427
- } catch (e) {
428
- console.warn(
429
- `Failed to update price feeds with endpoint ${endpoint}: ${e}`
430
- );
431
- }
432
-
433
- throw new Error('Failed to update price feeds with all endpoins');
434
- }
435
- } catch (_e) {
436
- for (const coinName of lackPricesCoinNames) {
437
- const price = await this._query.getPriceFromPyth(coinName);
438
- this._priceMap.set(coinName, {
439
- price: price,
440
- publishTime: Date.now(),
441
- });
442
- coinPrices[coinName] = price;
443
- }
462
+ if (failedRequests.size > 0) {
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
+ );
444
473
  }
445
474
  }
446
475
 
@@ -1,7 +1,5 @@
1
1
  import { normalizeStructTag } from '@mysten/sui.js/utils';
2
- import { SuiTxBlock as SuiKitTxBlock } from '@scallop-io/sui-kit';
3
2
  import {
4
- IS_VE_SCA_TEST,
5
3
  SUPPORT_BORROW_INCENTIVE_POOLS,
6
4
  SUPPORT_BORROW_INCENTIVE_REWARDS,
7
5
  } from '../constants';
@@ -41,10 +39,9 @@ export const queryBorrowIncentivePools = async (
41
39
  const queryPkgId = query.address.get('borrowIncentive.query');
42
40
  const incentivePoolsId = query.address.get('borrowIncentive.incentivePools');
43
41
 
44
- const txBlock = new SuiKitTxBlock();
45
42
  const queryTarget = `${queryPkgId}::incentive_pools_query::incentive_pools_data`;
46
- txBlock.moveCall(queryTarget, [incentivePoolsId]);
47
- const queryResult = await query.suiKit.inspectTxn(txBlock);
43
+ const args = [incentivePoolsId];
44
+ const queryResult = await query.cache.queryInspectTxn({ queryTarget, args });
48
45
  const borrowIncentivePoolsQueryData = queryResult.events[0]
49
46
  .parsedJson as BorrowIncentivePoolsQueryInterface;
50
47
 
@@ -170,10 +167,9 @@ export const queryBorrowIncentiveAccounts = async (
170
167
  'borrowIncentive.incentiveAccounts'
171
168
  );
172
169
  const queryTarget = `${queryPkgId}::incentive_account_query::incentive_account_data`;
170
+ const args = [incentiveAccountsId, obligationId];
173
171
 
174
- const txBlock = new SuiKitTxBlock();
175
- txBlock.moveCall(queryTarget, [incentiveAccountsId, obligationId]);
176
- const queryResult = await query.suiKit.inspectTxn(txBlock);
172
+ const queryResult = await query.cache.queryInspectTxn({ queryTarget, args });
177
173
  const borrowIncentiveAccountsQueryData = queryResult.events[0]
178
174
  .parsedJson as BorrowIncentiveAccountsQueryInterface;
179
175
 
@@ -211,9 +207,7 @@ export const getBindedObligationId = async (
211
207
  ): Promise<string | null> => {
212
208
  const borrowIncentiveObjectId = query.address.get('borrowIncentive.object');
213
209
  const incentivePoolsId = query.address.get('borrowIncentive.incentivePools');
214
- const veScaPkgId = IS_VE_SCA_TEST
215
- ? '0xb220d034bdf335d77ae5bfbf6daf059c2cc7a1f719b12bfed75d1736fac038c8'
216
- : query.address.get('vesca.id');
210
+ const veScaObjId = query.address.get('vesca.object');
217
211
 
218
212
  const client = query.suiKit.client();
219
213
 
@@ -232,7 +226,7 @@ export const getBindedObligationId = async (
232
226
  .id as string;
233
227
 
234
228
  // check if veSca is inside the bind table
235
- const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaPkgId}::ve_sca::VeScaKey>`;
229
+ const keyType = `${borrowIncentiveObjectId}::typed_id::TypedID<${veScaObjId}::ve_sca::VeScaKey>`;
236
230
  const veScaBindTableResponse = await client.getDynamicFieldObject({
237
231
  parentId: veScaBindTableId,
238
232
  name: {