认证
访问地址
生产URL: https://bopenapi.bgwapi.io
APIKey的申请
- APIKey需要找我司对接人员申请,默认的限流阈值见每个接口的定义,如果需要申请超过默认阈值的APIKey,需要找对接人员特别申请
- 每个APIKey需要在指定的服务器上执行,在使用APIKey之前需要添加ip白名单给我司对接人员进行配置(本地访问可使用生产测试key,这个key每秒2qps的限流,但不需要添加ip白名单)
- 如果只是测试/调试使用,可以先使用以下APIKey:
- Key:
6AE25C9BFEEC4D815097ECD54DDE36B9A1F2B069 - Secret:
C2638D162310C10D5DAFC8013871F2868E065040
- Key:
接口鉴权
必填的header定义
| 参数名 | 说明 |
|---|---|
| x-api-key | 在我司申请的APIKey |
| x-api-timestamp | 接口调用的时间戳,由客户端根据本地时间生成,如果和服务间时间偏差超过正负10分钟,请求将被拒绝 |
| x-api-signature | 接口签名,使用接口文档中的算法生成,签名错误时接口将被拒绝 |
签名算法
签名Content组成
- APIKey
- APITimestamp(毫秒)
- Path
- Query
- Body
注意: content的json中的key需要按照字典序进行排序
curl -H 'x-api-key:'key' \
-H 'x-api-timestamp:17200001' \
-H 'x-api-signature:待计算的签名' \
https://{GATEWAY_URL}/swap/api/test?param1=test1¶m2=test2 -d'{"data":"test"}'
===> Content为
{"apiPath":"/swap/api/test","body":{\"data\":\"test\"},"param1":"test1", "param2":"test2", "x-api-key":"key", "x-api-timestamp":"17200001"}签名生成
- 将签名content使用我方支持人员提供的APISecret进行HMAC签名
- 将签名的结果转为base64串
注意
apiPath为不带参数的签名
开发示例
golang 版本签名代码
func signature(path, apiKey string, apiSecret, timestamp string, query map[string]string, body string) string {
contentMap := make(map[string]string)
contentMap["x-api-key"] = apiKey
contentMap["x-api-timestamp"] = timestamp
contentMap["apiPath"] = path
for key, value := range query {
contentMap[key] = value
}
contentMap["body"] = body
content, _ := json.Marshal(contentMap)
mac := hmac.New(sha256.New, []byte(apiSecret))
mac.Write(content)
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}JAVA版本签名代码
package org.example;
import com.google.gson.Gson;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class Main {
private static String Signature(String path, String apiKey, String apiSecret, String timestamp, HashMap<String, String> query, String body) throws Exception {
TreeMap<String, String> mapping = new TreeMap<>();
// 组装content
mapping.put("x-api-key", apiKey);
mapping.put("x-api-timestamp", timestamp);
mapping.put("apiPath", path);
mapping.put("body", body);
Set<Map.Entry<String, String>> entries = query.entrySet();
for (Map.Entry<String, String> mapEntry : entries) {
mapping.put(mapEntry.getKey(), mapEntry.getValue());
}
// 序列化
Gson gson = new Gson();
String content = gson.toJson(mapping);
// Hmac签名
Mac sha256_HMAC = Mac.getInstance("HmacSha256");
SecretKeySpec secretKey = new SecretKeySpec(apiSecret.getBytes(), "HmacSha256");
sha256_HMAC.init(secretKey);
byte[] mac = sha256_HMAC.doFinal(content.getBytes());
// base64
Base64.Encoder base = Base64.getEncoder();
return base.encodeToString(mac);
}
public static void main(String[] args) throws Exception {
HashMap<String, String> query = new HashMap<>();
query.put("key1", "val1");
query.put("key2", "val2");
System.out.println(Signature("/test", "123456", "7890", "1733366175000",query, "{\"body\":\"test\"}"));
}
}Node.js 版本签名代码
function getSignature(apiPath, body, apiKey, apiSecret, timeStamp, queryParams = {}) {
// build contentTpl with all keys (base fields + queryParams keys)
const contentTpl = {
"apiPath": "",
"body": "",
"x-api-key": "",
"x-api-timestamp": "",
};
// add queryParams keys to template
if (queryParams && typeof queryParams === "object") {
for (const key of Object.keys(queryParams)) {
contentTpl[key] = "";
}
}
// build content with actual values
const content = {
"apiPath": apiPath,
"body": body,
"x-api-key": apiKey,
"x-api-timestamp": timeStamp,
};
if (queryParams && typeof queryParams === "object") {
for (const [key, value] of Object.entries(queryParams)) {
content[key] = String(value);
}
}
// sort only by contentTpl keys
const sortedKeys = Object.keys(contentTpl).sort();
const sortedContent = Object.fromEntries(sortedKeys.map(key => [key, content[key]]));
const payload = JSON.stringify(sortedContent);
return crypto
.createHmac("sha256", apiSecret)
.update(payload)
.digest("base64");
}HTTP状态码定义
| 状态码 | 说明 |
|---|---|
| 200 | success |
| 400 | Bad Request |
| 403 | Forbidden(未加白名单或者是签名错误) |
| 429 | Too many requests(被限频) |
链名字典
| 名称 | 标识 | 链ID | 备注 |
|---|---|---|---|
| Bitcoin | btc | 0 | |
| Ethereum | eth | 1 | |
| Solana | sol | 100278 | |
| Base | base | 8453 | |
| BNB Chain | bnb | 56 | |
| Ton | ton | 100280 | |
| SUI | suinet | 100281 | |
| Tron | trx | 6 | |
| Mantle | mnt | 5000 | |
| Sei | seiv2 | 1329 | |
| Avalanche-C | avax_c | 43114 | |
| Aptos | apt | 100279 | |
| Arbitrum | arbitrum | 42161 | |
| zkSync Era | zksv2 | 324 | |
| Fantom | ftm | 250 | |
| Core | coredao | 1116 | |
| Optimism | optimism | 10 | |
| Blast | blast | 81457 | |
| opBNB | opbnb | 204 | |
| Linea | linea | 59144 | |
| Merlin Chain | merlin | 4200 | |
| Manta | manta | 169 | |
| FscScan | fsc | 201022 |
Last updated on


