xync-client 0.0.25.dev105__tar.gz → 0.0.25.dev110__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.dev105 → xync_client-0.0.25.dev110}/.env.sample +1 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/.gitignore +2 -1
- {xync_client-0.0.25.dev105/xync_client.egg-info → xync_client-0.0.25.dev110}/PKG-INFO +1 -1
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/Agent.py +21 -24
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/AuthTrait.py +3 -2
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/Ex.py +20 -23
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/types.py +4 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/etype/ad.py +4 -1
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Gate/ex.py +8 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Okx/ex.py +8 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/agent.py +79 -71
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/auth.py +3 -1
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/pyd.py +8 -2
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110/xync_client.egg-info}/PKG-INFO +1 -1
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client.egg-info/SOURCES.txt +0 -1
- xync_client-0.0.25.dev105/tests/res.js +0 -26953
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/.pre-commit-config.yaml +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/README.md +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/makefile +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/pyproject.toml +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/setup.cfg +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/TestAgent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/TestAsset.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/TestEx.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/TestOrder.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Binance/test_binance.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Gate/test_gate.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Wallet/test_agent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/Wallet/test_ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/tests/_todo_refact/_test_ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/Asset.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/Base.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/BaseTest.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/InAgent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Abc/Order.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/binance_async.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/earn_api.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/exceptions.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/sapi.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Binance/web_c2c.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/agent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/base.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/req.mjs +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BingX/sign.js +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitGet/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitGet/agent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitGet/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitGet/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitGet/req.mjs +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/BitPapa/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Bybit/agent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Bybit/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Bybit/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Bybit/web_earn.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Bybit/web_p2p.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Gate/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Gate/premarket.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/agent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/earn.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/etype/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/etype/cred.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Htx/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/KuCoin/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/KuCoin/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/KuCoin/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/KuCoin/web.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Mexc/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Mexc/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Mexc/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Okx/etype/ad.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/Okx/etype/pm.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/asset.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/ex.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/inAgent.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/order.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/pyro.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/TgWallet/web.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/__init__.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/loader.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client/pm_unifier.py +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client.egg-info/dependency_links.txt +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client.egg-info/requires.txt +0 -0
- {xync_client-0.0.25.dev105 → xync_client-0.0.25.dev110}/xync_client.egg-info/top_level.txt +0 -0
|
@@ -2,11 +2,12 @@ from abc import abstractmethod
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
from xync_schema import models
|
|
5
|
-
from xync_schema.models import OrderStatus, Coin, Cur, Ad, AdStatus, Agent, Cred
|
|
5
|
+
from xync_schema.models import OrderStatus, Coin, Cur, Ad, AdStatus, Agent, Cred
|
|
6
6
|
from xync_schema.types import BaseAd, AdSaleIn, AdBuyIn, BaseOrder
|
|
7
7
|
|
|
8
8
|
from xync_client.Abc.Ex import BaseExClient
|
|
9
9
|
from xync_client.Abc.Base import BaseClient
|
|
10
|
+
from xync_client.Abc.types import CredExOut
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class BaseAgentClient(BaseClient):
|
|
@@ -48,24 +49,24 @@ class BaseAgentClient(BaseClient):
|
|
|
48
49
|
|
|
49
50
|
# 25: Список реквизитов моих платежных методов
|
|
50
51
|
@abstractmethod
|
|
51
|
-
async def creds(self) -> list: ... # {
|
|
52
|
+
async def creds(self) -> list: ... # {credex.exid: {cred}}
|
|
52
53
|
|
|
53
54
|
# Создание реквизита на бирже
|
|
54
|
-
async def
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
async def cred_new(self, cred: models.Cred) -> CredExOut: ...
|
|
56
|
+
|
|
57
|
+
# await models.Actor.get_or_create({"name": cred.exid}, ex=self.ex_client.ex, exid=self.agent.actor.exid)
|
|
58
|
+
# cred_db: Cred = (await self.cred_pyd2db(cred, self.agent.user_id))[0]
|
|
59
|
+
# if not (credex := models.CredEx.get_or_none(cred=cred_db, ex=self.agent.ex)):
|
|
60
|
+
# credex, _ = models.CredEx.update_or_create({}, cred=cred_db, ex=self.agent.ex)
|
|
61
|
+
# return credex
|
|
61
62
|
|
|
62
63
|
# 27: Редактирование реквизита моего платежного метода
|
|
63
64
|
@abstractmethod
|
|
64
|
-
async def
|
|
65
|
+
async def cred_upd(self, cred: models.Cred, exid: int) -> CredExOut: ...
|
|
65
66
|
|
|
66
67
|
# 28: Удаление реквизита моего платежного метода
|
|
67
68
|
@abstractmethod
|
|
68
|
-
async def
|
|
69
|
+
async def cred_del(self, exid: int) -> int: ...
|
|
69
70
|
|
|
70
71
|
# # # Ad
|
|
71
72
|
# 29: Список моих объявлений
|
|
@@ -82,7 +83,7 @@ class BaseAgentClient(BaseClient):
|
|
|
82
83
|
self,
|
|
83
84
|
offer_id: int,
|
|
84
85
|
amount: int,
|
|
85
|
-
|
|
86
|
+
creds: list[Cred] = None,
|
|
86
87
|
price: float = None,
|
|
87
88
|
is_float: bool = None,
|
|
88
89
|
min_fiat: int = None,
|
|
@@ -130,15 +131,11 @@ class BaseAgentClient(BaseClient):
|
|
|
130
131
|
await ad_db.creds.add(*getattr(ad_pydin, "creds_", []))
|
|
131
132
|
return ad_db
|
|
132
133
|
|
|
133
|
-
@staticmethod
|
|
134
|
-
async def
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
@staticmethod
|
|
142
|
-
async def fiat_cred2db(cred: Cred) -> Cred:
|
|
143
|
-
fiat, _ = await Cred.get_or_create(cred=cred)
|
|
144
|
-
return fiat
|
|
134
|
+
# @staticmethod
|
|
135
|
+
# async def cred_e2db(cred_in: BaseUpd, banks: list[str] = None) -> bool:
|
|
136
|
+
# cred_db, _ = await models.Cred.update_or_create(**cred_in.df_unq())
|
|
137
|
+
# credex_in = models.CredEx.validate({"exid": cred_in.id, "cred_id": cred_db.id})
|
|
138
|
+
# credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
|
|
139
|
+
# if banks: # only for SBP
|
|
140
|
+
# await cred_db.banks.add(*[await PmexBank.get(exid=b) for b in banks])
|
|
141
|
+
# return True
|
|
@@ -18,10 +18,11 @@ class BaseAuthTrait(Client):
|
|
|
18
18
|
# noinspection PyUnresolvedReferences
|
|
19
19
|
self.session.headers.update(auth_hdrs)
|
|
20
20
|
|
|
21
|
-
async def _post(self, url: str, data: dict = None, data_key: str = None):
|
|
21
|
+
async def _post(self, url: str, data: dict = None, data_key: str = None, headers: dict = None):
|
|
22
22
|
dt = {"json" if isinstance(data, dict) else "data": data}
|
|
23
23
|
# noinspection PyUnresolvedReferences
|
|
24
|
-
|
|
24
|
+
hdrs = {**self._prehook(data), **(headers or {})}
|
|
25
|
+
resp = await self.session.post(url, **dt, headers=hdrs)
|
|
25
26
|
return await self._proc(resp, data_key, data)
|
|
26
27
|
|
|
27
28
|
async def _proc(self, resp: ClientResponse, data_key: str = None, body: dict | str = None) -> dict | str:
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from abc import abstractmethod
|
|
3
|
-
from asyncio import sleep
|
|
4
3
|
|
|
5
4
|
import msgspec
|
|
6
|
-
from aiohttp import ClientSession
|
|
7
5
|
from msgspec import Struct
|
|
8
6
|
from tortoise.exceptions import MultipleObjectsReturned, IntegrityError
|
|
9
7
|
from xync_schema import models
|
|
10
|
-
from xync_schema.enums import FileType
|
|
11
8
|
from xync_schema.types import CurEx, CoinEx, BaseAd, BaseAdIn
|
|
12
9
|
|
|
13
10
|
from xync_client.Abc.Base import BaseClient, MapOfIdsList
|
|
@@ -69,7 +66,7 @@ class BaseExClient(BaseClient):
|
|
|
69
66
|
|
|
70
67
|
# Импорт Pm-ов (с Pmcur-, Pmex- и Pmcurex-ами) и валют (с Curex-ами) с биржи в бд
|
|
71
68
|
async def set_pmcurexs(self):
|
|
72
|
-
|
|
69
|
+
PyroClient(bot)
|
|
73
70
|
# Curs
|
|
74
71
|
cur_pyds: dict[str, CurEx] = await self.curs()
|
|
75
72
|
curs: dict[int | str, models.Cur] = {
|
|
@@ -157,25 +154,25 @@ class BaseExClient(BaseClient):
|
|
|
157
154
|
await models.Pmex.update_or_create({"pm": pm_}, ex=self.ex, exid=k, name=pm.name)
|
|
158
155
|
else:
|
|
159
156
|
pmin = models.Pm.validate({**pmu.model_dump(), "country_id": country_id, "typ": pm.typ})
|
|
160
|
-
# logo
|
|
161
|
-
if pm.logo and not await models.File.exists(name=pm.logo):
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
# /logo
|
|
157
|
+
# # logo
|
|
158
|
+
# if pm.logo and not await models.File.exists(name=pm.logo):
|
|
159
|
+
# if not pm.logo.startswith("https:"):
|
|
160
|
+
# if not pm.logo.startswith("/"):
|
|
161
|
+
# pm.logo = "/" + pm.logo
|
|
162
|
+
# pm.logo = "https://" + pm.logo
|
|
163
|
+
# async with ClientSession() as ss:
|
|
164
|
+
# resp = await ss.get(pm.logo)
|
|
165
|
+
# if resp.ok:
|
|
166
|
+
# byts = await resp.read()
|
|
167
|
+
# upf, ref = await pyro.save_file(byts, resp.content_type)
|
|
168
|
+
# await sleep(1)
|
|
169
|
+
# typ = FileType[resp.content_type.split("/")[-1]]
|
|
170
|
+
# file, _ = await models.File.update_or_create(
|
|
171
|
+
# {"ref": ref, "size": len(byts), "typ": typ}, name=pm.logo
|
|
172
|
+
# )
|
|
173
|
+
# # fil = await pyro.get_file(file.ref) # check
|
|
174
|
+
# pmin.logo_id = file.id
|
|
175
|
+
# # /logo
|
|
179
176
|
try:
|
|
180
177
|
pms[k], _ = await models.Pm.update_or_create(**pmin.df_unq())
|
|
181
178
|
except (MultipleObjectsReturned, IntegrityError) as e:
|
|
@@ -16,6 +16,7 @@ class TradeMethod(BaseModel):
|
|
|
16
16
|
tradeMethodName: str
|
|
17
17
|
tradeMethodShortName: Optional[str] = None
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
class Adv(BaseModel):
|
|
20
21
|
abnormalStatusList: Optional[List[str]] = None
|
|
21
22
|
adAdditionalKycVerifyItems: Optional[List[Any]] = None
|
|
@@ -91,6 +92,7 @@ class Adv(BaseModel):
|
|
|
91
92
|
userTradeVolumeMax: Optional[str] = None
|
|
92
93
|
userTradeVolumeMin: Optional[str] = None
|
|
93
94
|
|
|
95
|
+
|
|
94
96
|
class Advertiser(BaseModel):
|
|
95
97
|
activeTimeInSecond: int
|
|
96
98
|
advConfirmTime: Optional[str] = None
|
|
@@ -115,8 +117,9 @@ class Advertiser(BaseModel):
|
|
|
115
117
|
userType: str
|
|
116
118
|
vipLevel: Optional[int] = None
|
|
117
119
|
|
|
120
|
+
|
|
118
121
|
class Ad(BaseAd):
|
|
119
122
|
adv: Adv
|
|
120
123
|
advertiser: Advertiser
|
|
121
124
|
privilegeDesc: Optional[str] = None
|
|
122
|
-
privilegeType: int
|
|
125
|
+
privilegeType: int | None = None
|
|
@@ -15,9 +15,17 @@ from xync_client.Abc.Ex import BaseExClient
|
|
|
15
15
|
from xync_client.loader import PG_DSN
|
|
16
16
|
from xync_client.Abc.types import PmEx
|
|
17
17
|
from xync_client.Gate.etype import ad
|
|
18
|
+
from xync_client.pm_unifier import PmUnifier
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
class ExClient(BaseExClient):
|
|
22
|
+
class GateUnifier(PmUnifier):
|
|
23
|
+
pm_map = {
|
|
24
|
+
"SBP - Fast Bank Transfer": "SBP"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
unifier_class = GateUnifier
|
|
28
|
+
|
|
21
29
|
# Данные для р2р из html Gate.io
|
|
22
30
|
async def c2c_data(self) -> dict:
|
|
23
31
|
await sleep(1)
|
|
@@ -9,9 +9,17 @@ from xync_client.Abc.Ex import BaseExClient
|
|
|
9
9
|
from xync_client.loader import PG_DSN
|
|
10
10
|
from xync_client.Okx.etype import ad, pm
|
|
11
11
|
from xync_client.Abc.types import PmEx
|
|
12
|
+
from xync_client.pm_unifier import PmUnifier
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class ExClient(BaseExClient):
|
|
16
|
+
class OkxUnifier(PmUnifier):
|
|
17
|
+
pm_map = {
|
|
18
|
+
"SBP Fast Bank Transfer": "SBP"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
unifier_class = OkxUnifier
|
|
22
|
+
|
|
15
23
|
async def _pms(self, cur) -> list[pm.PmE]:
|
|
16
24
|
params = {
|
|
17
25
|
"quoteCurrency": cur,
|
|
@@ -4,6 +4,7 @@ from enum import StrEnum
|
|
|
4
4
|
from http.client import HTTPException
|
|
5
5
|
|
|
6
6
|
from x_model import init_db
|
|
7
|
+
|
|
7
8
|
from xync_client.TgWallet.ex import ExClient
|
|
8
9
|
from xync_schema import models
|
|
9
10
|
|
|
@@ -17,13 +18,14 @@ from xync_client.TgWallet.pyd import (
|
|
|
17
18
|
AdMakerSale,
|
|
18
19
|
AdMakerNewSale,
|
|
19
20
|
_AdNew,
|
|
20
|
-
FiatEpydIn,
|
|
21
21
|
_PmsTrait,
|
|
22
22
|
OneAdTakerBuy,
|
|
23
23
|
OrderEpyd,
|
|
24
24
|
AdMakerNewBuy,
|
|
25
25
|
OrderEpydIn,
|
|
26
26
|
AvailableVolume,
|
|
27
|
+
CredEpydNew,
|
|
28
|
+
CredEpydUpd,
|
|
27
29
|
)
|
|
28
30
|
from xync_client.loader import PG_DSN
|
|
29
31
|
from xync_schema.enums import AdStatus, UserStatus, OrderStatus
|
|
@@ -176,7 +178,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
176
178
|
resp = await self._post("/p2p/public-api/v3/payment-details/get/by-user-id")
|
|
177
179
|
return [CredEpyd(**cred) for cred in resp["data"]]
|
|
178
180
|
|
|
179
|
-
async def
|
|
181
|
+
async def cred_epyd2db(self, cred: CredEpyd) -> models.CredEx:
|
|
180
182
|
if not (pmex := await models.Pmex.get_or_none(exid=cred.paymentMethod.code, ex=self.ex_client.ex)):
|
|
181
183
|
raise HTTPException(f"No Pmex {cred.paymentMethod.code} on ex#{self.ex_client.ex.name}", 404)
|
|
182
184
|
if not (pmcur := await models.Pmcur.get_or_none(cur__ticker=cred.currency, pm_id=pmex.pm_id)):
|
|
@@ -184,90 +186,96 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
184
186
|
if not (person := await models.Person.get_or_none(actors__exid=cred.userId)):
|
|
185
187
|
raise HTTPException(f"No Pmcur with cur#{cred.currency} and pm#{cred.paymentMethod.code}", 404)
|
|
186
188
|
dct = {"pmcur_id": pmcur.id, "name": cred.name, "person_id": person.id}
|
|
189
|
+
banks: list[str] | None = None
|
|
187
190
|
for val in cred.attributes.values:
|
|
188
191
|
if val.name == "BANKS":
|
|
189
|
-
|
|
192
|
+
banks = [b.code for b in val.value]
|
|
190
193
|
else:
|
|
191
194
|
dct["detail"] = val.value
|
|
192
|
-
cred_in = models.Cred.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
)
|
|
201
|
-
return cred_in
|
|
195
|
+
cred_in = models.Cred.validate(dct, False)
|
|
196
|
+
cred_db, _ = await models.Cred.update_or_create(**cred_in.df_unq())
|
|
197
|
+
credex_in = models.CredEx.validate({"exid": cred.id, "cred_id": cred_db.id, "ex_id": self.ex.id})
|
|
198
|
+
if banks: # only for SBP
|
|
199
|
+
await cred_db.banks.add(*[await models.PmexBank.get(exid=b) for b in banks])
|
|
200
|
+
credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
|
|
201
|
+
return credex_db
|
|
202
202
|
|
|
203
203
|
# 25: Список реквизитов моих платежных методов
|
|
204
|
-
async def set_fiats(self) -> list[models.
|
|
204
|
+
async def set_fiats(self) -> list[models.CredEx]:
|
|
205
205
|
creds_epyd: list[CredEpyd] = await self.creds()
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
credexs: list[models.CredEx] = [await self.cred_epyd2db(f) for f in creds_epyd]
|
|
207
|
+
return credexs
|
|
208
|
+
|
|
209
|
+
async def challenge(self, name: str, payload: dict):
|
|
210
|
+
req = {
|
|
211
|
+
"deviceSerial": self.agent.auth["ds"],
|
|
212
|
+
"passcode": "0909",
|
|
213
|
+
"language": "en",
|
|
214
|
+
"operation": {"name": name, "payload": payload},
|
|
215
|
+
}
|
|
216
|
+
return await self._post("/v2api/challenges", req)
|
|
210
217
|
|
|
211
218
|
# 26: Создание реквизита моего платежного метода
|
|
212
|
-
async def cred_new(self, cred:
|
|
213
|
-
|
|
214
|
-
|
|
219
|
+
async def cred_new(self, cred: models.Cred) -> models.CredEx:
|
|
220
|
+
pmcur: models.Pmcur = await cred.pmcur
|
|
221
|
+
exid = await models.Pmex.get(pm_id=pmcur.pm_id, ex=self.ex_client.ex).values_list("exid", flat=True)
|
|
222
|
+
cur = await models.Cur[pmcur.cur_id]
|
|
215
223
|
vals = (
|
|
216
|
-
[
|
|
217
|
-
|
|
218
|
-
|
|
224
|
+
[
|
|
225
|
+
{"name": "PHONE", "value": cred.detail.replace(" ", "")},
|
|
226
|
+
{"name": "BANKS", "value": [b.exid for b in banks]},
|
|
227
|
+
]
|
|
228
|
+
if (banks := await cred.banks)
|
|
229
|
+
else [{"name": "PAYMENT_DETAILS_NUMBER", "value": cred.detail}]
|
|
219
230
|
)
|
|
220
|
-
|
|
221
|
-
paymentMethodCode=
|
|
231
|
+
cred_new = CredEpydNew(
|
|
232
|
+
paymentMethodCode=exid,
|
|
222
233
|
currencyCode=cur.ticker,
|
|
223
234
|
name=cred.name,
|
|
224
|
-
attributes={"values": vals},
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
cur = await models.Cur.get(ticker=add_cred["data"]["currency"])
|
|
235
|
-
pmcur, _ = await models.Pmcur.get_or_create(cur=cur, pm_id=pmex.pm_id)
|
|
236
|
-
attrs = {a["name"]: a["value"] for a in add_cred["data"]["attributes"]["values"]}
|
|
237
|
-
f, _ = await models.Cred.update_or_create(
|
|
238
|
-
{"detail": attrs["PAYMENT_DETAILS_NUMBER"]}, pmcur=pmcur, user_id=self.agent.user_id
|
|
239
|
-
)
|
|
240
|
-
return f
|
|
235
|
+
attributes={"version": "V2" if banks else "V1", "values": vals},
|
|
236
|
+
).model_dump()
|
|
237
|
+
challenge = await self.challenge("p2p/create-payment-details", cred_new)
|
|
238
|
+
hdrs = {
|
|
239
|
+
"x-wallet-operation-token": challenge["operationToken"],
|
|
240
|
+
"x-wallet-device-serial": self.agent.auth["ds"],
|
|
241
|
+
}
|
|
242
|
+
add_cred = await self._post("/p2p/public-api/v3/payment-details/create", cred_new, headers=hdrs)
|
|
243
|
+
cred_epyd = CredEpyd(**add_cred["data"])
|
|
244
|
+
return await self.cred_epyd2db(cred_epyd)
|
|
241
245
|
|
|
242
246
|
# 27: Редактирование реквизита моего платежного метода
|
|
243
|
-
async def cred_upd(self,
|
|
244
|
-
|
|
245
|
-
pmex = await models.Pmex.get(pm_id=
|
|
246
|
-
cur = await models.Cur[
|
|
247
|
-
|
|
248
|
-
"
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
"paymentMethodCode": pmex.exid,
|
|
252
|
-
"currencyCode": cur.ticker,
|
|
253
|
-
"name": name,
|
|
254
|
-
"attributes": {"version": "V1", "values": [{"name": "PAYMENT_DETAILS_NUMBER", "value": detail}]},
|
|
255
|
-
},
|
|
256
|
-
)
|
|
257
|
-
pmex = await models.Pmex.get(exid=edit_cred["data"]["paymentMethod"]["code"], ex=self.ex_client.ex)
|
|
258
|
-
cur = await models.Cur.get(ticker=edit_cred["data"]["currency"])
|
|
259
|
-
pmcur, _ = await models.Pmcur.get_or_create(cur=cur, pm_id=pmex.pm_id)
|
|
260
|
-
attrs = {a["name"]: a["value"] for a in edit_cred["data"]["attributes"]["values"]}
|
|
261
|
-
f, _ = await models.Cred.update_or_create(
|
|
262
|
-
{"detail": attrs["PAYMENT_DETAILS_NUMBER"]}, pmcur=pmcur, user_id=self.agent.user_id
|
|
247
|
+
async def cred_upd(self, cred: models.Cred, exid: int) -> models.CredEx:
|
|
248
|
+
pmcur: models.Pmcur = await cred.pmcur
|
|
249
|
+
pmex = await models.Pmex.get(pm_id=pmcur.pm_id, ex=self.ex_client.ex)
|
|
250
|
+
cur = await models.Cur[pmcur.cur_id]
|
|
251
|
+
vals = (
|
|
252
|
+
[{"name": "PHONE", "value": cred.detail}, {"name": "BANKS", "value": [b.exid for b in banks]}]
|
|
253
|
+
if (banks := await cred.banks)
|
|
254
|
+
else [{"name": "PAYMENT_DETAILS_NUMBER", "value": cred.detail}]
|
|
263
255
|
)
|
|
264
|
-
|
|
265
|
-
|
|
256
|
+
cred_upd = CredEpydUpd(
|
|
257
|
+
id=exid,
|
|
258
|
+
paymentMethodCode=pmex.exid,
|
|
259
|
+
currencyCode=cur.ticker,
|
|
260
|
+
name=cred.name,
|
|
261
|
+
attributes={"version": "V2" if banks else "V1", "values": vals},
|
|
262
|
+
).model_dump()
|
|
263
|
+
challenge = await self.challenge("p2p/edit-payment-details", cred_upd)
|
|
264
|
+
hdrs = {
|
|
265
|
+
"x-wallet-operation-token": challenge["operationToken"],
|
|
266
|
+
"x-wallet-device-serial": self.agent.auth["ds"],
|
|
267
|
+
}
|
|
268
|
+
edit_cred = await self._post("/p2p/public-api/v3/payment-details/edit", cred_upd, headers=hdrs)
|
|
269
|
+
cred_epyd = CredEpyd(**edit_cred["data"])
|
|
270
|
+
return await self.cred_epyd2db(cred_epyd)
|
|
266
271
|
|
|
267
272
|
# 28: Удаление реквизита моего платежного метода
|
|
268
|
-
async def cred_del(self, cred_id: int) ->
|
|
269
|
-
|
|
270
|
-
|
|
273
|
+
async def cred_del(self, cred_id: int) -> int: # exid
|
|
274
|
+
res: dict = await self._post("/p2p/public-api/v3/payment-details/delete", {"id": cred_id})
|
|
275
|
+
if res.get("status") == "SUCCESS":
|
|
276
|
+
return res["data"]["id"]
|
|
277
|
+
else:
|
|
278
|
+
logging.error(res)
|
|
271
279
|
|
|
272
280
|
async def ad_epyd2pydin(self, ad_: OneAdTakerMakerSale | OneAdMakerBuy | OneAdTakerBuy) -> AdBuyIn | AdSaleIn:
|
|
273
281
|
ad_in: BaseAdIn = await self.ex_client.ad_common_epyd2pydin(ad_)
|
|
@@ -279,7 +287,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
279
287
|
pmexs__ex=self.ex_client.ex, pmexs__exid__in=[p.code for p in ad_.paymentMethods]
|
|
280
288
|
),
|
|
281
289
|
)
|
|
282
|
-
creds_pin: list[
|
|
290
|
+
creds_pin: list[models.Cred.in_type()] = [await self.cred_epyd2db(c) for c in ad_.paymentDetails]
|
|
283
291
|
creds_ = [(await models.Cred.update_or_create((a := cp.args())[0], **a[1]))[0] for cp in creds_pin]
|
|
284
292
|
return AdSaleIn(**ad_in.model_dump(), creds_=creds_)
|
|
285
293
|
|
|
@@ -308,7 +316,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
308
316
|
) -> AdMakerNewSale | AdMakerNewBuy:
|
|
309
317
|
coinex = await models.Coinex.get(coin=coin, ex=self.ex)
|
|
310
318
|
curex = await models.Curex.get(ex=self.ex, cur=cur)
|
|
311
|
-
creds = await models.Cred.filter(ch__actor__agent__user_id=self.agent.user_id, pmcur__cur=cur).limit(5)
|
|
319
|
+
creds = await models.Cred.filter(ch__actor__agent__user_id=self.agent.ac.user_id, pmcur__cur=cur).limit(5)
|
|
312
320
|
# todo: ordering and filtering by fiat.amount-target
|
|
313
321
|
ad_ein = _AdNew(
|
|
314
322
|
type="SALE" if is_sell else "PURCHASE",
|
|
@@ -437,8 +445,8 @@ async def main():
|
|
|
437
445
|
)
|
|
438
446
|
mcl: AgentClient = maker.client()
|
|
439
447
|
tcl: AgentClient = taker.client()
|
|
440
|
-
await tcl.set_fiats()
|
|
441
448
|
await mcl.set_fiats()
|
|
449
|
+
await tcl.set_fiats()
|
|
442
450
|
my_ads = await mcl.my_ads()
|
|
443
451
|
my_ads_in = [await mcl.ad_epyd2pydin(ma) for ma in my_ads]
|
|
444
452
|
_my_ads_db = [await mcl.ad_pydin2db(ma) for ma in my_ads_in]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from x_client.http import Client as HttpClient
|
|
2
|
-
from xync_schema.models import Agent
|
|
2
|
+
from xync_schema.models import Agent, User, Person
|
|
3
3
|
|
|
4
4
|
from xync_client.Abc.AuthTrait import BaseAuthTrait
|
|
5
5
|
from xync_client.Abc.Base import BaseClient
|
|
@@ -14,6 +14,8 @@ class AuthClient(BaseAuthTrait, BaseClient):
|
|
|
14
14
|
.prefetch_related("actor__person__user")
|
|
15
15
|
.first()
|
|
16
16
|
)
|
|
17
|
+
elif not isinstance(self.agent.actor.person, Person) or not isinstance(self.agent.actor.person.user, User):
|
|
18
|
+
await self.agent.fetch_related("actor__person__user")
|
|
17
19
|
pyro = PyroClient(self.agent)
|
|
18
20
|
init_data = await pyro.get_init_data()
|
|
19
21
|
tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
|
|
@@ -2,6 +2,8 @@ from typing import Literal
|
|
|
2
2
|
from pydantic import BaseModel, computed_field
|
|
3
3
|
from xync_schema.types import BaseAd, BaseOrder
|
|
4
4
|
|
|
5
|
+
from xync_client.Abc.types import CredExOut
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
# Модели для вложенных структур
|
|
7
9
|
class UserStatistics(BaseModel):
|
|
@@ -113,14 +115,18 @@ class PmEpydRoot(PmEpyd):
|
|
|
113
115
|
banks: list[PmEpyd] | None = None
|
|
114
116
|
|
|
115
117
|
|
|
116
|
-
class
|
|
118
|
+
class CredEpydNew(BaseModel):
|
|
117
119
|
paymentMethodCode: str
|
|
118
120
|
currencyCode: str
|
|
119
121
|
name: str
|
|
120
122
|
attributes: Attrs | AttrsV2In
|
|
121
123
|
|
|
122
124
|
|
|
123
|
-
class
|
|
125
|
+
class CredEpydUpd(CredEpydNew):
|
|
126
|
+
id: int
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class CredEpyd(CredExOut):
|
|
124
130
|
id: int
|
|
125
131
|
userId: int
|
|
126
132
|
paymentMethod: PmEpydRoot
|