149 lines
4.6 KiB
Markdown
149 lines
4.6 KiB
Markdown
# HTTP Messages
|
|
|
|
A specification for sending/receiving HTTP messages (request/response) via a remote server. Header / Body etc are encrypted, either in the `content` (small messages) or via a blossom server (larger requests).
|
|
|
|

|
|
|
|
## Overview
|
|
|
|
Enables a local client to make and receive http requests (PUT, POST, GET, PATCH etc) from a remote computer. Requires:
|
|
|
|
* A trusted machine to process the messages (can be a home PC or Raspberry Pi)
|
|
* A relay (can be untrusted)
|
|
* A blossom server (can be untrusted)
|
|
|
|
|
|
## Architecture
|
|
|
|
```mermaid
|
|
architecture-beta
|
|
group user(internet)[Nostr Client]
|
|
group cloud(cloud)[Untrusted Servers]
|
|
group home(server)[Trusted Device]
|
|
service client(internet) in user
|
|
service blossom(database)[Blossom Storage] in cloud
|
|
service relay(logos:aws-ec2)[Relays] in cloud
|
|
service pc(logos:aws-elb) in home
|
|
service bbi[Big Bad Internet]
|
|
|
|
client:R -- L:blossom
|
|
client:B -- L:relay
|
|
pc:L -- R:blossom
|
|
pc:L -- R:relay
|
|
pc:B <--> T:bbi
|
|
|
|
```
|
|
|
|
## Sequence Diagram
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autoNumber
|
|
participant c as Nostr Client
|
|
participant r as Nostr Relay
|
|
participant b as Blossom Server
|
|
participant s as HTTP Server
|
|
|
|
Note over c: Convert <br>HTTP Request<br>into kind 21120
|
|
c-->>b: Encrypt & push payload (if large)
|
|
c->>r: Publish <br>Event
|
|
r<<-->>s: Fetch event
|
|
Note over s: Decrypt event
|
|
s<<-->>b: Fetch payload <br>(if large)
|
|
Note over s: Make HTTP REQUEST
|
|
Note over s: Get HTTP RESPONSE
|
|
s-->>b: Encrypt & push <br>payload (if large)
|
|
Note over s: Create kind<br>21120 (Response)
|
|
s->>r: Publish Event
|
|
r<<-->>c: Fetch event
|
|
Note over c: Decrypt event
|
|
b<<-->>c: Fetch payload (if large)
|
|
Note over c: Convert<br> kind 21120 into<br> HTTP Response
|
|
c-->>b: Delete REQUEST blob (if exists)
|
|
c->>r: Delete REQUEST event
|
|
|
|
```
|
|
|
|
The remote server should periodically scan for expired RESPONSE events (and associated blossom blobs) and delete them.
|
|
|
|
## Event Structure
|
|
|
|
Example **request** with a small payload. Payload is in `content` and `P` tag is the npub of the remote HTTP server.
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 21120,
|
|
"pubkey": "<pubkey>",
|
|
"content": "$encryptedPayload",
|
|
"tags": [
|
|
["p", "<pubkey of remote server>"], // P tag entry, this is a REQUEST
|
|
["key","nip44Encrypt($decryptkey)"],
|
|
["r", "https://relay.one"],
|
|
["expiration",<unix timestamp>]
|
|
],
|
|
// other fields...
|
|
}
|
|
```
|
|
|
|
Example **response** with a large payload. Valid JSON is in `content` and `E` tag is populated. For privacy, the requestor npub is NOT shown - the requestor instead should be fetching the response using the `E` tag.
|
|
|
|
```jsonc
|
|
{
|
|
"kind": 21120,
|
|
"pubkey": "<pubkey>",
|
|
"content": "encrypt({'url':'blossom.one','hash':'xx'},$decryptkey)",
|
|
"tags": [
|
|
["key","nip44Encrypt($decryptkey)"],
|
|
["E", "<request event id>"], // E tag entry, this is a RESPONSE
|
|
["expiration",<unix timestamp>]
|
|
],
|
|
// other fields...
|
|
}
|
|
```
|
|
|
|
Explanations:
|
|
|
|
* `kind:21120` - BIP39 word #1120 ([message](https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt#L1120)), plus 20,000 to be treated as ephemeral (not stored by relays).
|
|
* `"content"` - encrypted JSON with location of blob **OR** the content itself (if under a threshold). NIP-44 is NOT used as the payload may be large, affecting bunker signing stability.
|
|
* `"p"` - the pubkey of the remote HTTP server. Indicates that this is a REQUEST.
|
|
* `"key"` - the decryption key for the `content` field, also the key for the blossom blob (if used).
|
|
* `"E"` - ID of the request event. Enables a response to be identified, and fetched.
|
|
* `"expiration"` - remote servers should not process requests after this time. Relays SHOULD delete events after this time.
|
|
* `"r"` - (optional) relay on which the response should be sent. For Requests only.
|
|
|
|
|
|
## Considerations
|
|
|
|
This approach only makes sense in cases where privacy and anonymity are important, or if censorship is a concern.
|
|
|
|
There are a number of drawbacks to the approach:
|
|
|
|
- Complexity. Many more moving parts than a direct request.
|
|
- Speed. Each request/response now requires:
|
|
- Encrypting the payload
|
|
- Loading to blossom (if large)
|
|
- Signing event
|
|
- broadcasting event
|
|
- remote server fetching event
|
|
- remote server decrypting event
|
|
- remote server fetching blossom blob (if large)
|
|
- remote server decrypting blossom blob (if used)
|
|
- making the actual request
|
|
|
|
And the same flow in reverse.
|
|
|
|
So why would you use it? Several reasons:
|
|
|
|
- enables a plethora of open source apps to be made available from inside private networks (localhost) but over nostr
|
|
- maximum server privacy (no domain needed, or port forwarding)
|
|
- Make regular API calls over Nostr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|