Skip to content

Commit 5ed4aee

Browse files
refactor: rewrite to use Skill API (copenapi) — replace ToB API entirely
1 parent 1377f59 commit 5ed4aee

2 files changed

Lines changed: 607 additions & 243 deletions

File tree

bgw/api.py

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,41 @@
1-
"""Bitget Wallet ToB API client with built-in signing."""
1+
"""Bitget Wallet API client with BKHmacAuth signing."""
2+
from __future__ import annotations
23

3-
import base64
44
import hashlib
5-
import hmac
65
import json
76
import os
87
import time
98

109
import requests
1110

12-
BASE_URL = "https://bopenapi.bgwapi.io"
11+
BASE_URL = "https://copenapi.bgwapi.io"
12+
WALLET_ID = os.environ.get("BGW_WALLET_ID", "")
1313

14-
# Public demo credentials for testing. These may change over time —
15-
# if they stop working, please update to get the latest keys.
16-
# Public demo credentials for testing purposes. These may change over time —
17-
# if they stop working, please update to get the latest keys.
18-
# Override via BGW_API_KEY / BGW_API_SECRET env vars.
19-
API_KEY = os.environ.get("BGW_API_KEY", "4843D8C3F1E20772C0E634EDACC5C5F9A0E2DC92")
20-
API_SECRET = os.environ.get("BGW_API_SECRET", "F2ABFDC684BDC6775FD6286B8D06A3AAD30FD587")
21-
PARTNER_CODE = os.environ.get("BGW_PARTNER_CODE", "bgw_swap_public")
2214

23-
24-
def _sign(api_path: str, body_str: str, timestamp: str) -> str:
25-
content = {
26-
"apiPath": api_path,
27-
"body": body_str,
28-
"x-api-key": API_KEY,
29-
"x-api-timestamp": timestamp,
30-
}
31-
payload = json.dumps(dict(sorted(content.items())), separators=(",", ":"))
32-
sig = hmac.new(API_SECRET.encode(), payload.encode(), hashlib.sha256).digest()
33-
return base64.b64encode(sig).decode()
15+
def _make_sign(method: str, path: str, body_str: str, ts: str) -> str:
16+
"""BKHmacAuth signature: SHA256(Method + Path + Body + Timestamp)."""
17+
message = method + path + body_str + ts
18+
digest = hashlib.sha256(message.encode("utf-8")).hexdigest()
19+
return "0x" + digest
3420

3521

3622
def request(path: str, body: dict | None = None) -> dict:
37-
timestamp = str(int(time.time() * 1000))
38-
body_str = json.dumps(body, separators=(",", ":"), sort_keys=True) if body else ""
39-
signature = _sign(path, body_str, timestamp)
40-
23+
"""POST request with BKHmacAuth signing."""
24+
ts = str(int(time.time() * 1000))
25+
body_str = json.dumps(body, separators=(",", ":"), ensure_ascii=False) if body else ""
26+
sign = _make_sign("POST", path, body_str, ts)
27+
token_val = WALLET_ID if WALLET_ID else "toc_agent"
4128
headers = {
4229
"Content-Type": "application/json",
43-
"x-api-key": API_KEY,
44-
"x-api-timestamp": timestamp,
45-
"x-api-signature": signature,
30+
"channel": "toc_agent",
31+
"brand": "toc_agent",
32+
"clientversion": "10.0.0",
33+
"language": "en",
34+
"token": token_val,
35+
"X-SIGN": sign,
36+
"X-TIMESTAMP": ts,
4637
}
47-
if "/swapx/" in path:
48-
headers["Partner-Code"] = PARTNER_CODE
49-
5038
resp = requests.post(BASE_URL + path, data=body_str or None, headers=headers, timeout=30)
5139
if resp.status_code != 200:
52-
return {"error": f"HTTP {resp.status_code}", "message": resp.text[:500]}
40+
return {"status": -1, "error_code": resp.status_code, "msg": resp.text[:500]}
5341
return resp.json()

0 commit comments

Comments
 (0)