aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-07-10 22:56:12 -0700
committerAdam Soltys <[email protected]>2026-07-10 22:56:12 -0700
commit7d8cd769e6cf91dda70fdf06db72a0b03e263dd7 (patch)
tree343ba42197a168a8aaa9354990b94d22542ff87e /lib
parentfa029437a162088ff79f36872110fa4087011530 (diff)
downloadcoinos-server-7d8cd769e6cf91dda70fdf06db72a0b03e263dd7.tar.gz
coinos-server-7d8cd769e6cf91dda70fdf06db72a0b03e263dd7.zip
invoices: reject sub-300-sat on-chain invoice amounts
On-chain deposits below 300 sats are dropped by the dust filter in the confirm/credit path, so a specific-amount bitcoin/liquid invoice under that threshold can never be credited. Reject creating one at generation time and point the user at lightning. Any-amount (0) addresses are unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/invoices.ts12
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/invoices.ts b/lib/invoices.ts
index 79bf6f19..fb81914f 100644
--- a/lib/invoices.ts
+++ b/lib/invoices.ts
@@ -53,6 +53,18 @@ export const generate = async ({ invoice, user }) => {
if (!rate) rate = rates[currency];
if (fiat) amount = Math.round((SATS * fiat) / rate);
if (amount < 0) fail("invalid amount");
+ // On-chain deposits below 300 sats are silently dropped by the dust filter in
+ // the /confirm credit path (routes/payments.ts), so reject creating a bitcoin/
+ // liquid invoice for a specific sub-300-sat amount rather than letting a
+ // deposit vanish. amount = 0 (any-amount address) is unaffected.
+ if (
+ (type === PaymentType.bitcoin || type === PaymentType.liquid) &&
+ amount > 0 &&
+ amount < 300
+ )
+ fail(
+ "On-chain deposits must be at least 300 sats. Use a Lightning invoice for smaller amounts.",
+ );
if (tip < 0) fail("invalid tip");
if (rate < 0) fail("invalid rate");
if (memo && memo.length > 5000) fail("memo too long");