Skip to content

Commit

Permalink
feat(collectibles): add list assets command (#3908)
Browse files Browse the repository at this point in the history
Add the ability to list assets via the cli.

Run `tari_collectibles --help` for details
  • Loading branch information
stringhandler authored May 3, 2022
1 parent d2ceedc commit 5b726a6
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 131 deletions.
100 changes: 97 additions & 3 deletions applications/tari_collectibles/src-tauri/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use clap::Parser;
use crate::{
app_state::ConcurrentAppState, commands, commands::assets::inner_assets_list_registered_assets,
};
use clap::{Parser, Subcommand};
use tari_app_utilities::common_cli_args::CommonCliArgs;
use tari_common::exit_codes::{ExitCode, ExitError};
use uuid::Uuid;

const DEFAULT_NETWORK: &str = "dibbler";

Expand All @@ -32,8 +37,8 @@ pub(crate) struct Cli {
#[clap(flatten)]
pub common: CommonCliArgs,
/// Command to run
#[clap(long)]
pub command: Option<String>,
#[clap(subcommand)]
pub command: Option<Commands>,
/// Supply a network (overrides existing configuration)
#[clap(long, default_value = DEFAULT_NETWORK)]
pub network: String,
Expand All @@ -49,3 +54,92 @@ impl Cli {
overrides
}
}

#[derive(Subcommand, Debug)]
pub enum Commands {
ListAssets {
#[clap(default_value = "0")]
offset: u64,
#[clap(default_value = "20")]
count: u64,
},
MakeItRain {
asset_public_key: String,
amount_per_transaction: u64,
number_transactions: u32,
destination_address: String,
source_address: Option<String>,
},
}

pub fn list_assets(offset: u64, count: u64, state: &ConcurrentAppState) -> Result<(), ExitError> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to build a runtime!");
match runtime.block_on(inner_assets_list_registered_assets(offset, count, state)) {
Ok(rows) => {
println!("{}", serde_json::to_string_pretty(&rows).unwrap());
Ok(())
}
Err(e) => Err(ExitError::new(ExitCode::CommandError, &e)),
}
}

// make-it-rain <asset_public_key> <amount_per_transaction> <number_transactions> <destination address> <source address - optional>
pub(crate) fn make_it_rain(
asset_public_key: String,
amount: u64,
number_transactions: u32,
to_address: String,
source_address: Option<String>,
state: &ConcurrentAppState,
) -> Result<(), ExitError> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to build a runtime!");
let id = match runtime.block_on(commands::wallets::inner_wallets_list(state)) {
Ok(rows) => {
if rows.is_empty() {
return Err(ExitError::new(
ExitCode::CommandError,
"There is no wallet!",
));
}
match source_address {
Some(source_address) => {
let source_uuid = Uuid::parse_str(&source_address)
.map_err(|e| ExitError::new(ExitCode::CommandError, &e))?;
if !rows.iter().any(|wallet| wallet.id == source_uuid) {
return Err(ExitError::new(ExitCode::CommandError, "Wallet not found!"));
}
source_uuid
}
None => rows[0].id,
}
}
Err(e) => {
return Err(ExitError::new(ExitCode::CommandError, e.to_string()));
}
};

runtime
.block_on(commands::wallets::inner_wallets_unlock(id, state))
.map_err(|e| ExitError::new(ExitCode::CommandError, e.to_string()))?;
println!(
"Sending {} of {} to {} {} times.",
asset_public_key, amount, to_address, number_transactions
);
for _ in 0..number_transactions {
runtime
.block_on(commands::asset_wallets::inner_asset_wallets_send_to(
asset_public_key.clone(),
amount,
to_address.clone(),
state,
))
.map_err(|e| ExitError::new(ExitCode::CommandError, e.to_string()))?;
}
Ok(())
}
4 changes: 2 additions & 2 deletions applications/tari_collectibles/src-tauri/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ impl Default for CollectiblesConfig {
Self {
override_from: None,
validator_node_grpc_address: "/ip4/127.0.0.1/tcp/18144".parse().unwrap(),
base_node_grpc_address: "/ip4/127.0.0.1/18142".parse().unwrap(),
wallet_grpc_address: "/ip4/127.0.0.1/tpc/18143".parse().unwrap(),
base_node_grpc_address: "/ip4/127.0.0.1/tcp/18142".parse().unwrap(),
wallet_grpc_address: "/ip4/127.0.0.1/tcp/18143".parse().unwrap(),
}
}
}
Expand Down
140 changes: 16 additions & 124 deletions applications/tari_collectibles/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use std::error::Error;
use tauri::{Menu, MenuItem, Submenu};

use clap::Parser;
use tari_common::{
exit_codes::{ExitCode, ExitError},
load_configuration, DefaultConfigLoader,
};
use uuid::Uuid;
use std::path::PathBuf;
use tari_common::{exit_codes::ExitError, load_configuration, DefaultConfigLoader};

use crate::{app_state::ConcurrentAppState, cli::Cli, config::CollectiblesConfig};
use crate::{
app_state::ConcurrentAppState,
cli::{Cli, Commands},
config::CollectiblesConfig,
};

#[macro_use]
extern crate diesel;
Expand All @@ -36,133 +37,23 @@ mod schema;
mod status;
mod storage;

