diff --git a/src/commands/vault.rs b/src/commands/vault.rs
index 716947789d010412f329d410f6822bb9ca0b0bb3..267a0c26bc870482f0c246fab2ba48eb20c2ce4e 100644
--- a/src/commands/vault.rs
+++ b/src/commands/vault.rs
@@ -1,9 +1,13 @@
 use crate::commands::cesium::compute_g1v1_public_key;
 use crate::entities::vault_account;
-use crate::entities::vault_account::{AccountTreeNode, DbAccountId};
+use crate::entities::vault_account::{
+	fetch_base_account_tree_node_hierarchy_unwrapped, get_account_tree_node_for_address,
+	get_base_parent_hierarchy_account_tree_node, AccountTreeNode, ActiveModel, DbAccountId,
+};
 use crate::*;
 use age::secrecy::Secret;
 use comfy_table::{Cell, Table};
+use sea_orm::ActiveValue::Set;
 use sea_orm::ModelTrait;
 use sea_orm::{ConnectionTrait, TransactionTrait};
 use sp_core::crypto::AddressUri;
@@ -66,6 +70,11 @@ pub enum Subcommand {
 		#[clap(flatten)]
 		address_or_vault_name: AddressOrVaultNameGroup,
 	},
+	/// Inspect a vault entry, retrieving its Substrate URI (will provide more data in a future version)
+	Inspect {
+		#[clap(flatten)]
+		address_or_vault_name: AddressOrVaultNameGroup,
+	},
 	/// (deprecated)List available key files (needs to be migrated with command `vault migrate` in order to use them)
 	ListFiles,
 	/// (deprecated)Migrate old key files into db (will have to provide password for each key)
@@ -206,53 +215,16 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 				}
 			}
 
-			let address_to_import = vault_data_for_import.key_pair.address();
-
-			println!("Trying to import for SS58 address :'{}'", address_to_import);
-
-			if let Some(check_account) =
-				vault_account::find_by_id(db, &DbAccountId::from(address_to_import)).await?
-			{
-				println!(
-					"Vault entry already exists for that address: {}",
-					check_account
-				);
-
-				let account_tree_node_hierarchy =
-					vault_account::fetch_base_account_tree_node_hierarchy_unwrapped(
-						db,
-						&check_account.address.to_string(),
-					)
-					.await?;
-
-				println!("Here are all the SS58 Addresses linked to it in the vault:");
-
-				let table = compute_vault_accounts_table(&[account_tree_node_hierarchy])?;
-				println!("{table}");
-
-				return Ok(());
-				//TODO For later, possibly allow to replace the entry
-			}
-
-			println!("Enter password to protect the key");
-			let password = inputs::prompt_password_confirm()?;
-
-			println!("(Optional) Enter a name for the vault entry");
-			let name = inputs::prompt_vault_name()?;
-
 			let txn = db.begin().await?;
 
-			let _account = create_account_for_vault_data_to_import(
-				&txn,
-				&vault_data_for_import,
-				&password,
-				name.as_ref(),
-			)
-			.await?;
+			println!();
+			let _account =
+				create_base_account_for_vault_data_to_import(&txn, &vault_data_for_import, None)
+					.await?;
 
 			txn.commit().await?;
 
-			println!("Import done");
+			println!("Change done");
 		}
 		Subcommand::Derive {
 			address_or_vault_name,
@@ -289,6 +261,19 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 
 			println!("Adding derivation to: {account_to_derive}");
 
+			let base_parent_hierarchy_account_tree_node_to_derive =
+				get_base_parent_hierarchy_account_tree_node(&account_tree_node_to_derive);
+
+			let parent_hierarchy_table_account_to_derive =
+				compute_vault_accounts_table(&[base_parent_hierarchy_account_tree_node_to_derive])?;
+
+			println!();
+			println!("It's parent hierarchy is this:");
+			println!("{parent_hierarchy_table_account_to_derive}");
+			println!();
+
+			println!("The linked <Base> account is {base_account}");
+
 			println!("Enter password to decrypt the <Base> account key");
 			let password = inputs::prompt_password()?;
 
@@ -297,6 +282,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 				password,
 			)?;
 
