# 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", "<my_pubkey>"]`
- These are events meant for me to process

### 2. Event Structure I Expect
```json
{
  "kind": 22222,
  "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 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", "<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 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.