diff --git a/subxt/Cargo.toml b/subxt/Cargo.toml index 12e98e3e36..8fec9c4862 100644 --- a/subxt/Cargo.toml +++ b/subxt/Cargo.toml @@ -111,11 +111,11 @@ subxt-signer = { path = "../signer" } tracing-subscriber = { workspace = true } [[example]] -name = "unstable_light_client_tx_basic" -path = "examples/unstable_light_client_tx_basic.rs" +name = "light_client_tx_basic" +path = "examples/light_client_tx_basic.rs" required-features = ["unstable-light-client", "jsonrpsee"] [[example]] -name = "unstable_light_client_parachains" -path = "examples/unstable_light_client_parachains.rs" +name = "light_client_parachains" +path = "examples/light_client_parachains.rs" required-features = ["unstable-light-client", "jsonrpsee", "native"] diff --git a/subxt/examples/unstable_light_client_parachains.rs b/subxt/examples/light_client_parachains.rs similarity index 100% rename from subxt/examples/unstable_light_client_parachains.rs rename to subxt/examples/light_client_parachains.rs diff --git a/subxt/examples/unstable_light_client_tx_basic.rs b/subxt/examples/light_client_tx_basic.rs similarity index 100% rename from subxt/examples/unstable_light_client_tx_basic.rs rename to subxt/examples/light_client_tx_basic.rs diff --git a/subxt/examples/rpc_legacy.rs b/subxt/examples/rpc_legacy.rs new file mode 100644 index 0000000000..787cd7b5a5 --- /dev/null +++ b/subxt/examples/rpc_legacy.rs @@ -0,0 +1,60 @@ +use subxt::backend::{legacy::LegacyRpcMethods, rpc::RpcClient}; +use subxt::config::DefaultExtrinsicParamsBuilder as Params; +use subxt::{OnlineClient, PolkadotConfig}; +use subxt_signer::sr25519::dev; + +#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata_small.scale")] +pub mod polkadot {} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // First, create a raw RPC client: + let rpc_client = RpcClient::from_url("ws://127.0.0.1:9944").await?; + + // Use this to construct our RPC methods: + let rpc = LegacyRpcMethods::::new(rpc_client.clone()); + + // We can use the same client to drive our full Subxt interface too: + let api = OnlineClient::::from_rpc_client(rpc_client.clone()).await?; + + // Now, we can make some RPC calls using some legacy RPC methods. + println!( + "šŸ“› System Name: {:?}\n🩺 Health: {:?}\nšŸ–« Properties: {:?}\nšŸ”— Chain: {:?}\n", + rpc.system_name().await?, + rpc.system_health().await?, + rpc.system_properties().await?, + rpc.system_chain().await? + ); + + // We can also interleave RPC calls and using the full Subxt client, here to submit multiple + // transactions using the legacy `system_account_next_index` RPC call, which returns a nonce + // that is adjusted for any transactions already in the pool: + + let alice = dev::alice(); + let bob = dev::bob(); + + loop { + let current_nonce = rpc + .system_account_next_index(&alice.public_key().into()) + .await?; + let current_header = rpc.chain_get_header(None).await?.unwrap(); + + let ext_params = Params::new().mortal(¤t_header, 8).build(); + + let balance_transfer = polkadot::tx() + .balances() + .transfer_allow_death(bob.public_key().into(), 1_000_000); + + let ext_hash = api + .tx() + .create_signed_with_nonce(&balance_transfer, &alice, current_nonce, ext_params)? + .submit() + .await?; + + println!("Submitted ext {ext_hash} with nonce {current_nonce}"); + + // Sleep less than block time, but long enough to ensure + // not all transactions end up in the same block. + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + } +} diff --git a/subxt/src/book/mod.rs b/subxt/src/book/mod.rs index 14e710022c..dcd57dc068 100644 --- a/subxt/src/book/mod.rs +++ b/subxt/src/book/mod.rs @@ -92,6 +92,8 @@ //! reading the extrinsics, events and storage at these blocks. //! - [Runtime APIs](usage::runtime_apis): Subxt can make calls into pallet runtime APIs to retrieve //! data. +//! - [Custom values](usage::custom_values): Subxt can access "custom values" stored in the metadata. +//! - [Raw RPC calls](usage::rpc): Subxt can be used to make raw RPC requests to compatible nodes. //! //! ## Examples //! diff --git a/subxt/src/book/usage/light_client.rs b/subxt/src/book/usage/light_client.rs index 02f187bfdc..33dbc6668b 100644 --- a/subxt/src/book/usage/light_client.rs +++ b/subxt/src/book/usage/light_client.rs @@ -23,7 +23,9 @@ //! Alternately, you can have the `LightClient` download the chain spec from a trusted node when it //! initializes, which is not recommended in production but is useful for examples and testing, as below. //! -//! ## Example +//! ## Examples +//! +//! ### Basic Example //! //! This example connects to a local chain and submits a transaction. To run this, you first need //! to have a local polkadot node running using the following command: @@ -36,12 +38,19 @@ //! in the `subxt` crate: //! //! ```bash -//! cargo run --example unstable_light_client_tx_basic --features=unstable-light-client +//! cargo run --example light_client_tx_basic --features=unstable-light-client //! ``` //! //! This is the code that will be executed: //! //! ```rust,ignore -#![doc = include_str!("../../../examples/unstable_light_client_tx_basic.rs")] +#![doc = include_str!("../../../examples/light_client_tx_basic.rs")] //! ``` //! +//! ### Connecting to a parachain +//! +//! This example connects to a parachain using the light client. Currently, it's quite verbose to do this. +//! +//! ```rust,ignore +#![doc = include_str!("../../../examples/light_client_parachains.rs")] +//! ``` diff --git a/subxt/src/book/usage/mod.rs b/subxt/src/book/usage/mod.rs index 9986d3d7c0..fe7439e9fa 100644 --- a/subxt/src/book/usage/mod.rs +++ b/subxt/src/book/usage/mod.rs @@ -12,6 +12,7 @@ //! - [Runtime APIs](runtime_apis) //! - [Unstable Light Client](light_client) //! - [Custom Values](custom_values) +//! - [RPC calls](rpc) //! //! Alternately, [go back](super). @@ -20,6 +21,7 @@ pub mod constants; pub mod custom_values; pub mod events; pub mod light_client; +pub mod rpc; pub mod runtime_apis; pub mod storage; pub mod transactions; diff --git a/subxt/src/book/usage/rpc.rs b/subxt/src/book/usage/rpc.rs new file mode 100644 index 0000000000..a5fb61863a --- /dev/null +++ b/subxt/src/book/usage/rpc.rs @@ -0,0 +1,20 @@ +// 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. + +//! # RPC calls +//! +//! Subxt exposes low level interfaces that can be used to make RPC requests; [`crate::backend::legacy::rpc_methods`] +//! and [`crate::backend::unstable::rpc_methods`]. +//! +//! These interfaces cannot be accessed directly through an [`crate::OnlineClient`]; this is so that the high level +//! Subxt APIs can target either the "legacy" or the more modern "unstable" sets of RPC methods by selecting an appropriate +//! [`crate::backend::Backend`]. It also means that there could exist a backend in the future that doesn't use JSON-RPC at all. +//! +//! # Example +//! +//! Here's an example which calls some legacy JSON-RPC methods, and reuses the same connection to run a full Subxt client +//! +//! ```rust,ignore +#![doc = include_str!("../../../examples/rpc_legacy.rs")] +//! ```