@scallop-io/sui-scallop-sdk 2.3.0-lst-x-oracle-alpha.8 → 2.3.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.
Files changed (73) hide show
  1. package/dist/index.d.mts +1811 -1750
  2. package/dist/index.d.ts +1811 -1750
  3. package/dist/index.js +49 -2
  4. package/dist/index.mjs +15 -2
  5. package/package.json +8 -5
  6. package/src/builders/borrowIncentiveBuilder.ts +4 -4
  7. package/src/builders/coreBuilder.ts +86 -59
  8. package/src/builders/index.ts +2 -2
  9. package/src/builders/loyaltyProgramBuilder.ts +2 -2
  10. package/src/builders/oracles/index.ts +365 -114
  11. package/src/builders/oracles/pyth.ts +135 -0
  12. package/src/builders/referralBuilder.ts +4 -10
  13. package/src/builders/sCoinBuilder.ts +2 -6
  14. package/src/builders/spoolBuilder.ts +2 -2
  15. package/src/builders/vescaBuilder.ts +5 -5
  16. package/src/constants/common.ts +3 -0
  17. package/src/constants/index.ts +1 -1
  18. package/src/constants/queryKeys.ts +1 -1
  19. package/src/constants/testAddress.ts +95 -183
  20. package/src/constants/xoracle.ts +2 -8
  21. package/src/index.ts +1 -1
  22. package/src/models/index.ts +1 -2
  23. package/src/models/interface.ts +6 -6
  24. package/src/models/rateLimiter.ts +55 -0
  25. package/src/models/scallop.ts +1 -1
  26. package/src/models/scallopAddress.ts +5 -25
  27. package/src/models/scallopBuilder.ts +14 -11
  28. package/src/models/scallopClient.ts +31 -14
  29. package/src/models/scallopConstants.ts +3 -3
  30. package/src/models/scallopIndexer.ts +3 -4
  31. package/src/models/scallopQuery.ts +112 -56
  32. package/src/models/scallopQueryClient.ts +1 -1
  33. package/src/models/scallopSuiKit.ts +1 -1
  34. package/src/models/scallopUtils.ts +12 -7
  35. package/src/queries/borrowIncentiveQuery.ts +4 -3
  36. package/src/queries/coreQuery.ts +114 -186
  37. package/src/queries/index.ts +3 -4
  38. package/src/queries/loyaltyProgramQuery.ts +2 -2
  39. package/src/queries/ownerQuery.ts +32 -0
  40. package/src/queries/poolAddressesQuery.ts +1 -3
  41. package/src/queries/portfolioQuery.ts +68 -16
  42. package/src/queries/priceQuery.ts +2 -3
  43. package/src/queries/sCoinQuery.ts +2 -2
  44. package/src/queries/spoolQuery.ts +57 -74
  45. package/src/queries/vescaQuery.ts +3 -3
  46. package/src/queries/xOracleQuery.ts +4 -21
  47. package/src/types/address.ts +47 -85
  48. package/src/types/builder/core.ts +40 -15
  49. package/src/types/builder/index.ts +17 -1
  50. package/src/types/constant/enum.ts +64 -0
  51. package/src/types/constant/index.ts +1 -2
  52. package/src/types/constant/xOracle.ts +7 -10
  53. package/src/types/index.ts +1 -1
  54. package/src/types/query/core.ts +3 -0
  55. package/src/types/query/index.ts +1 -0
  56. package/src/types/query/sCoin.ts +1 -0
  57. package/src/{builders/utils.ts → utils/builder.ts} +1 -1
  58. package/src/utils/core.ts +18 -0
  59. package/src/utils/index.ts +5 -0
  60. package/src/utils/indexer.ts +47 -0
  61. package/src/{queries/utils.ts → utils/query.ts} +7 -25
  62. package/src/utils/util.ts +42 -0
  63. package/src/builders/oracles/error.ts +0 -29
  64. package/src/builders/oracles/oraclePackageRegistry.ts +0 -322
  65. package/src/builders/oracles/priceFeedUpdater.ts +0 -112
  66. package/src/builders/oracles/priceUpdateRequester.ts +0 -50
  67. package/src/builders/oracles/xOracleUpdateStrategy.ts +0 -178
  68. package/src/builders/oracles/xOracleUpdater.ts +0 -160
  69. package/src/constants/api.ts +0 -2
  70. package/src/models/utils.ts +0 -97
  71. package/src/types/builder/type.ts +0 -25
  72. package/src/types/constant/package.ts +0 -16
  73. /package/src/types/{util.ts → utils.ts} +0 -0
