← Back to Skills
Communication

bitkit-cli

ovitrif By ovitrif 👁 23 views ▲ 0 votes

Bitcoin Lightning payment CLI for agents.

GitHub
---
name: bitkit-cli
description: Bitcoin Lightning payment CLI for agents. Lowest LSP fees. Self-custody wallet with LNURL, typed exit codes, JSON envelope output, encrypted messaging, and daemon mode.
version: 0.2.0
metadata:
  clawdbot:
    requires:
      bins: [bitkit]
    homepage: https://github.com/synonymdev/bitkit-cli
    emoji: "\u26A1"
---

# bitkit-cli -- AI Agent Skill

Bitcoin Lightning payment CLI for agents. Lowest LSP fees. Self-custody wallet with LNURL/Lightning Address support, typed exit codes, JSON envelope output, encrypted Pubky messaging, and daemon mode.

**Install:** `curl -sSL https://raw.githubusercontent.com/synonymdev/bitkit-cli/main/install.sh | sh`
**Binary names:** `bitkit` or `bk` (identical alias)
**Always use:** `--json` flag on every invocation for parseable output.

## JSON Envelope

All `--json` output uses a consistent envelope:

**Success** (stdout):
```json
{ "ok": true, "data": { ... } }
```

**Error** (stderr):
```json
{ "ok": false, "error": "message", "code": 1 }
```

Parse with: `jq -r '.data.field'` for success data, check `.ok` first.

## Quick Start

```bash
# 1. Create wallet (no encryption for agent use)
bk init --no-password --json

# 2. Start daemon for instant command execution
bk start --json

# 3. Get on-chain address and fund it
ADDRESS=$(bk address --json | jq -r '.data.address')

# 4. Order inbound Lightning liquidity via LSP
ORDER=$(bk lsp create-order 500000 --json)
ORDER_ID=$(echo "$ORDER" | jq -r '.data.order_id')

# 5. Pay the order (on-chain to payment_address), then open channel
bk lsp open-channel "$ORDER_ID" --listen 9735 --json

# 6. Create an invoice and receive payment
bk invoice 5000 --description "agent service" --wait --listen 9735 --json

# 7. Pay someone else's invoice
bk pay lnbc50u1p... --json

# 8. Check balance and history
bk balance --json
bk history --json

# 9. Stop daemon when done
bk stop --json
```

## Daemon Mode

By default each command cold-starts the LDK node (slow). Start a persistent daemon for instant execution:

```bash
bk start --json           # start daemon (default port 3457)
bk status --json          # check if running
bk balance --json         # instant -- proxied through daemon
bk stop --json            # stop daemon
```

When the daemon is running, all commands automatically proxy through its HTTP API. When stopped, commands fall back to per-command cold-start. No code changes needed.

### `start`

Start the background daemon. Idempotent -- returns current PID if already running.

```bash
bk start --json
bk start --port 8080 --json
```

```json
{
  "ok": true,
  "data": {
    "status": "started",
    "pid": 12345,
    "port": 3457
  }
}
```

| Arg | Default | Description |
|-----|---------|-------------|
| `--port <port>` | `3457` | HTTP API port |

`status` is `"started"` or `"already_running"`.

### `stop`

Stop the running daemon.

```bash
bk stop --json
```

```json
{
  "ok": true,
  "data": {
    "status": "stopped",
    "pid": 12345
  }
}
```

Errors if no daemon is running (exit code 1).

### `status`

Check daemon status.

```bash
bk status --json
```

```json
{
  "ok": true,
  "data": {
    "running": true,
    "pid": 12345,
    "port": 3457,
    "started_at": "2026-02-19T10:00:00+00:00",
    "version": "0.1.0"
  }
}
```

When stopped: `running` is `false`, all other fields are `null`.

## Global Flags

| Flag | Env Variable | Default | Description |
|------|-------------|---------|-------------|
| `--json` | -- | off | Machine-readable JSON to stdout |
| `--dir <path>` | `BITKIT_DIR` | `~/.bitkit/` | Wallet data directory |
| `--network <net>` | `BITKIT_NETWORK` | `mainnet` | `mainnet` or `regtest` |
| `--listen <port>` | `BITKIT_LISTEN` | off | P2P listen port on `0.0.0.0:<port>` |
| `--password <pw>` | `BITKIT_PASSWORD` | -- | Wallet password (for encrypted seeds) |

## Command Reference

### Wallet

#### `init`

Create a new wallet. Idempotent -- re-running prints existing wallet info.

```bash
bk init --no-password --json
```

```json
{
  "ok": true,
  "data": {
    "node_id": "02abc123...",
    "seed_phrase": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
    "wallet_dir": "/root/.bitkit",
    "network": "mainnet",
    "pubky_id": "8pinxrz9tuxfz3qo5gkhdebuhtq6mrimh3matdncsrsno7kg45mo"
  }
}
```

| Arg | Required | Description |
|-----|----------|-------------|
| `--no-password` | one of | Store seed as plaintext (for agents) |
| `--password <pw>` | one of | Encrypt seed with AES-256-GCM + Argon2id |

#### `info`

Show node status, channel counts, sync state.

```bash
bk info --json
```

```json
{
  "ok": true,
  "data": {
    "node_id": "02abc123...",
    "network": "mainnet",
    "channels_active": 1,
    "channels_pending": 0,
    "block_height": 880000,
    "synced": true,
    "wallet_dir": "/root/.bitkit"
  }
}
```

#### `balance`

Show Lightning and on-chain balances in satoshis.

```bash
bk balance --json
```

