/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2025 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::sync::Arc; use clap::{Parser, Subcommand}; use darkfi::{cli_desc, Result}; use prettytable::{format, row, Table}; use smol::Executor; use rlnd_cli::RlndCli; #[derive(Parser)] #[command(about = cli_desc!())] struct Args { #[arg(short, long, default_value = "tcp://127.0.0.1:25637")] /// rldn JSON-RPC endpoint endpoint: String, #[command(subcommand)] /// Sub command to execute command: Subcmd, } #[derive(Subcommand)] enum Subcmd { /// Send a ping request to the rlnd RPC endpoint Ping, /// List all memberships List, /// Register a membership Register { /// Stake of this membership stake: u64, }, /// Slash a membership Slash { /// Membership id to slash id: String, }, } fn main() -> Result<()> { // Initialize an executor let executor = Arc::new(Executor::new()); let ex = executor.clone(); smol::block_on(executor.run(async { // Parse arguments let args = Args::parse(); // Execute a subcommand let rlnd_cli = RlndCli::new(&args.endpoint, ex).await?; match args.command { Subcmd::Ping => { rlnd_cli.ping().await?; } Subcmd::List => { match rlnd_cli.get_all_memberships().await { Ok(memberships) => { // Create a prettytable with the memberships: let mut table = Table::new(); table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR); table.set_titles(row!["ID", "Leaf Position", "Stake"]); for (id, membership) in memberships.iter() { table.add_row(row![ id, format!("{:?}", membership.leaf_position), membership.stake ]); } if table.is_empty() { println!("No memberships found"); } else { println!("{table}"); } } Err(e) => println!("Membership registration failed: {e}"), } } Subcmd::Register { stake } => match rlnd_cli.register_membership(stake).await { Ok((id, membership)) => println!("Registered membership {id:?}: {membership:?}"), Err(e) => println!("Membership registration failed: {e}"), }, Subcmd::Slash { id } => { println!("Slashing membership: {id}"); match rlnd_cli.slash_membership(&id).await { Ok(membership) => println!("Slashed membership {id}: {membership:?}"), Err(e) => println!("Membership slashing failed: {e}"), } } } rlnd_cli.rpc_client.stop().await; Ok(()) })) }