110 lines
4.2 KiB
Nix
110 lines
4.2 KiB
Nix
# regtest-interactive — turns the shared regtest stack into a friendly,
|
|
# SSH-able dev VM (driven by `nix run .#regtest`).
|
|
#
|
|
# Layered on top of tests/regtest-node.nix + nix-bitcoin (see flake.nix).
|
|
# Unlike the CI test's QEMU console / Python REPL, this gives you a real
|
|
# terminal: copy/paste, scrollback, no log spam, landed straight in the
|
|
# `operator` user with the CLIs preconfigured.
|
|
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
settings ? {
|
|
sshKeys = [ ];
|
|
},
|
|
...
|
|
}:
|
|
let
|
|
# Fund LND on-chain and open an LND -> CLN channel, so you start with a
|
|
# working channel instead of building it by hand every session. Runs as
|
|
# operator (the CLIs are on its PATH); waits for the daemons first.
|
|
regtest-fund = pkgs.writeShellScriptBin "regtest-fund" ''
|
|
set -euo pipefail
|
|
echo "⏳ waiting for the lightning daemons..."
|
|
until lncli getinfo >/dev/null 2>&1 && lightning-cli getinfo >/dev/null 2>&1; do
|
|
sleep 2
|
|
done
|
|
|
|
echo "💰 funding LND on-chain..."
|
|
addr=$(lncli newaddress p2wkh | jq -r .address)
|
|
bitcoin-cli -rpcwallet=test sendtoaddress "$addr" 5 >/dev/null
|
|
mine=$(bitcoin-cli -rpcwallet=test getnewaddress)
|
|
bitcoin-cli -rpcwallet=test generatetoaddress 6 "$mine" >/dev/null
|
|
until [ "$(lncli walletbalance | jq -M '.confirmed_balance | tonumber')" -gt 0 ]; do
|
|
sleep 2
|
|
done
|
|
|
|
echo "🔗 opening LND -> CLN channel..."
|
|
cln=$(lightning-cli getinfo | jq -r .id)
|
|
lncli connect "$cln@127.0.0.1:9735" >/dev/null 2>&1 || true
|
|
lncli openchannel --node_key="$cln" --local_amt=1000000 >/dev/null
|
|
bitcoin-cli -rpcwallet=test generatetoaddress 6 "$mine" >/dev/null
|
|
|
|
echo "⏳ waiting for the channel to activate..."
|
|
until [ "$(lncli listchannels | jq '[.channels[] | select(.active)] | length')" -ge 1 ]; do
|
|
bitcoin-cli -rpcwallet=test generatetoaddress 1 "$mine" >/dev/null
|
|
sleep 2
|
|
done
|
|
|
|
echo "✓ channel active. Try:"
|
|
echo " bolt11=\$(cln invoice 50000000 demo demo | jq -r .bolt11)"
|
|
echo " lncli payinvoice --force \$bolt11"
|
|
'';
|
|
in
|
|
{
|
|
networking.hostName = "regtest";
|
|
|
|
# Throwaway VM — value is irrelevant, set only to silence the eval warning.
|
|
system.stateVersion = "24.11";
|
|
|
|
# SSH is the whole point — a clean terminal you can paste into.
|
|
services.openssh = {
|
|
enable = true;
|
|
settings.PasswordAuthentication = true;
|
|
};
|
|
|
|
# Land as `operator` (the nix-bitcoin user the CLIs are wired for).
|
|
# Simple shared password for a throwaway local VM with fake coins; also
|
|
# accept the adopter's SSH keys if settings.nix has any.
|
|
users.users.operator = {
|
|
password = "password"; # pragma: allowlist secret
|
|
extraGroups = [ "wheel" ];
|
|
openssh.authorizedKeys.keys = settings.sshKeys or [ ];
|
|
};
|
|
# Auto-login operator on the serial console too (if you skip SSH).
|
|
services.getty.autologinUser = "operator";
|
|
|
|
# Convenience aliases. `bitcoin-cli` already auto-selects the single
|
|
# loaded `test` wallet, but `btc` makes it explicit and short. We avoid
|
|
# aliasing `ln` (that's coreutils) — use the real `lncli`.
|
|
environment.shellAliases = {
|
|
btc = "bitcoin-cli -rpcwallet=test";
|
|
cln = "lightning-cli";
|
|
};
|
|
|
|
environment.systemPackages = [ regtest-fund ];
|
|
|
|
users.motd = ''
|
|
|
|
┌─ Omnixient regtest dev VM ───────────────────────────────────┐
|
|
user: operator password: password (sudo enabled)
|
|
aliases: btc → bitcoin-cli -rpcwallet=test
|
|
cln → lightning-cli lncli → LND CLI
|
|
helper: regtest-fund fund LND + open an LND→CLN channel
|
|
nodes: bitcoind(regtest) CLN :9735 LND :9736
|
|
note: the stack pre-mines 110 blocks on boot — give it a few
|
|
seconds, then run `regtest-fund`.
|
|
quit: `exit` (the VM is discarded)
|
|
└───────────────────────────────────────────────────────────┘
|
|
'';
|
|
|
|
# Headless + host:2222 -> guest:22 so `nix run .#regtest` can SSH in.
|
|
virtualisation.graphics = false;
|
|
virtualisation.forwardPorts = [
|
|
{
|
|
from = "host";
|
|
host.port = 2222;
|
|
guest.port = 22;
|
|
}
|
|
];
|
|
}
|