67 production .py modules that the running PINK service imports but which were never committed: prod/bingx/ (HTTP client, market/user streams, journal, config), prod/clean_arch/ adapters/persistence/runtime/dita/dita_v2 production modules and their co-located tests. Rule going forward: every module imported by launch_dolphin_pink.py / pink_direct.py must appear in git ls-files. Excludes _backup dirs, __pycache__, and non-code files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
1.3 KiB
Python
49 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import hmac
|
|
import time
|
|
from collections.abc import Mapping
|
|
from urllib.parse import urlencode
|
|
|
|
|
|
def utc_timestamp_ms() -> int:
|
|
return int(time.time() * 1000)
|
|
|
|
|
|
def canonical_query(params: Mapping[str, object]) -> str:
|
|
filtered = {
|
|
key: value
|
|
for key, value in params.items()
|
|
if value is not None and value != ""
|
|
}
|
|
ordered = sorted(filtered.items(), key=lambda item: item[0])
|
|
return urlencode(ordered, doseq=True)
|
|
|
|
|
|
def sign_query(secret_key: str, query: str) -> str:
|
|
return hmac.new(
|
|
secret_key.encode("utf-8"),
|
|
query.encode("utf-8"),
|
|
hashlib.sha256,
|
|
).hexdigest()
|
|
|
|
|
|
def build_signed_params(
|
|
params: Mapping[str, object],
|
|
secret_key: str,
|
|
*,
|
|
timestamp_ms: int | None = None,
|
|
recv_window_ms: int | None = 5_000,
|
|
) -> dict[str, object]:
|
|
signed = dict(params)
|
|
signed["timestamp"] = utc_timestamp_ms() if timestamp_ms is None else int(timestamp_ms)
|
|
try:
|
|
parsed_recv_window = int(recv_window_ms) if recv_window_ms is not None else 5_000
|
|
except Exception:
|
|
parsed_recv_window = 5_000
|
|
signed["recvWindow"] = parsed_recv_window if parsed_recv_window > 0 else 5_000
|
|
query = canonical_query(signed)
|
|
signed["signature"] = sign_query(secret_key, query)
|
|
return signed
|