upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--88.md130
-rw-r--r--README.md3
2 files changed, 133 insertions, 0 deletions
diff --git a/88.md b/88.md
new file mode 100644
index 0000000..08f5c41
--- /dev/null
+++ b/88.md
@@ -0,0 +1,130 @@
1# NIP-88
2
3## Polls
4
5`draft` `optional`
6
7This NIP defines the event scheme that describe Polls on nostr.
8
9## Events
10
11### Poll Event
12
13The poll event is defined as a `kind:1068` event.
14
15- **content** key holds the label for the poll.
16
17Major tags in the poll event are:
18
19- **option**: The option tags contain an OptionId(any alphanumeric) field, followed by an option label field.
20- **relay**: One or multiple tags that the poll is expecting respondents to respond on.
21- **polltype**: can be "singlechoice" or "multiplechoice". Polls that do not have a polltype should be considered a "singlechoice" poll.
22- **endsAt**: signifying at which unix timestamp the poll is meant to end.
23
24Example Event
25
26```json
27{
28 "content": "Pineapple on pizza",
29 "created_at": 1719888496,
30 "id": "9d1b6b9562e66f2ecf35eb0a3c2decc736c47fddb13d6fb8f87185a153ea3634",
31 "kind": 1068,
32 "pubkey": "dee45a23c4f1d93f3a2043650c5081e4ac14a778e0acbef03de3768e4f81ac7b",
33 "sig": "7fa93bf3c430eaef784b0dacc217d3cd5eff1c520e7ef5d961381bc0f014dde6286618048d924808e54d1be03f2f2c2f0f8b5c9c2082a4480caf45a565ca9797",
34 "tags": [
35 ["option", "qj518h583", "Yay"],
36 ["option", "gga6cdnqj", "Nay"],
37 ["relay", "<relay url1>"],
38 ["relay", "<relay url2>"],
39 ["polltype", "singlechoice"],
40 ["endsAt", "<unix timestamp in seconds>"]
41 ]
42}
43```
44
45### Responses
46
47The 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.
48
49- **response** : The tag contains "response" as it's first positional argument followed by the option Id selected.
50
51The responses are meant to be published to the relays specified in the poll event.
52
53Example Response Event
54
55```json
56{
57 "content": "",
58 "created_at": 1720097117,
59 "id": "60a005e32e9596c3f544a841a9bc4e46d3020ca3650d6a739c95c1568e33f6d8",
60 "kind": 1018,
61 "pubkey": "1bc70a0148b3f316da33fe7e89f23e3e71ac4ff998027ec712b905cd24f6a411",
62 "sig": "30071a633c65db8f3a075c7a8de757fbd8ce65e3607f4ba287fe6d7fbf839a380f94ff4e826fbba593f6faaa13683b7ea9114ade140720ecf4927010ebf3e44f",
63 "tags": [
64 ["e", "1fc80cf813f1af33d5a435862b7ef7fb96b47e68a48f1abcadf8081f5a545550"],
65 ["response", "gga6cdnqj"],
66 ["response", "m3agjsdq1"]
67 ]
68}
69```
70
71### Poll Types
72
73The polltype setting dictates how multiple response tags are handled in the `kind:1018` event.
74
75- **polltype: singlechoice**: The first response tag is to be considered the actual response.
76- **polltype: multiplechoice**: The first response tag pointing to each id is considered the actual response, without considering the order of the response tags.
77
78### Counting Results
79
80Results can be queried by fetching `kind:1018` events from the relays specified in the poll.
81The results displayed should only be 1 vote event per pubkey.
82In case of multiple events for a pubkey, the event with the largest timestamp within the poll limits should be considered.
83
84Example for querying polls.
85
86```ts
87const fetchVoteEvents = (filterPubkeys: string[]) => {
88 let resultFilter: Filter = {
89 "#e": [pollEvent.id],
90 kinds: [1018],
91 };
92 if (filterPubkeys?.length) {
93 resultFilter.authors = filterPubkeys;
94 }
95 if (pollExpiration) {
96 resultFilter.until = Number(pollExpiration);
97 }
98 pool.subscribeMany(relays, [resultFilter], {
99 onevent: handleResultEvent,
100 });
101};
102```
103
104Example for maintaining OneVotePerPubkey
105
106```ts
107const oneVotePerPubkey = (events: Event[]) => {
108 const eventMap = new Map<string, Event>();
109
110 events.forEach((event) => {
111 if (
112 !eventMap.has(event.pubkey) ||
113 event.created_at > eventMap.get(event.pubkey)!.created_at
114 ) {
115 eventMap.set(event.pubkey, event);
116 }
117 });
118
119 return Array.from(eventMap.values());
120};
121```
122
123### Relays
124
125It is advisable for poll authors to use relays that do not allow backdated events and do not honor kind:5 (delete) requests for vote events in order to maintain the integrity of poll results after the poll has ended.
126
127### Curation
128
129The clients may configure fetching results by specific people. This can be achieved by creating `kind:30000` follow sets, and fetching results only from the follow set.
130Clients can also employ other curation algorithms, like Proof Of Work and Web of Trust scores for result curations.
diff --git a/README.md b/README.md
index ed8336c..91d3c67 100644
--- a/README.md
+++ b/README.md
@@ -89,6 +89,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
89- [NIP-78: Application-specific data](78.md) 89- [NIP-78: Application-specific data](78.md)
90- [NIP-84: Highlights](84.md) 90- [NIP-84: Highlights](84.md)
91- [NIP-86: Relay Management API](86.md) 91- [NIP-86: Relay Management API](86.md)
92- [NIP-88: Polls](88.md)
92- [NIP-89: Recommended Application Handlers](89.md) 93- [NIP-89: Recommended Application Handlers](89.md)
93- [NIP-90: Data Vending Machines](90.md) 94- [NIP-90: Data Vending Machines](90.md)
94- [NIP-92: Media Attachments](92.md) 95- [NIP-92: Media Attachments](92.md)
@@ -128,11 +129,13 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
128| `44` | Channel Mute User | [28](28.md) | 129| `44` | Channel Mute User | [28](28.md) |
129| `64` | Chess (PGN) | [64](64.md) | 130| `64` | Chess (PGN) | [64](64.md) |
130| `818` | Merge Requests | [54](54.md) | 131| `818` | Merge Requests | [54](54.md) |
132| `1018` | Poll Response | [88](88.md) |
131| `1021` | Bid | [15](15.md) | 133| `1021` | Bid | [15](15.md) |
132| `1022` | Bid confirmation | [15](15.md) | 134| `1022` | Bid confirmation | [15](15.md) |
133| `1040` | OpenTimestamps | [03](03.md) | 135| `1040` | OpenTimestamps | [03](03.md) |
134| `1059` | Gift Wrap | [59](59.md) | 136| `1059` | Gift Wrap | [59](59.md) |
135| `1063` | File Metadata | [94](94.md) | 137| `1063` | File Metadata | [94](94.md) |
138| `1068` | Poll | [88](88.md) |
136| `1111` | Comment | [22](22.md) | 139| `1111` | Comment | [22](22.md) |
137| `1311` | Live Chat Message | [53](53.md) | 140| `1311` | Live Chat Message | [53](53.md) |
138| `1617` | Patches | [34](34.md) | 141| `1617` | Patches | [34](34.md) |