@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.
- package/.claude-plugin/marketplace.json +36 -0
- package/.claude-plugin/plugin.json +12 -0
- package/README.md +307 -0
- package/bin/lightning-mcp-server +15 -0
- package/docs/architecture.md +455 -0
- package/docs/commerce.md +357 -0
- package/docs/l402-and-lnget.md +267 -0
- package/docs/mcp-server.md +285 -0
- package/docs/quickref.md +263 -0
- package/docs/security.md +298 -0
- package/docs/two-agent-setup.md +394 -0
- package/package.json +52 -0
- package/postinstall.js +160 -0
- package/skills/aperture/SKILL.md +330 -0
- package/skills/aperture/scripts/install.sh +68 -0
- package/skills/aperture/scripts/setup.sh +155 -0
- package/skills/aperture/scripts/start.sh +81 -0
- package/skills/aperture/scripts/stop.sh +57 -0
- package/skills/aperture/templates/aperture-regtest.yaml +36 -0
- package/skills/aperture/templates/aperture.yaml.template +64 -0
- package/skills/aperture/templates/docker-compose-aperture.yml +59 -0
- package/skills/commerce/SKILL.md +211 -0
- package/skills/lib/config-gen.sh +127 -0
- package/skills/lib/rest.sh +69 -0
- package/skills/lightning-security-module/SKILL.md +253 -0
- package/skills/lightning-security-module/references/architecture.md +133 -0
- package/skills/lightning-security-module/scripts/docker-start.sh +117 -0
- package/skills/lightning-security-module/scripts/docker-stop.sh +53 -0
- package/skills/lightning-security-module/scripts/export-credentials.sh +268 -0
- package/skills/lightning-security-module/scripts/install.sh +178 -0
- package/skills/lightning-security-module/scripts/setup-signer.sh +307 -0
- package/skills/lightning-security-module/scripts/start-signer.sh +152 -0
- package/skills/lightning-security-module/scripts/stop-signer.sh +240 -0
- package/skills/lightning-security-module/templates/docker-compose-signer.yml +35 -0
- package/skills/lightning-security-module/templates/signer-lnd.conf.template +69 -0
- package/skills/lnd/SKILL.md +441 -0
- package/skills/lnd/profiles/debug.env +4 -0
- package/skills/lnd/profiles/default.env +3 -0
- package/skills/lnd/profiles/regtest.env +4 -0
- package/skills/lnd/profiles/taproot.env +3 -0
- package/skills/lnd/profiles/wumbo.env +3 -0
- package/skills/lnd/references/security.md +156 -0
- package/skills/lnd/scripts/create-wallet.sh +464 -0
- package/skills/lnd/scripts/docker-start.sh +256 -0
- package/skills/lnd/scripts/docker-stop.sh +109 -0
- package/skills/lnd/scripts/import-credentials.sh +145 -0
- package/skills/lnd/scripts/install.sh +195 -0
- package/skills/lnd/scripts/lncli.sh +150 -0
- package/skills/lnd/scripts/start-lnd.sh +241 -0
- package/skills/lnd/scripts/stop-lnd.sh +218 -0
- package/skills/lnd/scripts/unlock-wallet.sh +134 -0
- package/skills/lnd/templates/docker-compose-regtest.yml +122 -0
- package/skills/lnd/templates/docker-compose-watchonly.yml +71 -0
- package/skills/lnd/templates/docker-compose.yml +49 -0
- package/skills/lnd/templates/litd-regtest.conf.template +61 -0
- package/skills/lnd/templates/litd-watchonly.conf.template +57 -0
- package/skills/lnd/templates/litd.conf.template +88 -0
- package/skills/lnd/templates/lnd.conf.template +91 -0
- package/skills/lnget/SKILL.md +288 -0
- package/skills/lnget/scripts/install.sh +69 -0
- package/skills/macaroon-bakery/SKILL.md +179 -0
- package/skills/macaroon-bakery/scripts/bake.sh +337 -0
- package/skills/mcp-lnc/SKILL.md +280 -0
- package/skills/mcp-lnc/scripts/configure.sh +130 -0
- package/skills/mcp-lnc/scripts/install.sh +103 -0
- package/skills/mcp-lnc/scripts/setup-claude-config.sh +162 -0
- package/skills/mcp-lnc/templates/env.template +16 -0
- 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
|