xync-client 0.0.16.dev4__tar.gz → 0.0.16.dev9__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 (68) hide show
  1. {xync_client-0.0.16.dev4/xync_client.egg-info → xync_client-0.0.16.dev9}/PKG-INFO +2 -2
  2. xync_client-0.0.16.dev9/tests/TestAgent.py +141 -0
  3. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Agent.py +12 -12
  4. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/agent.py +121 -66
  5. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/ex.py +1 -1
  6. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9/xync_client.egg-info}/PKG-INFO +2 -2
  7. xync_client-0.0.16.dev4/tests/TestAgent.py +0 -53
  8. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.env.sample +0 -0
  9. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.gitignore +0 -0
  10. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.pre-commit-config.yaml +0 -0
  11. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/README.md +0 -0
  12. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/makefile +0 -0
  13. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/pyproject.toml +0 -0
  14. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/setup.cfg +0 -0
  15. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/TestEx.py +0 -0
  16. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/TestOrder.py +0 -0
  17. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Binance/test_binance.py +0 -0
  18. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  19. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  20. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Gate/test_gate.py +0 -0
  21. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
  22. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  23. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  24. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/__init__.py +0 -0
  25. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/_test_ex.py +0 -0
  26. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Auth.py +0 -0
  27. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Base.py +0 -0
  28. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/BaseTest.py +0 -0
  29. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Ex.py +0 -0
  30. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Order.py +0 -0
  31. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/__init__.py +0 -0
  32. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/binance_async.py +0 -0
  33. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/earn_api.py +0 -0
  34. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/ex.py +0 -0
  35. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/exceptions.py +0 -0
  36. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/sapi.py +0 -0
  37. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/web_c2c.py +0 -0
  38. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/__init__.py +0 -0
  39. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/base.py +0 -0
  40. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/ex.py +0 -0
  41. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/req.mjs +0 -0
  42. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/sign.js +0 -0
  43. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/__init__.py +0 -0
  44. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/agent.py +0 -0
  45. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/ex.py +0 -0
  46. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/req.mjs +0 -0
  47. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/agent.py +0 -0
  48. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/ex.py +0 -0
  49. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/web_earn.py +0 -0
  50. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/web_p2p.py +0 -0
  51. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Gate/ex.py +0 -0
  52. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Gate/premarket.py +0 -0
  53. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/agent.py +0 -0
  54. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/earn.py +0 -0
  55. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/ex.py +0 -0
  56. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/KuCoin/pub.py +0 -0
  57. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/KuCoin/web.py +0 -0
  58. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Okx/ex.py +0 -0
  59. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/auth.py +0 -0
  60. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/order.py +0 -0
  61. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/pyro.py +0 -0
  62. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/web.py +0 -0
  63. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/__init__.py +0 -0
  64. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/loader.py +0 -0
  65. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/SOURCES.txt +0 -0
  66. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/dependency_links.txt +0 -0
  67. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/requires.txt +0 -0
  68. {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: xync-client
3
- Version: 0.0.16.dev4
3
+ Version: 0.0.16.dev9
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
@@ -0,0 +1,141 @@
1
+ import logging
2
+
3
+ import pytest
4
+ from xync_schema.enums import ExStatus, ExAction
5
+ from xync_schema.models import Ex, TestEx, Fiat, Ad, Coin, Cur
6
+ from xync_schema.pydantic import FiatNew
7
+
8
+ from xync_client.Abc.BaseTest import BaseTest
9
+ from xync_client.Abc.Agent import BaseAgentClient
10
+ from xync_client.Abc.Base import BaseClient, DictOfDicts, ListOfDicts
11
+ from xync_client.TgWallet.ex import ExClient
12
+
13
+
14
+ @pytest.mark.asyncio(loop_scope="session")
15
+ class TestAgent(BaseTest):
16
+ @pytest.fixture(scope="class", autouse=True)
17
+ async def clients(self) -> tuple[BaseClient, BaseClient]:
18
+ exs = await Ex.filter(status__gt=ExStatus.plan).prefetch_related("agents__ex")
19
+ agents = [[ag for ag in ex.agents if ag.auth][:2] for ex in exs]
20
+ clients: list[tuple[BaseClient, BaseClient]] = [(t.client(), m.client()) for t, m in agents]
21
+ yield clients
22
+ [(await taker.close(), await maker.close()) for taker, maker in clients]
23
+
24
+ # 0
25
+ async def test_get_orders(self, clients: list[BaseAgentClient]):
26
+ for taker, maker in clients:
27
+ get_orders: ListOfDicts = await taker.get_orders()
28
+ ok = self.is_list_of_dicts(get_orders, False)
29
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.get_orders)
30
+ assert t.ok, "No get orders"
31
+ logging.info(f"{taker.agent.ex_id}:{ExAction.get_orders.name} - ok")
32
+
33
+ # 1
34
+ async def test_order_request(self, clients: list[BaseAgentClient]):
35
+ for taker, maker in clients:
36
+ await taker.agent.fetch_related("ex", "ex__agents")
37
+ ex_client: ExClient = taker.agent.ex.client()
38
+ ads = await ex_client.ads("NOT", "RUB", False)
39
+ for ad in ads:
40
+ order_request: dict | bool = await taker.order_request(ad["id"], ad["orderAmountLimits"]["min"])
41
+ if order_request:
42
+ break
43
+ ok = order_request["status"] == "SUCCESS"
44
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.order_request)
45
+ assert t.ok, "No get orders"
46
+ logging.info(f"{taker.agent.ex_id}:{ExAction.order_request.name} - ok")
47
+
48
+ # 25
49
+ async def test_my_fiats(self, clients: list[BaseAgentClient]):
50
+ for taker, maker in clients:
51
+ my_fiats: DictOfDicts = await taker.my_fiats()
52
+ ok = self.is_dict_of_dicts(my_fiats)
53
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.my_fiats)
54
+ assert t.ok, "No my fiats"
55
+ logging.info(f"{taker.agent.ex_id}:{ExAction.my_fiats.name} - ok")
56
+
57
+ # 26
58
+ async def test_fiat_new(self, clients: list[BaseAgentClient]):
59
+ for taker, maker in clients:
60
+ fn = FiatNew(cur_id=11, pm_id=22, detail="123456789")
61
+ fiat_new: Fiat = await taker.fiat_new(fn)
62
+ ok = isinstance(fiat_new, Fiat)
63
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.fiat_new)
64
+ assert t.ok, "No add fiat"
65
+ logging.info(f"{taker.agent.ex_id}:{ExAction.fiat_new.name} - ok")
66
+
67
+ # 27
68
+ async def test_fiat_upd(self, clients: list[BaseAgentClient]):
69
+ for taker, maker in clients:
70
+ my_fiats = await taker.my_fiats()
71
+ fiats = [fiat for fiat in my_fiats.values()]
72
+ fiat_upd: Fiat = await taker.fiat_upd(fiat_id=fiats[0]["id"], detail="347890789")
73
+ ok = isinstance(fiat_upd, Fiat)
74
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.fiat_upd)
75
+ assert t.ok, "No upd fiat"
76
+ logging.info(f"{taker.agent.ex_id}:{ExAction.fiat_upd.name} - ok")
77
+
78
+ # 28
79
+ async def test_fiat_del(self, clients: list[BaseAgentClient]):
80
+ for taker, maker in clients:
81
+ my_fiats = await taker.my_fiats()
82
+ fiats = [fiat for fiat in my_fiats.values()]
83
+ fiat_del: bool = await taker.fiat_del(fiat_id=fiats[0]["id"])
84
+ ok = fiat_del["status"] == "SUCCESS"
85
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.fiat_del)
86
+ assert t.ok, "No del fiat"
87
+ logging.info(f"{taker.agent.ex_id}:{ExAction.fiat_del.name} - ok")
88
+
89
+ # 29
90
+ async def test_my_ads(self, clients: list[BaseAgentClient]):
91
+ for taker, maker in clients:
92
+ my_ads: ListOfDicts = await taker.my_ads()
93
+ ok = self.is_list_of_dicts(my_ads, False)
94
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.my_ads)
95
+ assert t.ok, "No del fiat"
96
+ logging.info(f"{taker.agent.ex_id}:{ExAction.my_ads.name} - ok")
97
+
98
+ # 30
99
+ async def test_ad_new(self, clients: list[BaseAgentClient]):
100
+ for taker, maker in clients:
101
+ my_fiats = await taker.my_fiats()
102
+ my_fiat = list(my_fiats.values())[0]
103
+ coin = await Coin.get(ticker="USDT")
104
+ cur = await Cur.get(ticker=my_fiat["currency"])
105
+ # pm = await Fiatex.get()
106
+ ad_new: Ad.pyd() = await taker.ad_new(
107
+ coin=coin, cur=cur, is_sell=True, fiats=[my_fiat["id"]], amount="10", price="120", min_fiat="500"
108
+ )
109
+ ok = ad_new["status"] == "SUCCESS"
110
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.ad_new)
111
+ assert t.ok, "No add new ad"
112
+ logging.info(f"{taker.agent.ex_id}:{ExAction.ad_new.name} - ok")
113
+
114
+ # 31
115
+ async def test_ad_upd(self, clients: list[BaseAgentClient]):
116
+ for taker, maker in clients:
117
+ my_ads: ListOfDicts = await taker.my_ads()
118
+ ad_upd: Ad.pyd() = await taker.ad_upd(offer_id=my_ads[0]["id"], amount="11")
119
+ ok = ad_upd["status"] == "SUCCESS"
120
+ t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=taker.agent.ex_id, action=ExAction.ad_upd)
121
+ assert t.ok, "No add new ad"
122
+ logging.info(f"{taker.agent.ex_id}:{ExAction.ad_upd.name} - ok")
123
+
124
+ # 32
125
+ async def test_ad_del(self, clients: list[BaseAgentClient]):
126
+ for taker, maker in clients:
127
+ my_ads: ListOfDicts = await taker.my_ads()
128
+ ad_del: bool = await taker.ad_del(offer_id=my_ads[0]["id"])
129
+ t, _ = await TestEx.update_or_create({"ok": ad_del}, ex_id=taker.agent.ex_id, action=ExAction.ad_del)
130
+ assert t.ok, "No add new ad"
131
+ logging.info(f"{taker.agent.ex_id}:{ExAction.ad_del.name} - ok")
132
+
133
+ # 33
134
+ async def test_ad_switch(self, clients: list[BaseAgentClient]):
135
+ for taker, maker in clients:
136
+ my_ads: ListOfDicts = await taker.my_ads()
137
+ new_status = not (my_ads[0]["status"] == "ACTIVE")
138
+ ad_switch: bool = await taker.ad_switch(offer_id=my_ads[0]["id"], active=new_status)
139
+ t, _ = await TestEx.update_or_create({"ok": ad_switch}, ex_id=taker.agent.ex_id, action=ExAction.ad_switch)
140
+ assert t.ok, "No ad active/off"
141
+ logging.info(f"{taker.agent.ex_id}:{ExAction.ad_switch.name} - ok")
@@ -26,47 +26,47 @@ class BaseAgentClient(BaseAuthClient):
26
26
  @abstractmethod
