شروع به کار
در این راهنما، لیست سفارشها بازار را دریافت میکنید، کلید API میسازید و با Python پروفایل خود را میخوانید.
اگر فقط به دادههای عمومی بازار نیاز دارید، مرحلهٔ اول کافی است و نیازی به ورود یا ساخت کلید ندارید.
پیشنیازها
- برای درخواست اول، ابزار
curlرا داشته باشید. - درخواستها را از IP ایران ارسال کنید؛ جزئیات در سوالات متداول آمده است.
- برای اجرای مثال پایتونی، uv را نصب کنید.
آدرس پایه API: https://apiv2.nobitex.ir (محیط اصلی)
درخواستهای این راهنما فقط اطلاعات را میخوانند و معامله یا برداشتی انجام نمیدهند.
۱. اولین درخواست: دریافت لیست سفارشها
لیست سفارشها، فهرست سفارشهای خرید و فروش یک بازار است. در این مثال، بازار بیتکوین
به تتر (BTCUSDT) را میخوانید. این درخواست به توکن یا کلید API نیاز ندارد.
هدر User-Agent نام و نسخهٔ برنامهٔ شما را مشخص میکند.
curl "https://apiv2.nobitex.ir/v3/orderbook/BTCUSDT" --header "User-Agent: TraderBot/GettingStarted-1.0.0"
در Windows، همین دستور را با curl.exe بهجای curl اجرا کنید.
نمونهٔ پاسخ با قیمتها و حجمهای فرضی:
{
"status": "ok",
"lastUpdate": 1657620166710,
"lastTradePrice": "64000",
"bids": [["64000", "0.011121"]],
"asks": [["64001", "0.003500"]]
}
bids سفارشهای خرید و asks سفارشهای فروش هستند. هر جفت مقدار، بهترتیب قیمت
و حجم سفارش را نشان میدهد؛ در این بازار، قیمت بر حسب تتر و حجم بر حسب بیتکوین است.
برای پارامترها و پاسخ کامل، مرجع دریافت لیست سفارشها نسخه ۳ را ببینید.
۲. ساخت کلید API از پنل کاربری
برای دریافت اطلاعات حساب، کلیدی با دسترسی READ بسازید؛ این دسترسی اجازهٔ معامله یا برداشت نمیدهد.
- در مرورگر وارد حساب خود در وبسایت نوبیتکس شوید. اگر حساب ندارید، ابتدا ثبتنام کنید.
- در پنل کاربری، پروفایل، خدمات API را باز کنید.
- گزینهٔ ایجاد کلید API را انتخاب کنید. اگر احراز هویت دوعاملی (TOTP) حساب فعال نیست، ابتدا آن را طبق راهنمای پنل فعال کنید.
- برای کلید نامی مانند
getting-startedوارد کنید و فقط دسترسی خواندن (READ) را انتخاب کنید. - حتماً کوتاهترین زمان انقضای قابل انتخاب در پنل را برای کلید تعیین کنید تا اگر فراموش کردید آن را حذف کنید، خودکار منقضی شود. در صورت نیاز به محدودیت IP، آدرس خروجی اینترنت دستگاه یا سروری را وارد کنید که درخواستها را میفرستد.
- ساخت کلید را با وارد کردن کد دوعاملی و تکمیل تأییدهای پنل نهایی کنید.
- کلید عمومی و کلید خصوصی نمایشدادهشده را کپی و در محل امن ذخیره کنید.
- کلید عمومی (Public Key): همراه هر درخواست در هدر
Nobitex-Keyارسال میشود. - کلید خصوصی (Private Key): برنامه با آن امضا میسازد؛ خود این مقدار به سرور ارسال نمیشود.
کلید خصوصی فقط یک بار، هنگام ساخت کلید نمایش داده میشود. پیش از بستن پنجره آن را ذخیره کنید؛ در مخزن کد، لاگ یا پیامها قرار ندهید. اگر آن را از دست بدهید، باید کلید جدید بسازید.
۳. دریافت پروفایل با کلید API
کد زیر با ارسال درخواست امضاشده به GET /users/profile، پروفایل شما را دریافت میکند.
کد زیر را در فایلی به نام profile.py ذخیره کنید. در ابتدای کد، YOUR_PUBLIC_KEY
را با کلید عمومی کپیشده از پنل جایگزین کنید و علامتهای نقلقول را نگه دارید.
کلید خصوصی را در فایل ننویسید؛ هنگام اجرای اسکریپت در ترمینال، آن را در پاسخ به
Nobitex private key: وارد کنید. هنگام ورود کلید، کاراکترها نمایش داده نمیشوند.
import base64
import json
import time
from getpass import getpass
from http.client import HTTPSConnection
from urllib.parse import urlsplit
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
BASE_URL = 'https://apiv2.nobitex.ir'
PUBLIC_KEY = 'YOUR_PUBLIC_KEY'
USER_AGENT = 'TraderBot/GettingStarted-1.0.0'
def get_profile():
private_key_b64 = getpass('Nobitex private key: ')
method = 'GET'
full_path = '/users/profile'
raw_body = b''
timestamp = str(int(time.time()))
payload = (
timestamp.encode('utf-8')
+ method.encode('ascii')
+ full_path.encode('utf-8')
+ raw_body
)
private_key = Ed25519PrivateKey.from_private_bytes(
base64.urlsafe_b64decode(private_key_b64)
)
signature = base64.urlsafe_b64encode(private_key.sign(payload)).decode('ascii')
parsed_url = urlsplit(BASE_URL)
if parsed_url.scheme != 'https' or not parsed_url.hostname:
raise ValueError('BASE_URL must be an HTTPS URL')
connection = HTTPSConnection(
parsed_url.hostname,
parsed_url.port or 443,
timeout=15,
)
try:
connection.request(
method,
full_path,
body=raw_body,
headers={
'User-Agent': USER_AGENT,
'Nobitex-Key': PUBLIC_KEY,
'Nobitex-Signature': signature,
'Nobitex-Timestamp': timestamp,
},
)
response = connection.getresponse()
response_body = response.read()
finally:
connection.close()
if response.status >= 400:
raise RuntimeError(
f'HTTP {response.status}: {response_body.decode("utf-8", "replace")}'
)
print(json.dumps(json.loads(response_body), ensure_ascii=False, indent=2))
if __name__ == '__main__':
get_profile()
در پوشهٔ فایل، دستور زیر را اجرا کنید؛ uv بستهٔ cryptography را نصب و اسکریپت را اجرا میکند.
uv run --with cryptography profile.py
در صورت موفقیت، خروجی JSON شامل status: "ok" و اطلاعات پروفایل شما خواهد بود.
ساختار کامل پاسخ در مرجع دریافت پروفایل آمده است.
امضای درخواست چگونه ساخته میشود؟
کد بالا چهار بخش زیر را بدون هیچ جداکنندهای به هم وصل میکند، آنها را با کلید خصوصی و الگوریتم Ed25519 امضا میکند و نتیجه را به صورت URL-safe Base64 در هدر میفرستد:
timestamp + METHOD + full_path + raw_body
| بخش | مقدار در این مثال |
|---|---|
timestamp | زمان Unix بر حسب ثانیه، به صورت رشته؛ همان مقدار هدر Nobitex-Timestamp |
METHOD | GET؛ متد HTTP همیشه با حروف بزرگ نوشته میشود |
full_path | /users/profile؛ مسیر بدون دامنه و https:// |
raw_body | خالی است، چون این درخواست بدنه ندارد |
احراز هویت درخواست با این سه هدر انجام میشود:
| هدر | مقدار |
|---|---|
Nobitex-Key | کلید عمومی کپیشده از پنل |
Nobitex-Signature | امضای ساختهشده برای همین درخواست |
Nobitex-Timestamp | همان زمان استفادهشده در امضا |
اگر مثال را برای مسیر دیگری تغییر میدهید، پارامترهای آدرس (query string) هم باید
جزو full_path باشند؛ مثلاً /market/orders/list?fromId=123. برای درخواست دارای بدنه،
دقیقاً همان بایتهایی را امضا کنید که ارسال میکنید: تغییر فاصلهها، ترتیب فیلدهای JSON
یا شکست خط، امضا را نامعتبر میکند. برای هر درخواست، زمان و امضای جدید بسازید.
ساعت سیستم را همگام نگه دارید؛ زمان درخواست نباید بیش از ۳۰ ثانیه با ساعت سرور اختلاف داشته باشد.
قدم بعدی
برای افزودن درخواستهای دیگر، راهنمای کلید API را ببینید و دسترسی مورد نیاز هر درخواست را در صفحهٔ مرجع آن بررسی کنید. قواعد مشترک پاسخها و خطاها در ملاحظات عمومی آمده است.
پس از پایان آزمایش، اگر دیگر به کلید نیاز ندارید، آن را از بخش «خدمات API» پنل حذف کنید.