API Reference Documentation
基础信息
- Base URL:
http://opinion.predictscan.dev:10001 - 协议: HTTP/1.1
- 数据格式: JSON
- 字符编码: UTF-8
通用响应格式
成功响应(分页)
{
success: true,
data: T[],
pagination: {
page: number, // 当前页码
pageSize: number, // 每页数量
total: number, // 总记录数
totalPages: number // 总页数
}
}成功响应(游标分页)
{
success: true,
data: T[],
nextCursor: string | null, // 下一页游标(null 表示无更多数据)
hasMore: boolean // 是否有更多数据
}成功响应(列表)
{
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
获取最近的吃单订单列表(游标分页)。缓存 30 秒。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 游标(首次请求不传) |
| limit | number | 否 | 每次获取数量(默认 100,最大 1000) |
| startTime | number | 否 | 开始时间(Unix 时间戳,秒) |
| endTime | number | 否 | 结束时间(Unix 时间戳,秒) |
响应
成功 (200)
{
success: true,
data: AggregatedTakerOrder[],
nextCursor: string | null, // 下一页游标
hasMore: boolean // 是否有更多数据
}AggregatedTakerOrder 结构
{
orderHash: string, // 订单哈希
maker: string, // Maker 地址
assetId: string, // 实际交易的资产 ID
amount: number, // USDT 金额(已转换精度的浮点数)
shares: number, // Token 数量(已转换精度的浮点数)
fee: number, // 手续费(已转换精度的浮点数)
side: number, // 订单方向(1=BUY, 0=SELL)
sideStr: "BUY" | "SELL", // 订单方向(字符串形式)
price: string, // 订单价格(保留三位小数)
fillCount: number, // 成交次数
firstFillTime: number, // 首次成交时间(Unix 时间戳,秒)
lastFillTime: number, // 最后成交时间(Unix 时间戳,秒)
txHashes: string[] // 交易哈希列表
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/orders/recent?page=1&pageSize=2"GET /api/orders/by-asset/:assetId
按 Asset ID 查询吃单交易信息(游标分页)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetId | string | 是 | Asset ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 游标(首次请求不传) |
| limit | number | 否 | 每次获取数量(默认 100,最大 1000) |
| filter | string | 否 | 筛选类型:'all' | 'taker' | 'maker'(默认 'taker') |
| aggregated | string | 否 | 是否聚合订单:'true' | 'false'(默认 'true','false' 时返回原始记录) |
响应
成功 (200)
{
success: true,
data: Order[],
nextCursor: string | null, // 下一页游标
hasMore: boolean // 是否有更多数据
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/orders/by-asset/72328986599454660492851558931881986229058826133693803755503603230417419524977?limit=100&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://opinion.predictscan.dev: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://opinion.predictscan.dev:10001/api/orders/order/0x51c955bce965cf2f921af4babb542a63784e42f7403dcfa45bc468a81859db22"GET /api/orders/by-maker/:maker
按 Maker 地址查询订单列表(游标分页)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| maker | string | 是 | Maker 地址(以 0x 开头的以太坊地址) |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 游标(首次请求不传) |
| limit | number | 否 | 每次获取数量(默认 100,最大 1000) |
| aggregated | string | 否 | 是否聚合订单:'true' | 'false'(默认 'true','false' 时返回碎单子) |
| afterTime | number | 否 | 只返回该时间戳之后的订单(Unix 秒) |
| assetIds | string | 否 | assetId 过滤数组(逗号分隔),只返回匹配的订单(OR 关系) |
响应
成功 (200)
{
success: true,
data: Order[],
nextCursor: string | null, // 下一页游标
hasMore: boolean // 是否有更多数据
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/orders/by-maker/0x66ffba070e8e5961c37607e57049acd1fb3e2b37?limit=100"带过滤参数
curl "http://opinion.predictscan.dev:10001/api/orders/by-maker/0x66ffba070e8e5961c37607e57049acd1fb3e2b37?aggregated=false&afterTime=1704067200&assetIds=123,456,789"市场接口
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://opinion.predictscan.dev: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://opinion.predictscan.dev: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://opinion.predictscan.dev:10001/api/markets/by-asset/113755959939275329144876348306876245206310381053103529193135814928962195374122"POST /api/markets/batch-by-assets
批量从 Asset IDs 获取市场信息。
请求参数
Body Parameters (JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetIds | string[] | 是 | Asset ID 数组(最多 500 个) |
响应
成功 (200)
{
success: true,
data: Record<string, Market> // key 为 assetId,value 为市场信息
}参数错误 (400)
{
success: false,
error: {
message: "assetIds must be a non-empty array",
code: "INVALID_ASSET_IDS"
}
}{
success: false,
error: {
message: "assetIds array exceeds maximum limit of 500",
code: "TOO_MANY_ASSET_IDS"
}
}示例
请求
curl -X POST http://opinion.predictscan.dev:10001/api/markets/batch-by-assets \
-H "Content-Type: application/json" \
-d '{"assetIds": ["123456789", "987654321"]}'GET /api/markets/search
搜索市场(模糊匹配 marketTitle + parentEventTitle)。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| q | string | 是 | 搜索关键词 |
| limit | number | 否 | 返回数量(默认 10,最大 50) |
响应
成功 (200)
{
success: true,
data: SearchResult[],
total: number
}SearchResult 结构
{
marketId: number,
title: string,
yesTokenId: string,
noTokenId: string,
parentEvent?: {
title: string,
eventMarketId: string
},
searchScore: number
}参数错误 (400)
{
success: false,
error: {
message: "Search query \"q\" is required",
code: "MISSING_QUERY"
}
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/markets/search?q=bitcoin&limit=10"GET /api/markets/wrap-events
获取统一封装的 WrapEvent 列表(将 Events 和 BinaryMarkets 统一成相同结构)。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | number | 否 | 每页数量(默认 1000,最大 1000) |
| offset | number | 否 | 偏移量(默认 0) |
响应
成功 (200)
{
success: true,
data: WrapEvent[],
total: number,
limit: number,
offset: number
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/markets/wrap-events?limit=100&offset=0"GET /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://opinion.predictscan.dev:10001/api/markets/detail-params/1464分析接口
GET /api/analyze/top20
获取 Top20 交易量/交易数分析。缓存 5 分钟。
请求参数
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://opinion.predictscan.dev:10001/api/analyze/top20?tag=volume&timewindow=1h"GET /api/analyze/top-makers
获取 Top20 交易量/交易数按 Maker 分析。
请求参数
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tag | string | 否 | 排序方式:'volume' | 'txn'(默认 'volume') |
| timewindow | string | 否 | 时间窗口:'15m' | '1h'(默认 '15m') |
响应
成功 (200)
{
success: true,
data: {
timeWindow: '15m' | '1h',
sortBy: 'volume' | 'txn',
startTime: number,
endTime: number,
top20: Top20MakerItem[]
}
}Top20MakerItem 结构
{
maker: string, // Maker 地址
orderCount: number, // 订单数量
totalVolume: number, // 总交易量
totalFee: number, // 总手续费
firstTxTime: number, // 首次交易时间(Unix 时间戳,秒)
lastTxTime: number // 最后交易时间(Unix 时间戳,秒)
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/analyze/top-makers?tag=volume&timewindow=15m"用户接口
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://opinion.predictscan.dev:10001/api/user/contract-creator/0x1234567890abcdef1234567890abcdef12345678"GET /api/user/profile/:address
获取用户资料信息。根据链配置选择不同的 API:
- BSC (56): Opinion API
- Polygon (137): Polymarket API
缓存 10 分钟。
请求参数
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://opinion.predictscan.dev:10001/api/user/profile/0x66ffba070e8e5961c37607e57049acd1fb3e2b37"GET /api/user/resolveUser/:address
解析用户上下文(支持 EOA 或 maker 地址输入)。缓存 1 小时。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| address | string | 是 | 用户地址(EOA 或 maker 地址) |
响应
成功 (200)
{
success: true,
data: {
eoaAddress: string, // EOA 地址
makerAddress: string, // Maker 地址
profile: UserProfile | null, // 用户资料
hitCache: boolean // 是否命中缓存
}
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/user/resolveUser/0x66ffba070e8e5961c37607e57049acd1fb3e2b37"GET /api/user/positions/:address
获取用户所有仓位快照(游标分页)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| address | string | 是 | 用户地址 |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 游标(首次请求不传) |
| limit | number | 否 | 每页数量(默认 1000,最大 5000) |
| includeConditionId | string | 否 | 是否包含 conditionId 字段:'true' | 'false'(默认 'false') |
响应
成功 (200)
{
success: true,
data: {
data: PositionSnapshot[],
nextCursor: string | null,
hasMore: boolean
}
}PositionSnapshot 结构
{
maker: string,
assetId: string,
isClaimed: boolean,
shares: string,
totalBuyShares: string,
totalBuyUsdt: string,
totalSellShares: string,
totalSellUsdt: string,
splitShares: string,
mergeShares: string,
claimUsdt: string,
totalFee: string,
lastUpdated: Date,
conditionId?: string // 仅当 includeConditionId=true 时返回
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/user/positions/0x66ffba070e8e5961c37607e57049acd1fb3e2b37?limit=1000"健康检查接口
GET /api/health
简单的健康检查端点,前端每分钟轮询一次以检测服务是否可用。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
status: 'ok',
timestamp: number // 毫秒时间戳
}示例
请求
curl http://opinion.predictscan.dev:10001/api/healthGET /api/health/ping
更轻量的 ping 端点。
请求参数
无需参数。
响应
成功 (200)
{
pong: true
}示例
请求
curl http://opinion.predictscan.dev:10001/api/health/ping交易记录接口
GET /api/transactions/by-maker/:maker
按 maker 地址查询所有链上交易记录(order, split, merge, claim)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| maker | string | 是 | Maker 地址(以 0x 开头) |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | number | 否 | 时间戳游标(Unix 秒,返回该时间戳之前的记录,首次请求不传) |
| limit | number | 否 | 每次获取数量(默认 50,最大 200) |
| types | string | 否 | 交易类型过滤(逗号分隔,如 'order,split,merge,claim') |
响应
成功 (200)
{
success: true,
data: UserTransaction[],
nextCursor: string | null, // 下一页游标
hasMore: boolean // 是否有更多数据
}UserTransaction 结构
{
type: 'order' | 'split' | 'merge' | 'claim',
txHash: string,
timestamp: number,
// 其他字段根据 type 不同而不同
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/transactions/by-maker/0x66ffba070e8e5961c37607e57049acd1fb3e2b37?limit=50&types=order,split"Orderbook 接口
GET /api/orderbook/:assetId
获取指定 Asset ID 的市场深度数据。缓存 1 秒。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetId | string | 是 | Asset ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| chainId | string | 否 | 链 ID(默认 '56',即 BSC) |
响应
成功 (200)
{
success: true,
data: {
asks: [string, string][], // 卖单列表 [价格, 数量]
bids: [string, string][], // 买单列表 [价格, 数量]
lastPrice: string, // 最新成交价
questionId: string, // 问题 ID
assetId: string, // 资产 ID
timestamp: number // 上游时间戳(毫秒)
},
cached: boolean // 是否来自缓存
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/orderbook/123456789?chainId=56"POST /api/orderbook/batchprice
批量获取 Asset ID 的最新价格。优先级:condition_payout > orderFilledV2。
请求参数
Body Parameters (JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assetIds | string[] | 是 | Asset ID 数组(最多 1000 个) |
响应
成功 (200)
{
success: true,
data: AssetPriceResult[]
}AssetPriceResult 结构
{
assetId: string,
price: number | null, // 价格(null 表示未找到)
source: 'payout' | 'order' | 'none' // 价格来源
}参数错误 (400)
{
success: false,
error: {
message: "assetIds must be a non-empty array",
code: "INVALID_ASSET_IDS"
}
}示例
请求
curl -X POST http://opinion.predictscan.dev:10001/api/orderbook/batchprice \
-H "Content-Type: application/json" \
-d '{"assetIds": ["123456789", "987654321"]}'链配置接口
GET /api/chain-config
获取当前项目的链配置信息。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: {
projectId: string,
chainId: number,
config: {
name: string,
displayName: string,
webDomain: string,
viemChain: string,
nativeCurrency: any,
explorer: any,
contracts: any,
decimals: any,
database: any
},
supportedProjects: string[]
}
}示例
请求
curl http://opinion.predictscan.dev:10001/api/chain-configGET /api/chain-config/:projectId
获取指定项目的链配置信息。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| projectId | string | 是 | 项目 ID |
响应
成功 (200)
与 GET /api/chain-config 响应格式相同。
未找到 (404)
{
success: false,
error: {
message: "Project not found: xxx",
code: "PROJECT_NOT_FOUND"
}
}示例
请求
curl http://opinion.predictscan.dev:10001/api/chain-config/opinion网络接口
GET /api/network/:marketId
获取指定市场的 Maker Network(交易关系图)。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| marketId | string | 是 | 市场 ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| minTxCount | number | 否 | 最小交易次数(默认 1) |
| minAmount | number | 否 | 最小总金额(默认 0) |
| limit | number | 否 | 最大返回边数(默认 1000,最大 50000) |
响应
成功 (200)
{
success: true,
data: {
nodes: string[], // 所有参与交易的 maker 地址
edges: MakerNetworkEdge[] // maker 之间的交易关系
}
}MakerNetworkEdge 结构
{
from: string, // 源 maker 地址
to: string, // 目标 maker 地址
txCount: number, // 交易次数
amount: number // 交易总金额
}示例
请求
curl "http://opinion.predictscan.dev:10001/api/network/1464?minTxCount=5&limit=500"卡片数据接口
GET /api/card-data/stats
获取卡片数据服务统计信息。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: ServiceStats
}示例
请求
curl http://opinion.predictscan.dev:10001/api/card-data/statsGET /api/card-data/crypto
获取所有加密货币数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: Record<string, PriceChartData>
}示例
请求
curl http://opinion.predictscan.dev:10001/api/card-data/cryptoGET /api/card-data/stock
获取所有股票数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: Record<string, PriceChartData>
}示例
请求
curl http://opinion.predictscan.dev:10001/api/card-data/stockGET /api/card-data/f1
获取 F1 车手积分数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: F1StandingsData
}示例
请求
curl http://opinion.predictscan.dev:10001/api/card-data/f1GET /api/card-data/aivshuman
获取 AI vs Human ROI 数据。
请求参数
无需参数。
响应
成功 (200)
{
success: true,
data: AIvsHumanData
}示例
请求
curl http://opinion.predictscan.dev:10001/api/card-data/aivshumanGET /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://opinion.predictscan.dev: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://opinion.predictscan.dev:10001/api/card-data/refreshPOST /api/card-data/batch
批量获取卡片数据,过滤掉 type 为 'none' 的结果。
请求参数
Body Parameters (JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| items | Array<{ eventId: string; title?: string }> | 是 | 事件 ID 和标题数组 |
响应
成功 (200)
{
success: true,
data: Record<string, CardData> // key 为 eventId
}参数错误 (400)
{
success: false,
error: {
message: "Invalid request: items array is required",
code: "INVALID_REQUEST"
}
}示例
请求
curl -X POST http://opinion.predictscan.dev:10001/api/card-data/batch \
-H "Content-Type: application/json" \
-d '{"items": [{"eventId": "123", "title": "Bitcoin"}, {"eventId": "456"}]}'GET /api/card-data/:eventId
根据 eventId 获取卡片数据。
请求参数
Path Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| eventId | string | 是 | 事件 ID |
Query Parameters
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | string | 否 | 事件标题(用于辅助查询) |
响应
成功 (200)
{
success: true,
data: CardData
}示例
请求
curl "http://opinion.predictscan.dev: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://opinion.predictscan.dev:10001/api/issue \
-H "Content-Type: application/json" \
-d '{"content": "发现一个bug..."}'WebSocket 接口
ws://opinion.predictscan.dev:10001/ws
实时订阅订单更新和卡片数据更新。
连接
const ws = new WebSocket('ws://opinion.predictscan.dev: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 地址
assetId: string, // 实际交易的资产 ID
amount: number, // USDT 金额(已转换精度的浮点数)
shares: number, // Token 数量(已转换精度的浮点数)
fee: number, // 手续费(已转换精度的浮点数)
side: number, // 订单方向(1=BUY, 0=SELL)
sideStr: "BUY" | "SELL", // 订单方向(字符串形式)
price: string, // 订单价格
fillCount: number, // 成交次数
firstFillTime: number, // 首次成交时间
lastFillTime: number, // 最后成交时间
txHashes: string[] // 所有交易哈希
}卡片数据更新
{
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://opinion.predictscan.dev: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://opinion.predictscan.dev: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://opinion.predictscan.dev: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 | 市场未找到 |
| PROJECT_NOT_FOUND | 项目未找到 |
| MISSING_QUERY | 缺少搜索关键词 |
| SEARCH_MARKETS_ERROR | 搜索市场失败 |
| FETCH_MARKETS_ERROR | 获取市场列表失败 |
| FETCH_ASSET_IDS_ERROR | 获取 Asset IDs 失败 |
| FETCH_MARKET_BY_ASSET_ERROR | 通过 Asset ID 获取市场失败 |
| BATCH_FETCH_MARKETS_ERROR | 批量获取市场失败 |
| FETCH_WRAP_EVENTS_ERROR | 获取 WrapEvents 列表失败 |
| FETCH_MARKET_DETAIL_PARAMS_ERROR | 获取市场详情参数失败 |
| ANALYZE_ERROR | 分析接口错误 |
| INVALID_PARAM | 参数无效 |
| INVALID_ASSET_IDS | Asset IDs 参数无效 |
| TOO_MANY_ASSET_IDS | Asset IDs 数量超限 |
| INVALID_REQUEST | 请求格式无效 |
| FETCH_STATS_ERROR | 获取统计信息失败 |
| FETCH_CRYPTO_ERROR | 获取加密货币数据失败 |
| FETCH_STOCK_ERROR | 获取股票数据失败 |
| FETCH_F1_ERROR | 获取 F1 数据失败 |
| FETCH_AIVSHUMAN_ERROR | 获取 AIvsHuman 数据失败 |
| SYMBOL_NOT_FOUND | 未找到指定的 Symbol |
| FETCH_SYMBOL_DATA_ERROR | 获取 Symbol 数据失败 |
| FETCH_CARD_DATA_ERROR | 获取卡片数据失败 |
| FETCH_BATCH_CARD_DATA_ERROR | 批量获取卡片数据失败 |
| REFRESH_ERROR | 刷新服务失败 |
| FETCH_ORDERBOOK_ERROR | 获取 Orderbook 失败 |
| BATCH_PRICE_ERROR | 批量价格查询失败 |
| SDK_NOT_AVAILABLE | SDK 不可用 |
| FETCH_CHAIN_CONFIG_ERROR | 获取链配置失败 |
| MISSING_MARKET_ID | 缺少 marketId 参数 |
| FETCH_MAKER_NETWORK_ERROR | 获取 Maker 网络失败 |
| INVALID_FORMAT | WebSocket 消息格式无效 |
| PARSE_ERROR | WebSocket 消息解析失败 |
注意事项
- 时间格式: 所有时间戳均为 Unix 时间戳(秒),除了 Orderbook 接口返回毫秒。
- BigInt 处理: 所有 BigInt 数值以字符串形式返回,避免 JavaScript 精度丢失。
- 分页限制: 每页最大数量为 100 条记录(游标分页除外)。
- 地址格式: 所有以太坊地址均以 0x 开头的小写格式。
- WebSocket 连接: 保持心跳,避免超时断开。
- 缓存: 部分接口有内存缓存,数据可能有延迟:
/api/orders/recent: 30 秒/api/analyze/top20: 5 分钟/api/analyze/top-makers: 1-3 分钟(根据时间窗口)/api/analyze/activity-stats: 1 小时/api/user/profile: 10 分钟/api/user/resolveUser: 1 小时/api/orderbook/:assetId: 1 秒