Files
winning-wallet-finder/DEPLOY.md
T
gavindiaz 125470b24a sync: upstream + our customizations (dashboard, healthcheck, docs)
Synced from github/main: aebcfa2d copybot: live paper feed [skip ci]
Our additions: serve_dashboard.py, bot_dashboard.html, mihomo-healthcheck.sh,
中文文档, 我们的钱包配置
2026-07-21 07:35:48 +08:00

738 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```