+			println!();
 			let derivation_path = inputs::prompt_vault_derivation_path()?;
 
 			let derivation_secret_suri =
@@ -307,28 +293,19 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 
 			let derivation_address: String = derivation_keypair.address().to_string();
 
-			let check_derivation =
-				vault_account::find_by_id(db, &DbAccountId::from_str(&derivation_address)?).await?;
-
-			//TODO For later, possibly allow to replace the entry
-			if check_derivation.is_some() {
-				println!("Derivation already exists for address:'{derivation_address}'");
-				return Ok(());
-			}
-
-			println!("(Optional) Enter a name for the new derivation");
-			let name = inputs::prompt_vault_name()?;
+			let txn = db.begin().await?;
 
-			let _derivation = vault_account::create_derivation_account(
-				db,
+			println!();
+			let _derivation = create_derivation_account(
+				&txn,
 				&derivation_address,
-				name.as_ref(),
 				&derivation_path,
 				&account_to_derive.address.to_string(),
 			)
 			.await?;
 
-			println!("Derive done");
+			txn.commit().await?;
+			println!("Change done");
 		}
 		Subcommand::Rename { address } => {
 			let account =
@@ -348,7 +325,8 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 			);
 
 			println!("Enter new name for address (leave empty to remove the name)");
-			let name = inputs::prompt_vault_name()?;
+			let name =
+				inputs::prompt_vault_name_and_check_availability(db, account.name.as_ref()).await?;
 
 			let _account = vault_account::update_account_name(db, account, name.as_ref()).await?;
 
@@ -408,6 +386,22 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 
 			println!("Done removing address:'{address_to_delete}'");
 		}
+		Subcommand::Inspect {
+			address_or_vault_name,
+		} => {
+			let account_tree_node_to_derive =
+				retrieve_account_tree_node(&data, address_or_vault_name).await?;
+
+			println!("Enter password to decrypt the <Base> account key");
+			let password = inputs::prompt_password()?;
+
+			let account_to_derive_secret_suri = vault_account::compute_suri_account_tree_node(
+				&account_tree_node_to_derive,
+				password,
+			)?;
+
+			println!("Substrate URI: '{account_to_derive_secret_suri}'")
+		}
 		Subcommand::Migrate => {
 			println!("Migrating existing key files to db");
 
@@ -450,16 +444,23 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 
 				let txn = db.begin().await?;
 
-				let account = create_account_for_vault_data_to_import(
+				let account = create_base_account_for_vault_data_to_import(
 					&txn,
 					&vault_data_to_import,
-					&vault_data_from_file.password,
-					None,
+					Some(&vault_data_from_file.password),
 				)
-				.await?;
+				.await;
 
-				txn.commit().await?;
-				println!("Import done: {}", account);
+				match account {
+					Ok(_account) => {
+						txn.commit().await?;
+						println!("Change done");
+					}
+					Err(error) => {
+						println!("Error occurred: {error}");
+						println!("Continuing to next key");
+					}
+				}
 			}
 
 			println!("Migration done");
@@ -568,7 +569,7 @@ async fn compute_vault_key_files_table(vault_key_addresses: &[String]) -> Result
 	Ok(table)
 }
 
