nips/70.md
2023-02-19 13:09:26 -05:00

6.6 KiB

NIP-70

Signature Request Event & Response

draft rfc optional author:3yekn

  • update to ephemeral event kinds and numbers
  • create specific examples of PSBTs
  • create specific examples of Ricardian contracts for Docusign replacement
  • create reference implementation in rust: https://github.com/3yekn/nostr/pull/1
  • create reference implementation in Go
  • develop improved subscribers and verifiers
  • add examples of encrypted signature requests
  • develop example showing combination with NIP-57 (ZAPs) in exchange for approvals
  • develop Bitcoin Proof-of-Reserves example

This proposal introduces an event type with kind 10010 representing a peer-to-peer request for signature of a specific payload and event kind 10011 as the signature response.

The initial purpose of this event type is for requesting approval of partially signed bitcoin transactions (PSBT), but the event type may also be used in more general purpose approval-style workflows.

Motivation

Bitcoin PSBTs

Alice, Bob, Charlie, David, and Erika manage a company's bitcoin treasury that is used to pay vendors. The amounts are large, so the treasury is protected in a multisignature wallet. The payment frequency is low, so there is not a need for an L2 such as lightning.

They often use popular bitcoin wallets such as Electrum or Sparrow to manage the treasury. These wallets require that a spending proposer export the PSBT to a text file, send the file out-of-band, where the prospective approver must then import the PSBT, sign, export, and repeat. Eventually, the PSBT or combination of signatures reaches the threshold for the transaction to be finalized and broadcast.

The treasurers wish to improve and streamline the process using Nostr and user-friendly policy editors such as BDK's Elephant.

Document Signatures

This feature set could replace common legal document approval/signature applications such as DocuSign or Adobe Sign. Instead of a PSBT, the content could be markdown, plain text, or content such as OpenLaw markup, the Accord project, or other types of Ricardian contracts.

Notes & RFC

Privacy

  • The content may or may not be encrypted. Some public DAO treasuries may desire open approvals, although most will likely be encrypted.
  • It will likely be common for this feature to be used on private or permissioned relays.

Tagging Prospective Approvers

  • The p tag is for tagging a specific account, presuming requesting approval from that user. If it is common for non-approval pubkeys to also be tagged, then a new tag type spec for requested_signer should be added. (TBD)

Bitcoin PSBT and Payload Decoding

  • Bitcoin signature request URIs have been proposed over the years but it is unclear how many wallets support them. The content in a 10010 event may contain a URI encoded PSBT or a non-URI encoded PSBT.
  • Some legal agreement specifications provide templated or handlebars-style hydration. In these cases, an event may reference an commonly adopted template (via URL, namespace, or hash) and provide the data in the Event tags (e.g. NDA template with a name and expiration date as data fields).

Fields Specifications

  • Kind 10010 MUST have a tag where the first array element is to_sign. If that does not parse, the content is assumed to be the payload to sign.
  • Kind 10011 MUST have a tag where the first array element is signature. If that does not parse, the content is assumed to be the signature.

Example

The simple example for illustration below is from Bob, requesting an approval from Alice, and Alice returns it.

Simple Example

Signature Request - 10010

Bob asks Alice to approve of having filet for dinner tonight.

{
  "pubkey": "5e79d85b377943fed828365d2a7712a0578272b6c1e0511154f6517e2a13925e", // bob 
  "kind": 10010,
  "tags": [
    [
      "p",
      "0e1db7418df1c6453ce42e7f4507b8823fc23e86e1f4f33d7fafc83d366e6e97", // alice
      "wss://r1.hashed.systems"
    ],
    [
      "to_sign",
      "I hereby approve of eating the filet tonight", // payload to sign
    ],
  ],
  "content": "please approve this because I already started the grill",
  "id": "the_ID_of_the_signature_request_event", // derived based on NIP-01
  "sig": <signature of the nostr event>,
  <other fields>
}

Signature Reply - 10011

Alice approves of having filet tonight.

{
  "pubkey": "0e1db7418df1c6453ce42e7f4507b8823fc23e86e1f4f33d7fafc83d366e6e97", // alice
  "kind": 10011,
  "tags": [
    [
      "p",
      "5e79d85b377943fed828365d2a7712a0578272b6c1e0511154f6517e2a13925e", // bob
      "wss://r1.hashed.systems"
    ],
    [
      "e",
      "the_ID_of_the_signature_request_event", // per reply style spec
      "wss://r1.hashed.systems"
    ],
    [
      "signature",
      "7d08c5d295ad7d5b29ba0c47e4a56323894e9b7a124a20ca59917428001b5b485d1aab20f58353b7a7e64be562d3ac5f458cc07dfe297d1850d4a5f4c18d6308", // signature
    ],
  ],
  "content": "sounds good to me",
  "sig": <signature of the nostr event>,
  <other fields>
}

Additional Examples

Additional examples are planned to be developed for further illustrations.

Example Client Implementation

Clients may show the event under DMs or in a specific signature-request zone.

Clients may add Approve or Reject or ... (more) buttons directly in the client, or provide a URI to open the signature request within a bitcoin wallet (similar to the zap functionality).

Miscellaneous References