Skip to content

Commit eec572f

Browse files
committed
Add Spec for Sovereign Backends
1 parent 0619f37 commit eec572f

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

N1.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Remote Procedure Calls over Nostr
2+
3+
NRPC defines a Remote Procedure Call (RPC) mechanism over Nostr events. Requests and responses are expressed as signed events and routed via relays. This enables backend services to be hosted without requiring inbound network access, cloud infrastructure, or centralized API management.
4+
5+
## Problems Addressed
6+
7+
Traditional backend services typically require:
8+
9+
- A publicly reachable server (static IP, port forwarding, or tunneling).
10+
11+
- Domain names and TLS termination.
12+
13+
- Centralized API key or token management.
14+
15+
This specification removes those requirements by using Nostr’s event transport. Services can operate with only outbound relay connections, authentication is inherent in event signatures, and requests and responses can be processed asynchronously.
16+
17+
## Specification
18+
19+
### Event Kinds
20+
21+
- Request Event: kind: 22068
22+
23+
- Response Event: kind: 22069
24+
25+
### Request Event (22068)
26+
27+
- Author: Caller’s pubkey.
28+
29+
- Tags:
30+
31+
```
32+
["p", "<callee_pubkey>"] — target service identity.
33+
34+
["method", "<method_name>"] — method to invoke.
35+
36+
["param", "<key>", "<value>"] — optional, repeatable parameters.
37+
```
38+
39+
- Content: optional payload
40+
41+
### Response Event (22069)
42+
43+
- Author: Callee’s pubkey.
44+
45+
- Tags:
46+
47+
```
48+
["e", "<request_event_id>"] — ID of the request being answered.
49+
50+
["p", "<caller_pubkey>"] — recipient of this response.
51+
52+
["status", "<http_status_code>"] — HTTP-style status code.
53+
```
54+
55+
On success:
56+
57+
```
58+
["result", "<key>", "<value>"] — repeatable.
59+
60+
["result_json", "<json_string>"] — optional structured payload.
61+
```
62+
63+
On error:
64+
65+
```
66+
["error", "<http_status_code>", "<message>"]
67+
```
68+
69+
- Content: optional payload (e.g., JSON string).
70+
71+
### Examples
72+
73+
Request Example
74+
75+
```
76+
{
77+
"kind": 22068,
78+
"tags": [
79+
[
80+
"p",
81+
"62a904c9c0e4ac1e221dc91202ee3bd98f6fd2460b619d953921108adda1af72"
82+
],
83+
[
84+
"method",
85+
"sendDM"
86+
]
87+
],
88+
"content": "",
89+
"created_at": 1758638576,
90+
"pubkey": "c21b1a6cdb247ccbd938dcb16b15a4fa382d00ffd7b12d5cbbad172a0cd4d170",
91+
"id": "aa05848fac18ecd4e0be17f4e041b808eb949963b03dd128ca7b9d610257639b",
92+
"sig": "8153860b5ddacceff0c89ff3d86c7e323f4e826f8415aa288d587c962ff7b209e40dace4199ff5edb21d69ab14f7f0d74328e36e48d06897d120418eaeec3e8b"
93+
}
94+
```
95+
96+
Response Example
97+
98+
```
99+
RESPONSE EVENT {
100+
kind: 22069,
101+
pubkey: '62a904c9c0e4ac1e221dc91202ee3bd98f6fd2460b619d953921108adda1af72',
102+
created_at: 1758640291,
103+
tags: [
104+
[
105+
'e',
106+
'af955bdb56977df2e0acd43791377cfcf671e334d4a5d5859af810e3c6a5cff6'
107+
],
108+
[
109+
'p',
110+
'c21b1a6cdb247ccbd938dcb16b15a4fa382d00ffd7b12d5cbbad172a0cd4d170'
111+
],
112+
[ 'status', '200' ],
113+
[ 'result_json', '{}' ]
114+
],
115+
content: '',
116+
id: 'ce1fa98bd61128beb2ba3f213086ece096eb75dc30b012d4bd2672f23415ae57',
117+
sig: '2647f1cad66d6a85752cbb1b07feb37077299c089bf5d1dbb79c0fd37b86ac54bbd09960d719c1b7afdcab103e148c30899b90d4367525dbb1be75f7c1c3de07',
118+
[Symbol(verified)]: true
119+
}
120+
```
121+
122+
## TODO
123+
124+
Work out a protocol, for encrypted requests and responses, it will be similar to NIP-17 using NIP-59 Giftwraps, but an implementation is still WIP.

0 commit comments

Comments
 (0)