nips/62.md
2024-03-11 20:57:38 -05:00

4.4 KiB

NIP-62

Signed and Versioned Third-Party Objects

draft optional

This specification defines a protocol by which Nostr events may be used to authenticate third-party objects, which may be versioned. With Nostr, the cryptographic identity afforded by an npub/nsec keypair can be used to attest to the authenticity of an object outside of the Nostr network. Thus, the level of trust a user gives to a specific npub may be assigned to third-party objects that npub is willing to attest to. Such objects may include, but certainly are not limited to, Git commits, documents, and images.

Kind 32000: Simple Third-Party Object

An event of kind 32000 SHALL serve to authenticate an unversioned object hosted by a third-party service (i.e., not a Nostr client or relay). The content field MAY contain a description of the object or its contents. The following tags SHALL be used:

  • The d tag MUST contain a unique identifier for the object. This identifier SHOULD be a hash of the object itself to provide an additional means of validating its authenticity.
  • The r tag MUST indicate one or more URLs at which the object can be found.
  • The m tag MAY be included to indicate the MIME type of the object.
  • The client tag, as defined in NIP-89, MAY be included to indicate a preferred client for handling the Nostr event and its associated object.
  • The hash tag MUST be used when the object's unique identifier is a hash to indicate the hash method used.

Event Format

{
  ...,
  "kind": 32000,
  "tags": [
    ["d", <unique identifier>],
    ["r", <comma-separated urls>],
    ["m", <MIME type>],
    ["client", <name>, <address>, <relay hint>],
    ["hash", <hash method>]
  ],
  "content": <arbitrary string>,
  ...
}

Kind 32001: Versioned Third-Party Object

An event of kind 32001 SHALL serve to authenticate a versioned object hosted by a third-party service (i.e., not a Nostr client or relay). Events of this kind MUST implement the specification for kind 32000, along with the following rules:

  • The a tag MUST reference the kind 32000 event that represents the initial version of the object.
  • A second a tag MUST reference the kind 32001 event that represents the immediately previous version of the object when the previous version is represented by a kind 32001 event.
  • The d tag MUST use as an identifier a hash of the versioned object, so that each version is uniquely identified.
  • The hash tag MUST be included to specify the hash method used to produce the object's unique identifier.
  • The initial version of an object SHOULD be represented by a kind 32000 event, and all subsequent versions MUST by represented by events of kind 32001.

Event Format

{
  ...,
  "kind": 32001,
  "tags": [
    ["d", <unique identifier>],
    ["r", <comma-separated urls>],
    ["a", <previous event id>, <relay hint>],
    ["a", <root event id>, <relay hint>],
    ["m", <MIME type>],
    ["client", <name>, <address>, <relay hint>],
    ["hash", <hash method>]
  ],
  "content": <arbitrary string>,
  ...
}

Usage Notes

This specification is designed to provide the foundations by which file hosting and version control, akin to GitHub or SharePoint, may be implemented on Nostr.

The first instance of any third-party object authenticated with Nostr should be a kind 32000 event, since that kind has no a tag antecedent. If the third-party object or its host location is changed, the changes may be versioned or unversioned.

When the host location of an object changes, the event can simply be replaced with a new event with the same d tag, but updated r tags. Likewise, when an object with a simple ID (i.e., not a hash) is updated in-place, the change may be indicated by replacing the kind 32000 event with a new one that has the same d tag but a different content.

Version control, such as Git or SVN, may be represented on Nostr using kinds 32000 and 32001. In such cases, the d tag may be the commit or change ID, and commit details may be included in the content, though other schemes are certainly conceivable. For a fully versioned object, the start of that objects history would be represented by a kind 32000 event, and subsequent changes by a series of kind 32001 events, each referring to the previous change. A complete file history may be constructed from such a sequence.