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.
- {xync_client-0.0.16.dev4/xync_client.egg-info → xync_client-0.0.16.dev9}/PKG-INFO +2 -2
- xync_client-0.0.16.dev9/tests/TestAgent.py +141 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Agent.py +12 -12
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/agent.py +121 -66
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/ex.py +1 -1
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9/xync_client.egg-info}/PKG-INFO +2 -2
- xync_client-0.0.16.dev4/tests/TestAgent.py +0 -53
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.env.sample +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.gitignore +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/.pre-commit-config.yaml +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/README.md +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/makefile +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/pyproject.toml +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/setup.cfg +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/TestEx.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/TestOrder.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Binance/test_binance.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Gate/test_gate.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Wallet/test_agent.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Wallet/test_ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/__init__.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/_test_ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Auth.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Base.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/BaseTest.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Abc/Order.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/__init__.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/binance_async.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/earn_api.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/exceptions.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/sapi.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Binance/web_c2c.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/__init__.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/base.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/req.mjs +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BingX/sign.js +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/__init__.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/agent.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/BitGet/req.mjs +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/agent.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/web_earn.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Bybit/web_p2p.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Gate/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Gate/premarket.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/agent.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/earn.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Htx/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/KuCoin/pub.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/KuCoin/web.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/Okx/ex.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/auth.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/order.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/pyro.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/TgWallet/web.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/__init__.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client/loader.py +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/SOURCES.txt +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/dependency_links.txt +0 -0
- {xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/requires.txt +0 -0
- {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
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: xync-client
|
|
3
|
-
Version: 0.0.16.
|
|
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
|
|
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
|
|
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: Список моих
|
|
42
|
+
# 29: Список моих объявлений
|
|
43
43
|
@abstractmethod
|
|
44
44
|
async def my_ads(self, status: AdStatus = None) -> ListOfDicts: ...
|
|
45
45
|
|
|
46
|
-
# 30: Создание
|
|
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
|
-
|
|
54
|
-
amount:
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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(
|
|
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[
|
|
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(
|
|
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[
|
|
39
|
-
|
|
40
|
-
|
|
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":
|
|
48
|
-
"amount": {
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
85
|
-
|
|
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
|
-
|
|
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: Список моих
|
|
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: Создание
|
|
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
|
-
|
|
115
|
-
amount:
|
|
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": {
|
|
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":
|
|
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(
|
|
140
|
-
return get_own[
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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[
|
|
161
|
-
"type": ad[
|
|
190
|
+
"paymentConfirmTimeout": ad["paymentConfirmTimeout"],
|
|
191
|
+
"type": ad["type"],
|
|
162
192
|
"orderRoundingRequired": False,
|
|
163
|
-
"price": {"type": "FIXED", "value": price},
|
|
164
|
-
"orderAmountLimits": {"min":
|
|
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":
|
|
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[
|
|
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[
|
|
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[
|
|
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())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: xync-client
|
|
3
|
-
Version: 0.0.16.
|
|
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")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Binance/test_binance.py
RENAMED
|
File without changes
|
|
File without changes
|
{xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/tests/_todo_refact/Bybit/test_bybit_p2p.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xync_client-0.0.16.dev4 → xync_client-0.0.16.dev9}/xync_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|