3.8 KiB
NIP-20
Command Results
draft
optional
author:jb55
depends:01
When submitting events to relays, clients currently have no way to know if an event was successfully committed to the database. This NIP introduces the concept of command results which are like NOTICE's except provide more information about if an event was accepted or rejected.
A command result is a JSON object with the following structure that is returned when an event is successfully saved to the database or rejected:
["OK", <event_id>, <true|false>, <message>]
Relays MUST return true
when the event is a duplicate and has already been saved. The message
SHOULD start with duplicate:
in this case.
Relays MUST return false
when the event was rejected and not saved.
The message
SHOULD provide additional information as to why the command succeeded or failed.
The message
SHOULD start with blocked:
if the pubkey or network address has been blocked, banned, or is not on a whitelist.
The message
SHOULD start with invalid:
if the event is invalid or doesn't meet some specific criteria (created_at is too far off, id is wrong, signature is wrong, etc)
The message
SHOULD start with pow:
if the event doesn't meet some proof-of-work difficulty. The client MAY consult the relay metadata at this point to retrieve the required posting difficulty.
The message
SHOULD start with rate-limited:
if the event was rejected due to rate limiting techniques.
The message
SHOULD start with error:
if the event failed to save due to a server issue.
Ephemeral events are not acknowledged with OK responses, unless there is a failure.
If the event or EVENT
command is malformed and could not be parsed, a NOTICE message SHOULD be used instead of a command result. This NIP only applies to non-malformed EVENT commands.
Examples
Event successfully written to the database:
["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", true, ""]
Event successfully written to the database because of a reason:
["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", true, "pow: difficulty 25>=24"]
Event blocked due to ip filter
["OK", "b1a649ebe8...", false, "blocked: tor exit nodes not allowed"]
Event blocked due to pubkey ban
["OK", "b1a649ebe8...", false, "blocked: you are banned from posting here"]
Event blocked, pubkey not registered
["OK", "b1a649ebe8...", false, "blocked: please register your pubkey at https://my-expensive-relay.example.com"]
Event rejected, rate limited
["OK", "b1a649ebe8...", false, "rate-limited: slow down there chief"]
Event rejected, created_at
too far off
["OK", "b1a649ebe8...", false, "invalid: event creation date is too far off from the current time. Is your system clock in sync?"]
Event rejected, insufficient proof-of-work difficulty
["OK", "b1a649ebe8...", false, "pow: difficulty 26 is less than 30"]
Event failed to save,
["OK", "b1a649ebe8...", false, "error: could not connect to the database"]
Client Handling
messages
are meant for humans, with reason:
prefixes so that clients can be slightly more intelligent with what to do with them. For example, with a rate-limited:
reason the client may not show anything and simply try again with a longer timeout.
For the pow:
prefix it may query relay metadata to get the updated difficulty requirement and try again in the background.
For the invalid:
and blocked:
prefix the client may wish to show these as styled error popups.
The prefixes include a colon so that the message can be cleanly separated from the prefix by taking everything after :
and trimming it.
Future Extensions
This proposal SHOULD be extended to support further commands in the future, such as REQ and AUTH. They are left out of this initial version to keep things simpler.