Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-21 extension. Adding Nostr Data URI #1447

Closed
vir2alexport opened this issue Aug 26, 2024 · 13 comments
Closed

NIP-21 extension. Adding Nostr Data URI #1447

vir2alexport opened this issue Aug 26, 2024 · 13 comments

Comments

@vir2alexport
Copy link

vir2alexport commented Aug 26, 2024

### NIP-21 extension

NIP-22 extension

Nostr Data URI
Nostr Smart Widgets

The idea is to store small files inline in nostr events.
The idea is to introduce smart widgets.

The rationale is when you store data as proposed with bossom or according to NIP-92 and NIP-94 guidance you can spot if the original file was edited and prevent the loading, but then you can't serve complete message to the end user. This is where nostr Data URI come into play to provide user with immutable data.

For more info see Data URLs, MIME type

instead of creating new tlv, use naddr
nostr:naddr1....

More details below 👇

@staab
Copy link
Member

staab commented Aug 26, 2024

NACK, this has been done before in the early days, and it has lots of problems associated with it. Relay operators do not want to store images, because they are often treated differently from text in terms of legal liability. Files of a size large enough to be useful are also a completely different problem in terms of implementation (postgres for example does weird things like TOAST to deal with inline files). The only thing this could really be useful for are emoji and profile images, and even those aren't trivially small.

@vir2alexport
Copy link
Author

Files of a size large enough to be useful are also a completely different problem in terms of implementation

This proposal for small files. A tiny feature for exceptional cases. I have hundreds of scripts that are <10 KB, for example.

@vir2alexport
Copy link
Author

vir2alexport commented Aug 31, 2024

Ok, let's try to come in from the other side, since I was intially thinking how to make widgets.

Relay operators do not want to store images, because they are often treated differently from text in terms of legal liability.

can be limited based on mime-type, so let's say we have something like this

event.content = {
   mimeType: "<mime-type>",
   data: "<data>" //  <data> part of data-uri
}

and so as relay operator you can check the mime-type and then if you want dynamic content w/o legal liabilities / scripts / clicks etc, you use DOMParser to sanitize <data> and then if you're a client simply render like this

<img src="data:<mime-type>,<data>"

and if you want clickable objects you take the <data> part, parse it with DOMParser to sanitize scripts etc and get something like this

event.content = {
   mimeType: "image/svg+xml",
   data:'<svg viewBox="0 0 10 5" xmlns="http://www.w3.org/2000/svg"><a href="https://relays.xport.top" target="_blank"><rect width="10" height="5"><animate attributeName="rx" values="0;5;0" dur="2s" repeatCount="indefinite" /></rect></a></svg>'
};

and then you render it like so

element.innerHTML = event.content.data;

EXAMPLE

And so to make it into nostr:ndata1.... we will need to extend tlv for that to be able to store let's say 128kB as this is in range with limits of most relays and so we end up with something like this

{
	hrp: "ndata",
	tlv: [
		{
			type: 0,
			length: <up to 128000>,
			value: {
                           mimeType: 'image/svg+xml',
                           data: '<svg viewBox="0 0 10 5" xmlns="http://www.w3.org/2000/svg"><a href="https://relays.xport.top" target="_blank"><rect width="10" height="5"><animate attributeName="rx" values="0;5;0" dur="2s" repeatCount="indefinite" /></rect></a></svg>'
                        }
		}
	]
}

is this makes sense?

postgres for example does weird things like TOAST to deal with inline files

I don't really understand what the problem is. It seems to me that it has more to do with the knowledge to be able to work with data and depends on the relay operator.

@staab
Copy link
Member

staab commented Aug 31, 2024

My point is, you can do what you want to put large payloads in events, but relays are generally going to block your events. Creating a NIP that recommends doing something that won't generally work on the network is an exercise in futility.

@vir2alexport
Copy link
Author

My point is, you can do what you want to put large payloads in events, but relays are generally going to block your events. Creating a NIP that recommends doing something that won't generally work on the network is an exercise in futility.

I can show you my event of kind 3 that is around 512kB and is on the network for at least a year and is still there. Anyway, thanks for your comment and for taking care of the network, I respect that. Widgets will appear one way or another and it will probably be better if we think about the standards before everyone will do what they decide for them.

@vir2alexport
Copy link
Author

Another point I have completely forgot to mention is widgets are kind=30031 as proposed by NIP-22 which is parameterized replaceable, so it may solve the issue you were talking about.

