@@ -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 */
82134export 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}
0 commit comments