@@ -0,0 +1,5 @@
1
+ export * from './builder';
2
+ export * from './query';
3
+ export * from './util';
4
+ export * from './indexer';
5
+ export * from './core';
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Generic wrapper for methods with indexer fallback.
3
+ *
4
+ * @param method - The method to call with fallback behavior.
5
+ * @param context - The context (`this`) of the class instance.
6
+ * @param args - The arguments to pass to the method.
7
+ * @returns The result of the method call.
8
+ */
9
+ export async function callMethodWithIndexerFallback(
10
+ method: Function,
11
+ context: any,
12
+ ...args: any[]
13
+ ) {
14
+ const lastArgs = args[args.length - 1]; // Assume last argument is always `indexer`
15
+
16
+ if (typeof lastArgs === 'object' && lastArgs.indexer) {
17
+ try {
18
+ return await method.apply(context, args);
19
+ } catch (e: any) {
20
+ console.warn(
21
+ `Indexer requests failed: ${e.message}. Retrying without indexer..`
22
+ );
23
+ return await method.apply(context, [
24
+ ...args.slice(0, -1),
25
+ {
26
+ ...lastArgs,
27
+ indexer: false,
28
+ },
29
+ ]);
30
+ }
31
+ }
32
+ return await method.apply(context, args);
33
+ }
34
+
35
+ /**
36
+ * This function creates a wrapper for methods that have an indexer parameter.
37
+ * It ensures fallback behavior if indexer fails.
38
+ *
39
+ * @param method - The method to wrap.
40
+ * @returns A function that applies indexer fallback.
41
+ */
42
+ export function withIndexerFallback(method: Function) {
43
+ return (...args: any[]) => {
44
+ // @ts-ignore
45
+ return callMethodWithIndexerFallback(method, this, ...args); // Preserve `this` with arrow function
46
+ };
47
+ }
@@ -1,7 +1,7 @@
1
1
  import BigNumber from 'bignumber.js';
2
2
  import { normalizeStructTag } from '@mysten/sui/utils';
