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.
- xync_client/Abc/AdLoader.py +299 -0
- xync_client/Abc/Agent.py +94 -10
- xync_client/Abc/Ex.py +27 -22
- xync_client/Abc/HasAbotUid.py +10 -0
- xync_client/Abc/InAgent.py +0 -11
- xync_client/Abc/PmAgent.py +42 -35
- xync_client/Abc/xtype.py +24 -2
- xync_client/Binance/ex.py +2 -2
- xync_client/BingX/ex.py +2 -2
- xync_client/BitGet/ex.py +2 -2
- xync_client/Bybit/InAgent.py +229 -114
- xync_client/Bybit/agent.py +584 -572
- xync_client/Bybit/etype/ad.py +11 -56
- xync_client/Bybit/etype/cred.py +29 -9
- xync_client/Bybit/etype/order.py +55 -62
- xync_client/Bybit/ex.py +17 -4
- xync_client/Gate/ex.py +2 -2
- xync_client/Gmail/__init__.py +119 -98
- xync_client/Htx/agent.py +162 -31
- xync_client/Htx/etype/ad.py +18 -11
- xync_client/Htx/ex.py +9 -11
- xync_client/KuCoin/ex.py +2 -2
- xync_client/Mexc/agent.py +85 -0
- xync_client/Mexc/api.py +636 -0
- xync_client/Mexc/etype/order.py +639 -0
- xync_client/Mexc/ex.py +12 -10
- xync_client/Okx/ex.py +2 -2
- xync_client/Pms/Payeer/__init__.py +147 -43
- xync_client/Pms/Payeer/login.py +29 -2
- xync_client/Pms/Volet/__init__.py +148 -94
- xync_client/Pms/Volet/api.py +17 -13
- xync_client/TgWallet/ex.py +2 -2
- xync_client/details.py +44 -0
- xync_client/loader.py +2 -1
- xync_client/pm_unifier.py +1 -1
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/METADATA +6 -1
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/RECORD +39 -33
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/WHEEL +0 -0
- {xync_client-0.0.114.dist-info → xync_client-0.0.155.dist-info}/top_level.txt +0 -0
xync_client/Bybit/InAgent.py
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
47
|
+
t = await self.ott()
|
|
40
48
|
ts = int(float(t["time_now"]) * 1000)
|
|
41
|
-
await self.ws_prv(self.
|
|
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" {
|
|
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
|
-
|
|
83
|
-
|
|
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.
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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 {
|
|
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
|
-
|
|
171
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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"^
|
|
210
|
-
|
|
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.
|
|
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
|
|
248
|
-
|
|
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.
|
|
255
|
-
credex = await models.CredEx.get(cred=order_db.cred, ex=self.
|
|
256
|
-
self.
|
|
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(
|
|
264
|
-
|
|
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
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
|
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.
|
|
396
|
+
ex=self.ex_client.ex,
|
|
296
397
|
exid__in=[ptl.id for ptl in order.paymentTermList],
|
|
297
|
-
cred__person=self.
|
|
398
|
+
cred__person=self.actor.person,
|
|
298
399
|
).prefetch_related("cred__pmcur__cur")
|
|
299
|
-
pmas = [pma for cdx in cdxs if (pma := self.
|
|
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.
|
|
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
|
-
|
|
425
|
+
cn = await init_db(TORM, True)
|
|
325
426
|
logging.basicConfig(level=logging.INFO)
|
|
326
427
|
|
|
327
|
-
|
|
328
|
-
await models.
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
346
|
-
|
|
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__":
|