-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V15 Metadata: Support accessing custom types #1106
Changes from all commits
09a045f
e2af2cb
72ad54b
8a9e76a
50da61c
e8f2140
00cbee4
f286b26
2f83d36
57be757
4a9000a
922fee2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,54 @@ | ||||||
// Copyright 2019-2023 Parity Technologies (UK) Ltd. | ||||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0. | ||||||
// see LICENSE for license details. | ||||||
|
||||||
//! # Custom Values | ||||||
//! | ||||||
//! Substrate-based chains can expose custom values in their metadata. | ||||||
//! Each of these values: | ||||||
//! | ||||||
//! - can be accessed by a unique __name__. | ||||||
//! - refers to a concrete __type__ stored in the metadata. | ||||||
//! - contains a scale encoded __value__ of that type. | ||||||
//! | ||||||
//! ## Getting a custom value | ||||||
//! | ||||||
//! Custom values can be accessed via a [`CustomValuesClient`](crate::custom_values::CustomValuesClient). | ||||||
//! The client exposes an `at` function by which a custom value can be fetched, given an address to this custom value. | ||||||
//! An address can be as simple as the aforementioned __name__ as a [str]. This will return a dynamic value, that you can manually decode into the type you want. | ||||||
//! Suppose, the custom types contain a value of type `Foo` under the name `"foo"` you can access it like in this example: | ||||||
//! | ||||||
//! ```rust,ignore | ||||||
//! use subxt::{OnlineClient, PolkadotConfig, ext::{codec::Decode, scale_decode::DecodeAsType}}; | ||||||
//! | ||||||
//! #[derive(Decode, DecodeAsType, Debug)] | ||||||
//! struct Foo { | ||||||
//! n: u8, | ||||||
//! b: bool, | ||||||
//! } | ||||||
//! | ||||||
//! let api = OnlineClient::<PolkadotConfig>::new().await?; | ||||||
//! let custom_value_client = api.custom_values(); | ||||||
//! let foo_dynamic = custom_value_client.at("foo")?; | ||||||
//! let foo: Foo = foo_dynamic.as_type()?; | ||||||
//! | ||||||
//! ``` | ||||||
//! | ||||||
//! Alternatively we also provide a statically generated api for custom values: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the logic for this is a followup PR, but as long as we don't do another release before the static stuff merges too then it's ok to leave the docs here :) |
||||||
//! | ||||||
//! ```rust,ignore | ||||||
//! #[subxt::subxt(runtime_metadata_path = "some_metadata.scale")] | ||||||
//! pub mod interface {} | ||||||
//! | ||||||
//! let static_address = interface::custom().foo(); | ||||||
//! | ||||||
//! let api = OnlineClient::<PolkadotConfig>::new().await?; | ||||||
//! let custom_value_client = api.custom_values(); | ||||||
//! | ||||||
//! // Now the `at()` function already decodes the value into the Foo type: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
//! let foo = custom_value_client.at(&static_address)?; | ||||||
//! ``` | ||||||
//! | ||||||
//! Note: Names of custom values are converted to __snake_case__ to produce a valid function name during code generation. | ||||||
//! If there are multiple values where the names would be equal when converted to __snake_case__, functions might not be statically generated for some of them, because of naming conflicts. | ||||||
//! Make sure names in the custom values of your metadata differ significantly. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Just because I think it's covered above, and users often won't have the ability to influence chain metadata anyway :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use crate::dynamic::DecodedValueThunk; | ||
use crate::metadata::DecodeWithMetadata; | ||
|
||
/// This represents the address of a custom value in in the metadata. | ||
/// Anything, that implements the [CustomValueAddress] trait can be used, to fetch | ||
/// custom values from the metadata. | ||
pub trait CustomValueAddress { | ||
/// The type of the custom value. | ||
type Target: DecodeWithMetadata; | ||
|
||
/// the name (key) by which the custom value can be accessed in the metadata. | ||
fn name(&self) -> &str; | ||
} | ||
|
||
impl CustomValueAddress for str { | ||
type Target = DecodedValueThunk; | ||
|
||
fn name(&self) -> &str { | ||
self | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely docs; nice one!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two small things you'll need to do to make tests pass:
#[tokio::main] async fn main()
thing (use#
to hide this; check out other examples to see :))There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lovely docs indeed! 🚀