@scallop-io/sui-scallop-sdk 1.3.0-alpha.3 → 1.3.0-alpha.5

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.
@@ -0,0 +1,105 @@
1
+ import { DynamicFieldInfo, DynamicFieldName } from '@mysten/sui/client';
2
+ import { ScallopAddress, ScallopUtils } from 'src/models';
3
+ import { SupportPoolCoins } from 'src/types';
4
+ import { z as zod } from 'zod';
5
+
6
+ const isolatedAssetZod = zod.object({
7
+ dataType: zod.string(),
8
+ type: zod.string(),
9
+ hasPublicTransfer: zod.boolean(),
10
+ fields: zod.object({
11
+ id: zod.object({
12
+ id: zod.string(),
13
+ }),
14
+ name: zod.object({
15
+ type: zod.string(),
16
+ }),
17
+ value: zod.boolean(),
18
+ }),
19
+ });
20
+
21
+ const ISOLATED_ASSET_KEY =
22
+ '0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::IsolatedAssetKey';
23
+
24
+ /**
25
+ * Return list of isolated assets coin types
26
+ * @param utils ScallopUtils
27
+ * @returns list of isolated assets coin types
28
+ */
29
+ export const getIsolatedAssets = async (
30
+ address: ScallopAddress
31
+ ): Promise<string[]> => {
32
+ const marketObject = address.get('core.market');
33
+ const isolatedAssets: string[] = [];
34
+ if (!marketObject) return isolatedAssets;
35
+
36
+ let hasNextPage = false;
37
+ let nextCursor: string | null | undefined = null;
38
+
39
+ const isIsolatedDynamicField = (
40
+ dynamicField: DynamicFieldInfo
41
+ ): dynamicField is DynamicFieldInfo & {
42
+ name: DynamicFieldName & { value: { type: { name: string } } };
43
+ } => {
44
+ return dynamicField.name.type === ISOLATED_ASSET_KEY;
45
+ };
46
+
47
+ do {
48
+ const response = await address.cache.queryGetDynamicFields({
49
+ parentId: marketObject,
50
+ cursor: nextCursor,
51
+ limit: 10,
52
+ });
53
+ if (!response) break;
54
+
55
+ const isolatedAssetCoinTypes = response.data
56
+ .filter(isIsolatedDynamicField)
57
+ .map(({ name }) => `0x${name.value.type.name}`);
58
+ isolatedAssets.push(...isolatedAssetCoinTypes);
59
+
60
+ if (response && response.hasNextPage && response.nextCursor) {
61
+ hasNextPage = true;
62
+ nextCursor = response.nextCursor;
63
+ } else {
64
+ hasNextPage = false;
65
+ }
66
+ } while (hasNextPage);
67
+ return isolatedAssets;
68
+ };
69
+
70
+ /**
71
+ * Check if the coin type is an isolated asset
72
+ * @param coinName coin name
73
+ * @returns true if the coin type is an isolated asset
74
+ */
75
+ export const isIsolatedAsset = async (
76
+ utils: ScallopUtils,
77
+ coinName: SupportPoolCoins
78
+ ): Promise<boolean> => {
79
+ const marketObject = utils.address.get('core.market');
80
+
81
+ // check if the coin type is in the list
82
+ const cachedData = utils.address.cache.queryClient.getQueryData<string[]>([
83
+ 'getDynamicFields',
84
+ marketObject,
85
+ ]);
86
+ if (cachedData) {
87
+ const coinType = utils.parseCoinType(coinName);
88
+ return cachedData.includes(coinType);
89
+ }
90
+
91
+ // fetch dynamic field object
92
+ const coinType = utils.parseCoinType(coinName).slice(2);
93
+
94
+ const object = await utils.cache.queryGetDynamicFieldObject({
95
+ parentId: marketObject,
96
+ name: {
97
+ type: ISOLATED_ASSET_KEY,
98
+ value: coinType,
99
+ },
100
+ });
101
+
102
+ const parsedData = isolatedAssetZod.safeParse(object?.data?.content);
103
+ if (!parsedData.success) return false;
104
+ return parsedData.data.fields.value;
105
+ };
@@ -269,6 +269,7 @@ export const getLending = async (
269
269
  availableUnstakeCoin: availableUnstakeCoin.toNumber(),
270
270
  availableClaimAmount: availableClaimAmount.toNumber(),
271
271
  availableClaimCoin: availableClaimCoin.toNumber(),
272
+ isIsolated: marketPool ? marketPool.isIsolated : false,
272
273
  };
273
274
 
