Sets up Bitcoin Lightning nodes on Ubuntu with litd (Lightning Terminal), Neutrino or bitcoind backends, and remote signer architecture for production.
How this skill is triggered — by the user, by Claude, or both
Slash command
/lightning-agent-tools:run-litdThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Reference for setting up litd (Lightning Terminal) and LND on Ubuntu, including the recommended remote signer architecture that separates key-holding from routing.
bitcoind_setup.shbitcoind_setup_binary.shlitd_setup.shlitd_setup2.shlitd_setup3.shlitd_setup_binary.shlitd_wallet_create.shneutrino/neutrino_setup3.shneutrino/neutrino_setup_binary.shneutrino/remote-signer-neutrino-binary.shremote-signer/remote-signer-binary.shremote-signer/remote-signer.shremote-signer/routing-node-binary.shremote-signer/routing-node.shremote-signer/routing-node2.shremote-signer/routing-node3.shReference for setting up litd (Lightning Terminal) and LND on Ubuntu, including the recommended remote signer architecture that separates key-holding from routing.
Tested on Ubuntu 24.04 LTS. Current target versions: bitcoind v31.0, litd v0.16.1-alpha, LND v0.20.1-beta.
Source scripts: https://github.com/HannahMR/run-litd
| Role | Software | Holds keys? | Internet-exposed? |
|---|---|---|---|
| Single node | litd (integrated) | Yes | Yes |
| Signer node | LND (standalone) | Yes — wallet + private keys | No — ideally on private network |
| Routing node | litd (watch-only) | No | Yes — public Lightning node |
The remote signer architecture is recommended for production: the signer holds keys and is never internet-exposed; the routing node handles payments. Three files transfer from signer to routing node: tls.cert (rename to signer-tls.cert), signer.macaroon, accounts.json.
| Neutrino (default) | bitcoind | |
|---|---|---|
| Bitcoin backend | Lightweight SPV, built into LND | Full node |
| Disk required | ~1 GB | 80 GB+ pruned / 800 GB+ full |
| Sync time | Minutes | Hours–days |
| Mainnet routing | Not recommended | ✓ |
| Signet / dev | ✓ Ideal | ✓ |
Default behaviour: unless the user explicitly asks for bitcoind or a source build, always use the Neutrino binary path.
datadir=/path/to/disk in bitcoin.confThe setup scripts require root to install binaries to /usr/local/bin/, install packages via apt-get, write systemd service files to /etc/systemd/system/, and run systemctl commands. Check that passwordless sudo is working before doing anything else:
sudo -n true 2>/dev/null && echo "OK" || echo "NEEDS_SETUP"
If the output is NEEDS_SETUP, explain to the user why these permissions are needed — the setup scripts must install binaries to /usr/local/bin/, install packages via apt-get, write systemd service files to /etc/systemd/system/, and run systemctl commands, all of which require root. Claude cannot enter a password interactively, so passwordless sudo must be configured first. Then ask them to run the fix:
"I need you to open a new SSH terminal tab and paste these two commands, then let me know when done. This is a one-time setup for this server. Note that each command pipes through
sudo tee— thesudois required to write to/etc/sudoers.d/, so you will be prompted for your password. Do not removesudofrom the commands."echo 'Defaults:ubuntu !use_pty' | sudo tee /etc/sudoers.d/ubuntu-nopty > /dev/null sudo chmod 0440 /etc/sudoers.d/ubuntu-noptyecho 'ubuntu ALL=(ALL) NOPASSWD: ALL' | sudo tee /etc/sudoers.d/ubuntu-nopasswd > /dev/null sudo chmod 0440 /etc/sudoers.d/ubuntu-nopasswd
Wait for the user to confirm, then re-run sudo -n true to verify before continuing.
Ask the user:
Default behaviour: use the Neutrino binary path unless the user explicitly asks for bitcoind or a source build. Neutrino is built into LND — no separate Bitcoin node or service needed. It is ideal for signet and development but not recommended for mainnet production routing nodes due to peer dependency.
Once you have the answers, run sudo -v to cache credentials, then jump to the relevant section below.
Neutrino is a lightweight SPV Bitcoin client built into LND — no bitcoind installation required. litd still needs its own lit.conf and systemd service; neutrino_setup3.sh handles both.
Important: the setup scripts use interactive read prompts that Claude CLI cannot respond to. Generate the config files directly before running the scripts — each script checks for existing files and skips the interactive config section automatically.
This path installs litd with a Neutrino backend. litd provides the web UI and integrated LND node.
Before running the script, ask the user for:
Then generate the config files using the Bash tool. Read ${CLAUDE_SKILL_DIR}/neutrino/neutrino_setup_binary.sh to see the exact config structure the script would produce, then reproduce it with the user's values substituted in:
mkdir -p ~/.lnd ~/.lit
openssl rand -hex 21 > ~/.lnd/wallet_password
chmod 600 ~/.lnd/wallet_password
# Write ~/.lit/lit.conf via heredoc — structure is in neutrino_setup_binary.sh
Once the config files exist, run the install script — it installs litd and skips the interactive config section:
chmod +x ${CLAUDE_SKILL_DIR}/neutrino/neutrino_setup_binary.sh ${CLAUDE_SKILL_DIR}/neutrino/neutrino_setup3.sh
sudo ${CLAUDE_SKILL_DIR}/neutrino/neutrino_setup_binary.sh
After the install script completes, create the wallet automatically:
chmod +x ${CLAUDE_SKILL_DIR}/litd_wallet_create.sh
sudo ${CLAUDE_SKILL_DIR}/litd_wallet_create.sh
This starts litd in the background, creates the wallet via the LND REST API, saves the seed to ~/.lnd/seed_phrase.txt, and stops litd. Prompt the user to back up and delete the seed:
"Your seed phrase has been saved to
~/.lnd/seed_phrase.txt. Back it up to offline storage now — it is your only recovery option. Then delete it:shred -u ~/.lnd/seed_phrase.txt"
Wait for confirmation, then enable auto-unlock and the systemd service:
sudo ${CLAUDE_SKILL_DIR}/neutrino/neutrino_setup3.sh
This path installs LND only (no litd, no web UI) and uses Neutrino as the Bitcoin backend. The routing node runs litd with bitcoind separately.
Before running the script, ask the user for:
Then generate the config files using the Bash tool. Read ${CLAUDE_SKILL_DIR}/neutrino/remote-signer-neutrino-binary.sh to see the exact config structure the script would produce, then reproduce it with the user's values substituted in:
mkdir -p ~/.lnd
openssl rand -hex 21 > ~/.lnd/wallet_password
chmod 600 ~/.lnd/wallet_password
# Write ~/.lnd/lnd.conf via heredoc — structure is in remote-signer-neutrino-binary.sh
Once the config files exist, run the script:
chmod +x ${CLAUDE_SKILL_DIR}/neutrino/remote-signer-neutrino-binary.sh
sudo ${CLAUDE_SKILL_DIR}/neutrino/remote-signer-neutrino-binary.sh
The script installs LND, skips config generation (files already exist), creates the lnd systemd service, and automatically creates and initialises the wallet via REST — no manual lncli create step needed.
When the script completes, prompt the user to back up the seed:
"Your seed phrase has been saved to
~/.lnd/seed_phrase.txt. Back it up to offline storage now — it is your only recovery option. Then delete it:shred -u ~/.lnd/seed_phrase.txt"
Then follow Step 2 — Transfer Files and Step 3 — Routing Node from the Remote Signer Setup section below.
Use this path when the user has specifically asked for a bitcoind-backed node. Run bitcoind first, then litd.
The bitcoind script generates its own RPC password via rpcauth.py — Claude cannot pre-generate it. Before running, tell the user:
"The bitcoind setup script will display an RPC password. Please copy it and paste it back to me when prompted — I'll use it to configure litd. The script will also ask which network you want (signet or mainnet)."
sudo ${CLAUDE_SKILL_DIR}/bitcoind_setup_binary.sh
# Source build alternative: sudo ${CLAUDE_SKILL_DIR}/bitcoind_setup.sh
After the script completes, ask the user: "What RPC password did the script display?" Then store it — you will use it in the next step. Verify bitcoind is running before continuing:
bitcoin-cli -signet getblockchaininfo # signet
bitcoin-cli getblockchaininfo # mainnet
Before running the script, ask the user for:
Then pre-generate the config files. Read ${CLAUDE_SKILL_DIR}/litd_setup_binary.sh to see the exact config structure, then reproduce it using the network from Before You Begin Step 2, the RPC password from Step 1 above, and the UI password and alias just collected:
mkdir -p ~/.lnd ~/.lit
openssl rand -hex 21 > ~/.lnd/wallet_password
chmod 600 ~/.lnd/wallet_password
# Write ~/.lit/lit.conf via heredoc — structure is in litd_setup_binary.sh
Once config files exist, run the install script — it installs litd and skips the interactive config section:
sudo ${CLAUDE_SKILL_DIR}/litd_setup_binary.sh
After the install script completes, create the wallet automatically:
chmod +x ${CLAUDE_SKILL_DIR}/litd_wallet_create.sh
sudo ${CLAUDE_SKILL_DIR}/litd_wallet_create.sh
This starts litd in the background, creates the wallet via the LND REST API, saves the seed to ~/.lnd/seed_phrase.txt, and stops litd. Prompt the user to back up and delete the seed:
"Your seed phrase has been saved to
~/.lnd/seed_phrase.txt. Back it up to offline storage now — it is your only recovery option. Then delete it:shred -u ~/.lnd/seed_phrase.txt"
Wait for confirmation, then enable auto-unlock and the systemd service:
sudo ${CLAUDE_SKILL_DIR}/litd_setup3.sh
Source build: litd_setup.sh (installs Go/Node/Yarn) → new shell → litd_setup2.sh (builds litd) → source ~/.profile if litd/lncli are not found → create wallet as above → litd_setup3.sh.
Two options depending on whether bitcoind is available on the signer machine:
Neutrino signer (default — no bitcoind needed):
Follow the pre-generation steps in the Neutrino remote signer section above — collect signer IP and node alias, generate wallet_password and lnd.conf, then run:
chmod +x ${CLAUDE_SKILL_DIR}/neutrino/remote-signer-neutrino-binary.sh
sudo ${CLAUDE_SKILL_DIR}/neutrino/remote-signer-neutrino-binary.sh
bitcoind signer (explicit request only — bitcoind must already be installed and running):
chmod +x ${CLAUDE_SKILL_DIR}/remote-signer/remote-signer-binary.sh
sudo ${CLAUDE_SKILL_DIR}/remote-signer/remote-signer-binary.sh
The script:
~/.lnd/ and generates wallet_passwordlnd.conf for signing role (no p2p, nolisten=true, gRPC on 0.0.0.0:10009, tlsextraip=<signer-ip>)lnd.service via systemd/v1/genseed), initialises the wallet, saves seed to ~/.lnd/seed_phrase.txtlncli wallet accounts list > ~/.lnd/accounts.json~/.lnd/signer.macaroonImmediately after the script completes, back up the seed:
cat ~/.lnd/seed_phrase.txt
shred -u ~/.lnd/seed_phrase.txt
Copy three files from the signer to the routing node. The signer's TLS cert must be renamed to avoid collision with litd's own cert.
# Run from routing node (or adjust source/destination)
scp ubuntu@<signer-ip>:~/.lnd/tls.cert ~/.lnd/signer-tls.cert
scp ubuntu@<signer-ip>:~/.lnd/signer.macaroon ~/.lnd/signer.macaroon
scp ubuntu@<signer-ip>:~/.lnd/accounts.json ~/.lnd/accounts.json
Verify all three files are present before running the routing node script:
ls -la ~/.lnd/signer-tls.cert ~/.lnd/signer.macaroon ~/.lnd/accounts.json
Run on the routing node machine. Bitcoind must already be installed and running. All three signer files must be in ~/.lnd/ before running.
Before running the script, the routing node script also has interactive prompts. Pre-generate the config using the same pattern as the bitcoind + litd section:
${CLAUDE_SKILL_DIR}/remote-signer/routing-node-binary.sh for the exact lit.conf structure — it includes lnd.remotesigner.* settings pointing at the signer IP from Step 1:mkdir -p ~/.lnd ~/.lit
openssl rand -hex 21 > ~/.lnd/wallet_password
chmod 600 ~/.lnd/wallet_password
# Write ~/.lit/lit.conf via heredoc — structure is in routing-node-binary.sh
Binary install:
chmod +x ${CLAUDE_SKILL_DIR}/remote-signer/routing-node-binary.sh ${CLAUDE_SKILL_DIR}/remote-signer/routing-node3.sh
sudo ${CLAUDE_SKILL_DIR}/remote-signer/routing-node-binary.sh
The script:
scp instructions if any are missing~/.lit/lit.conf with remotesigner.* settings pointing at the signerCreate the watch-only wallet (manual step between scripts):
# Start litd without systemd for first-time wallet setup
litd
# In a new terminal — initialise watch-only wallet from signer's xpubs
lncli --network=signet createwatchonly ~/.lnd/accounts.json
# Use the password from ~/.lnd/wallet_password
# Stop litd (Ctrl-C)
Enable auto-unlock and systemd service:
sudo ${CLAUDE_SKILL_DIR}/remote-signer/routing-node3.sh
routing-node3.sh uncomments the wallet unlock lines in lit.conf and creates litd.service.
Source build: routing-node.sh (installs Go/Node/Yarn) → new shell → routing-node2.sh (builds litd) → source ~/.profile if litd/lncli are not found → create watch-only wallet as above → routing-node3.sh.
# Node info (shows synced_to_chain, synced_to_graph, pubkey)
lncli --network=signet getinfo
# Check wallet balance
lncli --network=signet walletbalance
# List peers
lncli --network=signet listpeers
# Connect to a peer (required before synced_to_graph=true)
lncli --network=signet connect <pubkey>@<host>:<port>
# Check service status
systemctl status litd
systemctl status lnd # signer node only
systemctl status bitcoind
# Tail logs
journalctl -fu litd
journalctl -fu lnd
# Verify signer connectivity from routing node
lncli --network=signet --macaroonpath=~/.lnd/signer.macaroon \
--tlscertpath=~/.lnd/signer-tls.cert \
--rpcserver=<signer-ip>:10009 \
getinfo
| Pitfall | Fix |
|---|---|
synced_to_graph: false on routing node | Connect to at least one peer: lncli connect <pubkey>@<host>:<port> |
| Script exits "Missing required signer file" | Run scp to copy all three files from signer — see Step 2 above. Don't forget to rename tls.cert → signer-tls.cert. |
tls.cert and signer-tls.cert confusion | The routing node generates its own ~/.lit/tls.cert. The signer's cert must live at ~/.lnd/signer-tls.cert. lit.conf must point remotesigner.tlscertpath to the signer cert, not the local one. |
| Watch-only wallet creation fails | createwatchonly must be run while litd is running but before auto-unlock lines are uncommented in lit.conf. Run routing-node3.sh only after the wallet exists. |
wallet-unlock-allow-create=true causes issues | This flag is intentionally commented out in the initial config. routing-node3.sh uncomments it. Do not uncomment manually before the watch-only wallet is created. |
| Signer not reachable from routing node | Check that port 10009 is open between the two machines. The signer's lnd.conf must have tlsextraip=<signer-ip> set before the wallet was initialised (TLS cert bakes the IP in). If the IP was wrong, delete ~/.lnd/tls.cert and ~/.lnd/tls.key and restart lnd to regenerate. |
| Scripts fail on re-run after interruption | All scripts check existing state and skip completed steps — safe to re-run. |
| Seed phrase not backed up | The remote signer scripts and litd_wallet_create.sh all save the seed to ~/.lnd/seed_phrase.txt. Back it up to offline storage and then shred -u ~/.lnd/seed_phrase.txt immediately. |
lncli uses wrong macaroon/network | Always pass `--network=<mainnet |
| litd binary not found in PATH after install | Binary installs go to /usr/local/bin — check it is in $PATH. Source builds install to ~/go/bin — run source ~/.profile or start a new shell after litd_setup2.sh or routing-node2.sh if litd or lncli are not found. |
npx claudepluginhub lightninglabs/lightning-agent-tools --plugin lightning-agent-toolsInstalls and runs Lightning Terminal (litd) — a Docker bundle of lnd, loop, pool, tapd, and faraday. Supports watch-only with remote signer, standalone mode, and regtest. Use for Lightning payments, channel/liquidity management, or taproot assets.
Explain Bitcoin Lightning channel factories and the SuperScalar protocol for scalable onboarding using shared UTXOs, Taproot, and MuSig2.
Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.