diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis-ts.html b/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis-ts.html new file mode 100644 index 000000000..e04b71118 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis-ts.html @@ -0,0 +1,12 @@ +
+ npx tsx runtime-apis.ts + + Connected to Polkadot Hub TestNet + Querying runtime APIs for: 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5 + + AccountNonceApi Results: + Account Nonce: 11 + + Metadata API Results: + Supported Metadata Versions: [14, 15, 16] +
diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis.ts b/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis.ts new file mode 100644 index 000000000..08519872d --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis.ts @@ -0,0 +1,31 @@ +import { DedotClient, WsProvider } from 'dedot'; +import type { PolkadotAssetHubApi } from '@dedot/chaintypes'; + +const POLKADOT_TESTNET_RPC = 'INSERT_WS_ENDPOINT'; + +// Example address to query +const ADDRESS = 'INSERT_ADDRESS'; + +async function main() { + // Initialize provider and client with Polkadot TestNet types + const provider = new WsProvider(POLKADOT_TESTNET_RPC); + const client = await DedotClient.new(provider); + + console.log('Connected to Polkadot Hub TestNet'); + console.log(`Querying runtime APIs for: ${ADDRESS}\n`); + + // Call AccountNonceApi to get the account nonce + const nonce = await client.call.accountNonceApi.accountNonce(ADDRESS); + console.log('AccountNonceApi Results:'); + console.log(` Account Nonce: ${nonce}`); + + // Query metadata versions using Metadata runtime API + const metadataVersions = await client.call.metadata.metadataVersions(); + console.log('\nMetadata API Results:'); + console.log(` Supported Metadata Versions: [${metadataVersions.join(', ')}]`); + + // Disconnect the client + await client.disconnect(); +} + +main().catch(console.error); diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis-ts.html b/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis-ts.html new file mode 100644 index 000000000..e04b71118 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis-ts.html @@ -0,0 +1,12 @@ +
+ npx tsx runtime-apis.ts + + Connected to Polkadot Hub TestNet + Querying runtime APIs for: 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5 + + AccountNonceApi Results: + Account Nonce: 11 + + Metadata API Results: + Supported Metadata Versions: [14, 15, 16] +
diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis.ts b/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis.ts new file mode 100644 index 000000000..93a3e1630 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis.ts @@ -0,0 +1,37 @@ +import { createClient } from 'polkadot-api'; +import { getWsProvider } from 'polkadot-api/ws-provider/node'; +import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat'; +import { polkadotTestNet } from '@polkadot-api/descriptors'; + +const POLKADOT_TESTNET_RPC = 'INSERT_WS_ENDPOINT'; + +// Example address to query +const ADDRESS = 'INSERT_ADDRESS'; + +async function main() { + // Create the client connection + const client = createClient( + withPolkadotSdkCompat(getWsProvider(POLKADOT_TESTNET_RPC)) + ); + + // Get the typed API for Polkadot Hub TestNet + const api = client.getTypedApi(polkadotTestNet); + + console.log('Connected to Polkadot Hub TestNet'); + console.log(`Querying runtime APIs for: ${ADDRESS}\n`); + + // Call AccountNonceApi to get the account nonce + const nonce = await api.apis.AccountNonceApi.account_nonce(ADDRESS); + console.log('AccountNonceApi Results:'); + console.log(` Account Nonce: ${nonce}`); + + // Query metadata versions using Metadata runtime API + const metadataVersions = await api.apis.Metadata.metadata_versions(); + console.log('\nMetadata API Results:'); + console.log(` Supported Metadata Versions: [${metadataVersions.join(', ')}]`); + + // Disconnect the client + client.destroy(); +} + +main().catch(console.error); diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis-js.html b/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis-js.html new file mode 100644 index 000000000..d828e1fdc --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis-js.html @@ -0,0 +1,12 @@ +
+ node runtime-apis.js + + Connected to Polkadot Hub TestNet + Querying runtime APIs for: 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5 + + AccountNonceApi Results: + Account Nonce: 11 + + Metadata API Results: + Supported Metadata Versions: [14, 15, 16] +
diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis.js b/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis.js new file mode 100644 index 000000000..a59cd0578 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis.js @@ -0,0 +1,34 @@ +import { ApiPromise, WsProvider } from '@polkadot/api'; + +const POLKADOT_TESTNET_RPC = 'INSERT_WS_ENDPOINT'; + +// Example address to query +const ADDRESS = 'INSERT_ADDRESS'; + +async function main() { + // Create a WebSocket provider + const wsProvider = new WsProvider(POLKADOT_TESTNET_RPC); + + // Initialize the API + const api = await ApiPromise.create({ provider: wsProvider }); + + console.log('Connected to Polkadot Hub TestNet'); + console.log(`Querying runtime APIs for: ${ADDRESS}\n`); + + // Call AccountNonceApi to get the account nonce + const nonce = await api.call.accountNonceApi.accountNonce(ADDRESS); + console.log('AccountNonceApi Results:'); + console.log(` Account Nonce: ${nonce.toString()}`); + + // Query metadata versions using Metadata runtime API + const metadataVersions = await api.call.metadata.metadataVersions(); + console.log('\nMetadata API Results:'); + console.log( + ` Supported Metadata Versions: [${metadataVersions.map((v) => v.toString()).join(', ')}]` + ); + + // Disconnect from the node + await api.disconnect(); +} + +main().catch(console.error); diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime-apis-py.html b/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime-apis-py.html new file mode 100644 index 000000000..148ac81de --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime-apis-py.html @@ -0,0 +1,14 @@ +
+ python runtime_apis.py + + Connected to Polkadot Hub TestNet + Querying runtime APIs for: 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5 + + AccountNonceApi Results: + Account Nonce: 11 + + Core API Results: + Spec Name: asset-hub-paseo + Spec Version: 1004001 + Impl Version: 0 +
diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime_apis.py b/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime_apis.py new file mode 100644 index 000000000..5ef58091b --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/psi/runtime_apis.py @@ -0,0 +1,33 @@ +from substrateinterface import SubstrateInterface + +POLKADOT_TESTNET_RPC = "INSERT_WS_ENDPOINT" + +# Example address to query +ADDRESS = "INSERT_ADDRESS" + + +def main(): + # Connect to Polkadot Hub TestNet + substrate = SubstrateInterface(url=POLKADOT_TESTNET_RPC) + + print("Connected to Polkadot Hub TestNet") + print(f"Querying runtime APIs for: {ADDRESS}\n") + + # Call AccountNonceApi to get the account nonce + nonce = substrate.runtime_call("AccountNonceApi", "account_nonce", [ADDRESS]) + print("AccountNonceApi Results:") + print(f" Account Nonce: {nonce.value}") + + # Query runtime version using Core runtime API + version = substrate.runtime_call("Core", "version", []) + print("\nCore API Results:") + print(f" Spec Name: {version.value['spec_name']}") + print(f" Spec Version: {version.value['spec_version']}") + print(f" Impl Version: {version.value['impl_version']}") + + # Close connection + substrate.close() + + +if __name__ == "__main__": + main() diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/Cargo.toml b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/Cargo.toml new file mode 100644 index 000000000..70123cc97 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "subxt-runtime-api-example" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "runtime_apis" +path = "src/bin/runtime_apis.rs" + +[dependencies] +subxt = "0.44.0" +tokio = { version = "1", features = ["rt", "macros"] } diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/runtime-apis-rs.html b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/runtime-apis-rs.html new file mode 100644 index 000000000..31b4f4a42 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/runtime-apis-rs.html @@ -0,0 +1,12 @@ +
+ cargo run --bin runtime_apis + + Connected to Polkadot Hub TestNet + Querying runtime APIs for: 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5 + + AccountNonceApi Results: + Account Nonce: 11 + + Metadata API Results: + Supported Metadata Versions: (14, 15, 16) +
diff --git a/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/src/bin/runtime_apis.rs b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/src/bin/runtime_apis.rs new file mode 100644 index 000000000..7f08faf61 --- /dev/null +++ b/.snippets/code/chain-interactions/query-data/runtime-api-calls/subxt/src/bin/runtime_apis.rs @@ -0,0 +1,50 @@ +use std::str::FromStr; +use subxt::dynamic::Value; +use subxt::utils::AccountId32; +use subxt::{OnlineClient, PolkadotConfig}; + +// Generate an interface from the node's metadata +#[subxt::subxt(runtime_metadata_path = "polkadot_testnet_metadata.scale")] +pub mod polkadot_testnet {} + +const POLKADOT_TESTNET_RPC: &str = "INSERT_WS_ENDPOINT"; + +// Example address to query +const ADDRESS: &str = "INSERT_ADDRESS"; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box> { + // Initialize the Subxt client + let api = OnlineClient::::from_url(POLKADOT_TESTNET_RPC).await?; + + println!("Connected to Polkadot Hub TestNet"); + println!("Querying runtime APIs for: {}\n", ADDRESS); + + // Parse the address + let account = AccountId32::from_str(ADDRESS)?; + + // Call AccountNonceApi using static interface + let nonce_call = polkadot_testnet::apis() + .account_nonce_api() + .account_nonce(account.clone()); + let nonce = api.runtime_api().at_latest().await?.call(nonce_call).await?; + println!("AccountNonceApi Results:"); + println!(" Account Nonce: {}", nonce); + + // Call Metadata API to get supported versions using dynamic call + let metadata_versions_call = + subxt::dynamic::runtime_api_call("Metadata", "metadata_versions", Vec::::new()); + let versions_result = api + .runtime_api() + .at_latest() + .await? + .call(metadata_versions_call) + .await?; + println!("\nMetadata API Results:"); + println!( + " Supported Metadata Versions: {}", + versions_result.to_value()? + ); + + Ok(()) +} diff --git a/chain-interactions/query-data/runtime-api-calls.md b/chain-interactions/query-data/runtime-api-calls.md index 30404ce4c..a4a8e42b9 100644 --- a/chain-interactions/query-data/runtime-api-calls.md +++ b/chain-interactions/query-data/runtime-api-calls.md @@ -1 +1,347 @@ -TODO \ No newline at end of file +--- +title: Runtime API Calls +description: Learn how to call Polkadot runtime APIs to access the Wasm runtime and retrieve computed results using PAPI, Polkadot.js, Dedot, Python, and Subxt. +categories: Chain Interactions +--- + +# Runtime API Calls + +## Introduction + +Polkadot SDK runtime APIs provide direct access to the blockchain's WebAssembly (Wasm) runtime, enabling specialized queries and computations that go beyond simple storage reads. Unlike storage queries that fetch static data, runtime APIs execute logic within the runtime to compute results dynamically. + +Common runtime APIs include: + +- **AccountNonceApi**: Retrieves the current transaction nonce for an account. +- **Metadata**: Queries available metadata versions and runtime information. +- **TransactionPaymentApi**: Estimates transaction fees before submission. +- **NominationPoolsApi**: Retrieves staking pool information and pending rewards. +- **StakingApi**: Accesses staking-related computations. + +## Call Runtime APIs + +This section demonstrates how to call runtime APIs using the following SDKs: + +- **Polkadot API (PAPI)**: Modern TypeScript library with type-safe APIs. +- **Polkadot.js API**: Comprehensive JavaScript library (maintenance mode). +- **Dedot**: Lightweight TypeScript library optimized for performance. +- **Python Substrate Interface**: Python library for Substrate chains. +- **Subxt**: Rust library with compile-time type safety. + +Select your preferred SDK below to see complete, runnable examples that query Polkadot Hub TestNet for account nonces and metadata information. + +=== "PAPI" + + **Prerequisites** + + - [Node.js](https://nodejs.org/){target=\_blank} v18 or higher + - npm, pnpm, or yarn package manager + + **Environment Setup** + + 1. Create and initialize a new project: + + ```bash + mkdir papi-runtime-api-example && cd papi-runtime-api-example && \ + npm init -y && npm pkg set type=module + ``` + + 2. Install dependencies: + + ```bash + npm install polkadot-api && \ + npm install --save-dev @types/node tsx typescript + ``` + + 3. Generate types for Polkadot Hub TestNet: + + ```bash + npx papi add polkadotTestNet -w wss://asset-hub-paseo.dotters.network + ``` + + **Call Runtime APIs** + + The following example demonstrates calling several runtime APIs: + + - **`AccountNonceApi.account_nonce`**: Gets the current nonce for an account. + - **`Metadata.metadata_versions`**: Retrieves supported metadata versions. + + Create a file named `runtime-apis.ts` and add the following code: + + ```typescript title="runtime-apis.ts" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis.ts" + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with a valid WebSocket endpoint (e.g., `wss://asset-hub-paseo.dotters.network`) and `INSERT_ADDRESS` with the account address you want to query. + + Run the script: + + ```bash + npx tsx runtime-apis.ts + ``` + + You should see output similar to: + + --8<-- 'code/chain-interactions/query-data/runtime-api-calls/papi/runtime-apis-ts.html' + +=== "Polkadot.js" + + !!! warning "Maintenance Mode Only" + The Polkadot.js API is no longer actively developed. New projects should use [PAPI](/reference/tools/papi/){target=\_blank} or [Dedot](/reference/tools/dedot/){target=\_blank} as actively maintained alternatives. + + **Prerequisites** + + - [Node.js](https://nodejs.org/){target=\_blank} v18 or higher + - npm, pnpm, or yarn package manager + + **Environment Setup** + + 1. Create and initialize a new project: + + ```bash + mkdir pjs-runtime-api-example && cd pjs-runtime-api-example && \ + npm init -y && npm pkg set type=module + ``` + + 2. Install dependencies: + + ```bash + npm install @polkadot/api + ``` + + **Call Runtime APIs** + + The following example demonstrates calling several runtime APIs: + + - **`accountNonceApi.accountNonce`**: Gets the current nonce for an account. + - **`metadata.metadataVersions`**: Retrieves supported metadata versions. + + Create a file named `runtime-apis.js` and add the following code: + + ```javascript title="runtime-apis.js" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis.js" + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with a valid WebSocket endpoint (e.g., `wss://asset-hub-paseo.dotters.network`) and `INSERT_ADDRESS` with the account address you want to query. + + Run the script: + + ```bash + node runtime-apis.js + ``` + + You should see output similar to: + + --8<-- 'code/chain-interactions/query-data/runtime-api-calls/pjs/runtime-apis-js.html' + +=== "Dedot" + + **Prerequisites** + + - [Node.js](https://nodejs.org/){target=\_blank} v18 or higher + - npm, pnpm, or yarn package manager + + **Environment Setup** + + 1. Create and initialize a new project: + + ```bash + mkdir dedot-runtime-api-example && cd dedot-runtime-api-example && \ + npm init -y && npm pkg set type=module + ``` + + 2. Install dependencies: + + ```bash + npm install dedot && \ + npm install --save-dev @dedot/chaintypes @types/node tsx typescript + ``` + + **Call Runtime APIs** + + The following example demonstrates calling several runtime APIs: + + - **`accountNonceApi.accountNonce`**: Gets the current nonce for an account. + - **`metadata.metadataVersions`**: Retrieves supported metadata versions. + + Create a file named `runtime-apis.ts` and add the following code: + + ```typescript title="runtime-apis.ts" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis.ts" + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with a valid WebSocket endpoint (e.g., `wss://asset-hub-paseo.dotters.network`) and `INSERT_ADDRESS` with the account address you want to query. + + Run the script: + + ```bash + npx tsx runtime-apis.ts + ``` + + You should see output similar to: + + --8<-- 'code/chain-interactions/query-data/runtime-api-calls/dedot/runtime-apis-ts.html' + +=== "Py Substrate Interface" + + **Prerequisites** + + - [Python](https://www.python.org/){target=\_blank} 3.8 or higher + - pip package manager + + **Environment Setup** + + 1. Create a new project directory and set up a virtual environment: + + ```bash + mkdir psi-runtime-api-example && cd psi-runtime-api-example && \ + python3 -m venv venv && source venv/bin/activate + ``` + + 2. Install the substrate-interface package: + + ```bash + pip install substrate-interface + ``` + + **Call Runtime APIs** + + The following example demonstrates calling several runtime APIs: + + - **`AccountNonceApi.account_nonce`**: Gets the current nonce for an account. + - **`Core.version`**: Retrieves runtime version information. + + Create a file named `runtime_apis.py` and add the following code: + + ```python title="runtime_apis.py" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/psi/runtime_apis.py" + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with a valid WebSocket endpoint (e.g., `wss://asset-hub-paseo.dotters.network`) and `INSERT_ADDRESS` with the account address you want to query. + + Run the script: + + ```bash + python runtime_apis.py + ``` + + You should see output similar to: + + --8<-- 'code/chain-interactions/query-data/runtime-api-calls/psi/runtime-apis-py.html' + +=== "Subxt" + + [Subxt](/reference/tools/subxt/){target=\_blank} is a Rust library that provides compile-time type safety through code generation from chain metadata. + + **Prerequisites** + + - [Rust](https://rustup.rs/){target=\_blank} toolchain (latest stable) + - Cargo package manager + + **Environment Setup** + + 1. Create a new Rust project: + + ```bash + cargo new subxt-runtime-api-example && cd subxt-runtime-api-example + ``` + + 2. Install the Subxt CLI: + + ```bash + cargo install subxt-cli@{{ dependencies.crates.subxt_cli.version }} + ``` + + 3. Download the Polkadot Hub TestNet metadata: + + ```bash + subxt metadata --url INSERT_WS_ENDPOINT -o polkadot_testnet_metadata.scale + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with the proper WebSocket endpoint, such as `wss://asset-hub-paseo.dotters.network` for Polkadot Hub TestNet. + + 4. Update `Cargo.toml` with the required dependencies: + + ```toml title="Cargo.toml" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/subxt/Cargo.toml" + ``` + + **Call Runtime APIs** + + The following example demonstrates calling several runtime APIs: + + - **`AccountNonceApi.account_nonce`**: Gets the current nonce using the static interface. + - **`Metadata.metadata_versions`**: Retrieves supported metadata versions using the dynamic interface. + + Create a file at `src/bin/runtime_apis.rs` and add the following code: + + ```rust title="src/bin/runtime_apis.rs" + --8<-- "code/chain-interactions/query-data/runtime-api-calls/subxt/src/bin/runtime_apis.rs" + ``` + + Ensure to replace `INSERT_WS_ENDPOINT` with a valid WebSocket endpoint (e.g., `wss://asset-hub-paseo.dotters.network`) and `INSERT_ADDRESS` with the account address you want to query. + + Run the script: + + ```bash + cargo run --bin runtime_apis + ``` + + You should see output similar to: + + --8<-- 'code/chain-interactions/query-data/runtime-api-calls/subxt/runtime-apis-rs.html' + +## Available Runtime APIs + +The following runtime APIs are commonly available on Polkadot SDK-based chains: + +| API | Description | +|-----|-------------| +| `AccountNonceApi` | Get current transaction nonce for an account | +| `TransactionPaymentApi` | Query transaction fees and weight information | +| `TransactionPaymentCallApi` | Estimate fees for a call without creating an extrinsic | +| `Metadata` | Query metadata versions and runtime metadata | +| `BlockBuilder` | Access block building functionality | +| `Core` | Core runtime version and execution | +| `TaggedTransactionQueue` | Validate transactions in the pool | +| `OffchainWorkerApi` | Offchain worker functionality | +| `SessionKeys` | Session key management | +| `GrandpaApi` | GRANDPA finality information | +| `BabeApi` | BABE consensus information | +| `NominationPoolsApi` | Nomination pools data and pending rewards | +| `StakingApi` | Staking-related computations | + +!!! note + Available runtime APIs vary by chain. Check your target chain's metadata to see which APIs are exposed. + +## Where to Go Next + +Now that you understand how to call runtime APIs to execute logic within the runtime, explore these related topics: + +
+ +- __Query with SDKs__ + + --- + + Use TypeScript, Python, or Rust SDKs for programmatic access. + + [:octicons-arrow-right-24: Get Started](/chain-interactions/query-data/query-sdks/) + +- __Query On-Chain State with Sidecar REST API__ + + --- + + Learn how to query on-chain state using the Sidecar REST API + + [:octicons-arrow-right-24: Get Started](/chain-interactions/query-data/query-rest/) + +- __Send Transactions__ + + --- + + Learn to construct and submit transactions. + + [:octicons-arrow-right-24: Get Started](/chain-interactions/send-transactions/with-sdks/) + +
\ No newline at end of file