-
Notifications
You must be signed in to change notification settings - Fork 708
NIP-41: Add places -- geohash ladder addressable locations (kind - 37515) #2074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
2b0dbb0
b59fcb2
59422fc
7a7319d
cf17f7f
aeee8cb
42f5563
4b75061
cdf9db6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| # NIP-41 | ||
|
|
||
| ## Places (geohash ladder addressable locations) | ||
|
|
||
| `draft` `optional` | ||
|
|
||
| Clients need a simple, relay-indexable way to discover physical places (e.g., RV parks, cafés, venues) and to query them efficiently on maps. It should work with relays that don't have "Search Capability" (NIP-50). This NIP defines a parameterized replaceable event for “Places” that are **geohash-addressable** via a ladder of `g` tags—from coarse to fine precision—so clients can query by exact `#g` matches without prefix search. | ||
|
|
||
| ## 2. Event Kind | ||
|
|
||
| - **Kind:** `37515` | ||
| - **Type:** Addressable (NIP-01) | ||
| - **Parameterized key:** the first `["d", <identifier>]` tag (e.g., a business permit, slug, or another stable ID) | ||
|
|
||
| ## 3. Required/Recommended Fields | ||
|
|
||
| ### 3.1. Required fields/tags | ||
|
|
||
| - `["d", "<stable-id>"]` — stable place identifier (e.g., `permit:FL:44-54-00003` or `slug:lochloosa-harbor`) | ||
| - At least one `["g", "<geohash>"]` tag. | ||
| The **recommended pattern** is to include a **ladder** of geohash prefixes from coarse to fine precision (e.g., `d`, `dj`, `dj3`, `dj3p`, …). This enables fast map queries with `#g` matching at various zoom levels. | ||
|
|
||
| ### 3.2. Recommended tags | ||
|
|
||
| - `["name", "<display name>"]` | ||
| - `["r", "<canonical url>"]` — official website or listing | ||
| - `["image", "<absolute url>"]` — cover image | ||
| - `["phone", "<E.164 or human>"]` | ||
| - `["addr", "<street>", "<city>", "<region>", "<postal>", "<country>"]` | ||
| - `["t", "<type>", ...]` — freeform type tags (e.g., `business`, `rv_park`, `restaurant`, `accepts_btc`) used to reduce results for usecase | ||
|
||
| - Provider cross-refs, inventory, and flags as needed—for example: | ||
staab marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `["provider", "<name>", "<id-or-slug>"]` | ||
| - `["rv_spaces", "<count>"]` | ||
| - `["accepts_btc", "yes"|"no"]` | ||
|
|
||
| ### 3.3. Optional tags | ||
|
|
||
| - Hours, amenities, compliance, etc. (namespaced if domain-specific): | ||
| - `["hours", "Mo-Su 08:00-20:00"]` (freeform for now) | ||
| - `["amenity", "wifi"]`, `["amenity", "laundry"]`, … | ||
| - `["permit", "jurisdiction", "id"]` (if you don’t use it in `d`) | ||
|
|
||
| ### 3.4. Content | ||
|
|
||
| - `content` is a short human description (markdown or plain text). Rich, machine-readable details should live in tags to remain filterable. | ||
btcjt marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| --- | ||
|
|
||
| ## 4. Geohash (`g`) Tag Rules | ||
|
|
||
| - A `g` tag value is a standard **Base32 geohash** (lowercase), length 1–12. | ||
| - Include **multiple** `g` tags forming a **coarse→fine ladder** for the same point, e.g.: | ||
|
|
||
| ``` | ||
| ["g","d"] | ||
| ["g","dj"] | ||
| ["g","dj3"] | ||
| ["g","dj3p"] | ||
| ["g","dj3pz"] | ||
| ["g","dj3pzs"] | ||
| ["g","dj3pzsu"] | ||
| ["g","dj3pzsuc"] | ||
| ``` | ||
|
|
||
| - Reason: relays and clients can match `#g` **exactly** at any zoom level without needing prefix search. The Place then appears in map queries that request any of those zoom-appropriate buckets. | ||
|
|
||
| > Publishers **should** generate the ladder from a single point (lat/lon → geohash) and decide the deepest precision they care to expose (e.g., 7–9 chars for point-of-interest). | ||
|
|
||
| --- | ||
|
|
||
| ## 5. Querying | ||
|
|
||
| ### 5.1. Relay filters | ||
|
|
||
| - Fetch all Places within a geohash bucket: | ||
|
|
||
| ```json | ||
| { "kinds": [37515], "#g": ["dj3pzs"], "#t": ["rv_park"] } | ||
| ``` | ||
|
|
||
| - Zoom out: use shorter prefixes already present as `#g` values (e.g., `["dj3p"]`). | ||
|
|
||
| - Fetch/refresh a specific place (parameterized key): | ||
|
|
||
| ```json | ||
| { | ||
| "kinds": [37515], | ||
| "authors": ["<pubkey>"], | ||
| "#d": ["permit:FL:44-54-00003"] | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 6. Example (valid per this NIP) | ||
|
|
||
| ```json | ||
| { | ||
| "kind": 37515, | ||
| "pubkey": "598cece47f7ed9516a30d43f0045b6cfb78454af3829c18a941c4196959345ee", | ||
| "created_at": 1758720595, | ||
| "tags": [ | ||
| ["d", "permit:FL:44-54-00003"], | ||
| ["t", "business"], | ||
| ["t", "rv_park"], | ||
| ["t", "accepts_btc"], | ||
| ["name", "CSTP RENTALS, LLC"], | ||
| ["r", "https://www.mhvillage.com/parks/121442"], | ||
| [ | ||
| "image", | ||
| "https://assets.mhvillage.com/assets/image/search-results/home-gray-600.jpg" | ||
| ], | ||
| ["phone", "(305) 451-5880"], | ||
| ["addr", "95350 Overseas Highway", "Key Largo", "FL", "33037", "USA"], | ||
| ["provider", "campspot", "lochloosa-harbor"], | ||
| ["rv_spaces", "28"], | ||
| ["booking_url", "https://www.mhvillage.com/parks/121442"], | ||
| ["g", "d"], | ||
| ["g", "dh"], | ||
| ["g", "dhq"], | ||
| ["g", "dhqy"], | ||
| ["g", "dhqy8"], | ||
| ["g", "dhqy82"], | ||
| ["g", "dhqy82n"] | ||
| ], | ||
| "content": "CSTP Rentals, LLC mobile home park located in Key Largo, FL. All-Ages community mobile homes for sale. View lots, community details, photos, and more.", | ||
| "id": "8121da23881ebfa4be496392a78130699d97e434206c2995465d0df8cbc9fa40", | ||
| "sig": "dd00e06be69158902987e1c5d643d47b284e52f367988e62e1d644a6f0d15fb5b0c5e86ccd954c4117a10df435b15825568fd07d533b447c2062450d0b2f0f0f" | ||
| } | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 7. Client Guidance | ||
|
|
||
| - Clients may choose to `limit` returned events at a more coarse precision. | ||
| - For map tiles/zoom levels, choose the geohash precision to query: | ||
| - World/continent: 1–2 chars | ||
| - Region/state: 3–4 | ||
| - Metro/city: 5–6 | ||
| - Neighborhood/POI: 7–9 | ||
| - Query one or more `#g` values covering the viewport. (For polygons, derive covering geohash buckets and query all of them.) | ||
|
|
||
| --- | ||
|
|
||
| ## 8. Examples | ||
|
|
||
| - https://rvparker.westernbtc.com | ||
| - https://go.yondar.me | ||
|
|
||
| ## 9. Validation Rules and Privacy | ||
|
|
||
| - Must have at least one `["d", ...]` and one `["g", ...]`. | ||
| - `["g", ...]` must be valid Base32 geohash, lowercase, no `a,i,l,o`. | ||
| - Publishing precise geohashes reveals location; authors may choose a coarser precision if needed. | ||
| - Clients should treat unauthenticated data as unverified and display provenance. | ||
Uh oh!
There was an error while loading. Please reload this page.