Skip to content

Conversation

@franzaps
Copy link
Contributor

@franzaps franzaps commented Jun 29, 2024

Rendered

This event represents an application as used in Zapstore. It is actively being used in a production setting for many months already.

This relates to NIP-51 (kind 30063), those artifact sets point to their application (this event, kind 32267).

Feedback welcome

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jun 29, 2024

hum.. isn't it possible to merge this with kind 31990? Kind 31990 is insufficiently defined on NIP-89 but most apps already have their entry due to https://nostrapp.link/

We could just add the additional tags needed by zap.store to that definition.

@franzaps
Copy link
Contributor Author

NIP-89 is for apps that handle nostr events, isn't it? It's not at all what I'm defining here. In fact, 90%+ of the apps on zap.store do not handle nostr events.

It feels very contrived to try to fit this simple definition on the complexity of NIP-89.

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jun 29, 2024

Yes, that's what NIP-89 needed it for, but those app definitions don't need to exist to solely respond to Nostr events. Actually, I believe most apps don't event that "response" field setup correctly. Right now they are just there to receive reviews.

DVMs also reuse the same kind to define their applications.

Reusing the kind doesnt mean you have to implement NIP-89 to support yours.

@franzaps
Copy link
Contributor Author

franzaps commented Jun 29, 2024

Are you saying I can keep my schema as-is and change 32267 to 31990? In such case I would have to change content which will break other NIP-89 clients.

Or do you mean I should stuff all my metadata into a stringified metadata and put it in content?

@vitorpamplona
Copy link
Collaborator

Hum.. yeah I missed the content discrepancy.

@pablof7z, do you see a possibility of merging those two?

Or are we going to have to define our apps in two places?

@franzaps
Copy link
Contributor Author

Do you know what is the rationale for putting stringified JSON in content (unless it has to be encrypted)? I've noticed the pattern in several places

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jun 29, 2024

Do you know what is the rationale for putting stringified JSON in content

