@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,53 @@
1
+ #!/usr/bin/env bash
2
+ # Stop the remote signer container.
3
+ #
4
+ # Usage:
5
+ # docker-stop.sh # Stop (preserve data)
6
+ # docker-stop.sh --clean # Stop and remove volumes
7
+
8
+ set -e
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ TEMPLATE_DIR="$SCRIPT_DIR/../templates"
12
+ CLEAN=false
13
+
14
+ # Parse arguments.
15
+ while [[ $# -gt 0 ]]; do
16
+ case $1 in
17
+ --clean|-v)
18
+ CLEAN=true
19
+ shift
20
+ ;;
21
+ -h|--help)
22
+ echo "Usage: docker-stop.sh [options]"
23
+ echo ""
24
+ echo "Stop the remote signer container."
25
+ echo ""
26
+ echo "Options:"
27
+ echo " --clean, -v Remove volumes (clean state)"
28
+ exit 0
29
+ ;;
30
+ *)
31
+ echo "Unknown option: $1" >&2
32
+ exit 1
33
+ ;;
34
+ esac
35
+ done
36
+
37
+ # Check if the signer container is running.
38
+ if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -qx 'litd-signer'; then
39
+ echo "Signer container is not running."
40
+ exit 0
41
+ fi
42
+
43
+ cd "$TEMPLATE_DIR"
44
+
45
+ echo "Stopping signer container..."
46
+
47
+ if [ "$CLEAN" = true ]; then
48
+ docker compose -f docker-compose-signer.yml down -v
49
+ echo "Stopped and removed volumes."
50
+ else
51
+ docker compose -f docker-compose-signer.yml down
52
+ echo "Stopped (volumes preserved)."
53
+ fi
@@ -0,0 +1,268 @@
1
+ #!/usr/bin/env bash
2
+ # Export credentials bundle from a running signer for watch-only node import.
3
+ #
4
+ # Container mode (default — auto-detects litd-signer container):
5
+ # export-credentials.sh # Auto-detect container
6
+ # export-credentials.sh --container litd-signer # Explicit container
7
+ #
8
+ # Native mode:
9
+ # export-credentials.sh --native # Local signer
10
+ # export-credentials.sh --native --network testnet # Testnet
11
+ # export-credentials.sh --native --output /path # Custom output dir
12
+ #
13
+ # Remote mode:
14
+ # export-credentials.sh --rpcserver remote:10012 \
15
+ # --tlscertpath ~/tls.cert \
16
+ # --macaroonpath ~/admin.macaroon
17
+ #
18
+ # Produces:
19
+ # ~/.lnget/signer/credentials-bundle/accounts.json
20
+ # ~/.lnget/signer/credentials-bundle/tls.cert
21
+ # ~/.lnget/signer/credentials-bundle/admin.macaroon
22
+ # ~/.lnget/signer/credentials-bundle.tar.gz.b64 (portable base64)
23
+
24
+ set -e
25
+
26
+ LNGET_SIGNER_DIR="${LNGET_SIGNER_DIR:-$HOME/.lnget/signer}"
27
+ LND_SIGNER_DIR="${LND_SIGNER_DIR:-}"
28
+ NETWORK="testnet"
29
+ RPC_PORT=10012
30
+ OUTPUT_DIR=""
31
+ CONTAINER=""
32
+ NATIVE=false
33
+ RPCSERVER=""
34
+ TLSCERTPATH=""
35
+ MACAROONPATH=""
36
+
37
+ # Parse arguments.
38
+ while [[ $# -gt 0 ]]; do
39
+ case $1 in
40
+ --network)
41
+ NETWORK="$2"
42
+ shift 2
43
+ ;;
44
+ --lnddir)
45
+ LND_SIGNER_DIR="$2"
46
+ shift 2
47
+ ;;
48
+ --rpc-port)
49
+ RPC_PORT="$2"
50
+ shift 2
51
+ ;;
52
+ --output)
53
+ OUTPUT_DIR="$2"
54
+ shift 2
55
+ ;;
56
+ --container)
57
+ CONTAINER="$2"
58
+ shift 2
59
+ ;;
60
+ --native)
61
+ NATIVE=true
62
+ shift
63
+ ;;
64
+ --rpcserver)
65
+ RPCSERVER="$2"
66
+ shift 2
67
+ ;;
68
+ --tlscertpath)
69
+ TLSCERTPATH="$2"
70
+ shift 2
71
+ ;;
72
+ --macaroonpath)
73
+ MACAROONPATH="$2"
74
+ shift 2
75
+ ;;
76
+ -h|--help)
77
+ echo "Usage: export-credentials.sh [options]"
78
+ echo ""
79
+ echo "Export credentials bundle from a running signer."
80
+ echo ""
81
+ echo "Connection options:"
82
+ echo " --container NAME Export from signer in a Docker container"
83
+ echo " --native Export from local signer process"
84
+ echo " --rpcserver HOST:PORT Connect to a remote signer node"
85
+ echo " --tlscertpath PATH TLS certificate for remote connection (also bundled)"
86
+ echo " --macaroonpath PATH Macaroon for remote authentication (also bundled)"
87
+ echo ""
88
+ echo "Options:"
89
+ echo " --network NETWORK Bitcoin network (default: testnet)"
90
+ echo " --lnddir DIR Signer lnd data directory (default: ~/.lnd-signer)"
91
+ echo " --rpc-port PORT Signer RPC port (default: 10012)"
92
+ echo " --output DIR Output directory (default: ~/.lnget/signer/credentials-bundle)"
93
+ echo ""
94
+ echo "Container auto-detection: looks for litd-signer container."
95
+ exit 0
96
+ ;;
97
+ *)
98
+ echo "Unknown option: $1" >&2
99
+ exit 1
100
+ ;;
101
+ esac
102
+ done
103
+
104
+ # Auto-detect container if not native, no container, and no remote.
105
+ if [ "$NATIVE" = false ] && [ -z "$CONTAINER" ] && [ -z "$RPCSERVER" ]; then
106
+ if command -v docker &>/dev/null; then
107
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx 'litd-signer'; then
108
+ CONTAINER="litd-signer"
109
+ fi
110
+ fi
111
+
112
+ # If no container found, fall back to native.
113
+ if [ -z "$CONTAINER" ]; then
114
+ NATIVE=true
115
+ fi
116
+ fi
117
+
118
+ # Apply default lnddir if not set.
119
+ if [ -z "$LND_SIGNER_DIR" ]; then
120
+ if [ -n "$CONTAINER" ]; then
121
+ LND_SIGNER_DIR="/root/.lnd"
122
+ else
123
+ LND_SIGNER_DIR="$HOME/.lnd-signer"
124
+ fi
125
+ fi
126
+
127
+ BUNDLE_DIR="${OUTPUT_DIR:-$LNGET_SIGNER_DIR/credentials-bundle}"
128
+
129
+ echo "=== Exporting Credentials Bundle ==="
130
+ echo ""
131
+ echo "Network: $NETWORK"
132
+ if [ -n "$CONTAINER" ]; then
133
+ echo "Container: $CONTAINER"
134
+ elif [ -n "$RPCSERVER" ]; then
135
+ echo "Remote: $RPCSERVER"
136
+ else
137
+ echo "Signer dir: $LND_SIGNER_DIR"
138
+ fi
139
+ echo "Output: $BUNDLE_DIR"
140
+ echo ""
141
+
142
+ # Verify lncli is available.
143
+ if [ -n "$CONTAINER" ]; then
144
+ if ! docker exec "$CONTAINER" which lncli &>/dev/null; then
145
+ echo "Error: lncli not found in container '$CONTAINER'." >&2
146
+ exit 1
147
+ fi
148
+ elif [ -z "$RPCSERVER" ]; then
149
+ if ! command -v lncli &>/dev/null; then
150
+ echo "Error: lncli not found. Run install.sh first." >&2
151
+ exit 1
152
+ fi
153
+ else
154
+ if ! command -v lncli &>/dev/null; then
155
+ echo "Error: lncli not found. Install lncli to connect to the remote signer." >&2
156
+ exit 1
157
+ fi
158
+ fi
159
+
160
+ # Create bundle directory.
161
+ mkdir -p "$BUNDLE_DIR"
162
+ chmod 700 "$BUNDLE_DIR"
163
+
164
+ # Build lncli connection flags.
165
+ LNCLI_CONN=()
166
+ if [ -n "$RPCSERVER" ]; then
167
+ LNCLI_CONN+=("--rpcserver=$RPCSERVER")
168
+ else
169
+ LNCLI_CONN+=("--rpcserver=localhost:$RPC_PORT")
170
+ fi
171
+ LNCLI_CONN+=("--lnddir=$LND_SIGNER_DIR" "--network=$NETWORK")
172
+ if [ -n "$TLSCERTPATH" ]; then
173
+ LNCLI_CONN+=("--tlscertpath=$TLSCERTPATH")
174
+ fi
175
+ if [ -n "$MACAROONPATH" ]; then
176
+ LNCLI_CONN+=("--macaroonpath=$MACAROONPATH")
177
+ fi
178
+
179
+ # Export accounts list.
180
+ echo "Exporting accounts..."
181
+ if [ -n "$CONTAINER" ]; then
182
+ docker exec "$CONTAINER" lncli "${LNCLI_CONN[@]}" \
183
+ wallet accounts list > "$BUNDLE_DIR/accounts.json"
184
+ else
185
+ lncli "${LNCLI_CONN[@]}" \
186
+ wallet accounts list > "$BUNDLE_DIR/accounts.json"
187
+ fi
188
+
189
+ if [ ! -s "$BUNDLE_DIR/accounts.json" ]; then
190
+ echo "Error: Failed to export accounts. Is the signer running and unlocked?" >&2
191
+ exit 1
192
+ fi
193
+ echo " accounts.json exported."
194
+
195
+ # Copy TLS certificate.
196
+ if [ -n "$RPCSERVER" ]; then
197
+ # Remote mode: use the provided --tlscertpath as the bundle cert.
198
+ if [ -z "$TLSCERTPATH" ]; then
199
+ echo "Error: --tlscertpath required for remote export (needed for bundle)." >&2
200
+ exit 1
201
+ fi
202
+ cp "$TLSCERTPATH" "$BUNDLE_DIR/tls.cert"
203
+ elif [ -n "$CONTAINER" ]; then
204
+ TLS_CERT="$LND_SIGNER_DIR/tls.cert"
205
+ docker cp "$CONTAINER:$TLS_CERT" "$BUNDLE_DIR/tls.cert" 2>/dev/null
206
+ if [ ! -f "$BUNDLE_DIR/tls.cert" ]; then
207
+ echo "Error: TLS certificate not found at $TLS_CERT in container '$CONTAINER'" >&2
208
+ exit 1
209
+ fi
210
+ else
211
+ TLS_CERT="$LND_SIGNER_DIR/tls.cert"
212
+ if [ ! -f "$TLS_CERT" ]; then
213
+ echo "Error: TLS certificate not found at $TLS_CERT" >&2
214
+ exit 1
215
+ fi
216
+ cp "$TLS_CERT" "$BUNDLE_DIR/tls.cert"
217
+ fi
218
+ echo " tls.cert copied."
219
+
220
+ # Copy admin macaroon.
221
+ if [ -n "$RPCSERVER" ]; then
222
+ # Remote mode: use the provided --macaroonpath as the bundle macaroon.
223
+ if [ -z "$MACAROONPATH" ]; then
224
+ echo "Error: --macaroonpath required for remote export (needed for bundle)." >&2
225
+ exit 1
226
+ fi
227
+ cp "$MACAROONPATH" "$BUNDLE_DIR/admin.macaroon"
228
+ elif [ -n "$CONTAINER" ]; then
229
+ MACAROON="$LND_SIGNER_DIR/data/chain/bitcoin/$NETWORK/admin.macaroon"
230
+ docker cp "$CONTAINER:$MACAROON" "$BUNDLE_DIR/admin.macaroon" 2>/dev/null
231
+ if [ ! -f "$BUNDLE_DIR/admin.macaroon" ]; then
232
+ echo "Error: Admin macaroon not found at $MACAROON in container '$CONTAINER'" >&2
233
+ exit 1
234
+ fi
235
+ else
236
+ MACAROON="$LND_SIGNER_DIR/data/chain/bitcoin/$NETWORK/admin.macaroon"
237
+ if [ ! -f "$MACAROON" ]; then
238
+ echo "Error: Admin macaroon not found at $MACAROON" >&2
239
+ exit 1
240
+ fi
241
+ cp "$MACAROON" "$BUNDLE_DIR/admin.macaroon"
242
+ fi
243
+ echo " admin.macaroon copied."
244
+ echo ""
245
+
246
+ # Create portable base64-encoded tar.gz bundle.
247
+ BUNDLE_ARCHIVE="$LNGET_SIGNER_DIR/credentials-bundle.tar.gz.b64"
248
+ echo "Creating portable bundle..."
249
+ tar -czf - -C "$BUNDLE_DIR" accounts.json tls.cert admin.macaroon | base64 > "$BUNDLE_ARCHIVE"
250
+ echo " Bundle saved to $BUNDLE_ARCHIVE"
251
+ echo ""
252
+
253
+ echo "=== Credentials Bundle Ready ==="
254
+ echo ""
255
+ echo "Bundle contents:"
256
+ echo " $BUNDLE_DIR/accounts.json — account xpubs for watch-only import"
257
+ echo " $BUNDLE_DIR/tls.cert — signer TLS certificate"
258
+ echo " $BUNDLE_DIR/admin.macaroon — signer admin macaroon"
259
+ echo ""
260
+ echo "Portable bundle (base64):"
261
+ echo " $BUNDLE_ARCHIVE"
262
+ echo ""
263
+ echo "To transfer, either:"
264
+ echo " 1. Copy the credentials-bundle/ directory to the agent machine"
265
+ echo " 2. Copy-paste the base64 string from $BUNDLE_ARCHIVE"
266
+ echo ""
267
+ echo "On the agent machine:"
268
+ echo " skills/lnd/scripts/import-credentials.sh --bundle <path-or-base64>"
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env bash
2
+ # Install lnd for the remote signer machine.
3
+ #
4
+ # Default: pulls the pre-built Docker image (fast, no Go required).
5
+ # Fallback: --source builds lnd from source (requires Go 1.21+).
6
+ #
7
+ # The signer only needs lnd (not litd) since it only performs signing
8
+ # operations via gRPC — no loop, pool, tapd, or UI needed.
9
+ #
10
+ # Usage:
11
+ # install.sh # Docker pull (default)
12
+ # install.sh --version v0.20.0-beta # Specific version
13
+ # install.sh --source # Build from source
14
+
15
+ set -e
16
+
17
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18
+ VERSIONS_FILE="$SCRIPT_DIR/../../../versions.env"
19
+
20
+ # Source pinned versions.
21
+ if [ -f "$VERSIONS_FILE" ]; then
22
+ source "$VERSIONS_FILE"
23
+ fi
24
+
25
+ VERSION=""
26
+ SOURCE=false
27
+ BUILD_TAGS="signrpc walletrpc chainrpc invoicesrpc routerrpc peersrpc kvdb_sqlite neutrinorpc"
28
+
29
+ # Parse arguments.
30
+ while [[ $# -gt 0 ]]; do
31
+ case $1 in
32
+ --version)
33
+ VERSION="$2"
34
+ shift 2
35
+ ;;
36
+ --source)
37
+ SOURCE=true
38
+ shift
39
+ ;;
40
+ --tags)
41
+ BUILD_TAGS="$2"
42
+ shift 2
43
+ ;;
44
+ -h|--help)
45
+ echo "Usage: install.sh [options]"
46
+ echo ""
47
+ echo "Install lnd for the remote signer."
48
+ echo ""
49
+ echo "Default: pulls the pre-built Docker image."
50
+ echo ""
51
+ echo "Options:"
52
+ echo " --version VERSION Image tag or git tag (default: from versions.env)"
53
+ echo " --source Build lnd from source instead of pulling Docker image"
54
+ echo " --tags TAGS Build tags for --source mode"
55
+ exit 0
56
+ ;;
57
+ *)
58
+ echo "Unknown option: $1" >&2
59
+ exit 1
60
+ ;;
61
+ esac
62
+ done
63
+
64
+ if [ "$SOURCE" = true ]; then
65
+ # --- Source build mode: clone and build lnd from source ---
66
+ echo "=== Installing lnd (signer) from source ==="
67
+ echo ""
68
+
69
+ # Verify Go is installed.
70
+ if ! command -v go &>/dev/null; then
71
+ echo "Error: Go is not installed." >&2
72
+ echo "Install Go from https://go.dev/dl/" >&2
73
+ exit 1
74
+ fi
75
+
76
+ GO_VERSION=$(go version | grep -oE 'go[0-9]+\.[0-9]+' | head -1)
77
+ echo "Go version: $GO_VERSION"
78
+ echo "Build tags: $BUILD_TAGS"
79
+ echo ""
80
+
81
+ # Use LND_VERSION from versions.env if no --version given.
82
+ SOURCE_VERSION="${VERSION:-${LND_VERSION:-}}"
83
+
84
+ # Clone lnd into a temp directory and build from source.
85
+ TMPDIR=$(mktemp -d)
86
+ trap "rm -rf $TMPDIR" EXIT
87
+
88
+ echo "Cloning lnd..."
89
+ git clone --quiet https://github.com/lightningnetwork/lnd.git "$TMPDIR/lnd"
90
+
91
+ cd "$TMPDIR/lnd"
92
+
93
+ # Checkout specific version if requested, otherwise use latest tag.
94
+ if [ -n "$SOURCE_VERSION" ]; then
95
+ echo "Checking out $SOURCE_VERSION..."
96
+ git checkout --quiet "$SOURCE_VERSION"
97
+ else
98
+ LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
99
+ if [ -n "$LATEST_TAG" ]; then
100
+ echo "Using latest tag: $LATEST_TAG"
101
+ git checkout --quiet "$LATEST_TAG"
102
+ else
103
+ echo "Using HEAD (no tags found)."
104
+ fi
105
+ fi
106
+ echo ""
107
+
108
+ GOBIN=$(go env GOPATH)/bin
109
+
110
+ # Build lnd.
111
+ echo "Building lnd..."
112
+ go build -tags "$BUILD_TAGS" -o "$GOBIN/lnd" ./cmd/lnd
113
+ echo "Done."
114
+
115
+ # Build lncli.
116
+ echo "Building lncli..."
117
+ go build -tags "$BUILD_TAGS" -o "$GOBIN/lncli" ./cmd/lncli
118
+ echo "Done."
119
+ echo ""
120
+
121
+ # Verify installation.
122
+ if command -v lnd &>/dev/null; then
123
+ echo "lnd installed: $(which lnd)"
124
+ lnd --version 2>/dev/null || true
125
+ else
126
+ echo "Warning: lnd not found on PATH." >&2
127
+ echo "Ensure \$GOPATH/bin is in your PATH." >&2
128
+ echo " export PATH=\$PATH:\$(go env GOPATH)/bin" >&2
129
+ fi
130
+
131
+ if command -v lncli &>/dev/null; then
132
+ echo "lncli installed: $(which lncli)"
133
+ else
134
+ echo "Warning: lncli not found on PATH." >&2
135
+ fi
136
+
137
+ echo ""
138
+ echo "Source installation complete."
139
+ echo ""
140
+ echo "Next steps:"
141
+ echo " 1. Set up signer: skills/lightning-security-module/scripts/setup-signer.sh"
142
+
143
+ else
144
+ # --- Docker mode (default): pull pre-built lnd image ---
145
+ echo "=== Installing lnd (signer) via Docker ==="
146
+ echo ""
147
+
148
+ # Verify Docker is available.
149
+ if ! command -v docker &>/dev/null; then
150
+ echo "Error: Docker is not installed." >&2
151
+ echo "Install Docker from https://docs.docker.com/get-docker/" >&2
152
+ echo "" >&2
153
+ echo "Or use --source to build from source (requires Go 1.21+)." >&2
154
+ exit 1
155
+ fi
156
+
157
+ IMAGE="${LND_IMAGE:-lightninglabs/lnd}"
158
+ TAG="${VERSION:-${LND_VERSION:-v0.20.0-beta}}"
159
+
160
+ echo "Image: $IMAGE:$TAG"
161
+ echo ""
162
+
163
+ # Pull the image.
164
+ echo "Pulling image..."
165
+ docker pull "$IMAGE:$TAG"
166
+ echo ""
167
+
168
+ # Verify the image works.
169
+ echo "Verifying installation..."
170
+ docker run --rm "$IMAGE:$TAG" lnd --version 2>/dev/null || true
171
+ echo ""
172
+
173
+ echo "Installation complete."
174
+ echo ""
175
+ echo "Next steps:"
176
+ echo " 1. Start signer: skills/lightning-security-module/scripts/docker-start.sh"
177
+ echo " 2. Set up signer: skills/lightning-security-module/scripts/setup-signer.sh"
178
+ fi