Skip to content

api: add Client #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions spaces-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ description = "spacesvm cli for issuing RPC commands"
license = "BSD-3-Clause"
homepage = "https://avax.network"

[[bin]]
name = "spaces-cli"
path = "src/bin/spaces-cli/main.rs"

[dependencies]
avalanche-types = { version = "0.0.138", features = ["subnet"] }
clap = { version = "4.0", features = ["derive"] }
hex = "0.4.3"
jsonrpc-core = "18.0.0"
jsonrpc-core-client = { version = "18.0.0" }
jsonrpc-client-transports = "18.0.0"
jsonrpc-derive = "18.0"
log = "0.4.17"
spacesvm = { path = "../spacesvm" }
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.87"
tokio = { version = "1.21.2", features = ["full"] }
spacesvm = { path = "../spacesvm" }
tokio = { version = "1.22.0", features = ["full"] }
110 changes: 110 additions & 0 deletions spaces-cli/src/bin/spaces-cli/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::error;

use clap::{Parser, Subcommand};
use jsonrpc_core::futures;
use spacesvm::{
api::{
client::{claim_tx, delete_tx, get_or_create_pk, set_tx, Client, Uri},
DecodeTxArgs, IssueTxArgs, ResolveArgs,
},
chain::tx::{decoder, unsigned::TransactionData},
};

#[derive(Subcommand, Debug)]
enum Command {
Claim {
space: String,
},
Set {
space: String,
key: String,
value: String,
},
Delete {
space: String,
key: String,
},
Get {
space: String,
key: String,
},
Ping {},
}

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
/// Endpoint for RPC calls.
#[clap(long)]
endpoint: String,

/// Private key file.
#[clap(long, default_value = ".spacesvm-cli-pk")]
private_key_file: String,

/// Which subcommand to call.
#[command(subcommand)]
command: Command,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn error::Error>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to use the anyhow::Result<> type as the response type. I especially like it for CLI tools. We don't have to end up with a type erased box in the signature.

For an example, see https://github.com/exdx/dcp/blob/main/src/main.rs

We could tackle this as a follow-up though.

let cli = Cli::parse();

let secret_key = get_or_create_pk(&cli.private_key_file)?;
let uri = cli.endpoint.parse::<Uri>()?;
let mut client = Client::new(uri);

if let Command::Get { space, key } = &cli.command {
let resp = futures::executor::block_on(client.resolve(ResolveArgs {
space: space.as_bytes().to_vec(),
key: key.as_bytes().to_vec(),
}))
.map_err(|e| e.to_string())?;
log::debug!("resolve response: {:?}", resp);

println!("{}", serde_json::to_string(&resp)?);
return Ok(());
}

if let Command::Ping {} = &cli.command {
let resp = futures::executor::block_on(client.ping()).map_err(|e| e.to_string())?;

println!("{}", serde_json::to_string(&resp)?);
return Ok(());
}

// decode tx
let tx_data = command_to_tx(cli.command)?;
let resp = futures::executor::block_on(client.decode_tx(DecodeTxArgs { tx_data }))
.map_err(|e| e.to_string())?;

let typed_data = &resp.typed_data;

// create signature
let dh = decoder::hash_structured_data(typed_data)?;
let sig = secret_key.sign_digest(&dh.as_bytes())?;

// issue tx
let resp = futures::executor::block_on(client.issue_tx(IssueTxArgs {
typed_data: resp.typed_data,
signature: sig.to_bytes().to_vec(),
}))
.map_err(|e| e.to_string())?;
println!("{}", serde_json::to_string(&resp)?);

Ok(())
}

/// Takes a TX command and returns transaction data.
fn command_to_tx(command: Command) -> std::io::Result<TransactionData> {
match command {
Command::Claim { space } => Ok(claim_tx(space)),
Command::Set { space, key, value } => Ok(set_tx(space, key, value.as_bytes().to_vec())),
Command::Delete { space, key } => Ok(delete_tx(space, key)),
_ => Err(std::io::Error::new(
std::io::ErrorKind::Other,
"not a supported tx",
)),
}
}
194 changes: 0 additions & 194 deletions spaces-cli/src/main.rs

This file was deleted.

9 changes: 7 additions & 2 deletions spacesvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ name = "spacesvm"
path = "src/bin/spaces/main.rs"

[dependencies]
avalanche-types = { version = "0.0.138", features = ["subnet"] }
avalanche-types = { version = "0.0.140", features = ["subnet"] }
byteorder = "1.4.3"
chrono = "0.4.22"
crossbeam-channel = "0.5.6"
Expand All @@ -27,6 +27,7 @@ eip-712 = "0.1.0"
env_logger = "0.9.3"
hex = "0.4.3"
http = "0.2.8"
hyper = "0.14.23"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can create a new feature client and make stuff like hyper optional.

jsonrpc-core = "18.0.0"
jsonrpc-core-client = { version = "18.0.0" }
jsonrpc-derive = "18.0"
Expand All @@ -47,4 +48,8 @@ typetag = "0.2"

[dev-dependencies]
jsonrpc-tcp-server = "18.0.0"
futures-test = "0.3.24"
futures-test = "0.3.24"

[[test]]
name = "integration"
path = "tests/integration_tests.rs"
Loading