27
27
  async def my_fiats(self, cur: Cur = None) -> DictOfDicts: ... # {fiat.exid: {fiat}}
28
28
 
29
- # 26: Создание
29
+ # 26: Создание реквизита моего платежного метода
30
30
  @abstractmethod
31
- async def fiat_new(self, fiat: FiatNew) -> Fiat.pyd(): ...
31
+ async def fiat_new(self, fiat: FiatNew) -> Fiat: ...
32
32
 
33
- # 27: Редактирование
33
+ # 27: Редактирование реквизита моего платежного метода
34
34
  @abstractmethod
35
- async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> Fiat.pyd(): ...
35
+ async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> Fiat: ...
36
36
 
37
- # 28: Удаление
37
+ # 28: Удаление реквизита моего платежного метода
38
38
  @abstractmethod
39
39
  async def fiat_del(self, fiat_id: int) -> bool: ...
40
40
 
41
41
  # # # Ad
42
- # 29: Список моих ad
42
+ # 29: Список моих объявлений
43
43
  @abstractmethod
44
44
  async def my_ads(self, status: AdStatus = None) -> ListOfDicts: ...
45
45
 
46
- # 30: Создание ad:
46
+ # 30: Создание объявления
47
47
  @abstractmethod
48
48
  async def ad_new(
49
49
  self,
50
50
  coin: Coin,
51
51
  cur: Cur,
52
52
  is_sell: bool,
53
- pms: list[Pm],
54
- amount: int,
53
+ fiats: list[Fiat],
54
+ amount: str,
55
55
  price: float,
56
+ min_fiat: str,
56
57
  is_float: bool = True,
57
- min_fiat: int = None,
58
58
  details: str = None,
59
59
  autoreply: str = None,
60
60
  status: AdStatus = AdStatus.active,
61
61
  ) -> Ad.pyd(): ...
