Gruruya / nmostr

Nim library for Nostr
https://gruruya.github.io/nmostr/
GNU Affero General Public License v3.0
10 stars 0 forks source link

media type in nmostr? #2

Closed ghost closed 1 year ago

ghost commented 1 year ago

Hello everyone!

FAQ

I would like to know if it would be possible to have media type in nmostr. Would it be possible to have media type in mnostr?

Motivations

  1. Notes or events in nostr "may not be" text only, in that sense I think we should specify the most common media types as media/plaintext, media/html, media/yaml etc in nostr. In that case, we can support the rfc that specifies this.
  2. [RFC2046] specifies that Media Types (formerly known as MIME types) and Media Subtypes will be assigned and listed by the IANA.
  3. Specifying the rfc for the media type means making the nostr something like "http" - in the most commonly used sense.
  4. There are several discussions about techniques here: Different nostr: schemes for different types of apps/nips, Embedding decentralized media
  5. In my opinion, we should support things like 'url', 'uri' and 'urn'. And with that, having support for all types of media initially for nostr.

Intro

"RFC2046" specifies that Media Types (formerly known as MIME types) and Media Subtypes will be assigned and listed by the IANA. Procedures for registering Media Types can be found in RFC6838, RFC4289, RFC6657. Additional procedures for registering media types for transfer via Real-time Transport Protocol (RTP) can be found in RFC4855. See this: https://www.iana.org/assignments/media-types/media-types.xhtml

Idea

We might have a syntax for media/type as:

import pkg/[nmostr, whisky]
#  The example below is a conceptual sketch for this.
socket.send CMEvent(event: note(keypair, "media/type", "string")).toJson

Syntax

In the theory:

Example

example 1: media/urn urn: urn:<NAMESPACE-IDENTIFIER>:<NAMESPACE-SPECIFIC-STRING>: The placeholder stands for a string representing the resource category you want to identify. The is the resource's specific identifier, and its format depends on the namespace identifier. The following are examples of URNs: urn:isbn:1234567890, urn:ISSN:0167-6423, urn:ietf:rfc:2648

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/urn", "urn:ietf:rfc:2648")).toJson 

example 2: media/uri uri: https://the-great-chef.com/languages/recipe: The URI acronym stands for Uniform Resource Identifier. Shortly, it is a string that identifies a resource. From a syntactical point of view, a URI string mostly follows the same format as... the URL!

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/uri", "https://the-great-chef.com/languages/recipe")).toJson 

example 3: media/plaintext In cryptography, plaintext usually means unencrypted information pending input into cryptographic algorithms, usually encryption algorithms.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/plaintext", "Hello world from nmostr!")).toJson 

example 4: media/url URL identifies the web address or location of a unique resource.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/url", "https://jwt.io")).toJson

example 5: media/text-fragments Text fragments allow you linking directly to a specific portion of text in a web document, without requiring the author to annotate it with an ID, using particular syntax in the URL fragment.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/text-fragments", "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#:~:text=human")).toJson

example 6: media/bibtext 'BibTeX' stands for a tool and a file format which are used to describe and process lists of references, mostly in conjunction with LaTeX documents.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/bibtext", "http://sample-opensource-orgs.org/demo/sample.bib")).toJson

example 7: media/ipfs Relays can't be expected to host media, the infrastructure requirements would be immense. URLs break and many image/video hosts do annoying things that prevent simple unobtrusive viewing of media. Use of decentralized URN to embed media in messages should be normalized.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/urn", "urn:ipfs:bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi")).toJson

example 8: media/bittorrent Let's assume in this theoretical example that you want to share a link to an iso file of a linux distribution to your friends on nostr. You could do something like this:

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/bittorrent", "https://linuxfreetest.com/linux_2023-05-13_k61.iso.torrent")).toJson

example 9: media/file

file: URI Scheme is a URI scheme defined in RFC 8089, typically used to retrieve files from within one's own computer. This is very useful indoors where you want to share common data paths.

import pkg/[nmostr, whisky]
socket.send CMEvent(event: note(keypair, "media/file", "file://listlinux.com/free/public_html/chaps")).toJson

Implementation

import pkg/[nmostr, whisky]
import std/uri
let host = parseUri("https://nim-lang.org")
assert $host == "https://nim-lang.org"

let keypair = newKeypair()
echo "New secret key: " & keypair.seckey.toBech32
echo "The public key: " & keypair.pubkey.toBech32

# Post a note
let socket = newWebSocket("wss://nostr.oxtr.dev") # Remember to build with -d:ssl
socket.send CMEvent(event: note(keypair, "media/url", host)).toJson
let response = socket.receiveMessage().get.data
echo response

# Read the note back
unpack fromMessage(response), msg:
  when msg is SMOk:
    socket.send CMRequest(id: randomID(), filter: Filter(ids: @[msg.id])).toJson
    echo socket.receiveMessage().get.data

socket.close()
Gruruya commented 1 year ago

Sure, you can make whatever helpers you want. note is just a kind 1 wrapper around Event.init as you can see here: https://github.com/Gruruya/nmostr/blob/8a5e1f23f2d873539ffddf295c9bb9bdeb850210/src/nmostr/events.nim#L105-L107

I think you just want to add some tags, to do this you transform whatever tags you want this way: JSON: ["p", "17b3edfcf6cb1a96f7fd3d9f85dd37c3137d9927dad5e00b0788707e91fb889a"] Nim: @["p", "17b3edfcf6cb1a96f7fd3d9f85dd37c3137d9927dad5e00b0788707e91fb889a"] and put it inside the tags sequence like this:

socket.send CMEvent(event: note(keypair, "This kind 1 event has a tag", tags = @[@["p", "17b3edfcf6cb1a96f7fd3d9f85dd37c3137d9927dad5e00b0788707e91fb889a"]])).toJson

So just do that with whatever tags you decide to use and you're golden.