3
- import type { ScallopUtils } from 'src/models';
4
- import {
3
+ import type { ScallopUtils } from '../models';
4
+ import type {
5
5
  OriginMarketPoolData,
6
6
  ParsedMarketPoolData,
7
7
  CalculatedMarketPoolData,
@@ -14,17 +14,16 @@ import {
14
14
  OriginSpoolRewardPoolData,
15
15
  ParsedSpoolRewardPoolData,
16
16
  CalculatedSpoolRewardPoolData,
17
- OriginBorrowIncentivePoolPointData,
18
- ParsedBorrowIncentivePoolPointData,
19
17
  OriginBorrowIncentivePoolData,
20
18
  ParsedBorrowIncentivePoolData,
19
+ OriginBorrowIncentiveAccountData,
20
+ ParsedBorrowIncentiveAccountData,
21
+ OriginBorrowIncentivePoolPointData,
22
+ ParsedBorrowIncentivePoolPointData,
21
23
  CalculatedBorrowIncentivePoolPointData,
22
24
  OriginBorrowIncentiveAccountPoolData,
23
25
  ParsedBorrowIncentiveAccountPoolData,
24
- OriginBorrowIncentiveAccountData,
25
- ParsedBorrowIncentiveAccountData,
26
- } from 'src/types/query';
27
- import { SuiObjectData } from '@mysten/sui/client';
26
+ } from '../types';
28
27
 
29
28
  /**
30
29
  * Parse origin market pool data to a more readable format.
@@ -643,20 +642,3 @@ export const estimatedFactor = (
643
642
 
644
643
  return adjustFactor;
645
644
  };
646
-
647
- export const parseObjectAs = <T>(object: SuiObjectData): T => {
648
- if (!(object && object.content && 'fields' in object.content))
649
- throw new Error(`Failed to parse object ${object}`);
650
-
651
- const fields = object.content.fields as any;
652
-
653
- if (typeof fields === 'object' && 'value' in fields) {
654
- const value = fields.value;
655
- if (typeof value === 'object' && 'fields' in value)
656
- return value.fields as T;
657
- return value as T;
658
- } else if (typeof fields === 'object') {
659
- return fields as T;
660
- }
661
- return fields as T;
662
- };
@@ -0,0 +1,42 @@
1
+ import { MAX_LOCK_DURATION } from 'src/constants';
2
+ // import { ScallopConstants } from 'src/models/scallopConstants';
3
+
4
+ /**
5
+ * Find the closest unlock round timestamp (12AM) to the given unlock at timestamp in seconds.
6
+ *
7
+ * @param unlockAtInSecondTimestamp - Unlock at in seconds timestamp to find the closest round.
8
+ * @returns Closest round (12AM) in seconds timestamp.
9
+ */
10
+ export const findClosestUnlockRound = (unlockAtInSecondTimestamp: number) => {
11
+ const unlockDate = new Date(unlockAtInSecondTimestamp * 1000);
12
+ const closestTwelveAM = new Date(unlockAtInSecondTimestamp * 1000);
13
+
14
+ closestTwelveAM.setUTCHours(0, 0, 0, 0); // Set the time to the next 12 AM UTC
15
+
16
+ // If the current time is past 12 AM, set the date to the next day
17
+ if (unlockDate.getUTCHours() >= 0) {
18
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() + 1);
19
+ }
20
+
21
+ const now = new Date().getTime();
22
+ // check if unlock period > 4 years
23
+ if (closestTwelveAM.getTime() - now > MAX_LOCK_DURATION * 1000) {
24
+ closestTwelveAM.setUTCDate(closestTwelveAM.getUTCDate() - 1);
25
+ }
26
+ return Math.floor(closestTwelveAM.getTime() / 1000);
27
+ };
28
+
29
+ export const partitionArray = <T>(array: T[], chunkSize: number) => {
30
+ const result: T[][] = [];
31
+ for (let i = 0; i < array.length; i += chunkSize) {
32
+ result.push(array.slice(i, i + chunkSize));
33
+ }
34
+ return result;
35
+ };
36
+
37
+ export const parseUrl = (url: string) => {
38
+ if (url.endsWith('/')) {
39
+ url = url.slice(0, -1);
40
+ }
41
+ return url;
42
+ };
@@ -1,29 +0,0 @@
1
- /**
2
- * Thrown when someone asks for an oracle type we haven’t onboarded yet.
3
- */
4
- class UnsupportedOracleError extends Error {
5
- constructor(oracle: string) {
6
- super(`Unsupported oracle type: ${oracle}`);
7
- this.name = 'UnsupportedOracleError';
8
- }
9
- }
10
-
11
- class UnsupportedLstUpdateError extends Error {
12
- constructor(lst: string) {
13
- super(`Unsupported LST update for: ${lst}`);
14
- this.name = 'UnsupportedLstUpdateError';
15
- }
16
- }
17
-
18
- class UnsupportedLstOracleError extends Error {
19
- constructor(lst: string, oracle: string) {
20
- super(`Unsupported LST oracle update for: ${lst} with oracle: ${oracle}`);
21
- this.name = 'UnsupportedLstOracleError';
22
- }
23
- }
24
-
25
- export {
26
- UnsupportedOracleError,
27
- UnsupportedLstUpdateError,
28
- UnsupportedLstOracleError,
29
- };
@@ -1,322 +0,0 @@
1
- import { TransactionArgument } from '@scallop-io/sui-kit';
2
- import { ScallopUtils } from 'src/models';
3
- import {
4
- AddressStringPath,
5
- BasePackage,
6
- OracleLst,
7
- OracleLstConfig,
8
- SupportOracleLst,
9
- } from 'src/types/address';
10
- import { UnsupportedOracleError } from './error';
11
- import { SupportedOracleSuiLst, SupportOracleType } from 'src/types/constant';
12
-
13
- export type XOraclePackages = {
14
- xOraclePackageId: string;
15
- xOracleId: TransactionArgument | string;
16
- };
17
-
18
- type LstPackages<
19
- T extends SupportOracleLst,
20
- U extends SupportedOracleSuiLst = SupportedOracleSuiLst,
21
- > = {
22
- [K in U]: OracleLst<T, U>[K] & BasePackage;
23
- };
24
-
25
- type MaybeWithLstPackage<T, U> = T extends SupportOracleLst
26
- ? U & { lst: LstPackages<T> }
27
- : U;
28
-
29
- type PythStaticPackages = {
30
- pythPackageId: string;
31
- pythRegistryId: TransactionArgument | string;
32
- pythStateId: TransactionArgument | string;
33
- };
34
-
35
- type PythDynamicPackages = MaybeWithLstPackage<
36
- 'pyth',
37
- {
38
- pythFeedObjectId: TransactionArgument | string;
39
- }
40
- >;
41
-
42
- export type PythPackages = PythStaticPackages & PythDynamicPackages;
43
-
44
- type SwitchboardStaticPackages = {
45
- switchboardPackageId: string;
46
- switchboardRegistryId: TransactionArgument | string;
47
- };
48
-
49
- type SwitchboardDynamicPackages = MaybeWithLstPackage<
50
- 'switchboard',
51
- {
52
- switchboardAggregatorId: TransactionArgument | string;
53
- }
54
- >;
55
-
56
- export type SwitchboardPackages = SwitchboardStaticPackages &
57
- SwitchboardDynamicPackages;
58
-
59
- export type SupraPackages = {
60
- supraPackageId: string;
61
- supraHolderId: TransactionArgument | string;
62
- supraRegistryId: TransactionArgument | string;
63
- };
64
-
65
- export type OraclePackages<T extends SupportOracleType> = T extends 'pyth'
66
- ? PythPackages
67
- : T extends 'switchboard'
68
- ? SwitchboardPackages
69
- : T extends 'supra'
70
- ? SupraPackages
71
- : never;
72
-
73
- type getLstPackagesReturnType<T> = T extends SupportOracleLst
74
- ? LstPackages<T, SupportedOracleSuiLst>
75
- : never;
76
-
77
- export interface IOraclePackageRegistry<
78
- T extends SupportOracleType = SupportOracleType,
79
- > {
80
- utils: ScallopUtils;
81
- oracleName: T;
82
- packageId: string;
83
- getLstPackages(coinName: SupportedOracleSuiLst): getLstPackagesReturnType<T>;
84
- getPackages(coinName: string): OraclePackages<T>;
85
- }
86
-
87
- interface IHasStaticPackages {
88
- getStaticPackages: Record<string, TransactionArgument | string>;
89
- }
90
-
91
- export class XOraclePackageRegistry
92
- implements
93
- Omit<
94
- IOraclePackageRegistry,
95
- 'oracleName' | 'packageId' | 'getPackages' | 'getLstPackages'
96
- >
97
- {
98
- constructor(readonly utils: ScallopUtils) {}
99
-
100
- getAddressPath(path: AddressStringPath) {
101
- return this.utils.address.get(path);
102
- }
103
-
104
- get getXOraclePackages() {
105
- return {
106
- xOraclePackageId: this.getAddressPath('core.packages.xOracle.id'),
107
- xOracleId: this.getAddressPath('core.oracles.xOracle'),
108
- };
109
- }
110
- }
111
-
112
- abstract class BasePackageRegistry implements IOraclePackageRegistry {
113
- abstract readonly oracleName: SupportOracleType;
114
-
115
- constructor(
116
- protected readonly xOraclePackageRegistry: XOraclePackageRegistry
117
- ) {}
118
-
119
- abstract getPackages(
120
- coinName: string
121
- ): OraclePackages<typeof this.oracleName>;
122
-
123
- abstract getLstPackages(
124
- coinName: SupportedOracleSuiLst
125
- ): getLstPackagesReturnType<typeof this.oracleName>;
126
-
127
- get utils() {
128
- return this.xOraclePackageRegistry.utils;
129
- }
130
-
131
- get packageId() {
132
- return this.xOraclePackageRegistry.getAddressPath(
133
- `core.packages.${this.oracleName}.id`
134
- );
135
- }
136
- }
137
-
138
- class PythPackageRegistry
139
- extends BasePackageRegistry
140
- implements IHasStaticPackages
141
- {
142
- readonly oracleName = 'pyth';
143
-
144
- constructor(
145
- protected readonly xOraclePackageRegistry: XOraclePackageRegistry
146
- ) {
147
- super(xOraclePackageRegistry);
148
- }
149
-
150
- get getStaticPackages() {
151
- return {
152
- pythPackageId: this.packageId,
153
- pythRegistryId: this.xOraclePackageRegistry.getAddressPath(
154
- 'core.oracles.pyth.registry'
155
- ),
156
- pythStateId: this.xOraclePackageRegistry.getAddressPath(
157
- 'core.oracles.pyth.state'
158
- ),
159
- };
160
- }
161
-
162
- private getLstOracleConfigPackages(coinName: SupportedOracleSuiLst) {
163
- const oracleLstConfig = this.xOraclePackageRegistry.getAddressPath(
164
- `core.oracles.pyth.lst.${coinName}`
165
- ) as OracleLstConfig<typeof coinName>[typeof coinName];
166
- return oracleLstConfig;
167
- }
168
-
169
- getLstPackages(coinName: SupportedOracleSuiLst) {
170
- const lstPackages = this.xOraclePackageRegistry.getAddressPath(
171
- `core.packages.pyth.lst.${coinName}`
172
- ) as BasePackage;
173
-
174
- // get the oracle config for the coin
175
- const oracleLstConfig = this.getLstOracleConfigPackages(coinName);
176
- return {
177
- [coinName]: {
178
- ...lstPackages,
179
- ...oracleLstConfig,
180
- },
181
- };
182
- }
183
-
184
- getPackages(coinName: string): OraclePackages<'pyth'> {
185
- const lstPackages = this.getLstPackages(coinName as SupportedOracleSuiLst);
186
-
187
- return {
188
- ...this.getStaticPackages,
189
- pythFeedObjectId: this.xOraclePackageRegistry.getAddressPath(
190
- `core.coins.${coinName}.oracle.pyth.feedObject`
191
- ),
192
- lst: lstPackages,
193
- };
194
- }
195
- }
196
-
197
- class SupraPackageRegistry extends BasePackageRegistry {
198
- readonly oracleName = 'supra';
199
-
200
- constructor(
201
- protected readonly xOraclePackageRegistry: XOraclePackageRegistry
202
- ) {
203
- super(xOraclePackageRegistry);
204
- }
205
-
206
- getLstPackages(
207
- _: SupportedOracleSuiLst
208
- ): getLstPackagesReturnType<typeof this.oracleName> {
209
- throw new Error('Method not implemented.');
210
- }
211
-
212
- getPackages(_: string) {
213
- return {
214
- supraPackageId: this.packageId,
215
- supraRegistryId: this.xOraclePackageRegistry.getAddressPath(
216
- 'core.oracles.supra.registry'
217
- ),
218
- supraHolderId: this.xOraclePackageRegistry.getAddressPath(
219
- 'core.oracles.supra.holder'
220
- ),
221
- } as OraclePackages<typeof this.oracleName>;
222
- }
223
- }
224
-
225
- class SwitchboardPackageRegistry
226
- extends BasePackageRegistry
227
- implements IHasStaticPackages
228
- {
229
- readonly oracleName = 'switchboard';
230
-
231
- constructor(
232
- protected readonly xOraclePackageRegistry: XOraclePackageRegistry
233
- ) {
234
- super(xOraclePackageRegistry);
235
- }
236
-
237
- getLstPackages(
238
- _: SupportedOracleSuiLst
239
- ): getLstPackagesReturnType<typeof this.oracleName> {
240
- throw new Error('Method not implemented.');
241
- }
242
-
243
- get getStaticPackages() {
244
- return {
245
- switchboardPackageId: this.packageId,
246
- switchboardRegistryId: this.xOraclePackageRegistry.getAddressPath(
247
- 'core.oracles.switchboard.registry'
248
- ),
249
- };
250
- }
251
-
252
- getPackages(coinName: string) {
253
- return {
254
- ...this.getStaticPackages,
255
- switchboardAggregatorId: this.xOraclePackageRegistry.getAddressPath(
256
- `core.coins.${coinName}.oracle.switchboard`
257
- ),
258
- } as OraclePackages<typeof this.oracleName>;
259
- }
260
- }
261
-
262
- export class OraclePackageRegistry {
263
- private readonly registryMap = new Map<
264
- SupportOracleType,
265
- IOraclePackageRegistry
266
- >();
267
-
268
- constructor(readonly xOraclePackageRegistry: XOraclePackageRegistry) {}
269
-
270
- /**
271
- * Register a new updater (pyth, supra, switchboard)
272
- */
273
- register(
274
- cb: (
275
- xOraclePackageRegistry: XOraclePackageRegistry
276
- ) => IOraclePackageRegistry
277
- ): void {
278
- const registry = cb(this.xOraclePackageRegistry);
279
- if (this.registryMap.has(registry.oracleName)) {
280
- throw new Error(
281
- `Updater already registered for oracleKey: ${registry.oracleName}`
282
- );
283
- }
284
- this.registryMap.set(registry.oracleName, registry);
285
- }
286
-
287
- /**
288
- * Retrieve the handler by key; throws if missing
289
- */
290
- get(oracleName: SupportOracleType): IOraclePackageRegistry {
291
- const handler = this.registryMap.get(oracleName);
292
- if (!handler) {
293
- throw new Error(
294
- `No XOraclePriceUpdater registered for oracle: ${oracleName}`
295
- );
296
- }
297
- return handler;
298
- }
299
-
300
- /**
301
- * Optional: Check if a handler exists for the given key
302
- */
303
- has(oracleName: SupportOracleType): boolean {
304
- return this.registryMap.has(oracleName);
305
- }
306
- }
307
-
308
- export const createPackageRegistry = (
309
- oracleName: SupportOracleType,
310
- xOraclePackageRegistry: XOraclePackageRegistry
311
- ): IOraclePackageRegistry => {
312
- switch (oracleName) {
313
- case 'pyth':
314
- return new PythPackageRegistry(xOraclePackageRegistry);
315
- case 'supra':
316
- return new SupraPackageRegistry(xOraclePackageRegistry);
317
- case 'switchboard':
318
- return new SwitchboardPackageRegistry(xOraclePackageRegistry);
319
- default:
320
- throw new UnsupportedOracleError(oracleName);
321
- }
322
- };
@@ -1,112 +0,0 @@
1
- import {
2
- SuiPriceServiceConnection,
3
- SuiPythClient,
4
- } from '@pythnetwork/pyth-sui-js';
5
- import { SuiTxBlock } from '@scallop-io/sui-kit';
6
- import { ScallopBuilder } from 'src/models';
7
- import { SupportOracleType } from 'src/types/constant';
8
-
9
- type PythPriceFeedUpdateOptions = {
10
- usePythPullModel: boolean;
11
- useOnChainXOracleList: boolean;
12
- pythSponsoredFeeds: string[];
13
- };
14
-
15
- type SupraPriceFeedUpdateOptions = {};
16
- type SwitchboardPriceFeedUpdateOptions = {};
17
-
18
- export type PriceFeedUpdateOptions = PythPriceFeedUpdateOptions &
19
- SupraPriceFeedUpdateOptions &
20
- SwitchboardPriceFeedUpdateOptions;
21
-
22
- export interface IPriceFeedUpdater {
23
- oracleName: SupportOracleType;
24
- updatePriceFeeds(): Promise<void>;
25
- }
26
-
27
- class PythPriceFeedUpdater implements IPriceFeedUpdater {
28
- public readonly oracleName: SupportOracleType = 'pyth';
29
-
30
- constructor(
31
- public readonly tx: SuiTxBlock,
32
- private readonly builder: ScallopBuilder,
33
- private readonly coinNames: string[],
34
- private readonly options: {
35
- usePythPullModel: boolean;
36
- useOnChainXOracleList: boolean;
37
- pythSponsoredFeeds: string[];
38
- }
39
- ) {}
40
-
41
- private filterSponsoredFeeds() {
42
- const { usePythPullModel, pythSponsoredFeeds } = this.options;
43
- const sponsoredFeedsSet = new Set(pythSponsoredFeeds);
44
-
45
- return this.coinNames.filter((coinName) => {
46
- const notUsingPullAndNotSponsored =
47
- !usePythPullModel && !sponsoredFeedsSet.has(coinName);
48
- return usePythPullModel || notUsingPullAndNotSponsored;
49
- });
50
- }
51
-
52
- async updatePriceFeeds(): Promise<void> {
53
- const pythClient = new SuiPythClient(
54
- this.builder.suiKit.client,
55
- this.builder.address.get('core.oracles.pyth.state'),
56
- this.builder.address.get('core.oracles.pyth.wormholeState')
57
- );
58
- const filteredCoinNames = this.filterSponsoredFeeds();
59
- if (filteredCoinNames.length === 0) {
60
- return;
61
- }
62
- const priceIds = filteredCoinNames.map((assetCoinName) =>
63
- this.builder.address.get(`core.coins.${assetCoinName}.oracle.pyth.feed`)
64
- );
65
-
66
- // iterate through the endpoints
67
- const endpoints = this.builder.utils.pythEndpoints ?? [
68
- ...this.builder.constants.whitelist.pythEndpoints,
69
- ];
70
- for (const endpoint of endpoints) {
71
- try {
72
- const pythConnection = new SuiPriceServiceConnection(endpoint);
73
- const priceUpdateData =
74
- await pythConnection.getPriceFeedsUpdateData(priceIds);
75
- await pythClient.updatePriceFeeds(
76
- this.tx.txBlock,
77
- priceUpdateData,
78
- priceIds
79
- );
80
-
81
- break;
82
- } catch (e) {
83
- console.warn(
84
- `Failed to update price feeds with endpoint ${endpoint}: ${e}`
85
- );
86
- }
87
- }
88
- }
89
- }
90
-
91
- export const createPriceFeedUpdater = (
92
- oracleName: SupportOracleType,
93
- tx: SuiTxBlock,
94
- builder: ScallopBuilder,
95
- coinNames: string[],
96
- options: {
97
- usePythPullModel: boolean;
98
- useOnChainXOracleList: boolean;
99
- pythSponsoredFeeds: string[];
100
- }
101
- ) => {
102
- switch (oracleName) {
103
- case 'pyth':
104
- return new PythPriceFeedUpdater(tx, builder, coinNames, options);
105
- case 'supra':
106
- throw new Error('Supra price feed updater is not implemented yet.');
107
- case 'switchboard':
108
- throw new Error('Switchboard price feed updater is not implemented yet.');
109
- default:
110
- throw new Error(`Unsupported oracle type: ${oracleName}`);
111
- }
112
- };
@@ -1,50 +0,0 @@
1
- import {
2
- SUI_CLOCK_OBJECT_ID,
3
- SuiTxBlock,
4
- TransactionArgument,
5
- } from '@scallop-io/sui-kit';
6
- import { XOraclePackageRegistry } from './oraclePackageRegistry';
7
-
8
- interface IPriceUpdateRequester {
9
- buildRequest(coinName: string): TransactionArgument;
10
- confirmRequest(coinName: string, request: TransactionArgument): void;
11
- }
12
-
13
- export class PriceUpdateRequester implements IPriceUpdateRequester {
14
- constructor(
15
- private readonly txBlock: SuiTxBlock,
16
- private readonly xOraclePackageRegistry: XOraclePackageRegistry
17
- ) {}
18
-
19
- get utils() {
20
- return this.xOraclePackageRegistry.utils;
21
- }
22
-
23
- buildRequest(coinName: string): TransactionArgument {
24
- const { xOraclePackageId, xOracleId } =
25
- this.xOraclePackageRegistry.getXOraclePackages;
26
- const target = `${xOraclePackageId}::x_oracle::price_update_request`;
27
- const typeArgs = [this.utils.parseCoinType(coinName)];
28
- return this.txBlock.moveCall(target, [xOracleId], typeArgs);
29
- }
30
-
31
- confirmRequest(coinName: string, request: TransactionArgument): void {
32
- const { xOraclePackageId, xOracleId } =
33
- this.xOraclePackageRegistry.getXOraclePackages;
34
- const target = `${xOraclePackageId}::x_oracle::confirm_price_update_request`;
35
- const typeArgs = [this.utils.parseCoinType(coinName)];
36
- this.txBlock.moveCall(
37
- target,
38
- [
39
- xOracleId,
40
- request,
41
- this.txBlock.sharedObjectRef({
42
- objectId: SUI_CLOCK_OBJECT_ID,
43
- mutable: false,
44
- initialSharedVersion: '1',
45
- }),
46
- ],
47
- typeArgs
48
- );
49
- }
50
- }