├── .github
├── release-drafter.yml
└── workflows
│ ├── check-lables.yml
│ ├── ci.yml
│ └── draft-release.yml
├── .gitignore
├── .taplo.toml
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── about.hbs
├── about.toml
├── api-client
├── Cargo.toml
└── src
│ ├── api
│ ├── api_client.rs
│ ├── error.rs
│ ├── mod.rs
│ ├── rpc_api
│ │ ├── author.rs
│ │ ├── chain.rs
│ │ ├── events.rs
│ │ ├── frame_system.rs
│ │ ├── mod.rs
│ │ ├── pallet_balances.rs
│ │ ├── pallet_transaction_payment.rs
│ │ ├── runtime_update.rs
│ │ └── state.rs
│ └── runtime_api
│ │ ├── account_nonce.rs
│ │ ├── api_core.rs
│ │ ├── authority_discovery.rs
│ │ ├── block_builder.rs
│ │ ├── metadata.rs
│ │ ├── mmr.rs
│ │ ├── mod.rs
│ │ ├── session_keys.rs
│ │ ├── staking.rs
│ │ ├── transaction_payment.rs
│ │ └── transaction_payment_call.rs
│ ├── extrinsic
│ ├── balances.rs
│ ├── contracts.rs
│ ├── mod.rs
│ ├── offline_extrinsic.rs
│ ├── staking.rs
│ └── utility.rs
│ ├── lib.rs
│ └── rpc
│ ├── error.rs
│ ├── helpers.rs
│ ├── jsonrpsee_client
│ ├── mod.rs
│ └── subscription.rs
│ ├── mocks.rs
│ ├── mod.rs
│ ├── tungstenite_client
│ ├── client.rs
│ ├── mod.rs
│ └── subscription.rs
│ └── ws_client
│ ├── client.rs
│ ├── mod.rs
│ └── subscription.rs
├── compose-macros
├── Cargo.toml
├── README.md
└── src
│ ├── lib.rs
│ └── rpc.rs
├── docs
├── README.md
└── overview_code_structure.svg
├── examples
├── async
│ ├── Cargo.toml
│ └── examples
│ │ ├── benchmark_bulk_xt.rs
│ │ ├── check_extrinsic_events.rs
│ │ ├── compose_extrinsic.rs
│ │ ├── custom_nonce.rs
│ │ ├── get_blocks.rs
│ │ ├── get_storage.rs
│ │ ├── minimal_template_runtime.compact.compressed.wasm
│ │ ├── new_json_rpc_api_calls.rs
│ │ ├── print_metadata.rs
│ │ ├── query_runtime_api.rs
│ │ ├── runtime_update_async.rs
│ │ ├── staking_batch_payout_untested.rs
│ │ ├── subscribe_events.rs
│ │ └── sudo.rs
├── sync
│ ├── Cargo.toml
│ └── examples
│ │ ├── minimal_template_runtime.compact.compressed.wasm
│ │ ├── runtime_update_sync.rs
│ │ └── transfer_with_tungstenite_client.rs
└── wasm
│ ├── Cargo.toml
│ └── examples
│ └── wasm_example.rs
├── keystore
├── Cargo.toml
├── README.md
└── src
│ ├── keystore_ext.rs
│ └── lib.rs
├── ksm_metadata_v14.bin
├── license_header_scs.txt
├── node-api
├── Cargo.toml
├── README.md
└── src
│ ├── error
│ ├── dispatch_error.rs
│ └── mod.rs
│ ├── events
│ ├── event_details.rs
│ ├── mod.rs
│ └── raw_event_details.rs
│ ├── lib.rs
│ ├── metadata
│ ├── error.rs
│ ├── from_v14_to_v15.rs
│ ├── metadata_types.rs
│ ├── mod.rs
│ ├── print_metadata.rs
│ └── variant_index.rs
│ ├── storage.rs
│ └── test_utils.rs
├── primitives
├── Cargo.toml
├── README.md
└── src
│ ├── config
│ ├── asset_runtime_config.rs
│ ├── default_runtime_config.rs
│ ├── mod.rs
│ └── rococo_runtime_config.rs
│ ├── extrinsics
│ ├── extrinsic_params.rs
│ ├── extrinsic_params_without_hash_check.rs
│ ├── extrinsic_v4.rs
│ ├── mod.rs
│ └── signer.rs
│ ├── lib.rs
│ ├── rpc_numbers.rs
│ ├── rpc_params.rs
│ └── types.rs
├── rust-toolchain.toml
├── rustfmt.toml
├── test-no-std
├── Cargo.toml
├── README.md
└── src
│ └── main.rs
└── testing
├── async
├── Cargo.toml
└── examples
│ ├── author_tests.rs
│ ├── chain_tests.rs
│ ├── dispatch_errors_tests.rs
│ ├── dump_metadata.rs
│ ├── events_tests.rs
│ ├── frame_system_tests.rs
│ ├── jsonrpsee_tests.rs
│ ├── pallet_balances_tests.rs
│ ├── pallet_transaction_payment_tests.rs
│ ├── runtime_api_tests.rs
│ └── state_tests.rs
└── sync
├── Cargo.toml
└── examples
├── keystore_tests.rs
└── tungstenite_client_test.rs
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: 'v$RESOLVED_VERSION'
2 | tag-template: 'v$RESOLVED_VERSION'
3 | exclude-labels:
4 | - 'E0-silent'
5 | categories:
6 | - title: '⚡ Breaking API changes'
7 | labels:
8 | - 'E2-breaksapi'
9 | - title: ' 🌈 Features'
10 | labels:
11 | - 'F6-optimization'
12 | - 'F8-newfeature'
13 | - 'F7-enhancement'
14 | - title: '🐛 Bug Fixes'
15 | labels:
16 | - 'F1-security'
17 | - 'F2-bug'
18 | - title: ' Miscellaneous '
19 | collapse-after: 5
20 | label:
21 | - 'E1-breaksnothing'
22 | - 'E2-breaksapi'
23 | change-template: '- $TITLE (#$NUMBER) @$AUTHOR '
24 | change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
25 | template: |
26 | ## What's Changed since $PREVIOUS_TAG
27 |
28 | $CHANGES
29 |
--------------------------------------------------------------------------------
/.github/workflows/check-lables.yml:
--------------------------------------------------------------------------------
1 | # File is copy-pasted from Integritee worker:
2 | # https://github.com/integritee-network/worker/blob/1a58d6a625fa76935902f16c798efa453bcef9a4/.github/workflows/label-checker.yml
3 |
4 | name: Check labels
5 | on:
6 | pull_request:
7 | types: [opened, labeled, unlabeled, synchronize, ready_for_review]
8 |
9 | jobs:
10 | check_for_matching_labels:
11 | runs-on: ubuntu-latest
12 | if: github.base_ref == 'master' && github.event.pull_request.draft == false
13 | steps:
14 | - name: E Label check
15 | env:
16 | enforced_labels: "E0-silent,E1-breaksnothing,E2-breaksapi"
17 | run: |
18 | MATCH=$(jq -cn '${{ toJSON(github.event.pull_request.labels.*.name) }} as $USER_LABELS |
19 | ${{ toJSON(env.enforced_labels) }} | split(",") as $LABELS |
20 | $USER_LABELS - ($USER_LABELS - $LABELS)')
21 | if [[ "$MATCH" == '[]' ]]; then
22 | exit 1
23 | fi
24 | - name: F Label check
25 | env:
26 | enforced_labels: "F0-miscellaneous,F1-security,F2-bug,F3-test,F4-documentation,F5-refactor,F6-optimization,F7-enhancement,F8-newfeature,F9-dependencies"
27 | run: |
28 | MATCH=$(jq -cn '${{ toJSON(github.event.pull_request.labels.*.name) }} as $USER_LABELS |
29 | ${{ toJSON(env.enforced_labels) }} | split(",") as $LABELS |
30 | $USER_LABELS - ($USER_LABELS - $LABELS)')
31 | if [[ "$MATCH" == '[]' ]]; then
32 | exit 1
33 | fi
34 |
--------------------------------------------------------------------------------
/.github/workflows/draft-release.yml:
--------------------------------------------------------------------------------
1 | name: Release - Publish Draft
2 |
3 | on:
4 | push:
5 | tags:
6 | # Catches v1.2.3 and v1.2.3-rc1
7 | - v[0-9]+.[0-9]+.[0-9]+*
8 | jobs:
9 | update_release_draft:
10 | permissions:
11 | # write permission is required to create a github release
12 | contents: write
13 | runs-on: ubuntu-latest
14 | steps:
15 | # Drafts your next Release notes as Pull Requests are merged into "master"
16 | - uses: release-drafter/release-drafter@v5
17 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
18 | with:
19 | tag: ${{ github.ref_name }}
20 | name: ${{ github.ref_name }}
21 | env:
22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | **/target/
4 |
5 |
6 | # These are backup files generated by rustfmt
7 | **/*.rs.bk
8 |
9 |
10 | #Added by cargo
11 | #
12 | #already existing elements are commented out
13 |
14 | # IntelliJ
15 | **/.idea/
16 | *.iml
17 |
18 |
19 | # VScode
20 | **/.vscode
21 |
--------------------------------------------------------------------------------
/.taplo.toml:
--------------------------------------------------------------------------------
1 | include = ["**/Cargo.toml"]
2 |
3 | [formatting]
4 | array_auto_expand = false
5 | array_auto_collapse = false
6 | indent_string = " "
7 | inline_table_expand = false
8 |
9 | [[rule]]
10 | include = ["**/Cargo.toml"]
11 | keys = ["dependencies", "target", "patch"]
12 |
13 | [rule.formatting]
14 | reorder_keys = true
15 |
16 | [[rule]]
17 | include = ["**/Cargo.toml"]
18 | keys = ["features"]
19 |
20 | [rule.formatting]
21 | array_auto_expand = true
22 |
23 | [[rule]]
24 | keys = ["package"]
25 | formatting.reorder_keys = false
--------------------------------------------------------------------------------
/about.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
36 |
37 |
38 |
39 |
40 |
41 |
Third Party Licenses
42 |
This page lists the licenses of the projects used in 'Substrate Api Client' repository.
43 |
44 |
45 | Overview of licenses:
46 |
47 | {{#each overview}}
48 | - {{name}} ({{count}})
49 | {{/each}}
50 |
51 |
52 | All license text:
53 |
54 | {{#each licenses}}
55 | -
56 |
{{name}}
57 | Used by:
58 |
63 | {{text}}
64 |
65 | {{/each}}
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/about.toml:
--------------------------------------------------------------------------------
1 | accepted = [
2 | "Apache-2.0",
3 | "MIT",
4 | "Apache-2.0 WITH LLVM-exception",
5 | "BSD-2-Clause",
6 | "CC0-1.0",
7 | "BSD-3-Clause",
8 | "CDLA-Permissive-2.0",
9 | "ISC",
10 | "OpenSSL",
11 | "Unicode-DFS-2016",
12 | "Unicode-3.0",
13 | "NOASSERTION",
14 | "Zlib",
15 | "GPL-3.0",
16 | "GPL-3.0 WITH Classpath-exception-2.0"
17 | ]
18 | ignore-dev-dependencies = true
19 | ignore-build-dependencies = true
20 | workarounds = [
21 | "ring",
22 | ]
23 |
--------------------------------------------------------------------------------
/api-client/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "substrate-api-client"
3 | version = "1.18.0"
4 | authors = ["Supercomputing Systems AG "]
5 | license = "Apache-2.0"
6 | edition = "2021"
7 | repository = "https://github.com/scs/substrate-api-client"
8 | description = "Json-rpc client with helper functions compatible with any Substrate node"
9 | readme = "../README.md"
10 | keywords = ["json", "rpc", "polkadot", "api", "blockchain"]
11 | categories = ["no-std", "wasm"]
12 |
13 |
14 | [dependencies]
15 | # crates.io no_std
16 | async-trait = { workspace = true }
17 | codec = { workspace = true }
18 | derive_more = { workspace = true }
19 | frame-metadata = { workspace = true }
20 | futures-util = { workspace = true }
21 | hex = { workspace = true }
22 | log = { workspace = true }
23 | maybe-async = { workspace = true }
24 | serde = { workspace = true }
25 | serde_json = { workspace = true }
26 |
27 |
28 | # crates.io std only
29 | url = { workspace = true, optional = true }
30 |
31 | # websocket dependent features
32 | jsonrpsee = { workspace = true, optional = true, features = ["async-client", "client-ws-transport-tls", "jsonrpsee-types"] }
33 | tungstenite = { workspace = true, optional = true, features = ["native-tls", "url"] }
34 | ws = { workspace = true, optional = true, features = ["ssl"] }
35 |
36 | # Substrate no_std dependencies
37 | sp-core = { workspace = true, features = ["full_crypto", "serde"] }
38 | sp-crypto-hashing = { workspace = true }
39 | sp-inherents = { workspace = true }
40 | sp-runtime = { workspace = true, features = ["serde"] }
41 | sp-runtime-interface = { workspace = true }
42 | sp-storage = { workspace = true, features = ["serde"] }
43 | sp-version = { workspace = true, features = ["serde"] }
44 |
45 | # substrate std / wasm only
46 | frame-support = { workspace = true, optional = true }
47 |
48 | # local deps
49 | ac-compose-macros = { workspace = true }
50 | ac-node-api = { workspace = true }
51 | ac-primitives = { workspace = true }
52 |
53 |
54 | [dev-dependencies]
55 | ac-node-api = { workspace = true, features = ["mocks"] }
56 | rococo-runtime = { workspace = true }
57 | scale-info = { workspace = true, features = ["derive"] }
58 | test-case = { workspace = true }
59 |
60 | [features]
61 | default = ["std", "jsonrpsee-client"]
62 | # To support `no_std` builds in non-32 bit environments.
63 | disable_target_static_assertions = [
64 | "sp-runtime-interface/disable_target_static_assertions",
65 | ]
66 |
67 | # If this is active all the code compiles in synchronous mode. If not selected, code will compile to async mode.
68 | sync-api = ["ac-compose-macros/sync-api", "maybe-async/is_sync"]
69 |
70 | # Use the `jsonrpsee` crate for websocket communication. Does only provide async support and needs a tokio runtime.
71 | # Provides convenience functions such as subscription callbacks.
72 | # Most examples use the `jsonrpsee` feature and can be used for reference.
73 | jsonrpsee-client = ["std", "dep:jsonrpsee"]
74 |
75 | # Use the `tungstenite` crate for websocket communication. No async support but has some reconnection capabilities.
76 | # See the example `transfer_with_tungstenite_client` on how to use it.
77 | tungstenite-client = ["std", "tungstenite", "sync-api"]
78 |
79 | # Use the `ws` crate for websocket communication. No async support.
80 | # Establishes a new connection for each request and therefore is limited in terms of performance.
81 | # See the example `transfer_with_ws_client` on how to use it.
82 | ws-client = ["std", "ws", "sync-api"]
83 |
84 | # Enables functionality that helps to create extrinsics for `pallet-staking`.
85 | # See the `StakingExtrinsics` trait and the `staking_batch_payout` example to get an understanding
86 | # of the functionality this feature provides
87 | staking-xt = ["std", "ac-primitives/staking-xt"]
88 |
89 | # Enables functionality that helps to create extrinsics for `pallet-contracts`.
90 | # See the `ContractsExtrinsics` trait and the `contract_instantiate_with_code` example to get an understanding
91 | # of the functionality this feature provides.
92 | contracts-xt = ["std", "ac-primitives/contracts-xt"]
93 |
94 | # Enables all std features of dependencies in case of std build.
95 | std = [
96 | # crates.io no_std
97 | "codec/std",
98 | "frame-metadata/std",
99 | "hex/std",
100 | "log/std",
101 | "serde/std",
102 | "serde_json/std",
103 | "futures-util/std",
104 | # crates.io std only
105 | "url",
106 | # substrate no_std
107 | "sp-core/std",
108 | "sp-runtime/std",
109 | "sp-runtime-interface/std",
110 | "sp-storage/std",
111 | "sp-version/std",
112 | # substrate std
113 | "frame-support",
114 | # local deps
115 | "ac-compose-macros/std",
116 | "ac-node-api/std",
117 | "ac-primitives/std",
118 | ]
119 |
--------------------------------------------------------------------------------
/api-client/src/api/error.rs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2019 Supercomputing Systems AG
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 | */
17 |
18 | use crate::{api::UnexpectedTxStatus, rpc::Error as RpcClientError, ExtrinsicReport};
19 | use ac_node_api::{
20 | error::DispatchError,
21 | metadata::{MetadataConversionError, MetadataError},
22 | };
23 | use alloc::{boxed::Box, vec::Vec};
24 | use codec::{Decode, Encode};
25 | use core::error::Error as ErrorT;
26 |
27 | pub type Result = core::result::Result;
28 |
29 | #[derive(Debug, derive_more::From)]
30 | pub enum Error {
31 | /// Could not fetch the genesis hash from node.
32 | FetchGenesisHash,
33 | /// Expected a signer, but none is assigned.
34 | NoSigner,
35 | /// Rpc Client Error.
36 | RpcClient(RpcClientError),
37 | /// Metadata Error.
38 | Metadata(MetadataError),
39 | /// Invalid Metadata Error.
40 | InvalidMetadata(MetadataConversionError),
41 | /// Node Api Error.
42 | NodeApi(ac_node_api::error::Error),
43 | /// Encode / Decode Error.
44 | Codec(codec::Error),
45 | /// Could not convert NumberOrHex with try_from.
46 | TryFromIntError,
47 | /// Extrinsic failed onchain. Contains the encoded report and the associated dispatch error.
48 | FailedExtrinsic(FailedExtrinsicError),
49 | /// Encountered unexpected tx status during watch process.
50 | UnexpectedTxStatus(UnexpectedTxStatus),
51 | /// Could not send update because the Stream has been closed unexpectedly.
52 | NoStream,
53 | /// Could not find the expected extrinsic.
54 | ExtrinsicNotFound,
55 | /// Could not find the expected block hash.
56 | BlockHashNotFound,
57 | /// Could not find the expected block.
58 | BlockNotFound,
59 | /// Operation needs events but events are missing.
60 | EventsMissing,
61 | /// Operation wants to add events but they are already present.
62 | EventsAlreadyPresent,
63 | /// Any custom Error.
64 | Other(Box),
65 | }
66 |
67 | /// Encountered unexpected tx status during watch process or the extrinsic failed.
68 | #[derive(Debug)]
69 | pub struct FailedExtrinsicError {
70 | dispatch_error: DispatchError,
71 | encoded_report: Vec,
72 | }
73 |
74 | impl FailedExtrinsicError {
75 | pub fn new(dispatch_error: DispatchError, encoded_report: Vec) -> Self {
76 | Self { dispatch_error, encoded_report }
77 | }
78 |
79 | pub fn dispatch_error(&self) -> &DispatchError {
80 | &self.dispatch_error
81 | }
82 |
83 | pub fn get_report(&self) -> Result> {
84 | let report = Decode::decode(&mut self.encoded_report.as_slice())?;
85 | Ok(report)
86 | }
87 |
88 | pub fn encoded_report(&self) -> &[u8] {
89 | &self.encoded_report
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/api-client/src/api/rpc_api/mod.rs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2019 Supercomputing Systems AG
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 |
14 | pub use self::{
15 | author::*, chain::*, events::*, frame_system::*, pallet_balances::*,
16 | pallet_transaction_payment::*, runtime_update::*, state::*,
17 | };
18 |
19 | pub mod author;
20 | pub mod chain;
21 | pub mod events;
22 | pub mod frame_system;
23 | pub mod pallet_balances;
24 | pub mod pallet_transaction_payment;
25 | pub mod runtime_update;
26 | pub mod state;
27 |
--------------------------------------------------------------------------------
/api-client/src/api/rpc_api/pallet_balances.rs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2019 Supercomputing Systems AG
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | use crate::{
14 | api::{Api, GetStorage, Result},
15 | rpc::Request,
16 | };
17 | use ac_primitives::config::Config;
18 | #[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
19 | use alloc::boxed::Box;
20 |
21 | /// Interface to common calls of the substrate balances pallet.
22 | #[maybe_async::maybe_async(?Send)]
23 | pub trait GetBalance {
24 | type Balance;
25 |
26 | async fn get_existential_deposit(&self) -> Result;
27 | }
28 |
29 | #[maybe_async::maybe_async(?Send)]
30 | impl GetBalance for Api
31 | where
32 | T: Config,
33 | Client: Request,
34 | {
35 | type Balance = T::Balance;
36 |
37 | async fn get_existential_deposit(&self) -> Result {
38 | self.get_constant("Balances", "ExistentialDeposit").await
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/api-client/src/api/rpc_api/pallet_transaction_payment.rs:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2019 Supercomputing Systems AG
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 | http://www.apache.org/licenses/LICENSE-2.0
7 | Unless required by applicable law or agreed to in writing, software
8 | distributed under the License is distributed on an "AS IS" BASIS,
9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | See the License for the specific language governing permissions and
11 | limitations under the License.
12 | */
13 | use crate::{
14 | api::{Api, Error, Result},
15 | rpc::Request,
16 | };
17 | use ac_compose_macros::rpc_params;
18 | use ac_primitives::{config::Config, FeeDetails, InclusionFee, NumberOrHex, RuntimeDispatchInfo};
19 | #[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
20 | use alloc::boxed::Box;
21 | use core::str::FromStr;
22 | use sp_core::Bytes;
23 | /// Interface to common calls of the substrate transaction payment pallet.
24 | #[maybe_async::maybe_async(?Send)]
25 | pub trait GetTransactionPayment {
26 | type Hash;
27 | type Balance;
28 |
29 | async fn get_fee_details(
30 | &self,
31 | encoded_extrinsic: &Bytes,
32 | at_block: Option,
33 | ) -> Result