upleb.uk

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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Fernandez <p@f7z.io>2023-10-29 12:48:57 +0200
committerGitHub <noreply@github.com>2023-10-29 12:48:57 +0200
commit7a2de8ab25ceaa35376e6b7457f08b5bffde70b3 (patch)
tree84a8080b9ab75216ad273a5f4cc551bd240c697b
parentca73c5dd5ea19dec29a2781f1d3bd93ef95985f9 (diff)
parent435147149af83cbdbb7a183b9d8769ed1dbb717d (diff)
Merge pull request #682 from nostr-protocol/vending-machine
NIP-90: Data Vending Machines
-rw-r--r--90.md171
-rw-r--r--README.md5
2 files changed, 175 insertions, 1 deletions
diff --git a/90.md b/90.md
new file mode 100644
index 0000000..4c0eff6
--- /dev/null
+++ b/90.md
@@ -0,0 +1,171 @@
1NIP-90
2======
3
4Data Vending Machine
5--------------------
6
7`draft` `optional` `author:pablof7z` `author:dontbelievethehype`
8
9This NIP defines the interaction between customers and Service Providers for performing on-demand computation.
10
11Money in, data out.
12
13## Kinds
14This NIP reserves the range `5000-7000` for data vending machine use.
15
16| Kind | Description |
17| ---- | ----------- |
18| 5000-5999 | Job request kinds |
19| 6000-6999 | Job result |
20| 7000 | Job feedback |
21
22Job results always use a kind number that is `1000` higher than the job request kind. (e.g. request: `kind:5001` gets a result: `kind:6001`).
23
24Job request types are defined [separately](https://github.com/nostr-protocol/data-vending-machines/tree/master/kinds).
25
26## Rationale
27Nostr can act as a marketplace for data processing, where users request jobs to be processed in certain ways (e.g., "speech-to-text", "summarization", etc.), but they don't necessarily care about "who" processes the data.
28
29This NIP is not to be confused with a 1:1 marketplace; instead, it describes a flow where a user announces a desired output, willingness to pay, and service providers compete to fulfill the job requirement in the best way possible.
30
31### Actors
32There are two actors in the workflow described in this NIP:
33* Customers (npubs who request a job)
34* Service providers (npubs who fulfill jobs)
35
36## Job request (`kind:5000-5999`)
37A request to process data, published by a customer. This event signals that an customer is interested in receiving the result of some kind of compute.
38
39```json
40{
41 "kind": 5xxx, // kind in 5000-5999 range
42 "content": "",
43 "tags": [
44 [ "i", "<data>", "<input-type>", "<relay>", "<marker>" ],
45 [ "output", "<mime-type>" ],
46 [ "relays", "wss://..."],
47 [ "bid", "<msat-amount>" ],
48 [ "t", "bitcoin" ]
49 ]
50}
51```
52
53All tags are optional.
54
55* `i` tag: Input data for the job (zero or more inputs)
56 * `<data>`: The argument for the input
57 * `<input-type>`: The way this argument should be interpreted. MUST be one of:
58 * `url`: A URL to be fetched of the data that should be processed.
59 * `event`: A Nostr event ID.
60 * `job`: The output of a previous job with the specified event ID. The dermination of which output to build upon is up to the service provider to decide (e.g. waiting for a signaling from the customer, waiting for a payment, etc.)
61 * `text`: `<data>` is the value of the input, no resolution is needed
62 * `<relay>`: If `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string
63 * `<marker>`: An optional field indicating how this input should be used within the context of the job
64* `output`: Expected output format. Different job request `kind` defines this more precisely.
65* `param`: Optional parameters for the job as key (first argument)/value (second argument). Different job request `kind` defines this more precisely. (e.g. `[ "param", "lang", "es" ]`)
66* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay
67* `relays`: List of relays where Service Providers SHOULD publish responses to
68* `p`: Service Providers the customer is interested in. Other SPs MIGHT still choose to process the job
69
70## Job result (`kind:6000-6999`)
71
72Service providers publish job results, providing the output of the job result. They should tag the original job request event id as well as the customer's pubkey.
73
74```json
75{
76 "pubkey": "<service-provider pubkey>",
77 "content": "<payload>",
78 "kind": 6xxx,
79 "tags": [
80 [ "request", "<job-request>" ],
81 [ "e", "<job-request-id>", "<relay-hint>" ],
82 [ "i", "<input-data>" ],
83 [ "p", "<customer's-pubkey>" ],
84 [ "amount", "requested-payment-amount", "<optional-bolt11>" ]
85 ]
86}
87```
88
89* `request`: The job request event stringified-JSON.
90* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
91* `i`: The original input(s) specified in the request.
92
93## Job feedback
94Service providers can give feedback about a job back to the customer.
95
96```json
97{
98 "kind": 7000,
99 "content": "<empty-or-payload>",
100 "tags": [
101 [ "status", "<status>", "<extra-info>" ],
102 [ "amount", "requested-payment-amount", "<bolt11>" ],
103 [ "e", "<job-request-id>", "<relay-hint>" ],
104 [ "p", "<customer's-pubkey>" ],
105 ]
106}
107```
108
109* `content`: Either empty or a job-result (e.g. for partial-result samples)
110* `amount` tag: as defined in the [Job Result](#job-result) section.
111* `status` tag: Service Providers SHOULD indicate what this feedback status refers to. [Appendix 1](#appendix-1-job-feedback-status) defines status. Extra human-readable information can be added as an extra argument.
112
113### Job feedback status
114
115| status | description |
116|--------|-------------|
117| `payment-required` | Service Provider requires payment before continuing. |
118| `processing` | Service Provider is processing the job. |
119| `error` | Service Provider was unable to process the job. |
120| `success` | Service Provider successfully processed the job. |
121| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
122
123Any job feedback event MIGHT include results in the `.content` field, as described in the [Job Result](#job-result) section. This is useful for service providers to provide a sample of the results that have been processed so far.
124
125
126# Protocol Flow
127* Customer publishes a job request (e.g. `kind:5000` speech-to-text).
128* Service Providers MAY submit `kind:7000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
129* Upon completion, the service provider publishes the result of the job with a `kind:6000` job-result event.
130* At any point, if there is an `amount` pending to be paid as instructed by the service provider, the user can pay the included `bolt11` or zap the job result event the service provider has sent to the user
131
132Job feedback (`kind:7000`) and Job Results (`kind:6000-6999`) events MAY include an `amount` tag, this can be interpreted as a suggestion to pay. Service Providers MUST use the `payment-required` feedback event to signal that a payment is required and no further actions will be performed until the payment is sent.
133
134Customers can always either pay the included `bolt11` invoice or zap the event requesting the payment and service providers should monitor for both if they choose to include a bolt11 invoice.
135
136## Notes about the protocol flow
137The flow is deliberately ambiguous, allowing vast flexibility for the interaction between customers and service providers so that service providers can model their behavior based on their own decisions/perceptions of risk.
138
139Some service providers might choose to submit a `payment-required` as the first reaction before sending a `processing` or before delivering results, some might choose to serve partial results for the job (e.g. a sample), send a `payment-required` to deliver the rest of the results, and some service providers might choose to assess likelihood of payment based on an npub's past behavior and thus serve the job results before requesting payment for the best possible UX.
140
141It's not up to this NIP to define how individual vending machines should choose to run their business.
142
143# Cancellation
144A job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
145
146# Appendix 1: Job chaining
147A Customer MAY request multiple jobs to be processed as a chain, where the output of a job is the input of another job. (e.g. podcast transcription -> summarization of the transcription). This is done by specifying as input an event id of a different job with the `job` type.
148
149Service Providers MAY begin processing a subsequent job the moment they see the prior job's result, but they will likely wait for a zap to be published first. This introduces a risk that Service Provider of job #1 might delay publishing the zap event in order to have an advantage. This risk is up to Service Providers to mitigate or to decide whether the service provider of job #1 tends to have good-enough results so as to not wait for an explicit zap to assume the job was accepted.
150
151This gives a higher level of flexibility to service providers (which sophisticated service providers would take anyway).
152
153# Appendix 2: Service provider discoverability
154Service Providers MAY use NIP-89 announcements to advertise their support for job kinds:
155
156```json
157{
158 "kind": 31990,
159 "pubkey": "<pubkey>",
160 "content": "{
161 \"name\": \"Translating DVM\",
162 \"about\": \"I'm a DVM specialized in translating Bitcoin content.\"
163 }",
164 "tags": [
165 [ "k", 5005 ], // e.g. translation
166 [ "t", "bitcoin" ] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains"
167 ]
168}
169```
170
171Customers can use NIP-89 to see what service providers their follows use. \ No newline at end of file
diff --git a/README.md b/README.md
index e9f08bd..8044b24 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
67- [NIP-75: Zap Goals](75.md) 67- [NIP-75: Zap Goals](75.md)
68- [NIP-78: Application-specific data](78.md) 68- [NIP-78: Application-specific data](78.md)
69- [NIP-89: Recommended Application Handlers](89.md) 69- [NIP-89: Recommended Application Handlers](89.md)
70- [NIP-90: Data Vending Machines](90.md)
70- [NIP-94: File Metadata](94.md) 71- [NIP-94: File Metadata](94.md)
71- [NIP-98: HTTP Auth](98.md) 72- [NIP-98: HTTP Auth](98.md)
72- [NIP-99: Classified Listings](99.md) 73- [NIP-99: Classified Listings](99.md)
@@ -96,6 +97,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
96| `1984` | Reporting | [56](56.md) | 97| `1984` | Reporting | [56](56.md) |
97| `1985` | Label | [32](32.md) | 98| `1985` | Label | [32](32.md) |
98| `4550` | Community Post Approval | [72](72.md) | 99| `4550` | Community Post Approval | [72](72.md) |
100| `7000` | Job Feedback | [90](90.md) |
99| `9041` | Zap Goal | [75](75.md) | 101| `9041` | Zap Goal | [75](75.md) |
100| `9734` | Zap Request | [57](57.md) | 102| `9734` | Zap Request | [57](57.md) |
101| `9735` | Zap | [57](57.md) | 103| `9735` | Zap | [57](57.md) |
@@ -128,7 +130,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
128| `31989` | Handler recommendation | [89](89.md) | 130| `31989` | Handler recommendation | [89](89.md) |
129| `31990` | Handler information | [89](89.md) | 131| `31990` | Handler information | [89](89.md) |
130| `34550` | Community Definition | [72](72.md) | 132| `34550` | Community Definition | [72](72.md) |
131 133| `65000` | Job Feedback | [90](90.md) |
134| `65001` | Job Result | [90](90.md) |
132 135
133## Message types 136## Message types
134 137