mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-12-22 08:25:53 -05:00
feat(surv): update nip & use parameterized replaceable events for surv-answer
This commit is contained in:
parent
44a886e119
commit
1aa3ddf0e1
195
41.md
195
41.md
|
@ -1,69 +1,158 @@
|
||||||
NIP-XX
|
NIP-41
|
||||||
======
|
======
|
||||||
|
|
||||||
Surveys / polls
|
# Surveys / polls / quizzes
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
`draft` `optional` `require:nip-20` `author:fernandolguevara`
|
`draft` `optional` `require:nip-13` `require:nip-57` `author:fernandolguevara`
|
||||||
|
|
||||||
The `surv` & `surv-resp` tags enables users to have surveys/polls experiences on the network.
|
The `surv` tag & `surv-answer` (kind: `30041`) enables users to have surveys/polls/quizzes experiences on the network.
|
||||||
|
|
||||||
|
## Spec
|
||||||
|
|
||||||
#### Spec
|
### surv
|
||||||
|
|
||||||
##### Message
|
To start a survey on the network, an event with one or many 'surv' tags may be created.
|
||||||
|
|
||||||
```
|
|
||||||
tag: surv
|
|
||||||
options:
|
|
||||||
- <multi|single> allow others to reply with one or multiple options
|
|
||||||
- <ttl> TTL (in seconds|timestamp) when surv expires, 0 TTL don't expire
|
|
||||||
- [<choice>]: up to 4 choices each limited to 25 chars
|
|
||||||
````
|
|
||||||
|
|
||||||
```
|
|
||||||
tag: surv-resp
|
|
||||||
options:
|
|
||||||
- [<choice>]: based on surv type it can have one or multi
|
|
||||||
````
|
|
||||||
|
|
||||||
##### Relays
|
|
||||||
|
|
||||||
One vote per key, relays needs to discard all subsequent votes, as well as invalid requests.
|
|
||||||
|
|
||||||
##### Invalid responses
|
|
||||||
```json
|
```json
|
||||||
["OK", <event_id>, false, 'ALREADY_ANSWERED'],
|
{"tags":[
|
||||||
["OK", <event_id>, false, 'EXPIRED'],
|
["surv", "{single|multiple}", "ttl", "(label)", "option 1", "option 2", "option 3", "option 4"]
|
||||||
["OK", <event_id>, false, 'SINGLE_OPTION'],
|
["nonce", "1", "32"]
|
||||||
["OK", <event_id>, false, 'INVALID_OPTION', 'optionX', ...],
|
["amount", "milli-satoshi value"]
|
||||||
|
]}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example
|
#### tags
|
||||||
|
- `surv`:
|
||||||
|
- `{single|multiple}`: allow others to reply with single or multiple choice.
|
||||||
|
- `ttl:unix-time`: when survey expires, `0` don't expire.
|
||||||
|
- `(label):string`: if present, clients should use it as surv label.
|
||||||
|
- `option:string`: survey options
|
||||||
|
- `nonce`: if present, pow is mandatory for answer. ref: [13](13.md)
|
||||||
|
- `amount`: if present, zap is mandatory for answer. ref: [57](57.md)
|
||||||
|
|
||||||
|
### surv-answer
|
||||||
|
|
||||||
|
To reply to a survey on the network, an event of kind `30041` is created.
|
||||||
|
|
||||||
|
```meta
|
||||||
|
["surv-answer", "surv-index", "option-index", ...]
|
||||||
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"pubkey": "<pub-key>",
|
"kind": 30041,
|
||||||
"created_at": 1000000000,
|
"tags":[
|
||||||
"kind": 1,
|
["e", "<event-id-root>", "wss://...", "root"]
|
||||||
"tags": [
|
["d", "surv-answer/{event-id-root}"]
|
||||||
["t", "hastag"],
|
["surv-answer", "0", "option-index:int", "{...}"]
|
||||||
["surv", "<multi|single>", "<ttl>", "option 1", "option 2", "option 3"]
|
["nonce", "1", "32"],
|
||||||
],
|
["amount", "milli-satoshi value"],
|
||||||
"content": "#hastag what is your favorite option?",
|
]
|
||||||
"id": "<event-id>"
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"pubkey": "<pub-key>",
|
|
||||||
"created_at": 1000000000,
|
|
||||||
"kind": 1,
|
|
||||||
"tags": [
|
|
||||||
["p", "<pub-key-root>", "wss://..."],
|
|
||||||
["e", "<event-id-root>", "wss://...", "root"],
|
|
||||||
["t", "tag"],
|
|
||||||
["surv-resp", "option 1", "option 2"...] // based on root event surv type it can have one or multi
|
|
||||||
],
|
|
||||||
"content": "hello #tag\n",
|
|
||||||
"id": "<event-id>"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
at least one selected option index should present on the answer event the tag `surv-answer`
|
||||||
|
|
||||||
|
tags:
|
||||||
|
- `e`: `<event-id-root>` origin event.
|
||||||
|
- `d`: the value should be an string formed using origin `event-id-root` for the survey.
|
||||||
|
- `surv-answer`:
|
||||||
|
- `surv-index:int`: starting at 0.
|
||||||
|
- `option-index:int`: starting at 0.
|
||||||
|
- `nonce`: if present, pow is mandatory for answer.
|
||||||
|
- `amount`: if present, zap is mandatory for answer.
|
||||||
|
|
||||||
|
|
||||||
|
## Relay and client recommendations
|
||||||
|
- `surv` tag:
|
||||||
|
- Should have at least `two` options.
|
||||||
|
- The value of the `label` field should allow enough characters to express the questions.
|
||||||
|
- The `options` items should be limited up to 4.
|
||||||
|
- Each `option` should be 25 chars limited.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Example surv single
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 1,
|
||||||
|
"tags": [
|
||||||
|
["t", "hastag"],
|
||||||
|
["surv", "single", "0", "", "option 1", "option 2", "options 3"],
|
||||||
|
],
|
||||||
|
"content": "#hastag what is your favorite option?",
|
||||||
|
"id": "<event-id>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 30041,
|
||||||
|
"tags": [
|
||||||
|
["e", "<event-id-root>", "wss://...", "root"],
|
||||||
|
["t", "tag"],
|
||||||
|
["surv-answer", "", "0"]
|
||||||
|
],
|
||||||
|
"content": "here my favorite option is #option1 \n",
|
||||||
|
"id": "<event-id>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example surv multiple with expiration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 1,
|
||||||
|
"tags": [
|
||||||
|
["t", "hastag"],
|
||||||
|
["surv", "multiple", "1684599600"],
|
||||||
|
["options", "option 1", "option 2", "options 3"],
|
||||||
|
],
|
||||||
|
"content": "#hastag what are your favorite options?",
|
||||||
|
"id": "<event-id>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 30041,
|
||||||
|
"tags": [
|
||||||
|
["e", "<event-id-root>", "wss://...", "root"],
|
||||||
|
["t", "tag"],
|
||||||
|
["surv-answer", "", "0", "2"]
|
||||||
|
],
|
||||||
|
"content": "here my favorite option is #option1 \n",
|
||||||
|
"id": "<event-id>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### Example multiple surv
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 1,
|
||||||
|
"tags": [
|
||||||
|
["t", "hastag"],
|
||||||
|
["surv", "single", "0", "surv 1?", "option 1", "option 2", "options 3"],
|
||||||
|
["surv", "multiple", "0", "surv 2?", "option 1", "option 2", "options 3"],
|
||||||
|
],
|
||||||
|
"content": "#hastag Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do?",
|
||||||
|
"id": "<event-id>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pubkey": "<pub-key>",
|
||||||
|
"created_at": 1000000000,
|
||||||
|
"kind": 30041,
|
||||||
|
"tags": [
|
||||||
|
["e", "<event-id-root>", "wss://...", "root"],
|
||||||
|
["surv-answer", "0", "0"]
|
||||||
|
["surv-answer", "1", "0", "2"]
|
||||||
|
],
|
||||||
|
"content": "quis nostrud exercitation ullamco laboris!\n",
|
||||||
|
"id": "<event-id>"
|
||||||
|
}
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user