These resources are written by Freedom Lab members. Join our Freedom Lab server to be a part of the community and receive support directly.

ResourcesNunchuk + Claude: AI Bitcoin Agent with Spending Limits

Nunchuk + Claude: AI Bitcoin Agent with Spending Limits

Tutorial Bitcoin Open-source AI

Audience: Intermediate — basic Bitcoin knowledge and command-line comfort required

Duration: 60–90 min

Outcomes: By the end, students will:

Abstract

Most AI agent setups give Claude access to a hot wallet or an API with full spending power. That's convenient but brittle — a misbehaving prompt, a confused agent, or a supply chain compromise and your funds are gone. There's a better design: give the AI bounded signing authority on one key in a multisig, and let cryptographic policy enforce the ceiling.

This walkthrough shows you how to build exactly that using the Nunchuk CLI and Claude Code. You'll create a 2-of-3 multisig wallet where Nunchuk's Platform key enforces a daily spending limit. Claude holds one key, you hold another, and Nunchuk's HSM holds the third. Any two signers can authorize a transaction — but the Platform key will only co-sign if the spend is within the policy limit. Above the cap, you have to cosign manually. The AI can pay invoices and rebalance within its budget. It cannot go rogue.

Concept Primer

Before getting into commands, here's the vocabulary you need:

Multisig wallets

A multisig (multi-signature) wallet requires M of N keys to authorize a transaction. A 2-of-3 means any 2 of the 3 key holders can sign — no single person can move funds unilaterally. This is the basis of both collaborative custody and AI-bounded authority: the AI is one keyholder, not all of them.

Platform key

Nunchuk's Platform key is an HSM-backed key held by Nunchuk's servers. Unlike a human cosigner, the Platform key applies programmable policies before signing. You set a daily spending limit in USD — the Platform key auto-signs anything under the limit and refuses everything over it. Changing the policy requires a signed dummy PSBT from the wallet's other signers, so the AI cannot raise its own limit.

PSBTs

A Partially Signed Bitcoin Transaction (PSBT) is the standard format for passing a transaction between multiple signers. Each signer adds their signature and passes it along. Nunchuk uses this same rail for policy changes — a dummy PSBT encodes a governance action (like a policy update) rather than a real spend, but it still requires the same M-of-N signatures to execute.

BIP32 and BIP39

BIP39 defines the 12- or 24-word mnemonic seed phrase. BIP32 defines how a single seed derives an unlimited tree of key pairs — your root key, your wallet xpub, and the individual signing keys all come from the same seed. When the CLI generates a software key, it creates a BIP39 mnemonic and derives keys from it using BIP32. Write the mnemonic down if this is a real wallet.

Agent skills

Agent skills are markdown files that tell Claude Code how to use a specific tool. Installing nunchuk-io/agent-skills drops seven skill files into Claude's skill directory. Claude reads them and learns the exact commands, flags, and error patterns for each Nunchuk operation — so natural language like "create a 2-of-3 wallet" maps directly to the right CLI invocations.

Bounded authority

The core design principle: the AI doesn't have the wallet. It has a key in a multisig with a cap. If Claude goes rogue — hallucination, prompt injection, a malicious skill — it cannot authorize a spend above the daily limit without your cosignature. The cryptographic policy is the fence, and neither you nor the AI can remove it unilaterally.

Agenda

Part Topic Time
1 Connecting Claude to Nunchuk — install CLI, authenticate, install skills 15 min
2 Use cases for AI treasury agents — the why before the how 10 min
3 Building the wallet — generate key, sandbox, Platform key, policy, finalize 25 min
4 Putting it to work — send under cap, hit the fence, policy enforcement demo 15 min

Prerequisites

Do this walkthrough on testnet first. Testnet coins have no monetary value — mistakes cost nothing. Switch to mainnet only after you've run the full flow at least once and understand what each step does.

Part 1: Connecting Claude to Nunchuk

1.1 Install the CLI

The Nunchuk CLI is a Node package that bundles the crypto, the Electrum client, and the Nunchuk API wrapper into a single binary. Install it globally so Claude can call it as a shell tool from any directory.

npm install -g nunchuk-cli
nunchuk --help

A successful install prints the command tree: auth, sandbox, wallet, tx, key, network, config. If the binary isn't found after install, check that your npm global bin directory is on your PATH.

What to tell Claude: "Install the Nunchuk CLI globally and confirm it's working."

1.2 Get an API key