62
62
 
63
- # 31: Редактирование
63
+ # 31: Редактирование объявления
64
64
  @abstractmethod
65
65
  async def ad_upd(
66
66
  self,
67
67
  offer_id: int,
68
68
  amount: int,
69
- pms: [Pm] = None,
69
+ fiats: list[Fiat] = None,
70
70
  price: float = None,
71
71
  is_float: bool = None,
72
72
  min_fiat: int = None,
@@ -1,15 +1,18 @@
1
+ from asyncio import run
1
2
  from enum import StrEnum
2
- from typing import Literal
3
3
 
4
- from xync_schema.enums import AdStatus
4
+ from x_model import init_db
5
+ from xync_schema import models
6
+ from xync_schema.enums import AdStatus, ExStatus
5
7
 
6
- from xync_client.Abc.Base import ListOfDicts, MapOfIdsList, DictOfDicts
8
+ from xync_client.Abc.Base import ListOfDicts, DictOfDicts, BaseClient
7
9
  from xync_client.TgWallet.auth import AuthClient
8
- from xync_schema.models import User, Cur, Order, Coin, OrderStatus, Pmex, Fiat, Ad, Pm
10
+ from xync_schema.models import Cur, Coin, OrderStatus, Pmex, Fiat, Ad, Pm, Pmcur, Fiatex, Ex
9
11
  from xync_schema.pydantic import FiatNew
10
12
 
11
13
  from xync_client.Abc.Agent import BaseAgentClient
12
14
  from xync_client.TgWallet.ex import ExClient
15
+ from xync_client.loader import PG_DSN
13
16
 
14
17
 
15
18
  class Exceptions(StrEnum):
@@ -22,37 +25,43 @@ class Exceptions(StrEnum):
22
25
 
23
26
  class AgentClient(BaseAgentClient, AuthClient):
24
27
  # 0: Получшение ордеров в статусе status, по монете coin, в валюте coin, в направлении is_sell: bool
25
- async def get_orders(self, status: OrderStatus = OrderStatus.created, coin: Coin = None, cur: Cur = None, is_sell: bool = None) -> ListOfDicts:
28
+ async def get_orders(
29
+ self, status: OrderStatus = OrderStatus.created, coin: Coin = None, cur: Cur = None, is_sell: bool = None
30
+ ) -> ListOfDicts:
26
31
  orders = await self._post(
27
32
  "/p2p/public-api/v2/offer/order/history/get-by-user-id",
28
33
  {"offset": 0, "limit": 100, "filter": {"status": "ALL_ACTIVE"}}, # "limit": 20
29
34
  )
30
- return orders['data']
35
+ return orders["data"]
31
36
 
32
37
  # 1: [T] Запрос на старт сделки
33
38
  async def order_request(self, ad_id: int, amount: float) -> dict | bool:
34
- await self.agent.fetch_related('ex', 'ex__agents')
39
+ await self.agent.fetch_related("ex", "ex__agents")
35
40
  ex_client: ExClient = self.agent.ex.client()
36
41
  ad = await ex_client._get_ad(offer_id=ad_id)
37
42
  fiats = await self.my_fiats()
38
- fiats_pms = [fiat['id'] for fiat in fiats.values()]
39
- ad_pms = [pm['id'] for pm in ad['paymentDetails']]
40
- result = list(set(fiats_pms) & set(ad_pms))
43
+ fiats_pms = {fiat["paymentMethod"]["code"]: fiat["id"] for fiat in fiats.values()}
44
+ if not (pms := ad.get("paymentMethods")):
45
+ print(ad)
46
+ ad_pms = [pm["code"] for pm in pms]
47
+ result = list(set(fiats_pms.keys()) & set(ad_pms))
41
48
  if not result:
42
49
  return False
50
+ pid = result[0]
43
51
  request = await self._post(
44
52
  "/p2p/public-api/v2/offer/order/create-by-amount",
45
53
  {
46
54
  "offerId": ad_id,
47
- "paymentDetailsId": result[0],
48
- "amount": {
49
- "currencyCode": ad['orderAmountLimits']['currencyCode'],
50
- "amount": amount
51
- },
52
- "type": ad['type']
53
- }, 'data'
55
+ "paymentDetailsId": fiats_pms[pid],
56
+ "amount": {"currencyCode": ad["orderAmountLimits"]["currencyCode"], "amount": amount},
57
+ "type": ad["type"],
58
+ },
59
+ "data",
54
60
  )
55
- return request
61
+ confirm = await self._post(
62
+ "/p2p/public-api/v2/offer/order/confirm", {"orderId": request["id"], "type": ad["type"]}
63
+ )
64
+ return confirm
56
65
 
57
66
  # 25: Список реквизитов моих платежных методов
58
67
  async def my_fiats(self, cur: Cur = None) -> DictOfDicts:
@@ -60,9 +69,9 @@ class AgentClient(BaseAgentClient, AuthClient):
60
69
  fiats = {fiat["id"]: fiat for fiat in fiats["data"]}
61
70
  return fiats
62
71
 
63
- # 26: Создание
64
- async def fiat_new(self, fiat: FiatNew) -> Fiat.pyd():
65
- pmex = await Pmex.get_or_create(pm_id=fiat.pm_id, ex=self.agent.ex) # .prefetch_related('pm')
72
+ # 26: Создание реквизита моего платежного метода
73
+ async def fiat_new(self, fiat: FiatNew) -> Fiat:
74
+ pmex, _ = await Pmex.get_or_create(pm_id=fiat.pm_id, ex=self.agent.ex) # .prefetch_related('pm')
66
75
  cur = await Cur[fiat.cur_id]
67
76
  add_fiat = await self._post(
68
77
  "/p2p/public-api/v3/payment-details/create",
@@ -73,52 +82,68 @@ class AgentClient(BaseAgentClient, AuthClient):
73
82
  "attributes": {"version": "V1", "values": [{"name": "PAYMENT_DETAILS_NUMBER", "value": fiat.detail}]},
74
83
  },
