import hashlib
import time
import json
import requests
from nacl.signing import SigningKey
class NBTSigner:
"""NBT API 签名工具类"""
def __init__(self, api_key: str, api_secret: str, base_url: str = "https://apidev.nusd.me"):
self.api_key = api_key
self.api_secret = api_secret
self.base_url = base_url
def sign(self, method: str, path: str, params: str = "", body: str = "") -> dict:
"""
生成签名并返回请求头
Args:
method: HTTP 方法 (GET/POST)
path: API 路径 (如 /nps/balance)
params: 查询参数字符串 (如 wallet_id=xxx)
body: 请求体 JSON 字符串
Returns:
包含签名信息的请求头字典
"""
timestamp = str(int(time.time() * 1000))
str_to_sign = f"{method}|{path}|{timestamp}|{params}|{body}"
# 双重 SHA256
content_hash = hashlib.sha256(
hashlib.sha256(str_to_sign.encode()).digest()
).digest()
# Ed25519 签名
signing_key = SigningKey(bytes.fromhex(self.api_secret))
signature = signing_key.sign(content_hash).signature.hex()
return {
"BIZ-API-KEY": self.api_key,
"Biz-Api-Nonce": timestamp,
"Biz-Api-Signature": signature,
"Content-Type": "application/json",
}
def get(self, path: str, params: dict = None) -> dict:
"""发送签名 GET 请求"""
from urllib.parse import urlencode
query_string = urlencode(params) if params else ""
headers = self.sign("GET", path, params=query_string)
url = f"{self.base_url}{path}"
if query_string:
url += f"?{query_string}"
return requests.get(url, headers=headers).json()
def post(self, path: str, data: dict = None) -> dict:
"""发送签名 POST 请求"""
body = json.dumps(data, ensure_ascii=False) if data else ""
headers = self.sign("POST", path, body=body)
return requests.post(
f"{self.base_url}{path}", headers=headers, data=body
).json()
# 使用示例
if __name__ == "__main__":
signer = NBTSigner(
api_key="your_api_key",
api_secret="your_api_secret_hex"
)
# GET 请求示例
result = signer.get("/nps/balance", {"wallet_id": "your_wallet_id"})
print("Balance:", result)
# POST 请求示例
result = signer.post("/nps/address", {
"wallet_id": "your_wallet_id",
"chain_id": "BASE_ETH",
"user_token": "user_123"
})
print("Address:", result)