Merge 9cde8b117f94d826792d3dc709494b4cfd942baa into d8a8bdfc97cbf679d99ca9956e8fc8f25846002e

This commit is contained in:
fryorcraken 2026-02-16 16:47:13 +02:00 committed by GitHub
commit 8dac551f57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,6 +3,7 @@ use clap::Subcommand;
use itertools::Itertools as _;
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
use nssa::{Account, PublicKey, program::Program};
use serde::Serialize;
use token_core::{TokenDefinition, TokenHolding};
use crate::{
@ -119,41 +120,88 @@ impl WalletSubcommand for NewSubcommand {
}
}
/// Formats account details for display, returning (description, json_view)
fn format_account_details(account: &Account) -> (String, String) {
#[derive(Debug, Serialize)]
pub struct TokenDefinitionAccountView {
pub account_type: String,
pub name: String,
pub total_supply: u128,
}
impl From<TokenDefinition> for TokenDefinitionAccountView {
fn from(value: TokenDefinition) -> Self {
let (sub_type, name, total_supply) = match value {
TokenDefinition::Fungible {
name, total_supply, ..
} => ("fungible", name, total_supply),
TokenDefinition::NonFungible {
name,
printable_supply,
..
} => ("non-fungible", name, printable_supply),
};
Self {
account_type: format!("Token definition ({sub_type})"),
name,
total_supply,
}
}
}
#[derive(Debug, Serialize)]
pub struct TokenHoldingAccountView {
pub account_type: String,
pub definition_id: String,
pub balance: u128,
}
impl From<TokenHolding> for TokenHoldingAccountView {
fn from(value: TokenHolding) -> Self {
let (sub_type, balance) = match &value {
TokenHolding::Fungible { balance, .. } => ("fungible", *balance),
TokenHolding::NftMaster { print_balance, .. } => ("NFT master", *print_balance),
TokenHolding::NftPrintedCopy { owned, .. } => {
("NFT printed copy", if *owned { 1 } else { 0 })
}
};
Self {
account_type: format!("Token holding ({sub_type})"),
definition_id: value.definition_id().to_string(),
balance,
}
}
}
/// Formats program-specific account details for display.
/// Returns Some((description, json_view)) for program-specific info, or None if no extra info.
fn format_program_details(account: &Account) -> Option<(String, String)> {
let auth_tr_prog_id = Program::authenticated_transfer_program().id();
let token_prog_id = Program::token().id();
match &account.program_owner {
o if *o == auth_tr_prog_id => (
"Account owned by authenticated transfer program".to_string(),
serde_json::to_string(&account).unwrap(),
),
o if *o == token_prog_id => {
_ if account.program_owner == auth_tr_prog_id => None,
_ if account.program_owner == token_prog_id => {
if let Ok(token_def) = TokenDefinition::try_from(&account.data) {
(
"Definition account owned by token program".to_string(),
serde_json::to_string(&token_def).unwrap(),
)
let acc_view: TokenDefinitionAccountView = token_def.into();
Some((
"Token definition".to_string(),
serde_json::to_string(&acc_view).unwrap(),
))
} else if let Ok(token_hold) = TokenHolding::try_from(&account.data) {
(
"Holding account owned by token program".to_string(),
serde_json::to_string(&token_hold).unwrap(),
)
let acc_view: TokenHoldingAccountView = token_hold.into();
Some((
"Token holding".to_string(),
serde_json::to_string(&acc_view).unwrap(),
))
} else {
let account_hr: HumanReadableAccount = account.clone().into();
(
"Unknown token program account".to_string(),
serde_json::to_string(&account_hr).unwrap(),
)
None
}
}
_ => {
let account_hr: HumanReadableAccount = account.clone().into();
(
"Account".to_string(),
Some((
"Account data".to_string(),
serde_json::to_string(&account_hr).unwrap(),
)
))
}
}
}
@ -233,9 +281,13 @@ impl WalletSubcommand for AccountSubcommand {
return Ok(SubcommandReturnValue::Empty);
}
let (description, json_view) = format_account_details(&account);
println!("{description}");
println!("{json_view}");
// Always show native balance first
println!("Native balance: {}", account.balance);
// Then show program-specific details if any
if let Some((description, json_view)) = format_program_details(&account) {
println!("{description}: {json_view}");
}
if keys {
display_keys(wallet_core)?;
@ -308,6 +360,14 @@ impl WalletSubcommand for AccountSubcommand {
return Ok(SubcommandReturnValue::Empty);
}
// Helper to print account details
let print_account_details = |account: &Account| {
println!(" Native balance: {}", account.balance);
if let Some((description, json_view)) = format_program_details(account) {
println!(" {description}: {json_view}");
}
};
// Detailed listing with --long flag
// Preconfigured public accounts
for id in user_data.default_pub_account_signing_keys.keys().copied() {
@ -317,9 +377,7 @@ impl WalletSubcommand for AccountSubcommand {
);
match wallet_core.get_account_public(id).await {
Ok(account) if account != Account::default() => {
let (description, json_view) = format_account_details(&account);
println!(" {description}");
println!(" {json_view}");
print_account_details(&account);
}
Ok(_) => println!(" Uninitialized"),
Err(e) => println!(" Error fetching account: {e}"),
@ -334,9 +392,7 @@ impl WalletSubcommand for AccountSubcommand {
);
match wallet_core.get_account_private(id) {
Some(account) if account != Account::default() => {
let (description, json_view) = format_account_details(&account);
println!(" {description}");
println!(" {json_view}");
print_account_details(&account);
}
Some(_) => println!(" Uninitialized"),
None => println!(" Not found in local storage"),
@ -351,9 +407,7 @@ impl WalletSubcommand for AccountSubcommand {
);
match wallet_core.get_account_public(*id).await {
Ok(account) if account != Account::default() => {
let (description, json_view) = format_account_details(&account);
println!(" {description}");
println!(" {json_view}");
print_account_details(&account);
}
Ok(_) => println!(" Uninitialized"),
Err(e) => println!(" Error fetching account: {e}"),
@ -368,9 +422,7 @@ impl WalletSubcommand for AccountSubcommand {
);
match wallet_core.get_account_private(*id) {
Some(account) if account != Account::default() => {
let (description, json_view) = format_account_details(&account);
println!(" {description}");
println!(" {json_view}");
print_account_details(&account);
}
Some(_) => println!(" Uninitialized"),
None => println!(" Not found in local storage"),