tensor_eigen/
setup.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use anyhow::{anyhow, Result};
use dirs::home_dir;
use serde::{Deserialize, Serialize};
use solana_client::rpc_client::RpcClient;
use solana_sdk::{
    clock::Slot,
    commitment_config::CommitmentConfig,
    hash::Hash,
    signature::{read_keypair_file, Keypair},
};
use std::{fs::File, path::PathBuf, str::FromStr};

#[derive(Debug, Deserialize, Serialize)]
struct SolanaConfig {
    pub json_rpc_url: String,
    pub keypair_path: String,
    pub commitment: String,
}

pub struct CliConfig {
    pub client: RpcClient,
    pub keypair: Keypair,
    pub recent_blockhash: Hash,
    pub recent_slot: Slot,
}

#[derive(Debug, Default)]
pub struct CliConfigBuilder {
    pub json_rpc_url: Option<String>,
    pub keypair_path: Option<PathBuf>,
    pub commitment: Option<String>,
}

impl CliConfigBuilder {
    pub fn new() -> Self {
        Self {
            json_rpc_url: None,
            keypair_path: None,
            commitment: None,
        }
    }
    pub fn rpc_url(mut self, json_rpc_url: String) -> Self {
        self.json_rpc_url = Some(json_rpc_url);
        self
    }
    pub fn keypair_path(mut self, keypair_path: PathBuf) -> Self {
        self.keypair_path = Some(keypair_path);
        self
    }
    pub fn commitment(mut self, commitment: String) -> Self {
        self.commitment = Some(commitment);
        self
    }
    pub fn build(&self) -> Result<CliConfig> {
        let rpc_url = self
            .json_rpc_url
            .clone()
            .ok_or_else(|| anyhow!("No rpc url provided"))?;

        let commitment = match self.commitment.clone() {
            Some(commitment) => CommitmentConfig::from_str(&commitment)?,
            None => CommitmentConfig::confirmed(),
        };

        let client = RpcClient::new_with_commitment(rpc_url, commitment);

        let keypair_path = self
            .keypair_path
            .clone()
            .ok_or_else(|| anyhow!("No keypair path provided"))?;

        let keypair =
            read_keypair_file(keypair_path).map_err(|_| anyhow!("Unable to read keypair file"))?;

        let recent_blockhash = client.get_latest_blockhash()?;
        let recent_slot = client.get_slot()?;

        Ok(CliConfig {
            client,
            keypair,
            recent_blockhash,
            recent_slot,
        })
    }
}

impl CliConfig {
    pub fn new(keypair_path: Option<PathBuf>, rpc_url: Option<String>) -> Result<Self> {
        let mut builder = CliConfigBuilder::new();
        let solana_config = parse_solana_config();

        if let Some(config) = solana_config {
            builder = builder
                .rpc_url(config.json_rpc_url)
                .keypair_path(config.keypair_path.into())
                .commitment(config.commitment);
        }

        if let Some(keypair_path) = keypair_path {
            builder = builder.keypair_path(keypair_path);
        }

        if let Some(rpc_url) = rpc_url {
            builder = builder.rpc_url(rpc_url);
        }

        let config = builder.build()?;

        Ok(config)
    }

    #[allow(unused)]
    pub fn update_blocks(&mut self) -> Result<()> {
        self.recent_blockhash = self.client.get_latest_blockhash()?;
        self.recent_slot = self.client.get_slot()?;

        Ok(())
    }
}

fn parse_solana_config() -> Option<SolanaConfig> {
    let home_path = home_dir().expect("Couldn't find home dir");

    let solana_config_path = home_path
        .join(".config")
        .join("solana")
        .join("cli")
        .join("config.yml");

    let config_file = File::open(solana_config_path).ok();

    if let Some(config_file) = config_file {
        let config: SolanaConfig = serde_yaml::from_reader(config_file).ok()?;
        return Some(config);
    }
    None
}