Commit Graph

7 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
924438f6b7 Apply remaining changes
Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>
2026-09-07 22:05:53 +02:00
copilot-swe-agent[bot]
13db94d5a2 Restore package-lock.json platform flags dropped by a stray npm install
No dependency changed; keep the lockfile byte-identical to the base branch.

Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>
2026-09-07 22:05:53 +02:00
Copilot
0a24983585 Rename package and establish version 1.0.0 (#71)
* Initial plan

* Wire package metadata into About app

Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>

* Complete About version test wiring

Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>
2026-09-07 17:23:40 +02:00
mroxso
8d594d7d69 Add Lightning zaps with optional Nostr Wallet Connect (#62)
* Add Lightning zaps with optional Nostr Wallet Connect

Signed-in users can zap a note or reply, and see its zap total, from
the feed, a thread view, and replies. Zapping opens a dialog to pick
an amount (presets or custom) and an optional comment, then:

- Builds and signs a NIP-57 zap request and fetches an invoice from
  the recipient's LNURL/lud16 callback (rejecting non-https endpoints).
- If a wallet is connected via Nostr Wallet Connect (NIP-47, Settings
  > Lightning wallet), pays the invoice automatically and only reports
  success once the wallet returns a payment preimage.
- Otherwise shows the invoice as a QR code plus a copy/`lightning:`
  link for the user's own wallet, and polls for a matching zap receipt
  to confirm payment without ever asserting success it can't verify.

Zap totals sum kind-9735 receipts defensively: a receipt only counts
if it carries a bolt11 amount and a description whose embedded zap
request is a well-formed, signature-valid event, so a malformed or
forged receipt can't inflate the total.

The NWC connection secret is stored only in this browser, scoped to
the signed-in pubkey, and is used solely to sign/send payment requests
to the wallet's own relay — never published, logged, or shown besides
a truncated pubkey once connected.

Closes #54

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto

* Address PR #62 review feedback: NWC relay security, N+1 zap queries, manual-payment confirmation

Addresses Copilot review comments on PR #62:

- nwc.ts: reject plaintext ws:// Wallet Connect relays, requiring wss://.
  Every request is signed by the connection secret (a private key); even
  with an encrypted payload, an unencrypted transport still leaks metadata
  about the connection and admits tampering.
- ZapButton/useZaps: fixed the N+1 query pattern — a feed page mounted one
  unconditional zap-receipts query (limit 500) per rendered note. Added a
  `revealed` gate so the query only fires once a note is actually hovered
  or focused (the same interaction that already reveals the action row via
  CSS), confirmed live: 0 queries fired across 49 mounted notes before any
  interaction, exactly 1 after hovering one.
- ZapDialog: manual-payment confirmation compared the note's total receipt
  *count* against a baseline, so anyone else zapping the same note while
  the dialog waited would falsely confirm the viewer's own unpaid invoice.
  Added `hasValidReceiptForInvoice` to match against the specific invoice
  instead, with unit tests covering the exact race the review described.
- useZaps.ts: corrected a docstring overclaiming that receipt validation
  prevents "forged" receipts from inflating totals — it only rules out
  structurally invalid data; NIP-57 receipts are vouched for by the
  recipient's own LNURL server, so trusting one is inherent to the
  protocol, not something client-side validation can prove.

Investigated but did not change: the review's claim that
`nip04.decrypt(...)` needs an `await` because it returns a Promise. Not
correct for this project's actual `nostr-tools` dependency — confirmed by
running the real encrypt/decrypt round trip, `decrypt` is synchronous and
returns the plaintext string directly, so the existing `JSON.parse` call
already worked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYiUtZMQeA5RHggQw73wto

* Merge main and resolve action conflicts

Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com>

---------

Co-authored-by: highperfocused <highperfocused@pm.me>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-09-07 17:16:10 +02:00
mroxso
949a551492 feat: New Web OS design (#12)
* new web os frontend

* add docs

* Add CNAME and restore NIP-05 nostr.json for GitHub Pages

The Pages custom domain (layer.systems) is only stored in repo settings;
a CNAME file in the build output makes it survive Pages reconfiguration.
Restore public/.well-known/nostr.json, which this branch had dropped —
removing it would break the existing NIP-05 identifiers on layer.systems.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YtQoCzkP7Bo8nruhxojPi

* Ignore eslint and tsc build caches

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YtQoCzkP7Bo8nruhxojPi

* Rebrand page title and metadata to LAYER.systems

The site ships on layer.systems, so the document title, meta and OG
description, and the web manifest now carry that name instead of
"Nostr OS". OsShell sets the title at runtime, so it is updated too —
otherwise the tab would fall back to the old branding after hydration.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YtQoCzkP7Bo8nruhxojPi

* Rename remaining visible "Nostr OS" strings to LAYER.systems

Covers the About window heading, the mobile shell header and the app
icon's aria-label, so the visible branding matches the page title.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014YtQoCzkP7Bo8nruhxojPi

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 11:37:43 +02:00
007725dd7a chore: update Radix UI dependencies and add mobile hook
- Updated @radix-ui/react-dialog from ^1.1.2 to ^1.1.15
- Updated @radix-ui/react-separator from ^1.1.0 to ^1.1.8
- Updated @radix-ui/react-slot from ^1.1.0 to ^1.2.4
- Updated @radix-ui/react-tooltip from ^1.1.4 to ^1.2.8
- Added a new hook `useIsMobile` to determine if the viewport is mobile-sized
- Refactored tailwind.config.ts for better readability and maintainability
2025-12-28 12:48:21 +01:00
a833997770 initial code commit 2025-12-27 21:42:31 +01:00