@vir2alexport
Copy link
Author

I just looked through all the widgets available on the network based on proposed in NIP-22 and the largest takes up about 6kB, so I think there is really nothing to worry about.

@staab
Copy link
Member

staab commented Aug 31, 2024

Maybe I'm misunderstanding what you're trying to accomplish here, because I'm not sure how widgets relate. Are you talking about embedding widgets in kind 1 notes? Or using SVGs instead of widgets? I'm not quite following.

@vir2alexport
Copy link
Author

I was thinking how to make widgets using what is already there, so that you don't have to reinvent the wheel for interpretation on the client's side

Are you talking about embedding widgets in kind 1 notes? Or using SVGs instead of widgets?

Just like now I can write a long-form content and then link it with naddr/nevent NIP-19 and reference according to NIP-27 and NIP-21, It seems to me widgets need the same mecahnics.

The most flexible imo is to use svg as you can describe any animation you want this way w/o scripts, but you can probably do similar things using html/css or whatever

I need some time to implement this and then we’ll continue if you don't mind.

@vir2alexport
Copy link
Author

vir2alexport commented Sep 1, 2024

NIP-22 Smart Widgets

Smart Widgets are customizable, interactive components that can be embedded within Nostr events and allow to create rich, dynamic content. This proposal outlines the structure, implementation, and potential use cases of Smart Widgets.

Motivation

Traditional static content limits user interaction and engagement. Smart Widgets provide a way to embed dynamic components, such as buttons, images, and polls, directly into Nostr events, enabling more interactive and responsive content.

Event kind

A new addressable event kind is proposed for Smart Widgets kind 30031. This event kind will encapsulate the data necessary to render and interact with the Smart Widgets.

Event Structure

The content of these events MUST be of a specified mime-type in a corresponding m tag. It is required and can't be empty.
For more info see

The list of tags are as follows:

d (required) universally unique identifier (UUID). Generated by the client creating the smart widget event.
m (required) allows clients to easily know file type before downloading it.
title (optional) title of the smart widget.
summary (optional) description of the smart widget and its usage.
client (optional) reference for the used client for creating the smart widget according to NIP-89.
published_at (optional) Publishing time of the smart widget differs from the created_at for edited smart widgets.

{
	"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
	"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,
	"created_at": <Unix timestamp in seconds>,
	"kind": 30031,
	"content": <JSON-stringified-data>,
	"tags": [
		["d", "UUID"],
		["m", <mime-type>],
		["title", "<title of smart widget event>"],
		["summary", "<description of smart widget event>"],
		["client", "<client_name>", "31990:app1_pubkey:<d_identifier>"],
		["published_at", "<Unix timestamp in seconds>"],
	]
}

A stringified JSON of the kind 30031 smart widget would look like this:

{
    "created_at": 1725188436112,
    "kind": 30031,
    "tags": [
        [
            "d",
            "534304df-be5e-47bf-a761-1e6515e3ca75"
        ],
        [
            "m",
            "image/svg+xml"
        ],
        [
            "client",
            "My Client",
            "31990:app1-pubkey:<d-identifier>"
        ],
        [
            "title",
            "Learn how to set up Nostr Relay with relays.xport.top article"
        ],
        [
            "summary",
            "Take control of your relay lists, or let them control you."
        ],
        [
            "published_at",
            1725188436112
        ]
    ],
    "content": "<svg viewBox=\"0 0 10 5\" xmlns=\"http://www.w3.org/2000/svg\"><a href=\"https://relays.xport.top\" target=\"_blank\"><rect width=\"10\" height=\"5\"><animate attributeName=\"rx\" values=\"0;5;0\" dur=\"2s\" repeatCount=\"indefinite\" /></rect></a></svg>",
    "pubkey": "b12e28991eae808d408208743f382d99b777c51887286c6002258b5bed9d9c8b",
    "id": "fbd1d692610c0dc1090fd37058d36d749b753d57b9ad5521f1d84dad3914a044",
    "sig": "8d51e221ebd570f0eb3c899ebe1a8248e468a0db44f35591901c7ccb668db6e6f02d787216eaae58dfdced41e6677f270467933cb36b67d6297417fcda09a60e"
}

@melvincarvalho
Copy link

did you think about putting the mime type in a tag?

@vir2alexport
Copy link
Author

#1468

@vir2alexport
Copy link
Author

did you think about putting the mime type in a tag?

can be done no problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants