system_properties - Kusama RPC Method
Get chain properties on Kusama including token symbol, decimals, and the address-format prefix when the chain exposes one. Essential for token formatting, wallet configuration, and address handling.
Returns the chain-specific properties for Kusama, including the native token symbol, token decimals, and the address-format prefix when the chain exposes one. This information is critical for correctly formatting balances, validating addresses, and configuring wallets.
Why Kusama? Build on Polkadot's canary network for real-world testing with live economic conditions with 7-day governance cycles (vs 1 month on Polkadot), lower bonding requirements, live KSM token economy, and first-to-market feature testing.
When to Use This Method
system_properties is essential for experimental dApp developers, parachain teams, and early adopters validating new features:
- Token Formatting -- Get the correct decimals and symbol to display human-readable balances on Kusama
- Address Validation -- Retrieve the SS58 prefix to encode and validate addresses for parachain experimentation, early feature deployment, and production-grade testing with real value
- Wallet and dApp Configuration -- Dynamically configure your UI with the correct token symbol, decimals, and address format
- Multi-Chain Support -- Automatically adapt your application to different Substrate chains without hardcoding properties
Code Examples
Common Use Cases
1. Human-Readable Balance Formatting
Format raw on-chain balances into human-readable token amounts:
import { ApiPromise, WsProvider } from '@polkadot/api';
import { BN } from '@polkadot/util';
async function formatBalance(api, rawBalance) {
const properties = await api.rpc.system.properties();
const raw = properties.toJSON();
const decimalsRaw = raw.tokenDecimals;
const symbolRaw = raw.tokenSymbol;
const decimals = Array.isArray(decimalsRaw) ? decimalsRaw[0] : decimalsRaw;
const symbol = Array.isArray(symbolRaw) ? symbolRaw[0] : symbolRaw;
const divisor = new BN(10).pow(new BN(decimals));
const whole = new BN(rawBalance).div(divisor);
const fractional = new BN(rawBalance).mod(divisor).toString().padStart(decimals, '0');
return `${whole}.${fractional.slice(0, 4)} ${symbol}`;
}
// Example output depends on the chain's live token symbol and decimals.2. Dynamic Wallet Configuration
Auto-configure your wallet or dApp based on chain properties:
async function configureWallet(endpoint) {
const provider = new WsProvider(endpoint);
const api = await ApiPromise.create({ provider });
const [chain, properties] = await Promise.all([
api.rpc.system.chain(),
api.rpc.system.properties()
]);
const raw = properties.toJSON();
const symbolsRaw = raw.tokenSymbol;
const decimalsRaw = raw.tokenDecimals;
const symbols = Array.isArray(symbolsRaw) ? symbolsRaw : [symbolsRaw];
const decimals = Array.isArray(decimalsRaw) ? decimalsRaw : [decimalsRaw];
const ss58Format = raw.ss58Format ?? raw.SS58Prefix ?? null;
const config = {
chainName: chain.toString(),
ss58Format,
tokens: symbols.map((symbol, idx) => ({
symbol,
decimals: decimals[idx] ?? decimals[0],
}))
};
console.log('Wallet configured for:', config.chainName);
console.log('Native token:', config.tokens[0].symbol, `(${config.tokens[0].decimals} decimals)`);
console.log('Address format SS58:', config.ss58Format ?? 'not exposed');
await api.disconnect();
return config;
}3. SS58 Address Encoding and Validation
Use the SS58 prefix to properly encode addresses for the target chain:
import { encodeAddress, decodeAddress } from '@polkadot/util-crypto';
async function formatAddressForChain(api, genericAddress) {
const properties = await api.rpc.system.properties();
const raw = properties.toJSON();
const ss58Format = raw.ss58Format ?? raw.SS58Prefix;
if (ss58Format == null) {
throw new Error('This chain does not expose an SS58 prefix through system_properties.');
}
// Convert any SS58 address to this chain's format
const publicKey = decodeAddress(genericAddress);
const chainAddress = encodeAddress(publicKey, ss58Format);
console.log(`Address on ${ss58Format}: ${chainAddress}`);
return chainAddress;
}Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32603 | Internal error | Node may be starting up -- retry after delay |
| -32005 | Rate limit exceeded | Reduce request frequency or implement client-side rate limiting |
| Connection refused | Node unreachable | Verify the RPC endpoint URL and that the node is running |
| Empty or alternate result fields | Chain spec missing properties or using SS58Prefix | Normalize scalar vs array values and fall back to SS58Prefix when ss58Format is absent |
Related Methods
system_chain-- Get the chain namesystem_name-- Get the node implementation namesystem_version-- Get the node implementation versionstate_getMetadata-- Get full runtime metadata including pallet definitionsrpc_methods-- List all available RPC methods
system_name
Get the node implementation name on Kusama. Identify the client software powering your node for diagnostics, compatibility checks, and infrastructure management.
author_submitExtrinsic
Submit a signed extrinsic to Kusama for inclusion in a block. Broadcast transactions for token transfers, staking operations, governance votes, and smart contract calls.