Dumb decisions. They probably just copied how kind 0 works :(

@franzaps
Copy link
Contributor Author

franzaps commented Jul 1, 2024

I also need data to be in tags for full text indexing purpose.

31990 seems built for something else which is fine: all apps can sign a 32267 and if they want nostr interop also sign a 31990.

I will keep using kind 32267 unless there's a better alternative to describe an application

@DanConwayDev
Copy link
Contributor

Love to see this and look forward to adding releases to nip34 clients.

Instead of referencing a nip34 announcement event in repository tag it should be referenced with an a tag so it will be indexed by relays. clients should look for an a tag with 30617 kind if repository is omitted.

The release event:

  1. should be moved into this nip from the example section of nip51.
  2. should be immutable and not a replaceable event. then trust attestations could be placed on the event eg. validation that the checksums of a reproducible build match.
  3. should include an optional ["commit-id","<SHA1-commit-id-used-to-build-release>"] tag

From a style point of view: I see most nips describe events using jsonc rather than a table of tags, which is easier to read. Is this now the standard?

lastly, the app event could support the maintainers tag like nip34 announcements This means clients could optionally interpret app events by the pubkeys listed with identical d tags as referring to the same app. ["maintainers", "<other-recognized-maintainer>", ...]

@franzaps
Copy link
Contributor Author

franzaps commented Jul 3, 2024

Love to see this and look forward to adding releases to nip34 clients.

Looking forward too!

Instead of referencing a nip34 announcement event in repository tag it should be referenced with an a tag so it will be indexed by relays. clients should look for an a tag with 30617 kind if repository is omitted.

Sounds great

The release event:

1. should be moved into this nip from the example section of nip51.

Sure, I can do that

2. should be immutable and not a replaceable event. then trust attestations could be placed on the event  eg. validation that the checksums of a reproducible build match.

We're probably talking about different things. The release set is a NIP-51 replaceable event (kind 30063) that is simply a pointer to a set of software releases (binaries). Trust attestations should be applied to NIP-94 (kind 1063) events because they carry a checksum of the binaries. Moreover, if a developer made a mistake in the file collection or a typo in the release notes, it's useful that they can update the event.

3. should include an optional `["commit-id","<SHA1-commit-id-used-to-build-release>"]` tag

Sure - in kind 1063s

From a style point of view: I see most nips describe events using jsonc rather than a table of tags, which is easier to read. Is this now the standard?

I don't think we have a standard for whether to include tables or not. Other NIPs use bullet points.

lastly, the app event could support the maintainers tag like nip34 announcements This means clients could optionally interpret app events by the pubkeys listed with identical d tags as referring to the same app. ["maintainers", "<other-recognized-maintainer>", ...]

This is currently done via attribution p/zap tags. I think a better idea is to include maintainers in releases (not apps).

@bezysoftware
Copy link
Contributor

Do you know what is the rationale for putting stringified JSON in content

Dumb decisions. They probably just copied how kind 0 works :(

Sorry to go off topic, but what is so bad about putting stringified json in content? Why are tags better?

@franzaps
Copy link
Contributor Author

franzaps commented Jul 4, 2024

@bezysoftware I would ask what is good about putting stringified JSON in content. It makes no sense to encode JSON inside JSON for no gain (unless it needs to be encrypted) since values of that object are strings anyway. Tags can be indexed.

Copy link
Contributor

@DanConwayDev DanConwayDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is a suggested update reflecting the comments you were receptive to

@franzaps
Copy link
Contributor Author

I rewrote good part of this NIP.

As suggested by @NielLiesmons application description should be a wiki article. With that, developers also get access to better tools for updating information.

Presented the tags in jsonc example format as suggested by @DanConwayDev

Lastly, made a clarification on NIP-89.

Events on relay.zap.store do not yet conform to this spec but will be migrated shortly.

@franzaps
Copy link
Contributor Author

Updated the NIP to reflect the usage on Zapstore.

Since it has been used for months now and it's pretty stable, can we get this merged?

@staab
Copy link
Member

staab commented Dec 10, 2024

Is this in use by anyone other than zap.store?

@franzaps
Copy link
Contributor Author

@staab Not that I'm aware of.

Other than, maybe, @Giszmo ?

@staab
Copy link
Member

staab commented Dec 10, 2024

Normally NIPs are merged once there's some compatibility that needs to be ensured. It's good to have it documented in a draft, but update here when there are other apps using the standard

@franzaps
Copy link
Contributor Author

This data structure will probably end up in NDK and used in Yana and probably in a relay-based community started by @NielLiesmons

@vitorpamplona
Copy link
Collaborator

It would be nice to have a common way of doing. I could imagine switching back one version and having to "search" for what each store/publisher is using as dtag.

@v0l
Copy link
Member

v0l commented Feb 14, 2025

Also missing some documentation about the NIP-94, i published events as per this PR but it doesnt open in Zapstore app,

What is apk_signature_hash for?

@franzaps
Copy link
Contributor Author

Also missing some documentation about the NIP-94, i published events as per this PR but it doesnt open in Zapstore app,

What is apk_signature_hash for?

Should be apk_certificate_hash really (used in Zapstore to detect cert mismatches early which for sure will result in failed package updates). None of the NIP-94 extensions are documented. I don't know whether it should be another NIP or what.

@vitorpamplona
Copy link
Collaborator

Pictures and Videos were on NIP-94 and recently moved away from it into their own event kinds. That seems to have been a good move.

The same can happen here if software applications need their own NIP-94-like kind where not only specialized tags (like apk_certificate_hash) can be defined just for these file types but also the procedures to validate those hashes can be discussed.

@ZigBalthazar
Copy link
Contributor

ZigBalthazar commented Feb 22, 2025

@franzaps

+1 relay implementation:
https://github.com/dezh-tech/ddsr/tree/main/zapoli

@franzaps
Copy link
Contributor Author

Pictures and Videos were on NIP-94 and recently moved away from it into their own event kinds. That seems to have been a good move.

The same can happen here if software applications need their own NIP-94-like kind where not only specialized tags (like apk_certificate_hash) can be defined just for these file types but also the procedures to validate those hashes can be discussed.

Makes sense. Should we have one NIP for all software package related things? How about adding those things here?

@franzaps
Copy link
Contributor Author

franzaps commented May 27, 2025

Updating the NIP with:

And overall more clarity in the description.

This is work in progress, I plan to finalize it over the next few weeks.

@franzaps franzaps changed the title Software applications event Software applications events May 27, 2025
Copy link
Contributor

@dluvian dluvian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Software releases being replaceable have multiple downsides:

  • Breaks chronological order: Impossible to figure out which is the latest release because the latest timestamp may be an edit. Querying 10 releases will not yield the 10 latest releases when an old release has been edited.
  • Can't differentiate between initial release and update: A Github-style activity feed may only want to display new releases and not their edits.
  • Minor downside of getting rugged by edits.

I would prefer a non-replaceable release event and a replaceable edit event for fixing bad releases. I we keep the replaceability then edits should add an initial-time timestamp tag to keep the created_at of the initial release event. This tag aids in ordering releases and differentiating edit from initial release.

@franzaps
Copy link
Contributor Author

Software releases being replaceable have multiple downsides:

* Breaks chronological order: **Impossible** to figure out which is the latest release because the latest timestamp may be an edit. Querying 10 releases will not yield the 10 latest releases when an old release has been edited.

I understand your point, however, I have never seen this happen in practice. Replaceable releases (kind 30063) have been live on Zapstore for over a year now.

When developers figure out mistakes and need to edit a release, it's very likely they do before cutting a newer release.

Creating events in the past to edit an old release is possible, easy and enforceable by publishing tools like zapstore CLI - which again, in practice, most developers use. So in my experience this is a non-issue.

* Can't differentiate between initial release and update: A Github-style activity feed may only want to display new releases and not their edits.

I'm fine with adding an original_created_at though I don't see how it would differ from created_at in value. Having it could be useful to show an "edited" label.

* Minor downside of getting rugged by edits.

Not sure what this means exactly. In Zapstore for example zaps (and eventually comments and other) refer to the asset, which is a regular non-replaceable event, not the release. In general if you think a developer is rugging you stop trusting them.

@dluvian
Copy link
Contributor

dluvian commented Jul 12, 2025

Releases are replaceable to fix typos and broken artifacts but you're only supposed to fix the latest release or otherwise you will break the release order. Or you use specialized software that hack around this design flaw.

I have never seen this happen in practice

Yeah, but to be fair there are not many people that are publishing on nostr right now.

What about using 30063 as the edit event for a non-replaceable release event? Both with same structure described in your proposal. So we can have sane ordering with editable releases.

@franzaps
Copy link
Contributor Author

franzaps commented Jul 12, 2025

Releases are replaceable to fix typos and broken artifacts but you're only supposed to fix the latest release or otherwise you will break the release order. Or you use specialized software that hack around this design flaw.

Does a similar mechanism exist for long-form articles (kind 30023)? Or any other replaceable for that matter? Why are we singling this one out?

If you are a developer who modifies a 6-month old release (unlikely but possible) to presumably improve correctness of your event, why wouldn't you also take care of the correctness of the created_at date? It's not like you are forced to timestamp it with the current date.

An app that wishes to show latest releases could also query and sort client side by version (or even version_code if Android).

Also, if you really wanted to rely on non-replaceables, with a little creativity you can work around it. Query for the latest assets (kind 3063) for a specific platform (f tag) and you will get non-replaceable events that have a version tag in them. Sort accordingly.

What about using 30063 as the edit event for a non-replaceable release event? Both with same structure described in your proposal. So we can have sane ordering with editable releases.

While I agree your proposal is technically more correct, there is a tradeoff of one additional query per release just to check if there were any edits. For something low-risk and for which there are more than decent alternatives as I laid out. Tradeoffs in favor of leaving it unchanged in my opinion.

@dluvian
Copy link
Contributor

dluvian commented Jul 13, 2025

Why are we singling this one out?

Because it's much more important to figure out the latest release than the latest blog post.

While I agree your proposal is technically more correct, there is a tradeoff of one additional query per release just to check if there were any edits. For something low-risk and for which there are more than decent alternatives as I laid out. Tradeoffs in favor of leaving it unchanged in my opinion.

That's fair 🤝

| Kind mute sets | 30007 | mute pubkeys by kinds<br>`"d"` tag MUST be the kind string | `"p"` (pubkeys) |
| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) |
| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) |
| Release artifact sets | 30063 | group of artifacts of a software release | `"e"` (kind:1063 [file metadata](94.md) events), `"a"` (software application event) |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used by anyone?
30063 is already reserved in rust-nostr as Kind::ReleaseArtifactSet @yukibtc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You remind me that we should update NIP-51 with changes here (mention that kind 30063 is covered here, and that it should point to kind 3063 events)