75
84
  )
76
- return add_fiat
77
-
78
- # 27: Редактирование
79
- async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> Fiat.pyd():
85
+ pmex = await Pmex.get(exid=add_fiat["data"]["paymentMethod"]["code"], ex=self.agent.ex)
86
+ cur = await Cur.get(ticker=add_fiat["data"]["currency"])
87
+ pmcur, _ = await Pmcur.get_or_create(cur=cur, pm_id=pmex.pm_id)
88
+ attrs = {a["name"]: a["value"] for a in add_fiat["data"]["attributes"]["values"]}
89
+ f, _ = await Fiat.update_or_create(
90
+ {"detail": attrs["PAYMENT_DETAILS_NUMBER"]}, pmcur=pmcur, user_id=self.agent.user_id
91
+ )
92
+ await Fiatex.update_or_create({"exid": add_fiat["data"]["id"]}, ex=self.agent.ex, fiat=f)
93
+ return f
94
+
95
+ # 27: Редактирование реквизита моего платежного метода
96
+ async def fiat_upd(self, fiat_id: int, detail: str, name: str = None) -> Fiat:
97
+ fiat = await Fiat.get(fiatexs__exid=fiat_id, fiatexs__ex=self.agent.ex).prefetch_related("pmcur")
98
+ pmex = await Pmex.get(pm_id=fiat.pmcur.pm_id, ex=self.agent.ex)
99
+ cur = await Cur[fiat.pmcur.cur_id]
80
100
  edit_fiat = await self._post(
81
101
  "/p2p/public-api/v3/payment-details/edit",
82
102
  {
83
103
  "id": fiat_id,
84
- # "paymentMethodCode": code_pms,
85
- # "currencyCode": cur,
104
+ "paymentMethodCode": pmex.exid,
105
+ "currencyCode": cur.ticker,
86
106
  "name": name,
87
107
  "attributes": {"version": "V1", "values": [{"name": "PAYMENT_DETAILS_NUMBER", "value": detail}]},
88
108
  },
89
109
  )
90
- return edit_fiat
110
+ pmex = await Pmex.get(exid=edit_fiat["data"]["paymentMethod"]["code"], ex=self.agent.ex)
111
+ cur = await Cur.get(ticker=edit_fiat["data"]["currency"])
112
+ pmcur, _ = await Pmcur.get_or_create(cur=cur, pm_id=pmex.pm_id)
113
+ attrs = {a["name"]: a["value"] for a in edit_fiat["data"]["attributes"]["values"]}
114
+ f, _ = await Fiat.update_or_create(
115
+ {"detail": attrs["PAYMENT_DETAILS_NUMBER"]}, pmcur=pmcur, user_id=self.agent.user_id
116
+ )
117
+ await Fiatex.update_or_create({"exid": edit_fiat["data"]["id"]}, ex=self.agent.ex, fiat=f)
118
+ return f
91
119
 
92
- # 28: Удаление
120
+ # 28: Удаление реквизита моего платежного метода
93
121
  async def fiat_del(self, fiat_id: int) -> bool:
94
122
  del_fiat = await self._post("/p2p/public-api/v3/payment-details/delete", {"id": fiat_id})
95
123
  return del_fiat
96
124
 
97
- # 29: Список моих ad
125
+ # 29: Список моих объявлений
98
126
  async def my_ads(self, status: AdStatus = None) -> ListOfDicts:
99
- mapping = {
100
- AdStatus.defActive: "INACTIVE",
101
- AdStatus.active: "ACTIVE"
102
- }
127
+ mapping = {AdStatus.defActive: "INACTIVE", AdStatus.active: "ACTIVE"}
103
128
  ads = await self._post(
104
129
  "/p2p/public-api/v2/offer/user-own/list", {"offset": 0, "limit": 20, "offerType": "SALE"}
105
130
  )
106
- return [ad for ad in ads["data"] if ad["status"] == mapping[status]] if status else ads
131
+ return [ad for ad in ads["data"] if ad["status"] == mapping[status]] if status else ads['data']
107
132
 
108
- # 30: Создание ad
133
+ # 30: Создание объявления
109
134
  async def ad_new(
110
135
  self,
111
136
  coin: Coin,
112
137
  cur: Cur,
113
138
  is_sell: bool,
114
- pms: list[Pm],
115
- amount: int,
139
+ fiats: list[Fiat],
140
+ amount: str,
116
141
  price: float,
142
+ min_fiat: str,
117
143
  is_float: bool = True,
118
- min_fiat: int = None,
119
144
  details: str = None,
120
145
  autoreply: str = None,
121
- status: AdStatus = AdStatus.active
146
+ status: AdStatus = AdStatus.active,
122
147
  ) -> Ad.pyd():
123
148
  create = await self._post(
124
149
  "/p2p/public-api/v2/offer/create",
@@ -126,45 +151,50 @@ class AgentClient(BaseAgentClient, AuthClient):
126
151
  "type": "SALE" if is_sell else "BUY",
127
152
  "initVolume": {"currencyCode": coin.ticker, "amount": f"{amount}"},
128
153
  "orderRoundingRequired": False,
129
- "price": {"type": "FIXED", "baseCurrencyCode": coin.ticker, "quoteCurrencyCode": cur.ticker, "value": price},
154
+ "price": {
155
+ "type": "FIXED",
156
+ "baseCurrencyCode": coin.ticker,
157
+ "quoteCurrencyCode": cur.ticker,
158
+ "value": price,
159
+ },
130
160
  "orderAmountLimits": {"min": min_fiat},
131
161
  "paymentConfirmTimeout": "PT15M" if is_sell else "PT3H",
132
162
  "comment": "",
133
- "paymentDetailsIds": pms,
163
+ "paymentDetailsIds": fiats,
134
164
  },
135
165
  )
136
166
  return create
137
167
 
138
168
  async def _get_my_ad(self, offer_id: int):
139
- get_own = await self._post('/p2p/public-api/v2/offer/get-user-own/', {"offerId": offer_id})
140
- return get_own['data']
169
+ get_own = await self._post("/p2p/public-api/v2/offer/get-user-own/", {"offerId": offer_id})
170
+ return get_own["data"]
141
171
 
