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 /// Does this extension authorize the transaction, eg by containing a signature
28 /// like `VerifyMultiSignature` does? Such an extension signs the transaction
29 /// extension version, the call data, and the values and implicits of only the
30 /// extensions _after_ it, and so when a V5 signer payload is built, the value
31 /// and implicit bytes of an authorization extension, and of every extension
32 /// before it, are excluded from the payload.
33 ///
34 /// This defaults to `false`, which is correct for any extension which doesn't
35 /// authorize the transaction.
36 fn is_authorization_extension(&self) -> bool {
37 false
38 }
39
40 /// Given type information for the expected transaction extension,
41 /// this should encode the value (ie the bytes that will appear in the
42 /// transaction) to the provided `Vec`, or encode nothing and emit an error.
43 fn encode_value_to(
44 &self,
45 type_id: Resolver::TypeId,
46 type_resolver: &Resolver,
47 out: &mut Vec<u8>,
48 ) -> Result<(), TransactionExtensionError>;
49
50 /// Given type information for the expected transaction extension,
51 /// this should encode the implicit (ie the bytes that will appear in the
52 /// signer payload) to the provided `Vec`, or encode nothing and emit an error.
53 fn encode_implicit_to(
54 &self,
55 type_id: Resolver::TypeId,
56 type_resolver: &Resolver,
57 out: &mut Vec<u8>,
58 ) -> Result<(), TransactionExtensionError>;
59}
60
61/// This error will be returned if any of the methods in [`TransactionExtension`] fail.
62pub type TransactionExtensionError = Box<dyn core::error::Error + Send + Sync + 'static>;