diff --git a/doc/nostr/nip-place-photos.md b/doc/nostr/nip-place-photos.md new file mode 100644 index 0000000..4994cf0 --- /dev/null +++ b/doc/nostr/nip-place-photos.md @@ -0,0 +1,105 @@ +# NIP-XX: Place Photos and Media + +`draft` `optional` + +## Abstract + +This NIP defines a standardized event format for sharing photos, videos, and other visual media tied to specific real-world locations (e.g., OpenStreetMap POIs). + +While NIP-68 (Picture-first feeds) caters to general visual feeds, this NIP specifically targets map-based applications, travel logs, and location directories by mandating strict entity identifiers (`i` tags) and spatial indexing (`g` tags). + +## Event Kind + +`kind: 360` + +## Content + +The `.content` of the event SHOULD generally be empty. If a user wishes to provide a detailed description, summary, or caption for a place, clients SHOULD encourage them to create a Place Review event (`kind: 30360`) instead. + +## Tags + +This NIP relies on existing Nostr tag conventions to link media to places and provide inline metadata. + +### Required Tags + +#### 1. `i` — Entity Identifier + +Identifies the exact place the media depicts using an external identifier (as defined in NIP-73). OpenStreetMap data is the default: + +```json +["i", "osm:node:123456"] +``` +* For OSM POIs, `` MUST be one of: `node`, `way`, `relation`. + +#### 2. `g` — Geohash + +Used for spatial indexing and discovery. Events MUST include at least one high-precision geohash. To optimize for map-based discovery across different zoom levels, clients SHOULD include geohashes at multiple resolutions: + +```json +["g", "thrr"] // coarse (~city) +["g", "thrrn5"] // medium (~1km) +["g", "thrrn5k"] // fine (~150m) +["g", "thrrn5kxyz"] // exact +``` + +#### 3. `imeta` — Inline Media Metadata + +Media files MUST be attached using the `imeta` tag as defined in NIP-92. Each `imeta` tag represents one media item. The primary `url` SHOULD also be appended to the event's `.content` for backwards compatibility with clients that do not parse `imeta` tags. + +Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `m` (MIME type), and `blurhash` where possible. + +```json +[ + "imeta", + "url https://example.com/photo.jpg", + "m image/jpeg", + "dim 3024x4032", + "alt A steaming bowl of ramen on a wooden table at the restaurant.", + "blurhash eVF$^OI:${M{o#*0-nNFxakD-?xVM}WEWB%iNKxvR-oetmo#R-aen$" +] +``` + +### Optional Tags + +* `t`: Hashtags for categorization (e.g., `["t", "food"]`, `["t", "architecture"]`). +* `content-warning`: If the media contains NSFW or sensitive imagery. +* `published_at`: Unix timestamp of when the photo was originally taken or published. + +## Example Event + +```json +{ + "id": "<32-bytes hex>", + "pubkey": "<32-bytes hex>", + "created_at": 1713205000, + "kind": 360, + "content": "", + "tags": [ + ["i", "osm:node:987654321"], + ["g", "xn0m"], + ["g", "xn0m7h"], + ["g", "xn0m7hwq"], + + ["imeta", + "url https://example.com/ramen.jpg", + "m image/jpeg", + "dim 1080x1080", + "alt A close-up of spicy miso ramen with chashu pork, soft boiled egg, and scallions.", + "blurhash UHI=0o~q4T-o~q%MozM{x]t7RjRPt7oKkCWB" + ], + + ["t", "ramen"], + ["t", "food"] + ] +} +``` + +## Rationale + +### Why not use NIP-68 (Picture-first feeds)? + +NIP-68 is designed for general-purpose social feeds (like Instagram). Place photos require strict guarantees about what entity is being depicted to be useful for map clients, directories, and review aggregators. By mandating the `i` tag for POI linking and the `g` tag for spatial querying, this kind ensures interoperability for geo-spatial applications without cluttering general picture feeds with mundane POI images (like photos of storefronts or menus). + +### Separation from Place Reviews + +Reviews (kind 30360) and media have different lifecycles and data models. A user might upload 10 photos of a park without writing a review, or write a detailed review without attaching photos. Keeping them as separate events allows clients to query `imeta` attachments for a specific `i` tag to quickly build a photo gallery for a place, regardless of whether a review was attached. diff --git a/doc/nostr/nip-place-reviews.md b/doc/nostr/nip-place-reviews.md index a0221d2..efe8861 100644 --- a/doc/nostr/nip-place-reviews.md +++ b/doc/nostr/nip-place-reviews.md @@ -1,5 +1,7 @@ # NIP-XX: Place Reviews +`draft` `optional` + ## Abstract This NIP defines a standardized event format for decentralized place reviews using Nostr. Reviews are tied to real-world locations (e.g. OpenStreetMap POIs) via tags, and include structured, multi-aspect ratings, a binary recommendation signal, and optional contextual metadata. @@ -11,13 +13,9 @@ The design prioritizes: * Flexibility for different place types * Efficient geospatial querying using geohashes ---- - ## Event Kind -`kind: 30315` (suggested; subject to coordination) - ---- +`kind: 30360` ## Tags @@ -51,8 +49,6 @@ Examples: ["i", "osm:way:987654"] ``` ---- - ### Geospatial Tags #### `g` — Geohash @@ -91,8 +87,6 @@ Geospatial queries are performed using the `g` tag. Note: Other queries (e.g. fetching reviews for a specific place) are performed using the `i` tag and are outside the scope of geospatial querying. ---- - ## Content (JSON) The event `content` MUST be valid JSON matching the following schema. @@ -183,8 +177,6 @@ The event `content` MUST be valid JSON matching the following schema. } ``` ---- - ## Example ### Restaurant Review Event @@ -232,8 +224,6 @@ The event `content` MUST be valid JSON matching the following schema. } ``` ---- - ## Semantics ### Ratings @@ -248,8 +238,6 @@ The event `content` MUST be valid JSON matching the following schema. * Clients MAY define and interpret aspect keys * Clients SHOULD reuse commonly established aspect keys where possible ---- - ## Recommendation Signal The `recommend` field represents a binary verdict: @@ -259,8 +247,6 @@ The `recommend` field represents a binary verdict: Clients SHOULD strongly encourage users to provide this value. ---- - ## Familiarity Represents user familiarity with the place: @@ -271,8 +257,6 @@ Represents user familiarity with the place: Clients MAY use this signal for weighting during aggregation. ---- - ## Context Optional metadata about the visit. @@ -281,8 +265,6 @@ Optional metadata about the visit. * `duration_minutes` represents time spent * `party_size` indicates group size ---- - ## Interoperability This specification defines a content payload only. @@ -292,8 +274,6 @@ This specification defines a content payload only. Content payloads SHOULD NOT include place identifiers. ---- - ## Rationale ### No Place Field in Content @@ -320,8 +300,6 @@ Multiple resolutions balance: * small event size * early-stage discoverability ---- - ## Future Work * Standardized aspect vocabularies @@ -329,15 +307,7 @@ Multiple resolutions balance: * Indexing/aggregation services * Cross-protocol mappings ---- - ## Security Considerations * Clients SHOULD validate all input * Malicious or spam reviews may require external moderation or reputation systems - ---- - -## Copyright - -This NIP is public domain.