The bolt11 amount decoder is correct — the three failing tests used the wrong invoice fixture. Per BOLT11, `lnbc2100n` = 2100 x 1e-9 BTC x 1e8 sats = 210 sats, not 21. A 21-sat invoice is `lnbc210n`. The passing `lnbc1000n = 100 sats` case confirms the decoder's math. Corrected the three cases in bolt11.test.ts and verifyInvoice.test.ts to use `lnbc210n` (21 sats) so they exercise the intended 21-sat / 1-sat slack scenarios against the correct implementation. Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
37 lines
1.5 KiB
TypeScript
37 lines
1.5 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { assertInvoiceAmount } from './verifyInvoice';
|
|
|
|
describe('assertInvoiceAmount', () => {
|
|
it('accepts an invoice whose amount matches the expected sats', () => {
|
|
// lnbc210n… = 210 * 1e-9 BTC = 21 sats
|
|
expect(() => assertInvoiceAmount('lnbc210n1pvjluez', 21)).not.toThrow();
|
|
});
|
|
|
|
it('accepts a 1-sat rounding difference (millisat↔sat slack)', () => {
|
|
// lnbc210n… = 21 sats, expected 22 → diff of 1 is allowed
|
|
expect(() => assertInvoiceAmount('lnbc210n1pvjluez', 22)).not.toThrow();
|
|
});
|
|
|
|
it('rejects an over-charging invoice (the core attack it defends against)', () => {
|
|
// Invoice requests 250,000 sats but the user intended 21.
|
|
expect(() => assertInvoiceAmount('lnbc2500u1pvjluez', 21)).toThrow(/mismatch/i);
|
|
});
|
|
|
|
it('rejects an amountless invoice when a concrete amount was expected', () => {
|
|
expect(() => assertInvoiceAmount('lnbc1pvjluez', 21)).toThrow(/no fixed amount/i);
|
|
});
|
|
|
|
it('rejects a malformed / unparseable invoice', () => {
|
|
expect(() => assertInvoiceAmount('not-an-invoice', 21)).toThrow(/could not verify/i);
|
|
});
|
|
|
|
it('rejects empty / non-string input', () => {
|
|
expect(() => assertInvoiceAmount('', 21)).toThrow(/invalid invoice/i);
|
|
// @ts-expect-error deliberately passing a non-string
|
|
expect(() => assertInvoiceAmount(null, 21)).toThrow(/invalid invoice/i);
|
|
});
|
|
|
|
it('allows an amountless invoice when nothing specific was expected', () => {
|
|
expect(() => assertInvoiceAmount('lnbc1pvjluez', 0)).not.toThrow();
|
|
});
|
|
});
|