Skip to content

Commit 365a264

Browse files
0xLuccanhussein110xlukemdawnkelly09
authored
Add Subxt docs at "API Libraries" section (#421)
* wip: subxt * Replace code with snippets * Apply suggestions from code review Co-authored-by: Nicolás Hussein <[email protected]> * Apply suggestions * Apply suggestions * Add bold * Apply suggestions from code review Co-authored-by: Lucas Malizia <[email protected]> * Apply suggestions * Apply suggestions from code review Co-authored-by: Dawn Kelly <[email protected]> * Update llms.txt --------- Co-authored-by: Nicolás Hussein <[email protected]> Co-authored-by: Lucas Malizia <[email protected]> Co-authored-by: Dawn Kelly <[email protected]>
1 parent bd344d0 commit 365a264

File tree

5 files changed

+480
-1
lines changed

5 files changed

+480
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "my-project"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
subxt = "0.39.0"
8+
subxt-signer = "0.39.0"
9+
tokio = { version = "1.43.0", features = ["rt", "macros"] }
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::str::FromStr;
2+
use subxt::utils::AccountId32;
3+
use subxt::{OnlineClient, PolkadotConfig};
4+
use subxt_signer::{bip39::Mnemonic,sr25519::Keypair};
5+
6+
// Generate an interface that we can use from the node's metadata.
7+
#[subxt::subxt(runtime_metadata_path = "./polkadot_metadata.scale")]
8+
pub mod polkadot {}
9+
10+
#[tokio::main(flavor = "current_thread")]
11+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
12+
// Define the node URL.
13+
const NODE_URL: &str = "INSERT_NODE_URL";
14+
15+
// Initialize the Subxt client to interact with the blockchain.
16+
let api = OnlineClient::<PolkadotConfig>::from_url(NODE_URL).await?;
17+
18+
// A query to obtain some constant.
19+
let constant_query = polkadot::constants().balances().existential_deposit();
20+
21+
// Obtain the value.
22+
let value = api.constants().at(&constant_query)?;
23+
24+
println!("Existential deposit: {:?}", value);
25+
26+
// Define the target account address.
27+
const ADDRESS: &str = "INSERT_ADDRESS";
28+
let account = AccountId32::from_str(ADDRESS).unwrap();
29+
30+
// Build a storage query to access account information.
31+
let storage_query = polkadot::storage().system().account(&account.into());
32+
33+
// Fetch the latest state for the account.
34+
let result = api
35+
.storage()
36+
.at_latest()
37+
.await?
38+
.fetch(&storage_query)
39+
.await?
40+
.unwrap();
41+
42+
println!("Account info: {:?}", result);
43+
44+
// Define the recipient address and transfer amount.
45+
const DEST_ADDRESS: &str = "INSERT_DEST_ADDRESS";
46+
const AMOUNT: u128 = INSERT_AMOUNT;
47+
48+
// Convert the recipient address into an `AccountId32`.
49+
let dest = AccountId32::from_str(DEST_ADDRESS).unwrap();
50+
51+
// Build the balance transfer extrinsic.
52+
let balance_transfer_tx = polkadot::tx()
53+
.balances()
54+
.transfer_allow_death(dest.into(), AMOUNT);
55+
56+
// Load the sender's keypair from a mnemonic phrase.
57+
const SECRET_PHRASE: &str = "INSERT_SECRET_PHRASE";
58+
let mnemonic = Mnemonic::parse(SECRET_PHRASE).unwrap();
59+
let sender_keypair = Keypair::from_phrase(&mnemonic, None).unwrap();
60+
61+
// Sign and submit the extrinsic, then wait for it to be finalized.
62+
let events = api
63+
.tx()
64+
.sign_and_submit_then_watch_default(&balance_transfer_tx, &sender_keypair)
65+
.await?
66+
.wait_for_finalized_success()
67+
.await?;
68+
69+
// Check for a successful transfer event.
70+
if let Some(event) = events.find_first::<polkadot::balances::events::Transfer>()? {
71+
println!("Balance transfer successful: {:?}", event);
72+
}
73+
74+
Ok(())
75+
}

