xync-client 0.0.151__tar.gz → 0.0.152__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 (127) hide show
  1. {xync_client-0.0.151/xync_client.egg-info → xync_client-0.0.152}/PKG-INFO +1 -1
  2. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/AdLoader.py +4 -13
  3. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Agent.py +18 -2
  4. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Ex.py +2 -1
  5. xync_client-0.0.152/xync_client/Abc/InAgent.py +10 -0
  6. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/InAgent.py +34 -37
  7. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/agent.py +69 -54
  8. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/etype/ad.py +10 -55
  9. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/etype/cred.py +28 -9
  10. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/etype/order.py +2 -38
  11. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/ex.py +12 -1
  12. {xync_client-0.0.151 → xync_client-0.0.152/xync_client.egg-info}/PKG-INFO +1 -1
  13. xync_client-0.0.151/xync_client/Abc/InAgent.py +0 -23
  14. {xync_client-0.0.151 → xync_client-0.0.152}/.env.sample +0 -0
  15. {xync_client-0.0.151 → xync_client-0.0.152}/.gitignore +0 -0
  16. {xync_client-0.0.151 → xync_client-0.0.152}/.pre-commit-config.yaml +0 -0
  17. {xync_client-0.0.151 → xync_client-0.0.152}/README.md +0 -0
  18. {xync_client-0.0.151 → xync_client-0.0.152}/__init__.py +0 -0
  19. {xync_client-0.0.151 → xync_client-0.0.152}/makefile +0 -0
  20. {xync_client-0.0.151 → xync_client-0.0.152}/pyproject.toml +0 -0
  21. {xync_client-0.0.151 → xync_client-0.0.152}/setup.cfg +0 -0
  22. {xync_client-0.0.151 → xync_client-0.0.152}/tests/TestAgent.py +0 -0
  23. {xync_client-0.0.151 → xync_client-0.0.152}/tests/TestAsset.py +0 -0
  24. {xync_client-0.0.151 → xync_client-0.0.152}/tests/TestEx.py +0 -0
  25. {xync_client-0.0.151 → xync_client-0.0.152}/tests/TestOrder.py +0 -0
  26. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Binance/test_binance.py +0 -0
  27. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  28. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  29. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Gate/test_gate.py +0 -0
  30. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  31. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  32. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/__init__.py +0 -0
  33. {xync_client-0.0.151 → xync_client-0.0.152}/tests/_todo_refact/_test_ex.py +0 -0
  34. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Asset.py +0 -0
  35. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Auth.py +0 -0
  36. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/BaseTest.py +0 -0
  37. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Exception.py +0 -0
  38. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/HasAbotUid.py +0 -0
  39. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/Order.py +0 -0
  40. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/PmAgent.py +0 -0
  41. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Abc/xtype.py +0 -0
  42. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/__init__.py +0 -0
  43. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/binance_async.py +0 -0
  44. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/earn_api.py +0 -0
  45. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/etype/ad.py +0 -0
  46. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/etype/pm.py +0 -0
  47. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/ex.py +0 -0
  48. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/exceptions.py +0 -0
  49. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/sapi.py +0 -0
  50. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Binance/web_c2c.py +0 -0
  51. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/__init__.py +0 -0
  52. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/agent.py +0 -0
  53. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/base.py +0 -0
  54. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/etype/ad.py +0 -0
  55. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/etype/pm.py +0 -0
  56. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/ex.py +0 -0
  57. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/req.mjs +0 -0
  58. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BingX/sign.js +0 -0
  59. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BitGet/__init__.py +0 -0
  60. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BitGet/agent.py +0 -0
  61. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BitGet/etype/ad.py +0 -0
  62. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BitGet/ex.py +0 -0
  63. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/BitPapa/ex.py +0 -0
  64. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/order.py +0 -0
  65. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/web_earn.py +0 -0
  66. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/web_p2p.py +0 -0
  67. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Bybit/ws.py +0 -0
  68. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Gate/etype/ad.py +0 -0
  69. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Gate/ex.py +0 -0
  70. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Gate/premarket.py +0 -0
  71. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Gmail/__init__.py +0 -0
  72. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/agent.py +0 -0
  73. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/earn.py +0 -0
  74. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/etype/__init__.py +0 -0
  75. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/etype/ad.py +0 -0
  76. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/etype/cred.py +0 -0
  77. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/etype/pm.py +0 -0
  78. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/etype/test.py +0 -0
  79. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Htx/ex.py +0 -0
  80. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/KuCoin/etype/ad.py +0 -0
  81. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/KuCoin/etype/pm.py +0 -0
  82. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/KuCoin/ex.py +0 -0
  83. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/KuCoin/web.py +0 -0
  84. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Mexc/agent.py +0 -0
  85. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Mexc/etype/ad.py +0 -0
  86. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Mexc/etype/pm.py +0 -0
  87. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Mexc/ex.py +0 -0
  88. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Okx/etype/ad.py +0 -0
  89. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Okx/etype/pm.py +0 -0
  90. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Okx/ex.py +0 -0
  91. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/.gitignore +0 -0
  92. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Alfa/__init__.py +0 -0
  93. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Alfa/state.json +0 -0
  94. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/MTS/__init__.py +0 -0
  95. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Ozon/__init__.py +0 -0
  96. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Payeer/.gitignore +0 -0
  97. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Payeer/__init__.py +0 -0
  98. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Payeer/api.py +0 -0
  99. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Payeer/login.py +0 -0
  100. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Sber/__init__.py +0 -0
  101. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Sber/utils.py +0 -0
  102. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  103. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Volet/__init__.py +0 -0
  104. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  105. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  106. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Volet/api.py +0 -0
  107. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Volet/pl.py +0 -0
  108. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Xync/__main__.py +0 -0
  109. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Xync/ed.py +0 -0
  110. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/Pms/Yandex/__init__.py +0 -0
  111. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/agent.py +0 -0
  112. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/asset.py +0 -0
  113. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/auth.py +0 -0
  114. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/ex.py +0 -0
  115. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/inAgent.py +0 -0
  116. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/order.py +0 -0
  117. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/pyd.py +0 -0
  118. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/pyro.py +0 -0
  119. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/TgWallet/web.py +0 -0
  120. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/__init__.py +0 -0
  121. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/details.py +0 -0
  122. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/loader.py +0 -0
  123. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client/pm_unifier.py +0 -0
  124. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client.egg-info/SOURCES.txt +0 -0
  125. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client.egg-info/dependency_links.txt +0 -0
  126. {xync_client-0.0.151 → xync_client-0.0.152}/xync_client.egg-info/requires.txt +0 -0
  127. {xync_client-0.0.151 → xync_client-0.0.152}/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.151
