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

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.
@@ -457,4 +457,12 @@ export declare class ScallopQuery {
457
457
  * Get supply limit of supply pool
458
458
  */
459
459
  getPoolSupplyLimit(poolName: SupportPoolCoins): Promise<string | null>;
460
+ /**
461
+ * Get list of isolated assets
462
+ */
463
+ getIsolatedAssets(): Promise<string[]>;
464
+ /**
465
+ * Check if asset is an isolated asset
466
+ */
467
+ isIsolatedAsset(assetCoinName: SupportAssetCoins): Promise<boolean>;
460
468
  }
@@ -0,0 +1,14 @@
1
+ import { ScallopAddress, ScallopUtils } from 'src/models';
2
+ import { SupportPoolCoins } from 'src/types';
3
+ /**
4
+ * Return list of isolated assets coin types
5
+ * @param utils ScallopUtils
6
+ * @returns list of isolated assets coin types
7
+ */
8
+ export declare const getIsolatedAssets: (address: ScallopAddress) => Promise<string[]>;
9
+ /**
10
+ * Check if the coin type is an isolated asset
11
+ * @param coinName coin name
12
+ * @returns true if the coin type is an isolated asset
13
+ */
14
+ export declare const isIsolatedAsset: (utils: ScallopUtils, coinName: SupportPoolCoins) => Promise<boolean>;
@@ -123,6 +123,7 @@ export type MarketPool = {
123
123
  coinDecimal: number;
124
124
  coinPrice: number;
125
125
  maxSupplyCoin: number;
126
+ isIsolated: boolean;
126
127
  } & Required<Pick<ParsedMarketPoolData, 'highKink' | 'midKink' | 'reserveFactor' | 'borrowWeight' | 'borrowFee' | 'marketCoinSupplyAmount' | 'minBorrowAmount'>> & CalculatedMarketPoolData;
127
128
  export type MarketCollateral = {
128
129
  coinName: SupportCollateralCoins;
@@ -6,7 +6,7 @@ type OptionalKeys<T> = {
6
6
  };
7
7
  export type Lendings = OptionalKeys<Record<SupportPoolCoins, Lending>>;
8
8
  export type ObligationAccounts = OptionalKeys<Record<string, ObligationAccount>>;
9
- export type Lending = Required<Pick<MarketPool, 'coinName' | 'symbol' | 'coinType' | 'marketCoinType' | 'coinDecimal' | 'coinPrice' | 'conversionRate'> & Pick<Spool, 'marketCoinPrice'>> & {
9
+ export type Lending = Required<Pick<MarketPool, 'coinName' | 'symbol' | 'coinType' | 'marketCoinType' | 'coinDecimal' | 'coinPrice' | 'conversionRate' | 'isIsolated'> & Pick<Spool, 'marketCoinPrice'>> & {
10
10
  supplyApr: number;
11
11
  supplyApy: number;
12
12
  rewardApr: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scallop-io/sui-scallop-sdk",
3
- "version": "1.3.0-alpha.3",
3
+ "version": "1.3.0-alpha.4",
4
4
  "description": "Typescript sdk for interacting with Scallop contract on SUI",
5
5
  "keywords": [
6
6
  "sui",
@@ -32,7 +32,7 @@ export const OLD_BORROW_INCENTIVE_PROTOCOL_ID =
32
32
 
33
33
  export const SUPPORT_POOLS = [
34
34
  'usdc', // native USDC
35
- 'sbeth', // native ETH
35
+ 'sbeth', // sui bridge ETH
36
36
  'weth',
37
37
  'wbtc',
38
38
  'wusdc',
@@ -49,7 +49,7 @@ export const SUPPORT_POOLS = [
49
49
 
50
50
  export const SUPPORT_COLLATERALS = [
51
51
  'usdc', // native USDC
52
- 'sbeth', // native ETH
52
+ 'sbeth', // sui bridge ETH
53
53
  'weth',
54
54
  'wbtc',
55
55
  'wusdc',
@@ -63,6 +63,7 @@ import {
63
63
  import { normalizeSuiAddress } from '@mysten/sui/utils';
64
64
  import { getSupplyLimit } from 'src/queries/supplyLimit';
65
65
  import { withIndexerFallback } from 'src/utils/indexer';
66
+ import { getIsolatedAssets, isIsolatedAsset } from 'src/queries/isolatedAsset';
66
67
 
67
68
  /**
68
69
  * @description
@@ -739,4 +740,18 @@ export class ScallopQuery {
739
740
  public async getPoolSupplyLimit(poolName: SupportPoolCoins) {
740
741
  return await getSupplyLimit(this.utils, poolName);
741
742
  }
743
+
744
+ /**
745
+ * Get list of isolated assets
746
+ */
747
+ public async getIsolatedAssets() {
748
+ return await getIsolatedAssets(this.address);
749
+ }
750
+
751
+ /**
752
+ * Check if asset is an isolated asset
753
+ */
754
+ public async isIsolatedAsset(assetCoinName: SupportAssetCoins) {
755
+ return isIsolatedAsset(this.utils, assetCoinName);
756
+ }
742
757
  }
@@ -38,6 +38,7 @@ import {
38
38
  } from '../types';
39
39
  import BigNumber from 'bignumber.js';
40
40
  import { getSupplyLimit } from './supplyLimit';
41
+ import { isIsolatedAsset } from './isolatedAsset';
41
42
 
42
43
  /**
43
44
  * Query market data.
@@ -155,6 +156,7 @@ export const queryMarket = async (
155
156
  borrowFee: parsedMarketPoolData.borrowFee,
156
157
  marketCoinSupplyAmount: parsedMarketPoolData.marketCoinSupplyAmount,
157
158
  minBorrowAmount: parsedMarketPoolData.minBorrowAmount,
159
+ isIsolated: await isIsolatedAsset(query.utils, poolCoinName),
158
160
  maxSupplyCoin,
159
161
  ...calculatedMarketPoolData,
160
162
  };
@@ -492,6 +494,7 @@ export const getMarketPool = async (
492
494
  marketCoinSupplyAmount: parsedMarketPoolData.marketCoinSupplyAmount,
493
495
  minBorrowAmount: parsedMarketPoolData.minBorrowAmount,
494
496
  maxSupplyCoin,
497
+ isIsolated: await isIsolatedAsset(query.utils, poolCoinName),
495
498
  ...calculatedMarketPoolData,
496
499
  };
497
500
  }
@@ -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
  });
@@ -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
  > & {
@@ -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();