@scallop-io/sui-scallop-sdk 1.4.14 → 1.4.15-rc.2

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 (48) hide show
  1. package/dist/constants/poolAddress.d.ts +15 -4
  2. package/dist/constants/queryKeys.d.ts +1 -2
  3. package/dist/constants/tokenBucket.d.ts +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +873 -416
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +826 -371
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/models/scallopCache.d.ts +1 -0
  10. package/dist/models/scallopQuery.d.ts +21 -17
  11. package/dist/queries/coreQuery.d.ts +18 -19
  12. package/dist/queries/index.d.ts +2 -0
  13. package/dist/queries/isolatedAssetQuery.d.ts +2 -2
  14. package/dist/queries/objectsQuery.d.ts +3 -0
  15. package/dist/queries/poolAddressesQuery.d.ts +16 -0
  16. package/dist/queries/spoolQuery.d.ts +6 -2
  17. package/dist/test.d.ts +1 -0
  18. package/dist/types/query/core.d.ts +22 -5
  19. package/dist/types/query/spool.d.ts +20 -0
  20. package/dist/types/utils.d.ts +7 -2
  21. package/dist/utils/core.d.ts +2 -0
  22. package/dist/utils/index.d.ts +2 -0
  23. package/dist/utils/util.d.ts +1 -0
  24. package/package.json +1 -1
  25. package/src/constants/poolAddress.ts +291 -29
  26. package/src/constants/queryKeys.ts +5 -5
  27. package/src/constants/tokenBucket.ts +1 -1
  28. package/src/index.ts +1 -0
  29. package/src/models/scallopCache.ts +43 -11
  30. package/src/models/scallopQuery.ts +25 -20
  31. package/src/queries/borrowIncentiveQuery.ts +1 -1
  32. package/src/queries/coreQuery.ts +378 -248
  33. package/src/queries/index.ts +2 -0
  34. package/src/queries/isolatedAssetQuery.ts +37 -31
  35. package/src/queries/objectsQuery.ts +20 -0
  36. package/src/queries/poolAddressesQuery.ts +140 -0
  37. package/src/queries/portfolioQuery.ts +14 -7
  38. package/src/queries/priceQuery.ts +3 -1
  39. package/src/queries/spoolQuery.ts +189 -122
  40. package/src/test.ts +17 -0
  41. package/src/types/query/core.ts +21 -5
  42. package/src/types/query/spool.ts +21 -0
  43. package/src/types/utils.ts +8 -3
  44. package/src/utils/core.ts +18 -0
  45. package/src/utils/index.ts +2 -0
  46. package/src/utils/query.ts +16 -2
  47. package/src/utils/tokenBucket.ts +2 -2
  48. package/src/utils/util.ts +8 -0
@@ -10,3 +10,5 @@ export * from './spoolQuery';
10
10
  export * from './supplyLimitQuery';
11
11
  export * from './vescaQuery';
12
12
  export * from './borrowLimitQuery';
13
+ export * from './poolAddressesQuery';
14
+ export * from './objectsQuery';
@@ -1,7 +1,8 @@
1
1
  import { DynamicFieldInfo, DynamicFieldName } from '@mysten/sui/client';
2
- import { ScallopAddress, ScallopUtils } from '../models';
2
+ import { ScallopQuery, ScallopUtils } from '../models';
3
3
  import { SupportPoolCoins } from '../types';
4
4
  import { z as zod } from 'zod';
5
+ import { POOL_ADDRESSES, SUPPORT_POOLS } from 'src/constants';
5
6
 
