@scallop-io/sui-scallop-sdk 1.4.27 → 1.5.0

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.
@@ -12,3 +12,4 @@ export * from './vescaQuery';
12
12
  export * from './borrowLimitQuery';
13
13
  export * from './poolAddressesQuery';
14
14
  export * from './objectsQuery';
15
+ export * from './xOracleQuery';
@@ -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
@@ -107,7 +107,7 @@ export const parseDataFromPythPriceFeed = (
107
107
  publishTime: Number(feed.price.publishTime) * 10 ** 3,
108
108
  };
109
109
  } else {
110
- throw new Error('Invalid feed id');
110
+ throw new Error(`Invalid feed id: ${feed.id}`);
111
111
  }
112
112
  };
113
113