develop/toolkit/api-libraries/.pages

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ nav:
44
- 'Polkadot.js API': polkadot-js-api.md
55
- 'Polkadot-API': papi.md
66
- 'Sidecar Rest API': sidecar.md
7-
- 'Python Substrate Interface': py-substrate-interface.md
7+
- 'Python Substrate Interface': py-substrate-interface.md
8+
- 'Subxt': subxt.md
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: Subxt Rust API
3+
description: Subxt is a Rust library for type-safe interaction with Polkadot SDK blockchains, enabling transactions, state queries, runtime API access, and more.
4+
---
5+
6+
# Subxt Rust API
7+
8+
## Introduction
9+
10+
subxt is a Rust library designed to interact with Polkadot SDK-based blockchains. It provides a type-safe interface for submitting transactions, querying on-chain state, and performing other blockchain interactions. By leveraging Rust's strong type system, subxt ensures that your code is validated at compile time, reducing runtime errors and improving reliability.
11+
12+
## Prerequisites
13+
14+
Before using subxt, ensure you have the following requirements:
15+
16+
- Rust and Cargo installed on your system. You can install them using [Rustup](https://rustup.rs/){target=\_blank}
17+
- A Rust project initialized. If you don't have one, create it with:
18+
```bash
19+
cargo new my_project && cd my_project
20+
```
21+
22+
## Installation
23+
24+
To use subxt in your project, you must install the necessary dependencies. Each plays a specific role in enabling interaction with the blockchain:
25+
26+
1. **Install the subxt CLI** - [`subxt-cli`](https://crates.io/crates/subxt-cli){target=\_blank} is a command-line tool that provides utilities for working with Polkadot SDK metadata. In the context of subxt, it is essential to download chain metadata, which is required to generate type-safe Rust interfaces for interacting with the blockchain. Install it using:
27+
28+
```bash
29+
cargo install subxt-cli
30+
```
31+
32+
2. **Add core dependencies** - these dependencies are essential for interacting with the blockchain:
33+
34+
- **[subxt](https://crates.io/crates/subxt){target=\_blank}** - the main library for communicating with Polkadot SDK nodes. It handles RPC requests, encoding/decoding, and type generation
35+
36+
```bash
37+
cargo add subxt
38+
```
39+
40+
- **[subxt-signer](https://crates.io/crates/subxt-signer){target=\_blank}** - provides cryptographic functionality for signing transactions. Without this, you can only read data but cannot submit transactions
41+
42+
```bash
43+
cargo add subxt-signer
44+
```
45+
46+
- **[tokio](https://crates.io/crates/tokio){target=\_blank}** - an asynchronous runtime for Rust. Since blockchain operations are async, Tokio enables the efficient handling of network requests. The `rt` feature enables Tokio's runtime, including the current-thread single-threaded scheduler, which is necessary for async execution. The `macros` feature provides procedural macros like `#[tokio::main]` to simplify runtime setup
47+
48+
```bash
49+
cargo add tokio --features rt,macros
50+
```
51+
52+
After adding the dependencies, your `Cargo.toml` should look like this:
53+
54+
```toml
55+
--8<-- 'code/develop/toolkit/api-libraries/subxt/Cargo.toml'
56+
```
57+
58+
## Get Started
59+
60+
This guide will walk you through the fundamental operations of subxt, from setting up your environment to executing transactions and querying blockchain state.
61+
62+
### Download Chain Metadata
63+
64+
Before interacting with a blockchain, you need to retrieve its metadata. This metadata defines storage structures, extrinsics, and other runtime details. Use the `subxt-cli` tool to download the metadata, replacing `INSERT_NODE_URL` with the URL of the node you want to interact with:
65+
66+
```bash
67+
subxt metadata --url INSERT_NODE_URL > polkadot_metadata.scale
68+
```
69+
70+
### Generate Type-Safe Interfaces
71+
72+
Use the `#[subxt::subxt]` macro to generate a type-safe Rust interface from the downloaded metadata:
73+
74+
```rust
75+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs:6:8'
76+
```
77+
78+
Once subxt interfaces are generated, you can interact with your node in the following ways. You can use the links below to view the related subxt documentation:
79+
80+
- **[Transactions](https://docs.rs/subxt/latest/subxt/book/usage/transactions/index.html){target=\_blank}** - builds and submits transactions, monitors their inclusion in blocks, and retrieves associated events
81+
- **[Storage](https://docs.rs/subxt/latest/subxt/book/usage/storage/index.html){target=\_blank}** - enables querying of node storage data
82+
- **[Events](https://docs.rs/subxt/latest/subxt/book/usage/events/index.html){target=\_blank}** - retrieves events emitted from recent blocks
83+
- **[Constants](https://docs.rs/subxt/latest/subxt/book/usage/constants/index.html){target=\_blank}** - accesses constant values stored in nodes that remain unchanged across a specific runtime version.
84+
- **[Blocks](https://docs.rs/subxt/latest/subxt/book/usage/blocks/index.html){target=\_blank}** - loads recent blocks or subscribes to new/finalized blocks, allowing examination of extrinsics, events, and storage at those blocks
85+
- **[Runtime APIs](https://docs.rs/subxt/latest/subxt/book/usage/runtime_apis/index.html){target=\_blank}** - makes calls into pallet runtime APIs to fetch data
86+
- **[Custom values](https://docs.rs/subxt/latest/subxt/book/usage/custom_values/index.html){target=\_blank}** - accesses "custom values" contained within metadata
87+
- **[Raw RPC calls](https://docs.rs/subxt/latest/subxt/book/usage/rpc/index.html){target=\_blank}** - facilitates raw RPC requests to compatible nodes
88+
89+
### Initialize the Subxt client
90+
91+
To interact with a blockchain node using subxt, create an asynchronous main function and initialize the client. Replace `INSERT_NODE_URL` with the URL of your target node:
92+
93+
```rust
94+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs::17'
95+
// Your code here...
96+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs:73:75'
97+
```
98+
99+
### Read Chain Data
100+
101+
subxt provides multiple ways to access on-chain data:
102+
103+
- **Constants** - constants are predefined values in the runtime that remain unchanged unless modified by a runtime upgrade
104+
105+
For example, to retrieve the existential deposit, use:
106+
107+
```rust
108+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs:18:24'
109+
```
110+
111+
- **State** - state refers to the current chain data, which updates with each block
112+
113+
To fetch account information, replace `INSERT_ADDRESS` with the address you want to fetch data from and use:
114+
115+
```rust
116+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs:26:42'
117+
```
118+
119+
### Submit Transactions
120+
121+
To submit a transaction, you must construct an extrinsic, sign it with your private key, and send it to the blockchain. Replace `INSERT_DEST_ADDRESS` with the recipient's address, `INSERT_AMOUNT` with the amount to transfer, and `INSERT_SECRET_PHRASE` with the sender's mnemonic phrase:
122+
123+
```rust
124+
--8<-- 'code/develop/toolkit/api-libraries/subxt/subxt.rs:44:72'
125+
```
126+
127+
## Where to Go Next
128+
129+
Now that you've covered the basics dive into the official [subxt documentation](https://docs.rs/subxt/latest/subxt/book/index.html){target=\_blank} for comprehensive reference materials and advanced features.

0 commit comments

Comments
 (0)