#[derive(Debug)]
pub enum Command {
MakeItRain {
asset_public_key: String,
amount_per_transaction: u64,
number_transactions: u32,
destination_address: String,
source_address: Option<String>,
},
}

fn parse_make_it_rain(src: &[&str]) -> Result<Command, ExitError> {
if src.len() < 4 && 5 < src.len() {
return Err(ExitError::new(
ExitCode::CommandError,
&"Invalid arguments for make-it-rain",
));
}
let asset_public_key = src[0].to_string();
let amount_per_transaction = src[1]
.to_string()
.parse::<u64>()
.map_err(|e| ExitError::new(ExitCode::CommandError, &e.to_string()))?;
let number_transactions = src[2]
.to_string()
.parse::<u32>()
.map_err(|e| ExitError::new(ExitCode::CommandError, &e.to_string()))?;
let destination_address = src[3].to_string();
let source_address = match src.len() {
5 => Some(src[4].to_string()),
_ => None,
};
Ok(Command::MakeItRain {
asset_public_key,
amount_per_transaction,
number_transactions,
destination_address,
source_address,
})
}

fn parse_command(src: &str) -> Result<Command, ExitError> {
let args: Vec<_> = src.split(' ').collect();
if args.is_empty() {
return Err(ExitError::new(ExitCode::CommandError, &"Empty command"));
}
match args.get(0) {
Some(&"make-it-rain") => parse_make_it_rain(&args[1..]),
_ => Err(ExitError::new(ExitCode::CommandError, &"Invalid command")),
}
}

// make-it-rain <asset_public_key> <amount_per_transaction> <number_transactions> <destination address> <source address - optional>
fn make_it_rain(
asset_public_key: String,
amount: u64,
number_transactions: u32,
to_address: String,
source_address: Option<String>,
state: &ConcurrentAppState,
) -> Result<(), ExitError> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to build a runtime!");
let id = match runtime.block_on(commands::wallets::inner_wallets_list(state)) {
Ok(rows) => {
if rows.is_empty() {
return Err(ExitError::new(
ExitCode::CommandError,
&"There is no wallet!",
));
}
match source_address {
Some(source_address) => {
let source_uuid = Uuid::parse_str(&source_address)
.map_err(|e| ExitError::new(ExitCode::CommandError, &e.to_string()))?;
if !rows.iter().any(|wallet| wallet.id == source_uuid) {
return Err(ExitError::new(ExitCode::CommandError, &"Wallet not found!"));
}
source_uuid
}
None => rows[0].id,
}
}
Err(e) => {
return Err(ExitError::new(ExitCode::CommandError, &e.to_string()));
}
};

runtime
.block_on(commands::wallets::inner_wallets_unlock(id, state))
.map_err(|e| ExitError::new(ExitCode::CommandError, &e.to_string()))?;
println!(
"Sending {} of {} to {} {} times.",
asset_public_key, amount, to_address, number_transactions
);
for _ in 0..number_transactions {
runtime
.block_on(commands::asset_wallets::inner_asset_wallets_send_to(
asset_public_key.clone(),
amount,
to_address.clone(),
state,
))
.map_err(|e| ExitError::new(ExitCode::CommandError, &e.to_string()))?;
}
Ok(())
}

pub fn process_command(command: Command, state: &ConcurrentAppState) -> Result<(), ExitError> {
println!("command {:?}", command);
pub fn process_command(command: Commands, state: &ConcurrentAppState) -> Result<(), ExitError> {
match command {
Command::MakeItRain {
Commands::MakeItRain {
asset_public_key,
amount_per_transaction,
number_transactions: number_transaction,
number_transactions,
destination_address,
source_address,
} => make_it_rain(
} => cli::make_it_rain(
asset_public_key,
amount_per_transaction,
number_transaction,
number_transactions,
destination_address,
source_address,
state,
),
Commands::ListAssets { offset, count } => cli::list_assets(offset, count, state),
}
}

Expand All @@ -177,11 +68,12 @@ fn main() -> Result<(), Box<dyn Error>> {
let config = CollectiblesConfig::load_from(&cfg)?;
let state = ConcurrentAppState::new(cli.common.get_base_path(), config);

if let Some(ref command) = cli.command {
let command = parse_command(command)?;
if let Some(command) = cli.command {
process_command(command, &state)?;
return Ok(());
}
//let (bootstrap, config, _) = init_configuration(ApplicationType::Collectibles)?;
let state = ConcurrentAppState::new(PathBuf::from("."), CollectiblesConfig::default());

tauri::Builder::default()
.menu(build_menu())
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_console_wallet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn main_inner() -> Result<(), ExitError> {
let password = cli
.password
.as_ref()
.or(config.wallet.password.as_ref())
.or_else(|| config.wallet.password.as_ref())
.map(|s| s.to_owned());

if password.is_none() {
Expand Down
2 changes: 1 addition & 1 deletion common/src/exit_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct ExitError {
}

impl ExitError {
pub fn new(exit_code: ExitCode, details: &impl ToString) -> Self {
pub fn new(exit_code: ExitCode, details: impl ToString) -> Self {
let details = Some(details.to_string());
Self { exit_code, details }
}
Expand Down

0 comments on commit 5b726a6

Please sign in to comment.