@scallop-io/sui-scallop-sdk 0.44.27 → 0.45.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 (39) hide show
  1. package/dist/builders/borrowIncentiveBuilder.d.ts +0 -7
  2. package/dist/constants/cache.d.ts +8 -0
  3. package/dist/index.js +538 -268
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +522 -253
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/models/index.d.ts +1 -0
  8. package/dist/models/scallop.d.ts +7 -1
  9. package/dist/models/scallopAddress.d.ts +4 -2
  10. package/dist/models/scallopBuilder.d.ts +2 -0
  11. package/dist/models/scallopCache.d.ts +71 -0
  12. package/dist/models/scallopClient.d.ts +2 -0
  13. package/dist/models/scallopIndexer.d.ts +5 -3
  14. package/dist/models/scallopQuery.d.ts +14 -0
  15. package/dist/models/scallopUtils.d.ts +1 -0
  16. package/dist/queries/borrowIncentiveQuery.d.ts +8 -0
  17. package/dist/types/model.d.ts +2 -0
  18. package/dist/types/query/vesca.d.ts +2 -1
  19. package/package.json +2 -1
  20. package/src/builders/borrowIncentiveBuilder.ts +8 -57
  21. package/src/builders/vescaBuilder.ts +7 -3
  22. package/src/constants/cache.ts +15 -0
  23. package/src/models/index.ts +1 -0
  24. package/src/models/scallop.ts +26 -7
  25. package/src/models/scallopAddress.ts +24 -19
  26. package/src/models/scallopBuilder.ts +14 -4
  27. package/src/models/scallopCache.ts +245 -0
  28. package/src/models/scallopClient.ts +15 -4
  29. package/src/models/scallopIndexer.ts +58 -84
  30. package/src/models/scallopQuery.ts +34 -5
  31. package/src/models/scallopUtils.ts +53 -24
  32. package/src/queries/borrowIncentiveQuery.ts +99 -7
  33. package/src/queries/coreQuery.ts +62 -75
  34. package/src/queries/priceQuery.ts +4 -6
  35. package/src/queries/spoolQuery.ts +12 -15
  36. package/src/queries/vescaQuery.ts +20 -8
  37. package/src/types/model.ts +2 -0
  38. package/src/types/query/borrowIncentive.ts +0 -107
  39. package/src/types/query/vesca.ts +2 -1
@@ -0,0 +1,245 @@
1
+ import { QueryClient, QueryClientConfig } from '@tanstack/query-core';
2
+ import { SuiTxArg, SuiTxBlock } from '@scallop-io/sui-kit';
3
+ import { SuiKit } from '@scallop-io/sui-kit';
4
+ import type {
5
+ SuiObjectResponse,
6
+ SuiObjectDataOptions,
7
+ SuiObjectData,
8
+ PaginatedObjectsResponse,
9
+ GetOwnedObjectsParams,
10
+ DevInspectResults,
11
+ GetDynamicFieldsParams,
12
+ DynamicFieldPage,
13
+ GetDynamicFieldObjectParams,
14
+ } from '@mysten/sui.js/client';
15
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
16
+
17
+ type QueryInspectTxnParams = {
18
+ queryTarget: string;
19
+ args: SuiTxArg[];
20
+ typeArgs?: any[];
21
+ };
22
+
23
+ /**
24
+ * @description
25
+ * It provides caching for moveCall, RPC Request, and API Request.
26
+ *
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const scallopCache = new scallopCache(<parameters>);
31
+ * scallopCache.<indexer functions>();
32
+ * await scallopCache.<indexer async functions>();
33
+ * ```
34
+ */
35
+
36
+ export class ScallopCache {
37
+ public readonly queryClient: QueryClient;
38
+ public readonly _suiKit?: SuiKit;
39
+
40
+ public constructor(cacheOptions?: QueryClientConfig, suiKit?: SuiKit) {
41
+ this.queryClient = new QueryClient(cacheOptions ?? DEFAULT_CACHE_OPTIONS);
42
+ this._suiKit = suiKit;
43
+ }
44
+
45
+ private get suiKit(): SuiKit {
46
+ if (!this._suiKit) {
47
+ throw new Error('SuiKit instance is not initialized');
48
+ }
49
+ return this._suiKit;
50
+ }
51
+
52
+ /**
53
+ * @description Invalidate cache based on the refetchType parameter
54
+ * @param refetchType Determines the type of queries to be refetched. Defaults to `active`.
55
+ *
56
+ * - `active`: Only queries that match the refetch predicate and are actively being rendered via useQuery and related functions will be refetched in the background.
57
+ * - `inactive`: Only queries that match the refetch predicate and are NOT actively being rendered via useQuery and related functions will be refetched in the background.
58
+ * - `all`: All queries that match the refetch predicate will be refetched in the background.
59
+ * - `none`: No queries will be refetched. Queries that match the refetch predicate will only be marked as invalid.
60
+ */
61
+ public invalidateAndRefetchAllCache(
62
+ refetchType: 'all' | 'active' | 'inactive' | 'none'
63
+ ) {
64
+ return this.queryClient.invalidateQueries({
65
+ refetchType,
66
+ });
67
+ }
68
+
69
+ /**
70
+ * @description Cache protocol config call for 60 seconds.
71
+ * @returns Promise<ProtocolConfig>
72
+ */
73
+ private async getProtocolConfig() {
74
+ return await this.queryClient.fetchQuery({
75
+ queryKey: ['getProtocolConfig'],
76
+ queryFn: async () => {
77
+ return await this.suiKit.client().getProtocolConfig();
78
+ },
79
+ staleTime: 30000,
80
+ });
81
+ }
82
+
83
+ /**
84
+ * @description Provides cache for inspectTxn of the SuiKit.
85
+ * @param QueryInspectTxnParams
86
+ * @param txBlock
87
+ * @returns Promise<DevInspectResults>
88
+ */
89
+ public async queryInspectTxn({
90
+ queryTarget,
91
+ args,
92
+ typeArgs,
93
+ }: QueryInspectTxnParams): Promise<DevInspectResults> {
94
+ const txBlock = new SuiTxBlock();
95
+
96
+ // resolve all the object args to prevent duplicate getNormalizedMoveFunction calls
97
+ const resolvedArgs = await Promise.all(
98
+ args.map(async (arg) => {
99
+ if (typeof arg === 'string') {
100
+ return (await this.queryGetObject(arg, { showContent: true })).data;
101
+ }
102
+ return arg;
103
+ })
104
+ );
105
+ txBlock.moveCall(queryTarget, resolvedArgs, typeArgs);
106
+
107
+ // build the txBlock to prevent duplicate getProtocolConfig calls
108
+ const txBytes = await txBlock.txBlock.build({
109
+ client: this.suiKit.client(),
110
+ onlyTransactionKind: true,
111
+ protocolConfig: await this.getProtocolConfig(),
112
+ });
113
+
114
+ const query = await this.queryClient.fetchQuery({
115
+ queryKey: typeArgs
116
+ ? ['inspectTxn', queryTarget, JSON.stringify(args)]
117
+ : [
118
+ 'inspectTxn',
119
+ queryTarget,
120
+ JSON.stringify(args),
121
+ JSON.stringify(typeArgs),
122
+ ],
123
+ queryFn: async () => {
124
+ return await this.suiKit.inspectTxn(txBytes);
125
+ },
126
+ staleTime: 8000, // make stale time longer for inspectTxn results
127
+ });
128
+ return query;
129
+ }
130
+
131
+ /**
132
+ * @description Provides cache for getObject of the SuiKit.
133
+ * @param objectId
134
+ * @param QueryObjectParams
135
+ * @returns Promise<SuiObjectResponse>
136
+ */
137
+ public async queryGetObject(
138
+ objectId: string,
139
+ options?: SuiObjectDataOptions
140
+ ): Promise<SuiObjectResponse> {
141
+ const queryKey = ['getObject', objectId, this.suiKit.currentAddress()];
142
+ if (options) {
143
+ queryKey.push(JSON.stringify(options));
144
+ }
145
+ return this.queryClient.fetchQuery({
146
+ queryKey,
147
+ queryFn: async () => {
148
+ return await this.suiKit.client().getObject({
149
+ id: objectId,
150
+ options,
151
+ });
152
+ },
153
+ });
154
+ }
155
+
156
+ /**
157
+ * @description Provides cache for getObjects of the SuiKit.
158
+ * @param objectIds
159
+ * @returns Promise<SuiObjectData[]>
160
+ */
161
+ public async queryGetObjects(
162
+ objectIds: string[],
163
+ options?: SuiObjectDataOptions
164
+ ): Promise<SuiObjectData[]> {
165
+ const queryKey = [
166
+ 'getObjects',
167
+ JSON.stringify(objectIds),
168
+ this.suiKit.currentAddress(),
169
+ ];
170
+ return this.queryClient.fetchQuery({
171
+ queryKey,
172
+ queryFn: async () => {
173
+ return await this.suiKit.getObjects(objectIds, options);
174
+ },
175
+ });
176
+ }
177
+
178
+ /**
179
+ * @description Provides cache for getOwnedObjects of the SuiKit.
180
+ * @param input
181
+ * @returns Promise<PaginatedObjectsResponse>
182
+ */
183
+ public async queryGetOwnedObjects(
184
+ input: GetOwnedObjectsParams
185
+ ): Promise<PaginatedObjectsResponse> {
186
+ const queryKey = ['getOwnedObjects', input.owner];
187
+ if (input.cursor) {
188
+ queryKey.push(JSON.stringify(input.cursor));
189
+ }
190
+ if (input.options) {
191
+ queryKey.push(JSON.stringify(input.options));
192
+ }
193
+ if (input.filter) {
194
+ queryKey.push(JSON.stringify(input.filter));
195
+ }
196
+ if (input.limit) {
197
+ queryKey.push(JSON.stringify(input.limit));
198
+ }
199
+
200
+ return this.queryClient.fetchQuery({
201
+ queryKey,
202
+ queryFn: async () => {
203
+ return await this.suiKit.client().getOwnedObjects(input);
204
+ },
205
+ });
206
+ }
207
+
208
+ public async queryGetDynamicFields(
209
+ input: GetDynamicFieldsParams
210
+ ): Promise<DynamicFieldPage> {
211
+ const queryKey = ['getDynamicFields', input.parentId];
212
+ if (input.cursor) {
213
+ queryKey.push(JSON.stringify(input.cursor));
214
+ }
215
+ if (input.cursor) {
216
+ queryKey.push(JSON.stringify(input.cursor));
217
+ }
218
+ if (input.limit) {
219
+ queryKey.push(JSON.stringify(input.limit));
220
+ }
221
+
222
+ return this.queryClient.fetchQuery({
223
+ queryKey,
224
+ queryFn: async () => {
225
+ return await this.suiKit.client().getDynamicFields(input);
226
+ },
227
+ });
228
+ }
229
+
230
+ public async queryGetDynamicFieldObject(
231
+ input: GetDynamicFieldObjectParams
232
+ ): Promise<SuiObjectResponse> {
233
+ const queryKey = [
234
+ 'getDynamicFieldObject',
235
+ input.parentId,
236
+ input.name.value,
237
+ ];
238
+ return this.queryClient.fetchQuery({
239
+ queryKey,
240
+ queryFn: async () => {
241
+ return await this.suiKit.client().getDynamicFieldObject(input);
242
+ },
243
+ });
244
+ }
245
+ }
@@ -24,6 +24,8 @@ import type {
24
24
  SupportBorrowIncentiveCoins,
25
25
  ScallopTxBlock,
26
26
  } from '../types';
