# Thrower Rules ## What I Am I am a Thrower - an anonymizing node that provides location privacy for Nostr users by catching, unwrapping, rewrapping and throwing Superballs (wrapped encrypted events) with timing delays and size obfuscation. ## What I Look For ### 1. Routing Events (Kind 22222) - Monitor all relays I'm connected to - Look for events with `kind: 22222` - Check if `tags` contains `["p", ""]` - These are events meant for me to process ### 2. Event Structure I Expect ```json { "kind": 22222, "pubkey": "", // Not important to me "content": "", // This is what I need "tags": [["p", ""]], "created_at": , "id": "", "sig": "" } ``` ## 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 22222 ### 2. Decrypt and Identify Payload Type - Use my private key with NIP-44 to decrypt the content - Check payload structure to determine type: #### 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_thrower_pubkey", // Optional - missing means final posting "audit": "audit_tag", // Required audit tag "payment": "eCash_token", // Optional "add_padding_bytes": 256 // Optional } } ``` #### Type 2: Padding Payload (Created by Previous Thrower) ```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 #### Relays - Post to ALL relays in the `relays` array that don't require AUTH - Skip AUTH-required relays when posting final events (can't authenticate as original author) - Validate all relay URLs are properly formatted - Provides redundancy and availability within AUTH constraints #### Next Hop Logic - **`p` field present**: Forward to next Thrower 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", ""]` 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 payment - **`payment` field missing**: Process for free (if thrower allows) ### 5. Forward Event #### Two-Path Processing **Path 1: Forward to Next Thrower (`p` field present)** - Create padding-only wrapper (never create routing instructions) - Generate fresh ephemeral keypair - Create padding payload: ```json { "event": { /* The still-encrypted inner event */ }, "padding": "random_padding_data_123456789" } ``` - Encrypt to next Thrower's pubkey - Create routing event with next hop's pubkey in p tag **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. **Throwers 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 ### Security Rules 1. **Never log sensitive data** - Don't store decrypted content or routing info 2. **Generate new keys** - Use fresh ephemeral keys for each forward 3. **Validate everything** - Check signatures, event structure, relay URLs ### Privacy Rules 1. **No correlation** - Don't link input events to output events in logs 2. **Clear memory** - Immediately clear decrypted data after processing ### Processing Rules 1. **First come, first served** - Process events in order received 2. **Fail silently** - Drop invalid events without response 3. **Retry logic** - Attempt to post 3 times before giving up 4. **Resource limits** - Drop oldest queued events if memory/queue full ### Network Rules 1. **Multiple relays** - Connect to diverse set of relays 2. **Separate connections** - Use different connections for input/output 3. **AUTH constraint** - Can only write to relays that do NOT require AUTH (since I post events I didn't sign) 4. **Read capability** - Can read from any relay (AUTH or non-AUTH) to monitor for Superballs 5. **NIP-65 compliance** - Maintain accurate relay list marking read-only vs write-capable relays 6. **Authentication testing** - Regularly test relays to determine AUTH requirements 7. **Rotate connections** - Periodically reconnect to prevent fingerprinting ## What I Never Do 1. **Never modify final signatures** - Only remove padding tags, never add to signed events 2. **Never store routing paths** - Process and forget 3. **Never respond to clients** - Silent operation only 4. **Never correlate users** - Each Superball is independent 5. **Never log destinations** - Only log operational metrics ## Example Processing Flow ### Single Unwrapping (Routing Payload) 1. **Receive**: Kind 22222 event with my pubkey in p tag 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 Thrower that helps users post content while hiding their location. I ask no questions, store no logs, and remember nothing about the Superballs that pass through me.