@scallop-io/sui-scallop-sdk 1.4.23 → 1.5.0-alpha.1

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 (43) hide show
  1. package/dist/constants/index.d.ts +1 -0
  2. package/dist/constants/xoracle.d.ts +2 -0
  3. package/dist/index.js +564 -619
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +574 -630
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/models/scallopIndexer.d.ts +1 -0
  8. package/dist/models/scallopPrice.d.ts +0 -0
  9. package/dist/models/scallopQuery.d.ts +25 -3
  10. package/dist/queries/coreQuery.d.ts +1 -1
  11. package/dist/queries/index.d.ts +1 -0
  12. package/dist/queries/poolAddressesQuery.d.ts +2 -2
  13. package/dist/queries/priceQuery.d.ts +1 -1
  14. package/dist/queries/xOracleQuery.d.ts +13 -0
  15. package/dist/types/address.d.ts +1 -0
  16. package/dist/types/constant/index.d.ts +1 -0
  17. package/dist/types/constant/xOracle.d.ts +9 -0
  18. package/package.json +1 -1
  19. package/src/builders/borrowIncentiveBuilder.ts +11 -25
  20. package/src/builders/coreBuilder.ts +15 -72
  21. package/src/builders/oracle.ts +73 -46
  22. package/src/builders/referralBuilder.ts +9 -20
  23. package/src/builders/spoolBuilder.ts +10 -38
  24. package/src/builders/vescaBuilder.ts +11 -26
  25. package/src/constants/enum.ts +10 -5
  26. package/src/constants/index.ts +1 -0
  27. package/src/constants/poolAddress.ts +343 -184
  28. package/src/constants/testAddress.ts +35 -252
  29. package/src/constants/xoracle.ts +25 -0
  30. package/src/models/scallopIndexer.ts +11 -0
  31. package/src/models/scallopPrice.ts +0 -0
  32. package/src/models/scallopQuery.ts +58 -11
  33. package/src/models/scallopUtils.ts +1 -1
  34. package/src/queries/coreQuery.ts +16 -6
  35. package/src/queries/index.ts +1 -0
  36. package/src/queries/poolAddressesQuery.ts +5 -2
  37. package/src/queries/priceQuery.ts +10 -3
  38. package/src/queries/vescaQuery.ts +8 -17
  39. package/src/queries/xOracleQuery.ts +124 -0
  40. package/src/types/address.ts +1 -0
  41. package/src/types/constant/index.ts +1 -0
  42. package/src/types/constant/xOracle.ts +11 -0
  43. package/src/utils/util.ts +1 -1
@@ -2,7 +2,10 @@ import { PYTH_FEED_IDS, SUPPORT_POOLS } from 'src/constants';
2
2
  import { ScallopQuery } from 'src/models';
3
3
  import { OptionalKeys, SupportPoolCoins } from 'src/types';
4
4
 
