diff --git a/core/sr-api-macros/src/decl_runtime_apis.rs b/core/sr-api-macros/src/decl_runtime_apis.rs
index 13498003c2ee479a6f07b82a8f9de62100b8aac9..17d85c14c0344e3a01f52e7c03d368c050b3cdc1 100644
--- a/core/sr-api-macros/src/decl_runtime_apis.rs
+++ b/core/sr-api-macros/src/decl_runtime_apis.rs
@@ -18,6 +18,7 @@ use utils::{
 	generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait,
 	fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows,
 	generate_native_call_generator_fn_name, return_type_extract_type,
+	generate_method_runtime_api_impl_name
 };
 
 use proc_macro;
@@ -27,8 +28,9 @@ use quote::quote;
 
 use syn::{
 	spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, ReturnType,
-	fold::{self, Fold}, FnDecl, parse_quote, ItemTrait, Generics, GenericParam, Attribute,
-	visit::{Visit, self}, FnArg, Pat, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, Type
+	fold::{self, Fold}, parse_quote, ItemTrait, Generics, GenericParam, Attribute, FnArg,
+	visit::{Visit, self}, Pat, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, Type,
+	TraitItemMethod
 };
 
 use std::collections::HashMap;
@@ -308,17 +310,123 @@ struct ToClientSideDecl<'a> {
 	found_attributes: &'a mut HashMap<&'static str, Attribute>,
 }
 
