corepc
Bitcoin Core JSON-RPC support for Rust. Replaces the archived
rust-bitcoincore-rpc.
Repo: github.com/rust-bitcoin/corepc. As of September 2026 the GitHub
README carries a "This repository has moved" banner pointing at the
org's own Forgejo instance, git.rust-bitcoin.org/rust-bitcoin/corepc;
issues and PRs belong there, crates still publish to crates.io as
normal.
Read the upstream guidance first
The README is explicit and unusual, so do not skip it:
If you require a JSON RPC client in production software it is expected you write your own and only use the
corepc-typescrate in your dependency graph.Please do not use
corepc-clientin production and raise bugs, issues, or feature requests.
So the supported split is: corepc-types is the production
dependency; corepc-client exists to exercise those types and to
drive nodes in tests. Meanwhile the archived rust-bitcoincore-rpc
README (archived 25 November 2025) tells its users to switch to
corepc-client. Both statements are upstream; reconcile them by taking
the types crate plus a thin client of your own for a service, and
corepc-client for tests and tooling.
Crates (versions as of September 2026)
| Crate | Version | Released | Role |
|---|---|---|---|
corepc-types | 0.15.0 | 18 June 2026 | RPC response types |
corepc-client | 0.16.0 | 18 June 2026 | Blocking / async client |
bitcoind | 0.41.0 | 18 June 2026 | Regtest node harness |
jsonrpc | 0.20.1 | 27 May 2026 | JSON-RPC 2.0 plumbing |
bitreq | 0.3.7 | 28 May 2026 | Minimal HTTP client |
electrsd | 0.41.0 | 18 June 2026 | Regtest electrs harness |
MSRV across the workspace is Rust 1.75.0; the crates build against
bitcoin = "0.32.0". Releases came roughly fortnightly from April to
June 2026 (client 0.11.0 → 0.16.0); nothing has been tagged since the
18 June 2026 wave.
Version-aware design
The whole point of the repo is that a Core RPC response shape depends on
which Core you are talking to. corepc-types therefore has one module
per Core major - v17 through v31 - holding the literal JSON shape
that version returns, plus a model module of version-agnostic types.
Convert with into_model():
use corepc_client::client_sync::v31::Client;
use corepc_client::client_sync::Auth;
// cargo add corepc-client --features client-sync
let client = Client::new_with_auth(
"http://127.0.0.1:8332",
Auth::UserPass("user".into(), "pass".into()),
)?;
let json = client.get_blockchain_info()?; // corepc_types::v31 shape
let info = json.into_model()?; // corepc_types::model shape
println!("{} at height {}", info.chain, info.blocks);
Client::new(url) exists for unauthenticated endpoints. Features:
client-sync (blocking) and client-async; neither is on by default.
The v31 client asserts the server version it was built for
(impl_client_check_expected_server_version!({ [310000] })), so pointing
a v31::Client at a v29 node fails loudly instead of mis-deserialising.
No crate here sniffs the peer's version for you - picking the right
module is the application's job.
Integration testing with bitcoind
[dev-dependencies]
bitcoind = { version = "0.41", features = ["latest", "download"] }
use bitcoind::BitcoinD;
let node = BitcoinD::from_downloaded()?; // needs the `download` feature
let info = node.client.get_blockchain_info()?;
assert_eq!(info.chain, "regtest");
// node killed on drop; datadir is a tempfile::TempDir
BitcoinD::new(exe) / BitcoinD::with_conf(exe, &conf) use a binary
already on the host instead. The crate re-exports version-specific types
as vtype and the model types as mtype.
Version features select which Core the harness expects, and they cascade downwards:
default = ["0_17_2"],latest = ["31_0"].- One pinned Core binary per supported major:
31_0→ 31.0,30_2→ 30.2,29_0→ 29.0, then28_2,27_2,26_2, ... back to0_17_2(as ofbitcoind0.41.0, June 2026). There is no30_0or30_1feature, excluded upstream because of a wallet migration bug. - No feature exists for Core 29.1-29.4, 30.3 or 31.1, although all of
those tags shipped (as of September 2026). Upstream's
Cargo.tomlcomment about supporting every minor of the latest three majors is stale;bitcoind/src/versions.rsis the authority. - Enabling several version features is not an error; the highest wins.
Migrating from rust-bitcoincore-rpc
rust-bitcoin/rust-bitcoincore-rpc was archived on 25 November 2025 with
bitcoincore-rpc frozen at 0.19.0 (May 2024) and its README recommending
corepc-client. The bitcoind crate name is the same crate lineage: it
was renamed to corepc-node and then renamed back to bitcoind in
0.37.0 (16 April 2026, PR #542), with the version number bumped past the
old standalone bitcoind releases. corepc-node is frozen at 0.12.0
(April 2026) - move to bitcoind 0.37.0+.
Shape differences to expect when porting:
- Responses are per-version types, not one universal struct. Add an
into_model()hop, or read thev3xfields directly. into_model()is fallible - Core returns-1in fields typed as numeric, and amounts have to survive the float round trip.- Method coverage is deliberately exhaustive - every documented RPC since client 0.9.0 (September 2025), plus hidden ones added in client 0.11.0 (April 2026) - so missing-method workarounds can go.
Common pitfalls
- Shipping
corepc-clientin a production service. Upstream says not to and will not take bug reports for it. - Mixing crate versions from different release waves.
corepc-client0.16.0 pinscorepc-types0.15.0 andbitcoind0.41.0 pinscorepc-client0.16.0 - take one wave. - Assuming
bitcoind's default feature targets a modern node: the default is0_17_2. Passlatestor an explicit version feature. downloadpulls a Core binary over the network at build time, which most sealed CI images will refuse. Pre-fetch and useBitcoinD::new(exe)there.- Choosing the client module by guesswork. Read
getnetworkinfoonce at startup and fail fast if the node is not the major you compiled for.