Skip to content

Commit

Permalink
integrate rpc client
Browse files Browse the repository at this point in the history
  • Loading branch information
pgarg66 committed Oct 6, 2023
1 parent 5982bbf commit c6a06d5
Show file tree
Hide file tree
Showing 7 changed files with 379 additions and 17 deletions.
67 changes: 65 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ tokio-serde = "0.8"
tokio-stream = "0.1.14"
tokio-tungstenite = "0.20.1"
tokio-util = "0.6"
toml = "0.8.0"
tonic = "0.9.2"
tonic-build = "0.9.2"
trees = "0.4.2"
Expand Down
11 changes: 11 additions & 0 deletions cargo-registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,26 @@ license = { workspace = true }
edition = { workspace = true }

[dependencies]
clap = { workspace = true }
flate2 = { workspace = true }
git2 = { workspace = true }
hyper = { workspace = true, features = ["full"] }
hyper-staticfile = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
solana-clap-utils = { workspace = true }
solana-cli = { workspace = true }
solana-cli-config = { workspace = true }
solana-cli-output = { workspace = true }
solana-remote-wallet = { workspace = true, features = ["default"] }
solana-rpc-client = { workspace = true, features = ["default"] }
solana-rpc-client-api = { workspace = true }
solana-sdk = { workspace = true }
solana-version = { workspace = true }
tar = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true, features = ["full"] }
toml = { workspace = true }

[dev-dependencies]

Expand Down
212 changes: 212 additions & 0 deletions cargo-registry/src/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
use {
clap::{crate_description, crate_name, value_t_or_exit, App, Arg, ArgMatches},
solana_clap_utils::{
hidden_unless_forced,
input_validators::is_url_or_moniker,
keypair::{DefaultSigner, SignerIndex},
},
solana_cli::{
cli::{DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS, DEFAULT_RPC_TIMEOUT_SECONDS},
program_v4::ProgramV4CommandConfig,
},
solana_cli_config::{Config, ConfigInput},
solana_cli_output::OutputFormat,
solana_rpc_client::rpc_client::RpcClient,
solana_sdk::{
commitment_config,
signature::{read_keypair_file, Keypair},
},
std::{error, sync::Arc, time::Duration},
};

pub struct ClientConfig<'a>(pub ProgramV4CommandConfig<'a>);

impl<'a> ClientConfig<'a> {
pub fn new(client: &'a Client) -> Self {
Self {
0: ProgramV4CommandConfig {
websocket_url: &client.websocket_url,
commitment: client.commitment,
payer: &client.cli_signers[0],
authority: &client.cli_signers[client.authority_signer_index],
output_format: &OutputFormat::Display,
use_quic: true,
},
}
}
}

pub struct Client {
pub rpc_client: Arc<RpcClient>,
pub port: u16,
websocket_url: String,
commitment: commitment_config::CommitmentConfig,
cli_signers: Vec<Keypair>,
authority_signer_index: SignerIndex,
}

impl Client {
fn get_keypair(
matches: &ArgMatches<'_>,
config_path: &str,
name: &str,
) -> Result<Keypair, Box<dyn error::Error>> {
let (_, default_signer_path) = ConfigInput::compute_keypair_path_setting(
matches.value_of(name).unwrap_or(""),
config_path,
);

let default_signer = DefaultSigner::new(name, &default_signer_path);

read_keypair_file(default_signer.path)
}

fn get_clap_app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, 'v> {
App::new(name)
.about(about)
.version(version)
.arg(
Arg::with_name("config_file")
.short("C")
.long("config")
.value_name("FILEPATH")
.takes_value(true)
.global(true)
.help("Configuration file to use"),
)
.arg(
Arg::with_name("json_rpc_url")
.short("u")
.long("url")
.value_name("URL_OR_MONIKER")
.takes_value(true)
.global(true)
.validator(is_url_or_moniker)
.help(
"URL for Solana's JSON RPC or moniker (or their first letter): \
[mainnet-beta, testnet, devnet, localhost]",
),
)
.arg(
Arg::with_name("keypair")
.short("k")
.long("keypair")
.value_name("KEYPAIR")
.global(true)
.takes_value(true)
.help("Filepath or URL to a keypair"),
)
.arg(
Arg::with_name("authority")
.short("a")
.long("authority")
.value_name("KEYPAIR")
.global(true)
.takes_value(true)
.help("Filepath or URL to program authority keypair"),
)
.arg(
Arg::with_name("port")
.short("p")
.long("port")
.value_name("PORT")
.global(true)
.takes_value(true)
.help("Cargo registry's local TCP port. The server will bind to this port and wait for requests."),
)
.arg(
Arg::with_name("commitment")
.long("commitment")
.takes_value(true)
.possible_values(&[
"processed",
"confirmed",
"finalized",
])
.value_name("COMMITMENT_LEVEL")
.hide_possible_values(true)
.global(true)
.help("Return information at the selected commitment level [possible values: processed, confirmed, finalized]"),
)
.arg(
Arg::with_name("rpc_timeout")
.long("rpc-timeout")
.value_name("SECONDS")
.takes_value(true)
.default_value(DEFAULT_RPC_TIMEOUT_SECONDS)
.global(true)
.hidden(hidden_unless_forced())
.help("Timeout value for RPC requests"),
)
.arg(
Arg::with_name("confirm_transaction_initial_timeout")
.long("confirm-timeout")
.value_name("SECONDS")
.takes_value(true)
.default_value(DEFAULT_CONFIRM_TX_TIMEOUT_SECONDS)
.global(true)
.hidden(hidden_unless_forced())
.help("Timeout value for initial transaction status"),
)
}

pub fn new() -> Result<Client, Box<dyn error::Error>> {
let matches = Self::get_clap_app(
crate_name!(),
crate_description!(),
solana_version::version!(),
)
.get_matches();

let config = if let Some(config_file) = matches.value_of("config_file") {
Config::load(config_file).unwrap_or_default()
} else {
Config::default()
};

let (_, json_rpc_url) = ConfigInput::compute_json_rpc_url_setting(
matches.value_of("json_rpc_url").unwrap_or(""),
&config.json_rpc_url,
);

let (_, websocket_url) = ConfigInput::compute_websocket_url_setting(
matches.value_of("websocket_url").unwrap_or(""),
&config.websocket_url,
matches.value_of("json_rpc_url").unwrap_or(""),
&config.json_rpc_url,
);

let (_, commitment) = ConfigInput::compute_commitment_config(
matches.value_of("commitment").unwrap_or(""),
&config.commitment,
);

let rpc_timeout = value_t_or_exit!(matches, "rpc_timeout", u64);
let rpc_timeout = Duration::from_secs(rpc_timeout);

let confirm_transaction_initial_timeout =
value_t_or_exit!(matches, "confirm_transaction_initial_timeout", u64);
let confirm_transaction_initial_timeout =
Duration::from_secs(confirm_transaction_initial_timeout);

let payer_keypair = Self::get_keypair(&matches, &config.keypair_path, "keypair".as_ref())?;
let authority_keypair =
Self::get_keypair(&matches, &config.keypair_path, "authority".as_ref())?;

let port = value_t_or_exit!(matches, "port", u16);

Ok(Client {
rpc_client: Arc::new(RpcClient::new_with_timeouts_and_commitment(
json_rpc_url.to_string(),
rpc_timeout,
commitment,
confirm_transaction_initial_timeout,
)),
port,
websocket_url,
commitment,
cli_signers: vec![payer_keypair, authority_keypair],
authority_signer_index: 1,
})
}
}
Loading

0 comments on commit c6a06d5

Please sign in to comment.