system_properties - Moonriver RPC Method
Get chain properties on Moonriver 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 Moonriver, 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 Moonriver? Build on the Moonbeam canary network on Kusama for real-world testing of EVM dApps with Moonbeam code ships here first, full EVM compatibility on Kusama, 80% fee burn mechanism, and XCM cross-chain messaging.
When to Use This Method
system_properties is essential for dApp developers testing on Kusama, early adopters, and teams requiring production-ready experimentation:
- Token Formatting -- Get the correct decimals and symbol to display human-readable balances on Moonriver
- Address Validation -- Retrieve the SS58 prefix to encode and validate addresses for production-grade dApp testing, early feature deployment, and Kusama-based EVM applications
- 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 Moonriver. Identify the client software powering your node for diagnostics, compatibility checks, and infrastructure management.
author_submitExtrinsic
Submit a signed extrinsic to Moonriver for inclusion in a block. Broadcast transactions for token transfers, staking operations, governance votes, and smart contract calls.