Reinstate NIP 88

This commit is contained in:
Abhay 2024-09-20 13:00:02 +05:30
parent b83b0c1602
commit 802d7ab132
2 changed files with 60 additions and 16 deletions

73
88.md
View File

@ -6,11 +6,6 @@
This NIP defines the event scheme that describe Polls on nostr. This NIP defines the event scheme that describe Polls on nostr.
The NIP makes the following tradeoffs.
1. All votes are public.
2. All votes are editable (latest response by timestamp considered last vote)
## Events ## Events
### Poll Event ### Poll Event
@ -24,34 +19,37 @@ Major tags in the poll event are:
- **option**: The option tags contain an OptionId(any alphanumeric) field, followed by an option label field. - **option**: The option tags contain an OptionId(any alphanumeric) field, followed by an option label field.
- **relay**: One or multiple tags that the poll is expecting respondents to respond on. - **relay**: One or multiple tags that the poll is expecting respondents to respond on.
- **polltype**: can be "singlechoice", "multiplechoice", or "rankedchoice". Polls that do not have a polltype should be considered a "singlechoice" poll. - **polltype**: can be "singlechoice", "multiplechoice", or "rankedchoice". Polls that do not have a polltype should be considered a "singlechoice" poll.
- **endsAt**: signifying at which unix timestamp the poll is meant to end.
Example Event Example Event
```json ```json
{ {
"content": "", "content": "Pineapple on pizza",
"created_at": 1719888496, "created_at": 1719888496,
"id": "9d1b6b9562e66f2ecf35eb0a3c2decc736c47fddb13d6fb8f87185a153ea3634", "id": "9d1b6b9562e66f2ecf35eb0a3c2decc736c47fddb13d6fb8f87185a153ea3634",
"kind": 1068, "kind": 1068,
"pubkey": "dee45a23c4f1d93f3a2043650c5081e4ac14a778e0acbef03de3768e4f81ac7b", "pubkey": "dee45a23c4f1d93f3a2043650c5081e4ac14a778e0acbef03de3768e4f81ac7b",
"sig": "7fa93bf3c430eaef784b0dacc217d3cd5eff1c520e7ef5d961381bc0f014dde6286618048d924808e54d1be03f2f2c2f0f8b5c9c2082a4480caf45a565ca9797", "sig": "7fa93bf3c430eaef784b0dacc217d3cd5eff1c520e7ef5d961381bc0f014dde6286618048d924808e54d1be03f2f2c2f0f8b5c9c2082a4480caf45a565ca9797",
"tags": [ "tags": [
["label", "Pineapple on Pizza"],
["option", "qj518h583", "Yay"], ["option", "qj518h583", "Yay"],
["option", "gga6cdnqj", "Nay"], ["option", "gga6cdnqj", "Nay"],
["relay", "<relay url1>"], ["relay", "<relay url1>"],
["relay", "<relay url2>"], ["relay", "<relay url2>"],
["polltype", "singlechoice"] ["polltype", "singlechoice"],
["endsAt", "<unix timestamp in seconds>"]
] ]
} }
``` ```
### Responses ### Responses
The response event is a `kind:30068` event. It contains a d tag with the poll event it is referencing, followed by one or more response tags. The response event is a `kind:1018` event. It contains an e tag with the poll event it is referencing, followed by one or more response tags.
- **response** : The tag contains "response" as it's first positional argument followed by the option Id selected. - **response** : The tag contains "response" as it's first positional argument followed by the option Id selected.
The responses are meant to be published to the relays specified in the poll event.
Example Response Event Example Response Event
```json ```json
@ -63,7 +61,7 @@ Example Response Event
"pubkey": "1bc70a0148b3f316da33fe7e89f23e3e71ac4ff998027ec712b905cd24f6a411", "pubkey": "1bc70a0148b3f316da33fe7e89f23e3e71ac4ff998027ec712b905cd24f6a411",
"sig": "30071a633c65db8f3a075c7a8de757fbd8ce65e3607f4ba287fe6d7fbf839a380f94ff4e826fbba593f6faaa13683b7ea9114ade140720ecf4927010ebf3e44f", "sig": "30071a633c65db8f3a075c7a8de757fbd8ce65e3607f4ba287fe6d7fbf839a380f94ff4e826fbba593f6faaa13683b7ea9114ade140720ecf4927010ebf3e44f",
"tags": [ "tags": [
["d", "1fc80cf813f1af33d5a435862b7ef7fb96b47e68a48f1abcadf8081f5a545550"], ["e", "1fc80cf813f1af33d5a435862b7ef7fb96b47e68a48f1abcadf8081f5a545550"],
["response", "gga6cdnqj"], ["response", "gga6cdnqj"],
["response", "m3agjsdq1"] ["response", "m3agjsdq1"]
] ]
@ -72,17 +70,60 @@ Example Response Event
### Poll Types ### Poll Types
Poll Types can be configured in the settings object of the poll, the setting dictates how multiple response tags are handled in the `kind:30068` event. The polltype setting dictates how multiple response tags are handled in the `kind:1018` event.
- **PollType: singlechoice**: The first response tag is to be considered the actual response. - **polltype: singlechoice**: The first response tag is to be considered the actual response.
- **PollType: multiplechoice**: The first response tag pointing to each id is considered the actual response, without considering the order of the response tags. - **polltype: multiplechoice**: The first response tag pointing to each id is considered the actual response, without considering the order of the response tags.
- **PollType: rankedchoice**: The first response tag pointing to each id is the considered the actual response, while also taking into account the order of the response tags. - **polltype: rankedchoice**: The first response tag pointing to each id is the considered the actual response, while also taking into account the order of the response tags.
### Counting Results ### Counting Results
Results can be queried by fetching `kind:30068` events from the relays specified in the poll. Results can be queried by fetching `kind:1018` events from the relays specified in the poll.
The results displayed should only be 1 vote event per pubkey. The results displayed should only be 1 vote event per pubkey.
In case of multiple events for a pubkey, the event with the largest timestamp should be considered. In case of multiple events for a pubkey, the event with the largest timestamp within the poll limits should be considered.
Example for querying polls.
```ts
const fetchVoteEvents = (filterPubkeys: string[]) => {
let resultFilter: Filter = {
"#e": [pollEvent.id],
kinds: [1070, 1018],
};
if (filterPubkeys?.length) {
resultFilter.authors = filterPubkeys;
}
if (pollExpiration) {
resultFilter.until = Number(pollExpiration);
}
poolRef.current.subscribeMany(relays, [resultFilter], {
onevent: handleResultEvent,
});
};
```
Example for maintaining OneVotePerPubkey
```ts
const oneVotePerPubkey = (events: Event[]) => {
const eventMap = new Map<string, Event>();
events.forEach((event) => {
if (
!eventMap.has(event.pubkey) ||
event.created_at > eventMap.get(event.pubkey)!.created_at
) {
eventMap.set(event.pubkey, event);
}
});
return Array.from(eventMap.values());
};
```
### Relays
It is advisable for the users to use relays that do not allow back dated events i.e. events with timestamp not matching the current time, to achieve authenticity in the poll results.
### Curation ### Curation