3
+ Version: 0.0.152
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
@@ -57,7 +57,6 @@ class AdLoader:
57
57
  coinex: models.CoinEx = None,
58
58
  curex: models.CurEx = None,
59
59
  rname: str = None,
60
- pms_from_cond: bool = False,
61
60
  ) -> models.Ad:
62
61
  if not maker:
63
62
  if not (maker := await models.Actor.get_or_none(exid=pad.userId, ex=self.ex)):
@@ -87,13 +86,13 @@ class AdLoader:
87
86
  price=int(float(pad.price) * cur_scale),
88
87
  premium=int(float(pad.premium) * 100),
89
88
  cond_id=cid,
89
+ status=self.ad_status(ad_upd.status),
90
90
  )
91
91
  try:
92
92
  ad_db, _ = await models.Ad.update_or_create(**df_unq)
93
93
  except OperationalError as e:
94
94
  raise e
95
- if not pms_from_cond:
96
- await ad_db.pms.add(*(await models.Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=pad.payments)))
95
+ await ad_db.pms.add(*(await models.Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=pad.payments)))
97
96
  return ad_db
98
97
 
99
98
  async def cond_load( # todo: refact from Bybit Ad format to universal
@@ -120,13 +119,7 @@ class AdLoader:
120
119
  # if not len((old_cond := await Cond.get(id=old_cid).prefetch_related('ads')).ads):
121
120
  # await old_cond.delete()
122
121
  # logging.warning(f"Cond#{old_cid} deleted!")
123
- return (
124
- ad_db
125
- or force
126
- and await self.ad_load(
127
- ad, cid, ps, coinex=coinex, curex=curex, rname=rname, pms_from_cond=pms_from_cond
128
- )
129
- ), False
122
+ return (ad_db or force and await self.ad_load(ad, cid, ps, coinex=coinex, curex=curex, rname=rname)), False
130
123
  # если эта объява в таким ид уже есть в бд, но с другим условием (или без), а текущего условия еще нет в бд
131
124
  if ad_db:
132
125
  await ad_db.fetch_related("cond__ads", "maker")
@@ -154,9 +147,7 @@ class AdLoader:
154
147
  return ad_db, False
155
148
 
156
149
  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
- )
150
+ ad_db = await self.ad_load(ad, cond.id, ps, coinex=coinex, curex=curex, rname=rname)
160
151
  ad_db.cond = cond
161
152
  return ad_db, True
162
153
 
@@ -1,10 +1,13 @@
1
1
  from abc import abstractmethod
2
+ from asyncio.tasks import gather
2
3
 
3
4
  from pydantic import BaseModel
4
5
  from pyro_client.client.file import FileClient
5
6
  from x_client import df_hdrs
6
7
  from x_client.aiohttp import Client as HttpClient
7
8
  from xync_bot import XyncBot
9
+ from xync_client.Abc.InAgent import BaseInAgentClient
10
+
8
11
  from xync_client.Bybit.etype.order import TakeAdReq
9
12
  from xync_schema import models
10
13
  from xync_schema.models import OrderStatus, Coin, Cur, Ad, AdStatus, Actor, Agent
@@ -15,13 +18,14 @@ from xync_client.Abc.xtype import CredExOut, BaseOrderReq, BaseAdUpdate
15
18
  from xync_client.Gmail import GmClient
16
19
 
17
20
 
