# SparkBTCBot > A self-custodial Bitcoin wallet for AI agents, on the Spark Layer 2 — built like a hot wallet under adversarial input. The agent holds its own keys, sends and receives instantly over Spark and Lightning, pays L402 paywalls, and buys real-world goods (gift cards, eSIMs, VPNs, phone numbers) at three Bitcoin-accepting merchants with no account, no KYC and no API key. Encrypted seed at rest, private by default, spend budgets, an outbound allowlist, payment dedup that makes retries safe, and an always-fresh unilateral-exit backup. Open source, MIT, live-tested on mainnet. SparkBTCBot is an agent skill plus a runtime. The skill is the behavioral guidance an LLM loads (`SKILL.md` and 18 reference docs); the runtime is the `sparkbtcbot-skill` npm package (built on `@buildonspark/spark-sdk`), which ships the `SparkAgent` wrapper, the encryption helpers and one `sparkbtcbot` CLI. Install it as a Claude Code plugin, add it as a shared Grok Bot, or load the skill text into any other LLM agent framework. Current release: **0.8.0** (2026-09-15). Node ≥ 20. **Reach for this when** an agent needs to pay for something, get paid, or buy a digital good with Bitcoin: settling an L402 paywall or an API bill from code, issuing or paying a Lightning invoice, "friend owes me $100 — make something they can pay", "I got paid, how do I get my money out", buying a gift card, eSIM, VPN or phone number, or any agent that has to move money on Bitcoin — even when Spark is never mentioned by name. ## Why a Spark wallet for agents - **Self-custodial**: a BIP39 mnemonic is the wallet. No account, no approval process, no custodian holding the agent's funds — and a unilateral exit to Bitcoin L1 if the operators ever go dark. - **Instant and free between Spark wallets**: Spark-to-Spark transfers settle in under a second at zero fee. Lightning interop costs 0.15–0.25%; a BOLT11 paid to a Spark-backed payee settles Spark-direct for free. - **No infrastructure**: no node to run, no channels to open or rebalance, no inbound liquidity to source. The SDK talks to the Spark operators directly. - **Lightning-native**: create and pay standard BOLT11 invoices, so the agent is payable from any Lightning wallet and can pay any Lightning merchant or L402 endpoint. - **A bridge in both directions**: receive over Lightning and cooperatively exit to on-chain Bitcoin, or deposit on-chain and pay any Lightning invoice from the balance. - **Real-world purchasing power**: ~10,000 Bitrefill products and 10,500+ Cryptorefills brands across 180+ countries, plus nadanada VPNs, eSIMs in 200+ countries and burner numbers — all paid over Lightning without an account. ## What the agent can do - Create a wallet from a BIP39 mnemonic; check balance; sign messages to prove identity - Send and receive sats between Spark wallets (instant, free) - Create and pay Lightning invoices (BOLT11); native Spark invoices in sats or tokens - Transfer BTKN / LRC20 tokens, including batch transfers and token invoices - Deposit from Bitcoin L1 (static address, 3 confirmations) and withdraw back via cooperative exit, with fee quotes first - Pay L402 / LSAT paywalls: preview the price, pay the invoice, cache the credential, retry the request - Buy gift cards, phone top-ups and eSIMs at Bitrefill and Cryptorefills; VPNs, eSIMs and disposable or rental phone numbers at nadanada — every invoice verified against its quote, confirmed before buying, secrets delivered once - Serve someone who doesn't know Bitcoin: a fiat-denominated invoice ("€50", "$100") sized from a live rate cross-checked across two sources, then a gift card at a store they use, sized under the balance with fees counted ## Security is the product The agent gets full custody the moment the seed is decrypted, so the design assumes the process can be lied to — by a webpage, a merchant reply, a paywall response — and bounds what a successful lie can cost. - **Encrypted seed at rest** (scrypt + AES, `~/.spark/seed.enc`, mode 0600): the mnemonic is never printed and never written in plaintext. Only the user can reveal it, in their own terminal — `reveal-mnemonic` refuses to run without a TTY, so an agent cannot capture it. - **Private by default** (0.8.0): Spark wallets are publicly readable by address out of the box; setup and every boot enable per-wallet privacy, so counterparties and explorers no longer see the balance and full history. Optional read-only viewer keys for monitoring without the seed. - **Spend ceilings**: a rolling 24-hour budget (`SPARK_DAILY_BUDGET_SATS`) that stops a loop of individually valid sends; per-call amount and fee caps; a `dryRun` preview on every send; an outbound recipient allowlist. Optionally seal the budget into the encrypted seed itself, so the ledger fails closed if tampered with and the agent cannot lift the cap without destroying the wallet it guards. - **Safe retries** (0.7.0): one persisted payment identity per Lightning invoice, minted before the first attempt, so a crash or timeout mid-payment no longer forces a choice between double-paying and never retrying. Verified on mainnet: duplicate pays on both rails produced one debit. - **Merchant payment policy**: invoice-vs-quote verification, amount ceilings, confirm-before-buy, PII consent, bearer-secret handling — shared across all three merchants and enforced in the wrapper. - **Unilateral-exit backup**: an auto-maintained recovery bundle (`spark.unilateral-exit-bundle.v1`) consumed by Blink's `spark-unilateral-exit` tool, so funds are recoverable to L1 even if every Spark operator disappears. - **Evidence, not promises**: live-validated on mainnet with real purchases at all three merchants and real L1 withdrawals; 419 offline unit tests that assert the pinned SDK's actual export surface; 38 reply-graded evals covering the moments real users hit ("he says he paid", "support needs my recovery words", a pasted invoice that doesn't match the story); the 0.7.0 delta reviewed with Trail of Bits' open-source security skills (differential-review, sharp-edges, supply-chain-risk-auditor) with every verified finding fixed and regression-tested. Read before funding anything: this path has no server-enforced limits. The funded balance is the only cap that survives a compromised process, so fund a dedicated wallet with an operational float you can afford to lose, set the daily budget, and sweep earnings out regularly. ## How it works 1. **Install the skill and the runtime.** The skill text arrives as a Claude Code plugin, a shared Grok Bot, or via the npm package; the runtime is always `sparkbtcbot-skill`, installed in your own project and pinned by your lockfile. 2. **Run setup once.** `sparkbtcbot setup` generates a BIP39 mnemonic, encrypts it with your passphrase into `~/.spark/seed.enc`, turns on wallet privacy, and prints only the wallet's Spark address. You back the words up offline with `reveal-mnemonic` in your own terminal. 3. **Fund it.** Hand out a BOLT11 invoice (any Lightning wallet can pay it), a bare Spark address (free from other Spark wallets), or an L1 deposit address for larger on-chain amounts. 4. **Let the agent transact.** It reads `SPARK_PASSPHRASE` from the environment, decrypts the seed once at boot, and then pays invoices, settles paywalls, answers incoming transfers and buys goods on its own — with every send checked against the budget, allowlist and fee ceilings before a sat moves. ## Quick start **One prompt, any agent with a shell.** Paste this into Claude Code, Cursor, Codex, opencode or your own harness: ``` Run curl -sL https://sparkbtcbot.yvrbtclabs.dev/skills/setup.md and use the returned setup instructions to set up my Spark wallet. ``` The fetched document is an agent-facing setup guide: the non-negotiable rules first, then preflight, an offer of npm supply-chain hardening before anything is installed (settings sourced from the `echennells/supply-chain-hardening` repo, applied only with consent), the runtime install pinned in your project, installing the skill so future sessions have it, passphrase and setup, the user-run backup step, spend guardrails, and funding. Everything below is the same setup by hand. **Claude Code** (the skill loads automatically when it triggers): ``` /plugin marketplace add https://github.com/echennells/sparkbtcbot /plugin install sparkbtcbot@sparkbtcbot ``` From a terminal the same two steps are `claude plugin marketplace add …` and `claude plugin install …`; an already-open session needs `/reload-plugins`. **Grok Bot** (xAI's desktop agent): add the shared Bot template **Bitcoin** — https://x.ai/bot/0_MAfMhNwRYCPKiC0Cm1Z — open the link, preview it, and choose *Add to Grok Bot* (the Grok Bot app is required to finish). Adding a shared Bot copies its configuration, skills and routines into your own account; it never copies files, logins or seed material, so the wallet runtime below still has to be installed on your own computer. **Any other LLM agent framework** (Cursor, LangChain, OpenAI Agents SDK, Aider, your own harness): install the package and load the skill body into the system prompt. ``` npm install --ignore-scripts sparkbtcbot-skill ``` ```javascript import { getSkillContent, getReference, listReferences } from "sparkbtcbot-skill"; const instructions = await getSkillContent(); // always-loaded skill body const l402 = await getReference("l402"); // any of the 18 references on demand ``` opencode discovers skills by scanning directories rather than calling `getSkillContent()`: clone the repo (it reads `AGENTS.md` automatically) or symlink `node_modules/sparkbtcbot-skill/skills/sparkbtcbot` into a skills directory it scans. **Then, in every setup — the runtime lives in your project:** ``` npm install --ignore-scripts sparkbtcbot-skill # once, in your project echo 'SPARK_PASSPHRASE=<12+ characters>' >> .env # before setup; keep .env out of git npm exec --no -- sparkbtcbot setup # encrypts the mnemonic at ~/.spark/seed.enc npm exec --no -- sparkbtcbot reveal-mnemonic # YOU run this, in your own terminal, to back up the words ``` Two rules the skill will hold you to: use `npm exec --no --` (or `./node_modules/.bin/sparkbtcbot`), never a bare `npx`, for any wallet command — `npx` fetches a registry package named after the command when the local binary is missing, and it does so silently with no TTY; and `--ignore-scripts` on every install, because one transitive dependency runs code at install time and nothing here needs it. Set `SPARK_NETWORK=REGTEST` in `.env` to develop with no real funds; mainnet is the default. `SPARK_DAILY_BUDGET_SATS` is opt-in and strongly recommended for any autonomous agent. The full variable list is in `.env.example`. Everything else — the operating rules, the receive-artifact decision table, fee tables, recovery, the merchant playbooks — lives in the skill. If you are an agent that is not Claude Code, read `AGENTS.md` first, then `SKILL.md`. ## The skill - [setup.md](https://sparkbtcbot.yvrbtclabs.dev/skills/setup.md): the one-prompt setup guide for agents — rules, supply-chain hardening offer, install, wallet creation, backup handoff, guardrails, funding - [SKILL.md](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/SKILL.md): the always-loaded body — custody model, guardrails, the rules for handling seed material, which artifact to hand out when asked to receive, setup, and the navigator to the references below - [AGENTS.md](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/AGENTS.md): the short list of non-negotiable rules for any agent that is not Claude Code (never print the mnemonic or passphrase, never run the reveal or policy ceremonies yourself, never bare `npx`, always `--ignore-scripts`) - [README.md](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/README.md): install paths, example scripts, environment variables, security recommendations, disclaimer - [CHANGELOG.md](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/CHANGELOG.md): every release with the reasoning behind each change - [SECURITY.md](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/SECURITY.md): how to report a vulnerability; the retired-binary-name policy ### References (loaded on demand by `getReference(name)`) - [first-spend](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/first-spend.md): the product path for a user who doesn't know Bitcoin — fiat-first invoice, then "I got paid, now what": balance in their currency and a gift card sized under it - [wallet](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/wallet.md): balance, deposits, transfers, transfer history, cooperative withdrawal with fee quotes - [lightning](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/lightning.md): BOLT11 create and pay, fee estimation, payment dedup and the retry doctrine, the L1 → Lightning on-ramp - [l402](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/l402.md): paying L402 / LSAT paywalls — 402 challenge, invoice, preimage, credential caching - [spark-invoices](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/spark-invoices.md): native Spark invoices in sats or tokens, and why never to hand one to a human by default - [tokens](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/tokens.md): BTKN / LRC20 balances, transfers, batch operations, operator-enforced allowances - [agent-class](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/agent-class.md): the drop-in `SparkAgent` class that wraps the SDK with the guardrails - [merchant-spending](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/merchant-spending.md): the shared payment policy for every merchant purchase — quote guard, confirm-before-buy, bearer-secret deliverables - [bitrefill](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/bitrefill.md): gift cards, eSIMs and top-ups via Bitrefill's agent MCP - [cryptorefills](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/cryptorefills.md): 10,500+ brands via Cryptorefills' keyless MCP purchase wizard - [nadanada](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/nadanada.md): VPNs, eSIMs and disposable or rental phone numbers, hold-invoice semantics - [architecture](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/architecture.md): how Spark works, the 1-of-n trust model, fee tables, comparison with Lightning and on-chain - [encrypted-seed](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/encrypted-seed.md): the seed-file format, setup modes, migration, the seed-bound spending policy - [security](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/security.md): the full-custody threat model, wallet privacy and viewer keys, sweeping, monitoring, what the allowlist does and does not bound - [unilateral-exit](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/unilateral-exit.md): the leaf-vault recovery bundle and exiting to L1 without operators - [recovery-scenarios](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/recovery-scenarios.md): tested recovery behaviour — stale-backup failure modes and the on-chain-verified timelock defence - [supply-chain](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/supply-chain.md): offering npm hardening before installing on a user's behalf - [extras](https://raw.githubusercontent.com/echennells/sparkbtcbot/main/skills/sparkbtcbot/references/extras.md): message signing, event listeners, error handling, token issuance ## Merchants All three are usable with no account, no KYC and no API key. The payment leg is Spark → Lightning at ~0.25% plus routing fees. - [Bitrefill](https://www.bitrefill.com): ~10,000 digital products — gift cards, eSIMs, phone top-ups — across 180+ countries - [Cryptorefills](https://www.cryptorefills.com): 10,500+ brands across 180+ countries including flights and hotels; requires an email address at checkout - [nadanada](https://nadanada.me): no-log WireGuard VPNs, data eSIMs in 200+ countries, disposable and rental phone numbers for SMS verification No partnership with any of them; this is independent guidance. The skill carries the author's referral code for nadanada and referral links for Bitrefill and Cryptorefills — none is a prerequisite, the accountless flow always works, and the agent strips them on request. ## Tested setups No lock-in to one model or harness. The wallet, merchant and bridge flows have been run end-to-end with real mainnet sats under [Claude Code](https://claude.com/claude-code) (plugin path) and under [opencode](https://opencode.ai) running GLM-5.2 via OpenRouter (clone path). Anything that can load the skill text should behave the same way. ## Links - [Website](https://sparkbtcbot.yvrbtclabs.dev) - [Wallet setup and seed security](https://sparkbtcbot.yvrbtclabs.dev/docs.html): how the wallet is created, what the user must back up, the threat model, recovery scenarios - [Install methods](https://sparkbtcbot.yvrbtclabs.dev/docs.html#install): Claude Code plugin, Grok Bot, the npm package in any other agent (including opencode's skill-directory registration), or a clone - [Fees](https://sparkbtcbot.yvrbtclabs.dev/docs.html#fees): the measured flat L1 withdrawal fee by amount, and why to batch small exits - [GitHub](https://github.com/echennells/sparkbtcbot) - [Releases](https://github.com/echennells/sparkbtcbot/releases) - [npm: sparkbtcbot-skill](https://www.npmjs.com/package/sparkbtcbot-skill) - [Grok Bot: Bitcoin by lightning](https://x.ai/bot/0_MAfMhNwRYCPKiC0Cm1Z): the shared Bot template — open on x.ai and choose Add to Grok Bot - [YVR BTC Labs](https://yvrbtclabs.dev) ## Optional - [Spark documentation](https://docs.spark.money/llms.txt): the Layer 2 this wallet runs on - [Spark SDK on npm](https://www.npmjs.com/package/@buildonspark/spark-sdk) - [Sparkscan](https://sparkscan.io): Spark network explorer - [L402 protocol](https://l402.tech/llms.txt): the HTTP 402 payment protocol the paywall flow implements - [spark-unilateral-exit](https://github.com/blinkbitcoin/spark-unilateral-exit): Blink's tool that consumes the recovery bundle - [supply-chain-hardening](https://github.com/echennells/supply-chain-hardening): the npm hardening config the skill offers before installing ## License MIT — https://github.com/echennells/sparkbtcbot/blob/main/LICENSE