@scallop-io/sui-scallop-sdk 1.4.8 → 1.4.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 (36) hide show
  1. package/dist/constants/common.d.ts +6 -6
  2. package/dist/constants/enum.d.ts +2 -2
  3. package/dist/constants/poolAddress.d.ts +1 -1
  4. package/dist/constants/queryKeys.d.ts +2 -4
  5. package/dist/index.js +165 -159
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +165 -159
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/models/scallopCache.d.ts +1 -1
  10. package/dist/models/scallopQuery.d.ts +13 -7
  11. package/dist/models/scallopUtils.d.ts +2 -2
  12. package/dist/queries/borrowIncentiveQuery.d.ts +2 -0
  13. package/dist/queries/coreQuery.d.ts +1 -0
  14. package/dist/queries/objectsQuery.d.ts +1 -2
  15. package/dist/queries/poolAddressesQuery.d.ts +2 -2
  16. package/dist/queries/portfolioQuery.d.ts +4 -3
  17. package/dist/queries/priceQuery.d.ts +2 -0
  18. package/dist/queries/sCoinQuery.d.ts +1 -1
  19. package/package.json +1 -1
  20. package/src/constants/coinGecko.ts +1 -0
  21. package/src/constants/common.ts +4 -1
  22. package/src/constants/enum.ts +38 -20
  23. package/src/constants/poolAddress.ts +47 -18
  24. package/src/constants/pyth.ts +1 -0
  25. package/src/constants/queryKeys.ts +2 -8
  26. package/src/constants/testAddress.ts +3 -0
  27. package/src/models/scallop.ts +1 -0
  28. package/src/models/scallopCache.ts +70 -56
  29. package/src/queries/borrowIncentiveQuery.ts +4 -12
  30. package/src/queries/coreQuery.ts +7 -27
  31. package/src/queries/loyaltyProgramQuery.ts +1 -3
  32. package/src/queries/objectsQuery.ts +1 -3
  33. package/src/queries/poolAddressesQuery.ts +7 -10
  34. package/src/queries/priceQuery.ts +2 -7
  35. package/src/queries/spoolQuery.ts +3 -11
  36. package/src/queries/vescaQuery.ts +3 -7
@@ -37,18 +37,12 @@ export const queryKeys = {
37
37
  getObject: (objectId?: string, options?: SuiObjectDataOptions) => [
38
38
  'rpc',
39
39
  'getObject',
40
- { options, objectId },
40
+ { objectId, options },
41
41
  ],
42
- getObjects: (
43
- objectIds?: string[],
44
- walletAddress?: string,
45
- options?: SuiObjectDataOptions
46
- ) => [
42
+ getObjects: (objectIds?: string[]) => [
47
43
  'rpc',
48
44
  'getObjects',
49
45
  {
50
- walletAddress,
51
- options,
52
46
  objectIds: JSON.stringify(objectIds ?? undefined),
53
47
  },
54
48
  ],
@@ -236,6 +236,9 @@ export const TEST_ADDRESSES: AddressesInterface = {
236
236
  },
237
237
  },
238
238
  },
239
+ // @TODO: add test address
240
+ // @ts-ignore
241
+ sbusdt: {},
239
242
  fdusd: {
240
243
  id: '0xf16e6b723f242ec745dfd7634ad072c42d5c1d9ac9d62a39c381303eaa57693a',
241
244
  metaData:
@@ -163,6 +163,7 @@ export class Scallop {
163
163
  },
164
164
  {
165
165
  address: this.address,
166
+ suiKit: this.suiKit,
166
167
  }
167
168
  );
168
169
 
