|
@@ -1,42 +1,96 @@
|
|
|
-# Pinnacle Proxy API Auth
|
|
|
|
|
|
|
+# Pinnacle Proxy Frontend Auth
|
|
|
|
|
|
|
|
-`/api/pinnacle` 不需要登录态,但每个调用方需要配置独立用户和密钥,并通过动态签名访问接口。
|
|
|
|
|
|
|
+前端访问 `/api/pinnacle` 时,需要使用动态签名。请求中不会直接传密钥。
|
|
|
|
|
|
|
|
-## 服务端配置
|
|
|
|
|
|
|
+## 支持的接口
|
|
|
|
|
|
|
|
-在 `pinnacle/.env` 中配置:
|
|
|
|
|
|
|
+本地数据接口:
|
|
|
|
|
|
|
|
-```env
|
|
|
|
|
-PINNACLE_PROXY_USERS=alice:aliceSecret:/events,/v3/sports;bob:bobSecret:*
|
|
|
|
|
|
|
+```txt
|
|
|
|
|
+GET /api/pinnacle/events
|
|
|
|
|
+POST /api/pinnacle/events
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-格式:
|
|
|
|
|
|
|
+Pinnacle Lines API:
|
|
|
|
|
|
|
|
```txt
|
|
```txt
|
|
|
-用户名:密钥:权限列表;用户名:密钥:权限列表
|
|
|
|
|
|
|
+GET /api/pinnacle/v2/line
|
|
|
|
|
+POST /api/pinnacle/v3/line/parlay
|
|
|
|
|
+POST /api/pinnacle/v1/line/teaser
|
|
|
|
|
+GET /api/pinnacle/v2/line/special
|
|
|
|
|
+GET /api/pinnacle/v3/sports
|
|
|
|
|
+GET /api/pinnacle/v3/leagues
|
|
|
|
|
+GET /api/pinnacle/v1/periods
|
|
|
|
|
+GET /api/pinnacle/v2/inrunning
|
|
|
|
|
+GET /api/pinnacle/v1/cancellationreasons
|
|
|
|
|
+GET /api/pinnacle/v2/currencies
|
|
|
|
|
+GET /api/pinnacle/v1/client/balance
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-说明:
|
|
|
|
|
|
|
+Pinnacle Bets API:
|
|
|
|
|
+
|
|
|
|
|
+```txt
|
|
|
|
|
+POST /api/pinnacle/v4/bets/place
|
|
|
|
|
+POST /api/pinnacle/v4/bets/parlay
|
|
|
|
|
+POST /api/pinnacle/v4/bets/teaser
|
|
|
|
|
+POST /api/pinnacle/v4/bets/special
|
|
|
|
|
+GET /api/pinnacle/v3/bets
|
|
|
|
|
+GET /api/pinnacle/v3/bets/settled
|
|
|
|
|
+GET /api/pinnacle/v1/regrades/wager-history
|
|
|
|
|
+GET /api/pinnacle/v1/bets/betting-status
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
-- `用户名`:前端请求时放在 `X-Api-User`。
|
|
|
|
|
-- `密钥`:只保存在服务端和可信调用方,不在请求中明文传递。
|
|
|
|
|
-- `权限列表`:逗号分隔,写 `/api/pinnacle` 后面的实际路径。
|
|
|
|
|
-- `*` 表示允许访问所有 `/api/pinnacle` 接口。
|
|
|
|
|
|
|
+签名中的 `PATH` 不包含 `/api/pinnacle` 前缀。例如请求 `/api/pinnacle/events`,签名时 `PATH` 使用 `/events`。
|
|
|
|
|
|
|
|
-示例:
|
|
|
|
|
|
|
+## /events 参数
|
|
|
|
|
|
|
|
-```env
|
|
|
|
|
-PINNACLE_PROXY_USERS=viewer:viewerSecret:/events,/v2/currencies;trader:traderSecret:/events,/v4/bets/place,/v4/bets/parlay
|
|
|
|
|
|
|
+`/events` 是本地数据接口,不请求上游 Pinnacle,直接读取服务端内存中的 `GLOBAL_DATA.gamesMap`。
|
|
|
|
|
+
|
|
|
|
|
+GET 支持 query 参数:
|
|
|
|
|
+
|
|
|
|
|
+```txt
|
|
|
|
|
+GET /api/pinnacle/events
|
|
|
|
|
+GET /api/pinnacle/events?id=123
|
|
|
|
|
+GET /api/pinnacle/events?ids=123,456
|
|
|
|
|
+GET /api/pinnacle/events?eventId=123
|
|
|
|
|
+GET /api/pinnacle/events?eventIds=123,456
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-对应权限:
|
|
|
|
|
|
|
+POST 支持 JSON body:
|
|
|
|
|
|
|
|
-- `viewer` 可以访问 `/api/pinnacle/events` 和 `/api/pinnacle/v2/currencies`
|
|
|
|
|
-- `trader` 可以访问 `/api/pinnacle/events`、`/api/pinnacle/v4/bets/place`、`/api/pinnacle/v4/bets/parlay`
|
|
|
|
|
|
|
+```json
|
|
|
|
|
+{ "id": 123 }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{ "ids": [123, 456] }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{ "eventId": 123 }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{ "eventIds": "123,456" }
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+参数优先级:
|
|
|
|
|
+
|
|
|
|
|
+```txt
|
|
|
|
|
+ids -> id -> eventIds -> eventId
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+返回说明:
|
|
|
|
|
+
|
|
|
|
|
+- 始终返回数组。
|
|
|
|
|
+- 传入单个 ID 时,返回匹配到的 0 或 1 条数据。
|
|
|
|
|
+- 传入多个 ID 时,返回匹配到的多条数据。
|
|
|
|
|
+- 不传 ID 时,返回当前 `GLOBAL_DATA.gamesMap` 中的全部赛事。
|
|
|
|
|
+- 找不到 ID 时不会报错,只是不返回对应项。
|
|
|
|
|
|
|
|
## 请求头
|
|
## 请求头
|
|
|
|
|
|
|
|
-前端每次请求 `/api/pinnacle` 都需要带:
|
|
|
|
|
|
|
+每次请求都需要带:
|
|
|
|
|
|
|
|
```txt
|
|
```txt
|
|
|
X-Api-User: alice
|
|
X-Api-User: alice
|
|
@@ -47,6 +101,7 @@ X-Api-Signature: hmac-sha256-hex
|
|
|
|
|
|
|
|
说明:
|
|
说明:
|
|
|
|
|
|
|
|
|
|
+- `X-Api-User`:服务端 `.env` 中配置的用户名。
|
|
|
- `X-Api-Timestamp`:当前毫秒时间戳,允许和服务端相差 5 分钟。
|
|
- `X-Api-Timestamp`:当前毫秒时间戳,允许和服务端相差 5 分钟。
|
|
|
- `X-Api-Nonce`:每次请求都要不同,防止重放。
|
|
- `X-Api-Nonce`:每次请求都要不同,防止重放。
|
|
|
- `X-Api-Signature`:用用户密钥对签名内容做 HMAC-SHA256。
|
|
- `X-Api-Signature`:用用户密钥对签名内容做 HMAC-SHA256。
|
|
@@ -84,7 +139,7 @@ abc123
|
|
|
- `TIMESTAMP`:同 `X-Api-Timestamp`
|
|
- `TIMESTAMP`:同 `X-Api-Timestamp`
|
|
|
- `NONCE`:同 `X-Api-Nonce`
|
|
- `NONCE`:同 `X-Api-Nonce`
|
|
|
|
|
|
|
|
-## 前端示例
|
|
|
|
|
|
|
+## 签名工具
|
|
|
|
|
|
|
|
浏览器端可使用 Web Crypto API:
|
|
浏览器端可使用 Web Crypto API:
|
|
|
|
|
|
|
@@ -151,7 +206,7 @@ const createPinnacleHeaders = async ({ method, path, query = {}, body, user, sec
|
|
|
};
|
|
};
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-GET 请求:
|
|
|
|
|
|
|
+## GET 示例
|
|
|
|
|
|
|
|
```js
|
|
```js
|
|
|
const user = 'alice';
|
|
const user = 'alice';
|
|
@@ -172,7 +227,7 @@ const res = await fetch(`/api/pinnacle${path}?${search}`, { headers });
|
|
|
const data = await res.json();
|
|
const data = await res.json();
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-POST 请求:
|
|
|
|
|
|
|
+## POST 示例
|
|
|
|
|
|
|
|
```js
|
|
```js
|
|
|
const user = 'trader';
|
|
const user = 'trader';
|
|
@@ -213,4 +268,3 @@ const data = await res.json();
|
|
|
- `401 API nonce has already been used`:nonce 重复。
|
|
- `401 API nonce has already been used`:nonce 重复。
|
|
|
- `401 Invalid API signature`:签名不匹配。
|
|
- `401 Invalid API signature`:签名不匹配。
|
|
|
- `403 Forbidden`:用户没有该接口权限。
|
|
- `403 Forbidden`:用户没有该接口权限。
|
|
|
-
|
|
|