Skip to content

Commit 2c542f9

Browse files
author
Stanisław Drozd
authored
xc-tool: Initial commit (#366)
1 parent c3f34a0 commit 2c542f9

File tree

5 files changed

+339
-0
lines changed

5 files changed

+339
-0
lines changed

xc-tool/Cargo.lock

Lines changed: 215 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

xc-tool/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "pyth-xc-tool"
3+
authors = ["Pyth Network Contributors"]
4+
description = "The cross-chain priest for the Pyth oracle (it knows all the rituals)"
5+
version = "0.1.0"
6+
edition = "2021"
7+
8+
[dependencies]
9+
clap = {version = "4.0", features = ["derive", "cargo"]}
10+
shell-words = "1.1.0"

xc-tool/src/cli.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use clap::{Parser, Subcommand, ValueEnum};
2+
3+
#[derive(Parser)]
4+
#[clap(
5+
about = "Pyth Tool - the admin swiss army knife",
6+
author = "Pyth Network Contributors"
7+
)]
8+
pub struct Cli {
9+
#[clap(subcommand)]
10+
pub action: Action,
11+
/// Mainnet/testnet
12+
#[clap(default_value = "testnet")]
13+
pub net: Net,
14+
}
15+
16+
/// This struct helps reuse action parsing logic for interactive mode.
17+
#[derive(Parser)]
18+
#[clap(
19+
about = "Pyth Tool - the admin swiss army knife",
20+
author = "Pyth Network Contributors"
21+
)]
22+
pub struct CliInteractive {
23+
#[clap(subcommand)]
24+
pub action: Action,
25+
}
26+
27+
#[derive(Subcommand, PartialEq)]
28+
pub enum Action {
29+
#[clap(about = "Attempt sanity-check access for all known blockchains")]
30+
PingAll,
31+
#[clap(about = "Fires up a repl letting user directly perform all other actions")]
32+
Interactive,
33+
}
34+
35+
/// For most chains, we pick a production blockchain network and a
36+
/// testing one, closely following Wormhole's choices.
37+
#[derive(ValueEnum, Clone)]
38+
pub enum Net {
39+
Mainnet,
40+
Testnet,
41+
}

xc-tool/src/main.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
mod cli;
2+
mod util;
3+
4+
use clap::Parser;
5+
6+
use std::io::{self, Write};
7+
8+
use cli::{Action, Cli, CliInteractive};
9+
10+
use util::ErrBox;
11+
12+
pub const PROMPT: &'static str = concat!(env!("CARGO_PKG_NAME"), "> ");
13+
14+
fn main() -> Result<(), ErrBox> {
15+
let cli = Cli::parse();
16+
17+
// Handle interactive mode separately
18+
if cli.action == Action::Interactive {
19+
start_cli_interactive(cli)?;
20+
} else {
21+
handle_action_noninteractive(&cli)?;
22+
}
23+
Ok(())
24+
}
25+
26+
pub fn start_cli_interactive(mut cli: Cli) -> Result<(), ErrBox> {
27+
let stdin = io::stdin();
28+
loop {
29+
print!("{}", PROMPT);
30+
io::stdout().flush()?;
31+
let mut ln = String::new();
32+
stdin.read_line(&mut ln)?;
33+
34+
if ln.trim().is_empty() {
35+
continue;
36+
}
37+
38+
match shell_words::split(&ln)
39+
.map_err(|e| -> ErrBox { e.into() })
40+
.and_then(|mut shell_split| {
41+
// Trick clap into thinking there's a binary name
42+
let mut with_name = vec!["".to_owned()];
43+
with_name.append(&mut shell_split);
44+
Ok(CliInteractive::try_parse_from(with_name)?)
45+
})
46+
.and_then(|cmd| {
47+
// We just swap out the action, preserving the top-level arguments
48+
cli.action = cmd.action;
49+
Ok(handle_action_noninteractive(&cli)?)
50+
}) {
51+
Err(e) => {
52+
println!("Could not understand that! Error:\n{}", e.to_string());
53+
}
54+
Ok(()) => {}
55+
};
56+
}
57+
}
58+
59+
/// The following code is reused by interactive mode. Interactive mode
60+
/// is assumed to already be detected at top-level in main, making it an invalid action.
61+
pub fn handle_action_noninteractive(cli: &Cli) -> Result<(), ErrBox> {
62+
match &cli.action {
63+
// It makes no sense starting interactive already inside it
64+
Action::Interactive => {
65+
return Err(format!("Bruh...?").into());
66+
}
67+
Action::PingAll => {
68+
println!("Pinging all blockchains...");
69+
}
70+
}
71+
Ok(())
72+
}

xc-tool/src/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub type ErrBox = Box<dyn std::error::Error>;

0 commit comments

Comments
 (0)