21-dot-dev/swift-bitcoinkernel
Swift package for Bitcoin consensus validation, optionally embedding a full Bitcoin node in-process. The BitcoinKernel product wraps libbitcoinkernel from Bitcoin Core; the `Bit
Contents
Which product?
| Goal | Product | Demo app | Getting started | |------|---------|----------|-----------------| | Validate consensus or sync a chain, no networking | BitcoinKernel | KernelApp | Guide | | Run a full node with in-process RPC | Bitcoin | NodeApp | Guide |
Features
- Wrap Bitcoin Core's
libbitcoinkernelfor consensus validation without a daemon - Embed
bitcoindin-process via a typedBitcoinConfigbuilder andDaemonlifecycle - Cover all 171 Bitcoin Core v31.0 JSON-RPCs through an async/await
RPCClient - Route RPCs through pluggable transports: direct in-process, HTTP, cookie-file, or auto-detect
- Ship a
BlockchainSyncengine and aBlockSourceprotocol for custom block providers - Track chain-sync progress with KVO-observable
Foundation.Progressfor SwiftUI bindings andBGContinuedProcessingTaskbudgets - Route block downloads or RPC traffic through Tor with a SOCKS5-configured
URLSession
Installation
Add to your Package.swift:
.package(url: "https://github.com/21-DOT-DEV/swift-bitcoinkernel.git", exact: "0.1.0"),Include BitcoinKernel in your target:
.target(name: "<target>", dependencies: [
.product(name: "BitcoinKernel", package: "swift-bitcoinkernel"),
]),For the Bitcoin product (embedded daemon and RPC client), opt your target into Swift's C++ interoperability mode:
.target(name: "<target>",
dependencies: [
.product(name: "Bitcoin", package: "swift-bitcoinkernel"),
],
swiftSettings: [
.interoperabilityMode(.Cxx),
]
),Or use Xcode: File → Add Packages…, then enter https://github.com/21-DOT-DEV/swift-bitcoinkernel. For the Bitcoin product in Xcode, set C++ and Objective-C Interoperability to C++/Objective-C++ in the target's Build Settings.
Pin with a version tag. At a tagged release the package excludes its development plugins (tuist, subtree, docc); pinning a commit or branch instead resolves that full toolchain into your dependency graph.
Package Traits
The package uses SE-0450 Package Traits to gate optional functionality. No traits are enabled by default.
wallet
Opts into Bitcoin Core's wallet RPCs (createwallet, sendtoaddress, walletProcessPSBT, etc.). Off by default to keep the dependency graph small.
.package(
url: "https://github.com/21-DOT-DEV/swift-bitcoinkernel.git",
exact: "0.1.0",
traits: ["wallet"]
),[!NOTE] The
wallettrait is a dependency and binary-size optimization, not a security boundary. Underswift buildthe trait is honored fully. Under Xcode it is not: Xcode doesn't resolve SwiftPM trait conditions, so wallet sources guarded by#if Xcode || ENABLE_WALLETalways compile and the wallet API surface is always present. If your threat model requires wallet code to be absent, do not rely on the trait; run the daemon with-disablewallet.
Platform notes
- tvOS builds
BitcoinKernelonly. TheBitcoinproduct depends onexecvp(marked__TVOS_PROHIBITED) and does not compile for tvOS. - Linux consumers of
Bitcoinlink the system SQLite. Installlibsqlite3-dev(Debian/Ubuntu) orsqlite-devel(Fedora/RHEL). - Storage: regtest and signet stay in the tens of MB. Pruned mainnet keeps roughly 12 GB of UTXO chainstate plus the pruned block target (≥ 550 MiB). A full mainnet node is ~700 GB and growing.
Usage Examples
Validate consensus with BitcoinKernel
Boot the validation engine against a fresh regtest data directory and read the tip height to confirm the chainstate loaded. Context(chain:) wraps the options builder for the common case:
import BitcoinKernel
import Foundation
let context = try Context(chain: .regtest)
let dataDirectory = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString)
.path(percentEncoded: false)
let manager = try ChainstateManager(context: context, dataDirectory: dataDirectory)
print(manager.bestEntry.height) // 0 on a fresh regtest directory→ Full guide: Getting Started — BitcoinKernel
Embed bitcoind and query it with RPCClient
Start an embedded bitcoind on regtest and call a typed JSON-RPC method. Cookie authentication derives the endpoint and credentials from the config, so they are supplied once and no RPC password lives in your code:
import Bitcoin
import Foundation
// Bitcoin Core requires the data directory to exist before startup.
let dataDir = URL.temporaryDirectory.appending(path: "bitcoin-regtest")
try FileManager.default.createDirectory(at: dataDir, withIntermediateDirectories: true)
let config = BitcoinConfig
.regtest()
.server()
.dataDir(dataDir.path(percentEncoded: false))
let client = try await Daemon.startAndConnect(with: config)
let info = try await client.getBlockchainInfo()
print("Chain: \(info.chain), blocks: \(info.blocks)")
_ = try await client.stop()
Daemon.waitUntilStopped()→ Full guide: Getting Started — Bitcoin
Demo Apps
Two SwiftUI apps in the Projects/ Tuist workspace exercise the package end to end. NodeApp drives the embedded bitcoind lifecycle, the typed RPCClient, and an optional Tor SOCKS proxy. KernelApp runs a BitcoinKernel chain sync through BlockchainSync over an Esplora block source.
swift package --disable-sandbox tuist generate -p Projects/ --no-open
open Projects/Bitcoin.xcworkspacePick the NodeApp or KernelApp scheme and run. Projects/README.md has the full tour, including the Tor wiring and the macOS/iOS build-and-test commands.
Documentation
The DocC catalogs for Bitcoin and BitcoinKernel cover the embedded daemon and consensus-validation surfaces:
- Getting Started — Bitcoin — full node walkthrough from
Daemon.startthrough the first RPC round-trip - Getting Started — BitcoinKernel — boot
libbitcoinkernelwith aContext,ChainstateManagerOptions, andChainstateManager - Embedding BitcoinKernel on iOS — shipping the consensus engine inside an iPhone, iPad, or Apple Silicon Mac app
Build the hyperlinked archive locally:
swift package generate-documentation --target Bitcoin
swift package generate-documentation --target BitcoinKernelEach tagged release also publishes a downloadable .doccarchive.zip on the corresponding GitHub Release.
Contributing
Contributions are welcome. Read AGENTS.md for project architecture and the subtree extraction flow, Projects/AGENTS.md for the Tuist workspace, and the 21-DOT-DEV contributing guidelines for branching conventions.
[!IMPORTANT] Files under
Sources/{bitcoind,libbitcoinkernel,secp256k1,leveldb,minisketch,crc32c}/are extracted from upstream and overwritten on every subtree sync. Local changes for SPM/embedded use live inpatches/— seepatches/README.md.
Security
For vulnerability reports, see SECURITY.md. Patches to the vendored Bitcoin Core never touch consensus code; see the patch policy.
License
Released under the MIT License — see LICENSE. Vendored dependencies carry their own licenses:
- Bitcoin Core — MIT
- LevelDB — BSD-3-Clause (Google)
- crc32c — BSD-3-Clause (Google)
- secp256k1 — MIT
- minisketch — MIT
Package Metadata
Repository: 21-dot-dev/swift-bitcoinkernel
Default branch: main
README: README.md