mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 02:08:02 +00:00
Add a basic book and fix broken docs
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ readme = "../README.md"
|
||||
repository.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
description = "Submit extrinsics (transactions) to a substrate node via RPC"
|
||||
description = "Interact with Substrate based chains on the Polkadot Network"
|
||||
keywords = ["parity", "substrate", "blockchain"]
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//! Build
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
// We want to be able to link to examples on GitHub specific to the current version.
|
||||
// So, output an env var with either the git tag if one points to the current code, or
|
||||
// the git hash pointing to the current code if no tag, or master if we
|
||||
// encounter some error and can't be more specific.
|
||||
if let Ok(tag) = Command::new("git").args(["tag", "--points-at"]).output()
|
||||
&& tag.status.success()
|
||||
&& !tag.stdout.is_empty()
|
||||
{
|
||||
write_to_out(&tag.stdout)
|
||||
} else if let Ok(commit_hash) = Command::new("git").args(["rev-parse", "HEAD"]).output()
|
||||
&& commit_hash.status.success()
|
||||
&& !commit_hash.stdout.is_empty()
|
||||
{
|
||||
write_to_out(&commit_hash.stdout)
|
||||
} else {
|
||||
write_to_out(b"master")
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_out(v: &[u8]) {
|
||||
let out = String::from_utf8_lossy(v);
|
||||
println!("cargo::rustc-env=SUBXT_REF={out}");
|
||||
println!("cargo::rerun-if-env-changed=SUBXT_REF");
|
||||
}
|
||||
@@ -32,7 +32,7 @@ pub struct ArchiveBackend<T: Config> {
|
||||
}
|
||||
|
||||
impl<T: Config> ArchiveBackend<T> {
|
||||
/// Configure and construct an [`ArchiveBackend`] and the associated [`ChainHeadBackendDriver`].
|
||||
/// Configure and construct an [`ArchiveBackend`].
|
||||
pub fn new(client: impl Into<RpcClient>) -> ArchiveBackend<T> {
|
||||
let methods = ChainHeadRpcMethods::new(client.into());
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2019-2025 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! # The book
|
||||
//!
|
||||
//! Subxt is a library for interacting with Substrate based chains. In the early days, it had a focus on
|
||||
//! **sub**mitting e**xt**rinsics, hence the name, however it has since evolved into a full featured library for
|
||||
//! interacting with many aspects of chains across the Polkadot Network.
|
||||
//!
|
||||
//! ## The Polkadot Network
|
||||
//!
|
||||
//! The Polkadot Network is a collection of interconnected Blockchains. Each chain can accept different
|
||||
//! transactions and store different data, as well as fundamentally differing in other areas, such as the
|
||||
//! size and format of account addresses, the data expected to be provided alongside transactions, and
|
||||
//! even more fundamental properties such at the number of bytes used to represent a block number.
|
||||
//!
|
||||
//! Blockchains on the Polkadot network are essentially distributed databases:
|
||||
//! - To write to a chain, users submit _transactions_. Transactions are packets of data that are submitted to a
|
||||
//! chain, usually _from_ a specific account. The result of executing these transactions (assuming everything was
|
||||
//! successful) is that one or more _storage entries_ in the blockchain will be updated.
|
||||
//! - _Storage Entries_ are sets of values of a given shape. We can read these in order to see what the current
|
||||
//! state of affairs is.
|
||||
//!
|
||||
//! Transactions are appended to the blockchain in batches known as blocks, where each block points to the previous
|
||||
//! one. Blocks are immutable and cannot be altered once added, and so the blockchain is essentially a big append-only
|
||||
//! log of all of the transactions every submitted. Storage entries update at each block in response to the transactions
|
||||
//! in it. Interactions with a blockchain happen _at_ a certain block; transactions are submitted to update the state
|
||||
//! at a given block, and state can be read at a given block.
|
||||
//!
|
||||
//! Chains on the Polkadot network are typically created using the Substrate library. This library provides
|
||||
//! various primitives and defaults which make it much simpler to build a new blockchain. Substrate based chains group the
|
||||
//! functionality that they expose to users into _pallets_, where each pallet is a self contained module which contains
|
||||
//! its own storage entries and accepts its own set of transactions. For example, the _Balances_ pallet would accept
|
||||
//! transactions related to transferring tokens between users, and expose storage indicating which user has what tokens.
|
||||
//!
|
||||
//! Aside from transactions and storage entries, pallets also expose:
|
||||
//! - _Constants_, which are fixed values at a given runtime version.
|
||||
//! - _View Functions_, which are read-only functions that can be called and return some result.
|
||||
//!
|
||||
//! Outside of pallets, _Runtime APIs_ also exist, which are read-only functions that can be called and return some result.
|
||||
//!
|
||||
//! All of this logic lives inside the _runtime_ of a chain. An important aspect of Substrate based chains is that this
|
||||
//! runtime can be upgraded. Runtime upgrades allow the functionality of a chain to be changed over time. This means
|
||||
//! that the values that you can read and write from can change from one block to the next.
|
||||
//!
|
||||
//! In order to understand what interactions are possible at a specific runtime version, each runtime exposes
|
||||
//! [_metadata_](https://github.com/paritytech/frame-metadata/). Metadata contains all of the information needed to
|
||||
//! understand what interactions are possible at this runtime. The shape of metadata itself can also change, which
|
||||
//! is why metadatas are versioned. Typically, we refer to metadata at version 14 or above as "modern" metadata, and
|
||||
//! metadata older than this as "historic" or "legacy" metadata. In order to interact with blocks at runtimes which expose
|
||||
//! historic metadata, additional type information needs to be provided by the user, as it was not present in the
|
||||
//! metadata.
|
||||
//!
|
||||
//! ### TL;DR:
|
||||
//! - Each chain can be configured differently.
|
||||
//! - Transactions write to the blockchain, and update storage entries which can be read from.
|
||||
//! - Reading and writing to a chain happens in the context of a specific block.
|
||||
//! - Functionality is organized into _pallets_.
|
||||
//! - This functionality can change over time as Runtime updates occur.
|
||||
//! - Metadata describes what functionality is available for a given runtime.
|
||||
//!
|
||||
//! ## Interacting with the Polkadot Network
|
||||
//!
|
||||
//! Subxt is built for interacting with Substrate based chains on the Polkadot. The basic steps for using Subxt are:
|
||||
//!
|
||||
//! 0. (Optional) Generate an interface to the chain you wish to interact with. This provides type safe APIs.
|
||||
//! 1. Create/instantiate some configuration for the chain you wish to interact with. Subxt provides a default
|
||||
//! [`crate::config::SubstrateConfig`] which works with most chains, or [`crate::config::PolkadotConfig`] which
|
||||
//! is configured specifically for the Polkadot Relay Chain.
|
||||
//! 2. Create a _client_ for interacting with the chain, which consumes this configuration. typically, you'll create
|
||||
//! an [`crate::client::OnlineClient`] which will connect to the chain. It's also possible to create an
|
||||
//! [`crate::client::OfflineClient`] in the event that you want to avoid any network connection, although in this
|
||||
//! case you'll obviously have much more limited functionality available to you.
|
||||
//! 3. Pick a block to work at. To work at the current block at the time of calling, you'd use
|
||||
//! [`crate::client::OnlineClient::at_current_block()`].
|
||||
//! 4. Do things in the context of this block.
|
||||
//!
|
||||
//! Behind the scenes, Subxt takes are of things like:
|
||||
//! - Downloading the metadata at the given blocks where needed.
|
||||
//! - Ensuring that anything you try to do is actually valid at the given block.
|
||||
//! - Encoding and decoding the various data sent back and forth.
|
||||
//! - Translating older metadatas into a useful format
|
||||
//!
|
||||
//! See
|
||||
#, "/subxt/examples)")]
|
||||
//! for more.
|
||||
+1
-1
@@ -98,7 +98,7 @@ pub trait Config: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
fn set_metadata_for_spec_version(&self, _spec_version: u32, _metadata: ArcMetadata) {}
|
||||
|
||||
/// Return legacy types (ie types to use with Runtimes that return pre-V14 metadata) for a given spec version.
|
||||
/// If this returns `None`, [`subxt`] will return an error if type definitions are needed to access some older
|
||||
/// If this returns `None`, [`subxt`](crate) will return an error if type definitions are needed to access some older
|
||||
/// block.
|
||||
///
|
||||
/// This doesn't need to live for long; it will be used to translate any older metadata returned from the node
|
||||
|
||||
+5
-5
@@ -160,7 +160,7 @@ impl<T: Config> Events<T> {
|
||||
|
||||
/// Iterate through the events, Decoding and returning any that match the given type.
|
||||
///
|
||||
/// This is a convenience function for calling [`Self::iter`] and then [`Event::decode_call_data_fields_as`]
|
||||
/// This is a convenience function for calling [`Events::iter`] and then [`Event::decode_fields_as`]
|
||||
/// on each event that we iterate over, filtering those that don't match.
|
||||
pub fn find<E: DecodeAsEvent>(&self) -> impl Iterator<Item = Result<E, EventsError>> {
|
||||
self.iter()
|
||||
@@ -381,9 +381,9 @@ impl<'events, T: Config> Event<'events, T> {
|
||||
Ok(decoded)
|
||||
}
|
||||
|
||||
/// Decode the event call data fields into some type which implements [`DecodeAsEvent`].
|
||||
/// Decode the event fields into some type which implements [`DecodeAsEvent`].
|
||||
///
|
||||
/// Event types generated via the [`crate::subxt!`] macro implement this.
|
||||
/// Event types generated via the [`macro@crate::subxt`] macro implement this.
|
||||
pub fn decode_fields_as<E: DecodeAsEvent>(&self) -> Option<Result<E, EventsError>> {
|
||||
if self.is::<E>() {
|
||||
Some(self.decode_fields_unchecked_as::<E>())
|
||||
@@ -392,12 +392,12 @@ impl<'events, T: Config> Event<'events, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decode the event call data fields into some type which implements [`DecodeAsFields`].
|
||||
/// Decode the event fields into some type which implements [`DecodeAsFields`].
|
||||
///
|
||||
/// This ignores the pallet and event name information, so you should check those via [`Self::pallet_name()`]
|
||||
/// and [`Self::event_name()`] to confirm that this event is the one you are intending to decode.
|
||||
///
|
||||
/// Prefer to use [`Self::decode_call_data_fields_as`] where possible.
|
||||
/// Prefer to use [`Self::decode_fields_as`] where possible.
|
||||
pub fn decode_fields_unchecked_as<E: DecodeAsFields>(&self) -> Result<E, EventsError> {
|
||||
let bytes = &mut self.field_bytes();
|
||||
let event_metadata = self.event_metadata();
|
||||
|
||||
@@ -242,7 +242,7 @@ where
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This is a subset of [`Self::call_bytes`] that does not include the
|
||||
/// This is a subset of [`Self::call_data_bytes`] that does not include the
|
||||
/// first two bytes that denote the pallet index and the variant index.
|
||||
pub fn call_data_field_bytes(&self) -> &[u8] {
|
||||
&self.bytes()[self.info.call_data_args_range()]
|
||||
@@ -314,7 +314,7 @@ where
|
||||
|
||||
/// Decode the extrinsic call data fields into some type which implements [`DecodeAsExtrinsic`].
|
||||
///
|
||||
/// Extrinsic types generated via the [`crate::subxt!`] macro implement this.
|
||||
/// Extrinsic types generated via the [`macro@crate::subxt`] macro implement this.
|
||||
pub fn decode_call_data_fields_as<E: DecodeAsExtrinsic>(
|
||||
&self,
|
||||
) -> Option<Result<E, ExtrinsicError>> {
|
||||
|
||||
+14
-2
@@ -2,13 +2,24 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this:
|
||||
//! Subxt is a library for interacting with Substrate based nodes. Here's what it looks like:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../examples/submit_transaction.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt.
|
||||
//! Take a look at
|
||||
#, "/subxt/examples)")]
|
||||
//! to get off to a quick start, or check out [the book](book) for a more in depth introduction to Subxt.
|
||||
//!
|
||||
//! In addition to the single-file examples above, we have a few self contained project examples to show off specific
|
||||
//! use cases:
|
||||
#, "/examples/parachain-example)")]
|
||||
//! is an example which uses Zombienet to spawn a parachain locally, and then connects to it using Subxt.
|
||||
#, "/examples/wasm-example)")]
|
||||
//! is an example of writing a Rust web application which uses Subxt to interact with a chain entirely in the browser.
|
||||
#, "/examples/ffi-example)")]
|
||||
//! shows off how Subxt can be called via FFI from Node.JS and Python.
|
||||
|
||||
#[cfg(any(
|
||||
all(feature = "web", feature = "native"),
|
||||
@@ -36,6 +47,7 @@ compile_error!("subxt: exactly one of the 'web' and 'native' features should be
|
||||
pub extern crate alloc;
|
||||
|
||||
pub mod backend;
|
||||
pub mod book;
|
||||
pub mod client;
|
||||
pub mod config;
|
||||
pub mod constants;
|
||||
|
||||
@@ -34,7 +34,7 @@ use std::borrow::Cow;
|
||||
pub use default_params::DefaultParams;
|
||||
pub use payload::{DynamicPayload, Payload, StaticPayload, dynamic};
|
||||
pub use signer::Signer;
|
||||
pub use transaction_progress::{TransactionProgress, TransactionStatus};
|
||||
pub use transaction_progress::{TransactionInBlock, TransactionProgress, TransactionStatus};
|
||||
pub use validation_result::{
|
||||
TransactionInvalid, TransactionUnknown, TransactionValid, ValidationResult,
|
||||
};
|
||||
@@ -570,10 +570,10 @@ impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>>
|
||||
self.sign_with_account_and_signature(&signer.account_id(), &signature)
|
||||
}
|
||||
|
||||
/// Convert this [`PartialTransaction`] into a [`SubmittableTransaction`], ready to submit.
|
||||
/// Convert this [`SignableTransaction`] into a [`SubmittableTransaction`], ready to submit.
|
||||
/// An address, and something representing a signature that can be SCALE encoded, are both
|
||||
/// needed in order to construct it. If you have a `Signer` to hand, you can use
|
||||
/// [`PartialTransaction::sign()`] instead.
|
||||
/// [`SignableTransaction::sign()`] instead.
|
||||
pub fn sign_with_account_and_signature(
|
||||
&mut self,
|
||||
account_id: &T::AccountId,
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
/// given that we aren't far off having more than 12 transaction extensions already.
|
||||
///
|
||||
/// If you have params which are _not_ a tuple and which you'd like to be instantiated automatically
|
||||
/// when calling [`TxClient::sign_and_submit_default()`] or [`TxClient::sign_and_submit_then_watch_default()`],
|
||||
/// then you'll need to implement this trait for them.
|
||||
/// when calling [`crate::transactions::TransactionsClient::sign_and_submit_default()`] or
|
||||
/// [`crate::transactions::TransactionsClient::sign_and_submit_then_watch_default()`], then you'll
|
||||
/// need to implement this trait for them.
|
||||
pub trait DefaultParams: Sized {
|
||||
/// Instantiate a default instance of the parameters.
|
||||
fn default_params() -> Self;
|
||||
|
||||
@@ -75,26 +75,24 @@ pub struct ValidationDetails<'a> {
|
||||
|
||||
/// A transaction payload containing some generic `CallData`.
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct DefaultPayload<CallData> {
|
||||
pub struct StaticPayload<CallData> {
|
||||
pallet_name: Cow<'static, str>,
|
||||
call_name: Cow<'static, str>,
|
||||
call_data: CallData,
|
||||
validation_hash: Option<[u8; 32]>,
|
||||
}
|
||||
|
||||
/// The payload type used by static codegen.
|
||||
pub type StaticPayload<Calldata> = DefaultPayload<Calldata>;
|
||||
/// The type of a payload typically used for dynamic transaction payloads.
|
||||
pub type DynamicPayload = DefaultPayload<Composite<()>>;
|
||||
pub type DynamicPayload<CallData> = StaticPayload<CallData>;
|
||||
|
||||
impl<CallData> DefaultPayload<CallData> {
|
||||
/// Create a new [`DefaultPayload`].
|
||||
impl<CallData> StaticPayload<CallData> {
|
||||
/// Create a new [`StaticPayload`].
|
||||
pub fn new(
|
||||
pallet_name: impl Into<String>,
|
||||
call_name: impl Into<String>,
|
||||
call_data: CallData,
|
||||
) -> Self {
|
||||
DefaultPayload {
|
||||
StaticPayload {
|
||||
pallet_name: Cow::Owned(pallet_name.into()),
|
||||
call_name: Cow::Owned(call_name.into()),
|
||||
call_data,
|
||||
@@ -102,7 +100,7 @@ impl<CallData> DefaultPayload<CallData> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`DefaultPayload`] using static strings for the pallet and call name.
|
||||
/// Create a new [`StaticPayload`] using static strings for the pallet and call name.
|
||||
/// This is only expected to be used from codegen.
|
||||
#[doc(hidden)]
|
||||
pub fn new_static(
|
||||
@@ -111,7 +109,7 @@ impl<CallData> DefaultPayload<CallData> {
|
||||
call_data: CallData,
|
||||
validation_hash: [u8; 32],
|
||||
) -> Self {
|
||||
DefaultPayload {
|
||||
StaticPayload {
|
||||
pallet_name: Cow::Borrowed(pallet_name),
|
||||
call_name: Cow::Borrowed(call_name),
|
||||
call_data,
|
||||
@@ -143,8 +141,8 @@ impl<CallData> DefaultPayload<CallData> {
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultPayload<Composite<()>> {
|
||||
/// Convert the dynamic `Composite` payload into a [`Value`].
|
||||
impl StaticPayload<Composite<()>> {
|
||||
/// Convert the `Composite` payload into a [`Value`].
|
||||
/// This is useful if you want to use this as an argument for a
|
||||
/// larger dynamic call that wants to use this as a nested call.
|
||||
pub fn into_value(self) -> Value<()> {
|
||||
@@ -160,7 +158,7 @@ impl DefaultPayload<Composite<()>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<CallData: EncodeAsFields> Payload for DefaultPayload<CallData> {
|
||||
impl<CallData: EncodeAsFields> Payload for StaticPayload<CallData> {
|
||||
fn encode_call_data_to(
|
||||
&self,
|
||||
metadata: &Metadata,
|
||||
@@ -202,14 +200,13 @@ impl<CallData: EncodeAsFields> Payload for DefaultPayload<CallData> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a transaction at runtime; essentially an alias to [`DefaultPayload::new()`]
|
||||
/// which provides a [`Composite`] value for the call data.
|
||||
pub fn dynamic(
|
||||
/// Construct a transaction at runtime; essentially an alias to [`DynamicPayload::new()`].
|
||||
pub fn dynamic<CallData>(
|
||||
pallet_name: impl Into<String>,
|
||||
call_name: impl Into<String>,
|
||||
call_data: impl Into<Composite<()>>,
|
||||
) -> DynamicPayload {
|
||||
DefaultPayload::new(pallet_name, call_name, call_data.into())
|
||||
call_data: CallData,
|
||||
) -> DynamicPayload<CallData> {
|
||||
StaticPayload::new(pallet_name, call_name, call_data.into())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -232,7 +229,7 @@ mod tests {
|
||||
("value", scale_value::Value::string("not_a_number")), // String instead of u128
|
||||
]);
|
||||
|
||||
let payload = DefaultPayload::new("Balances", "transfer_allow_death", incompatible_data);
|
||||
let payload = StaticPayload::new("Balances", "transfer_allow_death", incompatible_data);
|
||||
|
||||
let mut out = Vec::new();
|
||||
let result = payload.encode_call_data_to(&metadata, &mut out);
|
||||
@@ -257,7 +254,7 @@ mod tests {
|
||||
("value", scale_value::Value::u128(1000)),
|
||||
]);
|
||||
|
||||
let payload = DefaultPayload::new("Balances", "transfer_allow_death", valid_data);
|
||||
let payload = StaticPayload::new("Balances", "transfer_allow_death", valid_data);
|
||||
|
||||
// This should succeed
|
||||
let mut out = Vec::new();
|
||||
|
||||
@@ -66,7 +66,7 @@ where
|
||||
/// instance when it is, or an error if there was a problem waiting for finalization.
|
||||
///
|
||||
/// **Note:** consumes `self`. If you'd like to perform multiple actions as the state of the
|
||||
/// transaction progresses, use [`TxProgress::next()`] instead.
|
||||
/// transaction progresses, use [`TransactionProgress::next()`] instead.
|
||||
///
|
||||
/// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some
|
||||
/// probability that the transaction will not make it into a block but there is no guarantee
|
||||
@@ -101,7 +101,7 @@ where
|
||||
/// as well as a couple of other details (block hash and extrinsic hash).
|
||||
///
|
||||
/// **Note:** consumes self. If you'd like to perform multiple actions as progress is made,
|
||||
/// use [`TxProgress::next()`] instead.
|
||||
/// use [`TransactionProgress::next()`] instead.
|
||||
///
|
||||
/// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some
|
||||
/// probability that the transaction will not make it into a block but there is no guarantee
|
||||
@@ -199,7 +199,7 @@ pub enum TransactionStatus<'atblock, T: Config, C> {
|
||||
|
||||
impl<'atblock, T: Config, C> TransactionStatus<'atblock, T, C> {
|
||||
/// A convenience method to return the finalized details. Returns
|
||||
/// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`].
|
||||
/// [`None`] if the enum variant is not [`TransactionStatus::InFinalizedBlock`].
|
||||
pub fn as_finalized(&self) -> Option<&TransactionInBlock<'atblock, T, C>> {
|
||||
match self {
|
||||
Self::InFinalizedBlock(val) => Some(val),
|
||||
@@ -208,7 +208,7 @@ impl<'atblock, T: Config, C> TransactionStatus<'atblock, T, C> {
|
||||
}
|
||||
|
||||
/// A convenience method to return the best block details. Returns
|
||||
/// [`None`] if the enum variant is not [`TxStatus::InBestBlock`].
|
||||
/// [`None`] if the enum variant is not [`TransactionStatus::InBestBlock`].
|
||||
pub fn as_in_block(&self) -> Option<&TransactionInBlock<'atblock, T, C>> {
|
||||
match self {
|
||||
Self::InBestBlock(val) => Some(val),
|
||||
@@ -258,7 +258,7 @@ impl<'atblock, T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<'atbloc
|
||||
/// **Note:** If multiple `ExtrinsicFailed` errors are returned (for instance
|
||||
/// because a pallet chooses to emit one as an event, which is considered
|
||||
/// abnormal behaviour), it is not specified which of the errors is returned here.
|
||||
/// You can use [`TxInBlock::fetch_events`] instead if you'd like to
|
||||
/// You can use [`TransactionInBlock::fetch_events`] instead if you'd like to
|
||||
/// work with multiple "error" events.
|
||||
///
|
||||
/// **Note:** This has to download block details from the node and decode events
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::error::ExtrinsicError;
|
||||
use codec::Decode;
|
||||
|
||||
/// The result of performing [`SubmittableTransaction::validate()`].
|
||||
/// The result of performing [`crate::transactions::SubmittableTransaction::validate()`].
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ValidationResult {
|
||||
/// The transaction is valid
|
||||
|
||||
Reference in New Issue
Block a user