nips/44.md
2023-01-01 08:49:46 -06:00

12 KiB

NIP-44

Geospatial Types

draft optional author:rossbates author:milesbates

Description

An event of kind 4326 is a geospatial note supporting various location-based clients such as transportation, travel, home automation, and social media applications. The data for this event is stored in the content field and should contain only valid GeoJSON objects.

This proposal recommends storing geographic features in standalone events that reference other e and p tags, similar to how kind 7 responses work. By requiring geographic features to link to related keys and events, rather than embedding location data within events, collections of notes in nostr will remain composable. Using GeoJSON as the geospatial data type for nostr supports interoperability with existing web standards and designating it type kind 4326 provides a standard method for future nostr kinds to integrate it in their applications.

For example, developers might implement notes that represent objects such as calendar events, restaurant reviews, or concert tickets - in this situation each of these notes would have a convenient way to integrate existing location data using e and p tags linked to kind 4326 notes. If no useable data exists, they can create new kind 4326 notes. All of this would be fully backwards compatible with the nostr protocol.

An object represented by p could potentially be a fixed location such as a building, a shape boundary such as a geofence or border, or a moving object such as a truck or a nostr user. Each of these potentially has geospatial data that can be represented using GeoJSON. There are no minimum or maximum number of kind 4326 notes that can be associated with a given p, nor are there restrictions on who can create them. This provides the most freedom for relays and clients to build solutions for making nostr objects spatially aware while adhering to the existing protocol standards.

Example

Here is an example of how the use of kind 4326 notes could be used in a real world example. In this scenario there are 3 nostr users (A,B,C) attending a nostr developer meetup in the evening who would like to privately share their location with their trusted contacts so they can coordinate dinner and transportation. They'll do this using the same nostr mobile app they use to communicate with a wider group of people.

The meetup is taking place at a building in downtown Austin represented by the following note.

["EVENT", {
	"id": "2953ae40dfc6c814cabef08a34e917e9886ffe3b11be54e0f14e0e76d1692197",
	"pubkey": "90f415eb9dd25616185f252f1565d9cfc0392906e4e2638d13fda1242aa00b09",
	"created_at": 1671975000,
	"kind": 4326,
	"tags": [],
	"content": "{'type': 'Point','coordinates': [-97.74274456131394,30.268100484614934]}",
	"sig": "0ecf4b5649366ab7f99123ff6ae9767bca988d8545300e545f09e1d9a956a0fa2e013ab12360c7abb4bbfa56338477f7ce5513754b06f472f5cc3eb40f6f2cab"
}]

At 5:30pm User A posts a kind 1 note using their nostr app reminding everyone about the event. In this note they tagged both the location as well as the 2 friends who will also be attending. This was done using the e tag for the location and the p of the contacts.

["EVENT", {
	"id": "f040fc0ba2620264efb19d2764ceaa7978977256034594c9af5b4a5be356c797",
	"pubkey": "c403fbbc3808913bccdc4460986dd09f3985376ecf07d4b471d18644075d0c4c",
	"created_at": 1674603000,
	"kind": 1,
	"tags": [
		["e", "2953ae40dfc6c814cabef08a34e917e9886ffe3b11be54e0f14e0e76d1692197", "wss...", "root"],
		["p", "3c8d410ef11ae8abbc541783cacecbb35075b93d23837fa59d59c3610c1c580c"],
		["p", "24226e17fcecdab9277218ab126ee882192c6ae3f1fec5689924e77754f00c11"]
	],
	"content": "Excited to see everyone this evening at the ATX nostr dev meetup.",
	"sig": "8a2228542bb69ab7b9a12824cd0df88eafd27e4993eec990c107b79a519754a436c1f5114188db254d8499cc6b7b5095ea34ade9173a8903739845da6d4a2815"
}]

In the same post User A chooses the option to attach their current location (created as kind 4326) to the note. The app generates an event referencing the original kind 1 note which goes to all public relays, while both events also get posted to a private relay.

["EVENT", {
	"id": "9850551d116a4c2c69b7d084a6b27aa95e0ba6ddf8b04cac33145ab290465733",
	"pubkey": "c403fbbc3808913bccdc4460986dd09f3985376ecf07d4b471d18644075d0c4c",
	"created_at": 1674603000,
	"kind": 4326,
	"tags": [
		["e", "f040fc0ba2620264efb19d2764ceaa7978977256034594c9af5b4a5be356c797", "wss...", "reply"]
	],
	"content": "{'type': 'Point','coordinates': [-97.73995249685214, 30.282439538024022]}",
	"sig": "026174991b8e956a4ef591c08bb69e506d5f42a07aa652d6af106a33a83017f646ed37f85e010aa0cd7b1e0beb0fc546c0acdb564a8daff84047d437e358f7e2"
}]

Users A, B and C all share access to the same private relay which supports receiving and responding to kind 4326 messages. Each client is also still able to filter for all public and private responses to the kind 1 note using the same interface. When user A sends a kind 4326 note that references p tags the relay can automatically generate a kind 1 note for all parties to prompt or alert them. This however is just an example, the client developers can customize the experience however it best suits the users.

Here user B & C decide to acknowldge and respond using only a kind 4326 note sent over the same private relay. These responses can include their current location coordinates, as well as other any other related p tags such as the Coffee Shop or Park they're currently at. The location data is the response.

User B Response:

["EVENT", {
	"id": "49734138379434153a4af1275fe6afcc18937a326ff950875a0c7165ac2be123",
	"pubkey": "3c8d410ef11ae8abbc541783cacecbb35075b93d23837fa59d59c3610c1c580c",
	"created_at": 1674603213,
	"kind": 4326,
	"tags": [
		["e", "9850551d116a4c2c69b7d084a6b27aa95e0ba6ddf8b04cac33145ab290465733", "wss...", "reply"]
	],
	"content": "{'type': 'Point','coordinates': [-97.7491855918345, 30.251096509429328]}",
	"sig": "b9889b3ae92ed5942a7270b6322b80d55230b256bd416d25e519ea07989a8eea8d105b0debb2d30366c70cd479b638453e16b2b9e8a016991b7f941fff553f05"
}]

User C Response:

["EVENT", {
	"id": "36fbb58a1dcd30aa3420eb456306435d4b06be4b804987fe000be8b58b2efed1",
	"pubkey": "24226e17fcecdab9277218ab126ee882192c6ae3f1fec5689924e77754f00c11",
	"created_at": 1674603321,
	"kind": 4326,
	"tags": [
		["e", "9850551d116a4c2c69b7d084a6b27aa95e0ba6ddf8b04cac33145ab290465733", "wss...", "reply"]
	],
	"content": "{'type': 'Point','coordinates': [-97.75077606389179, 30.26308185185999]}",
	"sig": "230f53ea5aa2c9a979badbb400f31edafa227ae526f019c1ffadf69ec257b21c360ca6ef779ea592a4eb7ffa7e8cedd6b5877c99ff202d1ecbdca99f76137d4c"
}]

This is a basic example to demonstrate the kind 4326 data structures and for showing how an initial handshake between peers over public and private relays would work. From this point forward the clients and the private relay now have everything needed to work in coordinatation - potentially executing geofence and nearby queries on the notes, generating arrival estimates, status updates, routing suggestions, ride-share integration, etc.... There are many possibilties for client experiences that go beyond the scope of the NIP.

Summary of Benefits

Privacy Controls: notes with kind 4326 can be routed separately to private and/or user specified relays for handling. This provides users with options to protect their private data if they choose, and it provides client developers a solution for combining public and private data into composite events.

Proof of Location: This design makes it so anyone is free to build validation and attestation services that an event took place in a physical location. For example, users could check-in at a concert using any nostr client to receive a special badge. Attestation and issuance could originate from any number of trusted sources, such as the artist and/and venue, without requiring users to be running a specific application or platform. Attestation could come from sources such as nostr peers, payment systems, photos or QR codes - or a combination of these using nostr multi-sig. Location proofs could be provided for any valid event, by any signer, with no barriers to entry.

Decentralized Data Providers: Support for nostr data types such as kind 4326 will open up opportunities for nostr relay operators to serve as data service providers. A kind 4326 event can be any valid geometry including buildings, geofences, and points of interest. This is similar to the concept of linked data URIs, but it's much simpler - p can represent any location on earth. Relay operators could charge for custom key/data management services.

Relay Performance: By separating data types and content using this approach, relays can route events without the need for content inspection. Notes with kind 4326 can be forwarded to backend indexing services which respond with new events when conditions are met. As the network grows, some relays may be dedicated solely to routing events based on their type.

Open Issues

NIP-16

What is the desired behavior when it's reasonable for an event to be either a Regular event (1000 <= n < 10000), Replaceable event (10000 <= n < 20000), or Ephemeral (20000 <= n < 30000) event as defined by NIP-16? Take for example a bus tracking application where the users are checking on the status of their bus identified by.

["p", "b68cf380888a13fab39afb144fb9e9502a8560af85943fa0cdcf1e3e130a109d"]

As the bus travels it's route it will generate a series of location updates. One solution could be a new type created such as kind 14326 or kind 24326 for use as the "current status" location. If however the client app is also tracking the history of the bus then kind 14326 is basically equal to the most recent kind 4326. Should this be something defined by the protocol, or left up to the developers?

To be clear, this decision is not a technical challenge, but as types in nostr begin to increase some guidelines for how these types are assigned and used will need to be figured out. For now this NIP proposes using only kind 4326

Content Field

The most common event on the network is kind 1 which relays assume will have a string in the content field. The event object itself is already valid JSON, so allowing for valid JSON to be sent in the content would be more efficient for client developers because they would not need to wrap/unwrap and validate JSON content. This could be a complexity trade-off for relays because they would need to support both strings and objects in the content field. Because the event must already be valid JSON, and the purpose of the event is that it's entire contents are verifiable by it's signature, it would be reasonable to require relays to support valid JSON in the object field.

Other Notes

  • The value 4326 was selected because it is the default coordinate reference system (CRS) for the GeoJSON specification. If a client or relay wants to use another reference system the GeoJSON spec fully supports including it as a tag.

  • There have been suggestions about using a more compact binary encoding scheme to improve efficiency over the wire. This would require a format to be chosen which would inherently have implications for developers. Plain text ensures notes of this type can be exchanged by all relays and client no matter what languages or platforms they're using.

  • A proof-of-concept has been developed using a fork of Damus iOS as the client and a fork of Dave St. Germain's nostr_relay as the server. This will be made available at geonostr.org for people who want to participate testing. Reach out to rossbates on nostr if interested:

    npub1u656f7znujcagfhtgngvtkcflhzptnj38enyzx85da0lh63sfj7qva332p