Rebuild the regtest dev fixture: bitcoind + 3 LND nodes + RTL
The setup in docker/ has been unable to start since Feb 2021. The boltz
service added in f817ae39 references BOLTZ_* variables that are not in .env
(so its ports render as ":" and compose rejects the file with "invalid
proto"), a ./boltz build context that has never existed in the repo, and
boltz_data/boltz_shared volumes that are never declared. Because compose
validates the whole project up front, this broke every service: "docker
compose up -d bitcoind", the first command in the README, failed too.
Rather than repair a five-year-old file pinned to bitcoind 0.19.0 and lnd
0.12.0-beta, this replaces it.
What changed:
- bitcoind 30.0 and 3x lnd 0.20.0-beta, using Polar's images. They are
multi-arch, so nothing is built locally and this works on arm64. The old
setup built bitcoind and lnd from local Dockerfiles.
- Three nodes, not one: alice -> bob -> carol. bob forwards, so RTL's
routing and forwarding screens have data. Two nodes leave them empty.
- scripts/seed.sh funds the nodes, opens channels, and makes payments with
fixed amounts. A fresh run reproduces identical state, so screenshots
taken before and after a change differ only by the change. It is
deliberately not idempotent and refuses to run against a seeded network,
since re-running would double-fund it.
- rtl/RTL-Config.regtest.json configures all three nodes. RTL rewrites its
config on startup, so an init container stages a copy into a volume: a
read-only bind mount makes RTL exit with EROFS, and a writable one would
let RTL modify a tracked file. It is not named RTL-Config.json because
.gitignore matches that bare name at any depth.
- bin/ln-cli now takes a node name and passes --lnddir=/home/lnd/.lnd,
because 'docker compose exec' lands as root while lnd's datadir is under
/home/lnd. Both helpers use compose v2.
- README rewritten to match.
Boltz, Core Lightning and Eclair are left out of this pass. Polar publishes
multi-arch clightning and eclair images, so adding them later needs compose
services, config entries and seed adapters, but no image building.
Verified from a clean 'down -v': all nodes sync, channels go active, 5/5
payments route through bob, bob records 5 forwards, and RTL serves the UI
with all three nodes configured. Two independent from-scratch runs produced
identical balances.
The old bitcoind/ and lnd/ build contexts are now unreferenced but left in
place for a follow-up.
2026-07-15 23:09:03 -07:00
|
|
|
{
|
2026-07-15 23:59:53 -07:00
|
|
|
"multiPass": "rtldev",
|
Rebuild the regtest dev fixture: bitcoind + 3 LND nodes + RTL
The setup in docker/ has been unable to start since Feb 2021. The boltz
service added in f817ae39 references BOLTZ_* variables that are not in .env
(so its ports render as ":" and compose rejects the file with "invalid
proto"), a ./boltz build context that has never existed in the repo, and
boltz_data/boltz_shared volumes that are never declared. Because compose
validates the whole project up front, this broke every service: "docker
compose up -d bitcoind", the first command in the README, failed too.
Rather than repair a five-year-old file pinned to bitcoind 0.19.0 and lnd
0.12.0-beta, this replaces it.
What changed:
- bitcoind 30.0 and 3x lnd 0.20.0-beta, using Polar's images. They are
multi-arch, so nothing is built locally and this works on arm64. The old
setup built bitcoind and lnd from local Dockerfiles.
- Three nodes, not one: alice -> bob -> carol. bob forwards, so RTL's
routing and forwarding screens have data. Two nodes leave them empty.
- scripts/seed.sh funds the nodes, opens channels, and makes payments with
fixed amounts. A fresh run reproduces identical state, so screenshots
taken before and after a change differ only by the change. It is
deliberately not idempotent and refuses to run against a seeded network,
since re-running would double-fund it.
- rtl/RTL-Config.regtest.json configures all three nodes. RTL rewrites its
config on startup, so an init container stages a copy into a volume: a
read-only bind mount makes RTL exit with EROFS, and a writable one would
let RTL modify a tracked file. It is not named RTL-Config.json because
.gitignore matches that bare name at any depth.
- bin/ln-cli now takes a node name and passes --lnddir=/home/lnd/.lnd,
because 'docker compose exec' lands as root while lnd's datadir is under
/home/lnd. Both helpers use compose v2.
- README rewritten to match.
Boltz, Core Lightning and Eclair are left out of this pass. Polar publishes
multi-arch clightning and eclair images, so adding them later needs compose
services, config entries and seed adapters, but no image building.
Verified from a clean 'down -v': all nodes sync, channels go active, 5/5
payments route through bob, bob records 5 forwards, and RTL serves the UI
with all three nodes configured. Two independent from-scratch runs produced
identical balances.
The old bitcoind/ and lnd/ build contexts are now unreferenced but left in
place for a follow-up.
2026-07-15 23:09:03 -07:00
|
|
|
"port": "3000",
|
|
|
|
|
"defaultNodeIndex": 1,
|
|
|
|
|
"dbDirectoryPath": "/RTL/database",
|
|
|
|
|
"SSO": {
|
|
|
|
|
"rtlSSO": 0,
|
|
|
|
|
"rtlCookiePath": "",
|
|
|
|
|
"logoutRedirectLink": ""
|
|
|
|
|
},
|
|
|
|
|
"nodes": [
|
|
|
|
|
{
|
|
|
|
|
"index": 1,
|
|
|
|
|
"lnNode": "alice",
|
|
|
|
|
"lnImplementation": "LND",
|
|
|
|
|
"authentication": {
|
|
|
|
|
"macaroonPath": "/lnd/alice/data/chain/bitcoin/regtest"
|
|
|
|
|
},
|
|
|
|
|
"settings": {
|
|
|
|
|
"userPersona": "OPERATOR",
|
|
|
|
|
"themeMode": "DAY",
|
|
|
|
|
"themeColor": "PURPLE",
|
|
|
|
|
"logLevel": "ERROR",
|
|
|
|
|
"lnServerUrl": "https://alice:8080",
|
|
|
|
|
"fiatConversion": false,
|
|
|
|
|
"unannouncedChannels": false,
|
|
|
|
|
"blockExplorerUrl": "https://mempool.space"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": 2,
|
|
|
|
|
"lnNode": "bob",
|
|
|
|
|
"lnImplementation": "LND",
|
|
|
|
|
"authentication": {
|
|
|
|
|
"macaroonPath": "/lnd/bob/data/chain/bitcoin/regtest"
|
|
|
|
|
},
|
|
|
|
|
"settings": {
|
|
|
|
|
"userPersona": "OPERATOR",
|
|
|
|
|
"themeMode": "DAY",
|
|
|
|
|
"themeColor": "PURPLE",
|
|
|
|
|
"logLevel": "ERROR",
|
|
|
|
|
"lnServerUrl": "https://bob:8080",
|
|
|
|
|
"fiatConversion": false,
|
|
|
|
|
"unannouncedChannels": false,
|
|
|
|
|
"blockExplorerUrl": "https://mempool.space"
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": 3,
|
|
|
|
|
"lnNode": "carol",
|
|
|
|
|
"lnImplementation": "LND",
|
|
|
|
|
"authentication": {
|
|
|
|
|
"macaroonPath": "/lnd/carol/data/chain/bitcoin/regtest"
|
|
|
|
|
},
|
|
|
|
|
"settings": {
|
|
|
|
|
"userPersona": "MERCHANT",
|
|
|
|
|
"themeMode": "DAY",
|
|
|
|
|
"themeColor": "PURPLE",
|
|
|
|
|
"logLevel": "ERROR",
|
|
|
|
|
"lnServerUrl": "https://carol:8080",
|
|
|
|
|
"fiatConversion": false,
|
|
|
|
|
"unannouncedChannels": false,
|
|
|
|
|
"blockExplorerUrl": "https://mempool.space"
|
|
|
|
|
}
|
Add a Core Lightning node to the regtest docker fixture
The fixture had only bitcoind + three LND nodes, so RTL's Core Lightning screens
had no backend to exercise. Add a `cln` node (official elementsproject/lightningd
image, multi-arch) wired to RTL over clnrest with rune auth, and have the seed
open a cln->alice channel so the CLN channel/peer screens have real data.
- docker-compose.yml: cln service (clnrest on 0.0.0.0:3010, https), a healthcheck
gated on the rune file so rtl waits for it, and rtl now mounts the cln volume
read-only and depends on cln being healthy. The rtl image is parameterized via
${RTL_IMAGE:-...} so an unreleased build can be tested against the fixture.
- cln/poststart.d/create-rune.sh: once the RPC is up, create a master rune and
write it as LIGHTNING_RUNE="..." where RTL reads it (runePath). Polls for RPC
readiness because the image entrypoint can invoke poststart before the socket
exists.
- RTL-Config.regtest.json: add node index 4 (CLN, rune auth, https://cln:3010).
- seed.sh: fund cln, connect to alice, open a 4,000,000 sat channel, wait active.
- README + release notes updated.
Used to verify the CLN channel connection-status fix (#1606) end-to-end.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 10:03:34 -07:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": 4,
|
|
|
|
|
"lnNode": "cln",
|
|
|
|
|
"lnImplementation": "CLN",
|
|
|
|
|
"authentication": {
|
|
|
|
|
"runePath": "/cln/rtl.rune"
|
|
|
|
|
},
|
|
|
|
|
"settings": {
|
|
|
|
|
"userPersona": "OPERATOR",
|
|
|
|
|
"themeMode": "DAY",
|
|
|
|
|
"themeColor": "PURPLE",
|
|
|
|
|
"logLevel": "ERROR",
|
|
|
|
|
"lnServerUrl": "https://cln:3010",
|
|
|
|
|
"fiatConversion": false,
|
|
|
|
|
"unannouncedChannels": false,
|
|
|
|
|
"blockExplorerUrl": "https://mempool.space"
|
|
|
|
|
}
|
Add an Eclair node to the regtest docker fixture
Completes backend coverage of RTL's three implementations in the docker/
dev fixture: an eclair node (polarlightning/eclair 0.13.1) joins the three
LND nodes and the CLN node, wired to RTL over its HTTP API with basic auth,
and the seed opens an eclair->bob channel (3.5M sats, 1M pushed), sends two
direct payments and leaves one open invoice.
Non-obvious plumbing this needed:
- polarlightning/eclair instead of acinq/eclair: the official image is
amd64-only (useless on Apple Silicon) and its newest versioned tag is
years stale; Polar builds the same ACINQ source multi-arch.
- Eclair has no on-chain wallet of its own -- it drives a bitcoind wallet.
A new eclair-wallet-init container creates a dedicated "eclair" wallet
before the node starts; without it eclair attaches to "the default
loaded wallet", i.e. the rtldev mining wallet.
- bitcoind now also publishes a zmqpubhashblock endpoint (28336): eclair's
bitcoind.zmqblock consumes the hashblock topic, not the rawblock one LND
uses. Wired to rawblock, eclair never sees new blocks and channels hang
in WAIT_FOR_FUNDING_CONFIRMED.
- Eclair confirms channels at 8 blocks (channel.min-depth-blocks), not 6,
and 'open' returns before the funding tx is broadcast -- the seed waits
for the mempool and mines 8 blocks for this channel.
Adds a bin/e-cli helper (eclair-cli with the API password), updates the
README, and verified end-to-end: seed completes, the channel reaches
NORMAL, both payments settle, and RTL's /rtl/api/ecl endpoints return the
node, channel and invoice data.
2026-07-18 00:23:08 -07:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"index": 5,
|
|
|
|
|
"lnNode": "eclair",
|
|
|
|
|
"lnImplementation": "ECL",
|
|
|
|
|
"authentication": {
|
|
|
|
|
"lnApiPassword": "rtldev"
|
|
|
|
|
},
|
|
|
|
|
"settings": {
|
|
|
|
|
"userPersona": "OPERATOR",
|
|
|
|
|
"themeMode": "DAY",
|
|
|
|
|
"themeColor": "PURPLE",
|
|
|
|
|
"logLevel": "ERROR",
|
|
|
|
|
"lnServerUrl": "http://eclair:8080",
|
|
|
|
|
"fiatConversion": false,
|
|
|
|
|
"unannouncedChannels": false,
|
|
|
|
|
"blockExplorerUrl": "https://mempool.space"
|
|
|
|
|
}
|
Rebuild the regtest dev fixture: bitcoind + 3 LND nodes + RTL
The setup in docker/ has been unable to start since Feb 2021. The boltz
service added in f817ae39 references BOLTZ_* variables that are not in .env
(so its ports render as ":" and compose rejects the file with "invalid
proto"), a ./boltz build context that has never existed in the repo, and
boltz_data/boltz_shared volumes that are never declared. Because compose
validates the whole project up front, this broke every service: "docker
compose up -d bitcoind", the first command in the README, failed too.
Rather than repair a five-year-old file pinned to bitcoind 0.19.0 and lnd
0.12.0-beta, this replaces it.
What changed:
- bitcoind 30.0 and 3x lnd 0.20.0-beta, using Polar's images. They are
multi-arch, so nothing is built locally and this works on arm64. The old
setup built bitcoind and lnd from local Dockerfiles.
- Three nodes, not one: alice -> bob -> carol. bob forwards, so RTL's
routing and forwarding screens have data. Two nodes leave them empty.
- scripts/seed.sh funds the nodes, opens channels, and makes payments with
fixed amounts. A fresh run reproduces identical state, so screenshots
taken before and after a change differ only by the change. It is
deliberately not idempotent and refuses to run against a seeded network,
since re-running would double-fund it.
- rtl/RTL-Config.regtest.json configures all three nodes. RTL rewrites its
config on startup, so an init container stages a copy into a volume: a
read-only bind mount makes RTL exit with EROFS, and a writable one would
let RTL modify a tracked file. It is not named RTL-Config.json because
.gitignore matches that bare name at any depth.
- bin/ln-cli now takes a node name and passes --lnddir=/home/lnd/.lnd,
because 'docker compose exec' lands as root while lnd's datadir is under
/home/lnd. Both helpers use compose v2.
- README rewritten to match.
Boltz, Core Lightning and Eclair are left out of this pass. Polar publishes
multi-arch clightning and eclair images, so adding them later needs compose
services, config entries and seed adapters, but no image building.
Verified from a clean 'down -v': all nodes sync, channels go active, 5/5
payments route through bob, bob records 5 forwards, and RTL serves the UI
with all three nodes configured. Two independent from-scratch runs produced
identical balances.
The old bitcoind/ and lnd/ build contexts are now unreferenced but left in
place for a follow-up.
2026-07-15 23:09:03 -07:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|