Commit graph

21 commits

Author SHA1 Message Date
SkateSpots
5b163c632f feat(trades): My Trades page + block-filter DM relays
- New '/trades' page: action-needed (incoming 'confirm this sale' requests as
  seller, pending confirmations as buyer) with inline actions, a reputation
  card, and the user's own trade records (role/counterparty/state) linking to
  each listing. Nav entry (auth-only) + smoke route.
- DM inbox relays (kind 10050) are now block-filtered on both read and delivery
  (closes the last relay caveat).
- AGENTS.md updated.

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 22:56:52 +07:00
SkateSpots
78f643d7a9 feat(mints,escrow): MintRadar polish + escrow status in shared actions
- Mints page: 'Online only' toggle + result count ('N of M mints')
- Wallet page: 'Browse Cashu mints' link to /mints
- ListingTradeActions now renders the EscrowPanel for a viewer's active escrow,
  so escrow status shows on both the grid card and the detail page
- AGENTS.md project map: marketplace detail page + shared actions

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 22:39:58 +07:00
SkateSpots
21a0390ed5 refactor(relays): route every relay consumer through useRelays()
So Local relays are used and Blocked relays are excluded EVERYWHERE, not just in
the NPool routers:
- useListingReports, useSellerInfo, useSkateRelays (read+write), useZaps
  (NIP-57 relays tag), usePurchasePro, CollectionDetailPage, CrewForm,
  useDirectMessages write fallback
- AppProvider's empty-relays defaults check is the only intentional direct reader
- AGENTS.md updated

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 22:36:14 +07:00
SkateSpots
c0aec3d912 chore(lint): reach zero warnings (react-refresh)
The last 7 react-refresh warnings are dev-only HMR DX from intentional
component+hook/helper colocations (EventCountdown, SortDropdown, TrustFilter,
LanguageContext, NewsletterPage). Splitting them into new files is broad import
churn for no runtime benefit, so each carries a justified file-level disable.

npm test: 0 errors, 0 warnings, 101 tests; boot smoke green.
2026-09-26 22:23:45 +07:00
SkateSpots
6def78fffe chore(lint): clear all no-unused-vars warnings (position-precise)
Removed/renamed the remaining 39 unused locals/dead code, file-by-file:
- unused destructured bindings/params (remove the binding, keep the call)
- unused single-line pure consts and dead functions/interfaces removed
- deleted the dead _FeedItem component and its now-unused imports
- amber _readChunks self-call fixed; SpotMap popup call site updated

Warnings: 182 -> 7 (only react-refresh/only-export-components remain).
no-explicit-any=0, exhaustive-deps=0, no-unused-vars=0.
Gate: 101 tests, 0 errors, boot smoke green. AGENTS.md baseline + guidance updated.
2026-09-26 22:20:21 +07:00
SkateSpots
721a5d4b67 chore(lint): clear all react-hooks/exhaustive-deps warnings
Triage per file (not a blanket sweep):
- Memoise shared getters with useCallback and depend on them:
  EventsPage/LabPage/MapPage getTrustScore+getCommentCount (+MapPage getZapTotal)
- Memoise derived values that were recreated each render: CrewChat 'messages',
  RiderCardPage 'cardData'
- Justified eslint-disable for intentional mount-only effects with a comment:
  AppProvider (seed defaults/theme), SpotMap (Leaflet init once),
  SpamFeePayment (auto-pay keyed to invoice/state, not the recreated handler)
- EventCountdown: keep the intentional 'tick' recompute dep (documented disable)

exhaustive-deps: 14 -> 0. Warnings 60 -> 46 (39 unused-vars, 7 react-refresh).
Gate: 101 tests, 0 errors, boot smoke green. AGENTS.md baseline updated.
2026-09-26 22:09:43 +07:00
SkateSpots
dc305fbc08 docs(agents): lint baseline 60 warnings + note unsafe mass unused-var fixes 2026-09-26 21:59:44 +07:00
SkateSpots
d1f8870379 chore(lint): remove all explicit any + sweep dead imports
- Fix all 12 no-explicit-any (NPool, NostrEvent[], LabProfile, structural
  Cluster type, explicit SkateSpot cast) -> 0 remaining
- Remove unused imports/vars across 48 files (manual + a verified codemod for
  unused import specifiers only); tsc + tests + boot smoke all green
- Warning backlog: 182 -> 76 (remaining: ~55 no-unused-vars locals,
  14 react-hooks/exhaustive-deps, 7 react-refresh)
- AGENTS.md baseline updated
2026-09-26 21:40:42 +07:00
SkateSpots
30ef511e78 feat(relays): NIP-17 DM inbox relays (kind 10050)
- RelayMetadata.dmRelays; Relays UI to add/remove, publishing kind 10050
- NostrSync fetches the user's 10050 on login (alongside 10002)
- DMs deliver gift wraps to recipients' + own DM relays (fallback: write relays)
  and read from own DM relays + NIP-65 read relays
- useDmRelays() to look up others' DM relay lists

Also fixes a latent data-loss bug: NostrSync's 10002 fetch replaced
relayMetadata wholesale, which would wipe the new local/blocked/dm lists on
login — it now merges. 'Trusted' category intentionally skipped (no distinct
behaviour -> no empty UI); documented in AGENTS.md.
2026-09-26 21:32:53 +07:00
SkateSpots
e75c4a8355 feat(relays): Local + Blocked relay categories
Add a purposeful subset of Amethyst-style relay categories (not a full clone):
- App-local 'Local relays' (never published; added to reads+writes)
- App-local 'Blocked relays' (excluded from every read/write)
- src/lib/relays.ts: resolveRelays()/useRelays() + URL normalisation
- NostrProvider req/event routers go through resolveRelays (blocklist applied)
- RelayListManager: Local/Blocked editors; NIP-65 save now preserves the new
  lists instead of overwriting relayMetadata

