diff --git a/cumulus/polkadot-parachains/parachains-common/src/lib.rs b/cumulus/polkadot-parachains/parachains-common/src/lib.rs
index f592b94e56b14200f25a4f42ee2ecc2bfad28a49..c04f0a37798bf18385e25f2313bbd245f53783f4 100644
--- a/cumulus/polkadot-parachains/parachains-common/src/lib.rs
+++ b/cumulus/polkadot-parachains/parachains-common/src/lib.rs
@@ -52,6 +52,13 @@ mod types {
 	// Aura consensus authority.
 	pub type AuraId = sp_consensus_aura::sr25519::AuthorityId;
 
+	// Aura consensus authority used by Statemint.
+	//
+	// Because of registering the authorities with an ed25519 key before switching from Shell
+	// to Statemint, we were required to deploy a hotfix that changed Statemint to ed22519.
+	// In the future that may change again.
+	pub type StatemintAuraId = sp_consensus_aura::ed25519::AuthorityId;
+
 	// Id used for identifying assets.
 	pub type AssetId = u32;
 }
diff --git a/cumulus/polkadot-parachains/src/chain_spec.rs b/cumulus/polkadot-parachains/src/chain_spec.rs
index b0cbda9d9f0efdb37be62a765b5246c00ed7e49b..c0ea616343137cfcc8751356d6ce6effa778d1a0 100644
--- a/cumulus/polkadot-parachains/src/chain_spec.rs
+++ b/cumulus/polkadot-parachains/src/chain_spec.rs
@@ -220,7 +220,7 @@ fn seedling_testnet_genesis(
 	}
 }
 
-use parachains_common::Balance as StatemintBalance;
+use parachains_common::{Balance as StatemintBalance, StatemintAuraId};
 
 /// Specialized `ChainSpec` for the normal parachain runtime.
 pub type StatemintChainSpec =
@@ -244,14 +244,14 @@ pub fn get_public_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pa
 /// Generate collator keys from seed.
 ///
 /// This function's return type must always match the session keys of the chain in tuple format.
