Merge cdf9db61e6
into 2ace01cf1a
This commit is contained in:
commit
f82aec81a4
|
@ -0,0 +1,182 @@
|
||||||
|
# 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:** `33000`
|
||||||
|
- **Type:** Addressable (NIP-01)
|
||||||
|
- **Parameterized key:** the first `["d", <identifier>]` tag (e.g., a random ID)
|
||||||
|
|
||||||
|
## 3. Required/Recommended Fields
|
||||||
|
|
||||||
|
### 3.1. Required fields/tags
|
||||||
|
|
||||||
|
- `["d", "<stable-id>"]` — a random ID (e.g., `permit:FL:44-54-00003`, `slug:lochloosa-harbor`, etc.)
|
||||||
|
- 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`, …). **Recommended precision is at least 7**. This enables fast map queries with `#g` matching at various zoom levels.
|
||||||
|
|
||||||
|
### 3.2. Recommended tags
|
||||||
|
|
||||||
|
- `["name", "<display name>"]`
|
||||||
|
- `["website", "<website url>"]` — official website or listing
|
||||||
|
- `["image", "<absolute url>"]` — cover image
|
||||||
|
- `["phone", "<E.164 or human>"]`
|
||||||
|
- `["payment_method", "<currency code>", "<type>"]` - e.g.: ["payment_method", "USD", "cash"]
|
||||||
|
- `["address", "<street>", "<city>", "<region>", "<postal>", "<country>"]`
|
||||||
|
- `["amenity", "<amenity type>"]`
|
||||||
|
- `["hours", "<day of week abbrevation>", "<shift one>", "<shift two>", ...]` - e.g., ["hours","thu","09:00/12:30","13:30/17:00"]
|
||||||
|
- `["L", "physical-location"]`
|
||||||
|
- `["l", "<physical-location-type>", "physical-location"]` - freeform type labels used to reduce results for usecase (e.g., `business`, `rv-park`, `restaurant`, etc.)
|
||||||
|
|
||||||
|
### 3.3. Optional tags
|
||||||
|
|
||||||
|
- Non-indexed labels for usecase:
|
||||||
|
- `["rv_spaces", "<count>"]`
|
||||||
|
- `["booking_provider", "<booking provider name>", "<specific booking provider id>"]`
|
||||||
|
|
||||||
|
### 3.4. Content
|
||||||
|
|
||||||
|
- `content` is a plain text short readable description.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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. 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–8 chars for point-of-interest).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Querying
|
||||||
|
|
||||||
|
### 5.1. Relay filters
|
||||||
|
|
||||||
|
- Fetch all Places within a geohash bucket:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"kinds": [33000],
|
||||||
|
"#g": [
|
||||||
|
"dhvj",
|
||||||
|
"dhvm",
|
||||||
|
"dhvn",
|
||||||
|
"dhvp",
|
||||||
|
"dhvq",
|
||||||
|
"dhvr",
|
||||||
|
"dhvt",
|
||||||
|
"dhvw",
|
||||||
|
"dhvx",
|
||||||
|
"djj0",
|
||||||
|
"djj2",
|
||||||
|
"djj8"
|
||||||
|
],
|
||||||
|
"#l": ["rv-park"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Zoom out: use shorter prefixes already present as `#g` values (e.g., `["dhv"]`).
|
||||||
|
|
||||||
|
- Fetch/refresh a specific place (parameterized key):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"kinds": [33000],
|
||||||
|
"authors": ["<pubkey>"],
|
||||||
|
"#d": ["permit:FL:44-54-00003"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Example (valid per this NIP)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"kind": 33000,
|
||||||
|
"pubkey": "598cece47f7ed9516a30d43f0045b6cfb78454af3829c18a941c4196959345ee",
|
||||||
|
"created_at": 1758720595,
|
||||||
|
"tags": [
|
||||||
|
["d", "permit:FL:1234567"],
|
||||||
|
["L", "physical-location"],
|
||||||
|
["l", "business", "physical-location"],
|
||||||
|
["l", "rv-park", "physical-location"],
|
||||||
|
["name", "Lochloosa Harbor RV Park"],
|
||||||
|
["payment_method", "USD", "credit_card"],
|
||||||
|
["payment_method", "USD", "apple_pay"],
|
||||||
|
["payment_method", "USD", "cash"],
|
||||||
|
["payment_method", "BTC", "onchain"],
|
||||||
|
["payment_method", "BTC", "lightning"],
|
||||||
|
["hours", "mon", "09:00/17:00"],
|
||||||
|
["hours", "tue", "09:00/17:00"],
|
||||||
|
["hours", "wed", "09:00/20:00"],
|
||||||
|
["hours", "thu", "09:00/12:30", "13:30/17:00"],
|
||||||
|
["hours", "fri", "10:00/22:00"],
|
||||||
|
["hours", "sat", "10:00/24:00"],
|
||||||
|
["hours", "sun"],
|
||||||
|
["amenity", "WiFi"],
|
||||||
|
["amenity", "Washer / Dryer"],
|
||||||
|
["website", "https://westernbtc.com"],
|
||||||
|
["image", "https://lochloosaharbor.example/cover.jpg"],
|
||||||
|
["phone", "+1-352-555-0123"],
|
||||||
|
["address", "123 Harbor Rd", "Hawthorne", "FL", "32640", "USA"],
|
||||||
|
["booking_provider", "campspot", "lochloosa-harbor"],
|
||||||
|
["booking_url", "https://example.com"],
|
||||||
|
["rv_spaces", "82"],
|
||||||
|
["g", "d"],
|
||||||
|
["g", "dj"],
|
||||||
|
["g", "dj3"],
|
||||||
|
["g", "dj3p"],
|
||||||
|
["g", "dj3pz"],
|
||||||
|
["g", "dj3pzs"],
|
||||||
|
["g", "dj3pzsu"],
|
||||||
|
["g", "dj3pzsuc"]
|
||||||
|
],
|
||||||
|
"content": "Some description.",
|
||||||
|
"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
|
||||||
|
|
||||||
|
## 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.
|
|
@ -57,6 +57,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||||
- [NIP-38: User Statuses](38.md)
|
- [NIP-38: User Statuses](38.md)
|
||||||
- [NIP-39: External Identities in Profiles](39.md)
|
- [NIP-39: External Identities in Profiles](39.md)
|
||||||
- [NIP-40: Expiration Timestamp](40.md)
|
- [NIP-40: Expiration Timestamp](40.md)
|
||||||
|
- [NIP-41: Physical Locations](41.md)
|
||||||
- [NIP-42: Authentication of clients to relays](42.md)
|
- [NIP-42: Authentication of clients to relays](42.md)
|
||||||
- [NIP-44: Encrypted Payloads (Versioned)](44.md)
|
- [NIP-44: Encrypted Payloads (Versioned)](44.md)
|
||||||
- [NIP-45: Counting results](45.md)
|
- [NIP-45: Counting results](45.md)
|
||||||
|
@ -263,10 +264,11 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||||
| `31989` | Handler recommendation | [89](89.md) |
|
| `31989` | Handler recommendation | [89](89.md) |
|
||||||
| `31990` | Handler information | [89](89.md) |
|
| `31990` | Handler information | [89](89.md) |
|
||||||
| `32267` | Software Application | |
|
| `32267` | Software Application | |
|
||||||
|
| `33000` | Physical Location | [42](42.md) |
|
||||||
| `34550` | Community Definition | [72](72.md) |
|
| `34550` | Community Definition | [72](72.md) |
|
||||||
|
| `37516` | Geocache listing | [geocaching](geocaching) |
|
||||||
| `38172` | Cashu Mint Announcement | [87](87.md) |
|
| `38172` | Cashu Mint Announcement | [87](87.md) |
|
||||||
| `38173` | Fedimint Announcement | [87](87.md) |
|
| `38173` | Fedimint Announcement | [87](87.md) |
|
||||||
| `37516` | Geocache listing | [geocaching](geocaching) |
|
|
||||||
| `38383` | Peer-to-peer Order events | [69](69.md) |
|
| `38383` | Peer-to-peer Order events | [69](69.md) |
|
||||||
| `39000-9` | Group metadata events | [29](29.md) |
|
| `39000-9` | Group metadata events | [29](29.md) |
|
||||||
| `39089` | Starter packs | [51](51.md) |
|
| `39089` | Starter packs | [51](51.md) |
|
||||||
|
|
Loading…
Reference in New Issue