xync-client 0.0.25.dev40__tar.gz → 0.0.25.dev41__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.25.dev40/xync_client.egg-info → xync_client-0.0.25.dev41}/PKG-INFO +1 -1
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/TestAgent.py +12 -1
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/TestEx.py +21 -22
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/Ex.py +24 -31
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/agent.py +3 -2
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/etype/ad.py +4 -3
- xync_client-0.0.25.dev41/xync_client/Htx/ex.py +157 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/ex.py +17 -16
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41/xync_client.egg-info}/PKG-INFO +1 -1
- xync_client-0.0.25.dev40/xync_client/Htx/ex.py +0 -90
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/.env.sample +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/.gitignore +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/.pre-commit-config.yaml +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/README.md +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/makefile +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/pyproject.toml +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/setup.cfg +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/TestAsset.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/TestOrder.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Binance/test_binance.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Gate/test_gate.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Wallet/test_agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Wallet/test_ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/_test_ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/Agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/Asset.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/AuthTrait.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/Base.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/BaseTest.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/InAgent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Abc/Order.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/binance_async.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/earn_api.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/exceptions.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/sapi.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Binance/web_c2c.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/base.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/pyd.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/req.mjs +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/sign.js +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BingX/test/main.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BitGet/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BitGet/agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BitGet/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/BitGet/req.mjs +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Bybit/agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Bybit/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Bybit/web_earn.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Bybit/web_p2p.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Gate/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Gate/premarket.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/earn.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/etype/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/etype/cred.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Htx/etype/pm.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/KuCoin/pub.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/KuCoin/web.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Okx/ex.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/Okx/pyd.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/agent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/asset.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/auth.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/inAgent.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/order.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/pyd.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/pyro.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/TgWallet/web.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/__init__.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/loader.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client/pyro.py +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client.egg-info/SOURCES.txt +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client.egg-info/dependency_links.txt +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client.egg-info/requires.txt +0 -0
- {xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/xync_client.egg-info/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
import pytest
|
|
4
4
|
from xync_schema.enums import ExStatus, ExAction
|
|
5
5
|
from xync_schema.models import Ex, TestEx, Fiat, Ad, Coin, Cur
|
|
6
|
-
from xync_schema.
|
|
6
|
+
from xync_schema.types import FiatNew, BaseAd
|
|
7
7
|
|
|
8
8
|
from xync_client.Abc.Base import DictOfDicts, ListOfDicts
|
|
9
9
|
from xync_client.Abc.BaseTest import BaseTest
|
|
@@ -25,6 +25,17 @@ class TestAgent(BaseTest):
|
|
|
25
25
|
yield clients
|
|
26
26
|
[(await taker.close(), await maker.close()) for taker, maker in clients]
|
|
27
27
|
|
|
28
|
+
# 42
|
|
29
|
+
async def test_ad(self, clients: list[BaseExClient]):
|
|
30
|
+
for client in clients:
|
|
31
|
+
if not self.ad.get(client.ex.id):
|
|
32
|
+
await self.test_ads(clients)
|
|
33
|
+
ad: BaseAd = await client.ad(self.ad[client.ex.id].id)
|
|
34
|
+
ok = isinstance(ad, BaseAd)
|
|
35
|
+
t, _ = await TestEx.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.ad)
|
|
36
|
+
assert t.ok, "No ad"
|
|
37
|
+
logging.info(f"{client.ex.name}: {ExAction.ad.name} - ok")
|
|
38
|
+
|
|
28
39
|
# 0
|
|
29
40
|
async def test_get_orders(self, clients: list[BaseAgentClient]):
|
|
30
41
|
for taker, maker in clients:
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
|
-
from xync_schema.
|
|
4
|
+
from xync_schema.types import Pm, BaseAd, CurE, CoinE
|
|
5
5
|
|
|
6
6
|
from xync_client.Abc.BaseTest import BaseTest
|
|
7
7
|
from xync_schema.enums import ExStatus, ExType, ExAction
|
|
8
8
|
from xync_schema.models import Ex, TestEx as ExTest
|
|
9
9
|
|
|
10
|
-
from xync_client.Abc.Base import BaseClient,
|
|
10
|
+
from xync_client.Abc.Base import BaseClient, MapOfIdsList
|
|
11
11
|
from xync_client.Abc.Ex import BaseExClient
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@pytest.mark.asyncio(loop_scope="session")
|
|
15
15
|
class TestEx(BaseTest):
|
|
16
|
-
|
|
16
|
+
coins: dict[int, dict[str, CoinE]] = {}
|
|
17
|
+
curs: dict[int, dict[str, CurE]] = {}
|
|
18
|
+
ad: dict[int, BaseAd] = {}
|
|
17
19
|
|
|
18
20
|
@pytest.fixture
|
|
19
21
|
async def clients(self) -> list[BaseClient]:
|
|
@@ -26,17 +28,18 @@ class TestEx(BaseTest):
|
|
|
26
28
|
# 19
|
|
27
29
|
async def test_curs(self, clients: list[BaseExClient]):
|
|
28
30
|
for client in clients:
|
|
29
|
-
curs:
|
|
30
|
-
ok = self.
|
|
31
|
+
curs: dict[str, CurE] = await client.curs()
|
|
32
|
+
ok = self.is_dict_of_objects(curs, CurE)
|
|
31
33
|
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.curs)
|
|
32
34
|
assert t.ok, "No curs"
|
|
35
|
+
self.curs[client.ex.id] = curs
|
|
33
36
|
logging.info(f"{client.ex.name}: {ExAction.curs.name} - ok")
|
|
34
37
|
|
|
35
38
|
# 20
|
|
36
39
|
async def test_pms(self, clients: list[BaseExClient]):
|
|
37
40
|
for client in clients:
|
|
38
|
-
pms: dict[int | str,
|
|
39
|
-
ok = self.is_dict_of_objects(pms,
|
|
41
|
+
pms: dict[int | str, Pm] = await client.pms()
|
|
42
|
+
ok = self.is_dict_of_objects(pms, Pm)
|
|
40
43
|
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.pms)
|
|
41
44
|
assert t.ok, "No pms"
|
|
42
45
|
logging.info(f"{client.ex.name}: {ExAction.pms.name} - ok")
|
|
@@ -53,17 +56,18 @@ class TestEx(BaseTest):
|
|
|
53
56
|
# 22
|
|
54
57
|
async def test_coins(self, clients: list[BaseExClient]):
|
|
55
58
|
for client in clients:
|
|
56
|
-
coins:
|
|
57
|
-
ok = self.
|
|
59
|
+
coins: dict[str, CoinE] = await client.coins()
|
|
60
|
+
ok = self.is_dict_of_objects(coins, CoinE)
|
|
58
61
|
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.coins)
|
|
59
62
|
assert t.ok, "No coins"
|
|
63
|
+
self.coins[client.ex.id] = coins
|
|
60
64
|
logging.info(f"{client.ex.name}: {ExAction.coins.name} - ok")
|
|
61
65
|
|
|
62
66
|
# 23
|
|
63
67
|
async def test_pairs(self, clients: list[BaseExClient]):
|
|
64
68
|
for client in clients:
|
|
65
|
-
|
|
66
|
-
ok = self.is_map_of_ids(
|
|
69
|
+
pairs_buy, pairs_sell = await client.pairs()
|
|
70
|
+
ok = self.is_map_of_ids(pairs_buy) and self.is_map_of_ids(pairs_sell)
|
|
67
71
|
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.pairs)
|
|
68
72
|
assert t.ok, "No coins"
|
|
69
73
|
logging.info(f"{client.ex.name}: {ExAction.pairs.name} - ok")
|
|
@@ -71,18 +75,13 @@ class TestEx(BaseTest):
|
|
|
71
75
|
# 24
|
|
72
76
|
async def test_ads(self, clients: list[BaseExClient]):
|
|
73
77
|
for client in clients:
|
|
74
|
-
|
|
78
|
+
self.coins[client.ex.id] = self.coins.get(client.ex.id) or await client.coins()
|
|
79
|
+
self.curs[client.ex.id] = self.curs.get(client.ex.id) or await client.curs()
|
|
80
|
+
coin: int | str = self.coins[client.ex.id]["USDT"].exid
|
|
81
|
+
cur: int | str = self.curs[client.ex.id]["EUR"].exid
|
|
82
|
+
ads: list[BaseAd] = await client.ads(coin, cur, False)
|
|
75
83
|
ok = self.is_list_of_objects(ads, BaseAd)
|
|
76
84
|
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.ads)
|
|
77
85
|
assert t.ok, "No ads"
|
|
78
|
-
self.ad[client.ex.
|
|
86
|
+
self.ad[client.ex.id] = ads[0] # for further use in test_ad
|
|
79
87
|
logging.info(f"{client.ex.name}: {ExAction.ads.name} - ok")
|
|
80
|
-
|
|
81
|
-
# 42
|
|
82
|
-
async def test_ad(self, clients: list[BaseExClient]):
|
|
83
|
-
for client in clients:
|
|
84
|
-
ad: BaseAd = await client.ad(self.ad.get(client.ex.name, (await client.ads("USDT", "RUB", False))[0]).id)
|
|
85
|
-
ok = isinstance(ad, BaseAd)
|
|
86
|
-
t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.ad)
|
|
87
|
-
assert t.ok, "No ad"
|
|
88
|
-
logging.info(f"{client.ex.name}: {ExAction.ad.name} - ok")
|
|
@@ -38,7 +38,7 @@ class PmUnifier:
|
|
|
38
38
|
# "GTB Bank (Guarantee Trust Bank)": "GTBank",
|
|
39
39
|
}
|
|
40
40
|
re_bank = [
|
|
41
|
-
r"^bank (?!of )|
|
|
41
|
+
r"^bank (?!of )|bank$",
|
|
42
42
|
r" banka$",
|
|
43
43
|
r" bankas$",
|
|
44
44
|
r" bankası$",
|
|
@@ -81,14 +81,11 @@ class PmUnifier:
|
|
|
81
81
|
self.cts = countries
|
|
82
82
|
|
|
83
83
|
def countries(self, name: str):
|
|
84
|
-
cmap = {
|
|
85
|
-
"kazakstan": "kazakhstan",
|
|
86
|
-
}
|
|
87
84
|
for ct in self.cts:
|
|
88
85
|
# Если имя кончается на "Название_страны" в скобках
|
|
89
86
|
if (
|
|
90
87
|
ct
|
|
91
|
-
and self.pms[name].norm.endswith((ct + ")",
|
|
88
|
+
and self.pms[name].norm.endswith((ct + ")", ct))
|
|
92
89
|
and not self.pms[name].norm.endswith((" of " + ct, " of the " + ct, " and " + ct, " de " + ct))
|
|
93
90
|
):
|
|
94
91
|
self.pms[name].norm = self.pms[name].norm.replace(ct, "")
|
|
@@ -130,7 +127,7 @@ class PmUnifier:
|
|
|
130
127
|
).upper()
|
|
131
128
|
if len(acr) >= 2 and (
|
|
132
129
|
f"({acr})" in self.pms[name].norm
|
|
133
|
-
or self.pms[name].norm.startswith(acr + " ")
|
|
130
|
+
or self.pms[name].norm.startswith((acr + " ", acr + ":"))
|
|
134
131
|
or self.pms[name].norm.endswith(" " + acr)
|
|
135
132
|
):
|
|
136
133
|
self.pms[name].norm = self.pms[name].norm.replace(acr, "", 1).replace("()", "", 1).strip()
|
|
@@ -146,7 +143,7 @@ class PmUnifier:
|
|
|
146
143
|
self.pms[name].norm = self.pms[name].norm.replace(src, trgt)
|
|
147
144
|
|
|
148
145
|
def clear(self, name: str):
|
|
149
|
-
self.pms[name].norm = self.pms[name].norm.replace("()", "").replace(" ", " ").strip("
|
|
146
|
+
self.pms[name].norm = self.pms[name].norm.replace("()", "").replace(" ", " ").strip(" -:")
|
|
150
147
|
|
|
151
148
|
def __call__(self, s: str) -> PmUni:
|
|
152
149
|
# если в словаре замен есть текущее назвние - меняем, иначе берем строку до запятой
|
|
@@ -179,7 +176,7 @@ class BaseExClient(BaseClient):
|
|
|
179
176
|
|
|
180
177
|
# 19: Список поддерживаемых валют тейкера
|
|
181
178
|
@abstractmethod
|
|
182
|
-
async def curs(self) ->
|
|
179
|
+
async def curs(self) -> dict[str, types.CurE]: # {cur.ticker: cur}
|
|
183
180
|
...
|
|
184
181
|
|
|
185
182
|
# 20: Список платежных методов
|
|
@@ -194,12 +191,12 @@ class BaseExClient(BaseClient):
|
|
|
194
191
|
|
|
195
192
|
# 22: Список торгуемых монет (с ограничениям по валютам, если есть)
|
|
196
193
|
@abstractmethod
|
|
197
|
-
async def coins(self) ->
|
|
194
|
+
async def coins(self) -> dict[str, types.CoinE]: # {coin.ticker: coin}
|
|
198
195
|
...
|
|
199
196
|
|
|
200
197
|
# 23: Список пар валюта/монет
|
|
201
198
|
@abstractmethod
|
|
202
|
-
async def pairs(self) -> MapOfIdsList: ...
|
|
199
|
+
async def pairs(self) -> tuple[MapOfIdsList, MapOfIdsList]: ...
|
|
203
200
|
|
|
204
201
|
# 24: Список объяв по (buy/sell, cur, coin, pm)
|
|
205
202
|
@abstractmethod
|
|
@@ -217,20 +214,18 @@ class BaseExClient(BaseClient):
|
|
|
217
214
|
async def ad_epyd2pydin(self, ad: types.BaseAd) -> types.BaseAdIn: ... # my_uid: for MyAd
|
|
218
215
|
|
|
219
216
|
# 99: Страны
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
async def countries(self) -> list[Struct]:
|
|
218
|
+
return []
|
|
222
219
|
|
|
223
220
|
# Импорт Pm-ов (с Pmcur-, Pmex- и Pmcurex-ами) и валют (с Curex-ами) с биржи в бд
|
|
224
221
|
async def set_pmcurexs(self):
|
|
225
222
|
# Curs
|
|
226
|
-
cur_pyds:
|
|
223
|
+
cur_pyds: dict[str, types.CurE] = await self.curs()
|
|
227
224
|
curs: dict[int | str, models.Cur] = {
|
|
228
|
-
cur_pyd.exid: (
|
|
229
|
-
|
|
230
|
-
)[0]
|
|
231
|
-
for cur_pyd in cur_pyds
|
|
225
|
+
cur_pyd.exid: (await models.Cur.update_or_create({"rate": cur_pyd.rate}, ticker=tkr))[0]
|
|
226
|
+
for tkr, cur_pyd in cur_pyds.items()
|
|
232
227
|
}
|
|
233
|
-
curexs
|
|
228
|
+
curexs = [models.Curex(**c.model_dump(), cur=curs[c.exid], ex=self.ex) for c in cur_pyds.values()]
|
|
234
229
|
# Curex
|
|
235
230
|
await models.Curex.bulk_create(
|
|
236
231
|
curexs, update_fields=["minimum", "rounding_scale"], on_conflict=["cur_id", "ex_id"]
|
|
@@ -288,10 +283,11 @@ class BaseExClient(BaseClient):
|
|
|
288
283
|
uni = PmUnifier(cntrs)
|
|
289
284
|
for k, pm in pms_epyds.items():
|
|
290
285
|
pmu: PmUni = uni(pm.name)
|
|
286
|
+
country = await models.Country.get(name__iexact=cnt) if (cnt := pmu.country) else None
|
|
291
287
|
if prev[2] == pm.name and pmu.country == prev[3]: # оригинальное имя не уникально на этой бирже
|
|
292
288
|
logging.warning(f"Pm: '{pm.name}' duplicated with ids {prev[0]}: {k} on {self.ex.name}")
|
|
293
289
|
# новый Pm не добавляем, а берем старый с этим названием
|
|
294
|
-
pm_ = pms.get(prev[0], await models.Pm.get_or_none(norm=prev[1]))
|
|
290
|
+
pm_ = pms.get(prev[0], await models.Pm.get_or_none(norm=prev[1], country=country))
|
|
295
291
|
# и добавляем Pmex для него
|
|
296
292
|
await models.Pmex.update_or_create({"name": pm.name}, ex=self.ex, exid=k, pm=pm_)
|
|
297
293
|
elif (
|
|
@@ -302,19 +298,16 @@ class BaseExClient(BaseClient):
|
|
|
302
298
|
)
|
|
303
299
|
# новый Pm не добавляем, только Pmex для него
|
|
304
300
|
# новый Pm не добавляем, а берем старый с этим названием
|
|
305
|
-
pm_ = pms.get(prev[0], await models.Pm.get_or_none(norm=prev[1]))
|
|
301
|
+
pm_ = pms.get(prev[0], await models.Pm.get_or_none(norm=prev[1], country=country))
|
|
306
302
|
# и добавляем.обновляем Pmex для него
|
|
307
303
|
await models.Pmex.update_or_create({"pm": pm_}, ex=self.ex, exid=k, name=pm.name)
|
|
308
304
|
else:
|
|
309
305
|
# todo: add logo and all other
|
|
310
|
-
d = pmu.df_unq()
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
"type_": pm.type_,
|
|
316
|
-
}
|
|
317
|
-
)
|
|
306
|
+
d = {**pmu.df_unq(), "country": country}
|
|
307
|
+
if pm.logo:
|
|
308
|
+
d["defaults"]["logo"] = pm.logo
|
|
309
|
+
if pm.type_:
|
|
310
|
+
d["defaults"]["type_"] = pm.type_
|
|
318
311
|
try:
|
|
319
312
|
pms[k], _ = await models.Pm.update_or_create(**d)
|
|
320
313
|
except (MultipleObjectsReturned, IntegrityError) as e:
|
|
@@ -350,12 +343,12 @@ class BaseExClient(BaseClient):
|
|
|
350
343
|
|
|
351
344
|
# Импорт монет (с Coinex-ами) с биржи в бд
|
|
352
345
|
async def set_coinexs(self):
|
|
353
|
-
coins:
|
|
346
|
+
coins: dict[str, types.CoinE] = await self.coins()
|
|
354
347
|
coins_db: dict[int, models.Coin] = {
|
|
355
|
-
c.exid: (await models.Coin.update_or_create(ticker=c.ticker))[0] for c in coins
|
|
348
|
+
c.exid: (await models.Coin.update_or_create(ticker=c.ticker))[0] for c in coins.values()
|
|
356
349
|
}
|
|
357
350
|
coinexs: list[models.Coinex] = [
|
|
358
|
-
models.Coinex(coin=coins_db[c.exid], ex=self.ex, exid=c.exid, minimum=c.minimum) for c in coins
|
|
351
|
+
models.Coinex(coin=coins_db[c.exid], ex=self.ex, exid=c.exid, minimum=c.minimum) for c in coins.values()
|
|
359
352
|
]
|
|
360
353
|
await models.Coinex.bulk_create(coinexs, update_fields=["minimum"], on_conflict=["coin_id", "ex_id"])
|
|
361
354
|
|
|
@@ -83,8 +83,9 @@ class Private(BaseAgentClient):
|
|
|
83
83
|
async def ads_switch(self) -> bool:
|
|
84
84
|
pass
|
|
85
85
|
|
|
86
|
-
async def get_user(self, user_id) -> dict:
|
|
87
|
-
|
|
86
|
+
async def get_user(self, user_id: int) -> dict:
|
|
87
|
+
user = (await self._get(f"/-/x/otc/v1/user/{user_id}/info"))["data"]
|
|
88
|
+
return user
|
|
88
89
|
|
|
89
90
|
async def send_user_msg(self, msg: str, file=None) -> bool:
|
|
90
91
|
pass
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Literal
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
|
+
from xync_schema.types import BaseAd
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class TradeRule(BaseModel):
|
|
@@ -56,7 +57,7 @@ class PayName(BaseModel):
|
|
|
56
57
|
id: int
|
|
57
58
|
|
|
58
59
|
|
|
59
|
-
class Resp(
|
|
60
|
+
class Resp(BaseAd):
|
|
60
61
|
blockType: int
|
|
61
62
|
chargeType: bool
|
|
62
63
|
coinId: int
|
|
@@ -71,12 +72,12 @@ class Resp(BaseModel):
|
|
|
71
72
|
labelName: str | None = None
|
|
72
73
|
maxTradeLimit: str
|
|
73
74
|
merchantLevel: int
|
|
74
|
-
merchantTags: str | None
|
|
75
|
+
merchantTags: list[str] | None
|
|
75
76
|
minTradeLimit: str
|
|
76
77
|
orderCompleteRate: str
|
|
77
78
|
payMethod: str
|
|
78
79
|
payMethods: list[PayMethod]
|
|
79
|
-
payName: list[PayName] # приходит массив объектов внутри строки
|
|
80
|
+
payName: str # list[PayName] # приходит массив объектов внутри строки
|
|
80
81
|
payTerm: int
|
|
81
82
|
price: str
|
|
82
83
|
seaViewRoom: str | None = None
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from asyncio import run
|
|
2
|
+
|
|
3
|
+
from msgspec import convert
|
|
4
|
+
from x_model import init_db
|
|
5
|
+
from xync_schema import models, types
|
|
6
|
+
from xync_schema.models import Ex, Cur
|
|
7
|
+
from xync_schema.enums import PmType
|
|
8
|
+
|
|
9
|
+
from xync_client.Abc.Base import MapOfIdsList
|
|
10
|
+
from xync_client.Abc.Ex import BaseExClient
|
|
11
|
+
from xync_client.Htx.etype import pm, Country, ad
|
|
12
|
+
from xync_client.loader import PG_DSN
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ExClient(BaseExClient):
|
|
16
|
+
def pm_type_map(self, type_: models.Pmex) -> str:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
async def pairs(self) -> tuple[MapOfIdsList, MapOfIdsList]:
|
|
20
|
+
self.session.headers["client-type"] = "web"
|
|
21
|
+
reb = (await self._get("/-/x/otc/v1/trade/fast/config/list?side=buy&tradeMode=c2c_simple"))["data"]
|
|
22
|
+
res = (await self._get("/-/x/otc/v1/trade/fast/config/list?side=sell&tradeMode=c2c_simple"))["data"]
|
|
23
|
+
coins = await self.coins()
|
|
24
|
+
curs = await self.curs()
|
|
25
|
+
b = {
|
|
26
|
+
cur.exid: cns
|
|
27
|
+
for tkr, cur in curs.items()
|
|
28
|
+
if (
|
|
29
|
+
cns := set(
|
|
30
|
+
coins[c["cryptoAsset"]["name"]].exid for c in reb if tkr in [q["name"] for q in c["quoteAsset"]]
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
s = {
|
|
35
|
+
cur.exid: cns
|
|
36
|
+
for tkr, cur in curs.items()
|
|
37
|
+
if (
|
|
38
|
+
cns := set(
|
|
39
|
+
coins[c["cryptoAsset"]["name"]].exid for c in res if tkr in [q["name"] for q in c["quoteAsset"]]
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
return b, s
|
|
44
|
+
|
|
45
|
+
async def ads(
|
|
46
|
+
self, coin_exid: int, cur_exid: int, is_sell: bool, pm_exids: list[str] = None, amount: int = None
|
|
47
|
+
) -> list[types.BaseAd]:
|
|
48
|
+
params = {
|
|
49
|
+
"coinId": coin_exid,
|
|
50
|
+
"currency": cur_exid,
|
|
51
|
+
"tradeType": "sell" if is_sell else "buy",
|
|
52
|
+
"currPage": 1,
|
|
53
|
+
"payMethod": ",".join(pm_exids) if pm_exids else 0,
|
|
54
|
+
"acceptOrder": 0,
|
|
55
|
+
"blockType": "general",
|
|
56
|
+
"online": 1,
|
|
57
|
+
"range": 0,
|
|
58
|
+
"amount": amount or "",
|
|
59
|
+
"onlyTradable": "false",
|
|
60
|
+
"isFollowed": "false",
|
|
61
|
+
}
|
|
62
|
+
res = (await self._get("/-/x/otc/v1/data/trade-market", params))["data"]
|
|
63
|
+
ads = [ad.Resp(**a) for a in res]
|
|
64
|
+
return ads
|
|
65
|
+
|
|
66
|
+
async def ad(self, ad_id: int) -> types.BaseAd:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
# 20: Get all pms
|
|
70
|
+
async def pms(self, _cur: Cur = None) -> dict[int, types.Pm]:
|
|
71
|
+
dist = {
|
|
72
|
+
0: PmType.card,
|
|
73
|
+
1: PmType.bank,
|
|
74
|
+
2: PmType.cash,
|
|
75
|
+
3: PmType.emoney,
|
|
76
|
+
4: PmType.emoney,
|
|
77
|
+
5: PmType.IFSC,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
pms: list[pm.Resp] = [convert(p, pm.Resp) for p in (await self._coin_curs_pms())["payMethod"]]
|
|
81
|
+
|
|
82
|
+
pmsd = {
|
|
83
|
+
p.payMethodId: types.Pm(
|
|
84
|
+
name=p.name,
|
|
85
|
+
type_=dist.get(p.template),
|
|
86
|
+
logo=p.bankImage or p.bankImageWeb,
|
|
87
|
+
)
|
|
88
|
+
for p in pms
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return pmsd
|
|
92
|
+
|
|
93
|
+
# 21: Get all: currency,pay,allCountry,coin
|
|
94
|
+
async def curs(self) -> dict[str, types.CurE]:
|
|
95
|
+
self.session.headers["client-type"] = "web"
|
|
96
|
+
curs: list[dict] = (await self._coin_curs_pms())["currency"]
|
|
97
|
+
cmap: dict[str, int] = {c["nameShort"]: c["currencyId"] for c in curs}
|
|
98
|
+
res = (await self._get("/-/x/otc/v1/trade/fast/config/list?side=sell&tradeMode=c2c_simple"))["data"]
|
|
99
|
+
cursd: dict[str, float] = {}
|
|
100
|
+
for c in res:
|
|
101
|
+
for q in c["quoteAsset"]:
|
|
102
|
+
cursd[q["name"]] = max(cursd.get(q["name"], 0), float(q["minAmount"]))
|
|
103
|
+
return {tkr: types.CurE(exid=exid, ticker=tkr, minimum=cursd.get(tkr)) for tkr, exid in cmap.items()}
|
|
104
|
+
|
|
105
|
+
# 22: Список платежных методов по каждой валюте
|
|
106
|
+
async def cur_pms_map(self) -> dict[int, set[int]]:
|
|
107
|
+
res = await self._coin_curs_pms()
|
|
108
|
+
wrong_pms = {4, 34, 498, 548, 20009, 20010} # , 212, 239, 363 # these ids not exist in pms
|
|
109
|
+
return {c["currencyId"]: set(c["supportPayments"]) - wrong_pms for c in res["currency"] if c["supportPayments"]}
|
|
110
|
+
|
|
111
|
+
# 23: Список торгуемых монет
|
|
112
|
+
async def coins(self) -> dict[str, types.CoinE]:
|
|
113
|
+
self.session.headers["client-type"] = "web"
|
|
114
|
+
coins: list[dict] = (await self._coin_curs_pms())["coin"]
|
|
115
|
+
cmap: dict[str, int] = {c["coinCode"]: c["coinId"] for c in coins}
|
|
116
|
+
res = (await self._get("/-/x/otc/v1/trade/fast/config/list?side=buy&tradeMode=c2c_simple"))["data"]
|
|
117
|
+
coinsl: list[str] = [c["cryptoAsset"]["name"] for c in res]
|
|
118
|
+
return {tkr: types.CoinE(exid=cid, ticker=tkr, p2p=tkr in coinsl) for tkr, cid in cmap.items()}
|
|
119
|
+
|
|
120
|
+
# 99: Страны
|
|
121
|
+
async def countries(self) -> list[Country]:
|
|
122
|
+
cmap = {
|
|
123
|
+
"Kazakstan": "Kazakhstan",
|
|
124
|
+
}
|
|
125
|
+
res = await self._coin_curs_pms()
|
|
126
|
+
cts = [
|
|
127
|
+
Country(
|
|
128
|
+
id=c["countryId"],
|
|
129
|
+
code=c["code"],
|
|
130
|
+
name=cmap.get(ct := name[:-1] if (name := c["name"].split(",")[0]).endswith(".") else name, ct),
|
|
131
|
+
short=c["appShort"],
|
|
132
|
+
cur_id=c["currencyId"],
|
|
133
|
+
)
|
|
134
|
+
for c in res["country"]
|
|
135
|
+
]
|
|
136
|
+
return cts
|
|
137
|
+
|
|
138
|
+
# Get all: currency,pay,allCountry,coin
|
|
139
|
+
async def _coin_curs_pms(self) -> (dict, dict, dict, dict):
|
|
140
|
+
res = (await self._get("/-/x/otc/v1/data/config-list?type=currency,pay,coin,allCountry"))["data"]
|
|
141
|
+
res["currency"][0]["currencyId"] = 1
|
|
142
|
+
[c.update({"currencyId": 1, "name": ""}) for c in res["country"] if c["currencyId"] == 172]
|
|
143
|
+
return res
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
async def main():
|
|
147
|
+
_ = await init_db(PG_DSN, models, True)
|
|
148
|
+
ex = await Ex.get(name="Htx")
|
|
149
|
+
cl = ExClient(ex)
|
|
150
|
+
await cl.pairs()
|
|
151
|
+
await cl.set_pmcurexs()
|
|
152
|
+
await cl.set_coinexs()
|
|
153
|
+
await cl.close()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
if __name__ == "__main__":
|
|
157
|
+
run(main())
|
|
@@ -32,17 +32,17 @@ class ExClient(BaseExClient, AuthClient):
|
|
|
32
32
|
return settings["data"]
|
|
33
33
|
|
|
34
34
|
# 19: Список поддерживаемых валют тейкера
|
|
35
|
-
async def curs(self) ->
|
|
35
|
+
async def curs(self) -> dict[str, types.CurE]:
|
|
36
36
|
coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
|
|
37
37
|
stg = await self._settings()
|
|
38
38
|
roundings: dict[str, int] = stg["offerSettings"]["roundingScaleByFiatCurrency"]
|
|
39
39
|
minimums: dict[str, str] = stg["offerSettings"]["minOrderAmountByCurrencyCode"]
|
|
40
|
-
return
|
|
41
|
-
types.CurE(
|
|
40
|
+
return {
|
|
41
|
+
c["code"]: types.CurE(
|
|
42
42
|
exid=c["code"], ticker=c["code"], rounding_scale=roundings.get(c["code"]), minimum=minimums[c["code"]]
|
|
43
43
|
)
|
|
44
44
|
for c in coins_curs["data"]["fiat"]
|
|
45
|
-
|
|
45
|
+
}
|
|
46
46
|
|
|
47
47
|
async def _pms(self, cur: str) -> dict[str, PmEpydRoot]:
|
|
48
48
|
pms = await self._post("/p2p/public-api/v3/payment-details/get-methods/by-currency-code", {"currencyCode": cur})
|
|
@@ -54,7 +54,7 @@ class ExClient(BaseExClient, AuthClient):
|
|
|
54
54
|
if cur:
|
|
55
55
|
pms = await self._pms(cur)
|
|
56
56
|
else:
|
|
57
|
-
for cur in await self.curs():
|
|
57
|
+
for cur in (await self.curs()).values():
|
|
58
58
|
pms |= await self._pms(cur.exid)
|
|
59
59
|
return {
|
|
60
60
|
k: types.Pm(
|
|
@@ -67,25 +67,25 @@ class ExClient(BaseExClient, AuthClient):
|
|
|
67
67
|
|
|
68
68
|
# 21: Список платежных методов по каждой валюте
|
|
69
69
|
async def cur_pms_map(self) -> MapOfIdsList:
|
|
70
|
-
return {cur.exid: list(await self._pms(cur.exid)) for cur in await self.curs()}
|
|
70
|
+
return {cur.exid: list(await self._pms(cur.exid)) for cur in (await self.curs()).values()}
|
|
71
71
|
|
|
72
72
|
# 22: Список торгуемых монет (с ограничениям по валютам, если есть)
|
|
73
|
-
async def coins(self) ->
|
|
73
|
+
async def coins(self) -> dict[str, types.CoinE]:
|
|
74
74
|
coins_curs = await self._post("/p2p/public-api/v2/currency/all-supported")
|
|
75
75
|
stg = await self._settings()
|
|
76
76
|
lims = list(stg["offerSettings"]["offerVolumeLimitsPerMarket"].values())
|
|
77
77
|
coins = {k: max(float(v[k]["minInclusive"]) for v in lims) for k, v in lims[0].items()}
|
|
78
|
-
return
|
|
79
|
-
types.CoinE(exid=c["code"], ticker=c["code"], minimum=coins[c["code"]])
|
|
78
|
+
return {
|
|
79
|
+
c["code"]: types.CoinE(exid=c["code"], ticker=c["code"], minimum=coins[c["code"]])
|
|
80
80
|
for c in coins_curs["data"]["crypto"]
|
|
81
|
-
|
|
81
|
+
}
|
|
82
82
|
|
|
83
83
|
# 23: Список пар валюта/монет
|
|
84
|
-
async def pairs(self) -> MapOfIdsList:
|
|
84
|
+
async def pairs(self) -> tuple[MapOfIdsList, MapOfIdsList]:
|
|
85
85
|
coins = await self.coins()
|
|
86
86
|
curs = await self.curs()
|
|
87
|
-
pairs = {cur.exid: set(c.exid for c in coins) for cur in curs}
|
|
88
|
-
return pairs
|
|
87
|
+
pairs = {cur.exid: set(c.exid for c in coins.values()) for cur in curs.values()}
|
|
88
|
+
return pairs, pairs
|
|
89
89
|
|
|
90
90
|
# 42: Чужая объява по id
|
|
91
91
|
async def ad(self, ad_id: int) -> _TakerOne:
|
|
@@ -126,9 +126,10 @@ class ExClient(BaseExClient, AuthClient):
|
|
|
126
126
|
|
|
127
127
|
async def ad_taker_epyd2pydin(self, ad: _TakerOne) -> types.AdBuyIn:
|
|
128
128
|
adx: types.BaseAdIn = await self.ad_common_epyd2pydin(ad)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
act_unq = dict(ex=self.ex, exid=ad.user.userId)
|
|
130
|
+
if not (actor := await models.Actor.get_or_none(**act_unq)):
|
|
131
|
+
actor = await models.Actor.create(**act_unq, name=ad.user.nickname, person=await models.Person.create())
|
|
132
|
+
adx.maker = actor
|
|
132
133
|
pms = ad.paymentMethods if isinstance(ad, _PmsTrait) else [pd.paymentMethod for pd in ad.paymentDetails]
|
|
133
134
|
return types.AdBuyIn(
|
|
134
135
|
**adx.model_dump(), pms_=await models.Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=[p.code for p in pms])
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
from asyncio import run
|
|
2
|
-
|
|
3
|
-
from msgspec import convert
|
|
4
|
-
from x_model import init_db
|
|
5
|
-
from xync_schema import models, types
|
|
6
|
-
from xync_schema.models import Ex, Cur
|
|
7
|
-
from xync_schema.enums import PmType
|
|
8
|
-
|
|
9
|
-
from xync_client.Abc.Ex import BaseExClient
|
|
10
|
-
from xync_client.Htx.etype import pm, Country
|
|
11
|
-
from xync_client.loader import PG_DSN
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class ExClient(BaseExClient):
|
|
15
|
-
# 20: Get all pms
|
|
16
|
-
async def pms(self, _cur: Cur = None) -> dict[int, types.Pm]:
|
|
17
|
-
dist = {
|
|
18
|
-
0: PmType.card,
|
|
19
|
-
1: PmType.bank,
|
|
20
|
-
2: PmType.cash,
|
|
21
|
-
3: PmType.emoney,
|
|
22
|
-
4: PmType.emoney,
|
|
23
|
-
5: PmType.IFSC,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pms: list[pm.Resp] = [convert(p, pm.Resp) for p in (await self._coin_curs_pms())["payMethod"]]
|
|
27
|
-
|
|
28
|
-
pmsd = {
|
|
29
|
-
p.payMethodId: types.Pm(
|
|
30
|
-
name=p.name,
|
|
31
|
-
type_=dist.get(p.template),
|
|
32
|
-
logo=p.bankImage or p.bankImageWeb,
|
|
33
|
-
)
|
|
34
|
-
for p in pms
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return pmsd
|
|
38
|
-
|
|
39
|
-
# 21: Get all: currency,pay,allCountry,coin
|
|
40
|
-
async def curs(self) -> list[types.CurE]:
|
|
41
|
-
res = (await self._coin_curs_pms())["currency"]
|
|
42
|
-
return [
|
|
43
|
-
types.CurE(exid=c["currencyId"], ticker=c["nameShort"]) for c in res
|
|
44
|
-
] # if c['showPtoP'] todo: wht "showPtoP" is means
|
|
45
|
-
|
|
46
|
-
# 22: Список платежных методов по каждой валюте
|
|
47
|
-
async def cur_pms_map(self) -> dict[int, set[int]]:
|
|
48
|
-
res = await self._coin_curs_pms()
|
|
49
|
-
wrong_pms = {4, 34, 498, 548, 20009, 20010} # , 212, 239, 363 # these ids not exist in pms
|
|
50
|
-
return {c["currencyId"]: set(c["supportPayments"]) - wrong_pms for c in res["currency"] if c["supportPayments"]}
|
|
51
|
-
|
|
52
|
-
# 23: Список торгуемых монет
|
|
53
|
-
async def coins(self) -> list[types.CoinE]:
|
|
54
|
-
coins: list[dict] = (await self._coin_curs_pms())["coin"]
|
|
55
|
-
return [types.CoinE(exid=c["coinId"], ticker=c["coinCode"]) for c in coins if c["coinType"] == 2]
|
|
56
|
-
|
|
57
|
-
# 99: Страны
|
|
58
|
-
async def countries(self) -> list[Country]:
|
|
59
|
-
res = await self._coin_curs_pms()
|
|
60
|
-
cts = [
|
|
61
|
-
Country(
|
|
62
|
-
id=c["countryId"],
|
|
63
|
-
code=c["code"],
|
|
64
|
-
name=name[:-1] if (name := c["name"].split(",")[0]).endswith(".") else name,
|
|
65
|
-
short=c["appShort"],
|
|
66
|
-
cur_id=c["currencyId"],
|
|
67
|
-
)
|
|
68
|
-
for c in res["country"]
|
|
69
|
-
]
|
|
70
|
-
return cts
|
|
71
|
-
|
|
72
|
-
# Get all: currency,pay,allCountry,coin
|
|
73
|
-
async def _coin_curs_pms(self) -> (dict, dict, dict, dict):
|
|
74
|
-
res = (await self._get("/-/x/otc/v1/data/config-list?type=currency,pay,coin,allCountry"))["data"]
|
|
75
|
-
res["currency"][0]["currencyId"] = 1
|
|
76
|
-
[c.update({"currencyId": 1, "name": ""}) for c in res["country"] if c["currencyId"] == 172]
|
|
77
|
-
return res
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
async def main():
|
|
81
|
-
_ = await init_db(PG_DSN, models, True)
|
|
82
|
-
ex = await Ex.get(name="Htx")
|
|
83
|
-
cl = ExClient(ex)
|
|
84
|
-
await cl.set_pmcurexs()
|
|
85
|
-
await cl.set_coinexs()
|
|
86
|
-
await cl.close()
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if __name__ == "__main__":
|
|
90
|
-
run(main())
|
|
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.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Binance/test_binance.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Bybit/test_bybit.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Bybit/test_bybit_p2p.py
RENAMED
|
File without changes
|
|
File without changes
|
{xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Htx/test_htx_p2p.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev40 → xync_client-0.0.25.dev41}/tests/_todo_refact/Wallet/test_agent.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
|
|
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.25.dev40 → xync_client-0.0.25.dev41}/xync_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|