diff --git a/Cargo.lock b/Cargo.lock
index aa5fa37f7bf8eb11c38c4c92450a4ee366dc512c..2005b13471f27ced27db06cde75c85bf65b62268 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2355,7 +2355,6 @@ dependencies = [
  "hex",
  "inquire",
  "log",
- "nacl",
  "parity-scale-codec",
  "reqwest",
  "rpassword",
@@ -3536,12 +3535,6 @@ dependencies = [
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "nacl"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30aefc44d813c51b5e7952950e87c17f2e0e1a3274d63c8281a701e05323d548"
-
 [[package]]
 name = "native-tls"
 version = "0.2.12"
diff --git a/Cargo.toml b/Cargo.toml
index 9a52f00dddde4c6e5977d96530c30604452c74a5..48423dd41bee2516e85d8e27a96147fbc49e125b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -49,7 +49,6 @@ sea-orm = { version = "1.1.0", features = [ "sqlx-sqlite", "runtime-tokio-native
 
 # crypto
 scrypt = { version = "^0.11", default-features = false } # for old-style key generation
-nacl = { version = "^0.5.3" }                            # for old-style key generation
 # this is beta crate for password-encrypted files
 age = { default-features = false, version = "^0.10.0", features = ["armor"] }
 bip39 = { version = "^2.0.0", features = ["rand"] }                           # mnemonic
diff --git a/src/commands/cesium.rs b/src/commands/cesium.rs
index 146a6500a24b1793597ce98f673639f63d58fa8c..56a40439039d1d808e7cc9259c66ebb37515ea72 100644
--- a/src/commands/cesium.rs
+++ b/src/commands/cesium.rs
@@ -33,52 +33,12 @@ pub async fn handle_command(_data: Data, command: Subcommand) -> Result<(), Gcli
 			println!("Address (SS58): {}", address);
 		}
 		Subcommand::Prompt => {
-			let keypair = prompt_secret_cesium();
-			println!("Pubkey: {}", bs58::encode(keypair.pkey).into_string());
-			let address: AccountId = keypair.pkey.into();
+			let pair = prompt_secret_cesium();
+			let public = pair.public();
+			println!("Pubkey: {}", bs58::encode(public).into_string());
+			let address: AccountId = public.into();
 			println!("Address: {}", address);
 		}
 	}
 	Ok(())
 }
-
-pub struct CesiumSigner<T: subxt::Config> {
-	account_id: T::AccountId,
-	keypair: nacl::sign::Keypair,
-}
-impl<T> CesiumSigner<T>
-where
-	T: subxt::Config,
-	T::AccountId: From<[u8; 32]>,
-{
-	pub fn new(keypair: nacl::sign::Keypair) -> Self {
-		Self {
-			account_id: T::AccountId::from(keypair.pkey),
-			keypair,
-		}
-	}
-}
-impl<T> subxt::tx::Signer<T> for CesiumSigner<T>
-where
-	T: subxt::Config,
-	T::Address: From<T::AccountId>,
-	T::Signature: From<sp_core::ed25519::Signature>,
-{
-	fn account_id(&self) -> T::AccountId {
-		self.account_id.clone()
-	}
-
-	fn address(&self) -> T::Address {
-		self.account_id.clone().into()
-	}
-
-	fn sign(&self, payload: &[u8]) -> T::Signature {
-		sp_core::ed25519::Signature::from_raw(
-			nacl::sign::signature(payload, &self.keypair.skey)
-				.unwrap()
-				.try_into()
-				.expect("could not read signature"),
-		)
-		.into()
-	}
-}
diff --git a/src/commands/identity.rs b/src/commands/identity.rs
index 91299fd38d1f13731bb05ccde860ff648c5ba4e6..e0ddf8af3436c2a4b6e1f2f8e1b1b01d4ae9c1d5 100644
--- a/src/commands/identity.rs
+++ b/src/commands/identity.rs
@@ -523,11 +523,6 @@ pub fn generate_link_account(
 			let signature = keypair.sign(&payload);
 			(payload, Signature::Ed25519(signature))
 		}
-		//FIXME Cleanup
-		KeyPair::Nacl(keypair) => {
-			let signature = nacl::sign::signature(&payload, &keypair.skey).expect("could not sign");
-			(payload, Signature::Nacl(signature))
-		}
 	}
 }
 
