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 newtag
type spec forrequested_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 isto_sign
. If that does not parse, thecontent
is assumed to be the payload to sign. - Kind
10011
MUST have a tag where the first array element issignature
. If that does not parse, thecontent
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.
- Partially signed bitcoin transactions
- Purchase Order
- Bill of Lading
- Non-disclosure Agreement
- Multisignature nostr post (e.g. https://github.com/nickfarrow/frostr)
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
- Bill Clinton's speech on Electronic Signatures Act
- Ricardian contracts
- Electronic Data Interchange, a very old yet widely used protocol for business documents
- Coinstr presentation, bitcoin multi-custody signature orchestration using Nostr
- Coinstr website