feat: add configurable dispatch_error_module for rebranded chains (v0.43)

Add a new `dispatch_error_module` option to the subxt macro and CodegenBuilder
that allows chains with rebranded runtime modules to specify their own path for
the DispatchError type.

By default, subxt generates:
  pub type DispatchError = runtime_types::sp_runtime::DispatchError;

Chains like Kurdistan SDK (Pezkuwi) that rebrand sp_runtime to pezsp_runtime
can now specify:
  dispatch_error_module = "pezsp_runtime"

This generates:
  pub type DispatchError = runtime_types::pezsp_runtime::DispatchError;

Changes:
- codegen/src/lib.rs: Add dispatch_error_module field to CodegenBuilder
- codegen/src/api/mod.rs: Pass dispatch_error_module to generate_runtime
- codegen/src/api/calls.rs: Use configurable module path for DispatchError
- macro/src/lib.rs: Add dispatch_error_module attribute parsing

Based on v0.43.0 for API compatibility with Kurdistan SDK.
This commit is contained in:
2025-12-17 10:14:41 +03:00
parent 841a43b1ec
commit 4705a4e3fd
4 changed files with 41 additions and 3 deletions
+4 -1
View File
@@ -18,10 +18,12 @@ use subxt_metadata::PalletMetadata;
/// - `type_gen` - [`scale_typegen::TypeGenerator`] that contains settings and all types from the runtime metadata.
/// - `pallet` - Pallet metadata from which the calls are generated.
/// - `crate_path` - The crate path under which the `subxt-core` crate is located, e.g. `::subxt::ext::subxt_core` when using subxt as a dependency.
/// - `dispatch_error_module` - The module path for DispatchError (e.g., "sp_runtime" or "pezsp_runtime").
pub fn generate_calls(
type_gen: &TypeGenerator,
pallet: &PalletMetadata,
crate_path: &syn::Path,
dispatch_error_module: &str,
) -> Result<TokenStream2, CodegenError> {
// Early return if the pallet has no calls.
let Some(call_ty) = pallet.call_ty_id() else {
@@ -115,6 +117,7 @@ pub fn generate_calls(
let docs = type_gen.docs_from_scale_info(&call_ty.docs);
let types_mod_ident = type_gen.types_mod_ident();
let dispatch_error_mod_ident = format_ident!("{}", dispatch_error_module);
Ok(quote! {
#docs
@@ -123,7 +126,7 @@ pub fn generate_calls(
use super::root_mod;
use super::#types_mod_ident;
type DispatchError = #types_mod_ident::sp_runtime::DispatchError;
type DispatchError = #types_mod_ident::#dispatch_error_mod_ident::DispatchError;
pub mod types {
use super::#types_mod_ident;
+5 -2
View File
@@ -111,6 +111,7 @@ impl RuntimeGenerator {
/// * `type_substitutes` - Provide custom type substitutes.
/// * `crate_path` - Path to the `subxt` crate.
/// * `should_gen_docs` - True if the generated API contains the documentation from the metadata.
/// * `dispatch_error_module` - The module path for DispatchError (e.g., "sp_runtime" or "pezsp_runtime").
pub fn generate_runtime(
&self,
item_mod: syn::ItemMod,
@@ -118,6 +119,7 @@ impl RuntimeGenerator {
type_substitutes: scale_typegen::TypeSubstitutes,
crate_path: syn::Path,
should_gen_docs: bool,
dispatch_error_module: &str,
) -> Result<TokenStream2, CodegenError> {
let item_mod_attrs = item_mod.attrs.clone();
let item_mod_ir = ir::ItemMod::try_from(item_mod)?;
@@ -130,6 +132,7 @@ impl RuntimeGenerator {
.generate_types_mod()?
.to_token_stream(type_gen.settings());
let types_mod_ident = type_gen.types_mod_ident();
let dispatch_error_mod_ident = format_ident!("{}", dispatch_error_module);
let pallets_with_mod_names = self
.metadata
.pallets()
@@ -161,7 +164,7 @@ impl RuntimeGenerator {
let modules = pallets_with_mod_names
.iter()
.map(|(pallet, mod_name)| {
let calls = calls::generate_calls(&type_gen, pallet, &crate_path)?;
let calls = calls::generate_calls(&type_gen, pallet, &crate_path, dispatch_error_module)?;
let event = events::generate_events(&type_gen, pallet, &crate_path)?;
@@ -268,7 +271,7 @@ impl RuntimeGenerator {
pub static RUNTIME_APIS: [&str; #runtime_api_names_len] = [ #(#runtime_api_names,)* ];
/// The error type that is returned when there is a runtime issue.
pub type DispatchError = #types_mod_ident::sp_runtime::DispatchError;
pub type DispatchError = #types_mod_ident::#dispatch_error_mod_ident::DispatchError;
/// The outer event enum.
pub type Event = #event_path;
+22
View File
@@ -66,6 +66,9 @@ pub struct CodegenBuilder {
attributes_for_type: HashMap<syn::TypePath, Vec<syn::Attribute>>,
derives_for_type_recursive: HashMap<syn::TypePath, Vec<syn::Path>>,
attributes_for_type_recursive: HashMap<syn::TypePath, Vec<syn::Attribute>>,
/// The module path for DispatchError (default: "sp_runtime").
/// This allows chains with rebranded runtime modules to specify their own path.
dispatch_error_module: String,
}
impl Default for CodegenBuilder {
@@ -86,6 +89,7 @@ impl Default for CodegenBuilder {
attributes_for_type: HashMap::new(),
derives_for_type_recursive: HashMap::new(),
attributes_for_type_recursive: HashMap::new(),
dispatch_error_module: "sp_runtime".to_string(),
}
}
}
@@ -130,6 +134,23 @@ impl CodegenBuilder {
self.runtime_types_only = true;
}
/// Set the module path for DispatchError type.
///
/// By default, this is "sp_runtime", which generates code like:
/// `pub type DispatchError = runtime_types::sp_runtime::DispatchError;`
///
/// Chains that have rebranded their runtime modules can use this to specify
/// a different module path. For example, setting this to "pezsp_runtime" would
/// generate: `pub type DispatchError = runtime_types::pezsp_runtime::DispatchError;`
pub fn set_dispatch_error_module(&mut self, module: impl Into<String>) {
self.dispatch_error_module = module.into();
}
/// Get the configured dispatch error module path.
pub fn dispatch_error_module(&self) -> &str {
&self.dispatch_error_module
}
/// Set the additional derives that will be applied to all types. By default,
/// a set of derives required for Subxt are automatically added for all types.
///
@@ -292,6 +313,7 @@ impl CodegenBuilder {
type_substitutes,
crate_path,
should_gen_docs,
&self.dispatch_error_module,
)
}
}