Stage 03.4 - private auth skeleton
This commit is contained in:
@@ -40,7 +40,7 @@ def load_settings() -> Settings:
|
|||||||
bot_parse_mode=os.getenv("BOT_PARSE_MODE", "HTML").strip() or "HTML",
|
bot_parse_mode=os.getenv("BOT_PARSE_MODE", "HTML").strip() or "HTML",
|
||||||
app_env=os.getenv("APP_ENV", "dev").strip() or "dev",
|
app_env=os.getenv("APP_ENV", "dev").strip() or "dev",
|
||||||
log_level=os.getenv("LOG_LEVEL", "INFO").strip().upper() or "INFO",
|
log_level=os.getenv("LOG_LEVEL", "INFO").strip().upper() or "INFO",
|
||||||
tz=os.getenv("TZ", "Europe/Madrid").strip() or "Europe/Madrid",
|
tz=os.getenv("TZ", "Europe/Minsk").strip() or "Europe/Minsk",
|
||||||
exchange_enabled=_parse_bool(os.getenv("EXCHANGE_ENABLED", "false")),
|
exchange_enabled=_parse_bool(os.getenv("EXCHANGE_ENABLED", "false")),
|
||||||
exchange_name=os.getenv("EXCHANGE_NAME", "dzengi").strip() or "dzengi",
|
exchange_name=os.getenv("EXCHANGE_NAME", "dzengi").strip() or "dzengi",
|
||||||
exchange_base_url=os.getenv("EXCHANGE_BASE_URL", "").strip(),
|
exchange_base_url=os.getenv("EXCHANGE_BASE_URL", "").strip(),
|
||||||
|
|||||||
25
app/src/integrations/exchange/auth.py
Normal file
25
app/src/integrations/exchange/auth.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class ExchangeAuth:
|
||||||
|
def __init__(self, api_key: str, api_secret: str):
|
||||||
|
self.api_key = api_key
|
||||||
|
self.api_secret = api_secret.encode()
|
||||||
|
|
||||||
|
def sign(self, query: str) -> str:
|
||||||
|
return hmac.new(self.api_secret, query.encode(), hashlib.sha256).hexdigest()
|
||||||
|
|
||||||
|
def build_headers(self):
|
||||||
|
return {
|
||||||
|
"X-MBX-APIKEY": self.api_key,
|
||||||
|
}
|
||||||
|
|
||||||
|
def build_signed_params(self, params: dict):
|
||||||
|
params["timestamp"] = int(time.time() * 1000)
|
||||||
|
query = "&".join(f"{k}={v}" for k, v in params.items())
|
||||||
|
signature = self.sign(query)
|
||||||
|
params["signature"] = signature
|
||||||
|
return params
|
||||||
24
app/src/integrations/exchange/private_client.py
Normal file
24
app/src/integrations/exchange/private_client.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
from src.core.config import load_settings
|
||||||
|
from src.integrations.exchange.rest_client import ExchangeRestClient
|
||||||
|
from src.integrations.exchange.auth import ExchangeAuth
|
||||||
|
|
||||||
|
|
||||||
|
class ExchangePrivateClient:
|
||||||
|
def __init__(self):
|
||||||
|
settings = load_settings()
|
||||||
|
self.client = ExchangeRestClient()
|
||||||
|
self.auth = ExchangeAuth(
|
||||||
|
api_key=settings.exchange_api_key,
|
||||||
|
api_secret=settings.exchange_api_secret,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_account_info(self):
|
||||||
|
params = {}
|
||||||
|
signed = self.auth.build_signed_params(params)
|
||||||
|
|
||||||
|
return self.client.get_json(
|
||||||
|
"/api/v2/account",
|
||||||
|
params=signed,
|
||||||
|
headers=self.auth.build_headers(),
|
||||||
|
)
|
||||||
10
docs/stages/stage-03-4-auth.md
Normal file
10
docs/stages/stage-03-4-auth.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
# Stage 03.4 — Auth
|
||||||
|
|
||||||
|
## Что реализовано
|
||||||
|
- HMAC подпись
|
||||||
|
- headers
|
||||||
|
- private client
|
||||||
|
|
||||||
|
## Дальше
|
||||||
|
Stage 03.5 — account + balances
|
||||||
Reference in New Issue
Block a user