nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-07: Add NIP-26 createDelegation function

Open joshr4 opened this issue 2 years ago • 11 comments

In order to implement NIP-26 by way of NIP-07, a createDelegation function needs to be exposed by the NIP-07 extension.

joshr4 avatar Feb 11 '23 20:02 joshr4

Makes sense but I wonder who will go through the trouble of setting up delegation, and also do it from a web browser extension? And also should this feature be exposed to web apps? Perhaps would make more sense to go into the Nos2x/Nostore/Alby settings panel and there be a "create delegator token" option. Just adding my opinionated 2 cents as usual.

barkyq avatar Feb 11 '23 23:02 barkyq

Although certainly it might make sense for some apps to have this feature (e.g., allow app X to post notes from you?) What are the use cases you had in mind for web apps calling this function?

barkyq avatar Feb 11 '23 23:02 barkyq

Good questions, I'm trying to think through how NIP-07 and NIP-26 might relate to one another. I suppose the best question here is how a NIP-07 extension may be best used to facilitate the delegated event signing detailed in NIP-26, if at all.

I'm thinking about these two user workflows that could be used for delegated event signing. Assuming a user has a primary root key and one or many delegated keys.

Primary root key saved in NIP-07

  1. User saves primary key to NIP-07 extension.
  2. User creates delegatee key and stores in web-app.
  3. User creates delegation token for delegatee key, and signs with NIP-07 extension via new createDelegation function.
  4. User’s web-app signs delegated events (NIP-26). a. Web-app can sign event with its delegatee key and store delegation tag. b. NIP-07 extension can be a centralized delegation tag store and provide to web-apps.

Delegated key saved in NIP-07

  1. User saves delegated key to NIP-07 extension. Primary root key is kept in "cold-storage".
  2. User creates delegation token, signs with primary key. Signing can be done by either: a. NIP-07 extension via new createDelegation function (would require loading primary root key into the extension as well). b. A process external to NIP-07 extension.
  3. User saves signed delegation tag to either: a. NIP-07 extension, extension adds the tag to events. b. Web-app, web-app adds the tag to events.
  4. NIP-07 extension signs delegated events.

It looks like if the chosen workflow here is saving the delegated key to the extension, then the user can manage their associated delegation tag data external to the extension (within the web-app). There would be no need for a change to NIP-07.

For the parameters object, I was looking at copying this type:

type Parameters = {
  pubkey: string // the key to whom the delegation will be given
  kind: number | undefined
  until: number | undefined // delegation will only be valid until this date
  since: number | undefined // delegation will be valid from this date on
}

joshr4 avatar Feb 12 '23 15:02 joshr4

I was looking at adding NIP-07 capabilities (https://github.com/kdmukai/nostrtool/issues/1) to @kdmukai's NostrTool - https://nostrtool.com/. NIP-26 has been added to that tool, so am trying to think through how NIP-07 may fit into that picture and brainstorming ideas on that relationship.

joshr4 avatar Feb 12 '23 15:02 joshr4

For this implied use case, rather than createDelegation I would just simplify it to signDelegationToken(delegationToken).

In NIP-26 terms, the "delegation token" is what's signed; the resulting signature is then assembled into the final "delegation tag" that gets inserted into the event.

To @barkyq's point, I expect delegation construction/authorization to be the less common use case. And maybe it's just a nice-to-have; if you're using some other tool to construct your delegation (e.g. NostrTool), maybe you just do the whole thing there. So I'm not sure if this needs to be in the NIP-07 extension, but I think it doesn't hurt. And maybe there are other contexts where it does make more sense (e.g. Nostr web clients making it easy for users to migrate away from using their main identity PK: create new "hot" PK, sign this delegation, carry on).


But the most important change here that NIP-26 would require would be for @joshr4's second flow above: NIP-26 delegatee and its delegation tag are in the NIP-07 extension while the main identity PK stays offline.

To support this use case:

  • Explicitly allow signEvent to add the delegation tag to the event's tags and note that clients should be aware that the pubkey could come back as the delegatee key's pubkey.
  • Also note that when a delegatee is active in the NIP-07 extension, it should respond with the main identity's pubkey when prompted for getPublicKey(). In other words: getPublicKey() is more like: Get current identity (regardless of who may end up signing on behalf of that identity).

kdmukai avatar Feb 12 '23 16:02 kdmukai

see #238 for PR related to @joshr4 's second workflow.

barkyq avatar Feb 12 '23 17:02 barkyq

There’s a PR on get Alby implementing something similar to this PR’s proposal: https://github.com/getAlby/lightning-browser-extension/pull/2063

pablof7z avatar Feb 12 '23 17:02 pablof7z

I have also been experimenting with delegation in Nostore, as you saw from the other PR. I am glad to see some experimentation happening on multiple fronts!

There is an experimental feature in Nostore coming in the next TestFlight build that implements something very similar to method 2. It doesn’t require the extension to store the primary private key, it just creates a delegatee profile and stores a presigned delegation token.

All that is required from a client perspective is to check for the presence of a delegation token in the signed event returned from the extension.

The advantages of this method is that users do not not need to store the primary key. They just enter it to sign the token or “refresh” the profile (time expires). Also, later on, users will be able to export the token to be signed by a cold storage device and never need to enter key into extension at all.

While this doesn’t require a change to the NIP-07 interface, my PR did include language to make clear to client and extension developers that this is a possibility.

ursuscamp avatar Feb 12 '23 21:02 ursuscamp

I don’t think these two workflows are mutually exclusive. Unless the community wants one right way to do delegation, then they can both coexist.

ursuscamp avatar Feb 13 '23 00:02 ursuscamp

I am on board, but I think that the rules of the condition string need to be ironed out before the token-creation starts getting implemented in browser extensions. See #208.

Ideally also some clients would support the proper display of delegated events before apps start letting normal users create delegate tokens. Perhaps some expert users can make delegation tokens (once #208 is resolved, hopefully) and start testing / bugging the main clients and relays to handle NIP-26 properly. I made a delegation token the other night, and queried for events authored by "me" and delegated events were returned. I noticed that nostr-tools was blocking these events because they had the wrong pubkey. Just an example of how it seems like there is still stuff to be ironed-out.

Seems pretty harmless to enable the "delegated signing" feature now though, i.e. #238. Just my 2 cents.

barkyq avatar Feb 14 '23 05:02 barkyq

I went ahead and preemptively made a PR for this change in the nos2x repo https://github.com/fiatjaf/nos2x/pull/29

joshr4 avatar Feb 18 '23 16:02 joshr4