xync-client 0.0.148__tar.gz → 0.0.150__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.

Files changed (126) hide show
  1. {xync_client-0.0.148/xync_client.egg-info → xync_client-0.0.150}/PKG-INFO +1 -1
  2. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/AdLoader.py +21 -13
  3. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Agent.py +20 -1
  4. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/agent.py +86 -56
  5. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/etype/order.py +6 -2
  6. xync_client-0.0.150/xync_client/Mexc/agent.py +84 -0
  7. {xync_client-0.0.148 → xync_client-0.0.150/xync_client.egg-info}/PKG-INFO +1 -1
  8. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client.egg-info/SOURCES.txt +1 -0
  9. {xync_client-0.0.148 → xync_client-0.0.150}/.env.sample +0 -0
  10. {xync_client-0.0.148 → xync_client-0.0.150}/.gitignore +0 -0
  11. {xync_client-0.0.148 → xync_client-0.0.150}/.pre-commit-config.yaml +0 -0
  12. {xync_client-0.0.148 → xync_client-0.0.150}/README.md +0 -0
  13. {xync_client-0.0.148 → xync_client-0.0.150}/__init__.py +0 -0
  14. {xync_client-0.0.148 → xync_client-0.0.150}/makefile +0 -0
  15. {xync_client-0.0.148 → xync_client-0.0.150}/pyproject.toml +0 -0
  16. {xync_client-0.0.148 → xync_client-0.0.150}/setup.cfg +0 -0
  17. {xync_client-0.0.148 → xync_client-0.0.150}/tests/TestAgent.py +0 -0
  18. {xync_client-0.0.148 → xync_client-0.0.150}/tests/TestAsset.py +0 -0
  19. {xync_client-0.0.148 → xync_client-0.0.150}/tests/TestEx.py +0 -0
  20. {xync_client-0.0.148 → xync_client-0.0.150}/tests/TestOrder.py +0 -0
  21. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Binance/test_binance.py +0 -0
  22. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  23. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  24. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Gate/test_gate.py +0 -0
  25. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  26. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  27. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/__init__.py +0 -0
  28. {xync_client-0.0.148 → xync_client-0.0.150}/tests/_todo_refact/_test_ex.py +0 -0
  29. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Asset.py +0 -0
  30. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Auth.py +0 -0
  31. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/BaseTest.py +0 -0
  32. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Ex.py +0 -0
  33. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Exception.py +0 -0
  34. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/HasAbotUid.py +0 -0
  35. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/InAgent.py +0 -0
  36. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/Order.py +0 -0
  37. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/PmAgent.py +0 -0
  38. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Abc/xtype.py +0 -0
  39. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/__init__.py +0 -0
  40. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/binance_async.py +0 -0
  41. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/earn_api.py +0 -0
  42. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/etype/ad.py +0 -0
  43. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/etype/pm.py +0 -0
  44. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/ex.py +0 -0
  45. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/exceptions.py +0 -0
  46. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/sapi.py +0 -0
  47. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Binance/web_c2c.py +0 -0
  48. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/__init__.py +0 -0
  49. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/agent.py +0 -0
  50. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/base.py +0 -0
  51. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/etype/ad.py +0 -0
  52. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/etype/pm.py +0 -0
  53. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/ex.py +0 -0
  54. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/req.mjs +0 -0
  55. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BingX/sign.js +0 -0
  56. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BitGet/__init__.py +0 -0
  57. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BitGet/agent.py +0 -0
  58. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BitGet/etype/ad.py +0 -0
  59. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BitGet/ex.py +0 -0
  60. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/BitPapa/ex.py +0 -0
  61. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/InAgent.py +0 -0
  62. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/etype/ad.py +0 -0
  63. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/etype/cred.py +0 -0
  64. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/ex.py +0 -0
  65. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/order.py +0 -0
  66. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/web_earn.py +0 -0
  67. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/web_p2p.py +0 -0
  68. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Bybit/ws.py +0 -0
  69. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Gate/etype/ad.py +0 -0
  70. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Gate/ex.py +0 -0
  71. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Gate/premarket.py +0 -0
  72. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Gmail/__init__.py +0 -0
  73. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/agent.py +0 -0
  74. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/earn.py +0 -0
  75. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/etype/__init__.py +0 -0
  76. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/etype/ad.py +0 -0
  77. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/etype/cred.py +0 -0
  78. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/etype/pm.py +0 -0
  79. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/etype/test.py +0 -0
  80. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Htx/ex.py +0 -0
  81. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/KuCoin/etype/ad.py +0 -0
  82. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/KuCoin/etype/pm.py +0 -0
  83. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/KuCoin/ex.py +0 -0
  84. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/KuCoin/web.py +0 -0
  85. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Mexc/etype/ad.py +0 -0
  86. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Mexc/etype/pm.py +0 -0
  87. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Mexc/ex.py +0 -0
  88. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Okx/etype/ad.py +0 -0
  89. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Okx/etype/pm.py +0 -0
  90. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Okx/ex.py +0 -0
  91. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/.gitignore +0 -0
  92. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Alfa/__init__.py +0 -0
  93. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Alfa/state.json +0 -0
  94. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/MTS/__init__.py +0 -0
  95. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Ozon/__init__.py +0 -0
  96. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Payeer/.gitignore +0 -0
  97. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Payeer/__init__.py +0 -0
  98. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Payeer/api.py +0 -0
  99. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Payeer/login.py +0 -0
  100. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Sber/__init__.py +0 -0
  101. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Sber/utils.py +0 -0
  102. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  103. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Volet/__init__.py +0 -0
  104. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  105. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  106. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Volet/api.py +0 -0
  107. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Volet/pl.py +0 -0
  108. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Xync/__main__.py +0 -0
  109. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Xync/ed.py +0 -0
  110. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/Pms/Yandex/__init__.py +0 -0
  111. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/agent.py +0 -0
  112. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/asset.py +0 -0
  113. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/auth.py +0 -0
  114. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/ex.py +0 -0
  115. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/inAgent.py +0 -0
  116. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/order.py +0 -0
  117. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/pyd.py +0 -0
  118. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/pyro.py +0 -0
  119. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/TgWallet/web.py +0 -0
  120. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/__init__.py +0 -0
  121. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/details.py +0 -0
  122. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/loader.py +0 -0
  123. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client/pm_unifier.py +0 -0
  124. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client.egg-info/dependency_links.txt +0 -0
  125. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client.egg-info/requires.txt +0 -0
  126. {xync_client-0.0.148 → xync_client-0.0.150}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.148