18
- class BaseAgentClient(HttpClient):
21
+ class BaseAgentClient(HttpClient, BaseInAgentClient):
19
22
  bbot: XyncBot
20
23
  fbot: FileClient
21
24
 
22
25
  def __init__(
23
26
  self,
24
27
  agent: Agent,
28
+ ex_client: BaseExClient,
25
29
  fbot: FileClient,
26
30
  bbot: XyncBot,
27
31
  headers: dict[str, str] = df_hdrs,
@@ -32,8 +36,20 @@ class BaseAgentClient(HttpClient):
32
36
  self.agent: Agent = agent
33
37
  self.actor: Actor = agent.actor
34
38
  self.gmail = GmClient(agent.actor.person.user)
39
+ self.ex_client: BaseExClient = ex_client
35
40
  super().__init__(self.actor.ex.host_p2p, headers, cookies)
36
- self.ex_client: BaseExClient = self.actor.ex.client(fbot)
41
+
42
+ async def start(self):
43
+ tasks = []
44
+ if not self.is_started:
45
+ if self.agent.status & 1: # race
46
+ tasks.append(self.start_race())
47
+ if self.agent.status & 2: # in agent
48
+ tasks.append(self.start_listen())
49
+ if self.agent.status & 4: # for further
50
+ ...
51
+ self.is_started = True
52
+ return await gather(*tasks)
37
53
 
38
54
  # 0: Получшение ордеров в статусе status, по монете coin, в валюте coin, в направлении is_sell: bool
39
55
  @abstractmethod
@@ -17,6 +17,7 @@ from xync_client.pm_unifier import PmUnifier, PmUni
17
17
 
18
18
 
19
19
  class BaseExClient(HttpClient, AdLoader):
20
+ host: str = None
20
21
  cur_map: dict[int, str] = {}
21
22
  unifier_class: type = PmUnifier
22
23
  logo_pre_url: str
@@ -34,7 +35,7 @@ class BaseExClient(HttpClient, AdLoader):
34
35
  ):
35
36
  self.ex = ex
36
37
  self.bot = bot
37
- super().__init__(getattr(ex, attr), headers, cookies, proxy and proxy.str())
38
+ super().__init__(self.host or getattr(ex, attr), headers, cookies, proxy and proxy.str())
38
39
 
39
40
  @abstractmethod
40
41
  def pm_type_map(self, typ: models.PmEx) -> str: ...
@@ -0,0 +1,10 @@
1
+ from abc import abstractmethod
2
+
3
+
4
+ class BaseInAgentClient:
5
+ @abstractmethod
6
+ async def start_listen(self) -> bool: ...
7
+
8
+ # 3N: [T] - Уведомление об одобрении запроса на сделку
9
+ @abstractmethod
10
+ async def request_accepted_notify(self) -> int: ... # id
@@ -9,6 +9,7 @@ import websockets
9
9
  from asyncio import run, sleep
10
10
  from decimal import Decimal
11
11
 
12
+ from bybit_p2p import P2P
12
13
  from playwright.async_api import async_playwright
13
14
  from pydantic import ValidationError
14
15
  from pyro_client.client.file import FileClient
@@ -16,6 +17,7 @@ from tortoise.exceptions import IntegrityError
16
17
  from tortoise.timezone import now
17
18
  from tortoise.transactions import in_transaction
18
19
  from xync_bot import XyncBot
20
+ from xync_client.Bybit.ex import ExClient
19
21
 
20
22
  from xync_client.Abc.PmAgent import PmAgentClient
21
23
  from xync_schema import models
@@ -32,16 +34,17 @@ from xync_client.Bybit.etype.order import (
32
34
  )
33
35
  from xync_client.loader import NET_TOKEN, PAY_TOKEN
34
36
  from xync_client.Abc.InAgent import BaseInAgentClient
35
- from xync_client.Bybit.agent import AgentClient
36
37
 
37
38
 
38
39
  class InAgentClient(BaseInAgentClient):
39
- agent_client: AgentClient
40
+ actor: models.Actor
41
+ api: P2P
42
+ ex_client: ExClient
40
43
 
41
44
  async def start_listen(self):
42
- t = await self.agent_client.ott()
45
+ t = await self.ott()
43
46
  ts = int(float(t["time_now"]) * 1000)
44
- await self.ws_prv(self.agent_client.agent.auth["deviceId"], t["result"], ts)
47
+ await self.ws_prv(self.actor.agent.auth["deviceId"], t["result"], ts)
45
48
 
46
49
  # 3N: [T] - Уведомление об одобрении запроса на сделку
47
50
  async def request_accepted_notify(self) -> int: ... # id
@@ -87,11 +90,11 @@ class InAgentClient(BaseInAgentClient):
87
90
  except ValidationError as e:
88
91
  logging.error(e)
89
92
  logging.error(data["data"])
90
- order = self.agent_client.api.get_order_details(orderId=upd.id)
93
+ order = self.api.get_order_details(orderId=upd.id)
91
94
  order = OrderFull.model_validate(order["result"])
