发布数据时签名无效的问题

问题描述 投票:0回答:1

问题在于尝试在某些交换 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&timestamp=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)
python cryptography aiohttp ed25519
1个回答
0
投票

整个历史中的事情是这个 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)与某些内容发生冲突,这就是签名问题。

© www.soinside.com 2019 - 2024. All rights reserved.