-fn compute_vault_accounts_table(
+pub fn compute_vault_accounts_table(
 	account_tree_nodes: &[Rc<RefCell<AccountTreeNode>>],
 ) -> Result<Table, GcliError> {
 	let mut table = Table::new();
@@ -767,51 +768,252 @@ fn prompt_secret_and_compute_vault_data_to_import(
 	}
 }
 
-/// Creates an account for the vault data to import
+/// Creates a `base` vault account for vault_data provided and returns it
+///
+/// Does extra checks and asks for user input in case the address is already present in the vault.
 ///
-/// Does it all using "db" parameter that should better be a transaction since multiple operations can be done
-pub async fn create_account_for_vault_data_to_import<C>(
-	db: &C,
+/// Can request password and (optional) name to the user at the proper time
+///
+/// Typically used for `vault import|migrate` commands
+pub async fn create_base_account_for_vault_data_to_import<C>(
+	db_tx: &C,
 	vault_data: &VaultDataToImport,
-	password: &str,
-	name: Option<&String>,
+	password: Option<&String>,
 ) -> Result<vault_account::Model, GcliError>
 where
 	C: ConnectionTrait,
 {
 	let address_to_import = vault_data.key_pair.address().to_string();
-	//To be safe
-	if vault_account::find_by_id(db, &DbAccountId::from_str(&address_to_import)?)
-		.await?
-		.is_some()
+	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?
 	{
-		//TODO Later possibly allow to replace the entry
-		return Err(GcliError::Input(format!(
-			"Vault entry already exists for address {}",
-			&address_to_import
-		)));
-	}
+		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 =
+				fetch_base_account_tree_node_hierarchy_unwrapped(db_tx, &address_to_import).await?;
+			let account_tree_node_for_address =
+				get_account_tree_node_for_address(&account_tree_node_hierarchy, &address_to_import);
+
+			let base_parent_hierarchy_account_tree_node =
+				get_base_parent_hierarchy_account_tree_node(&account_tree_node_for_address);
+
+			let parent_hierarchy_table =
+				compute_vault_accounts_table(&[base_parent_hierarchy_account_tree_node])?;
+
+			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!("It's 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 secret_format = vault_data.secret_format;
+		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 = encrypt(
-		vault_data.secret_suri.clone().as_bytes(),
-		password.to_string(),
-	)
-	.map_err(|e| anyhow!(e))?;
+				println!(
+					"(Optional) Enter a name for the vault entry (leave empty to remove the name)"
+				);
+				let name = inputs::prompt_vault_name_and_check_availability(
+					db_tx,
+					existing_vault_account.name.as_ref(),
+				)
+				.await?;
 
-	let crypto_scheme = map_secret_format_to_crypto_scheme(secret_format);
+				// Since links are made based on address / parent(address) we can just edit the existing entry and it should be fine
+				let mut vault_account: ActiveModel = existing_vault_account.into();
+				vault_account.path = Set(None);
+				vault_account.parent = Set(None);
+				vault_account.crypto_scheme = Set(Some(
+					map_secret_format_to_crypto_scheme(vault_data.secret_format).into(),
+				));
+				vault_account.encrypted_suri = Set(Some(encrypted_suri));
+				vault_account.name = Set(name.clone());
+				let updated_vault_account =
+					vault_account::update_account(db_tx, vault_account).await?;
+
+				println!("Updating vault account {updated_vault_account}");
+				updated_vault_account
+			}
+			_ => {
+				return Err(GcliError::Input("import canceled".into()));
+			}
+		}
+	} else {
+		//New entry
+		let secret_format = vault_data.secret_format;
 
-	let base_account = vault_account::create_base_account(
-		db,
-		&address_to_import,
-		name,
-		crypto_scheme,
-		encrypted_suri,
-	)
-	.await?;
+		let encrypted_suri = compute_encrypted_suri(password, vault_data.secret_suri.clone())?;
+
+		println!("(Optional) Enter a name for the vault entry");
+		let name = inputs::prompt_vault_name_and_check_availability(db_tx, None).await?;
+
+		let crypto_scheme = map_secret_format_to_crypto_scheme(secret_format);
+
+		let base_account = vault_account::create_base_account(
+			db_tx,
+			&address_to_import,
+			name.as_ref(),
+			crypto_scheme,
+			encrypted_suri,
+		)
+		.await?;
+		println!("Creating <Base> account {base_account}");
+
+		base_account
+	};
+
+	Ok(vault_account)
+}
+
+/// Creates a `derivation` vault account for data provided and returns it
+///
+/// Does extra checks and asks for user input in case the address is already present in the vault.
+///
+/// Can request (optional) name to the user at the proper time
+///
+/// Typically used for `vault derive` command
+pub async fn create_derivation_account<C>(
+	db_tx: &C,
+	derivation_address: &String,
+	derivation_path: &String,
+	parent_address: &String,
+) -> Result<vault_account::Model, GcliError>
+where
+	C: ConnectionTrait,
+{
+	println!("Trying to create derivation with address '{derivation_address}'");
+	println!();
+	let vault_account = if let Some(existing_vault_account) =
+		vault_account::find_by_id(db_tx, &DbAccountId::from(derivation_address.clone())).await?
+	{
+		// Existing account
+		println!("You are trying to derive '{derivation_path}' from parent '{parent_address}'");
+
+		if existing_vault_account.is_base_account() {
+			println!(
+				"but it is already present as a direct <Base> account '{}'",
+				existing_vault_account.address
+			);
+
+			println!("Do you want to:");
+			println!("1. keep the existing <Base> account and cancel import");
+			println!("2. delete the existing <Base> account and associated key and replace it with the new derivation account (children will be re-parented)");
+		} else {
+			//Existing derivation
+			let existing_account_tree_node_hierarchy =
+				fetch_base_account_tree_node_hierarchy_unwrapped(db_tx, derivation_address).await?;
+
+			let existing_account_tree_node_for_address = get_account_tree_node_for_address(
+				&existing_account_tree_node_hierarchy,
+				derivation_address,
+			);
+
+			let base_parent_hierarchy_existing_account_tree_node =
+				get_base_parent_hierarchy_account_tree_node(
+					&existing_account_tree_node_for_address,
+				);
+
+			let parent_hierarchy_table_existing_account =
+				compute_vault_accounts_table(&[base_parent_hierarchy_existing_account_tree_node])?;
+
+			println!(
+				"but it is already present as `{}` derivation of '{}' account.",
+				existing_vault_account.path.clone().unwrap(),
+				existing_vault_account.parent.clone().unwrap()
+			);
+
+			println!();
+			println!("It's parent hierarchy is this:");
+			println!("{parent_hierarchy_table_existing_account}");
+			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 this new derivation (children will be re-parented)");
+		}
+
+		let result = inputs::select_action("Your choice?", vec!["1", "2"])?;
+		match result {
+			"2" => {
+				println!(
+					"(Optional) Enter a name for the vault entry (leave empty to remove the name)"
+				);
+				let name = inputs::prompt_vault_name_and_check_availability(
+					db_tx,
+					existing_vault_account.name.as_ref(),
+				)
+				.await?;
+
+				// Since links are made based on address / parent(address) we can just edit the existing entry and it should be fine
+				let mut vault_account: ActiveModel = existing_vault_account.into();
+				vault_account.path = Set(Some(derivation_path.clone()));
+				vault_account.parent = Set(Some(DbAccountId::from(parent_address.clone())));
+				vault_account.crypto_scheme = Set(None);
+				vault_account.encrypted_suri = Set(None);
+				vault_account.name = Set(name.clone());
+				let updated_vault_account =
+					vault_account::update_account(db_tx, vault_account).await?;
+
+				println!("Updating vault account {updated_vault_account}");
+				updated_vault_account
+			}
+			_ => {
+				return Err(GcliError::Input("derive canceled".into()));
+			}
+		}
+	} else {
+		println!("(Optional) Enter a name for the vault entry");
+		let name = inputs::prompt_vault_name_and_check_availability(db_tx, None).await?;
+
+		let derivation = vault_account::create_derivation_account(
+			db_tx,
+			derivation_address,
+			name.as_ref(),
+			derivation_path,
+			parent_address,
+		)
+		.await?;
+		println!("Creating derivation account {derivation}");
+
+		derivation
+	};
+
+	Ok(vault_account)
+}
+
+/// Function will ask for password if not present and compute the encrypted suri
+fn compute_encrypted_suri(
+	password: Option<&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(base_account)
+	Ok(encrypt(secret_suri.as_bytes(), password).map_err(|e| anyhow!(e))?)
 }
 
 fn get_vault_key_path(data: &Data, vault_filename: &str) -> PathBuf {
diff --git a/src/entities/vault_account.rs b/src/entities/vault_account.rs
index 71905ec368d410630e4c5bedb9560e072b1098b9..797a50e4bad9bd368de882d6783e55bd368895b9 100644
--- a/src/entities/vault_account.rs
+++ b/src/entities/vault_account.rs
@@ -4,7 +4,6 @@ use anyhow::anyhow;
 use sea_orm::prelude::async_trait::async_trait;
 use sea_orm::prelude::StringLen;
 use sea_orm::ActiveValue::Set;
-use sea_orm::FromJsonQueryResult;
 use sea_orm::QueryFilter;
 use sea_orm::{
 	ActiveModelBehavior, ColumnTrait, DbErr, DeriveEntityModel, DerivePrimaryKey, EnumIter, Linked,
@@ -12,6 +11,7 @@ use sea_orm::{
 };
 use sea_orm::{ActiveModelTrait, ConnectionTrait, PrimaryKeyTrait};
 use sea_orm::{DeriveActiveEnum, EntityTrait};
+use sea_orm::{FromJsonQueryResult, PaginatorTrait};
 use serde::{Deserialize, Serialize};
 use std::cell::RefCell;
 use std::collections::HashMap;
@@ -228,8 +228,8 @@ impl ActiveModelBehavior for ActiveModel {
 						&& self.encrypted_suri.try_as_ref().unwrap().is_some()))
 				{
 					return Err(DbErr::Custom(
-					"A \"base\" vault account must have path:None, parent:None, crypto_scheme:Some(_), encrypted_suri:Some(_)".into(),
-				));
+                        "A \"base\" vault account must have path:None, parent:None, crypto_scheme:Some(_), encrypted_suri:Some(_)".into(),
+                    ));
 				}
 			} else if !((self.path.is_set() && self.path.try_as_ref().unwrap().is_some())
 				&& (self.parent.is_set() && self.parent.try_as_ref().unwrap().is_some())
@@ -239,20 +239,53 @@ impl ActiveModelBehavior for ActiveModel {
 					|| self.encrypted_suri.try_as_ref().unwrap().is_none()))
 			{
 				return Err(DbErr::Custom(
-					"A \"derivation\" vault account must have path:Some(_), parent:Some(_), crypto_scheme:None, encrypted_suri:None".into(),
-				));
+                    "A \"derivation\" vault account must have path:Some(_), parent:Some(_), crypto_scheme:None, encrypted_suri:None".into(),
+                ));
 			}
 		} else {
-			//Update checks
-			if !(self.crypto_scheme.is_unchanged()
-				&& self.encrypted_suri.is_unchanged()
-				&& self.path.is_unchanged()
-				&& self.parent.is_unchanged()
-				&& self.address.is_unchanged())
+			//Updates to accept:
+			//	* Name Only
+			//	* Overriding Base with Base account => only changing encrypted_suri
+			//		* Should also support changing name at the same time
+			//	* Overriding Derivation with Base account => upd Path=>None Parent=>None crypto=>Some enc_suri=>Some
+			//		* Should also support changing name at the same time
+			//	* Overriding Derivation with Derivation account => upd (Path=>Some) (Parent=>Some)
+			//		* Should also support changing name at the same time
+			//	* Overriding Base with Derivation account => upd Path=>Some Parent=>Some crypto=>None enc_suri=>None
+			//		* Should also support changing name at the same time
+
+			// If updating all path, parent, crypto_scheme, encrypted_suri
+			if self.path.is_set()
+				&& self.parent.is_set()
+				&& self.crypto_scheme.is_set()
+				&& self.encrypted_suri.is_set()
+			{
+				if self.parent.try_as_ref().unwrap().is_some() {
+					if !(self.path.try_as_ref().unwrap().is_some()
+						&& self.crypto_scheme.try_as_ref().unwrap().is_none()
+						&& self.encrypted_suri.try_as_ref().unwrap().is_none())
+					{
+						return Err(DbErr::Custom(
+							"An update to \"derivation\" vault account must have path:Some(_), parent:Some(_), crypto_scheme:None, encrypted_suri:None".into(),
+						));
+					}
+				} else if !(self.path.try_as_ref().unwrap().is_none()
+					&& self.crypto_scheme.try_as_ref().unwrap().is_some()
+					&& self.encrypted_suri.try_as_ref().unwrap().is_some())
+				{
+					return Err(DbErr::Custom(
+							"An update to \"base\" vault account must have path:None, parent:None, crypto_scheme:Some(_), encrypted_suri:Some(_)".into(),
+						));
+				}
+			}
+			// Else if updating path || parent both needs to have Some(_) value (update of Derivation)
+			else if (self.path.is_set() || self.parent.is_set())
+				&& !(self.parent.try_as_ref().unwrap().is_some()
+					&& self.path.try_as_ref().unwrap().is_some())
 			{
 				return Err(DbErr::Custom(
-					"Only the name can be updated for a vault account".into(),
-				));
+							"An update of \"derivation\" parent/path must have both path:Some(_), parent:Some(_)".into(),
+						));
 			}
 		}
 
