xync-client 0.0.114__py3-none-any.whl → 0.0.155__py3-none-any.whl

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.
Files changed (39) hide show
  1. xync_client/Abc/AdLoader.py +299 -0
  2. xync_client/Abc/Agent.py +94 -10
  3. xync_client/Abc/Ex.py +27 -22
  4. xync_client/Abc/HasAbotUid.py +10 -0
  5. xync_client/Abc/InAgent.py +0 -11
  6. xync_client/Abc/PmAgent.py +42 -35
  7. xync_client/Abc/xtype.py +24 -2
  8. xync_client/Binance/ex.py +2 -2
  9. xync_client/BingX/ex.py +2 -2
  10. xync_client/BitGet/ex.py +2 -2
  11. xync_client/Bybit/InAgent.py +229 -114
  12. xync_client/Bybit/agent.py +584 -572
  13. xync_client/Bybit/etype/ad.py +11 -56
  14. xync_client/Bybit/etype/cred.py +29 -9
  15. xync_client/Bybit/etype/order.py +55 -62
  16. xync_client/Bybit/ex.py +17 -4
  17. xync_client/Gate/ex.py +2 -2
  18. xync_client/Gmail/__init__.py +119 -98
  19. xync_client/Htx/agent.py +162 -31
  20. xync_client/Htx/etype/ad.py +18 -11
  21. xync_client/Htx/ex.py +9 -11
  22. xync_client/KuCoin/ex.py +2 -2
  23. xync_client/Mexc/agent.py +85 -0
  24. xync_client/Mexc/api.py +636 -0
  25. xync_client/Mexc/etype/order.py +639 -0
  26. xync_client/Mexc/ex.py +12 -10
  27. xync_client/Okx/ex.py +2 -2
  28. xync_client/Pms/Payeer/__init__.py +147 -43
  29. xync_client/Pms/Payeer/login.py +29 -2
  30. xync_client/Pms/Volet/__init__.py +148 -94
  31. xync_client/Pms/Volet/api.py +17 -13
  32. xync_client/TgWallet/ex.py +2 -2
  33. xync_client/details.py +44 -0
  34. xync_client/loader.py +2 -1
  35. xync_client/pm_unifier.py +1 -1
  36. {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/METADATA +6 -1
  37. {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/RECORD +39 -33
  38. {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/WHEEL +0 -0
  39. {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/top_level.txt +0 -0
@@ -1,23 +1,28 @@
1
1
  import json
2
2
  import logging
3
3
  import re
4
- from datetime import datetime, timezone
4
+ import traceback
5
+ from datetime import datetime, timezone, timedelta
5
6
  from uuid import uuid4
6
7
 
7
8
  import websockets
8
- from asyncio import run
9
+ from asyncio import run, sleep
9
10
  from decimal import Decimal
10
11
 
12
+ from bybit_p2p import P2P
11
13
  from playwright.async_api import async_playwright
14
+ from pydantic import ValidationError
12
15
  from pyro_client.client.file import FileClient
16
+ from tortoise.exceptions import IntegrityError
17
+ from tortoise.timezone import now
13
18
  from tortoise.transactions import in_transaction
14
- from xync_schema.models import CredEx
19
+ from xync_bot import XyncBot
20
+ from xync_client.Bybit.ex import ExClient
15
21
 
16
22
  from xync_client.Abc.PmAgent import PmAgentClient
17
23
  from xync_schema import models
18
24
  from xync_schema.enums import UserStatus, OrderStatus
19
25
 
20
- from xync_client.Pms.Payeer import Client
21
26
  from xync_client.Bybit.etype.order import (
22
27
  StatusChange,
23
28
  CountDown,
@@ -27,18 +32,21 @@ from xync_client.Bybit.etype.order import (
27
32
  OrderFull,
28
33
  StatusApi,
29
34
  )
30
- from xync_client.loader import TOKEN
35
+ from xync_client.loader import NET_TOKEN, PAY_TOKEN
31
36
  from xync_client.Abc.InAgent import BaseInAgentClient
32
- from xync_client.Bybit.agent import AgentClient
33
37
 
34
38
 
35
39
  class InAgentClient(BaseInAgentClient):
36
- agent_client: AgentClient
40
+ actor: models.Actor
41
+ agent: models.Agent
42
+ api: P2P
43
+ ex_client: ExClient
44
+ pm_clients: dict[int, PmAgentClient]
37
45
 
38
46
  async def start_listen(self):
39
- t = await self.agent_client.ott()
47
+ t = await self.ott()
40
48
  ts = int(float(t["time_now"]) * 1000)
41
- await self.ws_prv(self.agent_client.actor.agent.auth["deviceId"], t["result"], ts)
49
+ await self.ws_prv(self.agent.auth["deviceId"], t["result"], ts)
42
50
 
43
51
  # 3N: [T] - Уведомление об одобрении запроса на сделку
44
52
  async def request_accepted_notify(self) -> int: ... # id
@@ -74,76 +82,126 @@ class InAgentClient(BaseInAgentClient):
74
82
  while resp := await websocket.recv():
75
83
  if data := json.loads(resp):
76
84
  upd, order_db = None, None
77
- logging.info(f" {datetime.now().strftime('%H:%M:%S')} upd: {data.get('topic')}:{data.get('type')}")
85
+ logging.info(f" {now().strftime('%H:%M:%S')} upd: {data.get('topic')}:{data.get('type')}")
78
86
  match data.get("topic"):
79
87
  case "OTC_ORDER_STATUS":
80
88
  match data["type"]:
81
89
  case "STATUS_CHANGE":
82
- upd = StatusChange.model_validate(data["data"])
83
- order = self.agent_client.api.get_order_details(orderId=upd.id)
90
+ try:
91
+ upd = StatusChange.model_validate(data["data"])
92
+ except ValidationError as e:
93
+ logging.error(e)
94
+ logging.error(data["data"])
95
+ order = self.api.get_order_details(orderId=upd.id)
84
96
  order = OrderFull.model_validate(order["result"])
85
97
  order_db = await models.Order.get_or_none(
86
98
  exid=order.id, ad__exid=order.itemId
87
- ) or await self.agent_client.create_order(order)
99
+ ) or await self.create_order(order)
88
100
  match upd.status:
89
101
  case StatusApi.created:
90
102
  logging.info(f"Order {order.id} created at {order.createDate}")
91
- if upd.side == 1: # я покупатель - ждем мою оплату
92
- dest = order.paymentTermList[0].accountNo
93
- if not re.match(r"^P\d{8,10}$", dest):
103
+ # сразу уменьшаем доступный остаток монеты/валюты
104
+ await self.money_upd(order_db)
105
+ if upd.side: # я покупатель - ждем мою оплату
106
+ _dest = order.paymentTermList[0].accountNo
107
+ if not re.match(r"^([PpРр])\d{7,10}\b", _dest):
94
108
  continue
95
109
  await order_db.fetch_related("ad__pair_side__pair", "cred__pmcur__cur")
96
- await self.send_payment(order_db, dest)
110
+ await self.send_payment(order_db)
97
111
  case StatusApi.wait_for_buyer:
98
112
  if upd.side == 0: # ждем когда покупатель оплатит
99
113
  if not (pmacdx := await self.get_pma_by_cdex(order)):
100
114
  continue
101
115
  pma, cdx = pmacdx
102
- am, tid = pma.check_in(
116
+ am, tid = await pma.check_in(
103
117
  Decimal(order.amount),
104
118
  cdx.cred.pmcur.cur.ticker,
105
- datetime.fromtimestamp(float(order.createDate) / 1000),
119
+ # todo: почему в московском час.поясе?
120
+ datetime.fromtimestamp(float(order.transferDate) / 1000),
106
121
  )
107
122
  if not tid:
108
123
  logging.info(
109
124
  f"Order {order.id} created at {order.createDate}, not paid yet"
110
125
  )
111
126
  continue
112
- t, is_new = await models.Transfer.update_or_create(
113
- dict(
114
- amount=int(float(order.amount) * 100),
115
- accepted_at=datetime.now(timezone.utc),
116
- ),
117
- order=order_db,
118
- pmid=tid,
119
- )
120
- if not is_new:
127
+ try:
128
+ t, is_new = await models.Transfer.update_or_create(
129
+ dict(
130
+ amount=int(float(order.amount) * 100),
131
+ order=order_db,
132
+ ),
133
+ pmid=tid,
134
+ )
135
+ except IntegrityError as e:
136
+ logging.error(tid)
137
+ logging.error(order)
138
+ logging.exception(e)
139
+
140
+ if not is_new: # если по этому платежу уже отпущен другая продажа
121
141
  continue
122
- await order_db.fetch_related("ad__pair_side__pair")
123
- async with in_transaction():
124
- # добавляем остаток монеты
125
- ass = await models.Asset.get(
126
- addr__coin_id=order_db.ad.pair_side.pair.coin_id,
127
- addr__actor=self.agent_client.actor,
142
+
143
+ # если висят незавершенные продажи с такой же суммой
144
+ pos = (await self.get_orders_active(1))["result"]
145
+ pos = [
146
+ o
147
+ for o in pos.get("items", [])
148
+ if (
149
+ o["amount"] == order.amount
150
+ and o["id"] != upd.id
151
+ and int(order.createDate)
152
+ < int(o["createDate"]) + 15 * 60 * 1000
153
+ # get full_order from o, and cred or pm from full_order:
154
+ and self.api.get_order_details(orderId=o["id"])["result"][
155
+ "paymentTermList"
156
+ ][0]["accountNo"]
157
+ == order.paymentTermList[0].accountNo
128
158
  )
129
- ass.free -= int(order_db.amount / order_db.ad.price)
130
- await ass.save(update_fields=["free"])
131
- # обновляем остаток валюты
132
- fiat = await models.Fiat.get(cred_id=order_db.cred_id)
133
- fiat.amount += order_db.amount
134
- await fiat.save(update_fields=["amount"])
135
- # отправляем деньги
136
- self.agent_client.api.release_assets(orderId=upd.id)
137
- logging.info(
138
- f"Order {order.id} created, paid before #{tid}:{am} at {order.createDate}, and RELEASED at {datetime.now()}"
159
+ ]
160
+ curex = await models.CurEx.get(
161
+ cur__ticker=order.currencyId, ex=self.ex_client.ex
162
+ )
163
+ pos_db = await models.Order.filter(
164
+ exid__not=order.id,
165
+ cred_id=order_db.cred_id,
166
+ amount=int(float(order.amount) * 10**curex.scale),
167
+ status__not_in=[OrderStatus.completed, OrderStatus.canceled],
168
+ created_at__gt=now() - timedelta(minutes=15),
169
+ )
170
+ if pos or pos_db:
171
+ await self.ex_client.bot.send(
172
+ f"[Duplicate amount!]"
173
+ f"(https://www.bybit.com/ru-RU/p2p/orderList/{order.id})",
174
+ self.actor.person.user.username_id,
139
175
  )
176
+ logging.warning("Duplicate amount!")
177
+ continue
178
+
179
+ # !!! ОТПРАВЛЯЕМ ДЕНЬГИ !!!
180
+ self.api.release_assets(orderId=upd.id)
181
+ logging.info(
182
+ f"Order {order.id} created, paid before #{tid}:{am} at {order.createDate}, and RELEASED at {now()}"
183
+ )
140
184
  elif upd.side == 1: # я покупатель - ждем мою оплату
141
- continue # logging.warning(f"Order {order.id} PAID at {datetime.now()}: {int_am}")
185
+ continue # logging.warning(f"Order {order.id} PAID at {now()}: {int_am}")
142
186
  else:
143
187
  ...
144
188
  # todo: check is always canceling
145
189
  # await order_db.update_from_dict({"status": OrderStatus.canceled}).save()
146
190
  # logging.info(f"Order {order.id} canceled at {datetime.now()}")
191
+
192
+ case StatusApi.wait_for_seller:
193
+ if order_db.status == OrderStatus.paid:
194
+ continue
195
+ await order_db.update_from_dict(
196
+ {
197
+ "status": OrderStatus.paid,
198
+ "payed_at": datetime.fromtimestamp(
199
+ float(order.transferDate) / 1000
200
+ ),
201
+ }
202
+ ).save()
203
+ logging.info(f"Order {order.id} payed at {order_db.payed_at}")
204
+
147
205
  case StatusApi.appealed:
148
206
  # todo: appealed by WHO? щас наугад стоит by_seller
149
207
  await order_db.update_from_dict(
@@ -155,9 +213,12 @@ class InAgentClient(BaseInAgentClient):
155
213
  }
156
214
  ).save()
157
215
  logging.info(f"Order {order.id} appealed at {order_db.appealed_at}")
216
+
158
217
  case StatusApi.canceled:
159
218
  await order_db.update_from_dict({"status": OrderStatus.canceled}).save()
160
219
  logging.info(f"Order {order.id} canceled at {datetime.now()}")
220
+ await self.money_upd(order_db)
221
+
161
222
  case StatusApi.completed:
162
223
  await order_db.update_from_dict(
163
224
  {
@@ -167,19 +228,8 @@ class InAgentClient(BaseInAgentClient):
167
228
  ),
168
229
  }
169
230
  ).save()
170
- logging.info(f"Order {order.id} completed at {order_db.confirmed_at}")
171
- case StatusApi.wait_for_seller:
172
- if order_db.status == OrderStatus.paid:
173
- continue
174
- await order_db.update_from_dict(
175
- {
176
- "status": OrderStatus.paid,
177
- "payed_at": datetime.fromtimestamp(
178
- float(order.transferDate) / 1000
179
- ),
180
- }
181
- ).save()
182
- logging.info(f"Order {order.id} payed at {order_db.payed_at}")
231
+ await self.money_upd(order_db)
232
+
183
233
  case _:
184
234
  logging.warning(f"Order {order.id} UNKNOWN STATUS {datetime.now()}")
185
235
  case "COUNT_DOWN":
@@ -191,30 +241,33 @@ class InAgentClient(BaseInAgentClient):
191
241
  case "RECEIVE":
192
242
  upd = Receive.model_validate(data["data"])
193
243
  if order_db := await models.Order.get_or_none(
194
- exid=upd.orderId, ad__maker__ex=self.agent_client.actor.ex
244
+ exid=upd.orderId, ad__maker__ex=self.actor.ex
195
245
  ).prefetch_related("ad__pair_side__pair", "cred__pmcur__cur"):
196
- im_taker = order_db.taker_id == self.agent_client.actor.id
246
+ im_taker = order_db.taker_id == self.actor.id
197
247
  im_buyer = order_db.ad.pair_side.is_sell == im_taker
198
- if order_db.ad.auto_msg != upd.message and upd.roleType not in ("sys", "alarm"):
248
+ if order_db.ad.auto_msg != upd.message and upd.roleType == "user":
199
249
  msg, _ = await models.Msg.update_or_create(
200
250
  {
201
- "to_maker": upd.userId == self.agent_client.actor.exid and im_taker,
251
+ "to_maker": upd.userId == self.actor.exid and im_taker,
252
+ "sent_at": datetime.fromtimestamp(float(upd.createDate) / 1000),
202
253
  },
203
- sent_at=datetime.fromtimestamp(float(upd.createDate) / 1000),
204
254
  txt=upd.message,
205
255
  order=order_db,
206
256
  )
207
257
  if not upd.message:
208
258
  ...
209
- if im_buyer and re.match(r"^P\d{8,10}$", upd.message):
210
- await self.send_payment(order_db, upd.message)
259
+ if im_buyer and (g := re.match(r"^[PpРр]\d{7,10}\b", upd.message)):
260
+ if not order_db.cred.detail.startswith(dest := g.group()):
261
+ order_db.cred.detail = dest
262
+ await order_db.save()
263
+ await self.send_payment(order_db)
211
264
  case "READ":
212
265
  upd = Read.model_validate(data["data"])
213
266
  # if upd.status not in (StatusWs.created, StatusWs.canceled, 10, StatusWs.completed):
214
267
  if upd.orderStatus in (
215
268
  StatusApi.wait_for_buyer,
216
269
  ): # todo: тут приходит ордер.статус=10, хотя покупатель еще не нажал оплачено
217
- order = self.agent_client.api.get_order_details(orderId=upd.orderId)["result"]
270
+ order = self.api.get_order_details(orderId=upd.orderId)["result"]
218
271
  order = OrderFull.model_validate(order)
219
272
 
220
273
  case "CLEAR":
@@ -244,59 +297,107 @@ class InAgentClient(BaseInAgentClient):
244
297
  if not upd:
245
298
  logging.warning(data, "NOT PROCESSED UPDATE")
246
299
 
247
- async def send_payment(self, order_db: models.Order, dest):
248
- if order_db.status not in (OrderStatus.created, OrderStatus.requested):
300
+ async def money_upd(self, odb: models.Order):
301
+ # обновляем остаток монеты
302
+ await odb.fetch_related("ad__pair_side__pair", "ad__my_ad__credexs__cred__fiat", "cred__pmcur", "transfer")
303
+ ass = await models.Asset.get(addr__coin_id=odb.ad.pair_side.pair.coin_id, addr__actor=self.actor)
304
+ # обновляем остаток валюты
305
+ im_maker = odb.ad.maker_id == self.actor.id
306
+ im_seller = odb.ad.pair_side.is_sell == im_maker
307
+ if im_maker:
308
+ if _fiats := [cx.cred.fiat for cx in odb.ad.my_ad.credexs if cx.cred.fiat]:
309
+ fiat = _fiats[0]
310
+ await fiat.fetch_related("cred__pmcur__pm")
311
+ else:
312
+ raise ValueError(odb, "No Fiat")
313
+ elif im_seller: # im taker
314
+ fltr = dict(cred__person_id=self.actor.person_id)
315
+ fltr |= (
316
+ {"cred__ovr_pm_id": odb.cred.ovr_pm_id, "cred__pmcur__cur_id": odb.cred.pmcur.cur_id}
317
+ if odb.cred.ovr_pm_id
318
+ else {"cred__pmcur_id": odb.cred.pmcur_id}
319
+ )
320
+ if not (fiat := await models.Fiat.get_or_none(**fltr).prefetch_related("cred__pmcur__pm")):
321
+ raise ValueError(odb, "No Fiat")
322
+ fee = round(odb.amount * (fiat.cred.pmcur.pm.fee or 0) * 0.0001)
323
+ # k = int(im_seller) * 2 - 1 # im_seller: 1, im_buyer: -1
324
+ if odb.status == OrderStatus.created:
325
+ if im_seller:
326
+ ass.free -= odb.quantity
327
+ ass.freeze += odb.quantity
328
+ else: # я покупатель
329
+ fiat.amount -= odb.amount + fee
330
+ elif odb.status == OrderStatus.completed:
331
+ if im_seller:
332
+ fiat.amount += odb.amount
333
+ else: # я покупатель
334
+ ass.free += odb.quantity
335
+ elif odb.status == OrderStatus.canceled:
336
+ if im_seller:
337
+ ass.free += odb.quantity
338
+ ass.freeze -= odb.quantity
339
+ else: # я покупатель
340
+ fiat.amount += odb.amount + fee
341
+ else:
342
+ logging.exception(odb.id, f"STATUS: {odb.status.name}")
343
+ await ass.save(update_fields=["free", "freeze"])
344
+ await fiat.save(update_fields=["amount"])
345
+ logging.info(f"Order #{odb.id} {odb.status.name}. Fiat: {fiat.amount}, Asset: {ass.free}")
346
+
347
+ async def send_payment(self, order_db: models.Order):
348
+ if order_db.status != OrderStatus.created:
249
349
  return
250
350
  fmt_am = round(order_db.amount * 10**-2, 2)
251
351
  pma, cur = await self.get_pma_by_pmex(order_db)
252
352
  async with in_transaction():
253
353
  # отмечаем ордер на бирже "оплачен"
254
- pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.pm_id, ex=self.agent_client.actor.ex)
255
- credex = await models.CredEx.get(cred=order_db.cred, ex=self.agent_client.actor.ex)
256
- self.agent_client.api.mark_as_paid(
354
+ pmex = await models.PmEx.get(pm_id=order_db.cred.pmcur.pm_id, ex=self.actor.ex)
355
+ credex = await models.CredEx.get(cred=order_db.cred, ex=self.actor.ex)
356
+ self.api.mark_as_paid(
257
357
  orderId=str(order_db.exid),
258
358
  paymentType=pmex.exid, # pmex.exid
259
359
  paymentId=str(credex.exid), # credex.exid
260
360
  )
261
361
  # проверяем не отправляли ли мы уже перевод по этому ордеру
262
362
  if t := await models.Transfer.get_or_none(order=order_db, amount=order_db.amount):
263
- await pma.bot.send(f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {dest} #{t.pmid}!")
264
- raise Exception(f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {dest} #{t.pmid}!")
363
+ await pma.bot.send(
364
+ f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {order_db.cred.detail} #{t.pmid}!",
365
+ self.actor.person.user.username_id,
366
+ )
367
+ raise Exception(
368
+ f"Order# {order_db.exid}: Double send {fmt_am}{cur} to {order_db.cred.detail} #{t.pmid}!"
369
+ )
265
370
 
266
371
  # ставим в бд статус "оплачен"
267
372
  order_db.status = OrderStatus.paid
268
373
  order_db.payed_at = datetime.now(timezone.utc)
269
374
  await order_db.save()
270
- # добавляем остаток монеты
271
- ass = await models.Asset.get(
272
- addr__coin_id=order_db.ad.pair_side.pair.coin_id, addr__actor=self.agent_client.actor
273
- )
274
- ass.free += int(order_db.amount / order_db.ad.price)
275
- await ass.save(update_fields=["free"])
276
- # отправляем деньги
277
- tid, img, rest_amount = await pma.send(dest=dest, amount=fmt_am, cur=cur)
278
375
  # создаем перевод в бд
279
- t, _ = await models.Transfer.update_or_create(
280
- {"amount": order_db.amount},
281
- order=order_db,
282
- pmid=tid,
283
- )
284
- # обновляем остаток валюты
285
- await models.Fiat.update_or_create({"amount": rest_amount * 100}, cred_id=order_db.cred_id)
286
- # отправляем продавцу чек
287
- if res := self.agent_client.api.upload_chat_file(upload_file=f"tmp/{dest}.png").get("result"):
288
- self.agent_client.api.send_chat_message(
289
- orderId=str(order_db.exid), contentType="pic", message=res["url"], msgUuid=uuid4().hex
290
- )
376
+ t = models.Transfer(order=order_db, amount=order_db.amount, updated_at=now())
377
+ # отправляем деньги
378
+ tid, img = await pma.send(t)
379
+ t.pmid = tid
380
+ await t.save()
381
+ await self.send_receipt(str(order_db.exid), tid) # отправляем продавцу чек
291
382
  logging.info(f"Order {order_db.exid} PAID at {datetime.now()}: {fmt_am}!")
292
383
 
293
- async def get_pma_by_cdex(self, order: OrderFull) -> tuple[PmAgentClient | None, CredEx] | None:
384
+ async def send_receipt(self, oexid: str, tid: int) -> tuple[PmAgentClient | None, models.CredEx] | None:
385
+ try:
386
+ if res := self.api.upload_chat_file(upload_file=f"tmp/{tid}.png").get("result"):
387
+ await sleep(0.5)
388
+ self.api.send_chat_message(orderId=oexid, contentType="pic", message=res["url"], msgUuid=uuid4().hex)
389
+ except Exception as e:
390
+ logging.error(e)
391
+ await sleep(0.5)
392
+ self.api.send_chat_message(orderId=oexid, contentType="str", message=f"#{tid}", msgUuid=uuid4().hex)
393
+
394
+ async def get_pma_by_cdex(self, order: OrderFull) -> tuple[PmAgentClient | None, models.CredEx] | None:
294
395
  cdxs = await models.CredEx.filter(
295
- ex=self.agent_client.ex_client.ex,
396
+ ex=self.ex_client.ex,
296
397
  exid__in=[ptl.id for ptl in order.paymentTermList],
297
- cred__person=self.agent_client.actor.person,
398
+ cred__person=self.actor.person,
298
399
  ).prefetch_related("cred__pmcur__cur")
299
- pmas = [pma for cdx in cdxs if (pma := self.pmacs.get(cdx.cred.pmcur.pm_id))]
400
+ pmas = [pma for cdx in cdxs if (pma := self.pm_clients.get(cdx.cred.pmcur.pm_id))]
300
401
  if not len(pmas):
301
402
  # raise ValueError(order.paymentTermList, f"No pm_agents for {order.paymentTermList[0].paymentType}")
302
403
  return None
@@ -306,7 +407,7 @@ class InAgentClient(BaseInAgentClient):
306
407
  return pmas[0], cdxs[0]
307
408
 
308
409
  async def get_pma_by_pmex(self, order_db: models.Order) -> tuple[PmAgentClient, str]:
309
- pma = self.pmacs.get(order_db.cred.pmcur.pm_id)
410
+ pma = self.pm_clients.get(order_db.cred.pmcur.pm_id)
310
411
  if pma:
311
412
  return pma, order_db.cred.pmcur.cur.ticker
312
413
  logging.error(f"No pm_agents for {order_db.cred.pmcur.pm_id}")
@@ -321,29 +422,43 @@ async def main():
321
422
  from x_model import init_db
322
423
  from xync_client.loader import TORM
323
424
 
324
- _ = await init_db(TORM, True)
425
+ cn = await init_db(TORM, True)
325
426
  logging.basicConfig(level=logging.INFO)
326
427
 
327
- actor = (
328
- await models.Actor.filter(
329
- ex_id=4,
330
- agent__auth__isnull=False,
331
- person__user__status=UserStatus.ACTIVE,
332
- person__user__pm_agents__isnull=False,
428
+ agent = (
429
+ await models.Agent.filter(
430
+ actor__ex_id=4,
431
+ status__in=[3],
432
+ auth__isnull=False,
433
+ actor__person__user__status=UserStatus.ACTIVE,
434
+ actor__person__user__pm_agents__pm_id=366,
435
+ actor__person_id=1,
333
436
  )
334
- .prefetch_related("ex", "agent", "person__user__pm_agents")
437
+ .prefetch_related("actor__ex", "actor__person__user__gmail")
335
438
  .first()
336
439
  )
440
+ pm_agents = await models.PmAgent.filter(
441
+ active=True,
442
+ auth__isnull=False,
443
+ user__status=UserStatus.ACTIVE,
444
+ ).prefetch_related("pm", "user__gmail")
337
445
 
338
- async with FileClient(TOKEN) as b:
339
- cl: InAgentClient = actor.in_client(b)
340
- # await cl.agent_client.export_my_ads()
341
- payeer_cl = Client(actor.person.user.username_id)
342
- for pma in actor.person.user.pm_agents:
343
- cl.pmacs[pma.pm_id] = await payeer_cl.start(await async_playwright().start(), True)
446
+ bbot = XyncBot(PAY_TOKEN, cn)
344
447
 
345
- _ = await cl.start_listen()
346
- await cl.agent_client.close()
448
+ async with FileClient(NET_TOKEN) as b:
449
+ b: FileClient
450
+ cl = InAgentClient(agent, b, bbot)
451
+ # await cl.agent_client.export_my_ads()
452
+ # payeer_cl = Client(actor.person.user.username_id)
453
+ for pma in pm_agents:
454
+ pcl: PmAgentClient = pma.client(bbot)
455
+ cl.pm_clients[pma.pm_id] = await pcl.start(await async_playwright().start(), False)
456
+ try:
457
+ _ = await cl.start_listen()
458
+ except Exception as e:
459
+ await b.send("😱Bybit InAgent CRASHED!!!😱", agent.actor.person.user.username_id)
460
+ await b.send(f"```\n{''.join(traceback.format_exception(e))}\n```", agent.actor.person.user.username_id)
461
+ await cl.close()
347
462
 
348
463
 
349
464
  if __name__ == "__main__":