3
+ Version: 0.0.150
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -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(coin_id=ps.pair.cur_id, ex=self.ex)).scale
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=int(float(pad.quantity) * float(pad.price) * cur_scale),
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=pad.maxAmount and int(float(pad.maxAmount) * cur_scale),
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
- ad_db, _ = await models.Ad.update_or_create(**df_unq)
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
- cid = await self.cond_new(cleaned, {int(ad.userId)})
136
- ad_db.cond_id = cid
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
- cid = await self.cond_new(cleaned, {int(ad.userId)})
151
- return await self.ad_load(
152
- ad, cid, ps, coinex=coinex, curex=curex, rname=rname, pms_from_cond=pms_from_cond
153
- ), True
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]) -> 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.id
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] = None,
27
+ headers: dict[str, str] = df_hdrs,
26
28
  cookies: dict[str, str] = None,
27
29
  ):
28
30
  self.bbot = bbot
@@ -131,6 +133,23 @@ 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
+
139
+ async def take_ad(self, req: TakeAdReq):
140
+ if req.is_sell:
141
+ fltr = dict(ex_id=self.actor.ex_id, cred__pmcur__pm_id=req.pm_id, cred__person_id=self.actor.person.id)
142
+ if req.cur_:
143
+ fltr |= dict(cred__pmcur__cur__ticker=req.cur_)
144
+ pmexs = await models.CredEx.filter(**fltr)
145
+ else:
146
+ pmexs = await models.PmEx.filter(ex_id=self.actor.ex_id, pm_id=req.pm_id)
147
+ if len(pmexs) > 1:
148
+ pmexs = [p for p in pmexs if p.name.endswith(f" ({req.cur_})")]
149
+ req.pm_id = pmexs[0].exid
150
+ req.quantity = round(req.amount / req.price, 4) # todo: to get the scale from coinEx
151
+ return await self._take_ad(req)
152
+
134
153
  # Сохранение объявления (с Pm/Cred-ами) в бд
135
154
  # async def ad_pydin2db(self, ad_pydin: AdSaleIn | AdBuyIn) -> Ad:
136
155
  # ad_db = await self.ex_client.ad_pydin2db(ad_pydin)
@@ -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
@@ -53,8 +54,11 @@ class NoMakerException(Exception):
53
54
 
54
55
 