274
275
  return lending;
@@ -17,7 +17,7 @@ const supplyLimitZod = zod.object({
17
17
  }),
18
18
  });
19
19
 
20
- const SUPPLY_LIMIT_TYPE =
20
+ const SUPPLY_LIMIT_KEY =
21
21
  '0x6e641f0dca8aedab3101d047e96439178f16301bf0b57fe8745086ff1195eb3e::market_dynamic_keys::SupplyLimitKey';
22
22
 
23
23
  /**
@@ -37,7 +37,7 @@ export const getSupplyLimit = async (
37
37
  const object = await utils.cache.queryGetDynamicFieldObject({
38
38
  parentId: marketObject,
39
39
  name: {
40
- type: SUPPLY_LIMIT_TYPE,
40
+ type: SUPPLY_LIMIT_KEY,
41
41
  value: poolCoinType,
42
42
  },
43
43
  });
@@ -10,6 +10,7 @@ import { MAX_LOCK_DURATION } from 'src/constants';
10
10
  import { SUI_CLOCK_OBJECT_ID, SuiTxBlock } from '@scallop-io/sui-kit';
11
11
  import { bcs } from '@mysten/sui/bcs';
12
12
  import { z as zod } from 'zod';
13
+ import { queryKeys } from 'src/constants';
13
14
  import assert from 'assert';
14
15
  /**
15
16
  * Query all owned veSca key.
@@ -226,10 +227,10 @@ const getTotalVeScaTreasuryAmount = async (
226
227
 
227
228
  // return result
228
229
  const res = await utils.cache.queryClient.fetchQuery<DevInspectResults>({
229
- queryKey: [
230
- 'getTotalVeScaTreasuryAmount',
231
- JSON.stringify([...refreshArgs, ...veScaAmountArgs]),
232
- ],
230
+ queryKey: queryKeys.rpc.getTotalVeScaTreasuryAmount(
231
+ refreshArgs,
232
+ veScaAmountArgs
233
+ ),
233
234
  queryFn: async () => {
234
235
  return await utils.suiKit.inspectTxn(txBytes);
235
236
  },
@@ -130,6 +130,7 @@ export type MarketPool = {
130
130
  coinDecimal: number;
131
131
  coinPrice: number;
132
132
  maxSupplyCoin: number;
133
+ isIsolated: boolean;
133
134
  } & Required<
134
135
  Pick<
135
136
  ParsedMarketPoolData,
@@ -25,6 +25,7 @@ export type Lending = Required<
25
25
  | 'coinDecimal'
26
26
  | 'coinPrice'
27
27
  | 'conversionRate'
28
+ | 'isIsolated'
28
29
  > &
29
30
  Pick<Spool, 'marketCoinPrice'>
30
31
  > & {
@@ -16,8 +16,8 @@ export async function callMethodWithIndexerFallback(
16
16
  if (indexer) {
17
17
  try {
18
18
  return await method.apply(context, args);
19
- } catch (_e) {
20
- console.warn('Indexer requests failed. Retrying without indexer..');
19
+ } catch (e: any) {
20
+ console.warn(`Indexer requests failed: ${e}. Retrying without indexer..`);
21
21
  return await method.apply(context, [...args.slice(0, -1), false]);
22
22
  }
23
23
  }
@@ -65,7 +65,7 @@ const callWithRateLimit = async <T>(
65
65
  await new Promise((resolve) => setTimeout(resolve, delay));
66
66
  return tryRequest();
67
67
  } else {
68
- console.error('An error occurred:', error);
68
+ console.error('An error occurred:', error.message);
69
69
  return null;
70
70
  }
71
71
  }
package/dist/test.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};
package/src/test.ts DELETED
@@ -1,26 +0,0 @@
1
- import { ScallopQuery } from './models';
2
-
3
- const query = new ScallopQuery({
4
- walletAddress:
5
- '0xe78704e7c188b1902dbb630dc4c3ef7f46740c8cf121e38b3438ac1daea09f2d',
6
- });
7
-
8
- const main = async () => {
9
- try {
10
- await query.init();
11
- const result = await query.suiKit.client().getObject({
12
- id: '0xaa72bd551b25715b8f9d72f226fa02526bdf2e085a86faec7184230c5209bb6e',
13
- options: {
14
- showContent: true,
15
- showType: true,
16
- },
17
- });
18
- console.dir(result.data, { depth: null });
19
- } catch (e) {
20
- console.error(e);
21
- } finally {
22
- process.exit(0);
23
- }
24
- };
25
-
26
- main();