@franzaps
Copy link
Contributor Author

Why are we singling this one out?

Because it's much more important to figure out the latest release than the latest blog post.

While I agree your proposal is technically more correct, there is a tradeoff of one additional query per release just to check if there were any edits. For something low-risk and for which there are more than decent alternatives as I laid out. Tradeoffs in favor of leaving it unchanged in my opinion.

That's fair 🤝

I appreciate your input.

@franzaps franzaps marked this pull request as draft July 13, 2025 22:10
@dluvian
Copy link
Contributor

dluvian commented Aug 14, 2025

I'm already using Software Release kind 30063 to show new software releases in the activity feed in Gitplaza and I would like to support listing and creating repo releases with the same kind. Can you add an optional a tag to the documentation so we can point releases to a repo? @franzaps

@NielLiesmons
Copy link

Very cool!

Yeah, both a Repo event and a Docs event (I need a place to link to the NIPs and other specs, tools, ... that were used in the App) would be useful.

Don't know at what level is best, Release I guess.

@franzaps
Copy link
Contributor Author

franzaps commented Aug 14, 2025

I'm already using Software Release kind 30063 to show new software releases in the activity feed in Gitplaza and I would like to support listing and creating repo releases with the same kind. Can you add an optional a tag to the documentation so we can point releases to a repo? @franzaps

