Providers

A provider is where sats gets its chain data: your balance, history, fee estimates, and sending. Each network uses one provider. You don't need to set one up: mempool.space is the default.

ProviderConnect withSet up
mempool.spaceNothingDefault
SubfrostAPI keysats providers add subfrost
Your Esplora serverURL, optional bearer tokensats providers add esplora --url URL

Not supported yet: Rebar Labs and UniSat.

sats doesn't show inscriptions, Runes, or BRC-20 yet, whatever the provider. To avoid spending an inscription by accident, it skips outputs worth 546 or 330 sats (see Inscription postage).

Commands

sats providers                    # this network's provider (same as `sats providers list`)
sats providers add subfrost       # save and check your key, then use Subfrost
sats providers use mempool        # switch: mempool, subfrost, or esplora
sats providers remove subfrost    # delete the key
signet  Subfrost · signet.subfrost.io · key saved

Every command acts on the active network; --network picks another. With --json, each prints the network's provider as one object: network, provider (mempool, subfrost, or esplora), url (the origin only), auth (none, api_key, or bearer), and source (default, config, or override).

Endpoints

ProviderEndpoint
mempoolhttps://mempool.space/signet/api or /testnet4/api
subfrostSubfrost's signet endpoint, or a --url you give
esploraThe server you add. Regtest defaults to http://localhost:3002.

sats providers add makes the added provider the network's provider, and sats providers use switches between them. Both check the endpoint's genesis block, and so its network, before saving. If the check fails, nothing is saved.

Inscription postage

Before selecting coins, sats excludes outputs worth exactly 546 or 330 sats, the usual inscription postage, so it doesn't spend an inscription by accident. This check is local and needs no provider. It is a heuristic: assets on other values aren't detected. A human can pass --allow-dust to include these outputs for one send. Agents never can.

Alkanes

sats alkanes is experimental and not in default builds (see CLI). It uses the network's provider, which must be Subfrost. Views are read-only and never authorize anything. sats alkanes encodes only calls it builds itself (in the sats-alkanes crate) and displays view results without trusting them.

Adding a provider

sats providers add subfrost asks for your API key with hidden input. Without a terminal it reads one line from stdin, so printf '%s\n' "$KEY" | sats providers add subfrost works in scripts. A credential is never a command-line argument. One saved key serves every network. Pressing enter keeps it only while the endpoint stays the same: a new --url, including another network's, needs the key typed again, so the saved key never goes to an endpoint you haven't given it to.

sats providers add esplora --url URL asks for an optional bearer token; press enter for none. A saved token is kept on enter only for the same URL: it never follows a new one.

--url URL sets the endpoint. It is required for Esplora, and for Subfrost on testnet4 and regtest.

Subfrost's JSON-RPC methods map onto sats's sync, fee, broadcast, and Alkanes view operations, and broadcast uses btc_sendrawtransaction. On a fresh wallet the driver derives scripts lazily and stops after 20 consecutive unused scripts on each of the receive and change keychains.

Removing a provider

sats providers remove subfrost deletes the key and every Subfrost endpoint setting. Any network that used Subfrost goes back to its default provider, and the command says so. sats providers remove esplora removes the active network's Esplora server, and the network goes back to its default if it was using it.

Configuration

The commands above write the config file. You can also edit it by hand:

network = "signet"

[subfrost]
api_key = "replace-with-key"        # shared by every network

[signet]
chain = "subfrost"                  # provider: mempool (default), subfrost, or esplora
fee_target = 1008                   # confirmation target in blocks

[testnet4]
chain = "esplora"

[testnet4.esplora]
url = "https://testnet4.example/api"
bearer = "replace-with-token"       # optional

[regtest]
subfrost_url = "http://localhost:18888/v4/jsonrpc"

subfrost_url replaces the built-in Subfrost endpoint for one network. It is how Subfrost is set up where it has no public endpoint.

sats writes config.toml owner-only (0600, in an owner-only directory). If you edit it yourself, keep its permissions restrictive. Every change made with sats providers rewrites the file, so comments are not kept. Diagnostics, debug output, and sats providers show only an endpoint's origin. User-info, paths, queries, fragments, and response bodies are omitted, including from failures saved on agent requests. Credentials are never copied into the MCP setup commands.

A config file in the earlier [providers.<name>], [esplora], or [fee_targets] format is refused with instructions: remove those sections and run sats providers add again.

A choice the network can't serve, such as chain = "esplora" with no URL or chain = "subfrost" with no Subfrost set up, is an error for every command that needs the provider. Local commands keep working while you fix it, and sats providers shows the settings as written next to the error.

Fee targets

Providers estimate fees; you choose the confirmation target, per network, from 1 to 1008 blocks (default 2), with fee_target under [<network>]. The target applies to every send, including approved agent requests. A human --fee-rate overrides it for one command. Agents can't choose a target or rate, and their grant's fee cap still applies to the real fee.

One-off overrides

sats --provider esplora=https://mempool.space/signet/api balance
sats --provider subfrost=https://signet.subfrost.io/v4/jsonrpc balance

--provider KIND=URL replaces the network's provider for one command, and can be given once. The saved Subfrost key is never sent to an override URL.

Failure behavior

Adding a driver

Provider code is security-sensitive. Follow the recipe in AGENTS.md.