API Reference Documentation
基础信息
- Base URL:
http://opinionanalytics.xyz:10001 - 协议: HTTP/1.1
- 数据格式: JSON
- 字符编码: UTF-8
通用响应格式
成功响应(分页)
{
success: true,
data: T[],
pagination: {
page: number, // 当前页码
pageSize: number, // 每页数量
total: number, // 总记录数
totalPages: number // 总页数
}
}成功响应(列表)
{
success: true,
data: T[],
total: number // 总记录数
}成功响应(单条)
{
success: true,
data: T
}错误响应
{
success: false,
error: {
message: string, // 错误消息
code?: string // 错误代码(可选)
}
}分页参数
所有支持分页的接口都接受以下查询参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| page | number | 否 | 1 | 页码,从 1 开始 |
| pageSize | number | 否 | 20 | 每页数量,最大 100 |
订单接口
GET /api/orders/recent
获取最近的吃单订单列表。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| startTime | number | 否 | 开始时间(Unix 时间戳,秒) |
| endTime | number | 否 | 结束时间(Unix 时间戳,秒) |
| page | number | 否 | 页码(默认 1) |
| pageSize | number | 否 | 每页数量(默认 20,最大 100) |
响应
成功 (200)
{
success: true,
data: AggregatedTakerOrder[],
pagination: {
page: number,
pageSize: number,
total: number,
totalPages: number
}
}AggregatedTakerOrder 结构
{
orderHash: string, // 订单哈希
maker: string, // Maker 地址
makerAssetId: string, // Maker 资产 ID(BigInt 字符串)
takerAssetId: string, // Taker 资产 ID(BigInt 字符串)
totalMakerAmountFilled: string, // 聚合的 Maker 成交量(BigInt 字符串)
totalTakerAmountFilled: string, // 聚合的 Taker 成交量(BigInt 字符串)
totalFee: string, // 聚合的手续费(USDT,BigInt 字符串)
side: "BUY" | "SELL", // 订单方向
price: string, // 订单价格(保留三位小数)
assetId: string, // 实际交易的资产 ID
fillCount: number, // 成交次数
firstFillTime: number, // 首次成交时间(Unix 时间戳,秒)
lastFillTime: number, // 最后成交时间(Unix 时间戳,秒)
txHashes: string[], // 交易哈希列表
amount: string, // 交易额(USDT,保留两位小数)
shares: string // 交易量(token 数量,保留两位小数)
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/orders/recent?page=1&pageSize=2"GET /api/orders/by-asset/:assetId
按 Asset ID 查询吃单交易信息。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetId | string | 是 | Asset ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| startTime | number | 否 | 开始时间(Unix 时间戳,秒) |
| endTime | number | 否 | 结束时间(Unix 时间戳,秒) |
| page | number | 否 | 页码(默认 1) |
| pageSize | number | 否 | 每页数量(默认 20,最大 100) |
| filter | string | 否 | 筛选类型:'all' | 'taker' | 'maker'(默认 'taker') |
响应
与 /api/orders/recent 响应格式相同。
示例
请求
curl "http://opinionanalytics.xyz:10001/api/orders/by-asset/72328986599454660492851558931881986229058826133693803755503603230417419524977?page=1&pageSize=10&filter=all"GET /api/orders/tx/:txHash
根据 txHash 获取交易详情。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| txHash | string | 是 | 交易哈希(以 0x 开头) |
响应
成功 (200)
{
success: true,
data: TxDetail
}未找到 (404)
{
success: false,
error: {
message: "Transaction not found"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/orders/tx/0xb44dccaa91caeaab279824ffb8d20a70b029f47e154a63ae60fb8c1bf32fc398"GET /api/orders/order/:orderHash
根据 orderHash 获取所有相关的交易详情。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| orderHash | string | 是 | 订单哈希(以 0x 开头) |
响应
成功 (200)
{
success: true,
data: {
orderHash: string,
txCount: number,
transactions: TxDetail[]
}
}未找到 (404)
{
success: false,
error: {
message: "Order not found"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/orders/order/0x51c955bce965cf2f921af4babb542a63784e42f7403dcfa45bc468a81859db22"GET /api/orders/by-maker/:maker
按 Maker 地址查询订单列表。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| maker | string | 是 | Maker 地址(以 0x 开头的以太坊地址) |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | number | 否 | 页码(默认 1) |
| pageSize | number | 否 | 每页数量(默认 20,最大 100) |
响应
与 /api/orders/recent 响应格式相同。
示例
请求
curl "http://opinionanalytics.xyz:10001/api/orders/by-maker/0x66ffba070e8e5961c37607e57049acd1fb3e2b37?page=1&pageSize=10"市场接口
GET /api/markets
获取所有市场列表。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: Market[],
total: number
}Market 结构
{
marketId: number, // 市场 ID
marketTitle: string, // 市场标题
status: number, // 市场状态码
statusEnum: string, // 市场状态枚举(Activated/Resolved 等)
childMarkets: Market[] | null, // 子市场列表
yesLabel: string, // Yes 标签
noLabel: string, // No 标签
rules: string, // 市场规则
yesTokenId: string, // Yes Token ID
noTokenId: string, // No Token ID
conditionId: string, // 条件 ID
resultTokenId: string, // 结果 Token ID
volume: string, // 交易量
quoteToken: string, // 报价代币地址
chainId: string, // 链 ID
questionId: string, // 问题 ID
createdAt: number, // 创建时间(Unix 时间戳,秒)
cutoffAt: number, // 截止时间(Unix 时间戳,秒)
resolvedAt: number, // 解决时间(Unix 时间戳,秒)
title: string, // 标题
topicType: number, // 主题类型
parentEvent?: { // 父事件信息(如果是子市场,可选)
title: string, // 父事件标题
eventMarketId: number // 父事件市场 ID
}
}示例
请求
curl http://opinionanalytics.xyz:10001/api/marketsGET /api/markets/asset-ids/:marketId
从 Market ID 获取 Asset ID 信息(yesTokenId 和 noTokenId)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| marketId | string | 是 | 市场 ID |
响应
成功 (200)
{
success: true,
data: {
marketId: number,
yesTokenId: string,
noTokenId: string
}
}未找到 (404)
{
success: false,
error: {
message: string,
code: "MARKET_NOT_FOUND"
}
}示例
请求
curl http://opinionanalytics.xyz:10001/api/markets/asset-ids/1464GET /api/markets/by-asset/:assetId
从 Asset ID 反查 Market ID 及完整的市场信息。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetId | string | 是 | Asset ID |
响应
成功 (200)
{
success: true,
data: Market
}未找到 (404)
{
success: false,
error: {
message: string,
code: "MARKET_NOT_FOUND"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/markets/by-asset/113755959939275329144876348306876245206310381053103529193135814928962195374122"GET /api/markets/wrap-events
获取统一封装的 WrapEvent 列表(将 Events 和 BinaryMarkets 统一成相同结构)。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: WrapEvent[],
total: number
}示例
请求
curl http://opinionanalytics.xyz:10001/api/markets/wrap-eventsGET /api/markets/detail-params/:marketId
通过 marketId 获取跳转到 marketDetail 页面所需的参数。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| marketId | string | 是 | 市场 ID |
响应
成功 (200)
{
success: true,
data: {
yesTokenId: string,
noTokenId: string,
title: string,
yesLabel: string,
noLabel: string
}
}未找到 (404)
{
success: false,
error: {
message: string,
code: "MARKET_NOT_FOUND"
}
}示例
请求
curl http://opinionanalytics.xyz:10001/api/markets/detail-params/1464分析接口
GET /api/analyze/top20
获取 Top20 交易量/交易数分析。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tag | string | 否 | 排序方式:'volume' | 'txn'(默认 'volume') |
| timewindow | string | 否 | 时间窗口:'1h' | '4h' | '24h'(默认 '1h') |
响应
成功 (200)
{
success: true,
data: {
timeWindow: '1h' | '4h' | '24h',
sortBy: 'volume' | 'txn',
startTime: number,
endTime: number,
top20: Top20Item[]
}
}Top20Item 结构
{
parentEventTitle: string, // 父事件标题
marketTitle: string, // 市场标题
totalVolume: number, // 总交易量
txnCount: number, // 交易次数
totalFee: number, // 总手续费
assetIds: string[], // 相关的 Asset ID 列表
orders: EnrichedOrder[], // 订单列表
yesTokenId: string, // Yes Token ID
noTokenId: string // No Token ID
}EnrichedOrder 结构
{
orderHash: string,
maker: string,
assetId: string,
amount: string,
shares: string,
totalFee: string,
fillCount: number,
firstFillTime: number,
lastFillTime: number,
txHashes: string[],
side: 'BUY' | 'SELL',
marketTitle: string,
parentEventTitle: string
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/analyze/top20?tag=volume&timewindow=1h"用户接口
GET /api/user/contract-creator/:contractAddress
获取合约的创建者地址。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| contractAddress | string | 是 | 合约地址(以 0x 开头) |
响应
成功 (200)
{
success: true,
data: {
contractAddress: string,
contractCreator: string
}
}未找到 (404)
{
success: false,
error: {
message: "Contract creator not found"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/user/contract-creator/0x1234567890abcdef1234567890abcdef12345678"GET /api/user/profile/:address
获取用户资料信息。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| address | string | 是 | 用户钱包地址(以 0x 开头) |
响应
成功 (200)
{
success: true,
data: UserProfile
}UserProfile 结构
{
Volume: string,
VolumeIncRate: string,
alert: boolean,
avatarUrl: string,
balance: UserBalance[],
email: string,
followed: boolean,
follower: number,
following: number,
introduction: string,
location: string,
multiSignedWalletAddress: Record<string, string>,
netWorth: string,
portfolio: string,
profitIncRate: string,
rankTheWeek: number,
score: string,
totalProfit: string,
userName: string,
walletAddress: string,
xUserId: string,
xUsername: string
}未找到 (404)
{
success: false,
error: {
message: "User profile not found"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/user/profile/0x66ffba070e8e5961c37607e57049acd1fb3e2b37"卡片数据接口
GET /api/card-data/stats
获取卡片数据服务统计信息。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: ServiceStats
}示例
请求
curl http://opinionanalytics.xyz:10001/api/card-data/statsGET /api/card-data/crypto
获取所有加密货币数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: Record<string, PriceChartData>
}示例
请求
curl http://opinionanalytics.xyz:10001/api/card-data/cryptoGET /api/card-data/stock
获取所有股票数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: Record<string, PriceChartData>
}示例
请求
curl http://opinionanalytics.xyz:10001/api/card-data/stockGET /api/card-data/f1
获取 F1 车手积分数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: F1StandingsData
}示例
请求
curl http://opinionanalytics.xyz:10001/api/card-data/f1GET /api/card-data/symbol/:symbol
直接按 symbol 获取价格数据。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| symbol | string | 是 | 交易对符号(如 BTC、ETH、AAPL) |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetType | string | 否 | 资产类型:'crypto' | 'stock'(默认 'crypto') |
响应
成功 (200)
{
success: true,
data: PriceChartData
}未找到 (404)
{
success: false,
error: {
message: "No data found for symbol: xxx",
code: "SYMBOL_NOT_FOUND"
}
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/card-data/symbol/BTC?assetType=crypto"POST /api/card-data/refresh
手动刷新数据服务。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: {
message: "Service refreshed successfully"
}
}示例
请求
curl -X POST http://opinionanalytics.xyz:10001/api/card-data/refreshGET /api/card-data/:eventId
根据 eventId 获取卡片数据。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| eventId | string | 是 | 事件 ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 否 | 事件标题(用于辅助查询) |
响应
成功 (200)
{
success: true,
data: CardData
}示例
请求
curl "http://opinionanalytics.xyz:10001/api/card-data/123?title=Bitcoin"问题反馈接口
POST /api/issue
保存用户反馈到本地文件。
请求参数
Body Parameters (JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| content | string | 是 | 反馈内容 |
响应
成功 (200)
{
success: true,
message: "Issue submitted successfully"
}参数错误 (400)
{
success: false,
error: {
message: "Content is required"
}
}示例
请求
curl -X POST http://opinionanalytics.xyz:10001/api/issue \
-H "Content-Type: application/json" \
-d '{"content": "发现一个bug..."}'WebSocket 接口
ws://opinionanalytics.xyz:10001/ws
实时订阅订单更新和卡片数据更新。
连接
const ws = new WebSocket('ws://opinionanalytics.xyz:10001/ws');支持的订阅频道
| 频道 | 说明 | value 格式 |
|---|---|---|
| assetId | 订阅指定 Asset ID 的订单更新 | Asset ID 字符串 |
| maker | 订阅指定 Maker 地址的订单更新 | Maker 地址(会自动转小写) |
| cardData | 订阅指定 Symbol 的卡片数据更新 | Symbol 字符串(会自动转大写,如 BTC、ETH) |
| all | 订阅所有订单更新 | 任意字符串(如 "all") |
订阅消息(客户端发送)
订阅 Asset ID
{
type: "subscribe",
channel: "assetId",
value: string // Asset ID
}订阅 Maker 地址
{
type: "subscribe",
channel: "maker",
value: string // Maker 地址
}订阅卡片数据(按 Symbol)
{
type: "subscribe",
channel: "cardData",
value: string // Symbol(如 BTC、ETH、AAPL)
}订阅所有订单
{
type: "subscribe",
channel: "all",
value: string // 任意值(如 "all")
}取消订阅
{
type: "unsubscribe",
channel: "assetId" | "maker" | "cardData" | "all",
value: string
}推送消息(服务端发送)
订单更新
{
type: "order_update",
channel: "assetId" | "maker" | "all",
value: string,
data: OrderUpdateData,
timestamp: number
}OrderUpdateData 结构
{
orderHash: string, // 订单哈希
maker: string, // Maker 地址
makerAssetId: string, // Maker 资产 ID
takerAssetId: string, // Taker 资产 ID
totalMakerAmountFilled: string, // 聚合的 Maker 成交量
totalTakerAmountFilled: string, // 聚合的 Taker 成交量
totalFee: string, // 聚合的手续费(USDT)
side: "BUY" | "SELL", // 订单方向
price: string, // 订单价格
assetId: string, // 实际交易的资产 ID
fillCount: number, // 成交次数
firstFillTime: number, // 首次成交时间
lastFillTime: number, // 最后成交时间
txHashes: string[], // 所有交易哈希
amount: string, // 交易额(USDT)
shares: string // 交易量(token 数量)
}卡片数据更新
{
type: "card_update",
channel: "cardData",
value: string, // Symbol(大写)
data: any, // 卡片数据(价格、图表等)
timestamp: number
}成功消息
{
type: "success",
message: string,
action: "subscribed" | "unsubscribed",
channel: "assetId" | "maker" | "cardData" | "all",
value: string
}错误消息
{
type: "error",
message: string,
code?: string
}示例
订阅 Asset ID
const ws = new WebSocket('ws://opinionanalytics.xyz:10001/ws');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'assetId',
value: '113755959939275329144876348306876245206310381053103529193135814928962195374122'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('Received:', message);
};订阅卡片数据
const ws = new WebSocket('ws://opinionanalytics.xyz:10001/ws');
ws.onopen = () => {
// 订阅 BTC 价格数据
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'cardData',
value: 'BTC'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'card_update') {
console.log('Price update:', message.data);
}
};订阅所有订单
const ws = new WebSocket('ws://opinionanalytics.xyz:10001/ws');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'all',
value: 'all'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'order_update') {
console.log('Order update:', message.data);
}
};错误代码
| 代码 | 说明 |
|---|---|
| NOT_FOUND | 端点未找到 |
| MARKET_NOT_FOUND | 市场未找到 |
| FETCH_MARKETS_ERROR | 获取市场列表失败 |
| FETCH_ASSET_IDS_ERROR | 获取 Asset IDs 失败 |
| FETCH_MARKET_BY_ASSET_ERROR | 通过 Asset ID 获取市场失败 |
| FETCH_WRAP_EVENTS_ERROR | 获取 WrapEvents 列表失败 |
| FETCH_MARKET_DETAIL_PARAMS_ERROR | 获取市场详情参数失败 |
| ANALYZE_ERROR | 分析接口错误 |
| INVALID_PARAM | 参数无效 |
| FETCH_STATS_ERROR | 获取统计信息失败 |
| FETCH_CRYPTO_ERROR | 获取加密货币数据失败 |
| FETCH_STOCK_ERROR | 获取股票数据失败 |
| FETCH_F1_ERROR | 获取 F1 数据失败 |
| SYMBOL_NOT_FOUND | 未找到指定的 Symbol |
| FETCH_SYMBOL_DATA_ERROR | 获取 Symbol 数据失败 |
| FETCH_CARD_DATA_ERROR | 获取卡片数据失败 |
| REFRESH_ERROR | 刷新服务失败 |
| INVALID_FORMAT | WebSocket 消息格式无效 |
| PARSE_ERROR | WebSocket 消息解析失败 |
注意事项
- 时间格式: 所有时间戳均为 Unix 时间戳(秒),除了健康检查接口返回毫秒。
- BigInt 处理: 所有 BigInt 数值以字符串形式返回,避免 JavaScript 精度丢失。
- 分页限制: 每页最大数量为 100 条记录。
- 地址格式: 所有以太坊地址均以 0x 开头的小写格式。
- WebSocket 连接: 保持心跳,避免超时断开。
- 缓存: 部分接口(如 /api/analyze/top20、/api/user/profile)有内存缓存,数据可能有几分钟延迟。