-pub fn get_collator_keys_from_seed(seed: &str) -> AuraId {
+pub fn get_collator_keys_from_seed<AuraId: Public>(seed: &str) -> <AuraId::Pair as Pair>::Public {
 	get_public_from_seed::<AuraId>(seed)
 }
 
 /// Generate the session keys from individual elements.
 ///
 /// The input must be a tuple of individual keys (a single arg for now since we have just one key).
-pub fn statemint_session_keys(keys: AuraId) -> statemint_runtime::SessionKeys {
+pub fn statemint_session_keys(keys: StatemintAuraId) -> statemint_runtime::SessionKeys {
 	statemint_runtime::SessionKeys { aura: keys }
 }
 
@@ -286,7 +286,7 @@ pub fn statemint_development_config() -> StatemintChainSpec {
 				// initial collators.
 				vec![(
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
-					get_collator_keys_from_seed("Alice"),
+					get_collator_keys_from_seed::<StatemintAuraId>("Alice"),
 				)],
 				vec![
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
@@ -324,11 +324,11 @@ pub fn statemint_local_config() -> StatemintChainSpec {
 				vec![
 					(
 						get_account_id_from_seed::<sr25519::Public>("Alice"),
-						get_collator_keys_from_seed("Alice"),
+						get_collator_keys_from_seed::<StatemintAuraId>("Alice"),
 					),
 					(
 						get_account_id_from_seed::<sr25519::Public>("Bob"),
-						get_collator_keys_from_seed("Bob"),
+						get_collator_keys_from_seed::<StatemintAuraId>("Bob"),
 					),
 				],
 				vec![
@@ -418,7 +418,7 @@ pub fn statemint_config() -> StatemintChainSpec {
 }
 
 fn statemint_genesis(
-	invulnerables: Vec<(AccountId, AuraId)>,
+	invulnerables: Vec<(AccountId, StatemintAuraId)>,
 	endowed_accounts: Vec<AccountId>,
 	id: ParaId,
 ) -> statemint_runtime::GenesisConfig {
@@ -474,7 +474,7 @@ pub fn statemine_development_config() -> StatemineChainSpec {
 				// initial collators.
 				vec![(
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
-					get_collator_keys_from_seed("Alice"),
+					get_collator_keys_from_seed::<AuraId>("Alice"),
 				)],
 				vec![
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
@@ -512,11 +512,11 @@ pub fn statemine_local_config() -> StatemineChainSpec {
 				vec![
 					(
 						get_account_id_from_seed::<sr25519::Public>("Alice"),
-						get_collator_keys_from_seed("Alice"),
+						get_collator_keys_from_seed::<AuraId>("Alice"),
 					),
 					(
 						get_account_id_from_seed::<sr25519::Public>("Bob"),
-						get_collator_keys_from_seed("Bob"),
+						get_collator_keys_from_seed::<AuraId>("Bob"),
 					),
 				],
 				vec![
@@ -657,7 +657,7 @@ pub fn westmint_development_config() -> WestmintChainSpec {
 				// initial collators.
 				vec![(
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
-					get_collator_keys_from_seed("Alice"),
+					get_collator_keys_from_seed::<AuraId>("Alice"),
 				)],
 				vec![
 					get_account_id_from_seed::<sr25519::Public>("Alice"),
@@ -694,11 +694,11 @@ pub fn westmint_local_config() -> WestmintChainSpec {
 				vec![
 					(
 						get_account_id_from_seed::<sr25519::Public>("Alice"),
-						get_collator_keys_from_seed("Alice"),
+						get_collator_keys_from_seed::<AuraId>("Alice"),
 					),
 					(
 						get_account_id_from_seed::<sr25519::Public>("Bob"),
-						get_collator_keys_from_seed("Bob"),
+						get_collator_keys_from_seed::<AuraId>("Bob"),
 					),
 				],
 				vec![
diff --git a/cumulus/polkadot-parachains/src/command.rs b/cumulus/polkadot-parachains/src/command.rs
index 73a9690fd9208aa918ae38394d1bf24a65201374..4f0ed19b69488b149a4d32dc14af9826dbca75c3 100644
--- a/cumulus/polkadot-parachains/src/command.rs
+++ b/cumulus/polkadot-parachains/src/command.rs
@@ -27,6 +27,7 @@ use codec::Encode;
 use cumulus_client_service::genesis::generate_genesis_block;
 use cumulus_primitives_core::ParaId;
 use log::info;
+use parachains_common::{AuraId, StatemintAuraId};
 use polkadot_parachain::primitives::AccountIdConversion;
 use sc_cli::{
 	ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams,
@@ -254,7 +255,7 @@ macro_rules! construct_async_run {
 			runner.async_run(|$config| {
 				let $components = new_partial::<westmint_runtime::RuntimeApi, WestmintRuntimeExecutor, _>(
 					&$config,
-					crate::service::statemint_build_import_queue,
+					crate::service::statemint_build_import_queue::<_, _, AuraId>,
 				)?;
 				let task_manager = $components.task_manager;
 				{ $( $code )* }.map(|v| (v, task_manager))
@@ -263,7 +264,7 @@ macro_rules! construct_async_run {
 			runner.async_run(|$config| {
 				let $components = new_partial::<statemine_runtime::RuntimeApi, StatemineRuntimeExecutor, _>(
 					&$config,
-					crate::service::statemint_build_import_queue,
+					crate::service::statemint_build_import_queue::<_, _, AuraId>,
 				)?;
 				let task_manager = $components.task_manager;
 				{ $( $code )* }.map(|v| (v, task_manager))
@@ -272,7 +273,7 @@ macro_rules! construct_async_run {
 			runner.async_run(|$config| {
 				let $components = new_partial::<statemint_runtime::RuntimeApi, StatemintRuntimeExecutor, _>(
 					&$config,
-					crate::service::statemint_build_import_queue,
+					crate::service::statemint_build_import_queue::<_, _, StatemintAuraId>,
 				)?;
 				let task_manager = $components.task_manager;
 				{ $( $code )* }.map(|v| (v, task_manager))
@@ -502,6 +503,7 @@ pub fn run() -> Result<()> {
 					crate::service::start_statemint_node::<
 						statemint_runtime::RuntimeApi,
 						StatemintRuntimeExecutor,
+						StatemintAuraId,
 					>(config, polkadot_config, id)
 					.await
 					.map(|r| r.0)
@@ -510,6 +512,7 @@ pub fn run() -> Result<()> {
 					crate::service::start_statemint_node::<
 						statemine_runtime::RuntimeApi,
 						StatemineRuntimeExecutor,
+						AuraId,
 					>(config, polkadot_config, id)
 					.await
 					.map(|r| r.0)
@@ -518,6 +521,7 @@ pub fn run() -> Result<()> {
 					crate::service::start_statemint_node::<
 						westmint_runtime::RuntimeApi,
 						WestmintRuntimeExecutor,
+						AuraId,
 					>(config, polkadot_config, id)
 					.await
 					.map(|r| r.0)
diff --git a/cumulus/polkadot-parachains/src/service.rs b/cumulus/polkadot-parachains/src/service.rs
index d248240a5a75cc1181431c9ed4d9bb09af6bfc9c..c8001eef541f3eaa5f7033841d76c5443698ba68 100644
--- a/cumulus/polkadot-parachains/src/service.rs
+++ b/cumulus/polkadot-parachains/src/service.rs
@@ -14,6 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
 
+use codec::Codec;
 use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion};
 use cumulus_client_consensus_common::{
 	ParachainBlockImport, ParachainCandidate, ParachainConsensus,
@@ -46,13 +47,15 @@ use sc_service::{Configuration, PartialComponents, Role, TFullBackend, TFullClie
 use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
 use sp_api::{ApiExt, ConstructRuntimeApi};
 use sp_consensus::{CacheKeyId, SlotData};
-use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi};
+use sp_consensus_aura::AuraApi;
+use sp_core::crypto::Pair;
 use sp_keystore::SyncCryptoStorePtr;
 use sp_runtime::{
+	app_crypto::AppKey,
 	generic::BlockId,
 	traits::{BlakeTwo256, Header as HeaderT},
 };
-use std::{sync::Arc, time::Duration};
+use std::{marker::PhantomData, sync::Arc, time::Duration};
 use substrate_prometheus_endpoint::Registry;
 
 /// Native executor instance.
@@ -907,27 +910,30 @@ impl<R> BuildOnAccess<R> {
 
 /// Special [`ParachainConsensus`] implementation that waits for the upgrade from
 /// shell to a parachain runtime that implements Aura.
-struct WaitForAuraConsensus<Client> {
+struct WaitForAuraConsensus<Client, AuraId> {
 	client: Arc<Client>,
 	aura_consensus: Arc<Mutex<BuildOnAccess<Box<dyn ParachainConsensus<Block>>>>>,
 	relay_chain_consensus: Arc<Mutex<Box<dyn ParachainConsensus<Block>>>>,
+	_phantom: PhantomData<AuraId>,
 }
 
-impl<Client> Clone for WaitForAuraConsensus<Client> {
+impl<Client, AuraId> Clone for WaitForAuraConsensus<Client, AuraId> {
 	fn clone(&self) -> Self {
 		Self {
 			client: self.client.clone(),
 			aura_consensus: self.aura_consensus.clone(),
 			relay_chain_consensus: self.relay_chain_consensus.clone(),
+			_phantom: PhantomData,
 		}
 	}
 }
 
 #[async_trait::async_trait]
-impl<Client> ParachainConsensus<Block> for WaitForAuraConsensus<Client>
+impl<Client, AuraId> ParachainConsensus<Block> for WaitForAuraConsensus<Client, AuraId>
 where
 	Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync,
 	Client::Api: AuraApi<Block, AuraId>,
+	AuraId: Send + Codec + Sync,
 {
 	async fn produce_candidate(
 		&mut self,
@@ -958,17 +964,19 @@ where
 	}
 }
 
-struct Verifier<Client> {
+struct Verifier<Client, AuraId> {
 	client: Arc<Client>,
 	aura_verifier: BuildOnAccess<Box<dyn VerifierT<Block>>>,
 	relay_chain_verifier: Box<dyn VerifierT<Block>>,
+	_phantom: PhantomData<AuraId>,
 }
 
 #[async_trait::async_trait]
-impl<Client> VerifierT<Block> for Verifier<Client>
+impl<Client, AuraId> VerifierT<Block> for Verifier<Client, AuraId>
 where
 	Client: sp_api::ProvideRuntimeApi<Block> + Send + Sync,
 	Client::Api: AuraApi<Block, AuraId>,
+	AuraId: Send + Sync + Codec,
 {
 	async fn verify(
 		&mut self,
@@ -990,7 +998,7 @@ where
 }
 
 /// Build the import queue for the statemint/statemine/westmine runtime.
-pub fn statemint_build_import_queue<RuntimeApi, Executor>(
+pub fn statemint_build_import_queue<RuntimeApi, Executor, AuraId: AppKey>(
 	client: Arc<TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<Executor>>>,
 	config: &Configuration,
 	telemetry_handle: Option<TelemetryHandle>,
@@ -1015,38 +1023,39 @@ where
 			StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>,
 		> + sp_offchain::OffchainWorkerApi<Block>
 		+ sp_block_builder::BlockBuilder<Block>
-		+ sp_consensus_aura::AuraApi<Block, AuraId>,
+		+ sp_consensus_aura::AuraApi<Block, <<AuraId as AppKey>::Pair as Pair>::Public>,
 	sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
 	Executor: sc_executor::NativeExecutionDispatch + 'static,
+	<<AuraId as AppKey>::Pair as Pair>::Signature:
+		TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec,
 {
 	let client2 = client.clone();
 
 	let aura_verifier = move || {
 		let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client2).unwrap();
 
-		Box::new(cumulus_client_consensus_aura::build_verifier::<
-			sp_consensus_aura::sr25519::AuthorityPair,
-			_,
-			_,
-			_,
-		>(cumulus_client_consensus_aura::BuildVerifierParams {
-			client: client2.clone(),
-			create_inherent_data_providers: move |_, _| async move {
-				let time = sp_timestamp::InherentDataProvider::from_system_time();
-
-				let slot =
+		Box::new(
+			cumulus_client_consensus_aura::build_verifier::<<AuraId as AppKey>::Pair, _, _, _>(
+				cumulus_client_consensus_aura::BuildVerifierParams {
+					client: client2.clone(),
+					create_inherent_data_providers: move |_, _| async move {
+						let time = sp_timestamp::InherentDataProvider::from_system_time();
+
+						let slot =
 					sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
 						*time,
 						slot_duration.slot_duration(),
 					);
 
-				Ok((time, slot))
-			},
-			can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(
-				client2.executor().clone(),
+						Ok((time, slot))
+					},
+					can_author_with: sp_consensus::CanAuthorWithNativeVersion::new(
+						client2.executor().clone(),
+					),
+					telemetry: telemetry_handle,
+				},
 			),
-			telemetry: telemetry_handle,
-		})) as Box<_>
+		) as Box<_>
 	};
 
 	let relay_chain_verifier =
@@ -1056,6 +1065,7 @@ where
 		client: client.clone(),
 		relay_chain_verifier,
 		aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))),
+		_phantom: PhantomData,
 	};
 
 	let registry = config.prometheus_registry().clone();
@@ -1071,7 +1081,7 @@ where
 }
 
 /// Start a statemint/statemine/westmint parachain node.
-pub async fn start_statemint_node<RuntimeApi, Executor>(
+pub async fn start_statemint_node<RuntimeApi, Executor, AuraId: AppKey>(
 	parachain_config: Configuration,
 	polkadot_config: Configuration,
 	id: ParaId,
@@ -1093,18 +1103,20 @@ where
 		> + sp_offchain::OffchainWorkerApi<Block>
 		+ sp_block_builder::BlockBuilder<Block>
 		+ cumulus_primitives_core::CollectCollationInfo<Block>
-		+ sp_consensus_aura::AuraApi<Block, AuraId>
+		+ sp_consensus_aura::AuraApi<Block, <<AuraId as AppKey>::Pair as Pair>::Public>
 		+ pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
 		+ frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
 	sc_client_api::StateBackendFor<TFullBackend<Block>, Block>: sp_api::StateBackend<BlakeTwo256>,
 	Executor: sc_executor::NativeExecutionDispatch + 'static,
+	<<AuraId as AppKey>::Pair as Pair>::Signature:
+		TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec,
 {
 	start_node_impl::<RuntimeApi, Executor, _, _, _>(
 		parachain_config,
 		polkadot_config,
 		id,
 		|_| Ok(Default::default()),
-		statemint_build_import_queue,
+		statemint_build_import_queue::<_, _, AuraId>,
 		|client,
 		 prometheus_registry,
 		 telemetry,
@@ -1132,7 +1144,7 @@ where
 					telemetry2.clone(),
 				);
 
-				AuraConsensus::build::<sp_consensus_aura::sr25519::AuthorityPair, _, _, _, _, _, _>(
+				AuraConsensus::build::<<AuraId as AppKey>::Pair, _, _, _, _, _, _>(
 					BuildAuraConsensusParams {
 						proposer_factory,
 						create_inherent_data_providers:
@@ -1220,6 +1232,7 @@ where
 				client: client.clone(),
 				aura_consensus: Arc::new(Mutex::new(aura_consensus)),
 				relay_chain_consensus: Arc::new(Mutex::new(relay_chain_consensus)),
+				_phantom: PhantomData,
 			});
 
 			Ok(parachain_consensus)
diff --git a/cumulus/polkadot-parachains/statemint/src/lib.rs b/cumulus/polkadot-parachains/statemint/src/lib.rs
index b83752e267dcdc39145c1710688c52528e553a3e..566eff5a051c6c02ca232a0055f7e86fb0f37e1b 100644
--- a/cumulus/polkadot-parachains/statemint/src/lib.rs
+++ b/cumulus/polkadot-parachains/statemint/src/lib.rs
@@ -57,8 +57,9 @@ use frame_system::{
 pub use parachains_common as common;
 use parachains_common::{
 	impls::{AssetsToBlockAuthor, DealWithFees, NonZeroIssuance},
-	opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature,
-	AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
+	opaque, AccountId, AssetId, Balance, BlockNumber, Hash, Header, Index, Signature,
+	StatemintAuraId as AuraId, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT,
+	NORMAL_DISPATCH_RATIO, SLOT_DURATION,
 };
 
 #[cfg(any(feature = "std", test))]