Skip to content

Repository files navigation

Substrate4J

A full-featured, statically-typed Java library for Substrate-based blockchains

Interact with Polkadot, Kusama, and any Substrate chain — construct and submit extrinsics, subscribe to storage and events, and manage keys — all in pure Java, with full type safety and no native bindings.

Java License

Features

  • Fully static and type-safe APIs and types for safe, compile-time-checked chain interaction
  • Chain-specific clients tailored to each network's runtime, eliminating ambiguity
  • Most types auto-generated from on-chain metadata, with handwritten types where needed
  • Continuously updated to track the latest runtimes of supported networks
  • it covers the full spectrum of chain interaction
  • Construct, sign, and submit extrinsics (transactions)
  • Read and subscribe to storage items
  • Access pallet constants
  • Subscribe to runtime events
  • Built on the new Polkadot JSON-RPC spec
  • 100% native Java — no JNI, no native bindings required
  • Full support for SR25519, Ed25519, and ECDSA key pairs, BIP-39 mnemonics and Substrate-style key derivation
  • A complete, fully tested SCALE codec for encoding and decoding
  • Fully async and high-performance, built for non-blocking, high-throughput applications

Getting Started

connect, subscribe to blocks, and query an account balance:

// Create an API instance to interact with the network
PolkadotApi api = PolkadotApi.create("wss://rpc.example.io");

// The api exposes two sets of interfaces:
// - chain():   generic, non-runtime-aware primitives
// - runtime(): the fully typed runtime API for this chain

// Subscribe to finalized blocks
api.chain().finalizedBlocks().subscribe(block -> {
    System.out.printf("number: %d, hash: %s, parentHash: %s\n",
            block.number(), block.hash(), block.parentHash());
});

// Read the balance of an account
AccountId32 accountId32 = AccountId32.fromSs58("138PvUNqAtUWL9tiaJkt9cBDttXFf2Uih2rkQEUhU5zzHFwH");
StorageValue accountInfo =
        api.runtime().system().storage.account(accountId32).query().block();

System.out.printf("balance: %s\n", accountInfo.value().data().free());

Overview

Create an API Instance

PolkadotApi api = PolkadotApi.create("wss://rpc.example.io");

api connects you to the network. From there, two entry points give you everything:

  • api.chain() — generic, non-runtime-aware chain primitives (block streams, raw storage etc.)
  • api.runtime() — the full, statically typed runtime API for your specific chain

Subscribe to Finalized Blocks

Flux<Block> stream = api.chain().finalizedBlocks();
stream.subscribe(block -> 
        System.out.printf("number: %d, hash: %s, parentHash: %s\n",
            block.number(), block.hash(), block.parentHash())
        );

Read Pallet Constants

// Runtime constants are accessed as plain Java fields, fully typed:
RuntimeVersion version = api.runtime().system().constants.VERSION;
System.out.printf("specName: %s, specVersion: %s, implVersion: %s%n",
        version.specName(), version.specVersion(), version.implVersion());

Read Storage

// Reading the current block finalized number from the `System` pallet:
StorageValue<Void, U32> number = api.runtime().system().storage.number().query().block();
System.out.println(number.value());

Subscribe to Storage

// storage live subscription:
Flux<StorageValue<Void, U32>> stream = api.runtime().system().storage.number().watch();
stream.subscribe(n -> System.out.println(n.value()));

Subscribe to Runtime Events

// watch specific events from any pallet:
api.runtime().system().event.extrinsicSuccess().watch().subscribe(System.out::println);

Construct, Sign and Submit Extrinsics (Transactions)

Substrate4J supports all three Substrate cryptographic schemes natively, SR25519, Ed25519, and ECDSA; implemented in pure Java with no JNI or native bindings.

// Create a key pair from a mnemonic phrase:
SR25519Pair pair = SR25519Pair.factory()
    .fromPhrase("whale supreme diet sheriff income silk pulse mention dizzy parent rookie veteran", null)
    .f0();

// Or use a Substrate-style secret string (ED25519Pair and ECDSAPair are also supported):
SR25519Pair pair = SR25519Pair.factory().fromString("//Alice", null);

// Construct, sign, and submit the extrinsic:
SentExtrinsic<RuntimeEvent> sent = api.runtime().system().call
    .remarkWithEvent("I am using Substrate4j to send this extrinsic!".getBytes())
    .signAndSend(pair);

// sent can be used to listen to extrinsic lifecycle events and also events it emmit in runtime 
// Subscribe to lifecycle events (Validated, BestChainBlockIncluded, Finalized and so on):
sent.lifecycleEvents().subscribe(e -> System.out.printf("Lifecycle: %s", e));

// And subscribe to the runtime events emitted by the extrinsic:
sent.runtimeEvents().subscribe(e -> System.out.printf("Runtime event: %s", e));

Installation

Each supported network has its own generated client artifact, versioned against the runtime specVersion it was built from (r<specVersion>.<build version>-c<core-version>). Add the client for the network you want to interact with:

Polkadot

Maven

<dependency>
    <groupId>org.substrate4j</groupId>
    <artifactId>polkadot</artifactId>
    <version>r2003000.0-c0.0.2</version>
</dependency>

Gradle

implementation 'org.substrate4j:polkadot:r2003000.0-c0.0.2'

Kusama

Maven

<dependency>
    <groupId>org.substrate4j</groupId>
    <artifactId>kusama</artifactId>
    <version>r2003000.0-c0.0.2</version>
</dependency>

Gradle

implementation 'org.substrate4j:kusama:r2003000.0-c0.0.2'

Polkadot Asset Hub

Maven

<dependency>
    <groupId>org.substrate4j</groupId>
    <artifactId>assethub</artifactId>
    <version>r2003001.0-c0.0.2</version>
</dependency>

Gradle

implementation 'org.substrate4j:assethub:r2003001.0-c0.0.2'

Project Modules

Module Description
bip39 Complete BIP-39 implementation; mnemonic generation, validation, and seed derivation
clients Generated network clients; one per supported chain, built from runtime metadata
common Shared types and utilities used across modules
core RPC layer (legacy and new Polkadot JSON-RPC spec definitions), ChainApi, extrinsic encoding/decoding, storage operations, runtime API calls, and shared types such as Era
crypto Hashing, key pairs (SR25519, Ed25519, ECDSA), key derivation (Substrate secret strings), and SS58 codec
gen Code generator; produces a typed runtime client from chain metadata for each network
merlin Pure Java port of dalek-cryptography/merlin, the transcript protocol used by SR25519
metadata Substrate runtime metadata types for v14, v15, and v16, mapped to an internal IR
scale Full SCALE codec; type metadata expressed as STN (Scale Type Notation), embeddable via annotations
sr25519 Complete SR25519 signature scheme (schnorrkel); native Java, no JNI
ss58-registry SS58 prefix registry, generated from the upstream JSON source

Supported Networks

  • Polkadot (Relay Chain)
  • Kusama
  • Polkadot Asset Hub

Support for additional Substrate-based chains will be introduced once the project reaches a stable release.

About

Interact with Polkadot (Substrate based nodes) in Java

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages