Skip to content
chainkit / signal · providers — · 24h fleet telemetry
p95 ·
non-custodial Bitcoin payments · funds settle to your wallet, not ours

Take Bitcoin payments.
Settled to your wallet.

chainkit is a non-custodial Bitcoin payment processor — think Stripe, except the money never touches us. Issue fiat-priced invoices in € or $, your customer pays in BTC, and it settles directly to your own wallet. Under 1% of settled volume, no custody, no chargebacks. You register an xpub — never a seed.

Start accepting Bitcoin
0custody
xpub-only, never seeds
<1%
of settled volume
0chargebacks
on-chain, final
non-custodial your wallet · your keys
MIT open-source Go SDK
same SDK routes RPC through mempool.space Blockstream BlockCypher Tatum Blockchain.com + 4
View on GitHub →
How it works · end to end

One invoice. Three points of view.

Watch a single payment move through all three parties — you the merchant, chainkit the rails, and your customer. Each step shows what happens and what that side gets. Play it, or click any step to replay it.

You issue a fiat-priced invoice — chainkit derives a fresh address from your xpub.

You the merchant
inv_8f2a1c pending
€49.00 0.00071 BTC
issued · awaiting payment
  • Fiat-priced invoices
  • HMAC-signed webhooks
  • Your wallet · no chargebacks
invoice
chainkit the rails
custody: none
ready xpub registered · rate locked
  • Fresh address per invoice
  • Watches the chain for you
  • Never holds your funds
Your customer the buyer
waiting for a payment link…
  • Just a link · no account
  • Pay with any wallet
  • Instant receipt
The payment processor · non-custodial by design

Bitcoin checkout. None of the custody.

Everything a Bitcoin merchant needs — invoices, receipts, webhooks, exports — with one line you won't find on Stripe: we never hold your money. Payments settle on-chain to the wallet behind your xpub, and the same Go SDK that powers your backend verifies each one.

Settles to your wallet

Register an xpub; every payment lands on-chain straight to you. We never hold, forward, or freeze funds. xprv/yprv/zprv are rejected at the API and the form.

Fiat-priced invoices

Price in € or $. chainkit locks the BTC amount at issuance and renders an immutable PDF receipt carrying your VAT id and tax breakdown.

HMAC-signed webhooks

Idempotent invoice creation; every callback is signed. Verify it in one SDK call — or let the SDK-side watcher see confirmations before the cloud does.

Fresh address per invoice

A new address is derived from your xpub for every invoice. No reuse means no address-clustering — customer privacy by default.

No chargebacks

On-chain settlement is final. No card-network reversals, no 120-day holds. Reconcile once and the money is yours.

EU-hosted, GDPR-ready

Customer PII redaction endpoint for "forget" requests, EU-based hosting and processor, CSV/JSON exports and a bulk receipts ZIP for quarter-end.

checkout.go · with chainkit/payment
non-custodial
1 // Your xpub. Funds settle straight to your wallet.
2 import "github.com/exapsy/chainkit/payment"
3
4 pay, _ := payment.New(payment.Config{
5 APIKey: os.Getenv("CHAINKIT_KEY"),
6 ProjectID: os.Getenv("CHAINKIT_PROJECT"),
7 Xpub: os.Getenv("MERCHANT_XPUB"), // xpub only — never a seed
8 })
9
10 // Fiat-priced — chainkit locks the BTC at issuance.
11 inv, _ := pay.CreateInvoice(ctx, payment.InvoiceParams{
12 AmountFiat: payment.EUR(4900), // €49.00
13 Reference: "order-1042",
14 })
15 // inv.Address → a fresh address from your xpub. No reuse.
16
17 // On the webhook — verify the signature, then trust it.
18 ev, err := payment.ParseWebhook(body, sig, secret)
19 if err != nil { return http.StatusUnauthorized }
20 // ev.Invoice.IsFinal ✓ — the sats are already in your wallet.
Like Stripe — minus the parts you didn't want
Custody Stripe holds your money, can freeze or claw it back chainkit never touches it — on-chain, straight to you
Fees cards ~2.9% + 30¢ per charge under 1% of settled volume — you pay when you settle
Reversals chargebacks land months later final the moment it confirms — reconcile once
The other half · one SDK, every RPC provider

And your blockchain calls never lock in.

The same SDK is a control plane for RPC. Declare a chain of providers; the scoring engine picks the healthiest one per call and fails over on its own. No cloud account required — it runs entirely in your Go process, and your calls never touch our wire.

chainkit router btc/mainnet
demo
234 req/min example traffic share · illustrative
  • mempool.space 142 ms 38%
  • blockstream 98 ms 27%
  • tatum 204 ms 18%
  • blockcypher 812 ms 5%
  • blockchain.com × 0%
  • bitref.com 256 ms 4%
  • coingecko 88 ms 5%
  • binance 71 ms 3%
scoring re-evaluates per call · circuit breaker active 8 providers
main.go · without chainkit
vendor-locked
1 // Tied to mempool.space's API surface. If they 5xx,
2 // rate-limit, or double the price — you rewrite every
3 // call site below.
4 import "github.com/mempool/client-go"
5
6 mempool := mempool.NewClient("https://mempool.space/api")
7
8 balance, err := mempool.GetBalance(ctx, addr)
9 utxos, err := mempool.GetUTXOs(ctx, addr)
10 txid, err := mempool.Broadcast(ctx, raw)
11
12 // ↑ Provider name appears 3× — change one client
13 // later means changing every line that touches it.
main.go · with chainkit
vendor-free
1 // One interface, three (or nine) providers.
2 // chainkit's scoring engine picks the healthiest one
3 // for each call. Add/remove providers in the builder.
4 import "github.com/exapsy/chainkit"
5
6 client, _ := chainkit.NewMixedProvidersBuilder().
7 WithBalanceFetcherChain(
8 chainkit.BalanceFetcherConfig{Fetcher: mempool, Priority: 1},
9 chainkit.BalanceFetcherConfig{Fetcher: blockstream, Priority: 2},
10 chainkit.BalanceFetcherConfig{Fetcher: blockcypher, Priority: 3},
11 ).
12 Build()
13
14 balance, err := client.GetBalance(ctx, addr)

Every routing strategy has a sweet spot — and a catch. Here's which to pick, and when it bites.

Pick a real-world situation below — chainkit tells you the best strategy for it and the one to avoid. Cost depends on where each strategy sends traffic: lean on free providers and you pay nothing, spread blindly and you feed paid ones. Live simulation of the SDK's selection strategies.

pick your situation
Cost-sensitive steady state live · touring
Best here Priority pins your top configured (free) provider and stays cache-warm — cheapest and most stable when nothing is wrong.
Watch out Round-robin sprays traffic across the paid providers at the bottom of your list, running up the biggest bill of the four.
↳ Least-loaded looks free here only because your fastest provider happens to be free — that flips the moment it isn’t (see “Peak load”).
live · 2 req/s per panel· 0 simulated
no weather · pool stable
provider pricing free · public API freemium · free quota then metered paid · billed from request 1 illustrative
Each panel lists your 8 providers in configured order — cheapest first, the way a cost-aware developer sets them up. Adaptive blends that order with live health, so it prefers your free providers and only reaches for a paid one when it has to.
Priority SelectionStrategyPriorityOnly
✓ best here
now
Best when one cheap provider covers your volume — pins it, stays cache-warm, cheapest and most stable in steady state.
Worst when your primary slows or throttles — it keeps hammering it until it hard-fails, so you eat the spike first.
  • mempool.space free 142ms public API · rate-limited under load 0 / 80
  • Blockstream free 82ms public API · rate-limited under load 0 / 80
  • Binance free 71ms public API · rate-limited under load 0 / 80
  • CoinGecko freemium 88ms 0 / 80
  • Tatum freemium 184ms 0 / 80
  • BlockCypher freemium 220ms 0 / 80
  • Bitref.com paid 196ms 0 / 80
  • Blockchain.com paid 245ms 0 / 80
est. cost/mo
measuring…
avg p50
stability
0sw
load balance
0%
Round-robin SelectionStrategyRoundRobin
⚠ watch out
now
Best when a traffic spike would blow any single free tier — even spread keeps each provider under quota, no hot-spots, no lock-in.
Worst when steady cost-sensitive traffic — blind to price, it feeds paid providers you never needed. Usually the biggest bill.
  • mempool.space free 142ms public API · rate-limited under load 0 / 80
  • Blockstream free 82ms public API · rate-limited under load 0 / 80
  • Binance free 71ms public API · rate-limited under load 0 / 80
  • CoinGecko freemium 88ms 0 / 80
  • Tatum freemium 184ms 0 / 80
  • BlockCypher freemium 220ms 0 / 80
  • Bitref.com paid 196ms 0 / 80
  • Blockchain.com paid 245ms 0 / 80
est. cost/mo
measuring…
avg p50
stability
0sw
load balance
0%
Adaptive SelectionStrategyAdaptive
now
Best when you want to ship one setting and forget it — follows the live health score, never the worst on any axis.
Worst when you have one hard single objective — a specialist (Priority for cost, Least-loaded for latency) beats the all-rounder on that number.
  • mempool.space free 142ms public API · rate-limited under load 0 / 80
  • Blockstream free 82ms public API · rate-limited under load 0 / 80
  • Binance free 71ms public API · rate-limited under load 0 / 80
  • CoinGecko freemium 88ms 0 / 80
  • Tatum freemium 184ms 0 / 80
  • BlockCypher freemium 220ms 0 / 80
  • Bitref.com paid 196ms 0 / 80
  • Blockchain.com paid 245ms 0 / 80
est. cost/mo
measuring…
avg p50
stability
0sw
load balance
0%
Least-loaded SelectionStrategyLeastLoaded
now
Best when latency is the product and one provider lags — routes to whoever is fastest right now and reroutes the instant it slows.
Worst when your fastest provider is paid or its free tier runs out — it piles traffic on, and the bill flips from cheapest to most expensive.
  • mempool.space free 142ms public API · rate-limited under load 0 / 80
  • Blockstream free 82ms public API · rate-limited under load 0 / 80
  • Binance free 71ms public API · rate-limited under load 0 / 80
  • CoinGecko freemium 88ms 0 / 80
  • Tatum freemium 184ms 0 / 80
  • BlockCypher freemium 220ms 0 / 80
  • Bitref.com paid 196ms 0 / 80
  • Blockchain.com paid 245ms 0 / 80
est. cost/mo
measuring…
avg p50
stability
0sw
load balance
0%
window last 80 picks · 40s 8 providers · btc/mainnet faithful simulation of the SDK's selection strategies · pricing illustrative quickstart →
Built in public · real early-access telemetry

We run chainkit ourselves. Here's our actual telemetry — small but real.

These numbers come live from GET /v1/public/stats — the same source that powers our live scoreboard. They're modest because we're in early access on a small fleet. We'd rather show you the real, honest numbers than invent big ones.

events ingested · 24h
Total telemetry rows landed in the warehouse over the last 24h.
avg ops/min · 24h
Calls per minute, averaged across the 24h window.
aggregate p95
95th percentile across every operation and provider, weighted by traffic.
providers live · 24h
Distinct providers that served real traffic in the window.

Take Bitcoin in an afternoon. Keep every satoshi.

Register your xpub, issue an invoice, and the money settles to your wallet — we never sit in the middle. The same SDK routes your RPC across nine providers, free and MIT.

Pricing

You only pay when you get paid.

The SDK is MIT and free forever.
Payments bill on settled volume with a monthly minimum — no per-transaction card fee, no chargeback risk.
SDK · open source

The SDK is free

The Go SDK — 9-provider RPC routing — is yours forever, cloud or not.

$0 MIT, forever
  • 9 providers wired in, per-call failover
  • Circuit breaker, retry, jitter
  • OTel + Prometheus hooks
  • No account required to run it
go get →

See what each tier includes or the head-to-head with Blockonomics.