Skip to content
Snippets Groups Projects
Select Git revision
  • 250494e936be0eea7aafbcec8cd1d8f33b504cb1
  • main default protected
2 results

HomeView.vue

Blame
  • display.rs 24.26 KiB
    use crate::commands::cesium;
    use crate::entities::vault_account;
    use crate::entities::vault_account::AccountTreeNode;
    use crate::keys::CryptoScheme;
    use crate::utils::GcliError;
    use comfy_table::{Cell, Table};
    use serde::Serialize;
    use std::cell::RefCell;
    use std::rc::Rc;
    use std::str;
    
    #[deprecated(
    	note = "Should be removed in a future version when db persistence of vault is present for a while"
    )]
    pub fn compute_vault_key_files_table(vault_key_addresses: &[String]) -> Result<Table, GcliError> {
    	let mut table = Table::new();
    	table.load_preset(comfy_table::presets::UTF8_BORDERS_ONLY);
    	table.set_header(vec!["Key file"]);
    
    	vault_key_addresses.iter().for_each(|address| {
    		table.add_row(vec![Cell::new(address)]);
    	});
    
    	Ok(table)
    }
    
    pub fn compute_vault_accounts_table(
    	account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
    ) -> Result<Table, GcliError> {
    	// Calling the new function with show_g1v1 = true to maintain compatibility
    	compute_vault_accounts_table_with_g1v1(account_tree_nodes, true)
    }
    
    pub fn compute_vault_accounts_table_with_g1v1(
    	account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
    	show_g1v1: bool,
    ) -> Result<Table, GcliError> {
    	let mut table = Table::new();
    	table.load_preset(comfy_table::presets::UTF8_BORDERS_ONLY);
    
    	// Prepare header based on options
    	table.set_header(vec![
    		if show_g1v1 {
    			"SS58 Address/G1v1 public key"
    		} else {
    			"SS58 Address"
    		},
    		"Crypto",
    		"Path",
    		"Name",
    	]);
    
    	for account_tree_node in account_tree_nodes {
    		let _ = add_account_tree_node_to_table_with_g1v1(&mut table, account_tree_node, show_g1v1);
    	}
    
    	Ok(table)
    }
    
    fn add_account_tree_node_to_table_with_g1v1(
    	table: &mut Table,
    	account_tree_node: &Rc<RefCell<AccountTreeNode>>,
    	show_g1v1: bool,
    ) -> Result<(), GcliError> {
    	let rows = compute_vault_accounts_row_with_g1v1(account_tree_node, show_g1v1)?;
    	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);
    	}
    
    	Ok(())
    }
    
    /// 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 if show_g1v1 is true
    pub fn compute_vault_accounts_row_with_g1v1(
    	account_tree_node: &Rc<RefCell<AccountTreeNode>>,
    	show_g1v1: bool,
    ) -> Result<Vec<Vec<Cell>>, GcliError> {
    	let empty_string = "".to_string();
    
    	let depth_account_tree_node = vault_account::count_depth_account_tree_node(account_tree_node);
    
    	let name = if let Some(name) = account_tree_node.borrow().account.name.clone() {
    		name
    	} else if let Some(computed_name) =
    		vault_account::compute_name_account_tree_node(account_tree_node)
    	{
    		format!("<{}>", computed_name)
    	} else {
    		empty_string.clone()
    	};
    
    	let account_tree_node = account_tree_node.borrow();
    
    	let address = if depth_account_tree_node > 0 {
    		let ancestors = "│ ".repeat(depth_account_tree_node - 1);
    		format!("{}├ {}", ancestors, account_tree_node.account.address)
    	} else {
    		account_tree_node.account.address.to_string()
    	};
    
    	let mut rows: Vec<Vec<Cell>> = vec![];
    
    	let (path, crypto) = if let Some(path) = account_tree_node.account.path.clone() {
    		(path, empty_string.clone())
    	} else {
    		let crypto_scheme = CryptoScheme::from(account_tree_node.account.crypto_scheme.unwrap());
    		let crypto_scheme_str: &str = crypto_scheme.into();
    
    		// 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!(
    				"└ G1v1: {}",
    				cesium::compute_g1v1_public_key_from_ed25519_account_id(
    					&account_tree_node.account.address.0
    				)
    			))]);
    		}
    
    		(
    			format!("<{}>", account_tree_node.account.account_type()),
    			crypto_scheme_str.to_string(),
    		)
    	};
    
    	// Add the first line
    	rows.insert(
    		0,
    		vec![
    			Cell::new(&address),
    			Cell::new(crypto),
    			Cell::new(&path),
    			Cell::new(&name),
    		],
    	);
    
    	Ok(rows)
    }
    
    /// Serializable structure for JSON output
    #[derive(Serialize)]
    pub struct VaultAccountView {
    	address: String,
    	crypto_scheme: Option<String>,
    	path: String,
    	name: String,
    	g1v1_public_key: Option<String>,
    	children: Vec<VaultAccountView>,
    }
    
    /// Compute a serializable structure for JSON output
    pub fn compute_vault_accounts_json(
    	account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
    	show_g1v1: bool,
    ) -> Vec<VaultAccountView> {
    	let mut result = Vec::new();
    
    	for account_tree_node in account_tree_nodes {
    		result.push(compute_vault_account_json(account_tree_node, show_g1v1));
    	}
    
    	result
    }
    
    /// Compute a serializable structure for a single account tree node
    fn compute_vault_account_json(
    	account_tree_node: &Rc<RefCell<AccountTreeNode>>,
    	show_g1v1: bool,
    ) -> VaultAccountView {
    	let empty_string = "".to_string();
    	let borrowed_node = account_tree_node.borrow();
    
    	let name = if let Some(name) = borrowed_node.account.name.clone() {
    		name
    	} else if let Some(computed_name) =
    		vault_account::compute_name_account_tree_node(account_tree_node)
    	{
    		format!("<{}>", computed_name)
    	} else {
    		empty_string.clone()
    	};
    
    	let (path, crypto_scheme, g1v1_public_key) =
    		if let Some(path) = borrowed_node.account.path.clone() {
    			(path, None, None)
    		} else {
    			let crypto_scheme = borrowed_node.account.crypto_scheme.map(|cs| {
    				let scheme = CryptoScheme::from(cs);
    				let scheme_str: &str = scheme.into();
    				scheme_str.to_string()
    			});
    
    			let g1v1_public_key = if show_g1v1 && crypto_scheme.as_deref() == Some("ed25519") {
    				Some(cesium::compute_g1v1_public_key_from_ed25519_account_id(
    					&borrowed_node.account.address.0,
    				))
    			} else {
    				None
    			};
    
    			(
    				format!("<{}>", borrowed_node.account.account_type()),
    				crypto_scheme,
    				g1v1_public_key,
    			)
    		};
    
    	let mut children = Vec::new();
    	for child in &borrowed_node.children {
    		children.push(compute_vault_account_json(child, show_g1v1));
    	}
    
    	VaultAccountView {
    		address: borrowed_node.account.address.to_string(),
    		crypto_scheme,
    		path,
    		name,
    		g1v1_public_key,
    		children,
    	}
    }
    
    #[cfg(test)]
    mod tests {
    	mod vault_accounts_table_tests {
    		use crate::commands::vault::display::{
    			compute_vault_accounts_table, compute_vault_accounts_table_with_g1v1,
    		};
    		use crate::entities::vault_account::tests::account_tree_node_tests::{
    			mother_account_tree_node, mother_g1v1_account_tree_node,
    		};
    		use indoc::indoc;
    
    		// Tests for compute_vault_accounts_table (old function)
    		#[test]
    		fn test_compute_vault_accounts_table_empty() {
    			let table = compute_vault_accounts_table(&[]).unwrap();
    
    			let expected_table = indoc! {r#"
    			┌─────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key   Crypto   Path   Name │
    			╞═════════════════════════════════════════════════════╡
    			└─────────────────────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table.to_string(), expected_table);
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_table() {
    			let account_tree_node = mother_account_tree_node();
    			let g1v1_account_tree_node = mother_g1v1_account_tree_node();
    
    			let table =
    				compute_vault_accounts_table(&[account_tree_node, g1v1_account_tree_node]).unwrap();
    
    			let expected_table = indoc! {r#"
    			┌──────────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key                           Crypto    Path     Name           │
    			╞══════════════════════════════════════════════════════════════════════════════════════════╡
    			│ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV       sr25519   <Base>   Mother         │
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH               //0      Child 1        │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d             //0      Grandchild 1   │
    			│ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o               //1      <Mother//1>    │
    			│ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT             //1      <Mother//1//1> │
    			│ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4       ed25519   <Base>   MotherG1v1     │
    			│ └ G1v1: 86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7                                     │
    			└──────────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table.to_string(), expected_table);
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_table_partial() {
    			let mother = mother_account_tree_node();
    			let child1 = mother.borrow().children[0].clone();
    
    			let table = compute_vault_accounts_table(&[child1]).unwrap();
    
    			let expected_table = indoc! {r#"
    			┌─────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key                           Crypto   Path   Name         │
    			╞═════════════════════════════════════════════════════════════════════════════════════╡
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH              //0    Child 1      │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d            //0    Grandchild 1 │
    			└─────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table.to_string(), expected_table);
    		}
    
    		// Tests for compute_vault_accounts_table_with_g1v1
    		#[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 expected_table_with_g1v1 = indoc! {r#"
    			┌─────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key   Crypto   Path   Name │
    			╞═════════════════════════════════════════════════════╡
    			└─────────────────────────────────────────────────────┘"#
    			};
    
    			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 expected_table_without_g1v1 = indoc! {r#"
    			┌─────────────────────────────────────┐
    			│ SS58 Address   Crypto   Path   Name │
    			╞═════════════════════════════════════╡
    			└─────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table.to_string(), expected_table_without_g1v1);
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_table_with_g1v1() {
    			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_g1v1 = true (default behavior)
    			let table_with_g1v1 =
    				compute_vault_accounts_table_with_g1v1(&account_tree_nodes, true).unwrap();
    			let expected_table_with_g1v1 = indoc! {r#"
    			┌──────────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key                           Crypto    Path     Name           │
    			╞══════════════════════════════════════════════════════════════════════════════════════════╡
    			│ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV       sr25519   <Base>   Mother         │
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH               //0      Child 1        │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d             //0      Grandchild 1   │
    			│ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o               //1      <Mother//1>    │
    			│ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT             //1      <Mother//1//1> │
    			│ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4       ed25519   <Base>   MotherG1v1     │
    			│ └ G1v1: 86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7                                     │
    			└──────────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			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 expected_table_without_g1v1 = indoc! {r#"
    			┌──────────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address                                           Crypto    Path     Name           │
    			╞══════════════════════════════════════════════════════════════════════════════════════════╡
    			│ 5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV       sr25519   <Base>   Mother         │
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH               //0      Child 1        │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d             //0      Grandchild 1   │
    			│ ├ 5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o               //1      <Mother//1>    │
    			│ │ ├ 5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT             //1      <Mother//1//1> │
    			│ 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4       ed25519   <Base>   MotherG1v1     │
    			└──────────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1);
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_table_with_g1v1_partial() {
    			let mother = mother_account_tree_node();
    			let child1 = mother.borrow().children[0].clone();
    			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 expected_table_with_g1v1 = indoc! {r#"
    			┌─────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address/G1v1 public key                           Crypto   Path   Name         │
    			╞═════════════════════════════════════════════════════════════════════════════════════╡
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH              //0    Child 1      │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d            //0    Grandchild 1 │
    			└─────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			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 expected_table_without_g1v1 = indoc! {r#"
    			┌─────────────────────────────────────────────────────────────────────────────────────┐
    			│ SS58 Address                                           Crypto   Path   Name         │
    			╞═════════════════════════════════════════════════════════════════════════════════════╡
    			│ ├ 5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH              //0    Child 1      │
    			│ │ ├ 5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d            //0    Grandchild 1 │
    			└─────────────────────────────────────────────────────────────────────────────────────┘"#
    			};
    
    			assert_eq!(table_without_g1v1.to_string(), expected_table_without_g1v1);
    		}
    	}
    
    	mod vault_accounts_json_view_tests {
    		use crate::commands::vault::display::{compute_vault_accounts_json, VaultAccountView};
    		use crate::entities::vault_account::tests::account_tree_node_tests::{
    			mother_account_tree_node, mother_g1v1_account_tree_node,
    		};
    		use log::{debug, LevelFilter};
    		use pretty_assertions::assert_eq;
    		use serde_json::{json, Value};
    
    		/// This allows to activate debug logs for the tests (to retrieve ACTUAL values in logs)
    		#[allow(dead_code)]
    		fn init_logger_in_debug() {
    			let _ = env_logger::builder()
    				.is_test(true)
    				.filter_level(LevelFilter::Debug)
    				.try_init();
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_json_view_with_g1v1() {
    			// init_logger_in_debug();
    
    			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_g1v1 = true (default behavior)
    			let view_with_g1v1 = compute_vault_accounts_json(&account_tree_nodes, true);
    			let expected_json_with_g1v1 = json! ([
    			  {
    				"address": "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV",
    				"crypto_scheme": "sr25519",
    				"path": "<Base>",
    				"name": "Mother",
    				"g1v1_public_key": null,
    				"children": [
    				  {
    					"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
    					"crypto_scheme": null,
    					"path": "//0",
    					"name": "Child 1",
    					"g1v1_public_key": null,
    					"children": [
    					  {
    						"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
    						"crypto_scheme": null,
    						"path": "//0",
    						"name": "Grandchild 1",
    						"g1v1_public_key": null,
    						"children": []
    					  }
    					]
    				  },
    				  {
    					"address": "5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
    					"crypto_scheme": null,
    					"path": "//1",
    					"name": "<Mother//1>",
    					"g1v1_public_key": null,
    					"children": [
    					  {
    						"address": "5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT",
    						"crypto_scheme": null,
    						"path": "//1",
    						"name": "<Mother//1//1>",
    						"g1v1_public_key": null,
    						"children": []
    					  }
    					]
    				  }
    				]
    			  },
    			  {
    				"address": "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4",
    				"crypto_scheme": "ed25519",
    				"path": "<Base>",
    				"name": "MotherG1v1",
    				"g1v1_public_key": "86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7",
    				"children": [],
    			  }
    			]);
    
    			assert_eq!(get_json_value(&view_with_g1v1), expected_json_with_g1v1);
    
    			// Test with show_g1v1 = false
    			let view_without_g1v1 = compute_vault_accounts_json(&account_tree_nodes, false);
    			let expected_json_without_g1v1 = json! ([
    			  {
    				"address": "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqRzV",
    				"crypto_scheme": "sr25519",
    				"path": "<Base>",
    				"name": "Mother",
    				"g1v1_public_key": null,
    				"children": [
    				  {
    					"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
    					"crypto_scheme": null,
    					"path": "//0",
    					"name": "Child 1",
    					"g1v1_public_key": null,
    					"children": [
    					  {
    						"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
    						"crypto_scheme": null,
    						"path": "//0",
    						"name": "Grandchild 1",
    						"g1v1_public_key": null,
    						"children": []
    					  }
    					]
    				  },
    				  {
    					"address": "5GBNeWRhZc2jXu7D55rBimKYDk8PGk8itRYFTPfC8RJLKG5o",
    					"crypto_scheme": null,
    					"path": "//1",
    					"name": "<Mother//1>",
    					"g1v1_public_key": null,
    					"children": [
    					  {
    						"address": "5CvdJuB9HLXSi5FS9LW57cyHF13iCv5HDimo2C45KxnxriCT",
    						"crypto_scheme": null,
    						"path": "//1",
    						"name": "<Mother//1//1>",
    						"g1v1_public_key": null,
    						"children": []
    					  }
    					]
    				  }
    				]
    			  },
    			  {
    				"address": "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4",
    				"crypto_scheme": "ed25519",
    				"path": "<Base>",
    				"name": "MotherG1v1",
    				"g1v1_public_key": null,
    				"children": []
    			  }
    			]);
    
    			assert_eq!(
    				get_json_value(&view_without_g1v1),
    				expected_json_without_g1v1
    			);
    		}
    
    		#[test]
    		fn test_compute_vault_accounts_json_view_with_g1v1_partial() {
    			// init_logger_in_debug();
    
    			let mother = mother_account_tree_node();
    			let child1 = mother.borrow().children[0].clone();
    			let account_tree_nodes = vec![child1];
    
    			// Test with show_g1v1 = true (default behavior)
    			let view_with_g1v1 = compute_vault_accounts_json(&account_tree_nodes, true);
    			let expected_json_with_g1v1_unused = json! ([
    			  {
    				"address": "5D34dL5prEUaGNQtPPZ3yN5Y6BnkfXunKXXz6fo7ZJbLwRRH",
    				"crypto_scheme": null,
    				"path": "//0",
    				"name": "Child 1",
    				"g1v1_public_key": null,
    				"children": [
    				  {
    					"address": "5Fh5PLQNt1xuEXm71dfDtQdnwceSew4oHewWBLsWAkKspV7d",
    					"crypto_scheme": null,
    					"path": "//0",
    					"name": "Grandchild 1",
    					"g1v1_public_key": null,
    					"children": [],
    				  }
    				]
    			  }
    			]);
    
    			assert_eq!(
    				get_json_value(&view_with_g1v1),
    				expected_json_with_g1v1_unused
    			);
    
    			// Test with show_g1v1 = false
    			let view_without_g1v1 = compute_vault_accounts_json(&account_tree_nodes, false);
    
    			assert_eq!(
    				get_json_value(&view_without_g1v1),
    				expected_json_with_g1v1_unused
    			);
    		}
    
    		fn get_json_value(views: &Vec<VaultAccountView>) -> Value {
    			let view_json_string = serde_json::to_string_pretty(&views).unwrap();
    			debug!("Actual JSON:\n{}", view_json_string);
    			let view_json_value: Value = serde_json::from_str(&view_json_string).unwrap();
    			view_json_value
    		}
    	}
    }