nips icon indicating copy to clipboard operation
nips copied to clipboard

Nip07/event ids

Open nostrband opened this issue 1 year ago • 8 comments

Right now it's unspecified who should generate the event ID (and thus who can do Proof of Work) - apps or signers.

Nip07 signers can generate IDs themselves, but some libs (NDK) and apps generate their own IDs and signers are forced to sign them (and thus can't do POW on such events).

Recommending apps and libs to delegate ID generation to signers would allow users to inject POW support into any app through the signer they're using. Signer could do POW by itself, or could do integration with third-party POW services.

Does this make sense?

I'm not sure about the wording and the scope (nip07) of this suggestion, but accepting something like this and advocating among devs could help with wider PoW adoption, and maybe help with recent concerns about spam/abuse/etc.

nostrband avatar Apr 26 '24 08:04 nostrband

@pablof7z @fiatjaf @staab @hzrd149 @v0l

nostrband avatar Apr 26 '24 08:04 nostrband

This is already the case, see the definition of signEvent:

async window.nostr.signEvent(event: { created_at: number, kind: number, tags: string[][], content: string }): Event // takes an event object, adds `id`, `pubkey` and `sig` and returns it

fiatjaf avatar Apr 26 '24 09:04 fiatjaf

But here is what NDK does:

// toNostrEvent:
            this.id = this.getEventHash();

// signEvent
        const nostrEvent = await this.toNostrEvent();
        this.sig = await signer.sign(nostrEvent);

It generates it's own ID and only uses .sig from the signer. It assumes signer won't touch the event and thus will generate the same ID.

Snort/system does the same: https://github.com/v0l/snort/blob/a6a1198f0493e116a58a34ed21dec7e877410af0/packages/system/src/impl/nip7.ts#L49

So even though the nip07 has long-time suggested that signer should generate the ID, clients thought (rightly?) that signer won't modify the event and thus they could only use sig from the signEvent return value. This logic also saved them from an issue where signer unexpectedly signs with other keys (user switched the npub in extension without the app knowing) and app shows one npub to the user but then publishes the event signed by another npub. With current approach the event will be invalid (sig from another npub) and we're safe.

Also, adding PoW wouldn't just change the ID, it would add nonce to tags. So I'm realizing maybe the whole idea of "signer can do PoW" is not great bcs it also changes the event and this might break other assumptions the clients might be making.

So wdyt, is PoW in signer such a good idea for everyone to re-evaluate their assumptions here?

nostrband avatar Apr 26 '24 10:04 nostrband

I like PoW in signer and I think clients should accomodate and allow it. It's not as if the signer is some untrusted malicious actor that your client should protect you from -- the signer is yourself.

fiatjaf avatar Apr 26 '24 14:04 fiatjaf

I like PoW in signer too, and agree that signer is you (much closer to you) than any app so assuming it could modify the event makes sense.

We could state that "signer not only generates the ID, it can modify anything". But that means app has to re-verify the returned event and throw error if signer returned nonsense (changed kind etc).

We could say "it can add pow tag and change id", but then something else pops up and we'll have this discussion again.

Maybe "signer can add tags and change ID" is a sensible middle ground?

nostrband avatar Apr 26 '24 14:04 nostrband

Snort/system does the same:

I didnt do this until i added NDK support in @snort/system https://github.com/v0l/snort/commit/eee76e64e501ac324c4f26ca2ca49e25f89b1897#diff-910dd63e658fe6c99e13a8ebd17f57ea246c444386b436b0f414a8811d588a3c

v0l avatar Apr 26 '24 15:04 v0l

There are times when you might want to create an event with an id, but no signature (known as a rumor, see NIP 59). This doesn't really conflict with what we're talking about here, but I thought I'd mention it.

I don't think the sign method should be expected to do arbitrary modifications to events. PoW is very special, since the output of the generated id matters, which is a unique case.

staab avatar Apr 26 '24 16:04 staab

There are times when you might want to create an event with an id, but no signature (known as a rumor, see NIP 59). This doesn't really conflict with what we're talking about here, but I thought I'd mention it.

Thanks for bringing this up. I guess if someone wanted to do pow on a rumor they could pass it through signer and discard the signature (although they should figure out signer is doing pow to be that smart). Otherwise rumors seem to need a signed wrap to be useful, so pow could go there?

I don't think the sign method should be expected to do arbitrary modifications to events. PoW is very special, since the output of the generated id matters, which is a unique case.

Maybe you're right. I wanted to bring up opentimestamp but I see the spec was changed and it's a separate event now. Well then I guess 'signer could do pow and add nonce and change id so beware' could work?

nostrband avatar Apr 26 '24 19:04 nostrband