55
56
  class AgentClient(BaseAgentClient): # Bybit client
56
- host = "api2.bybit.com"
57
- headers = {"cookie": ";"} # rewrite token for public methods
57
+ headers = {
58
+ # "accept": "application/json",
59
+ "Cookie": ";",
60
+ }
61
+ # rewrite token for public methods
58
62
  api: P2P
59
63
  last_ad_id: list[str] = []
60
64
  update_ad_body = {
@@ -95,13 +99,13 @@ class AgentClient(BaseAgentClient): # Bybit client
95
99
 
96
100
  async def fiat_new(self, payment_type: int, real_name: str, account_number: str) -> FlatDict | None:
97
101
  method1 = await self._post(
98
- "/fiat/otc/user/payment/new_create",
102
+ "/x-api/fiat/otc/user/payment/new_create",
99
103
  {"paymentType": payment_type, "realName": real_name, "accountNo": account_number, "securityRiskToken": ""},
100
104
  )
101
105
  if srt := method1["result"]["securityRiskToken"]:
102
106
  await self._check_2fa(srt)
103
107
  method2 = await self._post(
104
- "/fiat/otc/user/payment/new_create",
108
+ "/x-api/fiat/otc/user/payment/new_create",
105
109
  {
106
110
  "paymentType": payment_type,
107
111
  "realName": real_name,
@@ -140,8 +144,7 @@ class AgentClient(BaseAgentClient): # Bybit client
140
144
  pmex.pm.df_cur_id
141
145
  or (pmex.pm.country_id and (await pmex.pm.country).cur_id)
142
146
  # or (ecdx.currencyBalance and await models.Cur.get_or_none(ticker=ecdx.currencyBalance[0]))
143
- or (0 < len(pmex.pm.curs) < 30 and pmex.pm.curs[-1].id)
144
- or await self.guess_cur(ecdx)
147
+ or await self.guess_cur(ecdx, len(pmex.pm.curs) > 1 and pmex.pm.curs)
145
148
  )
146
149
  if not cur_id:
147
150
  raise Exception(f"Set default cur for {pmex.name}")
@@ -160,7 +163,7 @@ class AgentClient(BaseAgentClient): # Bybit client
160
163
  credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
161
164
  return credex_db
162
165
 
163
- async def guess_cur(self, ecdx: CredEpyd):
166
+ async def guess_cur(self, ecdx: CredEpyd, curs: list[models.Cur]):
164
167
  mbs = ecdx.bankName.split(", ")
165
168
  mbs += ecdx.branchName.split(" / ")
166
169
  mbs = {mb.lower(): mb for mb in mbs}
@@ -172,7 +175,7 @@ class AgentClient(BaseAgentClient): # Bybit client
172
175
  .values("pmcurs__cur_id", "names", "ccnt")
173
176
  ):
174
177
  return pms[0]["pmcurs__cur_id"]
175
- curs = {c.ticker: c.id for c in await models.Cur.all()}
178
+ curs = {c.ticker: c.id for c in curs or await models.Cur.all()}
176
179
  for cur, cid in curs.items():
177
180
  if re.search(re.compile(rf"\({cur}\)$"), ecdx.bankName):
178
181
  return cid
@@ -182,6 +185,8 @@ class AgentClient(BaseAgentClient): # Bybit client
182
185
  return cid
183
186
  if re.search(re.compile(rf"\({cur}\)$"), ecdx.payMessage):
184
187
  return cid
188
+ if re.search(re.compile(rf"\({cur}\)$"), ecdx.paymentExt1):
189
+ return cid
185
190
  return None
186
191
 
187
192
  # 25: Список реквизитов моих платежных методов
@@ -199,7 +204,7 @@ class AgentClient(BaseAgentClient): # Bybit client
199
204
  fiat = self.get_payment_method(fiat_id)
200
205
  fiat.realName = name
201
206
  fiat.accountNo = detail
202
- result = await self._post("/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
207
+ result = await self._post("/x-api/fiat/otc/user/payment/new_update", fiat.model_dump(exclude_none=True))
203
208
  srt = result["result"]["securityRiskToken"]
204
209
  await self._check_2fa(srt)
205
210
  fiat.securityRiskToken = srt
@@ -209,16 +214,16 @@ class AgentClient(BaseAgentClient): # Bybit client
209
214
  # 28
210
215
  async def fiat_del(self, fiat_id: int) -> dict | str:
211
216
  data = {"id": fiat_id, "securityRiskToken": ""}
212
- method = await self._post("/fiat/otc/user/payment/new_delete", data)
217
+ method = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
213
218
  srt = method["result"]["securityRiskToken"]
214
219
  await self._check_2fa(srt)
215
220
  data["securityRiskToken"] = srt
216
- delete = await self._post("/fiat/otc/user/payment/new_delete", data)
221
+ delete = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
217
222
  return delete
218
223
 
219
224
  async def switch_ads(self, new_status: AdStatus) -> dict:
220
225
  data = {"workStatus": new_status.name} # todo: переделать на апи, там status 0 -> 1
221
- res = await self._post("/fiat/otc/maker/work-config/switch", data)
226
+ res = await self._post("/x-api/fiat/otc/maker/work-config/switch", data)
222
227
  return res
223
228
 
224
229
  async def ads(
@@ -256,22 +261,37 @@ class AgentClient(BaseAgentClient): # Bybit client
256
261
  return len(res)
257
262
 
258
263
  def get_security_token_create(self):
259
- data = self._post("/fiat/otc/item/create", self.create_ad_body)
264
+ data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
260
265
  if data["ret_code"] == 912120019: # Current user can not to create add as maker
261
266
  raise NoMakerException(data)
262
267
  security_risk_token = data["result"]["securityRiskToken"]
263
268
  return security_risk_token
264
269
 
265
270
  async def _check_2fa(self, risk_token) -> int:
266
- cres = await self._post("/user/public/risk/components", {"risk_token": risk_token})
267
- if cres["ret_msg"] != "success":
271
+ res = await self._post(
272
+ "/x-api/user/public/risk/components",
273
+ {"risk_token": risk_token},
274
+ hdrs={
275
+ # "Accept-Language": "ru,en;q=0.9",
276
+ },
277
+ )
278
+ if res["ret_msg"] != "success":
268
279
  raise HTTPException("get")
269
- cres = cres["result"]["component_list"]
280
+ cres = sorted(res["result"]["component_list"], key=lambda c: c["component_id"], reverse=True)
281
+ # cres = [{"component_id": "payment_password_verify"}]
282
+ vdata = {
283
+ "risk_token": risk_token,
284
+ "component_list": {c["component_id"]: await self.__get_2fa(c["component_id"], risk_token) for c in cres},
285
+ }
270
286
  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},
287
+ "/x-api/user/public/risk/verify",
288
+ vdata,
289
+ hdrs={
290
+ "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",
291
+ "accept-language": "ru,en;q=0.9",
292
+ # "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
293
+ "accept-encoding": "gzip, deflate, br, zstd",
294
+ "accept": "application/json",
275
295
  },
276
296
  )
277
297
  if res["ret_msg"] != "success":
@@ -280,25 +300,32 @@ class AgentClient(BaseAgentClient): # Bybit client
280
300
  await self._check_2fa(risk_token)
281
301
  return res["ret_code"]
282
302
 
283
- async def __get_2fa(self, typ: Literal["google2fa", "email_verify", "payment_password_verify"], rt: str = None):
284
- if typ == "google2fa":
285
- bybit_secret = self.agent.auth["2fa"]
286
- totp = pyotp.TOTP(bybit_secret)
287
- return totp.now()
288
- elif typ == "email_verify":
289
- res = await self._post("/user/public/risk/send/code", {"risk_token": rt, "component_id": "email_verify"})
290
- if res["ret_msg"] != "success":
291
- return self.gmail.bybit_code()
292
- elif cool_down := int(res["result"]["cool_down"]):
293
- await sleep(cool_down)
303
+ async def __get_2fa(
304
+ self, typ: Literal["google2fa", "email_verify", "payment_password_verify", "phone_verify"], rt: str = None
305
+ ):
306
+ res = {"ret_msg": "success"}
307
+ if typ != "google2fa":
308
+ # "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
309
+ # "accept": "application/json"
310
+ res = await self._post("/x-api/user/public/risk/send/code", {"risk_token": rt, "component_id": typ})
311
+ if res["ret_msg"] == "success":
312
+ if typ == "google2fa":
313
+ bybit_secret = self.agent.auth["2fa"]
314
+ totp = pyotp.TOTP(bybit_secret)
315
+ return totp.now()
316
+ elif typ == "email_verify":
294
317
  return self.gmail.bybit_code()
295
- elif typ == "payment_password_verify":
296
- return self.agent.auth["pass"]
318
+ elif typ == "payment_password_verify":
319
+ hp = sha256(self.agent.auth["pass"].encode()).hexdigest()
320
+ return hp
321
+ elif cool_down := int(res["result"]["cool_down"]):
322
+ await sleep(cool_down)
323
+ return self.__get_2fa(typ, rt)
297
324
  raise Exception("2fa fail")
298
325
 
299
326
  def _post_ad(self, risk_token: str):
300
327
  self.create_ad_body.update({"securityRiskToken": risk_token})
301
- data = self._post("/fiat/otc/item/create", self.create_ad_body)
328
+ data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
302
329
  return data
303
330
 
304
331
  # создание объявлений
@@ -324,7 +351,7 @@ class AgentClient(BaseAgentClient): # Bybit client
324
351
 
325
352
  def get_security_token_update(self) -> str:
326
353
  self.update_ad_body["id"] = self.last_ad_id
327
- data = self._post("/fiat/otc/item/update", self.update_ad_body)
354
+ data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
328
355
  security_risk_token = data["result"]["securityRiskToken"]
329
356
  return security_risk_token
330
357
 
@@ -341,7 +368,7 @@ class AgentClient(BaseAgentClient): # Bybit client
341
368
 
342
369
  def update_ad(self, risk_token: str):
343
370
  self.update_ad_body.update({"securityRiskToken": risk_token})
344
- data = self._post("/fiat/otc/item/update", self.update_ad_body)
371
+ data = self._post("/x-api/fiat/otc/item/update", self.update_ad_body)
345
372
  return data
346
373
 
347
374
  def ad_del(self, ad_id: int):
@@ -349,7 +376,7 @@ class AgentClient(BaseAgentClient): # Bybit client
349
376
  return data
350
377
 
351
378
  async def __preorder_request(self, ad_id: int) -> PreOrderResp:
352
- res = await self._post("/fiat/otc/item/simple", data={"item_id": str(ad_id)})
379
+ res = await self._post("/x-api/fiat/otc/item/simple", json={"item_id": str(ad_id)})
353
380
  if res["ret_code"] == 0:
354
381
  res = res["result"]
355
382
  return PreOrderResp.model_validate(res)
@@ -360,20 +387,18 @@ class AgentClient(BaseAgentClient): # Bybit client
360
387
  tokenId=br.coin_exid,
361
388
  currencyId=br.cur_exid,
362
389
  side="1" if br.is_sell else "0",
363
- amount=str(br.fiat_amount),
390
+ amount=f"{br.fiat_amount:.2f}".rstrip("0").rstrip("."),
364
391
  curPrice=por.curPrice,
365
392
  quantity=str(round(br.fiat_amount / float(por.price), br.coin_scale)),
366
393
  flag="amount",
367
- # paymentType="51",
368
- # paymentId="20399134",
369
394
  # online="0"
370
395
  )
