Add test infrastructure helpers for e2e testing
New devenv.nix scripts: - test-setup: Validates entire test environment (services, connectivity, blockchain state, channels, and runs a payment test) - fund-atm: Funds ATM Lightning.Pub account via Alice - test-payment: Quick e2e payment test (ATM → customer) - alice-invoice: Create invoice on Alice's node - node-info: Display node pubkeys and channel information Script improvements: - fund-dev.mjs: Use FUND_AMOUNT env var instead of hardcoded value - test-pay.mjs: Use NOSTR_RELAY_URL env var with localhost fallback - Both scripts now use localhost:7777 by default instead of hardcoded IP Updated shell hook to document new testing commands. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5b0e0e0d91
commit
6d0485bfb5
3 changed files with 236 additions and 4 deletions
|
|
@ -278,6 +278,228 @@
|
||||||
echo "Paying invoice from Alice's node..."
|
echo "Paying invoice from Alice's node..."
|
||||||
docker exec lamassu-lnd-alice lncli --network=regtest payinvoice --force "$1"
|
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 ""
|
||||||
|
|
||||||
|
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"
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
@ -312,5 +534,12 @@
|
||||||
echo " alice-pay Pay invoice from Alice's node"
|
echo " alice-pay Pay invoice from Alice's node"
|
||||||
echo " relay-test Test Nostr relay connection"
|
echo " relay-test Test Nostr relay connection"
|
||||||
echo ""
|
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 ""
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import { randomUUID } from 'crypto'
|
||||||
|
|
||||||
const DEV_PRIVATE_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
const DEV_PRIVATE_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
||||||
const LIGHTNING_PUB_PUBKEY = 'f454c5eec4ec4474128e19b57b45e49c3d0851d01eea960b39ce391cdba76fc6'
|
const LIGHTNING_PUB_PUBKEY = 'f454c5eec4ec4474128e19b57b45e49c3d0851d01eea960b39ce391cdba76fc6'
|
||||||
const RELAY_URL = 'ws://192.168.1.122:7777'
|
const RELAY_URL = process.env.NOSTR_RELAY_URL || 'ws://localhost:7777'
|
||||||
|
const FUND_AMOUNT = parseInt(process.env.FUND_AMOUNT || '100000', 10)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const identity = loadIdentityFromHex(DEV_PRIVATE_KEY)
|
const identity = loadIdentityFromHex(DEV_PRIVATE_KEY)
|
||||||
|
|
@ -26,13 +27,15 @@ async function main() {
|
||||||
params: {},
|
params: {},
|
||||||
query: {},
|
query: {},
|
||||||
body: {
|
body: {
|
||||||
amountSats: 100000,
|
amountSats: FUND_AMOUNT,
|
||||||
memo: 'Fund dev account',
|
memo: `Fund dev account (${FUND_AMOUNT} sats)`,
|
||||||
},
|
},
|
||||||
authIdentifier: identity.publicKey,
|
authIdentifier: identity.publicKey,
|
||||||
requestId,
|
requestId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Creating invoice for', FUND_AMOUNT, 'sats')
|
||||||
|
|
||||||
console.log('Request structure:', JSON.stringify(rpcRequest, null, 2))
|
console.log('Request structure:', JSON.stringify(rpcRequest, null, 2))
|
||||||
|
|
||||||
const encryptedContent = encryptContent(identity, LIGHTNING_PUB_PUBKEY, rpcRequest)
|
const encryptedContent = encryptContent(identity, LIGHTNING_PUB_PUBKEY, rpcRequest)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { randomUUID } from 'crypto'
|
||||||
|
|
||||||
const DEV_PRIVATE_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
const DEV_PRIVATE_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
||||||
const LIGHTNING_PUB_PUBKEY = 'f454c5eec4ec4474128e19b57b45e49c3d0851d01eea960b39ce391cdba76fc6'
|
const LIGHTNING_PUB_PUBKEY = 'f454c5eec4ec4474128e19b57b45e49c3d0851d01eea960b39ce391cdba76fc6'
|
||||||
const RELAY_URL = 'ws://192.168.1.122:7777'
|
const RELAY_URL = process.env.NOSTR_RELAY_URL || 'ws://localhost:7777'
|
||||||
|
|
||||||
// Get a fresh invoice from Alice first:
|
// Get a fresh invoice from Alice first:
|
||||||
// docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt 1000
|
// docker exec lamassu-lnd-alice lncli --network=regtest addinvoice --amt 1000
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue