-
Notifications
You must be signed in to change notification settings - Fork 577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NIP-88: Discreet Log Contracts over Nostr #919
Draft
benthecarman
wants to merge
5
commits into
nostr-protocol:master
Choose a base branch
from
benthecarman:dlcs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
ceaf163
NIP-88: Discreet Log Contracts over Nostr
benthecarman 7089bf7
additional clarity around message content and tags
conduition 9157321
Merge pull request #1 from conduition/dlcs
benthecarman 083f112
add title and description tags to oracle announcement
conduition eb4f408
Merge pull request #2 from conduition/dlcs
benthecarman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
NIP-88 | ||
====== | ||
|
||
Discreet Log Contracts over nostr | ||
----------------- | ||
|
||
`draft` `optional` | ||
|
||
This NIP describes a way to use Discreet Log Contracts (DLCs) over Nostr. This comes in four main | ||
components: `kind:8_888` for sending DLC messages between wallets. `kind:30088` for posting DLC offers to the global | ||
market. `kind:88` and `kind:89` for publishing DLC oracle announcements and attestations. And `kind:90` for a DLC | ||
"receipt" that can publish the result of a DLC for social interaction. | ||
|
||
## DLC Messages | ||
|
||
DLCs typically use [BOLT 8](https://github.com/lightning/bolts/blob/master/08-transport.md) for sending messages but | ||
this has various problems: it requires the ability to accept incoming connections and an always-on node. Nostr provides | ||
a unique opportunity to use a different transport layer for DLCs. This NIP proposes a new `kind:8_888` message that | ||
acts like a mailbox for DLC messages. The DLC messages are sent over nostr and available for the user the next time | ||
they open their wallet. This allows for a more mobile-friendly DLC experience. | ||
|
||
DLC protocol messages are binary-serialized messages described concretely in | ||
[this document](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md). | ||
Whenever embedding DLC messages inside Nostr events (which are encoded as JSON), we serialize those DLC messages in base64. | ||
|
||
### `kind:8_888` | ||
|
||
Kind 8_888 is a simple message that contains a [NIP04](04.md) encrypted DLC message and is tagged with the recipient's | ||
public key with a `p` tag and if it is in reply to another event, that event should be tagged with an `e` tag. The DLC | ||
message is first serialized in binary, and then encrypted with [NIP04](04.md). | ||
|
||
A DLC wallet should only process messages that are tagged with their public key and that are in reply to a message they | ||
sent unless it is an offer. This is to prevent spam and to prevent a malicious actor from sending a message to a user | ||
that looks like it is from a different user. | ||
|
||
```json | ||
{ | ||
"kind": 8888, | ||
"content": "TJob1dQrf2ndsmdbeGU+05HT5GMnBSx3fx8QdDY/g3NvCa7klfzgaQCmRZuo1d3WQjHDOjzSY1+MgTK5WjewFFumCcOZniWtOMSga9tJk1ky00tLoUUzyLnb1v9x95h/iT/KpkICJyAwUZ+LoJBUzLrK52wNTMt8M5jSLvCkRx8C0BmEwA/00pjOp4eRndy19H4WUUehhjfV2/VV/k4hMAjJ7Bb5Hp9xdmzmCLX9+64+MyeIQQjQAHPj8dkSsRahP7KS3MgMpjaF8nL48Bg5suZMxJayXGVp3BLtgRZx5z5nOk9xyrYk+71e2tnP9IDvSMkiSe76BcMct+m7kGVrRcavDI4n62goNNh25IpghT+a1OjjkpXt9me5wmaL7fxffV1pchdm+A7KJKIUU3kLC7QbUifF22EucRA9xiEyxETusNludBXN24O3llTbOy4vYFsq35BeZl4v1Cse7n2htZicVkItMz3wjzj1q1I1VqbnorNXFgllkRZn4/YXfTG/RMnoK/bDogRapOV+XToZ+IvsN0BqwKSUDx+ydKpci6htDRF2WDRkU+VQMqwM0CoLzy2H6A2cqyMMMD9SLRRzBg==?iv=S3rFeFr1gsYqmQA7bNnNTQ==", | ||
"tags": [ | ||
[ | ||
"p", | ||
"04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9" | ||
], | ||
[ | ||
"e", | ||
"9ae37aa68f48645127299e9453eb5d908a0cbb6058ff340d528ed4d37c8994fb" | ||
] | ||
], | ||
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", | ||
"created_at": 1679673265, | ||
"id": "30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
"sig": "f2cb581a84ed10e4dc84937bd98e27acac71ab057255f6aa8dfa561808c981fe8870f4a03c1e3666784d82a9c802d3704e174371aa13d63e2aeaf24ff5374d9d" | ||
} | ||
``` | ||
|
||
## DLC Offers | ||
|
||
DLCs are done between two parties and Nostr provides a unique opportunity to create a global market for DLCs. This | ||
benthecarman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
market can be constructed with a simple list of DLC offers that can be filtered by the user's wallet. The user can then | ||
select an offer and send a message to the offerer to begin the DLC process. `kind:30088` is an event that contains a DLC | ||
offer. | ||
|
||
A parameterized replaceable event is used to allow the offerer to update the offer or remove it from the market. The `d` | ||
tag should be the Offer's id to allow replacement of the offer. If the user wishes to remove the offer from the market, | ||
they can replace the event with an `expires` tag that is in the past. The `relays` tag indicates the relays on which to | ||
contact the offerer. | ||
|
||
The `content` field must be the base64-encoding of a binary-serialized | ||
[`contract_info` object](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-contract_info-type). | ||
|
||
### `kind:30_088` | ||
|
||
```jsonc | ||
{ | ||
"kind": 30088, | ||
"content": "base64 contract_info", | ||
"tags": [ | ||
[ | ||
"relays", | ||
"wss://nostr.mutinywallet.com", | ||
"wss://relay.damus.io" | ||
], | ||
[ | ||
"expires", | ||
"1695327657" | ||
], | ||
[ | ||
"d", | ||
"6423394a32f37a4f0590e74f9308f5aee06e59e14f50c4cd6d59365caed13cb7" | ||
], | ||
], | ||
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", | ||
"created_at": 1679673265, | ||
"id": "30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
"sig": "f2cb581a84ed10e4dc84937bd98e27acac71ab057255f6aa8dfa561808c981fe8870f4a03c1e3666784d82a9c802d3704e174371aa13d63e2aeaf24ff5374d9d" | ||
} | ||
``` | ||
|
||
## DLC Oracle Gossip | ||
|
||
DLCs require an oracle to attest to the outcome of real world events. This is done by the oracle signing a message | ||
containing the outcome of the event. Before they attest to the outcome, they must create an announcement where they | ||
publish the intent to sign the future event. This announcement is then used by the DLC participants to create the | ||
contract. Here we define two events, `kind:88` and `kind:89` that are used to publish the oracle's announcement and | ||
attestations respectively. | ||
|
||
### `kind:88` | ||
|
||
```jsonc | ||
{ | ||
"kind": 88, | ||
"content": "base64 oracle_annoucement", | ||
"tags": [ | ||
[ | ||
"relays", // the relays the oracle will publish attestations to | ||
"wss://nostr.mutinywallet.com", | ||
"wss://relay.damus.io" | ||
], | ||
[ | ||
"title", | ||
"Optional Event Title" | ||
], | ||
[ | ||
"description", | ||
"An optional human-readable description of the event which the oracle will attest to, in plain text." | ||
] | ||
], | ||
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", | ||
"created_at": 1679673265, | ||
"id": "30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
"sig": "f2cb581a84ed10e4dc84937bd98e27acac71ab057255f6aa8dfa561808c981fe8870f4a03c1e3666784d82a9c802d3704e174371aa13d63e2aeaf24ff5374d9d" | ||
} | ||
``` | ||
|
||
The `content` field must be the base64-encoding of a binary-serialized | ||
[`oracle_annoucement` object](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-oracle_annoucement-type). | ||
|
||
The optional `title` tag gives observers a short human-readable title with which to display the announcement in cards, hyperlinks, etc. It _should_ be at most 100 characters of UTF8 text. Clients _should_ ignore or truncate titles longer than 100 characters. This tag must NOT be parsed as markdown or HTML. | ||
|
||
The optional `description` tag provides a human-readable summary of the real-world event which this announcement is for. The `description` should give observers context, so that they know how the real-world event in question will be reflected in the oracle's final attestation. This tag must NOT be parsed as markdown or HTML. | ||
|
||
### `kind:89` | ||
|
||
```jsonc | ||
{ | ||
"kind": 89, | ||
"content": "base64 oracle_attestation", | ||
"tags": [ | ||
[ | ||
"e", // the Nostr event id of the announcement | ||
"30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
], | ||
], | ||
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", | ||
"created_at": 1679673265, | ||
"id": "30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
"sig": "f2cb581a84ed10e4dc84937bd98e27acac71ab057255f6aa8dfa561808c981fe8870f4a03c1e3666784d82a9c802d3704e174371aa13d63e2aeaf24ff5374d9d" | ||
} | ||
``` | ||
|
||
The `content` field must be the base64-encoding of a binary-serialized | ||
[`oracle_attestation` object](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-oracle_attestation-type). | ||
|
||
Note that the `e` tag is the _Nostr event identifier_ for the `kind:88` announcement event, which is distinct from the identifier | ||
embedded [in the announcement](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#oracle_event) or | ||
[in the attestation itself](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#oracle_attestation). The `e` | ||
tag is intended to be used to look up the corresponding announcement event. | ||
|
||
Upon receiving an attestation, clients _should_ validate that the `event_id` field inside the `oracle_announcement` object matches | ||
the `event_id` field in the `oracle_attestation` object. | ||
|
||
## DLC Receipts | ||
|
||
DLCs can be fun, social events. This NIP proposes a `kind:90` event that can be used to publish the result of a DLC | ||
contract. This event can be used to show off the result of a DLC to the user's followers, similar [Zaps](57.md) but for | ||
DLC bets. | ||
|
||
### `kind:90` | ||
|
||
todo I still need to think about this one |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right here seems to be the perfect spot to insert a description of the DLC messages' structure and encoding. Assuming you meant it this way, we should add a link to the DLC specifications to be explicit about what the
base64 contract details
, orbase64 oracle announcement
concretely encode.