371
396
  if br.is_sell:
372
397
  credex = await models.CredEx.get(
373
398
  cred__person_id=self.actor.person_id,
374
- pmcur__pm__pmexs__exid=por.payments[0],
375
- pmcur__pm__pmexs__ex_id=self.ex_client.ex.id,
376
- pmcur__cur_id=br.cur_exid,
399
+ cred__pmcur__pm__pmexs__exid=por.payments[0],
400
+ cred__pmcur__pm__pmexs__ex_id=self.ex_client.ex.id,
401
+ cred__pmcur__cur__ticker=br.cur_exid,
377
402
  )
378
403
  req = OrderSellRequest(**req.model_dump(), paymentType=por.payments[0], paymentId=str(credex.exid))
379
404
  return req
@@ -385,9 +410,12 @@ class AgentClient(BaseAgentClient): # Bybit client
385
410
  return await self.__order_create(req, bor)
386
411
 
387
412
  async def __order_create(self, req: OrderRequest | OrderSellRequest, bor: BaseOrderReq) -> OrderResp:
388
- res: dict = await self._post("/fiat/otc/order/create", data=req.model_dump())
413
+ res: dict = await self._post("/x-api/fiat/otc/order/create", json=req.model_dump())
389
414
  if res["ret_code"] == 0:
