xync-client 0.0.25.dev19__tar.gz → 0.0.25.dev22__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.
- {xync_client-0.0.25.dev19/xync_client.egg-info → xync_client-0.0.25.dev22}/PKG-INFO +1 -1
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/TestEx.py +1 -1
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/Agent.py +3 -3
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/base.py +2 -7
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/ex.py +19 -22
- xync_client-0.0.25.dev22/xync_client/BingX/pyd.py +32 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/agent.py +34 -19
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/auth.py +3 -5
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/ex.py +2 -2
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/pyro.py +0 -1
- xync_client-0.0.25.dev22/xync_client/pyro.py +66 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22/xync_client.egg-info}/PKG-INFO +1 -1
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client.egg-info/SOURCES.txt +2 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/.env.sample +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/.gitignore +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/.pre-commit-config.yaml +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/README.md +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/makefile +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/pyproject.toml +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/setup.cfg +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/TestAgent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/TestAsset.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/TestOrder.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Binance/test_binance.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Gate/test_gate.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Wallet/test_agent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Wallet/test_ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/__init__.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/_test_ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/Asset.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/AuthTrait.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/Base.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/BaseTest.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/Ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/InAgent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Abc/Order.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/__init__.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/binance_async.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/earn_api.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/exceptions.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/sapi.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Binance/web_c2c.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/__init__.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/agent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/req.mjs +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/sign.js +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BingX/test/main.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BitGet/__init__.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BitGet/agent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BitGet/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/BitGet/req.mjs +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Bybit/agent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Bybit/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Bybit/web_earn.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Bybit/web_p2p.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Gate/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Gate/premarket.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Htx/agent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Htx/earn.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Htx/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/KuCoin/pub.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/KuCoin/web.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/Okx/ex.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/asset.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/inAgent.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/order.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/pyd.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/TgWallet/web.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/__init__.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client/loader.py +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client.egg-info/dependency_links.txt +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client.egg-info/requires.txt +0 -0
- {xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client.egg-info/top_level.txt +0 -0
|
@@ -18,7 +18,7 @@ class TestEx(BaseTest):
|
|
|
18
18
|
@pytest.fixture
|
|
19
19
|
async def clients(self) -> list[BaseClient]:
|
|
20
20
|
exs = await Ex.filter(status__gt=ExStatus.plan)
|
|
21
|
-
[await ex.fetch_related("
|
|
21
|
+
[await ex.fetch_related("actors__agent") for ex in exs if ex.type_ == ExType.tg]
|
|
22
22
|
clients: list[BaseExClient] = [ex.client() for ex in exs]
|
|
23
23
|
yield clients
|
|
24
24
|
[await cl.close() for cl in clients]
|
|
@@ -13,7 +13,7 @@ from xync_client.Abc.Base import BaseClient
|
|
|
13
13
|
class BaseAgentClient(BaseClient):
|
|
14
14
|
def __init__(self, agent: Agent):
|
|
15
15
|
self.agent: Agent = agent
|
|
16
|
-
super().__init__(self.agent.
|
|
16
|
+
super().__init__(self.agent.actor.ex) # , "host_p2p"
|
|
17
17
|
self.ex_client: BaseExClient = self.ex.client()
|
|
18
18
|
|
|
19
19
|
@abstractmethod
|
|
@@ -97,12 +97,12 @@ class BaseAgentClient(BaseClient):
|
|
|
97
97
|
async def fiat_f2in(self, fiat_new: FiatNew) -> FiatPydIn:
|
|
98
98
|
if not (_pmcur := await Pmcur.get_or_none(cur_id=fiat_new.cur_id, pm_id=fiat_new.pm_id)):
|
|
99
99
|
raise HTTPException(FailReason.body, f"No Pmcur with cur#{fiat_new.cur_id} and pm#{fiat_new.pm_id}", 404)
|
|
100
|
-
# cred = await Cred.create({"exid": }, pmcur=pmcur,
|
|
100
|
+
# cred = await Cred.create({"exid": }, pmcur=pmcur, actor=self.agent.actor)
|
|
101
101
|
# df = {"detail": fiat_pyd.detail, "name": fiat_pyd.name, "amount": fiat_pyd.amount, "target": fiat_pyd.target}
|
|
102
102
|
# unq = {"pmcur": pmcur, "user_id": uid}
|
|
103
103
|
|
|
104
104
|
# async def fiat_new(self, fiat: FiatNew) -> Fiat:
|
|
105
|
-
#
|
|
105
|
+
# actor = await Actor.get_or_create({"name": }, ex=self.ex_client.ex, exid=self.agent.actor.exid)
|
|
106
106
|
# FiatPydIn()
|
|
107
107
|
# fiat_db: Fiat = (await self.fiat_pyd2db(fiat, self.agent.user_id))[0]
|
|
108
108
|
# if not (fiatex := Fiatex.get_or_none(fiat=fiat_db, ex=self.agent.ex)):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import subprocess
|
|
3
2
|
from datetime import datetime
|
|
4
3
|
from json import dumps
|
|
4
|
+
from os.path import dirname
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from xync_client.Abc.Base import BaseClient
|
|
@@ -12,12 +12,7 @@ class BaseBingXClient(BaseClient):
|
|
|
12
12
|
traceid = str(uuid4()).replace("-", "")
|
|
13
13
|
now = str(int(datetime.now().timestamp() * 1000))
|
|
14
14
|
payload = dumps(_payload, separators=(",", ":"), sort_keys=True) if _payload else "{}"
|
|
15
|
-
|
|
16
|
-
"tests": "../xync_client/BingX/",
|
|
17
|
-
"xync_client": "BingX/",
|
|
18
|
-
}
|
|
19
|
-
pref = prefs.get(os.getcwd().split("/")[-1], "xync_client/BingX/")
|
|
20
|
-
p = subprocess.Popen(["node", pref + "req.mjs", now, traceid, payload], stdout=subprocess.PIPE)
|
|
15
|
+
p = subprocess.Popen(["node", dirname(__file__) + "/req.mjs", now, traceid, payload], stdout=subprocess.PIPE)
|
|
21
16
|
sign = p.stdout.read().decode().strip()
|
|
22
17
|
return {
|
|
23
18
|
"sign": sign,
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
from asyncio import run
|
|
2
2
|
|
|
3
3
|
from x_model import init_db
|
|
4
|
-
from xync_client.Abc.Base import DictOfDicts, FlatDict
|
|
5
4
|
from xync_schema import models
|
|
6
5
|
from xync_schema.models import Ex
|
|
6
|
+
from xync_schema.pydantic import PmPyd, CurEpyd, CoinEpyd
|
|
7
7
|
|
|
8
|
+
from xync_client.Abc.Base import FlatDict
|
|
8
9
|
from xync_client.Abc.Ex import BaseExClient
|
|
9
10
|
from xync_client.BingX.base import BaseBingXClient
|
|
10
11
|
from xync_client.loader import PG_DSN
|
|
12
|
+
from xync_client.Abc.Base import MapOfIdsList
|
|
13
|
+
from xync_client.BingX.pyd import PmEpyd
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class ExClient(BaseExClient, BaseBingXClient):
|
|
@@ -24,47 +27,42 @@ class ExClient(BaseExClient, BaseBingXClient):
|
|
|
24
27
|
"x-requested-with": "XMLHttpRequest",
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
async def _pms(self, cur):
|
|
30
|
+
async def _pms(self, cur) -> list[PmEpyd]:
|
|
28
31
|
pms = await self._get("/api/c2c/v1/advert/payment/list", params={"fiat": cur})
|
|
29
|
-
return pms["data"]
|
|
32
|
+
return [PmEpyd(**pm) for pm in pms["data"]["paymentMethodList"]]
|
|
30
33
|
|
|
31
34
|
# 19: Список всех платежных методов на бирже
|
|
32
|
-
async def pms(self) ->
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return
|
|
35
|
+
async def pms(self, cur: str = None) -> dict[int, PmPyd]:
|
|
36
|
+
all_pms = {}
|
|
37
|
+
for cur in await self.curs():
|
|
38
|
+
pms = await self._pms(cur.ticker)
|
|
39
|
+
for pm in pms:
|
|
40
|
+
all_pms[pm.id] = PmPyd(id=pm.id, name=pm.name, logo=pm.icon)
|
|
41
|
+
return all_pms
|
|
39
42
|
|
|
40
43
|
# 20: Список поддерживаемых валют на BingX
|
|
41
|
-
async def curs(self) ->
|
|
44
|
+
async def curs(self) -> list[CurEpyd]: # {cur.exid: cur.ticker}
|
|
42
45
|
params = {
|
|
43
46
|
"type": "1",
|
|
44
47
|
"asset": "USDT",
|
|
45
48
|
"coinType": "2",
|
|
46
49
|
}
|
|
47
50
|
curs = await self._get("/api/c2c/v1/common/supportCoins", params=params)
|
|
48
|
-
return
|
|
51
|
+
return [CurEpyd(exid=cur["id"], ticker=cur["name"]) for cur in curs["data"]["coins"]]
|
|
49
52
|
|
|
50
53
|
# 21: cur_pms_map на BingX
|
|
51
54
|
async def cur_pms_map(self):
|
|
52
|
-
|
|
53
|
-
pp = {}
|
|
54
|
-
for cur in curs.values():
|
|
55
|
-
pms = await self._pms(cur)
|
|
56
|
-
pp.update({cur: [p["id"] for p in pms["paymentMethodList"]]})
|
|
57
|
-
return pp
|
|
55
|
+
return {cur.exid: list(await self._pms(cur.exid)) for cur in await self.curs()}
|
|
58
56
|
|
|
59
57
|
# 22: Монеты на BingX
|
|
60
58
|
async def coins(self) -> FlatDict:
|
|
61
|
-
return
|
|
59
|
+
return [CoinEpyd(exid="USDT", ticker="USDT")]
|
|
62
60
|
|
|
63
61
|
# 23: Список пар валюта/монет
|
|
64
|
-
async def pairs(self):
|
|
62
|
+
async def pairs(self) -> MapOfIdsList:
|
|
65
63
|
coins = await self.coins()
|
|
66
64
|
curs = await self.curs()
|
|
67
|
-
return {cur: set(coins) for cur in curs
|
|
65
|
+
return {cur.exid: set(c.exid for c in coins) for cur in curs}
|
|
68
66
|
|
|
69
67
|
# 24: ads
|
|
70
68
|
async def ads(self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None):
|
|
@@ -86,7 +84,6 @@ async def main():
|
|
|
86
84
|
_ = await init_db(PG_DSN, models, True)
|
|
87
85
|
bg = await Ex.get(name="BingX")
|
|
88
86
|
cl = ExClient(bg)
|
|
89
|
-
# await cl.curs()
|
|
90
87
|
await cl.pms()
|
|
91
88
|
await cl.close()
|
|
92
89
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class User(BaseModel):
|
|
5
|
+
nickname: str
|
|
6
|
+
avatar: str
|
|
7
|
+
phone: bool
|
|
8
|
+
email: bool
|
|
9
|
+
# payMethods: dict
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AvailableVolume(BaseModel):
|
|
13
|
+
tradeUSDTNum30: float
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Price(BaseModel):
|
|
17
|
+
asset: str
|
|
18
|
+
fiat: str
|
|
19
|
+
value: str
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class OrderLimitsIn(BaseModel):
|
|
23
|
+
minAmount: str
|
|
24
|
+
maxAmount: str
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class PmEpyd(BaseModel):
|
|
28
|
+
id: int
|
|
29
|
+
name: str
|
|
30
|
+
mainColor: str
|
|
31
|
+
icon: str
|
|
32
|
+
number: int
|
|
@@ -43,7 +43,7 @@ from xync_schema.models import (
|
|
|
43
43
|
Coinex,
|
|
44
44
|
Pm,
|
|
45
45
|
Order,
|
|
46
|
-
|
|
46
|
+
Actor,
|
|
47
47
|
)
|
|
48
48
|
from xync_schema.pydantic import FiatNew, BaseAdPydIn, AdBuyPydIn, AdSalePydIn, CredPydIn, OrderPydIn
|
|
49
49
|
|
|
@@ -81,8 +81,22 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
81
81
|
orders = await self._post("/p2p/public-api/v2/offer/order/get", {"orderId": oid})
|
|
82
82
|
return orders["data"]
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
async def order_ad2epydin(self, ad: Ad, amount: float, cred_id: int = None) -> OrderEpydIn:
|
|
85
|
+
if not cred_id: # i am taker
|
|
86
|
+
iam_maker = self.agent.actor_id == ad.maker_id
|
|
87
|
+
iam_seller = ad.direction.sell == iam_maker
|
|
88
|
+
cred_filter = (
|
|
89
|
+
{"actor__agent__user_id": self.agent.user_id}
|
|
90
|
+
if iam_seller
|
|
91
|
+
else { # its a buy ad, i am taker
|
|
92
|
+
"actor": ad.maker
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
await Cred.filter(
|
|
96
|
+
**cred_filter,
|
|
97
|
+
pmcur__pms__in=ad.pms,
|
|
98
|
+
# todo: ordering and filtering by fiat.amount-target
|
|
99
|
+
).first() if iam_seller else 0
|
|
86
100
|
await ad.fetch_related("direction__pairex__pair__cur")
|
|
87
101
|
return OrderEpydIn(
|
|
88
102
|
offerId=ad.exid,
|
|
@@ -103,16 +117,12 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
103
117
|
|
|
104
118
|
async def order_epyd2pydin(self, order: OrderEpyd) -> OrderPydIn:
|
|
105
119
|
ad = await Ad.get(exid=order.offerId, direction__pairex__ex=self.ex)
|
|
106
|
-
cred = await Cred.get(exid=order.paymentDetails.id,
|
|
107
|
-
iam_maker = self.agent.
|
|
120
|
+
cred = await Cred.get(exid=order.paymentDetails.id, actor__ex=self.ex)
|
|
121
|
+
iam_maker = self.agent.actor == ad.maker
|
|
108
122
|
taker = (
|
|
109
|
-
(
|
|
110
|
-
await Contragent.get(
|
|
111
|
-
exid=(order.seller if order.is_sell == iam_maker else order.buyer).userId, ex=self.ex
|
|
112
|
-
)
|
|
113
|
-
)
|
|
123
|
+
(await Actor.get(exid=(order.seller if order.is_sell == iam_maker else order.buyer).userId, ex=self.ex))
|
|
114
124
|
if iam_maker
|
|
115
|
-
else self.agent.
|
|
125
|
+
else self.agent.actor
|
|
116
126
|
)
|
|
117
127
|
return OrderPydIn(
|
|
118
128
|
exid=order.id,
|
|
@@ -185,7 +195,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
185
195
|
cred_pin = CredPydIn(
|
|
186
196
|
exid=fiat.id,
|
|
187
197
|
pmcur=pmcur,
|
|
188
|
-
|
|
198
|
+
actor=self.agent.actor,
|
|
189
199
|
name=fiat.name,
|
|
190
200
|
)
|
|
191
201
|
for val in fiat.attributes.values:
|
|
@@ -266,7 +276,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
266
276
|
|
|
267
277
|
async def ad_epyd2pydin(self, ad_: OneAdTakerMakerSale | OneAdMakerBuy | OneAdTakerBuy) -> AdBuyPydIn | AdSalePydIn:
|
|
268
278
|
ad_in: BaseAdPydIn = await self.ex_client.ad_common_epyd2pydin(ad_)
|
|
269
|
-
ad_in.maker = self.agent.
|
|
279
|
+
ad_in.maker = self.agent.actor
|
|
270
280
|
if isinstance(ad_, _PmsTrait):
|
|
271
281
|
return AdBuyPydIn(
|
|
272
282
|
**ad_in.model_dump(),
|
|
@@ -292,7 +302,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
292
302
|
async def my_ad(self, ad_id: int) -> OneAdMakerBuy | OneAdTakerMakerSale:
|
|
293
303
|
ad = await self._post("/p2p/public-api/v2/offer/get-user-own", {"offerId": ad_id})
|
|
294
304
|
ad: dict = ad["data"]
|
|
295
|
-
assert ad["user"]["userId"] == self.agent.
|
|
305
|
+
assert ad["user"]["userId"] == self.agent.actor.exid, "Not your ad"
|
|
296
306
|
model = OneAdTakerMakerSale if ad["type"] == "SALE" else OneAdMakerBuy
|
|
297
307
|
return model(**ad)
|
|
298
308
|
|
|
@@ -301,7 +311,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
301
311
|
) -> AdMakerNewSale | AdMakerNewBuy:
|
|
302
312
|
coinex = await Coinex.get(coin=coin, ex=self.ex)
|
|
303
313
|
curex = await Curex.get(ex=self.ex, cur=cur)
|
|
304
|
-
creds = await Cred.filter(
|
|
314
|
+
creds = await Cred.filter(actor__agent__user_id=self.agent.user_id, pmcur__cur=cur).limit(5)
|
|
305
315
|
# todo: ordering and filtering by fiat.amount-target
|
|
306
316
|
ad_ein = _AdNew(
|
|
307
317
|
type="SALE" if is_sell else "PURCHASE",
|
|
@@ -320,7 +330,7 @@ class AgentClient(BaseAgentClient, AuthClient):
|
|
|
320
330
|
if ad_ein.type == "SALE":
|
|
321
331
|
ad_ein = AdMakerNewSale(**ad_ein.model_dump(exclude_none=True), paymentDetailsIds=[c.exid for c in creds])
|
|
322
332
|
else:
|
|
323
|
-
pmexs = await Pmex.filter(ex=self.agent.
|
|
333
|
+
pmexs = await Pmex.filter(ex=self.agent.actor.ex, pm__pmcurs__id__in=[c.pmcur_id for c in creds])
|
|
324
334
|
ad_ein = AdMakerNewBuy(**ad_ein.model_dump(exclude_none=True), paymentMethodCodes=[p.exid for p in pmexs])
|
|
325
335
|
return ad_ein
|
|
326
336
|
|
|
@@ -414,10 +424,10 @@ async def main():
|
|
|
414
424
|
maker: Agent
|
|
415
425
|
taker: Agent
|
|
416
426
|
maker, taker = (
|
|
417
|
-
await Agent.filter(
|
|
427
|
+
await Agent.filter(actor__ex_id=34, auth__isnull=False, user__status__gte=UserStatus.MEMBER)
|
|
418
428
|
.order_by("user_id")
|
|
419
429
|
.limit(2)
|
|
420
|
-
.prefetch_related("
|
|
430
|
+
.prefetch_related("actor__ex")
|
|
421
431
|
)
|
|
422
432
|
mcl: AgentClient = maker.client()
|
|
423
433
|
tcl: AgentClient = taker.client()
|
|
@@ -436,10 +446,15 @@ async def main():
|
|
|
436
446
|
await tcl.ad_switch(sad.id, True)
|
|
437
447
|
await mcl.ad_switch(bad.id, True)
|
|
438
448
|
sad_in = await tcl.ad_epyd2pydin(sad)
|
|
439
|
-
await Ad.create(**sad_in.model_dump(exclude_none=True))
|
|
449
|
+
sad_db = await Ad.create(**sad_in.model_dump(exclude_none=True))
|
|
440
450
|
bad_in = await mcl.ad_epyd2pydin(bad)
|
|
441
451
|
await Ad.create(**bad_in.model_dump(exclude_none=True))
|
|
442
452
|
|
|
453
|
+
order_epin: OrderEpydIn = await tcl.order_ad2epydin(sad_db, float(sad.orderAmountLimits.min))
|
|
454
|
+
new_order: OrderEpyd = await tcl.order_request(order_epin)
|
|
455
|
+
order_pin: OrderPydIn = await tcl.order_epyd2pydin(new_order)
|
|
456
|
+
_order_db = await tcl.order_pydin2db(order_pin)
|
|
457
|
+
|
|
443
458
|
# order_epin: OrderEpydIn = await tcl.order_ad2epydin(ad_db, float(mad.orderAmountLimits.min), cred_ids[0])
|
|
444
459
|
# new_order: OrderEpyd = await tcl.order_request(order_epin)
|
|
445
460
|
# order_pin: OrderPydIn = await tcl.order_epyd2pydin(new_order)
|
|
@@ -9,13 +9,11 @@ from xync_client.TgWallet.pyro import PyroClient
|
|
|
9
9
|
class AuthClient(BaseAuthTrait, BaseClient):
|
|
10
10
|
async def _get_auth_hdrs(self) -> dict[str, str]:
|
|
11
11
|
if not self.agent:
|
|
12
|
-
self.agent = (
|
|
13
|
-
await Agent.filter(contragent__ex=self.ex, auth__isnull=False).prefetch_related("contragent").first()
|
|
14
|
-
)
|
|
12
|
+
self.agent = await Agent.filter(actor__ex=self.ex, auth__isnull=False).prefetch_related("actor").first()
|
|
15
13
|
pyro = PyroClient(self.agent)
|
|
16
14
|
init_data = await pyro.get_init_data()
|
|
17
15
|
tokens = HttpClient("walletbot.me")._post("/api/v1/users/auth/", init_data)
|
|
18
|
-
self.agent.
|
|
19
|
-
await self.agent.
|
|
16
|
+
self.agent.actor.exid = tokens["user_id"]
|
|
17
|
+
await self.agent.actor.save()
|
|
20
18
|
pref = "" if self.__class__.__name__ == "AssetClient" else "Bearer "
|
|
21
19
|
return {"Wallet-Authorization": tokens["jwt"], "Authorization": pref + tokens["value"]}
|
|
@@ -4,7 +4,7 @@ from x_model import init_db
|
|
|
4
4
|
from xync_schema.pydantic import PmPyd, PmexBankPyd, CurEpyd, CoinEpyd, BaseAdPydIn, AdBuyPydIn
|
|
5
5
|
|
|
6
6
|
from xync_schema import models
|
|
7
|
-
from xync_schema.models import Ex, Direction, Pair, Coin, Cur, Pm,
|
|
7
|
+
from xync_schema.models import Ex, Direction, Pair, Coin, Cur, Pm, Actor, PairEx
|
|
8
8
|
|
|
9
9
|
from xync_client.TgWallet.pyd import (
|
|
10
10
|
PmEpydRoot,
|
|
@@ -123,7 +123,7 @@ class ExClient(BaseExClient, AuthClient):
|
|
|
123
123
|
|
|
124
124
|
async def ad_taker_epyd2pydin(self, ad: _TakerOne) -> AdBuyPydIn:
|
|
125
125
|
adx: BaseAdPydIn = await self.ad_common_epyd2pydin(ad)
|
|
126
|
-
adx.maker = (await
|
|
126
|
+
adx.maker = (await Actor.update_or_create({"name": ad.user.nickname}, ex=self.ex, exid=ad.user.userId))[0]
|
|
127
127
|
pms = ad.paymentMethods if isinstance(ad, _PmsTrait) else [pd.paymentMethod for pd in ad.paymentDetails]
|
|
128
128
|
return AdBuyPydIn(
|
|
129
129
|
**adx.model_dump(), pms_=await Pm.filter(pmexs__ex=self.ex, pmexs__exid__in=[p.code for p in pms])
|
|
@@ -11,7 +11,6 @@ from xync_schema.models import Agent
|
|
|
11
11
|
|
|
12
12
|
class PyroClient:
|
|
13
13
|
def __init__(self, agent: Agent):
|
|
14
|
-
self.agent = agent
|
|
15
14
|
self.app: Client = Client(str(agent.user_id), TG_API_ID, TG_API_HASH, session_string=agent.auth["sess"])
|
|
16
15
|
|
|
17
16
|
async def get_init_data(self) -> dict:
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from asyncio import run
|
|
2
|
+
from pyrogram import Client
|
|
3
|
+
from pyrogram.errors import UserNotParticipant
|
|
4
|
+
from pyrogram.raw.functions.channels import ToggleForum
|
|
5
|
+
from pyrogram.raw.types import InputChannel
|
|
6
|
+
from pyrogram.types import ChatPrivileges
|
|
7
|
+
from src.loader import PG_DSN
|
|
8
|
+
from tg_auth import UserStatus
|
|
9
|
+
from x_model import init_db
|
|
10
|
+
from xync_client.loader import TG_API_ID, TG_API_HASH
|
|
11
|
+
from xync_schema import models
|
|
12
|
+
from xync_schema.models import Agent
|
|
13
|
+
|
|
14
|
+
max_privs = ChatPrivileges(
|
|
15
|
+
# can_manage_chat=True, 3 default
|
|
16
|
+
can_delete_messages=True,
|
|
17
|
+
can_manage_video_chats=True, # Groups and supergroups only
|
|
18
|
+
can_restrict_members=True,
|
|
19
|
+
can_promote_members=True,
|
|
20
|
+
can_change_info=True,
|
|
21
|
+
can_invite_users=True,
|
|
22
|
+
can_pin_messages=True, # Groups and supergroups only
|
|
23
|
+
can_manage_topics=True, # Supergroups only
|
|
24
|
+
is_anonymous=True
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PyroClient:
|
|
29
|
+
def __init__(self, agent: Agent):
|
|
30
|
+
self.app: Client = Client(str(agent.user_id), TG_API_ID, TG_API_HASH, session_string=agent.auth["sess"])
|
|
31
|
+
|
|
32
|
+
async def create_orders_forum(self, uid: int | str) -> tuple[int, bool]:
|
|
33
|
+
async with self.app as app:
|
|
34
|
+
app: Client
|
|
35
|
+
forum = await app.create_supergroup(f"xync{uid}", "Xync Orders")
|
|
36
|
+
if not (_ := await app.toggle_forum_topics(chat_id=forum.id, enabled=True)):
|
|
37
|
+
r = await app.delete_channel(forum.id)
|
|
38
|
+
r = await forum.leave()
|
|
39
|
+
raise Exception(f"Chat {forum.id} for {app.me.username} not converted to forum")
|
|
40
|
+
added = await forum.add_members([uid, "XyncNetBot"]) # , "xync_bot"
|
|
41
|
+
try:
|
|
42
|
+
await forum.get_member(uid)
|
|
43
|
+
except UserNotParticipant:
|
|
44
|
+
added = False
|
|
45
|
+
await forum.promote_member("XyncNetBot", max_privs)
|
|
46
|
+
# await forum.leave()
|
|
47
|
+
return forum.id, added
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def main():
|
|
51
|
+
_ = await init_db(PG_DSN, models, True)
|
|
52
|
+
agent = await Agent.filter(
|
|
53
|
+
actor__ex__name="TgWallet", auth__isnull=False, user__status__gt=UserStatus.RESTRICTED
|
|
54
|
+
).first() # .order_by("-user__created_forums__count")
|
|
55
|
+
pcl = PyroClient(agent)
|
|
56
|
+
res = await pcl.create_orders_forum("cryrub")
|
|
57
|
+
print(res)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
from dotenv import load_dotenv
|
|
62
|
+
from os import getenv as env
|
|
63
|
+
|
|
64
|
+
load_dotenv()
|
|
65
|
+
PG_DSN = f"postgres://{env('POSTGRES_USER')}:{env('POSTGRES_PASSWORD')}@{env('POSTGRES_HOST', 'xyncdbs')}:{env('POSTGRES_PORT', 5432)}/{env('POSTGRES_DB', env('POSTGRES_USER'))}"
|
|
66
|
+
run(main())
|
|
@@ -19,6 +19,7 @@ tests/_todo_refact/Wallet/test_agent.py
|
|
|
19
19
|
tests/_todo_refact/Wallet/test_ex.py
|
|
20
20
|
xync_client/__init__.py
|
|
21
21
|
xync_client/loader.py
|
|
22
|
+
xync_client/pyro.py
|
|
22
23
|
xync_client.egg-info/PKG-INFO
|
|
23
24
|
xync_client.egg-info/SOURCES.txt
|
|
24
25
|
xync_client.egg-info/dependency_links.txt
|
|
@@ -43,6 +44,7 @@ xync_client/BingX/__init__.py
|
|
|
43
44
|
xync_client/BingX/agent.py
|
|
44
45
|
xync_client/BingX/base.py
|
|
45
46
|
xync_client/BingX/ex.py
|
|
47
|
+
xync_client/BingX/pyd.py
|
|
46
48
|
xync_client/BingX/req.mjs
|
|
47
49
|
xync_client/BingX/sign.js
|
|
48
50
|
xync_client/BingX/test/main.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Binance/test_binance.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Bybit/test_bybit.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Bybit/test_bybit_p2p.py
RENAMED
|
File without changes
|
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Htx/test_htx_p2p.py
RENAMED
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/tests/_todo_refact/Wallet/test_agent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xync_client-0.0.25.dev19 → xync_client-0.0.25.dev22}/xync_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|