Nunchuk's server brokers multisig coordination — sandbox invites, encrypted PSBT relay, and Platform key signing. You need an API key to identify yourself to it. This is not a custodial account: the server never sees your private keys, only encrypted blobs.

Go to developer.nunchuk.io, sign in, create an API key, and copy it to your clipboard. This is a manual browser step — paste the key into your terminal when prompted in the next step.

1.3 Authenticate

This writes your API key into ~/.nunchuk-cli/config.json and creates an AES-256-GCM encrypted SQLite database at ~/.nunchuk-cli/data/<emailHash>/<network>/storage.sqlite. Every key, sandbox, and wallet state lives here, encrypted row-by-row with a master key at ~/.nunchuk-cli/master.key.

nunchuk auth login --api-key <your-key>

Verify with nunchuk auth status — it should report that you're logged in and your local vault is initialized.

What to tell Claude: "Log into Nunchuk with this API key: <key>."

1.4 Install Agent Skills

Agent skills are markdown-based plugins that tell Claude when to use a capability and how to invoke it. Installing nunchuk-io/agent-skills drops seven skill files into Claude's skill directory, teaching it the exact commands and error patterns for each Nunchuk operation.

npx skills add nunchuk-io/agent-skills --all --global

What to tell Claude: "Install all Nunchuk agent skills globally."

After installation, seven skills become available: nunchuk-setup, nunchuk-wallet-creation, nunchuk-invitations, nunchuk-platform-key, nunchuk-wallet-management, nunchuk-wallet-transactions, and nunchuk-coldcard-hsm. Restart your Claude Code session so they load.

After restarting Claude Code, try asking: "What Nunchuk skills do you have?" Claude should list all seven skills and their descriptions, confirming the install worked.

1.5 Pick a network

Nunchuk supports mainnet (real BTC), testnet (free test coins), and signet. For this walkthrough, use testnet — mistakes cost nothing. Network state is stored in config and applies to all subsequent commands.

nunchuk network set testnet

All subsequent commands will talk to testnet endpoints and use testnet BIP32 derivation paths (m/48h/1h/... instead of m/48h/0h/...).

What to tell Claude: "Switch Nunchuk to testnet."

Part 2: Use Cases for AI Treasury Agents

Before building the wallet, it helps to anchor the why. The combination of CLI + agent skills + Platform key policies unlocks use cases that custodial apps can't touch and that hot wallets can't do safely:

The key distinction: the AI doesn't have the wallet. It has bounded signing authority on one key in a multisig. This is a fundamentally different security model than giving an agent a hot wallet or API key with full spending power.

Part 3: Building the Wallet

3.1 Generate the agent's key

This creates a BIP39 24-word mnemonic, derives a BIP32 root, and extracts the xpub at the multisig derivation path m/48h/1h/0h/2h (testnet, native segwit). The key lives encrypted in SQLite on this machine — Claude can use it to sign, but the mnemonic never leaves the device.

nunchuk key generate --name "Agent"

What to tell Claude: "Generate a new software key named Agent."

A fingerprint (8 hex characters) prints to confirm success. Run nunchuk key list to verify it's stored. If this is a real mainnet wallet, write the mnemonic down — losing the device without a backup means losing the key permanently.

On testnet, losing the key just means losing test coins. On mainnet, it means losing real funds. Back up the mnemonic before loading any mainnet value into the wallet.

3.2 Create the sandbox

A sandbox is the pre-finalization state of a multisig wallet. It holds the wallet structure (M-of-N, address type, name) while participants add their keys. Once all N slots are filled, you finalize it into a real wallet.

nunchuk sandbox create --name "Agent Wallet" --m 2 --n 3 --address-type NATIVE_SEGWIT

What to tell Claude: "Create a 2-of-3 native segwit sandbox called Agent Wallet."

A sandbox ID prints. Run nunchuk sandbox get <id> to confirm 3 empty slots with status PENDING.

3.3 Enable the Platform key

This tells the sandbox that one of the 3 keys will be Nunchuk's HSM-backed Platform key. You don't supply an xpub — the server contributes its own xpub to the descriptor. This is the key that spending policies will apply to.

nunchuk sandbox platform-key enable <sandbox-id>

What to tell Claude: "Enable the Platform key on sandbox <id>."

After this command, one slot shows as filled by Nunchuk. Two slots remain for you and the agent.

3.4 Set the policy

This defines the bounded authority. The --auto-broadcast flag means the Platform key will co-sign and push to the network any transaction under the daily limit without asking. Above the limit, it refuses — and there's no way for the agent to override this without your cosigning a dummy PSBT.

nunchuk sandbox platform-key set-policy <sandbox-id> \
  --auto-broadcast \
  --limit-amount 100 --limit-currency USD --limit-interval DAILY

What to tell Claude: "Set a $100/day spending limit on the Platform key with auto-broadcast."

Run nunchuk sandbox platform-key get <id> to confirm the policy is attached before moving on.

3.5 Add your key and the agent's key

Fill the remaining 2 slots. One is your human key (from a hardware wallet, Nunchuk mobile, or another software key); the other is the agent key you generated in 3.1. Exporting your hardware wallet xpub requires using your device's export function — the exact steps depend on your hardware wallet model.

# Agent's software key — already on this device
nunchuk sandbox add-key <sandbox-id> --slot 1 --fingerprint <agent-xfp>

# Your key — paste the descriptor exported from your hardware wallet or Nunchuk mobile
nunchuk sandbox add-key <sandbox-id> --slot 2 \
  --descriptor "[abcd1234/48h/1h/0h/2h]xpub..."

What to tell Claude: "Add the agent's key to slot 1. I'll paste my hardware wallet descriptor for slot 2."

Run nunchuk sandbox get <id> to confirm all 3 slots are filled before finalizing.

3.6 Finalize

Finalizing turns the sandbox into a real wallet. The CLI assembles the multisig descriptor, computes a wallet ID (a hash of the descriptor), and stores the finalized wallet locally and server-side. After this step, the wallet can receive funds.

nunchuk sandbox finalize <sandbox-id>
nunchuk wallet address get <wallet-id>
nunchuk wallet export <wallet-id> > agent-wallet-backup.txt

What to tell Claude: "Finalize the sandbox, give me a receive address, and export a backup."

You'll get a wallet ID, a testnet bech32 address starting with tb1q..., and a descriptor backup file. Send testnet coins to the address from a faucet to fund it for the next steps.

Keep agent-wallet-backup.txt safe. It contains the full multisig descriptor. If you ever need to recover the wallet in a different app, you'll need this file plus the individual seed phrases for each key.

3.7 Policy updates require cosigning

To prove the agent cannot raise its own spending limit: Nunchuk constructs a dummy PSBT — a non-broadcastable transaction that encodes the policy change. The wallet's M signers must sign it for the change to take effect. This is the same cryptographic rail that guards real spends, repurposed for governance.

# Attempt to raise the limit
nunchuk wallet platform-key update <wallet-id> \
  --limit-amount 1000 --limit-currency USD --limit-interval DAILY

# Nunchuk returns a dummy transaction ID requiring signatures
nunchuk wallet dummy-tx list <wallet-id>
nunchuk wallet dummy-tx sign <wallet-id> --dummy-tx-id <id>
# The agent's signature alone is not enough — you must cosign from your hardware wallet

What to tell Claude: "Try to raise the limit to $1,000/day. Show me the dummy transaction it generates."

Claude's signature alone is insufficient. You must cosign from your hardware wallet for the policy change to execute. This is the enforcement demo: the fence holds even against the agent's own requests.

Part 4: Putting It to Work

4.1 Agent sends under the cap

With the wallet funded and policy set, instruct Claude to send a transaction end-to-end — construct, sign with the agent key, and broadcast — all from a single natural-language prompt.

nunchuk tx create --wallet <wallet-id> --to <address> --amount 50 --currency USD
nunchuk tx sign --wallet <wallet-id> --tx-id <tx-id>
nunchuk tx broadcast --wallet <wallet-id> --tx-id <tx-id>

What to tell Claude: "Send $50 from the agent wallet to tb1q..."

Claude runs all three commands. The Platform key auto-cosigns (the amount is under the $100 daily cap) and the transaction is broadcast. Verify in a testnet block explorer that it went through.

4.2 Agent tries to exceed the cap

Now test the fence. Ask Claude to send more than the daily limit. The transaction creation and the agent's signing step will both succeed — but the Platform key will refuse its cosignature. The transaction stays PENDING_SIGNATURE until a human cosigns from their hardware wallet.

What to tell Claude: "Send $500 from the agent wallet."

Observe that tx create and the agent's tx sign both succeed, but the broadcast never happens. Run nunchuk tx list --wallet <wallet-id> to see the transaction stuck at PENDING_SIGNATURE. This is bounded authority working as designed.

PENDING_SIGNATURE is not an error — it's the system working. The transaction will complete as soon as the required cosignature is added. You can reject it entirely by double-spending the input from your hardware wallet if needed.

Reference Links