diff --git a/src/commands/vault.rs b/src/commands/vault.rs index ce9942b4f373610c45794ed25cc8cde36828bd5a..10dcdb16e495d50b514c66cf8c3933f217b78930 100644 --- a/src/commands/vault.rs +++ b/src/commands/vault.rs @@ -91,34 +91,46 @@ pub enum Subcommand { Where, } -#[derive(Clone, Debug, clap::Parser)] +/// List subcommands +#[derive(Clone, Debug, clap::Subcommand)] pub enum ListChoice { - /// List all <Base> SS58 Addresses and their linked derivations in the vault + /// List all accounts + #[clap(alias = "a")] All { - /// Show G1v1 public keys - #[clap(long, default_value = "false")] + /// Show G1v1 public key for ed25519 keys + #[clap(long)] + show_g1v1: bool, + /// Show wallet type (g1v1 or mnemonic) + #[clap(long)] + show_type: bool, + }, + /// List only base accounts + #[clap(alias = "b")] + Base { + /// Show G1v1 public key for ed25519 keys + #[clap(long)] show_g1v1: bool, + /// Show wallet type (g1v1 or mnemonic) + #[clap(long)] + show_type: bool, }, - /// List <Base> and Derivation SS58 Addresses linked to the selected one + /// List accounts for a specific address + #[clap(alias = "f")] For { #[clap(flatten)] address_or_vault_name: AddressOrVaultNameGroup, - - /// Show G1v1 public keys - #[clap(long, default_value = "false")] - show_g1v1: bool, - }, - /// List all <Base> SS58 Addresses in the vault - Base { - /// Show G1v1 public keys - #[clap(long, default_value = "false")] + /// Show G1v1 public key for ed25519 keys + #[clap(long)] show_g1v1: bool, + /// Show wallet type (g1v1 or mnemonic) + #[clap(long)] + show_type: bool, }, } impl Default for ListChoice { fn default() -> Self { - ListChoice::All { show_g1v1: false } + ListChoice::All { show_g1v1: false, show_type: false } } } @@ -172,20 +184,20 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE // match subcommand match command { Subcommand::List(choice) => match choice { - ListChoice::All { show_g1v1 } => { + ListChoice::All { show_g1v1, show_type } => { let all_account_tree_node_hierarchies = vault_account::fetch_all_base_account_tree_node_hierarchies(db).await?; - let table = display::compute_vault_accounts_table_with_g1v1(&all_account_tree_node_hierarchies, show_g1v1)?; + let table = display::compute_vault_accounts_table_with_g1v1(&all_account_tree_node_hierarchies, show_g1v1, show_type)?; println!("available SS58 Addresses:"); println!("{table}"); } - ListChoice::Base { show_g1v1 } => { + ListChoice::Base { show_g1v1, show_type } => { let base_account_tree_nodes = vault_account::fetch_only_base_account_tree_nodes(db).await?; - let table = display::compute_vault_accounts_table_with_g1v1(&base_account_tree_nodes, show_g1v1)?; + let table = display::compute_vault_accounts_table_with_g1v1(&base_account_tree_nodes, show_g1v1, show_type)?; println!("available <Base> SS58 Addresses:"); println!("{table}"); @@ -193,6 +205,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE ListChoice::For { address_or_vault_name, show_g1v1, + show_type, } => { let account_tree_node = retrieve_account_tree_node(db, address_or_vault_name).await?; @@ -200,7 +213,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE let base_account_tree_node = vault_account::get_base_account_tree_node(&account_tree_node); - let table = display::compute_vault_accounts_table_with_g1v1(&[base_account_tree_node], show_g1v1)?; + let table = display::compute_vault_accounts_table_with_g1v1(&[base_account_tree_node], show_g1v1, show_type)?; println!( "available SS58 Addresses linked to {}:", @@ -742,67 +755,31 @@ fn prompt_secret_and_compute_vault_data_to_import( pub async fn create_base_account_for_vault_data_to_import<C>( db_tx: &C, vault_data: &VaultDataToImport, - password: Option<&String>, + password_opt: Option<&String>, crypto_scheme: Option<CryptoScheme>, ) -> Result<vault_account::Model, GcliError> where C: ConnectionTrait, { - let address_to_import = vault_data.key_pair.address().to_string(); - println!("Trying to import for SS58 address :'{}'", address_to_import); - println!(); - - let vault_account = if let Some(existing_vault_account) = - vault_account::find_by_id(db_tx, &DbAccountId::from(address_to_import.clone())).await? - { - if existing_vault_account.is_base_account() { - println!("You are trying to add {address_to_import} as a <Base> account while it already exists as a <Base> account."); - println!(); - println!("Do you want to:"); - println!("1. keep the existing <Base> account and cancel import"); - println!("2. overwrite existing <Base> account with the new encrypted key (children will be re-parented)"); - } else { - // Existing derivation account - let account_tree_node_hierarchy = - vault_account::fetch_base_account_tree_node_hierarchy_unwrapped( - db_tx, - &address_to_import, - ) - .await?; - let account_tree_node_for_address = vault_account::get_account_tree_node_for_address( - &account_tree_node_hierarchy, - &address_to_import, - ); + let address = vault_data.key_pair.address().to_string(); - let base_parent_hierarchy_account_tree_node = - vault_account::get_base_parent_hierarchy_account_tree_node( - &account_tree_node_for_address, - ); - - let parent_hierarchy_table = - display::compute_vault_accounts_table(&[base_parent_hierarchy_account_tree_node])?; + // Check if the account already exists + let existing_vault_account = vault_account::find_by_id(db_tx, &DbAccountId(vault_data.key_pair.address())).await?; - println!("You are trying to add {address_to_import} as a <Base> account"); - println!( - "but it is already present as `{}` derivation of {} account.", - existing_vault_account.path.clone().unwrap(), - existing_vault_account.parent.clone().unwrap() - ); - println!(); - println!("Its parent hierarchy is this:"); - println!("{parent_hierarchy_table}"); - println!(); - println!("Do you want to:"); - println!("1. keep the existing derivation and cancel import"); - println!("2. delete the derivation account and replace it with the new <Base> account (children will be re-parented)"); - } + let password = match password_opt { + Some(password) => password.clone(), + None => inputs::prompt_password_query("Enter password to encrypt the key: ")?, + }; - let result = inputs::select_action("Your choice?", vec!["1", "2"])?; - match result { - "2" => { - let encrypted_suri = - compute_encrypted_suri(password, vault_data.secret_suri.clone())?; + let encrypted_suri = compute_encrypted_suri(password.clone(), vault_data.secret_suri.clone())?; + if let Some(existing_vault_account) = existing_vault_account { + // Existing account + match inputs::confirm_action(&format!( + "Account {} already exists. Do you want to update it?", + existing_vault_account + ))? { + true => { println!( "(Optional) Enter a name for the vault entry (leave empty to remove the name)" ); @@ -821,14 +798,15 @@ where )); vault_account.encrypted_suri = Set(Some(encrypted_suri)); vault_account.name = Set(name.clone()); + vault_account.secret_format = Set(Some(vault_data.secret_format.into())); let updated_vault_account = vault_account::update_account(db_tx, vault_account).await?; - + println!("Updating vault account {updated_vault_account}"); - updated_vault_account + Ok(updated_vault_account) } _ => { - return Err(GcliError::Input("import canceled".into())); + Err(GcliError::Input("import canceled".into())) } } } else { @@ -842,20 +820,19 @@ where let crypto_scheme = map_secret_format_to_crypto_scheme(secret_format, crypto_scheme); - let base_account = vault_account::create_base_account( + let account = vault_account::create_base_account( db_tx, - &address_to_import, + &address, name.as_ref(), crypto_scheme, encrypted_suri, + secret_format, ) .await?; - println!("Creating <Base> account {base_account}"); - - base_account - }; - - Ok(vault_account) + + println!("Creating <Base> account {account}"); + Ok(account) + } } /// Creates a `derivation` vault account for data provided and returns it @@ -982,18 +959,10 @@ where /// Function will ask for password if not present and compute the encrypted suri fn compute_encrypted_suri( - password: Option<&String>, + password: String, secret_suri: String, ) -> Result<Vec<u8>, GcliError> { - let password = match password.cloned() { - Some(password) => password, - _ => { - println!("Enter password to protect the key"); - inputs::prompt_password_confirm()? - } - }; - - Ok(encrypt(secret_suri.as_bytes(), password).map_err(|e| anyhow!(e))?) + encrypt(secret_suri.as_bytes(), password).map_err(|e| GcliError::Input(e.to_string())) } fn get_vault_key_path(data: &Data, vault_filename: &str) -> PathBuf { @@ -1144,12 +1113,12 @@ mod tests { Some(String::from("//Alice")) )] #[case( - String::from( - "bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice//Bob/soft1/soft2" - ), - Some(String::from("bottom drive obey lake curtain smoke basket hold race lonely fit walk")), - Some(String::from("//Alice//Bob/soft1/soft2")) - )] + String::from( + "bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice//Bob/soft1/soft2" + ), + Some(String::from("bottom drive obey lake curtain smoke basket hold race lonely fit walk")), + Some(String::from("//Alice//Bob/soft1/soft2")) + )] #[case( String::from("bottom drive obey lake curtain smoke basket hold race lonely fit walk"), Some(String::from( diff --git a/src/commands/vault/display.rs b/src/commands/vault/display.rs index e51560a30e07d61807bc51fe0672fb3ad4fea009..935b55e88519068902385ca42b2fa498967c7754 100644 --- a/src/commands/vault/display.rs +++ b/src/commands/vault/display.rs @@ -27,24 +27,36 @@ pub fn compute_vault_accounts_table( account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>], ) -> Result<Table, GcliError> { // Appel to the new function with show_g1v1 = true to maintain compatibility - compute_vault_accounts_table_with_g1v1(account_tree_nodes, true) + compute_vault_accounts_table_with_g1v1(account_tree_nodes, true, false) } pub fn compute_vault_accounts_table_with_g1v1( account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>], show_g1v1: bool, + show_type: bool, ) -> Result<Table, GcliError> { let mut table = Table::new(); table.load_preset(comfy_table::presets::UTF8_BORDERS_ONLY); - table.set_header(vec![ + + // Prepare header based on options + let mut header = vec![ if show_g1v1 { "SS58 Address/G1v1 public key" } else { "SS58 Address" }, "Crypto", - "Path", - "Name", - ]); + ]; + + // Add Type column if show_type is true + if show_type { + header.push("Type"); + } + + // Add remaining columns + header.push("Path"); + header.push("Name"); + + table.set_header(header); for account_tree_node in account_tree_nodes { - let _ = add_account_tree_node_to_table_with_g1v1(&mut table, account_tree_node, show_g1v1); + let _ = add_account_tree_node_to_table_with_g1v1(&mut table, account_tree_node, show_g1v1, show_type); } Ok(table) @@ -55,21 +67,22 @@ fn add_account_tree_node_to_table( account_tree_node: &Rc<RefCell<AccountTreeNode>>, ) -> Result<(), GcliError> { // Appel to the new function with show_g1v1 = true to maintain compatibility - add_account_tree_node_to_table_with_g1v1(table, account_tree_node, true) + add_account_tree_node_to_table_with_g1v1(table, account_tree_node, true, false) } fn add_account_tree_node_to_table_with_g1v1( table: &mut Table, account_tree_node: &Rc<RefCell<AccountTreeNode>>, show_g1v1: bool, + show_type: bool, ) -> Result<(), GcliError> { - let rows = compute_vault_accounts_row_with_g1v1(account_tree_node, show_g1v1)?; + let rows = compute_vault_accounts_row_with_g1v1(account_tree_node, show_g1v1, show_type)?; rows.iter().for_each(|row| { table.add_row(row.clone()); }); for child in &account_tree_node.borrow().children { - let _ = add_account_tree_node_to_table_with_g1v1(table, child, show_g1v1); + let _ = add_account_tree_node_to_table_with_g1v1(table, child, show_g1v1, show_type); } Ok(()) @@ -77,12 +90,12 @@ fn add_account_tree_node_to_table_with_g1v1( /// Computes one or more row of the table for selected account_tree_node /// -/// For ed25519 keys, will display over 2 rows to also show the base 58 G1v1 public key +/// For ed25519 keys, will display over 2 rows to also show the base 58 G1v1 public key if show_g1v1 is true pub fn compute_vault_accounts_row( account_tree_node: &Rc<RefCell<AccountTreeNode>>, ) -> Result<Vec<Vec<Cell>>, GcliError> { // Appel to the new function with show_g1v1 = true to maintain compatibility - compute_vault_accounts_row_with_g1v1(account_tree_node, true) + compute_vault_accounts_row_with_g1v1(account_tree_node, true, false) } /// Computes one or more row of the table for selected account_tree_node @@ -91,6 +104,7 @@ pub fn compute_vault_accounts_row( pub fn compute_vault_accounts_row_with_g1v1( account_tree_node: &Rc<RefCell<AccountTreeNode>>, show_g1v1: bool, + show_type: bool, ) -> Result<Vec<Vec<Cell>>, GcliError> { let empty_string = "".to_string(); @@ -117,42 +131,70 @@ pub fn compute_vault_accounts_row_with_g1v1( let mut rows: Vec<Vec<Cell>> = vec![]; - let (path, crypto) = if let Some(path) = account_tree_node.account.path.clone() { - (path, empty_string.clone()) + let (path, crypto, wallet_type) = if let Some(path) = account_tree_node.account.path.clone() { + (path, empty_string.clone(), empty_string.clone()) } else { let crypto_scheme = CryptoScheme::from(account_tree_node.account.crypto_scheme.unwrap()); let crypto_scheme_str: &str = crypto_scheme.into(); - // Check if it's an ed25519 key (for G1v1, we always use Ed25519) - // We don't have access to the secret_format field, so we rely only on the crypto_scheme - let is_ed25519 = crypto_scheme == CryptoScheme::Ed25519; + // Determine the wallet type based on the secret format + let wallet_type = if let Some(secret_format) = &account_tree_node.account.secret_format { + // If the secret format is available, use it to determine the type + match crate::keys::SecretFormat::from(*secret_format) { + crate::keys::SecretFormat::G1v1 => "G1v1".to_string(), + crate::keys::SecretFormat::Substrate => "Mnemonic".to_string(), + crate::keys::SecretFormat::Seed => "Seed".to_string(), + crate::keys::SecretFormat::Predefined => "Predefined".to_string(), + } + } else { + // If the secret format is not available, display "Unknown" + "Unknown".to_string() + }; - // Adding 2nd row for G1v1 public key only if show_g1v1 is true and it's an Ed25519 key + // Add a second line for the G1v1 public key only if show_g1v1 is true and it's an Ed25519 key + let is_ed25519 = crypto_scheme == CryptoScheme::Ed25519; if show_g1v1 && is_ed25519 { - rows.push(vec![Cell::new(format!( + let mut g1v1_row = vec![Cell::new(format!( "â”” G1v1: {}", cesium::compute_g1v1_public_key_from_ed25519_account_id( &account_tree_node.account.address.0 ) - ))]); + ))]; + + // Add empty cells to align with the main line + g1v1_row.push(Cell::new("")); + if show_type { + g1v1_row.push(Cell::new("")); + } + g1v1_row.push(Cell::new("")); + g1v1_row.push(Cell::new("")); + + rows.push(g1v1_row); } ( format!("<{}>", account_tree_node.account.account_type()), crypto_scheme_str.to_string(), + wallet_type, ) }; - // Adding 1st row - rows.insert( - 0, - vec![ - Cell::new(&address), - Cell::new(crypto), - Cell::new(&path), - Cell::new(&name), - ], - ); + // Add the first line + let mut main_row = vec![ + Cell::new(&address), + Cell::new(crypto), + ]; + + // Add the Type column if show_type is true + if show_type { + main_row.push(Cell::new(wallet_type)); + } + + // Add the remaining columns + main_row.push(Cell::new(&path)); + main_row.push(Cell::new(&name)); + + rows.insert(0, main_row); Ok(rows) } @@ -229,7 +271,7 @@ mod tests { #[test] fn test_compute_vault_accounts_table_with_g1v1_empty() { // Test with show_g1v1 = true (default behavior) - let table = compute_vault_accounts_table_with_g1v1(&[], true).unwrap(); + let table = compute_vault_accounts_table_with_g1v1(&[], true, false).unwrap(); let expected_table_with_g1v1 = indoc! {r#" ┌─────────────────────────────────────────────────────┠@@ -241,7 +283,7 @@ mod tests { assert_eq!(table.to_string(), expected_table_with_g1v1); // Test with show_g1v1 = false - let table = compute_vault_accounts_table_with_g1v1(&[], false).unwrap(); + let table = compute_vault_accounts_table_with_g1v1(&[], false, false).unwrap(); let expected_table_without_g1v1 = indoc! {r#" ┌─────────────────────────────────────┠@@ -260,7 +302,7 @@ mod tests { let account_tree_nodes = vec![account_tree_node, g1v1_account_tree_node]; // Test with show_g1v1 = true (default behavior) - let table_with_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true).unwrap(); + let table_with_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true, false).unwrap(); let expected_table_with_g1v1 = indoc! {r#" ┌──────────────────────────────────────────────────────────────────────────────────────────┠@@ -279,7 +321,7 @@ mod tests { assert_eq!(table_with_g1v1.to_string(), expected_table_with_g1v1); // Test with show_g1v1 = false - let table_without_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false).unwrap(); + let table_without_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false, false).unwrap(); let expected_table_without_g1v1 = indoc! {r#" ┌──────────────────────────────────────────────────────────────────────────────────────────┠@@ -304,7 +346,7 @@ mod tests { let account_tree_nodes = vec![child1]; // Test with show_g1v1 = true (default behavior) - let table_with_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true).unwrap(); + let table_with_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true, false).unwrap(); let expected_table_with_g1v1 = indoc! {r#" ┌─────────────────────────────────────────────────────────────────────────────────────┠@@ -318,7 +360,7 @@ mod tests { assert_eq!(table_with_g1v1.to_string(), expected_table_with_g1v1); // Test with show_g1v1 = false - let table_without_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false).unwrap(); + let table_without_g1v1 = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false, false).unwrap(); let expected_table_without_g1v1 = indoc! {r#" ┌─────────────────────────────────────────────────────────────────────────────────────┠@@ -331,5 +373,49 @@ mod tests { assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1); } + + #[test] + fn test_compute_vault_accounts_table_with_type() { + let account_tree_node = mother_account_tree_node(); + let g1v1_account_tree_node = mother_g1v1_account_tree_node(); + let account_tree_nodes = vec![account_tree_node, g1v1_account_tree_node]; + + // Test with show_type = true and show_g1v1 = true + let table_with_g1v1_and_type = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true, true).unwrap(); + + let expected_table_with_g1v1_and_type = indoc! {r#" + ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┠+ │ SS58 Address/G1v1 public key Crypto Type Path Name │ + â•žâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•¡ + │ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV sr25519 Mnemonic <Base> Mother │ + │ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │ + │ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │ + │ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o //1 <Mother//1> │ + │ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT //1 <Mother//1//1> │ + │ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 ed25519 G1v1 <Base> MotherG1v1 │ + │ â”” G1v1: 86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7 │ + └─────────────────────────────────────────────────────────────────────────────────────────────────────┘"# + }; + + assert_eq!(table_with_g1v1_and_type.to_string(), expected_table_with_g1v1_and_type); + + // Test with show_type = true and show_g1v1 = false + let table_with_type = compute_vault_accounts_table_with_g1v1(&account_tree_nodes, false, true).unwrap(); + + let expected_table_with_type = indoc! {r#" + ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┠+ │ SS58 Address Crypto Type Path Name │ + â•žâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•¡ + │ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV sr25519 Mnemonic <Base> Mother │ + │ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH //0 Child 1 │ + │ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d //0 Grandchild 1 │ + │ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o //1 <Mother//1> │ + │ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT //1 <Mother//1//1> │ + │ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 ed25519 G1v1 <Base> MotherG1v1 │ + └─────────────────────────────────────────────────────────────────────────────────────────────────────┘"# + }; + + assert_eq!(table_with_type.to_string(), expected_table_with_type); + } } } diff --git a/src/entities/vault_account.rs b/src/entities/vault_account.rs index d04b02ad71ce2f1805c7b63a683a28d834d545ad..939ee755f5083ef0ad0864caa5676bc965f12b5b 100644 --- a/src/entities/vault_account.rs +++ b/src/entities/vault_account.rs @@ -40,6 +40,8 @@ pub struct Model { pub encrypted_suri: Option<Vec<u8>>, /// ForeignKey to parent vault_account SS58 Address - None if for a "base" account pub parent: Option<DbAccountId>, + /// Secret format used for the account - Only set for "base" accounts + pub secret_format: Option<DbSecretFormat>, } impl Model { @@ -243,6 +245,46 @@ impl From<DbCryptoScheme> for crate::keys::CryptoScheme { } } +/// Enum for SecretFormat in the database +#[derive(Debug, Copy, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)] +#[sea_orm( + rs_type = "String", + db_type = "String(StringLen::None)", + enum_name = "secret_format" +)] +pub enum DbSecretFormat { + #[sea_orm(string_value = "seed")] + Seed, + #[sea_orm(string_value = "substrate")] + Substrate, + #[sea_orm(string_value = "predefined")] + Predefined, + #[sea_orm(string_value = "g1v1")] + G1v1, +} + +impl From<crate::keys::SecretFormat> for DbSecretFormat { + fn from(format: crate::keys::SecretFormat) -> Self { + match format { + crate::keys::SecretFormat::Seed => DbSecretFormat::Seed, + crate::keys::SecretFormat::Substrate => DbSecretFormat::Substrate, + crate::keys::SecretFormat::Predefined => DbSecretFormat::Predefined, + crate::keys::SecretFormat::G1v1 => DbSecretFormat::G1v1, + } + } +} + +impl From<DbSecretFormat> for crate::keys::SecretFormat { + fn from(format: DbSecretFormat) -> Self { + match format { + DbSecretFormat::Seed => crate::keys::SecretFormat::Seed, + DbSecretFormat::Substrate => crate::keys::SecretFormat::Substrate, + DbSecretFormat::Predefined => crate::keys::SecretFormat::Predefined, + DbSecretFormat::G1v1 => crate::keys::SecretFormat::G1v1, + } + } +} + #[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation { ParentAccount, @@ -868,6 +910,7 @@ pub async fn create_base_account<C>( name: Option<&String>, crypto_scheme: crate::keys::CryptoScheme, encrypted_suri: Vec<u8>, + secret_format: crate::keys::SecretFormat, ) -> Result<Model, GcliError> where C: ConnectionTrait, @@ -890,6 +933,7 @@ where crypto_scheme: Set(Some(crypto_scheme.into())), encrypted_suri: Set(Some(encrypted_suri)), parent: Default::default(), + secret_format: Set(Some(secret_format.into())), }; vault_account.insert(db).await? } @@ -927,6 +971,7 @@ where crypto_scheme: Set(None), encrypted_suri: Set(None), parent: Set(Some(parent_address.to_string().into())), + secret_format: Set(None), }; vault_account.insert(db).await? } @@ -983,6 +1028,7 @@ pub mod tests { crypto_scheme: None, encrypted_suri: None, parent: Some(child1_address.clone()), + secret_format: None, }, children: vec![], parent: None, @@ -997,6 +1043,7 @@ pub mod tests { crypto_scheme: None, encrypted_suri: None, parent: Some(child2_address.clone()), + secret_format: None, }, children: vec![], parent: None, @@ -1010,6 +1057,7 @@ pub mod tests { crypto_scheme: None, encrypted_suri: None, parent: Some(mother_address.clone()), + secret_format: None, }, children: vec![grandchild1.clone()], parent: None, @@ -1024,6 +1072,7 @@ pub mod tests { crypto_scheme: None, encrypted_suri: None, parent: Some(mother_address.clone()), + secret_format: None, }, children: vec![grandchild2.clone()], parent: None, @@ -1039,6 +1088,7 @@ pub mod tests { vault::encrypt(SUBSTRATE_MNEMONIC.as_bytes(), "".to_string()).unwrap(), ), parent: None, + secret_format: Some(DbSecretFormat::Substrate), }, children: vec![child1.clone(), child2.clone()], parent: None, @@ -1073,6 +1123,7 @@ pub mod tests { vault::encrypt(secret_suri.as_bytes(), "".to_string()).unwrap(), ), parent: None, + secret_format: Some(DbSecretFormat::G1v1), }, children: vec![], parent: None,