142
- # 31: Редактирование
172
+ # 31: Редактирование объявления
143
173
  async def ad_upd(
144
- self,
145
- offer_id: int,
146
- amount: int,
147
- pms: [Pm] = None,
148
- price: float = None,
149
- is_float: bool = None,
150
- min_fiat: int = None,
151
- details: str = None,
152
- autoreply: str = None,
153
- status: AdStatus = None,
174
+ self,
175
+ offer_id: int,
176
+ amount: int,
177
+ fiats: list[Fiat] = None,
178
+ price: float = None,
179
+ is_float: bool = None,
180
+ min_fiat: int = None,
181
+ details: str = None,
182
+ autoreply: str = None,
183
+ status: AdStatus = None,
154
184
  ) -> Ad.pyd():
155
185
  ad = await self._get_my_ad(offer_id)
156
186
  upd = await self._post(
157
187
  "/p2p/public-api/v2/offer/edit",
158
188
  {
159
189
  "offerId": offer_id,
160
- "paymentConfirmTimeout": ad['paymentConfirmTimeout'],
161
- "type": ad['type'],
190
+ "paymentConfirmTimeout": ad["paymentConfirmTimeout"],
191
+ "type": ad["type"],
162
192
  "orderRoundingRequired": False,
163
- "price": {"type": "FIXED", "value": price},
164
- "orderAmountLimits": {"min": min_fiat},
193
+ "price": {"type": "FIXED", "value": ad['price']['value']},
194
+ "orderAmountLimits": {"min": ad["orderAmountLimits"]["min"]},
165
195
  "comment": "", # TODO: comment
166
196
  "volume": f"{amount}",
167
- "paymentDetailsIds": pms,
197
+ "paymentDetailsIds": [a['id'] for a in ad["paymentDetails"]],
168
198
  },
169
199
  )
170
200
  return upd
@@ -172,18 +202,18 @@ class AgentClient(BaseAgentClient, AuthClient):
172
202
  # 32: Удаление
173
203
  async def ad_del(self, offer_id: int) -> bool:
174
204
  ad = await self._get_my_ad(offer_id)
175
- ad_del = await self._post("/p2p/public-api/v2/offer/delete", {"type": ad['type'], "offerId": offer_id})
176
- return ad_del
205
+ ad_del = await self._post("/p2p/public-api/v2/offer/delete", {"type": ad["type"], "offerId": offer_id})
206
+ return ad_del['status'] == "SUCCESS"
177
207
 
178
208
  # 33: Вкл/выкл объявления
179
209
  async def ad_switch(self, offer_id: int, active: bool) -> bool:
180
210
  ad = await self._get_my_ad(offer_id)
181
211
  if active:
182
- active = await self._post("/p2p/public-api/v2/offer/activate", {"type": ad['type'], "offerId": offer_id})
183
- return active
212
+ active = await self._post("/p2p/public-api/v2/offer/activate", {"type": ad["type"], "offerId": offer_id})
213
+ return active['status'] == "SUCCESS"
184
214
  else:
185
- off = await self._post("/p2p/public-api/v2/offer/deactivate", {"type": ad['type'], "offerId": offer_id})
186
- return off
215
+ off = await self._post("/p2p/public-api/v2/offer/deactivate", {"type": ad["type"], "offerId": offer_id})
216
+ return off['status'] == "SUCCESS"
187
217
 
188
218
  # 34: Вкл/выкл всех объявлений
189
219
  async def ads_switch(self, active: bool) -> bool:
@@ -208,6 +238,13 @@ class AgentClient(BaseAgentClient, AuthClient):
208
238
  # 39: Балансы моих монет
209
239
  async def my_assets(self) -> dict: ...
210
240
 
241
+
242
+
243
+
244
+
245
+
246
+
247
+
211
248
  # base_url = 'https://p2p.walletbot.me'
212
249
  # middle_url = '/p2p/'
213
250
 
@@ -244,3 +281,21 @@ class AgentClient(BaseAgentClient, AuthClient):
244
281
  async def order_payment_confirm(self, order_id: str):
245
282
  payment_confirm = await self._post("/p2p/public-api/v2/payment-details/confirm", {"orderId": order_id})
246
283
  return payment_confirm