390
415
  resp = OrderResp.model_validate(res["result"])
416
+ elif res["ret_code"] == 10001:
417
+ logging.error(req.model_dump(), "POST", self.session._base_url)
418
+ raise HTTPException()
391
419
  elif res["ret_code"] == 912120030 or res["ret_msg"] == "The price has changed, please try again later.":
392
420
  resp = await self._order_request(bor)
393
421
  if not resp.orderId and resp.needSecurityRisk:
@@ -401,15 +429,15 @@ class AgentClient(BaseAgentClient): # Bybit client
401
429
 
402
430
  async def cancel_order(self, order_id: str) -> bool:
403
431
  cr = CancelOrderReq(orderId=order_id)
404
- res = await self._post("/fiat/otc/order/cancel", cr.model_dump())
432
+ res = await self._post("/x-api/fiat/otc/order/cancel", cr.model_dump())
405
433
  return res["ret_code"] == 0
406
434
 
407
435
  def get_order_info(self, order_id: str) -> dict:
408
- data = self._post("/fiat/otc/order/info", json={"orderId": order_id})
436
+ data = self._post("/x-api/fiat/otc/order/info", json={"orderId": order_id})
409
437
  return data["result"]
410
438
 
411
439
  def get_chat_msg(self, order_id):
412
- data = self._post("/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
440
+ data = self._post("/x-api/fiat/otc/order/message/listpage", json={"orderId": order_id, "size": 100})
413
441
  msgs = [
414
442
  {"text": msg["message"], "type": msg["contentType"], "role": msg["roleType"], "user_id": msg["userId"]}
415
443
  for msg in data["result"]["result"]
@@ -418,14 +446,14 @@ class AgentClient(BaseAgentClient): # Bybit client
418
446
  return msgs
419
447
 
420
448
  def block_user(self, user_id: str):
421
- return self._post("/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
449
+ return self._post("/x-api/fiat/p2p/user/add_block_user", {"blockedUserId": user_id})
422
450
 
423
451
  def unblock_user(self, user_id: str):
424
- return self._post("/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
452
+ return self._post("/x-api/fiat/p2p/user/delete_block_user", {"blockedUserId": user_id})
425
453
 
426
454
  def user_review_post(self, order_id: str):
427
455
  return self._post(
428
- "/fiat/otc/order/appraise/modify",
456
+ "/x-api/fiat/otc/order/appraise/modify",
429
457
  {
430
458
  "orderId": order_id,
431
459
  "anonymous": "0",
@@ -445,7 +473,7 @@ class AgentClient(BaseAgentClient): # Bybit client
445
473
  self, side: int = None, status: int = None, begin_time: int = None, end_time: int = None, token_id: str = None
446
474
  ):
447
475
  return await self._post(
448
- "/fiat/otc/order/pending/simplifyList",
476
+ "/x-api/fiat/otc/order/pending/simplifyList",
449
477
  {
450
478
  "status": status,
451
479
  "tokenId": token_id,
@@ -459,7 +487,7 @@ class AgentClient(BaseAgentClient): # Bybit client
459
487
 
460
488
  def get_orders_done(self, begin_time: int, end_time: int, status: int, side: int, token_id: str):
461
489
  return self._post(
462
- "/fiat/otc/order/simplifyList",
490
+ "/x-api/fiat/otc/order/simplifyList",
463
491
  {
464
492
  "status": status, # 50 - завершено
465
493
  "tokenId": token_id,
@@ -944,15 +972,17 @@ class AgentClient(BaseAgentClient): # Bybit client
944
972
  bc, sc = mdl + mdl * (perc / 2), mdl - mdl * (perc / 2)
945
973
  return (bc, sc), hp, vmf, zplace
946
974
 
947
- async def take_ad(self, req: TakeAdReq):
948
- ad: Ad = Ad.model_validate(self.api.get_ad_details(itemId=req.ad_id))
975
+ async def _take_ad(self, req: TakeAdReq):
976
+ res = self.api.get_ad_details(itemId=req.ad_id)["result"]
977
+ ad: Ad = Ad.model_validate(res)
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,
985
+ coin_scale=ad.symbolInfo.token.scale,
956
986
  pm_id=req.pm_id,
957
987
  )
958
988
  resp: OrderResp = await self._order_request(bor)
@@ -47,7 +47,11 @@ class StatusApi(IntEnum):
47
47
  class TakeAdReq(BaseModel):
48
48
  ad_id: int | str
49
49
  amount: float
50
- pm_id: int = None
50
+ quantity: float = None
51
+ is_sell: bool
52
+ price: float
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
@@ -0,0 +1,84 @@
1
+ from asyncio import run
2
+ from uuid import uuid4
3
+
4
+ from pyro_client.client.file import FileClient
5
+ from xync_bot import XyncBot
6
+ from xync_client.Bybit.etype.order import TakeAdReq
7
+
8
+ from xync_client.loader import PAY_TOKEN, NET_TOKEN
9
+ from xync_schema import models
10
+ from xync_schema.enums import UserStatus
11
+
12
+ from xync_client.Abc.Agent import BaseAgentClient
13
+
14
+
15
+ class AgentClient(BaseAgentClient):
16
+ i: int = 0
17
+ headers = {
18
+ "accept-language": "ru,en;q=0.9",
19
+ "language:": "ru-RU",
20
+ "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",
21
+ }
22
+
23
+ async def _take_ad(self, req: TakeAdReq):
24
+ self.i = 33 if self.i > 9998 else self.i + 2
25
+ hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
26
+ auth = {
27
+ "p0": "hzE/loX7MBr0j8vnx7n5qY72DCChDHOiNG/ZAXbc0BrKIiwLc7cqg0vDdK15x/qArCO1xCX2jNqmtGO0aUxa0yrspnh2xX8tJnZ1oDbvkqPjcJuKdnvehVL2rMHVXOtC0ImfcZ++zfmIXrNFchhC+u2O9LqyjiHw8F5XNtdkMVWzcgs2tNAZmZiyliHDQso3WslCuRyp0iAogxT99DdP2A5bNoqOFvcurk0+/mMFskoeGwykq7OBVAGKhHwr4jbFFURGE5DYN1tKHUtIYkDaul5b+wpLn83IEYSEhwwxfSE+cy3VvKE7xPiAOf/ptmZa9s0FyALNb8jCeTLwa8Wh4stO0qM/flL0oOHXXA+dxiQtQIDOdFqOIKoDhPrZ9nnqq0V/UyhACk4Omf7dc9ElVtbNuX4Q/bgZefAE674y+IXvBHl9ss36kVOImui2xpT0lH+sc35pR8xht5SndOTz6+oiHLIr+z850DYSVpj06i343sSjTfQxNj1bKATpRTXgOVwPTUO67hMFSFFpNLQ7Mxl5IeKEXI7dZjud1qlxIVSPJAYe6m3vomY6jm4U50C11Nh9CXC9p9TcD0e7QPfchzoSiFjzkwCxfOjAsxWzKkSpSnoaQTHO58c6RieHszMsahazVqCQ9rtLJV4kJ65lKLPegKrBY/yI4gXQs0NdvtdFjdGd5EBTC1inr3g7PeSvNZc9PzN5y/x0oC5r2KGBY4CdxqWxzAnr7Tvnl2sL8MPZ6WDcizCnK6aegfl0Kk976MOlC221ZfPutfYTuyB4d1utADE82g2X63idNtF/h6iUl9bIsAKisoNzgUz26MCzkG/K++Cm/0/Sip40znh4lmT0z6XNhA4GiXmjbkxrhUsI4M8HiVRjuNWvrdq7D2l81j5K+JYHFWOaAUQuDNx+bB4eB9KJnHX03hxkJYfhYQtxr+X1LAPITWWfb+qmFy8x4+mWP1TVTBl27j7FAqWXnCL8FeJQ4sSP7Xphj3t7Fd62RtQewiq5L/BYegJGD3c9NvQBvC2gOXMuhTIE9RcQAUdXDsKKizZ4mXpXTvcGYXwednrVwz1SaLe8WhEe54e6tSLRf5Or3pce/7epsDqrKQXDeKugo6so//SN8y7wPsd8xpGeBtUjhvrESwNcRp305pYm4f+2A4lF71a92P6PHSOQm5ruGT7qB+9uwvzXIoFY985dI8aRq7g7GbAyQ1z7LhhjJzS11xUEpekunxdAxySl6OOFcAlTjnx8FgGBl2xiP+KtTJeSVB4b07OsqoUmAS54I0Sj19Tm8WQz+FKbKZ0eReApT+gyyqFJBSRcJYIyA3dLL/fYSNfNmNUu76KGR+o3xMHTSb8V/kVHmgWs6qmE98NE1BcXWnABiHVkqZU0lU/R0b9jhuUaYXB0md0VjyY61MztgfEk6VQnWfPQT/POuic6lBf4UJ3IWolsGttYlLo9sa9mAUqLXuDeSo+mTs7nDECVyYGZK/E+BCG+eEnhmwKB8dvY500kE/0Megf4i4Ymi0GG0jjy3z8VLsjP2cnUGrQHfe8d/etqgPN0CFI7crxEFoAeo8fl9VfEyr+ug61MWt+jcFtU2wfK66A75iPHobQpZVxW1tOv72PhiKTDWjgsLifJlYmFG1Eoadq8kiSEgkldsSCEYPTSjj4anXGSVBicRiaNliyQTuDT8DOjKmv3jGgu7opv/wKQ8Lz1FZDwL6i9WJExFzebdgJn+RNRZjpjWWKH0A9c0ZTd0Xa9q9WZyxEe8bycEkf4e4jnoalL4w==",
28
+ "k0": "Dt/l/MGcXIAOoCeR1L1VW5vTgqRcc4qqXzXrb6O+/a/2c9pHywRAVhPZZm46Us91VyNi2zg3S6Dzpe3FiwnC/NC1zwFAfKLIcKYgnDxTHesv5jUEYghDFlDsZFzCeY6b0TJ6ZlNr7+/NOQ4Hx1gbCsOlO0BrcMJ+DlqJlR7KM0od2SBWmbmJO1Dh25H/PzKnPhzq4NDuzHGcsDMrlkqmsKFHvkF01IiPVOCMFMdOWfCy3O4HGsSu3r9b/JvhxsC8hdfOZg1JKKDtKOGaHo8Fmajqozp39akG8EKk4C27hf2qDT2zh0LLrb3ZL0Gnd0y33LJTvUbYBSfFK1b7xv0i0A==",
29
+ "chash": "ccef0ebde038ce0e7cb086851c51781c498a429be65ab70bf4f46671c637516e",
30
+ "mtoken": "9482d04a3235e3090e954d3b6a8871e1",
31
+ "mhash": "06cabb6939e0262495aa5d55e44dfc27",
32
+ }
33
+ data = {
34
+ "scene": "TRADE_BUY",
35
+ "quantity": req.quantity,
36
+ "amount": req.amount,
37
+ "orderId": req.ad_id,
38
+ "authVersion": "v2",
39
+ "deviceId": auth["mtoken"],
40
+ }
41
+ res = await self._post("/api/verify/second_auth/risk/scene", json=data, hdrs=hdrs)
42
+ data = {
43
+ "amount": req.amount,
44
+ "authVersion": "v2",
45
+ "orderId": req.ad_id,
46
+ "price": req.price,
47
+ "ts": int(1761155700.8372989 * 1000),
48
+ "userConfirmPaymentId" if req.is_sell else "userConfirmPayMethodId": req.pm_id,
49
+ }
50
+ self.i = 33 if self.i > 9999 else self.i + 1
51
+ hdrs = self.headers | {"trochilus-trace-id": f"{uuid4()}-{self.i:04d}"}
52
+ res = await self._post("/api/order/deal?mhash=" + auth["mhash"], data=auth | data, hdrs=hdrs)
53
+ return res["data"]
54
+
55
+
56
+ async def main():
57
+ from x_model import init_db
58
+ from xync_client.loader import TORM
59
+
60
+ cn = await init_db(TORM, True)
61
+
62
+ agent = (
63
+ await models.Agent.filter(
64
+ actor__ex_id=12,
65
+ active=True,
66
+ auth__isnull=False,
67
+ actor__person__user__status=UserStatus.ACTIVE,
68
+ actor__person__user__pm_agents__isnull=False,
69
+ )
70
+ .prefetch_related("actor__ex", "actor__person__user__gmail")
71
+ .first()
72
+ )
73
+
74
+ bbot = XyncBot(PAY_TOKEN, cn)
75
+ fbot = FileClient(NET_TOKEN)
76
+
77
+ cl = agent.client(fbot, bbot)
78
+ req = TakeAdReq(ad_id="a1574088909645125632", amount=500, pm_id=366, cur_="RUB", price=85.8, is_sell=True)
79
+ res = await cl.take_ad(req)
80
+ print(res)
81
+
82
+
83
+ if __name__ == "__main__":
84
+ run(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.148
3
+ Version: 0.0.150
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -86,6 +86,7 @@ xync_client/KuCoin/ex.py
86
86
  xync_client/KuCoin/web.py
87
87
  xync_client/KuCoin/etype/ad.py
88
88
  xync_client/KuCoin/etype/pm.py
89
+ xync_client/Mexc/agent.py
89
90
  xync_client/Mexc/ex.py
90
91
  xync_client/Mexc/etype/ad.py
91
92
  xync_client/Mexc/etype/pm.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes