gcli 2.0.0-pre.1

Gear program CLI
Documentation
// Copyright (C) Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

use crate::app::App;
use anyhow::Result;
use clap::Parser;
use colored::Colorize;
use gsdk::AccountKeyring;
use gsigner::{
    cli::{GSignerCommands, display_result, execute_command},
    keyring::KeystoreEntry,
    sr25519::PrivateKey,
};

const DEFAULT_DEV: AccountKeyring = AccountKeyring::Alice;

/// Gear wallet manager.
#[derive(Clone, Debug, Parser)]
pub enum Wallet {
    /// Switch to development account
    Dev {
        /// The name of the dev account.
        #[clap(short, long, default_value = "_dev_alice")]
        name: String,
        /// The URI of the dev account.
        #[clap(short, long)]
        uri: Option<String>,
    },
    /// gsigner commands embedded into gcli.
    #[clap(flatten)]
    Signer(GSignerCommands),
}

impl Wallet {
    /// Run the wallet command.
    pub fn exec(self, app: &mut App) -> Result<()> {
        match self {
            Wallet::Dev { name, uri } => Self::dev(&name, uri.clone(), app),
            Wallet::Signer(command) => {
                let result = execute_command(command.clone())?;
                display_result(&result);
                Ok(())
            }
        }
    }

    /// Switch to development account.
    pub fn dev(name: &str, uri: Option<String>, app: &mut App) -> Result<()> {
        let mut keyring = app.keyring()?;

        if !keyring
            .list()
            .iter()
            .any(|keystore| keystore.name() == name)
        {
            let private_key = uri
                .as_deref()
                .and_then(|suri| PrivateKey::from_suri(suri, None).ok())
                .unwrap_or_else(|| PrivateKey::from_keypair(DEFAULT_DEV.pair().into()));
            keyring.add(name, private_key, None)?;
        }

        keyring.set_primary(name)?;
        println!("Successfully switched to dev account {} !", name.cyan());
        Ok(())
    }
}