问题在于尝试在某些交换 API 上使用 aiohttp 发送 post 请求。有了这个请求,我必须发送这个标头:
headers = {
'X-Timestamp': str(timestamp),
'X-Window': str(self.WINDOW),
'X-API-Key': self.public_key,
'X-Signature': signature
}
除了签名之外,所有标题都是正确的(我测试过)。
如果有签名格式,我总是显示“无效签名”。
它的结构一定是这样的:
instruction=orderExecute&postOnly=False&price=1&quantity=10&selfTradePrevention=Allow&side=Bid&symbol=SOL_USDC&timeInForce=IOC×tamp=1710451343478&window=6000
这是我试图发布的内容
并且它必须由 private_key 签名,这是一对标头的公钥,然后我才发送带有一些主体参数的数据。
!!!“无效签名”!!!.
主体“参数”是正确的(更改它们会给出另一个响应)
“headers”也是正确的,与正文“params”的原因相同
带有签名结构的API文档:https://docs.backpack.exchange/#section/Authentication
这是我的代码
class Site:
WINDOW = 6000
def __init__(self, token, private_key):
self.public_key = token
self.private_key = private_key
async def headers(self, params: dict, instruction: str) -> dict:
timestamp = await self._unix_time()
params["window"] = self.WINDOW
params["timestamp"] = timestamp
sorted_params = sorted(params.items())
query_string = f"instruction={instruction}&"+'&'.join(f"{key}={value}" for key, value in sorted_params)
signature = await self._sign(query_string)
headers = {
'X-Timestamp': str(timestamp),
'X-Window': str(self.WINDOW),
'X-API-Key': self.public_key,
'X-Signature': signature
}
return headers
async def _sign(self, data):
private_key_bytes = base64.b64decode(self.private_key)
private_key = Ed25519PrivateKey.from_private_bytes(private_key_bytes)
signature = private_key.sign(data.encode())
signature_base64 = base64.b64encode(signature).decode()
return signature_base64
@staticmethod
async def _unix_time():
async with aiohttp.ClientSession() as session:
async with session.get("https://api.backpack.exchange/api/v1/time") as response:
return await response.text()
class Trade(Site):
def __init__(self, public_key, private_key):
super().__init__(public_key, private_key)
async def buy_order(self):
params = {
"orderType": OrderType.LIMIT.value,
"postOnly": PostOnly.FALSE.value,
"price": "1",
"quantity": "10",
"selfTradePrevention": SelfTradePrevention.ALLOW.value,
"side": Side.BUY.value,
"symbol": Symbol.SOL.value,
"timeInForce": TimeInForce.IOC.value,
}
headers = await self.headers(params=params, instruction=Instruction.ORDER_EXECUTE.value)
headers['Content-Type'] = 'application/json; charset=utf-8'
body = json.dumps(params)
r = await _handle_post(headers=headers, body=body)
整个历史中的事情是这个 API 非常新(而且很糟糕)。 所以当它接受带有这个参数的 body 时:
params = {
"orderType": OrderType.LIMIT.value,
"postOnly": PostOnly.FALSE.value,
"price": "1",
"quantity": "10",
"selfTradePrevention": SelfTradePrevention.ALLOW.value,
"side": Side.BUY.value,
"symbol": Symbol.SOL.value,
"timeInForce": TimeInForce.IOC.value,
}
如果您尝试删除其中一些数据,您会收到回复说您身体出了问题。 如果不是,则表示问题出在签名中(事实并非如此)。
param "postOnly"(无论 True 或 False)与某些内容发生冲突,这就是签名问题。