@@ -554,12 +549,6 @@ pub fn generate_chok_payload(
 			let signature = keypair.sign(&payload);
 			(payload, Signature::Ed25519(signature))
 		}
-		//FIXME Cleanup
-		KeyPair::Nacl(keypair) => {
-			// should not migrate to Nacl
-			let signature = nacl::sign::signature(&payload, &keypair.skey).expect("could not sign");
-			(payload, Signature::Nacl(signature))
-		}
 	}
 }
 
@@ -575,8 +564,6 @@ pub async fn link_account(
 	let signature = match signature {
 		Signature::Sr25519(signature) => MultiSignature::Sr25519(signature.into()),
 		Signature::Ed25519(signature) => MultiSignature::Ed25519(signature.into()),
-		//FIXME Cleanup
-		Signature::Nacl(signature) => MultiSignature::Ed25519(signature.try_into().unwrap()),
 	};
 
 	submit_call_and_look_event::<
@@ -601,8 +588,6 @@ pub async fn change_owner_key(
 	let signature = match signature {
 		Signature::Sr25519(signature) => MultiSignature::Sr25519(signature.into()),
 		Signature::Ed25519(signature) => MultiSignature::Ed25519(signature.into()),
-		//FIXME Cleanup
-		Signature::Nacl(signature) => MultiSignature::Ed25519(signature.try_into().unwrap()),
 	};
 
 	submit_call_and_look_event::<
diff --git a/src/commands/vault.rs b/src/commands/vault.rs
index b253c988448ed7425de120767b386d0a7e383a23..3918f906955bc1bf603314b29b89e806c9f3128d 100644
--- a/src/commands/vault.rs
+++ b/src/commands/vault.rs
@@ -84,8 +84,7 @@ pub enum ListChoice {
 
 pub struct VaultDataToImport {
 	secret_format: SecretFormat,
-	secret: keys::Secret,
-	address: AccountId,
+	secret_suri: String,
 	key_pair: KeyPair,
 }
 
@@ -202,15 +201,13 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 			let vault_data_for_import =
 				prompt_secret_and_compute_vault_data_to_import(secret_format)?;
 
-			println!(
-				"Trying to import for address :'{}'",
-				vault_data_for_import.address
-			);
+			let address_to_import = vault_data_for_import.key_pair.address().to_string();
 
-			if let Some(derivation) =
-				vault_derivation::Entity::find_by_id(vault_data_for_import.address.to_string())
-					.one(data.connection.as_ref().unwrap())
-					.await?
+			println!("Trying to import for address :'{}'", address_to_import);
+
+			if let Some(derivation) = vault_derivation::Entity::find_by_id(&address_to_import)
+				.one(data.connection.as_ref().unwrap())
+				.await?
 			{
 				println!(
 					"Vault entry already exists for that address: {}",
@@ -444,9 +441,8 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE
 				};
 
 				let vault_data_to_import = VaultDataToImport {
-					secret_format: SecretFormat::Substrate,
-					secret: keys::Secret::SimpleSecret(vault_data_from_file.secret),
-					address: AccountId::from_str(&address).expect("invalid address"),
+					secret_format: vault_data_from_file.secret_format,
+					secret_suri: vault_data_from_file.secret,
 					key_pair: vault_data_from_file.key_pair,
 				};
 
@@ -680,15 +676,14 @@ fn create_vault_data_to_import<F, P>(
 	prompt_fn: F,
 ) -> Result<VaultDataToImport, GcliError>
 where
-	F: Fn() -> (keys::Secret, P),
+	F: Fn() -> (String, P),
 	P: Into<KeyPair>,
 {
 	let (secret, pair) = prompt_fn();
 	let key_pair = pair.into();
 	Ok(VaultDataToImport {
 		secret_format,
-		secret,
-		address: key_pair.address(),
+		secret_suri: secret,
 		key_pair,
 	})
 }
@@ -724,53 +719,25 @@ pub async fn create_derivation_for_vault_data_to_import<C>(
 where
 	C: ConnectionTrait,
 {
+	let address_to_import = vault_data.key_pair.address().to_string();
 	//To be safe
-	if vault_derivation::Entity::find_by_id(vault_data.address.to_string())
+	if vault_derivation::Entity::find_by_id(&address_to_import)
 		.one(db)
 		.await?
 		.is_some()
 	{
 		return Err(GcliError::Input(format!(
 			"Vault entry already exists for address {}",
-			vault_data.address
+			&address_to_import
 		)));
 	}
 
-	let secret_suri: String = match &vault_data.secret_format {
-		SecretFormat::Cesium => {
-			if let KeyPair::Nacl(keypair) = &vault_data.key_pair {
-				// In case of cesium key, we will store the seed suri instead of id/password (so it supports derivations)
-				let seed: [u8; 32] = keypair.skey[0..32]
-					.try_into()
-					.expect("slice with incorrect length");
-				format!("0x{}", hex::encode(seed))
-			} else {
-				return Err(GcliError::Input("Expected KeyPair::Nacl".to_string()));
-			}
-		}
-		SecretFormat::Seed => {
-			if let keys::Secret::SimpleSecret(seed_str) = &vault_data.secret {
-				format!("0x{seed_str}")
-			} else {
-				return Err(GcliError::Input("Expected SimpleSecret".to_string()));
-			}
-		}
-		SecretFormat::Substrate | SecretFormat::Predefined => {
-			if let keys::Secret::SimpleSecret(secret_suri) = &vault_data.secret {
-				secret_suri.clone()
-			} else {
-				return Err(GcliError::Input("Expected SimpleSecret".to_string()));
-			}
-		}
-	};
-
 	let secret_format = vault_data.secret_format;
 
 	let (root_secret_suri, derivation_path_opt, root_address, derivation_address) =
-		compute_root_and_derivation_data(&secret_format, secret_suri)?;
+		compute_root_and_derivation_data(&secret_format, vault_data.secret_suri.clone())?;
 
 	// Making sure the computed address is the same as the address to import
-	let address_to_import = vault_data.address.to_string();
 	if let Some(derivation_address) = &derivation_address {
 		if *derivation_address != address_to_import {
 			return Err(GcliError::Input(format!(
@@ -966,9 +933,9 @@ pub fn compute_keypair(crypto_type: CryptoType, secret_suri: &str) -> Result<Key
 }
 
 pub struct VaultDataFromFile {
-	address: String,
 	secret_format: SecretFormat,
 	secret: String,
+	#[allow(dead_code)]
 	path: PathBuf,
 	password: String,
 	key_pair: KeyPair,
@@ -992,7 +959,6 @@ pub fn try_fetch_vault_data_from_file(
 		let key_pair = pair_from_sr25519_str(&secret)?.into();
 
 		Ok(Some(VaultDataFromFile {
-			address: address.to_string(),
 			secret_format: SecretFormat::Substrate,
 			secret,
 			path,
diff --git a/src/inputs.rs b/src/inputs.rs
index e430312798847ec6861a4c829b962054c56a774c..31c53925bbbb21a55577eee5bc4d134265a1dd92 100644
--- a/src/inputs.rs
+++ b/src/inputs.rs
@@ -16,6 +16,26 @@ pub fn prompt_password_query(query: impl ToString) -> Result<String, GcliError>
 		.map_err(|e| GcliError::Input(e.to_string()))
 }
 
+pub fn prompt_seed() -> Result<String, GcliError> {
+	inquire::Password::new("Seed:")
+		.without_confirmation()
+		.with_validator(|input: &str| {
+			if input.chars().any(|c| !c.is_ascii_hexdigit()) {
+				Ok(Validation::Invalid(
+					"Seed value must only contain valid hexadecimal characters [0-9a-fA-F]".into(),
+				))
+			} else if input.len() < 64 || input.len() > 64 {
+				Ok(Validation::Invalid(
+					"Seed value must be 32 bytes in hexadecimal format (64 characters long)".into(),
+				))
+			} else {
+				Ok(Validation::Valid)
+			}
+		})
+		.prompt()
+		.map_err(|e| GcliError::Input(e.to_string()))
+}
+
 pub fn prompt_password_query_confirm(query: impl ToString) -> Result<String, GcliError> {
 	inquire::Password::new(query.to_string().as_str())
 		.prompt()
diff --git a/src/keys.rs b/src/keys.rs
index d2468293922d015e614513460fe63d5265395af4..73c230d6fb9ccc6903ee74814c548bb015384e2a 100644
--- a/src/keys.rs
+++ b/src/keys.rs
@@ -20,11 +20,6 @@ pub enum SecretFormat {
 	Cesium,
 }
 
-pub enum Secret {
-	SimpleSecret(String),
-	DualSecret(String, String),
-}
-
 impl FromStr for SecretFormat {
 	type Err = std::io::Error;
 
@@ -62,15 +57,12 @@ impl From<SecretFormat> for OsStr {
 pub enum KeyPair {
 	Sr25519(Sr25519Pair),
 	Ed25519(Ed25519Pair),
-	//FIXME Cleanup
-	Nacl(nacl::sign::Keypair),
 }
 impl KeyPair {
 	pub fn address(&self) -> AccountId {
 		match self {
 			KeyPair::Sr25519(keypair) => keypair.public().into(),
 			KeyPair::Ed25519(keypair) => keypair.public().into(),
-			KeyPair::Nacl(keypair) => keypair.pkey.into(),
 		}
 	}
 }
@@ -80,10 +72,6 @@ impl Clone for KeyPair {
 		match self {
 			KeyPair::Sr25519(keypair) => KeyPair::Sr25519(keypair.clone()),
 			KeyPair::Ed25519(keypair) => KeyPair::Ed25519(*keypair),
-			KeyPair::Nacl(keypair) => KeyPair::Nacl(nacl::sign::Keypair {
-				skey: keypair.skey,
-				pkey: keypair.pkey,
-			}),
 		}
 	}
 }
@@ -97,16 +85,9 @@ impl From<Ed25519Pair> for KeyPair {
 		KeyPair::Ed25519(pair)
 	}
 }
-impl From<nacl::sign::Keypair> for KeyPair {
-	fn from(pair: nacl::sign::Keypair) -> KeyPair {
-		KeyPair::Nacl(pair)
-	}
-}
 pub enum Signature {
 	Sr25519(sr25519::Signature),
 	Ed25519(ed25519::Signature),
-	//FIXME Cleanup
-	Nacl(Vec<u8>),
 }
 
 /// get keypair in any possible way
@@ -181,12 +162,6 @@ pub fn pair_from_predefined(deriv: &str) -> Result<Sr25519Pair, GcliError> {
 	pair_from_sr25519_str(&predefined_mnemonic(deriv))
 }
 
-/// get keypair from Cesium id/pwd
-pub fn pair_from_cesium(id: String, pwd: String) -> nacl::sign::Keypair {
-	let seed = seed_from_cesium(&id, &pwd);
-	nacl::sign::generate_keypair(&seed)
-}
-
 /// get seed from Cesium id/pwd
 fn seed_from_cesium(id: &str, pwd: &str) -> [u8; 32] {
 	let params = scrypt::Params::new(12u8, 16u32, 1u32, 32).unwrap();
@@ -201,29 +176,33 @@ pub fn prompt_secret_substrate() -> Sr25519Pair {
 	prompt_secret_substrate_and_compute_keypair().1
 }
 
-pub fn prompt_secret_substrate_and_compute_keypair() -> (Secret, Sr25519Pair) {
+pub fn prompt_secret_substrate_and_compute_keypair() -> (String, Sr25519Pair) {
 	loop {
-		let mnemonic = rpassword::prompt_password("Mnemonic: ").unwrap();
-		match pair_from_sr25519_str(&mnemonic) {
-			Ok(pair) => return (Secret::SimpleSecret(mnemonic), pair),
+		let mnemonic_suri = rpassword::prompt_password("Mnemonic: ").unwrap();
+		match pair_from_sr25519_str(&mnemonic_suri) {
+			Ok(pair) => return (mnemonic_suri, pair),
 			Err(_) => println!("Invalid secret"),
 		}
 	}
 }
 
 /// ask user pass (Cesium format)
-pub fn prompt_secret_cesium() -> nacl::sign::Keypair {
+pub fn prompt_secret_cesium() -> Ed25519Pair {
 	// Only interested in the keypair which is the second element of the tuple
 	prompt_secret_cesium_and_compute_keypair().1
 }
 
-pub fn prompt_secret_cesium_and_compute_keypair() -> (Secret, nacl::sign::Keypair) {
+pub fn prompt_secret_cesium_and_compute_keypair() -> (String, Ed25519Pair) {
 	let id = rpassword::prompt_password("Cesium id: ").unwrap();
 	let pwd = rpassword::prompt_password("Cesium password: ").unwrap();
-	(
-		Secret::DualSecret(id.clone(), pwd.clone()),
-		pair_from_cesium(id, pwd),
-	)
+
+	let seed = seed_from_cesium(&id, &pwd);
+	let secret_suri = format!("0x{}", hex::encode(seed));
+
+	match pair_from_ed25519_str(&secret_suri) {
+		Ok(pair) => (secret_suri, pair),
+		Err(_) => panic!("Could not compute KeyPair from Cesium id/pwd"),
+	}
 }
 
 /// ask user to input a seed
@@ -232,11 +211,13 @@ pub fn prompt_seed() -> Sr25519Pair {
 	prompt_seed_and_compute_keypair().1
 }
 
-pub fn prompt_seed_and_compute_keypair() -> (Secret, Sr25519Pair) {
+pub fn prompt_seed_and_compute_keypair() -> (String, Sr25519Pair) {
 	loop {
-		let seed = rpassword::prompt_password("Seed: ").unwrap();
-		match pair_from_sr25519_seed(&seed) {
-			Ok(pair) => return (Secret::SimpleSecret(seed), pair),
+		let seed_str = inputs::prompt_seed().unwrap();
+		let secret_suri = format!("0x{}", seed_str);
+
+		match pair_from_sr25519_str(&secret_suri) {
+			Ok(pair) => return (secret_suri, pair),
 			Err(_) => println!("Invalid seed"),
 		}
 	}
@@ -248,10 +229,10 @@ pub fn prompt_predefined() -> Sr25519Pair {
 	prompt_predefined_and_compute_keypair().1
 }
 
-pub fn prompt_predefined_and_compute_keypair() -> (Secret, Sr25519Pair) {
+pub fn prompt_predefined_and_compute_keypair() -> (String, Sr25519Pair) {
 	let deriv = rpassword::prompt_password("Enter derivation path: ").unwrap();
 	(
-		Secret::SimpleSecret(predefined_mnemonic(&deriv)),
+		predefined_mnemonic(&deriv),
 		pair_from_predefined(&deriv).expect("invalid secret"),
 	)
 }
@@ -585,54 +566,47 @@ mod tests {
 			let expected_cesium_v1_ss58_address: String =
 				"5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4".to_string();
 
-			let cesium_keypair = pair_from_cesium(cesium_id, cesium_pwd);
-
-			println!(
-				"Nacl keypair: pkey:'0x{}' skey:'0x{}'",
-				hex::encode(cesium_keypair.pkey),
-				hex::encode(cesium_keypair.skey)
-			);
-
-			let cesium_v1_pubkey = bs58::encode(cesium_keypair.pkey).into_string();
-			println!("Cesium v1 Pubkey: '{}'", cesium_v1_pubkey);
-			let cesium_v1_address: AccountId = cesium_keypair.pkey.into();
-			println!("SS58 Address: '{}'", cesium_v1_address);
-
-			assert_eq!(
-				expected_cesium_v1_ss58_address,
-				cesium_v1_address.to_string()
-			);
+			let seed = seed_from_cesium(&cesium_id, &cesium_pwd);
 
-			//ed25519 seed **seems** to be the first 32 bytes of the secret key from nacl keypair
-			let mut seed: [u8; 32] = [0; 32];
-			seed.copy_from_slice(&cesium_keypair.skey[0..32]);
 			println!();
-			println!("ed25519 seed: '0x{}'", hex::encode(seed));
+			println!("seed: '0x{}'", hex::encode(seed));
 
 			let ed25519_pair_from_seed = sp_core::ed25519::Pair::from_seed(&seed);
 
 			println!();
 			println!(
-				"ed25519 keypair from seed : public:'0x{}' raw_vec:'0x{}'",
+				"ed25519 keypair from seed: public:'0x{}' raw_vec:'0x{}'",
 				hex::encode(ed25519_pair_from_seed.public().0),
 				hex::encode(ed25519_pair_from_seed.to_raw_vec().as_slice())
 			);
+
+			println!(
+				"ed25519 keypair from seed: Cesium v1 Pubkey: '{}'",
+				bs58::encode(ed25519_pair_from_seed.public()).into_string()
+			);
+
 			let ed25519_address_from_seed: AccountId = ed25519_pair_from_seed.public().into();
 			println!(
-				"ed25519 keypair from seed : public SS58 Address:'{}'",
+				"ed25519 keypair from seed: public SS58 Address:'{}'",
 				ed25519_address_from_seed
 			);
-			assert_eq!(cesium_v1_address, ed25519_address_from_seed);
+			assert_eq!(
+				expected_cesium_v1_ss58_address,
+				ed25519_address_from_seed.to_string()
+			);
 
 			let root_suri = "0x".to_string() + &hex::encode(seed);
 			let ed25519_pair_from_suri =
 				sp_core::ed25519::Pair::from_string(&root_suri, None).unwrap();
 			let ed25519_address_from_suri: AccountId = ed25519_pair_from_suri.public().into();
 			println!(
-				"ed25519 keypair from suri : public SS58 Address:'{}'",
+				"ed25519 keypair from suri: public SS58 Address:'{}'",
 				ed25519_address_from_suri
 			);
-			assert_eq!(cesium_v1_address, ed25519_address_from_suri);
+			assert_eq!(
+				expected_cesium_v1_ss58_address,
+				ed25519_address_from_suri.to_string()
+			);
 
 			// Tested derivation manually with `subkey` command using adapted suri: `0x2101d2bc68de9ad149c06293bfe489c8608de576c88927aa5439a81be17aae84//0`
 			let expected_ss58_address_derivation_0 =
@@ -648,6 +622,12 @@ mod tests {
 				hex::encode(derived_ed25519_pair.public().0),
 				hex::encode(derived_ed25519_pair.to_raw_vec().as_slice())
 			);
+
+			println!(
+				"derived ed25519 keypair: Cesium v1 Pubkey: '{}'",
+				bs58::encode(derived_ed25519_pair.public()).into_string()
+			);
+
 			let derived_ed25519_address =
 				subxt::utils::AccountId32::from(derived_ed25519_pair.public());
 			println!(
@@ -666,7 +646,7 @@ mod tests {
 			let derived_ed25519_address_from_suri: AccountId =
 				derived_ed25519_pair_from_suri.public().into();
 			println!(
-				"derived ed25519 keypair from suri : public SS58 Address:'{}'",
+				"derived ed25519 keypair from suri: public SS58 Address:'{}'",
 				derived_ed25519_address_from_suri
 			);
 			assert_eq!(
diff --git a/src/utils.rs b/src/utils.rs
index 2393bd33af5a78af2201ffd00eee318098e336a9..c6b936eeb4be2292fc11502ea0de731e86d4b33f 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -69,12 +69,6 @@ pub async fn submit_call<TxPayload: Payload>(
 			&PairSigner::<Runtime, sp_core::ed25519::Pair>::new(keypair),
 			DefaultExtrinsicParamsBuilder::new().nonce(nonce).build(),
 		),
-		//FIXME cleanup
-		KeyPair::Nacl(keypair) => data.client().tx().create_signed_offline(
-			payload,
-			&commands::cesium::CesiumSigner::new(keypair),
-			DefaultExtrinsicParamsBuilder::new().nonce(nonce).build(),
-		),
 	}?
 	.submit_and_watch()
 	.await