xync-client 0.0.11.dev0__tar.gz → 0.0.11.dev4__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 (60) hide show
  1. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/.gitignore +2 -1
  2. {xync_client-0.0.11.dev0/xync_client.egg-info → xync_client-0.0.11.dev4}/PKG-INFO +1 -1
  3. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/Binance/test_binance.py +3 -5
  4. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/test_ex.py +5 -6
  5. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Abc/Agent.py +3 -43
  6. xync_client-0.0.11.dev4/xync_client/Abc/Auth.py +9 -0
  7. xync_client-0.0.11.dev4/xync_client/Abc/Base.py +12 -0
  8. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Abc/Ex.py +16 -21
  9. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Abc/Order.py +17 -8
  10. xync_client-0.0.11.dev4/xync_client/Abc/Test.py +21 -0
  11. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/ex.py +11 -16
  12. xync_client-0.0.11.dev4/xync_client/BingX/ex.py +52 -0
  13. xync_client-0.0.11.dev4/xync_client/BingX/test/main.py +22 -0
  14. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/BitGet/agent.py +3 -3
  15. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/BitGet/ex.py +14 -4
  16. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Gate/premarket.py +1 -1
  17. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Gate/pub.py +7 -3
  18. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/KuCoin/pub.py +7 -3
  19. xync_client-0.0.11.dev0/xync_client/Okx/pub.py → xync_client-0.0.11.dev4/xync_client/Okx/ex.py +9 -8
  20. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/TgWallet/agent.py +2 -5
  21. xync_client-0.0.11.dev4/xync_client/TgWallet/auth.py +39 -0
  22. xync_client-0.0.11.dev4/xync_client/TgWallet/ex.py +40 -0
  23. xync_client-0.0.11.dev4/xync_client/TgWallet/order.py +77 -0
  24. xync_client-0.0.11.dev4/xync_client/__init__.py +0 -0
  25. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4/xync_client.egg-info}/PKG-INFO +1 -1
  26. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client.egg-info/SOURCES.txt +8 -1
  27. xync_client-0.0.11.dev0/xync_client/TgWallet/ex.py +0 -78
  28. xync_client-0.0.11.dev0/xync_client/TgWallet/order.py +0 -215
  29. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/.env.sample +0 -0
  30. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/.pre-commit-config.yaml +0 -0
  31. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/README.md +0 -0
  32. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/makefile +0 -0
  33. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/pyproject.toml +0 -0
  34. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/setup.cfg +0 -0
  35. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/Bybit/test_bybit.py +0 -0
  36. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/Bybit/test_bybit_p2p.py +0 -0
  37. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/Gate/test_gate.py +0 -0
  38. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/Htx/test_htx_p2p.py +0 -0
  39. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/tests/__init__.py +0 -0
  40. {xync_client-0.0.11.dev0/xync_client/BitGet → xync_client-0.0.11.dev4/xync_client/Binance}/__init__.py +0 -0
  41. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/binance_async.py +0 -0
  42. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/earn_api.py +0 -0
  43. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/exceptions.py +0 -0
  44. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/sapi.py +0 -0
  45. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Binance/web_c2c.py +0 -0
  46. {xync_client-0.0.11.dev0/xync_client → xync_client-0.0.11.dev4/xync_client/BitGet}/__init__.py +0 -0
  47. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/BitGet/req.mjs +0 -0
  48. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Bybit/ex.py +0 -0
  49. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Bybit/web_earn.py +0 -0
  50. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Bybit/web_p2p.py +0 -0
  51. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Htx/agent.py +0 -0
  52. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Htx/earn.py +0 -0
  53. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/Htx/ex.py +0 -0
  54. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/KuCoin/web.py +0 -0
  55. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/TgWallet/pyro.py +0 -0
  56. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/TgWallet/web.py +0 -0
  57. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client/loader.py +0 -0
  58. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client.egg-info/dependency_links.txt +0 -0
  59. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client.egg-info/requires.txt +0 -0
  60. {xync_client-0.0.11.dev0 → xync_client-0.0.11.dev4}/xync_client.egg-info/top_level.txt +0 -0
@@ -5,4 +5,5 @@
5
5
  __pycache__
6
6
  /dist
7
7
  /*.egg-info
8
- /build
8
+ /build
9
+ .vscode
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xync-client
3
- Version: 0.0.11.dev0
3
+ Version: 0.0.11.dev4
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
@@ -1,14 +1,12 @@
1
1
  from x_model import init_db
2
- from xync_client.loader import DSN, BKEY, BSEC
2
+ from xync_client.loader import PG_DSN
3
3
  from xync_schema import models
4
4
  from xync_schema.models import Ex
5
5
 
6
- from xync_client.Binance.ex import Client
7
-
8
6
 
9
7
  async def test_cur_filter():
10
- _ = await init_db(DSN, models, True)
8
+ _ = await init_db(PG_DSN, models, True)
11
9
  ex = await Ex.get(name="Binance")
12
- bn = Client(ex, (BKEY, BSEC))
10
+ bn = await ex.client()
13
11
  resp = await bn.cur_pms_map()
14
12
  assert len(resp[0]) and len(resp[1]), "No data"
@@ -7,7 +7,6 @@ from x_model import init_db
7
7
  from xync_schema import models
8
8
  from xync_schema.models import Agent, ExAction, TestEx
9
9
 
10
- from xync_client.TgWallet.ex import PublicClient
11
10
  from xync_client.loader import PG_DSN
12
11
 
13
12
 
@@ -36,26 +35,26 @@ class TestWallet:
36
35
  # 20 - all_pms
37
36
  async def test_all_pms(self, cl):
38
37
  pms = await cl.pms()
39
- ok = pms and cl.is_pms(pms)
38
+ pms and cl.is_pms(pms)
40
39
  test, _ = await TestEx.update_or_create({"ok": bool(pms)}, ex=cl.ex, action=ExAction.pms)
41
40
  assert test.ok, "No pms"
42
41
 
43
42
  # 21 - all_curs
44
43
  async def test_all_curs(self, cl):
45
44
  curs = await cl.curs()
46
- test, _ = await TestEx.update_or_create({"ok": bool(curs)}, ex__name="TgWallet", action=ExAction.curs)
45
+ test, _ = await TestEx.update_or_create({"ok": bool(curs)}, ex=cl.ex, action=ExAction.curs)
47
46
  assert test.ok, "No curs"
48
47
 
49
48
  # 22 - all_pms
50
49
  async def test_cur_pms_map(self, cl):
51
50
  pms = await cl.cur_pms_map()
52
- test, _ = await TestEx.update_or_create({"ok": bool(pms)}, ex__name="TgWallet", action=ExAction.pms)
51
+ test, _ = await TestEx.update_or_create({"ok": bool(pms)}, ex=cl.ex, action=ExAction.pms)
53
52
  assert test.ok, "No pms"
54
53
 
55
54
  # 23 - all_coins
56
55
  async def test_all_coins(self, cl):
57
56
  coins = await cl.coins()
58
- test, _ = await TestEx.update_or_create({"ok": bool(coins)}, ex__name="TgWallet", action=ExAction.coins)
57
+ test, _ = await TestEx.update_or_create({"ok": bool(coins)}, ex=cl.ex, action=ExAction.coins)
59
58
  assert test.ok, "No coins"
60
59
 
61
60
  # 24 - all_ads
@@ -65,4 +64,4 @@ class TestWallet:
65
64
  for tt in True, False:
66
65
  ads = await cl.ads(coin, cur, tt)
67
66
  assert len(ads), "No data"
68
- await TestEx.update_or_create({"ok": bool(ads)}, ex__name="TgWallet", action=ExAction.ads)
67
+ await TestEx.update_or_create({"ok": bool(ads)}, ex=cl.ex, action=ExAction.ads)
@@ -1,33 +1,12 @@
1
- import logging
2
1
  from abc import abstractmethod
3
2
 
4
- from aiohttp import ClientResponse
5
- from aiohttp.http_exceptions import HttpProcessingError
6
- from x_client.aiohttp import Client as HttpClient
3
+ from xync_client.Abc.Auth import BaseAuthClient
7
4
  from xync_schema.enums import PmType
8
- from xync_schema.models import Agent, Ex, OrderStatus, Coin, Cur, Order, Pm, Ad, AdStatus, Fiat
5
+ from xync_schema.models import OrderStatus, Coin, Cur, Order, Pm, Ad, AdStatus, Fiat
9
6
  from xync_schema.pydantic import FiatNew
10
7
 
11
8
 
12
- class Client(HttpClient):
13
- def __init__(self, agent: Agent):
14
- self.agent: Agent = agent
15
- assert isinstance(agent.ex, Ex), "`ex` should be fetched in `agent`"
16
- assert agent.ex.host_p2p, "`ex.host_p2p` shouldn't be empty"
17
- self.meth = {
18
- "GET": self._get,
19
- "POST": self._post,
20
- }
21
- super().__init__(agent.ex.host_p2p)
22
-
23
- # Login: returns auth headers dict
24
- async def _get_auth_hdrs(self) -> dict[str, str]:
25
- return self.agent.auth
26
-
27
- async def login(self) -> None:
28
- auth_hdrs: dict[str, str] = await self._get_auth_hdrs()
29
- self.session.headers.update(auth_hdrs)
30
-
9
+ class BaseAgentClient(BaseAuthClient):
31
10
  # 0: Получшение ордеров в статусе status, по монете coin, в валюте coin, в направлении is_sell: bool
32
11
  @abstractmethod
33
12
  async def get_orders(
@@ -120,22 +99,3 @@ class Client(HttpClient):
120
99
  # 38: Поставить отзыв юзеру
121
100
  @abstractmethod
122
101
  async def rate_user(self, positive: bool) -> bool: ...
123
-
124
- async def _proc(self, resp: ClientResponse, data: dict = None) -> dict | str:
125
- try:
126
- return await super()._proc(resp)
127
- except HttpProcessingError as e:
128
- if e.code == 401:
129
- logging.warning(e)
130
- await self.login()
131
- res = await self.meth[resp.method](resp.url.path, data)
132
- return res
133
-
134
- @staticmethod
135
- async def payment_methods(*methods_list):
136
- payment_list = []
137
- for method in methods_list:
138
- method_cleared = method.lower().replace(" ", "").replace("-", "").replace("(", "").replace(")", "")
139
- if method_cleared not in payment_list:
140
- payment_list.append(method_cleared)
141
- return payment_list
@@ -0,0 +1,9 @@
1
+ from xync_client.Abc.Base import BaseClient
2
+ from xync_schema.models import Agent
3
+
4
+
5
+ class BaseAuthClient(BaseClient):
6
+ def __init__(self, agent: Agent):
7
+ self.headers.update(agent.auth)
8
+ self.agent = agent
9
+ super().__init__(agent.ex)
@@ -0,0 +1,12 @@
1
+ from x_client.aiohttp import Client
2
+ from xync_schema.models import Ex
3
+
4
+ DictOfDicts = dict[int | str, dict]
5
+ ListOfDicts = list[dict]
6
+ FlatDict = dict[int | str, str]
7
+ MapOfIdsList = dict[int | str, list[int | str]]
8
+
9
+
10
+ class BaseClient(Client):
11
+ def __init__(self, ex: Ex):
12
+ super().__init__(ex.host_p2p)
@@ -1,13 +1,12 @@
1
1
  import logging
2
2
  import re
3
3
  from abc import abstractmethod
4
- from typing import TypeGuard
5
4
 
6
- from x_client.aiohttp import Client
5
+ from xync_client.Abc.Base import BaseClient, DictOfDicts, FlatDict, ListOfDicts, MapOfIdsList
7
6
  from xync_schema.models import Ex, Coin, Cur, Pm, Pmex, Curex, Pmcur, Pmcurex, Coinex
8
7
 
9
8
 
10
- class ExClient(Client):
9
+ class BaseExClient(BaseClient):
11
10
  ex: Ex
12
11
  pm_map: dict[str, str] = {
13
12
  "Юmoney": "YooMoney",
@@ -23,51 +22,47 @@ class ExClient(Client):
23
22
 
24
23
  def __init__(self, ex: Ex):
25
24
  self.ex = ex
26
- self.acrs: dict[str, str] = {} # for pm norm
27
- super().__init__(ex.host_p2p)
28
-
29
- @staticmethod
30
- def is_pms(val: dict[int | str, dict]) -> TypeGuard[dict[int | str, dict]]:
31
- return all(isinstance(k, int | str) and isinstance(v, dict) for k, v in val.items())
25
+ self.acronyms: dict[str, str] = {} # for pm norm
26
+ super().__init__(ex)
32
27
 
33
28
  # 20: Список всех платежных методов на бирже
34
29
  @abstractmethod
35
- async def pms(self) -> dict[int | str, dict]: # {pm.exid: pm}
30
+ async def pms(self) -> DictOfDicts: # {pm.exid: pm}
36
31
  ...
37
32
 
38
33
  # 21: Список поддерживаемых валют
39
34
  @abstractmethod
40
- async def curs(self) -> dict[int | str, str]: # {cur.exid: cur.ticker}
35
+ async def curs(self) -> FlatDict: # {cur.exid: cur.ticker}
41
36
  ...
42
37
 
43
38
  # 22: Список платежных методов по каждой валюте
44
39
  @abstractmethod
45
- async def cur_pms_map(self) -> dict[int | str, list[int | str]]: # {cur.exid: [pm.exid]}
40
+ async def cur_pms_map(self) -> MapOfIdsList: # {cur.exid: [pm.exid]}
46
41
  ...
47
42
 
48
43
  # 23: Список торгуемых монет (с ограничениям по валютам, если есть)
49
44
  @abstractmethod
50
- async def coins(self) -> dict[int | str, str]: # {coin.exid: coin.ticker}
45
+ async def coins(self) -> FlatDict: # {coin.exid: coin.ticker}
51
46
  ...
52
47
 
53
48
  # 24: Список объяв по (buy/sell, cur, coin, pm)
54
49
  @abstractmethod
55
50
  async def ads(
56
51
  self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None
57
- ) -> list[dict]: # [ad]
52
+ ) -> ListOfDicts: # {ad.id: ad}
58
53
  ...
59
54
 
60
- def _pmnorm(self, s: str, idtf: str = None) -> str:
55
+ def _pmnorm(self, s: str) -> str:
61
56
  def get_and_remove_acro(title: str) -> str:
62
57
  acr = "".join(word[0] for word in title.split(" ") if len(word) > 1 and word.istitle())
63
58
  if len(acr) > 2:
64
59
  title = title.replace(acr, "", 1)
65
- self.acrs[acr] = title # заполняем словарь аббревиатур
60
+ self.acronyms[acr] = title # заполняем словарь аббревиатур
66
61
  return title
67
62
 
68
63
  def find_and_replace_only_acro(title: str) -> str:
69
- if " " not in title and title.isupper() and title in self.acrs:
70
- title = self.acrs[title]
64
+ if " " not in title and title.isupper() and title in self.acronyms:
65
+ title = self.acronyms[title]
71
66
  return title
72
67
 
73
68
  def remove(rms: str | list[str], st: str, regexp: bool = False) -> str:
@@ -120,17 +115,17 @@ class ExClient(Client):
120
115
  async def set_pmcurexs(self):
121
116
  # Pms
122
117
  pmsd = {k: v for k, v in sorted((await self.pms()).items(), key=lambda x: x[1]["name"])} # sort by name
123
- pms: dict[int | str, Pm] = {}
118
+ pms: dict[int | str, Pm] = dict({})
124
119
  prev = 0, "", "" # id, normd-name, orig-name
125
120
  for k, pm in pmsd.items():
126
121
  norm = self._pmnorm(pm["name"])
127
122
  if prev[1:] == (norm, pm["name"]):
128
- logging.warning(f"Pm: '{pm['name']}' duplicated with ids {prev[0]}:{k} on {self.ex.name}")
123
+ logging.warning(f"Pm: '{pm['name']}' duplicated with ids {prev[0]}: {k} on {self.ex.name}")
129
124
  pm_ = pms.get(prev[0], (await Pm.get_or_none(name=prev[2])) or await Pm.get_or_none(identifier=prev[1]))
130
125
  await Pmex.update_or_create({"pm": pm_}, ex=self.ex, exid=k, name=pm["name"])
131
126
  elif prev[1] == norm:
132
127
  logging.error(
133
- f"Pm: '{pm['name']}' and '{prev[2]}' overnormed as '{norm}' with ids {prev[0]}:{k} on {self.ex.name}"
128
+ f"Pm: '{pm['name']}' & '{prev[2]}' overnormd as '{norm}' with ids {prev[0]}: {k} on {self.ex.name}"
134
129
  )
135
130
  await Pmex.update_or_create(
136
131
  {"pm": pms.get(prev[0], await Pm.get(name=prev[2]))}, ex=self.ex, exid=k, name=pm["name"]
@@ -1,13 +1,22 @@
1
1
  from abc import abstractmethod
2
2
 
3
- from x_client.aiohttp import Client
4
- from xync_schema.models import Order
5
-
6
-
7
- class OrderClient:
8
- def __init__(self, cl: Client, order: Order):
9
- self.cl: Client = cl
10
- self.order: Order = order
3
+ from xync_client.Abc.Auth import BaseAuthClient
4
+ from xync_schema.models import Order, Agent
5
+
6
+
7
+ class BaseOrderClient(BaseAuthClient):
8
+ order: Order
9
+ is_sell: bool
10
+ im_maker: bool
11
+ im_seller: bool
12
+
13
+ def __init__(self, agent: Agent, order: Order):
14
+ self.order = order
15
+ self.is_sell = order.ad.direction.sell
16
+ # self.im_maker = order.ad.agent_id == agent.id
17
+ self.im_maker = order.taker_id != agent.id
18
+ self.im_seller = self.is_sell and self.im_maker
19
+ super().__init__(agent)
11
20
 
12
21
  # 2: [T] Отмена запроса на сделку
13
22
  @abstractmethod
@@ -0,0 +1,21 @@
1
+ from typing import TypeGuard
2
+
3
+ from xync_client.Abc.Base import DictOfDicts, ListOfDicts, FlatDict, MapOfIdsList
4
+
5
+
6
+ class BaseTest:
7
+ @staticmethod
8
+ def is_dod(dct: DictOfDicts) -> TypeGuard[DictOfDicts]:
9
+ return all(isinstance(k, int | str) and isinstance(v, dict) for k, v in dct.items())
10
+
11
+ @staticmethod
12
+ def is_lod(lst: ListOfDicts) -> TypeGuard[ListOfDicts]:
13
+ return all(isinstance(el, dict) for el in lst)
14
+
15
+ @staticmethod
16
+ def is_fd(dct: FlatDict) -> TypeGuard[FlatDict]:
17
+ return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
18
+
19
+ @staticmethod
20
+ def is_moil(dct: MapOfIdsList) -> TypeGuard[MapOfIdsList]:
21
+ return all(isinstance(k, int | str) and isinstance(v, str) for k, v in dct.items())
@@ -1,16 +1,11 @@
1
- from asyncio import run
2
-
3
- from x_model import init_db
4
1
  from xync_schema.enums import PmType
5
2
 
6
- from xync_client.Abc.Ex import ExClient
3
+ from xync_client.Abc.Ex import BaseClient
7
4
  from xync_client.Binance.sapi import Sapi
8
- from xync_client.loader import PG_DSN, BKEY, BSEC
9
- from xync_schema import models
10
5
  from xync_schema.models import Ex
11
6
 
12
7
 
13
- class Client(ExClient):
8
+ class Client(BaseClient):
14
9
  def __init__(self, ex: Ex, bkeys):
15
10
  self.sapi = Sapi(*bkeys)
16
11
  super().__init__(ex)
@@ -74,12 +69,12 @@ class Client(ExClient):
74
69
  # }
75
70
 
76
71
 
77
- async def main():
78
- _ = await init_db(PG_DSN, models, True)
79
- ex = await Ex.get(name="Binance")
80
- cl = Client(ex, (BKEY, BSEC))
81
- await cl.set_pmcurexs()
82
- await cl.close()
83
-
84
-
85
- run(main())
72
+ # async def main():
73
+ # _ = await init_db(PG_DSN, models, True)
74
+ # ex = await Ex.get(name="Binance")
75
+ # cl = Client(ex, (BKEY, BSEC))
76
+ # await cl.set_pmcurexs()
77
+ # await cl.close()
78
+ #
79
+ #
80
+ # run(main())
@@ -0,0 +1,52 @@
1
+ from asyncio import run
2
+
3
+ from x_model import init_db
4
+ from xync_schema import models
5
+ from xync_schema.models import Ex
6
+
7
+ from xync_client.Abc.Ex import BaseExClient
8
+ from xync_client.loader import PG_DSN
9
+
10
+
11
+ class Client(BaseExClient):
12
+ # 20: order_request
13
+ async def pms(self):
14
+ # for cur in self.curs():
15
+ for cur in ["RUB", "THB", "PHP"]: # todo: temp hardcode curs
16
+ params = {
17
+ "coinName": "USDT",
18
+ "tradeCoinName": cur,
19
+ "type": "1",
20
+ "amount": "500",
21
+ }
22
+ pms = await self._get("/api/fiat/v1/rapid-buy-integration", params=params)
23
+
24
+ return [pm.get("paymentMethod")["name"] for pm in pms["data"]["matchOptimalAdvertListVo"]["optimals"]]
25
+
26
+ # 21: order_request_ask
27
+ async def curs(self):
28
+ pass
29
+
30
+ # 22: cur_pms_map
31
+ async def cur_pms_map(self):
32
+ pass
33
+
34
+ # 23: coins
35
+ async def coins(self):
36
+ pass
37
+
38
+ # 24: ads
39
+ async def ads(self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None):
40
+ pass
41
+
42
+
43
+ async def main():
44
+ _ = await init_db(PG_DSN, models, True)
45
+ bg = await Ex.get(name="BingX")
46
+ cl = Client(bg)
47
+ await cl.curs()
48
+ await cl.pms()
49
+ await cl.close()
50
+
51
+
52
+ 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"]])
@@ -7,11 +7,11 @@ from xync_schema.enums import AdStatus, PmType, OrderStatus
7
7
  from xync_schema.models import User, Pm, Coin, Cur, Ad, Fiat, Order, Agent
8
8
  from xync_schema.pydantic import FiatNew
9
9
 
10
- from xync_client.Abc.Agent import Client as BaseClient
10
+ from xync_client.Abc.Agent import BaseAgentClient
11
11
  from xync_client.loader import PG_DSN
12
12
 
13
13
 
14
- class Client(BaseClient):
14
+ class Client(BaseAgentClient):
15
15
  headers = {"accept-language": "ru,en;q=0.9"}
16
16
 
17
17
  def __init__(self, agent: Agent):
@@ -106,7 +106,7 @@ async def main():
106
106
  _ = await init_db(PG_DSN, models, True)
107
107
  agent = await Agent.get(ex__name="BitGet").prefetch_related("ex")
108
108
  cl = Client(agent)
109
- fts = await cl.my_fiats()
109
+ await cl.my_fiats()
110
110
  await cl.close()
111
111
 
112
112
 
@@ -1,14 +1,18 @@
1
+ import json
2
+ import subprocess
1
3
  from asyncio import run
2
4
 
3
5
  from x_model import init_db
4
6
  from xync_schema import models
5
7
  from xync_schema.models import Cur, Ex
6
8
 
7
- from xync_client.Abc.Ex import ExClient
9
+ from xync_client.Abc.Ex import BaseClient
8
10
  from xync_client.loader import PG_DSN
9
11
 
10
12
 
11
- class Client(ExClient):
13
+ class Client(BaseClient):
14
+ headers = {"accept-language": "ru,en;q=0.9"}
15
+
12
16
  async def curs(self) -> dict[str, str]:
13
17
  curs = (await self._post("/v1/p2p/pub/currency/queryAllCoinAndFiat"))["data"]["fiatInfoRespList"]
14
18
  return {cur["fiatCode"]: cur["fiatCode"] for cur in curs}
@@ -18,7 +22,13 @@ class Client(ExClient):
18
22
  return {coin["coinCode"]: coin["coinCode"] for coin in coins}
19
23
 
20
24
  async def pms(self, cur: Cur = None) -> dict[int, dict]:
21
- curs = (await self._post("/v1/p2p/pub/currency/queryAllCoinAndFiat"))["data"]["fiatInfoRespList"]
25
+ # curs = (await self._post("pub/currency/queryAllCoinAndFiat"))["data"]["fiatInfoRespList"]
26
+ p = subprocess.Popen(
27
+ ["node", "req.mjs", "user/queryPaymethods", '{"languageType":6}', self.headers], stdout=subprocess.PIPE
28
+ )
29
+ out = p.stdout.read().decode()
30
+ curs: list[dict] = json.loads(out)
31
+
22
32
  pmcurs = {cur["fiatCode"]: cur["paymethodInfo"] for cur in curs}
23
33
  pp = {}
24
34
  [
@@ -69,7 +79,7 @@ async def main():
69
79
  # await cl.curs()
70
80
  # await cl.coins()
71
81
  # await cl.ads("BTC", "RUB", True, [1, 289, 375])
72
- # await cl.pms()
82
+ await cl.pms()
73
83
  # await cl.cur_pms_map()
74
84
  await cl.set_pmcurexs()
75
85
  await cl.set_coinexs()
@@ -2,7 +2,7 @@ from x_client.aiohttp import Client
2
2
 
3
3
 
4
4
  class Priv(Client):
5
- base_url = "www.gate.io"
5
+ host = "www.gate.io"
6
6
 
7
7
  def __init__(self, uid: str, pver: str):
8
8
  self.headers = {
@@ -7,14 +7,18 @@ from x_model import init_db
7
7
  from xync_schema import models
8
8
  from xync_schema.models import Coin, Cur, Pm, Ad, Ex, Curex
9
9
 
10
- from xync_client.Abc import PublicClient as BasePublicClient
10
+ from xync_client.Abc.Base import MapOfIdsList
11
+ from xync_client.Abc.Ex import BaseExClient
11
12
  from xync_client.loader import PG_DSN
12
13
 
13
14
 
14
- class PublicClient(BasePublicClient):
15
+ class PublicClient(BaseExClient):
16
+ async def cur_pms_map(self) -> MapOfIdsList:
17
+ pass
18
+
15
19
  async def curs(self) -> list[Cur]:
16
20
  curs = await self._post("/json_svr/buy_crypto_fiat_setting")
17
- curs = [(await Cur.update_or_create(ticker=cur["fiat"]))[0] for cur in curs if cur["p2p"]]
21
+ curs = [cur["fiat"] for cur in curs if cur["p2p"]]
18
22
  curexs = [Curex(cur=c, ex=self.ex) for c in curs]
19
23
  await Curex.bulk_create(curexs, ignore_conflicts=True)
20
24
  return curs
@@ -4,11 +4,15 @@ from x_model import init_db
4
4
  from xync_schema import models
5
5
  from xync_schema.models import Coin, Cur, Pm, Ad, Ex, Curex
6
6
 
7
- from xync_client.Abc import PublicClient as BasePublicClient
7
+ from xync_client.Abc.Base import MapOfIdsList
8
+ from xync_client.Abc.Ex import BaseExClient
8
9
  from xync_client.loader import PG_DSN
9
10
 
10
11
 
11
- class PublicClient(BasePublicClient):
12
+ class ExClient(BaseExClient):
13
+ async def cur_pms_map(self) -> MapOfIdsList:
14
+ pass
15
+
12
16
  async def curs(self) -> list[Cur]:
13
17
  curs = (await self._get("/_api/otc/dictionary/getData", {"type": "LEGAL"}))["data"]
14
18
  curs = [(await Cur.update_or_create(ticker=cur["typeCode"]))[0] for cur in curs]
@@ -34,7 +38,7 @@ class PublicClient(BasePublicClient):
34
38
  async def main():
35
39
  _ = await init_db(PG_DSN, models, True)
36
40
  bg = await Ex.get(name="KuCoin")
37
- cl = PublicClient(bg)
41
+ cl = ExClient(bg)
38
42
  # await cl.curs()
39
43
  # await cl.coins()
40
44
  await cl.pms()
@@ -2,23 +2,24 @@ from asyncio import run
2
2
 
3
3
  from x_model import init_db
4
4
  from xync_schema import models
5
- from xync_schema.models import Coin, Cur, Pm, Ad, Ex, Curex
5
+ from xync_schema.models import Coin, Cur, Pm, Ad, Ex
6
6
 
7
- from xync_client.Abc import PublicClient as BasePublicClient
7
+ from xync_client.Abc.Base import MapOfIdsList, ListOfDicts
8
+ from xync_client.Abc.Ex import BaseExClient
8
9
  from xync_client.loader import PG_DSN
9
10
 
10
11
 
11
- class PublicClient(BasePublicClient):
12
+ class ExClient(BaseExClient):
13
+ async def cur_pms_map(self) -> MapOfIdsList:
14
+ pass
15
+
12
16
  async def curs(self) -> list[Cur]:
13
17
  curs = (await self._get("/v3/users/common/list/currencies"))["data"]
14
- curs = [(await Cur.update_or_create(ticker=cur["isoCode"]))[0] for cur in curs]
15
- curexs = [Curex(cur=c, ex=self.ex) for c in curs]
16
- await Curex.bulk_create(curexs, ignore_conflicts=True)
17
18
  return curs
18
19
 
19
20
  async def coins(self, cur: Cur = None) -> list[Coin]: ...
20
21
 
21
- async def pms(self, cur: Cur = None) -> list[Pm]:
22
+ async def pms(self, cur: Cur = None) -> ListOfDicts:
22
23
  pmcurs = {
23
24
  cur.ticker: (await self._get("/v3/c2c/configs/receipt/templates", {"quoteCurrency": cur.ticker}))["data"]
24
25
  for cur in await self.curs()
@@ -35,7 +36,7 @@ class PublicClient(BasePublicClient):
35
36
  async def main():
36
37
  _ = await init_db(PG_DSN, models, True)
37
38
  bg = await Ex.get(name="Okx")
38
- cl = PublicClient(bg)
39
+ cl = ExClient(bg)
39
40
  # await cl.curs()
40
41
  # await cl.coins()
41
42
  await cl.pms()
@@ -5,7 +5,7 @@ from x_client.http import Client as HttpClient
5
5
  from xync_schema.models import User, Cur, Order, Coin, OrderStatus, Pmex
6
6
  from xync_schema.pydantic import FiatNew
7
7
 
8
- from xync_client.Abc.Agent import Client as BaseClient
8
+ from xync_client.Abc.Agent import BaseAgentClient
9
9
  from xync_client.TgWallet.pyro import PyroClient
10
10
 
11
11
 
@@ -17,16 +17,13 @@ class Status(IntEnum):
17
17
  ALL_ACTIVE = OrderStatus.active
18
18
 
19
19
 
20
- class Client(BaseClient):
20
+ class AgentClient(BaseAgentClient):
21
21
  async def order_request(self, ad_id: int, amount: float) -> Order:
22
22
  pass
23
23
 
24
24
  async def _get_auth_hdrs(self) -> dict[str, str]:
25
25
  pyro = PyroClient(self.agent)
26
26
  init_data = await pyro.get_init_data()
27
- # async with ClientSession(self.agent.ex.url_login) as sess:
28
- # resp = await sess.post('/api/v1/users/auth/', data=init_data, headers={'content-type': 'application/json;charset=UTF-8'})
29
- # tokens = await resp.json()
30
27
  tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
31
28
  return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
32
29
 
@@ -0,0 +1,39 @@
1
+ import logging
2
+
3
+ from aiohttp import ClientResponse
4
+ from aiohttp.http_exceptions import HttpProcessingError
5
+ from x_client.http import Client as HttpClient
6
+ from xync_client.Abc.Auth import BaseAuthClient
7
+ from xync_schema.models import Agent
8
+
9
+ from xync_client.TgWallet.pyro import PyroClient
10
+
11
+
12
+ class AuthClient(BaseAuthClient):
13
+ def __init__(self, agent: Agent):
14
+ self.meth = {
15
+ "GET": self._get,
16
+ "POST": self._post,
17
+ "DELETE": self._delete,
18
+ }
19
+ super().__init__(agent)
20
+
21
+ async def _get_auth_hdrs(self) -> dict[str, str]:
22
+ pyro = PyroClient(self.agent)
23
+ init_data = await pyro.get_init_data()
24
+ tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
25
+ return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
26
+
27
+ async def login(self) -> None:
28
+ auth_hdrs: dict[str, str] = await self._get_auth_hdrs()
29
+ self.session.headers.update(auth_hdrs)
30
+
31
+ async def _proc(self, resp: ClientResponse, data: dict = None) -> dict | str:
32
+ try:
33
+ return await super()._proc(resp)
34
+ except HttpProcessingError as e:
35
+ if e.code == 401:
36
+ logging.warning(e)
37
+ await self.login()
38
+ res = await self.meth[resp.method](resp.url.path, data)
39
+ return res
@@ -0,0 +1,40 @@
1
+ from xync_client.Abc.Auth import BaseAuthClient
2
+ from xync_schema.models import Pm
3
+
4
+ from xync_client.Abc.Ex import BaseExClient
5
+
6
+
7
+ class ExClient(BaseExClient, BaseAuthClient):
8
+ async def curs(self) -> dict[str, str]:
9
+ coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
10
+ return {c["code"]: c["code"] for c in coins_curs["data"]["fiat"]}
11
+
12
+ async def coins(self) -> dict[str, str]:
13
+ coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
14
+ return {c["code"]: c["code"] for c in coins_curs["data"]["crypto"]}
15
+
16
+ async def _pms(self, cur: str = "RUB") -> dict[str, dict]:
17
+ pms = await self._post("/p2p/public-api/v3/payment-details/get-methods/by-currency-code", {"currencyCode": cur})
18
+ return {pm["code"]: {"name": pm["nameEng"]} for pm in pms["data"]}
19
+
20
+ async def pms(self) -> dict[str, dict]:
21
+ pms = {}
22
+ for cur in await self.curs():
23
+ for k, pm in (await self._pms(cur)).items():
24
+ pms.update({k: pm})
25
+ return pms
26
+
27
+ async def cur_pms_map(self) -> dict[str, list[str]]:
28
+ return {cur: list(await self._pms(cur)) for cur in await self.curs()}
29
+
30
+ async def ads(self, coin: str, cur: str, is_sell: bool, pms: list[Pm] = None) -> list[dict]:
31
+ params = {
32
+ "baseCurrencyCode": coin,
33
+ "quoteCurrencyCode": cur,
34
+ "offerType": "SALE" if is_sell else "PURCHASE",
35
+ "offset": 0,
36
+ "limit": 10,
37
+ # ,"merchantVerified":"TRUSTED"
38
+ }
39
+ ads = await self._post("/p2p/public-api/v2/offer/depth-of-market/", params)
40
+ return ads
@@ -0,0 +1,77 @@
1
+ from enum import StrEnum, IntEnum
2
+ from xync_schema.models import Order, OrderStatus
3
+
4
+ from xync_client.Abc.Order import BaseOrderClient
5
+
6
+
7
+ class Exceptions(StrEnum):
8
+ PM_KYC = "OFFER_FIAT_COUNTRY_NOT_SUPPORTED_BY_USER_KYC_COUNTRY"
9
+
10
+
11
+ class Status(IntEnum):
12
+ ALL_ACTIVE = OrderStatus.active
13
+
14
+
15
+ class OrderClient(BaseOrderClient):
16
+ # 2
17
+ async def cancel_request(self) -> Order:
18
+ pass
19
+
20
+ # 2
21
+ async def accept_request(self) -> bool:
22
+ approve = await self._post(
23
+ "/p2p/public-api/v2/offer/order/accept",
24
+ {"orderId": self.order.id, "type": {True: "SALE", False: "BUY"}[self.im_seller]},
25
+ )
26
+ return approve
27
+
28
+ # 2
29
+ async def reject_request(self) -> bool:
30
+ reject = await self._post("/p2p/public-api/v2/offer/order/cancel/by-seller", {"orderId": self.order.id})
31
+ return reject
32
+
33
+ # 2
34
+ async def mark_payed(self, receipt):
35
+ pass
36
+
37
+ # 2
38
+ async def cancel_order(self) -> bool:
39
+ pass
40
+
41
+ # 7 - [S] payment received confirm
42
+ async def confirm(self) -> bool:
43
+ payment_confirm = await self._post("/p2p/public-api/v2/payment-details/confirm", {"orderId": self.order.id})
44
+ return payment_confirm
45
+
46
+ # 2
47
+ async def start_appeal(self, file) -> bool:
48
+ pass
49
+
50
+ # 2
51
+ async def dispute_appeal(self, file) -> bool:
52
+ pass
53
+
54
+ async def cancel_appeal(self) -> bool:
55
+ pass
56
+
57
+ # 2
58
+ async def send_order_msg(self, msg: str, file=None) -> bool:
59
+ pass
60
+
61
+ # 2
62
+ async def send_appeal_msg(self, file, msg: str = None) -> bool:
63
+ pass
64
+
65
+ # 2
66
+ async def _upload_file(self, order_id: int, path_to_file: str):
67
+ url = f"/public-api/v2/file-storage/file/upload?orderId={order_id}&uploadType=UPLOAD_BUYER_PAYMENT_RECEIPT"
68
+ data = {"file": open(path_to_file, "rb")}
69
+ upload_file = await self._post(url, data)
70
+ return upload_file
71
+
72
+ # 19 - order_paid
73
+ async def order_paid(self, order_id: str, file: dict):
74
+ paid = await self._post(
75
+ "/p2p/public-api/v2/offer/order/confirm-sending-payment", {"orderId": order_id, "paymentReceipt": file}
76
+ )
77
+ return paid
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xync-client
3
- Version: 0.0.11.dev0
3
+ Version: 0.0.11.dev4
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
@@ -19,14 +19,20 @@ xync_client.egg-info/dependency_links.txt
19
19
  xync_client.egg-info/requires.txt
20
20
  xync_client.egg-info/top_level.txt
21
21
  xync_client/Abc/Agent.py
22
+ xync_client/Abc/Auth.py
23
+ xync_client/Abc/Base.py
22
24
  xync_client/Abc/Ex.py
23
25
  xync_client/Abc/Order.py
26
+ xync_client/Abc/Test.py
27
+ xync_client/Binance/__init__.py
24
28
  xync_client/Binance/binance_async.py
25
29
  xync_client/Binance/earn_api.py
26
30
  xync_client/Binance/ex.py
27
31
  xync_client/Binance/exceptions.py
28
32
  xync_client/Binance/sapi.py
29
33
  xync_client/Binance/web_c2c.py
34
+ xync_client/BingX/ex.py
35
+ xync_client/BingX/test/main.py
30
36
  xync_client/BitGet/__init__.py
31
37
  xync_client/BitGet/agent.py
32
38
  xync_client/BitGet/ex.py
@@ -41,8 +47,9 @@ xync_client/Htx/earn.py
41
47
  xync_client/Htx/ex.py
42
48
  xync_client/KuCoin/pub.py
43
49
  xync_client/KuCoin/web.py
44
- xync_client/Okx/pub.py
50
+ xync_client/Okx/ex.py
45
51
  xync_client/TgWallet/agent.py
52
+ xync_client/TgWallet/auth.py
46
53
  xync_client/TgWallet/ex.py
47
54
  xync_client/TgWallet/order.py
48
55
  xync_client/TgWallet/pyro.py
@@ -1,78 +0,0 @@
1
- import logging
2
-
3
- from aiohttp import ClientResponse
4
- from aiohttp.http_exceptions import HttpProcessingError
5
- from x_client.http import Client
6
- from xync_schema.models import Pm, Agent, Ex
7
-
8
- from xync_client.Abc.Ex import ExClient
9
- from xync_client.TgWallet.pyro import PyroClient
10
-
11
-
12
- class PublicClient(ExClient):
13
- def __init__(self, agent: Agent):
14
- self.agent: Agent = agent
15
- assert isinstance(agent.ex, Ex), "`ex` should be fetched in `agent`"
16
- assert agent.ex.host_p2p, "`ex.host_p2p` shouldn't be empty"
17
- self.meth = {
18
- "GET": self._get,
19
- "POST": self._post,
20
- }
21
- super().__init__(agent.ex)
22
-
23
- async def _get_auth_hdrs(self) -> dict[str, str]:
24
- pyro = PyroClient(self.agent)
25
- init_data = await pyro.get_init_data()
26
- # async with ClientSession(self.agent.ex.url_login) as sess:
27
- # resp = await sess.post('/api/v1/users/auth/', data=init_data, headers={'content-type': 'application/json;charset=UTF-8'})
28
- # tokens = await resp.json()
29
- tokens = Client("walletbot.me")._post("/api/v1/users/auth/", init_data)
30
- return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
31
-
32
- async def login(self) -> None:
33
- auth_hdrs: dict[str, str] = await self._get_auth_hdrs()
34
- self.session.headers.update(auth_hdrs)
35
-
36
- async def _proc(self, resp: ClientResponse, data: dict = None) -> dict | str:
37
- try:
38
- return await super()._proc(resp)
39
- except HttpProcessingError as e:
40
- if e.code == 401:
41
- logging.warning(e)
42
- await self.login()
43
- res = await self.meth[resp.method](resp.url.path, data)
44
- return res
45
-
46
- async def curs(self) -> dict[str, str]:
47
- coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
48
- return {c["code"]: c["code"] for c in coins_curs["data"]["fiat"]}
49
-
50
- async def coins(self) -> dict[str, str]:
51
- coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
52
- return {c["code"]: c["code"] for c in coins_curs["data"]["crypto"]}
53
-
54
- async def _pms(self, cur: str = "RUB") -> dict[str, dict]:
55
- pms = await self._post("/p2p/public-api/v3/payment-details/get-methods/by-currency-code", {"currencyCode": cur})
56
- return {pm["code"]: {"name": pm["nameEng"]} for pm in pms["data"]}
57
-
58
- async def pms(self) -> dict[str, dict]:
59
- pms = {}
60
- for cur in await self.curs():
61
- for k, pm in (await self._pms(cur)).items():
62
- pms.update({k: pm})
63
- return pms
64
-
65
- async def cur_pms_map(self) -> dict[str, list[str]]:
66
- return {cur: list(await self._pms(cur)) for cur in await self.curs()}
67
-
68
- async def ads(self, coin: str, cur: str, is_sell: bool, pms: list[Pm] = None) -> list[dict]:
69
- params = {
70
- "baseCurrencyCode": coin,
71
- "quoteCurrencyCode": cur,
72
- "offerType": "SALE" if is_sell else "PURCHASE",
73
- "offset": 0,
74
- "limit": 10,
75
- # ,"merchantVerified":"TRUSTED"
76
- }
77
- ads = await self._post("/p2p/public-api/v2/offer/depth-of-market/", params)
78
- return ads
@@ -1,215 +0,0 @@
1
- from enum import StrEnum, IntEnum
2
- from typing import Literal
3
-
4
- from x_client.http import Client
5
- from xync_schema.models import User, Cur, Order, Coin, OrderStatus, Pmex
6
- from xync_schema.pydantic import FiatNew
7
-
8
- from xync_client.Abc.Agent import Client as BaseClient
9
- from xync_client.TgWallet.pyro import PyroClient
10
-
11
-
12
- class Exceptions(StrEnum):
13
- PM_KYC = "OFFER_FIAT_COUNTRY_NOT_SUPPORTED_BY_USER_KYC_COUNTRY"
14
-
15
-
16
- class Status(IntEnum):
17
- ALL_ACTIVE = OrderStatus.active
18
-
19
-
20
- class AgentClient(BaseClient):
21
- async def _get_auth_hdrs(self) -> dict[str, str]:
22
- pyro = PyroClient(self.agent)
23
- init_data = await pyro.get_init_data()
24
- # async with ClientSession(self.agent.ex.url_login) as sess:
25
- # resp = await sess.post('/api/v1/users/auth/', data=init_data, headers={'content-type': 'application/json;charset=UTF-8'})
26
- # tokens = await resp.json()
27
- tokens = Client("walletbot.me")._post("/api/v1/users/auth/", init_data)
28
- return {"Wallet-Authorization": tokens["jwt"], "Authorization": "Bearer " + tokens["value"]}
29
-
30
- async def get_orders(
31
- self, stauts: OrderStatus = OrderStatus.active, coin: Coin = None, cur: Cur = None, is_sell: bool = None
32
- ) -> list[Order]:
33
- orders = await self._post(
34
- "/p2p/public-api/v2/offer/order/history/get-by-user-id",
35
- {"offset": 0, "limit": 100, "filter": {"status": Status(stauts)}}, # "limit": 20
36
- )
37
- return orders
38
-
39
- async def order_request(self, ad_id: int, amount: float) -> Order: ...
40
-
41
- async def my_fiats(self, cur: Cur = None) -> dict:
42
- fiats = await self._post("/p2p/public-api/v3/payment-details/get/by-user-id")
43
- fiats = {fiat["id"]: fiat for fiat in fiats["data"]}
44
- return fiats
45
-
46
- async def fiat_new(self, fiat: FiatNew):
47
- pmex = await Pmex.get_or_create(pm_id=fiat.pm_id, ex=self.agent.ex) # .prefetch_related('pm')
48
- cur = await Cur[fiat.cur_id]
49
- add_fiat = await self._post(
50
- "/p2p/public-api/v3/payment-details/create",
51
- {
52
- "paymentMethodCode": pmex.exid,
53
- "currencyCode": cur.ticker,
54
- "name": fiat.name,
55
- "attributes": {"version": "V1", "values": [{"name": "PAYMENT_DETAILS_NUMBER", "value": fiat.detail}]},
56
- },
57
- )
58
- return add_fiat
59
-
60
- # 7 - fiat_edit
61
- async def fiat_upd(self, fiat_id: int, name: str, detail: str):
62
- edit_fiat = await self._post(
63
- "/p2p/public-api/v3/payment-details/edit",
64
- {
65
- "id": fiat_id,
66
- # "paymentMethodCode": code_pms,
67
- # "currencyCode": cur,
68
- "name": name,
69
- "attributes": {"version": "V1", "values": [{"name": "PAYMENT_DETAILS_NUMBER", "value": detail}]},
70
- },
71
- )
72
- return edit_fiat
73
-
74
- async def fiat_del(self, fiat_id: int):
75
- del_fiat = await self._post("/p2p/public-api/v3/payment-details/delete", {"id": fiat_id})
76
- return del_fiat
77
-
78
- async def ad_switch(self) -> bool:
79
- pass
80
-
81
- async def ads_switch(self) -> bool:
82
- pass
83
-
84
- async def get_user(self, user_id) -> User:
85
- pass
86
-
87
- async def send_user_msg(self, msg: str, file=None) -> bool:
88
- pass
89
-
90
- async def block_user(self, is_blocked: bool = True) -> bool:
91
- pass
92
-
93
- async def rate_user(self, positive: bool) -> bool:
94
- pass
95
-
96
- # base_url = 'https://p2p.walletbot.me'
97
- # middle_url = '/p2p/'
98
-
99
- # 1: all_curs
100
- async def all_curs(self):
101
- coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
102
- curs = [c["code"] for c in coins_curs["data"]["fiat"]]
103
- return curs
104
-
105
- # 2: all_coins
106
- async def all_coins(self):
107
- coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
108
- coins = [c["code"] for c in coins_curs["data"]["crypto"]]
109
- return coins
110
-
111
- # 3: all_coins
112
- async def all_pms(self):
113
- pms = await self._post(
114
- "/p2p/public-api/v3/payment-details/get-methods/by-currency-code", {"currencyCode": "RUB"}
115
- )
116
- return pms["data"]
117
-
118
- # 4: all_ads
119
- async def get_ads(
120
- self, coin: str = "TON", cur: str = "RUB", tt: str = "SALE", offset: int = 0, limit: int = 100
121
- ) -> dict:
122
- params = {
123
- "baseCurrencyCode": coin,
124
- "quoteCurrencyCode": cur,
125
- "offerType": tt,
126
- "offset": offset,
127
- "limit": limit,
128
- } # ,"merchantVerified":"TRUSTED"
129
- ads = await self._post("/p2p/public-api/v2/offer/depth-of-market/", params)
130
- return ads
131
-
132
- # 9 - my_ads
133
- async def my_ads(self, status: Literal["INACTIVE", "ACTIVE"] = None):
134
- ads = await self._post(
135
- "/p2p/public-api/v2/offer/user-own/list", {"offset": 0, "limit": 20, "offerType": "SALE"}
136
- )
137
- return [ad for ad in ads["data"] if ad["status"] == status] if status else ads
138
-
139
- # 10 - ad_new
140
- async def ad_new(self, fiats: list[int], amount: int, coin: str = "TON", cur: str = "RUB", tt: str = "SALE"):
141
- create = await self._post(
142
- "/p2p/public-api/v2/offer/create",
143
- {
144
- "type": tt,
145
- "initVolume": {"currencyCode": coin, "amount": f"{amount}"},
146
- "orderRoundingRequired": False,
147
- "price": {"type": "FLOATING", "baseCurrencyCode": coin, "quoteCurrencyCode": cur, "value": "120"},
148
- "orderAmountLimits": {"min": "500", "max": "2000"},
149
- "paymentConfirmTimeout": "PT15M",
150
- "comment": "",
151
- "paymentDetailsIds": fiats,
152
- },
153
- )
154
- return create
155
-
156
- # 11 - ad_upd
157
- async def ad_upd(self, typ: str, offer_id: int, fiats: list[int], amount: int):
158
- upd = await self._post(
159
- "/p2p/public-api/v2/offer/edit",
160
- {
161
- "offerId": offer_id,
162
- "paymentConfirmTimeout": "PT15M",
163
- "type": typ,
164
- "orderRoundingRequired": False,
165
- "price": {"type": "FLOATING", "value": "120"},
166
- "orderAmountLimits": {"min": "500", "max": "2000"},
167
- "comment": "",
168
- "volume": f"{amount}",
169
- "paymentDetailsIds": fiats,
170
- },
171
- )
172
- return upd
173
-
174
- # 12 - ad_del
175
- async def ad_del(self, typ: str, offer_id: int):
176
- ad_del = await self._post("/p2p/public-api/v2/offer/delete", {"type": typ, "offerId": offer_id})
177
- return ad_del
178
-
179
- # 13 - ad_on
180
- async def ad_on(self, typ: str, offer_id: int):
181
- active = await self._post("/p2p/public-api/v2/offer/activate", {"type": typ, "offerId": offer_id})
182
- return active
183
-
184
- # 14 - ad_off
185
- async def ad_off(self, typ: str, offer_id: int) -> dict[str, str]:
186
- off = await self._post("/p2p/public-api/v2/offer/deactivate", {"type": typ, "offerId": offer_id})
187
- return off
188
-
189
- # 15 - order_approve
190
- async def order_approve(self, order_id: int, typ: str):
191
- approve = await self._post("/p2p/public-api/v2/offer/order/accept", {"orderId": order_id, "type": typ})
192
- return approve
193
-
194
- # 16 - order_reject
195
- async def order_reject(self, order_id: str):
196
- reject = await self._post("/p2p/public-api/v2/offer/order/cancel/by-seller", {"orderId": order_id})
197
- return reject
198
-
199
- async def upload_file(self, order_id: int, path_to_file: str):
200
- url = f"public-api/v2/file-storage/file/upload?orderId={order_id}&uploadType=UPLOAD_BUYER_PAYMENT_RECEIPT"
201
- data = {"file": open(path_to_file, "rb")}
202
- upload_file = await self._post(url, data)
203
- return upload_file
204
-
205
- # 19 - order_paid
206
- async def order_paid(self, order_id: str, file: dict):
207
- paid = await self._post(
208
- "/p2p/public-api/v2/offer/order/confirm-sending-payment", {"orderId": order_id, "paymentReceipt": file}
209
- )
210
- return paid
211
-
212
- # 20 - order_payment_confirm
213
- async def order_payment_confirm(self, order_id: str):
214
- payment_confirm = await self._post("/p2p/public-api/v2/payment-details/confirm", {"orderId": order_id})
215
- return payment_confirm