This commit is contained in:
Your Name
2025-09-18 10:17:34 -04:00
parent 1b28f78f44
commit ecf248dfc2
4 changed files with 669 additions and 129 deletions

121
DAEMON.md
View File

@@ -31,48 +31,59 @@ I am Superball - an anonymizing node that provides location privacy for Nostr us
- Confirm the `p` tag contains my pubkey
- Ensure it's kind 22222
### 2. Decrypt
### 2. Decrypt and Identify Payload Type
- Use my private key with NIP-44 to decrypt the content
- Extract the payload which contains:
```json
{
"event": { /* The event to forward */ },
- Check payload structure to determine type:
"routing": { /* Superball Instructions */
"relays": ["wss://relay1.com", "wss://relay2.com"],
"delay": 30,
"padding": "+150", // or "-50"
"p": "next_superball_pubkey", // Optional - missing means final posting
"audit": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", // Required audit tag
"payment": "eCash_token" // Optional
}
#### Type 1: Routing Payload (Created by Builder)
```json
{
"event": { /* Final event or inner wrapped event */ },
"routing": { /* My routing instructions from builder */
"relays": ["wss://relay1.com", "wss://relay2.com"],
"delay": 30,
"p": "next_superball_pubkey", // Optional - missing means final posting
"audit": "audit_tag", // Required audit tag
"payment": "eCash_token", // Optional
"add_padding_bytes": 256 // Optional
}
```
}
```
### 3. Process Routing Instructions
#### Type 2: Padding Payload (Created by Previous Daemon)
```json
{
"event": { /* Still-encrypted inner event */ },
"padding": "01234567890123" // Padding data to discard
}
```
### 3. Handle Payload Type
#### If Padding Payload:
1. **Discard padding** - Ignore padding field completely
2. **Decrypt again** - The "event" field contains another encrypted payload
3. **Process the inner payload** - This will be a routing payload meant for me
#### If Routing Payload:
1. **Process routing instructions** - These were created by the builder specifically for me
2. **Continue with normal processing**
### 4. Process Routing Instructions
#### Delay
- Wait the specified number of seconds before forwarding
- Add random jitter (±10%) to prevent timing analysis
- Queue the event for delayed processing
#### Padding
- **Remove padding (`"padding": "-N"`)**: Delete N bytes worth of padding tags from the event
- **Add padding (`"padding": "+N"`)**: Create new routing wrapper with N bytes of padding tags
#### Relays
- Post to ALL relays in the `relays` array
- Validate all relay URLs are properly formatted
- Provides redundancy and availability
#### Next Hop Logic
- **`p` field present**: Create routing event for specified next Superball (can apply padding)
- **`p` field missing**: Extract inner event and post directly to relays (end chain, no padding changes)
#### Padding Logic
- **`p` field present + `padding` field**: Apply padding changes when creating routing wrapper
- **`p` field missing**: Ignore any `padding` field - cannot modify signed event
- **Final hop rule**: Never modify signed events, post exactly as received
- **`p` field present**: Forward to next Superball with padding-only wrapper
- **`p` field missing**: Post inner event directly to relays (end chain)
#### Audit Tag Processing
- **`audit` field**: Always present - include as `["p", "<audit_tag>"]` in routing event
@@ -83,30 +94,34 @@ I am Superball - an anonymizing node that provides location privacy for Nostr us
- **`payment` field present**: Process eCash token for service payment
- **`payment` field missing**: Process for free (if daemon allows)
### 4. Forward Event
### 5. Forward Event
#### Always Rewrap (Important for Privacy)
**ALWAYS** create a new routing event to hide whether padding was added or removed:
#### Two-Path Processing
**Path 1: Forward to Next Superball (`p` field present)**
- Create padding-only wrapper (never create routing instructions)
- Generate fresh ephemeral keypair
- Create padding payload:
```json
{
"kind": 22222, // Always use routing event
"pubkey": "<my_ephemeral_key>", // Generate fresh ephemeral key
"content": "<encrypted_inner_event>", // Re-encrypt with my key
"tags": [
["p", "<next_hop_or_final_destination>"],
["p", "<audit_tag_from_routing>"], // Always include audit tag as p tag
["padding", "<random_data_1>"], // Adjusted padding
["padding", "<random_data_2>"] // May be more or less than before
]
"event": { /* The still-encrypted inner event */ },
"padding": "random_padding_data_123456789"
}
```
- Encrypt to next Superball's pubkey
- Create routing event with next hop's pubkey in p tag
#### Next Hop Handling
- **If `p` field in routing**: Create routing event with that pubkey in p tag
- **If no `p` field in routing**: Extract inner event and post directly to all relays
- **Multi-relay posting**: Post to every relay in the `relays` array
- **End of chain**: When no `p` field, I am the final hop
**Path 2: Final Posting (`p` field missing)**
- Extract inner event from payload
- Post directly to all relays in routing.relays array
- No wrapping or encryption needed
- End of chain
#### Critical Rules
1. **Daemons NEVER create routing instructions** - Only padding
2. **Routing instructions come ONLY from the builder** - Pre-encrypted for each hop
3. **Always use fresh ephemeral keys** when forwarding
4. **Include audit tag** in routing event p tags for camouflage
## My Rules
@@ -144,11 +159,21 @@ I am Superball - an anonymizing node that provides location privacy for Nostr us
## Example Processing Flow
### Single Unwrapping (Routing Payload)
1. **Receive**: Kind 22222 event with my pubkey in p tag
2. **Decrypt**: Extract inner event + routing instructions
3. **Queue**: Schedule for delayed processing (e.g., 30 seconds + jitter)
4. **Process**: Apply padding changes and prepare for forwarding
5. **Forward**: Post to target relay(s)
6. **Clean**: Clear all decrypted data from memory
2. **Decrypt**: Get payload with routing instructions
3. **Process**: These routing instructions were created for me by builder
4. **Forward or Post**: Based on routing.p field
### Double Unwrapping (Padding Payload)
1. **Receive**: Kind 22222 event with my pubkey in p tag
2. **First Decrypt**: Get padding payload - discard padding
3. **Second Decrypt**: Decrypt the inner event to get my routing instructions
4. **Process**: These routing instructions were created for me by builder
5. **Forward or Post**: Based on routing.p field
### Clean Up
- **Queue**: Schedule for delayed processing (e.g., 30 seconds + jitter)
- **Clean**: Clear all decrypted data from memory after processing
I am a privacy-preserving relay that helps users post content while hiding their location. I ask no questions, store no logs, and remember nothing about the events that pass through me.