Skip to content

Commit 6c1cbce

Browse files
committed
refactor(programs): make params more general
1 parent 95c2eca commit 6c1cbce

File tree

4 files changed

+199
-50
lines changed

4 files changed

+199
-50
lines changed

governance/xc_admin/packages/xc_admin_common/src/programs/core/core_functions.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import {
3434
RawConfig,
3535
ValidationResult,
3636
CoreInstructionAccounts,
37+
GetConfigParams,
38+
ProgramType,
3739
} from "../types";
3840

3941
/**
@@ -128,9 +130,11 @@ export function isAvailableOnCluster(cluster: PythCluster): boolean {
128130
/**
129131
* Parse raw on-chain accounts into the Pyth Core configuration format
130132
*/
131-
export function getConfigFromRawAccounts(
132-
accounts: Array<{ pubkey: PublicKey; account: AccountInfo<Buffer> }>,
133-
): RawConfig {
133+
export function getConfig(params: GetConfigParams): RawConfig {
134+
if (params.programType !== ProgramType.PYTH_CORE) {
135+
throw new Error("Invalid program type for Core getConfig");
136+
}
137+
const accounts = params.accounts;
134138
const priceRawConfigs: { [key: string]: PriceRawConfig } = {};
135139
const rawConfig: RawConfig = { mappingAccounts: [] };
136140

governance/xc_admin/packages/xc_admin_common/src/programs/lazer/lazer_functions.ts

Lines changed: 98 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import {
44
ValidationResult,
55
DownloadableProduct,
66
LazerInstructionAccounts,
7+
LazerConfig,
8+
DownloadableConfig,
9+
LazerConfigParams,
10+
GetConfigParams,
711
} from "../types";
8-
import { ProgramType, PROGRAM_TYPE_NAMES } from "../types";
12+
import { ProgramType } from "../types";
913

1014
/**
1115
* Program ID for the Pyth Lazer program
@@ -42,21 +46,41 @@ export function isAvailableOnCluster(cluster: PythCluster): boolean {
4246
}
4347

4448
/**
45-
* Parse raw on-chain accounts into a configuration object
49+
* Get configuration for Lazer program
4650
*
47-
* @param accounts Array of account data from the blockchain
48-
* @param cluster The Pyth cluster where the accounts were fetched from
49-
* @returns Lazer-specific configuration object
51+
* @param params Parameters to fetch Lazer configuration
52+
* @returns Promise resolving to Lazer-specific configuration object
5053
*/
51-
export function getConfigFromRawAccounts(
52-
accounts: any[],
53-
cluster: PythCluster,
54-
): any {
55-
// Not implemented yet - minimal placeholder
54+
export function getConfig(params: GetConfigParams): LazerConfig {
55+
// Only process if this is a Lazer config request
56+
if (params.programType !== ProgramType.PYTH_LAZER) {
57+
throw new Error("Invalid program type for Lazer getConfig");
58+
}
59+
60+
// Cast to LazerConfigParams to extract the properties
61+
const { endpoint, network, options } = params as {
62+
programType: ProgramType.PYTH_LAZER;
63+
} & LazerConfigParams;
64+
65+
// Example implementation that would fetch data from a non-Solana source
66+
// For now, return a placeholder with empty feeds
67+
68+
// In a real implementation, this might:
69+
// 1. Connect to a REST API endpoint
70+
// 2. Query a database
71+
// 3. Read from a file
72+
// 4. Or even call a different blockchain's RPC
73+
74+
// Simulating some async operation
5675
return {
5776
programType: ProgramType.PYTH_LAZER,
58-
cluster,
77+
// Include cluster if provided in options
78+
cluster: options?.cluster as PythCluster | undefined,
5979
feeds: [],
80+
metadata: {
81+
source: endpoint || "unknown",
82+
network: network || "unknown",
83+
},
6084
};
6185
}
6286

@@ -66,9 +90,37 @@ export function getConfigFromRawAccounts(
6690
* @param config The program's configuration object
6791
* @returns Configuration formatted for download
6892
*/
69-
export function getDownloadableConfig(config: any): any {
70-
// For now, just return an empty config
71-
return {};
93+
export function getDownloadableConfig(config: LazerConfig): DownloadableConfig {
94+
// Transform LazerConfig to DownloadableConfig
95+
const downloadableConfig: DownloadableConfig = {};
96+
97+
// Convert each feed to a format compatible with DownloadableProduct
98+
config.feeds.forEach((feed) => {
99+
downloadableConfig[feed.id] = {
100+
address: "", // We'll need to determine how to represent this for Lazer
101+
metadata: {
102+
symbol: feed.id,
103+
// Convert feed metadata to match expected Product metadata format
104+
// This is a placeholder and will need to be adjusted based on actual metadata
105+
asset_type: feed.metadata.asset_type?.toString() || "",
106+
country: feed.metadata.country?.toString() || "",
107+
quote_currency: feed.metadata.quote_currency?.toString() || "",
108+
tenor: feed.metadata.tenor?.toString() || "",
109+
// Add other required fields
110+
},
111+
priceAccounts: [
112+
{
113+
address: "", // Will need to be determined based on Lazer's structure
114+
publishers: [], // Will need to be populated from Lazer data
115+
expo: 0, // Default value, update based on actual data
116+
minPub: 0, // Default value, update based on actual data
117+
maxLatency: 0, // Default value, update based on actual data
118+
},
119+
],
120+
};
121+
});
122+
123+
return downloadableConfig;
72124
}
73125

74126
/**
@@ -80,15 +132,32 @@ export function getDownloadableConfig(config: any): any {
80132
* @returns Object with validation result and optional error message
81133
*/
82134
export function validateUploadedConfig(
83-
existingConfig: any,
84-
uploadedConfig: any,
135+
existingConfig: DownloadableConfig,
136+
uploadedConfig: unknown,
85137
cluster: PythCluster,
86138
): ValidationResult {
87-
// Not implemented yet - return error
88-
return {
89-
isValid: false,
90-
error: "Uploading configuration for Pyth Lazer is not yet supported",
91-
};
139+
// Basic validation logic for Lazer config
140+
try {
141+
if (typeof uploadedConfig !== "object" || uploadedConfig === null) {
142+
return {
143+
isValid: false,
144+
error: "Invalid JSON format for Lazer configuration",
145+
};
146+
}
147+
148+
// More detailed validation would be implemented here
149+
// For now, return not implemented error
150+
return {
151+
isValid: false,
152+
error: "Uploading configuration for Pyth Lazer is not yet supported",
153+
};
154+
} catch (error) {
155+
return {
156+
isValid: false,
157+
error:
158+
error instanceof Error ? error.message : "Unknown validation error",
159+
};
160+
}
92161
}
93162

94163
/**
@@ -110,6 +179,13 @@ export async function generateInstructions(
110179
cluster: PythCluster,
111180
accounts: LazerInstructionAccounts,
112181
): Promise<TransactionInstruction[]> {
113-
// Not implemented yet - return empty array
182+
// Simple placeholder implementation that returns an empty array of instructions
183+
// In a real implementation, this would transform the changes into Lazer-specific instructions
184+
185+
// Example of how this might be implemented:
186+
// 1. For each change, determine if it's an add, update, or delete operation
187+
// 2. Map the DownloadableProduct format to Lazer-specific data structure
188+
// 3. Generate appropriate Lazer instructions based on the operation type
189+
114190
return [];
115191
}

governance/xc_admin/packages/xc_admin_common/src/programs/program_registry.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import { AccountInfo, PublicKey } from "@solana/web3.js";
22
import { PythCluster } from "@pythnetwork/client";
3-
import { DownloadableConfig, ProgramType, RawConfig } from "./types";
3+
import {
4+
DownloadableConfig,
5+
ProgramType,
6+
RawConfig,
7+
LazerConfig,
8+
ProgramConfig,
9+
GetConfigParams,
10+
LazerConfigParams,
11+
} from "./types";
412
import {
513
ProgramFunctions,
614
ValidationResult,
@@ -34,28 +42,35 @@ export const isAvailableOnCluster: Record<
3442
};
3543

3644
/**
37-
* Function to parse raw on-chain accounts into a configuration object
45+
* Function to get configuration for each program type
3846
*/
39-
export const getConfigFromRawAccounts: Record<
47+
export const getConfig: Record<
4048
ProgramType,
41-
(
42-
accounts: Array<{ pubkey: PublicKey; account: AccountInfo<Buffer> }>,
43-
cluster: PythCluster,
44-
) => RawConfig
49+
(params: GetConfigParams) => ProgramConfig
4550
> = {
46-
[ProgramType.PYTH_CORE]: pythCore.getConfigFromRawAccounts,
47-
[ProgramType.PYTH_LAZER]: pythLazer.getConfigFromRawAccounts,
51+
[ProgramType.PYTH_CORE]: pythCore.getConfig,
52+
[ProgramType.PYTH_LAZER]: pythLazer.getConfig,
4853
};
4954

5055
/**
5156
* Function to format the configuration for downloading as a JSON file
5257
*/
5358
export const getDownloadableConfig: Record<
5459
ProgramType,
55-
(config: RawConfig) => DownloadableConfig
60+
(config: ProgramConfig) => DownloadableConfig
5661
> = {
57-
[ProgramType.PYTH_CORE]: pythCore.getDownloadableConfig,
58-
[ProgramType.PYTH_LAZER]: pythLazer.getDownloadableConfig,
62+
[ProgramType.PYTH_CORE]: (config: ProgramConfig) => {
63+
if ("mappingAccounts" in config) {
64+
return pythCore.getDownloadableConfig(config as RawConfig);
65+
}
66+
throw new Error("Invalid config type for Pyth Core");
67+
},
68+
[ProgramType.PYTH_LAZER]: (config: ProgramConfig) => {
69+
if ("feeds" in config && config.programType === ProgramType.PYTH_LAZER) {
70+
return pythLazer.getDownloadableConfig(config as LazerConfig);
71+
}
72+
throw new Error("Invalid config type for Pyth Lazer");
73+
},
5974
};
6075

6176
/**
@@ -95,7 +110,7 @@ export function getProgramFunctions<T extends ProgramType>(
95110
return {
96111
getProgramAddress: getProgramAddress[type],
97112
isAvailableOnCluster: isAvailableOnCluster[type],
98-
getConfigFromRawAccounts: getConfigFromRawAccounts[type],
113+
getConfig: getConfig[type],
99114
getDownloadableConfig: getDownloadableConfig[type],
100115
validateUploadedConfig: validateUploadedConfig[type],
101116
generateInstructions: generateInstructions[

governance/xc_admin/packages/xc_admin_common/src/programs/types.ts

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,59 @@ export type RawConfig = {
6969
permissionAccount?: PermissionData;
7070
};
7171

72+
export type CoreConfigParams = {
73+
accounts: Array<{ pubkey: PublicKey; account: AccountInfo<Buffer> }>;
74+
cluster: PythCluster;
75+
};
76+
77+
/**
78+
* Lazer-specific configuration type
79+
* TODO: Change to actual Lazer config type
80+
*/
81+
export type LazerConfig = {
82+
programType: ProgramType.PYTH_LAZER;
83+
// Make cluster optional since Lazer might not be tied to a specific cluster
84+
cluster?: PythCluster;
85+
// More generic data source instead of Solana-specific accounts
86+
feeds: LazerFeed[];
87+
// Additional metadata that might be relevant for Lazer
88+
metadata?: Record<string, unknown>;
89+
};
90+
91+
/**
92+
* Parameters for getting Lazer configuration
93+
*/
94+
export type LazerConfigParams = {
95+
// Instead of requiring Solana accounts, allow any parameters needed
96+
endpoint?: string;
97+
network?: string;
98+
options?: Record<string, unknown>;
99+
};
100+
101+
/**
102+
* Union type for configuration parameters that can vary by program type
103+
*/
104+
export type GetConfigParams =
105+
| ({
106+
programType: ProgramType.PYTH_CORE;
107+
} & CoreConfigParams)
108+
| ({ programType: ProgramType.PYTH_LAZER } & LazerConfigParams);
109+
110+
/**
111+
* Function to get configuration data
112+
*/
113+
export type GetConfigFn = (params: GetConfigParams) => ProgramConfig;
114+
115+
/**
116+
* Lazer feed configuration
117+
* TODO: Change to actual Lazer feed type
118+
*/
119+
export type LazerFeed = {
120+
id: string;
121+
metadata: Record<string, string | number | boolean>;
122+
// Add other feed-specific properties as needed
123+
};
124+
72125
/**
73126
* Type for downloadable price account configuration
74127
*/
@@ -96,6 +149,11 @@ export type DownloadableConfig = {
96149
[symbol: string]: DownloadableProduct;
97150
};
98151

152+
/**
153+
* Type for configuration that can be either RawConfig for Pyth Core or LazerConfig for Lazer
154+
*/
155+
export type ProgramConfig = RawConfig | LazerConfig;
156+
99157
/**
100158
* Core program instruction accounts needed for generateInstructions
101159
*/
@@ -112,8 +170,10 @@ export interface CoreInstructionAccounts {
112170
*/
113171
export interface LazerInstructionAccounts {
114172
fundingAccount: PublicKey;
115-
// TODO: Add Lazer-specific account requirements here
116-
[key: string]: any;
173+
// Lazer-specific properties
174+
lazerProgramClient?: any; // Replace with proper type when available
175+
cluster: PythCluster;
176+
additionalAccounts?: Record<string, PublicKey>;
117177
}
118178

119179
/**
@@ -141,18 +201,12 @@ export type GetProgramAddressFn = (cluster: PythCluster) => PublicKey;
141201
*/
142202
export type IsAvailableOnClusterFn = (cluster: PythCluster) => boolean;
143203

144-
/**
145-
* Function to parse raw on-chain accounts into a configuration object
146-
*/
147-
export type GetConfigFromRawAccountsFn = (
148-
accounts: Array<{ pubkey: PublicKey; account: AccountInfo<Buffer> }>,
149-
cluster: PythCluster,
150-
) => RawConfig;
151-
152204
/**
153205
* Function to format the configuration for downloading as a JSON file
154206
*/
155-
export type GetDownloadableConfigFn = (config: RawConfig) => DownloadableConfig;
207+
export type GetDownloadableConfigFn = (
208+
config: ProgramConfig,
209+
) => DownloadableConfig;
156210

157211
/**
158212
* Result of validating an uploaded configuration
@@ -193,7 +247,7 @@ export type GenerateInstructionsFn<T extends ProgramType = ProgramType> = (
193247
export interface ProgramFunctions<T extends ProgramType = ProgramType> {
194248
getProgramAddress: GetProgramAddressFn;
195249
isAvailableOnCluster: IsAvailableOnClusterFn;
196-
getConfigFromRawAccounts: GetConfigFromRawAccountsFn;
250+
getConfig: GetConfigFn;
197251
getDownloadableConfig: GetDownloadableConfigFn;
198252
validateUploadedConfig: ValidateUploadedConfigFn;
199253
generateInstructions: GenerateInstructionsFn<T>;

0 commit comments

Comments
 (0)