From b42c2347096b39c5157f7c8fd15f55e07d476756 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Wed, 2 Sep 2026 20:58:51 +0700 Subject: [PATCH] Add Skater profiles (kind 35000) + /skaters directory - New app-native Skater Profile kind 35000 with `skateskater` marker tag, the anti-spam boundary that keeps generic kind-0 Nostr profiles out of the directory (queried only from the community relay). - Skater type, stance/style/level constants, and parser in types.ts. - useSkaters + useUserSkaterProfile hooks. - /skaters directory page: immersive hero, live count, search, style filter chips, ranked skater grid with NIP-05 verification badges and lazy author metadata. - /become-skater opt-in flow (bio, photo, styles, stance, level, years, home spot, location w/ geohash, socials). - Wire "Skaters" into the mobile nav and a cross-link banner in The Lab so plain skaters finally have a home. - Document kind 35000 in NIP.md. Co-authored-by: shakespeare.diy --- NIP.md | 47 ++++ src/AppRouter.tsx | 4 + src/components/Layout.tsx | 8 + src/hooks/useSkaters.ts | 67 ++++++ src/lib/types.ts | 100 +++++++++ src/pages/BecomeSkaterPage.tsx | 381 +++++++++++++++++++++++++++++++++ src/pages/LabPage.tsx | 21 ++ src/pages/SkatersPage.tsx | 313 +++++++++++++++++++++++++++ 8 files changed, 941 insertions(+) create mode 100644 src/hooks/useSkaters.ts create mode 100644 src/pages/BecomeSkaterPage.tsx create mode 100644 src/pages/SkatersPage.tsx diff --git a/NIP.md b/NIP.md index 11937cc..5fd1943 100644 --- a/NIP.md +++ b/NIP.md @@ -1478,6 +1478,53 @@ The value of a badge is proportional to the reputation of the witness: } ``` +## Skater Profile (kind 35000) + +The **Skater Profile** is the app-native identity that makes a Nostr pubkey a +*discoverable SkateSpots skater*. It is an addressable event identified by +`pubkey + kind + d-tag` (the `d` tag is always `skater-profile`, so a user has +exactly one). + +**This is the anti-spam boundary for the `/skaters` directory.** A plain kind-0 +metadata profile is shared by the entire Nostr network (every social client, +every bot) and is therefore never sufficient to appear in the directory. Only +events carrying kind `35000` **and** the `["t", "skateskater"]` marker tag — +published from within the app, and queried exclusively from the SkateSpots +community relay — are listed. This complements relay-level write restrictions: +the relay keeps junk out at the source, the marker defines who is a skater. + +Unlike Lab provider profiles, a Skater Profile advertises no paid service — it +exists purely for community discovery. + +```json +{ + "kind": 35000, + "content": "", + "tags": [ + ["d", "skater-profile"], + ["title", ""], + ["t", "skateskater"], + ["t", "skateboarding"], + ["alt", "SkateSpots skater: "], + ["stance", "regular | goofy | switch | mongo"], + ["level", "grom | intermediate | advanced | ripper"], + ["t", "