Query Account Information with SDKs
Introduction
Section titled “Introduction”Querying account information is a fundamental operation when interacting with Polkadot SDK-based blockchains. Account queries allow you to retrieve balances, nonces, account data, and other state information stored on-chain. Each SDK provides different methods for accessing this data efficiently.
This guide demonstrates how to query account information using five popular 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 account information on Polkadot Hub.
Prerequisites
Section titled “Prerequisites”- Access to a Polkadot SDK-compatible blockchain endpoint (WebSocket URL)
- An account address to query (can be any valid SS58 address)
Query Account Information
Section titled “Query Account Information”Prerequisites
- Node.js v18 or higher
- npm, pnpm, or yarn package manager
Environment Setup
-
Create and initialize a new project:
Terminal window mkdir papi-query-account-example && cd papi-query-account-example && \npm init -y && npm pkg set type=module -
Install dependencies:
Terminal window npm install polkadot-api@3.3.0 && \npm install --save-dev @types/node tsx typescript -
Generate types for Polkadot Hub:
Terminal window npx papi add polkadotTestNet -w wss://asset-hub-paseo.dotters.network
Query Account Data
The following example queries account information including balance, nonce, and other account data.
Create a file named query-account.ts and add the following code to it:
import { createClient } from 'polkadot-api';import { getWsProvider } from 'polkadot-api/ws';import { polkadotTestNet } from '@polkadot-api/descriptors';
const POLKADOT_HUB_RPC = 'INSERT_WS_ENDPOINT';const ACCOUNT_ADDRESS = 'INSERT_ACCOUNT_ADDRESS';const PAS_UNITS = 10_000_000_000;
async function main() { try { // Create the client connection const client = createClient(getWsProvider(POLKADOT_HUB_RPC));
// Get the typed API const api = client.getTypedApi(polkadotTestNet); console.log('Connected to Polkadot Hub');
console.log(`\nQuerying account: ${ACCOUNT_ADDRESS}\n`);
// Query account information const accountInfo = await api.query.System.Account.getValue( ACCOUNT_ADDRESS );
// Display account information console.log('Account Information:'); console.log('==================='); console.log(`Nonce: ${accountInfo.nonce}`); console.log(`Consumers: ${accountInfo.consumers}`); console.log(`Providers: ${accountInfo.providers}`); console.log(`Sufficients: ${accountInfo.sufficients}`);
console.log('\nBalance Details:'); console.log('================'); console.log( `Free Balance: ${accountInfo.data.free} (${ Number(accountInfo.data.free) / PAS_UNITS } PAS)` ); console.log( `Reserved Balance: ${accountInfo.data.reserved} (${ Number(accountInfo.data.reserved) / PAS_UNITS } PAS)` ); console.log( `Frozen Balance: ${accountInfo.data.frozen} (${ Number(accountInfo.data.frozen) / PAS_UNITS } PAS)` );
const total = Number(accountInfo.data.free) + Number(accountInfo.data.reserved); console.log(`\nTotal Balance: ${total} (${total / PAS_UNITS} PAS)`);
await client.destroy(); console.log('\nDisconnected'); } catch (error) { console.error('Error:', error); process.exit(1); }}
main();Run the script:
npx tsx query-account.tsYou should see output similar to:
Prerequisites
- Node.js v18 or higher
- npm, pnpm, or yarn package manager
Environment Setup
-
Create and initialize a new project:
Terminal window mkdir pjs-query-account-example && cd pjs-query-account-example && \npm init -y && npm pkg set type=module -
Install dependencies:
Terminal window npm install @polkadot/api
Query Account Data
The following example queries account information including balance, nonce, and other account data.
Create a file named query-account.js and add the following code to it:
import { ApiPromise, WsProvider } from '@polkadot/api';
const POLKADOT_HUB_RPC = 'INSERT_WS_ENDPOINT';const ACCOUNT_ADDRESS = 'INSERT_ACCOUNT_ADDRESS';const PAS_UNITS = 10_000_000_000;
async function main() { // Create a WebSocket provider const wsProvider = new WsProvider(POLKADOT_HUB_RPC);
// Initialize the API const api = await ApiPromise.create({ provider: wsProvider }); console.log('Connected to Polkadot Hub');
console.log(`\nQuerying account: ${ACCOUNT_ADDRESS}\n`);
// Query account information const accountInfo = await api.query.system.account(ACCOUNT_ADDRESS);
// Display account information console.log('Account Information:'); console.log('==================='); console.log(`Nonce: ${accountInfo.nonce.toString()}`); console.log(`Consumers: ${accountInfo.consumers.toString()}`); console.log(`Providers: ${accountInfo.providers.toString()}`); console.log(`Sufficients: ${accountInfo.sufficients.toString()}`);
console.log('\nBalance Details:'); console.log('================'); console.log( `Free Balance: ${accountInfo.data.free.toString()} (${ Number(accountInfo.data.free.toBigInt()) / PAS_UNITS } PAS)` ); console.log( `Reserved Balance: ${accountInfo.data.reserved.toString()} (${ Number(accountInfo.data.reserved.toBigInt()) / PAS_UNITS } PAS)` ); console.log( `Frozen Balance: ${accountInfo.data.frozen.toString()} (${ Number(accountInfo.data.frozen.toBigInt()) / PAS_UNITS } PAS)` );
const total = Number(accountInfo.data.free.toBigInt()) + Number(accountInfo.data.reserved.toBigInt()); console.log(`\nTotal Balance: ${total} (${total / PAS_UNITS} PAS)`);
// Disconnect from the node await api.disconnect(); console.log('\nDisconnected');}
main().catch(console.error);Run the script:
node query-account.jsYou should see output similar to:
Prerequisites
- Node.js v18 or higher
- npm, pnpm, or yarn package manager
Environment Setup
-
Create and initialize a new project:
Terminal window mkdir dedot-query-account-example && cd dedot-query-account-example && \npm init -y && npm pkg set type=module -
Install dependencies:
Terminal window npm install dedot && \npm install --save-dev @dedot/chaintypes @types/node tsx typescript
Query Account Data
The following example queries account information including balance, nonce, and other account data.
Create a file named query-account.ts and add the following code to it:
import { DedotClient, WsProvider } from 'dedot';import type { PolkadotAssetHubApi } from '@dedot/chaintypes';
const POLKADOT_HUB_RPC = 'INSERT_WS_ENDPOINT';const ACCOUNT_ADDRESS = 'INSERT_ACCOUNT_ADDRESS';const PAS_UNITS = 10_000_000_000;
async function main() { // Initialize provider and client with Asset Hub types const provider = new WsProvider(POLKADOT_HUB_RPC); const client = await DedotClient.new<PolkadotAssetHubApi>(provider);
console.log('Connected to Polkadot Hub');
console.log(`\nQuerying account: ${ACCOUNT_ADDRESS}\n`);
// Query account information const accountInfo = await client.query.system.account(ACCOUNT_ADDRESS);
// Display account information console.log('Account Information:'); console.log('==================='); console.log(`Nonce: ${accountInfo.nonce}`); console.log(`Consumers: ${accountInfo.consumers}`); console.log(`Providers: ${accountInfo.providers}`); console.log(`Sufficients: ${accountInfo.sufficients}`);
console.log('\nBalance Details:'); console.log('================'); console.log( `Free Balance: ${accountInfo.data.free} (${ Number(accountInfo.data.free) / PAS_UNITS } PAS)` ); console.log( `Reserved Balance: ${accountInfo.data.reserved} (${ Number(accountInfo.data.reserved) / PAS_UNITS } PAS)` ); console.log( `Frozen Balance: ${accountInfo.data.frozen} (${ Number(accountInfo.data.frozen) / PAS_UNITS } PAS)` );
const total = Number(accountInfo.data.free) + Number(accountInfo.data.reserved); console.log(`\nTotal Balance: ${total} (${total / PAS_UNITS} PAS)`);
// Disconnect the client await client.disconnect(); console.log('\nDisconnected from Polkadot Hub');}
main().catch(console.error);Run the script:
npx tsx query-account.tsYou should see output similar to:
Prerequisites
- Python 3.8 or higher
- pip package manager
Environment Setup
-
Create a new project directory and set up a virtual environment:
Terminal window mkdir psi-query-account-example && cd psi-query-account-example && \python3 -m venv venv && source venv/bin/activate -
Install the substrate-interface package:
Terminal window pip install substrate-interface
Query Account Data
The following example queries account information including balance, nonce, and other account data.
Create a file named query_account.py and add the following code to it:
from substrateinterface import SubstrateInterface
POLKADOT_HUB_RPC = "INSERT_WS_ENDPOINT" ACCOUNT_ADDRESS = "INSERT_ACCOUNT_ADDRESS" PAS_UNITS = 10_000_000_000
def main(): # Connect to Polkadot Hub substrate = SubstrateInterface(url=POLKADOT_HUB_RPC)
print("Connected to Polkadot Hub")
print(f"\nQuerying account: {ACCOUNT_ADDRESS}\n")
# Query account information account_info = substrate.query( module="System", storage_function="Account", params=[ACCOUNT_ADDRESS] )
# Display account information print("Account Information:") print("===================") print(f"Nonce: {account_info.value['nonce']}") print(f"Consumers: {account_info.value['consumers']}") print(f"Providers: {account_info.value['providers']}") print(f"Sufficients: {account_info.value['sufficients']}")
print("\nBalance Details:") print("================") free_balance = account_info.value["data"]["free"] reserved_balance = account_info.value["data"]["reserved"] frozen_balance = account_info.value["data"]["frozen"]
print(f"Free Balance: {free_balance} ({free_balance / PAS_UNITS} PAS)") print( f"Reserved Balance: {reserved_balance} ({reserved_balance / PAS_UNITS} PAS)" ) print(f"Frozen Balance: {frozen_balance} ({frozen_balance / PAS_UNITS} PAS)")
total = free_balance + reserved_balance print(f"\nTotal Balance: {total} ({total / PAS_UNITS} PAS)")
# Close connection substrate.close() print("\nDisconnected")
if __name__ == "__main__": main()Run the script:
python query_account.pyYou should see output similar to:
Prerequisites
- Rust toolchain (latest stable)
- Cargo package manager
Environment Setup
-
Create a new Rust project:
Terminal window cargo new subxt-query-account-example && cd subxt-query-account-example -
Install the Subxt CLI:
Terminal window cargo install subxt-cli@0.50.0 -
Download the Polkadot Hub metadata:
Terminal window subxt metadata --url INSERT_WS_ENDPOINT -o polkadot_testnet_metadata.scale -
Update
Cargo.tomlwith the required dependencies:Cargo.toml [package]name = "subxt-query-account-example"version = "0.1.0"edition = "2021"[[bin]]name = "query_account"path = "src/bin/query_account.rs"[dependencies]subxt = { version = "0.50.0" }tokio = { version = "1.36.0", features = ["macros", "rt"] }
Query Account Data
The following example queries account information including balance, nonce, and other account data.
Create a file at src/bin/query_account.rs and add the following code to it:
use std::str::FromStr;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";const ACCOUNT_ADDRESS: &str = "INSERT_ACCOUNT_ADDRESS";const PAS_UNITS: u128 = 10_000_000_000;
#[tokio::main(flavor = "current_thread")]async fn main() -> Result<(), Box<dyn std::error::Error>> { // Initialize the Subxt client let api = OnlineClient::<PolkadotConfig>::from_url(POLKADOT_TESTNET_RPC).await?;
// Anchor to the current block let at_block = api.at_current_block().await?;
println!("Connected to Polkadot Hub");
// Convert the account address into an AccountId32 let account = AccountId32::from_str(ACCOUNT_ADDRESS)?;
println!("\nQuerying account: {}\n", account);
// Query account information let account_storage = at_block .storage() .entry(polkadot_testnet::storage().system().account())?; let info = account_storage .fetch((account,)) .await? .decode()?;
// Display account information println!("Account Information:"); println!("==================="); println!("Nonce: {}", info.nonce); println!("Consumers: {}", info.consumers); println!("Providers: {}", info.providers); println!("Sufficients: {}", info.sufficients);
println!("\nBalance Details:"); println!("================"); println!( "Free Balance: {} ({} PAS)", info.data.free, info.data.free as f64 / PAS_UNITS as f64 ); println!( "Reserved Balance: {} ({} PAS)", info.data.reserved, info.data.reserved as f64 / PAS_UNITS as f64 ); println!( "Frozen Balance: {} ({} PAS)", info.data.frozen, info.data.frozen as f64 / PAS_UNITS as f64 );
let total = info.data.free + info.data.reserved; println!( "\nTotal Balance: {} ({} PAS)", total, total as f64 / PAS_UNITS as f64 );
println!("\nDisconnected");
Ok(())}Run the script:
cargo run --bin query_accountYou should see output similar to:
Understanding Account Data
Section titled “Understanding Account Data”When querying account information, you'll receive several key fields:
- Nonce: The number of transactions sent from this account, used to prevent replay attacks.
- Consumers: The number of modules depending on this account's existence.
- Providers: The number of modules providing for this account's existence.
- Sufficients: The number of modules that allow this account to exist on its own.
- Free Balance: The transferable balance available for transactions.
- Reserved Balance: Balance that is locked for specific purposes (staking, governance, etc.).
- Frozen Balance: Balance that cannot be used for transfers but may be used for other operations.
The total balance is the sum of free and reserved balances.
Where to Go Next
Section titled “Where to Go Next”-
Query On-Chain State
Explore other types of storage queries.
-
Send Transactions
Learn how to construct and submit transactions.