aboutsummaryrefslogtreecommitdiffstats
path: root/tools/bolt12-test.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-07 08:12:29 -0700
committerAdam Soltys <[email protected]>2026-10-07 08:12:29 -0700
commit90eb381d6610ab5ee456aefa83f6d8aaf5abcb7b (patch)
tree1f06ab41c6a5ea5a0eac8532aec527feface0a5f /tools/bolt12-test.js
parent3728af809ffe9d5475805ab3261a90215646fed0 (diff)
downloadcoinosv3-90eb381d6610ab5ee456aefa83f6d8aaf5abcb7b.tar.gz
coinosv3-90eb381d6610ab5ee456aefa83f6d8aaf5abcb7b.zip
bolt12-test: committed regtest offer/invoice fixtures instead of a vanished scratchpad
The default fixture paths pointed into an old session's scratchpad, so the test died reading them (exit 1, no output). Fresh pair from the regtest stack: offer from clc, invoice fetched by cln-ark. Network and expiry checks no longer assume mainnet or a recent wall clock. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'tools/bolt12-test.js')
-rw-r--r--tools/bolt12-test.js11
1 files changed, 7 insertions, 4 deletions
diff --git a/tools/bolt12-test.js b/tools/bolt12-test.js
index 28909d3..ab5109a 100644
--- a/tools/bolt12-test.js
+++ b/tools/bolt12-test.js
@@ -1,6 +1,7 @@
// BOLT 12 decode + signature verification against a REAL offer/invoice pair
// (fetched from a live CLN via fetchinvoice) plus tamper checks.
// Run: bun tools/bolt12-test.js [offer-file invoice-file]
+// Default fixtures: regtest clc offer, invoice fetched by cln-ark for 12345 msat.
import { readFileSync } from 'node:fs';
import {
decodeOffer, decodeBolt12Invoice, verifyOfferInvoice, encodeBech32Raw, decodeBech32Raw,
@@ -14,8 +15,9 @@ const check = (name, ok, detail = '') => {
const throws = (fn) => { try { fn(); return null; } catch (e) { return e.message; } };
const [offerFile, invoiceFile] = process.argv.slice(2);
-const offerStr = readFileSync(offerFile || '/tmp/claude-1000/-home-adam-coinosv3/556b3f05-c728-4e11-a426-50382ad8bd8d/scratchpad/fixture-offer.txt', 'utf8').trim();
-const invStr = readFileSync(invoiceFile || '/tmp/claude-1000/-home-adam-coinosv3/556b3f05-c728-4e11-a426-50382ad8bd8d/scratchpad/fixture-invoice.txt', 'utf8').trim();
+const fixture = (name) => new URL(`fixtures/${name}`, import.meta.url).pathname;
+const offerStr = readFileSync(offerFile || fixture('bolt12-offer.txt'), 'utf8').trim();
+const invStr = readFileSync(invoiceFile || fixture('bolt12-invoice.txt'), 'utf8').trim();
console.log('[codec]');
const rt = decodeBech32Raw(invStr);
@@ -25,7 +27,7 @@ check('bech32 roundtrips', encodeBech32Raw('lni', rt.bytes) === invStr.toLowerCa
console.log('\n[offer]');
const offer = decodeOffer(offerStr);
check('decodes', !!offer.records.length, `${offer.records.length} records`);
-check('mainnet', offer.network === 'mainnet');
+check('network known', ['mainnet', 'testnet', 'signet', 'regtest'].includes(offer.network), offer.network);
check('describes itself', typeof offer.description === 'string', offer.description);
console.log('\n[invoice]');
@@ -34,7 +36,8 @@ check('payment hash present', /^[0-9a-f]{64}$/.test(inv.paymentHash || ''), inv.
check('amount = 12345 msat', inv.amountMsat === 12345n, String(inv.amountMsat));
check('amount rounds up to 13 sat', inv.amountSat === 13);
check('signer named', /^[0-9a-f]{66}$/.test(inv.nodeId || ''), inv.nodeId);
-check('expiry sane', inv.expiresAt > Date.now() - 86400_000, new Date(inv.expiresAt).toISOString());
+check('same network as the offer', inv.network === offer.network, inv.network);
+check('expiry sane', inv.expiresAt > inv.createdAt * 1000, new Date(inv.expiresAt).toISOString());
console.log('\n[verification]');
check('real invoice verifies', throws(() => verifyOfferInvoice(offer, inv)) === null,