@scallop-io/sui-scallop-sdk 2.3.0-lst-x-oracle-alpha.9 → 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.
- package/dist/index.d.mts +1811 -1783
- package/dist/index.d.ts +1811 -1783
- package/dist/index.js +49 -2
- package/dist/index.mjs +15 -2
- package/package.json +8 -7
- package/src/builders/borrowIncentiveBuilder.ts +4 -4
- package/src/builders/coreBuilder.ts +86 -59
- package/src/builders/index.ts +2 -2
- package/src/builders/loyaltyProgramBuilder.ts +2 -2
- package/src/builders/oracles/index.ts +365 -114
- package/src/builders/oracles/pyth.ts +135 -0
- package/src/builders/referralBuilder.ts +4 -10
- package/src/builders/sCoinBuilder.ts +2 -2
- package/src/builders/spoolBuilder.ts +2 -2
- package/src/builders/vescaBuilder.ts +5 -5
- package/src/constants/common.ts +3 -0
- package/src/constants/index.ts +1 -1
- package/src/constants/queryKeys.ts +1 -1
- package/src/constants/testAddress.ts +99 -271
- package/src/constants/xoracle.ts +2 -8
- package/src/index.ts +1 -1
- package/src/models/index.ts +1 -2
- package/src/models/interface.ts +6 -6
- package/src/models/rateLimiter.ts +55 -0
- package/src/models/scallop.ts +1 -1
- package/src/models/scallopAddress.ts +5 -33
- package/src/models/scallopBuilder.ts +14 -11
- package/src/models/scallopClient.ts +31 -14
- package/src/models/scallopConstants.ts +3 -3
- package/src/models/scallopIndexer.ts +3 -4
- package/src/models/scallopQuery.ts +112 -56
- package/src/models/scallopQueryClient.ts +1 -1
- package/src/models/scallopSuiKit.ts +1 -1
- package/src/models/scallopUtils.ts +12 -7
- package/src/queries/borrowIncentiveQuery.ts +4 -3
- package/src/queries/coreQuery.ts +114 -186
- package/src/queries/index.ts +3 -4
- package/src/queries/loyaltyProgramQuery.ts +2 -2
- package/src/queries/ownerQuery.ts +32 -0
- package/src/queries/poolAddressesQuery.ts +1 -3
- package/src/queries/portfolioQuery.ts +68 -16
- package/src/queries/priceQuery.ts +2 -3
- package/src/queries/sCoinQuery.ts +2 -2
- package/src/queries/spoolQuery.ts +57 -74
- package/src/queries/vescaQuery.ts +3 -3
- package/src/queries/xOracleQuery.ts +4 -21
- package/src/types/address.ts +47 -98
- package/src/types/builder/core.ts +40 -15
- package/src/types/builder/index.ts +17 -1
- package/src/types/constant/enum.ts +64 -0
- package/src/types/constant/index.ts +1 -2
- package/src/types/constant/xOracle.ts +7 -10
- package/src/types/index.ts +1 -1
- package/src/types/query/core.ts +3 -0
- package/src/types/query/index.ts +1 -0
- package/src/types/query/sCoin.ts +1 -0
- package/src/{builders/utils.ts → utils/builder.ts} +1 -1
- package/src/utils/core.ts +18 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/indexer.ts +47 -0
- package/src/{queries/utils.ts → utils/query.ts} +7 -25
- package/src/utils/util.ts +42 -0
- package/src/builders/oracles/error.ts +0 -18
- package/src/builders/oracles/oraclePackageRegistry.ts +0 -336
- package/src/builders/oracles/priceFeedUpdater.ts +0 -112
- package/src/builders/oracles/priceUpdateRequester.ts +0 -50
- package/src/builders/oracles/xOracleUpdateStrategy.ts +0 -214
- package/src/builders/oracles/xOracleUpdater.ts +0 -153
- package/src/constants/api.ts +0 -2
- package/src/models/utils.ts +0 -97
- package/src/types/builder/type.ts +0 -25
- package/src/types/constant/package.ts +0 -16
- /package/src/types/{util.ts → utils.ts} +0 -0
|
@@ -1,7 +1,23 @@
|
|
|
1
|
+
import type { CoreTxBlock } from './core';
|
|
2
|
+
import type { SpoolTxBlock } from './spool';
|
|
3
|
+
import type { BorrowIncentiveTxBlock } from './borrowIncentive';
|
|
4
|
+
import type { VeScaTxBlock } from './vesca';
|
|
5
|
+
import type { ReferralTxBlock } from './referral';
|
|
6
|
+
import { LoyaltyProgramTxBlock } from './loyaltyProgram';
|
|
7
|
+
import { SCoinTxBlock } from './sCoin';
|
|
8
|
+
|
|
1
9
|
export type * from './core';
|
|
2
10
|
export type * from './spool';
|
|
3
11
|
export type * from './borrowIncentive';
|
|
4
12
|
export type * from './vesca';
|
|
5
13
|
export type * from './loyaltyProgram';
|
|
6
14
|
export type * from './sCoin';
|
|
7
|
-
|
|
15
|
+
|
|
16
|
+
export type BaseScallopTxBlock = ReferralTxBlock &
|
|
17
|
+
LoyaltyProgramTxBlock &
|
|
18
|
+
BorrowIncentiveTxBlock &
|
|
19
|
+
VeScaTxBlock;
|
|
20
|
+
|
|
21
|
+
export type SuiTxBlockWithSCoin = BaseScallopTxBlock & SCoinTxBlock;
|
|
22
|
+
export type SuiTxBlockWithSpool = SuiTxBlockWithSCoin & SpoolTxBlock;
|
|
23
|
+
export type ScallopTxBlock = SuiTxBlockWithSpool & CoreTxBlock;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type Coins = {
|
|
2
|
+
[K in string]: K;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
export type AssetCoins = {
|
|
6
|
+
[K in string]: K;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type MarketCoins = {
|
|
10
|
+
[K in string]: K;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type SCoins = {
|
|
14
|
+
[K in string]: K;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type StakeMarketCoins = {
|
|
18
|
+
[K in string]: K;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type StakeRewardCoins = {
|
|
22
|
+
[key in string]: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type SuiBridgeCoins = {
|
|
26
|
+
[K in string]: K;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type BorrowIncentiveRewardCoins = {
|
|
30
|
+
[key in string]: string[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type AssetCoinIds = {
|
|
34
|
+
[key in string]: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type SCoinIds = {
|
|
38
|
+
[key in string]: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type SCoinTreasuryCaps = {
|
|
42
|
+
[key in string]: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type SCoinConverterTreasury = {
|
|
46
|
+
[key in string]: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
type PickFromUnion<T, K extends string> = K extends T ? K : never;
|
|
50
|
+
|
|
51
|
+
export type WormholeCoinIds = {
|
|
52
|
+
[key in PickFromUnion<
|
|
53
|
+
string,
|
|
54
|
+
'weth' | 'wbtc' | 'wusdc' | 'wusdt' | 'wapt' | 'wsol'
|
|
55
|
+
>]: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type VoloCoinIds = {
|
|
59
|
+
[key in PickFromUnion<string, 'vsui'>]: string;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type SuiBridgedCoinPackageIds = {
|
|
63
|
+
[key in string]: string;
|
|
64
|
+
};
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
X_ORACLE_RULES,
|
|
4
|
-
SUPPORT_SUI_LST,
|
|
5
|
-
} from 'src/constants/xoracle';
|
|
1
|
+
export const _SUPPORT_ORACLES = ['supra', 'switchboard', 'pyth'] as const;
|
|
2
|
+
export type SupportOracleType = (typeof _SUPPORT_ORACLES)[number];
|
|
6
3
|
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
export type xOracleRules = {
|
|
5
|
+
primary: SupportOracleType[];
|
|
6
|
+
secondary: SupportOracleType[];
|
|
7
|
+
};
|
|
8
|
+
export type xOracleRuleType = keyof xOracleRules;
|
|
11
9
|
|
|
12
10
|
export type xOracleListType = {
|
|
13
11
|
[key in string]: xOracleRules;
|
|
14
12
|
};
|
|
15
|
-
export type SupportedOracleSuiLst = (typeof SUPPORT_SUI_LST)[number];
|
package/src/types/index.ts
CHANGED
package/src/types/query/core.ts
CHANGED
package/src/types/query/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type sCoinBalance = number;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SuiObjectData } from '@mysten/sui/client';
|
|
2
|
+
|
|
3
|
+
export const parseObjectAs = <T>(object: SuiObjectData): T => {
|
|
4
|
+
if (!(object && object.content && 'fields' in object.content))
|
|
5
|
+
throw new Error(`Failed to parse object ${object}`);
|
|
6
|
+
|
|
7
|
+
const fields = object.content.fields as any;
|
|
8
|
+
|
|
9
|
+
if (typeof fields === 'object' && 'value' in fields) {
|
|
10
|
+
const value = fields.value;
|
|
11
|
+
if (typeof value === 'object' && 'fields' in value)
|
|
12
|
+
return value.fields as T;
|
|
13
|
+
return value as T;
|
|
14
|
+
} else if (typeof fields === 'object') {
|
|
15
|
+
return fields as T;
|
|
16
|
+
}
|
|
17
|
+
return fields as T;
|
|
18
|
+
};
|
|
@@ -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 '
|
|
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
|
-
|
|
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,18 +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 UnsupportedLstOracleError extends Error {
|
|
12
|
-
constructor(lst: string, oracle: string) {
|
|
13
|
-
super(`Unsupported LST oracle update for: ${lst} with oracle: ${oracle}`);
|
|
14
|
-
this.name = 'UnsupportedLstOracleError';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { UnsupportedOracleError, UnsupportedLstOracleError };
|
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
import { TransactionArgument } from '@scallop-io/sui-kit';
|
|
2
|
-
import { ScallopUtils } from 'src/models';
|
|
3
|
-
import {
|
|
4
|
-
AddressStringPath,
|
|
5
|
-
BasePackage,
|
|
6
|
-
PythOracleLstConfig,
|
|
7
|
-
SupportOracleLst,
|
|
8
|
-
} from 'src/types/address';
|
|
9
|
-
import { UnsupportedOracleError } from './error';
|
|
10
|
-
import { SupportedOracleSuiLst, SupportOracleType } from 'src/types/constant';
|
|
11
|
-
import { SUPPORT_SUI_LST } from 'src/constants';
|
|
12
|
-
|
|
13
|
-
export type XOraclePackages = {
|
|
14
|
-
xOraclePackageId: string;
|
|
15
|
-
xOracleId: TransactionArgument | string;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
type RecordValueType<T> = T extends Record<any, infer V> ? V : never;
|
|
19
|
-
|
|
20
|
-
export type PythLstPackages<T extends SupportedOracleSuiLst> = RecordValueType<
|
|
21
|
-
PythOracleLstConfig<T>
|
|
22
|
-
> &
|
|
23
|
-
BasePackage;
|
|
24
|
-
|
|
25
|
-
type MaybeWithLstPackage<T, U> = T extends SupportOracleLst
|
|
26
|
-
? T extends 'pyth'
|
|
27
|
-
? U & { lst: PythLstPackages<SupportedOracleSuiLst> }
|
|
28
|
-
: never
|
|
29
|
-
: U;
|
|
30
|
-
|
|
31
|
-
type PythStaticPackages = {
|
|
32
|
-
pythPackageId: string;
|
|
33
|
-
pythRegistryId: TransactionArgument | string;
|
|
34
|
-
pythStateId: TransactionArgument | string;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
type PythDynamicPackages = MaybeWithLstPackage<
|
|
38
|
-
'pyth',
|
|
39
|
-
{
|
|
40
|
-
pythFeedObjectId: TransactionArgument | string;
|
|
41
|
-
}
|
|
42
|
-
>;
|
|
43
|
-
|
|
44
|
-
export type PythPackages = PythStaticPackages & PythDynamicPackages;
|
|
45
|
-
|
|
46
|
-
type SwitchboardStaticPackages = {
|
|
47
|
-
switchboardPackageId: string;
|
|
48
|
-
switchboardRegistryId: TransactionArgument | string;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
type SwitchboardDynamicPackages = MaybeWithLstPackage<
|
|
52
|
-
'switchboard',
|
|
53
|
-
{
|
|
54
|
-
switchboardAggregatorId: TransactionArgument | string;
|
|
55
|
-
}
|
|
56
|
-
>;
|
|
57
|
-
|
|
58
|
-
export type SwitchboardPackages = SwitchboardStaticPackages &
|
|
59
|
-
SwitchboardDynamicPackages;
|
|
60
|
-
|
|
61
|
-
export type SupraPackages = {
|
|
62
|
-
supraPackageId: string;
|
|
63
|
-
supraHolderId: TransactionArgument | string;
|
|
64
|
-
supraRegistryId: TransactionArgument | string;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export type OraclePackages<T extends SupportOracleType = SupportOracleType> =
|
|
68
|
-
T extends 'pyth'
|
|
69
|
-
? PythPackages
|
|
70
|
-
: T extends 'switchboard'
|
|
71
|
-
? SwitchboardPackages
|
|
72
|
-
: T extends 'supra'
|
|
73
|
-
? SupraPackages
|
|
74
|
-
: never;
|
|
75
|
-
|
|
76
|
-
type getLstPackagesReturnType<
|
|
77
|
-
T extends SupportOracleType,
|
|
78
|
-
U extends SupportedOracleSuiLst = SupportedOracleSuiLst,
|
|
79
|
-
> = T extends 'pyth' ? PythLstPackages<U> : never;
|
|
80
|
-
|
|
81
|
-
const PYTH_LST_PATHS: Record<SupportedOracleSuiLst, AddressStringPath> = {
|
|
82
|
-
afsui: 'core.oracles.pyth.lst.afsui',
|
|
83
|
-
hasui: 'core.oracles.pyth.lst.hasui',
|
|
84
|
-
};
|
|
85
|
-
export interface IOraclePackageRegistry<
|
|
86
|
-
T extends SupportOracleType = SupportOracleType,
|
|
87
|
-
> {
|
|
88
|
-
utils: ScallopUtils;
|
|
89
|
-
oracleName: T;
|
|
90
|
-
packageId: string;
|
|
91
|
-
getLstPackages(coinName: SupportedOracleSuiLst): getLstPackagesReturnType<T>;
|
|
92
|
-
getPackages(coinName: string): OraclePackages<T>;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
interface IHasStaticPackages {
|
|
96
|
-
getStaticPackages: Record<string, TransactionArgument | string>;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export class XOraclePackageRegistry
|
|
100
|
-
implements
|
|
101
|
-
Omit<
|
|
102
|
-
IOraclePackageRegistry,
|
|
103
|
-
'oracleName' | 'packageId' | 'getPackages' | 'getLstPackages'
|
|
104
|
-
>
|
|
105
|
-
{
|
|
106
|
-
constructor(readonly utils: ScallopUtils) {}
|
|
107
|
-
|
|
108
|
-
getAddressPath(path: AddressStringPath) {
|
|
109
|
-
return this.utils.address.get(path);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get getXOraclePackages() {
|
|
113
|
-
return {
|
|
114
|
-
xOraclePackageId: this.getAddressPath('core.packages.xOracle.id'),
|
|
115
|
-
xOracleId: this.getAddressPath('core.oracles.xOracle'),
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
abstract class BasePackageRegistry implements IOraclePackageRegistry {
|
|
121
|
-
abstract readonly oracleName: SupportOracleType;
|
|
122
|
-
|
|
123
|
-
constructor(
|
|
124
|
-
protected readonly xOraclePackageRegistry: XOraclePackageRegistry
|
|
125
|
-
) {}
|
|
126
|
-
|
|
127
|
-
abstract getPackages(
|
|
128
|
-
coinName: string
|
|
129
|
-
): OraclePackages<typeof this.oracleName>;
|
|
130
|
-
|
|
131
|
-
abstract getLstPackages(
|
|
132
|
-
coinName: SupportedOracleSuiLst
|
|
133
|
-
): getLstPackagesReturnType<typeof this.oracleName>;
|
|
134
|
-
|
|
135
|
-
get utils() {
|
|
136
|
-
return this.xOraclePackageRegistry.utils;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
get packageId() {
|
|
140
|
-
return this.xOraclePackageRegistry.getAddressPath(
|
|
141
|
-
`core.packages.${this.oracleName}.id`
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
class PythPackageRegistry
|
|
147
|
-
extends BasePackageRegistry
|
|
148
|
-
implements IHasStaticPackages
|
|
149
|
-
{
|
|
150
|
-
readonly oracleName = 'pyth';
|
|
151
|
-
|
|
152
|
-
constructor(
|
|
153
|
-
protected readonly xOraclePackageRegistry: XOraclePackageRegistry
|
|
154
|
-
) {
|
|
155
|
-
super(xOraclePackageRegistry);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
get getStaticPackages() {
|
|
159
|
-
return {
|
|
160
|
-
pythPackageId: this.packageId,
|
|
161
|
-
pythRegistryId: this.xOraclePackageRegistry.getAddressPath(
|
|
162
|
-
'core.oracles.pyth.registry'
|
|
163
|
-
),
|
|
164
|
-
pythStateId: this.xOraclePackageRegistry.getAddressPath(
|
|
165
|
-
'core.oracles.pyth.state'
|
|
166
|
-
),
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private getLstOracleConfigPackages(coinName: SupportedOracleSuiLst) {
|
|
171
|
-
const path = PYTH_LST_PATHS[coinName];
|
|
172
|
-
if (path) {
|
|
173
|
-
return this.xOraclePackageRegistry.getAddressPath(path);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
getLstPackages(coinName: SupportedOracleSuiLst) {
|
|
178
|
-
const lstPackages = this.xOraclePackageRegistry.getAddressPath(
|
|
179
|
-
`core.packages.pyth.lst.${coinName}`
|
|
180
|
-
) as BasePackage;
|
|
181
|
-
|
|
182
|
-
// get the oracle config for the coin
|
|
183
|
-
const oracleLstConfig = this.getLstOracleConfigPackages(coinName) ?? {};
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
...lstPackages,
|
|
187
|
-
...oracleLstConfig,
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private resolvePythFeedForSuiLst(coinName: string) {
|
|
192
|
-
if (SUPPORT_SUI_LST.includes(coinName as any)) {
|
|
193
|
-
return 'sui';
|
|
194
|
-
}
|
|
195
|
-
return coinName;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
getPackages(coinName: string) {
|
|
199
|
-
const lstPackages = this.getLstPackages(coinName as SupportedOracleSuiLst);
|
|
200
|
-
|
|
201
|
-
return {
|
|
202
|
-
...this.getStaticPackages,
|
|
203
|
-
pythFeedObjectId: this.xOraclePackageRegistry.getAddressPath(
|
|
204
|
-
`core.coins.${this.resolvePythFeedForSuiLst(coinName)}.oracle.pyth.feedObject`
|
|
205
|
-
),
|
|
206
|
-
lst: lstPackages,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
class SupraPackageRegistry extends BasePackageRegistry {
|
|
212
|
-
readonly oracleName = 'supra';
|
|
213
|
-
|
|
214
|
-
constructor(
|
|
215
|
-
protected readonly xOraclePackageRegistry: XOraclePackageRegistry
|
|
216
|
-
) {
|
|
217
|
-
super(xOraclePackageRegistry);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
getLstPackages(
|
|
221
|
-
_: SupportedOracleSuiLst
|
|
222
|
-
): getLstPackagesReturnType<typeof this.oracleName> {
|
|
223
|
-
throw new Error('Method not implemented.');
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
getPackages(_: string) {
|
|
227
|
-
return {
|
|
228
|
-
supraPackageId: this.packageId,
|
|
229
|
-
supraRegistryId: this.xOraclePackageRegistry.getAddressPath(
|
|
230
|
-
'core.oracles.supra.registry'
|
|
231
|
-
),
|
|
232
|
-
supraHolderId: this.xOraclePackageRegistry.getAddressPath(
|
|
233
|
-
'core.oracles.supra.holder'
|
|
234
|
-
),
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
class SwitchboardPackageRegistry
|
|
240
|
-
extends BasePackageRegistry
|
|
241
|
-
implements IHasStaticPackages
|
|
242
|
-
{
|
|
243
|
-
readonly oracleName = 'switchboard';
|
|
244
|
-
|
|
245
|
-
constructor(
|
|
246
|
-
protected readonly xOraclePackageRegistry: XOraclePackageRegistry
|
|
247
|
-
) {
|
|
248
|
-
super(xOraclePackageRegistry);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
getLstPackages(
|
|
252
|
-
_: SupportedOracleSuiLst
|
|
253
|
-
): getLstPackagesReturnType<typeof this.oracleName> {
|
|
254
|
-
throw new Error('Method not implemented.');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
get getStaticPackages() {
|
|
258
|
-
return {
|
|
259
|
-
switchboardPackageId: this.packageId,
|
|
260
|
-
switchboardRegistryId: this.xOraclePackageRegistry.getAddressPath(
|
|
261
|
-
'core.oracles.switchboard.registry'
|
|
262
|
-
),
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
getPackages(coinName: string) {
|
|
267
|
-
return {
|
|
268
|
-
...this.getStaticPackages,
|
|
269
|
-
switchboardAggregatorId: this.xOraclePackageRegistry.getAddressPath(
|
|
270
|
-
`core.coins.${coinName}.oracle.switchboard`
|
|
271
|
-
),
|
|
272
|
-
} as OraclePackages<typeof this.oracleName>;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
export class OraclePackageRegistry {
|
|
277
|
-
private readonly registryMap = new Map<
|
|
278
|
-
SupportOracleType,
|
|
279
|
-
IOraclePackageRegistry
|
|
280
|
-
>();
|
|
281
|
-
|
|
282
|
-
constructor(readonly xOraclePackageRegistry: XOraclePackageRegistry) {}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Register a new updater (pyth, supra, switchboard)
|
|
286
|
-
*/
|
|
287
|
-
register(
|
|
288
|
-
cb: (
|
|
289
|
-
xOraclePackageRegistry: XOraclePackageRegistry
|
|
290
|
-
) => IOraclePackageRegistry
|
|
291
|
-
): void {
|
|
292
|
-
const registry = cb(this.xOraclePackageRegistry);
|
|
293
|
-
if (this.registryMap.has(registry.oracleName)) {
|
|
294
|
-
throw new Error(
|
|
295
|
-
`Updater already registered for oracleKey: ${registry.oracleName}`
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
this.registryMap.set(registry.oracleName, registry);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Retrieve the handler by key; throws if missing
|
|
303
|
-
*/
|
|
304
|
-
get(oracleName: SupportOracleType): IOraclePackageRegistry {
|
|
305
|
-
const handler = this.registryMap.get(oracleName);
|
|
306
|
-
if (!handler) {
|
|
307
|
-
throw new Error(
|
|
308
|
-
`No XOraclePriceUpdater registered for oracle: ${oracleName}`
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
return handler;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Optional: Check if a handler exists for the given key
|
|
316
|
-
*/
|
|
317
|
-
has(oracleName: SupportOracleType): boolean {
|
|
318
|
-
return this.registryMap.has(oracleName);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
export const createPackageRegistry = (
|
|
323
|
-
oracleName: SupportOracleType,
|
|
324
|
-
xOraclePackageRegistry: XOraclePackageRegistry
|
|
325
|
-
): IOraclePackageRegistry => {
|
|
326
|
-
switch (oracleName) {
|
|
327
|
-
case 'pyth':
|
|
328
|
-
return new PythPackageRegistry(xOraclePackageRegistry);
|
|
329
|
-
case 'supra':
|
|
330
|
-
return new SupraPackageRegistry(xOraclePackageRegistry);
|
|
331
|
-
case 'switchboard':
|
|
332
|
-
return new SwitchboardPackageRegistry(xOraclePackageRegistry);
|
|
333
|
-
default:
|
|
334
|
-
throw new UnsupportedOracleError(oracleName);
|
|
335
|
-
}
|
|
336
|
-
};
|