From 9d60527106d248d7609f8f7f726216db1776dfe5 Mon Sep 17 00:00:00 2001 From: ananas Date: Sun, 20 Jul 2025 20:44:54 +0100 Subject: [PATCH 1/3] fix: unknown api error, and StateLookuptable not found --- sdk-libs/client/src/indexer/error.rs | 6 ++-- sdk-libs/client/src/indexer/photon_indexer.rs | 8 +++-- sdk-libs/client/src/rpc/client.rs | 32 +++++++++++++++++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/sdk-libs/client/src/indexer/error.rs b/sdk-libs/client/src/indexer/error.rs index 5e83fe2d08..2a5ca31e94 100644 --- a/sdk-libs/client/src/indexer/error.rs +++ b/sdk-libs/client/src/indexer/error.rs @@ -46,7 +46,9 @@ pub enum IndexerError { #[error("Error: `{0}`")] CustomError(String), - #[error("Indexer not initialized.")] + #[error( + "Indexer not initialized. Set photon_url in LightClientConfig to enable indexer API calls." + )] NotInitialized, #[error("Indexer slot has not reached the requested slot.")] IndexerNotSyncedToSlot, @@ -91,7 +93,7 @@ impl From> for IndexerError { IndexerError::ApiError(format!("Serialization error: {}", e)) } photon_api::apis::Error::Io(e) => IndexerError::ApiError(format!("IO error: {}", e)), - _ => IndexerError::ApiError("Unknown API error".to_string()), + _ => IndexerError::ApiError(format!("Unknown API error {}", error)), } } } diff --git a/sdk-libs/client/src/indexer/photon_indexer.rs b/sdk-libs/client/src/indexer/photon_indexer.rs index 0370cf392d..4ce19c11e3 100644 --- a/sdk-libs/client/src/indexer/photon_indexer.rs +++ b/sdk-libs/client/src/indexer/photon_indexer.rs @@ -132,9 +132,11 @@ impl PhotonIndexer { result: Option, ) -> Result { if let Some(error) = error { - let error_message = error - .message - .unwrap_or_else(|| "Unknown API error".to_string()); + let error_message = if let Some(message) = error.message.clone() { + message + } else { + format!("") + }; return Err(IndexerError::ApiError(format!( "API error in {} (code: {:?}): {}", context, error.code, error_message diff --git a/sdk-libs/client/src/rpc/client.rs b/sdk-libs/client/src/rpc/client.rs index 3102de4a72..d96a352785 100644 --- a/sdk-libs/client/src/rpc/client.rs +++ b/sdk-libs/client/src/rpc/client.rs @@ -129,6 +129,24 @@ impl LightClient { self.indexer = Some(PhotonIndexer::new(path, api_key)); } + /// Detects the network type based on the RPC URL + fn detect_network(&self) -> RpcUrl { + let url = self.client.url(); + + if url.contains("devnet") { + RpcUrl::Devnet + } else if url.contains("testnet") { + RpcUrl::Testnet + } else if url.contains("localhost") || url.contains("127.0.0.1") { + RpcUrl::Localnet + } else if url.contains("zk-testnet") { + RpcUrl::ZKTestnet + } else { + // Default to mainnet for production URLs and custom URLs + RpcUrl::Custom(url.to_string()) + } + } + async fn retry(&self, operation: F) -> Result where F: Fn() -> Fut, @@ -662,11 +680,19 @@ impl Rpc for LightClient { /// Fetch the latest state tree addresses from the cluster. async fn get_latest_active_state_trees(&mut self) -> Result, RpcError> { - let res = default_state_tree_lookup_tables().0; + let network = self.detect_network(); + let (mainnet_tables, devnet_tables) = default_state_tree_lookup_tables(); + + let lookup_tables = match network { + RpcUrl::Devnet | RpcUrl::Testnet | RpcUrl::ZKTestnet => &devnet_tables, + RpcUrl::Localnet => &devnet_tables, // Use devnet tables for local development + _ => &mainnet_tables, // Default to mainnet for production and custom URLs + }; + let res = get_light_state_tree_infos( self, - &res[0].state_tree_lookup_table, - &res[0].nullify_table, + &lookup_tables[0].state_tree_lookup_table, + &lookup_tables[0].nullify_table, ) .await?; self.state_merkle_trees = res.clone(); From 7c8ff4501ad43ba937d510263523d02eaa92a3c6 Mon Sep 17 00:00:00 2001 From: ananas Date: Sun, 20 Jul 2025 20:52:13 +0100 Subject: [PATCH 2/3] fix: get_latest_active_state_trees for localnet with hardcoded values --- sdk-libs/client/src/rpc/client.rs | 36 +++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/sdk-libs/client/src/rpc/client.rs b/sdk-libs/client/src/rpc/client.rs index d96a352785..87cf603b48 100644 --- a/sdk-libs/client/src/rpc/client.rs +++ b/sdk-libs/client/src/rpc/client.rs @@ -132,7 +132,7 @@ impl LightClient { /// Detects the network type based on the RPC URL fn detect_network(&self) -> RpcUrl { let url = self.client.url(); - + if url.contains("devnet") { RpcUrl::Devnet } else if url.contains("testnet") { @@ -681,14 +681,42 @@ impl Rpc for LightClient { /// Fetch the latest state tree addresses from the cluster. async fn get_latest_active_state_trees(&mut self) -> Result, RpcError> { let network = self.detect_network(); + + // Return default test values for localnet + if matches!(network, RpcUrl::Localnet) { + use crate::indexer::TreeInfo; + use light_compressed_account::TreeType; + use solana_pubkey::pubkey; + + #[cfg(feature = "v2")] + let default_trees = vec![TreeInfo { + tree: pubkey!("HLKs5NJ8FXkJg8BrzJt56adFYYuwg5etzDtBbQYTsixu"), + queue: pubkey!("6L7SzhYB3anwEQ9cphpJ1U7Scwj57bx2xueReg7R9cKU"), + cpi_context: Some(pubkey!("7Hp52chxaew8bW1ApR4fck2bh6Y8qA1pu3qwH6N9zaLj")), + next_tree_info: None, + tree_type: TreeType::StateV2, + }]; + + #[cfg(not(feature = "v2"))] + let default_trees = vec![TreeInfo { + tree: pubkey!("smt1NamzXdq4AMqS2fS2F1i5KTYPZRhoHgWx38d8WsT"), + queue: pubkey!("nfq1NvQDJ2GEgnS8zt9prAe8rjjpAW1zFkrvZoBR148"), + cpi_context: Some(pubkey!("cpi1uHzrEhBG733DoEJNgHCyRS3XmmyVNZx5fonubE4")), + next_tree_info: None, + tree_type: TreeType::StateV1, + }]; + + self.state_merkle_trees = default_trees.clone(); + return Ok(default_trees); + } + let (mainnet_tables, devnet_tables) = default_state_tree_lookup_tables(); - + let lookup_tables = match network { RpcUrl::Devnet | RpcUrl::Testnet | RpcUrl::ZKTestnet => &devnet_tables, - RpcUrl::Localnet => &devnet_tables, // Use devnet tables for local development _ => &mainnet_tables, // Default to mainnet for production and custom URLs }; - + let res = get_light_state_tree_infos( self, &lookup_tables[0].state_tree_lookup_table, From f327271db8a993fc7434ecde8d2e3ec1494e0dc8 Mon Sep 17 00:00:00 2001 From: ananas Date: Sun, 20 Jul 2025 20:56:24 +0100 Subject: [PATCH 3/3] fix: lint --- sdk-libs/client/src/indexer/photon_indexer.rs | 6 +----- sdk-libs/client/src/rpc/client.rs | 5 +++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sdk-libs/client/src/indexer/photon_indexer.rs b/sdk-libs/client/src/indexer/photon_indexer.rs index 4ce19c11e3..c3129aaba5 100644 --- a/sdk-libs/client/src/indexer/photon_indexer.rs +++ b/sdk-libs/client/src/indexer/photon_indexer.rs @@ -132,11 +132,7 @@ impl PhotonIndexer { result: Option, ) -> Result { if let Some(error) = error { - let error_message = if let Some(message) = error.message.clone() { - message - } else { - format!("") - }; + let error_message = error.message.unwrap_or_default(); return Err(IndexerError::ApiError(format!( "API error in {} (code: {:?}): {}", context, error.code, error_message diff --git a/sdk-libs/client/src/rpc/client.rs b/sdk-libs/client/src/rpc/client.rs index 87cf603b48..494ee9a218 100644 --- a/sdk-libs/client/src/rpc/client.rs +++ b/sdk-libs/client/src/rpc/client.rs @@ -684,10 +684,11 @@ impl Rpc for LightClient { // Return default test values for localnet if matches!(network, RpcUrl::Localnet) { - use crate::indexer::TreeInfo; use light_compressed_account::TreeType; use solana_pubkey::pubkey; + use crate::indexer::TreeInfo; + #[cfg(feature = "v2")] let default_trees = vec![TreeInfo { tree: pubkey!("HLKs5NJ8FXkJg8BrzJt56adFYYuwg5etzDtBbQYTsixu"), @@ -696,7 +697,7 @@ impl Rpc for LightClient { next_tree_info: None, tree_type: TreeType::StateV2, }]; - + #[cfg(not(feature = "v2"))] let default_trees = vec![TreeInfo { tree: pubkey!("smt1NamzXdq4AMqS2fS2F1i5KTYPZRhoHgWx38d8WsT"),