Open API 实施方案
Microcosm Open API 实施方案
版本: v2.2 状态: ✅ Phase 1-3 已部署 | ✅ Phase 5-8 已完成 | ✅ 科技树 API 已实施 | ✅ 用户来源追踪已实施 创建日期: 2026-01-08 更新日期: 2026-02-02 当前版本: open-api-service v1.1.22, blockchain-service v1.2.38 目标: 为所有外部项目提供标准化的 Microcosm 业务数据访问接口
v2.2 更新 (2026-02-02):
- ✅ 新增公开 stats 端点:
/v1/mcc/stats,/v1/mcd/stats(无需认证)- ✅ 用户来源追踪 (
source_project_id) 已实施,OAuth 登录自动记录- ✅ 开发者伴生矿已上线,DHC 项目配置完成
v2.1 更新 (2026-02-01): ✅ 新增 Microcosm 科技树 CronJob (
tech-tree-daily-update),基于 KPI 自动更新科技树状态v2.0 更新 (2026-02-01): ✅ 科技树 API (
/v1/tech-tree/*) 已实施,删除 Double Helix 历史遗留 CronJobv1.9 更新 (2026-01-25): ✅ Phase 8 项目注册与 MCD 白名单管理功能已实施完成
v1.7 更新 (2026-01-19): 新增 Section 16 价格预言机架构,Open API
/v1/mcc/price作为预言机备用价格来源v1.6 更新 (2026-01-16): 新增 Phase 7 Solana 合约 API(Territory NFT、Auction Solana、Fragment、Lending),共 23 个端点
v1.3 更新: 新增 Phase 5 交易类 API 架构设计,包含铸造提交、资金管理、转账请求、Webhook 回调机制和零信任安全模型
1. 背景与目标
1.1 当前问题
| 问题 | 描述 |
|---|---|
| 架构局限 | 当前 API 仅支持 K8s 集群内部访问 |
| 扩展性差 | 外部项目(AWS、阿里云等)无法安全访问 Microcosm 数据 |
| 临时方案泛滥 | 每个项目都在写临时代理代码 |
| 缺乏标准化 | 无统一的 API 规范和文档 |
1.2 目标
- 公开化: 提供可从任意网络访问的 Public API
- 标准化: 遵循 OpenAPI 3.1 规范
- 安全性: OAuth 2.0 + API Rate Limiting
- 可扩展: 支持未来新增业务数据
- 高可用: 多区域部署支持
2. 工业标准遵循
2.1 API 设计标准
| 标准 | 版本 | 用途 |
|---|---|---|
| OpenAPI Specification | 3.1.0 | API 文档规范 |
| RESTful API Design | Level 3 (HATEOAS) | 资源设计原则 |
| JSON:API | 1.1 | 响应格式规范 |
| RFC 7807 | - | Problem Details for HTTP APIs (错误响应) |
| RFC 6749 | - | OAuth 2.0 Authorization Framework |
| RFC 6750 | - | Bearer Token Usage |
| Semantic Versioning | 2.0.0 | API 版本管理 |
2.2 安全标准
| 标准 | 用途 |
|---|---|
| OAuth 2.0 + PKCE | 公共客户端授权 |
| JWT (RFC 7519) | Access Token 格式 |
| TLS 1.3 | 传输加密 |
| CORS | 跨域访问控制 |
| Rate Limiting (RFC 6585) | 速率限制响应头 |
3. API 架构设计
3.1 整体架构
外部项目层:
| 项目 | 部署平台 |
|---|---|
| Double Helix | GCP |
| Event Horizon | GCP |
| 第三方项目 A | AWS |
| 第三方项目 B | 阿里云 |
所有外部项目通过 HTTPS 请求访问统一入口。
Microcosm Open API Gateway (https://api.microcosm.money):
- OAuth 2.0 Token Validation
- Rate Limiting
- Request Logging
- API Versioning (/v1, /v2)
Microcosm K8s 集群内部:
- open-api-service (统一入口) 接收 Gateway 转发的请求
- open-api-service 根据请求类型转发到内部服务:
| 内部服务 | 职责 |
|---|---|
| user-service | 用户信息 |
| blockchain-service | 链上数据 |
| organization-service | 组织/领地 |
3.2 域名规划
| 域名 | 用途 |
|---|---|
api.microcosm.money | Open API 入口 (新增) |
auth.microcosm.money | OAuth 认证服务 (现有) |
microcosm.money | 前端门户 (现有) |
3.3 API 版本策略
https://api.microcosm.money/v1/mcc/balance
https://api.microcosm.money/v1/mcd/balance
https://api.microcosm.money/v2/mcc/balance (未来版本)
- URL Path Versioning:
/v1/,/v2/ - 版本生命周期: 新版本发布后,旧版本支持 12 个月
- Breaking Changes: 仅在大版本升级时引入
4. API 端点设计
4.1 链上数据 API (On-Chain)
4.1.1 MCC Token API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/mcc/balance | 获取当前用户 MCC 余额 | mcc:read |
| GET | /v1/mcc/balance/{address} | 获取指定地址 MCC 余额 | mcc:read:public |
| GET | /v1/mcc/transactions | 获取当前用户 MCC 交易记录 | mcc:read |
| GET | /v1/mcc/price | 获取 MCC 当前价格(预言机备用来源) | 公开 |
| POST | /v1/mcc/price | 设置管理员价格(预言机备用来源) | mcc:admin |
| GET | /v1/mcc/stats | 获取 MCC 全局统计 | 公开 |
价格预言机架构: 详见 Section 16
/v1/mcc/price 端点说明:
- 作为价格预言机服务的备用来源(优先级 2)
- 当 Pyth 市场价格不可用时,预言机服务读取此端点的管理员价格
- POST 端点仅限管理员设置价格,用于市场异常时的人工干预
4.1.2 MCD Token API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/mcd/balance | 获取当前用户 MCD 余额 | mcd:read |
| GET | /v1/mcd/transactions | 获取 MCD 交易记录 | mcd:read |
| GET | /v1/mcd/rewards | 获取 MCD 每日奖励记录 | mcd:read |
| GET | /v1/mcd/stats | 获取 MCD 全局统计 | 公开 |
4.2 链下数据 API (Off-Chain)
4.2.1 用户 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/users/me | 获取当前用户信息 | user:read |
| GET | /v1/users/me/profile | 获取用户详细资料 | user:read |
| PATCH | /v1/users/me/profile | 更新用户资料 (display_name) | user:write |
| POST | /v1/users/me/avatar | 上传用户头像 | user:write |
| GET | /v1/users/{uid} | 获取指定用户公开信息 | user:read:public |
4.2.2 组织 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/organizations | 获取组织列表 | org:read |
| GET | /v1/organizations/{id} | 获取组织详情 | org:read |
| GET | /v1/organizations/{id}/members | 获取组织成员 | org:read |
4.2.3 铸造 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/mining/records | 获取铸造记录 | mining:read |
| GET | /v1/mining/stats | 获取铸造统计 | mining:read |
4.2.4 科技树 API (2026-02-01 新增)
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/tech-tree/config | 获取科技树配置 | 公开 |
| GET | /v1/tech-tree/user | 获取用户科技树进度 | org:read |
| GET | /v1/tech-tree/bonus | 获取用户科技树加成 | org:read |
| POST | /v1/tech-tree/unlock | 解锁科技树节点 | org:read |
| POST | /v1/tech-tree/upgrade | 升级科技树节点 | org:read |
科技树加成用途:
- Double Helix 等项目用于计算用户铸造加成
- 返回
bonus_multiplier字段,直接用于铸造产出计算 - 示例:
bonus_multiplier = 1.15表示用户有 15% 的加成
科技树 KPI 规则:
| 配置项 | 值 | 说明 |
|---|---|---|
| 满员率阈值 | > 90% | Station 成员 ≥ 900/1000 |
| 人均铸造阈值 | ≥ 20 USDC/天 | 当日 Station 成员人均铸造投入 |
| 达标窗口 | 30 天 | 统计最近 30 天 KPI |
| 点亮条件 | ≥ 21 天达标 | 30 天内满足两个 KPI 条件的天数 |
科技树加成配置:
| 单位类型 | 加成 | 累加后 | 点亮条件 |
|---|---|---|---|
| Station | +10% | 10% | 自身 KPI ≥ 21天达标 |
| Matrix | +20% | 30% | 所辖 Station 平均达标天数 ≥ 21 |
| Sector | +30% | 60% | 所辖 Station 平均达标天数 ≥ 21 |
| System | +40% | 100% | 所辖 Station 平均达标天数 ≥ 21 |
CronJob: tech-tree-daily-update
- 执行时间: UTC 00:30 (北京时间 08:30)
- 配置文件:
k8s/tech-tree-update-cronjob.yaml - 执行流程:
- 计算每个 Station 的每日 KPI(满员率、人均铸造)
- 记录到
unit_kpi_daily表 - 更新所有单位的科技树状态
- 更新用户铸造加成缓存 (
user_mining_bonus_cache)
5. 认证与授权
5.1 OAuth 2.0 Scopes
| Scope | 描述 |
|---|---|
openid | OpenID Connect 基础 |
profile | 用户基本信息 |
email | 用户邮箱 |
mcc:read | 读取 MCC 余额和交易 |
mcd:read | 读取 MCD 余额和交易 |
user:read | 读取用户信息 |
user:write | 更新用户资料 (display_name, avatar) |
org:read | 读取组织信息 |
mining:read | 读取铸造记录 |
5.2 Token 获取流程
1. 外部项目在 Microcosm Developer Portal 注册应用
2. 获取 client_id 和 client_secret (机密客户端)
或仅 client_id (公共客户端, 需使用 PKCE)
3. 用户授权后获取 access_token
4. 使用 Bearer Token 调用 API
5.3 请求示例
# 获取 MCD 余额
curl -X GET "https://api.microcosm.money/v1/mcd/balance" \
-H "Authorization: Bearer {access_token}" \
-H "Accept: application/json"
5.4 响应格式 (JSON:API 规范)
成功响应:
{
"data": {
"type": "mcd_balance",
"id": "user_123",
"attributes": {
"total_balance": "1250.50",
"available_balance": "1200.00",
"frozen_balance": "50.50",
"updated_at": "2026-01-08T10:30:00Z"
}
},
"meta": {
"request_id": "req_abc123",
"api_version": "v1"
}
}
错误响应 (RFC 7807):
{
"type": "https://api.microcosm.money/errors/insufficient-scope",
"title": "Insufficient Scope",
"status": 403,
"detail": "The access token does not have the 'mcd:read' scope required for this endpoint.",
"instance": "/v1/mcd/balance"
}
6. 速率限制
6.1 限制策略
| 客户端类型 | 限制 | 窗口 |
|---|---|---|
| 免费开发者 | 100 请求 | 每分钟 |
| 标准项目 | 1,000 请求 | 每分钟 |
| 企业项目 | 10,000 请求 | 每分钟 |
6.2 响应头
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 998
X-RateLimit-Reset: 1704700800
Retry-After: 60 (仅在限制时返回)
6.3 超限响应
{
"type": "https://api.microcosm.money/errors/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded the rate limit of 1000 requests per minute.",
"retry_after": 45
}
7. 实施计划
Phase 1: 基础设施 ✅ 完成
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 1.1 域名配置 | 配置 api.microcosm.money DNS | A 记录指向 Gateway | ✅ |
| 1.2 SSL 证书 | 申请 Google Managed Certificate | 自动续期证书 | ✅ |
| 1.3 Gateway 配置 | 创建 HTTPRoute for Open API | 路由配置 | ✅ |
| 1.4 open-api-service | 创建新服务作为统一入口 | 服务代码 + Dockerfile | ✅ |
Phase 2: 核心 API ✅ 完成
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 2.1 MCC API | 实现 MCC 余额/交易接口 | API 端点 | ✅ |
| 2.2 MCD API | 实现 MCD 余额/奖励接口 | API 端点 | ✅ |
| 2.3 用户 API | 实现用户信息接口 | API 端点 | ✅ |
| 2.4 组织 API | 实现组织/单位信息接口 | API 端点 | ✅ |
| 2.5 铸造 API | 实现铸造记录/统计接口 | API 端点 | ✅ |
| 2.6 OpenAPI 文档 | 生成 OpenAPI 3.1 规范文档 | openapi.yaml | ✅ |
Phase 3: 安全加固 ✅ 完成
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 3.1 Scope 验证 | 实现 OAuth Scope 校验中间件 | 权限控制代码 | ✅ |
| 3.2 Rate Limiting | 实现基于 Redis 的速率限制 | 限流中间件 | ✅ |
| 3.3 请求日志 | 实现 API 调用审计日志 | 日志系统 | ✅ |
Phase 4: 开发者体验 (优先级: 中) ⏳ 待实施
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 4.1 Developer Portal | 创建开发者注册/管理页面 | 前端页面 | ⏳ |
| 4.2 API 文档站 | 部署交互式 API 文档 | Swagger UI / Redoc | ⏳ |
| 4.3 SDK 生成 | 自动生成 Python/TypeScript SDK | SDK 包 | ⏳ |
Phase 5: 交易类 API (优先级: 高) ✅ 代码实施完成
详细架构设计见 Section 13
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 5.1 铸造提交 API | 实现 /v1/mining/submit-activity | API 端点 | ✅ |
| 5.2 资金管理 API | 实现 /v1/funds/* 系列端点 (冻结/解冻/转账) | API 端点 | ✅ |
| 5.3 转账请求 API | 实现 /v1/transfer/* 系列端点 | API 端点 | ✅ |
| 5.4 Webhook 系统 | 实现 Webhook 注册、签名验证、异步发送 | Webhook 服务 | ✅ |
| 5.5 项目注册 | 实现项目管理 API 及权限配置 | 管理端点 | ✅ |
| 5.6 审计日志 | 实现交易审计系统 (transaction_audit_log 表) | 数据库表 + 日志 | ✅ |
| 5.7 限额控制 | 实现单次/每日操作限额检查 | 中间件 | ✅ |
| 5.8 幂等性控制 | 实现 idempotency_key 机制防重放 | 中间件 | ✅ |
Phase 6: 用户画像 API (优先级: 中) ✅ 代码实施完成
详细架构设计见 Section 15
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 6.1 用户基础画像 API | 实现 /v1/users/{uid}/profile | API 端点 | ✅ |
| 6.2 项目属性查询 API | 实现 /v1/users/{uid}/projects/{project_id}/attributes | API 端点 | ✅ |
| 6.3 完整画像聚合 API | 实现 /v1/users/{uid}/full-profile | API 端点 | ✅ |
| 6.4 项目状态查询 API | 实现 /v1/projects/{project_id}/status | API 端点 | ✅ |
| 6.5 项目属性上报 API | 实现 POST /v1/users/{uid}/attributes | API 端点 | ✅ |
| 6.6 属性删除 API | 实现 DELETE /v1/users/{uid}/attributes | API 端点 | ✅ |
| 6.7 批量属性查询 API | 实现 POST /v1/users/batch/attributes | API 端点 | ✅ |
| 6.8 数据库表 | 创建 user_project_attributes, project_status_history 表 | 数据库表 | ✅ |
Phase 7: Solana 合约 API (优先级: 高) ✅ 代码实施完成
为第三方项目提供 Solana 链上合约的只读查询接口
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 7.1 Territory NFT API | 实现 /v1/territory/* 系列端点 (4 个) | API 端点 | ✅ |
| 7.2 Auction Solana API | 实现 /v1/auction-solana/* 系列端点 (6 个) | API 端点 | ✅ |
| 7.3 Fragment API | 实现 /v1/fragment/* 系列端点 (5 个) | API 端点 | ✅ |
| 7.4 Lending API | 实现 /v1/lending/* 系列端点 (8 个) | API 端点 | ✅ |
端点详情:
| 模块 | 端点 | 方法 | 说明 |
|---|---|---|---|
| Territory NFT | /v1/territory/collection | GET | 获取 Collection 配置 |
/v1/territory/nft/{mint} | GET | 获取 NFT 元数据 | |
/v1/territory/nfts/{wallet} | GET | 获取用户 NFT 列表 | |
/v1/territory/unit/{unit_id}/nft | GET | 获取单位关联 NFT | |
| Auction Solana | /v1/auction-solana/config | GET | 获取拍卖配置 |
/v1/auction-solana/active | GET | 获取活跃拍卖列表 | |
/v1/auction-solana/auction/{id} | GET | 获取拍卖详情 | |
/v1/auction-solana/auction/{id}/bids | GET | 获取竞价历史 | |
/v1/auction-solana/bids/{wallet} | GET | 获取用户竞价记录 | |
/v1/auction-solana/auctions/{wallet} | GET | 获取用户创建的拍卖 | |
| Fragment | /v1/fragment/config | GET | 获取碎片化配置 |
/v1/fragment/vaults | GET | 获取所有 Vault 列表 | |
/v1/fragment/vault/{id} | GET | 获取 Vault 详情 | |
/v1/fragment/vault/{id}/holders | GET | 获取 Vault 持仓分布 | |
/v1/fragment/holdings/{wallet} | GET | 获取用户持仓 | |
| Lending | /v1/lending/pool | GET | 获取借贷池配置 |
/v1/lending/stats | GET | 获取借贷池统计 | |
/v1/lending/position/{wallet} | GET | 获取用户仓位 | |
/v1/lending/loans/{wallet} | GET | 获取用户贷款列表 | |
/v1/lending/loan/{wallet}/{loan_id} | GET | 获取贷款详情 | |
/v1/lending/lp-balance/{wallet} | GET | 获取 LP Token 余额 | |
/v1/lending/calculate-interest | POST | 计算利息 | |
/v1/lending/estimate-borrow-cost | POST | 估算借款成本 |
8. 技术栈选型
8.1 open-api-service 技术栈
| 组件 | 选择 | 理由 |
|---|---|---|
| 框架 | FastAPI | 自动 OpenAPI 生成,高性能 |
| 运行时 | Uvicorn + Gunicorn | 生产级 ASGI 服务器 |
| 缓存 | Redis | 速率限制 + 响应缓存 |
| 日志 | Structlog + Cloud Logging | 结构化日志 |
8.2 部署架构
# open-api-service 部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: open-api-service
namespace: microcosm
spec:
replicas: 2 # HA 部署
template:
spec:
containers:
- name: open-api-service
image: asia-northeast1-docker.pkg.dev/microcosm/microcosm/open-api-service:v1.0.0
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
9. Double Helix 接入示例
9.1 更新后的 API 调用
// frontend-service/lib/api/services.ts
const MICROCOSM_API_BASE = 'https://api.microcosm.money/v1'
export async function getMCDBalance(): Promise<APIResponse<MCDBalanceType>> {
const token = getAccessToken()
const response = await fetch(`${MICROCOSM_API_BASE}/mcd/balance`, {
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
})
return response.json()
}
export async function getMCDTransactions(params?: MCDHistoryParams): Promise<APIResponse<MCDTransaction[]>> {
const token = getAccessToken()
const queryString = new URLSearchParams(params as any).toString()
const response = await fetch(`${MICROCOSM_API_BASE}/mcd/transactions?${queryString}`, {
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
})
return response.json()
}
9.2 无需修改 api-gateway
由于直接调用 Microcosm Open API,不再需要在 Double Helix api-gateway 中添加代理路由。
10. 安全考虑
10.1 威胁模型
| 威胁 | 缓解措施 |
|---|---|
| Token 泄露 | 短 TTL (1小时) + Refresh Token 轮换 |
| API 滥用 | Rate Limiting + 异常检测 |
| 数据泄露 | TLS 1.3 强制 + 最小权限原则 |
| CSRF | SameSite Cookie + CORS 严格策略 |
10.2 CORS 配置
# open-api-service CORS 配置
ALLOWED_ORIGINS = [
"https://doublehelix.money",
"https://www.doublehelix.money",
"https://poly.microcosm.money",
"https://microcosm.money",
# 开发环境
"http://localhost:3000",
"http://localhost:3001",
]
11. 监控与告警
11.1 关键指标
| 指标 | 阈值 | 告警 |
|---|---|---|
| API 延迟 P99 | > 500ms | 警告 |
| API 延迟 P99 | > 1000ms | 严重 |
| 错误率 | > 1% | 警告 |
| 错误率 | > 5% | 严重 |
| Rate Limit 触发率 | > 10% | 警告 |
11.2 Grafana Dashboard
创建专用 Open API 监控面板,包含:
- 请求量 (QPS)
- 延迟分布
- 错误分类
- 调用者分布
- Rate Limit 统计
12. 审核清单
请确认以下事项后批准实施:
- API 端点设计是否满足业务需求
- OAuth Scope 划分是否合理
- Rate Limit 限制是否合适
- 实施阶段优先级是否正确
- 安全措施是否充分
- 是否需要添加其他 API 端点
附录 A: OpenAPI 规范示例
openapi: 3.1.0
info:
title: Microcosm Open API
version: 1.0.0
description: Public API for Microcosm ecosystem
servers:
- url: https://api.microcosm.money/v1
description: Production
security:
- oauth2: []
paths:
/mcd/balance:
get:
summary: Get MCD Balance
operationId: getMCDBalance
security:
- oauth2: [mcd:read]
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/MCDBalanceResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
components:
securitySchemes:
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.microcosm.money/oauth/authorize
tokenUrl: https://auth.microcosm.money/oauth/token
scopes:
mcd:read: Read MCD balance and transactions
mcc:read: Read MCC balance and transactions
user:read: Read user profile
org:read: Read organization information
mining:read: Read mining records and stats
附录 B: 实施记录
2026-01-09 Phase 1-3 实施完成
实施内容:
-
OAuth Scope 验证中间件 (
dependencies.py)- 实现
RequireScope类,支持多 scope 验证 - 预定义验证器:
require_mcc_read,require_mcd_read,require_user_read,require_org_read,require_mining_read - 管理员角色自动拥有所有权限
- Token 内省结果缓存 (5分钟 TTL)
- 实现
-
Redis Rate Limiting (
rate_limiter.py)- 滑动窗口算法实现
- 支持按 Token/API Key/IP 识别客户端
- Redis 不可用时自动降级到内存存储
- 配置: 默认 100 请求/分钟
-
请求审计日志 (
audit_logger.py)- 使用 structlog 输出结构化 JSON 日志
- 记录: 请求方法、路径、客户端 IP、延迟、状态码
- 自动添加
X-Request-ID响应头 - 安全事件专用日志函数
-
组织 API (
routers/organizations.py)GET /v1/organizations- 获取组织列表GET /v1/organizations/{id}- 获取组织详情GET /v1/organizations/{id}/members- 获取组织成员GET /v1/organizations/{id}/stats- 获取组织统计 (公开)
-
铸造 API (
routers/mining.py)GET /v1/mining/records- 获取铸造记录GET /v1/mining/stats- 获取个人铸造统计GET /v1/mining/global-stats- 获取全局铸造统计 (公开)
新增文件:
fastapi_app/rate_limiter.py- Redis 速率限制器fastapi_app/audit_logger.py- 审计日志系统fastapi_app/routers/organizations.py- 组织 APIfastapi_app/routers/mining.py- 铸造 APIk8s/redis.yaml- Redis 部署配置
更新文件:
fastapi_app/dependencies.py- 添加 Scope 验证fastapi_app/main.py- 注册新中间件和路由fastapi_app/routers/mcc.py- 添加 Scope 验证fastapi_app/routers/mcd.py- 添加 Scope 验证fastapi_app/routers/users.py- 添加 Scope 验证requirements.txt- 添加 redis, structlog 依赖k8s/deployment.yaml- 添加 REDIS_URL 环境变量
部署步骤:
# 1. 部署 Redis
kubectl apply -f services/open-api-service/k8s/redis.yaml
# 2. 构建并部署 open-api-service
cd services/open-api-service
gcloud builds submit --config=cloudbuild.yaml --region=asia-northeast1 \
--substitutions=_IMAGE_URI=<registry>/<project>/open-api-service:<version> .
# 3. 更新部署
kubectl set image deploy/open-api-service \
open-api-service=<registry>/<project>/open-api-service:<version> \
-n microcosm
2026-01-10 部署完成
部署状态:
| 组件 | 版本 | 状态 | 副本数 |
|---|---|---|---|
| Redis | 7-alpine | ✅ Running | 1 |
| open-api-service | v1.1.1 | ✅ Running | 2 |
已上线 API 端点:
| 分类 | 端点 | 权限 |
|---|---|---|
| MCC | /v1/mcc/balance | mcc:read |
| MCC | /v1/mcc/balance/{address} | 公开 |
| MCC | /v1/mcc/transactions | mcc:read |
| MCC | /v1/mcc/price | 公开 |
| MCC | /v1/mcc/stats | 公开 |
| MCD | /v1/mcd/balance | mcd:read |
| MCD | /v1/mcd/transactions | mcd:read |
| MCD | /v1/mcd/rewards | mcd:read |
| MCD | /v1/mcd/stats | 公开 |
| Users | /v1/users/me | user:read |
| Users | /v1/users/me/profile | user:read |
| Users | PATCH /v1/users/me/profile | user:write |
| Users | POST /v1/users/me/avatar | user:write |
| Users | /v1/users/{uid} | 公开 |
| Organizations | /v1/organizations | org:read |
| Organizations | /v1/organizations/{org_id} | org:read |
| Organizations | /v1/organizations/{org_id}/members | org:read |
| Organizations | /v1/organizations/{org_id}/stats | 公开 |
| Mining | /v1/mining/records | mining:read |
| Mining | /v1/mining/stats | mining:read |
| Mining | /v1/mining/global-stats | 公开 |
访问地址:
| 资源 | URL |
|---|---|
| API 根路径 | https://api.microcosm.money/ |
| Swagger UI | https://api.microcosm.money/docs |
| ReDoc | https://api.microcosm.money/redoc |
| OpenAPI Spec | https://api.microcosm.money/openapi.json |
修复记录:
- v1.1.1: 修复
audit_logger.py中 structlog 事件参数冲突问题
文档状态: ✅ Phase 1-3 已部署上线,Phase 4-5 待实施
13. Phase 5: 交易类 API 架构设计 (优先级: 高)
核心原则: Microcosm 是唯一的链上数据控制者,所有资产操作必须通过 Microcosm API 执行。
13.1 架构原则
Microcosm 作为链上数据的唯一控制者:
| 原则 | 说明 |
|---|---|
| 1. 所有资产操作必须通过 Microcosm API | 第三方项目不能直接操作链上数据,只能请求 Microcosm 执行操作 |
| 2. 资金验证由 Microcosm 负责 | 检查用户余额是否足够、冻结/解冻资金、验证交易证明 |
| 3. 链上写入只有 Microcosm 有私钥 | MCC Token Mint/Transfer、MCD 奖励发放、交易记录上链 |
| 4. 异步确认通过 Webhook 通知 | 链上交易确认后回调第三方项目、状态更新通知 |
13.2 数据流架构
参与方:
| 参与方 | 包含 |
|---|---|
| 外部项目 | Double Helix、Event Horizon、第三方项目 |
| Microcosm 内部 | open-api-service、blockchain-service、PostgreSQL、Webhook Service |
| 链上 | Solana Chain (MCC Token、交易记录) |
数据流:
- 请求阶段: 外部项目发送请求到 open-api-service (验证权限、验证签名、速率限制)
- 同步响应: open-api-service 返回
{status: "pending"},同时将请求转发给 blockchain-service (余额检查、冻结资金、链上写入) - 链上处理: blockchain-service 与 Solana Chain 交互,结果写入 PostgreSQL (pending_transactions、mining_activities、locked_funds)
- 异步回调: 链上确认后,Webhook Service 向外部项目发送回调通知
13.3 交易类 API 端点设计
13.3.1 铸造活动 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| POST | /v1/mining/submit-activity | 提交铸造活动 | mining:write |
| GET | /v1/mining/activity/{id} | 查询活动状态 | mining:read |
| POST | /v1/mining/batch-submit | 批量提交活动 | mining:write |
请求示例 - 提交铸造活动:
POST /v1/mining/submit-activity
Authorization: Bearer {project_access_token}
X-Project-ID: double_helix
{
"user_uid": "Drt0n1i6y1UVF8wqydT3ckQewM22",
"activity_type": "trading",
"activity_data": {
"trade_volume_usdc": 10000,
"trade_count": 15,
"profit_usdc": 250
},
"proof": {
"type": "signed_hash",
"hash": "0x...",
"signature": "...",
"timestamp": "2026-01-10T12:00:00Z"
},
"idempotency_key": "dh-2026-01-10-user123-batch1"
}
响应:
{
"data": {
"type": "mining_activity",
"id": "act_abc123",
"attributes": {
"status": "pending_verification",
"mcd_estimated": "50.00",
"created_at": "2026-01-10T12:00:01Z"
}
},
"meta": {
"webhook_url": "Will notify when confirmed"
}
}
13.3.2 资金管理 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| POST | /v1/funds/lock | 冻结用户资金 | funds:manage |
| POST | /v1/funds/unlock | 解冻用户资金 | funds:manage |
| POST | /v1/funds/transfer | 项目内转账 | funds:transfer |
| GET | /v1/funds/locked/{user_uid} | 查询冻结资金 | funds:read |
请求示例 - 冻结资金(拍卖出价):
POST /v1/funds/lock
Authorization: Bearer {project_access_token}
X-Project-ID: event_horizon
{
"user_uid": "user123",
"currency": "MCC",
"amount": "100.00",
"reason": "auction_bid",
"reference_id": "auction_456",
"expires_at": "2026-01-11T00:00:00Z",
"idempotency_key": "eh-auction-456-bid-user123"
}
响应:
{
"data": {
"type": "fund_lock",
"id": "lock_xyz789",
"attributes": {
"status": "locked",
"user_uid": "user123",
"currency": "MCC",
"amount": "100.00",
"available_balance": "900.00",
"locked_until": "2026-01-11T00:00:00Z"
}
}
}
13.3.3 转账请求 API
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| POST | /v1/transfer/request | 发起转账请求 | transfer:write |
| GET | /v1/transfer/{id} | 查询转账状态 | transfer:read |
| POST | /v1/transfer/{id}/cancel | 取消转账 | transfer:write |
请求示例 - 拍卖结算转账:
POST /v1/transfer/request
Authorization: Bearer {project_access_token}
X-Project-ID: event_horizon
{
"transfer_type": "auction_settlement",
"from_uid": "bidder_user",
"to_uid": "seller_user",
"currency": "MCC",
"amount": "100.00",
"reference": {
"auction_id": "auction_456",
"item_id": "item_789"
},
"requires_onchain": true,
"idempotency_key": "eh-auction-456-settlement"
}
13.4 Webhook 回调机制
13.4.1 Webhook 事件类型
| 事件 | 描述 | 触发时机 |
|---|---|---|
mining.activity.verified | 铸造活动已验证 | 活动验证通过 |
mining.reward.confirmed | 铸造奖励已确认 | 链上交易确认 |
funds.locked | 资金已冻结 | 冻结操作完成 |
funds.unlocked | 资金已解冻 | 解冻操作完成 |
transfer.completed | 转账已完成 | 链上交易确认 |
transfer.failed | 转账失败 | 交易被拒绝 |
13.4.2 Webhook 注册
POST /v1/webhooks/register
Authorization: Bearer {project_access_token}
{
"url": "https://doublehelix.money/api/webhooks/microcosm",
"events": ["mining.reward.confirmed", "transfer.completed"],
"secret": "whsec_xxx..."
}
13.4.3 Webhook 请求格式
POST https://doublehelix.money/api/webhooks/microcosm
X-Microcosm-Signature: sha256=xxx...
X-Microcosm-Event: mining.reward.confirmed
X-Microcosm-Delivery: evt_123
{
"id": "evt_abc123",
"type": "mining.reward.confirmed",
"created_at": "2026-01-10T12:05:00Z",
"data": {
"activity_id": "act_abc123",
"user_uid": "Drt0n1i6y1UVF8wqydT3ckQewM22",
"mcd_amount": "50.00",
"tx_signature": "5xyz...abc",
"block_height": 12345678
}
}
13.4.4 签名验证
import hmac
import hashlib
def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
13.5 项目级权限模型
13.5.1 项目注册
POST /v1/projects/register
Authorization: Bearer {admin_token}
{
"project_id": "double_helix",
"name": "Double Helix Trading",
"description": "Quantitative trading platform",
"webhook_url": "https://doublehelix.money/api/webhooks/microcosm",
"allowed_scopes": [
"mining:write",
"mining:read",
"funds:read"
],
"rate_limit_tier": "standard"
}
13.5.2 项目 Scopes
| Scope | 描述 | 适用场景 |
|---|---|---|
mining:write | 提交铸造活动 | Double Helix |
funds:manage | 冻结/解冻资金 | Event Horizon 拍卖 |
funds:transfer | 项目内转账 | Event Horizon 结算 |
transfer:write | 发起转账请求 | 所有需要转账的项目 |
auction:manage | 管理拍卖 | Event Horizon |
13.5.3 权限继承
| Token 类型 | 权限范围 |
|---|---|
| 用户 Token (OAuth) | 用户级权限: mcc:read, mcd:read, user:read |
| 项目 Token (API Key) | 项目级权限: mining:write, funds:manage;只能操作该项目的用户数据 |
13.6 安全模型
13.6.0 核心安全原则 ⚠️ 重要
零信任安全模型 - Microcosm 是链上数据的唯一控制者:
| # | 原则 | 详细说明 |
|---|---|---|
| 1 | Microcosm 持有所有 Authority 密钥 | MCC Token Mint Authority、MCD Token Mint Authority、Territory NFT Mint Authority、所有 PDA 控制权 |
| 2 | 项目开发者没有任何链上写入能力 | 项目不能直接调用 Solana 合约,不能持有任何 Authority 密钥,只能通过 Microcosm API 请求执行操作 |
| 3 | Microcosm 不信任项目传入的数据 | 项目声称"用户已充值 100 USDC" -- Microcosm 必须链上验证;项目声称"铸造活动有效" -- 必须独立验证交易证明;项目声称"资金已到账" -- 必须确认链上交易状态 |
| 4 | 资金到账必须链上确认 | 充值: 监听链上 Transfer 事件确认到账后才记入账户;铸造奖励: Microcosm 自己发起 Mint,不接受项目"已发放"声明;转账: 必须等待链上交易 finalized 才确认成功 |
| 5 | 每笔交易必须有唯一 ID (防止重复提交) | idempotency_key: 项目必须为每个操作提供唯一标识;24 小时内同一 key 只能使用一次;防止网络抖动导致的重复请求 |
| 6 | 项目必须使用 API 签名 | 请求头包含 X-Project-Signature;使用 HMAC-SHA256 签名请求体;验证失败直接拒绝请求 |
| 7 | 所有敏感操作有审计日志 | 记录: 项目 ID、用户 UID、操作类型、请求/响应、时间戳;日志不可篡改 (Cloud Logging + BigQuery 归档);支持事后审计和异常检测 |
13.6.1 API 签名验证
所有交易类 API 请求必须携带签名,用于验证请求来源和防止篡改。
请求头:
X-Project-ID: double_helix
X-Timestamp: 1704700800
X-Signature: sha256=abc123...
签名生成算法:
import hmac
import hashlib
import json
import time
def generate_signature(api_secret: str, method: str, path: str, body: dict, timestamp: int) -> str:
"""
生成 API 请求签名
签名格式: HMAC-SHA256(secret, method + path + timestamp + body_json)
"""
body_json = json.dumps(body, separators=(',', ':'), sort_keys=True)
payload = f"{method}\n{path}\n{timestamp}\n{body_json}"
signature = hmac.new(
api_secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return f"sha256={signature}"
# 使用示例
signature = generate_signature(
api_secret="whsec_xxx...",
method="POST",
path="/v1/mining/submit-activity",
body={"user_uid": "user123", "activity_type": "trading", ...},
timestamp=int(time.time())
)
服务端验证:
def verify_signature(request) -> bool:
project_id = request.headers.get("X-Project-ID")
timestamp = int(request.headers.get("X-Timestamp", 0))
signature = request.headers.get("X-Signature", "")
# 1. 时间戳验证 (5分钟窗口)
if abs(time.time() - timestamp) > 300:
return False
# 2. 获取项目密钥
api_secret = get_project_secret(project_id)
if not api_secret:
return False
# 3. 重新计算签名
expected = generate_signature(
api_secret=api_secret,
method=request.method,
path=request.path,
body=request.json(),
timestamp=timestamp
)
# 4. 常量时间比较
return hmac.compare_digest(expected, signature)
13.6.2 防重放攻击
- 幂等键 (Idempotency Key): 所有写入操作必须携带
- 时间窗口: 请求时间戳与服务器时间差不超过 5 分钟
- Nonce 检查: 同一幂等键 24 小时内不可重复使用
幂等键使用:
# Redis 存储已使用的 idempotency_key
def check_idempotency(key: str) -> bool:
"""返回 True 表示该 key 首次使用,False 表示重复"""
result = redis.set(f"idempotency:{key}", "1", nx=True, ex=86400) # 24小时过期
return result is not None
13.6.3 操作审计
-- 所有交易类操作记录
CREATE TABLE transaction_audit_log (
id SERIAL PRIMARY KEY,
project_id VARCHAR(50) NOT NULL,
operation_type VARCHAR(50) NOT NULL, -- 'mining_submit', 'funds_lock', 'transfer'
user_uid VARCHAR(100) NOT NULL,
request_body JSONB NOT NULL,
response_body JSONB,
status VARCHAR(20) NOT NULL, -- 'success', 'failed', 'pending'
idempotency_key VARCHAR(100) UNIQUE,
ip_address INET,
created_at TIMESTAMP DEFAULT NOW()
);
13.6.3 限额控制
| 操作 | 单次限额 | 每日限额 | 适用项目 |
|---|---|---|---|
| 铸造提交 | 1000 MCD | 10000 MCD | Double Helix |
| 资金冻结 | 10000 MCC | 100000 MCC | Event Horizon |
| 转账请求 | 5000 MCC | 50000 MCC | 所有项目 |
13.7 实施任务
| 任务 | 描述 | 产出 | 状态 |
|---|---|---|---|
| 5.1 铸造提交 API | 实现 /v1/mining/submit-activity | API 端点 | ⏳ |
| 5.2 资金管理 API | 实现 /v1/funds/* 系列端点 | API 端点 | ⏳ |
| 5.3 转账请求 API | 实现 /v1/transfer/* 系列端点 | API 端点 | ⏳ |
| 5.4 Webhook 系统 | 实现 Webhook 注册和发送 | Webhook 服务 | ⏳ |
| 5.5 项目注册 | 实现项目管理 API | 管理端点 | ⏳ |
| 5.6 审计日志 | 实现交易审计系统 | 数据库表 + 日志 | ⏳ |
| 5.7 限额控制 | 实现操作限额检查 | 中间件 | ⏳ |
13.8 第三方项目接入流程
- 项目注册: 在 Microcosm Developer Portal 注册项目,获取 project_id 和 api_secret,配置 Webhook URL
- 配置权限: 申请所需 Scopes (需审核),设置 IP 白名单 (可选),配置限额 (可选)
- 集成开发: 使用 SDK 或直接调用 API,实现 Webhook 接收端点,实现签名验证
- 测试验证: 使用沙箱环境测试,验证 Webhook 接收,验证错误处理
- 上线: 切换到生产环境,监控 API 调用状态
14. 场景示例
14.1 Double Helix 铸造场景
参与方: Double Helix (策略 Pod) / Microcosm Open API / Solana Chain
| 步骤 | 发送方 | 接收方 | 操作 |
|---|---|---|---|
| 1 | - | Double Helix | 用户完成一笔交易,profit = 250 USDC |
| 2 | Double Helix | Microcosm | POST /v1/mining/submit-activity { user_uid, trade_volume, proof } |
| 3 | - | Microcosm | 验证项目权限 |
| 4 | - | Microcosm | 验证交易证明 |
| 5 | - | Microcosm | 计算 MCD 奖励: 50 MCD |
| 6 | Microcosm | Double Helix | 返回 { status: "pending_onchain" } |
| 7 | Microcosm | Solana | 调用 blockchain-service,Mint 50 MCD to user |
| 8 | Solana | Microcosm | 返回 tx_signature |
| 9 | Microcosm | Double Helix | Webhook: mining.reward.confirmed { mcd_amount: 50, tx_sig: ... } |
14.2 Event Horizon 拍卖场景
参与方: Event Horizon (预测市场) / Microcosm Open API / Solana Chain
用户出价阶段:
| 步骤 | 发送方 | 接收方 | 操作 |
|---|---|---|---|
| 1 | Event Horizon | Microcosm | POST /v1/funds/lock { user_uid, amount: 100 MCC, reason: "auction_bid" } |
| 2 | - | Microcosm | 检查余额 |
| 3 | - | Microcosm | 冻结 100 MCC |
| 4 | Microcosm | Event Horizon | 返回 { status: "locked" } |
拍卖进行中,可能有多次出价...
拍卖结束阶段:
| 步骤 | 发送方 | 接收方 | 操作 |
|---|---|---|---|
| 5 | Event Horizon | Microcosm | POST /v1/transfer/request { from: bidder, to: seller, amount: 100 MCC } |
| 6 | - | Microcosm | 验证冻结资金 |
| 7 | Microcosm | Solana | 解冻 + Transfer on-chain |
| 8 | Solana | Microcosm | 链上确认 |
| 9 | Microcosm | Event Horizon | Webhook: transfer.completed { tx_signature: ... } |
| 10 | Event Horizon | Microcosm | POST /v1/funds/unlock { lock_id: ..., reason: "outbid" } |
| 11 | - | Microcosm | 解冻落选者资金 |
| 12 | Microcosm | Event Horizon | 返回 { status: "unlocked" } |
15. Phase 6: 用户画像 API 架构设计
核心理念: Microcosm 作为用户档案中心,聚合所有项目的用户属性数据,提供跨项目的用户画像查询能力。
15.1 用户角色模型
Microcosm 生态中有三种角色类型:
| 角色 | 范围 | 来源 | 说明 |
|---|---|---|---|
| Microcosm 角色 | 全局 | Microcosm 核心系统 | admin, unit_manager, unit_member, user 等 |
| 项目角色 | 项目内 | 各项目系统 | 如 Double Helix 的 trader, Event Horizon 的 bettor |
| 组织角色 | 组织内 | 组织系统 | 组织内的职位和权限 |
15.2 属性累积模型
用户属性累积模型
示例用户 UID:
Drt0n1i6y1UVF8wqydT3ckQewM22
Microcosm 基础属性 (全局可见):
| 属性 | 示例值 |
|---|---|
| user@example.com | |
| displayName | "用户昵称" |
| role | "unit_member" |
| mcc_balance | 1000.00 |
| mcd_balance | 5000.00 |
| created_at | "2024-01-15" |
Double Helix 属性 (项目私有,需授权访问):
| 属性 | 示例值 |
|---|---|
| project_role | "trader" |
| total_trade_volume | 150000.00 |
| total_profit | 3500.00 |
| active_strategies | 3 |
| risk_level | "medium" |
| last_trade_at | "2026-01-09" |
Event Horizon 属性 (项目私有,需授权访问):
| 属性 | 示例值 |
|---|---|
| project_role | "bettor" |
| total_bets | 45 |
| win_rate | 0.62 |
| prediction_accuracy | 0.71 |
| badges | ["early_adopter", "prediction_master"] |
15.3 属性可见性规则
| 属性类型 | 可见性 | 说明 |
|---|---|---|
| Microcosm 基础属性 | 公开 | 所有已登录用户可查询任意用户的基础信息 |
| 项目属性 (visibility=public) | 公开 | 项目设置为公开的属性,任何人可查询 |
| 项目属性 (visibility=private) | 私有 | 仅用户本人和该项目可查询 |
| 项目属性 (visibility=authorized) | 授权 | 用户授权的项目可查询 |
15.4 API 端点设计
15.4.1 读取类 API (OAuth Token 认证)
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/users/{uid}/profile | 获取用户 Microcosm 基础画像 | user:read |
| GET | /v1/users/{uid}/projects/{project_id}/attributes | 获取用户在特定项目的属性 | user:read + 可见性检查 |
| GET | /v1/users/{uid}/full-profile | 获取用户完整画像 (含所有可见项目属性) | user:read |
15.4.2 写入类 API (项目签名认证)
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| POST | /v1/users/{uid}/attributes | 项目上报用户属性 | 项目签名 |
| DELETE | /v1/users/{uid}/attributes | 项目删除用户属性 | 项目签名 |
| POST | /v1/users/batch/attributes | 批量查询用户属性 | 项目签名 |
15.4.3 公开 API (无需认证)
| 方法 | 端点 | 描述 | 权限 |
|---|---|---|---|
| GET | /v1/projects/{project_id}/status | 获取项目状态 | 公开 |
15.5 数据库设计
-- 用户项目属性表
CREATE TABLE user_project_attributes (
id SERIAL PRIMARY KEY,
uid VARCHAR(100) NOT NULL, -- 用户 UID
project_id VARCHAR(50) NOT NULL, -- 项目 ID
attribute_key VARCHAR(100) NOT NULL, -- 属性键
attribute_value JSONB NOT NULL, -- 属性值 (支持复杂结构)
visibility VARCHAR(20) DEFAULT 'private', -- public/private/authorized
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(uid, project_id, attribute_key)
);
-- 项目状态历史表
CREATE TABLE project_status_history (
id SERIAL PRIMARY KEY,
project_id VARCHAR(50) NOT NULL,
status VARCHAR(20) NOT NULL, -- active/maintenance/testing/discontinued/deleted
reason TEXT,
changed_by VARCHAR(100), -- 操作者 UID
created_at TIMESTAMP DEFAULT NOW()
);
-- 索引
CREATE INDEX idx_user_project_attrs_uid ON user_project_attributes(uid);
CREATE INDEX idx_user_project_attrs_project ON user_project_attributes(project_id);
CREATE INDEX idx_project_status_history ON project_status_history(project_id, created_at DESC);
15.6 项目状态生命周期
- active (正常运营) --> maintenance (维护中) --> 可恢复为 active
- active (正常运营) --> testing (测试中) --> 可恢复为 active
- active (正常运营) --> discontinued (已停运) --> deleted (已删除)
| 状态 | 说明 | 属性查询 | 属性写入 |
|---|---|---|---|
active | 正常运营 | ✅ | ✅ |
maintenance | 临时维护 | ✅ | ❌ |
testing | 测试阶段 | ✅ | ✅ |
discontinued | 已停运 | ✅ | ❌ |
deleted | 已删除 | ❌ | ❌ |
附录 C: Phase 6 实施记录
2026-01-10 Phase 6 实施完成
实施内容:
-
用户画像路由 (
routers/user_attributes.py)GET /v1/users/{uid}/profile- 获取 Microcosm 基础画像GET /v1/users/{uid}/projects/{project_id}/attributes- 获取项目属性GET /v1/users/{uid}/full-profile- 获取完整画像GET /v1/projects/{project_id}/status- 获取项目状态 (公开)POST /v1/users/{uid}/attributes- 项目上报属性DELETE /v1/users/{uid}/attributes- 删除属性POST /v1/users/batch/attributes- 批量查询
-
数据库表初始化
user_project_attributes表 (UPSERT 支持)project_status_history表
-
权限控制
- 读取 API: OAuth Token + Scope 验证
- 写入 API: 项目签名验证
- 可见性检查: public/private/authorized
新增文件:
fastapi_app/routers/user_attributes.py- 用户画像 API
更新文件:
fastapi_app/routers/__init__.py- 添加 user_attributes 导入fastapi_app/main.py- 注册新路由和表初始化
部署信息:
- 镜像:
open-api-service:phase6-user-profile - 命名空间:
microcosm
API 文档:
| 资源 | URL |
|---|---|
| Swagger UI | https://api.microcosm.money/docs |
| ReDoc | https://api.microcosm.money/redoc |
| OpenAPI Spec | https://api.microcosm.money/openapi.json |
Phase 6 新增端点:
| 分类 | 端点 | 权限 |
|---|---|---|
| User Profile | GET /v1/users/{uid}/profile | user:read |
| User Profile | GET /v1/users/{uid}/projects/{project_id}/attributes | user:read |
| User Profile | GET /v1/users/{uid}/full-profile | user:read |
| User Profile | POST /v1/users/{uid}/attributes | 项目签名 |
| User Profile | DELETE /v1/users/{uid}/attributes | 项目签名 |
| User Profile | POST /v1/users/batch/attributes | 项目签名 |
| Project | GET /v1/projects/{project_id}/status | 公开 |
2026-01-15 用户资料写入 API 实施完成
实施内容:
-
用户资料更新端点 (
routers/users.py)PATCH /v1/users/me/profile- 更新 display_namePOST /v1/users/me/avatar- 上传头像图片
-
服务间信任机制 (
user-service/app/middleware.py)- 新增
TRUSTED_INTERNAL_SERVICES列表 - 支持
X-Internal-Service+X-User-UID头部认证 - 允许 open-api-service 代理用户请求到 user-service
- 新增
-
新增 OAuth Scope
user:write- 更新用户资料权限
更新文件:
services/open-api-service/fastapi_app/routers/users.py- 添加 PATCH/POST 端点services/open-api-service/fastapi_app/dependencies.py- 添加require_user_writeservices/user-service/app/routes/users.py- 添加/profilePATCH 端点services/user-service/app/database/users.py- 添加update_display_name函数services/user-service/app/middleware.py- 添加服务间信任机制
部署版本:
- user-service: v2.1.8
- open-api-service: v1.2.0
API 文档:
| 端点 | 方法 | 权限 | 说明 |
|---|---|---|---|
/v1/users/me/profile | PATCH | user:write | 更新 display_name (1-50字符) |
/v1/users/me/avatar | POST | user:write | 上传头像 (jpg/png/gif/webp, 最大2MB) |
共享用户架构说明:
Microcosm 是统一用户平台,所有第三方项目 (Double Helix, Event Horizon 等) 共享同一用户系统。用户在任意项目更新 display_name 或 avatar 后,所有项目立即生效。
文档状态: ✅ Phase 1-3, 5, 6, 7 已部署上线,Phase 4 待实施
2026-01-16 Phase 7: Solana 合约 API 实施完成
实施内容:
-
Territory NFT API (
routers/territory.py)GET /v1/territory/collection- Collection 配置GET /v1/territory/nft/{mint}- NFT 元数据GET /v1/territory/nfts/{wallet}- 用户 NFT 列表GET /v1/territory/unit/{unit_id}/nft- 单位关联 NFT
-
Auction Solana API (
routers/auction_solana.py)GET /v1/auction-solana/config- 拍卖配置GET /v1/auction-solana/active- 活跃拍卖列表GET /v1/auction-solana/auction/{id}- 拍卖详情GET /v1/auction-solana/auction/{id}/bids- 竞价历史GET /v1/auction-solana/bids/{wallet}- 用户竞价记录GET /v1/auction-solana/auctions/{wallet}- 用户创建的拍卖
-
Fragment API (
routers/fragment.py)GET /v1/fragment/config- 碎片化配置GET /v1/fragment/vaults- 所有 Vault 列表GET /v1/fragment/vault/{id}- Vault 详情GET /v1/fragment/vault/{id}/holders- 持仓分布GET /v1/fragment/holdings/{wallet}- 用户持仓
-
Lending API (
routers/lending.py)GET /v1/lending/pool- 借贷池配置GET /v1/lending/stats- 借贷池统计GET /v1/lending/position/{wallet}- 用户仓位GET /v1/lending/loans/{wallet}- 用户贷款列表GET /v1/lending/loan/{wallet}/{loan_id}- 贷款详情GET /v1/lending/lp-balance/{wallet}- LP Token 余额POST /v1/lending/calculate-interest- 计算利息POST /v1/lending/estimate-borrow-cost- 估算借款成本
新增文件:
fastapi_app/routers/territory.py- Territory NFT APIfastapi_app/routers/auction_solana.py- Auction Solana APIfastapi_app/routers/fragment.py- Fragment APIfastapi_app/routers/lending.py- Lending API
更新文件:
fastapi_app/main.py- 注册 4 个新路由requirements.txt- 无新增依赖
部署版本:
- open-api-service: v1.1.0
API 统计:
- 新增端点: 23 个
- 总端点数: 约 50 个
2026-01-18 Open API Scope 别名映射修复
问题描述:
非 admin 角色用户(如 miner)在 Double Helix 前端无法显示头像和昵称,admin 用户正常。
根因分析:
- Open API 返回 403:
/v1/users/me/profile端点需要user:readscope - Double Helix OAuth token scope:
"openid profile email trading"- 没有user:read - admin 用户正常: RequireScope 类对 admin 角色自动跳过 scope 检查
- 共享模块缺失字段:
microcosm_common/users/repository.py的get_user_by_uid未返回display_name和avatar_url
修复内容:
修复 1: Open API Scope 别名映射 (fastapi_app/dependencies.py)
class RequireScope:
# OpenID Connect 标准 scope 到 Microcosm scope 的映射
SCOPE_ALIASES = {
"profile": {"user:read"}, # OIDC profile scope 等同于 user:read
}
async def __call__(self, request: Request) -> UserInfo:
user = await verify_oauth_token(request)
user_scopes = set(user.scopes)
# 展开 scope 别名 (OpenID Connect 兼容)
expanded_scopes = set(user_scopes)
for scope in user_scopes:
if scope in self.SCOPE_ALIASES:
expanded_scopes.update(self.SCOPE_ALIASES[scope])
# 管理员角色自动拥有所有权限
if user.role == "admin":
return user
# 检查是否拥有所需的 scope
missing_scopes = self.required_scopes - expanded_scopes
...
修复 2: 共享模块返回完整字段 (services/common/microcosm_common/users/repository.py)
def get_user_by_uid(uid: str) -> Optional[Dict[str, Any]]:
...
return {
'uid': user['uid'],
'email': user.get('email'),
'wallet_address': user.get('wallet_address'),
'role': user.get('role', 'user'),
'api_keys_configured': user.get('api_keys_configured', False),
'display_name': user.get('display_name'), # 新增
'avatar_url': user.get('avatar_url'), # 新增
'created_at': user.get('created_at'),
'updated_at': user.get('updated_at')
}
关键经验:
- OpenID Connect 兼容:
profile是 OIDC 标准 scope,应等同于user:read - admin 角色特殊: admin 自动拥有所有权限,不受 scope 限制,容易掩盖 scope 问题
- 共享模块一致性: 使用共享模块时要确保返回所有必要字段
部署版本:
- user-service: v2.1.9
- open-api-service: v1.1.2
影响范围:
- 所有非 admin 角色用户现在可以正常获取头像和昵称
- Double Helix、Event Horizon 等使用 OAuth 接入的项目均受益
2026-01-16 Double Helix OAuth Callback 用户资料修复
问题描述:
Double Helix 前端侧边栏无法显示用户头像和昵称(显示默认头像和 "User")。
根因分析:
OAuth callback 页面 (app/auth/callback/page.tsx) 在调用 authManager.setUser() 时,没有传递 displayName 和 avatarUrl 字段,即使 /api/users/profile API 已正确返回这些数据。
修复内容:
修改 c:\double-helix\services\frontend-service\app\auth\callback\page.tsx:
// 修复前 ❌
authManager.setUser({
uid: userData.uid,
email: userData.email || "",
role: finalRole as any,
apiKeysConfigured: userData.api_keys_configured || false,
})
// 修复后 ✅
authManager.setUser({
uid: userData.uid,
email: userData.email || "",
role: finalRole as any,
displayName: userData.display_name || null, // 新增
avatarUrl: userData.avatar_url || null, // 新增
apiKeysConfigured: userData.api_keys_configured || false,
})
关键经验:
- 字段名映射: API 返回
snake_case(display_name,avatar_url),前端 User 类型使用camelCase(displayName,avatarUrl) - 响应解包: Profile API 响应格式为
{success: true, user: {...}},需要兼容处理data.user || data - OAuth Callback 职责: Callback 必须在 setUser 时传递完整用户信息,包括 displayName 和 avatarUrl
部署版本:
- Double Helix frontend-service: v1.3.4
影响范围:
- 用户登录后侧边栏立即显示正确的头像和昵称
- 所有使用 Microcosm OAuth 的项目都需要注意此问题
16. 价格预言机架构
权威定义: 详见
docs/_definitions/distribution-ratios.mdv1.7 更新 (2026-01-19): 新增价格预言机架构,Open API 作为备用价格来源
16.1 架构概览
价格预言机架构 (Price Oracle Architecture)
价格来源 (按优先级):
| 优先级 | 来源 |
|---|---|
| 1 | Pyth 市场价格 |
| 2 | Open API 价格 |
| 3 | 默认 10 USDC |
以上价格来源汇入预言机服务 (链下),每 4 小时更新一次。
Reincarnation 合约 (链上):
| 参数 | 说明 |
|---|---|
| base_price | 预言机更新的 30 天均价 |
| premium_bps | 500 (5% 溢价) |
| buyback_price | base_price x 1.05 |
用户交易 (x402):
用户交易时从合约读取 buyback_price: 用户 MCC --> 合约读取 buyback_price --> 用户获得 USDC
16.2 核心原则
| 原则 | 说明 |
|---|---|
| 合约是唯一真实来源 | 用户交易价格从 Reincarnation 合约读取,不从数据库或 API |
| 合约不关心价格来源 | 合约只认预言机服务更新的 base_price |
| Open API 是备用来源 | /v1/mcc/price 作为 Pyth 不可用时的回退 |
| 价格来源有优先级 | Pyth > Open API > 默认价格 |
16.3 价格来源优先级
| 优先级 | 来源 | 说明 | 何时使用 |
|---|---|---|---|
| 1 | Pyth 市场价格 | 从 Pyth Network 获取的实时市场价格 | 正常情况下使用 |
| 2 | Open API 管理员价格 | 通过 /v1/mcc/price 设置的价格 | Pyth 不可用时回退 |
| 3 | 默认价格 | 10 USDC | 所有来源失效时的兜底 |
16.4 Open API 价格端点
GET /v1/mcc/price
获取当前 MCC 价格(供预言机服务查询)。
响应示例:
{
"data": {
"type": "mcc_price",
"attributes": {
"price_usdc": "10.50",
"source": "admin",
"updated_at": "2026-01-19T10:00:00Z"
}
}
}
POST /v1/mcc/price
设置管理员价格(仅限管理员)。
请求:
{
"price_usdc": "10.50"
}
响应:
{
"data": {
"type": "mcc_price",
"attributes": {
"price_usdc": "10.50",
"source": "admin",
"updated_at": "2026-01-19T10:00:00Z"
}
}
}
16.5 更新频率
| 组件 | 更新频率 | 说明 |
|---|---|---|
| 预言机服务 | 每 4 小时 | 聚合价格来源,计算 30 天均价 |
| 合约 base_price | 预言机触发时 | 预言机调用 update_price 指令 |
| 数据库缓存 | 每小时 | 仅用于前端展示,不用于交易 |
| 用户交易 | 实时 | 每次交易从合约读取最新价格 |
16.6 价格计算公式
base_price = AVG(30天 × 4小时收盘价) = 180 个数据点的平均值
buyback_price = base_price × 1.05 (+5% 溢价)
16.7 预言机服务职责
| 职责 | 说明 |
|---|---|
| 价格聚合 | 按优先级从多个来源获取价格 |
| 均价计算 | 计算 30 天 × 4 小时的 180 个数据点均值 |
| 合约更新 | 调用 Reincarnation 合约的 update_price 指令 |
| 价格历史 | 存储历史价格数据供均价计算 |
2026-01-19 v1.7 更新记录
新增内容:
-
价格预言机架构文档 (Section 16)
- 架构概览图
- 核心原则
- 价格来源优先级
- Open API 价格端点详细说明
- 更新频率表
- 价格计算公式
-
MCC API 端点更新 (Section 4.1.1)
- 更新
/v1/mcc/price描述:标注为预言机备用来源 - 新增
POST /v1/mcc/price端点:管理员设置价格
- 更新
关键架构变更:
- Open API
/v1/mcc/price现在是价格预言机服务的备用来源(优先级 2) - 预言机服务聚合价格后更新合约,合约是用户交易的唯一价格来源
- 遵循 x402 非托管架构:用户交易直接读取合约价格
17. Phase 8: 项目注册与 MCD 白名单管理
17.1 概述
本章节描述项目开发者注册流程和 MCD 钱包白名单管理机制。开发者在申请 Project ID 时需提交 MCC/MCD 钱包地址,管理员审核后将项目添加到链上白名单。
17.2 架构概览
项目注册与白名单流程:
| 步骤 | 操作方 | 动作 | 结果 |
|---|---|---|---|
| 1 | 开发者 (Portal) | 提交项目申请 | 数据库记录状态为 pending |
| 2 | 管理员 (Admin) | 审核申请 (Open API) | 状态更新为 approved |
| 3 | 系统 (Solana) | 链上同步白名单 | 创建 Whitelist PDA |
17.3 数据库表设计
17.3.1 project_applications 表
CREATE TABLE project_applications (
id SERIAL PRIMARY KEY,
application_id VARCHAR(36) NOT NULL UNIQUE, -- UUID
project_name VARCHAR(100) NOT NULL, -- 项目名称
project_description TEXT, -- 项目描述
developer_uid VARCHAR(100) NOT NULL, -- 申请人 Firebase UID
developer_email VARCHAR(255) NOT NULL, -- 申请人邮箱
company_name VARCHAR(100), -- 公司名称
website_url VARCHAR(255), -- 项目官网
-- 钱包地址
mcc_wallet_address VARCHAR(64), -- MCC 收款钱包地址
mcd_wallet_address VARCHAR(64) NOT NULL, -- MCD 收款钱包地址 (必填)
-- 审核信息
status VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending/approved/rejected/suspended
reviewed_by VARCHAR(100), -- 审核人 UID
reviewed_at TIMESTAMP, -- 审核时间
rejection_reason TEXT, -- 拒绝原因
-- 批准后生成
project_id INTEGER, -- 数据库自增 ID (审批后生成)
api_key VARCHAR(64), -- API Key (审批后生成)
api_secret_hash VARCHAR(128), -- API Secret Hash
-- 链上信息
whitelist_pda VARCHAR(64), -- 链上白名单 PDA 地址
whitelist_bump INTEGER, -- PDA bump
whitelist_tx VARCHAR(128), -- 上链交易签名
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_project_apps_status ON project_applications(status);
CREATE INDEX idx_project_apps_developer ON project_applications(developer_uid);
CREATE INDEX idx_project_apps_project_id ON project_applications(project_id);
17.3.2 mcd_wallet_whitelist 表
-- 此表已存在于 organization-service
-- 参考 CLAUDE.md 中的 MCD 白名单机制说明
CREATE TABLE mcd_wallet_whitelist (
id SERIAL PRIMARY KEY,
project_id INTEGER NOT NULL UNIQUE,
project_name VARCHAR(100) NOT NULL,
wallet_address VARCHAR(64) NOT NULL,
pda_address VARCHAR(64), -- 链上 PDA 地址
pda_bump INTEGER,
status VARCHAR(20) NOT NULL DEFAULT 'active', -- active/suspended/removed
created_by VARCHAR(100) NOT NULL, -- 创建人 UID
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_whitelist_wallet ON mcd_wallet_whitelist(wallet_address);
CREATE INDEX idx_whitelist_status ON mcd_wallet_whitelist(status);
17.4 API 端点定义
17.4.1 项目申请 API
POST /v1/projects/apply
开发者提交项目申请。
请求头:
Authorization: Bearer {firebase_id_token}
请求体:
{
"project_name": "My DApp",
"project_description": "A decentralized application for...",
"company_name": "My Company Ltd.",
"website_url": "https://mydapp.com",
"mcc_wallet_address": "5uo1HYjQXokE9UAd8UYiwAKomL5WACqpQMbV2Ftk7pXx",
"mcd_wallet_address": "GaQdEfHjJar2X3Kqo8ptAgyretc6hakX8ZqeLW1cmRuS" // 官方开发者项目备用钱包地址
}
响应 (201 Created):
{
"data": {
"type": "project_application",
"id": "app-uuid-12345",
"attributes": {
"project_name": "My DApp",
"status": "pending",
"mcd_wallet_address": "GaQdEfHjJar2X3Kqo8ptAgyretc6hakX8ZqeLW1cmRuS" // 官方开发者项目备用钱包地址,
"created_at": "2026-01-26T10:00:00Z"
}
}
}
验证规则:
mcd_wallet_address必填,必须是有效的 Solana Base58 地址mcc_wallet_address选填,如果提供必须是有效地址project_name长度 3-100 字符- 同一用户最多有 1 个 pending 状态的申请
GET /v1/projects/applications
查询当前用户的申请记录。
响应:
{
"data": [
{
"type": "project_application",
"id": "app-uuid-12345",
"attributes": {
"project_name": "My DApp",
"status": "approved",
"project_id": 2,
"api_key": "mc_live_abc123...",
"created_at": "2026-01-26T10:00:00Z",
"reviewed_at": "2026-01-26T12:00:00Z"
}
}
]
}
GET /v1/projects/applications/{application_id}
查询单个申请详情。
17.4.2 管理员审核 API
GET /v1/admin/projects/applications
获取所有项目申请列表(管理员)。
请求参数:
?status=pending # 筛选状态: pending/approved/rejected/all
?page=1&per_page=20 # 分页
响应:
{
"data": [
{
"type": "project_application",
"id": "app-uuid-12345",
"attributes": {
"project_name": "My DApp",
"developer_email": "dev@example.com",
"company_name": "My Company Ltd.",
"mcd_wallet_address": "GaQdEfHjJar2X3Kqo8ptAgyretc6hakX8ZqeLW1cmRuS" // 官方开发者项目备用钱包地址,
"status": "pending",
"created_at": "2026-01-26T10:00:00Z"
}
}
],
"meta": {
"total": 15,
"page": 1,
"per_page": 20
}
}
POST /v1/admin/projects/applications/{application_id}/approve
批准项目申请,自动创建 Project ID、API Key 并同步到链上白名单。
响应 (200 OK):
{
"data": {
"type": "project_application",
"id": "app-uuid-12345",
"attributes": {
"status": "approved",
"project_id": 2,
"api_key": "mc_live_xxxxxxxxxxxxxxxx",
"api_secret": "mc_secret_yyyyyyyyyyyy",
"whitelist_pda": "2sKFrgbgekkhw3jZgJiskP1YVhwKYrMkfLRTjHgD1Kio",
"whitelist_tx": "5ScZLQTuFqw3..."
}
}
}
注意: api_secret 仅在批准响应中返回一次,需提醒开发者妥善保存。
POST /v1/admin/projects/applications/{application_id}/reject
拒绝项目申请。
请求体:
{
"reason": "项目描述不符合接入标准"
}
17.4.3 MCD 白名单管理 API
GET /v1/admin/mcd/whitelist
获取 MCD 白名单列表。
响应:
{
"data": [
{
"type": "mcd_whitelist_entry",
"id": "1",
"attributes": {
"project_id": 2,
"project_name": "Double Helix",
"wallet_address": "4E4qsLLG2P88vLGTE4n39ayjaRAExbZRUdhJkrPCiBEA",
"pda_address": "4Ch4RXdjUf5Mjw2L9R9zemCTRwTk1iE8rySrYq8rnnB7",
"status": "active",
"created_at": "2026-01-26T00:00:00Z"
}
}
]
}
PUT /v1/admin/mcd/whitelist/{project_id}/status
更新白名单状态(暂停/激活)。
请求体:
{
"status": "suspended"
}
响应:
{
"data": {
"type": "mcd_whitelist_entry",
"id": "1",
"attributes": {
"status": "suspended",
"updated_at": "2026-01-26T15:00:00Z"
}
}
}
DELETE /v1/admin/mcd/whitelist/{project_id}
从白名单移除项目(链上 + 数据库)。
响应 (200 OK):
{
"data": {
"message": "Project removed from whitelist",
"remove_tx": "3kSVduyRZjYZAB2..."
}
}
17.5 链上白名单操作
17.5.1 PDA 派生
# Python 实现 (blockchain-service)
from solders.pubkey import Pubkey
MCD_PROGRAM_ID = Pubkey.from_string("J9UwVmFEr7ujLcp19T8nqpDnpBLcDzpL4cpwh5TMSd36")
MCD_WHITELIST_SEED = b"mcd_whitelist"
def get_whitelist_pda(project_id: int) -> tuple[Pubkey, int]:
"""计算白名单 PDA 地址"""
project_id_bytes = project_id.to_bytes(8, 'little')
pda, bump = Pubkey.find_program_address(
[MCD_WHITELIST_SEED, project_id_bytes],
MCD_PROGRAM_ID
)
return pda, bump
17.5.2 添加到白名单
async def add_to_whitelist(
project_id: int,
project_name: str,
wallet_address: str
) -> str:
"""
调用 MCD 合约 add_to_whitelist 指令
返回交易签名
"""
# 1. 计算 PDA
whitelist_pda, bump = get_whitelist_pda(project_id)
# 2. 构造指令
discriminator = get_instruction_discriminator("add_to_whitelist")
# [8 bytes discriminator] + [8 bytes project_id] + [4 bytes name_len] + [name bytes]
# 3. 发送交易
tx_sig = await send_transaction(...)
return tx_sig
17.5.3 链上指令列表
| 指令 | 用途 | 权限 |
|---|---|---|
add_to_whitelist | 添加项目到白名单 | 管理员 (authority) |
remove_from_whitelist | 移除项目 | 管理员 |
update_whitelist_status | 更新状态 (active/suspended) | 管理员 |
17.6 前端管理页面
17.6.1 开发者申请页面
路径: /developer/apply
功能:
- 填写项目信息表单
- 输入 MCC/MCD 钱包地址
- 钱包地址格式验证
- 提交申请
组件结构:
// app/(dashboard)/developer/apply/page.tsx
export default function ProjectApplicationPage() {
return (
<div className="container mx-auto py-8">
<h1>申请项目接入</h1>
<ProjectApplicationForm />
</div>
)
}
17.6.2 管理员项目审核页面
路径: /admin/project-applications
功能:
- 项目申请列表(按状态筛选)
- 查看申请详情
- 批准/拒绝操作
- 批准后显示生成的 API Key
组件结构:
// app/(dashboard)/admin/project-applications/page.tsx
export default function ProjectApplicationsAdminPage() {
return (
<div className="container mx-auto py-8">
<h1>项目申请管理</h1>
<Tabs defaultValue="pending">
<TabsList>
<TabsTrigger value="pending">待审核</TabsTrigger>
<TabsTrigger value="approved">已批准</TabsTrigger>
<TabsTrigger value="rejected">已拒绝</TabsTrigger>
</TabsList>
<TabsContent value="pending">
<ApplicationList status="pending" />
</TabsContent>
{/* ... */}
</Tabs>
</div>
)
}
17.6.3 MCD 白名单管理页面
路径: /admin/mcd-whitelist
功能:
- 白名单项目列表
- 项目状态管理(激活/暂停)
- 移除项目
- 链上 PDA 地址显示
- 交易记录查看
组件结构:
// app/(dashboard)/admin/mcd-whitelist/page.tsx
export default function McdWhitelistAdminPage() {
return (
<div className="container mx-auto py-8">
<h1>MCD 白名单管理</h1>
<WhitelistTable />
</div>
)
}
17.7 安全考虑
| 安全措施 | 说明 |
|---|---|
| 钱包地址验证 | 验证 Base58 格式,检查链上账户是否存在 |
| 权限控制 | 只有管理员可以批准/拒绝申请 |
| API Secret 安全 | 只在批准时返回一次,存储 hash 值 |
| 链上验证 | consume_mcd 指令验证目标地址是否在白名单 |
| 审计日志 | 所有审核操作记录到 audit_logs 表 |
17.8 实施清单
| 阶段 | 任务 | 服务 | 状态 |
|---|---|---|---|
| 1 | 创建 project_applications 表 | database | ✅ 完成 |
| 2 | 实现项目申请 API | open-api-service | ✅ 完成 |
| 3 | 实现管理员审核 API | open-api-service | ✅ 完成 |
| 4 | 集成链上白名单操作 | blockchain-service | ✅ 完成 |
| 5 | 开发者申请页面 | portal-service | ⏳ 待实施 |
| 6 | 管理员审核页面 | portal-service | ✅ 完成 |
| 7 | MCD 白名单管理页面 | portal-service | ✅ 完成 |
2026-01-25 v1.9 Phase 8 实施完成
✅ 已实施功能:
-
数据库 (✅ 完成)
project_applications表已创建mcd_wallet_whitelist表已创建
-
open-api-service v1.1.8 (✅ 完成)
POST /api/open/projects/applications- 开发者提交项目申请GET /api/open/projects/applications- 查询申请记录GET /api/open/admin/projects/applications- 管理员查看申请列表POST /api/open/admin/projects/applications/{id}/approve- 批准申请POST /api/open/admin/projects/applications/{id}/reject- 拒绝申请GET /api/open/admin/mcd/whitelist- 获取白名单列表PUT /api/open/admin/mcd/whitelist/{project_id}/status- 更新白名单状态DELETE /api/open/admin/mcd/whitelist/{project_id}- 移除白名单
-
blockchain-service v1.2.28 (✅ 完成)
McdService.add_to_whitelist()- 链上添加白名单McdService.update_whitelist_status()- 链上更新状态McdService.remove_from_whitelist()- 链上移除白名单
-
portal-service v1.7.23 (✅ 完成)
/admin/project-applications- 项目申请审核页面/admin/mcd-whitelist- MCD 白名单管理页面- 管理员菜单已添加两个新入口
待实施:
- 开发者申请页面 (用户端)
2026-01-26 v1.8 更新记录
新增内容:
-
Phase 8: 项目注册与 MCD 白名单管理 (Section 17)
- 完整的项目申请流程设计
- 数据库表结构 (
project_applications) - 开发者申请 API (
POST /v1/projects/apply) - 管理员审核 API (
/v1/admin/projects/applications/*) - MCD 白名单管理 API (
/v1/admin/mcd/whitelist/*) - 链上白名单操作说明
- 前端页面设计
-
新增 API 端点:
POST /v1/projects/apply- 开发者提交项目申请GET /v1/projects/applications- 查询申请记录GET /v1/admin/projects/applications- 管理员查看申请列表POST /v1/admin/projects/applications/{id}/approve- 批准申请POST /v1/admin/projects/applications/{id}/reject- 拒绝申请GET /v1/admin/mcd/whitelist- 获取白名单列表PUT /v1/admin/mcd/whitelist/{project_id}/status- 更新白名单状态DELETE /v1/admin/mcd/whitelist/{project_id}- 移除白名单
关键设计:
- 开发者申请时必须提交 MCD 钱包地址
- 管理员批准后自动生成 Project ID、API Key
- 批准后自动调用链上
add_to_whitelist指令 - 支持白名单状态管理(激活/暂停/移除)