system_properties - Bifrost RPC Method
Get chain properties on Bifrost 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 Bifrost, 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 Bifrost? Build on Polkadot's largest liquid staking appchain with 60% DOT LST market share and $125M+ TVL with first LST governance on OpenGov, 60% DOT market share, Hyperbridge ETH integration, and 500K DOT treasury support.
When to Use This Method
system_properties is essential for liquid staking developers, DeFi builders, and teams requiring cross-chain yield solutions:
- Token Formatting -- Get the correct decimals and symbol to display human-readable balances on Bifrost
- Address Validation -- Retrieve the SS58 prefix to encode and validate addresses for omnichain liquid staking (vDOT, vKSM, vGLMR, vMOVR, vASTR), cross-chain vToken governance, and DOT/ETH liquidity bridging
- 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 Bifrost. Identify the client software powering your node for diagnostics, compatibility checks, and infrastructure management.
author_submitExtrinsic
Submit a signed extrinsic to Bifrost for inclusion in a block. Broadcast transactions for token transfers, staking operations, governance votes, and smart contract calls.