@@ -384,6 +417,42 @@ pub fn get_account_tree_node_for_address(
 	Rc::clone(&account_tree_node_for_address)
 }
 
+/// Returns a new (limited) `AccountTreeNode` hierarchy including the selected account_tree_node and all it's parents.
+///
+/// The base of the new hierarchy will be returned
+pub fn get_base_parent_hierarchy_account_tree_node(
+	account_tree_node: &Rc<RefCell<AccountTreeNode>>,
+) -> Rc<RefCell<AccountTreeNode>> {
+	// Clone the current node to start the new hierarchy
+	let new_node = Rc::new(RefCell::new(AccountTreeNode {
+		account: account_tree_node.borrow().account.clone(),
+		children: Vec::new(),
+		parent: None,
+	}));
+
+	// Traverse up to the base node, creating new nodes for each parent
+	let mut current_new_node = Rc::clone(&new_node);
+	let mut current_node = Rc::clone(account_tree_node);
+
+	while let Some(parent_node) = {
+		let borrowed_node = current_node.borrow();
+		borrowed_node.parent.as_ref().map(Rc::clone)
+	} {
+		let new_parent_node = Rc::new(RefCell::new(AccountTreeNode {
+			account: parent_node.borrow().account.clone(),
+			children: vec![Rc::clone(&current_new_node)],
+			parent: None,
+		}));
+
+		current_new_node.borrow_mut().parent = Some(Rc::clone(&new_parent_node));
+		current_new_node = new_parent_node;
+		current_node = parent_node;
+	}
+
+	// Return the base of the new hierarchy
+	current_new_node
+}
+
 /// Returns a vec of all the accounts starting from `account_tree_node` and all its children; depth first
 ///
 /// Can be used to delete all the accounts in the hierarchy in the proper order
