xync-client 0.0.148__tar.gz → 0.0.151__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.
Potentially problematic release.
This version of xync-client might be problematic. Click here for more details.
- {xync_client-0.0.148/xync_client.egg-info → xync_client-0.0.151}/PKG-INFO +1 -1
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/AdLoader.py +21 -13
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Agent.py +6 -1
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/xtype.py +1 -1
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/InAgent.py +5 -5
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/agent.py +116 -78
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/etype/order.py +8 -4
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/agent.py +2 -2
- xync_client-0.0.151/xync_client/Mexc/agent.py +85 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Volet/__init__.py +1 -1
- {xync_client-0.0.148 → xync_client-0.0.151/xync_client.egg-info}/PKG-INFO +1 -1
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client.egg-info/SOURCES.txt +1 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/.env.sample +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/.gitignore +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/.pre-commit-config.yaml +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/README.md +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/makefile +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/pyproject.toml +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/setup.cfg +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/TestAgent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/TestAsset.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/TestEx.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/TestOrder.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Binance/test_binance.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Gate/test_gate.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Wallet/test_agent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/Wallet/test_ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/tests/_todo_refact/_test_ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Asset.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Auth.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/BaseTest.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Exception.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/HasAbotUid.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/InAgent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/Order.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Abc/PmAgent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/binance_async.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/earn_api.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/exceptions.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/sapi.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Binance/web_c2c.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/agent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/base.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/req.mjs +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BingX/sign.js +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BitGet/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BitGet/agent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BitGet/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BitGet/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/BitPapa/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/etype/cred.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/order.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/web_earn.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/web_p2p.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Bybit/ws.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Gate/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Gate/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Gate/premarket.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Gmail/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/earn.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/etype/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/etype/cred.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/etype/test.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Htx/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/KuCoin/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/KuCoin/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/KuCoin/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/KuCoin/web.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Mexc/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Mexc/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Mexc/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Okx/etype/ad.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Okx/etype/pm.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Okx/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/.gitignore +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Alfa/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Alfa/state.json +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/MTS/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Ozon/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Payeer/.gitignore +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Payeer/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Payeer/api.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Payeer/login.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Sber/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Sber/utils.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Tinkoff/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Volet/api.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Volet/pl.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Xync/__main__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Xync/ed.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/Pms/Yandex/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/agent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/asset.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/auth.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/ex.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/inAgent.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/order.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/pyd.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/pyro.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/TgWallet/web.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/__init__.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/details.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/loader.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client/pm_unifier.py +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client.egg-info/dependency_links.txt +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client.egg-info/requires.txt +0 -0
- {xync_client-0.0.148 → xync_client-0.0.151}/xync_client.egg-info/top_level.txt +0 -0
|
@@ -4,6 +4,7 @@ from asyncio import sleep
|
|
|
4
4
|
from collections import defaultdict
|
|
5
5
|
from difflib import SequenceMatcher
|
|
6
6
|
|
|
7
|
+
from tortoise.exceptions import OperationalError
|
|
7
8
|
from xync_schema import models
|
|
8
9
|
from xync_schema.xtype import BaseAd
|
|
9
10
|
|
|
@@ -72,20 +73,25 @@ class AdLoader:
|
|
|
72
73
|
# if not ps or not ps.pair:
|
|
73
74
|
# ... # THB/USDC: just for initial filling
|
|
74
75
|
ad_upd = models.Ad.validate(pad.model_dump(by_alias=True))
|
|
75
|
-
cur_scale = 10 ** (curex or await models.CurEx.get(
|
|
76
|
+
cur_scale = 10 ** (curex or await models.CurEx.get(cur_id=ps.pair.cur_id, ex=self.ex)).scale
|
|
76
77
|
coin_scale = 10 ** (coinex or await models.CoinEx.get(coin_id=ps.pair.coin_id, ex=self.ex)).scale
|
|
78
|
+
amt = int(float(pad.quantity) * float(pad.price) * cur_scale)
|
|
79
|
+
mxf = pad.maxAmount and int(float(pad.maxAmount) * cur_scale)
|
|
77
80
|
df_unq = ad_upd.df_unq(
|
|
78
81
|
maker_id=maker.id,
|
|
79
82
|
pair_side_id=ps.id,
|
|
80
|
-
amount=
|
|
83
|
+
amount=amt if amt < 4_294_967_295 else 4_294_967_295,
|
|
81
84
|
quantity=int(float(pad.quantity) * coin_scale),
|
|
82
85
|
min_fiat=int(float(pad.minAmount) * cur_scale),
|
|
83
|
-
max_fiat=
|
|
86
|
+
max_fiat=mxf if mxf < 4_294_967_295 else 4_294_967_295,
|
|
84
87
|
price=int(float(pad.price) * cur_scale),
|
|
85
88
|
premium=int(float(pad.premium) * 100),
|
|
86
89
|
cond_id=cid,
|
|
87
90
|
)
|
|
88
|
-
|
|
91
|
+
try:
|
|
92
|
+
ad_db, _ = await models.Ad.update_or_create(**df_unq)
|
|
93
|
+
except OperationalError as e:
|
|
94
|
+
raise e
|
|
89
95
|
if not pms_from_cond:
|
|
90
96
|
await ad_db.pms.add(*(await models.Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=pad.payments)))
|
|
91
97
|
return ad_db
|
|
@@ -132,10 +138,10 @@ class AdLoader:
|
|
|
132
138
|
{ra.maker_id for ra in rest_ads} - {ad_db.maker_id}
|
|
133
139
|
):
|
|
134
140
|
# создадим новое условие и присвоим его только текущей объяве
|
|
135
|
-
|
|
136
|
-
ad_db.cond_id =
|
|
141
|
+
cond = await self.cond_new(cleaned, {int(ad.userId)})
|
|
142
|
+
ad_db.cond_id = cond.id
|
|
137
143
|
await ad_db.save()
|
|
138
|
-
|
|
144
|
+
ad_db.cond = cond
|
|
139
145
|
return ad_db, True
|
|
140
146
|
# а если других объяв со старым условием этой обявы нет, либо они все этого же юзера
|
|
141
147
|
# обновляем условие (в тч во всех ЕГО объявах)
|
|
@@ -147,16 +153,18 @@ class AdLoader:
|
|
|
147
153
|
await self.fix_rel_sims(ad_db.cond_id, cleaned)
|
|
148
154
|
return ad_db, False
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
ad,
|
|
153
|
-
)
|
|
156
|
+
cond = await self.cond_new(cleaned, {int(ad.userId)})
|
|
157
|
+
ad_db = await self.ad_load(
|
|
158
|
+
ad, cond.id, ps, coinex=coinex, curex=curex, rname=rname, pms_from_cond=pms_from_cond
|
|
159
|
+
)
|
|
160
|
+
ad_db.cond = cond
|
|
161
|
+
return ad_db, True
|
|
154
162
|
|
|
155
|
-
async def cond_new(self, txt: str, uids: set[int]) ->
|
|
163
|
+
async def cond_new(self, txt: str, uids: set[int]) -> models.Cond:
|
|
156
164
|
new_cond, _ = await models.Cond.update_or_create(raw_txt=txt)
|
|
157
165
|
# и максимально похожую связь для нового условия (если есть >= 60%)
|
|
158
166
|
await self.cond_upd(new_cond, uids)
|
|
159
|
-
return new_cond
|
|
167
|
+
return new_cond
|
|
160
168
|
|
|
161
169
|
async def cond_upd(self, cond: models.Cond, uids: set[int]):
|
|
162
170
|
self.all_conds[cond.id] = cond.raw_txt, uids
|
|
@@ -2,8 +2,10 @@ from abc import abstractmethod
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
from pyro_client.client.file import FileClient
|
|
5
|
+
from x_client import df_hdrs
|
|
5
6
|
from x_client.aiohttp import Client as HttpClient
|
|
6
7
|
from xync_bot import XyncBot
|
|
8
|
+
from xync_client.Bybit.etype.order import TakeAdReq
|
|
7
9
|
from xync_schema import models
|
|
8
10
|
from xync_schema.models import OrderStatus, Coin, Cur, Ad, AdStatus, Actor, Agent
|
|
9
11
|
from xync_schema.xtype import BaseAd
|
|
@@ -22,7 +24,7 @@ class BaseAgentClient(HttpClient):
|
|
|
22
24
|
agent: Agent,
|
|
23
25
|
fbot: FileClient,
|
|
24
26
|
bbot: XyncBot,
|
|
25
|
-
headers: dict[str, str] =
|
|
27
|
+
headers: dict[str, str] = df_hdrs,
|
|
26
28
|
cookies: dict[str, str] = None,
|
|
27
29
|
):
|
|
28
30
|
self.bbot = bbot
|
|
@@ -131,6 +133,9 @@ class BaseAgentClient(HttpClient):
|
|
|
131
133
|
@abstractmethod
|
|
132
134
|
async def my_assets(self) -> dict: ...
|
|
133
135
|
|
|
136
|
+
@abstractmethod
|
|
137
|
+
async def take_ad(self, req: TakeAdReq): ...
|
|
138
|
+
|
|
134
139
|
# Сохранение объявления (с Pm/Cred-ами) в бд
|
|
135
140
|
# async def ad_pydin2db(self, ad_pydin: AdSaleIn | AdBuyIn) -> Ad:
|
|
136
141
|
# ad_db = await self.ex_client.ad_pydin2db(ad_pydin)
|
|
@@ -335,7 +335,7 @@ class InAgentClient(BaseInAgentClient):
|
|
|
335
335
|
pma, cur = await self.get_pma_by_pmex(order_db)
|
|
336
336
|
async with in_transaction():
|
|
337
337
|
# отмечаем ордер на бирже "оплачен"
|
|
338
|
-
pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.
|
|
338
|
+
pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.pmex_exid, ex=self.agent_client.actor.ex)
|
|
339
339
|
credex = await models.CredEx.get(cred=order_db.cred, ex=self.agent_client.actor.ex)
|
|
340
340
|
self.agent_client.api.mark_as_paid(
|
|
341
341
|
orderId=str(order_db.exid),
|
|
@@ -385,20 +385,20 @@ class InAgentClient(BaseInAgentClient):
|
|
|
385
385
|
exid__in=[ptl.id for ptl in order.paymentTermList],
|
|
386
386
|
cred__person=self.agent_client.actor.person,
|
|
387
387
|
).prefetch_related("cred__pmcur__cur")
|
|
388
|
-
pmas = [pma for cdx in cdxs if (pma := self.pmacs.get(cdx.cred.pmcur.
|
|
388
|
+
pmas = [pma for cdx in cdxs if (pma := self.pmacs.get(cdx.cred.pmcur.pmex_exid))]
|
|
389
389
|
if not len(pmas):
|
|
390
390
|
# raise ValueError(order.paymentTermList, f"No pm_agents for {order.paymentTermList[0].paymentType}")
|
|
391
391
|
return None
|
|
392
392
|
elif len(pmas) > 1:
|
|
393
|
-
logging.error(order.paymentTermList, f">1 pm_agents for {cdxs[0].cred.pmcur.
|
|
393
|
+
logging.error(order.paymentTermList, f">1 pm_agents for {cdxs[0].cred.pmcur.pmex_exid}")
|
|
394
394
|
else:
|
|
395
395
|
return pmas[0], cdxs[0]
|
|
396
396
|
|
|
397
397
|
async def get_pma_by_pmex(self, order_db: models.Order) -> tuple[PmAgentClient, str]:
|
|
398
|
-
pma = self.pmacs.get(order_db.cred.pmcur.
|
|
398
|
+
pma = self.pmacs.get(order_db.cred.pmcur.pmex_exid)
|
|
399
399
|
if pma:
|
|
400
400
|
return pma, order_db.cred.pmcur.cur.ticker
|
|
401
|
-
logging.error(f"No pm_agents for {order_db.cred.pmcur.
|
|
401
|
+
logging.error(f"No pm_agents for {order_db.cred.pmcur.pmex_exid}")
|
|
402
402
|
|
|
403
403
|
@staticmethod
|
|
404
404
|
def listen(data: dict | None):
|
|
@@ -5,6 +5,7 @@ from asyncio import sleep, gather
|
|
|
5
5
|
from datetime import datetime, timedelta, timezone
|
|
6
6
|
from difflib import SequenceMatcher
|
|
7
7
|
from enum import IntEnum
|
|
8
|
+
from hashlib import sha256
|
|
8
9
|
from http.client import HTTPException
|
|
9
10
|
from math import floor
|
|
10
11
|
from typing import Literal
|
|
@@ -21,6 +22,7 @@ from tortoise.expressions import Q
|
|
|
21
22
|
from tortoise.functions import Count
|
|
22
23
|
from tortoise.signals import post_save
|
|
23
24
|
from urllib3.exceptions import ReadTimeoutError
|
|
25
|
+
from x_client import df_hdrs
|
|
24
26
|
from x_model import init_db
|
|
25
27
|
from x_model.func import ArrayAgg
|
|
26
28
|
from xync_bot import XyncBot
|
|
@@ -53,8 +55,9 @@ class NoMakerException(Exception):
|
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
class AgentClient(BaseAgentClient): # Bybit client
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
headers = df_hdrs | {"accept-language": "ru-RU"}
|
|
59
|
+
sec_hdrs: dict[str, str]
|
|
60
|
+
# rewrite token for public methods
|
|
58
61
|
api: P2P
|
|
59
62
|
last_ad_id: list[str] = []
|
|
60
63
|
update_ad_body = {
|
|
@@ -87,6 +90,11 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
87
90
|
|
|
88
91
|
def __init__(self, agent: Agent, fbot: FileClient, bbot: XyncBot, **kwargs):
|
|
89
92
|
super().__init__(agent, fbot, bbot, **kwargs)
|
|
93
|
+
self.sec_hdrs = {
|
|
94
|
+
"accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
|
|
95
|
+
"gdfp": agent.auth["Risktoken"],
|
|
96
|
+
"tx-id": agent.auth["Risktoken"],
|
|
97
|
+
}
|
|
90
98
|
self.api = P2P(testnet=False, api_key=agent.auth["key"], api_secret=agent.auth["sec"])
|
|
91
99
|
self.hist: dict | None = None
|
|
92
100
|
self.completed_orders: list[int] | None = None
|
|
@@ -95,13 +103,13 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
95
103
|
|
|
96
104
|
async def fiat_new(self, payment_type: int, real_name: str, account_number: str) -> FlatDict | None:
|
|
97
105
|
method1 = await self._post(
|
|
98
|
-
"/fiat/otc/user/payment/new_create",
|
|
106
|
+
"/x-api/fiat/otc/user/payment/new_create",
|
|
99
107
|
{"paymentType": payment_type, "realName": real_name, "accountNo": account_number, "securityRiskToken": ""},
|
|
100
108
|
)
|
|
101
109
|
if srt := method1["result"]["securityRiskToken"]:
|
|
102
110
|
await self._check_2fa(srt)
|
|
103
111
|
method2 = await self._post(
|
|
104
|
-
"/fiat/otc/user/payment/new_create",
|
|
112
|
+
"/x-api/fiat/otc/user/payment/new_create",
|
|
105
113
|
{
|
|
106
114
|
"paymentType": payment_type,
|
|
107
115
|
"realName": real_name,
|
|
@@ -140,8 +148,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
140
148
|
pmex.pm.df_cur_id
|
|
141
149
|
or (pmex.pm.country_id and (await pmex.pm.country).cur_id)
|
|
142
150
|
# or (ecdx.currencyBalance and await models.Cur.get_or_none(ticker=ecdx.currencyBalance[0]))
|
|
143
|
-
or (
|
|
144
|
-
or await self.guess_cur(ecdx)
|
|
151
|
+
or await self.guess_cur(ecdx, len(pmex.pm.curs) > 1 and pmex.pm.curs)
|
|
145
152
|
)
|
|
146
153
|
if not cur_id:
|
|
147
154
|
raise Exception(f"Set default cur for {pmex.name}")
|
|
@@ -160,7 +167,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
160
167
|
credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
|
|
161
168
|
return credex_db
|
|
162
169
|
|
|
163
|
-
async def guess_cur(self, ecdx: CredEpyd):
|
|
170
|
+
async def guess_cur(self, ecdx: CredEpyd, curs: list[models.Cur]):
|
|
164
171
|
mbs = ecdx.bankName.split(", ")
|
|
165
172
|
mbs += ecdx.branchName.split(" / ")
|
|
166
173
|
mbs = {mb.lower(): mb for mb in mbs}
|
|
@@ -172,7 +179,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
172
179
|
.values("pmcurs__cur_id", "names", "ccnt")
|
|
173
180
|
):
|
|
174
181
|
return pms[0]["pmcurs__cur_id"]
|
|
175
|
-
curs = {c.ticker: c.id for c in await models.Cur.all()}
|
|
182
|
+
curs = {c.ticker: c.id for c in curs or await models.Cur.all()}
|
|
176
183
|
for cur, cid in curs.items():
|
|
177
184
|
if re.search(re.compile(rf"\({cur}\)$"), ecdx.bankName):
|
|
178
185
|
return cid
|
|
@@ -182,6 +189,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
182
189
|
return cid
|
|
183
190
|
if re.search(re.compile(rf"\({cur}\)$"), ecdx.payMessage):
|
|
184
191
|
return cid
|
|
192
|
+
if re.search(re.compile(rf"\({cur}\)$"), ecdx.paymentExt1):
|
|
193
|
+
return cid
|
|
185
194
|
return None
|
|
186
195
|
|
|
187
196
|
# 25: Список реквизитов моих платежных методов
|
|
@@ -199,7 +208,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
199
208
|
fiat = self.get_payment_method(fiat_id)
|
|
200
209
|
fiat.realName = name
|
|
201
210
|
fiat.accountNo = detail
|
|
202
|
-
result = await self._post("/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
|
|
211
|
+
result = await self._post("/x-api/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
|
|
203
212
|
srt = result["result"]["securityRiskToken"]
|
|
204
213
|
await self._check_2fa(srt)
|
|
205
214
|
fiat.securityRiskToken = srt
|
|
@@ -209,16 +218,16 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
209
218
|
# 28
|
|
210
219
|
async def fiat_del(self, fiat_id: int) -> dict | str:
|
|
211
220
|
data = {"id": fiat_id, "securityRiskToken": ""}
|
|
212
|
-
method = await self._post("/fiat/otc/user/payment/new_delete", data)
|
|
221
|
+
method = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
|
|
213
222
|
srt = method["result"]["securityRiskToken"]
|
|
214
223
|
await self._check_2fa(srt)
|
|
215
224
|
data["securityRiskToken"] = srt
|
|
216
|
-
delete = await self._post("/fiat/otc/user/payment/new_delete", data)
|
|
225
|
+
delete = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
|
|
217
226
|
return delete
|
|
218
227
|
|
|
219
228
|
async def switch_ads(self, new_status: AdStatus) -> dict:
|
|
220
229
|
data = {"workStatus": new_status.name} # todo: переделать на апи, там status 0 -> 1
|
|
221
|
-
res = await self._post("/fiat/otc/maker/work-config/switch", data)
|
|
230
|
+
res = await self._post("/x-api/fiat/otc/maker/work-config/switch", data)
|
|
222
231
|
return res
|
|
223
232
|
|
|
224
233
|
async def ads(
|
|
@@ -256,49 +265,54 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
256
265
|
return len(res)
|
|
257
266
|
|
|
258
267
|
def get_security_token_create(self):
|
|
259
|
-
data = self._post("/fiat/otc/item/create", self.create_ad_body)
|
|
268
|
+
data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
|
|
260
269
|
if data["ret_code"] == 912120019: # Current user can not to create add as maker
|
|
261
270
|
raise NoMakerException(data)
|
|
262
271
|
security_risk_token = data["result"]["securityRiskToken"]
|
|
263
272
|
return security_risk_token
|
|
264
273
|
|
|
265
274
|
async def _check_2fa(self, risk_token) -> int:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
raise HTTPException("get")
|
|
269
|
-
cres = cres["result"]["component_list"]
|
|
270
|
-
res = await self._post(
|
|
271
|
-
"/user/public/risk/verify",
|
|
272
|
-
{
|
|
273
|
-
"risk_token": risk_token,
|
|
274
|
-
"component_list": {c["component_id"]: self.__get_2fa(c["component_id"]) for c in cres},
|
|
275
|
-
},
|
|
276
|
-
)
|
|
275
|
+
data = {"risk_token": risk_token}
|
|
276
|
+
res = await self._post("/x-api/user/public/risk/components", data, hdrs=self.sec_hdrs)
|
|
277
277
|
if res["ret_msg"] != "success":
|
|
278
|
+
raise HTTPException("get")
|
|
279
|
+
cres = sorted(res["result"]["component_list"], key=lambda c: c["component_id"], reverse=True)
|
|
280
|
+
vdata = {
|
|
281
|
+
"risk_token": risk_token,
|
|
282
|
+
"component_list": {c["component_id"]: await self.__get_2fa(c["component_id"], risk_token) for c in cres},
|
|
283
|
+
}
|
|
284
|
+
res = await self._post("/x-api/user/public/risk/verify", vdata, hdrs=self.sec_hdrs)
|
|
285
|
+
if er_code := res["ret_code"] or res["result"]["ret_code"]: # если код не 0, значит ошибка
|
|
278
286
|
logging.error("Wrong 2fa, wait 5 secs and retry..")
|
|
279
287
|
await sleep(5)
|
|
280
|
-
await self._check_2fa(risk_token)
|
|
281
|
-
return
|
|
282
|
-
|
|
283
|
-
async def __get_2fa(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
res = await self._post("/user/public/risk/send/code",
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
288
|
+
return await self._check_2fa(risk_token)
|
|
289
|
+
return er_code
|
|
290
|
+
|
|
291
|
+
async def __get_2fa(
|
|
292
|
+
self, typ: Literal["google2fa", "email_verify", "payment_password_verify", "phone_verify"], rt: str = None
|
|
293
|
+
):
|
|
294
|
+
res = {"ret_msg": "success"}
|
|
295
|
+
if typ != "google2fa":
|
|
296
|
+
data = {"risk_token": rt, "component_id": typ}
|
|
297
|
+
res = await self._post("/x-api/user/public/risk/send/code", data, hdrs=self.sec_hdrs)
|
|
298
|
+
if res["ret_msg"] == "success":
|
|
299
|
+
if typ == "google2fa":
|
|
300
|
+
bybit_secret = self.agent.auth["2fa"]
|
|
301
|
+
totp = pyotp.TOTP(bybit_secret)
|
|
302
|
+
return totp.now()
|
|
303
|
+
elif typ == "email_verify":
|
|
294
304
|
return self.gmail.bybit_code()
|
|
295
|
-
|
|
296
|
-
|
|
305
|
+
elif typ == "payment_password_verify":
|
|
306
|
+
hp = sha256(self.agent.auth["pass"].encode()).hexdigest()
|
|
307
|
+
return hp
|
|
308
|
+
elif cool_down := int(res["result"]["cool_down"]):
|
|
309
|
+
await sleep(cool_down)
|
|
310
|
+
return self.__get_2fa(typ, rt)
|
|
297
311
|
raise Exception("2fa fail")
|
|
298
312
|
|
|
299
313
|
def _post_ad(self, risk_token: str):
|
|
300
314
|
self.create_ad_body.update({"securityRiskToken": risk_token})
|
|
301
|
-
data = self._post("/fiat/otc/item/create", self.create_ad_body)
|
|
315
|
+
data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
|
|
302
316
|
return data
|
|
303
317
|
|
|
304
318
|
# создание объявлений
|
|
@@ -324,7 +338,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
324
338
|
|
|
325
339
|
def get_security_token_update(self) -> str:
|
|
326
340
|
self.update_ad_body["id"] = self.last_ad_id
|
|
327
|
-
data = self._post("/fiat/otc/item/update", self.update_ad_body)
|
|
341
|
+
data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
|
|
328
342
|
security_risk_token = data["result"]["securityRiskToken"]
|
|
329
343
|
return security_risk_token
|
|
330
344
|
|
|
@@ -341,7 +355,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
341
355
|
|
|
342
356
|
def update_ad(self, risk_token: str):
|
|
343
357
|
self.update_ad_body.update({"securityRiskToken": risk_token})
|
|
344
|
-
data = self._post("/fiat/otc/item/update", self.update_ad_body)
|
|
358
|
+
data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
|
|
345
359
|
return data
|
|
346
360
|
|
|
347
361
|
def ad_del(self, ad_id: int):
|
|
@@ -349,45 +363,43 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
349
363
|
return data
|
|
350
364
|
|
|
351
365
|
async def __preorder_request(self, ad_id: int) -> PreOrderResp:
|
|
352
|
-
res = await self._post("/fiat/otc/item/simple",
|
|
366
|
+
res = await self._post("/x-api/fiat/otc/item/simple", json={"item_id": str(ad_id)})
|
|
353
367
|
if res["ret_code"] == 0:
|
|
354
368
|
res = res["result"]
|
|
355
369
|
return PreOrderResp.model_validate(res)
|
|
356
370
|
|
|
357
|
-
async def
|
|
371
|
+
async def _order_request(self, bor: BaseOrderReq) -> OrderResp:
|
|
372
|
+
por: PreOrderResp = await self.__preorder_request(bor.ad_id)
|
|
358
373
|
req = OrderRequest(
|
|
359
374
|
itemId=por.id,
|
|
360
|
-
tokenId=
|
|
361
|
-
currencyId=
|
|
362
|
-
side="1" if
|
|
363
|
-
amount=
|
|
375
|
+
tokenId=bor.coin_exid,
|
|
376
|
+
currencyId=bor.cur_exid,
|
|
377
|
+
side="1" if bor.is_sell else "0",
|
|
378
|
+
amount=f"{bor.fiat_amount:.2f}".rstrip("0").rstrip("."),
|
|
364
379
|
curPrice=por.curPrice,
|
|
365
|
-
quantity=str(round(
|
|
380
|
+
quantity=str(round(bor.fiat_amount / float(por.price), bor.coin_scale)),
|
|
366
381
|
flag="amount",
|
|
367
|
-
# paymentType="51",
|
|
368
|
-
# paymentId="20399134",
|
|
369
382
|
# online="0"
|
|
370
383
|
)
|
|
371
|
-
if
|
|
384
|
+
if bor.is_sell:
|
|
372
385
|
credex = await models.CredEx.get(
|
|
373
386
|
cred__person_id=self.actor.person_id,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
387
|
+
cred__pmcur__pm__pmexs__exid=[pp for pp in por.payments if pp == bor.pmex_exid][0], # bor.pmex_exid
|
|
388
|
+
cred__pmcur__pm__pmexs__ex_id=self.ex_client.ex.id,
|
|
389
|
+
cred__pmcur__cur__ticker=bor.cur_exid,
|
|
377
390
|
)
|
|
378
|
-
req = OrderSellRequest(**req.model_dump(), paymentType=
|
|
379
|
-
return req
|
|
380
|
-
|
|
381
|
-
async def _order_request(self, bor: BaseOrderReq) -> OrderResp:
|
|
382
|
-
por: PreOrderResp = await self.__preorder_request(bor.ad_id)
|
|
383
|
-
req: OrderRequest | OrderSellRequest = await self.__order_request_build(por, bor)
|
|
391
|
+
req = OrderSellRequest(**req.model_dump(), paymentType=bor.pmex_exid, paymentId=str(credex.exid))
|
|
384
392
|
# вот непосредственно сам запрос на ордер
|
|
385
393
|
return await self.__order_create(req, bor)
|
|
386
394
|
|
|
387
395
|
async def __order_create(self, req: OrderRequest | OrderSellRequest, bor: BaseOrderReq) -> OrderResp:
|
|
388
|
-
|
|
396
|
+
hdrs = {"Risktoken": self.sec_hdrs["gdfp"]}
|
|
397
|
+
res: dict = await self._post("/x-api/fiat/otc/order/create", json=req.model_dump(), hdrs=hdrs)
|
|
389
398
|
if res["ret_code"] == 0:
|
|
390
399
|
resp = OrderResp.model_validate(res["result"])
|
|
400
|
+
elif res["ret_code"] == 10001:
|
|
401
|
+
logging.error(req.model_dump(), "POST", self.session._base_url)
|
|
402
|
+
raise HTTPException()
|
|
391
403
|
elif res["ret_code"] == 912120030 or res["ret_msg"] == "The price has changed, please try again later.":
|
|
392
404
|
resp = await self._order_request(bor)
|
|
393
405
|
if not resp.orderId and resp.needSecurityRisk:
|
|
@@ -401,15 +413,15 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
401
413
|
|
|
402
414
|
async def cancel_order(self, order_id: str) -> bool:
|
|
403
415
|
cr = CancelOrderReq(orderId=order_id)
|
|
404
|
-
res = await self._post("/fiat/otc/order/cancel", cr.model_dump())
|
|
416
|
+
res = await self._post("/x-api/fiat/otc/order/cancel", cr.model_dump())
|
|
405
417
|
return res["ret_code"] == 0
|
|
406
418
|
|
|
407
419
|
def get_order_info(self, order_id: str) -> dict:
|
|
408
|
-
data = self._post("/fiat/otc/order/info", json={"orderId": order_id})
|
|
420
|
+
data = self._post("/x-api/fiat/otc/order/info", json={"orderId": order_id})
|
|
409
421
|
return data["result"]
|
|
410
422
|
|
|
411
423
|
def get_chat_msg(self, order_id):
|
|
412
|
-
data = self._post("/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
|
|
424
|
+
data = self._post("/x-api/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
|
|
413
425
|
msgs = [
|
|
414
426
|
{"text": msg["message"], "type": msg["contentType"], "role": msg["roleType"], "user_id": msg["userId"]}
|
|
415
427
|
for msg in data["result"]["result"]
|
|
@@ -418,14 +430,14 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
418
430
|
return msgs
|
|
419
431
|
|
|
420
432
|
def block_user(self, user_id: str):
|
|
421
|
-
return self._post("/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
|
|
433
|
+
return self._post("/x-api/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
|
|
422
434
|
|
|
423
435
|
def unblock_user(self, user_id: str):
|
|
424
|
-
return self._post("/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
|
|
436
|
+
return self._post("/x-api/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
|
|
425
437
|
|
|
426
438
|
def user_review_post(self, order_id: str):
|
|
427
439
|
return self._post(
|
|
428
|
-
"/fiat/otc/order/appraise/modify",
|
|
440
|
+
"/x-api/fiat/otc/order/appraise/modify",
|
|
429
441
|
{
|
|
430
442
|
"orderId": order_id,
|
|
431
443
|
"anonymous": "0",
|
|
@@ -445,7 +457,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
445
457
|
self, side: int = None, status: int = None, begin_time: int = None, end_time: int = None, token_id: str = None
|
|
446
458
|
):
|
|
447
459
|
return await self._post(
|
|
448
|
-
"/fiat/otc/order/pending/simplifyList",
|
|
460
|
+
"/x-api/fiat/otc/order/pending/simplifyList",
|
|
449
461
|
{
|
|
450
462
|
"status": status,
|
|
451
463
|
"tokenId": token_id,
|
|
@@ -459,7 +471,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
459
471
|
|
|
460
472
|
def get_orders_done(self, begin_time: int, end_time: int, status: int, side: int, token_id: str):
|
|
461
473
|
return self._post(
|
|
462
|
-
"/fiat/otc/order/simplifyList",
|
|
474
|
+
"/x-api/fiat/otc/order/simplifyList",
|
|
463
475
|
{
|
|
464
476
|
"status": status, # 50 - завершено
|
|
465
477
|
"tokenId": token_id,
|
|
@@ -945,15 +957,33 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
945
957
|
return (bc, sc), hp, vmf, zplace
|
|
946
958
|
|
|
947
959
|
async def take_ad(self, req: TakeAdReq):
|
|
948
|
-
|
|
960
|
+
if req.price and req.is_sell and req.cur_:
|
|
961
|
+
... # todo call the get_ad_details() only if lack of data
|
|
962
|
+
res = self.api.get_ad_details(itemId=req.ad_id)["result"]
|
|
963
|
+
ad: Ad = Ad.model_validate(res)
|
|
964
|
+
pmexs = await models.PmEx.filter(ex_id=self.actor.ex_id, pm_id=req.pm_id)
|
|
965
|
+
if len(pmexs) > 1:
|
|
966
|
+
pmexs = [p for p in pmexs if p.exid in ad.payments]
|
|
967
|
+
# if ad.side: # продажа, я (тейкер) покупатель
|
|
968
|
+
# pmexs = await models.PmEx.filter(ex_id=self.actor.ex_id, pm_id=req.pm_id)
|
|
969
|
+
# if len(pmexs) > 1:
|
|
970
|
+
# pmexs = [p for p in pmexs if p.name.endswith(f" ({ad.currencyId})")]
|
|
971
|
+
# else:
|
|
972
|
+
# pmexs = await models.CredEx.filter(
|
|
973
|
+
# ex_id=self.actor.ex_id, cred__person_id=self.actor.person_id,
|
|
974
|
+
# cred__pmcur__pm_id=req.pm_id, cred__pmcur__cur__ticker=ad.currencyId
|
|
975
|
+
# )
|
|
976
|
+
# req.pm_id = pmexs[0].exid
|
|
977
|
+
# req.quantity = round(req.amount / float(ad.price) - 0.00005, 4) # todo: to get the scale from coinEx
|
|
978
|
+
|
|
949
979
|
bor = BaseOrderReq(
|
|
950
980
|
ad_id=str(ad.id),
|
|
951
981
|
fiat_amount=req.amount,
|
|
952
|
-
is_sell=bool(ad.side),
|
|
982
|
+
is_sell=not bool(ad.side),
|
|
953
983
|
cur_exid=ad.currencyId,
|
|
954
984
|
coin_exid=ad.tokenId,
|
|
955
|
-
coin_scale=ad.token.scale,
|
|
956
|
-
|
|
985
|
+
coin_scale=ad.symbolInfo.token.scale,
|
|
986
|
+
pmex_exid=pmexs[0].exid,
|
|
957
987
|
)
|
|
958
988
|
resp: OrderResp = await self._order_request(bor)
|
|
959
989
|
return resp
|
|
@@ -1085,14 +1115,22 @@ async def main():
|
|
|
1085
1115
|
...
|
|
1086
1116
|
|
|
1087
1117
|
agent = (
|
|
1088
|
-
await models.Agent.filter(actor__ex_id=4, auth__isnull=False, active=True)
|
|
1089
|
-
.prefetch_related(
|
|
1118
|
+
await models.Agent.filter(actor__ex_id=4, auth__isnull=False, active=True, actor__person__user__id=2)
|
|
1119
|
+
.prefetch_related(
|
|
1120
|
+
"actor__ex",
|
|
1121
|
+
"actor__person__user__gmail",
|
|
1122
|
+
"actor__my_ads__my_ad__race",
|
|
1123
|
+
"actor__my_ads__pair_side__pair__cur",
|
|
1124
|
+
"actor__my_ads__pms",
|
|
1125
|
+
)
|
|
1090
1126
|
.first()
|
|
1091
1127
|
)
|
|
1092
1128
|
filebot = FileClient(NET_TOKEN)
|
|
1093
|
-
await filebot.start()
|
|
1129
|
+
# await filebot.start()
|
|
1094
1130
|
# b.add_handler(MessageHandler(cond_start_handler, command("cond")))
|
|
1095
1131
|
cl: AgentClient = agent.client(filebot, XyncBot(PAY_TOKEN, cn))
|
|
1132
|
+
req = TakeAdReq(ad_id=1955696985964089344, amount=504, pm_id=128)
|
|
1133
|
+
await cl.take_ad(req)
|
|
1096
1134
|
|
|
1097
1135
|
# await cl.ex_client.set_pairs()
|
|
1098
1136
|
# await cl.ex_client.set_pms()
|
|
@@ -47,7 +47,11 @@ class StatusApi(IntEnum):
|
|
|
47
47
|
class TakeAdReq(BaseModel):
|
|
48
48
|
ad_id: int | str
|
|
49
49
|
amount: float
|
|
50
|
-
|
|
50
|
+
quantity: float | None = None
|
|
51
|
+
is_sell: bool | None = None
|
|
52
|
+
price: float | None = None
|
|
53
|
+
pm_id: int | str = None
|
|
54
|
+
cur_: str | None = None
|
|
51
55
|
|
|
52
56
|
|
|
53
57
|
class OrderRequest(BaseModel):
|
|
@@ -82,7 +86,7 @@ class PreOrderResp(BaseModel):
|
|
|
82
86
|
isOnline: bool
|
|
83
87
|
lastLogoutTime: str # timestamp(0)+0
|
|
84
88
|
payments: list[str] # list[int]
|
|
85
|
-
status: Literal[10, 20]
|
|
89
|
+
status: Literal[10, 15, 20]
|
|
86
90
|
paymentTerms: list # empty
|
|
87
91
|
paymentPeriod: Literal[15, 30, 60]
|
|
88
92
|
totalAmount: str # float .cur.scale
|
|
@@ -102,8 +106,8 @@ class OrderResp(BaseModel):
|
|
|
102
106
|
confirmId: str = ""
|
|
103
107
|
success: bool
|
|
104
108
|
securityRiskToken: str = ""
|
|
105
|
-
riskTokenType: Literal["challenge"] =
|
|
106
|
-
riskVersion: Literal["1", "2"] =
|
|
109
|
+
riskTokenType: Literal["challenge", ""] = ""
|
|
110
|
+
riskVersion: Literal["1", "2", ""] = ""
|
|
107
111
|
needSecurityRisk: bool
|
|
108
112
|
isBulkOrder: bool
|
|
109
113
|
confirmed: str = None
|
|
@@ -46,7 +46,7 @@ class AgentClient(BaseAgentClient):
|
|
|
46
46
|
|
|
47
47
|
async def cred_new(self, cred: models.Cred) -> models.CredEx:
|
|
48
48
|
pmcur = await cred.pmcur
|
|
49
|
-
exid = str(await models.PmEx.get(pm_id=pmcur.
|
|
49
|
+
exid = str(await models.PmEx.get(pm_id=pmcur.pmex_exid, ex=self.ex_client.ex).values_list("exid", flat=True))
|
|
50
50
|
field_map = {
|
|
51
51
|
"payee": "name",
|
|
52
52
|
"bank": "extra",
|
|
@@ -71,7 +71,7 @@ class AgentClient(BaseAgentClient):
|
|
|
71
71
|
|
|
72
72
|
async def cred_upd(self, cred: models.Cred, exid: int) -> models.CredEx:
|
|
73
73
|
pmcur = await cred.pmcur
|
|
74
|
-
_exid = str(await models.PmEx.get(pm_id=pmcur.
|
|
74
|
+
_exid = str(await models.PmEx.get(pm_id=pmcur.pmex_exid, ex=self.ex_client.ex).values_list("exid", flat=True))
|
|
75
75
|
field_map = {
|
|
76
76
|
"payee": "name",
|
|
77
77
|
"bank": "extra",
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from asyncio import run
|
|
2
|
+
from hashlib import md5
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from pyro_client.client.file import FileClient
|
|
6
|
+
from xync_bot import XyncBot
|
|
7
|
+
from xync_client.Bybit.etype.order import TakeAdReq
|
|
8
|
+
|
|
9
|
+
from xync_client.loader import PAY_TOKEN, NET_TOKEN
|
|
10
|
+
from xync_schema import models
|
|
11
|
+
from xync_schema.enums import UserStatus
|
|
12
|
+
|
|
13
|
+
from xync_client.Abc.Agent import BaseAgentClient
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AgentClient(BaseAgentClient):
|
|
17
|
+
i: int = 0
|
|
18
|
+
headers = {
|
|
19
|
+
"accept-language": "ru,en;q=0.9",
|
|
20
|
+
"language:": "ru-RU",
|
|
21
|
+
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async def _take_ad(self, req: TakeAdReq):
|
|
25
|
+
self.i = 33 if self.i > 9998 else self.i + 2
|
|
26
|
+
hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
|
|
27
|
+
auth = {
|
|
28
|
+
"p0": self.actor.agent.auth["p0"],
|
|
29
|
+
"k0": self.actor.agent.auth["k0"],
|
|
30
|
+
"chash": self.actor.agent.auth["chash"],
|
|
31
|
+
"mtoken": self.actor.agent.auth["deviceId"],
|
|
32
|
+
"mhash": md5(self.actor.agent.auth["deviceId"].encode()).hexdigest(),
|
|
33
|
+
}
|
|
34
|
+
data = {
|
|
35
|
+
"scene": "TRADE_BUY",
|
|
36
|
+
"quantity": req.quantity,
|
|
37
|
+
"amount": req.amount,
|
|
38
|
+
"orderId": req.ad_id,
|
|
39
|
+
"authVersion": "v2",
|
|
40
|
+
"deviceId": auth["mtoken"],
|
|
41
|
+
}
|
|
42
|
+
res = await self._post("/api/verify/second_auth/risk/scene", json=data, hdrs=hdrs)
|
|
43
|
+
data = {
|
|
44
|
+
"amount": req.amount,
|
|
45
|
+
"authVersion": "v2",
|
|
46
|
+
"orderId": req.ad_id,
|
|
47
|
+
"price": req.price,
|
|
48
|
+
"ts": int(1761155700.8372989 * 1000),
|
|
49
|
+
"userConfirmPaymentId" if req.is_sell else "userConfirmPayMethodId": req.pm_id,
|
|
50
|
+
}
|
|
51
|
+
self.i = 33 if self.i > 9999 else self.i + 1
|
|
52
|
+
hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
|
|
53
|
+
res = await self._post("/api/order/deal?mhash=" + auth["mhash"], data=auth | data, hdrs=hdrs)
|
|
54
|
+
return res["data"]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
async def main():
|
|
58
|
+
from x_model import init_db
|
|
59
|
+
from xync_client.loader import TORM
|
|
60
|
+
|
|
61
|
+
cn = await init_db(TORM, True)
|
|
62
|
+
|
|
63
|
+
agent = (
|
|
64
|
+
await models.Agent.filter(
|
|
65
|
+
actor__ex_id=12,
|
|
66
|
+
active=True,
|
|
67
|
+
auth__isnull=False,
|
|
68
|
+
actor__person__user__status=UserStatus.ACTIVE,
|
|
69
|
+
actor__person__user__pm_agents__isnull=False,
|
|
70
|
+
)
|
|
71
|
+
.prefetch_related("actor__ex", "actor__person__user__gmail")
|
|
72
|
+
.first()
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
bbot = XyncBot(PAY_TOKEN, cn)
|
|
76
|
+
fbot = FileClient(NET_TOKEN)
|
|
77
|
+
|
|
78
|
+
cl = agent.client(fbot, bbot)
|
|
79
|
+
req = TakeAdReq(ad_id="a1574088909645125632", amount=500, pm_id=366, cur_="RUB", price=85.8, is_sell=True)
|
|
80
|
+
res = await cl.take_ad(req)
|
|
81
|
+
print(res)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
run(main())
|
|
@@ -273,7 +273,7 @@ async def _test():
|
|
|
273
273
|
pma = await models.PmAgent.get(
|
|
274
274
|
active=True,
|
|
275
275
|
auth__isnull=False,
|
|
276
|
-
pm_id=o.cred.pmcur.
|
|
276
|
+
pm_id=o.cred.pmcur.pmex_exid,
|
|
277
277
|
user__person__actors=o.ad.maker_id,
|
|
278
278
|
user__status=UserStatus.ACTIVE,
|
|
279
279
|
).prefetch_related("pm", "user__gmail", "user__username__session")
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|