@lightninglabs/lightning-mcp-server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.claude-plugin/marketplace.json +36 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/README.md +307 -0
  4. package/bin/lightning-mcp-server +15 -0
  5. package/docs/architecture.md +455 -0
  6. package/docs/commerce.md +357 -0
  7. package/docs/l402-and-lnget.md +267 -0
  8. package/docs/mcp-server.md +285 -0
  9. package/docs/quickref.md +263 -0
  10. package/docs/security.md +298 -0
  11. package/docs/two-agent-setup.md +394 -0
  12. package/package.json +52 -0
  13. package/postinstall.js +160 -0
  14. package/skills/aperture/SKILL.md +330 -0
  15. package/skills/aperture/scripts/install.sh +68 -0
  16. package/skills/aperture/scripts/setup.sh +155 -0
  17. package/skills/aperture/scripts/start.sh +81 -0
  18. package/skills/aperture/scripts/stop.sh +57 -0
  19. package/skills/aperture/templates/aperture-regtest.yaml +36 -0
  20. package/skills/aperture/templates/aperture.yaml.template +64 -0
  21. package/skills/aperture/templates/docker-compose-aperture.yml +59 -0
  22. package/skills/commerce/SKILL.md +211 -0
  23. package/skills/lib/config-gen.sh +127 -0
  24. package/skills/lib/rest.sh +69 -0
  25. package/skills/lightning-security-module/SKILL.md +253 -0
  26. package/skills/lightning-security-module/references/architecture.md +133 -0
  27. package/skills/lightning-security-module/scripts/docker-start.sh +117 -0
  28. package/skills/lightning-security-module/scripts/docker-stop.sh +53 -0
  29. package/skills/lightning-security-module/scripts/export-credentials.sh +268 -0
  30. package/skills/lightning-security-module/scripts/install.sh +178 -0
  31. package/skills/lightning-security-module/scripts/setup-signer.sh +307 -0
  32. package/skills/lightning-security-module/scripts/start-signer.sh +152 -0
  33. package/skills/lightning-security-module/scripts/stop-signer.sh +240 -0
  34. package/skills/lightning-security-module/templates/docker-compose-signer.yml +35 -0
  35. package/skills/lightning-security-module/templates/signer-lnd.conf.template +69 -0
  36. package/skills/lnd/SKILL.md +441 -0
  37. package/skills/lnd/profiles/debug.env +4 -0
  38. package/skills/lnd/profiles/default.env +3 -0
  39. package/skills/lnd/profiles/regtest.env +4 -0
  40. package/skills/lnd/profiles/taproot.env +3 -0
  41. package/skills/lnd/profiles/wumbo.env +3 -0
  42. package/skills/lnd/references/security.md +156 -0
  43. package/skills/lnd/scripts/create-wallet.sh +464 -0
  44. package/skills/lnd/scripts/docker-start.sh +256 -0
  45. package/skills/lnd/scripts/docker-stop.sh +109 -0
  46. package/skills/lnd/scripts/import-credentials.sh +145 -0
  47. package/skills/lnd/scripts/install.sh +195 -0
  48. package/skills/lnd/scripts/lncli.sh +150 -0
  49. package/skills/lnd/scripts/start-lnd.sh +241 -0
  50. package/skills/lnd/scripts/stop-lnd.sh +218 -0
  51. package/skills/lnd/scripts/unlock-wallet.sh +134 -0
  52. package/skills/lnd/templates/docker-compose-regtest.yml +122 -0
  53. package/skills/lnd/templates/docker-compose-watchonly.yml +71 -0
  54. package/skills/lnd/templates/docker-compose.yml +49 -0
  55. package/skills/lnd/templates/litd-regtest.conf.template +61 -0
  56. package/skills/lnd/templates/litd-watchonly.conf.template +57 -0
  57. package/skills/lnd/templates/litd.conf.template +88 -0
  58. package/skills/lnd/templates/lnd.conf.template +91 -0
  59. package/skills/lnget/SKILL.md +288 -0
  60. package/skills/lnget/scripts/install.sh +69 -0
  61. package/skills/macaroon-bakery/SKILL.md +179 -0
  62. package/skills/macaroon-bakery/scripts/bake.sh +337 -0
  63. package/skills/mcp-lnc/SKILL.md +280 -0
  64. package/skills/mcp-lnc/scripts/configure.sh +130 -0
  65. package/skills/mcp-lnc/scripts/install.sh +103 -0
  66. package/skills/mcp-lnc/scripts/setup-claude-config.sh +162 -0
  67. package/skills/mcp-lnc/templates/env.template +16 -0
  68. package/versions.env +23 -0
@@ -0,0 +1,298 @@
1
+ # Security Model
2
+
3
+ > How Lightning Agent Tools isolates private keys, scopes credentials, and
4
+ > controls what agents can do.
5
+
6
+ Agents that handle real bitcoin need a security model built for autonomous
7
+ operation. The core principle is straightforward: give the agent the minimum
8
+ credentials required for its task and keep private keys on a separate machine.
9
+ The kit enforces this through three tiers of access, each with different trust
10
+ assumptions and failure modes.
11
+
12
+ ## Three Tiers of Access
13
+
14
+ ```mermaid
15
+ graph LR
16
+ subgraph Tier1["Tier 1: Watch-Only + Remote Signer"]
17
+ direction TB
18
+ A1["Agent machine"]
19
+ S1["Signer machine"]
20
+ A1 --- |"gRPC/TLS"| S1
21
+ A1 -.- N1["No private keys"]
22
+ S1 -.- K1["Holds all keys"]
23
+ end
24
+
25
+ subgraph Tier2["Tier 2: Standalone"]
26
+ direction TB
27
+ A2["Agent machine"]
28
+ A2 -.- K2["Keys on disk<br/>(0600 permissions)"]
29
+ end
30
+
31
+ subgraph Tier3["Tier 3: Read-Only via MCP-LNC"]
32
+ direction TB
33
+ A3["Agent machine"]
34
+ MB["Mailbox relay"]
35
+ A3 --- |"encrypted WebSocket"| MB
36
+ A3 -.- N3["No credentials on disk<br/>Ephemeral keys only"]
37
+ end
38
+ ```
39
+
40
+ ### Tier 1: Watch-Only with Remote Signer
41
+
42
+ This is the default and recommended configuration. The agent machine runs an
43
+ lnd node in watch-only mode. It can see balances, manage channels, and route
44
+ payments, but it has no private keys. All signing is delegated to a separate
45
+ signer node over an authenticated gRPC connection.
46
+
47
+ **What the agent machine has:**
48
+ - Account xpubs (public keys for address derivation)
49
+ - A TLS certificate and macaroon for the signer's gRPC interface
50
+ - Scoped macaroons for the local lnd (baked via `macaroon-bakery`)
51
+
52
+ **What the agent machine does not have:**
53
+ - The wallet seed
54
+ - Any private keys (funding, revocation, HTLC, or on-chain)
55
+
56
+ **If the agent machine is compromised,** an attacker can observe channel state,
57
+ balances, and payment history. They can see which peers the node is connected to
58
+ and the topology of its channels. But they cannot sign transactions, sweep
59
+ funds, or forge channel commitment updates. The keys are simply not there.
60
+
61
+ **If the signer machine is compromised,** the attacker has full control over all
62
+ private keys and can sign arbitrary transactions. This is a complete compromise.
63
+ The signer machine should have a minimal attack surface: no public-facing
64
+ services, restricted network access (only the watch-only node should reach port
65
+ 10012), and ideally dedicated hardware.
66
+
67
+ **Setup:** Use the `lightning-security-module` skill on the signer machine and
68
+ the `lnd` skill in watch-only mode on the agent machine. See
69
+ [Architecture](architecture.md#remote-signer) for the signing flow.
70
+
71
+ ### Tier 2: Standalone
72
+
73
+ The node generates its own seed and stores it locally. The 24-word mnemonic is
74
+ written to `~/.lnget/lnd/seed.txt` and the wallet passphrase to
75
+ `~/.lnget/lnd/wallet-password.txt`, both with mode 0600.
76
+
77
+ This mode is appropriate for:
78
+ - Testnet and regtest development
79
+ - Small-value experiments on mainnet
80
+ - Environments where a separate signer machine is impractical
81
+
82
+ It is **not appropriate** for production deployments with significant funds.
83
+ Anyone with read access to `~/.lnget/lnd/seed.txt` can reconstruct the wallet's
84
+ private keys.
85
+
86
+ **Setup:** Pass `--mode standalone` to `create-wallet.sh`.
87
+
88
+ ### Tier 3: Read-Only via MCP-LNC
89
+
90
+ The MCP server connects to a Lightning node through an encrypted LNC tunnel
91
+ using a 10-word pairing phrase. No credentials are written to disk. The
92
+ pairing phrase is handled in memory and an ephemeral ECDSA keypair is generated
93
+ per session. When the session ends, the keypair is discarded.
94
+
95
+ This tier exposes 18 read-only tools. The agent can query balances, list
96
+ channels, decode invoices, and inspect the network graph, but it cannot send
97
+ payments, open channels, or modify any node state.
98
+
99
+ **If the agent machine is compromised,** the attacker gains read access to the
100
+ node's state for the duration of the active LNC session. Once the session is
101
+ closed, no credentials remain to reconnect.
102
+
103
+ **Setup:** Use the `mcp-lnc` skill. See [MCP Server](mcp-server.md) for the
104
+ setup walkthrough.
105
+
106
+ ## Remote Signer in Depth
107
+
108
+ The remote signer splits a Lightning node into two processes. The signer runs
109
+ lnd with the seed and private keys but does not connect to the peer-to-peer
110
+ network, does not route payments, and does not manage channels. The watch-only
111
+ node does everything else. By default, both run in Docker containers
112
+ (`litd-signer` and `litd` respectively); pass `--native` to scripts for local
113
+ binary mode.
114
+
115
+ ### Credential Bundle
116
+
117
+ When you run `setup-signer.sh`, the signer creates a wallet and exports a
118
+ credentials bundle to `~/.lnget/signer/credentials-bundle/`:
119
+
120
+ | File | What it contains | What it's used for |
121
+ |------|-----------------|-------------------|
122
+ | `accounts.json` | Account xpubs (public keys) | Watch-only wallet creation |
123
+ | `tls.cert` | Signer's TLS certificate | Authenticating the gRPC connection |
124
+ | `admin.macaroon` | Signer's admin macaroon | Authorizing signing RPCs |
125
+
126
+ A base64 tarball (`credentials-bundle.tar.gz.b64`) is also generated for
127
+ transfer. On the agent machine, `import-credentials.sh` unpacks it into
128
+ `~/.lnget/lnd/signer-credentials/`.
129
+
130
+ ### Signing Protocol
131
+
132
+ The watch-only node constructs transactions locally and sends them to the signer
133
+ for signature via gRPC. The signer validates each request, signs with the
134
+ appropriate key, and returns the signature. The watch-only node then assembles
135
+ and broadcasts the signed transaction.
136
+
137
+ ```mermaid
138
+ sequenceDiagram
139
+ participant WO as Watch-Only lnd<br/>(agent machine)
140
+ participant S as Signer lnd<br/>(secure machine)
141
+ participant Net as Bitcoin Network
142
+
143
+ Note over WO: Needs to close a channel
144
+ WO->>WO: Build unsigned commitment tx
145
+ WO->>S: SignOutputRaw(unsigned_tx, key_desc)
146
+ S->>S: Look up private key
147
+ S->>S: Validate request
148
+ S->>S: Produce signature
149
+ S-->>WO: Signature bytes
150
+ WO->>WO: Attach signature to tx
151
+ WO->>Net: Broadcast signed tx
152
+ ```
153
+
154
+ The gRPC connection between the watch-only node and the signer is secured with
155
+ mutual TLS. The watch-only node uses the signer's exported TLS certificate
156
+ (`tls.cert`) to verify the server's identity. The macaroon provides
157
+ authorization.
158
+
159
+ ### Hardening the Signer
160
+
161
+ For production deployments:
162
+
163
+ - **Scope the signer macaroon.** Replace `admin.macaroon` with a `signer-only`
164
+ macaroon baked via `macaroon-bakery`. This restricts the watch-only node to
165
+ signing operations and key derivation. It cannot call any other RPC on the
166
+ signer.
167
+
168
+ ```bash
169
+ # Container mode (auto-detects litd-signer)
170
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only --container litd-signer
171
+
172
+ # Native mode
173
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only \
174
+ --rpc-port 10012 --lnddir ~/.lnd-signer
175
+ ```
176
+
177
+ - **Firewall the signer.** Only the watch-only node's IP should be able to
178
+ reach port 10012. Block all other inbound traffic.
179
+
180
+ - **Dedicate the hardware.** Run the signer on a separate machine or hardened
181
+ VM with no other services. Minimize the installed software and disable remote
182
+ access except through a controlled management channel.
183
+
184
+ - **Rotate macaroons.** Bake new macaroons periodically and update the
185
+ watch-only node's configuration. The old root key can be revoked to
186
+ invalidate the previous macaroon.
187
+
188
+ ## Macaroon Security
189
+
190
+ Macaroons are bearer tokens. Anyone who has a copy of a macaroon can exercise
191
+ its permissions against the lnd node that issued it. Treat them like passwords:
192
+ store them with restrictive file permissions (0600), don't commit them to
193
+ version control, and don't transmit them over unencrypted channels.
194
+
195
+ ### Preset Roles
196
+
197
+ The `macaroon-bakery` skill provides five preset roles that cover common agent
198
+ use cases. Each role grants the minimum set of RPC permissions needed:
199
+
200
+ | Role | Permissions granted | Typical use case |
201
+ |------|-------------------|-----------------|
202
+ | `pay-only` | `SendPaymentSync`, `DecodePayReq`, `GetInfo` | Agent that buys L402 resources via lnget |
203
+ | `invoice-only` | `AddInvoice`, `LookupInvoice`, `ListInvoices`, `GetInfo` | Agent that sells resources via aperture |
204
+ | `read-only` | `GetInfo`, `WalletBalance`, `ChannelBalance`, `ListChannels`, `ListPeers`, `ListPayments`, `ListInvoices` | Monitoring and reporting |
205
+ | `channel-admin` | Everything in `read-only` + `OpenChannelSync`, `CloseChannel`, `ConnectPeer` | Node management |
206
+ | `signer-only` | `SignOutputRaw`, `ComputeInputScript`, `MuSig2Sign`, `DeriveKey`, `DeriveNextKey` | Remote signer credentials |
207
+
208
+ ### Custom Macaroons
209
+
210
+ For permissions that don't fit a preset role, bake a custom macaroon with
211
+ specific URI permissions:
212
+
213
+ ```bash
214
+ skills/macaroon-bakery/scripts/bake.sh --custom \
215
+ uri:/lnrpc.Lightning/SendPaymentSync \
216
+ uri:/lnrpc.Lightning/DecodePayReq \
217
+ uri:/lnrpc.Lightning/WalletBalance \
218
+ uri:/lnrpc.Lightning/GetInfo
219
+ ```
220
+
221
+ The full list of available permission URIs is available via:
222
+
223
+ ```bash
224
+ skills/macaroon-bakery/scripts/bake.sh --list-permissions
225
+ ```
226
+
227
+ ### Rotation
228
+
229
+ Macaroon rotation involves baking a new macaroon, updating the agent's
230
+ configuration to use it, and optionally revoking the old root key:
231
+
232
+ ```bash
233
+ # Bake replacement
234
+ skills/macaroon-bakery/scripts/bake.sh --role pay-only \
235
+ --save-to ~/pay-only-v2.macaroon
236
+
237
+ # Update agent config to point at the new macaroon
238
+
239
+ # Revoke old root key (invalidates all macaroons baked with it)
240
+ skills/lnd/scripts/lncli.sh bakemacaroon --root_key_id 0
241
+ ```
242
+
243
+ ## Production Checklist
244
+
245
+ Before deploying the kit with real funds:
246
+
247
+ 1. **Use the remote signer.** Set up `lightning-security-module` on a separate
248
+ machine. Run the agent's lnd in watch-only mode. Do not use standalone mode
249
+ for production.
250
+
251
+ 2. **Scope all macaroons.** Bake role-specific macaroons for each agent. Never
252
+ distribute `admin.macaroon`. A buyer agent gets `pay-only`; a seller agent
253
+ gets `invoice-only`; a monitoring agent gets `read-only`.
254
+
255
+ 3. **Scope the signer macaroon.** Replace the signer's `admin.macaroon` with
256
+ a `signer-only` macaroon. The watch-only node only needs signing and key
257
+ derivation permissions on the signer.
258
+
259
+ 4. **Firewall the signer.** Restrict port 10012 to the watch-only node's IP.
260
+ In container mode, port 10013 (REST) is bound to `0.0.0.0` for Docker
261
+ networking but is only host-mapped during wallet setup. In native mode,
262
+ `setup-signer.sh` rebinds REST to `localhost`.
263
+
264
+ 5. **Secure credential files.** Verify that `wallet-password.txt`, `seed.txt`,
265
+ and all `.macaroon` files have mode 0600. The kit's scripts set this
266
+ automatically, but verify after any manual operations.
267
+
268
+ 6. **Set spending limits.** Configure `--max-cost` on lnget commands to cap
269
+ per-request spending. Monitor wallet balances programmatically.
270
+
271
+ 7. **Back up the seed.** The signer's `seed.txt` is the only way to recover
272
+ funds if the signer's storage fails. Store the 24-word mnemonic securely
273
+ offline.
274
+
275
+ ## Credential File Reference
276
+
277
+ Every credential and secret file the kit manages:
278
+
279
+ | File | Mode | Machine | Purpose |
280
+ |------|------|---------|---------|
281
+ | `~/.lnget/lnd/wallet-password.txt` | 0600 | Agent | lnd wallet unlock passphrase |
282
+ | `~/.lnget/lnd/seed.txt` | 0600 | Agent | 24-word mnemonic (standalone only) |
283
+ | `~/.lnget/lnd/signer-credentials/tls.cert` | 0644 | Agent | Signer's TLS cert |
284
+ | `~/.lnget/lnd/signer-credentials/admin.macaroon` | 0600 | Agent | Signer RPC auth |
285
+ | `~/.lnget/lnd/signer-credentials/accounts.json` | 0600 | Agent | Account xpubs |
286
+ | `~/.lnget/signer/wallet-password.txt` | 0600 | Signer | Signer wallet passphrase |
287
+ | `~/.lnget/signer/seed.txt` | 0600 | Signer | Signer 24-word mnemonic |
288
+ | `~/.lnd/data/chain/bitcoin/<network>/admin.macaroon` | 0600 | Agent | lnd admin macaroon |
289
+ | `~/.lnd-signer/data/chain/bitcoin/<network>/admin.macaroon` | 0600 | Signer | Signer admin macaroon |
290
+ | `~/.lnget/tokens/<domain>/` | 0700 | Agent | Cached L402 tokens |
291
+ | `~/.aperture/aperture.yaml` | 0600 | Seller | Aperture config (may contain credentials) |
292
+
293
+ **Container mode note:** In container deployments, daemon data directories
294
+ (`~/.lnd/`, `~/.lnd-signer/`) live inside Docker volumes (`litd-data`,
295
+ `signer-data`) rather than on the host filesystem. The host-side credential
296
+ files under `~/.lnget/` remain the same in both modes. Use `docker cp` or
297
+ `export-credentials.sh --container` to extract macaroons and TLS certs from
298
+ running containers.
@@ -0,0 +1,394 @@
1
+ # Two-Agent Secure Setup
2
+
3
+ > Using one agent to set up the remote signer and another to run the
4
+ > watch-only node.
5
+
6
+ The recommended production deployment splits key management across two
7
+ machines: a signer that holds private keys and a node that handles payments
8
+ and channels. Each machine can be operated by its own agent. The signer agent
9
+ runs on the secure machine and exports a credentials bundle. The node agent
10
+ runs on the agent-facing machine, imports that bundle, and starts a watch-only
11
+ lnd instance that delegates all signing back to the signer.
12
+
13
+ This walkthrough covers the full flow from both sides.
14
+
15
+ ## Overview
16
+
17
+ ```mermaid
18
+ sequenceDiagram
19
+ participant SA as Signer Agent<br/>(secure machine)
20
+ participant Transfer as Credentials Transfer
21
+ participant NA as Node Agent<br/>(agent machine)
22
+
23
+ SA->>SA: Install lnd
24
+ SA->>SA: Create signer wallet
25
+ SA->>SA: Start signer lnd
26
+ SA->>SA: Export credentials bundle
27
+ SA->>Transfer: credentials-bundle.tar.gz.b64
28
+
29
+ Transfer->>NA: Copy bundle to agent machine
30
+
31
+ NA->>NA: Install lnd
32
+ NA->>NA: Import credentials bundle
33
+ NA->>NA: Create watch-only wallet
34
+ NA->>NA: Start watch-only lnd
35
+ NA->>NA: Verify connection to signer
36
+ ```
37
+
38
+ The credentials bundle contains three files:
39
+
40
+ | File | What it is | What it's for |
41
+ |------|-----------|---------------|
42
+ | `accounts.json` | Account xpubs (public keys only) | Creating the watch-only wallet |
43
+ | `tls.cert` | Signer's TLS certificate | Authenticating the gRPC connection |
44
+ | `admin.macaroon` | Signer's RPC token | Authorizing signing requests |
45
+
46
+ No private keys cross the wire. The bundle contains only public keys and
47
+ authentication material.
48
+
49
+ ## Container Mode (Recommended)
50
+
51
+ Docker is the default deployment method. All scripts auto-detect containers
52
+ and route commands through `docker exec`.
53
+
54
+ ### Signer Machine
55
+
56
+ ```bash
57
+ # Pull the lnd signer image.
58
+ skills/lightning-security-module/scripts/install.sh
59
+
60
+ # Create the signer wallet and export the credentials bundle.
61
+ # This launches the litd-signer container, creates the wallet via REST API,
62
+ # and exports the bundle to ~/.lnget/signer/credentials-bundle/.
63
+ skills/lightning-security-module/scripts/setup-signer.sh
64
+
65
+ # Start the signer container (if not already running from setup).
66
+ skills/lightning-security-module/scripts/start-signer.sh
67
+ ```
68
+
69
+ Transfer the credentials bundle to the agent machine:
70
+
71
+ ```bash
72
+ scp ~/.lnget/signer/credentials-bundle/credentials-bundle.tar.gz.b64 \
73
+ agent-machine:~/credentials-bundle.tar.gz.b64
74
+ ```
75
+
76
+ ### Agent Machine
77
+
78
+ ```bash
79
+ # Pull the litd image.
80
+ skills/lnd/scripts/install.sh
81
+
82
+ # Import the signer's credentials bundle.
83
+ skills/lnd/scripts/import-credentials.sh --bundle ~/credentials-bundle.tar.gz.b64
84
+
85
+ # Create the watch-only wallet (auto-detects the litd container).
86
+ skills/lnd/scripts/create-wallet.sh
87
+
88
+ # Start in watch-only mode (launches litd + signer containers via Docker Compose).
89
+ skills/lnd/scripts/start-lnd.sh --watchonly
90
+
91
+ # Verify.
92
+ skills/lnd/scripts/lncli.sh getinfo
93
+ skills/lnd/scripts/lncli.sh newaddress p2tr
94
+ ```
95
+
96
+ The `--watchonly` flag uses `docker-compose-watchonly.yml`, which starts both a
97
+ litd container (watch-only) and connects it to the signer via the Docker
98
+ network. The signer's gRPC address is pre-configured in the watch-only template
99
+ (`lnd.remotesigner.rpchost=signer:10012`).
100
+
101
+ ### Container Lifecycle
102
+
103
+ ```bash
104
+ # Stop containers.
105
+ skills/lnd/scripts/stop-lnd.sh
106
+
107
+ # Stop and remove volumes (destructive — removes chain data).
108
+ skills/lnd/scripts/stop-lnd.sh --clean
109
+
110
+ # On signer machine.
111
+ skills/lightning-security-module/scripts/stop-signer.sh
112
+ skills/lightning-security-module/scripts/stop-signer.sh --clean
113
+ ```
114
+
115
+ ### Scoping the Signer Macaroon (Container)
116
+
117
+ ```bash
118
+ # On the signer machine, bake a scoped macaroon inside the container.
119
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only --container litd-signer
120
+
121
+ # Re-export the credentials bundle with the scoped macaroon.
122
+ skills/lightning-security-module/scripts/export-credentials.sh --container litd-signer
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Native Mode
128
+
129
+ For environments without Docker, all scripts accept a `--native` flag to use
130
+ locally installed binaries.
131
+
132
+ ### Part 1: Signer Agent (Secure Machine)
133
+
134
+ The signer agent runs on a machine with restricted access. This machine will
135
+ hold all private keys and never connect to the Lightning Network directly.
136
+
137
+ ### Install lnd
138
+
139
+ ```bash
140
+ skills/lightning-security-module/scripts/install.sh --source
141
+ ```
142
+
143
+ This builds lnd from source with the signing-related build tags. The binary is
144
+ the same as a regular lnd install, but the signer's configuration restricts it
145
+ to signing operations only.
146
+
147
+ ### Create the signer wallet and export credentials
148
+
149
+ ```bash
150
+ skills/lightning-security-module/scripts/setup-signer.sh --native
151
+ ```
152
+
153
+ This does three things:
154
+
155
+ 1. Generates a new wallet with a random passphrase and 24-word seed mnemonic.
156
+ Both are saved to `~/.lnget/signer/` with mode 0600.
157
+ 2. Starts the signer lnd temporarily to extract account xpubs.
158
+ 3. Exports the credentials bundle to
159
+ `~/.lnget/signer/credentials-bundle/`.
160
+
161
+ The bundle directory contains the three files listed above plus a
162
+ base64-encoded tarball (`credentials-bundle.tar.gz.b64`) for easy transfer.
163
+
164
+ ### Start the signer
165
+
166
+ ```bash
167
+ skills/lightning-security-module/scripts/start-signer.sh --native
168
+ ```
169
+
170
+ The signer listens on port 10012 (gRPC) for signing requests from the
171
+ watch-only node. In native mode, REST binds to `localhost:10013` only. It does
172
+ not connect to any peers and does not participate in the Lightning Network.
173
+
174
+ ### Transfer the bundle
175
+
176
+ The base64-encoded bundle needs to reach the agent machine. How you transfer
177
+ it depends on your environment:
178
+
179
+ ```bash
180
+ # Option 1: scp
181
+ scp ~/.lnget/signer/credentials-bundle/credentials-bundle.tar.gz.b64 \
182
+ agent-machine:~/credentials-bundle.tar.gz.b64
183
+
184
+ # Option 2: Print to terminal and copy-paste
185
+ cat ~/.lnget/signer/credentials-bundle/credentials-bundle.tar.gz.b64
186
+ ```
187
+
188
+ The bundle contains a macaroon (bearer token) and a TLS certificate. Treat it
189
+ like a password during transfer.
190
+
191
+ ### Optional: scope the signer macaroon
192
+
193
+ The exported `admin.macaroon` grants full RPC access to the signer. For
194
+ production, replace it with a `signer-only` macaroon that restricts the
195
+ watch-only node to signing and key derivation:
196
+
197
+ ```bash
198
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only \
199
+ --rpc-port 10012 --lnddir ~/.lnd-signer
200
+ ```
201
+
202
+ Then re-export the credentials bundle with the scoped macaroon:
203
+
204
+ ```bash
205
+ skills/lightning-security-module/scripts/export-credentials.sh
206
+ ```
207
+
208
+ ### Part 2: Node Agent (Agent Machine)
209
+
210
+ The node agent runs on the machine where agents will operate. This machine
211
+ will have no private keys.
212
+
213
+ ### Install lnd
214
+
215
+ ```bash
216
+ skills/lnd/scripts/install.sh --source
217
+ ```
218
+
219
+ ### Import the credentials bundle
220
+
221
+ ```bash
222
+ skills/lnd/scripts/import-credentials.sh \
223
+ --bundle ~/credentials-bundle.tar.gz.b64
224
+ ```
225
+
226
+ This unpacks the bundle into `~/.lnget/lnd/signer-credentials/`, placing
227
+ `accounts.json`, `tls.cert`, and `admin.macaroon` where the watch-only node
228
+ expects them.
229
+
230
+ ### Create the watch-only wallet
231
+
232
+ ```bash
233
+ skills/lnd/scripts/create-wallet.sh --native \
234
+ --signer-host <signer-ip>:10012
235
+ ```
236
+
237
+ Replace `<signer-ip>` with the signer machine's IP address or hostname. This
238
+ creates a wallet that imports the account xpubs from the credentials bundle.
239
+ The wallet has no seed and no private keys. It generates a random passphrase
240
+ stored at `~/.lnget/lnd/wallet-password.txt` (mode 0600).
241
+
242
+ The `--signer-host` flag tells the wallet creation process where to find the
243
+ signer for initial key verification.
244
+
245
+ ### Start the watch-only node
246
+
247
+ ```bash
248
+ skills/lnd/scripts/start-lnd.sh --native \
249
+ --signer-host <signer-ip>:10012
250
+ ```
251
+
252
+ The node starts with `remotesigner.enable=true` in its config, pointing at
253
+ the signer's gRPC address. It connects to the Bitcoin network via Neutrino,
254
+ syncs headers, and begins normal operation. Any transaction that requires a
255
+ signature (channel opens, closes, on-chain sends) is forwarded to the signer
256
+ over the authenticated gRPC connection.
257
+
258
+ ### Verify
259
+
260
+ ```bash
261
+ skills/lnd/scripts/lncli.sh getinfo
262
+ ```
263
+
264
+ The node should report synced status. To confirm the signer connection is
265
+ working, try generating a new address (which requires key derivation from the
266
+ signer):
267
+
268
+ ```bash
269
+ skills/lnd/scripts/lncli.sh newaddress p2tr
270
+ ```
271
+
272
+ If this returns an address, the watch-only node and signer are communicating
273
+ correctly.
274
+
275
+ ## What Each Agent Can See
276
+
277
+ After setup, the two agents have different views of the system:
278
+
279
+ ```mermaid
280
+ graph LR
281
+ subgraph Signer["Signer Agent"]
282
+ S_seed["Wallet seed (24 words)"]
283
+ S_keys["All private keys"]
284
+ S_pass["Wallet passphrase"]
285
+ S_mac["Signer macaroons"]
286
+ end
287
+
288
+ subgraph Node["Node Agent"]
289
+ N_xpubs["Account xpubs (public)"]
290
+ N_cert["Signer TLS cert"]
291
+ N_smac["Signer macaroon (scoped)"]
292
+ N_pass["Node wallet passphrase"]
293
+ N_mac["Node macaroons"]
294
+ N_state["Channel state, balances, peers"]
295
+ end
296
+
297
+ subgraph Neither["Neither Agent Has"]
298
+ X1["Cross-machine shell access"]
299
+ X2["Each other's wallet passphrase"]
300
+ end
301
+ ```
302
+
303
+ The node agent can see balances, channel state, and payment history. It can
304
+ initiate payments and open channels (the signing is handled transparently by
305
+ the signer). It cannot extract private keys because they are not on its
306
+ machine.
307
+
308
+ The signer agent can see its own wallet state but has no visibility into the
309
+ watch-only node's channels or payment activity. It responds to signing
310
+ requests but does not initiate any network activity.
311
+
312
+ ## Network Requirements
313
+
314
+ The watch-only node needs to reach the signer on port 10012 (gRPC over TLS).
315
+ This is the only network path between the two machines.
316
+
317
+ ```mermaid
318
+ graph LR
319
+ WO["Watch-Only Node"] -->|"TCP :10012<br/>gRPC/TLS"| S["Signer"]
320
+ WO -->|"TCP :9735<br/>Lightning P2P"| LN["Lightning Network"]
321
+ WO -->|"TCP :18333<br/>Neutrino"| BTC["Bitcoin Peers"]
322
+
323
+ S -.-x|"No outbound<br/>connections"| LN
324
+ S -.-x|"No outbound<br/>connections"| BTC
325
+ ```
326
+
327
+ The signer should be firewalled to accept connections only from the watch-only
328
+ node's IP on port 10012. It makes no outbound connections.
329
+
330
+ ## Ongoing Operations
331
+
332
+ Once both sides are running, day-to-day operations happen on the node agent's
333
+ machine:
334
+
335
+ ```bash
336
+ # Check node status
337
+ skills/lnd/scripts/lncli.sh getinfo
338
+
339
+ # Fund the wallet
340
+ skills/lnd/scripts/lncli.sh newaddress p2tr
341
+ skills/lnd/scripts/lncli.sh walletbalance
342
+
343
+ # Open channels
344
+ skills/lnd/scripts/lncli.sh connect <pubkey>@<host>:9735
345
+ skills/lnd/scripts/lncli.sh openchannel --node_key=<pubkey> --local_amt=1000000
346
+
347
+ # Send payments
348
+ skills/lnd/scripts/lncli.sh sendpayment --pay_req=<bolt11>
349
+
350
+ # Use lnget for L402
351
+ lnget --max-cost 500 https://api.example.com/data
352
+ ```
353
+
354
+ The signer agent's role is maintenance: keeping the signer process running,
355
+ rotating macaroons periodically, and backing up the seed.
356
+
357
+ ```bash
358
+ # On the signer machine (container mode)
359
+ skills/lightning-security-module/scripts/start-signer.sh # delegates to docker-start.sh
360
+ skills/lightning-security-module/scripts/stop-signer.sh # delegates to docker-stop.sh
361
+
362
+ # Rotate the signer macaroon (container)
363
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only --container litd-signer
364
+ skills/lightning-security-module/scripts/export-credentials.sh --container litd-signer
365
+
366
+ # Rotate the signer macaroon (native)
367
+ skills/macaroon-bakery/scripts/bake.sh --role signer-only \
368
+ --rpc-port 10012 --lnddir ~/.lnd-signer
369
+ skills/lightning-security-module/scripts/export-credentials.sh --native
370
+
371
+ # Then transfer the new bundle to the node agent and re-import
372
+ ```
373
+
374
+ ## Credential Scoping for the Node Agent
375
+
376
+ After the watch-only node is running, bake scoped macaroons for the node
377
+ agent's specific tasks. Do not leave the node agent using `admin.macaroon`:
378
+
379
+ ```bash
380
+ # On the node agent's machine
381
+
382
+ # For a buyer agent (pays for L402 resources)
383
+ skills/macaroon-bakery/scripts/bake.sh --role pay-only
384
+
385
+ # For a seller agent (generates invoices via aperture)
386
+ skills/macaroon-bakery/scripts/bake.sh --role invoice-only
387
+
388
+ # For a monitoring agent
389
+ skills/macaroon-bakery/scripts/bake.sh --role read-only
390
+ ```
391
+
392
+ This gives you two layers of credential scoping: the signer macaroon limits
393
+ what the watch-only node can ask the signer to do, and the node macaroon
394
+ limits what the agent can ask the watch-only node to do.