frame_decode/
lib.rs

1// Copyright (C) 2022-2025 Parity Technologies (UK) Ltd. (admin@parity.io)
2// This file is a part of the frame-decode crate.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//         http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Decode extrinsics and storage values from substrate based networks which expose `frame-metadata::RuntimeMetadata`
17//! like Polkadot.
18//!
19//! - See [`extrinsics`] for decoding Extrinsics.
20//! - See [`storage`] for encoding/decoding storage keys and decoding values.
21//! - See [`runtime_apis`] for encoding Runtime API inputs and decoding Runtime API responses
22//! - See [`legacy_types`] to access historic type information for certain chains.
23//!
24#![deny(missing_docs)]
25#![cfg_attr(not(feature = "std"), no_std)]
26
27extern crate alloc;
28
29mod methods;
30mod utils;
31
32pub mod extrinsics {
33    //! This module contains functions for decoding extrinsics.
34    //!
35    //! - See [`decode_extrinsic`] for a general function to decode modern or historic extrinsics.
36    //! - See [`ExtrinsicTypeInfo`] for the underlying trait which extracts the relevant information.
37
38    pub use crate::methods::extrinsic_decoder::{
39        Extrinsic, ExtrinsicDecodeError, ExtrinsicExtensions, ExtrinsicOwned, ExtrinsicSignature,
40        ExtrinsicType, NamedArg, decode_extrinsic,
41    };
42    pub use crate::methods::extrinsic_type_info::{
43        ExtrinsicCallInfo, ExtrinsicExtensionInfo, ExtrinsicInfoArg, ExtrinsicInfoError,
44        ExtrinsicSignatureInfo, ExtrinsicTypeInfo,
45    };
46}
47
48pub mod storage {
49    //! This module contains functions for decoding storage keys and values.
50    //!
51    //! - See [`decode_storage_key`] and [`decode_storage_value`] to decode storage keys or values
52    //!   from modern or historic runtimes.
53    //! - See [`encode_storage_key_prefix`] to encode storage prefixes, and [`encode_storage_key`] to encode
54    //!   storage keys.
55    //! - See [`StorageTypeInfo`] for the underlying trait which extracts the relevant information.
56
57    pub use crate::methods::storage_decoder::{
58        StorageKey, StorageKeyDecodeError, StorageKeyPart, StorageKeyPartValue,
59        StorageKeyValueDecodeError, StorageValueDecodeError,
60        decode_default_storage_value_with_info, decode_storage_key, decode_storage_key_values,
61        decode_storage_key_with_info, decode_storage_value, decode_storage_value_with_info,
62    };
63    pub use crate::methods::storage_encoder::{
64        StorageKeyEncodeError, encode_storage_key, encode_storage_key_prefix,
65        encode_storage_key_suffix, encode_storage_key_suffix_to,
66        encode_storage_key_suffix_with_info_to, encode_storage_key_to,
67        encode_storage_key_with_info, encode_storage_key_with_info_to,
68    };
69    pub use crate::methods::storage_type_info::{
70        StorageEntry, StorageHasher, StorageInfo, StorageInfoError, StorageKeyInfo, StorageTypeInfo,
71    };
72    pub use crate::utils::{
73        DecodableValues, EncodableValues, IntoDecodableValues, IntoEncodableValues,
74    };
75}
76
77pub mod constants {
78    //! This module contains types and functions for working with constants.
79    //!
80    //! - See [`decode_constant`] and [`decode_constant_with_info`] to decode constants
81    //! - See [`ConstantTypeInfo`] for the underlying trait which extracts constant
82    //!   information from metadata.
83
84    pub use crate::methods::constant_decoder::{
85        ConstantDecodeError, decode_constant, decode_constant_with_info,
86    };
87    pub use crate::methods::constant_type_info::{
88        Constant, ConstantInfo, ConstantInfoError, ConstantTypeInfo,
89    };
90}
91
92pub mod runtime_apis {
93    //! This module contains types and functions for working with Runtime APIs.
94    //!
95    //! - See [`encode_runtime_api_name`] and [`encode_runtime_api_inputs`] to encode
96    //!   the name and inputs to make a Runtime API call.
97    //! - See [`decode_runtime_api_response`] to decode Runtime API responses.
98    //! - See [`RuntimeApiTypeInfo`] for the underlying trait which extracts the relevant information.
99
100    pub use crate::methods::runtime_api_decoder::{
101        RuntimeApiDecodeError, decode_runtime_api_response, decode_runtime_api_response_with_info,
102    };
103    pub use crate::methods::runtime_api_encoder::{
104        RuntimeApiInputsEncodeError, encode_runtime_api_inputs, encode_runtime_api_inputs_to,
105        encode_runtime_api_inputs_with_info_to, encode_runtime_api_name,
106    };
107    pub use crate::methods::runtime_api_type_info::{
108        RuntimeApi, RuntimeApiInfo, RuntimeApiInfoError, RuntimeApiInput, RuntimeApiTypeInfo,
109    };
110    pub use crate::utils::{EncodableValues, IntoEncodableValues};
111}
112
113pub mod view_functions {
114    //! This module contains types and functions for working with View Functions.
115    //!
116    //! - See [`RUNTIME_API_NAME`] and [`encode_view_function_inputs`] to obtain the Runtime API name
117    //!   and the encoded input data required to call a given View Function.
118    //! - See [`decode_view_function_response`] to decode View Function responses.
119    //! - See [`ViewFunctionTypeInfo`] for the underlying trait which extracts the relevant information.
120
121    pub use crate::methods::view_function_decoder::{
122        ViewFunctionDecodeError, decode_view_function_response,
123        decode_view_function_response_with_info,
124    };
125    pub use crate::methods::view_function_encoder::{
126        RUNTIME_API_NAME, ViewFunctionInputsEncodeError, encode_view_function_inputs,
127        encode_view_function_inputs_to, encode_view_function_inputs_with_info_to,
128    };
129    pub use crate::methods::view_function_type_info::{
130        ViewFunction, ViewFunctionInfo, ViewFunctionInfoError, ViewFunctionInput,
131        ViewFunctionTypeInfo,
132    };
133    pub use crate::utils::{EncodableValues, IntoEncodableValues};
134}
135
136pub mod custom_values {
137    //! This module contains types and functions for working with custom values.
138    //!
139    //! - See [`decode_custom_value`] and [`decode_custom_value_with_info`] to decode custom values
140    //! - See [`CustomValueTypeInfo`] for the underlying trait which extracts custom value
141    //!   information from metadata.
142
143    pub use crate::methods::custom_value_decoder::{
144        CustomValueDecodeError, decode_custom_value, decode_custom_value_with_info,
145    };
146    pub use crate::methods::custom_value_type_info::{
147        CustomValue, CustomValueInfo, CustomValueInfoError, CustomValueTypeInfo,
148    };
149}
150
151#[cfg(feature = "legacy-types")]
152pub mod legacy_types {
153    //! This module contains legacy types that can be used to decode pre-V14 blocks and storage.
154
155    pub mod polkadot {
156        //! Legacy types for Polkadot chains.
157
158        /// Legacy types for the Polkadot Relay Chain.
159        pub fn relay_chain() -> scale_info_legacy::ChainTypeRegistry {
160            // This is a convenience function to load the Polkadot relay chain types.
161            // It is used in the examples in this crate.
162            let bytes = include_bytes!("../types/polkadot_types.yaml");
163            serde_yaml::from_slice(bytes).expect("Polkadot types are valid YAML")
164        }
165    }
166}
167
168pub mod helpers {
169    //! Helper functions and types to assist with decoding.
170    //!
171    //! - [`type_registry_from_metadata`] is expected to be used when decoding things from historic
172    //!   runtimes, adding the ability to decode some types from information in the metadata.
173    //! - [`decode_with_error_tracing`] is like [`decode_with_visitor`], but
174    //!   will use a tracing visitor (if the `error-tracing` feature is enabled) to provide more
175    //!   information in the event that decoding fails.
176
177    pub use crate::utils::{
178        DecodableValues, DecodeErrorTrace, EncodableValues, IntoDecodableValues,
179        IntoEncodableValues, decode_with_error_tracing, list_storage_entries_any,
180    };
181    #[cfg(feature = "legacy")]
182    pub use crate::utils::{type_registry_from_metadata, type_registry_from_metadata_any};
183
184    /// An alias to [`scale_decode::visitor::decode_with_visitor`]. This can be used to decode the byte ranges
185    /// given back from functions like [`crate::extrinsics::decode_extrinsic`] or
186    /// [`crate::storage::decode_storage_key`].
187    pub use scale_decode::visitor::decode_with_visitor;
188
189    /// An alias to the underlying [`scale-decode`] crate.
190    pub use scale_decode;
191}
192
193#[cfg(test)]
194mod test {
195    use crate::methods::extrinsic_type_info::ExtrinsicTypeInfo;
196    use crate::methods::runtime_api_type_info::RuntimeApiTypeInfo;
197    use crate::methods::storage_type_info::StorageTypeInfo;
198    use crate::methods::view_function_type_info::ViewFunctionTypeInfo;
199    use crate::utils::ToTypeRegistry;
200
201    // This will panic if there is any issue decoding the legacy types we provide.
202    #[test]
203    fn test_deserializing_legacy_types() {
204        let _ = crate::legacy_types::polkadot::relay_chain();
205    }
206
207    macro_rules! impls_trait {
208        ($type:ty, $trait:path) => {
209            const _: () = {
210                const fn assert_impl<T: $trait>() {}
211                assert_impl::<$type>();
212            };
213        };
214    }
215
216    // Just a sanity check that all of the metadata versions we expect implement
217    // all of the key traits. Makes it harder to miss something when adding a new metadata
218    // version; just add it below and implement the traits until everything compiles.
219    #[rustfmt::skip]
220    const _: () = {
221        impls_trait!(frame_metadata::v8::RuntimeMetadataV8, ExtrinsicTypeInfo);
222        impls_trait!(frame_metadata::v9::RuntimeMetadataV9, ExtrinsicTypeInfo);
223        impls_trait!(frame_metadata::v10::RuntimeMetadataV10, ExtrinsicTypeInfo);
224        impls_trait!(frame_metadata::v11::RuntimeMetadataV11, ExtrinsicTypeInfo);
225        impls_trait!(frame_metadata::v12::RuntimeMetadataV12, ExtrinsicTypeInfo);
226        impls_trait!(frame_metadata::v13::RuntimeMetadataV13, ExtrinsicTypeInfo);
227        impls_trait!(frame_metadata::v14::RuntimeMetadataV14, ExtrinsicTypeInfo);
228        impls_trait!(frame_metadata::v15::RuntimeMetadataV15, ExtrinsicTypeInfo);
229        impls_trait!(frame_metadata::v16::RuntimeMetadataV16, ExtrinsicTypeInfo);
230
231        impls_trait!(frame_metadata::v8::RuntimeMetadataV8, StorageTypeInfo);
232        impls_trait!(frame_metadata::v9::RuntimeMetadataV9, StorageTypeInfo);
233        impls_trait!(frame_metadata::v10::RuntimeMetadataV10, StorageTypeInfo);
234        impls_trait!(frame_metadata::v11::RuntimeMetadataV11, StorageTypeInfo);
235        impls_trait!(frame_metadata::v12::RuntimeMetadataV12, StorageTypeInfo);
236        impls_trait!(frame_metadata::v13::RuntimeMetadataV13, StorageTypeInfo);
237        impls_trait!(frame_metadata::v14::RuntimeMetadataV14, StorageTypeInfo);
238        impls_trait!(frame_metadata::v15::RuntimeMetadataV15, StorageTypeInfo);
239        impls_trait!(frame_metadata::v16::RuntimeMetadataV16, StorageTypeInfo);
240
241        // Only V16+ metadata contains any view function information. Prior to this,
242        // hardly any view functions existed. We _could_ extend our legacy type information
243        // to support them if necessary, but it's unlikely it will be.
244        impls_trait!(frame_metadata::v16::RuntimeMetadataV16, ViewFunctionTypeInfo);
245
246        // Only V15+ metadata has Runtime API info in. For earlier, we lean on
247        // our scale-Info-legacy type registry to provide the information.
248        impls_trait!(scale_info_legacy::TypeRegistry, RuntimeApiTypeInfo);
249        impls_trait!(scale_info_legacy::TypeRegistrySet, RuntimeApiTypeInfo);
250        impls_trait!(frame_metadata::v15::RuntimeMetadataV15, RuntimeApiTypeInfo);
251        impls_trait!(frame_metadata::v16::RuntimeMetadataV16, RuntimeApiTypeInfo);
252
253        // This is a legacy trait and so only legacy metadata versions implement it:
254        impls_trait!(frame_metadata::v8::RuntimeMetadataV8, ToTypeRegistry);
255        impls_trait!(frame_metadata::v9::RuntimeMetadataV9, ToTypeRegistry);
256        impls_trait!(frame_metadata::v10::RuntimeMetadataV10, ToTypeRegistry);
257        impls_trait!(frame_metadata::v11::RuntimeMetadataV11, ToTypeRegistry);
258        impls_trait!(frame_metadata::v12::RuntimeMetadataV12, ToTypeRegistry);
259        impls_trait!(frame_metadata::v13::RuntimeMetadataV13, ToTypeRegistry);
260    };
261}