Deliberately omitted (documented in AGENTS.md): KeyPackage (10051, no MLS
consumer) and proxy/broadcast/private-home (no such discovery model here).
Follow-up noted: a few hooks still read config.relayMetadata.relays directly.
2026-09-26 21:26:13 +07:00
SkateSpots
a1c30cad4e feat(mints): Cashu mint directory (MintRadar) + same-origin proxy
New '/mints' page: browse Community MintRadar mints with health (online/latency/
degraded/archived), NUT count, terms, and add-to-wallet on native.

MintRadar has no CORS, so it's fetched same-origin at /api/mints/*:
- prod: Netlify proxy redirect in public/_redirects (+ 10m cache in _headers)
- dev: Vite server.proxy in vite.config.ts
This also hides users' IPs from MintRadar. Data is unofficial/rate-limited;
the page degrades to a friendly error state. Nav entry + smoke route added.
2026-09-26 21:20:19 +07:00
SkateSpots
6f28d1fe2a docs(escrow): on-device test checklist
Add a step-by-step Android verification checklist to ESCROW.md (preconditions,
advertise key -> buyer escrow -> seller redeem -> refund -> guard rails) and
point to it from the Status section and AGENTS.md. Escrow stays unverified until
every box passes on a device with tiny amounts.
2026-09-26 21:14:11 +07:00
SkateSpots
15901976ef feat(marketplace): wire Cashu escrow into the trade flow (native)
Completes the escrow feature on top of the tested core (src/lib/cashuEscrow.ts):
- useCashuEscrow: native-only hook wiring createEscrow (cashu-ts mint + NWC/WebLN
  funding), redeemEscrow, escrow-key derivation (coco keyring) and profile publish
- EscrowKeyCard (Wallet): advertise the kind-0 'cashu_escrow' pubkey
- EscrowRequestDialog (listing card): buyer locks funds (P2PK to seller, refundable
  after N days) and sends the 31872 carrying the cashu_token
- EscrowPanel + 'Redeem escrow' in the DM request banner (seller side); the panel
  is offline/parse-based so it renders on web too
- Buyer 'Escrow & request' supersedes the plain request when available

EXPERIMENTAL: mint-touching paths are unverified on a device (native-only wallet);
use small amounts first. Gate: 101 tests, 0 errors.
2026-09-26 21:08:36 +07:00
SkateSpots
26e951710e feat(marketplace): Cashu escrow core (time-locked P2PK) + design
Real, oracle-free escrow built on Cashu P2PK with a locktime + refund key:
buyer locks funds to the seller; seller redeems on delivery; the buyer can
reclaim after the deadline. Locked (not plain) tokens are what make the
cashu_token on a public 31872 safe.

- src/lib/cashuEscrow.ts: pubkey normalisation (x-only -> compressed), P2PK
  policy builder, offline token inspection (amount/mint/locktime/refund), and
  an injectable createEscrowToken mint flow (quote -> pay -> mintProofs{p2pk})
- 15 unit tests incl. the mint orchestration against a fake wallet
- Protocol: advertise a 'cashu_escrow' pubkey in kind 0 (NIP.md); token rides
  the existing 31872 cashu_token tag
- ESCROW.md: design, threat model, status, limitations
- AGENTS.md: project map + docs index updated

Wallet UI (cashu-ts + payment rail + profile publish) is native-only and still
needs on-device verification.
2026-09-26 21:01:31 +07:00
SkateSpots
8255d9d5e8 docs(agents): make AGENTS.md the maintained cross-session memory
- Add a 'this file is the ONLY persistent memory' directive: record non-obvious
  learnings in the same session, fix stale entries immediately, date claims
- Add a 'Project map' (HashRouter, custom kinds, marketplace/wallet/DM/lazy
  routes, npm test baselines, untracked-junk list)
- Fix stale facts: BrowserRouter -> HashRouter; /src/pages + /src/lib were
  understated; describe the smoke test's hash routes + crash-screen detection
- Strengthen System Prompt Management to treat AGENTS.md as long-term memory
2026-09-26 20:51:12 +07:00
SkateSpots
4e17852df3 fix(routes): self-healing lazy routes; document dev dep-cache crash
Symptom: in the long-running dev server some lazy routes (/settings, /stash,
/collections, /stats) hit the route error boundary ('This page slammed') while
others worked. Console: 'Failed to fetch dynamically imported module'; network:
504 for node_modules/.vite/deps/*.js. Vite's dep-optimizer cache had gone
missing after the server re-optimized on a lockfile change, leaving stale ?v=
hashes.

- Add lazyWithRetry: on a chunk-load failure, retry once, then do a single
  full reload per session (avoids reload loops); clears the flag on success
- Use it for all 53 lazy routes in AppRouter
- Document the dev dep-cache gotcha + fix in AGENTS.md
2026-09-26 20:36:14 +07:00
SkateSpots
acdde497b4 feat(deploy): boot-test the built bundle before deploying; document the vite chunking gotcha 2026-09-26 16:57:17 +07:00
SkateSpots
43d4773ce0 feat(deploy): add Netlify auto-deploy watcher (systemd timer) + ignore .netlify 2026-09-26 16:41:42 +07:00
SkateSpots
f56980ffcf docs(AGENTS): add project-specific dev, build, signing and release workflows 2026-09-26 16:21:49 +07:00
shakespeare.diy
27e14994b5 Import files from skate-spots project
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 20:04:15 +07:00
shakespeare.diy
06fae294b8 New project created with Shakespeare
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-15 19:49:07 +07:00