diff options
| author | Adam Soltys <[email protected]> | 2026-11-02 12:54:10 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-11-02 12:54:10 -0700 |
| commit | 8fbc6ea19c9f4959799f3d72b32e2b8661596ea8 (patch) | |
| tree | ea26d3daa86be2ea647e9ef86a2090099b5629fa /lib/invoices.ts | |
| parent | 9c7d26e0312b7e133801fe9a512e31908c2b29da (diff) | |
| download | coinos-server-8fbc6ea19c9f4959799f3d72b32e2b8661596ea8.tar.gz coinos-server-8fbc6ea19c9f4959799f3d72b32e2b8661596ea8.zip | |
payments: credit each on-chain output once and require uuid invoice ids
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6VN9xvnX1cgvV6hrUV
Diffstat (limited to 'lib/invoices.ts')
| -rw-r--r-- | lib/invoices.ts | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/invoices.ts b/lib/invoices.ts index 0028dc91..835b1247 100644 --- a/lib/invoices.ts +++ b/lib/invoices.ts @@ -91,6 +91,15 @@ export const generate = async ({ invoice, user }) => { if (!id) id = v4(); else { + // An internal invoice's id becomes its hash, and credit() writes + // `payment:<hash>`. A free-form id like "<txid>:<vout>" therefore lets a + // payer overwrite an on-chain deposit's dedup pointer, so ids must be the + // uuids we hand out. + if ( + typeof id !== "string" || + !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id) + ) + fail("invoice not found"); // A caller-supplied id re-uses an existing record (tip/webhook update, // repeated bolt12 offer create). It must be the caller's own: the write // below replaces `invoice:<id>` wholesale with uid = this user, and the |
