5.8 KiB
5.8 KiB
Superball Daemon Rules
What I Am
I am Superball - an anonymizing node that provides location privacy for Nostr users by forwarding their encrypted events with timing delays and size obfuscation.
What I Look For
1. Routing Events (Kind 30000)
- Monitor all relays I'm connected to
- Look for events with
kind: 30000
- Check if
tags
contains["p", "<my_pubkey>"]
- These are events meant for me to process
2. Event Structure I Expect
{
"kind": 30000,
"pubkey": "<some_ephemeral_key>", // Not important to me
"content": "<nip44_encrypted_payload>", // This is what I need
"tags": [["p", "<my_pubkey>"]],
"created_at": <timestamp>,
"id": "<event_id>",
"sig": "<signature>"
}
What I Do When I Receive An Event
1. Validate
- Verify the event signature is valid
- Confirm the
p
tag contains my pubkey - Ensure it's kind 30000
2. Decrypt
- Use my private key with NIP-44 to decrypt the content
- Extract the payload which contains:
{ "event": { /* The event to forward */ }, "routing": { "relays": ["wss://relay1.com", "wss://relay2.com"], "delay": 30, "pad": "+150", // or "-50" "p": "next_superball_pubkey", // Optional - missing means final posting "audit": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456", // Required audit tag "payment": "eCash_token" // Optional } }
3. 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 (
"pad": "-N"
): Delete N bytes worth of padding tags from the event - Add padding (
"pad": "+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 +pad
field: Apply padding changes when creating routing wrapperp
field missing: Ignore anypad
field - cannot modify signed event- Final hop rule: Never modify signed events, post exactly as received
Audit Tag Processing
audit
field: Always present - include as["p", "<audit_tag>"]
in routing event- Camouflage: Audit tag looks identical to real next-hop pubkeys
- Security: Enables user detection of dropped/delayed/modified events
Payment Processing
payment
field present: Process eCash token for service paymentpayment
field missing: Process for free (if daemon allows)
4. Forward Event
Always Rewrap (Important for Privacy)
ALWAYS create a new routing event to hide whether padding was added or removed:
{
"kind": 30000, // 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
]
}
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
My Rules
Security Rules
- Never log sensitive data - Don't store decrypted content or routing info
- Generate new keys - Use fresh ephemeral keys for each forward
- Validate everything - Check signatures, event structure, relay URLs
- Rate limiting - Don't process more than X events per minute from same source
Privacy Rules
- No correlation - Don't link input events to output events in logs
- Clear memory - Immediately clear decrypted data after processing
- Random timing - Add jitter to specified delays
- Mix traffic - Send decoy traffic when idle (optional)
Processing Rules
- First come, first served - Process events in order received
- Fail silently - Drop invalid events without response
- Retry logic - Attempt to post 3 times before giving up
- Resource limits - Drop oldest queued events if memory/queue full
Network Rules
- Multiple relays - Connect to diverse set of relays
- Separate connections - Use different connections for input/output
- AUTH support - Prefer relays that support AUTH for privacy
- Rotate connections - Periodically reconnect to prevent fingerprinting
What I Never Do
- Never modify final signatures - Only remove padding tags, never add to signed events
- Never store routing paths - Process and forget
- Never respond to clients - Silent operation only
- Never correlate users - Each event is independent
- Never log destinations - Only log operational metrics
Example Processing Flow
- Receive: Kind 30000 event with my pubkey in p tag
- Decrypt: Extract inner event + routing instructions
- Queue: Schedule for delayed processing (e.g., 30 seconds + jitter)
- Process: Apply padding changes and prepare for forwarding
- Forward: Post to target relay(s)
- Clean: Clear all decrypted data from memory
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.