# WireGuard Proxy for LongPort API (China Mainland Bypass)

## Problem
LongPort API blocks trading from mainland China IPs with error 602315:
> "Due to Mainland China regulatory requirements, you are currently located in Mainland China and cannot perform this action."

Read-only operations (quotes, positions) may still work, but order placement fails.

## Solution: WireGuard VPN with On-Demand Proxy

### Architecture
```
Server (China mainland) ──WireGuard──> VPS (HK/US/JP) ──> LongPort API
```

WireGuard is faster and more stable than application-layer proxies (Clash, V2Ray) because it operates at the kernel level.

### Setup Steps

#### 1. Install WireGuard
```bash
sudo apt update && sudo apt install -y wireguard resolvconf
```

#### 2. Get client config from WireGuard server
The user provides a config like:
```ini
[Interface]
PrivateKey = <key>
Address = 10.8.0.7/32
MTU = 1420
DNS = 1.1.1.1

[Peer]
PublicKey = <key>
PresharedKey = <key>
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Endpoint = wg.example.com:51820
```

#### 3. Install config
```bash
sudo cp /tmp/wg0.conf /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/wg0.conf
```

#### 4. Start WireGuard
```bash
sudo wg-quick up wg0
```

#### 5. Enable on boot
```bash
sudo systemctl enable wg-quick@wg0
```

#### 6. Verify
```bash
sudo wg show          # Check handshake
curl -s ifconfig.me   # Should show VPS IP, not mainland IP
```

### On-Demand Proxy Scripts

Instead of routing ALL traffic through VPN (slow), use on-demand scripts:

**`~/.local/bin/wg-trade`** — Run single command through VPN:
```bash
#!/bin/bash
# Usage: wg-trade <command>
CMD="$1"
shift
if [ -z "$1" ]; then
    echo "Usage: wg-trade <command>"
    exit 1
fi
if ! sudo wg show wg0 2>/dev/null | grep -q "latest handshake"; then
    echo "🔄 Starting WireGuard..."
    sudo wg-quick up wg0 2>/dev/null
fi
echo "🔒 Running via VPN: $@"
"$@"
```

**`~/.local/bin/wg-on`** / **`wg-off`** / **`wg-status`** — Toggle VPN:
```bash
#!/bin/bash
# wg-on: enable full VPN
sudo wg-quick up wg0 2>/dev/null
echo "✅ WireGuard ON — IP: $(curl -s --max-time 5 ifconfig.me)"

#!/bin/bash
# wg-off: disable VPN
sudo wg-quick down wg0 2>/dev/null
echo "❌ WireGuard OFF"

#!/bin/bash
# wg-status: check VPN status
if sudo wg show wg0 2>/dev/null | grep -q "latest handshake"; then
    echo "✅ WireGuard: Connected — VPN IP: $(curl -s --max-time 5 ifconfig.me)"
else
    echo "❌ WireGuard: Disconnected"
fi
```

Make executable: `chmod +x ~/.local/bin/wg-trade ~/.local/bin/wg-on ~/.local/bin/wg-off ~/.local/bin/wg-status`

### Usage with LongPort Trading

```bash
# Trade through VPN
wg-trade python3 ~/.hermes/scripts/rgti_auto_t.py status

# Or use Python SDK directly (WireGuard is already routing all traffic when up)
python3 -c "
import os
with open(os.path.expanduser('~/.bashrc')) as f:
    for line in f:
        line = line.strip()
        if line.startswith('export LONGBRIDGE_') or line.startswith('export LONGPORT_'):
            parts = line.replace('export ', '').split('=', 1)
            if len(parts) == 2:
                os.environ[parts[0]] = parts[1]

from longport import openapi
cfg = openapi.Config.from_env()
ctx = openapi.TradeContext(config=cfg)
resp = ctx.submit_order(
    symbol='SPCX.US',
    order_type=openapi.OrderType.LO,
    side=openapi.OrderSide.Buy,
    submitted_quantity=2,
    time_in_force=openapi.TimeInForceType.GoodTilCanceled,
    submitted_price=150.00,
    outside_rth=openapi.OutsideRTH.AnyTime,
)
print(f'Order ID: {resp.order_id}')
"
```

### Common WireGuard Commands
```bash
sudo wg-quick up wg0      # Start
sudo wg-quick down wg0    # Stop
sudo wg show              # Status (handshake, transfer)
sudo systemctl status wg-quick@wg0  # Service status
```

### Pitfalls
- **resolvconf not installed**: `wg-quick` fails with `resolvconf: command not found`. Fix: `sudo apt install -y resolvconf`
- **wg0 already exists**: If WireGuard was up and you try `wg-quick up wg0` again, it fails. Use `sudo wg show wg0` to check status, or `sudo wg-quick down wg0 && sudo wg-quick up wg0` to restart.
- **DNS leak**: With `AllowedIPs = 0.0.0.0/0`, DNS also goes through VPN. This is usually desired for geo-unblocking.
- **PersistentKeepalive**: Set to 25 for NAT traversal. Without it, idle tunnels may drop.
- **Speed**: WireGuard is kernel-level and fast, but still limited by VPS bandwidth. For non-trading traffic, consider split tunneling (only route LongPort IPs through VPN).
