feat: initial Netts energy orchestrator

This commit is contained in:
你的用户名
2025-11-03 19:26:48 +08:00
commit 891c32e288
25 changed files with 2210 additions and 0 deletions

95
docs/api.md Normal file
View File

@@ -0,0 +1,95 @@
# REST API 文档
## POST `/api/v1/energy/rent`
为指定 TRON 地址分析能量需求、确保 Host Mode 状态,并根据配置自动购买能量周期。
### 请求体
```json
{
"from_address": "T地址", // 必填,需与 Netts Host Mode 地址一致
"to_address": "T地址", // 必填,归集目标地址
"amount": "200.0", // 可选USDT 数量,默认 100.00
"callback_url": "https://..."// 可选,覆盖配置中的 callback
}
```
### 成功响应
```json
{
"from_address": "TFrom...",
"to_address": "TTo...",
"amount": "200.0",
"address_added": true,
"recommended_energy": 131000,
"energy_needed": 131000,
"cycles_before": 2,
"cycles_after": 5,
"cycles_purchased": 3,
"total_cycles": 5,
"order_id": "ORD-20231109-XXXX",
"order_status": "confirmed",
"total_cost": 9.75,
"next_delegation_time": 1700000000,
"analysis": {
"sender_address": "...",
"receiver_address": "...",
"usdt_amount": "200.0",
"recommended_energy": 131000,
"energy_needed": 131000,
"bandwidth_needed": 345,
"cost_breakdown": {
"energy_cost": "4.5",
"bandwidth_cost": "1.0",
"total_cost_trx": "5.5"
},
"savings_analysis": {
"vs_direct_burn": "21.0",
"vs_staking": "7.5",
"savings_percentage": 80.1
}
},
"status": {
"mode": "normal",
"status": "active",
"cycles_remaining": 5,
"open_orders": 0,
"expiry_time": 1700100000
}
}
```
字段说明:
| 字段 | 含义 |
| ---- | ---- |
| `address_added` | 是否在本次调用中自动执行了 `time/add` |
| `cycles_before` / `cycles_after` | 调用前后剩余周期 |
| `cycles_purchased` | 本次下单购买的周期数(如果无需下单,字段不存在) |
| `analysis` | 直接透传 Netts `usdt/analyze` 的结果 |
| `status` | 透传 Netts `time/status` 的核心字段 |
### 错误响应
```json
{
"error": "failed to ensure energy",
"details": "address Txxx not in host mode and autoAddHost disabled"
}
```
HTTP 状态码:
| 状态码 | 说明 |
| ------ | ---- |
| `200` | 成功 |
| `400` | 请求体格式错误或地址校验失败 |
| `502` | 与 Netts API 通信失败、或 Netts 返回错误 |
### 使用建议
- 在归集任务执行前调用,确保能量充足。
- 结果可缓存短时间(例如 60s避免频繁重复请求。
- 如需批量处理,可在外层编排多个地址循环调用。

80
docs/architecture.md Normal file
View File

@@ -0,0 +1,80 @@
# 架构设计
## 总体概览
```
┌───────────────┐ ┌────────────────┐ ┌─────────────────────┐
│ Client/BC系统 │ ---> │ Netts Energy API│ ---> │ Netts.io (Host Mode) │
└───────────────┘ └────────────────┘ └─────────────────────┘
│ │
│ REST /api/v1/energy/rent│
▼ ▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Netts Energy Orchestrator │
│ ┌────────────┐ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ HTTP Server│→│ Energy Service │→│ Netts Client (API v2) │ │
│ │ (chi) │ │ - 业务规则 │ │ - usdt/analyze │ │
│ │ │ │ - Host Mode判断 │ │ - time/status/add/order │ │
│ └────────────┘ └──────────────────┘ └──────────────────────────────┘ │
│ ▲ │ │
│ └──────────── config/logger ────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
```
## 模块分解
### 1. `cmd/server`
- 应用入口,解析 `-config` 参数。
- 初始化配置、日志、Netts Client、业务服务与 HTTP Server。
### 2. `internal/config`
- 负责加载 YAML 配置与环境变量覆盖。
- 内置默认值、校验逻辑,确保 API Key 与阈值正确。
### 3. `internal/logger`
- 基于 `log/slog` 的结构化日志工厂。
- 支持 text / json 输出格式。
### 4. `internal/netts`
- 轻量封装 Netts API。
- 具备重试、User-Agent、X-Real-IP 注入、错误码处理等。
-`GetAddressStatus` 中把 “Address not found” 映射为可识别的 `ErrAddressNotFound`
### 5. `internal/service`
- 业务编排核心:
1. 调用 `usdt/analyze` 计算推荐能量;
2. 检查 Host Mode 状态,必要时自动 `time/add`
3. 当周期低于阈值时,根据配置 `targetCycles` 自动下单;
4. 返回分析详情、周期变化、下单记录。
- 通过接口解耦,便于单元测试和未来 mock。
### 6. `internal/http`
- 使用 `chi` 构建 REST API。
- 提供健康检查与 `POST /api/v1/energy/rent` 主入口。
- 响应中包含分析、Host Mode 状态以及订单结果,方便上游系统直接使用。
## 关键流程
1. **租赁请求**:上游在归集前发送 `from_address``to_address`,可附带金额。
2. **能量分析**:调用 Netts `usdt/analyze` 获取推荐能量。
3. **Host Mode 确认**
- 如果地址未加入,且配置允许自动加入 ⇒ 调用 `time/add`
- 否则直接报错,交由上游处理。
4. **周期管理**
- 读取 `time/status`
-`cycles_remaining < minCycles` ⇒ 计算补足数量并调用 `time/order`
- 下单后可选等待 `postOrderWait` 秒,再次查询状态。
5. **响应汇总**:返回推荐能量、是否新增 Host Mode、下单详情、剩余周期、分析数据等。
## 与既有系统的协作
- **触发时机**:在归集执行前(或按周期任务)调用本服务,确保地址有足够能量。
- **地址生命周期**:推荐在创建新充值地址时即调用 `rent` 接口,让服务负责 Host Mode 注册;现有地址可批量调用 `time/add` 或逐次触发。
- **成本监控**:可据 `analysis.cost_breakdown``OrderResult` 中的 `total_cost` 统计能量开销,并和旧的 Feee 系统成本对比。
- **告警策略**:根据 `cycles_after``status.cycles_remaining` 制定阈值告警Netts 自带 webhook 可配合使用。
## 扩展点
- **多币种支持**Netts 文档提供更多接口(如 `prices``usdt-public`),可按需扩展。
- **持久化缓存**:目前状态全由 Netts API 提供,如需本地缓存可在 `service` 层引入数据库或 Redis。
- **批量调度**:可增加定时任务扫描地址列表并调用 `EnsureEnergy`,形成全自动化闭环。

92
docs/deployment.md Normal file
View File

@@ -0,0 +1,92 @@
# 部署与运维指南
## 环境要求
- Go 1.24+
- Netts API v2 账号,并完成:
- 获取 API Key
- 配置 IP 白名单(若使用代理,可在 `config.yaml` 中设置 `netts.realIp`
- 充值余额,以便购买能量周期。
## 构建
```bash
go build -o bin/netts-energy ./cmd/server
```
可选 Dockerfile伪代码
```dockerfile
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o /build/netts-energy ./cmd/server
FROM alpine:3.20
WORKDIR /srv/app
COPY --from=builder /build/netts-energy /usr/local/bin/netts-energy
COPY config.example.yaml ./config.yaml
CMD ["netts-energy", "-config", "/srv/app/config.yaml"]
```
## 运行时配置
1. 根据 `config.example.yaml` 编辑正式配置,或注入环境变量(`NETTS_API_KEY` 等)。
2. 建议通过 systemd / Supervisor 运行,示例:
```
[Unit]
Description=Netts Energy Orchestrator
After=network-online.target
[Service]
ExecStart=/srv/netts/netts-energy -config /srv/netts/config.yaml
Restart=on-failure
Environment=NETTS_API_KEY=***
[Install]
WantedBy=multi-user.target
```
3. 健康检查:
- HTTP GET `http://host:port/healthz` 返回 200。
- 可接入 Kubernetes / Nginx upstream 的健康探测。
## CI/CD 建议
仓库内置 GitHub Actions workflow (`.github/workflows/ci.yaml`)
- 安装依赖;
- `go fmt` + `go vet`
- `go test ./...`。
若需要自动部署服务器,可以在 CI 中加入以下步骤:
1. 在 GitHub 仓库配置 Secrets
- `SSH_HOST` / `SSH_USER` / `SSH_KEY`
- `DEPLOY_PATH` 等自定义变量。
2. 在 workflow 中追加 job简例
```yaml
- name: Deploy
if: github.ref == 'refs/heads/main'
run: |
scp bin/netts-energy ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DEPLOY_PATH }}
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'systemctl restart netts-energy'
```
> 注:部署脚本默认留空,需根据实际服务器环境完善。
## 与现有自动到账系统的集成
1. **地址维护**:在充值服务创建新用户地址后,触发一次 `rent` 调用,让服务自动加入 Host Mode。
2. **归集流程**:在执行 TRC20 归集前调用 `rent` 接口,确保能量充足后再发起链上交易。
3. **降级策略**:若 Netts API 不可用,可回退到旧的 Feee 方案;建议通过 Prometheus 指标或报警系统监控 `rent` 接口的失败率。
4. **费用对比**:响应中的 `analysis.cost_breakdown` 与订单 `total_cost` 方便和现有成本核算系统对接。
## 运维建议
- **日志**:标准输出为结构化日志,建议接入 Loki / ELK 做集中采集。
- **监控**:结合 Netts webhook 与本服务返回数据,设置周期不足、下单失败等告警。
- **升级**:新增 Netts 接口(例如 `time/infinitystart`)时,可在 `internal/netts` 中扩展方法并追加 service 策略。
- **安全**:谨慎保管 API Key生产环境务必使用 HTTPS 代理或反向代理,限制访问来源。