Skip to main content

frame_decode/methods/extrinsic_encoder/
transaction_extension.rs

1// Copyright (C) 2022-2026 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
16use alloc::boxed::Box;
17use alloc::vec::Vec;
18use scale_type_resolver::TypeResolver;
19
20/// This can be implemented for anything which is a valid Substrate transaction extension.
21/// Transaction extensions each have a unique name to identify them, and are able to encode
22/// explicit `value` bytes to a transaction, or "implicit" bytes to a transaction signer payload.
23pub trait TransactionExtension<Resolver: TypeResolver> {
24    /// The name of this transaction extension.
25    const NAME: &str;
26
27    /// Given type information for the expected transaction extension,
28    /// this should encode the value (ie the bytes that will appear in the
29    /// transaction) to the provided `Vec`, or encode nothing and emit an error.
30    fn encode_value_to(
31        &self,
32        type_id: Resolver::TypeId,
33        type_resolver: &Resolver,
34        out: &mut Vec<u8>,
35    ) -> Result<(), TransactionExtensionError>;
36
37    /// Given type information for the expected transaction extension,
38    /// this should encode the value that will be signed as a part of the
39    /// signer payload.
40    ///
41    /// This defaults to calling [`Self::encode_value_to`] if not implemented.
42    /// In most cases this is fine, but for V5 extrinsics we can optionally provide
43    /// the signature inside a transaction extension, and so that transaction would be
44    /// unable to encode anything for the signer payload and thus should override this
45    /// method to encode nothing.
46    fn encode_value_for_signer_payload_to(
47        &self,
48        type_id: Resolver::TypeId,
49        type_resolver: &Resolver,
50        out: &mut Vec<u8>,
51    ) -> Result<(), TransactionExtensionError> {
52        self.encode_value_to(type_id, type_resolver, out)
53    }
54
55    /// Given type information for the expected transaction extension,
56    /// this should encode the implicit (ie the bytes that will appear in the
57    /// signer payload) to the provided `Vec`, or encode nothing and emit an error.
58    fn encode_implicit_to(
59        &self,
60        type_id: Resolver::TypeId,
61        type_resolver: &Resolver,
62        out: &mut Vec<u8>,
63    ) -> Result<(), TransactionExtensionError>;
64}
65
66/// This error will be returned if any of the methods in [`TransactionExtension`] fail.
67pub type TransactionExtensionError = Box<dyn core::error::Error + Send + Sync + 'static>;