2023-02-26 22:12:09 -05:00
# Poll event
2023-02-26 22:00:50 -05:00
2023-03-02 23:39:30 -05:00
`draft` `optional` `author:toadlyBroodle`
2023-03-02 22:39:26 -05:00
A poll note is a [nostr event ](01.md ) (kind `6969` ) for conducting paid polls. A poll presents two or more voting options, which participants my vote on by sending regular [zap events ](57.md ) which include an additional `poll_option` vote tag. Poll results may be blinded, until after users have voted. Polls may specify a `closed_at` time, after which results should be unblinded, closed to new votes, and the tally considered final. Poll options may be tallied by either satoshi `value` or vote `count` . Polls may additionally specify a `consensus_threshold` .
2023-02-27 01:04:03 -05:00
2023-02-26 22:00:50 -05:00
## Purpose
2023-02-26 22:12:09 -05:00
2023-03-02 05:30:39 -05:00
The purpose of poll notes is to conduct quantitative public opinion polls over nostr by requiring voters pay to participate. By tying vote amounts and counts to real satoshi valuations, nostr polls intend to provide superior signal compared to other free polling models. Imposing real monetary costs on participants should also discourage attempts at fraudulent result manipulation, by automated or other means.
2023-02-27 22:28:43 -05:00
2023-02-28 04:18:50 -05:00
## Poll format
2023-02-27 01:04:03 -05:00
2023-03-02 05:30:39 -05:00
A poll event:
* MUST contain a primary description string, specified in the `content` field
* MUST contain a predefined list of voting options, defined in a `poll_options` tag
* MUST include at least 2 voting options, each with its own unique description string
2023-03-02 05:38:22 -05:00
* MUST specify a primary `tally_method` : either `value` OR `count`
2023-03-02 05:30:39 -05:00
* SHOULD specify a `closed_at` time:
* a `closed_at` value of less than or equal to the `created_at` field indicates a poll SHOULD NOT be closed.
* MAY include a `consensus_threshold` integar (0-100), representing a percentage threshold for any single vote option to achieve poll consensus
* a `consensus_threshold` of '0' indicates no threshold is specified.
2023-03-01 23:41:40 -05:00
```json
{
2023-03-02 23:27:12 -05:00
"id": < 32-bytes lowercase hex-encoded sha256 of the serialized event data >
2023-03-01 23:41:40 -05:00
"pubkey": < 32-bytes lowercase hex-encoded public key of the event creator > ,
"created_at": < unix timestamp in seconds > ,
"kind": 6969,
"tags": [
["e", < 32-bytes hex of the id of another event > , < recommended relay URL > ],
["p", < 32-bytes hex of the key > , < recommended relay URL > ],
["poll_options": [
["0", < poll option 0 description string > ],
["1", < poll option 1 description string > ],
["n", < poll option n description string > ],
],
["tally_method", "value"||"count"],
2023-03-02 23:27:12 -05:00
["consensus_threshold", < integer ( 0 . . 100 ) > ],
2023-03-02 04:53:27 -05:00
["closed_at", < unix timestamp in seconds > ],
2023-03-01 23:41:40 -05:00
],
"content": < primary poll description string > ,
"sig": < 64-bytes hex of the signature of the sha256 hash of the serialized event data , which is the same as the " id " field >
}
```
2023-03-02 04:45:53 -05:00
## Zap vote format
2023-03-02 22:39:26 -05:00
Poll options are voted on by sending [zap events ](57.md ) (to the original poll event) which include 1 additional `poll_option` tag within their otherwise standard [json structure ](57.md#the-zap-note ).
2023-03-02 05:30:39 -05:00
Zap vote events (kind `9734` and `9735` ):
* MUST include exactly 1 `poll_option` tag
2023-03-02 23:27:12 -05:00
* MUST reference the vote option by its corresponding integer `n` , chosen from the original poll event's list of predefined `polling_options`
2023-03-02 07:21:18 -05:00
* MUST transmit the exact `poll_option` between kind `9734` and `9735`
2023-03-02 04:45:53 -05:00
```json
"tags": [
...
["poll_option", "n"],
...
]
```
2023-02-27 01:04:03 -05:00
2023-03-02 07:21:18 -05:00
## Poll outcome
To avoid ambiguity of results, strict adherence to the following rules is vital when tallying and rendering poll outcomes.
A tallying client:
* MUST tally poll results according to the primary `tally_method` specified:
* when tallying by `value` , clients:
* MUST include full satoshi values from all relevant zap events
* MUST include multiple zap events from single users
* MUST treat the vote option with the highest satoshi value as the winning option
* when tallying by `count` , clients:
* MUST ONLY count the most recent zap from a unique user as 1 vote
* MUST NOT include zapped satoshi values in the tally
* MUST NOT count votes from anonymous users
* MUST treat the vote option with the most unique votes as the winning option
* when a `closed_at` time is specified, clients:
2023-03-02 23:27:12 -05:00
* MUST NOT include late votes received after `closed_at` time
* SHOULD publicly blind results until after a user's vote has been received
2023-03-02 07:21:18 -05:00
* SHOULD publicly display results after the `closed_at` time has passed
* when a `closed_at` time is NOT specified (is less than or equal to `created_at` ), clients:
* SHOULD include all votes in tallies
* SHOULD treat the most recent tally as the definitive outcome
After the above rules are applied and clearly rendered, a tallying client:
* MUST display the distribution percentages, from the total, for each vote option
* if a non-zero `consensus_threshold` is specified, clients:
* MUST indicate the state of consensus by displaying its value relative to the final percentage of the winning vote
* MAY display the secondary tally method result, for statistical purposes, along with other associated poll metrics and comments
2023-02-27 01:04:03 -05:00
2023-03-02 23:27:12 -05:00
Strict adherence to these requirements should enable a standardized means of quantitatively assessing the distribution of opinion regarding a poll's content amongst poll participants, determining a winning outcome, and possibly achieving consensus. However, until this protocol is further tested, refined, and proven robust, polls should probably not be considered authoritative nor binding.
2023-02-27 01:04:03 -05:00
2023-02-26 22:00:50 -05:00
## TODO
2023-03-02 04:45:53 -05:00
* refine standardized polling formats based on dev feedback
2023-03-02 00:05:49 -05:00
* send pull request (RFC) to nostr-protocol/NIPs
2023-02-27 01:04:03 -05:00
* implement polls in 1 relay
* implement polls in 2 clients
* merge with nostr-protocol/NIPs