xync-client 0.0.164__py3-none-any.whl → 0.0.172__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/Agent.py +154 -22
- xync_client/Abc/Ex.py +107 -127
- xync_client/Abc/Order.py +16 -17
- xync_client/Abc/xtype.py +139 -65
- xync_client/BingX/agent.py +1 -1
- xync_client/BitGet/agent.py +1 -3
- xync_client/Bybit/agent.py +72 -321
- xync_client/Bybit/etype/ad.py +79 -58
- xync_client/Bybit/etype/cred.py +25 -3
- xync_client/Bybit/etype/order.py +150 -95
- xync_client/Bybit/ex.py +24 -12
- xync_client/Bybit/{InAgent.py → inAgent.py} +5 -10
- xync_client/Bybit/order.py +33 -16
- xync_client/Htx/agent.py +9 -9
- xync_client/Htx/etype/ad.py +2 -4
- xync_client/Htx/etype/test.py +4 -4
- xync_client/Htx/ex.py +35 -3
- xync_client/Mexc/agent.py +6 -6
- xync_client/Mexc/ex.py +2 -2
- xync_client/TgWallet/agent.py +21 -21
- xync_client/TgWallet/ex.py +11 -11
- xync_client/TgWallet/pyd.py +5 -5
- xync_client/pm_unifier.py +3 -2
- {xync_client-0.0.164.dist-info → xync_client-0.0.172.dist-info}/METADATA +1 -1
- {xync_client-0.0.164.dist-info → xync_client-0.0.172.dist-info}/RECORD +27 -27
- {xync_client-0.0.164.dist-info → xync_client-0.0.172.dist-info}/WHEEL +0 -0
- {xync_client-0.0.164.dist-info → xync_client-0.0.172.dist-info}/top_level.txt +0 -0
xync_client/Bybit/agent.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
|
-
import re
|
|
5
4
|
from asyncio import sleep, gather
|
|
6
5
|
from asyncio.tasks import create_task
|
|
7
6
|
from datetime import datetime, timedelta, timezone
|
|
@@ -9,7 +8,6 @@ from difflib import SequenceMatcher
|
|
|
9
8
|
from enum import IntEnum
|
|
10
9
|
from hashlib import sha256
|
|
11
10
|
from http.client import HTTPException
|
|
12
|
-
from math import floor
|
|
13
11
|
from typing import Literal
|
|
14
12
|
from uuid import uuid4
|
|
15
13
|
|
|
@@ -21,27 +19,24 @@ from bybit_p2p._exceptions import FailedRequestError
|
|
|
21
19
|
from payeer_api import PayeerAPI
|
|
22
20
|
from pyro_client.client.file import FileClient
|
|
23
21
|
from tortoise import BaseDBAsyncClient
|
|
24
|
-
from tortoise.exceptions import IntegrityError
|
|
25
|
-
from tortoise.expressions import Q
|
|
26
|
-
from tortoise.functions import Count
|
|
27
22
|
from tortoise.signals import post_save
|
|
28
23
|
from tortoise.timezone import now
|
|
29
24
|
from tortoise.transactions import in_transaction
|
|
25
|
+
from websockets import ConnectionClosedError
|
|
30
26
|
from x_client import df_hdrs
|
|
31
27
|
from x_model import init_db
|
|
32
|
-
from x_model.func import ArrayAgg
|
|
33
28
|
from xync_bot import XyncBot
|
|
34
29
|
|
|
35
30
|
from xync_client.Bybit.ex import ExClient
|
|
36
31
|
from xync_schema import models
|
|
37
32
|
from xync_schema.enums import OrderStatus, AgentStatus
|
|
38
33
|
|
|
39
|
-
from xync_schema.models import
|
|
34
|
+
from xync_schema.models import Agent
|
|
40
35
|
|
|
41
36
|
from xync_client.Abc.Agent import BaseAgentClient
|
|
42
|
-
from xync_client.Abc.xtype import FlatDict, BaseOrderReq,
|
|
43
|
-
from xync_client.Bybit.etype.ad import AdPostRequest,
|
|
44
|
-
from xync_client.Bybit.etype.cred import CredEpyd
|
|
37
|
+
from xync_client.Abc.xtype import FlatDict, BaseOrderReq, AdUpdReq, GetAdsReq
|
|
38
|
+
from xync_client.Bybit.etype.ad import AdPostRequest, AdRequest, Ad, AdStatusReq, MyAd
|
|
39
|
+
from xync_client.Bybit.etype.cred import CredEpyd, PaymentTerm, CredEx
|
|
45
40
|
from xync_client.Bybit.etype.order import (
|
|
46
41
|
OrderRequest,
|
|
47
42
|
PreOrderResp,
|
|
@@ -77,6 +72,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
77
72
|
# rewrite token for public methods
|
|
78
73
|
api: P2P
|
|
79
74
|
orders: dict[int, tuple[models.Order, OrderFull]] = {} # pending
|
|
75
|
+
cdx_cls: type[CredEx] = CredEx
|
|
80
76
|
|
|
81
77
|
def __init__(
|
|
82
78
|
self,
|
|
@@ -122,95 +118,11 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
122
118
|
def get_payment_method(self, fiat_id: int) -> CredEpyd:
|
|
123
119
|
return self.creds()[fiat_id]
|
|
124
120
|
|
|
125
|
-
def
|
|
121
|
+
async def _get_creds(self) -> list[PaymentTerm]:
|
|
126
122
|
data = self.api.get_user_payment_types()
|
|
127
123
|
if data["ret_code"] > 0:
|
|
128
124
|
return data
|
|
129
|
-
return
|
|
130
|
-
|
|
131
|
-
async def cred_epyd2db(self, ecdx: CredEpyd, pers_id: int = None, cur_id: int = None) -> models.CredEx | None:
|
|
132
|
-
if ecdx.paymentType in (416,): # what is 416??
|
|
133
|
-
return None
|
|
134
|
-
if not (
|
|
135
|
-
pmex := await models.PmEx.get_or_none(exid=ecdx.paymentType, ex=self.ex_client.ex).prefetch_related(
|
|
136
|
-
"pm__curs"
|
|
137
|
-
)
|
|
138
|
-
):
|
|
139
|
-
raise HTTPException(f"No PmEx {ecdx.paymentType} on ex#{self.ex_client.ex.name}", 404)
|
|
140
|
-
if cred_old := await models.Cred.get_or_none(credexs__exid=ecdx.id, credexs__ex=self.actor.ex).prefetch_related(
|
|
141
|
-
"pmcur"
|
|
142
|
-
):
|
|
143
|
-
cur_id = cred_old.pmcur.cur_id
|
|
144
|
-
elif not cur_id: # is new Cred
|
|
145
|
-
cur_id = (
|
|
146
|
-
pmex.pm.df_cur_id
|
|
147
|
-
or await self.guess_cur(ecdx, len(pmex.pm.curs) > 1 and pmex.pm.curs)
|
|
148
|
-
or (pmex.pm.country_id and (await pmex.pm.country).cur_id)
|
|
149
|
-
# or (ecdx.currencyBalance and await models.Cur.get_or_none(ticker=ecdx.currencyBalance[0])) # это че еще за хуйня?
|
|
150
|
-
)
|
|
151
|
-
if not cur_id:
|
|
152
|
-
raise Exception(f"Set default cur for {pmex.name}")
|
|
153
|
-
if not (pmcur := await models.PmCur.get_or_none(cur_id=cur_id, pm_id=pmex.pm_id)):
|
|
154
|
-
raise HTTPException(f"No PmCur with cur#{cur_id} and pm#{ecdx.paymentType}", 404)
|
|
155
|
-
xtr = ecdx.branchName
|
|
156
|
-
if ecdx.bankName:
|
|
157
|
-
xtr += (" | " if xtr else "") + ecdx.bankName
|
|
158
|
-
elif ecdx.payMessage:
|
|
159
|
-
xtr += (" | " if xtr else "") + ecdx.payMessage
|
|
160
|
-
elif ecdx.qrcode:
|
|
161
|
-
xtr += (" | " if xtr else "") + ecdx.qrcode
|
|
162
|
-
elif ecdx.paymentExt1:
|
|
163
|
-
xtr += (" | " if xtr else "") + ecdx.paymentExt1
|
|
164
|
-
try:
|
|
165
|
-
cred_db, _ = await models.Cred.update_or_create(
|
|
166
|
-
{
|
|
167
|
-
"name": ecdx.realName,
|
|
168
|
-
"extra": xtr,
|
|
169
|
-
},
|
|
170
|
-
pmcur=pmcur,
|
|
171
|
-
person_id=pers_id or self.actor.person_id,
|
|
172
|
-
detail=ecdx.accountNo or ecdx.payMessage,
|
|
173
|
-
)
|
|
174
|
-
if cred_db.ovr_pm_id is None and (cred_db.detail.startswith("XyncPay") or xtr.startswith("XyncPay")):
|
|
175
|
-
cred_db.ovr_pm_id = 0
|
|
176
|
-
await cred_db.save()
|
|
177
|
-
credex_in = models.CredEx.validate({"exid": ecdx.id, "cred_id": cred_db.id, "ex_id": self.actor.ex.id})
|
|
178
|
-
credex_db, _ = await models.CredEx.update_or_create(**credex_in.df_unq())
|
|
179
|
-
except IntegrityError as e:
|
|
180
|
-
raise e
|
|
181
|
-
return credex_db
|
|
182
|
-
|
|
183
|
-
async def guess_cur(self, ecdx: CredEpyd, curs: list[models.Cur]):
|
|
184
|
-
mbs = ecdx.bankName.split(", ")
|
|
185
|
-
mbs += ecdx.branchName.split(" / ")
|
|
186
|
-
mbs = {mb.lower(): mb for mb in mbs}
|
|
187
|
-
if (
|
|
188
|
-
pms := await models.Pm.filter(Q(join_type="OR", pmexs__name__in=mbs.values(), norm__in=mbs.keys()))
|
|
189
|
-
.group_by("pmcurs__cur_id", "pmcurs__cur__ticker")
|
|
190
|
-
.annotate(ccnt=Count("id"), names=ArrayAgg("norm"))
|
|
191
|
-
.order_by("-ccnt", "pmcurs__cur__ticker")
|
|
192
|
-
.values("pmcurs__cur_id", "names", "ccnt")
|
|
193
|
-
):
|
|
194
|
-
return pms[0]["pmcurs__cur_id"]
|
|
195
|
-
curs = {c.ticker: c.id for c in curs or await models.Cur.all()}
|
|
196
|
-
for cur, cid in curs.items():
|
|
197
|
-
if re.search(re.compile(rf"\({cur}\)$"), ecdx.bankName):
|
|
198
|
-
return cid
|
|
199
|
-
if re.search(re.compile(rf"\({cur}\)$"), ecdx.branchName):
|
|
200
|
-
return cid
|
|
201
|
-
if re.search(re.compile(rf"\({cur}\)$"), ecdx.accountNo):
|
|
202
|
-
return cid
|
|
203
|
-
if re.search(re.compile(rf"\({cur}\)$"), ecdx.payMessage):
|
|
204
|
-
return cid
|
|
205
|
-
if re.search(re.compile(rf"\({cur}\)$"), ecdx.paymentExt1):
|
|
206
|
-
return cid
|
|
207
|
-
return None
|
|
208
|
-
|
|
209
|
-
# 25: Список реквизитов моих платежных методов
|
|
210
|
-
async def set_creds(self) -> list[models.CredEx]:
|
|
211
|
-
credexs_epyd: dict[int, CredEpyd] = self.creds()
|
|
212
|
-
credexs: list[models.CredEx] = [await self.cred_epyd2db(f) for f in credexs_epyd.values()]
|
|
213
|
-
return credexs
|
|
125
|
+
return [PaymentTerm.model_validate(credex) for credex in data["result"] if credex["id"] != "-1"]
|
|
214
126
|
|
|
215
127
|
async def ott(self):
|
|
216
128
|
t = await self._post("/x-api/user/private/ott")
|
|
@@ -238,7 +150,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
238
150
|
delete = await self._post("/x-api/fiat/otc/user/payment/new_delete", data)
|
|
239
151
|
return delete
|
|
240
152
|
|
|
241
|
-
async def switch_ads(self, new_status:
|
|
153
|
+
async def switch_ads(self, new_status: AdStatusReq) -> dict:
|
|
242
154
|
data = {"workStatus": new_status.name} # todo: переделать на апи, там status 0 -> 1
|
|
243
155
|
res = await self._post("/x-api/fiat/otc/maker/work-config/switch", data)
|
|
244
156
|
return res
|
|
@@ -248,26 +160,16 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
248
160
|
ads = [ad for ad in list_ads if set(ad["payments"]) - {"5", "51"}]
|
|
249
161
|
return float(ads[0]["price"])
|
|
250
162
|
|
|
251
|
-
def
|
|
252
|
-
resp = self.api.get_ads_list(
|
|
163
|
+
async def get_my_ads(self, active: bool = True, page: int = 1) -> list[MyAd]:
|
|
164
|
+
resp = self.api.get_ads_list(
|
|
165
|
+
size="30", page=str(page), status=AdStatusReq.active if active else AdStatusReq.sold_out
|
|
166
|
+
)
|
|
253
167
|
ads = [MyAd.model_validate(ad) for ad in resp["result"]["items"]]
|
|
254
|
-
|
|
255
|
-
|
|
168
|
+
# todo: вернуть, что бы спарсил все объявы, а не только первые 30
|
|
169
|
+
# if resp["result"]["count"] > 30 * page:
|
|
170
|
+
# ads.extend(await self.get_my_ads(active, page + 1))
|
|
256
171
|
return ads
|
|
257
172
|
|
|
258
|
-
async def export_my_ads(self, active: bool = None) -> int: # upserted)
|
|
259
|
-
ads = self.my_ads(True)
|
|
260
|
-
if not active:
|
|
261
|
-
ads += self.my_ads(False)
|
|
262
|
-
for ad in ads:
|
|
263
|
-
ad_db = await self.ex_client.ad_load(ad, maker=self.actor)
|
|
264
|
-
mad_db, _ = await models.MyAd.update_or_create(ad=ad_db)
|
|
265
|
-
exids = [pt.id for pt in ad.paymentTerms]
|
|
266
|
-
credexs = await models.CredEx.filter(ex_id=self.actor.ex_id, exid__in=exids).prefetch_related("cred")
|
|
267
|
-
await mad_db.credexs.clear()
|
|
268
|
-
await mad_db.credexs.add(*credexs)
|
|
269
|
-
return len(ads)
|
|
270
|
-
|
|
271
173
|
async def ads_share(self, cur_id: int = None) -> int:
|
|
272
174
|
mq = models.MyAd.hot_mads_query([4]).filter(ad__maker=self.actor)
|
|
273
175
|
if cur_id:
|
|
@@ -373,8 +275,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
373
275
|
data = self.api.post_new_ad(**ad.model_dump())
|
|
374
276
|
return data["result"]["itemId"] if data["ret_code"] == 0 else data
|
|
375
277
|
|
|
376
|
-
async def _ad_upd(self, req:
|
|
377
|
-
upd =
|
|
278
|
+
async def _ad_upd(self, req: AdUpdReq):
|
|
279
|
+
upd = AdRequest({})
|
|
378
280
|
params = upd.model_dump()
|
|
379
281
|
data = self.api.update_ad(**params)
|
|
380
282
|
return data["result"] if data["ret_code"] == 0 else data
|
|
@@ -418,9 +320,9 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
418
320
|
tokenId=bor.coin_exid,
|
|
419
321
|
currencyId=bor.cur_exid,
|
|
420
322
|
side="1" if bor.is_sell else "0",
|
|
421
|
-
amount=f"{bor.
|
|
323
|
+
amount=f"{bor.amount:.2f}".rstrip("0").rstrip("."),
|
|
422
324
|
curPrice=por.curPrice,
|
|
423
|
-
quantity=str(round(bor.
|
|
325
|
+
quantity=str(round(bor.amount / float(por.price), bor.coin_scale)),
|
|
424
326
|
flag="amount",
|
|
425
327
|
# online="0"
|
|
426
328
|
)
|
|
@@ -531,155 +433,6 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
531
433
|
},
|
|
532
434
|
)
|
|
533
435
|
|
|
534
|
-
async def create_order_db(self, order: OrderFull) -> models.Order:
|
|
535
|
-
curex = await models.CurEx.get_or_none(ex=self.ex_client.ex, exid=order.currencyId).prefetch_related("cur")
|
|
536
|
-
cur_scale = (curex.scale if curex.scale is not None else curex.cur.scale) if curex else 2
|
|
537
|
-
coinex = await models.CoinEx.get(ex=self.ex_client.ex, exid=order.tokenId).prefetch_related("coin")
|
|
538
|
-
coin_scale = coinex.scale if coinex.scale is not None else coinex.cur.scale
|
|
539
|
-
sb_names = order.sellerRealName, order.buyerRealName
|
|
540
|
-
im_maker = int(int(order.makerUserId) == self.actor.exid)
|
|
541
|
-
taker_id = (order.userId, order.targetUserId)[im_maker]
|
|
542
|
-
taker_name = sb_names[order.side] # todo: double check
|
|
543
|
-
taker_person = await self.ex_client.person_name_update(taker_name, taker_id)
|
|
544
|
-
seller_person = (
|
|
545
|
-
self.actor.person
|
|
546
|
-
if order.side
|
|
547
|
-
else await self.ex_client.person_name_update(order.sellerRealName, int(order.targetUserId))
|
|
548
|
-
)
|
|
549
|
-
taker_nick = (self.actor.name, order.targetNickName)[im_maker] # todo: check
|
|
550
|
-
ad_db = await models.Ad.get(exid=order.itemId)
|
|
551
|
-
if not ad_db:
|
|
552
|
-
ad = self.get_ad(order.itemId)
|
|
553
|
-
# ad_db, cond_isnew = await self.ex_client.cond_load(ad, force=True, rname=maker_name[order.side])
|
|
554
|
-
ad_db = await self.ex_client.ad_load(ad, maker=self.actor)
|
|
555
|
-
ecredex: CredEpyd = order.confirmedPayTerm
|
|
556
|
-
|
|
557
|
-
if ecredex.paymentType == 0 and im_maker and order.side:
|
|
558
|
-
ecredex = order.paymentTermList[0]
|
|
559
|
-
if ecredex.paymentType:
|
|
560
|
-
if ecredex.paymentType == 51:
|
|
561
|
-
ecredex.accountNo = ecredex.accountNo.replace("p", "P").replace("р", "P").replace("Р", "P")
|
|
562
|
-
# if not re.match(r"^([Pp])\d{7,10}$", ecredex.accountNo):
|
|
563
|
-
# msgs = self.api.get_chat_messages(orderId=order.id, size=100)["result"]["result"]
|
|
564
|
-
# msgs = [m["message"] for m in msgs if m["roleType"] == "user" and m["userId"] == order.targetUserId]
|
|
565
|
-
# msgs = [g.group() for m in msgs if (g := re.match(r"([PpРр])\d{7,10}\b", m))]
|
|
566
|
-
# crd = await models.Cred.get_or_none(
|
|
567
|
-
# detail=ecredex.accountNo, credexs__exid=ecredex.id, credexs__ex=self.ex_client.ex
|
|
568
|
-
# )
|
|
569
|
-
# if not msgs and re.match(r"^\d{7,10}$", ecredex.accountNo):
|
|
570
|
-
# ecredex.accountNo = "P" + ecredex.accountNo
|
|
571
|
-
# elif msgs:
|
|
572
|
-
# ecredex.accountNo = msgs[-1]
|
|
573
|
-
# else:
|
|
574
|
-
# ...
|
|
575
|
-
# if crd:
|
|
576
|
-
# crd.detail = ecredex.accountNo
|
|
577
|
-
# await crd.save(update_fields=["detail"])
|
|
578
|
-
if not (credex := await models.CredEx.get_or_none(exid=ecredex.id, ex=self.ex_client.ex)):
|
|
579
|
-
# cur_id = await Cur.get(ticker=ad.currencyId).values_list('id', flat=True)
|
|
580
|
-
# await self.cred_epyd2db(ecredex, ad_db.maker.person_id, cur_id)
|
|
581
|
-
if (
|
|
582
|
-
await PmCur.filter(
|
|
583
|
-
pm__pmexs__ex=self.ex_client.ex,
|
|
584
|
-
pm__pmexs__exid=ecredex.paymentType,
|
|
585
|
-
cur__ticker=order.currencyId,
|
|
586
|
-
).count()
|
|
587
|
-
!= 1
|
|
588
|
-
):
|
|
589
|
-
...
|
|
590
|
-
if not (
|
|
591
|
-
pmcur := await PmCur.get_or_none(
|
|
592
|
-
pm__pmexs__ex=self.ex_client.ex,
|
|
593
|
-
pm__pmexs__exid=ecredex.paymentType,
|
|
594
|
-
cur__ticker=order.currencyId,
|
|
595
|
-
)
|
|
596
|
-
):
|
|
597
|
-
...
|
|
598
|
-
if not (
|
|
599
|
-
crd := await models.Cred.get_or_none(pmcur=pmcur, person=seller_person, detail=ecredex.accountNo)
|
|
600
|
-
):
|
|
601
|
-
extr = ", ".join(
|
|
602
|
-
x
|
|
603
|
-
for xtr in [
|
|
604
|
-
ecredex.bankName,
|
|
605
|
-
ecredex.branchName,
|
|
606
|
-
ecredex.qrcode,
|
|
607
|
-
ecredex.payMessage,
|
|
608
|
-
ecredex.paymentExt1,
|
|
609
|
-
]
|
|
610
|
-
if (x := xtr.strip())
|
|
611
|
-
)
|
|
612
|
-
crd = await models.Cred.create(
|
|
613
|
-
detail=ecredex.accountNo,
|
|
614
|
-
pmcur=pmcur,
|
|
615
|
-
person=seller_person,
|
|
616
|
-
name=ecredex.realName,
|
|
617
|
-
extra=extr,
|
|
618
|
-
)
|
|
619
|
-
credex = await models.CredEx.create(exid=ecredex.id, ex=self.ex_client.ex, cred=crd)
|
|
620
|
-
try:
|
|
621
|
-
taker, _ = await Actor.get_or_create(
|
|
622
|
-
{"name": taker_nick, "person": taker_person}, ex=self.ex_client.ex, exid=taker_id
|
|
623
|
-
)
|
|
624
|
-
except IntegrityError as e:
|
|
625
|
-
logging.error(e)
|
|
626
|
-
odb, _ = await models.Order.update_or_create(
|
|
627
|
-
{
|
|
628
|
-
"amount": float(order.amount) * 10**cur_scale,
|
|
629
|
-
"quantity": float(order.quantity) * 10**coin_scale,
|
|
630
|
-
"status": OrderStatus[Status(order.status).name],
|
|
631
|
-
"created_at": ms2utc(order.createDate),
|
|
632
|
-
"payed_at": order.transferDate != "0" and ms2utc(order.transferDate) or None,
|
|
633
|
-
"confirmed_at": Status(order.status) == Status.completed and ms2utc(order.transferDate) or None,
|
|
634
|
-
"appealed_at": order.status == 30 and ms2utc(order.transferDate) or None,
|
|
635
|
-
"cred_id": ecredex.paymentType and credex.cred_id or None,
|
|
636
|
-
"taker": taker,
|
|
637
|
-
"ad": ad_db,
|
|
638
|
-
},
|
|
639
|
-
exid=order.id,
|
|
640
|
-
)
|
|
641
|
-
if order.status == Status.completed and ecredex.paymentType == 51:
|
|
642
|
-
await odb.fetch_related("cred", "transfer")
|
|
643
|
-
if odb.cred.detail != ecredex.accountNo:
|
|
644
|
-
...
|
|
645
|
-
frm = (odb.created_at + timedelta(minutes=180 - 1)).isoformat(sep=" ").split("+")[0]
|
|
646
|
-
to = ((odb.payed_at or odb.created_at) + timedelta(minutes=180 + 30)).isoformat(sep=" ").split("+")[0]
|
|
647
|
-
tsa = [
|
|
648
|
-
t
|
|
649
|
-
for tid, t in (self.hist.items() if self.hist else [])
|
|
650
|
-
if (ecredex.accountNo == t["to"] and t["from"] != "@merchant" and frm < t["date"] < to)
|
|
651
|
-
]
|
|
652
|
-
buyer_person = (
|
|
653
|
-
self.actor.person
|
|
654
|
-
if not order.side
|
|
655
|
-
else await self.ex_client.person_name_update(order.buyerRealName, int(order.targetUserId))
|
|
656
|
-
)
|
|
657
|
-
ts = [t for t in tsa if floor(fa := float(order.amount)) <= float(t["creditedAmount"]) <= round(fa)]
|
|
658
|
-
if len(ts) != 1:
|
|
659
|
-
if len(tsa) > 1:
|
|
660
|
-
summ = sum(float(t["creditedAmount"]) for t in tsa)
|
|
661
|
-
if floor(fa) <= summ <= round(fa):
|
|
662
|
-
for tr in tsa:
|
|
663
|
-
am = int(float(tr["creditedAmount"]) * 100)
|
|
664
|
-
await models.Transfer.create(
|
|
665
|
-
pmid=tr["id"], order=odb, amount=am, sender_acc=tr["from"], created_at=tr["date"]
|
|
666
|
-
)
|
|
667
|
-
else:
|
|
668
|
-
bcred, _ = await models.Cred.get_or_create(
|
|
669
|
-
{"detail": ts[0]["from"]}, person=buyer_person, pmcur_id=odb.cred.pmcur_id
|
|
670
|
-
)
|
|
671
|
-
am = int(float(ts[0]["creditedAmount"]) * 100)
|
|
672
|
-
try:
|
|
673
|
-
await models.Transfer.create(
|
|
674
|
-
pmid=ts[0]["id"], order=odb, amount=am, sender_acc=ts[0]["from"], created_at=ts[0]["date"]
|
|
675
|
-
)
|
|
676
|
-
except IntegrityError as e:
|
|
677
|
-
logging.error(e)
|
|
678
|
-
...
|
|
679
|
-
|
|
680
|
-
await odb.fetch_related("ad")
|
|
681
|
-
return odb
|
|
682
|
-
|
|
683
436
|
async def get_api_orders(
|
|
684
437
|
self,
|
|
685
438
|
page: int = 1,
|
|
@@ -708,7 +461,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
708
461
|
if o.status != Status.completed.value or oid in self.completed_orders:
|
|
709
462
|
continue
|
|
710
463
|
order = await self.get_order_full(o.id)
|
|
711
|
-
order_db = await self.
|
|
464
|
+
order_db = await self.order_save(order)
|
|
712
465
|
await sleep(1)
|
|
713
466
|
dmsgs = self.api.get_chat_messages(orderId=oid, size=200)["result"]["result"][::-1]
|
|
714
467
|
msgs = [Message.model_validate(m) for m in dmsgs if m["msgType"] in (1, 2, 7, 8)]
|
|
@@ -771,7 +524,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
771
524
|
|
|
772
525
|
bor = BaseOrderReq(
|
|
773
526
|
ad_id=str(req.ad_id),
|
|
774
|
-
|
|
527
|
+
amount=req.amount,
|
|
775
528
|
is_sell=req.is_sell,
|
|
776
529
|
cur_exid=curex.exid,
|
|
777
530
|
coin_exid=coinex.exid,
|
|
@@ -788,7 +541,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
788
541
|
i = 0
|
|
789
542
|
while True:
|
|
790
543
|
try:
|
|
791
|
-
breq =
|
|
544
|
+
breq = GetAdsReq(coin_id=1, cur_id=1, is_sell=False, limit=50)
|
|
792
545
|
bs = await self.ex_client.ads(breq, post_pmexs=post_pmexs)
|
|
793
546
|
bs = [b for b in bs if float(b.price) < 100 or int(b.userId) in mcs.keys()]
|
|
794
547
|
if bs:
|
|
@@ -810,7 +563,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
810
563
|
ord_resp: OrderResp = await self.take_ad(req)
|
|
811
564
|
# order: OrderFull = OrderFull(**self.api.get_order_details(orderId=ord_resp.orderId)["result"])
|
|
812
565
|
order: OrderFull = await self.get_order_info(ord_resp.orderId)
|
|
813
|
-
odb = await self.
|
|
566
|
+
odb = await self.order_save(order)
|
|
814
567
|
t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
815
568
|
await t.fetch_related("order__cred__pmcur__cur")
|
|
816
569
|
# res = await self.pm_clients[366].send(t)
|
|
@@ -826,7 +579,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
826
579
|
|
|
827
580
|
await sleep(5)
|
|
828
581
|
|
|
829
|
-
sreq =
|
|
582
|
+
sreq = GetAdsReq(coin_id=1, cur_id=1, is_sell=True, limit=50, kwargs={"post_pmexs": post_pmexs})
|
|
830
583
|
ss = await self.ex_client.ads(sreq, post_pmexs=post_pmexs)
|
|
831
584
|
ss = [s for s in ss if float(s.price) > 92 or int(s.userId) in mcs.keys()]
|
|
832
585
|
if ss:
|
|
@@ -848,7 +601,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
848
601
|
ord_resp: OrderResp = await self.take_ad(req)
|
|
849
602
|
# order: OrderFull = OrderFull(**self.api.get_order_details(orderId=ord_resp.orderId)["result"])
|
|
850
603
|
order: OrderFull = await self.get_order_info(ord_resp.orderId)
|
|
851
|
-
odb = await self.
|
|
604
|
+
odb = await self.order_save(order)
|
|
852
605
|
# t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
853
606
|
# await t.fetch_related("order__cred__pmcur__cur")
|
|
854
607
|
# res = await self.pm_clients[366].check_in(t)
|
|
@@ -879,7 +632,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
879
632
|
req = TakeAdReq(ad_id="1856989782009487360", amount=am, pm_id=366)
|
|
880
633
|
ord_resp: OrderResp = await self.take_ad(req)
|
|
881
634
|
order: OrderFull = await self.get_order_full(int(ord_resp.orderId))
|
|
882
|
-
odb = await self.
|
|
635
|
+
odb = await self.order_save(order)
|
|
883
636
|
t = await models.Transfer(order=odb, amount=odb.amount, updated_at=now())
|
|
884
637
|
await t.fetch_related("order__cred__pmcur__cur")
|
|
885
638
|
await self.pm_clients[366].send(t)
|
|
@@ -926,10 +679,14 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
926
679
|
|
|
927
680
|
sub_msg = json.dumps({"op": "subscribe", "args": ["FIAT_OTC_TOPIC", "FIAT_OTC_ONLINE_TOPIC"]})
|
|
928
681
|
await websocket.send(sub_msg)
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
682
|
+
try:
|
|
683
|
+
while resp := await websocket.recv():
|
|
684
|
+
if data := json.loads(resp):
|
|
685
|
+
logging.info(f" {now().strftime('%H:%M:%S')} upd: {data.get('topic')}:{data.get('type')}")
|
|
686
|
+
await self.proc(data)
|
|
687
|
+
except ConnectionClosedError as e:
|
|
688
|
+
logging.warning(e)
|
|
689
|
+
await self._start_listen()
|
|
933
690
|
|
|
934
691
|
async def proc(self, data: dict):
|
|
935
692
|
match data.get("topic"):
|
|
@@ -937,10 +694,12 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
937
694
|
match data["type"]:
|
|
938
695
|
case "STATUS_CHANGE":
|
|
939
696
|
upd = StatusChange.model_validate(data["data"])
|
|
940
|
-
|
|
697
|
+
if not upd.status:
|
|
698
|
+
logging.warning(data["data"])
|
|
699
|
+
order_db, order = await self.load_order(upd.exid)
|
|
941
700
|
match upd.status:
|
|
942
|
-
case
|
|
943
|
-
logging.info(f"Order {upd.
|
|
701
|
+
case OrderStatus.created:
|
|
702
|
+
logging.info(f"Order {upd.exid} CREATED at {upd.created_at}")
|
|
944
703
|
# await self.got_new_order(order_db, order)
|
|
945
704
|
|
|
946
705
|
# # сразу уменьшаем доступный остаток монеты/валюты
|
|
@@ -951,8 +710,8 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
951
710
|
# return
|
|
952
711
|
# await order_db.fetch_related("ad__pair_side__pair", "cred__pmcur__cur")
|
|
953
712
|
# await self.send_payment(order_db)
|
|
954
|
-
|
|
955
|
-
if upd.
|
|
713
|
+
# case OrderStatus.created:
|
|
714
|
+
if upd.ad__pair_side__is_sell == 0: # я продавец, ждем когда покупатель оплатит
|
|
956
715
|
# check_payment() # again
|
|
957
716
|
...
|
|
958
717
|
# if not (pmacdx := await self.get_pma_by_cdex(order)):
|
|
@@ -990,7 +749,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
990
749
|
# for o in pos.get("items", [])
|
|
991
750
|
# if (
|
|
992
751
|
# o["amount"] == order.amount
|
|
993
|
-
# and o["id"] != upd.
|
|
752
|
+
# and o["id"] != upd.exid
|
|
994
753
|
# and int(order.createDate) < int(o["createDate"]) + 15 * 60 * 1000
|
|
995
754
|
# # get full_order from o, and cred or pm from full_order:
|
|
996
755
|
# and self.api.get_order_details(orderId=o["id"])["result"][
|
|
@@ -1017,53 +776,53 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
1017
776
|
# return
|
|
1018
777
|
#
|
|
1019
778
|
# # !!! ОТПРАВЛЯЕМ ДЕНЬГИ !!!
|
|
1020
|
-
# self.api.release_assets(orderId=upd.
|
|
779
|
+
# self.api.release_assets(orderId=upd.exid)
|
|
1021
780
|
# logging.info(
|
|
1022
781
|
# f"Order {order.id} created, paid before #{tid}:{am} at {order.createDate}, and RELEASED at {now()}"
|
|
1023
782
|
# )
|
|
1024
|
-
elif upd.
|
|
783
|
+
elif upd.ad__pair_side__is_sell == 1: # я покупатель - ждем мою оплату
|
|
1025
784
|
# pay()
|
|
1026
|
-
logging.warning(f"Order {upd.
|
|
785
|
+
logging.warning(f"Order {upd.exid} CREATED2 at {now()}")
|
|
1027
786
|
|
|
1028
|
-
case
|
|
787
|
+
case OrderStatus.paid:
|
|
1029
788
|
if order_db.status == OrderStatus.paid:
|
|
1030
789
|
return
|
|
1031
790
|
await order_db.update_from_dict(
|
|
1032
791
|
{
|
|
1033
792
|
"status": OrderStatus.paid,
|
|
1034
|
-
"payed_at":
|
|
793
|
+
"payed_at": order.payed_at,
|
|
1035
794
|
}
|
|
1036
795
|
).save()
|
|
1037
|
-
logging.info(f"Order {order.
|
|
796
|
+
logging.info(f"Order {order.exid} payed at {order_db.payed_at}")
|
|
1038
797
|
|
|
1039
|
-
case
|
|
798
|
+
case OrderStatus.appealed_by_seller: # just any appealed
|
|
1040
799
|
# todo: appealed by WHO? щас наугад стоит by_seller
|
|
1041
800
|
await order_db.update_from_dict(
|
|
1042
801
|
{
|
|
1043
802
|
"status": OrderStatus.appealed_by_seller,
|
|
1044
|
-
"appealed_at":
|
|
803
|
+
"appealed_at": order.appealed_at,
|
|
1045
804
|
}
|
|
1046
805
|
).save()
|
|
1047
|
-
logging.info(f"Order {order.
|
|
806
|
+
logging.info(f"Order {order.exid} appealed at {order_db.appealed_at}")
|
|
1048
807
|
|
|
1049
|
-
case
|
|
808
|
+
case OrderStatus.canceled:
|
|
1050
809
|
await order_db.update_from_dict({"status": OrderStatus.canceled}).save()
|
|
1051
|
-
logging.info(f"Order {order.
|
|
810
|
+
logging.info(f"Order {order.exid} canceled at {datetime.now()}")
|
|
1052
811
|
# await self.money_upd(order_db)
|
|
1053
812
|
|
|
1054
|
-
case
|
|
813
|
+
case OrderStatus.completed:
|
|
1055
814
|
await order_db.refresh_from_db()
|
|
1056
815
|
if order_db.status != OrderStatus.completed:
|
|
1057
816
|
await order_db.update_from_dict(
|
|
1058
817
|
{
|
|
1059
818
|
"status": OrderStatus.completed,
|
|
1060
|
-
"confirmed_at":
|
|
819
|
+
"confirmed_at": order.confirmed_at,
|
|
1061
820
|
}
|
|
1062
821
|
).save(update_fields=["status", "confirmed_at"])
|
|
1063
822
|
# await self.money_upd(order_db)
|
|
1064
823
|
|
|
1065
824
|
case _:
|
|
1066
|
-
logging.warning(f"Order {order.
|
|
825
|
+
logging.warning(f"Order {order.exid} UNKNOWN STATUS {datetime.now()}")
|
|
1067
826
|
case "COUNT_DOWN":
|
|
1068
827
|
upd = CountDown.model_validate(data["data"])
|
|
1069
828
|
|
|
@@ -1080,7 +839,7 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
1080
839
|
# msg, _ = await models.Msg.update_or_create(
|
|
1081
840
|
# {
|
|
1082
841
|
# "to_maker": upd.userId == self.actor.exid and im_taker,
|
|
1083
|
-
# "sent_at":
|
|
842
|
+
# "sent_at": upd.createDate,
|
|
1084
843
|
# },
|
|
1085
844
|
# txt=upd.message,
|
|
1086
845
|
# order=order_db,
|
|
@@ -1112,29 +871,19 @@ class AgentClient(BaseAgentClient): # Bybit client
|
|
|
1112
871
|
# self.listen(data)
|
|
1113
872
|
case "SELLER_CANCEL_CHANGE":
|
|
1114
873
|
upd = SellerCancelChange.model_validate(data["data"])
|
|
874
|
+
order_db, order = await self.load_order(upd.id)
|
|
875
|
+
await order_db.cancel_request(self.agent.actor_id)
|
|
1115
876
|
case None:
|
|
1116
877
|
if not data.get("success"):
|
|
1117
|
-
|
|
878
|
+
raise HTTPException(401 if data["ret_msg"] == "Request not authorized" else data)
|
|
1118
879
|
else:
|
|
1119
880
|
return # success login, subscribes, input
|
|
1120
881
|
case _:
|
|
1121
882
|
logging.warning(data, "UNKNOWN TOPIC")
|
|
1122
883
|
|
|
1123
|
-
async def
|
|
1124
|
-
|
|
1125
|
-
return OrderFull.model_validate(
|
|
1126
|
-
|
|
1127
|
-
async def load_order(self, oid: int) -> tuple[models.Order, OrderFull]:
|
|
1128
|
-
if not self.orders.get(oid):
|
|
1129
|
-
order = await self.get_order_full(oid)
|
|
1130
|
-
if not (
|
|
1131
|
-
order_db := await models.Order.get_or_none(exid=oid, ad__maker__ex=self.actor.ex).prefetch_related(
|
|
1132
|
-
"ad__pair_side__pair", "cred__pmcur__cur"
|
|
1133
|
-
)
|
|
1134
|
-
):
|
|
1135
|
-
order_db = await self.create_order_db(order)
|
|
1136
|
-
self.orders[oid] = order_db, order
|
|
1137
|
-
return self.orders[oid]
|
|
884
|
+
async def _get_order_full(self, order_exid: int) -> OrderFull:
|
|
885
|
+
order_dict: dict = self.api.get_order_details(orderId=order_exid)["result"]
|
|
886
|
+
return OrderFull.model_validate(order_dict)
|
|
1138
887
|
|
|
1139
888
|
async def money_upd(self, odb: models.Order):
|
|
1140
889
|
# обновляем остаток монеты
|
|
@@ -1301,7 +1050,7 @@ async def main():
|
|
|
1301
1050
|
cn = await init_db(TORM)
|
|
1302
1051
|
|
|
1303
1052
|
agent = (
|
|
1304
|
-
await models.Agent.filter(actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, id=
|
|
1053
|
+
await models.Agent.filter(actor__ex_id=4, auth__isnull=False, status__gt=AgentStatus.off, id=2)
|
|
1305
1054
|
.prefetch_related(
|
|
1306
1055
|
"actor__ex",
|
|
1307
1056
|
"actor__person__user__gmail",
|
|
@@ -1315,11 +1064,11 @@ async def main():
|
|
|
1315
1064
|
# await filebot.start()
|
|
1316
1065
|
# b.add_handler(MessageHandler(cond_start_handler, command("cond")))
|
|
1317
1066
|
ex = await models.Ex.get(name="Bybit")
|
|
1318
|
-
|
|
1067
|
+
prx = PRX and "http://" + PRX
|
|
1068
|
+
ecl: ExClient = ex.client(filebot, proxy=prx)
|
|
1319
1069
|
abot = XyncBot(PAY_TOKEN, cn)
|
|
1320
1070
|
# pmas = await models.PmAgent.filter(active=True, user_id=1).prefetch_related("pm", "user__gmail")
|
|
1321
1071
|
# pm_clients = {pma.pm_id: pma.client(abot) for pma in pmas}
|
|
1322
|
-
prx = PRX and "http://" + PRX
|
|
1323
1072
|
cl: AgentClient = agent.client(ecl, filebot, abot, proxy=prx)
|
|
1324
1073
|
|
|
1325
1074
|
# req = TakeAdReq(ad_id=1955696985964089344, amount=504, pm_id=128)
|
|
@@ -1328,11 +1077,13 @@ async def main():
|
|
|
1328
1077
|
# await cl.actual_cond()
|
|
1329
1078
|
# cl.get_api_orders(), # 10, 1738357200000, 1742504399999
|
|
1330
1079
|
|
|
1080
|
+
# await cl.ex_client.set_coins()
|
|
1081
|
+
# await cl.ex_client.set_curs()
|
|
1331
1082
|
# await cl.ex_client.set_pairs()
|
|
1332
1083
|
# await cl.ex_client.set_pms()
|
|
1333
1084
|
|
|
1334
|
-
await cl.
|
|
1335
|
-
await cl.
|
|
1085
|
+
# await cl.load_creds()
|
|
1086
|
+
# await cl.load_my_ads()
|
|
1336
1087
|
|
|
1337
1088
|
my_ad = await models.MyAd[5]
|
|
1338
1089
|
await cl.ad_share(my_ad.id)
|
|
@@ -1381,7 +1132,7 @@ async def main():
|
|
|
1381
1132
|
|
|
1382
1133
|
# await cl.cancel_order(res.orderId)
|
|
1383
1134
|
await filebot.stop()
|
|
1384
|
-
await cl.
|
|
1135
|
+
await cl.stop()
|
|
1385
1136
|
|
|
1386
1137
|
|
|
1387
1138
|
if __name__ == "__main__":
|