27
+ import { ScallopCache } from './scallopCache';
28
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
27
29
 
28
30
  /**
29
31
  * @description
@@ -45,6 +47,7 @@ export class ScallopClient {
45
47
  public builder: ScallopBuilder;
46
48
  public query: ScallopQuery;
47
49
  public utils: ScallopUtils;
50
+ public cache: ScallopCache;
48
51
  public walletAddress: string;
49
52
 
50
53
  public constructor(
@@ -53,17 +56,23 @@ export class ScallopClient {
53
56
  ) {
54
57
  this.params = params;
55
58
  this.suiKit = instance?.suiKit ?? new SuiKit(params);
59
+ this.cache =
60
+ instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
56
61
  this.address =
57
62
  instance?.address ??
58
- new ScallopAddress({
59
- id: params?.addressesId || ADDRESSES_ID,
60
- network: params?.networkType,
61
- });
63
+ new ScallopAddress(
64
+ {
65
+ id: params?.addressesId || ADDRESSES_ID,
66
+ network: params?.networkType,
67
+ },
68
+ this.cache
69
+ );
62
70
  this.query =
63
71
  instance?.query ??
64
72
  new ScallopQuery(params, {
65
73
  suiKit: this.suiKit,
66
74
  address: this.address,
75
+ cache: this.cache,
67
76
  });
68
77
  this.utils =
69
78
  instance?.utils ??
@@ -71,6 +80,7 @@ export class ScallopClient {
71
80
  suiKit: this.suiKit,
72
81
  address: this.address,
73
82
  query: this.query,
83
+ cache: this.cache,
74
84
  });
75
85
  this.builder =
76
86
  instance?.builder ??
@@ -79,6 +89,7 @@ export class ScallopClient {
79
89
  address: this.address,
80
90
  query: this.query,
81
91
  utils: this.utils,
92
+ cache: this.cache,
82
93
  });
83
94
  this.walletAddress = normalizeSuiAddress(
84
95
  params?.walletAddress || this.suiKit.currentAddress()
@@ -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,6 +25,8 @@ import {
25
25
  getObligationAccounts,
26
26
  getObligationAccount,
27
27
  getTotalValueLocked,
28
+ getBindedObligationId,
29
+ getBindedVeScaKey,
28
30
  } from '../queries';
29
31
  import {
30
32
  ScallopQueryParams,
@@ -41,6 +43,8 @@ import {
41
43
  import { ScallopAddress } from './scallopAddress';
42
44
  import { ScallopUtils } from './scallopUtils';
43
45
  import { ScallopIndexer } from './scallopIndexer';
46
+ import { ScallopCache } from './scallopCache';
47
+ import { DEFAULT_CACHE_OPTIONS } from 'src/constants/cache';
44
48
 
45
49
  /**
46
50
  * @description
@@ -61,6 +65,7 @@ export class ScallopQuery {
61
65
  public address: ScallopAddress;
62
66
  public utils: ScallopUtils;
63
67
  public indexer: ScallopIndexer;
68
+ public cache: ScallopCache;
64
69
 
65
70
  public constructor(
66
71
  params: ScallopQueryParams,
@@ -68,20 +73,26 @@ export class ScallopQuery {
68
73
  ) {
69
74
  this.params = params;
70
75
  this.suiKit = instance?.suiKit ?? new SuiKit(params);
76
+ this.cache =
77
+ instance?.cache ?? new ScallopCache(DEFAULT_CACHE_OPTIONS, this.suiKit);
71
78
  this.address =
72
79
  instance?.address ??
73
- new ScallopAddress({
74
- id: params?.addressesId || ADDRESSES_ID,
75
- network: params?.networkType,
76
- });
80
+ new ScallopAddress(
81
+ {
82
+ id: params?.addressesId || ADDRESSES_ID,
83
+ network: params?.networkType,
84
+ },
85
+ this.cache
86
+ );
77
87
  this.utils =
78
88
  instance?.utils ??
79
89
  new ScallopUtils(this.params, {
80
90
  suiKit: this.suiKit,
81
91
  address: this.address,
92
+ cache: this.cache,
82
93
  query: this,
83
94
  });
84
- this.indexer = new ScallopIndexer();
95
+ this.indexer = new ScallopIndexer(this.params, { cache: this.cache });
85
96
  }
86
97
 
87
98
  /**
@@ -512,4 +523,22 @@ export class ScallopQuery {
512
523
  public async getTvl(indexer: boolean = false) {
513
524
  return await getTotalValueLocked(this, indexer);
514
525
  }
526
+
527
+ /**
528
+ * Get binded obligationId from a veScaKey if it exists.
529
+ * @param veScaKey
530
+ * @returns obligationId
531
+ */
532
+ public async getBindedObligationId(veScaKey: string) {
533
+ return await getBindedObligationId(this, veScaKey);
534
+ }
535
+
536
+ /**
537
+ * Get binded veSCA key from a obligationId if it exists.
538
+ * @param obligationId
539
+ * @returns veScaKey
540
+ */
541
+ public async getBindedVeScaKey(obligationId: string) {
542
+ return await getBindedVeScaKey(this, obligationId);
543
+ }
515
544
  }