-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmain.rs
More file actions
110 lines (93 loc) · 2.9 KB
/
Copy pathmain.rs
File metadata and controls
110 lines (93 loc) · 2.9 KB
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
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>> {
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",
)),
}
}