# Holders API 接口文档

## 概述
持有者统计页面使用以下 RESTful API 接口与后端通信。

## API 基础路径
```typescript
const API_BASE_URL = '/api'
```

开发环境代理配置：`/api/*` → `http://localhost:8080/api/*`

---

## 接口列表

### 1. 获取统计数据
获取所有代币类型的持有者统计信息。

**请求**
```http
GET /api/holders/stats
```

**响应**
```json
{
  "success": true,
  "data": [
    {
      "token_type": "YT-A",
      "holder_count": 150,
      "total_balance": 1000000
    },
    {
      "token_type": "YT-B",
      "holder_count": 80,
      "total_balance": 500000
    }
  ]
}
```

**数据结构**
- `token_type`: string - 代币类型 (YT-A, YT-B, YT-C, ytLP, Lending)
- `holder_count`: number - 持有者数量
- `total_balance`: number - 总余额

---

### 2. 获取持有者列表
获取指定代币类型的详细持有者列表。

**请求**
```http
GET /api/holders/{type}
```

**路径参数**
- `type`: string - 代币类型，可选值：`YT-A` | `YT-B` | `YT-C` | `ytLP` | `Lending`

**示例**
```http
GET /api/holders/YT-A
```

**响应**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "holder_address": "0x1234567890abcdef1234567890abcdef12345678",
      "token_type": "YT-A",
      "token_address": "0x0cA35994F033685E7a57ef9bc5d00dd3cf927330",
      "balance": "1000000000000000000",
      "first_seen": 1707800000,
      "last_updated": 1707900000
    }
  ]
}
```

**数据结构**
- `id`: number - 记录 ID
- `holder_address`: string - 持有者地址 (42位十六进制)
- `token_type`: string - 代币类型
- `token_address`: string - 代币合约地址
- `balance`: string - 余额 (wei 格式，需要使用 formatUnits 转换)
- `first_seen`: number - 首次持有时间戳 (Unix timestamp, 秒)
- `last_updated`: number - 最后更新时间戳 (Unix timestamp, 秒)

---

### 3. 手动触发更新
手动触发后端从区块链同步最新的持有者数据。

**请求**
```http
POST /api/holders/update
```

**响应**
```json
{
  "success": true,
  "message": "Update triggered successfully"
}
```

**错误响应**
```json
{
  "success": false,
  "error": "Update failed: reason"
}
```

**说明**
- 触发更新后，建议等待 5 秒再刷新数据（前端已实现）
- 频繁调用可能对后端造成压力，建议限制调用频率

---

## 错误处理

所有接口在失败时返回：
```json
{
  "success": false,
  "error": "错误信息"
}
```

常见错误类型：
- 网络错误：`Network error: [详细信息]`
- 数据获取失败：`Failed to fetch holders/stats`
- 更新失败：`Update failed`

---

## 前端使用示例

```typescript
// 获取统计数据
const fetchStats = async () => {
  try {
    const response = await fetch('/api/holders/stats');
    const data = await response.json();
    if (data.success) {
      setStats(data.data);
    }
  } catch (err) {
    console.error('Failed to fetch stats:', err);
  }
};

// 获取持有者列表
const fetchHolders = async (type: string) => {
  try {
    const response = await fetch(`/api/holders/${type}`);
    const data = await response.json();
    if (data.success) {
      setHolders(data.data);
    }
  } catch (err) {
    console.error('Failed to fetch holders:', err);
  }
};

// 触发更新
const triggerUpdate = async () => {
  try {
    const response = await fetch('/api/holders/update', {
      method: 'POST'
    });
    const data = await response.json();
    if (data.success) {
      // 等待 5 秒后刷新数据
      setTimeout(() => {
        fetchHolders(selectedType);
        fetchStats();
      }, 5000);
    }
  } catch (err) {
    console.error('Failed to trigger update:', err);
  }
};
```

---

## 后端实现注意事项

1. **API 路径规范**：使用 RESTful 风格，所有 holders 相关接口统一在 `/api/holders/*` 路径下

2. **数据格式**：
   - 余额使用 wei 格式字符串（避免精度丢失）
   - 时间戳使用 Unix timestamp（秒）
   - 地址使用小写十六进制格式

3. **性能优化**：
   - 建议实现缓存机制
   - 更新操作应该是异步的，不阻塞响应
   - 统计数据可以定期预计算

4. **安全性**：
   - 验证 token_type 参数是否在允许的值范围内
   - 限制更新接口的调用频率（防止滥用）
   - 对地址进行格式验证

---

## 版本历史

- **v2.0** (2024-02-13): 规范化 API 路径为 `/api/holders/*`
- **v1.0**: 初始版本，使用 `/api/stats` 和 `/api/update`（已废弃）
