Skip to main content

percli_chain/
config.rs

1use anyhow::{Context, Result};
2use solana_sdk::{
3    pubkey::Pubkey,
4    signature::Keypair,
5    signer::Signer,
6};
7use std::str::FromStr;
8
9const DEFAULT_PROGRAM_ID: &str = "PercQhVBxXnVCaAhfrPZFc2dVZcQANnwEYroogLJFwm";
10const DEFAULT_RPC_URL: &str = "https://api.devnet.solana.com";
11
12pub struct ChainConfig {
13    pub rpc_url: String,
14    pub keypair: Keypair,
15    pub program_id: Pubkey,
16}
17
18impl ChainConfig {
19    pub fn new(
20        rpc_url: Option<&str>,
21        keypair_path: Option<&str>,
22        program_id: Option<&str>,
23    ) -> Result<Self> {
24        let rpc_url = match rpc_url {
25            Some("devnet") => DEFAULT_RPC_URL.to_string(),
26            Some("mainnet") => "https://api.mainnet-beta.solana.com".to_string(),
27            Some("localhost" | "local") => "http://127.0.0.1:8899".to_string(),
28            Some(url) => url.to_string(),
29            None => DEFAULT_RPC_URL.to_string(),
30        };
31
32        let keypair_path = keypair_path
33            .map(|s| s.to_string())
34            .unwrap_or_else(|| {
35                let home = std::env::var("HOME").unwrap_or_default();
36                format!("{home}/.config/solana/id.json")
37            });
38
39        let keypair_bytes = std::fs::read(&keypair_path)
40            .with_context(|| format!("Failed to read keypair from {keypair_path}"))?;
41        let keypair_json: Vec<u8> = serde_json::from_slice(&keypair_bytes)
42            .with_context(|| "Invalid keypair JSON format")?;
43        let keypair = Keypair::try_from(keypair_json.as_slice())
44            .map_err(|e| anyhow::anyhow!("Invalid keypair bytes: {e}"))?;
45
46        let program_id = match program_id {
47            Some(id) => Pubkey::from_str(id)
48                .with_context(|| format!("Invalid program ID: {id}"))?,
49            None => Pubkey::from_str(DEFAULT_PROGRAM_ID).unwrap(),
50        };
51
52        Ok(Self {
53            rpc_url,
54            keypair,
55            program_id,
56        })
57    }
58
59    pub fn authority(&self) -> Pubkey {
60        self.keypair.pubkey()
61    }
62
63    pub fn market_pda(&self) -> (Pubkey, u8) {
64        Pubkey::find_program_address(
65            &[b"market", self.authority().as_ref()],
66            &self.program_id,
67        )
68    }
69}