@@ -33,6 +33,29 @@ type QueryInspectTxnParams = {
33
33
  const DEFAULT_TOKENS_PER_INTERVAL = 10;
34
34
  const DEFAULT_INTERVAL_IN_MS = 250;
35
35
 
36
+ const deepMergeObject = <T>(curr: T, update: T): T => {
37
+ const result = { ...curr }; // Clone the current object to avoid mutation
38
+
39
+ for (const key in update) {
40
+ if (
41
+ update[key] &&
42
+ typeof update[key] === 'object' &&
43
+ !Array.isArray(update[key])
44
+ ) {
45
+ // If the value is an object, recurse
46
+ result[key] = deepMergeObject(
47
+ curr[key] || ({} as T[Extract<keyof T, string>]),
48
+ update[key]
49
+ );
50
+ } else {
51
+ // Otherwise, directly assign the value
52
+ result[key] = update[key];
53
+ }
54
+ }
55
+
56
+ return result;
57
+ };
58
+
36
59
  /**
37
60
  * @description
38
61
  * It provides caching for moveCall, RPC Request, and API Request.
@@ -254,6 +277,7 @@ export class ScallopCache {
254
277
  ...options,
255
278
  showOwner: true,
256
279
  showContent: true,
280
+ showType: true,
257
281
  };
258
282
  return this.queryClient.fetchQuery({
259
283
  retry: this.retryFn,
@@ -276,42 +300,38 @@ export class ScallopCache {
276
300
  * @param objectIds
277
301
  * @returns Promise<SuiObjectData[]>
278
302
  */
279
- public async queryGetObjects(
280
- objectIds: string[],
281
- options: SuiObjectDataOptions = {
282
- showContent: true,
283
- }
284
- ): Promise<SuiObjectData[]> {
303
+ public async queryGetObjects(objectIds: string[]): Promise<SuiObjectData[]> {
285
304
  if (objectIds.length === 0) return [];
286
- // objectIds.sort();
305
+ const options: SuiObjectDataOptions = {
306
+ showContent: true,
307
+ showOwner: true,
308
+ showType: true,
309
+ };
287
310
 
288
311
  return this.queryClient.fetchQuery({
289
312
  retry: this.retryFn,
290
313
  retryDelay: 1000,
291
- queryKey: queryKeys.rpc.getObjects(
292
- objectIds,
293
- this.walletAddress,
294
- options
295
- ),
314
+ queryKey: queryKeys.rpc.getObjects(objectIds),
296
315
  queryFn: async () => {
297
316
  const results = await this.callWithRateLimit(
298
317
  async () => await this.suiKit.getObjects(objectIds, options)
299
318
  );
300
319
  if (results) {
301
320
  results.forEach((result) => {
302
- this.queryClient.setQueriesData(
303
- {
321
+ // fetch previous data
322
+ const queryKey = queryKeys.rpc.getObject(result.objectId);
323
+ const prevDatas =
324
+ this.queryClient.getQueriesData<SuiObjectResponse>({
304
325
  exact: false,
305
- queryKey: queryKeys.rpc.getObject(result.objectId, options),
306
- },
307
- {
308
- data: result,
309
- error: null,
310
- },
311
- {
312
- updatedAt: Date.now(),
313
- }
314
- );
326
+ queryKey,
327
+ });
328
+ prevDatas.forEach(([key, prevData]) => {
329
+ this.queryClient.setQueryData(
330
+ key,
331
+ deepMergeObject(prevData, { data: result, error: null }),
332
+ { updatedAt: Date.now() }
333
+ );
334
+ });
315
335
  });
316
336
  }
317
337
  return results;
@@ -325,7 +345,7 @@ export class ScallopCache {
325
345
  * @returns Promise<PaginatedObjectsResponse>
326
346
  */
327
347
  public async queryGetOwnedObjects(input: GetOwnedObjectsParams) {
328
- // TODO: This query need its own separate rate limiter (as owned objects can theoretically be infinite), need a better way to handle this
348
+ // @TODO: This query need its own separate rate limiter (as owned objects can theoretically be infinite), need a better way to handle this
329
349
  return this.queryClient.fetchQuery({
330
350
  retry: this.retryFn,
331
351
  retryDelay: 1000,
@@ -343,22 +363,20 @@ export class ScallopCache {
343
363
  NonNullable<{ data: SuiObjectData }> => !!result.data
344
364
  )
345
365
  .forEach((result) => {
346
- this.queryClient.setQueriesData(
347
- {
366
+ // fetch previous data
367
+ const queryKey = queryKeys.rpc.getObject(result.data.objectId);
368
+ const prevDatas =
369
+ this.queryClient.getQueriesData<SuiObjectResponse>({
348
370
  exact: false,
349
- queryKey: queryKeys.rpc.getObject(
350
- result.data.objectId,
351
- input.options ?? {}
352
- ),
353
- },
354
- {
355
- data: result.data,
356
- error: null,
357
- },
358
- {
359
- updatedAt: Date.now(),
360
- }
361
- );
371
+ queryKey,
372
+ });
373
+ prevDatas.forEach(([key, prevData]) => {
374
+ this.queryClient.setQueryData(
375
+ key,
376
+ deepMergeObject(prevData, { data: result.data, error: null }),
377
+ { updatedAt: Date.now() }
378
+ );
379
+ });
362
380
  });
363
381
  }
364
382
  return results;
@@ -393,22 +411,18 @@ export class ScallopCache {
393
411
  this.client.getDynamicFieldObject(input)
394
412
  );
395
413
  if (result?.data) {
396
- this.queryClient.setQueriesData(
397
- {
398
- exact: false,
399
- queryKey: queryKeys.rpc.getObject(result?.data.objectId, {
400
- showContent: true,
401
- showOwner: true,
402
- }),
403
- },
404
- {
405
- data: result.data,
406
- error: null,
407
- },
408
- {
409
- updatedAt: Date.now(),
410
- }
411
- );
414
+ const queryKey = queryKeys.rpc.getObject(result.data.objectId);
415
+ const prevDatas = this.queryClient.getQueriesData<SuiObjectResponse>({
416
+ exact: false,
417
+ queryKey,
418
+ });
419
+ prevDatas.forEach(([key, prevData]) => {
420
+ this.queryClient.setQueryData(
421
+ key,
422
+ deepMergeObject(prevData, { data: result.data, error: null }),
423
+ { updatedAt: Date.now() }
424
+ );
425
+ });
412
426
  }
413
427
  return result;
414
428
  },
@@ -246,12 +246,8 @@ export const getBindedObligationId = async (
246
246
  const veScaObjId = address.get('vesca.object');
247
247
 
248
248
  // get incentive pools
249
- const incentivePoolsResponse = await address.cache.queryGetObject(
250
- incentivePoolsId,
251
- {
252
- showContent: true,
253
- }
254
- );
249
+ const incentivePoolsResponse =
250
+ await address.cache.queryGetObject(incentivePoolsId);
255
251
 
256
252
  if (incentivePoolsResponse?.data?.content?.dataType !== 'moveObject')
257
253
  return null;
@@ -294,12 +290,8 @@ export const getBindedVeScaKey = async (
294
290
  const corePkg = address.get('core.object');
295
291
 
296
292
  // get IncentiveAccounts object
297
- const incentiveAccountsObject = await address.cache.queryGetObject(
298
- incentiveAccountsId,
299
- {
300
- showContent: true,
301
- }
302
- );
293
+ const incentiveAccountsObject =
294
+ await address.cache.queryGetObject(incentiveAccountsId);
303
295
  if (incentiveAccountsObject?.data?.content?.dataType !== 'moveObject')
304
296
  return null;
305
297
  const incentiveAccountsTableId = (
@@ -721,9 +721,7 @@ export const getMarketCollaterals = async (
721
721
  return marketCollaterals;
722
722
  }
723
723
 
724
- const marketObjectResponse = await query.cache.queryGetObject(marketId, {
725
- showContent: true,
726
- });
724
+ const marketObjectResponse = await query.cache.queryGetObject(marketId);
727
725
  await Promise.allSettled(
728
726
  collateralCoinNames.map(async (collateralCoinName) => {
729
727
  const marketCollateral = await getMarketCollateral(
@@ -781,12 +779,7 @@ export const getMarketCollateral = async (
781
779
 
782
780
  const marketId = query.address.get('core.market');
783
781
  marketObject =
784
- marketObject ||
785
- (
786
- await query.cache.queryGetObject(marketId, {
787
- showContent: true,
788
- })
789
- )?.data;
782
+ marketObject || (await query.cache.queryGetObject(marketId))?.data;
790
783
 
791
784
  if (!(marketObject && marketObject.content?.dataType === 'moveObject'))
792
785
  throw new Error(`Failed to fetch marketObject`);
@@ -949,10 +942,7 @@ export const getObligations = async (
949
942
  (content): content is SuiParsedData & { dataType: 'moveObject' } =>
950
943
  content?.dataType === 'moveObject'
951
944
  )
952
- .map((content) => (content.fields as any).ownership.fields.of),
953
- {
954
- showContent: true,
955
- }
945
+ .map((content) => (content.fields as any).ownership.fields.of)
956
946
  );
957
947
 
958
948
  await Promise.allSettled(
@@ -987,11 +977,7 @@ export const getObligationLocked = async (
987
977
  ) => {
988
978
  const obligationObjectData =
989
979
  typeof obligation === 'string'
990
- ? (
991
- await cache.queryGetObject(obligation, {
992
- showContent: true,
993
- })
994
- )?.data
980
+ ? (await cache.queryGetObject(obligation))?.data
995
981
  : obligation;
996
982
  let obligationLocked = false;
997
983
  if (
@@ -1179,16 +1165,12 @@ export const getFlashLoanFees = async (
1179
1165
  })
1180
1166
  .filter((t) => !!t) as string[];
1181
1167
 
1182
- const flashloanFeeObjects = await query.cache.queryGetObjects(objIds, {
1183
- showContent: true,
1184
- });
1168
+ const flashloanFeeObjects = await query.cache.queryGetObjects(objIds);
1185
1169
 
1186
1170
  if (missingAssets.length > 0) {
1187
1171
  // get market object
1188
1172
  const marketObjectId = query.address.get('core.market');
1189
- const marketObjectRes = await query.cache.queryGetObject(marketObjectId, {
1190
- showContent: true,
1191
- });
1173
+ const marketObjectRes = await query.cache.queryGetObject(marketObjectId);
1192
1174
  if (marketObjectRes?.data?.content?.dataType !== 'moveObject')
1193
1175
  throw new Error('Failed to get market object');
1194
1176
 
@@ -1215,9 +1197,7 @@ export const getFlashLoanFees = async (
1215
1197
  .map((field) => field.objectId) ?? [];
1216
1198
 
1217
1199
  flashloanFeeObjects.push(
1218
- ...(await query.cache.queryGetObjects(dynamicFieldObjectIds, {
1219
- showContent: true,
1220
- }))
1200
+ ...(await query.cache.queryGetObjects(dynamicFieldObjectIds))
1221
1201
  );
1222
1202
  }
1223
1203
 
@@ -36,9 +36,7 @@ export const getLoyaltyProgramInformations = async (
36
36
  const rewardPool = query.address.get('loyaltyProgram.rewardPool');
37
37
 
38
38
  // get fields from rewardPool object
39
- const rewardPoolObject = await query.cache.queryGetObject(rewardPool, {
40
- showContent: true,
41
- });
39
+ const rewardPoolObject = await query.cache.queryGetObject(rewardPool);
42
40
 
43
41
  if (rewardPoolObject?.data?.content?.dataType !== 'moveObject') return null;
44
42
  const rewardPoolFields = rewardPoolObject.data.content.fields;
@@ -1,18 +1,16 @@
1
- import { SuiObjectDataOptions } from '@mysten/sui/dist/cjs/client';
2
1
  import { ScallopCache } from 'src/models/scallopCache';
3
2
  import { partitionArray } from 'src/utils';
4
3
 
5
4
  export const queryMultipleObjects = async (
6
5
  cache: ScallopCache,
7
6
  objectIds: string[],
8
- options?: SuiObjectDataOptions,
9
7
  partitionSize = 50
10
8
  ) => {
11
9
  const objectIdsPartition = partitionArray(objectIds, partitionSize);
12
10
 
13
11
  const objects = [];
14
12
  for (const objectIds of objectIdsPartition) {
15
- const result = await cache.queryGetObjects(objectIds, options);
13
+ const result = await cache.queryGetObjects(objectIds);
16
14
  objects.push(...result);
17
15
  }
18
16
 
@@ -20,7 +20,7 @@ export const getAllAddresses = async (query: ScallopQuery) => {
20
20
  supplyLimitKey?: string;
21
21
  borrowLimitKey?: string;
22
22
  isolatedAssetKey?: string;
23
- coinDecimalId?: string;
23
+ coinMetadataId?: string;
24
24
  borrowIncentivePoolId?: string;
25
25
  coinType?: string;
26
26
  }
@@ -28,11 +28,7 @@ export const getAllAddresses = async (query: ScallopQuery) => {
28
28
  > = {};
29
29
 
30
30
  const marketId = query.address.get('core.market');
31
- const marketObject = (
32
- await query.cache.queryGetObject(marketId, {
33
- showContent: true,
34
- })
35
- )?.data;
31
+ const marketObject = (await query.cache.queryGetObject(marketId))?.data;
36
32
 
37
33
  if (!(marketObject && marketObject.content?.dataType === 'moveObject'))
38
34
  throw new Error(`Failed to fetch marketObject`);
@@ -80,7 +76,8 @@ export const getAllAddresses = async (query: ScallopQuery) => {
80
76
  },
81
77
  })
82
78
  )?.data?.objectId;
83
- } catch (_e) {
79
+ } catch (e: any) {
80
+ console.error(e.message);
84
81
  return undefined;
85
82
  }
86
83
  };
@@ -123,7 +120,7 @@ export const getAllAddresses = async (query: ScallopQuery) => {
123
120
  // @ts-ignore
124
121
  `scoin.coins.s${coinName}.treasury`
125
122
  );
126
- const coinDecimalId = query.address.get(
123
+ const coinMetadataId = query.address.get(
127
124
  `core.coins.${coinName}.metaData`
128
125
  );
129
126
  results[coinName as SupportPoolCoins] = {
@@ -140,11 +137,11 @@ export const getAllAddresses = async (query: ScallopQuery) => {
140
137
  spoolReward: rewardPool,
141
138
  sCoinTreasury,
142
139
  sCoinType,
143
- coinDecimalId,
140
+ coinMetadataId,
144
141
  coinType: `0x${coinType}`,
145
142
  };
146
143
 
147
- await new Promise((resolve) => setTimeout(resolve, 200));
144
+ await new Promise((resolve) => setTimeout(resolve, 500));
148
145
  })
149
146
  );
150
147
 
@@ -31,11 +31,7 @@ export const getPythPrice = async (
31
31
  );
32
32
  priceFeedObject =
33
33
  priceFeedObject ||
34
- (
35
- await address.cache.queryGetObject(pythFeedObjectId, {
36
- showContent: true,
37
- })
38
- )?.data;
34
+ (await address.cache.queryGetObject(pythFeedObjectId))?.data;
39
35
 
40
36
  if (priceFeedObject) {
41
37
  const priceFeedPoolObject = priceFeedObject;
@@ -99,8 +95,7 @@ export const getPythPrices = async (
99
95
 
100
96
  // Fetch multiple objects at once to save rpc calls
101
97
  const priceFeedObjects = await address.cache.queryGetObjects(
102
- Object.keys(pythPriceFeedIds),
103
- { showContent: true }
98
+ Object.keys(pythPriceFeedIds)
104
99
  );
105
100
 
106
101
  const assetToPriceFeedMapping = priceFeedObjects.reduce(
@@ -453,10 +453,7 @@ export const getStakePool = async (
453
453
  ) => {
454
454
  const poolId = utils.address.get(`spool.pools.${marketCoinName}.id`);
455
455
  let stakePool: StakePool | undefined = undefined;
456
- const stakePoolObjectResponse = await utils.cache.queryGetObject(poolId, {
457
- showContent: true,
458
- showType: true,
459
- });
456
+ const stakePoolObjectResponse = await utils.cache.queryGetObject(poolId);
460
457
  if (stakePoolObjectResponse?.data) {
461
458
  const stakePoolObject = stakePoolObjectResponse.data;
462
459
  const id = stakePoolObject.objectId;
@@ -515,13 +512,8 @@ export const getStakeRewardPool = async (
515
512
  `spool.pools.${marketCoinName}.rewardPoolId`
516
513
  );
517
514
  let stakeRewardPool: StakeRewardPool | undefined = undefined;
518
- const stakeRewardPoolObjectResponse = await utils.cache.queryGetObject(
519
- poolId,
520
- {
521
- showContent: true,
522
- showType: true,
523
- }
524
- );
515
+ const stakeRewardPoolObjectResponse =
516
+ await utils.cache.queryGetObject(poolId);
525
517
 
526
518
  if (stakeRewardPoolObjectResponse?.data) {
527
519
  const stakeRewardPoolObject = stakeRewardPoolObjectResponse.data;
@@ -195,8 +195,7 @@ const getTotalVeScaTreasuryAmount = async (
195
195
  const resolvedRefreshArgs = await Promise.all(
196
196
  refreshArgs.map(async (arg) => {
197
197
  if (typeof arg === 'string') {
198
- return (await utils.cache.queryGetObject(arg, { showContent: true }))
199
- ?.data;
198
+ return (await utils.cache.queryGetObject(arg))?.data;
200
199
  }
201
200
  return arg;
202
201
  })
@@ -205,8 +204,7 @@ const getTotalVeScaTreasuryAmount = async (
205
204
  const resolvedVeScaAmountArgs = await Promise.all(
206
205
  veScaAmountArgs.map(async (arg) => {
207
206
  if (typeof arg === 'string') {
208
- return (await utils.cache.queryGetObject(arg, { showContent: true }))
209
- ?.data;
207
+ return (await utils.cache.queryGetObject(arg))?.data;
210
208
  }
211
209
  return arg;
212
210
  })
@@ -254,9 +252,7 @@ export const getVeScaTreasuryInfo = async (
254
252
  utils: ScallopUtils
255
253
  ): Promise<VeScaTreasuryInfo | null> => {
256
254
  const veScaTreasuryId = utils.address.get('vesca.treasury');
257
- const veScaTreasury = await utils.cache.queryGetObject(veScaTreasuryId, {
258
- showContent: true,
259
- });
255
+ const veScaTreasury = await utils.cache.queryGetObject(veScaTreasuryId);
260
256
 
261
257
  if (!veScaTreasury || veScaTreasury.data?.content?.dataType !== 'moveObject')
262
258
  return null;