mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
Externalise Grin command line definition to .yaml file (#2089)
* move command line definition to .yaml file * rustfmt
This commit is contained in:
parent
b8c8840cec
commit
40ccb32be2
9 changed files with 327 additions and 326 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -261,6 +261,7 @@ dependencies = [
|
||||||
"textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -695,7 +696,6 @@ dependencies = [
|
||||||
"humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"reqwest 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tar 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -950,6 +950,7 @@ dependencies = [
|
||||||
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -964,6 +965,7 @@ dependencies = [
|
||||||
"prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rpassword 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2872,6 +2874,11 @@ name = "xi-unicode"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -3189,5 +3196,6 @@ dependencies = [
|
||||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||||
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
||||||
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
|
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
|
||||||
|
"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"
|
||||||
"checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e"
|
"checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e"
|
||||||
"checksum zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822"
|
"checksum zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "36b9e08fb518a65cf7e08a1e482573eb87a2f4f8c6619316612a3c1f162fe822"
|
||||||
|
|
|
@ -20,7 +20,7 @@ path = "src/bin/grin.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
blake2-rfc = "0.2"
|
blake2-rfc = "0.2"
|
||||||
chrono = "0.4.4"
|
chrono = "0.4.4"
|
||||||
clap = "2.31"
|
clap = { version = "2.31", features = ["yaml"] }
|
||||||
ctrlc = { version = "3.1", features = ["termination"] }
|
ctrlc = { version = "3.1", features = ["termination"] }
|
||||||
cursive = "0.9.0"
|
cursive = "0.9.0"
|
||||||
humansize = "1.1.0"
|
humansize = "1.1.0"
|
||||||
|
@ -29,7 +29,6 @@ serde = "1"
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
term = "0.5"
|
term = "0.5"
|
||||||
rpassword = "2.0.0"
|
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
failure_derive = "0.1"
|
failure_derive = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ mod client;
|
||||||
mod config;
|
mod config;
|
||||||
mod server;
|
mod server;
|
||||||
mod wallet;
|
mod wallet;
|
||||||
mod wallet_args;
|
|
||||||
|
|
||||||
pub use self::client::client_command;
|
pub use self::client::client_command;
|
||||||
pub use self::config::{config_command_server, config_command_wallet};
|
pub use self::config::{config_command_server, config_command_wallet};
|
||||||
|
|
|
@ -17,10 +17,9 @@ use std::path::PathBuf;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::wallet_args;
|
|
||||||
use config::GlobalWalletConfig;
|
use config::GlobalWalletConfig;
|
||||||
use core::global;
|
use core::global;
|
||||||
use grin_wallet::{self, command, WalletConfig, WalletSeed};
|
use grin_wallet::{self, command, command_args, WalletConfig, WalletSeed};
|
||||||
use servers::start_webwallet_server;
|
use servers::start_webwallet_server;
|
||||||
|
|
||||||
// define what to do on argument error
|
// define what to do on argument error
|
||||||
|
@ -74,12 +73,14 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
|
||||||
wallet_config.check_node_api_http_addr = sa.to_string().clone();
|
wallet_config.check_node_api_http_addr = sa.to_string().clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let global_wallet_args =
|
let global_wallet_args = arg_parse!(command_args::parse_global_args(
|
||||||
arg_parse!(wallet_args::parse_global_args(&wallet_config, &wallet_args));
|
&wallet_config,
|
||||||
|
&wallet_args
|
||||||
|
));
|
||||||
|
|
||||||
// closure to instantiate wallet as needed by each subcommand
|
// closure to instantiate wallet as needed by each subcommand
|
||||||
let inst_wallet = || {
|
let inst_wallet = || {
|
||||||
let res = wallet_args::instantiate_wallet(wallet_config.clone(), &global_wallet_args);
|
let res = command_args::inst_wallet(wallet_config.clone(), &global_wallet_args);
|
||||||
res.unwrap_or_else(|e| {
|
res.unwrap_or_else(|e| {
|
||||||
println!("{}", e);
|
println!("{}", e);
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
|
@ -88,17 +89,17 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
|
||||||
|
|
||||||
let res = match wallet_args.subcommand() {
|
let res = match wallet_args.subcommand() {
|
||||||
("init", Some(args)) => {
|
("init", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_init_args(&wallet_config, &args));
|
let a = arg_parse!(command_args::parse_init_args(&wallet_config, &args));
|
||||||
command::init(&global_wallet_args, a)
|
command::init(&global_wallet_args, a)
|
||||||
}
|
}
|
||||||
("recover", Some(args)) => {
|
("recover", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_recover_args(&global_wallet_args, &args));
|
let a = arg_parse!(command_args::parse_recover_args(&global_wallet_args, &args));
|
||||||
command::recover(&wallet_config, a)
|
command::recover(&wallet_config, a)
|
||||||
}
|
}
|
||||||
("listen", Some(args)) => {
|
("listen", Some(args)) => {
|
||||||
let mut c = wallet_config.clone();
|
let mut c = wallet_config.clone();
|
||||||
let mut g = global_wallet_args.clone();
|
let mut g = global_wallet_args.clone();
|
||||||
arg_parse!(wallet_args::parse_listen_args(&mut c, &mut g, &args));
|
arg_parse!(command_args::parse_listen_args(&mut c, &mut g, &args));
|
||||||
command::listen(&wallet_config, &g)
|
command::listen(&wallet_config, &g)
|
||||||
}
|
}
|
||||||
("owner_api", Some(_)) => {
|
("owner_api", Some(_)) => {
|
||||||
|
@ -111,23 +112,23 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
|
||||||
command::owner_api(inst_wallet(), &global_wallet_args)
|
command::owner_api(inst_wallet(), &global_wallet_args)
|
||||||
}
|
}
|
||||||
("account", Some(args)) => {
|
("account", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_account_args(&args));
|
let a = arg_parse!(command_args::parse_account_args(&args));
|
||||||
command::account(inst_wallet(), a)
|
command::account(inst_wallet(), a)
|
||||||
}
|
}
|
||||||
("send", Some(args)) => {
|
("send", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_send_args(&args));
|
let a = arg_parse!(command_args::parse_send_args(&args));
|
||||||
command::send(inst_wallet(), a)
|
command::send(inst_wallet(), a)
|
||||||
}
|
}
|
||||||
("receive", Some(args)) => {
|
("receive", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_receive_args(&args));
|
let a = arg_parse!(command_args::parse_receive_args(&args));
|
||||||
command::receive(inst_wallet(), &global_wallet_args, a)
|
command::receive(inst_wallet(), &global_wallet_args, a)
|
||||||
}
|
}
|
||||||
("finalize", Some(args)) => {
|
("finalize", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_finalize_args(&args));
|
let a = arg_parse!(command_args::parse_finalize_args(&args));
|
||||||
command::finalize(inst_wallet(), a)
|
command::finalize(inst_wallet(), a)
|
||||||
}
|
}
|
||||||
("info", Some(args)) => {
|
("info", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_info_args(&args));
|
let a = arg_parse!(command_args::parse_info_args(&args));
|
||||||
command::info(
|
command::info(
|
||||||
inst_wallet(),
|
inst_wallet(),
|
||||||
&global_wallet_args,
|
&global_wallet_args,
|
||||||
|
@ -141,7 +142,7 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
|
||||||
wallet_config.dark_background_color_scheme.unwrap_or(true),
|
wallet_config.dark_background_color_scheme.unwrap_or(true),
|
||||||
),
|
),
|
||||||
("txs", Some(args)) => {
|
("txs", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_txs_args(&args));
|
let a = arg_parse!(command_args::parse_txs_args(&args));
|
||||||
command::txs(
|
command::txs(
|
||||||
inst_wallet(),
|
inst_wallet(),
|
||||||
&global_wallet_args,
|
&global_wallet_args,
|
||||||
|
@ -150,11 +151,11 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) -> i
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
("repost", Some(args)) => {
|
("repost", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_repost_args(&args));
|
let a = arg_parse!(command_args::parse_repost_args(&args));
|
||||||
command::repost(inst_wallet(), a)
|
command::repost(inst_wallet(), a)
|
||||||
}
|
}
|
||||||
("cancel", Some(args)) => {
|
("cancel", Some(args)) => {
|
||||||
let a = arg_parse!(wallet_args::parse_cancel_args(&args));
|
let a = arg_parse!(command_args::parse_cancel_args(&args));
|
||||||
command::cancel(inst_wallet(), a)
|
command::cancel(inst_wallet(), a)
|
||||||
}
|
}
|
||||||
("restore", Some(_)) => command::restore(inst_wallet()),
|
("restore", Some(_)) => command::restore(inst_wallet()),
|
||||||
|
|
305
src/bin/grin.rs
305
src/bin/grin.rs
|
@ -26,10 +26,7 @@ extern crate serde_json;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
extern crate rpassword;
|
|
||||||
extern crate term;
|
extern crate term;
|
||||||
#[macro_use]
|
|
||||||
extern crate failure_derive;
|
|
||||||
|
|
||||||
extern crate grin_api as api;
|
extern crate grin_api as api;
|
||||||
extern crate grin_config as config;
|
extern crate grin_config as config;
|
||||||
|
@ -45,7 +42,7 @@ pub mod tui;
|
||||||
|
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::App;
|
||||||
|
|
||||||
use config::config::{SERVER_CONFIG_FILE_NAME, WALLET_CONFIG_FILE_NAME};
|
use config::config::{SERVER_CONFIG_FILE_NAME, WALLET_CONFIG_FILE_NAME};
|
||||||
use core::global;
|
use core::global;
|
||||||
|
@ -85,304 +82,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn real_main() -> i32 {
|
fn real_main() -> i32 {
|
||||||
let args = App::new("Grin")
|
let yml = load_yaml!("grin.yml");
|
||||||
.version(crate_version!())
|
let args = App::from_yaml(yml).get_matches();
|
||||||
.author("The Grin Team")
|
|
||||||
.about("Lightweight implementation of the MimbleWimble protocol.")
|
|
||||||
// specification of all the server commands and options
|
|
||||||
.subcommand(SubCommand::with_name("server")
|
|
||||||
.about("Control the Grin server")
|
|
||||||
.arg(Arg::with_name("config_file")
|
|
||||||
.short("c")
|
|
||||||
.long("config_file")
|
|
||||||
.help("Path to a grin-server.toml configuration file")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("port")
|
|
||||||
.short("p")
|
|
||||||
.long("port")
|
|
||||||
.help("Port to start the P2P server on")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("api_port")
|
|
||||||
.short("api")
|
|
||||||
.long("api_port")
|
|
||||||
.help("Port on which to start the api server (e.g. transaction pool api)")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("seed")
|
|
||||||
.short("s")
|
|
||||||
.long("seed")
|
|
||||||
.help("Override seed node(s) to connect to")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("wallet_url")
|
|
||||||
.short("w")
|
|
||||||
.long("wallet_url")
|
|
||||||
.help("The wallet listener to which mining rewards will be sent")
|
|
||||||
.takes_value(true))
|
|
||||||
.subcommand(SubCommand::with_name("config")
|
|
||||||
.about("Generate a configuration grin-server.toml file in the current directory"))
|
|
||||||
.subcommand(SubCommand::with_name("start")
|
|
||||||
.about("Start the Grin server as a daemon"))
|
|
||||||
.subcommand(SubCommand::with_name("stop")
|
|
||||||
.about("Stop the Grin server daemon"))
|
|
||||||
.subcommand(SubCommand::with_name("run")
|
|
||||||
.about("Run the Grin server in this console")))
|
|
||||||
|
|
||||||
// specification of all the client commands and options
|
|
||||||
.subcommand(SubCommand::with_name("client")
|
|
||||||
.about("Communicates with the Grin server")
|
|
||||||
.subcommand(SubCommand::with_name("status")
|
|
||||||
.about("Current status of the Grin chain"))
|
|
||||||
.subcommand(SubCommand::with_name("listconnectedpeers")
|
|
||||||
.about("Print a list of currently connected peers"))
|
|
||||||
.subcommand(SubCommand::with_name("ban")
|
|
||||||
.about("Ban peer")
|
|
||||||
.arg(Arg::with_name("peer")
|
|
||||||
.short("p")
|
|
||||||
.long("peer")
|
|
||||||
.help("Peer ip and port (e.g. 10.12.12.13:13414)")
|
|
||||||
.required(true)
|
|
||||||
.takes_value(true)))
|
|
||||||
.subcommand(SubCommand::with_name("unban")
|
|
||||||
.about("Unban peer")
|
|
||||||
.arg(Arg::with_name("peer")
|
|
||||||
.short("p")
|
|
||||||
.long("peer")
|
|
||||||
.help("Peer ip and port (e.g. 10.12.12.13:13414)")
|
|
||||||
.required(true)
|
|
||||||
.takes_value(true))))
|
|
||||||
|
|
||||||
|
|
||||||
// specification of the wallet commands and options
|
|
||||||
.subcommand(SubCommand::with_name("wallet")
|
|
||||||
.about("Wallet software for Grin")
|
|
||||||
.arg(Arg::with_name("pass")
|
|
||||||
.short("p")
|
|
||||||
.long("pass")
|
|
||||||
.help("Wallet passphrase used to encrypt wallet seed")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("account")
|
|
||||||
.short("a")
|
|
||||||
.long("account")
|
|
||||||
.help("Wallet account to use for this operation")
|
|
||||||
.takes_value(true)
|
|
||||||
.default_value("default"))
|
|
||||||
.arg(Arg::with_name("data_dir")
|
|
||||||
.short("dd")
|
|
||||||
.long("data_dir")
|
|
||||||
.help("Directory in which to store wallet files (defaults to current \
|
|
||||||
directory)")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("external")
|
|
||||||
.short("e")
|
|
||||||
.long("external")
|
|
||||||
.help("Listen on 0.0.0.0 interface to allow external connections (default is 127.0.0.1)")
|
|
||||||
.takes_value(false))
|
|
||||||
.arg(Arg::with_name("show_spent")
|
|
||||||
.short("s")
|
|
||||||
.long("show_spent")
|
|
||||||
.help("Show spent outputs on wallet output command")
|
|
||||||
.takes_value(false))
|
|
||||||
.arg(Arg::with_name("api_server_address")
|
|
||||||
.short("r")
|
|
||||||
.long("api_server_address")
|
|
||||||
.help("Api address of running node on which to check inputs and post transactions")
|
|
||||||
.takes_value(true))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("account")
|
|
||||||
.about("List wallet accounts or create a new account")
|
|
||||||
.arg(Arg::with_name("create")
|
|
||||||
.short("c")
|
|
||||||
.long("create")
|
|
||||||
.help("Name of new wallet account")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("listen")
|
|
||||||
.about("Runs the wallet in listening mode waiting for transactions.")
|
|
||||||
.arg(Arg::with_name("port")
|
|
||||||
.short("l")
|
|
||||||
.long("port")
|
|
||||||
.help("Port on which to run the wallet listener")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("method")
|
|
||||||
.short("m")
|
|
||||||
.long("method")
|
|
||||||
.help("Which method to use for communication")
|
|
||||||
.possible_values(&["http", "keybase"])
|
|
||||||
.default_value("http")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("owner_api")
|
|
||||||
.about("Runs the wallet's local web API."))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("web")
|
|
||||||
.about("Runs the local web wallet which can be accessed through a browser"))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("send")
|
|
||||||
.about("Builds a transaction to send coins and sends it to the specified \
|
|
||||||
listener directly.")
|
|
||||||
.arg(Arg::with_name("amount")
|
|
||||||
.help("Number of coins to send with optional fraction, e.g. 12.423")
|
|
||||||
.index(1))
|
|
||||||
.arg(Arg::with_name("minimum_confirmations")
|
|
||||||
.help("Minimum number of confirmations required for an output to be spendable.")
|
|
||||||
.short("c")
|
|
||||||
.long("min_conf")
|
|
||||||
.default_value("10")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("selection_strategy")
|
|
||||||
.help("Coin/Output selection strategy.")
|
|
||||||
.short("s")
|
|
||||||
.long("selection")
|
|
||||||
.possible_values(&["all", "smallest"])
|
|
||||||
.default_value("all")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("change_outputs")
|
|
||||||
.help("Number of change outputs to generate (mainly for testing).")
|
|
||||||
.short("o")
|
|
||||||
.long("change_outputs")
|
|
||||||
.default_value("1")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("method")
|
|
||||||
.help("Method for sending this transaction.")
|
|
||||||
.short("m")
|
|
||||||
.long("method")
|
|
||||||
.possible_values(&["http", "file", "self", "keybase"])
|
|
||||||
.default_value("http")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("dest")
|
|
||||||
.help("Send the transaction to the provided server (start with http://) or save as file.")
|
|
||||||
.short("d")
|
|
||||||
.long("dest")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("fluff")
|
|
||||||
.help("Fluff the transaction (ignore Dandelion relay protocol)")
|
|
||||||
.short("f")
|
|
||||||
.long("fluff"))
|
|
||||||
.arg(Arg::with_name("message")
|
|
||||||
.help("Optional participant message to include")
|
|
||||||
.short("g")
|
|
||||||
.long("message")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("stored_tx")
|
|
||||||
.help("If present, use the previously stored Unconfirmed transaction with given id.")
|
|
||||||
.short("t")
|
|
||||||
.long("stored_tx")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("receive")
|
|
||||||
.about("Processes a transaction file to accept a transfer from a sender.")
|
|
||||||
.arg(Arg::with_name("message")
|
|
||||||
.help("Optional participant message to include")
|
|
||||||
.short("g")
|
|
||||||
.long("message")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("input")
|
|
||||||
.help("Partial transaction to process, expects the sender's transaction file.")
|
|
||||||
.short("i")
|
|
||||||
.long("input")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("finalize")
|
|
||||||
.about("Processes a receiver's transaction file to finalize a transfer.")
|
|
||||||
.arg(Arg::with_name("input")
|
|
||||||
.help("Partial transaction to process, expects the receiver's transaction file.")
|
|
||||||
.short("i")
|
|
||||||
.long("input")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("fluff")
|
|
||||||
.help("Fluff the transaction (ignore Dandelion relay protocol)")
|
|
||||||
.short("f")
|
|
||||||
.long("fluff")))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("burn")
|
|
||||||
.about("** TESTING ONLY ** Burns the provided amount to a known \
|
|
||||||
key. Similar to send but burns an output to allow single-party \
|
|
||||||
transactions.")
|
|
||||||
.arg(Arg::with_name("amount")
|
|
||||||
.help("Number of coins to burn")
|
|
||||||
.index(1))
|
|
||||||
.arg(Arg::with_name("minimum_confirmations")
|
|
||||||
.help("Minimum number of confirmations required for an output to be spendable.")
|
|
||||||
.short("c")
|
|
||||||
.long("min_conf")
|
|
||||||
.default_value("10")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("outputs")
|
|
||||||
.about("raw wallet output info (list of outputs)"))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("txs")
|
|
||||||
.about("Display transaction information")
|
|
||||||
.arg(Arg::with_name("id")
|
|
||||||
.help("If specified, display transaction with given ID and all associated Inputs/Outputs")
|
|
||||||
.short("i")
|
|
||||||
.long("id")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("repost")
|
|
||||||
.about("Reposts a stored, completed but unconfirmed transaction to the chain, or dumps it to a file")
|
|
||||||
.arg(Arg::with_name("id")
|
|
||||||
.help("Transaction ID Containing the stored completed transaction")
|
|
||||||
.short("i")
|
|
||||||
.long("id")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("dumpfile")
|
|
||||||
.help("File name to duMp the tranaction to instead of posting")
|
|
||||||
.short("m")
|
|
||||||
.long("dumpfile")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("fluff")
|
|
||||||
.help("Fluff the transaction (ignore Dandelion relay protocol)")
|
|
||||||
.short("f")
|
|
||||||
.long("fluff")))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("cancel")
|
|
||||||
.about("Cancels an previously created transaction, freeing previously locked outputs for use again")
|
|
||||||
.arg(Arg::with_name("id")
|
|
||||||
.help("The ID of the transaction to cancel")
|
|
||||||
.short("i")
|
|
||||||
.long("id")
|
|
||||||
.takes_value(true))
|
|
||||||
.arg(Arg::with_name("txid")
|
|
||||||
.help("The TxID of the transaction to cancel")
|
|
||||||
.short("t")
|
|
||||||
.long("txid")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("info")
|
|
||||||
.about("basic wallet contents summary")
|
|
||||||
.arg(Arg::with_name("minimum_confirmations")
|
|
||||||
.help("Minimum number of confirmations required for an output to be spendable.")
|
|
||||||
.short("c")
|
|
||||||
.long("min_conf")
|
|
||||||
.default_value("10")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("init")
|
|
||||||
.about("Initialize a new wallet seed file and database.")
|
|
||||||
.arg(Arg::with_name("here")
|
|
||||||
.short("h")
|
|
||||||
.long("here")
|
|
||||||
.help("Create wallet files in the current directory instead of the default ~/.grin directory")
|
|
||||||
.takes_value(false))
|
|
||||||
.arg(Arg::with_name("short_wordlist")
|
|
||||||
.help("Generate a 12 word recovery phrase/seed instead of default 24.")
|
|
||||||
.short("s")
|
|
||||||
.long("short_wordlist")
|
|
||||||
.takes_value(false)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("recover")
|
|
||||||
.about("recover (create a new wallet.seed file) from a recovery phrase")
|
|
||||||
.arg(Arg::with_name("recovery_phrase")
|
|
||||||
.help("12 or 24 word recovery phrase (encased in quotes).")
|
|
||||||
.short("p")
|
|
||||||
.long("recovery_phrase")
|
|
||||||
.takes_value(true)))
|
|
||||||
|
|
||||||
.subcommand(SubCommand::with_name("restore")
|
|
||||||
.about("Attempt to restore wallet contents from the chain using seed. \
|
|
||||||
NOTE: Backup wallet.* and run `wallet listen` before running restore.")))
|
|
||||||
|
|
||||||
.get_matches();
|
|
||||||
let mut wallet_config = None;
|
let mut wallet_config = None;
|
||||||
let mut node_config = None;
|
let mut node_config = None;
|
||||||
|
|
||||||
|
|
287
src/bin/grin.yml
Normal file
287
src/bin/grin.yml
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
name: grin
|
||||||
|
version: "0.4.2"
|
||||||
|
about: Lightweight implementation of the MimbleWimble protocol.
|
||||||
|
author: The Grin Team
|
||||||
|
|
||||||
|
subcommands:
|
||||||
|
- server:
|
||||||
|
about: Control the Grin server
|
||||||
|
args:
|
||||||
|
- config_file:
|
||||||
|
help: Path to a grin-server.toml configuration file
|
||||||
|
short: c
|
||||||
|
long: config_file
|
||||||
|
takes_value: true
|
||||||
|
- port:
|
||||||
|
help: Port to start the P2P server on
|
||||||
|
short: p
|
||||||
|
long: port
|
||||||
|
takes_value: true
|
||||||
|
- api_port:
|
||||||
|
help: Port on which to start the api server (e.g. transaction pool api)
|
||||||
|
short: api
|
||||||
|
long: api_port
|
||||||
|
takes_value: true
|
||||||
|
- seed:
|
||||||
|
help: Override seed node(s) to connect to
|
||||||
|
short: s
|
||||||
|
long: seed
|
||||||
|
takes_value: true
|
||||||
|
- wallet_url:
|
||||||
|
help: The wallet listener to which mining rewards will be sent
|
||||||
|
short: w
|
||||||
|
long: wallet_url
|
||||||
|
takes_value: true
|
||||||
|
subcommands:
|
||||||
|
- config:
|
||||||
|
about: Generate a configuration grin-server.toml file in the current directory
|
||||||
|
- start:
|
||||||
|
about: Start the Grin server as a daemon
|
||||||
|
- stop:
|
||||||
|
about: Stop the Grin server daemon
|
||||||
|
- run:
|
||||||
|
about: Run the Grin server in this console
|
||||||
|
- client:
|
||||||
|
about: Communicates with the Grin server
|
||||||
|
subcommands:
|
||||||
|
- status:
|
||||||
|
about: Current status of the Grin chain
|
||||||
|
- listconnectedpeers:
|
||||||
|
about: Print a list of currently connected peers
|
||||||
|
- ban:
|
||||||
|
about: Ban peer
|
||||||
|
args:
|
||||||
|
- peer:
|
||||||
|
help: Peer ip and port (e.g. 10.12.12.13:13414)
|
||||||
|
short: p
|
||||||
|
long: peer
|
||||||
|
required: true
|
||||||
|
takes_value: true
|
||||||
|
- unban:
|
||||||
|
about: Unban peer
|
||||||
|
args:
|
||||||
|
- peer:
|
||||||
|
help: Peer ip and port (e.g. 10.12.12.13:13414)
|
||||||
|
short: p
|
||||||
|
long: peer
|
||||||
|
required: true
|
||||||
|
takes_value: true
|
||||||
|
- wallet:
|
||||||
|
about: Wallet software for Grin
|
||||||
|
args:
|
||||||
|
- pass:
|
||||||
|
help: Wallet passphrase used to encrypt wallet seed
|
||||||
|
short: p
|
||||||
|
long: pass
|
||||||
|
takes_value: true
|
||||||
|
- account:
|
||||||
|
help: Wallet account to use for this operation
|
||||||
|
short: a
|
||||||
|
long: account
|
||||||
|
takes_value: true
|
||||||
|
default_value: default
|
||||||
|
- data_dir:
|
||||||
|
help: Directory in which to store wallet files
|
||||||
|
short: dd
|
||||||
|
long: data_dir
|
||||||
|
takes_value: true
|
||||||
|
- external:
|
||||||
|
help: Listen on 0.0.0.0 interface to allow external connections (default is 127.0.0.1)
|
||||||
|
short: e
|
||||||
|
long: external
|
||||||
|
takes_value: false
|
||||||
|
- show_spent:
|
||||||
|
help: Show spent outputs on wallet output commands
|
||||||
|
short: s
|
||||||
|
long: show_spent
|
||||||
|
takes_value: false
|
||||||
|
- api_server_address:
|
||||||
|
help: Api address of running node on which to check inputs and post transactions
|
||||||
|
short: r
|
||||||
|
long: api_server_address
|
||||||
|
takes_value: true
|
||||||
|
subcommands:
|
||||||
|
- account:
|
||||||
|
about: List wallet accounts or create a new account
|
||||||
|
args:
|
||||||
|
- create:
|
||||||
|
help: Create a new wallet account with provided name
|
||||||
|
short: c
|
||||||
|
long: create
|
||||||
|
takes_value: true
|
||||||
|
- listen:
|
||||||
|
about: Runs the wallet in listening mode waiting for transactions
|
||||||
|
args:
|
||||||
|
- port:
|
||||||
|
help: Port on which to run the wallet listener
|
||||||
|
short: l
|
||||||
|
long: port
|
||||||
|
takes_value: true
|
||||||
|
- method:
|
||||||
|
help: Which method to use for communication
|
||||||
|
short: m
|
||||||
|
long: method
|
||||||
|
possible_values:
|
||||||
|
- http
|
||||||
|
- keybase
|
||||||
|
default_value: http
|
||||||
|
takes_value: true
|
||||||
|
- owner_api:
|
||||||
|
about: Runs the wallet's local web API
|
||||||
|
- web:
|
||||||
|
about: Runs the local web wallet which can be accessed through a browser
|
||||||
|
- send:
|
||||||
|
about: Builds a transaction to send coins and sends to the specified listener directly
|
||||||
|
args:
|
||||||
|
- amount:
|
||||||
|
help: Number of coins to send with optional fraction, e.g. 12.423
|
||||||
|
index: 1
|
||||||
|
- minimum_confirmations:
|
||||||
|
help: Minimum number of confirmations required for an output to be spendable
|
||||||
|
short: c
|
||||||
|
long: min_conf
|
||||||
|
default_value: "10"
|
||||||
|
takes_value: true
|
||||||
|
- selection_strategy:
|
||||||
|
help: Coin/Output selection strategy.
|
||||||
|
short: s
|
||||||
|
long: selection
|
||||||
|
possible_values:
|
||||||
|
- all
|
||||||
|
- smallest
|
||||||
|
default_value: all
|
||||||
|
takes_value: true
|
||||||
|
- change_outputs:
|
||||||
|
help: Number of change outputs to generate (mainly for testing)
|
||||||
|
short: o
|
||||||
|
long: change_outputs
|
||||||
|
default_value: "1"
|
||||||
|
takes_value: true
|
||||||
|
- method:
|
||||||
|
help: Method for sending this transaction
|
||||||
|
short: m
|
||||||
|
long: method
|
||||||
|
possible_values:
|
||||||
|
- http
|
||||||
|
- file
|
||||||
|
- self
|
||||||
|
- keybase
|
||||||
|
default_value: http
|
||||||
|
takes_value: true
|
||||||
|
- dest:
|
||||||
|
help: Send the transaction to the provided server (start with http://) or save as file.
|
||||||
|
short: d
|
||||||
|
long: dest
|
||||||
|
takes_value: true
|
||||||
|
- fluff:
|
||||||
|
help: Fluff the transaction (ignore Dandelion relay protocol)
|
||||||
|
short: f
|
||||||
|
long: fluff
|
||||||
|
- message:
|
||||||
|
help: Optional participant message to include
|
||||||
|
short: g
|
||||||
|
long: message
|
||||||
|
takes_value: true
|
||||||
|
- stored_tx:
|
||||||
|
help: If present, use the previously stored Unconfirmed transaction with given id
|
||||||
|
short: t
|
||||||
|
long: stored_tx
|
||||||
|
takes_value: true
|
||||||
|
- receive:
|
||||||
|
about: Processes a transaction file to accept a transfer from a sender
|
||||||
|
args:
|
||||||
|
- message:
|
||||||
|
help: Optional participant message to include
|
||||||
|
short: g
|
||||||
|
long: message
|
||||||
|
takes_value: true
|
||||||
|
- input:
|
||||||
|
help: Partial transaction to process, expects the sender's transaction file.
|
||||||
|
short: i
|
||||||
|
long: input
|
||||||
|
takes_value: true
|
||||||
|
- finalize:
|
||||||
|
about: Processes a receiver's transaction file to finalize a transfer.
|
||||||
|
args:
|
||||||
|
- input:
|
||||||
|
help: Partial transaction to process, expects the receiver's transaction file.
|
||||||
|
short: i
|
||||||
|
long: input
|
||||||
|
takes_value: true
|
||||||
|
- fluff:
|
||||||
|
help: Fluff the transaction (ignore Dandelion relay protocol)
|
||||||
|
short: f
|
||||||
|
long: fluff
|
||||||
|
- outputs:
|
||||||
|
about: Raw wallet output info (list of outputs)
|
||||||
|
- txs:
|
||||||
|
about: Display transaction information
|
||||||
|
args:
|
||||||
|
- id:
|
||||||
|
help: If specified, display transaction with given Id and all associated Inputs/Outputs
|
||||||
|
short: i
|
||||||
|
long: id
|
||||||
|
takes_value: true
|
||||||
|
- repost:
|
||||||
|
about: Reposts a stored, completed but unconfirmed transaction to the chain, or dumps it to a file
|
||||||
|
args:
|
||||||
|
- id:
|
||||||
|
help: Transaction ID containing the stored completed transaction
|
||||||
|
short: i
|
||||||
|
long: id
|
||||||
|
takes_value: true
|
||||||
|
- dumpfile:
|
||||||
|
help: File name to duMp the transaction to instead of posting
|
||||||
|
short: m
|
||||||
|
long: dumpfile
|
||||||
|
takes_value: true
|
||||||
|
- fluff:
|
||||||
|
help: Fluff the transaction (ignore Dandelion relay protocol)
|
||||||
|
short: f
|
||||||
|
long: fluff
|
||||||
|
- cancel:
|
||||||
|
about: Cancels an previously created transaction, freeing previously locked outputs for use again
|
||||||
|
args:
|
||||||
|
- id:
|
||||||
|
help: The ID of the transaction to cancel
|
||||||
|
short: i
|
||||||
|
long: id
|
||||||
|
takes_value: true
|
||||||
|
- txid:
|
||||||
|
help: The TxID UUID of the transaction to cancel
|
||||||
|
short: t
|
||||||
|
long: txid
|
||||||
|
takes_value: true
|
||||||
|
- info:
|
||||||
|
about: Basic wallet contents summary
|
||||||
|
args:
|
||||||
|
- minimum_confirmations:
|
||||||
|
help: Minimum number of confirmations required for an output to be spendable
|
||||||
|
short: c
|
||||||
|
long: min_conf
|
||||||
|
default_value: "10"
|
||||||
|
takes_value: true
|
||||||
|
- init:
|
||||||
|
about: Initialize a new wallet seed file and database
|
||||||
|
args:
|
||||||
|
- here:
|
||||||
|
help: Create wallet files in the current directory instead of the default ~/.grin directory
|
||||||
|
short: h
|
||||||
|
long: here
|
||||||
|
takes_value: false
|
||||||
|
- short_wordlist:
|
||||||
|
help: Generate a 12-word recovery phrase/seed instead of default 24
|
||||||
|
short: s
|
||||||
|
long: short_wordlist
|
||||||
|
takes_value: false
|
||||||
|
- recover:
|
||||||
|
about: recover (create a new wallet.seed file) from a recovery phrase
|
||||||
|
args:
|
||||||
|
- recovery_phrase:
|
||||||
|
help: 12 or 24 word recovery phrase (encased in quotes).
|
||||||
|
short: p
|
||||||
|
long: recovery_phrase
|
||||||
|
takes_value: true
|
||||||
|
- restore:
|
||||||
|
about: Initialize a new wallet seed file and database
|
||||||
|
|
|
@ -11,6 +11,8 @@ publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
blake2-rfc = "0.2"
|
blake2-rfc = "0.2"
|
||||||
|
clap = "2.31"
|
||||||
|
rpassword = "2.0.0"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
failure_derive = "0.1"
|
failure_derive = "0.1"
|
||||||
|
|
|
@ -18,9 +18,10 @@ use failure::Fail;
|
||||||
|
|
||||||
use api::TLSConfig;
|
use api::TLSConfig;
|
||||||
use core::core;
|
use core::core;
|
||||||
use grin_wallet::{self, command, WalletConfig, WalletSeed};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use util::file::get_first_line;
|
use util::file::get_first_line;
|
||||||
|
use ErrorKind;
|
||||||
|
use {command, instantiate_wallet, WalletConfig, WalletSeed};
|
||||||
|
|
||||||
/// Simple error definition, just so we can return errors from all commands
|
/// Simple error definition, just so we can return errors from all commands
|
||||||
/// and let the caller figure out what to do
|
/// and let the caller figure out what to do
|
||||||
|
@ -59,12 +60,12 @@ fn prompt_password_confirm() -> String {
|
||||||
|
|
||||||
// instantiate wallet (needed by most functions)
|
// instantiate wallet (needed by most functions)
|
||||||
|
|
||||||
pub fn instantiate_wallet(
|
pub fn inst_wallet(
|
||||||
config: WalletConfig,
|
config: WalletConfig,
|
||||||
g_args: &command::GlobalArgs,
|
g_args: &command::GlobalArgs,
|
||||||
) -> Result<command::WalletRef, Error> {
|
) -> Result<command::WalletRef, Error> {
|
||||||
let passphrase = prompt_password(&g_args.password);
|
let passphrase = prompt_password(&g_args.password);
|
||||||
let res = grin_wallet::instantiate_wallet(
|
let res = instantiate_wallet(
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&passphrase,
|
&passphrase,
|
||||||
&g_args.account,
|
&g_args.account,
|
||||||
|
@ -75,7 +76,7 @@ pub fn instantiate_wallet(
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let msg = {
|
let msg = {
|
||||||
match e.kind() {
|
match e.kind() {
|
||||||
grin_wallet::ErrorKind::Encryption => {
|
ErrorKind::Encryption => {
|
||||||
format!("Error decrypting wallet seed (check provided password)")
|
format!("Error decrypting wallet seed (check provided password)")
|
||||||
}
|
}
|
||||||
_ => format!("Error instantiating wallet: {}", e),
|
_ => format!("Error instantiating wallet: {}", e),
|
|
@ -27,6 +27,8 @@ extern crate serde_json;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
extern crate clap;
|
||||||
|
extern crate rpassword;
|
||||||
extern crate term;
|
extern crate term;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
|
@ -49,6 +51,7 @@ extern crate grin_util as util;
|
||||||
|
|
||||||
mod adapters;
|
mod adapters;
|
||||||
pub mod command;
|
pub mod command;
|
||||||
|
pub mod command_args;
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
pub mod display;
|
pub mod display;
|
||||||
mod error;
|
mod error;
|
||||||
|
|
Loading…
Reference in a new issue