284
+
285
+
286
+ # async def main():
287
+ # await init_db(PG_DSN, models, True)
288
+ # exs = await Ex.filter(status__gt=ExStatus.plan).prefetch_related("agents__ex")
289
+ # agents = [[ag for ag in ex.agents if ag.auth][:2] for ex in exs]
290
+ # clients: list[tuple[AgentClient, AgentClient]] = [(t.client(), m.client()) for t, m in agents]
291
+ # taker, maker = clients[0]
292
+ # my_fiats = await taker.my_fiats()
293
+ # my_fiat = list(my_fiats.values())[0]
294
+ # coin = await Coin.get(ticker="USDT")
295
+ # cur = await Cur.get(ticker=my_fiat["currency"])
296
+ # fiatex = await Fiatex.get(exid=my_fiat['id']).prefetch_related('fiat')
297
+ # e = await taker.ad_new(coin=coin, cur=cur, is_sell=True, fiats=[fiatex.fiat], amount='10', price='120', min_fiat='500')
298
+ # print(e)
299
+ #
300
+ # if __name__ == "__main__":
301
+ # run(main())
@@ -68,7 +68,7 @@ async def main():
68
68
  await init_db(PG_DSN, models, True)
69
69
  tgex = await Ex.get(name="TgWallet").prefetch_related("agents", "agents__ex")
70
70
  cl = tgex.client()
71
- e = await cl.set_pmcurexs()
71
+ e = await cl.pms()
72
72
  print(e)
73
73
 
74
74
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: xync-client
3
- Version: 0.0.16.dev4
3
+ Version: 0.0.16.dev9
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,53 +0,0 @@
1
- import logging
2
-
3
- import pytest
4
- from xync_schema.enums import ExStatus, ExAction
5
- from xync_schema.models import Ex, TestEx
6
-
7
- from xync_client.Abc.BaseTest import BaseTest
8
- from xync_client.Abc.Agent import BaseAgentClient
9
- from xync_client.Abc.Base import BaseClient, DictOfDicts, ListOfDicts
10
- from xync_client.TgWallet.ex import ExClient
11
-
12
-
13
- @pytest.mark.asyncio(loop_scope="session")
14
- class TestAgent(BaseTest):
15
- @pytest.fixture(scope="class", autouse=True)
16
- async def clients(self) -> list[BaseClient]:
17
- exs = await Ex.filter(status__gt=ExStatus.plan).prefetch_related("agents__ex")
18
- clients: list[BaseAgentClient] = [[ag for ag in ex.agents if ag.auth].pop().client() for ex in exs]
19
- yield clients
20
- [await cl.close() for cl in clients]
21
-
22
- # 0
23
- async def test_get_orders(self, clients: list[BaseAgentClient]):
24
- for client in clients:
25
- get_orders: ListOfDicts = await client.get_orders()
26
- ok = self.is_list_of_dicts(get_orders, False)
27
- t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=client.agent.ex_id, action=ExAction.get_orders)
28
- assert t.ok, "No get orders"
29
- logging.info(f"{client.agent.ex_id}:{ExAction.get_orders.name} - ok")
30
-
31
- # 1
32
- async def test_order_request(self, clients: list[BaseAgentClient]):
33
- for client in clients:
34
- await client.agent.fetch_related('ex', 'ex__agents')
35
- ex_client: ExClient = client.agent.ex.client()
36
- ads = await ex_client.ads('USDT', 'RUB', True)
37
- for ad in ads:
38
- order_request: dict | bool = await client.order_request(ad['id'], ad['orderAmountLimits']['min'])
39
- if order_request:
40
- continue
41
- ok = isinstance(order_request, dict)
42
- t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=client.agent.ex_id, action=ExAction.order_request)
43
- assert t.ok, "No get orders"
44
- logging.info(f"{client.agent.ex_id}:{ExAction.order_request.name} - ok")
45
-
46
- # 25
47
- async def test_my_fiats(self, clients: list[BaseAgentClient]):
48
- for client in clients:
49
- my_fiats: DictOfDicts = await client.my_fiats()
50
- ok = self.is_dict_of_dicts(my_fiats)
51
- t, _ = await TestEx.update_or_create({"ok": ok}, ex_id=client.agent.ex_id, action=ExAction.my_fiats)
52
- assert t.ok, "No my fiats"
53
- logging.info(f"{client.agent.ex_id}:{ExAction.my_fiats.name} - ok")