@@ -557,7 +626,6 @@ where
 /// This one unwraps the Option and gives a proper error message in case of None
 pub async fn fetch_base_account_tree_node_hierarchy_unwrapped<C>(
 	db: &C,
-	//FIXME Ripple parameter type to &AccountId in all methods (instead of &str)
 	address: &str,
 ) -> Result<Rc<RefCell<AccountTreeNode>>, GcliError>
 where
@@ -574,7 +642,6 @@ where
 /// Fetches the `base` account tree node hierarchy for the given address using db
 pub async fn fetch_base_account_tree_node_hierarchy<C>(
 	db: &C,
-	//FIXME Ripple parameter type to &AccountId in all methods (instead of &str)
 	address: &str,
 ) -> Result<Option<Rc<RefCell<AccountTreeNode>>>, GcliError>
 where
@@ -634,7 +701,8 @@ where
 }
 
 /// To make clippy happy... "warning: very complex type used. Consider factoring parts into `type` definitions"
-type AccountTreeNodeResult<'c> = Pin<Box<dyn Future<Output = Result<Rc<RefCell<AccountTreeNode>>, GcliError>> + 'c>>;
+type AccountTreeNodeResult<'c> =
+	Pin<Box<dyn Future<Output = Result<Rc<RefCell<AccountTreeNode>>, GcliError>> + 'c>>;
 
 /// This one seems necessary in order to handle async + recursion issue
 ///
