-
Notifications
You must be signed in to change notification settings - Fork 620
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: DLC oracle announcement/attestation event kinds #1681
Open
conduition
wants to merge
5
commits into
nostr-protocol:master
Choose a base branch
from
conduition:oracles
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.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
c78872e
NIP-88: DLC oracle announcement/attestation event kinds
conduition 16b2142
add profile event for trusted oracle declarations
conduition 69f9ca6
add `n` tag
conduition db45537
Notes about pubkey validation
conduition 0d0097d
register event kinds in the readme
conduition 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,121 @@ | ||
NIP-88 | ||
====== | ||
|
||
Discreet Log Contract Oracles on Nostr | ||
----------------- | ||
|
||
`draft` `optional` | ||
|
||
This NIP describes two event kinds, `88` and `89`, for [Discreet Log Contract (DLC)](https://bitcoinops.org/en/topics/discreet-log-contracts/) oracles to publish their announcements and attestations over Nostr. Clients can consume these signed events to create conditional payment contracts which fulfill differently based on the oracles' attestations. | ||
|
||
## Format | ||
|
||
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. | ||
|
||
## 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": "BA/cNhCpdD25j/MwDaa4F42QIq8NsOGmaW1MxyswZnipGWirwoxPhL1SmoHcp1JuCjYXF...", | ||
"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." | ||
], | ||
|
||
// optional, if this is a numeric event for an asset pair | ||
["n", "BTC"], | ||
["n", "USD"] | ||
], | ||
"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 UTF-8 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. | ||
|
||
The optional `n` tag is described further down this document. | ||
|
||
Upon receiving an announcement event of kind `88`, clients _should_ validate: | ||
- the base64-encoded announcement data contains a copy of the correct oracle attestation pubkey. The oracle's attestation key may be distinct from the oracle's Nostr key. | ||
- the announcement is signed correctly by the expected oracle attestation pubkey. | ||
- [the event descriptor included in the announcement](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-event_descriptor-type) matches the tags in the `kind:88` event. | ||
|
||
### `kind:89` | ||
|
||
```jsonc | ||
{ | ||
"kind": 89, | ||
"content": "w7HSaUaPQn7Fa00PoUwTqkR2+wXHCPjD8Da5f4OcJ0EACsUw6uSdQgUDLLG9o/e9daS...", | ||
"tags": [ | ||
[ | ||
"e", // the Nostr event id of the announcement | ||
"30efed56a035b2549fcaeec0bf2c1595f9a9b3bb4b1a38abaf8ee9041c4b7d93", | ||
], | ||
|
||
// optional, if this is a numeric attestation for an asset pair | ||
["n", "BTC"], | ||
["n", "USD"] | ||
], | ||
"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: | ||
- the base64-encoded attestation data [contains a copy](https://github.com/discreetlogcontracts/dlcspecs/blob/master/Messaging.md#the-oracle_attestation-type) of the correct oracle attestation pubkey. This should be the same as the pubkey contained in the corresponding announcement event, of `kind:88`. | ||
- the `event_id` field inside the `oracle_attestation` object matches the `event_id` field in the original `oracle_announcement` object, referred to by the `e` tag. | ||
- the attestation signatures are valid under the oracle's attestation key. | ||
|
||
### The `n` Tag | ||
|
||
DLCs are often numeric events, in which the oracle signs the relative price of two assets. In this common case, kind `88` or `89` events may include exactly two `n` tags which indicate the ticker symbols of the assets whose relative value is being signed. | ||
|
||
The order of the tags implies a specific denomination of the price attestation: The attestation's outcome should be **the value of the first symbol in units of the second symbol.** For example, `[... ["n", "BTC"], ["n", "USD"]]` indicates the attestation supposedly signs the price of `BTC` in units of `USD`. | ||
|
||
### Oracle Pubkeys | ||
|
||
Oracles are responsible for choosing how to manage their attestation keypair(s). Oracle announcements and attestations embed their own copies of the oracle's BIP340 attestation public key. Oracles should ideally never change their attestation key pair between events, but they _may_ choose to migrate their attestation key, or use different keys for different types of events if they desire. Clients are responsible for choosing secure policies regarding which oracle attestation keys to trust and use. | ||
|
||
**By default, all clients must accept announcement/attestation signatures issued by the oracle's Nostr key.** This requirement allows oracles to fall back on using their Nostr key pair if managing multiple keys is unnecessary, or if their existing attestation key(s) become unusable. | ||
|
||
### `kind:10088` | ||
|
||
Kind `10088` lists a user's trusted oracles, for the purpose of 3rd party protocols negotating DLCs or DLC-adjacent conditional payment contracts with the user. A kind `10088` event contains one or more `s` tags with a oracle's Nostr pubkey, and one or more relays where that oracle's announcement events (`kind:88`) may be found. | ||
|
||
```jsonc | ||
{ | ||
"kind": 10088, | ||
"tags": [ | ||
["s", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://bitagent.prices"], | ||
// ... | ||
], | ||
//... | ||
} | ||
``` |
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
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.
Is it beneficial to include this in kind-89 since you can look up the kind-88 announcement using the
e
tag to get the same data? The use-case for querying announcements by asset pair makes sense, but I don't see the value in being able to query for attestations by asset pair.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.
I thought about this as well, but i believe @vitorpamplona wants to use these attestations for displaying current asset prices to users in GUI based on their "trusted oracle" list.
While technically you could do a two-step process as you say - first look up the announcement, then search for the corresponding attestation - it is easier and more efficient to look up attestations by asset, especially if the current price is all you care about.
Otherwise, you'd need to parse the announcements, find one that is supposed to have matured recently, and then find its corresponding attestation event.
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.
More background in this PR: #1658
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.
Ahh makes sense, thanks for the explanation!