CLI Tool Explore Command: Runtime APIs, Events, Colorized outputs, scale-typegen integration (#1290)

* restructure cli commands

* config: Add `SkipCheckIfFeeless` signed extension (#1264)

* config: Add `SkipCheckIfFeeless` signed extension

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Add extra extension to the default params

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* examples: Adjust signed extension example

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Extend SkipCheckIfFeeless with inner signed extension

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Configure SkipCheck with inner signed extension params

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Implement Deafult for SkipCheckIfFeelessParams with Option

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* examples: Fix example with proper extension

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Extend <T as Config>::AssetId with EncodeAsType and Clone

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Add SkipCheck with AssetTx

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Encode as type from metadata the inner signed extensions

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Adjust examples

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* blocks: Use `SkipCheckIfFeeless` for decoding the tip of extensions

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Decode `SkipCheckIfFeeless` with `Self`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* tests: Adjust testing

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Descriptive errors for building `SkipCheckIfFeeless`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Add docs for extra error types

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Add extra derives to signed extensions

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* config: Use `Default::default` to simplify type init

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Replace removed lint (#1270)

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Add support for multi-chain usecase (#1238)

* lightclient: Make `smoldot::chainID` part of the RPC requests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Make `BackgroundTask` generic over `PlatformRef` and chain

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Construct from raw smoldot and target different chains

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* testing: Update cargo lock for wasm tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reuse `new_from_client` method and removed unused imports

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reexport smoldot client and RPC objects used in pub
interface

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Adjust `new_from_client` interface

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Extend background to poll over multiple RPC objects

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Build light client from raw and target different chains

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Add demo chain specs

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Move artifacts to dedicated folder

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Use SelectAll to drive all streams

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Fetch initial data from the target chain

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reexport other smoldot objects

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Target chain with potentially different config

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt/rpc: Log chainID for debugging

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt/examples: Add smoldot client with parachain example

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Propagate chain ID together with rpc responses object

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Multiplex responses by request ID and chain ID

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Add raw light client builder

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Add cargo feature flag for parachains example

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Derive default for internal structure

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Guard reexports by std feature flag

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update subxt/src/client/light_client/mod.rs

Co-authored-by: James Wilson <james@jsdw.me>

* lightclient: Update the builder pattern and chain targetting

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Fix documentation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Provide more insightful docs wrt native/wasm panics

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* examples: Adjust comment location

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Refactor UniqueChainId into the background task

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update lightclient/src/background.rs

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* Update subxt/src/client/light_client/builder.rs

Co-authored-by: James Wilson <james@jsdw.me>

* lightclient: Update docs wrt panics

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Update docs wrt to smoldot instance -> client

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Use IntoIter instead of Iterator

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Adjsut docs wrt [`Self::new_from_client`]

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Remove RawRpc from LightClient in favor of chainID

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reexport everything under smoldot module

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Use stateRootHash instead of genesis.raw

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: James Wilson <james@jsdw.me>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>

* Bump futures from 0.3.28 to 0.3.29 (#1272)

Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.28 to 0.3.29.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.28...0.3.29)

---
updated-dependencies:
- dependency-name: futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump zeroize from 1.6.0 to 1.7.0 (#1274)

Bumps [zeroize](https://github.com/RustCrypto/utils) from 1.6.0 to 1.7.0.
- [Commits](https://github.com/RustCrypto/utils/commits)

---
updated-dependencies:
- dependency-name: zeroize
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump tracing-subscriber from 0.3.17 to 0.3.18 (#1275)

Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.17...tracing-subscriber-0.3.18)

---
updated-dependencies:
- dependency-name: tracing-subscriber
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump tracing-subscriber from 0.3.17 to 0.3.18 (#1275)

Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.17...tracing-subscriber-0.3.18)

---
updated-dependencies:
- dependency-name: tracing-subscriber
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump getrandom from 0.2.10 to 0.2.11 (#1273)

Bumps [getrandom](https://github.com/rust-random/getrandom) from 0.2.10 to 0.2.11.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11)

---
updated-dependencies:
- dependency-name: getrandom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* impl RpcClientT for Arc<T> and Box<T> (#1277)

* impl RpcClientT for Arc<WsClient>

* fix grumbles: impl for Box<T> and Arc<T>

* grumbles: move RpcClientT impls

* first iteration of using scale_typegen

* introduce indoc for formatting

* calls, constants and home are cleaner now

* added event subcommand

* show runtime apis working

* add better code formatting

* fix style

* adjust tests, use owo_colorize to not add extra dependency

* fmt

* adjust docs

* move scale-typegen-description dependency to workspace

* improve `substrate-compat` (#1265)

* improve `substrate-compat`

* From => Into

---------

Co-authored-by: James Wilson <james@jsdw.me>

* Bump proc-macro2 from 1.0.69 to 1.0.70 (#1292)

Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.69 to 1.0.70.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.69...1.0.70)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump serde from 1.0.192 to 1.0.193 (#1291)

Bumps [serde](https://github.com/serde-rs/serde) from 1.0.192 to 1.0.193.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.192...v1.0.193)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* lightclient: Fix wasm socket closure called after being dropped (#1289)

* lightclient: Close wasm socket while dropping from connecting state

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Construct one time only closures

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* testing: Enable console logs for lightclient WASM testing

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Separate wakes and check connectivity on poll_read

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket depending on internal state

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert "lightclient: Separate wakes and check connectivity on poll_read"

This reverts commit 866094001d4c0b119a80ed681a74b323f74eae1b.

* lightclient: Return pending if socket is opening from poll_read

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket on `poll_close`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Reset closures on Drop to avoid recursive invokation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Close the socket if not already closing

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* workflows: Install rustup component for building substrate (#1295)

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Command to fetch chainSpec and optimise its size (#1278)

* cli: Add chainSpec command

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli/chainSpec: Move to dedicated module

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Compute the state root hash

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Remove code substitutes

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Update polkadot.json

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* scripts: Generate the chain spec

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Remove testing artifacts

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Fix clippy

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Apply rustfmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Introduce feature flag for smoldot dependency

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cli: Rename chain-spec to chain-spec-pruning

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* scripts: Update chain-spec command

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* update to new scale-typegen interfaces

* use released version of scale-typegen

* Merge branch 'master' into tadeohepperle/cli-support-runtime-apis

* remove unused debug file

* resolve merge errors

* adjustments

* constants file adjustment

* method renaming

* fix issue with encoding runtime api params

* Add logging to submit_transaction and unstable driver, and ensure unpin evs complete

* panic if None returned from subscription too, also with stats

* change panic to Err just to be on the safe side

* clippy

* make long tests run only after clippy + fmt pass

* megre in light client test change pr

* chore(subxt/src): typo fix (#1370)

* rpcmethods

* followstr

* mod and else

* Weekly Cronjob fetching artifacts and generating polkadot.rs file. (#1352)

* github CI action cronjob

* add commit message

* fix the CI yml files

* binary crate for CI script with substrate-runner

* update the CI script

* correct the artifacts script

* remove bash script

* lightclient(fix): Ensure lightclient chainSpec is at least one block old (#1372)

* testing(fix): Ensure lightclient chainSpec is at least one block old

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert "testing(fix): Ensure lightclient chainSpec is at least one block old"

This reverts commit 0eafcb2ca59d1f1cd2cef86b770f5a0401cce59f.

* lightclient(fix): Ensure lightclient chainSpec is at least one block old

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Link smoldot issue

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Use tokio under lightclient feature flag

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Do not sleep on errors to fetch the chainSpec

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* artifacts: Remove test file

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* lightclient: Subscribe to two finalized blocks

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Revert cargo toml

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* ci: Reduce the light client timeout to 15 minutes (#1373)

* ci: Reduce the light client timpeut to 15 seconds

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* ci: Use ubuntu-latest for light-client tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* actually only wait for machete+fmt, clippy can be much slower

* update CI file from Alex PR

* resolve clippy err

* Try a few RPC nodes in case one of them is not working

* fix submit_transaction debug logging of message

* Improve Signed Extension and Block Decoding Examples/Book (#1357)

* asset hub example and book adjustment

* formatting

* recursive derives

* polkadot monitor example and book adjustments

* formatting

* adjust docs and examples, add dynamic example

* james suggestions

* fmt

* chore(subxt/src): typo fix (#1370)

* rpcmethods

* followstr

* mod and else

* Weekly Cronjob fetching artifacts and generating polkadot.rs file. (#1352)

* github CI action cronjob

* add commit message

* fix the CI yml files

* binary crate for CI script with substrate-runner

* update the CI script

* correct the artifacts script

* remove bash script

---------

Co-authored-by: James Wilson <james@jsdw.me>
Co-authored-by: Pan chao <152830401+Pan-chao@users.noreply.github.com>

* fix formatting of returned sections

* make storage use execute flag as well

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
Co-authored-by: James Wilson <james@jsdw.me>
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: yjh <yjh465402634@gmail.com>
Co-authored-by: Pan chao <152830401+Pan-chao@users.noreply.github.com>
This commit is contained in:
Tadeo Hepperle
2024-01-19 17:57:16 +01:00
committed by GitHub
parent 0f48d54209
commit 05ced83f74
15 changed files with 1345 additions and 1135 deletions
@@ -0,0 +1,203 @@
use crate::utils::{
create_client, fields_composite_example, fields_description, first_paragraph_of_docs,
parse_string_into_scale_value, FileOrUrl, Indent, SyntaxHighlight,
};
use color_eyre::{
eyre::{bail, eyre},
owo_colors::OwoColorize,
};
use indoc::{formatdoc, writedoc};
use scale_typegen_description::type_description;
use scale_value::Value;
use subxt::{
ext::{scale_decode::DecodeAsType, scale_encode::EncodeAsType},
Metadata,
};
use subxt_metadata::RuntimeApiMetadata;
/// Runs for a specified runtime API trait.
/// Cases to consider:
/// ```norun
/// method is:
/// None => Show pallet docs + available methods
/// Some (invalid) => Show Error + available methods
/// Some (valid) => Show method docs + output type description
/// exectute is:
/// false => Show input type description + Example Value
/// true => validate (trailing args + build node connection)
/// validation is:
/// Err => Show Error
/// Ok => Make a runtime api call witht the provided args.
/// response is:
/// Err => Show Error
/// Ok => Show the result
/// ```
pub async fn run<'a>(
method: Option<String>,
execute: bool,
trailing_args: Vec<String>,
runtime_api_metadata: RuntimeApiMetadata<'a>,
metadata: &'a Metadata,
file_or_url: FileOrUrl,
output: &mut impl std::io::Write,
) -> color_eyre::Result<()> {
let api_name = runtime_api_metadata.name();
let usage = || {
let methods = methods_to_string(&runtime_api_metadata);
formatdoc! {"
Usage:
subxt explore api {api_name} <METHOD>
explore a specific runtime api method
{methods}
"}
};
// If method is None: Show pallet docs + available methods
let Some(method_name) = method else {
let doc_string = first_paragraph_of_docs(runtime_api_metadata.docs()).indent(4);
if !doc_string.is_empty() {
writedoc! {output, "
Description:
{doc_string}
"}?;
}
writeln!(output, "{}", usage())?;
return Ok(());
};
// If method is invalid: Show Error + available methods
let Some(method) = runtime_api_metadata
.methods()
.find(|e| e.name().eq_ignore_ascii_case(&method_name))
else {
return Err(eyre!(
"\"{method_name}\" method not found for \"{method_name}\" runtime api!\n\n{}",
usage()
));
};
// redeclare to not use the wrong capitalization of the input from here on:
let method_name = method.name();
// Method is valid. Show method docs + output type description
let doc_string = first_paragraph_of_docs(method.docs()).indent(4);
if !doc_string.is_empty() {
writedoc! {output, "
Description:
{doc_string}
"}?;
}
let input_value_placeholder = "<INPUT_VALUE>".blue();
// Output type description
let input_values = || {
if method.inputs().len() == 0 {
return format!("The method does not require an {input_value_placeholder}");
}
let fields: Vec<(Option<&str>, u32)> = method
.inputs()
.map(|f| (Some(f.name.as_str()), f.ty))
.collect();
let fields_description =
fields_description(&fields, method.name(), metadata.types()).indent(4);
let fields_example =
fields_composite_example(method.inputs().map(|e| e.ty), metadata.types())
.indent(4)
.highlight();
formatdoc! {"
The method expects an {input_value_placeholder} with this shape:
{fields_description}
For example you could provide this {input_value_placeholder}:
{fields_example}"}
};
let execute_usage = || {
let output = type_description(method.output_ty(), metadata.types(), true)
.expect("No Type Description")
.indent(4)
.highlight();
let input = input_values();
formatdoc! {"
Usage:
subxt explore api {api_name} {method_name} --execute {input_value_placeholder}
make a runtime api request
The Output of this method has the following shape:
{output}
{input}"}
};
writeln!(output, "{}", execute_usage())?;
if !execute {
return Ok(());
}
if trailing_args.len() != method.inputs().len() {
bail!("The number of trailing arguments you provided after the `execute` flag does not match the expected number of inputs!\n{}", execute_usage());
}
// encode each provided input as bytes of the correct type:
let args_data: Vec<Value> = method
.inputs()
.zip(trailing_args.iter())
.map(|(ty, arg)| {
let value = parse_string_into_scale_value(arg)?;
let value_str = value.indent(4);
// convert to bytes:
writedoc! {output, "
You submitted the following {input_value_placeholder}:
{value_str}
"}?;
// encode, then decode. This ensures that the scale value is of the correct shape for the param:
let bytes = value.encode_as_type(ty.ty, metadata.types())?;
let value = Value::decode_as_type(&mut &bytes[..], ty.ty, metadata.types())?
.map_context(|_| ());
Ok(value)
})
.collect::<color_eyre::Result<Vec<Value>>>()?;
let method_call = subxt::dynamic::runtime_api_call(api_name, method.name(), args_data);
let client = create_client(&file_or_url).await?;
let output_value = client
.runtime_api()
.at_latest()
.await?
.call(method_call)
.await?;
let output_value = output_value.to_value()?.to_string().highlight();
writedoc! {output, "
Returned value:
{output_value}
"}?;
Ok(())
}
fn methods_to_string(runtime_api_metadata: &RuntimeApiMetadata<'_>) -> String {
let api_name = runtime_api_metadata.name();
if runtime_api_metadata.methods().len() == 0 {
return format!("No <METHOD>'s available for the \"{api_name}\" runtime api.");
}
let mut output = format!("Available <METHOD>'s available for the \"{api_name}\" runtime api:");
let mut strings: Vec<_> = runtime_api_metadata.methods().map(|e| e.name()).collect();
strings.sort();
for variant in strings {
output.push_str("\n ");
output.push_str(variant);
}
output
}