{"id":8689,"library":"substrate-interface","title":"Substrate Interface","description":"The `substrate-interface` library provides a Pythonic way to interact with Substrate-based blockchain nodes, including Polkadot and Kusama. It supports both traditional RPC connections and lightweight client functionality via Smoldot integration introduced in v1.8.0. The library enables querying chain state, submitting extrinsics, and managing subscriptions. It is actively maintained with frequent updates, currently at version 1.8.1.","status":"active","version":"1.8.1","language":"en","source_language":"en","source_url":"https://github.com/polkascan/py-substrate-interface","tags":["blockchain","substrate","polkadot","web3","rpc","lightclient","cryptocurrency"],"install":[{"cmd":"pip install substrate-interface","lang":"bash","label":"Base installation"},{"cmd":"pip install \"substrate-interface[lightclient]\"","lang":"bash","label":"With Smoldot light client support"},{"cmd":"pip install \"substrate-interface[sr25519]\"","lang":"bash","label":"With SR25519 signing support"},{"cmd":"pip install \"substrate-interface[ed25519]\"","lang":"bash","label":"With Ed25519 signing support"}],"dependencies":[{"reason":"Core SCALE encoding/decoding for Substrate data types.","package":"scale-codec","optional":false},{"reason":"Required for establishing WebSocket RPC connections to Substrate nodes.","package":"websocket-client","optional":false},{"reason":"Utility functions, frequently updated and can cause conflicts with other libraries.","package":"eth-utils","optional":false},{"reason":"Logging library.","package":"loguru","optional":false},{"reason":"Functional programming tools.","package":"toolz","optional":false},{"reason":"XXH64 hash algorithm implementation.","package":"xxh64","optional":false},{"reason":"Elliptic Curve Digital Signature Algorithm implementation.","package":"ecdsa","optional":false},{"reason":"Provides a Rust-based WebAssembly light client for embedded node connectivity. Requires `[lightclient]` extra.","package":"smoldot","optional":true},{"reason":"SR25519 cryptography library for signing operations. Requires `[sr25519]` extra.","package":"py-sr25519","optional":true},{"reason":"Ed25519 cryptography library for signing operations. Requires `[ed25519]` extra.","package":"py-ed25519","optional":true}],"imports":[{"symbol":"SubstrateInterface","correct":"from substrateinterface import SubstrateInterface"}],"quickstart":{"code":"import os\nfrom substrateinterface import SubstrateInterface\n\n# Connect to a public Polkadot node by default\n# Override with environment variable SUBSTRATE_NODE_URL if needed\nnode_url = os.environ.get('SUBSTRATE_NODE_URL', 'wss://rpc.polkadot.io')\n\ntry:\n    substrate = SubstrateInterface(\n        url=node_url\n    )\n\n    print(f\"Connected to chain: {substrate.chain}\")\n    print(f\"Node name: {substrate.node_name}\")\n    print(f\"Node version: {substrate.node_version}\")\n    print(f\"Current block number: {substrate.chain_head}\")\n\n    # Example: Query account balance for a well-known test address (Alice)\n    # Override with environment variable POLKADOT_ALICE_ADDRESS if needed\n    alice_address = os.environ.get('POLKADOT_ALICE_ADDRESS', '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')\n    \n    # The 'System' module and 'Account' storage map are standard across Substrate chains.\n    # The exact structure of the account info might vary slightly by chain/runtime version.\n    result = substrate.query(\n        module='System',\n        function='Account',\n        params=[alice_address]\n    )\n    \n    # Accessing the free balance, typically found under 'data' and 'free'.\n    # Assuming 10 decimal places for Polkadot for display purposes.\n    # The '.value' attribute extracts the raw integer.\n    free_balance = result['data']['free'].value\n    print(f\"Balance for {alice_address}: {free_balance / 10**10} DOT\")\n\nexcept ConnectionRefusedError:\n    print(f\"Error: Connection refused. Is the node running or accessible at {node_url}?\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\nfinally:\n    if 'substrate' in locals() and substrate.is_connected:\n        substrate.close()","lang":"python","description":"This quickstart connects to a public Polkadot RPC endpoint, queries the chain and node information, and then retrieves the balance for a well-known test address. It demonstrates basic connection and state querying. Ensure you have network access to the specified node URL."},"warnings":[{"fix":"Upgrade `substrate-interface` to the latest version to ensure compatibility. If conflicts persist, consider using a dedicated virtual environment for your project or explicitly pinning `eth-utils` to a version compatible with all your installed libraries (e.g., `pip install \"eth-utils<6\"` if other libraries require earlier versions, but this might break `substrate-interface`).","message":"The `eth-utils` dependency frequently receives updates and has tight version pinning, which can lead to conflicts if other libraries in your environment require a different, incompatible version range.","severity":"gotcha","affected_versions":"All versions, particularly around major `eth-utils` bumps (e.g., v1.7.9, v1.7.11, v1.8.0)"},{"fix":"Always keep `substrate-interface` updated to the latest stable version to ensure compatibility with the most recent Substrate runtime metadata. Check release notes for specific metadata version support.","message":"Substrate runtimes (and thus their metadata) are constantly evolving. Older versions of `substrate-interface` may not correctly parse or interact with newer runtime metadata (e.g., MetadataV15, Ink! V5 contracts) and vice-versa.","severity":"breaking","affected_versions":"Pre-v1.7.10 (Ink! V5), Pre-v1.8.0a (MetadataV15), and potentially others with significant runtime changes."},{"fix":"Refer to the latest `substrate-interface` documentation and examples. Upgrade the library to benefit from updated and supported methods. If migrating from older code, review the changelog for removed or altered functionality.","message":"Certain older RPC calls or methods for interacting with node metadata may be deprecated or removed in newer versions of `substrate-interface` or on newer Substrate runtimes, leading to `ModuleNotFound` or `AttributeError`.","severity":"deprecated","affected_versions":"Versions prior to v1.7.6, where deprecated calls were explicitly removed; continuous evolution."}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install `substrate-interface` with the `lightclient` extra: `pip install \"substrate-interface[lightclient]\"`.","cause":"The `smoldot` light client dependency is optional and not installed by default with the base `pip install substrate-interface` command.","error":"ModuleNotFoundError: No module named 'smoldot_module_py'"},{"fix":"Verify the Substrate node is running and accessible at the specified URL (e.g., `ws://127.0.0.1:9944` or `wss://rpc.polkadot.io`). Check firewall rules or ensure the node is properly configured to accept connections.","cause":"The WebSocket connection to the Substrate node was unexpectedly terminated or could not be established. This often indicates the node is offline, inaccessible, or the URL is incorrect.","error":"websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed."},{"fix":"Ensure the Substrate node is running and listening on the expected address and port. Verify the `url` parameter in `SubstrateInterface()` is correct. Check local and network firewall configurations.","cause":"The attempt to connect to the Substrate node at the specified address and port was actively refused. This typically means there is no service listening on that port, or a firewall is blocking the connection.","error":"ConnectionRefusedError: [Errno 111] Connection refused"},{"fix":"Ensure `substrate-interface` is updated to the latest version to match the connected node's runtime metadata. Review the specific Substrate chain's documentation or use `substrate.get_metadata_dict()` to inspect the exact structure of modules, calls, and storage maps.","cause":"When querying chain state or decoding extrinsic results/events, an expected dictionary key (representing a module, function, or data field) was not found. This often points to a metadata mismatch or an incorrect understanding of the runtime's data structure.","error":"KeyError: 'some_expected_key_here'"}]}