Files
winning-wallet-finder/DEPLOY.md
T

738 lines
22 KiB
Markdown
Raw Normal View History

# DEPLOY.md - 手动部署 paper + live copybot 到新服务器
> 一步一步来,可以一边看一边敲。不要一次性复制粘贴大段命令--每一步做完、看到预期输出,再进下一步。
>
> 适用:把 paper bot + live bot 部署到一台新的 Linux 服务器(Ubuntu/Debian),从你自己的 Gitea 拉代码。如果服务器在 Polymarket 禁单地区(美国/英国/法国等),用 mihomo 代理绕开 geo-block。
>
> 完成时间参考:60-90 分钟(含每步等待 + live 配置)。
>
> 完成部署后提供:
> - **paper bot**24/7 模拟跟单(直连,不走代理)
> - **live bot**24/7 真钱跟单(走代理绕 geo-block)
> - **bot 实时账本(中文 web dashboard**`http://服务器IP:18080/`
> - **原始 JSON**`https://<GITEA>/<USERNAME>/winning-wallet-finder/raw/branch/main/live/copybot_live.json`
---
## 目录
- [Part A: Paper Bot 部署](#part-a-paper-bot-部署) (§0-§13
- [Part B: 代理配置(geo-block 绕行)](#part-b-代理配置geo-block-绕行) (§14-§16
- [Part C: Live Bot 部署](#part-c-live-bot-部署) (§17-§23
- [常见坑](#常见坑)
- [日常命令](#日常用的命令)
---
# Part A: Paper Bot 部署
## 0. 前置条件
- [ ] 一台 Linux VPSUbuntu 20.04+ / Debian 11+
- [ ] 你有 root SSH 权限
- [ ] 你的 Gitea 上有这个仓库的镜像
- [ ] Gitea PAT(权限 `repository: Write`
测 Polymarket 直连:
```bash
python3 -c "
import urllib.request, time
for url in [
'https://data-api.polymarket.com/v1/leaderboard?limit=1',
'https://gamma-api.polymarket.com/markets?limit=1',
'https://clob.polymarket.com/markets?next_cursor=',
]:
t = time.time()
try:
urllib.request.urlopen(urllib.request.Request(url, headers={'User-Agent':'Mozilla/5.0'}), timeout=10)
print(f'OK {(time.time()-t)*1000:6.0f}ms {url}')
except Exception as e:
print(f'FAIL {type(e).__name__}: {url}')
"
```
三行 `OK` = 能读 APIpaper 够用)。
## 1. 装基础依赖
```bash
ssh root@你的服务器IP
apt-get update
apt-get install -y git python3 python3-pip ca-certificates
```
## 2. 从 Gitea 拉代码
```bash
cd /opt
git clone https://<USERNAME>:<TOKEN>@<GITEA>/<USERNAME>/winning-wallet-finder.git
cd winning-wallet-finder/live
```
## 3. 装 duckdb + 首次回测
```bash
pip3 install duckdb --break-system-packages
python3 portfolio.py --days 30
```
预期:`portfolio[30d rolling]: equity $... | ... | -> portfolio.json`
## 4. 前台测试 bot
```bash
python3 ../copybot.py --config copybot.paper.json --state copybot_state.json --poll 60
```
看到 `watching N wallets` + 2-3 条心跳后 `Ctrl+C`
## 5. 配 Gitea 凭证
### 5.1 生成 PAT
Gitea -> 用户设置 -> Applications -> Generate Token(权限 `repository: Write`
### 5.2 写 .netrc
```bash
nano ~/.netrc
```
```
machine <GITEA域名>
login <USERNAME>
password <TOKEN>
```
```bash
chmod 600 ~/.netrc
cd /opt/winning-wallet-finder
git push origin main --dry-run
```
### 5.3 root git 白名单
```bash
git config --global --add safe.directory /opt/winning-wallet-finder
```
## 6. 建专用用户 wwf
```bash
useradd --system --shell /usr/sbin/nologin --home /opt/winning-wallet-finder wwf
chown -R wwf:wwf /opt/winning-wallet-finder
chmod -R u+rwX,g+rX,o-rwx /opt/winning-wallet-finder
sudo cp /root/.netrc /opt/winning-wallet-finder/.netrc
sudo chown wwf:wwf /opt/winning-wallet-finder/.netrc
sudo chmod 600 /opt/winning-wallet-finder/.netrc
sudo -u wwf git config --global user.name "copybot[bot]"
sudo -u wwf git config --global user.email "copybot@wwf.local"
```
> **坑**wwf 没配 git identity 会导致 commit 报 `Author identity unknown`。上面最后两行不能漏。
## 7. 写 paper systemd unit
```bash
cat > /etc/systemd/system/copybot-paper.service <<'EOF'
[Unit]
Description=Polymarket Paper Copybot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=wwf
Group=wwf
WorkingDirectory=/opt/winning-wallet-finder/live
ExecStart=/usr/bin/python3 /opt/winning-wallet-finder/copybot.py \
--config /opt/winning-wallet-finder/live/copybot.paper.json \
--state /opt/winning-wallet-finder/copybot_state.json \
--poll 60
Restart=always
RestartSec=10
TimeoutStopSec=30
Nice=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=copybot-paper
EnvironmentFile=-/etc/copybot/paper.env
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
RestrictSUIDSGID=true
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
SystemCallArchitectures=native
ReadWritePaths=/opt/winning-wallet-finder
[Install]
WantedBy=multi-user.target
EOF
```
## 8. 启动 paper bot
```bash
systemctl daemon-reload
systemctl enable --now copybot-paper
sleep 5
systemctl status copybot-paper
```
## 9. 验证 Gitea 推送
```bash
cd /opt/winning-wallet-finder
sudo -u wwf git add -A
sudo -u wwf git commit -m "manual sync"
sudo -u wwf git push
```
## 10. 加 Alchemy RPC
```bash
sudo install -d -m 750 -o wwf -g wwf /etc/copybot
sudo tee /etc/copybot/paper.env > /dev/null <<EOF
ALCHEMY_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/你的KEY
EOF
sudo chown wwf:wwf /etc/copybot/paper.env
sudo chmod 600 /etc/copybot/paper.env
sudo systemctl restart copybot-paper
```
## 11. 加每日 cron
```bash
timedatectl | grep "Time zone"
# UTC 服务器 -> 北京 10:00 = cron 0 2
(crontab -l 2>/dev/null; echo "0 2 * * * cd /opt/winning-wallet-finder/live && bash daily.sh >> daily.log 2>&1") | crontab -
```
## 12. 部署 web dashboard
```bash
cat > /etc/systemd/system/copybot-dashboard.service <<'EOF'
[Unit]
Description=Polymarket Copybot Live Dashboard
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=wwf
Group=wwf
WorkingDirectory=/opt/winning-wallet-finder/live
ExecStart=/usr/bin/python3 /opt/winning-wallet-finder/live/serve_dashboard.py
Restart=always
RestartSec=5
Nice=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=copybot-dashboard
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
RestrictNamespaces=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now copybot-dashboard
sleep 3
curl -s http://localhost:18080/api/feed | python3 -m json.tool | head -10
```
浏览器访问 `http://服务器IP:18080/`。如果打不开,放行防火墙 TCP 18080。
## 13. Paper 完成检查
- [x] paper bot systemd 24/7 跑
- [x] web dashboard @ :18080
- [x] Alchemy RPC ON
- [x] 状态推 Gitea
- [x] 每日 cron
---
# Part B: 代理配置(geo-block 绕行)
> **为什么要代理**Polymarket 禁止美国/英国/法国/德国/意大利/荷兰/波兰/新加坡/澳大利亚/加拿大安大略/巴西 等地区的 IP 下单。如果你的服务器在这些地区,live bot 需要走代理。
>
> paper bot 不受影响(只读 API 全球开放)。
## 14. 检查 geo-gate
```bash
cd /opt/winning-wallet-finder
python3 host/geocheck.py
```
- `VERDICT: TRADABLE` -> 跳过 Part B,直接去 Part C
- `VERDICT: BLOCKED` -> 继续往下配代理
## 15. 装 mihomoClash Meta 内核)
### 15.1 下载 mihomo
```bash
mkdir -p /etc/mihomo
cd /tmp
wget -q https://github.com/MetaCubeX/mihomo/releases/download/v1.19.0/mihomo-linux-amd64-v1.19.0.gz
gzip -d mihomo-linux-amd64-v1.19.0.gz
mv mihomo-linux-amd64-v1.19.0 /usr/local/bin/mihomo
chmod +x /usr/local/bin/mihomo
mihomo -v
```
### 15.2 拉订阅配置
> **坑**:机场会检测 User-Agent,wget 默认 UA 会被返回假节点。必须伪装 UA。
```bash
wget -O /etc/mihomo/config.yaml \
--user-agent="clash-verge/v1.7.7" \
"你的订阅链接&flag=meta"
```
验证拿到的是真实节点(不是"当前Clash客户端不支持本机场协议"):
```bash
grep "name:" /etc/mihomo/config.yaml | grep -i "日本\|香港\|新加坡" | head -10
```
### 15.3 改全局模式 + 启动
```bash
sed -i 's/^mode: rule/mode: global/' /etc/mihomo/config.yaml
nohup mihomo -d /etc/mihomo > /var/log/mihomo.log 2>&1 &
sleep 5
# 选一个非美国节点(以日本为例)
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL \
-H "Content-Type: application/json" \
-d '{"name":"节点名"}'
# 验证
HTTPS_PROXY=http://127.0.0.1:7890 python3 host/geocheck.py
```
期望 `VERDICT: TRADABLE`
### 15.4 做 systemd 服务
```bash
kill $(pgrep mihomo)
cat > /etc/systemd/system/mihomo.service <<'EOF'
[Unit]
Description=Mihomo (Clash Meta) Proxy
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mihomo
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now mihomo
sleep 5
# 重选节点(mihomo 重启会记住,但第一次要手动选)
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL \
-H "Content-Type: application/json" \
-d '{"name":"节点名"}'
# 验证代理 + geo-gate
HTTPS_PROXY=http://127.0.0.1:7890 python3 host/geocheck.py | tail -1
```
> **mihomo 会记住节点选择**`cache.db` 持久化,重启不丢。
### 15.5 自动健康检查(节点挂了自动换)
```bash
cat > /opt/mihomo-healthcheck.sh <<'SCRIPT'
#!/bin/bash
API="http://127.0.0.1:9090"
PROXY="http://127.0.0.1:7890"
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY \
"https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
if [ "$code" = "200" ]; then exit 0; fi
nodes=$(curl -s "$API/proxies" | python3 -c "
import sys, json
d = json.load(sys.stdin)
skip = {'DIRECT','REJECT','自动选择','故障转移','良心云','GLOBAL'}
for name, info in d.get('proxies', {}).items():
if name in skip: continue
if info.get('type') in ('Selector','URLTest','Fallback','LoadBalance'): continue
if any(k in name for k in ['美国','US','United States']): continue
print(name)
")
for node in $nodes; do
curl -s -X PUT "$API/proxies/GLOBAL" -H "Content-Type: application/json" -d "{\"name\":\"$node\"}" > /dev/null
sleep 2
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -x $PROXY \
"https://clob.polymarket.com/markets?next_cursor=" 2>/dev/null)
if [ "$code" = "200" ]; then
logger "mihomo-healthcheck: switched to $node"
exit 0
fi
done
logger "mihomo-healthcheck: ALL nodes failed"
exit 1
SCRIPT
chmod +x /opt/mihomo-healthcheck.sh
(crontab -l 2>/dev/null | grep -v mihomo-healthcheck; echo "*/5 * * * * /opt/mihomo-healthcheck.sh") | crontab -
```
> **代理只影响 live bot**mihomo 监听 `127.0.0.1:7890`,不是透明代理。只有设了 `HTTPS_PROXY` 的程序才走代理。paper bot / dashboard / Gitea 全部直连,不受影响。
>
> **不要**把 `HTTPS_PROXY` 写进 `/etc/environment` 或 `~/.bashrc`(会全局生效),只放在 `/etc/copybot/live.env` 里。
---
# Part C: Live Bot 部署
> **真钱!** 每一步验证完再进下一步。建议先 $3-5 测试。
## 17. 装 live 依赖
```bash
pip3 install py-clob-client==0.34.6 web3==7.16.0 polymarket-client==0.1.0b16 websocket-client --break-system-packages
```
> **坑**`preflight_live.py` 需要 `polymarket-client`(不是 `py-clob-client`),漏装会报 `ModuleNotFoundError: No module named 'polymarket'`。
## 18. 准备钱包
### 18.1 钱包架构说明
Polymarket 2026 新架构有两套钱包系统:
```
你的私钥(MetaMask 导出)
|
+-- EOA 地址(MetaMask 本身)
+-- 代理钱包(邮箱登录自动创建,POLY_PROXY type=1
+-- 存款钱包(API 自动创建,POLY_1271 type=3<- bot 用这个
```
**bot 只能用存款钱包**。pUSD 在 EOA 或代理钱包里 bot 看不到。
### 18.2 用 MetaMask 登录(推荐,比邮箱简单)
1. 浏览器装 MetaMask,创建新钱包
2. 用 MetaMask 登录 polymarket.com
3. MetaMask -> 账户详情 -> 导出私钥
### 18.3 创建存款钱包
```bash
cd /opt/winning-wallet-finder
export HTTPS_PROXY=http://127.0.0.1:7890
export LIVE_PRIVATE_KEY=0x你的MetaMask私钥
python3 -c "
from polymarket import SecureClient
client = SecureClient.create(private_key='$LIVE_PRIVATE_KEY')
print('存款钱包:', client.wallet)
b = client.get_balance_allowance(asset_type='COLLATERAL')
print('pUSD 余额: \$' + str(b.balance / 1e6))
client.close()
"
```
> **坑(邮箱登录用户)**:如果用邮箱登录的私钥(Magic.link 导出),`SecureClient.create()` 会报 `Gasless transactions require a Builder API Key`。需要用 Builder API 凭证创建存款钱包:
> ```python
> bk = BuilderApiKey(key=..., secret=..., passphrase=...)
> client = SecureClient.create(private_key=pk, api_key=bk)
> ```
> Builder 凭证在 polymarket.com -> Settings -> API Keys 获取。创建完存款钱包后不再需要 Builder 凭证。
>
> **MetaMask 登录用户不受此影响**,存款钱包自动创建。
### 18.4 充值 USDC -> pUSD
**关键**:必须充到**存款钱包地址**,不是 MetaMask 地址。
1. 从交易所提 USDC 到 Polygon 链
2. 接收地址 = 步骤 18.3 打印的存款钱包地址
3. 到账后 USDC 自动转成 pUSD
> **坑**:充到 Polymarket 网站显示的充值地址(代理钱包)是错的,bot 在存款钱包里看不到。必须充到存款钱包地址。
### 18.5 验证余额
```bash
export HTTPS_PROXY=http://127.0.0.1:7890
export LIVE_PRIVATE_KEY=0x你的私钥
python3 -c "
from polymarket import SecureClient
client = SecureClient.create(private_key='$LIVE_PRIVATE_KEY')
b = client.get_balance_allowance(asset_type='COLLATERAL')
print('pUSD: \$' + str(b.balance / 1e6))
client.close()
"
```
## 19. 创建 config.live.json
```bash
cd /opt/winning-wallet-finder
cp config.live.example.json config.live.json
# 改 bankroll_usd 为实际 pUSD 余额
sed -i 's/"bankroll_usd": 22.28/"bankroll_usd": 你的余额/' config.live.json
chown wwf:wwf config.live.json
chmod 640 config.live.json
```
> **坑**config.live.json 是 root 创建的,wwf 用户读不了会报 `PermissionError`。必须 `chown wwf:wwf`。
## 20. 创建 live.env
```bash
cat > /etc/copybot/live.env <<'EOF'
LIVE_PRIVATE_KEY=0x你的MetaMask私钥
LIVE_FUNDER_ADDRESS=0x你的MetaMask地址
LIVE_SIGNATURE_TYPE=1
LIVE_CONFIRM=TRADE LIVE
HTTPS_PROXY=http://127.0.0.1:7890
EOF
chown wwf:wwf /etc/copybot/live.env
chmod 600 /etc/copybot/live.env
```
> **坑 1**`LIVE_CONFIRM` 的值必须是 `TRADE LIVE`copytrade.py:48 的 `CONFIRM_PHRASE`),不是 `I understand real money is at risk`。填错会报 `Aborted - LIVE_CONFIRM is set but does not match the phrase`。
>
> **坑 2**systemd EnvironmentFile 里值**不要加引号**。`LIVE_CONFIRM=TRADE LIVE` 是对的,`LIVE_CONFIRM="TRADE LIVE"` 会让值带引号导致不匹配。
>
> **坑 3**`HTTPS_PROXY` 只在 live.env 里设,不要放 paper.envpaper bot 不需要代理)。
## 21. 跑 preflight
```bash
cd /opt/winning-wallet-finder
export LIVE_PRIVATE_KEY=$(grep LIVE_PRIVATE_KEY /etc/copybot/live.env | cut -d= -f2-)
export LIVE_FUNDER_ADDRESS=$(grep LIVE_FUNDER_ADDRESS /etc/copybot/live.env | cut -d= -f2-)
export HTTPS_PROXY=http://127.0.0.1:7890
python3 preflight_live.py
```
全绿才能继续。常见失败:
- `ModuleNotFoundError: No module named 'websocket'` -> `pip3 install websocket-client`
- `Gasless transactions require a Builder API Key` -> 见 §18.3 邮箱登录的坑
- `Invalid private_key: 'ascii' codec can't encode` -> 私钥里有非 ASCII 字符(中文占位符没替换)
## 22. 写 live systemd unit
```bash
cat > /etc/systemd/system/copybot-live.service <<'EOF'
[Unit]
Description=Polymarket LIVE Copybot (real money)
After=network-online.target mihomo.service
Wants=network-online.target
Requires=mihomo.service
[Service]
Type=simple
User=wwf
Group=wwf
WorkingDirectory=/opt/winning-wallet-finder/live
ExecStart=/usr/bin/python3 /opt/winning-wallet-finder/copybot.py \
--config /opt/winning-wallet-finder/config.live.json \
--state /opt/winning-wallet-finder/copybot_state.live.json \
--poll 60 --live
Restart=always
RestartSec=10
TimeoutStopSec=30
Nice=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=copybot-live
EnvironmentFile=/etc/copybot/live.env
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
RestrictSUIDSGID=true
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
SystemCallArchitectures=native
ReadWritePaths=/opt/winning-wallet-finder
[Install]
WantedBy=multi-user.target
EOF
```
> `Requires=mihomo.service` + `After=mihomo.service`:代理先启动,live bot 才启动。
## 23. 启动 live bot
```bash
systemctl daemon-reload
systemctl enable --now copybot-live
sleep 10
journalctl -u copybot-live --since "15 seconds ago" --no-pager
```
预期看到:
```
geo-gate: TRADABLE - order endpoint reachable
LIVE MODE - this will place REAL orders with REAL money.
confirmed via LIVE_CONFIRM env - armed.
mode: LIVE - REAL MONEY
watching 5 wallets
```
### 清空 live state(如果出现 LEDGER DRIFT
```bash
systemctl stop copybot-live
rm -f /opt/winning-wallet-finder/copybot_state.live.json
rm -f /opt/winning-wallet-finder/copybot_fills.live.jsonl
rm -f /opt/winning-wallet-finder/live/copybot_live_real.json
systemctl start copybot-live
```
### 监控第一笔成交
```bash
journalctl -u copybot-live -f
```
看到 `FOLLOW` + `[LIVE] order placed` = 第一笔真钱成交。然后去 polymarket.com 用 MetaMask 登录确认仓位。
---
# 完整部署架构
```
服务器
|
+-- mihomo.service 代理(日本节点,127.0.0.1:7890
| +-- healthcheck cron 每 5 分钟自动换节点
|
+-- copybot-paper.service paper bot(直连,不走代理)
| +-- EnvironmentFile: paper.envALCHEMY_RPC_URL
| +-- state: copybot_state.json
| +-- feed: live/copybot_live.json
|
+-- copybot-live.service live bot(走代理绕 geo-block
| +-- EnvironmentFile: live.envLIVE_PRIVATE_KEY + HTTPS_PROXY + TRADE LIVE
| +-- state: copybot_state.live.json
| +-- feed: live/copybot_live_real.json
|
+-- copybot-dashboard.service web dashboard:18080
|
+-- cron 每日 02:00 UTC daily.sh
```
---
# 常见坑
| 坑 | 症状 | 解法 |
| --- | --- | --- |
| 没装 duckdb | `ModuleNotFoundError: No module named 'duckdb'` | `pip3 install duckdb --break-system-packages` |
| 没装 polymarket-client | `ModuleNotFoundError: No module named 'polymarket'` | `pip3 install polymarket-client==0.1.0b16` |
| 没装 websocket-client | preflight 报 `No module named 'websocket'` / 日志 `rtds off` | `pip3 install websocket-client` |
| wwf 没配 git identity | commit 报 `Author identity unknown` | §6 最后两行 |
| root 看不到 wwf 仓库 | `dubious ownership` | `git config --global --add safe.directory ...` |
| config.live.json 权限 | `PermissionError: [Errno 13]` | `chown wwf:wwf config.live.json` |
| LIVE_CONFIRM 值错 | `Aborted - LIVE_CONFIRM is set but does not match` | 值必须是 `TRADE LIVE`,不加引号 |
| 私钥有非 ASCII 字符 | `UnicodeEncodeError: 'ascii' codec can't encode` | env 文件里私钥必须是纯 hex(0x + 64 位),不能有中文占位符 |
| 邮箱登录建存款钱包失败 | `Gasless transactions require a Builder API Key` | 用 Builder API 凭证创建(§18.3),或改用 MetaMask 登录 |
| 充错钱包 | bot 余额 $0 | 必须充到存款钱包地址,不是 MetaMask 地址或网站充值地址 |
| geo-gate BLOCKED | `VERDICT: BLOCKED` | 服务器在禁单区,需配代理(Part B) |
| 机场返回假节点 | 节点名是"当前Clash客户端不支持" | wget 加 `--user-agent="clash-verge/v1.7.7"` + `&flag=meta` |
| mihomo 重启丢节点 | 出口 IP 变回美国 | mihomo cache.db 自动记忆;第一次需手动选节点 |
| LEDGER DRIFT | `check_book could not attribute it` | 清空 live state 重来(§23 |
| bot 不自动 commit | dashboard 数据陈旧 | commit-on-change 节流,无新交易不写;手动 commit 见 §9 |
| 浏览器 dashboard 不更新 | 数据没变 | `Ctrl+Shift+R` 强制刷新 |
| cron 时区错 | daily.sh 时间不对 | 服务器 UTC,北京 10:00 = cron `0 2` |
| 防火墙挡 18080 | 浏览器打不开 dashboard | 放行 TCP 18080 |
---
# 日常用的命令
```bash
# === 看日志 ===
journalctl -u copybot-paper -f # paper bot
journalctl -u copybot-live -f # live bot
journalctl -u copybot-dashboard -f # dashboard
journalctl -u mihomo -f # 代理
# === 看 dashboard ===
# 浏览器:http://服务器IP:18080/
# === 改配置 ===
nano /opt/winning-wallet-finder/live/copybot.paper.json # paper 跟单钱包/金额
sudo systemctl restart copybot-paper
nano /opt/winning-wallet-finder/config.live.json # live 跟单钱包/金额
sudo systemctl restart copybot-live
# === 代理管理 ===
# 看当前节点
curl -s http://127.0.0.1:9090/proxies/GLOBAL | python3 -c "import sys,json;print(json.load(sys.stdin).get('now'))"
# 换节点
curl -s -X PUT http://127.0.0.1:9090/proxies/GLOBAL -H "Content-Type: application/json" -d '{"name":"节点名"}'
# 手动健康检查
/opt/mihomo-healthcheck.sh
# === 停/启动 ===
sudo systemctl stop copybot-live # 停 live(真钱!)
sudo systemctl start copybot-live
sudo systemctl stop copybot-paper # 停 paper
sudo systemctl stop mihomo # 停代理(live 也会停)
# === 完全卸载 ===
sudo systemctl disable --now copybot-paper copybot-live copybot-dashboard mihomo
sudo rm /etc/systemd/system/copybot-*.service /etc/systemd/system/mihomo.service
sudo userdel wwf
rm -rf /opt/winning-wallet-finder
```