Release: develop -> main - #70
Merged
Merged
Conversation
* 01a04a23 - Publish kind:0 picture, NIP-65, and kind:1 photo imeta * 01a04a23 - Keep zapped photo notes on their original event id * 01a04a23 - Filter photo resign to unpaid rows at the store --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* Persist forum invoice attempts and zap ingest decisions. POST /messages/:id/invoice now writes every attempt (success and failure) to message_invoice, including the BOLT11, description vs description_hash, and whether the invoice is a NIP-57 hash invoice. kind:9735 ingest records indexed and rejected outcomes in nostr_zap_ingest. Operators can list both via DEBUG_TOKEN GET /debug/invoices and GET /debug/zap-ingests. * Document invoice and zap-ingest methods on the in-memory store. Handbook bullets for migrateMessageSchema and InMemoryMessageStore now name message_invoice, nostr_zap_ingest, and the matching store methods. * Format CONTRIBUTING and debug-payments with Prettier. CI lint failed prettier --check on three files; this matches the repo style. * Cover invoice persist and zap-ingest mapper edge cases. Adds tests for null/array JSON mapping, sign_failed invoice rows, a non-object signed zap request, and ingest errors without a string pubkey so coverage meets the 100% gate. * Document debug invoice and zap-ingest routes in SPEC. Adds GET /debug/invoices and GET /debug/zap-ingests to the route table and contracts, and names the new tables in the CONTRIBUTING schema tree. * Reject non-uuid message ids on the invoice route. POST /messages/:id/invoice now uses the same uuid check as photo fetch, so Postgres is not asked to cast garbage into message_invoice.message_id. * Persist zap ingest when the receipt pubkey is not a string. Invoice tests with a non-integer sats body now use a uuid path so the new invoice id check does not turn them into 404. * Document invoice UUID check and persist in SPEC and handbook. POST /messages/:id/invoice now states the UUID guard, best-effort message_invoice rows, and the full result union on GET /debug/invoices. * Retrigger CI. GitHub did not start check-runs on the previous two commits. * Format CONTRIBUTING after rebase onto NIP-65 develop. * Forward photo-reset store methods in persist test stubs. After the NIP-65 rebase, MessageStore includes listSignedMissingPhoto and resetSignedEvent; the invoice/ingest test doubles now implement them. * Cover remaining persist branches for the 100% coverage gate. Ignores zod/cap and missing-key persist that sit behind existing v8 guards, records a null zap_request bind, and marks the catch-path pubkey ternary as unreachable after the ingest guard. * Exercise inspectBolt11 fields on a successful forum invoice. The ok persist path records paymentHash and descriptionHash when the BOLT11 inspects, covering the non-null optional-chaining branches. --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* Allow operator-provisioned accounts and passkey claim by view key POST /debug/accounts creates name plus Wallet of Satoshi rows without a passkey. Register begin accepts viewKey so the owner can bind a passkey to that same account. * Tighten provision uniqueness and cover debug POST in e2e Unique Lightning Address and one passkey per account. Playwright hits POST /debug/accounts and claim begin with an unknown view key. * Format the provision and claim files with Prettier CI lint failed on six files after the uniqueness follow-up. * Reject duplicate Lightning Addresses on create, update, and /me Memory adapter matches the unique index. Linking someone else's address returns 409. Claim-loser provision still updates the name. * Document Lightning Address uniqueness in handbook and TSDoc POST /me/lightning-address 409, unique indexes, and in-memory refuse now match the adapters. * Cover claim, provision race, and address 409 branches CI coverage missed claim Nostr/passkey races, POST provision 500/loser name update, and silent updateAccount refuse on /me. * Document POST /debug/accounts 500 and drop a reachable v8 ignore The provision 500 path is operator-visible. Claim Nostr keygen failure is covered by a unit test, so it must stay in coverage. * Align SPEC.md with provision and claim, cover nameless claim POST /debug/accounts, optional viewKey begin, and 409 on a taken Lightning Address now match the implemented HTTP surface. * Normalize provision rows and keep one passkey per account Validate every name and Lightning Address before writing on POST /debug/accounts. Adapters refuse a second credential for the same account. Docs and tests cover the 400 path and uniqueness. * Document that claim user.id is the provisioned account Mint still uses a pending UUID; a view-key claim encodes the existing row. * Format the DEBUG_TOKEN row after the develop rebase --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* 01a04a23 - Give Damus image URLs a .jpg/.png/.webp extension * 01a04a23 - Document photo Content-Disposition and .jpeg alias --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
Over-cap POST /messages/:id/invoice now persists bad_body instead of hiding behind a coverage ignore. Debug invoice and zap-ingest lists return 503 when the store throws, matching the other debug routes. Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* 01a052b6 - Put #bitcoin and #21gifts in kind:1 content Damus renders hashtags from note text, not from hidden t tags. Append the same discovery tags to kind:1 content and re-sign unpaid notes that still lack them. Forum message text is unchanged. * 01a052b6 - Keep hashtags in worker tests that CI runs Photo notes without bytes still get #bitcoin #21gifts in content. Zap ingest fixtures must already include those tags so re-sign does not replace the event id the receipt points at. * 01a052b6 - Format kind:1 photo URL tests after rebase --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
) * Add self-hosted Web Push with VAPID and an outbox worker Store browser subscriptions on the account, enqueue forum and zap notifications, and send them when VAPID is configured. Missing keys keep the process booting; push HTTP returns 503. * Reject malformed VAPID keys without failing boot Missing keys already returned 503. Garbage keys used to throw inside web-push during sender construction and would take down the process. Validate decoded lengths and subject, and catch constructor throws. * Fix unconfigured push-route tests that used a default VAPID key Passing undefined into the helper still applied the configured default, so POST returned 200 and DELETE 404 instead of 503. * Pin VAPID off in Playwright and assert debug ping 401 without bearer Default e2e boot already sets DEBUG_TOKEN, so an unauthenticated debug-ping is 401. Blank VAPID env so host keys cannot leak into the booted process. * Keep HTTP push off when VAPID construct fails and return stored createdAt Boot now passes an explicit empty public key so createApp cannot pick VAPID back up from the environment after a sender throw. Subscription upsert returns the persisted createdAt, including rebinds. * Cover push enqueue failures and drop a dead worker branch Forum and zap ingest now have tests for enqueue throws. The worker tick marks sent or failed without an unreachable else. Document upsert return values. * Document forum push enqueue and format CONTRIBUTING after rebase messagesRoutes handbook and TSDoc now mention optional pushStore. Prettier the env table after merging develop. * Cover remaining VAPID branches and skip overlapping worker ticks Empty/invalid base64, non-numeric push status codes, and Date leases are tested. The interval will not start a second tick until the first has settled. * Retrigger pull_request CI on the current head * Format docs after rebasing onto develop * Split Date vs null claimed_until mapping tests The null-lease case must stay null. Map a Date lease in its own test so v8 covers the instanceof Date branch. * Cover Date vs string timestamps and env VAPID on createApp Postgres mappers now see both Date and ISO string created_at. createApp without vapidPublicKey still reads a valid env pair. * Use a current session timestamp in the env VAPID createApp test createdAt of 1 was expired and evicted, so the request returned 401. --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* Reject non-NIP-57 forum invoices before returning pr
POST /messages/:id/invoice now returns { pr, amountSats } only when the
minted BOLT11 description_hash matches the zap request. Plaintext LN
invoices are persisted as not_zap for debug and rejected with 400 so
the client never shows a QR that cannot produce a kind:9735 receipt.
* Document that isNip57Invoice is only used for the invoice gate
The ok persist path stores a literal true after the gate, so the
handbook Used-by line must not claim a second call.
* Cover not_zap when the minted BOLT11 cannot be inspected
The 100% branch gate failed on inspected?.paymentHash when inspectBolt11
returns null (malformed LNURL invoice). Persist still stores the pr.
---------
Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* Update only the account name on provision upsert POST /debug/accounts no longer rewrites the whole account row when the Lightning Address already exists. Postgres SET name is atomic so a concurrent role or rules write is not lost. * Harden the name-only provision update against stale reads Look up and mutate the in-memory row without yielding. Fail the provision request when the persisted name is not the requested one. * Document the name-mismatch 500 on provision upsert POST /debug/accounts already returns 500 when the stored name is not the requested name. SPEC and handbook now say so. --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
* 01a052b6 - Do not reset pending notes to stamp Damus hashtags Resetting every signed row every tick renewed the 60s sign lease, so nothing reached a relay — including new forum posts. Only published unpaid notes are re-signed, and only after unsigned rows are signed, matching the photo-URL lease rule. * 01a052b6 - Align photo and hashtag resign after sign Both published-only resets now run after unsigned rows are signed, so new forum posts are not queued behind a 20-row rewrite of old notes. Pending notes still EVENT without being reset. Docs match that order. --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
noZap and not_zap now 400 with a stable English string so the app can tell the payer the author's wallet cannot receive the payment, without showing a QR. Unreachable LNURL still uses the generic start-payment error. Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
TaprootFreak
approved these changes
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automatic Release PR
Commits: 1 new commit(s)