View File

@ -82,6 +82,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-75: Zap Goals](75.md) - [NIP-75: Zap Goals](75.md)
- [NIP-78: Application-specific data](78.md) - [NIP-78: Application-specific data](78.md)
- [NIP-84: Highlights](84.md) - [NIP-84: Highlights](84.md)
- [NIP-88: Polls](88.md)
- [NIP-89: Recommended Application Handlers](89.md) - [NIP-89: Recommended Application Handlers](89.md)
- [NIP-90: Data Vending Machines](90.md) - [NIP-90: Data Vending Machines](90.md)
- [NIP-92: Media Attachments](92.md) - [NIP-92: Media Attachments](92.md)
@ -118,11 +119,13 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `44` | Channel Mute User | [28](28.md) | | `44` | Channel Mute User | [28](28.md) |
| `64` | Chess (PGN) | [64](64.md) | | `64` | Chess (PGN) | [64](64.md) |
| `818` | Merge Requests | [54](54.md) | | `818` | Merge Requests | [54](54.md) |
| `1018` | Poll Response | [88](88.md) |
| `1021` | Bid | [15](15.md) | | `1021` | Bid | [15](15.md) |
| `1022` | Bid confirmation | [15](15.md) | | `1022` | Bid confirmation | [15](15.md) |
| `1040` | OpenTimestamps | [03](03.md) | | `1040` | OpenTimestamps | [03](03.md) |
| `1059` | Gift Wrap | [59](59.md) | | `1059` | Gift Wrap | [59](59.md) |
| `1063` | File Metadata | [94](94.md) | | `1063` | File Metadata | [94](94.md) |
| `1068` | Poll | [88](88.md) |
| `1311` | Live Chat Message | [53](53.md) | | `1311` | Live Chat Message | [53](53.md) |
| `1617` | Patches | [34](34.md) | | `1617` | Patches | [34](34.md) |
| `1621` | Issues | [34](34.md) | | `1621` | Issues | [34](34.md) |