seed-hypermedia / mintter

Mintter: an app for knowledge communities. Powered by the Hypermedia protocol.
https://mintter.com
Apache License 2.0
161 stars 11 forks source link

Nostr compatibility #1455

Closed KoalaSat closed 10 months ago

KoalaSat commented 1 year ago

After messaging with @gabohbeaumont , I'm happy to share my thoughts about the topic of making Mintter compatible with the basics of the nostr protocol, specially the ideas he already had in mind, such as embedding nostr notes as part of Documents (quoting?) or taking advantages of his network effect in form of comments or any other interactions between the 2 protocols. I'll focus on the first one for this issue.

One of the characteristics of nostr is that there is nothing that ensures the reliability of the data in the network. That's why I think that, from Mintter perspective and for this specific case, nostr should be considered as an ephemeral database.

It appears to me that this characteristic directly confronts the local-first policy of Mintter and its focus on the long term availability of the data, but I don't consider it as an issue or downside for an integration between the 2 protocols, just something to be always considered for design.

There is a lot of note types, and the bast majority of them are not related to user messages, I recommend as a first approach to only be compatible with "kind 1" notes (https://github.com/MintterHypermedia/mintter/issues/1455) and will try to explain some options for including them in documents:

URI Scheme

The protocol defines the way to work with specific URI scheme (https://github.com/nostr-protocol/nips/blob/master/21.md)

nostr:note1fntxtkcy9pjwucqwa9mddn7v03wwwsu9j330jj350nvhpky2tuaspk6nqc  

The URI is an encrypted hash with the real public key and id of the note and (optionally) a list of relays where (potentially) this note can be found (https://github.com/nostr-protocol/nips/blob/master/19.md).

Any client with permissions to open this scheme will be able to open the note. This string can be parsed in the view just by removing the protocol section.

note1fntxtkcy9pjwucqwa9mddn7v03wwwsu9j330jj350nvhpky2tuaspk6nqc  

Pros

Easy implementation and maintenance

Cons

As mentioned above, this is not compliant with the local-first policy. The note might disappear from the network at any moment, and even if some relays still stores it, the user might be out of their rage.

Raw Note

A raw nostr note can be included as part of the document, so there is no necessity for the user to access the resource or even be connected to the internet. Notes can be independently verified by using secp256k1 with sig and pubkey:

{  
"id": "4376c6...3ed6a65",  
"pubkey": "6e46842...15deee93",  
"created_at": 1673347337,  
"kind": 1,  
"content": "Walled gardens became prisons, and nostr is the first step towards tearing down the prison walls.",  
"tags": [],  
"sig": "908a15e46...6f009262"  
}  

A new type of Block can be implemented to make this note accessible for the user.

Creator: 6e46842...15deee93

"Walled gardens became prisons, and nostr is the first step towards tearing down the prison walls."  

You might have noticed the only information about the creator is the public key. Mintter would need to access the network to obtain a new note kind with creator's profile, with the exact same the disadvantages mentioned above for notes. My suggestion is to make all references to secondary notes a URI Scheme link.

Creator: nprofile1elfc...a8qzvjptg

"Walled gardens became prisons, and nostr is the first step towards tearing down the prison walls."  

Mintter will require to dynamically calculate the bech32 scheme to make it compatible with clients, but that's something can be calculated offline.

Pros

Cons

References to other notes

A note can reference other notes in different ways. There are 2 basic cases:

Creator: npub10elfc...a8qzvjptg

"Hello @nostr:nprofile1qqs...g49ehqj6f9dh"  
Creator: npub10elfc...a8qzvjptg

"This is true"

nostr:note1f8c8ba...4cf5dfb43f4d

Insert Notes

It's really difficult for a nostr user to spot and obtain a raw note. Usually, everyone works with bech32 or id and leave to the client the job of finding it out.

To help in UX, I propose to create a new command to insert nostr notes. The user will input the id/bech32 of the note and Mintter will do its best to obtain the note.

Workflow

  1. The user types the /nostr command and a new nostr block appears in the document
  2. The user inputs the note id or bech32 string.
  3. If it's an id, Mintter should have a static list of trustable relays to connect and try to find the note
  4. If it's a bech32 string, Mintter will connect to the included list of relays, if the note is not found, the logic can fallback to step 3.
  5. The note will be inserted into the document.

Further Considerations

gzuuus commented 1 year ago

There is a lot of note types, and the bast majority of them are not related to user messages, I recommend as a first approach to only be compatible with "kind 1" notes (https://github.com/MintterHypermedia/mintter/issues/1455) and will try to explain some options for including them in documents:

Another interesting option would be to use highlights or quoting (kind9802), this is a new nip that is not yet merge in the main, but it is widely used in the ecosystem (highlighter.com , habla.news , coracle , and amethyst implement it) This kind allows to highlight a range of text, as described here: https://github.com/nostr-protocol/nips/blob/adedce709433887d1f36b24723d70ba4a253c946/84.md Being ideal for any application that wants to author text fragments, among others.

The protocol defines the way to work with specific URI scheme (https://github.com/nostr-protocol/nips/blob/master/21.md)

nostr:note1fntxtkcy9pjwucqwa9mddn7v03wwwsu9j330jj350nvhpky2tuaspk6nqc  

The URI is an encrypted hash with the real public key and id of the note and (optionally) a list of relays where (potentially) this note can be found (https://github.com/nostr-protocol/nips/blob/master/19.md).

The nip19 entities that store information about relay hints are not the note1... but the nevent1... you can check it here and you can also use a debuggin tool that I recommend to use during the development process https://nak.nostr.com/ Here you can enter anything related to nostr to make a breakdown of it, as well as all the nip19 entities. Another debugging tool that can be useful is https://nostrdebug.com/ to check notes on relays and other utilities.

References to other notes

A note can reference other notes in different ways. There are 2 basic cases:

* User mentions: The user can mention other users (https://github.com/nostr-protocol/nips/blob/master/27.md) as part of the message. The same solution mentioned above for creator's `pubkey` might also work for this case.
Creator: npub10elfc...a8qzvjptg

"Hello @nostr:nprofile1qqs...g49ehqj6f9dh"  

You are mixing old and new standards here, the URI scheme is standardised by using only the nostr: prefix. (not @nostr:)

Insert Notes

It's really difficult for a nostr user to spot and obtain a raw note. Usually, everyone works with bech32 or id and leave to the client the job of finding it out.

To help in UX, I propose to create a new command to insert nostr notes. The user will input the id/bech32 of the note and Mintter will do its best to obtain the note.

Workflow

1. The user types the /nostr command and a new nostr block appears in the document

2. The user inputs the note id or bech32 string.

3. If it's an id, Mintter should have a  static list of trustable relays to connect and try to find the note

4. If it's a bech32 string, Mintter will connect to the included list of relays, if the note is not found, the logic can fallback to step 3.

5. The note will be inserted into the document.

There is another consideration that may increase the rate of missing notes found:

Workflow

 1. The user types the command /nostr and a new nostr block appears in the document.

 2. The user enters the id of the note or the string bech32.

 3. If it is an id, Mintter should get the author's list of preferred relays (kind10002 and kind3) and preferably search in these relays.

 4. If it is a bech32 string with relay hints, Mintter will connect to the included list of relays; if the note is not found, the logic can go back to step 3.

 5. The note will be inserted into the document.

Also, a good way to try to improve the rate of lost notes found is that when mintter finds a note it re-broadcasts it to a list of trusted relays.

In any case, good proposal to join mintter and nostr, I'll keep an eye out if I can help in any other way.

KoalaSat commented 1 year ago

using only the nostr: prefix. (not @nostr:)

Yeah this was a very bad way to try to show how it will looks like on the interface, not a real example 😅 .

Thank you for your comments @gzuuus !!