sunshine-identity-cli 0.2.2

Cli interface for the identity module.
use crate::error::{Error, Result};
use clap::Clap;
use core::fmt::{Debug, Display};
use substrate_subxt::balances::{AccountData, Balances, TransferCallExt, TransferEventExt};
use substrate_subxt::sp_core::crypto::Ss58Codec;
use substrate_subxt::system::System;
use substrate_subxt::{Runtime, SignedExtension, SignedExtra};
use sunshine_core::ChainClient;
use sunshine_identity_client::{
    resolve, Error as IdentityError, Identifier, Identity, IdentityClient,
};

#[derive(Clone, Debug, Clap)]
pub struct WalletBalanceCommand {
    pub identifier: Option<String>,
}

impl WalletBalanceCommand {
    pub async fn exec<R: Runtime + Identity + Balances, C: IdentityClient<R>>(
        &self,
        client: &C,
    ) -> Result<(), C::Error>
    where
        <R as System>::AccountId: Ss58Codec,
        R: Identity<IdAccountData = AccountData<<R as Balances>::Balance>>,
        <C as ChainClient<R>>::Error: From<IdentityError>,
    {
        let identifier: Option<Identifier<R>> = if let Some(identifier) = &self.identifier {
            Some(identifier.parse()?)
        } else {
            None
        };
        let uid = resolve(client, identifier).await.map_err(Error::Client)?;
        let account = client.fetch_account(uid).await.map_err(Error::Client)?;
        println!("{:?}", account.free);
        Ok(())
    }
}

#[derive(Clone, Debug, Clap)]
pub struct WalletTransferCommand {
    pub identifier: String,
    pub amount: u128,
}

impl WalletTransferCommand {
    pub async fn exec<R: Runtime + Identity + Balances, C: IdentityClient<R>>(
        &self,
        client: &C,
    ) -> Result<(), C::Error>
    where
        <R as System>::AccountId: Ss58Codec + Into<<R as System>::Address>,
        <<<R as Runtime>::Extra as SignedExtra<R>>::Extra as SignedExtension>::AdditionalSigned:
            Send + Sync,
        <R as Balances>::Balance: From<u128> + Display,
        <C as ChainClient<R>>::Error: From<IdentityError>,
    {
        let identifier: Identifier<R> = self.identifier.parse()?;
        let uid = resolve(client, Some(identifier))
            .await
            .map_err(Error::Client)?;
        let keys = client.fetch_keys(uid, None).await.map_err(Error::Client)?;
        let signer = client.chain_signer().map_err(Error::Client)?;
        let event = client
            .chain_client()
            .transfer_and_watch(signer, &keys[0].clone().into(), self.amount.into())
            .await
            .map_err(|e| Error::Client(e.into()))?
            .transfer()
            .map_err(|_| Error::TransferEventDecode)?
            .ok_or(Error::TransferEventFind)?;
        println!("transfered {} to {}", event.amount, event.to.to_string());
        Ok(())
    }
}