5
- export const getAllAddresses = async (query: ScallopQuery) => {
5
+ export const getAllAddresses = async (
6
+ query: ScallopQuery,
7
+ pools: SupportPoolCoins[] = [...SUPPORT_POOLS]
8
+ ) => {
6
9
  const results: OptionalKeys<
7
10
  Record<
8
11
  SupportPoolCoins,
@@ -44,7 +47,7 @@ export const getAllAddresses = async (query: ScallopQuery) => {
44
47
 
45
48
  const fields = marketObject.content.fields as any;
46
49
 
47
- const coinTypesPairs = SUPPORT_POOLS.reduce(
50
+ const coinTypesPairs = pools.reduce(
48
51
  (acc, pool) => {
49
52
  acc.push([pool, query.utils.parseCoinType(pool).substring(2)]);
50
53
  return acc;
@@ -133,16 +133,23 @@ export const getPythPrices = async (
133
133
  export const getAllCoinPrices = async (
134
134
  query: ScallopQuery,
135
135
  marketPools?: MarketPools,
136
- coinPrices?: CoinPrices
136
+ coinPrices?: CoinPrices,
137
+ indexer: boolean = false
137
138
  ) => {
138
- coinPrices = coinPrices ?? (await query.utils.getCoinPrices());
139
+ coinPrices =
140
+ coinPrices ??
141
+ (indexer
142
+ ? await query.getCoinPricesByIndexer()
143
+ : await query.utils.getCoinPrices());
144
+
139
145
  marketPools =
140
146
  marketPools ??
141
- (await query.getMarketPools(undefined, { coinPrices })).pools;
147
+ (await query.getMarketPools(undefined, { coinPrices, indexer })).pools;
142
148
 
143
149
  if (!marketPools) {
144
150
  throw new Error(`Failed to fetch market pool for getAllCoinPrices`);
145
151
  }
152
+
146
153
  const sCoinPrices: OptionalKeys<Record<SupportSCoin, number>> = {};
147
154
  SUPPORT_SCOIN.forEach((sCoinName) => {
148
155
  const coinName = query.utils.parseCoinName(sCoinName);
@@ -184,28 +184,19 @@ const getTotalVeScaTreasuryAmount = async (
184
184
  veScaTreasury = veScaTreasury ?? utils.address.get('vesca.treasury');
185
185
 
186
186
  const txb = new SuiTxBlock();
187
+ const clockObjectRef = txb.sharedObjectRef({
188
+ objectId: SUI_CLOCK_OBJECT_ID,
189
+ mutable: false,
190
+ initialSharedVersion: '1',
191
+ });
192
+
187
193
  // refresh query
188
194
  const refreshQueryTarget = `${veScaPkgId}::treasury::refresh`;
189
- const refreshArgs = [
190
- veScaConfig,
191
- veScaTreasury,
192
- txb.sharedObjectRef({
193
- objectId: SUI_CLOCK_OBJECT_ID,
194
- mutable: false,
195
- initialSharedVersion: '1',
196
- }),
197
- ];
195
+ const refreshArgs = [veScaConfig, veScaTreasury, clockObjectRef];
198
196
 
199
197
  // query total veSca amount
200
198
  const veScaAmountQueryTarget = `${veScaPkgId}::treasury::total_ve_sca_amount`;
201
- const veScaAmountArgs = [
202
- veScaTreasury,
203
- txb.sharedObjectRef({
204
- objectId: SUI_CLOCK_OBJECT_ID,
205
- mutable: false,
206
- initialSharedVersion: '1',
207
- }),
208
- ];
199
+ const veScaAmountArgs = [veScaTreasury, clockObjectRef];
209
200
 
210
201
  // resolve each args
211
202
  const resolvedRefreshArgs = await Promise.all(
@@ -0,0 +1,124 @@
1
+ import { SuiObjectResponse } from '@mysten/sui/client';
2
+ import { ScallopAddress, ScallopUtils } from 'src/models';
3
+ import {
4
+ SupportAssetCoins,
5
+ SupportOracleType,
6
+ xOracleRuleType,
7
+ } from 'src/types';
8
+
9
+ const PRIMARY_PRICE_UPDATE_POLICY =
10
+ '0xbcd908d0ee6d63d726e61676f3feeec3d19817f4849bbecf372dd3399f247f6b'; // @TODO: move this constant to api address
11
+ const SECONDARY_PRICE_UPDDATE_POLICY =
12
+ '0x624a6f120777bb30e718b86e836c205ef4229448052377dc3d78272a6662b2c0'; // @TODO: move this constant to api address
13
+
14
+ /**
15
+ * Query the price update policy table ids. Usually the value for these table will be constant.
16
+ * @param query
17
+ * @returns
18
+ */
19
+ export const getPriceUpdatePolicies = async (
20
+ address: ScallopAddress
21
+ ): Promise<{
22
+ primary: SuiObjectResponse | null;
23
+ secondary: SuiObjectResponse | null;
24
+ }> => {
25
+ const priceUpdatePolicyRulesKeyType = `${address.get('core.packages.xOracle.object')}::price_update_policy::PriceUpdatePolicyRulesKey`;
26
+
27
+ const [primaryPriceUpdatePolicyTable, secondaryPriceUpdatePolicyTable] =
28
+ await Promise.all([
29
+ address.cache.queryGetDynamicFieldObject({
30
+ parentId: PRIMARY_PRICE_UPDATE_POLICY,
31
+ name: {
32
+ type: priceUpdatePolicyRulesKeyType,
33
+ value: { dummy_field: false },
34
+ },
35
+ }),
36
+ address.cache.queryGetDynamicFieldObject({
37
+ parentId: SECONDARY_PRICE_UPDDATE_POLICY,
38
+ name: {
39
+ type: priceUpdatePolicyRulesKeyType,
40
+ value: { dummy_field: false },
41
+ },
42
+ }),
43
+ ]);
44
+
45
+ return {
46
+ primary: primaryPriceUpdatePolicyTable,
47
+ secondary: secondaryPriceUpdatePolicyTable,
48
+ };
49
+ };
50
+
51
+ // const PRIMARY_PRICE_UPDATE_POLICY_KEY =
52
+ // '0x856d0930acc36780eda9ea47019c979ca6ad34fd36f158b181eb7350195acc00';
53
+ // const SECONDARY_PRICE_UPDATE_POLICY_KEY =
54
+ // '0x304d226734fa5e376423c9ff0f1d49aeb1e2572d4b617d31e11e2f69865b73ed';
55
+ const PRIMARY_PRICE_UPDATE_POLICY_VECSET_ID =
56
+ '0xfb1330aa028ed6a159b742c71b5a79b3b6824cf71efa40ea82b52486ad209264';
57
+ const SECONDARY_PRICE_UPDATE_POLICY_VECSET_ID =
58
+ '0x4b827acc73f3f53f808dd73a7ee0a60ae61e84322176bece72b26467030b467c';
59
+
60
+ export const getAssetOracles = async (
61
+ utils: ScallopUtils,
62
+ ruleType: xOracleRuleType
63
+ ): Promise<Record<SupportAssetCoins, SupportOracleType[]>> => {
64
+ const ruleTypeNameToOracleType: Record<string, SupportOracleType> = {
65
+ [`${utils.address.get('core.packages.pyth.object')}::rule::Rule`]: 'pyth',
66
+ [`${utils.address.get('core.packages.supra.object')}::rule::Rule`]: 'supra',
67
+ [`${utils.address.get('core.packages.switchboard.object')}::rule::Rule`]:
68
+ 'switchboard',
69
+ };
70
+
71
+ const assetPrimaryOracles = {} as Record<
72
+ SupportAssetCoins,
73
+ SupportOracleType[]
74
+ >;
75
+ let cursor = null;
76
+ do {
77
+ const response = await utils.cache.queryGetDynamicFields({
78
+ parentId:
79
+ ruleType === 'primary'
80
+ ? PRIMARY_PRICE_UPDATE_POLICY_VECSET_ID
81
+ : SECONDARY_PRICE_UPDATE_POLICY_VECSET_ID,
82
+ cursor,
83
+ limit: 10,
84
+ });
85
+ if (!response) break;
86
+ const { data, hasNextPage, nextCursor } = response;
87
+ cursor = nextCursor;
88
+
89
+ // Group object ids
90
+ const objectIds = data.map((dynamicField) => dynamicField.objectId);
91
+
92
+ // batch fetch object responses
93
+ const objectResponses = await utils.cache.queryGetObjects(objectIds);
94
+ objectResponses.forEach((object) => {
95
+ if (!object.content || object.content.dataType !== 'moveObject') return;
96
+ const fields = object.content.fields as any;
97
+ const typeName = (
98
+ fields.name as { type: string; fields: { name: string } }
99
+ ).fields.name;
100
+
101
+ const assetName = utils.parseCoinNameFromType(`0x${typeName}`);
102
+ if (!assetName) throw new Error(`Invalid asset name: ${assetName}`);
103
+ if (!assetPrimaryOracles[assetName]) {
104
+ assetPrimaryOracles[assetName] = [];
105
+ }
106
+
107
+ const value = fields.value as {
108
+ type: string;
109
+ fields: {
110
+ contents: Array<{ type: string; fields: { name: string } }>;
111
+ };
112
+ };
113
+
114
+ value.fields.contents.forEach((content) => {
115
+ assetPrimaryOracles[assetName].push(
116
+ ruleTypeNameToOracleType[`0x${content.fields.name}`]
117
+ );
118
+ });
119
+ });
120
+ if (!hasNextPage) break;
121
+ } while (cursor);
122
+
123
+ return assetPrimaryOracles;
124
+ };
@@ -65,6 +65,7 @@ export interface AddressesInterface {
65
65
  SupportPackageType,
66
66
  {
67
67
  id: string;
68
+ object?: string;
68
69
  upgradeCap: string;
69
70
  }
70
71
  >
@@ -1,2 +1,3 @@
1
1
  export type * from './common';
2
2
  export type * from './enum';
3
+ export type * from './xOracle';
@@ -0,0 +1,11 @@
1
+ import { SupportAssetCoins, SupportOracleType } from './common';
2
+
3
+ export type xOracleRules = {
4
+ primary: SupportOracleType[];
5
+ secondary: SupportOracleType[];
6
+ };
7
+ export type xOracleRuleType = keyof xOracleRules;
8
+
9
+ export type xOracleListType = {
10
+ [key in SupportAssetCoins]: xOracleRules;
11
+ };
package/src/utils/util.ts CHANGED
@@ -102,7 +102,7 @@ export const parseDataFromPythPriceFeed = (
102
102
  publishTime: Number(feed.price.publishTime) * 10 ** 3,
103
103
  };
104
104
  } else {
105
- throw new Error('Invalid feed id');
105
+ throw new Error(`Invalid feed id: ${feed.id}`);
106
106
  }
107
107
  };
108
108