6
7
  const isolatedAssetZod = zod.object({
7
8
  dataType: zod.string(),
@@ -27,10 +28,16 @@ const isolatedAssetKeyType = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da2
27
28
  * @returns list of isolated assets coin types
28
29
  */
29
30
  export const getIsolatedAssets = async (
30
- address: ScallopAddress
31
+ query: ScallopQuery
31
32
  ): Promise<string[]> => {
33
+ if (SUPPORT_POOLS.every((t) => !!POOL_ADDRESSES[t])) {
34
+ return SUPPORT_POOLS.filter(
35
+ (t): t is typeof t & { coinType: string; isolatedAssetKey: string } =>
36
+ !!POOL_ADDRESSES[t]?.isolatedAssetKey && !!POOL_ADDRESSES[t]?.coinType
37
+ ).map((t) => POOL_ADDRESSES[t as SupportPoolCoins]?.coinType!);
38
+ }
32
39
  try {
33
- const marketObject = address.get('core.market');
40
+ const marketObject = query.address.get('core.market');
34
41
  const isolatedAssets: string[] = [];
35
42
  if (!marketObject) return isolatedAssets;
36
43
 
@@ -46,7 +53,7 @@ export const getIsolatedAssets = async (
46
53
  };
47
54
 
48
55
  do {
49
- const response = await address.cache.queryGetDynamicFields({
56
+ const response = await query.cache.queryGetDynamicFields({
50
57
  parentId: marketObject,
51
58
  cursor: nextCursor,
52
59
  limit: 10,
@@ -81,34 +88,33 @@ export const isIsolatedAsset = async (
81
88
  utils: ScallopUtils,
82
89
  coinName: SupportPoolCoins
83
90
  ): Promise<boolean> => {
84
- try {
85
- const marketObject = utils.address.get('core.market');
86
- // check if the coin type is in the list
87
- const cachedData = utils.address.cache.queryClient.getQueryData<string[]>([
88
- 'getDynamicFields',
89
- marketObject,
90
- ]);
91
- if (cachedData) {
92
- const coinType = utils.parseCoinType(coinName);
93
- return cachedData.includes(coinType);
94
- }
91
+ if (POOL_ADDRESSES[coinName]) {
92
+ return !!POOL_ADDRESSES[coinName].isolatedAssetKey;
93
+ }
94
+
95
+ const marketObject = utils.address.get('core.market');
96
+ // check if the coin type is in the list
97
+ const cachedData = utils.address.cache.queryClient.getQueryData<string[]>([
98
+ 'getDynamicFields',
99
+ marketObject,
100
+ ]);
101
+ if (cachedData) {
102
+ const coinType = utils.parseCoinType(coinName);
103
+ return cachedData.includes(coinType);
104
+ }
95
105
 
96
- // fetch dynamic field object
97
- const coinType = utils.parseCoinType(coinName).slice(2);
106
+ // fetch dynamic field object
107
+ const coinType = utils.parseCoinType(coinName).slice(2);
98
108
 
99
- const object = await utils.cache.queryGetDynamicFieldObject({
100
- parentId: marketObject,
101
- name: {
102
- type: isolatedAssetKeyType,
103
- value: coinType,
104
- },
105
- });
109
+ const object = await utils.cache.queryGetDynamicFieldObject({
110
+ parentId: marketObject,
111
+ name: {
112
+ type: isolatedAssetKeyType,
113
+ value: coinType,
114
+ },
115
+ });
106
116
 
107
- const parsedData = isolatedAssetZod.safeParse(object?.data?.content);
108
- if (!parsedData.success) return false;
109
- return parsedData.data.fields.value;
110
- } catch (e) {
111
- console.error(e);
112
- return false;
113
- }
117
+ const parsedData = isolatedAssetZod.safeParse(object?.data?.content);
118
+ if (!parsedData.success) return false;
119
+ return parsedData.data.fields.value;
114
120
  };
@@ -0,0 +1,20 @@
1
+ import { SuiObjectDataOptions } from '@mysten/sui/dist/cjs/client';
2
+ import { ScallopCache } from 'src/models/scallopCache';
3
+ import { partitionArray } from 'src/utils';
4
+
5
+ export const queryMultipleObjects = async (
6
+ cache: ScallopCache,
7
+ objectIds: string[],
8
+ options?: SuiObjectDataOptions,
9
+ partitionSize = 50
10
+ ) => {
11
+ const objectIdsPartition = partitionArray(objectIds, partitionSize);
12
+
13
+ const objects = [];
14
+ for (const objectIds of objectIdsPartition) {
15
+ const result = await cache.queryGetObjects(objectIds, options);
16
+ objects.push(...result);
17
+ }
18
+
19
+ return objects;
20
+ };
@@ -0,0 +1,140 @@
1
+ import { SUPPORT_POOLS } from 'src/constants';
2
+ import { ScallopQuery } from 'src/models';
3
+ import { OptionalKeys, SupportPoolCoins } from 'src/types';
4
+
5
+ export const getAllAddresses = async (query: ScallopQuery) => {
6
+ const results: OptionalKeys<
7
+ Record<
8
+ SupportPoolCoins,
9
+ {
10
+ lendingPoolAddress?: string;
11
+ collateralPoolAddress?: string; // not all pool has collateral
12
+ borrowDynamic?: string;
13
+ spoolReward?: string;
14
+ spool?: string;
15
+ sCoinTreasury?: string;
16
+ interestModel?: string;
17
+ riskModel?: string;
18
+ borrowFeeKey?: string;
19
+ supplyLimitKey?: string;
20
+ borrowLimitKey?: string;
21
+ isolatedAssetKey?: string;
22
+ }
23
+ >
24
+ > = {};
25
+
26
+ const marketId = query.address.get('core.market');
27
+ const marketObject = (
28
+ await query.cache.queryGetObject(marketId, {
29
+ showContent: true,
30
+ })
31
+ )?.data;
32
+
33
+ if (!(marketObject && marketObject.content?.dataType === 'moveObject'))
34
+ throw new Error(`Failed to fetch marketObject`);
35
+
36
+ const fields = marketObject.content.fields as any;
37
+
38
+ const coinTypesPairs = SUPPORT_POOLS.reduce(
39
+ (acc, pool) => {
40
+ acc.push([pool, query.utils.parseCoinType(pool).substring(2)]);
41
+ return acc;
42
+ },
43
+ [] as [SupportPoolCoins, string][]
44
+ );
45
+ const balanceSheetParentId =
46
+ fields.vault.fields.balance_sheets.fields.table.fields.id.id;
47
+
48
+ const collateralStatsParentId =
49
+ fields.collateral_stats.fields.table.fields.id.id;
50
+
51
+ const borrowDynamicsParentid =
52
+ fields.borrow_dynamics.fields.table.fields.id.id;
53
+
54
+ const interestModelParentId =
55
+ fields.interest_models.fields.table.fields.id.id;
56
+
57
+ const riskModelParentId = fields.risk_models.fields.table.fields.id.id;
58
+
59
+ const ADDRESS_TYPE = `0x1::type_name::TypeName`;
60
+ const BORROW_FEE_TYPE = `0xc38f849e81cfe46d4e4320f508ea7dda42934a329d5a6571bb4c3cb6ea63f5da::market_dynamic_keys::BorrowFeeKey`;
61
+ const SUPPLY_LIMIT_TYPE = `0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey`;
62
+ const BORROW_LIMIT_TYPE = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::BorrowLimitKey`; // prod
63
+ const ISOLATED_ASSET_KEY = `0xe7dbb371a9595631f7964b7ece42255ad0e738cc85fe6da26c7221b220f01af6::market_dynamic_keys::IsolatedAssetKey`;
64
+ const fetchDynamicObject = async (
65
+ parentId: string,
66
+ type: string,
67
+ value: any
68
+ ) => {
69
+ try {
70
+ return (
71
+ await query.cache.queryGetDynamicFieldObject({
72
+ parentId,
73
+ name: {
74
+ type,
75
+ value,
76
+ },
77
+ })
78
+ )?.data?.objectId;
79
+ } catch (_e) {
80
+ return undefined;
81
+ }
82
+ };
83
+
84
+ await Promise.all(
85
+ coinTypesPairs.map(async ([coinName, coinType]) => {
86
+ const addresses = await Promise.all([
87
+ fetchDynamicObject(balanceSheetParentId, ADDRESS_TYPE, {
88
+ name: coinType,
89
+ }),
90
+ fetchDynamicObject(collateralStatsParentId, ADDRESS_TYPE, {
91
+ name: coinType,
92
+ }),
93
+ fetchDynamicObject(borrowDynamicsParentid, ADDRESS_TYPE, {
94
+ name: coinType,
95
+ }),
96
+ fetchDynamicObject(interestModelParentId, ADDRESS_TYPE, {
97
+ name: coinType,
98
+ }),
99
+ fetchDynamicObject(riskModelParentId, ADDRESS_TYPE, {
100
+ name: coinType,
101
+ }),
102
+ fetchDynamicObject(marketId, BORROW_FEE_TYPE, coinType),
103
+ fetchDynamicObject(marketId, SUPPLY_LIMIT_TYPE, coinType),
104
+ fetchDynamicObject(marketId, BORROW_LIMIT_TYPE, coinType),
105
+ fetchDynamicObject(marketId, ISOLATED_ASSET_KEY, coinType),
106
+ ]);
107
+
108
+ const spool = query.address.get(
109
+ // @ts-ignore
110
+ `spool.pools.s${coinName}.id`
111
+ );
112
+ const rewardPool = query.address.get(
113
+ // @ts-ignore
114
+ `spool.pools.s${coinName}.rewardPoolId`
115
+ );
116
+ const sCoinTreasury = query.address.get(
117
+ // @ts-ignore
118
+ `scoin.coins.s${coinName}.treasury`
119
+ );
120
+ results[coinName as SupportPoolCoins] = {
121
+ lendingPoolAddress: addresses[0],
122
+ collateralPoolAddress: addresses[1],
123
+ borrowDynamic: addresses[2],
124
+ interestModel: addresses[3],
125
+ riskModel: addresses[4],
126
+ borrowFeeKey: addresses[5],
127
+ supplyLimitKey: addresses[6],
128
+ borrowLimitKey: addresses[7],
129
+ isolatedAssetKey: addresses[8],
130
+ spool,
131
+ spoolReward: rewardPool,
132
+ sCoinTreasury,
133
+ };
134
+
135
+ await new Promise((resolve) => setTimeout(resolve, 200));
136
+ })
137
+ );
138
+
139
+ return results;
140
+ };
@@ -51,10 +51,13 @@ export const getLendings = async (
51
51
  ) as SupportStakeMarketCoins[];
52
52
 
53
53
  const coinPrices = await query.utils.getCoinPrices();
54
- const marketPools = await query.getMarketPools(poolCoinNames, {
55
- indexer,
56
- coinPrices,
57
- });
54
+ const marketPools = (
55
+ await query.getMarketPools(poolCoinNames, {
56
+ indexer,
57
+ coinPrices,
58
+ })
59
+ ).pools;
60
+
58
61
  const spools = await query.getSpools(stakeMarketCoinNames, {
59
62
  indexer,
60
63
  marketPools,
@@ -309,7 +312,8 @@ export const getObligationAccounts = async (
309
312
  indexer: boolean = false
310
313
  ) => {
311
314
  const coinPrices = await query.utils.getCoinPrices();
312
- const market = await query.queryMarket({ indexer, coinPrices });
315
+ // const market = await query.queryMarket({ indexer, coinPrices });
316
+ const market = await query.getMarketPools(undefined, { coinPrices, indexer });
313
317
  const [coinAmounts, obligations] = await Promise.all([
314
318
  query.getCoinAmounts(undefined, ownerAddress),
315
319
  query.getObligations(ownerAddress),
@@ -357,7 +361,8 @@ export const getObligationAccount = async (
357
361
  ...SUPPORT_COLLATERALS,
358
362
  ] as SupportCollateralCoins[];
359
363
 
360
- market = market ?? (await query.queryMarket({ indexer }));
364
+ // market = market ?? (await query.queryMarket({ indexer }));
365
+ market = market ?? (await query.getMarketPools(undefined, { indexer }));
361
366
  coinPrices =
362
367
  coinPrices ?? (await query.getAllCoinPrices({ marketPools: market.pools }));
363
368
  coinAmounts =
@@ -784,7 +789,8 @@ export const getTotalValueLocked = async (
784
789
  query: ScallopQuery,
785
790
  indexer: boolean = false
786
791
  ) => {
787
- const market = await query.queryMarket({ indexer });
792
+ // const market = await query.queryMarket({ indexer });
793
+ const market = await query.getMarketPools(undefined, { indexer });
788
794
 
789
795
  let supplyValue = BigNumber(0);
790
796
  let borrowValue = BigNumber(0);
@@ -811,6 +817,7 @@ export const getTotalValueLocked = async (
811
817
  );
812
818
  }
813
819
 
820
+ // console.dir(market.collaterals, { depth: null });
814
821
  for (const collateral of Object.values(market.collaterals)) {
815
822
  supplyValue = supplyValue.plus(
816
823
  BigNumber(collateral.depositCoin).multipliedBy(collateral.coinPrice)
@@ -142,7 +142,9 @@ export const getAllCoinPrices = async (
142
142
  ) => {
143
143
  coinPrices = coinPrices ?? (await query.utils.getCoinPrices());
144
144
  marketPools =
145
- marketPools ?? (await query.getMarketPools(undefined, { coinPrices }));
145
+ marketPools ??
146
+ (await query.getMarketPools(undefined, { coinPrices })).pools;
147
+
146
148
  if (!marketPools) {
147
149
  throw new Error(`Failed to fetch market pool for getAllCoinPrices`);
148
150
  }