Docs

state_getMetadata - Bittensor RPC Method

Get runtime metadata on Bittensor. Essential for decoding storage, building extrinsics, and discovering available pallets and calls on the decentralized machine intelligence network built around subnets, TAO staking, and validator-miner coordination.

Returns the runtime metadata for Bittensor as a SCALE-encoded hex string. Metadata describes all available pallets, storage items, calls, events, errors, and type definitions — everything needed to interact with the chain programmatically.

Why Bittensor? Build on the decentralized machine intelligence network built around subnets, TAO staking, and validator-miner coordination with Yuma Consensus, subnet-based specialization, dual Substrate and EVM surfaces, and onchain incentive coordination.

When to Use This Method

state_getMetadata is essential for AI/ML developers, subnet operators, and teams building decentralized machine learning applications:

  • Runtime Introspection — Discover available pallets, calls, and storage items on Bittensor
  • Extrinsic Building — Get call signatures and type information for constructing transactions for decentralized AI inference, subnet-specific AI models, TAO staking, and cross-subnet AI collaboration
  • Storage Key Generation — Build correct storage keys from metadata type definitions
  • Client Generation — Auto-generate typed APIs and SDKs from the runtime metadata
  • Upgrade Awareness — Detect metadata changes after runtime upgrades

Code Examples

Common Use Cases

1. Discover Available Pallets and Calls

Explore what functionality is available on Bittensor:

JavaScript
async function explorePallets(api) {
  const metadata = await api.rpc.state.getMetadata();
  const pallets = metadata.asLatest.pallets;

  for (const pallet of pallets) {
    const name = pallet.name.toString();
    const hasCalls = pallet.calls.isSome;
    const hasStorage = pallet.storage.isSome;
    const hasEvents = pallet.events.isSome;

    console.log(`${name}: calls=${hasCalls} storage=${hasStorage} events=${hasEvents}`);
  }
}

2. Build Storage Keys from Metadata

Generate correct storage keys for querying chain state:

JavaScript
import { xxhashAsHex } from '@polkadot/util-crypto';

function buildStorageKey(palletName, storageName) {
  const palletHash = xxhashAsHex(palletName, 128);
  const storageHash = xxhashAsHex(storageName, 128);

  return palletHash + storageHash.slice(2); // Concatenate without duplicate 0x
}

// Example: Build key for System.Account storage
const key = buildStorageKey('System', 'Account');
console.log('Storage prefix key:', key);

3. Metadata Version Tracking

Track metadata changes across runtime upgrades on Bittensor:

JavaScript
async function compareMetadataVersions(api, blockA, blockB) {
  const hashA = await api.rpc.chain.getBlockHash(blockA);
  const hashB = await api.rpc.chain.getBlockHash(blockB);

  const metaA = await api.rpc.state.getMetadata(hashA);
  const metaB = await api.rpc.state.getMetadata(hashB);

  const palletsA = new Set(metaA.asLatest.pallets.map(p => p.name.toString()));
  const palletsB = new Set(metaB.asLatest.pallets.map(p => p.name.toString()));

  const added = [...palletsB].filter(p => !palletsA.has(p));
  const removed = [...palletsA].filter(p => !palletsB.has(p));

  console.log('Added pallets:', added);
  console.log('Removed pallets:', removed);
}

Error Handling

Error CodeDescriptionSolution
-32603Internal errorNode may be syncing — retry with backoff
-32602Invalid paramsVerify block hash is valid hex with 0x prefix
-32601Method not foundVerify the node supports this RPC method
-32005Rate limit exceededCache metadata locally — it only changes on runtime upgrades