92
95
  order_db = await models.Order.get_or_none(
93
96
  exid=order.id, ad__exid=order.itemId
94
- ) or await self.agent_client.create_order(order)
97
+ ) or await self.create_order(order)
95
98
  match upd.status:
96
99
  case StatusApi.created:
97
100
  logging.info(f"Order {order.id} created at {order.createDate}")
@@ -136,7 +139,7 @@ class InAgentClient(BaseInAgentClient):
136
139
  continue
137
140
 
138
141
  # если висят незавершенные продажи с такой же суммой
139
- pos = (await self.agent_client.get_orders_active(1))["result"]
142
+ pos = (await self.get_orders_active(1))["result"]
140
143
  pos = [
141
144
  o
142
145
  for o in pos.get("items", [])
@@ -146,14 +149,14 @@ class InAgentClient(BaseInAgentClient):
146
149
  and int(order.createDate)
147
150
  < int(o["createDate"]) + 15 * 60 * 1000
148
151
  # get full_order from o, and cred or pm from full_order:
149
- and self.agent_client.api.get_order_details(orderId=o["id"])[
150
- "result"
151
- ]["paymentTermList"][0]["accountNo"]
152
+ and self.api.get_order_details(orderId=o["id"])["result"][
153
+ "paymentTermList"
154
+ ][0]["accountNo"]
152
155
  == order.paymentTermList[0].accountNo
153
156
  )
154
157
  ]
155
158
  curex = await models.CurEx.get(
156
- cur__ticker=order.currencyId, ex=self.agent_client.ex_client.ex
159
+ cur__ticker=order.currencyId, ex=self.ex_client.ex
157
160
  )
158
161
  pos_db = await models.Order.filter(
159
162
  exid__not=order.id,
@@ -163,16 +166,16 @@ class InAgentClient(BaseInAgentClient):
163
166
  created_at__gt=now() - timedelta(minutes=15),
164
167
  )
165
168
  if pos or pos_db:
166
- await self.agent_client.ex_client.bot.send(
169
+ await self.ex_client.bot.send(
167
170
  f"[Duplicate amount!]"
168
171
  f"(https://www.bybit.com/ru-RU/p2p/orderList/{order.id})",
169
- self.agent_client.actor.person.user.username_id,
172
+ self.actor.person.user.username_id,
170
173
  )
171
174
  logging.warning("Duplicate amount!")
172
175
  continue
173
176
 
174
177
  # !!! ОТПРАВЛЯЕМ ДЕНЬГИ !!!
175
- self.agent_client.api.release_assets(orderId=upd.id)
178
+ self.api.release_assets(orderId=upd.id)
176
179
  logging.info(
177
180
  f"Order {order.id} created, paid before #{tid}:{am} at {order.createDate}, and RELEASED at {now()}"
178
181
  )
@@ -236,14 +239,14 @@ class InAgentClient(BaseInAgentClient):
236
239
  case "RECEIVE":
237
240
  upd = Receive.model_validate(data["data"])
238
241
  if order_db := await models.Order.get_or_none(
239
- exid=upd.orderId, ad__maker__ex=self.agent_client.actor.ex
242
+ exid=upd.orderId, ad__maker__ex=self.actor.ex
240
243
  ).prefetch_related("ad__pair_side__pair", "cred__pmcur__cur"):
241
- im_taker = order_db.taker_id == self.agent_client.actor.id
244
+ im_taker = order_db.taker_id == self.actor.id
242
245
  im_buyer = order_db.ad.pair_side.is_sell == im_taker
243
246
  if order_db.ad.auto_msg != upd.message and upd.roleType == "user":
244
247
  msg, _ = await models.Msg.update_or_create(
245
248
  {
246
- "to_maker": upd.userId == self.agent_client.actor.exid and im_taker,
249
+ "to_maker": upd.userId == self.actor.exid and im_taker,
247
250
  "sent_at": datetime.fromtimestamp(float(upd.createDate) / 1000),
248
251
  },
249
252
  txt=upd.message,
@@ -262,7 +265,7 @@ class InAgentClient(BaseInAgentClient):
262
265
  if upd.orderStatus in (
263
266
  StatusApi.wait_for_buyer,
264
267
  ): # todo: тут приходит ордер.статус=10, хотя покупатель еще не нажал оплачено
265
- order = self.agent_client.api.get_order_details(orderId=upd.orderId)["result"]
268
+ order = self.api.get_order_details(orderId=upd.orderId)["result"]
266
269
  order = OrderFull.model_validate(order)
267
270
 
268
271
  case "CLEAR":
@@ -295,15 +298,13 @@ class InAgentClient(BaseInAgentClient):
295
298
  async def money_upd(self, order_db: models.Order):
296
299
  # обновляем остаток монеты
297
300
  await order_db.fetch_related("ad__pair_side__pair", "cred", "transfer")
298
- ass = await models.Asset.get(
299
- addr__coin_id=order_db.ad.pair_side.pair.coin_id, addr__actor=self.agent_client.actor
300
- )
301
+ ass = await models.Asset.get(addr__coin_id=order_db.ad.pair_side.pair.coin_id, addr__actor=self.actor)
301
302
  # обновляем остаток валюты
302
303
  fiat = await models.Fiat.get(
303
- cred__person_id=self.agent_client.actor.person_id, cred__pmcur_id=order_db.cred.pmcur_id
304
+ cred__person_id=self.actor.person_id, cred__pmcur_id=order_db.cred.pmcur_id
304
305
  ).prefetch_related("cred__pmcur__pm")
305
306
  fee = round(order_db.amount * (fiat.cred.pmcur.pm.fee or 0) * 0.0001)
306
- im_seller = order_db.ad.pair_side.is_sell == (_im_maker := order_db.ad.maker_id == self.agent_client.actor.id)
307
+ im_seller = order_db.ad.pair_side.is_sell == (_im_maker := order_db.ad.maker_id == self.actor.id)
307
308
  # k = int(im_seller) * 2 - 1 # im_seller: 1, im_buyer: -1
308
309
  if order_db.status == OrderStatus.created:
309
310
  if im_seller:
@@ -335,9 +336,9 @@ class InAgentClient(BaseInAgentClient):
335
336
  pma, cur = await self.get_pma_by_pmex(order_db)
336
337
  async with in_transaction():
337
338
  # отмечаем ордер на бирже "оплачен"
338
- pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.pmex_exid, ex=self.agent_client.actor.ex)
339
- credex = await models.CredEx.get(cred=order_db.cred, ex=self.agent_client.actor.ex)
340
- self.agent_client.api.mark_as_paid(
339
+ pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.pmex_exid, ex=self.actor.ex)
340
+ credex = await models.CredEx.get(cred=order_db.cred, ex=self.actor.ex)
341
+ self.api.mark_as_paid(
341
342
  orderId=str(order_db.exid),
342
343
  paymentType=pmex.exid, # pmex.exid
343
344
  paymentId=str(credex.exid), # credex.exid
@@ -346,7 +347,7 @@ class InAgentClient(BaseInAgentClient):
346
347
  if t := await models.Transfer.get_or_none(order=order_db, amount=order_db.amount):
347
348
  await pma.bot.send(
348
349
  f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {order_db.cred.detail} #{t.pmid}!",
349
- self.agent_client.actor.person.user.username_id,
350
+ self.actor.person.user.username_id,
350
351
  )
351
352
  raise Exception(
352
353
  f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {order_db.cred.detail} #{t.pmid}!"
@@ -367,23 +368,19 @@ class InAgentClient(BaseInAgentClient):
367
368
 
368
369
  async def send_receipt(self, oexid: str, tid: int) -> tuple[PmAgentClient | None, models.CredEx] | None:
369
370
  try:
370
- if res := self.agent_client.api.upload_chat_file(upload_file=f"tmp/{tid}.png").get("result"):
371
+ if res := self.api.upload_chat_file(upload_file=f"tmp/{tid}.png").get("result"):
371
372
  await sleep(0.5)
372
- self.agent_client.api.send_chat_message(
373
- orderId=oexid, contentType="pic", message=res["url"], msgUuid=uuid4().hex
374
- )
373
+ self.api.send_chat_message(orderId=oexid, contentType="pic", message=res["url"], msgUuid=uuid4().hex)
375
374
  except Exception as e:
376
375
  logging.error(e)
377
376
  await sleep(0.5)
378
- self.agent_client.api.send_chat_message(
379
- orderId=oexid, contentType="str", message=f"#{tid}", msgUuid=uuid4().hex
380
- )
377
+ self.api.send_chat_message(orderId=oexid, contentType="str", message=f"#{tid}", msgUuid=uuid4().hex)
381
378
 
382
379
  async def get_pma_by_cdex(self, order: OrderFull) -> tuple[PmAgentClient | None, models.CredEx] | None:
383
380
  cdxs = await models.CredEx.filter(
384
- ex=self.agent_client.ex_client.ex,
381
+ ex=self.ex_client.ex,
385
382
  exid__in=[ptl.id for ptl in order.paymentTermList],
386
- cred__person=self.agent_client.actor.person,
383
+ cred__person=self.actor.person,
387
384
  ).prefetch_related("cred__pmcur__cur")
388
385
  pmas = [pma for cdx in cdxs if (pma := self.pmacs.get(cdx.cred.pmcur.pmex_exid))]
389
386
  if not len(pmas):
@@ -445,7 +442,7 @@ async def main():
445
442
  except Exception as e:
446
443
  await b.send("😱Bybit InAgent CRASHED!!!😱", agent.actor.person.user.username_id)
447
444
  await b.send(f"```\n{''.join(traceback.format_exception(e))}\n```", agent.actor.person.user.username_id)
448
- await cl.agent_client.close()
445
+ await cl.close()
449
446
 
450
447
 
451
448
  if __name__ == "__main__":
@@ -26,14 +26,15 @@ from x_client import df_hdrs
26
26
  from x_model import init_db
27
27
  from x_model.func import ArrayAgg
28
28
  from xync_bot import XyncBot
29
+ from xync_client.Bybit.ex import ExClient
29
30
  from xync_schema import models
30
- from xync_schema.enums import OrderStatus
31
+ from xync_schema.enums import OrderStatus, AgentStatus
31
32
 
32
33
  from xync_schema.models import Actor, PmCur, Agent
33
34
 
34
35
  from xync_client.Abc.Agent import BaseAgentClient
35
36
  from xync_client.Abc.xtype import FlatDict, BaseOrderReq
36
- from xync_client.Bybit.etype.ad import AdPostRequest, AdUpdateRequest, Ad, AdStatus
37
+ from xync_client.Bybit.etype.ad import AdPostRequest, AdUpdateRequest, Ad, AdStatus, MyAd
37
38
  from xync_client.Bybit.etype.cred import CredEpyd
38
39
  from xync_client.Bybit.etype.order import (
39
40
  OrderRequest,
@@ -88,8 +89,8 @@ class AgentClient(BaseAgentClient): # Bybit client
88
89
  "securityRiskToken": "",
89
90
  }
90
91
 
91
- def __init__(self, agent: Agent, fbot: FileClient, bbot: XyncBot, **kwargs):
92
- super().__init__(agent, fbot, bbot, **kwargs)
92
+ def __init__(self, agent: Agent, ex_client: ExClient, fbot: FileClient, bbot: XyncBot, **kwargs):
93
+ super().__init__(agent, ex_client, fbot, bbot, **kwargs)
93
94
  self.sec_hdrs = {
94
95
  "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
95
96
  "gdfp": agent.auth["Risktoken"],
@@ -154,15 +155,24 @@ class AgentClient(BaseAgentClient): # Bybit client
154
155
  raise Exception(f"Set default cur for {pmex.name}")
155
156
  if not (pmcur := await models.PmCur.get_or_none(cur_id=cur_id, pm_id=pmex.pm_id)):
156
157
  raise HTTPException(f"No PmCur with cur#{ecdx.currencyBalance} and pm#{ecdx.paymentType}", 404)
157
- dct = {
158
- "pmcur_id": pmcur.id,
159
- "name": ecdx.realName,
160
- "person_id": pers_id or self.actor.person_id,
161
- "detail": ecdx.accountNo,
162
- "extra": ecdx.branchName or ecdx.bankName or ecdx.qrcode or ecdx.payMessage or ecdx.paymentExt1,
163
- } # todo: WTD with multicur pms?
164
- cred_in = models.Cred.validate(dct, False)
165
- cred_db, _ = await models.Cred.update_or_create(**cred_in.df_unq())
158
+ xtr = ecdx.branchName
159
+ if ecdx.bankName:
160
+ xtr += (" | " if xtr else "") + ecdx.bankName
161
+ elif ecdx.payMessage:
162
+ xtr += (" | " if xtr else "") + ecdx.payMessage
163
+ elif ecdx.qrcode:
164
+ xtr += (" | " if xtr else "") + ecdx.qrcode
165
+ elif ecdx.paymentExt1:
166
+ xtr += (" | " if xtr else "") + ecdx.paymentExt1
167
+ cred_db, _ = await models.Cred.update_or_create(
168
+ {
169
+ "name": ecdx.realName,
170
+ "extra": xtr,
171
+ },
172
+ pmcur=pmcur,
173
+ person_id=pers_id or self.actor.person_id,
174
+ detail=ecdx.accountNo,
175
+ )
166
176
  credex_in = models.CredEx.validate({"exid": ecdx.id, "cred_id": cred_db.id, "ex_id": self.actor.ex.id})
167
177
  credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
168
178
  return credex_db
@@ -249,9 +259,9 @@ class AgentClient(BaseAgentClient): # Bybit client
249
259
  ads = [ad for ad in list_ads if set(ad["payments"]) - {"5", "51"}]
250
260
  return float(ads[0]["price"])
251
261
 
252
- def my_ads(self, active: bool = True, page: int = 1) -> list[Ad]:
262
+ def my_ads(self, active: bool = True, page: int = 1) -> list[MyAd]:
253
263
  resp = self.api.get_ads_list(size="30", page=str(page), status=AdStatus.active if active else AdStatus.sold_out)
254
- ads = [Ad.model_validate(ad) for ad in resp["result"]["items"]]
264
+ ads = [MyAd.model_validate(ad) for ad in resp["result"]["items"]]
255
265
  if resp["result"]["count"] > 30 * page:
256
266
  ads.extend(self.my_ads(active, page + 1))
257
267
  return ads
@@ -260,9 +270,13 @@ class AgentClient(BaseAgentClient): # Bybit client
260
270
  ads = self.my_ads(True)
261
271
  if not active:
262
272
  ads += self.my_ads(False)
263
- res = [await self.ex_client.ad_load(ad, maker=self.actor) for ad in ads]
264
- res = [await models.MyAd.update_or_create(ad=ad) for ad in res]
265
- return len(res)
273
+ for ad in ads:
274
+ ad_db = await self.ex_client.ad_load(ad, maker=self.actor)
275
+ mad_db, _ = await models.MyAd.update_or_create(ad=ad_db)
276
+ exids = [pt.id for pt in ad.paymentTerms]
277
+ credexs = await models.CredEx.filter(ex_id=self.actor.ex_id, exid__in=exids)
278
+ await mad_db.creds.add(*credexs)
279
+ return len(ads)
266
280
 
267
281
  def get_security_token_create(self):
268
282
  data = self._post("/x-api/fiat/otc/item/create", self.create_ad_body)
@@ -741,10 +755,15 @@ class AgentClient(BaseAgentClient): # Bybit client
741
755
  # if round(cpc * new_premium / cpm, 2) == m
742
756
  # mad.premium = new_premium.to_eng_string()
743
757
 
744
- async def racing(
745
- self,
746
- race: models.Race,
747
- ):
758
+ async def start_race(self):
759
+ races = await models.Race.filter(started=True, road__ad__maker_id=self.actor.id).prefetch_related(
760
+ "road__ad__pair_side__pair__cur",
761
+ "road__ad__pms",
762
+ )
763
+ tasks = [asyncio.create_task(self.racing(race), name=f"Rc{race.id}") for race in races]
764
+ return await gather(*tasks)
765
+
766
+ async def racing(self, race: models.Race):
748
767
  coinex: models.CoinEx = await models.CoinEx.get(
749
768
  coin_id=race.road.ad.pair_side.pair.coin_id, ex=self.actor.ex
750
769
  ).prefetch_related("coin")
@@ -1099,23 +1118,26 @@ class ExcCode(IntEnum):
1099
1118
  Unknown = 912300014
1100
1119
 
1101
1120
 
1121
+ @post_save(models.Race)
1122
+ async def race_upserted(
1123
+ _cls: type[models.Race], race: models.Race, created: bool, _db: BaseDBAsyncClient, _updated: list[str]
1124
+ ):
1125
+ logging.warning(f"Race {race.id} is now upserted")
1126
+ asyncio.all_tasks()
1127
+ if created:
1128
+ ...
1129
+ else: # параметры гонки изменены
1130
+ ...
1131
+
1132
+
1102
1133
  async def main():
1103
1134
  logging.basicConfig(level=logging.INFO)
1104
1135
  cn = await init_db(TORM)
1105
1136
 
1106
- @post_save(models.Race)
1107
- async def race_upserted(
1108
- _cls: type[models.Race], race: models.Race, created: bool, _db: BaseDBAsyncClient, _updated: list[str]
1109
- ):
1110
- logging.warning(f"Race {race.id} is now upserted")
1111
- asyncio.all_tasks()
1112
- if created:
1113
- ...
1114
- else: # параметры гонки изменены
1115
- ...
1116
-
1117
1137
  agent = (
1118
- await models.Agent.filter(actor__ex_id=4, auth__isnull=False, active=True, actor__person__user__id=2)
1138
+ await models.Agent.filter(
1139
+ actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, actor__person__user__id=1
1140
+ )
1119
1141
  .prefetch_related(
1120
1142
  "actor__ex",
1121
1143
  "actor__person__user__gmail",
@@ -1128,15 +1150,24 @@ async def main():
1128
1150
  filebot = FileClient(NET_TOKEN)
1129
1151
  # await filebot.start()
1130
1152
  # b.add_handler(MessageHandler(cond_start_handler, command("cond")))
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)
1153
+ ex = await models.Ex.get(name="Bybit")
1154
+ ecl: ExClient = ex.client(filebot)
1155
+ cl: AgentClient = agent.client(ecl, filebot, XyncBot(PAY_TOKEN, cn))
1156
+
1157
+ # req = TakeAdReq(ad_id=1955696985964089344, amount=504, pm_id=128)
1158
+ # await cl.take_ad(req)
1159
+
1160
+ # await cl.actual_cond()
1161
+ # cl.get_api_orders(), # 10, 1738357200000, 1742504399999
1134
1162
 
1135
1163
  # await cl.ex_client.set_pairs()
1136
1164
  # await cl.ex_client.set_pms()
1137
- await cl.set_creds()
1165
+
1166
+ # await cl.set_creds()
1138
1167
  await cl.export_my_ads()
1139
1168
 
1169
+ await cl.start()
1170
+
1140
1171
  # создание гонок по мои активным объявам:
1141
1172
  # for ma in cl.my_ads():
1142
1173
  # my_ad = await models.MyAd.get(ad__exid=ma.id).prefetch_related('ad__pms', 'ad__pair_side__pair')
@@ -1161,22 +1192,6 @@ async def main():
1161
1192
  # )
1162
1193
  # await cl.get_api_orders() # 43, 1741294800000, 1749157199999)
1163
1194
 
1164
- races = await models.Race.filter(started=True, road__ad__maker_id=agent.actor_id).prefetch_related(
1165
- "road__ad__pair_side__pair__cur",
1166
- "road__ad__pms",
1167
- )
1168
- tasks = [asyncio.create_task(cl.racing(race), name=f"Rc{race.id}") for race in races]
1169
- # await cl.actual_cond()
1170
- try:
1171
- await gather(
1172
- *tasks
1173
- # cl.get_api_orders(), # 10, 1738357200000, 1742504399999
1174
- )
1175
- except Exception as e:
1176
- await filebot.send("🤬Bybit agent CRASHED!!!🤬", agent.actor.person.user.username_id)
1177
- await filebot.send(e.__repr__(), agent.actor.person.user.username_id)
1178
- raise e
1179
-
1180
1195
  # await cl.cancel_order(res.orderId)
1181
1196
  await filebot.stop()
1182
1197
  await cl.close()
@@ -1,7 +1,7 @@
1
1
  from enum import StrEnum
2
2
  from typing import List, Optional, Any, Literal
3
- from pydantic import BaseModel, Field, field_serializer
4
- from xync_schema import xtype
3
+ from pydantic import BaseModel, Field
4
+ from xync_client.Bybit.etype.cred import MyPaymentTerm
5
5
  from xync_schema.xtype import BaseAd
6
6
 
7
7
  from xync_client.Abc.xtype import BaseAdUpdate
@@ -126,59 +126,14 @@ class Ad(BaseAd):
126
126
  verificationOrderLabels: List[Any] = None # for initial actualize
127
127
  verificationOrderSwitch: bool = None # for initial actualize
128
128
  version: int = None # for initial actualize
129
- #
130
- #
131
- # class Ad(BaseAd):
132
- # accountId: str = None # for initial actualize
133
- # authStatus: int = None # for initial actualize
134
- # authTag: List[str] = None # for initial actualize
135
- # ban: bool = None # for initial actualize
136
- # baned: bool = None # for initial actualize
137
- # blocked: str = None # for initial actualize
138
- # createDate: str = None # for initial actualize
139
- # currencyId: str = None # for initial actualize
140
- # executedQuantity: str = None # for initial actualize
141
- # fee: str = None # for initial actualize
142
- # finishNum: int = None # for initial actualize
143
- # frozenQuantity: str = None # for initial actualize
144
- # exid: str = Field(serialization_alias="id")
145
- # isOnline: bool = None # for initial actualize
146
- # itemType: str = None # for initial actualize
147
- # lastLogoutTime: str = None # for initial actualize
148
- # quantity: str = Field(serialization_alias="lastQuantity")
149
- # makerContact: bool = None # for initial actualize
150
- # max_fiat: str = Field(serialization_alias="maxAmount")
151
- # min_fiat: str = Field(serialization_alias="minAmount")
152
- # nickName: str = None # for initial actualize
153
- # orderNum: int = None # for initial actualize
154
- # paymentPeriod: int = None # for initial actualize
155
- # payments: List[str] = None # for initial actualize
156
- # premium: str = None # for initial actualize
157
- # price: str = None # for initial actualize
158
- # priceType: Literal[0, 1] = None # for initial actualize # 0 - fix rate, 1 - floating
159
- # allQuantity: str = Field(serialization_alias="quantity") # for initial actualize
160
- # recentExecuteRate: int = None # for initial actualize
161
- # recentOrderNum: int = None # for initial actualize
162
- # recommend: bool = None # for initial actualize
163
- # recommendTag: str = None # for initial actualize
164
- # auto_msg: str = Field(serialization_alias="remark")
165
- # is_sell: Literal[0, 1] = Field(serialization_alias="side") # for initial actualize # 0 - покупка, 1 - продажа (для мейкера, т.е КАКАЯ объява)
166
- # status: Literal[10, 20, 30] # 10: online; 20: offline; 30: completed
167
- # symbolInfo: SymbolInfo = None # for initial actualize
168
- # tokenId: str = None # for initial actualize
169
- # tokenName: str = None # for initial actualize
170
- # tradingPreferenceSet: TradingPreferenceSet | None = None # for initial actualize
171
- # userId: str = Field(serialization_alias="maker__exid")
172
- # userMaskId: str = None # for initial actualize
173
- # userType: str = None # for initial actualize
174
- # verificationOrderAmount: str = None # for initial actualize
175
- # verificationOrderLabels: List[Any] = None # for initial actualize
176
- # verificationOrderSwitch: bool = None # for initial actualize
177
- # version: int = None # for initial actualize
178
-
179
- @field_serializer("status")
180
- def status(self, status, _info) -> xtype.AdStatus:
181
- return {10: xtype.AdStatus.active, 20: xtype.AdStatus.defActive, 30: xtype.AdStatus.soldOut}[status]
129
+
130
+ # @field_serializer("status")
131
+ # def status(self, status, _info) -> xtype.AdStatus:
132
+ # return {10: xtype.AdStatus.active, 20: xtype.AdStatus.defActive, 30: xtype.AdStatus.soldOut}[status]
133
+
134
+
135
+ class MyAd(Ad):
136
+ paymentTerms: List[MyPaymentTerm]
182
137
 
183
138
 
184
139
  class AdPostRequest(BaseModel):