subxt_metadata/from/
v16.rs

1// Copyright 2019-2025 Parity Technologies (UK) Ltd.
2// This file is dual-licensed as Apache-2.0 or GPL-3.0.
3// see LICENSE for license details.
4
5use super::TryFromError;
6
7use crate::utils::variant_index::VariantIndex;
8use crate::{
9    ArcStr, ConstantMetadata, ExtrinsicMetadata, Metadata, MethodParamMetadata, OuterEnumsMetadata,
10    PalletMetadataInner, RuntimeApiMetadataInner, RuntimeApiMethodMetadataInner,
11    StorageEntryMetadata, StorageEntryModifier, StorageEntryType, StorageHasher, StorageMetadata,
12    TransactionExtensionMetadataInner, ViewFunctionMetadataInner, utils::ordered_map::OrderedMap,
13};
14use frame_metadata::{v15, v16};
15use hashbrown::HashMap;
16use scale_info::form::PortableForm;
17
18impl TryFrom<v16::RuntimeMetadataV16> for Metadata {
19    type Error = TryFromError;
20    fn try_from(m: v16::RuntimeMetadataV16) -> Result<Self, TryFromError> {
21        let types = m.types;
22
23        let mut pallets = OrderedMap::new();
24        let mut pallets_by_index = HashMap::new();
25        for (pos, p) in m.pallets.into_iter().enumerate() {
26            let name: ArcStr = p.name.into();
27
28            let storage = p.storage.map(|s| StorageMetadata {
29                prefix: s.prefix,
30                entries: s
31                    .entries
32                    .into_iter()
33                    .map(|s| {
34                        let name: ArcStr = s.name.clone().into();
35                        (name.clone(), from_storage_entry_metadata(name, s))
36                    })
37                    .collect(),
38            });
39            let constants = p.constants.into_iter().map(|c| {
40                let name: ArcStr = c.name.clone().into();
41                (name.clone(), from_constant_metadata(name, c))
42            });
43            let view_functions = p.view_functions.into_iter().map(|v| {
44                let name: ArcStr = v.name.clone().into();
45                (name.clone(), from_view_function_metadata(name, v))
46            });
47
48            let call_variant_index = VariantIndex::build(p.calls.as_ref().map(|c| c.ty.id), &types);
49            let error_variant_index =
50                VariantIndex::build(p.error.as_ref().map(|e| e.ty.id), &types);
51            let event_variant_index =
52                VariantIndex::build(p.event.as_ref().map(|e| e.ty.id), &types);
53
54            let associated_types = p
55                .associated_types
56                .into_iter()
57                .map(|t| (t.name, t.ty.id))
58                .collect();
59
60            pallets_by_index.insert(p.index, pos);
61            pallets.push_insert(
62                name.clone(),
63                PalletMetadataInner {
64                    name,
65                    index: p.index,
66                    storage,
67                    call_ty: p.calls.map(|c| c.ty.id),
68                    call_variant_index,
69                    event_ty: p.event.map(|e| e.ty.id),
70                    event_variant_index,
71                    error_ty: p.error.map(|e| e.ty.id),
72                    error_variant_index,
73                    constants: constants.collect(),
74                    view_functions: view_functions.collect(),
75                    associated_types,
76                    docs: p.docs,
77                },
78            );
79        }
80
81        let apis = m.apis.into_iter().map(|api| {
82            let name: ArcStr = api.name.clone().into();
83            (name.clone(), from_runtime_api_metadata(name, api))
84        });
85
86        let custom_map = m
87            .custom
88            .map
89            .into_iter()
90            .map(|(key, val)| {
91                let custom_val = v15::CustomValueMetadata {
92                    ty: val.ty,
93                    value: val.value,
94                };
95                (key, custom_val)
96            })
97            .collect();
98
99        let dispatch_error_ty = types
100            .types
101            .iter()
102            .find(|ty| ty.ty.path.segments == ["sp_runtime", "DispatchError"])
103            .map(|ty| ty.id);
104
105        Ok(Metadata {
106            types,
107            pallets,
108            pallets_by_index,
109            extrinsic: from_extrinsic_metadata(m.extrinsic),
110            dispatch_error_ty,
111            apis: apis.collect(),
112            outer_enums: OuterEnumsMetadata {
113                call_enum_ty: m.outer_enums.call_enum_ty.id,
114                event_enum_ty: m.outer_enums.event_enum_ty.id,
115                error_enum_ty: m.outer_enums.error_enum_ty.id,
116            },
117            custom: v15::CustomMetadata { map: custom_map },
118        })
119    }
120}
121
122fn from_transaction_extension_metadata(
123    value: v16::TransactionExtensionMetadata<PortableForm>,
124) -> TransactionExtensionMetadataInner {
125    TransactionExtensionMetadataInner {
126        identifier: value.identifier,
127        extra_ty: value.ty.id,
128        additional_ty: value.implicit.id,
129    }
130}
131
132fn from_extrinsic_metadata(value: v16::ExtrinsicMetadata<PortableForm>) -> ExtrinsicMetadata {
133    ExtrinsicMetadata {
134        supported_versions: value.versions,
135        transaction_extensions_by_version: value
136            .transaction_extensions_by_version
137            .into_iter()
138            .map(|(version, idxs)| (version, idxs.into_iter().map(|idx| idx.0).collect()))
139            .collect(),
140        transaction_extensions: value
141            .transaction_extensions
142            .into_iter()
143            .map(from_transaction_extension_metadata)
144            .collect(),
145        address_ty: value.address_ty.id,
146        signature_ty: value.signature_ty.id,
147    }
148}
149
150fn from_storage_hasher(value: v16::StorageHasher) -> StorageHasher {
151    match value {
152        v16::StorageHasher::Blake2_128 => StorageHasher::Blake2_128,
153        v16::StorageHasher::Blake2_256 => StorageHasher::Blake2_256,
154        v16::StorageHasher::Blake2_128Concat => StorageHasher::Blake2_128Concat,
155        v16::StorageHasher::Twox128 => StorageHasher::Twox128,
156        v16::StorageHasher::Twox256 => StorageHasher::Twox256,
157        v16::StorageHasher::Twox64Concat => StorageHasher::Twox64Concat,
158        v16::StorageHasher::Identity => StorageHasher::Identity,
159    }
160}
161
162fn from_storage_entry_type(value: v16::StorageEntryType<PortableForm>) -> StorageEntryType {
163    match value {
164        v16::StorageEntryType::Plain(ty) => StorageEntryType::Plain(ty.id),
165        v16::StorageEntryType::Map {
166            hashers,
167            key,
168            value,
169        } => StorageEntryType::Map {
170            hashers: hashers.into_iter().map(from_storage_hasher).collect(),
171            key_ty: key.id,
172            value_ty: value.id,
173        },
174    }
175}
176
177fn from_storage_entry_modifier(value: v16::StorageEntryModifier) -> StorageEntryModifier {
178    match value {
179        v16::StorageEntryModifier::Optional => StorageEntryModifier::Optional,
180        v16::StorageEntryModifier::Default => StorageEntryModifier::Default,
181    }
182}
183
184fn from_storage_entry_metadata(
185    name: ArcStr,
186    s: v16::StorageEntryMetadata<PortableForm>,
187) -> StorageEntryMetadata {
188    StorageEntryMetadata {
189        name,
190        modifier: from_storage_entry_modifier(s.modifier),
191        entry_type: from_storage_entry_type(s.ty),
192        default: s.default,
193        docs: s.docs,
194    }
195}
196
197fn from_constant_metadata(
198    name: ArcStr,
199    s: v16::PalletConstantMetadata<PortableForm>,
200) -> ConstantMetadata {
201    ConstantMetadata {
202        name,
203        ty: s.ty.id,
204        value: s.value,
205        docs: s.docs,
206    }
207}
208
209fn from_runtime_api_metadata(
210    name: ArcStr,
211    s: v16::RuntimeApiMetadata<PortableForm>,
212) -> RuntimeApiMetadataInner {
213    RuntimeApiMetadataInner {
214        name,
215        docs: s.docs,
216        methods: s
217            .methods
218            .into_iter()
219            .map(|m| {
220                let name: ArcStr = m.name.clone().into();
221                (name.clone(), from_runtime_api_method_metadata(name, m))
222            })
223            .collect(),
224    }
225}
226
227fn from_runtime_api_method_metadata(
228    name: ArcStr,
229    s: v16::RuntimeApiMethodMetadata<PortableForm>,
230) -> RuntimeApiMethodMetadataInner {
231    RuntimeApiMethodMetadataInner {
232        name,
233        inputs: s
234            .inputs
235            .into_iter()
236            .map(|param| MethodParamMetadata {
237                name: param.name,
238                ty: param.ty.id,
239            })
240            .collect(),
241        output_ty: s.output.id,
242        docs: s.docs,
243    }
244}
245
246fn from_view_function_metadata(
247    name: ArcStr,
248    s: v16::PalletViewFunctionMetadata<PortableForm>,
249) -> ViewFunctionMetadataInner {
250    ViewFunctionMetadataInner {
251        name,
252        query_id: s.id,
253        inputs: s
254            .inputs
255            .into_iter()
256            .map(|param| MethodParamMetadata {
257                name: param.name,
258                ty: param.ty.id,
259            })
260            .collect(),
261        output_ty: s.output.id,
262        docs: s.docs,
263    }
264}