Skip to content
Snippets Groups Projects
identity.rs 2.58 KiB
Newer Older
use crate::{gdev, indexer::*, Args, Client};

use anyhow::{anyhow, Result};
use sp_core::crypto::AccountId32;
use std::str::FromStr;

pub async fn get_identity(
    client: Client,
    mut account_id: Option<AccountId32>,
    mut identity_id: Option<u32>,
    mut username: Option<String>,
    args: &Args,
) -> Result<()> {
    let parent_hash = client
        .storage()
        .fetch(&gdev::storage().system().parent_hash(), None)
        .await?
        .unwrap();

    let gql_client = reqwest::Client::builder()
        .user_agent("gcli/0.1.0")
        .build()?;

    let indexer = if args.no_indexer {
        None
    } else {
        Some(Indexer {
            gql_client,
            gql_url: &args.indexer,
        })
    };

    if let Some(account_id) = &account_id {
        identity_id = client
            .storage()
            .fetch(
                &gdev::storage().identity().identity_index_of(account_id),
                Some(parent_hash),
            )
            .await?;
    } else if let Some(identity_id) = &identity_id {
        account_id = client
            .storage()
            .fetch(
                &gdev::storage().identity().identities(identity_id),
                Some(parent_hash),
            )
            .await?
            .map(|idty| idty.owner_key);
    } else if let Some(username) = &username {
        let indexer = indexer.as_ref().ok_or(anyhow!(
            "Cannot fetch identity from username without indexer."
        ))?;
        if let Some(pubkey) = indexer.pubkey_by_username(username).await? {
            let some_account_id = AccountId32::from_str(&pubkey).map_err(|e| anyhow!(e))?;
            identity_id = client
                .storage()
                .fetch(
                    &gdev::storage()
                        .identity()
                        .identity_index_of(&some_account_id),
                    Some(parent_hash),
                )
                .await?;
            account_id = Some(some_account_id);
        }
    } else {
        return Err(anyhow!("One argument is needed to fetch the identity."));
    }

    println!(
        "Account id:  {}",
        account_id
            .as_ref()
            .map_or(String::new(), AccountId32::to_string)
    );
    println!(
        "Identity id: {}",
        identity_id.map_or(String::new(), |identity_id| format!("{identity_id}"))
    );

    if let (Some(indexer), Some(account_id), None) = (&indexer, &account_id, &username) {
        username = indexer.username_by_pubkey(&account_id.to_string()).await?;
    }

    println!("Username:    {}", username.unwrap_or_default());

    Ok(())
}