```json
{
  "ok": true,
  "data": {
    "lightning_sats": 450000,
    "onchain_sats": 50000,
    "total_sats": 500000,
    "total_onchain_sats": 55000,
    "anchor_reserve_sats": 5000,
    "pending_sweep_sats": 0,
    "pending_sweeps": []
  }
}
```

- `onchain_sats` -- spendable on-chain balance
- `total_onchain_sats` -- all on-chain funds including reserved
- `anchor_reserve_sats` -- sats reserved for anchor channel fees
- `pending_sweep_sats` -- funds sweeping from closed channels (not yet spendable)
- `pending_sweeps` -- array of sweep entries with `amount_sats`, `status`, `spending_txid`, `confirmation_height`

| Arg | Description |
|-----|-------------|
| `--btc` | Display in BTC instead of sats (human output only) |

#### `config`

Show resolved configuration with source tracking. Does not start the node.

```bash
bk config --json
```

```json
{
  "ok": true,
  "data": {
    "network": { "value": "mainnet", "source": "default" },
    "wallet_dir": { "value": "/root/.bitkit", "source": "default" },
    "chain_source": { "value": "esplora", "source": "file" },
    "esplora_url": { "value": "https://blockstream.info/api", "source": "file" },
    "electrum_url": { "value": "", "source": "file" },
    "rgs_url": { "value": "https://rapidsync.lightningdevkit.org/snapshot", "source": "file" },
    "blocktank_url": { "value": "https://api1.blocktank.to/api", "source": "file" },
    "listen_port": { "value": "off", "source": "default" }
  }
}
```

Each entry has `value` (resolved value) and `source` (`cli`, `env`, `file`, or `default`).

#### `address`

Get a new on-chain receive address. Generates a fresh address each call. Optionally validate an existing address.

```bash
bk address --json
bk address --type taproot --json
bk address --validate bc1q... --json
```

Generate address:
```json
{
  "ok": true,
  "data": { "address": "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", "address_type": "native-segwit" }
}
```

Validate address (`--validate`):
```json
{
  "ok": true,
  "data": { "address": "bc1q...", "valid": true, "network": "mainnet", "reason": null }
}
```

On invalid address: `valid` is `false` and `reason` explains why.

| Arg | Default | Description |
|-----|---------|-------------|
| `--type <type>` | `native-segwit` | Address type: `legacy`, `nested-segwit`, `native-segwit`, `taproot` |
| `--validate <addr>` | -- | Validate `<addr>` for the current network; no node start needed |
| `--qr` | off | Display address as QR code in terminal (human output only) |

#### `send`

Send bitcoin on-chain to an address.

```bash
bk send bc1q... 50000 --json
bk send bc1q... 50000 --fee-rate 5 --json
bk send bc1q... --drain --json
bk send bc1q... 50000 --utxo <txid>:<vout> --json
```

```json
{
  "ok": true,
  "data": {
    "txid": "abc123...",
    "address": "bc1q...",
    "amount_sats": 50000,
    "drain": false,
    "fee_rate_sat_per_vb": 5,
    "utxos_used": ["abc123...:0"]
  }
}
```

When `--drain` is used, `amount_sats` is `null`. When no `--fee-rate` is set, `fee_rate_sat_per_vb` is `null`.

| Arg | Default | Description |
|-----|---------|-------------|
| `<address>` | required | Destination Bitcoin address |
| `<amount_sats>` | -- | Amount in satoshis (omit with `--drain`) |
| `--drain` | off | Send all spendable funds (mutually exclusive with `--utxo`) |
| `--fee-rate <sat/vb>` | auto | Fee rate in sat/vb |
| `--utxo <txid:vout>` | -- | Spend a specific UTXO (repeatable; incompatible with `--drain`) |

#### `list-utxos`

List all spendable UTXOs in the on-chain wallet.

```bash
bk list-utxos --json
```

```json
{
  "ok": true,
  "data": {
    "utxos": [
      {
        "txid": "abc123...",
        "vout": 0,
        "value_sats": 1000000,
        "outpoint": "abc123...:0"
      }
    ],
    "total_sats": 1000000,
    "count": 1
  }
}
```

Use `outpoint` values (e.g. `abc123...:0`) as `--utxo` arguments for `send` and `estimate-fee`.

#### `estimate-fee`

Preview the fee for an on-chain send without broadcasting.

```bash
bk estimate-fee bc1q... 50000 --json
bk estimate-fee bc1q... 50000 --fee-rate 5 --json
```

```json
{
  "ok": true,
  "data": {
    "fee_sats": 250,
    "address": "bc1q...",
    "amount_sats": 50000,
    "fee_rate_sat_per_vb": 5
  }
}
```

`fee_rate_sat_per_vb` is `null` when not specified (node chooses automatically).

| Arg | Default | Description |
|-----|---------|-------------|
| `<address>` | required | Destination Bitcoin address |
| `<amount_sats>` | required | Amount to send in satoshis |
| `--fee-rate <sat/vb>` | auto | Override fee rate in sat/vb |
| `--utxo <txid:vout>` | -- | Restrict coin selection to specific UTXOs |

#### `bump-fee`

Replace an unconfirmed transaction with a higher-fee version (RBF). The original transaction must be in the mempool and RBF-enabled.

```bash
bk bump-fee <txid> <fee_rate> --json
```

```json
{
  "ok": true,
  "data": {
    "original_txid": "abc123...",
    "new_txid": "def456...",
    "fee_rate_sat_per_vb": 20
  }
}
```

| Arg | Description |
|-----|-------------|


... (truncated)
communication

Comments

Sign in to leave a comment

Loading comments...