Skip to content
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

feat(cli): added (multi)-wallet integration #2352

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
85 changes: 82 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions autonomi-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ autonomi = { path = "../autonomi", version = "0.2.2-rc.2", features = [
] }
clap = { version = "4.2.1", features = ["derive"] }
color-eyre = "~0.6"
const-hex = "1.13.1"
dirs-next = "~2.0.0"
prettytable = "0.10.0"
thiserror = "1.0"
indicatif = { version = "0.17.5", features = ["tokio"] }
rand = { version = "~0.8.5", features = ["small_rng"] }
rpassword = "7.0"
tokio = { version = "1.32.0", features = [
"io-util",
"macros",
Expand All @@ -51,6 +56,8 @@ sn_logging = { path = "../sn_logging", version = "0.2.38-rc.2" }
walkdir = "2.5.0"
serde_json = "1.0.132"
serde = "1.0.210"
hex = "0.4.3"
ring = "0.17.8"

[dev-dependencies]
autonomi = { path = "../autonomi", version = "0.2.2-rc.2", features = [
Expand Down
32 changes: 9 additions & 23 deletions autonomi-cli/src/access/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use crate::wallet::load_wallet_private_key;
use autonomi::client::registers::RegisterSecretKey;
use autonomi::client::vault::VaultSecretKey;
use autonomi::{get_evm_network_from_env, Wallet};
use color_eyre::eyre::{Context, Result};
use color_eyre::eyre::{eyre, Context, Result};
use color_eyre::Section;
use std::env;
use std::fs;
Expand All @@ -18,42 +19,27 @@ use std::path::PathBuf;
const SECRET_KEY_ENV: &str = "SECRET_KEY";
const REGISTER_SIGNING_KEY_ENV: &str = "REGISTER_SIGNING_KEY";

const SECRET_KEY_FILE: &str = "secret_key";
const REGISTER_SIGNING_KEY_FILE: &str = "register_signing_key";

/// EVM wallet
pub fn load_evm_wallet() -> Result<Wallet> {
pub fn load_evm_wallet_from_env() -> Result<Wallet> {
let secret_key =
get_secret_key().wrap_err("The secret key is required to perform this action")?;
get_secret_key_from_env().wrap_err("The secret key is required to perform this action")?;
let network = get_evm_network_from_env()?;
let wallet = Wallet::new_from_private_key(network, &secret_key)
.wrap_err("Failed to load EVM wallet from key")?;
Ok(wallet)
}

/// EVM wallet private key
pub fn get_secret_key() -> Result<String> {
// try env var first
let why_env_failed = match env::var(SECRET_KEY_ENV) {
Ok(key) => return Ok(key),
Err(e) => e,
};

// try from data dir
let dir = super::data_dir::get_client_data_dir_path()
.wrap_err(format!("Failed to obtain secret key from env var: {why_env_failed}, reading from disk also failed as couldn't access data dir"))
.with_suggestion(|| format!("make sure you've provided the {SECRET_KEY_ENV} env var"))?;

// load the key from file
let key_path = dir.join(SECRET_KEY_FILE);
fs::read_to_string(&key_path)
.wrap_err("Failed to read secret key from file")
.with_suggestion(|| format!("make sure you've provided the {SECRET_KEY_ENV} env var or have the key in a file at {key_path:?}"))
.with_suggestion(|| "the secret key should be a hex encoded string of your evm wallet private key")
pub fn get_secret_key_from_env() -> Result<String> {
env::var(SECRET_KEY_ENV).wrap_err(eyre!(
"make sure you've provided the {SECRET_KEY_ENV} env var"
))
}

pub fn get_vault_secret_key() -> Result<VaultSecretKey> {
let secret_key = get_secret_key()?;
let secret_key = load_wallet_private_key()?;
autonomi::client::vault::derive_vault_key(&secret_key)
.wrap_err("Failed to derive vault secret key from EVM secret key")
}
Expand Down
34 changes: 34 additions & 0 deletions autonomi-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
mod file;
mod register;
mod vault;
mod wallet;

use clap::Subcommand;
use color_eyre::Result;
Expand All @@ -34,6 +35,12 @@ pub enum SubCmd {
#[command(subcommand)]
command: VaultCmd,
},

/// Operations related to wallet management.
Wallet {
#[command(subcommand)]
command: WalletCmd,
},
}

#[derive(Subcommand, Debug)]
Expand Down Expand Up @@ -145,6 +152,25 @@ pub enum VaultCmd {
},
}

#[derive(Subcommand, Debug)]
pub enum WalletCmd {
/// Create a wallet.
Create {
/// Optional flag to not add a password.
#[clap(long, action)]
no_password: bool,
/// Optional hex-encoded private key.
#[clap(long)]
private_key: Option<String>,
/// Optional password to encrypt the wallet with.
#[clap(long, short)]
password: Option<String>,
},

/// Check the balance of the wallet.
Balance,
}

pub async fn handle_subcommand(opt: Opt) -> Result<()> {
let peers = crate::access::network::get_peers(opt.peers);
let cmd = opt.command;
Expand Down Expand Up @@ -180,5 +206,13 @@ pub async fn handle_subcommand(opt: Opt) -> Result<()> {
VaultCmd::Load => vault::load(peers.await?).await,
VaultCmd::Sync { force } => vault::sync(peers.await?, force).await,
},
SubCmd::Wallet { command } => match command {
WalletCmd::Create {
no_password,
private_key,
password,
} => wallet::create(no_password, private_key, password),
WalletCmd::Balance => Ok(wallet::balance().await?),
},
}
}
3 changes: 2 additions & 1 deletion autonomi-cli/src/commands/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// permissions and limitations relating to use of the SAFE Network Software.

use crate::utils::collect_upload_summary;
use crate::wallet::load_wallet;
use autonomi::client::address::addr_to_str;
use autonomi::Multiaddr;
use color_eyre::eyre::Context;
Expand All @@ -31,7 +32,7 @@ pub async fn cost(file: &str, peers: Vec<Multiaddr>) -> Result<()> {
}

pub async fn upload(file: &str, public: bool, peers: Vec<Multiaddr>) -> Result<()> {
let wallet = crate::keys::load_evm_wallet()?;
let wallet = load_wallet()?;
let mut client = crate::actions::connect_to_network(peers).await?;
let event_receiver = client.enable_client_events();
let (upload_summary_thread, upload_completed_tx) = collect_upload_summary(event_receiver);
Expand Down
3 changes: 2 additions & 1 deletion autonomi-cli/src/commands/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// permissions and limitations relating to use of the SAFE Network Software.

use crate::utils::collect_upload_summary;
use crate::wallet::load_wallet;
use autonomi::client::registers::RegisterAddress;
use autonomi::client::registers::RegisterPermissions;
use autonomi::client::registers::RegisterSecretKey;
Expand Down Expand Up @@ -51,7 +52,7 @@ pub async fn cost(name: &str, peers: Vec<Multiaddr>) -> Result<()> {
}

pub async fn create(name: &str, value: &str, public: bool, peers: Vec<Multiaddr>) -> Result<()> {
let wallet = crate::keys::load_evm_wallet()?;
let wallet = load_wallet()?;
let register_key = crate::keys::get_register_signing_key()
.wrap_err("The register key is required to perform this action")?;
let mut client = crate::actions::connect_to_network(peers).await?;
Expand Down
5 changes: 3 additions & 2 deletions autonomi-cli/src/commands/vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.

use crate::wallet::load_wallet;
use autonomi::Multiaddr;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
Expand All @@ -28,7 +29,7 @@ pub async fn cost(peers: Vec<Multiaddr>) -> Result<()> {

pub async fn create(peers: Vec<Multiaddr>) -> Result<()> {
let client = crate::actions::connect_to_network(peers).await?;
let wallet = crate::keys::load_evm_wallet()?;
let wallet = load_wallet()?;
let vault_sk = crate::keys::get_vault_secret_key()?;

println!("Retrieving local user data...");
Expand Down Expand Up @@ -59,7 +60,7 @@ pub async fn create(peers: Vec<Multiaddr>) -> Result<()> {
pub async fn sync(peers: Vec<Multiaddr>, force: bool) -> Result<()> {
let client = crate::actions::connect_to_network(peers).await?;
let vault_sk = crate::keys::get_vault_secret_key()?;
let wallet = crate::keys::load_evm_wallet()?;
let wallet = load_wallet()?;

println!("Fetching vault from network...");
let net_user_data = client
Expand Down
Loading
Loading