Files
winning-wallet-finder/云端架构.md
T

204 lines
9.7 KiB
Markdown
Raw Normal View History

## 全局地图
```
服务器
├── /opt/winning-wallet-finder/ ← 项目代码(git clone 来的)
│ ├── copybot.py ← bot 主程序
│ ├── copybot.paper.json ← paper 配置(跟哪些钱包、金额)
│ ├── config.live.json ← live 配置(跟哪些钱包、金额)
│ ├── copybot_state.json ← paper bot 的账本(自动生成)
│ ├── copybot_state.live.json ← live bot 的账本(自动生成)
│ ├── copybot_fills.jsonl ← paper 成交记录
│ ├── copybot_fills.live.jsonl ← live 成交记录
│ └── live/
│ ├── serve_dashboard.py ← 网页 dashboard 程序
│ ├── bot_dashboard.html ← 中文界面
│ ├── copybot_live.json ← paper bot 的实时 feed
│ ├── copybot_live_real.json ← live bot 的实时 feed
│ ├── portfolio.py ← 回测程序
│ ├── backtest.json ← 回测配置
│ ├── daily.sh ← 每日流水线
│ └── cache.duckdb ← 钱包历史数据缓存
├── /etc/systemd/system/ ← systemd 服务定义(4 个)
│ ├── copybot-paper.service ← paper bot 服务
│ ├── copybot-live.service ← live bot 服务
│ ├── copybot-dashboard.service ← dashboard 服务
│ └── mihomo.service ← 代理服务
├── /etc/copybot/ ← 环境变量文件(密钥、代理)
│ ├── paper.env ← paper bot 的环境变量
│ └── live.env ← live bot 的环境变量
├── /etc/mihomo/ ← 代理配置
│ ├── config.yaml ← Clash 订阅配置
│ └── cache.db ← 记住上次选的节点
├── /usr/local/bin/mihomo ← 代理程序本体(二进制)
├── /opt/mihomo-healthcheck.sh ← 代理健康检查脚本
├── /opt/winning-wallet-finder/.netrc ← Gitea PAT 认证(wwf 用户用,bot 自动 push 时读)
└── crontab ← 定时任务
├── 0 2 * * * daily.sh ← 每日 10:00 北京时间跑回测
└── */5 * * * * mihomo-healthcheck.sh ← 每 5 分钟检查代理
```
> `.netrc` 不在目录树里显示是因为它是隐藏文件(以 `.` 开头)。用 `ls -la` 才能看到。
## 三个文件夹的分工
| 文件夹 | 放什么 | 为什么在这 |
| ----------------------------- | -------------------------- | ---------------------------------- |
| `/opt/winning-wallet-finder/` | 项目代码 + 配置 + 状态 | git clone 来的,所有代码在这 |
| `/etc/systemd/system/` | 服务定义(.service 文件) | Linux 约定俗成,systemd 服务都放这 |
| `/etc/copybot/` | 环境变量(密钥、代理地址) | 敏感文件不放代码仓库,独立管理 |
| `/etc/mihomo/` | 代理配置 | mihomo 的数据目录 |
> `/opt` 是你的代码,`/etc` 是系统配置。分开是因为**密钥不应该跟代码放一起**(怕 commit 到 Gitea 泄露)。
## live.env 和 config.live.json 怎么连起来的
它们**不在一个文件夹**,但 systemd 是桥梁:
```
/etc/systemd/system/copybot-live.service
│ ExecStart=python3 copybot.py --config config.live.json --live
│ ↑
│ 读 /opt/winning-wallet-finder/config.live.json
│ (跟哪些钱包、金额、风险参数)
│ EnvironmentFile=/etc/copybot/live.env
│ ↑
│ 读 /etc/copybot/live.env
│ (私钥、代理地址、确认短语)
copybot.py 启动时:
1. 从 EnvironmentFile 读 LIVE_PRIVATE_KEY -> 放进 config["live"]["private_key"]
2. 从 EnvironmentFile 读 HTTPS_PROXY -> 所有网络请求走代理
3. 从 --config 读 config.live.json -> 知道跟哪些钱包、bankroll 多少
4. 合并两者 -> 完整配置
```
简单说:
| 文件 | 内容 | 在哪 | 谁读 |
| ------------------ | -------------------------- | ----------------------------- | ------------------------------------------ |
| `config.live.json` | 跟哪些钱包、金额、风险参数 | `/opt/winning-wallet-finder/` | `--config` 参数传给 copybot.py |
| `live.env` | 私钥、代理、确认短语 | `/etc/copybot/` | systemd `EnvironmentFile` 自动注入环境变量 |
**为什么要分开**config.live.json 可以 commit 到 Gitea(里面没有密钥),live.env 绝不能 commit(里面有私钥)。
## 每个服务的完整启动链
```
paper bot:
systemd -> copybot.py --config copybot.paper.json
+ EnvironmentFile: paper.env (ALCHEMY_RPC_URL)
= 直连 Polymarket,不走代理
live bot:
systemd -> copybot.py --config config.live.json --live
+ EnvironmentFile: live.env (LIVE_PRIVATE_KEY + HTTPS_PROXY + TRADE LIVE)
= 走代理绕 geo-block,真钱下单
dashboard:
systemd -> serve_dashboard.py
= 读本地 JSON 文件(不涉及 Gitea),网页展示
- /api/feed -> live/copybot_live.json (paper)
- /api/live -> live/copybot_live_real.json (live)
- / -> live/bot_dashboard.html (中文界面)
mihomo:
systemd -> mihomo -d /etc/mihomo
= 代理服务,监听 127.0.0.1:7890
```
## bot 自动推 Gitea(自动备份 + 远程可读)
bot 和 daily.sh 会自动把状态文件 commit + push 到 Gitea**不需要你手动操作**。
### 推什么
| 推什么 | 频率 | 谁推的 | 目的 |
|---|---|---|---|
| `copybot_state.json` / `copybot_state.live.json` | 有状态变化时(节流) | bot 自动(`publish_feed()` | 备份账本 |
| `live/copybot_live.json` / `live/copybot_live_real.json` | 有状态变化时 | bot 自动 | 备份 feed |
| `copybot_fills.jsonl` / `copybot_fills.live.jsonl` | 有成交时 | bot 自动 | 备份成交记录 |
| `live/watch_sharps.json` + `watch_skilled.json` + `dashboard.html` + `portfolio.json` | 每天 1 次 | daily.sh 自动 | 刷新钱包池 |
### 认证方式
wwf 用户的 `.netrc` 文件(`/opt/winning-wallet-finder/.netrc`)里有 Gitea PATgit push 时自动读,不需要手动输密码。
### git log 里你会看到
```
copybot: live paper feed [skip ci] ← bot 自动推的(每次有状态变化)
fix: re-query order after cancel... ← 你手动推的(改代码)
docs: add 日常使用.md... ← 你手动推的(改文档)
```
`[skip ci]` 表示跳过 CI(这个项目没配 CI,只是习惯标记)。
### 这导致的副作用
你在本地改完代码 `git push` 时经常被拒:
```
! [rejected] main -> main (fetch first)
```
因为服务器上的 bot 已经自动 commit 了新的 state。解决方法:
```bash
# 方法 1:rebase(推荐,保留你的改动)
git pull --rebase --autostash origin main && git push origin main
# 方法 2:强制用远程版本(会丢本地未提交的改动,慎用)
git fetch origin && git reset --hard origin/main
```
### 远程读 JSON(不用 SSH 上服务器)
Gitea 提供 raw URL,浏览器直接访问就能看 bot 的实时数据:
```
# paper bot feed
https://code.aifunny.ltd/gavindiaz/winning-wallet-finder/raw/branch/main/live/copybot_live.json
# live bot feed
https://code.aifunny.ltd/gavindiaz/winning-wallet-finder/raw/branch/main/live/copybot_live_real.json
# 钱包候选列表
https://code.aifunny.ltd/gavindiaz/winning-wallet-finder/raw/branch/main/live/watch_sharps.json
```
> 但 raw JSON 不好看,建议还是用 dashboard`http://45.207.206.36:18080/`)。
### ⚠️ 注意:本地 Clash 会拦截直连 IP
如果你本地开了 Clash Verge 系统代理,访问 `http://45.207.206.36:18080/` 可能被拦截(Clash 把直连 IP 也走了代理)。解决方法:
1. **关掉 Clash 系统代理**(最简单)
2. 或在 Clash 规则里加 `IP-CIDR,45.207.206.36/32,DIRECT`(让这个 IP 直连不走代理)
---
## 你日常改东西去哪改
| 想改什么 | 改哪个文件 | 在哪 |
| --------------------------- | ------------------------------------------ | ----------------------------- |
| 跟哪些钱包 / 金额 | `copybot.paper.json``config.live.json` | `/opt/winning-wallet-finder/` |
| 私钥 / 代理地址 / 确认短语 | `live.env` | `/etc/copybot/` |
| Alchemy RPC | `paper.env` | `/etc/copybot/` |
| bot 程序参数(poll 间隔等) | `.service` 文件 | `/etc/systemd/system/` |
| 代理节点 / 订阅 | `config.yaml` | `/etc/mihomo/` |
| 每日 cron 时间 | `crontab -e` | 系统 |
| dashboard 端口 | `.service` 文件加 `Environment="PORT=xxx"` | `/etc/systemd/system/` |
改完任何东西记得 `systemctl restart 对应服务`