@@ -688,7 +756,38 @@ where
 	Ok(current_node)
 }
 
-/// Creates a `base` vault account (if it doesn't exist) and returns it
+pub async fn check_name_available<C>(
+	db: &C,
+	old_name: Option<&String>,
+	new_name: Option<&String>,
+) -> Result<bool, GcliError>
+where
+	C: ConnectionTrait,
+{
+	if old_name == new_name {
+		return Ok(true);
+	}
+
+	if let Some(new_name) = new_name {
+		let name_usage_count = Entity::find()
+			.filter(Column::Name.eq(Some(new_name.clone())))
+			.count(db)
+			.await?;
+
+		Ok(name_usage_count == 0)
+	} else {
+		Ok(true)
+	}
+}
+
+pub async fn update_account<C>(db: &C, vault_account: ActiveModel) -> Result<Model, GcliError>
+where
+	C: ConnectionTrait,
+{
+	Ok(vault_account.update(db).await?)
+}
+
+/// Creates a `base` vault account and returns it
 ///
 /// Typically used for `vault import|migrate` commands
 pub async fn create_base_account<C>(
@@ -702,27 +801,14 @@ where
 	C: ConnectionTrait,
 {
 	let account_id = DbAccountId::from_str(address)?;
-	let vault_account = Entity::find_by_id(account_id.clone()).one(db).await?;
+	let existing_vault_account = Entity::find_by_id(account_id.clone()).one(db).await?;
 
-	Ok(match vault_account {
-		Some(vault_account) => {
-			//TODO Later possibly allow to replace the entry
+	Ok(match existing_vault_account {
+		Some(existing_vault_account) => {
+			// To be safe
 			return Err(GcliError::Input(format!(
-				"Already existing vault account {vault_account}"
+				"Already existing vault account {existing_vault_account}"
 			)));
-
-			// let overwrite_key =
-			// 	inputs::confirm_action("Do you want to overwrite with the new encrypted key ?")?;
-			// if overwrite_key {
-			// 	let mut vault_account: ActiveModel = vault_account.into();
-			// 	vault_account.encrypted_suri = Set(Some(encrypted_suri));
-			// 	let vault_account = vault_account.update(db).await?;
-			// 	println!("Updated vault account {vault_account}");
-			//
-			// 	vault_account
-			// } else {
-			// 	vault_account
-			// }
 		}
 		None => {
 			let vault_account = ActiveModel {
@@ -733,14 +819,12 @@ where
 				encrypted_suri: Set(Some(encrypted_suri)),
 				parent: Default::default(),
 			};
-			let vault_account = vault_account.insert(db).await?;
-			println!("Created base account {}", vault_account);
-			vault_account
+			vault_account.insert(db).await?
 		}
 	})
 }
 
-/// Creates a `derivation` vault account (if it doesn't exist) and returns it
+/// Creates a `derivation` vault account and returns it
 ///
 /// Typically used for `vault derive` command
 pub async fn create_derivation_account<C>(
@@ -758,7 +842,7 @@ where
 
 	Ok(match vault_account {
 		Some(vault_account) => {
-			//TODO Later possibly allow to replace the entry
+			// To be safe
 			return Err(GcliError::Input(format!(
 				"Already existing vault account {vault_account}"
 			)));
@@ -772,9 +856,7 @@ where
 				encrypted_suri: Set(None),
 				parent: Set(Some(parent_address.to_string().into())),
 			};
-			let vault_account = vault_account.insert(db).await?;
-			println!("Created derivation account {}", vault_account);
-			vault_account
+			vault_account.insert(db).await?
 		}
 	})
 }
@@ -925,6 +1007,44 @@ pub mod tests {
 			);
 		}
 
+		#[test]
+		fn test_get_base_parent_hierarchy_account_tree_node() {
+			let mother = mother_account_tree_node();
+			let child1 = mother.borrow().children[0].clone();
+
+			let new_mother = get_base_parent_hierarchy_account_tree_node(&child1);
+
+			// Check if the base of the new hierarchy is the mother node
+			assert_eq!(
+				new_mother.borrow().account.address.to_string(),
+				mother.borrow().account.address.to_string()
+			);
+			assert_eq!(new_mother.borrow().children.len(), 1);
+
+			// Check if the child1 node is correctly linked in the new hierarchy
+			let new_child1 = new_mother.borrow().children[0].clone();
+			assert_eq!(
+				new_child1.borrow().account.address.to_string(),
+				child1.borrow().account.address.to_string()
+			);
+			assert_eq!(new_child1.borrow().children.len(), 0);
+
+			// Check if the parent references are correctly set
+			assert!(new_mother.borrow().parent.is_none());
+			assert_eq!(
+				new_child1
+					.borrow()
+					.parent
+					.as_ref()
+					.unwrap()
+					.borrow()
+					.account
+					.address
+					.to_string(),
+				new_mother.borrow().account.address.to_string()
+			);
+		}
+
 		#[test]
 		fn test_retrieve_accounts_depth_first_from_account_tree_node() {
 			let mother = mother_account_tree_node();
diff --git a/src/inputs.rs b/src/inputs.rs
index 103ba3b293194937810b44ce9ef05ed7b506e8f2..082313029575334b85d44ce9392121bb406ccd13 100644
--- a/src/inputs.rs
+++ b/src/inputs.rs
@@ -1,6 +1,8 @@
 use crate::commands::vault;
+use crate::entities::vault_account;
 use crate::utils::GcliError;
 use inquire::validator::{ErrorMessage, Validation};
+use sea_orm::ConnectionTrait;
 
 pub fn prompt_password() -> Result<String, GcliError> {
 	prompt_password_query("Password")
@@ -46,25 +48,52 @@ pub fn prompt_password_query_confirm(query: impl ToString) -> Result<String, Gcl
 /// Prompt for a (direct) vault name (cannot contain derivation path)
 ///
 /// Also preventing to use '<' and '>' as those are used in the display
-pub fn prompt_vault_name() -> Result<Option<String>, GcliError> {
-	let name = inquire::Text::new("Name:")
-		.with_validator(|input: &str| {
-			if input.contains('<') || input.contains('>') || input.contains('/') {
-				Ok(Validation::Invalid(
-					"Name cannot contain characters '<', '>', '/'".into(),
-				))
-			} else {
+pub async fn prompt_vault_name_and_check_availability<C>(
+	db: &C,
+	initial_name: Option<&String>,
+) -> Result<Option<String>, GcliError>
+where
+	C: ConnectionTrait,
+{
+	loop {
+		let mut text_inquire = inquire::Text::new("Name:").with_validator({
+			|input: &str| {
+				if input.contains('<') || input.contains('>') || input.contains('/') {
+					return Ok(Validation::Invalid(
+						"Name cannot contain characters '<', '>', '/'".into(),
+					));
+				}
+
 				Ok(Validation::Valid)
 			}
-		})
-		.prompt()
-		.map_err(|e| GcliError::Input(e.to_string()))?;
+		});
+
+		if let Some(initial_name) = initial_name {
+			text_inquire = text_inquire.with_initial_value(initial_name);
+		}
 
-	Ok(if name.trim().is_empty() {
-		None
-	} else {
-		Some(name.trim().to_string())
-	})
+		let name = text_inquire
+			.prompt()
+			.map_err(|e| GcliError::Input(e.to_string()))?;
+
+		let name = if name.trim().is_empty() {
+			None
+		} else {
+			Some(name.trim().to_string())
+		};
+
+		let available =
+			vault_account::check_name_available(db, initial_name, name.as_ref()).await?;
+
+		if available {
+			return Ok(name);
+		}
+
+		println!(
+			"Name '{}' is already in use in the vault. Please choose another name.",
+			name.unwrap()
+		);
+	}
 }
 
 /// Prompt for a derivation path
@@ -97,3 +126,9 @@ pub fn confirm_action(query: impl ToString) -> Result<bool, GcliError> {
 		.prompt()
 		.map_err(|e| GcliError::Input(e.to_string()))
 }
+
+pub fn select_action(query: impl ToString, choices: Vec<&str>) -> Result<&str, GcliError> {
+	inquire::Select::new(query.to_string().as_str(), choices)
+		.prompt()
+		.map_err(|e| GcliError::Input(e.to_string()))
+}