- Add qrencode to devenv.nix packages - Display QR code in terminal for easy Zeus wallet scanning - Falls back to text if qrencode not available Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
572 lines
20 KiB
Nix
572 lines
20 KiB
Nix
{ pkgs, lib, config, ... }:
|
|
|
|
{
|
|
# Project metadata
|
|
name = "lamassu-next";
|
|
|
|
# ============================================
|
|
# Languages
|
|
# ============================================
|
|
|
|
languages.javascript = {
|
|
enable = true;
|
|
package = pkgs.nodejs_22;
|
|
pnpm = {
|
|
enable = true;
|
|
install.enable = true;
|
|
};
|
|
};
|
|
|
|
languages.typescript.enable = true;
|
|
|
|
# Use nixpkgs rust (simpler, no overlay needed)
|
|
packages = with pkgs; [
|
|
# Rust toolchain from nixpkgs
|
|
rustc
|
|
cargo
|
|
clippy
|
|
rustfmt
|
|
rust-analyzer
|
|
|
|
# Build tools
|
|
pkg-config
|
|
openssl
|
|
openssl.dev
|
|
|
|
# Electron dependencies (Linux)
|
|
# electron # Use npm-installed electron instead
|
|
|
|
# Python for node-gyp (native module builds)
|
|
(python3.withPackages (ps: [ ps.setuptools ]))
|
|
|
|
# Hardware access
|
|
libusb1
|
|
udev
|
|
|
|
# Serial port access
|
|
picocom
|
|
|
|
# Development utilities
|
|
just # Task runner
|
|
jq # JSON processing
|
|
websocat # WebSocket client
|
|
qrencode # QR code generation for terminal
|
|
|
|
# Database tools
|
|
pgcli
|
|
|
|
# Container tools (for Lightning.Pub, strfry)
|
|
docker-compose
|
|
];
|
|
|
|
# ============================================
|
|
# Services
|
|
# ============================================
|
|
|
|
services.postgres = {
|
|
enable = true;
|
|
initialDatabases = [{ name = "lamassu_dev"; }];
|
|
listen_addresses = "127.0.0.1";
|
|
};
|
|
|
|
# ============================================
|
|
# Git Hooks (formerly pre-commit)
|
|
# ============================================
|
|
|
|
git-hooks.hooks = {
|
|
# TypeScript/JavaScript
|
|
prettier = {
|
|
enable = true;
|
|
excludes = [ "pnpm-lock.yaml" ];
|
|
};
|
|
|
|
# Rust
|
|
rustfmt.enable = true;
|
|
|
|
# Nix formatting
|
|
nixpkgs-fmt.enable = true;
|
|
|
|
# TOML/YAML validation
|
|
check-toml.enable = true;
|
|
check-yaml.enable = true;
|
|
};
|
|
|
|
# ============================================
|
|
# Environment Variables
|
|
# ============================================
|
|
|
|
env = {
|
|
RUST_BACKTRACE = "1";
|
|
DATABASE_URL = "postgresql://localhost/lamassu_dev";
|
|
|
|
# Nostr development relay
|
|
NOSTR_RELAY_URL = "ws://localhost:7777";
|
|
|
|
# Lightning.Pub development
|
|
LIGHTNING_PUB_URL = "http://localhost:1776";
|
|
|
|
# For Tauri
|
|
PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig";
|
|
};
|
|
|
|
# ============================================
|
|
# Scripts (available as commands in shell)
|
|
# ============================================
|
|
|
|
scripts = {
|
|
dev.exec = "pnpm turbo dev";
|
|
build.exec = "pnpm turbo build";
|
|
test.exec = "pnpm turbo test";
|
|
lint.exec = "pnpm turbo lint";
|
|
|
|
# Start infrastructure
|
|
infra-up.exec = ''
|
|
echo "Starting development infrastructure..."
|
|
docker compose -f docker/docker-compose.dev.yml up -d
|
|
echo ""
|
|
echo "Waiting for services to be healthy..."
|
|
echo "(This may take 30-60 seconds on first run)"
|
|
echo ""
|
|
|
|
# Wait for strfry
|
|
echo -n "strfry relay: "
|
|
until docker exec lamassu-relay nc -z localhost 7777 2>/dev/null; do
|
|
echo -n "."
|
|
sleep 2
|
|
done
|
|
echo " ready"
|
|
|
|
# Wait for bitcoind
|
|
echo -n "bitcoind: "
|
|
until docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu getblockchaininfo >/dev/null 2>&1; do
|
|
echo -n "."
|
|
sleep 2
|
|
done
|
|
echo " ready"
|
|
|
|
# Wait for LND
|
|
echo -n "LND: "
|
|
until docker exec lamassu-lnd lncli --network=regtest getinfo >/dev/null 2>&1; do
|
|
echo -n "."
|
|
sleep 3
|
|
done
|
|
echo " ready"
|
|
|
|
# Wait for Alice's LND
|
|
echo -n "LND (Alice): "
|
|
until docker exec lamassu-lnd-alice lncli --network=regtest getinfo >/dev/null 2>&1; do
|
|
echo -n "."
|
|
sleep 3
|
|
done
|
|
echo " ready"
|
|
|
|
echo ""
|
|
echo "Infrastructure ready!"
|
|
echo " - Nostr relay: ws://localhost:7777"
|
|
echo " - Bitcoin RPC: localhost:18443 (regtest)"
|
|
echo " - LND gRPC: localhost:10009"
|
|
echo " - LND Alice gRPC: localhost:10010"
|
|
echo " - Lightning.Pub: http://localhost:1776"
|
|
echo " - PostgreSQL: localhost:5432"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. mine-blocks 101 # Fund the wallet (if first run)"
|
|
echo " 2. setup-channel # Open channel between Alice and LND"
|
|
echo ""
|
|
echo "Use 'infra-logs' to view logs, 'infra-status' to check status"
|
|
'';
|
|
|
|
infra-down.exec = ''
|
|
echo "Stopping development infrastructure..."
|
|
docker compose -f docker/docker-compose.dev.yml down
|
|
echo "Infrastructure stopped"
|
|
'';
|
|
|
|
infra-logs.exec = ''
|
|
docker compose -f docker/docker-compose.dev.yml logs -f "$@"
|
|
'';
|
|
|
|
infra-status.exec = ''
|
|
echo "Infrastructure Status:"
|
|
echo ""
|
|
docker compose -f docker/docker-compose.dev.yml ps
|
|
'';
|
|
|
|
# Mine regtest blocks (useful for testing)
|
|
mine-blocks.exec = ''
|
|
BLOCKS=''${1:-1}
|
|
echo "Mining $BLOCKS regtest block(s)..."
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu -generate "$BLOCKS"
|
|
'';
|
|
|
|
# Start auto-miner (mines 1 block every 30 seconds)
|
|
auto-mine.exec = ''
|
|
echo "Starting auto-miner (1 block every 30 seconds)..."
|
|
docker compose -f docker/docker-compose.dev.yml --profile mining up -d miner
|
|
echo ""
|
|
echo "Auto-miner started. This keeps LND in sync."
|
|
echo "Use 'auto-mine-stop' to stop it."
|
|
'';
|
|
|
|
# Stop auto-miner
|
|
auto-mine-stop.exec = ''
|
|
echo "Stopping auto-miner..."
|
|
docker stop lamassu-miner 2>/dev/null || true
|
|
docker rm lamassu-miner 2>/dev/null || true
|
|
echo "Auto-miner stopped."
|
|
'';
|
|
|
|
# Connect to LND CLI
|
|
lncli.exec = ''
|
|
docker exec -it lamassu-lnd lncli --network=regtest "$@"
|
|
'';
|
|
|
|
# Connect to Bitcoin CLI
|
|
btccli.exec = ''
|
|
docker exec -it lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu "$@"
|
|
'';
|
|
|
|
# Test relay connection
|
|
relay-test.exec = ''
|
|
echo "Testing Nostr relay connection..."
|
|
echo '["REQ", "test", {"kinds": [0], "limit": 1}]' | websocat ws://localhost:7777
|
|
'';
|
|
|
|
# Connect to Alice's LND CLI (second node for testing payments)
|
|
lncli-alice.exec = ''
|
|
docker exec -it lamassu-lnd-alice lncli --network=regtest "$@"
|
|
'';
|
|
|
|
# Setup Lightning channel between Alice and the main LND node
|
|
setup-channel.exec = ''
|
|
echo "Setting up Lightning channel between Alice and LND..."
|
|
echo ""
|
|
|
|
# Get LND's pubkey and address
|
|
LND_INFO=$(docker exec lamassu-lnd lncli --network=regtest getinfo 2>/dev/null)
|
|
LND_PUBKEY=$(echo "$LND_INFO" | jq -r '.identity_pubkey')
|
|
echo "LND pubkey: $LND_PUBKEY"
|
|
|
|
# Connect Alice to LND
|
|
echo "Connecting Alice to LND..."
|
|
docker exec lamassu-lnd-alice lncli --network=regtest connect "$LND_PUBKEY@lnd:9735" 2>/dev/null || true
|
|
|
|
# Check if Alice has enough funds
|
|
ALICE_BALANCE=$(docker exec lamassu-lnd-alice lncli --network=regtest walletbalance 2>/dev/null | jq -r '.confirmed_balance')
|
|
echo "Alice's on-chain balance: $ALICE_BALANCE sats"
|
|
|
|
if [ "$ALICE_BALANCE" -lt 1000000 ]; then
|
|
echo ""
|
|
echo "Alice needs funds. Getting new address..."
|
|
ALICE_ADDR=$(docker exec lamassu-lnd-alice lncli --network=regtest newaddress p2wkh | jq -r '.address')
|
|
echo "Alice's address: $ALICE_ADDR"
|
|
echo ""
|
|
echo "Sending 5 BTC to Alice..."
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu sendtoaddress "$ALICE_ADDR" 5
|
|
echo "Mining 6 blocks for confirmation..."
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu -generate 6 >/dev/null
|
|
sleep 2
|
|
ALICE_BALANCE=$(docker exec lamassu-lnd-alice lncli --network=regtest walletbalance 2>/dev/null | jq -r '.confirmed_balance')
|
|
echo "Alice's new balance: $ALICE_BALANCE sats"
|
|
fi
|
|
|
|
# Open channel from Alice to LND (1M sats)
|
|
echo ""
|
|
echo "Opening 1M sat channel from Alice to LND..."
|
|
docker exec lamassu-lnd-alice lncli --network=regtest openchannel --node_key="$LND_PUBKEY" --local_amt=1000000
|
|
|
|
echo ""
|
|
echo "Mining 6 blocks to confirm channel..."
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu -generate 6 >/dev/null
|
|
|
|
sleep 3
|
|
echo ""
|
|
echo "Channel status:"
|
|
docker exec lamassu-lnd-alice lncli --network=regtest listchannels | jq '.channels[] | {remote_pubkey, capacity, local_balance, remote_balance, active}'
|
|
echo ""
|
|
echo "Channel setup complete! Alice can now pay invoices to Lightning.Pub."
|
|
'';
|
|
|
|
# Pay an invoice from Alice's node
|
|
alice-pay.exec = ''
|
|
if [ -z "$1" ]; then
|
|
echo "Usage: alice-pay <invoice>"
|
|
exit 1
|
|
fi
|
|
echo "Paying invoice from Alice's node..."
|
|
docker exec lamassu-lnd-alice lncli --network=regtest payinvoice --force "$1"
|
|
'';
|
|
|
|
# Create invoice on Alice's node (for testing ATM payouts)
|
|
alice-invoice.exec = ''
|
|
AMOUNT=''${1:-1000}
|
|
MEMO=''${2:-"Test invoice"}
|
|
docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt="$AMOUNT" --memo="$MEMO" | jq -r '.payment_request'
|
|
'';
|
|
|
|
# Fund ATM account in Lightning.Pub
|
|
fund-atm.exec = ''
|
|
AMOUNT=''${1:-100000}
|
|
echo "Funding ATM account with $AMOUNT sats..."
|
|
echo ""
|
|
|
|
# Run the funding script from nostr-client package
|
|
cd packages/nostr-client
|
|
FUND_AMOUNT=$AMOUNT node fund-dev.mjs 2>&1 | tee /tmp/fund-atm-output.txt
|
|
|
|
# Extract the invoice
|
|
INVOICE=$(grep -o 'lnbcrt[a-zA-Z0-9]*' /tmp/fund-atm-output.txt | head -1)
|
|
|
|
if [ -z "$INVOICE" ]; then
|
|
echo "Failed to create invoice. Check the output above."
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "Invoice created. Paying from Alice..."
|
|
docker exec lamassu-lnd-alice lncli --network=regtest payinvoice --force "$INVOICE"
|
|
|
|
echo ""
|
|
echo "ATM account funded with $AMOUNT sats!"
|
|
'';
|
|
|
|
# Validate entire test setup
|
|
test-setup.exec = ''
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo " Lamassu Next - Test Setup Validation"
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
# Mine a block to wake up LND sync (regtest quirk: LND reports
|
|
# "not synced" when no blocks mined recently)
|
|
echo "Mining block to sync nodes..."
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu -generate 1 >/dev/null 2>&1
|
|
sleep 1
|
|
echo ""
|
|
|
|
PASSED=0
|
|
FAILED=0
|
|
|
|
check() {
|
|
if [ $1 -eq 0 ]; then
|
|
echo " ✓ $2"
|
|
PASSED=$((PASSED + 1))
|
|
else
|
|
echo " ✗ $2"
|
|
FAILED=$((FAILED + 1))
|
|
fi
|
|
}
|
|
|
|
echo "1. Services"
|
|
echo "───────────────────────────────────────────────────────────"
|
|
|
|
# Check containers
|
|
docker ps --format '{{.Names}}' | grep -q lamassu-relay
|
|
check $? "strfry relay running"
|
|
|
|
docker ps --format '{{.Names}}' | grep -q lamassu-bitcoind
|
|
check $? "bitcoind running"
|
|
|
|
docker ps --format '{{.Names}}' | grep -q lamassu-lnd
|
|
check $? "LND running"
|
|
|
|
docker ps --format '{{.Names}}' | grep -q lamassu-lnd-alice
|
|
check $? "LND Alice running"
|
|
|
|
docker ps --format '{{.Names}}' | grep -q lamassu-lightning-pub
|
|
check $? "Lightning.Pub running"
|
|
|
|
echo ""
|
|
echo "2. Connectivity"
|
|
echo "───────────────────────────────────────────────────────────"
|
|
|
|
# Check relay port is open
|
|
timeout 2 bash -c 'echo > /dev/tcp/localhost/7777' 2>/dev/null
|
|
check $? "Nostr relay port open"
|
|
|
|
# Check bitcoind RPC
|
|
docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu getblockchaininfo >/dev/null 2>&1
|
|
check $? "Bitcoin RPC responding"
|
|
|
|
# Check LND
|
|
docker exec lamassu-lnd lncli --network=regtest getinfo >/dev/null 2>&1
|
|
check $? "LND RPC responding"
|
|
|
|
# Check Alice
|
|
docker exec lamassu-lnd-alice lncli --network=regtest getinfo >/dev/null 2>&1
|
|
check $? "LND Alice RPC responding"
|
|
|
|
echo ""
|
|
echo "3. Blockchain State"
|
|
echo "───────────────────────────────────────────────────────────"
|
|
|
|
BLOCKS=$(docker exec lamassu-bitcoind bitcoin-cli -regtest -rpcuser=lamassu -rpcpassword=lamassu getblockcount 2>/dev/null)
|
|
[ "$BLOCKS" -ge 100 ]
|
|
check $? "Block height >= 100 (current: $BLOCKS)"
|
|
|
|
# Check LND synced
|
|
LND_SYNCED=$(docker exec lamassu-lnd lncli --network=regtest getinfo 2>/dev/null | jq -r '.synced_to_chain')
|
|
[ "$LND_SYNCED" = "true" ]
|
|
check $? "LND synced to chain"
|
|
|
|
# Check Alice synced
|
|
ALICE_SYNCED=$(docker exec lamassu-lnd-alice lncli --network=regtest getinfo 2>/dev/null | jq -r '.synced_to_chain')
|
|
[ "$ALICE_SYNCED" = "true" ]
|
|
check $? "LND Alice synced to chain"
|
|
|
|
echo ""
|
|
echo "4. Lightning Channels"
|
|
echo "───────────────────────────────────────────────────────────"
|
|
|
|
# Check Alice has active channels
|
|
ALICE_CHANNELS=$(docker exec lamassu-lnd-alice lncli --network=regtest listchannels 2>/dev/null | jq '.channels | length')
|
|
[ "$ALICE_CHANNELS" -ge 1 ]
|
|
check $? "Alice has active channels (count: $ALICE_CHANNELS)"
|
|
|
|
# Check channel is active
|
|
ACTIVE_CHANNEL=$(docker exec lamassu-lnd-alice lncli --network=regtest listchannels 2>/dev/null | jq '.channels[0].active')
|
|
[ "$ACTIVE_CHANNEL" = "true" ]
|
|
check $? "Channel is active"
|
|
|
|
# Check Alice has outbound capacity
|
|
ALICE_LOCAL=$(docker exec lamassu-lnd-alice lncli --network=regtest listchannels 2>/dev/null | jq -r '.channels[0].local_balance // 0')
|
|
[ "$ALICE_LOCAL" -ge 10000 ]
|
|
check $? "Alice has outbound capacity ($ALICE_LOCAL sats)"
|
|
|
|
echo ""
|
|
echo "5. Payment Test"
|
|
echo "───────────────────────────────────────────────────────────"
|
|
|
|
# Create test invoice on LND and pay from Alice
|
|
TEST_INVOICE=$(docker exec lamassu-lnd lncli --network=regtest addinvoice --amt=100 --memo="test-setup validation" 2>/dev/null | jq -r '.payment_request')
|
|
if [ -n "$TEST_INVOICE" ]; then
|
|
check 0 "Created 100 sat test invoice"
|
|
|
|
# Pay it
|
|
PAY_RESULT=$(docker exec lamassu-lnd-alice lncli --network=regtest payinvoice --force "$TEST_INVOICE" 2>&1)
|
|
if echo "$PAY_RESULT" | grep -q "SUCCEEDED"; then
|
|
check 0 "Payment Alice → LND succeeded"
|
|
else
|
|
check 1 "Payment Alice → LND failed"
|
|
fi
|
|
else
|
|
check 1 "Failed to create test invoice"
|
|
check 1 "Payment test skipped"
|
|
fi
|
|
|
|
echo ""
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo " Results: $PASSED passed, $FAILED failed"
|
|
echo "═══════════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
if [ $FAILED -gt 0 ]; then
|
|
echo "Some checks failed. Run 'infra-up' and 'setup-channel' first."
|
|
exit 1
|
|
else
|
|
echo "All checks passed! Ready for testing."
|
|
exit 0
|
|
fi
|
|
'';
|
|
|
|
# Quick e2e payment test (ATM pays customer invoice)
|
|
test-payment.exec = ''
|
|
AMOUNT=''${1:-1000}
|
|
echo "Testing e2e payment flow ($AMOUNT sats)..."
|
|
echo ""
|
|
|
|
# Create invoice on Alice (simulating customer's wallet)
|
|
echo "1. Creating invoice on Alice's wallet..."
|
|
INVOICE=$(docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt="$AMOUNT" --memo="E2E test" | jq -r '.payment_request')
|
|
echo " Invoice: ''${INVOICE:0:40}..."
|
|
|
|
# Use test-pay.mjs to pay via Lightning.Pub
|
|
echo ""
|
|
echo "2. Paying via Lightning.Pub (ATM flow)..."
|
|
cd packages/nostr-client
|
|
node test-pay.mjs "$INVOICE"
|
|
|
|
echo ""
|
|
echo "3. Verifying payment on Alice..."
|
|
sleep 2
|
|
PAID=$(docker exec lamassu-lnd-alice lncli --network=regtest listinvoices 2>/dev/null | jq '.invoices[-1].settled')
|
|
if [ "$PAID" = "true" ]; then
|
|
echo " ✓ Payment received!"
|
|
else
|
|
echo " ✗ Payment not received"
|
|
exit 1
|
|
fi
|
|
'';
|
|
|
|
# Show node info
|
|
node-info.exec = ''
|
|
echo ""
|
|
echo "Node Information"
|
|
echo "════════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
echo "LND (Lightning.Pub's node):"
|
|
docker exec lamassu-lnd lncli --network=regtest getinfo 2>/dev/null | jq '{pubkey: .identity_pubkey, alias: .alias, channels: .num_active_channels, peers: .num_peers}'
|
|
|
|
echo ""
|
|
echo "LND Alice (Payment source):"
|
|
docker exec lamassu-lnd-alice lncli --network=regtest getinfo 2>/dev/null | jq '{pubkey: .identity_pubkey, alias: .alias, channels: .num_active_channels, peers: .num_peers}'
|
|
|
|
echo ""
|
|
echo "Channel Details:"
|
|
docker exec lamassu-lnd-alice lncli --network=regtest listchannels 2>/dev/null | jq '.channels[] | {peer: .remote_pubkey[0:16], capacity, local: .local_balance, remote: .remote_balance, active}'
|
|
|
|
echo ""
|
|
echo "Lightning.Pub Nostr pubkey:"
|
|
echo " f454c5eec4ec4474128e19b57b45e49c3d0851d01eea960b39ce391cdba76fc6"
|
|
|
|
echo ""
|
|
echo "ATM Dev Identity:"
|
|
echo " 4646ae5047316b4230d0086c8acec687f00b1cd9d1dc634f6cb358ac0a9a8fff"
|
|
'';
|
|
};
|
|
|
|
# ============================================
|
|
# Shell Hook
|
|
# ============================================
|
|
|
|
enterShell = ''
|
|
echo ""
|
|
echo " ⚡ Lamassu Next - Nostr-Native Lightning ATM"
|
|
echo " ─────────────────────────────────────────────"
|
|
echo " Node.js: $(node --version)"
|
|
echo " Rust: $(rustc --version | cut -d' ' -f2)"
|
|
echo " pnpm: $(pnpm --version)"
|
|
echo ""
|
|
echo " Development:"
|
|
echo " dev Start development servers"
|
|
echo " build Build all packages"
|
|
echo " test Run tests"
|
|
echo ""
|
|
echo " Infrastructure:"
|
|
echo " infra-up Start Docker services (strfry, bitcoind, LND, Lightning.Pub)"
|
|
echo " infra-down Stop Docker services"
|
|
echo " infra-status Show service status"
|
|
echo " infra-logs Follow service logs"
|
|
echo ""
|
|
echo " Bitcoin/Lightning:"
|
|
echo " btccli Bitcoin CLI (regtest)"
|
|
echo " lncli LND CLI (Lightning.Pub's node)"
|
|
echo " lncli-alice LND CLI (Alice's node for testing payments)"
|
|
echo " mine-blocks Mine regtest blocks (default: 1)"
|
|
echo " auto-mine Start auto-miner (1 block/30s, keeps LND synced)"
|
|
echo " auto-mine-stop Stop auto-miner"
|
|
echo " setup-channel Setup channel between Alice and LND"
|
|
echo " alice-pay Pay invoice from Alice's node"
|
|
echo " relay-test Test Nostr relay connection"
|
|
echo ""
|
|
echo " Testing (E2E):"
|
|
echo " test-setup Validate test environment (services, channels, payments)"
|
|
echo " test-payment Quick e2e payment test (ATM → customer)"
|
|
echo " fund-atm Fund ATM account (default: 100k sats)"
|
|
echo " alice-invoice Create invoice on Alice's node"
|
|
echo " node-info Show node pubkeys and channel info"
|
|
echo ""
|
|
'';
|
|
}
|