Skip to content
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

Fix documentation examples #568

Merged
merged 6 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ jobs:
- name: Check internal documentation links
run: RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc -vv --workspace --no-deps --document-private-items

- name: Run cargo test on documentatin
uses: actions-rs/cargo@v1.0.3
with:
command: test
args: --doc

tests:
name: Cargo test
runs-on: ubuntu-latest
Expand Down
7 changes: 5 additions & 2 deletions codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
//!
//! ## Example
//!
//! ```rust
//! ```no_run
//! use std::fs;
//! use codec::Decode;
//! use frame_metadata::RuntimeMetadataPrefixed;
//! use subxt_codegen::DerivesRegistry;
//!
//! let encoded = fs::read("../artifacts/polkadot_metadata.scale").unwrap();
//!
//! // Runtime metadata obtained from a node.
//! let metadata = <RuntimeMetadataPrefixed as Decode>::decode(encoded)?;
//! let metadata = <RuntimeMetadataPrefixed as Decode>::decode(&mut &*encoded).unwrap();
//! // Module under which the API is generated.
//! let item_mod = syn::parse_quote!(
//! pub mod api {}
Expand Down
50 changes: 42 additions & 8 deletions docs/subxt.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Subxt generates a runtime API from downloaded static metadata. The metadata can

To generate the runtime API, use the `subxt` attribute which points at downloaded static metadata.

```rust
```ignore
#[subxt::subxt(runtime_metadata_path = "metadata.scale")]
pub mod node_runtime { }
```
Expand All @@ -38,14 +38,21 @@ For more information regarding the `node_runtime` hierarchy, please visit the

### Initializing the API client

```rust
```no_run
use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};

#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
pub mod polkadot {}

# #[tokio::main]
# async fn main() {
let api = ClientBuilder::new()
.set_url("wss://rpc.polkadot.io:443")
.build()
.await?
.to_runtime_api::<node_runtime::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
.await
.unwrap()
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
# }
```

The `RuntimeApi` type is generated by the `subxt` macro from the supplied metadata. This can be parameterized with user
Expand Down Expand Up @@ -116,21 +123,48 @@ call suffered changes.

Full metadata validation:

```rust
```no_run
# use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
# #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
# pub mod polkadot {}
# #[tokio::main]
# async fn main() {
# let api = ClientBuilder::new()
# .build()
# .await
# .unwrap()
# .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
// To make sure that all of our statically generated pallets are compatible with the
// runtime node, we can run this check:
api.validate_metadata()?;
api.validate_metadata().unwrap();
# }
```

Call level validation:

```rust
```ignore
# use sp_keyring::AccountKeyring;
# use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
# #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
# pub mod polkadot {}
# #[tokio::main]
# async fn main() {
# let api = ClientBuilder::new()
# .build()
# .await
# .unwrap()
# .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
// Submit the `transfer` extrinsic from Alice's account to Bob's.
let dest = AccountKeyring::Bob.to_account_id().into();

let extrinsic = api
.tx()
.balances()
// Constructing an extrinsic will fail if the metadata
// is not in sync with the generated API.
.transfer(dest, 123_456_789_012_345)?;
.transfer(dest, 123_456_789_012_345)
.unwrap();
# }
```

### Runtime Updates
Expand Down
36 changes: 27 additions & 9 deletions subxt/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,23 @@ impl ClientBuilder {
self
}

/// Creates a new Client.
/// Builder for [Client].
///
/// # Example
/// # Examples
///
/// ```rust
/// ```no_run
/// use subxt::{ClientBuilder, DefaultConfig};
///
/// let client = ClientBuilder::new()
/// .set_url("wss://rpc.polkadot.io:443")
/// .build::<DefaultConfig>()
/// .await?;
/// #[tokio::main]
/// async fn main() {
/// // Build the client.
/// let client = ClientBuilder::new()
/// .set_url("wss://rpc.polkadot.io:443")
/// .build::<DefaultConfig>()
/// .await
/// .unwrap();
/// // Use the client...
/// }
/// ```
pub async fn build<T: Config>(self) -> Result<Client<T>, BasicError> {
let client = if let Some(client) = self.client {
Expand Down Expand Up @@ -208,14 +214,26 @@ impl<T: Config> Client<T> {
/// performing runtime updates, while the API is still in use.
/// Without performing runtime updates the submitted extrinsics may fail.
///
/// # Example
/// # Examples
///
/// ```rust
/// ```no_run
/// # use subxt::{ClientBuilder, DefaultConfig};
/// #
/// # #[tokio::main]
/// # async fn main() {
/// # let client = ClientBuilder::new()
/// # .set_url("wss://rpc.polkadot.io:443")
/// # .build::<DefaultConfig>()
/// # .await
/// # .unwrap();
/// #
/// let update_client = client.updates();
/// // Spawn a new background task to handle runtime updates.
/// tokio::spawn(async move {
/// let result = update_client.perform_runtime_updates().await;
/// println!("Runtime update finished with result={:?}", result);
/// });
/// # }
/// ```
pub fn updates(&self) -> UpdateClient<T> {
UpdateClient::new(
Expand Down
44 changes: 37 additions & 7 deletions subxt/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
//!
//! This module is wrapped by the generated API in `RuntimeAPI::EventsApi`.
//!
//! # Example
//! # Examples
//!
//! ## Subscribe to all events
//!
Expand All @@ -31,12 +31,25 @@
//!
//! To obtain the events from a given block use `at()`.
//!
//! ```rust
//! let mut events = api.events().subscribe().await?;
//! ```no_run
//! # use futures::StreamExt;
//! # use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
//! pub mod polkadot {}
//!
//! # #[tokio::main]
//! # async fn main() {
//! # let api = ClientBuilder::new()
//! # .build()
//! # .await
//! # .unwrap()
//! # .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
//! let mut events = api.events().subscribe().await.unwrap();
//!
//! while let Some(ev) = events.next().await {
//! // Obtain all events from this block.
//! let ev: subxt::Events<_, _> = ev?;
//! let ev: subxt::Events<_, _> = ev.unwrap();
//! // Print block hash.
//! println!("Event at block hash {:?}", ev.block_hash());
//! // Iterate over all events.
Expand All @@ -45,6 +58,7 @@
//! println!("Event details {:?}", event_details);
//! }
//! }
//! # }
//! ```
//!
//! ## Filter events
Expand All @@ -55,16 +69,32 @@
//! returned directly. Otherwise, we'll be given a corresponding tuple of `Option`'s, with exactly
//! one variant populated each time.
//!
//! ```rust
//! let mut events = api
//! ```no_run
//! # use futures::StreamExt;
//! # use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
//! pub mod polkadot {}
//!
//! # #[tokio::main]
//! # async fn main() {
//! # let api = ClientBuilder::new()
//! # .build()
//! # .await
//! # .unwrap()
//! # .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
//!
//! let mut transfer_events = api
//! .events()
//! .subscribe()
//! .await?
//! .await
//! .unwrap()
//! .filter_events::<(polkadot::balances::events::Transfer,)>();
//!
//! while let Some(transfer_event) = transfer_events.next().await {
//! println!("Balance transfer event: {transfer_event:?}");
//! }
//! # }
//! ```

mod decoding;
Expand Down
50 changes: 40 additions & 10 deletions subxt/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,70 @@
//!
//! ## Fetch Storage
//!
//! ```rust
//! use subxt::rpc::Rpc;
//! use subxt::storage::StorageKeyPrefix;
//! ```no_run
//! # use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
//! # use subxt::storage::StorageKeyPrefix;
//! # use subxt::rpc::Rpc;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
//! pub mod polkadot {}
//!
//! # #[tokio::main]
//! # async fn main() {
//! # let api = ClientBuilder::new()
//! # .build()
//! # .await
//! # .unwrap()
//! # .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
//! // Storage prefix is `twox_128("System") ++ twox_128("ExtrinsicCount")`.
//! let key = StorageKeyPrefix::new::<node_runtime::system::storage::ExtrinsicCount>()
//! let key = StorageKeyPrefix::new::<polkadot::system::storage::ExtrinsicCount>()
//! .to_storage_key();
//!
//! // Obtain the RPC from a generated API
//! let rpc: &Rpc<_> = api
//! .client
//! .rpc();
//!
//! let result = rpc.storage(&key, None)?;
//! let result = rpc.storage(&key, None).await.unwrap();
//! println!("Storage result: {:?}", result);
//! # }
//! ```
//!
//! ## Fetch Keys
//!
//! ```rust
//! use subxt::rpc::Rpc;
//! use subxt::storage::StorageKeyPrefix;
//! let key = StorageKeyPrefix::new::<polkadot::xcm_pallet::storage::VersionNotifiers>();
//! ```no_run
//! # use subxt::{ClientBuilder, DefaultConfig, PolkadotExtrinsicParams};
//! # use subxt::storage::StorageKeyPrefix;
//! # use subxt::rpc::Rpc;
//!
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
//! pub mod polkadot {}
//!
//! # #[tokio::main]
//! # async fn main() {
//! # let api = ClientBuilder::new()
//! # .build()
//! # .await
//! # .unwrap()
//! # .to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, PolkadotExtrinsicParams<DefaultConfig>>>();
//! let key = StorageKeyPrefix::new::<polkadot::xcm_pallet::storage::VersionNotifiers>()
//! .to_storage_key();
//!
//! // Obtain the RPC from a generated API
//! let rpc: &Rpc<_> = api
//! .client
//! .rpc();
//!
//! // Fetch up to 10 keys.
//! let keys = rpc
//! .storage_keys_paged(Some(key), 10, None, None);
//! .storage_keys_paged(Some(key), 10, None, None)
//! .await
//! .unwrap();
//!
//! for key in keys.iter() {
//! println!("Key: 0x{}", hex::encode(&key));
//! }
//! # }
//! ```

// jsonrpsee subscriptions are interminable.
Expand Down
Loading