-impl<'a> Fold for ToClientSideDecl<'a> {
-	fn fold_fn_decl(&mut self, input: FnDecl) -> FnDecl {
-		let input = fold_fn_decl_for_client_side(
-			input,
+impl<'a> ToClientSideDecl<'a> {
+	fn fold_item_trait_items(&self, items: Vec<TraitItem>) -> Vec<TraitItem> {
+		let mut result = Vec::new();
+
+		items.into_iter().for_each(|i| match i {
+			TraitItem::Method(method) => {
+				let (fn_decl, fn_impl) = self.fold_trait_item_method(method);
+				result.push(fn_decl.into());
+				result.push(fn_impl.into());
+			},
+			r => result.push(r),
+		});
+
+		result
+	}
+
+	fn fold_trait_item_method(&self, method: TraitItemMethod) -> (TraitItemMethod, TraitItemMethod) {
+		let fn_impl = self.create_method_runtime_api_impl(&method);
+		let fn_decl = self.create_method_decl(method);
+
+		(fn_decl, fn_impl)
+	}
+
+	/// Takes the given method and creates a `method_runtime_api_impl` method that will be
+	/// implemented in the runtime for the client side.
+	fn create_method_runtime_api_impl(&self, method: &TraitItemMethod) -> TraitItemMethod {
+		let fn_decl = &method.sig.decl;
+		let ret_type = return_type_extract_type(&fn_decl.output);
+
+		// Get types and if the value is borrowed from all parameters.
+		// If there is an error, we push it as the block to the user.
+		let (param_types, error) = match extract_parameter_names_types_and_borrows(fn_decl) {
+			Ok(res) => (
+				res.into_iter().map(|v| {
+					let ty = v.1;
+					let borrow = v.2;
+					quote!( #borrow #ty )
+				}).collect::<Vec<_>>(),
+				None
+			),
+			Err(e) => (Vec::new(), Some(e.to_compile_error())),
+		};
+		let name = generate_method_runtime_api_impl_name(&method.sig.ident);
+		let block_id = self.block_id;
+		let crate_ = self.crate_;
+
+		let mut res: TraitItemMethod = parse_quote!{
+			#[doc(hidden)]
+			fn #name(
+				&self,
+				at: &#block_id,
+				params: Option<( #( #param_types ),* )>,
+				params_encoded: Vec<u8>
+			) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<#ret_type>>;
+		};
+
+		// Yeah... Just miss-use the block to "throw" our error to the user.
+		res.default = error.map(|e| parse_quote!( { #e }));
+
+		res
+	}
+
+	/// Takes the method declared by the user and creates the declaration we require for the runtime
+	/// api client side. This method will call by default the `method_runtime_api_impl` for doing
+	/// the actual call into the runtime.
+	fn create_method_decl(&self, mut method: TraitItemMethod) -> TraitItemMethod {
+		let (params, error) = match extract_parameter_names_types_and_borrows(&method.sig.decl) {
+			Ok(res) => (res.into_iter().map(|v| v.0).collect::<Vec<_>>(), None),
+			Err(e) => (Vec::new(), Some(e.to_compile_error())),
+		};
+		let params2 = params.clone();
+		let ret_type = return_type_extract_type(&method.sig.decl.output);
+
+		method.sig.decl = fold_fn_decl_for_client_side(
+			method.sig.decl.clone(),
 			&self.block_id,
 			&self.crate_
 		);
+		let name_impl = generate_method_runtime_api_impl_name(&method.sig.ident);
+		let crate_ = self.crate_;
+		let function_name = method.sig.ident.to_string();
+
+		// Generate the default implementation that calls the `method_runtime_api_impl` method.
+		method.default = Some(
+			parse_quote! {
+				{
+					let runtime_api_impl_params_encoded =
+						#crate_::runtime_api::Encode::encode(&( #( &#params ),* ));
+
+					// Bring the compile error to the user.
+					#( #error )*
+
+					self.#name_impl(at, Some(( #( #params2 ),* )), runtime_api_impl_params_encoded)
+						.and_then(|r|
+							match r {
+								#crate_::runtime_api::NativeOrEncoded::Native(n) => {
+									Ok(n)
+								},
+								#crate_::runtime_api::NativeOrEncoded::Encoded(r) => {
+									<#ret_type as #crate_::runtime_api::Decode>::decode(&mut &r[..])
+										.ok_or_else(||
+											#crate_::error::ErrorKind::CallResultDecode(
+												#function_name
+											).into()
+										)
+								}
+							}
+						)
+				}
+			}
+		);
 
-		fold::fold_fn_decl(self, input)
+		method
 	}
+}
 
+impl<'a> Fold for ToClientSideDecl<'a> {
 	fn fold_item_trait(&mut self, mut input: ItemTrait) -> ItemTrait {
 		extend_generics_with_block(&mut input.generics);
 
@@ -344,6 +452,7 @@ impl<'a> Fold for ToClientSideDecl<'a> {
 
 		// The client side trait is only required when compiling with the feature `std` or `test`.
 		input.attrs.push(parse_quote!( #[cfg(any(feature = "std", test))] ));
+		input.items = self.fold_item_trait_items(input.items);
 
 		fold::fold_item_trait(self, input)
 	}
diff --git a/core/sr-api-macros/src/impl_runtime_apis.rs b/core/sr-api-macros/src/impl_runtime_apis.rs
index 2909b07413f326580accac04773ddf9213c1ac0f..507b3fcb7be927fdfb639c7f1279fcddb8ddaa11 100644
--- a/core/sr-api-macros/src/impl_runtime_apis.rs
+++ b/core/sr-api-macros/src/impl_runtime_apis.rs
@@ -16,8 +16,8 @@
 
 use utils::{
 	unwrap_or_error, generate_crate_access, generate_hidden_includes,
-	generate_runtime_mod_name_for_trait, fold_fn_decl_for_client_side, generate_unique_pattern,
-	extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name
+	generate_runtime_mod_name_for_trait, generate_method_runtime_api_impl_name,
+	extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name, return_type_extract_type
 };
 
 use proc_macro;
@@ -28,7 +28,7 @@ use quote::quote;
 use syn::{
 	spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, MethodSig, Path,
 	ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath,
-	fold::{self, Fold}, FnDecl, parse_quote, FnArg
+	fold::{self, Fold}, parse_quote
 };
 
 use std::{collections::HashSet, iter};
@@ -336,8 +336,8 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result<TokenStrea
 				at: &#block_id,
 				function: &'static str,
 				args: Vec<u8>,
-				native_call: NC,
-			) -> #crate_::error::Result<R> {
+				native_call: Option<NC>,
+			) -> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<R>> {
 				let res = unsafe {
 					self.call.call_api_at(
 						at,
@@ -345,21 +345,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result<TokenStrea
 						args,
 						&mut *self.changes.borrow_mut(),
 						&mut *self.initialised_block.borrow_mut(),
-						Some(native_call),
-					).and_then(|r|
-						match r {
-							#crate_::runtime_api::NativeOrEncoded::Native(n) => {
-								Ok(n)
-							},
-							#crate_::runtime_api::NativeOrEncoded::Encoded(r) => {
-								R::decode(&mut &r[..])
-									.ok_or_else(||
-										#crate_::error::ErrorKind::CallResultDecode(
-											function
-										).into()
-									)
-							}
-						}
+						native_call,
 					)
 				};
 
@@ -446,50 +432,69 @@ impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> {
 		fold::fold_type_path(self, new_ty_path)
 	}
 
-	fn fold_fn_decl(&mut self, input: FnDecl) -> FnDecl {
-		let input = fold_fn_decl_for_client_side(
-			input,
-			&self.node_block_id,
-			&generate_crate_access(HIDDEN_INCLUDES_ID)
-		);
-
-		fold::fold_fn_decl(self, input)
-	}
-
 	fn fold_impl_item_method(&mut self, mut input: syn::ImplItemMethod) -> syn::ImplItemMethod {
 		let block = {
-			let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
-			let mut generated_name_counter = 0;
-			// Replace `_` with unique patterns and collect all patterns.
-			let arg_names = input.sig.decl.inputs.iter_mut().filter_map(|i| match i {
-				FnArg::Captured(ref mut arg) => Some(&mut arg.pat),
-				_ => None,
-			}).map(|p| {
-				*p = generate_unique_pattern(p.clone(), &mut generated_name_counter);
-				p.clone()
-			}).collect::<Vec<_>>();
-
 			let runtime_mod_path = self.runtime_mod_path;
 			let runtime = self.runtime_type;
-			let arg_names2 = arg_names.clone();
 			let fn_name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident);
 			let native_call_generator_ident =
 				generate_native_call_generator_fn_name(&input.sig.ident);
 			let trait_generic_arguments = self.trait_generic_arguments;
 			let node_block = self.node_block;
+			let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID);
+			let block_id = self.node_block_id;
+
+			// Generate the access to the native parameters
+			let param_tuple_access = if input.sig.decl.inputs.len() == 1 {
+				vec![ quote!( p ) ]
+			} else {
+				input.sig.decl.inputs.iter().enumerate().map(|(i, _)| {
+					let i = syn::Index::from(i);
+					quote!( p.#i )
+				}).collect::<Vec<_>>()
+			};
+
+			let (param_types, error) = match extract_parameter_names_types_and_borrows(&input.sig.decl) {
+				Ok(res) => (
+					res.into_iter().map(|v| {
+						let ty = v.1;
+						let borrow = v.2;
+						quote!( #borrow #ty )
+					}).collect::<Vec<_>>(),
+					None
+				),
+				Err(e) => (Vec::new(), Some(e.to_compile_error())),
+			};
+
+			// Rewrite the input parameters.
+			input.sig.decl.inputs = parse_quote! {
+				&self, at: &#block_id, params: Option<( #( #param_types ),* )>, params_encoded: Vec<u8>
+			};
+
+			input.sig.ident = generate_method_runtime_api_impl_name(&input.sig.ident);
+			let ret_type = return_type_extract_type(&input.sig.decl.output);
+
+			// Generate the correct return type.
+			input.sig.decl.output = parse_quote!(
+				-> #crate_::error::Result<#crate_::runtime_api::NativeOrEncoded<#ret_type>>
+			);
 
 			// Generate the new method implementation that calls into the runime.
 			parse_quote!(
 				{
-					let args = #crate_::runtime_api::Encode::encode(&( #( &#arg_names ),* ));
+					// Get the error to the user (if we have one).
+					#( #error )*
+
 					self.call_api_at(
 						at,
 						#fn_name,
-						args,
-						#runtime_mod_path #native_call_generator_ident ::
-							<#runtime, #node_block #(, #trait_generic_arguments )*> (
-							#( #arg_names2 ),*
-						)
+						params_encoded,
+						params.map(|p| {
+							#runtime_mod_path #native_call_generator_ident ::
+								<#runtime, #node_block #(, #trait_generic_arguments )*> (
+								#( #param_tuple_access ),*
+							)
+						})
 					)
 				}
 			)
diff --git a/core/sr-api-macros/src/utils.rs b/core/sr-api-macros/src/utils.rs
index 9df59b30a7ab0b56eb1d11753b0de2a805fbb497..d619fcb389e7922665d6f7460cf26b26c628c174 100644
--- a/core/sr-api-macros/src/utils.rs
+++ b/core/sr-api-macros/src/utils.rs
@@ -58,6 +58,11 @@ pub fn generate_runtime_mod_name_for_trait(trait_: &Ident) -> Ident {
 	Ident::new(&format!("runtime_decl_for_{}", trait_.to_string()), Span::call_site())
 }
 
+/// Generates a name for a method that needs to be implemented in the runtime for the client side.
+pub fn generate_method_runtime_api_impl_name(method: &Ident) -> Ident {
+	Ident::new(&format!("{}_runtime_api_impl", method.to_string()), Span::call_site())
+}
+
 /// Get the type of a `syn::ReturnType`.
 pub fn return_type_extract_type(rt: &syn::ReturnType) -> Type {
 	match rt {