@dluvian Very cool!

The tag is available in the application kind 32267 (not in 30063):

    [
      // OPTIONAL
      // Pointer to NIP-34 repository
      "a", "30617:<destination-pubkey>:<repo-id>", "<relay-url>"
    ],

FYI it will take 6+ weeks for Zapstore to start the migration to this new format. There are currently too many signers and we need to do this carefully.

@dluvian
Copy link
Contributor

dluvian commented Oct 20, 2025

No title tag for releases?

@franzaps
Copy link
Contributor Author

No title tag for releases?

Sure can add that

// OPTIONAL
// Minimum operating system version (minimum compatibility)
// NOTE: On Android this would be obtained from min_sdk_version
"min_os_version", "<min-os-version>"
Copy link
Contributor

@basantagoswami basantagoswami Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it have made sense to call it something like min_platform_version instead of min_os_version. Same for the target tag. Some applications can be things like browser extensions. Or mini apps within the new Damus Notedeck for example. It's probably too late to change it now but considering we already have the f tag for platforms, I thought it makes sense to call it platform instead of os

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good call

[
// REQUIRED, MULTIPLE
// Asset ID
"e", "<asset-id>"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble finding the assets, because there is no pubkey hint for a relay list look up. Can you add it?

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

Successfully merging this pull request may close these issues.