Skip to content

21-DOT-DEV/swift-bitcoinkernel

MIT License Apple Platforms Docker Builds Tuist Apps

₿ 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 Bitcoin product adds an embedded bitcoind and a typed async/await JSON-RPC client.

📚 BitcoinKernel · Bitcoin

Caution

Pre-1.0 (SemVer 0.y.z) — the public API may change at any release; pin with exact:. Mainnet operations move real value; test on regtest or signet first.

Contents

Features

  • Wrap Bitcoin Core's libbitcoinkernel for consensus validation without a daemon
  • Embed bitcoind in-process via a typed BitcoinConfig builder and Daemon lifecycle
  • 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 BlockchainSync engine and a BlockSource protocol for custom block providers
  • Track chain-sync progress with KVO-observable Foundation.Progress for SwiftUI bindings and BGContinuedProcessingTask budgets
  • 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.

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

Xcode doesn't resolve SwiftPM trait conditions for Swift settings. Wallet sources are guarded with #if Xcode || ENABLE_WALLET, so Xcode consumers always compile the wallet API surface regardless of the trait. The trait is honored fully under swift build.

Usage Examples

Validate consensus with BitcoinKernel

Boot the validation engine against a fresh regtest data directory and confirm the chainstate has loaded by reading the tip height:

import BitcoinKernel
import Foundation

let params = ChainParameters(.regtest)
let options = ContextOptions()
options.setChainParams(params)
let context = try Context(options: options)

let dataDirectory = FileManager.default.temporaryDirectory
    .appendingPathComponent(UUID().uuidString)
    .path(percentEncoded: false)

let managerOptions = try ChainstateManagerOptions(
    context: context,
    dataDirectory: dataDirectory
)
let manager = try ChainstateManager(options: managerOptions)

print(manager.bestEntry.height)  // 0 on a fresh regtest directory

→ Full guide: Getting Started — BitcoinKernel

Embed bitcoind and query it with RPCClient

Run an embedded bitcoind on regtest and call a typed JSON-RPC method:

import Bitcoin
import Foundation

// Demo credentials — username "111", password "222". Regtest only.
// Generate your own with Bitcoin Core's helper:
//     python3 share/rpcauth/rpcauth.py <username> <password>
let auth = RPCAuth(
    username: "111",
    salt: "14c1e13a71b7d6a4dab6c9d8f107bb5b",
    passwordHMAC: "73b9fbbd71dbbb1476efa6da7b37dde5111153a17ccb5fdef79537d276fd03d4"
)

// 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()
    .rpcAuth(auth)
    .server()
    .dataDir(dataDir.path(percentEncoded: false))

try Daemon.start(with: config)

// `Daemon.start(with:)` returns as soon as the daemon thread is launched.
// `bootstrap` polls until the RPC server is ready before the first call.
try await Daemon.bootstrap(
    url: URL(string: "http://127.0.0.1:18443")!,
    username: "111",
    password: "222"
)

let client = RPCClient(
    url: URL(string: "http://127.0.0.1:18443")!,
    username: "111",
    password: "222"
)

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.xcworkspace

Pick 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:

Build the hyperlinked archive locally:

swift package generate-documentation --target Bitcoin
swift package generate-documentation --target BitcoinKernel

Each 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 in patches/ — see patches/README.md.

Security

For vulnerability reports, see SECURITY.md.

License

Released under the MIT License — see LICENSE. Vendored dependencies carry their own licenses: