xync-client 0.0.11.dev12__tar.gz → 0.0.11.dev15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. {xync_client-0.0.11.dev12/xync_client.egg-info → xync_client-0.0.11.dev15}/PKG-INFO +1 -1
  2. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/README.md +2 -0
  3. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/pyproject.toml +1 -1
  4. xync_client-0.0.11.dev15/tests/Abc/AgentTest.py +17 -0
  5. xync_client-0.0.11.dev15/tests/Abc/BaseTest.py +56 -0
  6. xync_client-0.0.11.dev15/tests/TestEx.py +45 -0
  7. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Abc/Agent.py +9 -4
  8. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Abc/Auth.py +7 -5
  9. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/ex.py +4 -5
  10. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BingX/base.py +3 -1
  11. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BingX/ex.py +4 -3
  12. xync_client-0.0.11.dev15/xync_client/BingX/test/main.py +22 -0
  13. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BitGet/agent.py +1 -1
  14. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BitGet/ex.py +27 -12
  15. xync_client-0.0.11.dev12/xync_client/Bybit/ex.py → xync_client-0.0.11.dev15/xync_client/Bybit/agent.py +28 -59
  16. xync_client-0.0.11.dev15/xync_client/Bybit/ex.py +58 -0
  17. xync_client-0.0.11.dev12/xync_client/Gate/pub.py → xync_client-0.0.11.dev15/xync_client/Gate/ex.py +4 -3
  18. xync_client-0.0.11.dev15/xync_client/Htx/agent.py +115 -0
  19. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Htx/ex.py +7 -4
  20. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/agent.py +6 -13
  21. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/auth.py +2 -0
  22. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/ex.py +3 -2
  23. xync_client-0.0.11.dev15/xync_client/__init__.py +0 -0
  24. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15/xync_client.egg-info}/PKG-INFO +1 -1
  25. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client.egg-info/SOURCES.txt +8 -6
  26. xync_client-0.0.11.dev12/xync_client/AbcTest/AgentTest.py +0 -13
  27. xync_client-0.0.11.dev12/xync_client/AbcTest/BaseTest.py +0 -42
  28. xync_client-0.0.11.dev12/xync_client/AbcTest/ExTest.py +0 -12
  29. xync_client-0.0.11.dev12/xync_client/BingX/test/main.py +0 -39
  30. xync_client-0.0.11.dev12/xync_client/Htx/agent.py +0 -18
  31. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/.env.sample +0 -0
  32. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/.gitignore +0 -0
  33. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/.pre-commit-config.yaml +0 -0
  34. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/makefile +0 -0
  35. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/setup.cfg +0 -0
  36. {xync_client-0.0.11.dev12/xync_client/AbcTest → xync_client-0.0.11.dev15/tests/Abc}/OrderTest.py +0 -0
  37. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/Binance/test_binance.py +0 -0
  38. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/Bybit/test_bybit.py +0 -0
  39. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/Bybit/test_bybit_p2p.py +0 -0
  40. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/Gate/test_gate.py +0 -0
  41. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/Htx/test_htx_p2p.py +0 -0
  42. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/tests/__init__.py +0 -0
  43. /xync_client-0.0.11.dev12/tests/test_ex.py → /xync_client-0.0.11.dev15/tests/_test_ex.py +0 -0
  44. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Abc/Base.py +0 -0
  45. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Abc/Ex.py +0 -0
  46. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Abc/Order.py +0 -0
  47. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/__init__.py +0 -0
  48. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/binance_async.py +0 -0
  49. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/earn_api.py +0 -0
  50. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/exceptions.py +0 -0
  51. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/sapi.py +0 -0
  52. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Binance/web_c2c.py +0 -0
  53. {xync_client-0.0.11.dev12/xync_client/BitGet → xync_client-0.0.11.dev15/xync_client/BingX}/__init__.py +0 -0
  54. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BingX/req.mjs +0 -0
  55. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BingX/sign.js +0 -0
  56. {xync_client-0.0.11.dev12/xync_client → xync_client-0.0.11.dev15/xync_client/BitGet}/__init__.py +0 -0
  57. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/BitGet/req.mjs +0 -0
  58. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Bybit/web_earn.py +0 -0
  59. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Bybit/web_p2p.py +0 -0
  60. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Gate/premarket.py +0 -0
  61. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Htx/earn.py +0 -0
  62. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/KuCoin/pub.py +0 -0
  63. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/KuCoin/web.py +0 -0
  64. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/Okx/ex.py +0 -0
  65. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/order.py +0 -0
  66. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/pyro.py +0 -0
  67. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/TgWallet/web.py +0 -0
  68. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client/loader.py +0 -0
  69. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client.egg-info/dependency_links.txt +0 -0
  70. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client.egg-info/requires.txt +0 -0
  71. {xync_client-0.0.11.dev12 → xync_client-0.0.11.dev15}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xync-client
3
- Version: 0.0.11.dev12
3
+ Version: 0.0.11.dev15
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -159,3 +159,5 @@ classDef red stroke:#f00
159
159
  - 36N: Получение сообщения от юзера `get_user_msg => (msg:str, file=None)`
160
160
  - 37N: Получение уведомления о (раз)блокировке юзером `got_blocked => is_blocked:bool`
161
161
  - 38N: Получение уведомления о полученном отзыве `got_rated => (user_id:int, order_id:int)`
162
+
163
+ - 39: Получить балансы моих монет: `my_assets() => list[Asset]`
@@ -44,4 +44,4 @@ line-length = 120
44
44
 
45
45
  [tool.pytest.ini_options]
46
46
  asyncio_mode = "auto"
47
- asyncio_default_fixture_loop_scope = "class" # , "session", "module", "package", "function"
47
+ asyncio_default_fixture_loop_scope = "session" # , "class", "module", "package", "function"
@@ -0,0 +1,17 @@
1
+ import pytest
2
+
3
+ from tests.Abc.BaseTest import BaseTest
4
+ from xync_client.Abc.Agent import BaseAgentClient
5
+ from xync_client.Abc.Base import BaseClient
6
+
7
+
8
+ class AgentTest(BaseTest):
9
+ async def clients(self) -> list[BaseClient]:
10
+ pass
11
+
12
+ @pytest.fixture(scope="class", autouse=True)
13
+ async def cl(self) -> BaseAgentClient:
14
+ agent = (await self.ex).agents.filter(auth__not_isnull=True).first()
15
+ acl = BaseClient(agent)
16
+ yield acl
17
+ await acl.close()
@@ -0,0 +1,56 @@
1
+ from abc import abstractmethod
2
+
3
+ # from asyncio import AbstractEventLoop
4
+ from typing import TypeGuard
5
+
6
+ import pytest
7
+
8
+ # import uvloop
9
+ from tortoise.backends.asyncpg import AsyncpgDBClient
10
+ from x_model import init_db
11
+ from xync_client.Abc.Base import BaseClient, DictOfDicts, ListOfDicts, FlatDict, MapOfIdsList
12
+ from xync_schema import models
13
+
14
+ from xync_client.loader import PG_DSN
15
+
16
+
17
+ class BaseTest:
18
+ # loop: AbstractEventLoop
19
+
20
+ # @pytest.fixture(scope="session", autouse=True)
21
+ # def event_loop_policy(self):
22
+ # return uvloop.EventLoopPolicy()
23
+
24
+ @pytest.fixture(scope="session", autouse=True)
25
+ async def cn(self) -> AsyncpgDBClient:
26
+ cn: AsyncpgDBClient = await init_db(PG_DSN, models, True)
27
+ yield cn
28
+ await cn.close()
29
+
30
+ @abstractmethod
31
+ @pytest.fixture(scope="session")
32
+ async def clients(self) -> list[BaseClient]: ...
33
+
34
+ @staticmethod
35
+ def is_dict_of_dicts(dct: DictOfDicts, not_empty: bool = True) -> TypeGuard[DictOfDicts]:
36
+ if not_empty and not len(dct):
37
+ return False
38
+ return all(isinstance(k, int | str) and isinstance(v, dict) for k, v in dct.items())
39
+
40
+ @staticmethod
41
+ def is_list_of_dicts(lst: ListOfDicts, not_empty: bool = True) -> TypeGuard[ListOfDicts]:
42
+ if not_empty and not len(lst):
43
+ return False
44
+ return all(isinstance(el, dict) for el in lst)
45
+
46
+ @staticmethod
47
+ def is_flat_dict(dct: FlatDict, not_empty: bool = True) -> TypeGuard[FlatDict]:
48
+ if not_empty and not len(dct):
49
+ return False
50
+ return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
51
+
52
+ @staticmethod
53
+ def is_map_of_ids(dct: MapOfIdsList, not_empty: bool = True) -> TypeGuard[MapOfIdsList]:
54
+ if not_empty and not len(dct):
55
+ return False
56
+ return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
@@ -0,0 +1,45 @@
1
+ import logging
2
+
3
+ import pytest
4
+ from xync_schema.enums import ExStatus, ExType, ExAction
5
+ from xync_schema.models import Ex, TestEx as ExTest
6
+
7
+ from tests.Abc.BaseTest import BaseTest
8
+ from xync_client.Abc.Base import BaseClient, DictOfDicts, FlatDict
9
+ from xync_client.Abc.Ex import BaseExClient
10
+
11
+
12
+ @pytest.mark.asyncio(loop_scope="session")
13
+ class TestEx(BaseTest):
14
+ @pytest.fixture
15
+ async def clients(self) -> list[BaseClient]:
16
+ exs = await Ex.filter(status__gt=ExStatus.plan)
17
+ [await ex.fetch_related("agents") for ex in exs if ex.type_ == ExType.tg]
18
+ clients: list[BaseExClient] = [ex.client() for ex in exs]
19
+ yield clients
20
+ [await cl.close() for cl in clients]
21
+
22
+ # 20
23
+ async def test_pms(self, clients: list[BaseExClient]):
24
+ for client in clients:
25
+ pms: DictOfDicts = await client.pms()
26
+ t, _ = await ExTest.update_or_create({"ok": self.is_dict_of_dicts(pms)}, ex=client.ex, action=ExAction.pms)
27
+ assert t.ok, "No pms"
28
+ logging.info(f"{client.ex.name}:{ExAction.pms.name} - ok")
29
+
30
+ # 21
31
+ async def test_curs(self, clients: list[BaseExClient]):
32
+ for client in clients:
33
+ curs: FlatDict = await client.curs()
34
+ t, _ = await ExTest.update_or_create({"ok": self.is_flat_dict(curs)}, ex=client.ex, action=ExAction.curs)
35
+ assert t.ok, "No curs"
36
+ logging.info(f"{client.ex.name}:{ExAction.pms.name} - ok")
37
+
38
+ # 22
39
+ async def test_cur_pms_map(self, clients: list[BaseExClient]):
40
+ for client in clients:
41
+ cur_pms: DictOfDicts = await client.cur_pms_map()
42
+ ok = self.is_dict_of_dicts(cur_pms)
43
+ t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.cur_pms_map)
44
+ assert t.ok, "No pms for cur"
45
+ logging.info(f"{client.ex.name}:{ExAction.pms.name} - ok")
@@ -1,7 +1,8 @@
1
1
  from abc import abstractmethod
2
2
 
3
+ from xync_client.Abc.Base import ListOfDicts
4
+
3
5
  from xync_client.Abc.Auth import BaseAuthClient
4
- from xync_schema.enums import PmType
5
6
  from xync_schema.models import OrderStatus, Coin, Cur, Order, Pm, Ad, AdStatus, Fiat
6
7
  from xync_schema.pydantic import FiatNew
7
8
 
@@ -10,7 +11,7 @@ class BaseAgentClient(BaseAuthClient):
10
11
  # 0: Получшение ордеров в статусе status, по монете coin, в валюте coin, в направлении is_sell: bool
11
12
  @abstractmethod
12
13
  async def get_orders(
13
- self, stauts: OrderStatus = OrderStatus.active, coin: Coin = None, cur: Cur = None, is_sell: bool = None
14
+ self, stauts: OrderStatus = OrderStatus.created, coin: Coin = None, cur: Cur = None, is_sell: bool = None
14
15
  ) -> list[Order]: ...
15
16
 
16
17
  # 1: [T] Получшение ордеров в статусе status, по монете coin, в валюте coin, в направлении is_sell: bool
@@ -23,7 +24,7 @@ class BaseAgentClient(BaseAuthClient):
23
24
  # # # Fiat
24
25
  # 25: Список реквизитов моих платежных методов
25
26
  @abstractmethod
26
- async def my_fiats(self, cur: Cur = None) -> list[dict]: ...
27
+ async def my_fiats(self, cur: Cur = None) -> ListOfDicts: ...
27
28
 
28
29
  # 26: Создание
29
30
  @abstractmethod
@@ -31,7 +32,7 @@ class BaseAgentClient(BaseAuthClient):
31
32
 
32
33
  # 27: Редактирование
33
34
  @abstractmethod
34
- async def fiat_upd(self, detail: str = None, type_: PmType = None) -> bool: ...
35
+ async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> bool: ...
35
36
 
36
37
  # 28: Удаление
37
38
  @abstractmethod
@@ -99,3 +100,7 @@ class BaseAgentClient(BaseAuthClient):
99
100
  # 38: Поставить отзыв юзеру
100
101
  @abstractmethod
101
102
  async def rate_user(self, positive: bool) -> bool: ...
103
+
104
+ # 39: Балансы моих монет
105
+ @abstractmethod
106
+ async def my_assets(self) -> dict: ...
@@ -3,21 +3,23 @@ from abc import abstractmethod
3
3
 
4
4
  from aiohttp import ClientResponse
5
5
  from aiohttp.http_exceptions import HttpProcessingError
6
- from xync_schema.models import Agent
6
+ from xync_schema.models import Agent, Ex
7
7
 
8
8
  from xync_client.Abc.Base import BaseClient
9
9
 
10
10
 
11
11
  class BaseAuthClient(BaseClient):
12
- def __init__(self, agent: Agent):
13
- self.headers.update(agent.auth)
14
- self.agent = agent
12
+ def __init__(self, agent: Agent | Ex):
13
+ # dirty hack for multi-inheritance
14
+ self.agent = agent if isinstance(agent, Agent) else agent.agents[0]
15
+ ex = agent if isinstance(agent, Ex) else agent.ex
16
+ self.headers.update(self.agent.auth)
15
17
  self.meth = {
16
18
  "GET": self._get,
17
19
  "POST": self._post,
18
20
  "DELETE": self._delete,
19
21
  }
20
- super().__init__(agent.ex)
22
+ super().__init__(ex)
21
23
 
22
24
  @abstractmethod
23
25
  async def _get_auth_hdrs(self) -> dict[str, str]: ...
@@ -1,13 +1,12 @@
1
1
  from xync_schema.enums import PmType
2
2
 
3
- from xync_client.Abc.Ex import BaseClient
4
- from xync_client.Binance.sapi import Sapi
3
+ from xync_client.Abc.Ex import BaseExClient
5
4
  from xync_schema.models import Ex
6
5
 
7
6
 
8
- class Client(BaseClient):
9
- def __init__(self, ex: Ex, bkeys):
10
- self.sapi = Sapi(*bkeys)
7
+ class ExClient(BaseExClient):
8
+ def __init__(self, ex: Ex):
9
+ # self.sapi = Sapi(*bkeys)
11
10
  super().__init__(ex)
12
11
 
13
12
  async def curs(self) -> dict:
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import subprocess
2
3
  from datetime import datetime
3
4
  from json import dumps
@@ -11,7 +12,8 @@ class BaseBingXClient(BaseClient):
11
12
  traceid = str(uuid4()).replace("-", "")
12
13
  now = str(int(datetime.now().timestamp() * 1000))
13
14
  payload = dumps(_payload, separators=(",", ":"), sort_keys=True) if _payload else "{}"
14
- p = subprocess.Popen(["node", "req.mjs", now, traceid, payload], stdout=subprocess.PIPE)
15
+ pref = "../xync_client/BingX/" if os.getcwd().split("/")[-1] == "tests" else ""
16
+ p = subprocess.Popen(["node", pref + "req.mjs", now, traceid, payload], stdout=subprocess.PIPE)
15
17
  sign = p.stdout.read().decode().strip()
16
18
  return {
17
19
  "sign": sign,
@@ -10,7 +10,7 @@ from xync_client.BingX.base import BaseBingXClient
10
10
  from xync_client.loader import PG_DSN
11
11
 
12
12
 
13
- class Client(BaseExClient, BaseBingXClient):
13
+ class ExClient(BaseExClient, BaseBingXClient):
14
14
  headers: dict[str, str] = {
15
15
  "app_version": "9.0.5",
16
16
  "device_id": "ccfb6d50-b63b-11ef-b31f-ef1f76f67c4e",
@@ -53,9 +53,10 @@ class Client(BaseExClient, BaseBingXClient):
53
53
  async def main():
54
54
  _ = await init_db(PG_DSN, models, True)
55
55
  bg = await Ex.get(name="BingX")
56
- cl = Client(bg)
56
+ cl = ExClient(bg)
57
57
  await cl.pms()
58
58
  await cl.close()
59
59
 
60
60
 
61
- run(main())
61
+ if __name__ == "__main__":
62
+ run(main())
@@ -0,0 +1,22 @@
1
+ import requests
2
+
3
+ headers = {
4
+ "app_version": "8.10.0",
5
+ "device_id": "64a8c630-acc2-11ef-aa5e-9f6ee3baa1a5",
6
+ "lang": "ru-RU",
7
+ "platformid": "30",
8
+ "sign": "5679FBAAF1D0A199E6B0975616B44807220C5FC8824D41F0DE21D2261F2D8E18",
9
+ "timestamp": "1733496004073",
10
+ "traceid": "8557cddbfe574e07b36c3014b5773358",
11
+ }
12
+
13
+ params = {
14
+ "coinName": "USDT",
15
+ "tradeCoinName": "USD",
16
+ "type": "1",
17
+ "amount": "500",
18
+ }
19
+
20
+ response = requests.get("https://api-app.qq-os.com/api/fiat/v1/rapid-buy-integration", params=params, headers=headers)
21
+
22
+ print([i.get("paymentMethod")["name"] for i in response.json()["data"]["matchOptimalAdvertListVo"]["optimals"]])
@@ -19,7 +19,7 @@ class Client(BaseAgentClient):
19
19
  super().__init__(agent)
20
20
 
21
21
  async def get_orders(
22
- self, stauts: OrderStatus = OrderStatus.active, coin: Coin = None, cur: Cur = None, is_sell: bool = None
22
+ self, stauts: OrderStatus = OrderStatus.created, coin: Coin = None, cur: Cur = None, is_sell: bool = None
23
23
  ) -> list[Order]:
24
24
  pass
25
25
 
@@ -1,4 +1,5 @@
1
1
  import json
2
+ import os
2
3
  import subprocess
3
4
  from asyncio import run
4
5
 
@@ -7,12 +8,16 @@ from xync_client.Abc.Base import DictOfDicts
7
8
  from xync_schema import models
8
9
  from xync_schema.models import Cur, Ex
9
10
 
10
- from xync_client.Abc.Ex import BaseClient
11
+ from xync_client.Abc.Ex import BaseExClient
11
12
  from xync_client.loader import PG_DSN
12
13
 
13
14
 
14
- class Client(BaseClient):
15
- headers = {"accept-language": "ru,en;q=0.9"}
15
+ class ExClient(BaseExClient):
16
+ headers = {
17
+ "accept-language": "ru,en;q=0.9",
18
+ "content-type": "application/json;charset=UTF-8",
19
+ "deviceid": "883e1394d8a2278418b6f02804df16c4",
20
+ }
16
21
 
17
22
  async def curs(self) -> dict[str, str]:
18
23
  curs = (await self._post("/v1/p2p/pub/currency/queryAllCoinAndFiat"))["data"]["fiatInfoRespList"]
@@ -23,14 +28,23 @@ class Client(BaseClient):
23
28
  return {coin["coinCode"]: coin["coinCode"] for coin in coins}
24
29
 
25
30
  async def pms(self) -> DictOfDicts: # {pm.exid: pm}
26
- # curs = (await self._post("pub/currency/queryAllCoinAndFiat"))["data"]["fiatInfoRespList"]
27
- p = subprocess.Popen(
28
- ["node", "req.mjs", "user/queryPaymethods", '{"languageType":6}', self.headers], stdout=subprocess.PIPE
29
- )
30
- out = p.stdout.read().decode()
31
- curs: list[dict] = json.loads(out)
31
+ for id_, cur in (await self.curs()).items():
32
+ pref = "../xync_client/BitGet/" if os.getcwd().split("/")[-1] == "tests" else ""
33
+ data = {"fiatCode": cur, "languageType": 6}
34
+ p = subprocess.Popen(
35
+ [
36
+ "node",
37
+ pref + "req.mjs",
38
+ "pub/currency/query-popular-paymethod",
39
+ json.dumps(data, separators=(",", ":")),
40
+ json.dumps(self.headers, separators=(",", ":")),
41
+ ],
42
+ stdout=subprocess.PIPE,
43
+ )
44
+ out = p.stdout.read().decode()
45
+ pms: list[dict] = json.loads(out)
32
46
 
33
- pmcurs = {cur["fiatCode"]: cur["paymethodInfo"] for cur in curs}
47
+ pmcurs = {pm["fiatCode"]: pm["paymethodInfo"] for pm in pms}
34
48
  pp = {}
35
49
  [
36
50
  [pp.update({int(p["paymethodId"]): {"name": p["paymethodName"], "logo": p.get("iconUrl")}}) for p in ps]
@@ -76,7 +90,7 @@ class Client(BaseClient):
76
90
  async def main():
77
91
  _ = await init_db(PG_DSN, models, True)
78
92
  bg = await Ex.get(name="BitGet")
79
- cl = Client(bg)
93
+ cl = ExClient(bg)
80
94
  # await cl.curs()
81
95
  # await cl.coins()
82
96
  # await cl.ads("BTC", "RUB", True, [1, 289, 375])
@@ -87,4 +101,5 @@ async def main():
87
101
  await cl.close()
88
102
 
89
103
 
90
- run(main())
104
+ if __name__ == "__main__":
105
+ run(main())
@@ -2,8 +2,10 @@ from enum import IntEnum
2
2
  from time import sleep
3
3
 
4
4
  import pyotp
5
- from x_client.http import Client
5
+ from xync_client.Abc.Base import FlatDict
6
+ from xync_schema.models import Cur
6
7
 
8
+ from xync_client.Abc.Agent import BaseAgentClient
7
9
  from xync_client.loader import BYT2FA
8
10
 
9
11
 
@@ -16,10 +18,9 @@ class AdsStatus(IntEnum):
16
18
  WORKING = 1
17
19
 
18
20
 
19
- class BybitP2P(Client): # Bybit client
21
+ class ExClient(BaseAgentClient): # Bybit client
20
22
  host = "api2.bybit.com"
21
-
22
- pub_header = {"cookie": ";"} # rewrite token for public methods
23
+ headers = {"cookie": ";"} # rewrite token for public methods
23
24
 
24
25
  last_ad_id: list[str] = []
25
26
  create_ad_body = {
@@ -79,49 +80,15 @@ class BybitP2P(Client): # Bybit client
79
80
  "securityRiskToken": "",
80
81
  }
81
82
 
82
- """ PUBLIC METHS """
83
-
84
- def get_ads(self, coin: str, cur: str, sell: bool = False, amount: int = None, payment: list[str] = None) -> list:
85
- data = {
86
- "userId": "",
87
- "tokenId": coin,
88
- "currencyId": cur,
89
- "payment": payment or [],
90
- "side": "0" if sell else "1",
91
- "size": "10",
92
- "page": "1",
93
- "amount": str(amount) if amount else "",
94
- "authMaker": False,
95
- "canTrade": False,
96
- }
97
- ads = self._post("/fiat/otc/item/online/", data, self.pub_header)
98
- return ads["result"]["items"]
99
-
100
- def get_config(self):
101
- resp = self._get("/fiat/p2p/config/initial", self.pub_header)
102
- return resp["result"] # todo: tokens, pairs, ...
103
-
104
- def get_currencies(self):
105
- config = self.get_config()
106
- return config["symbols"]
107
-
108
- def get_coins(self):
109
- coins = self._get("/spot/api/basic/symbol_list", self.pub_header)
110
- return coins
111
-
112
- def get_payment_methods(self):
113
- pms = self._post("/fiat/otc/configuration/queryAllPaymentList/", headers=self.pub_header)
114
- return pms
115
-
116
83
  """ Private METHs"""
117
84
 
118
- def create_payment_method(self, payment_type: int, real_name: str, account_number: str) -> dict:
85
+ def fiat_new(self, payment_type: int, real_name: str, account_number: str) -> FlatDict:
119
86
  method1 = self._post(
120
87
  "/fiat/otc/user/payment/new_create",
121
88
  {"paymentType": payment_type, "realName": real_name, "accountNo": account_number, "securityRiskToken": ""},
122
89
  )
123
90
  if srt := method1["result"]["securityRiskToken"]:
124
- self.check_2fa(srt)
91
+ self._check_2fa(srt)
125
92
  method2 = self._post(
126
93
  "/fiat/otc/user/payment/new_create",
127
94
  {
@@ -142,24 +109,26 @@ class BybitP2P(Client): # Bybit client
142
109
  return fiat
143
110
  return list_methods[1]
144
111
 
145
- def update_payment_method(self, real_name: str, account_number: str, fiat_id: int = None) -> dict:
112
+ # 27
113
+ def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> dict:
146
114
  fiat = self.get_payment_method(fiat_id)
147
- fiat["realName"] = real_name
148
- fiat["accountNo"] = account_number
149
- result = self._post("/fiat/otc/user/payment/new_update", fiat)
115
+ fiat["realName"] = name
116
+ fiat["accountNo"] = detail
117
+ result = await self._post("/fiat/otc/user/payment/new_update", fiat)
150
118
  srt = result["result"]["securityRiskToken"]
151
- self.check_2fa(srt)
119
+ self._check_2fa(srt)
152
120
  fiat["securityRiskToken"] = srt
153
- result2 = self._post("/fiat/otc/user/payment/new_update", fiat)
121
+ result2 = await self._post("/fiat/otc/user/payment/new_update", fiat)
154
122
  return result2
155
123
 
156
- def delete_payment_method(self, ids: str) -> dict:
157
- data = {"id": ids, "securityRiskToken": ""}
158
- method = self._post("/fiat/otc/user/payment/new_delete", data)
124
+ # 28
125
+ def fiat_del(self, fiat_id: int) -> dict:
126
+ data = {"id": fiat_id, "securityRiskToken": ""}
127
+ method = await self._post("/fiat/otc/user/payment/new_delete", data)
159
128
  srt = method["result"]["securityRiskToken"]
160
- self.check_2fa(srt)
129
+ self._check_2fa(srt)
161
130
  data["securityRiskToken"] = srt
162
- delete = self._post("/fiat/otc/user/payment/new_delete", data)
131
+ delete = await self._post("/fiat/otc/user/payment/new_delete", data)
163
132
  return delete
164
133
 
165
134
  def switch_ads(self, new_status: AdsStatus) -> dict:
@@ -176,8 +145,8 @@ class BybitP2P(Client): # Bybit client
176
145
  ads = [ad for ad in list_ads if set(ad["payments"]) - {"5", "51"}]
177
146
  return float(ads[0]["price"])
178
147
 
179
- def get_user_pay_methods(self):
180
- upm = self._post("/fiat/otc/user/payment/list")
148
+ def my_fiats(self, cur: Cur = None):
149
+ upm = await self._post("/fiat/otc/user/payment/list")
181
150
  return upm["result"]
182
151
 
183
152
  def get_user_ads(self, active: bool = True) -> list:
@@ -191,7 +160,7 @@ class BybitP2P(Client): # Bybit client
191
160
  security_risk_token = data["result"]["securityRiskToken"]
192
161
  return security_risk_token
193
162
 
194
- def check_2fa(self, risk_token):
163
+ def _check_2fa(self, risk_token):
195
164
  # 2fa code
196
165
  bybit_secret = BYT2FA
197
166
  totp = pyotp.TOTP(bybit_secret)
@@ -203,7 +172,7 @@ class BybitP2P(Client): # Bybit client
203
172
  if res["ret_msg"] != "success":
204
173
  print("Wrong 2fa, wait 5 secs and retry..")
205
174
  sleep(5)
206
- self.check_2fa(risk_token)
175
+ self._check_2fa(risk_token)
207
176
  return res
208
177
 
209
178
  def post_ad(self, risk_token: str):
@@ -213,8 +182,8 @@ class BybitP2P(Client): # Bybit client
213
182
 
214
183
  # создание объявлений
215
184
  def post_create_ad(self, token: str):
216
- result_check_2fa = self.check_2fa(token)
217
- assert result_check_2fa["ret_msg"] == "success", "2FA code wrong"
185
+ result__check_2fa = self._check_2fa(token)
186
+ assert result__check_2fa["ret_msg"] == "success", "2FA code wrong"
218
187
 
219
188
  result_add_ad = self._post_ad(token)
220
189
  if result_add_ad["ret_msg"] != "SUCCESS":
@@ -230,8 +199,8 @@ class BybitP2P(Client): # Bybit client
230
199
  return security_risk_token
231
200
 
232
201
  def post_update_ad(self, token):
233
- result_check_2fa = self.check_2fa(token)
234
- assert result_check_2fa["ret_msg"] == "success", "2FA code wrong"
202
+ result__check_2fa = self._check_2fa(token)
203
+ assert result__check_2fa["ret_msg"] == "success", "2FA code wrong"
235
204
 
236
205
  result_update_ad = self.update_ad(token)
237
206
  if result_update_ad["ret_msg"] != "SUCCESS":
@@ -0,0 +1,58 @@
1
+ from enum import IntEnum
2
+
3
+ from xync_client.Abc.Base import ListOfDicts, MapOfIdsList
4
+ from xync_client.Abc.Ex import BaseExClient
5
+
6
+
7
+ class AdsStatus(IntEnum):
8
+ REST = 0
9
+ WORKING = 1
10
+
11
+
12
+ class ExClient(BaseExClient): # Bybit client
13
+ host = "api2.bybit.com"
14
+ headers = {"cookie": ";"} # rewrite token for public methods
15
+
16
+ """ PUBLIC METHS """
17
+
18
+ async def get_ads(
19
+ self, coin: str, cur: str, sell: bool = False, amount: int = None, payment: list[str] = None
20
+ ) -> list:
21
+ data = {
22
+ "userId": "",
23
+ "tokenId": coin,
24
+ "currencyId": cur,
25
+ "payment": payment or [],
26
+ "side": "0" if sell else "1",
27
+ "size": "10",
28
+ "page": "1",
29
+ "amount": str(amount) if amount else "",
30
+ "authMaker": False,
31
+ "canTrade": False,
32
+ }
33
+ ads = await self._post("/fiat/otc/item/online/", data)
34
+ return ads["result"]["items"]
35
+
36
+ async def get_config(self):
37
+ resp = await self._get("/fiat/p2p/config/initial")
38
+ return resp["result"] # todo: tokens, pairs, ...
39
+
40
+ async def curs(self):
41
+ config = await self.get_config()
42
+ return config["symbols"]
43
+
44
+ async def coins(self):
45
+ coins = await self._get("/spot/api/basic/symbol_list")
46
+ return coins
47
+
48
+ async def pms(self):
49
+ pms = await self._post("/fiat/otc/configuration/queryAllPaymentList/")
50
+ return pms
51
+
52
+ """ Private METHs"""
53
+
54
+ async def cur_pms_map(self) -> MapOfIdsList:
55
+ pass
56
+
57
+ async def ads(self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None) -> ListOfDicts:
58
+ pass
@@ -12,7 +12,7 @@ from xync_client.Abc.Ex import BaseExClient
12
12
  from xync_client.loader import PG_DSN
13
13
 
14
14
 
15
- class PublicClient(BaseExClient):
15
+ class ExClient(BaseExClient):
16
16
  async def cur_pms_map(self) -> MapOfIdsList:
17
17
  pass
18
18
 
@@ -60,10 +60,11 @@ class PublicClient(BaseExClient):
60
60
  async def main():
61
61
  _ = await init_db(PG_DSN, models, True)
62
62
  bg = await Ex.get(name="Gate")
63
- cl = PublicClient(bg)
63
+ cl = ExClient(bg)
64
64
  # await cl.curs()
65
65
  # await cl.coins()
66
66
  await cl.pms()
67
67
 
68
68
 
69
- run(main())
69
+ if __name__ == "__main__":
70
+ run(main())
@@ -0,0 +1,115 @@
1
+ from x_client.aiohttp import Client
2
+ from xync_schema.enums import AdStatus, PmType, OrderStatus
3
+ from xync_schema.models import Pm, Coin, Cur, Ad, Fiat, Order
4
+ from xync_schema.pydantic import FiatNew
5
+
6
+ from xync_client.Abc.Agent import BaseAgentClient
7
+
8
+ url_ads_req = "https://otc-cf.huobi.com/v1/data/trade-market"
9
+ url_ads_web = "https://www.huobi.com/en-us/fiat-crypto/trade/"
10
+ url_my_ads = "https://otc-api.trygofast.com/v1/data/trade-list?pageSize=50"
11
+ url_my_ad = "https://www.huobi.com/-/x/otc/v1/otc/trade/" # + id
12
+ url_my_bals = "https://www.huobi.com/-/x/otc/v1/capital/balance"
13
+ url_paccs = "https://www.huobi.com/-/x/otc/v1/user/receipt-account"
14
+
15
+
16
+ class Public(Client):
17
+ url_ads_web = "https://www.huobi.com/en-us/fiat-crypto/trade/"
18
+
19
+
20
+ class Private(BaseAgentClient):
21
+ # 0
22
+ async def get_orders(
23
+ self, stauts: OrderStatus = OrderStatus.created, coin: Coin = None, cur: Cur = None, is_sell: bool = None
24
+ ) -> list[Order]:
25
+ pass
26
+
27
+ async def order_request(self, ad_id: int, amount: float) -> dict:
28
+ pass
29
+
30
+ async def my_fiats(self, cur: Cur = None) -> list[dict]:
31
+ pass
32
+
33
+ async def fiat_new(self, fiat: FiatNew) -> Fiat.pyd():
34
+ pass
35
+
36
+ async def fiat_upd(self, detail: str = None, type_: PmType = None) -> bool:
37
+ pass
38
+
39
+ async def fiat_del(self, fiat_id: int) -> bool:
40
+ pass
41
+
42
+ async def my_ads(self) -> list[dict]:
43
+ res = await self._get(url_my_ads)
44
+ ads: [] = res["data"]
45
+ if (pages := res["totalPage"]) > 1:
46
+ for p in range(2, pages + 1):
47
+ ads += (await self._get(url_my_ads, {"currPage": p})).get("data", False)
48
+ return ads
49
+
50
+ async def ad_new(
51
+ self,
52
+ coin: Coin,
53
+ cur: Cur,
54
+ is_sell: bool,
55
+ pms: list[Pm],
56
+ price: float,
57
+ is_float: bool = True,
58
+ min_fiat: int = None,
59
+ details: str = None,
60
+ autoreply: str = None,
61
+ status: AdStatus = AdStatus.active,
62
+ ) -> Ad:
63
+ pass
64
+
65
+ async def ad_upd(
66
+ self,
67
+ pms: [Pm] = None,
68
+ price: float = None,
69
+ is_float: bool = None,
70
+ min_fiat: int = None,
71
+ details: str = None,
72
+ autoreply: str = None,
73
+ status: AdStatus = None,
74
+ ) -> bool:
75
+ pass
76
+
77
+ async def ad_del(self) -> bool:
78
+ pass
79
+
80
+ async def ad_switch(self) -> bool:
81
+ pass
82
+
83
+ async def ads_switch(self) -> bool:
84
+ pass
85
+
86
+ async def get_user(self, user_id) -> dict:
87
+ pass
88
+
89
+ async def send_user_msg(self, msg: str, file=None) -> bool:
90
+ pass
91
+
92
+ async def block_user(self, is_blocked: bool = True) -> bool:
93
+ pass
94
+
95
+ async def rate_user(self, positive: bool) -> bool:
96
+ pass
97
+
98
+ # 39
99
+ async def my_assets(self) -> dict:
100
+ assets = await self._get(url_my_bals)
101
+ return {c["coinId"]: c["total"] for c in assets["data"] if c["total"]}
102
+
103
+ async def _get_auth_hdrs(self) -> dict[str, str]:
104
+ pass
105
+
106
+ base_url = ""
107
+ middle_url = ""
108
+
109
+ htok: str = "Ev5lFfAvxDU2MA9BJ-Mc4U6zZG3Wb6qsp3Tx2fz6GIoY-uOP2m0-gvjE57ad1qDF"
110
+
111
+ url_ads_req = "https://otc-cf.huobi.com/v1/data/trade-market"
112
+ url_my_ads = "https://otc-api.trygofast.com/v1/data/trade-list?pageSize=50"
113
+ url_my_ad = "https://www.huobi.com/-/x/otc/v1/otc/trade/" # + id
114
+ url_my_bals = "https://www.huobi.com/-/x/otc/v1/capital/balance"
115
+ url_paccs = "https://www.huobi.com/-/x/otc/v1/user/receipt-account"
@@ -5,11 +5,11 @@ from xync_schema import models
5
5
  from xync_schema.models import Ex, Coin, Cur, Pm, Ad
6
6
  from xync_schema.enums import PmType
7
7
 
8
- from xync_client.Abc.Ex import ExClient
8
+ from xync_client.Abc.Ex import BaseExClient
9
9
  from xync_client.loader import PG_DSN
10
10
 
11
11
 
12
- class Client(ExClient):
12
+ class ExClient(BaseExClient):
13
13
  # 20: Get all pms
14
14
  async def pms(self) -> dict[int, dict]:
15
15
  dist = {
@@ -47,10 +47,12 @@ class Client(ExClient):
47
47
  wrong_pms = {4, 34, 498, 548, 20009, 20010} # , 212, 239, 363 # these ids not exist in pms
48
48
  return {c["currencyId"]: set(c["supportPayments"]) - wrong_pms for c in res["currency"] if c["supportPayments"]}
49
49
 
50
+ # 23: Список торгуемых монет
50
51
  async def coins(self) -> dict[int, str]:
51
52
  coins: list[dict] = (await self._coin_curs_pms())["coin"]
52
53
  return {c["coinId"]: c["coinCode"] for c in coins if c["coinType"] == 2}
53
54
 
55
+ # 24: Список объяв
54
56
  async def ads(self, coin: Coin, cur: Cur, is_sell: bool, pms: list[Pm] = None) -> list[Ad]:
55
57
  res = await self._coin_curs_pms()
56
58
  return res["country"]
@@ -64,10 +66,11 @@ class Client(ExClient):
64
66
  async def main():
65
67
  _ = await init_db(PG_DSN, models, True)
66
68
  ex = await Ex.get(name="Htx")
67
- cl = Client(ex)
69
+ cl = ExClient(ex)
68
70
  await cl.set_pmcurexs()
69
71
  await cl.set_coinexs()
70
72
  await cl.close()
71
73
 
72
74
 
73
- run(main())
75
+ if __name__ == "__main__":
76
+ run(main())
@@ -1,38 +1,31 @@
1
- from enum import StrEnum, IntEnum
1
+ from enum import StrEnum
2
2
  from typing import Literal
3
3
 
4
- from x_client.http import Client as HttpClient
4
+ from xync_client.TgWallet.auth import AuthClient
5
5
  from xync_schema.models import User, Cur, Order, Coin, OrderStatus, Pmex
6
6
  from xync_schema.pydantic import FiatNew
7
7
 
8
8
  from xync_client.Abc.Agent import BaseAgentClient
9
- from xync_client.TgWallet.pyro import PyroClient
10
9
 
11
10
 
12
11
  class Exceptions(StrEnum):
13
12
  PM_KYC = "OFFER_FIAT_COUNTRY_NOT_SUPPORTED_BY_USER_KYC_COUNTRY"
14
13
 
15
14
 
16
- class Status(IntEnum):
17
- ALL_ACTIVE = OrderStatus.active
15
+ # class Status(IntEnum):
16
+ # ALL_ACTIVE = OrderStatus.active
18
17
 
19
18
 
20
- class AgentClient(BaseAgentClient):
19
+ class AgentClient(BaseAgentClient, AuthClient):
21
20
  async def order_request(self, ad_id: int, amount: float) -> Order:
22
21
  pass
23
22
 
24
- async def _get_auth_hdrs(self) -> dict[str, str]:
25
- pyro = PyroClient(self.agent)
26
- init_data = await pyro.get_init_data()
27
- tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
28
- return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
29
-
30
23
  async def get_orders(
31
24
  self, stauts: OrderStatus = OrderStatus.active, coin: Coin = None, cur: Cur = None, is_sell: bool = None
32
25
  ) -> list[Order]:
33
26
  orders = await self._post(
34
27
  "/p2p/public-api/v2/offer/order/history/get-by-user-id",
35
- {"offset": 0, "limit": 100, "filter": {"status": Status(stauts)}}, # "limit": 20
28
+ {"offset": 0, "limit": 100, "filter": {"status": "ALL_ACTIVE"}}, # "limit": 20
36
29
  )
37
30
  return orders
38
31
 
@@ -9,4 +9,6 @@ class AuthClient(BaseAuthClient):
9
9
  pyro = PyroClient(self.agent)
10
10
  init_data = await pyro.get_init_data()
11
11
  tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
12
+ self.agent.exid = tokens["user_id"]
13
+ await self.agent.save()
12
14
  return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
@@ -1,10 +1,11 @@
1
- from xync_client.Abc.Auth import BaseAuthClient
1
+ from xync_client.TgWallet.auth import AuthClient
2
+
2
3
  from xync_schema.models import Pm
3
4
 
4
5
  from xync_client.Abc.Ex import BaseExClient
5
6
 
6
7
 
7
- class ExClient(BaseExClient, BaseAuthClient):
8
+ class ExClient(BaseExClient, AuthClient):
8
9
  async def curs(self) -> dict[str, str]:
9
10
  coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
10
11
  return {c["code"]: c["code"] for c in coins_curs["data"]["fiat"]}
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xync-client
3
- Version: 0.0.11.dev12
3
+ Version: 0.0.11.dev15
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -4,8 +4,12 @@
4
4
  README.md
5
5
  makefile
6
6
  pyproject.toml
7
+ tests/TestEx.py
7
8
  tests/__init__.py
8
- tests/test_ex.py
9
+ tests/_test_ex.py
10
+ tests/Abc/AgentTest.py
11
+ tests/Abc/BaseTest.py
12
+ tests/Abc/OrderTest.py
9
13
  tests/Binance/test_binance.py
10
14
  tests/Bybit/test_bybit.py
11
15
  tests/Bybit/test_bybit_p2p.py
@@ -23,10 +27,6 @@ xync_client/Abc/Auth.py
23
27
  xync_client/Abc/Base.py
24
28
  xync_client/Abc/Ex.py
25
29
  xync_client/Abc/Order.py
26
- xync_client/AbcTest/AgentTest.py
27
- xync_client/AbcTest/BaseTest.py
28
- xync_client/AbcTest/ExTest.py
29
- xync_client/AbcTest/OrderTest.py
30
30
  xync_client/Binance/__init__.py
31
31
  xync_client/Binance/binance_async.py
32
32
  xync_client/Binance/earn_api.py
@@ -34,6 +34,7 @@ xync_client/Binance/ex.py
34
34
  xync_client/Binance/exceptions.py
35
35
  xync_client/Binance/sapi.py
36
36
  xync_client/Binance/web_c2c.py
37
+ xync_client/BingX/__init__.py
37
38
  xync_client/BingX/base.py
38
39
  xync_client/BingX/ex.py
39
40
  xync_client/BingX/req.mjs
@@ -43,11 +44,12 @@ xync_client/BitGet/__init__.py
43
44
  xync_client/BitGet/agent.py
44
45
  xync_client/BitGet/ex.py
45
46
  xync_client/BitGet/req.mjs
47
+ xync_client/Bybit/agent.py
46
48
  xync_client/Bybit/ex.py
47
49
  xync_client/Bybit/web_earn.py
48
50
  xync_client/Bybit/web_p2p.py
51
+ xync_client/Gate/ex.py
49
52
  xync_client/Gate/premarket.py
50
- xync_client/Gate/pub.py
51
53
  xync_client/Htx/agent.py
52
54
  xync_client/Htx/earn.py
53
55
  xync_client/Htx/ex.py
@@ -1,13 +0,0 @@
1
- import pytest
2
-
3
- from xync_client.Abc.Base import BaseClient
4
- from xync_client.Abc.BaseTest import BaseTest
5
-
6
-
7
- class AgentTest(BaseTest):
8
- @pytest.fixture(scope="class", autouse=True)
9
- async def cl(self) -> BaseClient:
10
- agent = (await self.exq).agents.filter(auth__not_isnull=True).first()
11
- acl = BaseClient(agent)
12
- yield acl
13
- await acl.close()
@@ -1,42 +0,0 @@
1
- import pytest
2
- from typing import TypeGuard
3
- from src.loader import PG_DSN
4
- from tortoise.backends.asyncpg import AsyncpgDBClient
5
- from x_model import init_db
6
- from xync_schema import models
7
- from xync_schema.models import Ex
8
-
9
- from xync_client.Abc.Base import DictOfDicts, ListOfDicts, FlatDict, MapOfIdsList, BaseClient
10
-
11
-
12
- class BaseTest:
13
- def __init__(self, ex_name: str):
14
- self.exq = Ex.get(name=ex_name)
15
-
16
- @pytest.fixture(scope="class", autouse=True)
17
- async def cn(self) -> AsyncpgDBClient:
18
- cn: AsyncpgDBClient = await init_db(PG_DSN, models, True)
19
- yield cn
20
- await cn.close()
21
-
22
- @pytest.fixture(scope="class", autouse=True)
23
- async def cl(self) -> BaseClient:
24
- bcl = BaseClient(await self.exq)
25
- yield bcl
26
- await bcl.close()
27
-
28
- @staticmethod
29
- def is_dict_of_dicts(dct: DictOfDicts) -> TypeGuard[DictOfDicts]:
30
- return all(isinstance(k, int | str) and isinstance(v, dict) for k, v in dct.items())
31
-
32
- @staticmethod
33
- def is_list_of_dicts(lst: ListOfDicts) -> TypeGuard[ListOfDicts]:
34
- return all(isinstance(el, dict) for el in lst)
35
-
36
- @staticmethod
37
- def is_flat_dict(dct: FlatDict) -> TypeGuard[FlatDict]:
38
- return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
39
-
40
- @staticmethod
41
- def is_map_of_ids(dct: MapOfIdsList) -> TypeGuard[MapOfIdsList]:
42
- return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
@@ -1,12 +0,0 @@
1
- import pytest
2
-
3
- from xync_client.Abc.Ex import BaseExClient
4
- from xync_client.Abc.BaseTest import BaseTest
5
-
6
-
7
- class ExTest(BaseTest):
8
- @pytest.fixture(scope="class", autouse=True)
9
- async def cl(self) -> BaseExClient:
10
- ecl = BaseExClient(await self.exq)
11
- yield ecl
12
- await ecl.close()
@@ -1,39 +0,0 @@
1
- import requests
2
-
3
- headers = {
4
- "accept": "application/json, text/plain, */*",
5
- "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
6
- "app_version": "9.0.0",
7
- "appid": "30004",
8
- "appsiteid": "0",
9
- "channel": "official",
10
- "device_brand": "Linux_Chrome_131.0.0.0",
11
- "device_id": "64a8c630-acc2-11ef-aa5e-9f6ee3baa1a5",
12
- "lang": "ru-RU",
13
- "mainappid": "10009",
14
- "origin": "https://bingx.paycat.com",
15
- "platformid": "30",
16
- "priority": "u=1, i",
17
- "referer": "https://bingx.paycat.com/",
18
- "reg_channel": "official",
19
- "sec-ch-ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
20
- "sec-ch-ua-mobile": "?0",
21
- "sec-ch-ua-platform": '"Linux"',
22
- "sec-fetch-dest": "empty",
23
- "sec-fetch-mode": "cors",
24
- "sec-fetch-site": "cross-site",
25
- "sign": "C2F082935161A29256CDD98F2E33FBE3C9B2C0864A6FBCB1881013CBE6272AC8",
26
- "timestamp": "1734637010958",
27
- "timezone": "3",
28
- "traceid": "3e38538d69fb43c9a009ea1fc00a9b8f",
29
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
30
- "x-requested-with": "XMLHttpRequest",
31
- }
32
-
33
- params = {
34
- "fiat": "RUB",
35
- }
36
-
37
- response = requests.get("https://api-app.we-api.com/api/c2c/v1/advert/payment/list", params=params, headers=headers)
38
-
39
- print(i for i in response.json()["data"]["paymentMethodList"])
@@ -1,18 +0,0 @@
1
- from x_client.aiohttp import Client
2
-
3
-
4
- class Public(Client):
5
- url_ads_web = "https://www.huobi.com/en-us/fiat-crypto/trade/"
6
-
7
-
8
- class Private(Client):
9
- base_url = ""
10
- middle_url = ""
11
-
12
- htok: str = "Ev5lFfAvxDU2MA9BJ-Mc4U6zZG3Wb6qsp3Tx2fz6GIoY-uOP2m0-gvjE57ad1qDF"
13
-
14
- url_ads_req = "https://otc-cf.huobi.com/v1/data/trade-market"
15
- url_my_ads = "https://otc-api.trygofast.com/v1/data/trade-list?pageSize=50"
16
- url_my_ad = "https://www.huobi.com/-/x/otc/v1/otc/trade/" # + id
17
- url_my_bals = "https://www.huobi.com/-/x/otc/v1/capital/balance"
18
- url_paccs = "https://www.huobi.com/-/x/otc/v1/user/receipt-account"