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/Okx/ex.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from asyncio import run
|
|
2
2
|
|
|
3
3
|
from pyro_client.client.file import FileClient
|
|
4
|
-
from pyro_client.loader import
|
|
4
|
+
from pyro_client.loader import NET_TOKEN
|
|
5
5
|
from x_model import init_db
|
|
6
6
|
|
|
7
7
|
from xync_client.Abc.Exception import NoPairOnEx
|
|
@@ -102,7 +102,7 @@ class ExClient(BaseExClient):
|
|
|
102
102
|
async def main():
|
|
103
103
|
_ = await init_db(TORM)
|
|
104
104
|
bg = await models.Ex.get(name="Okx")
|
|
105
|
-
cl = ExClient(bg, FileClient(
|
|
105
|
+
cl = ExClient(bg, FileClient(NET_TOKEN))
|
|
106
106
|
await cl.ads("USDT", "EUR", True)
|
|
107
107
|
# curs = await cl.curs()
|
|
108
108
|
# coins = await cl.coins()
|
|
@@ -1,22 +1,65 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from asyncio import run
|
|
3
|
+
from base64 import b64encode
|
|
3
4
|
from datetime import datetime
|
|
4
5
|
from decimal import Decimal
|
|
5
6
|
from enum import StrEnum
|
|
7
|
+
from hashlib import sha256
|
|
8
|
+
from json import dumps
|
|
6
9
|
from math import ceil
|
|
10
|
+
from os import urandom
|
|
7
11
|
from time import sleep
|
|
12
|
+
from urllib.parse import urlencode
|
|
8
13
|
|
|
14
|
+
from PGram import Bot
|
|
9
15
|
from asyncpg.pgproto.pgproto import timedelta
|
|
16
|
+
from cryptography.hazmat.primitives import padding
|
|
17
|
+
from cryptography.hazmat.primitives.ciphers import Cipher
|
|
18
|
+
from cryptography.hazmat.primitives.ciphers.algorithms import AES
|
|
19
|
+
from cryptography.hazmat.primitives.ciphers.modes import CBC
|
|
10
20
|
from payeer_api import PayeerAPI
|
|
11
|
-
from playwright.async_api import async_playwright, Playwright, Error
|
|
21
|
+
from playwright.async_api import async_playwright, Playwright, Error, Browser
|
|
22
|
+
|
|
23
|
+
# noinspection PyProtectedMember
|
|
12
24
|
from playwright._impl._errors import TimeoutError
|
|
25
|
+
from tortoise.timezone import now
|
|
26
|
+
from xync_bot import XyncBot
|
|
27
|
+
from xync_schema.models import TopUp, TopUpAble, PmAgent, Transfer
|
|
13
28
|
|
|
14
|
-
from xync_client.loader import TORM
|
|
29
|
+
from xync_client.loader import TORM, PAY_TOKEN
|
|
15
30
|
|
|
16
31
|
from xync_client.Abc.PmAgent import PmAgentClient
|
|
17
32
|
from xync_client.Pms.Payeer.login import login
|
|
18
33
|
|
|
19
34
|
|
|
35
|
+
def encrypt_data(data: dict, md5digest: bytes):
|
|
36
|
+
# Convert data to JSON string (equivalent to json_encode)
|
|
37
|
+
bdata = dumps(data).encode()
|
|
38
|
+
|
|
39
|
+
# Generate random IV (16 bytes for AES)
|
|
40
|
+
iv = urandom(16)
|
|
41
|
+
|
|
42
|
+
# Pad or truncate key to 32 bytes
|
|
43
|
+
if len(md5digest) < 32:
|
|
44
|
+
md5digest = md5digest.ljust(32, b"\0") # Pad with null bytes
|
|
45
|
+
elif len(md5digest) > 32:
|
|
46
|
+
md5digest = md5digest[:32] # Truncate to 32 bytes
|
|
47
|
+
|
|
48
|
+
# Apply PKCS7 padding
|
|
49
|
+
padder = padding.PKCS7(128).padder() # 128 bits = 16 bytes block size
|
|
50
|
+
padded_data = padder.update(bdata)
|
|
51
|
+
padded_data += padder.finalize()
|
|
52
|
+
|
|
53
|
+
# Create cipher
|
|
54
|
+
cipher = Cipher(AES(md5digest), CBC(iv))
|
|
55
|
+
encryptor = cipher.encryptor()
|
|
56
|
+
|
|
57
|
+
# Encrypt
|
|
58
|
+
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
|
|
59
|
+
|
|
60
|
+
return iv + ciphertext
|
|
61
|
+
|
|
62
|
+
|
|
20
63
|
class Client(PmAgentClient):
|
|
21
64
|
class Pages(StrEnum):
|
|
22
65
|
_base = "https://payeer.com/en/"
|
|
@@ -26,40 +69,94 @@ class Client(PmAgentClient):
|
|
|
26
69
|
norm: str = "payeer"
|
|
27
70
|
pages: type(StrEnum) = Pages
|
|
28
71
|
api: PayeerAPI
|
|
72
|
+
with_userbot: bool = False
|
|
29
73
|
|
|
30
|
-
|
|
31
|
-
|
|
74
|
+
def __init__(self, agent: PmAgent, browser: Browser, abot: XyncBot):
|
|
75
|
+
super().__init__(agent, browser, abot)
|
|
32
76
|
if api_id := self.agent.auth.get("api_id"):
|
|
33
77
|
self.api = PayeerAPI(self.agent.auth["email"], api_id, self.agent.auth["api_sec"])
|
|
34
|
-
return self
|
|
35
78
|
|
|
36
79
|
async def _login(self):
|
|
37
80
|
await login(self.agent)
|
|
38
81
|
for cookie in self.agent.state["cookies"]:
|
|
39
82
|
await self.page.context.add_cookies([cookie])
|
|
40
|
-
await self.page.goto(self.pages.SEND)
|
|
83
|
+
await self.page.goto(self.pages.SEND, wait_until="commit")
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def form_redirect(topup: TopUp) -> tuple[str, dict | None]:
|
|
87
|
+
m_shop = str(topup.topupable.auth["id"])
|
|
88
|
+
m_orderid = str(topup.id)
|
|
89
|
+
m_amount = "{0:.2f}".format(topup.amount * 0.01)
|
|
90
|
+
m_curr = topup.cur.ticker
|
|
91
|
+
m_desc = b64encode(b"XyncPay top up").decode()
|
|
92
|
+
m_key = topup.topupable.auth["sec"]
|
|
93
|
+
data = [m_shop, m_orderid, m_amount, m_curr, m_desc]
|
|
94
|
+
|
|
95
|
+
# # additional
|
|
96
|
+
# m_params = {
|
|
97
|
+
# 'success_url': 'https://xync.net/topup?success=1',
|
|
98
|
+
# 'fail_url': 'https://xync.net/topup?success=0',
|
|
99
|
+
# 'status_url': 'https://xync.net/topup',
|
|
100
|
+
# 'reference': {'var1': '1'},
|
|
101
|
+
# }
|
|
102
|
+
#
|
|
103
|
+
# key = md5(m_orderid.to_bytes()).digest()
|
|
104
|
+
#
|
|
105
|
+
# base64url_encode(encrypt_data(params, key))
|
|
106
|
+
#
|
|
107
|
+
# data.append(m_params)
|
|
108
|
+
# # additional
|
|
109
|
+
|
|
110
|
+
data.append(m_key)
|
|
111
|
+
|
|
112
|
+
sign = sha256(":".join(data).encode()).hexdigest().upper()
|
|
113
|
+
|
|
114
|
+
params = {
|
|
115
|
+
"m_shop": m_shop,
|
|
116
|
+
"m_orderid": m_orderid,
|
|
117
|
+
"m_amount": m_amount,
|
|
118
|
+
"m_curr": m_curr,
|
|
119
|
+
"m_desc": m_desc,
|
|
120
|
+
"m_sign": sign,
|
|
121
|
+
# 'm_params': m_params,
|
|
122
|
+
# 'm_cipher_method': 'AES-256-CBC-IV',
|
|
123
|
+
"form[ps]": "2609",
|
|
124
|
+
"form[curr[2609]]": m_curr,
|
|
125
|
+
}
|
|
126
|
+
url = "https://payeer.com/merchant/?" + urlencode(params)
|
|
127
|
+
return url, None
|
|
128
|
+
|
|
129
|
+
def get_topup(self, tid: str) -> dict:
|
|
130
|
+
hi = self.api.get_history_info(tid)
|
|
131
|
+
ti = self.api.shop_order_info(hi["params"]["SHOP_ID"], hi["params"]["ORDER_ID"])["info"]
|
|
132
|
+
return ti["status"] == "execute" and {
|
|
133
|
+
"pmid": ti["id"],
|
|
134
|
+
"from_acc": hi["params"]["ACCOUNT_NUMBER"],
|
|
135
|
+
"oid": hi["params"]["ORDER_ID"],
|
|
136
|
+
"amount": int(float(ti["sumOut"]) * 100),
|
|
137
|
+
"ts": datetime.strptime(ti["dateCreate"], "%d.%m.%Y %H:%M:%S") - timedelta(hours=3),
|
|
138
|
+
}
|
|
41
139
|
|
|
42
|
-
async def send(self,
|
|
43
|
-
|
|
140
|
+
async def send(self, t: Transfer) -> tuple[str, bytes] | float:
|
|
141
|
+
dest, cur = t.order.cred.detail, t.order.cred.pmcur.cur.ticker
|
|
142
|
+
amount = round(t.order.amount * 10**-t.order.cred.pmcur.cur.scale, t.order.cred.pmcur.cur.scale)
|
|
143
|
+
self.last_active = now()
|
|
44
144
|
page = self.page
|
|
45
145
|
if not page.url.startswith(self.pages.SEND):
|
|
46
146
|
try:
|
|
47
|
-
await page.goto(self.pages.SEND)
|
|
147
|
+
await page.goto(self.pages.SEND, wait_until="commit")
|
|
48
148
|
except (TimeoutError, Error):
|
|
49
149
|
await login(self.agent)
|
|
50
150
|
for cookie in self.agent.state["cookies"]:
|
|
51
151
|
await page.context.add_cookies([cookie])
|
|
52
152
|
sleep(0.5)
|
|
53
|
-
await page.goto("https://payeer.com/en/account/send/")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
).all_text_contents()
|
|
57
|
-
has_amount = float(fiat_accounts[0].replace(",", "").strip())
|
|
58
|
-
if float(amount) <= has_amount:
|
|
153
|
+
await page.goto("https://payeer.com/en/account/send/", wait_until="commit")
|
|
154
|
+
has_amount = float(self.api.get_balance()[cur]["DOSTUPNO"])
|
|
155
|
+
if amount <= has_amount:
|
|
59
156
|
sleep(0.1)
|
|
60
157
|
await page.locator('input[name="param_ACCOUNT_NUMBER"]').fill(dest)
|
|
61
158
|
await page.locator("select[name=curr_receive]").select_option(value=cur)
|
|
62
|
-
sleep(0.
|
|
159
|
+
sleep(0.8)
|
|
63
160
|
await page.locator('input[name="sum_receive"]').fill(str(amount))
|
|
64
161
|
sleep(0.1)
|
|
65
162
|
# await page.locator("div.n-form--title").first.click()
|
|
@@ -67,7 +164,7 @@ class Client(PmAgentClient):
|
|
|
67
164
|
await page.click(".btn.n-form--btn.n-form--btn-mod")
|
|
68
165
|
sleep(0.5)
|
|
69
166
|
await page.click(".btn.n-form--btn.n-form--btn-mod")
|
|
70
|
-
sleep(1.
|
|
167
|
+
sleep(1.1)
|
|
71
168
|
if await page.locator(".input4").count():
|
|
72
169
|
await page.locator(".input4").fill(self.agent.auth.get("master_key"))
|
|
73
170
|
await page.click(".ok.button_green2")
|
|
@@ -77,42 +174,42 @@ class Client(PmAgentClient):
|
|
|
77
174
|
except TimeoutError as _:
|
|
78
175
|
logging.error("Repeat!")
|
|
79
176
|
sleep(0.5)
|
|
80
|
-
return await self.send(
|
|
177
|
+
return await self.send(t)
|
|
81
178
|
if await page.locator('.note_txt:has-text("successfully completed")').count():
|
|
82
179
|
transaction = await page.locator(".note_txt").all_text_contents()
|
|
83
|
-
trans_num =
|
|
84
|
-
await page.goto("https://payeer.com/ru/account/history/")
|
|
180
|
+
trans_num = transaction[0].replace("Transaction #", "").split()[0]
|
|
181
|
+
await page.goto("https://payeer.com/ru/account/history/", wait_until="commit")
|
|
85
182
|
await page.click(f".history-id-{trans_num} a.link")
|
|
86
183
|
sleep(1)
|
|
87
184
|
receipt = await page.query_selector(".ui-dialog.ui-corner-all")
|
|
88
|
-
return trans_num, await receipt.screenshot(path=f"tmp/{
|
|
185
|
+
return trans_num, receipt and await receipt.screenshot(path=f"tmp/{trans_num}.png")
|
|
89
186
|
else:
|
|
90
|
-
await self.
|
|
187
|
+
await self.receive("Payeer хз", photo=await self.page.screenshot())
|
|
91
188
|
return -1
|
|
92
189
|
else:
|
|
93
|
-
await self.
|
|
190
|
+
await self.receive(
|
|
94
191
|
f"Payeer no have {amount}, only {has_amount}{cur} to {dest}",
|
|
95
|
-
self.uid,
|
|
96
192
|
photo=await self.page.screenshot(),
|
|
97
193
|
)
|
|
98
194
|
return has_amount
|
|
99
195
|
|
|
100
|
-
def check_in(
|
|
101
|
-
self, amount: Decimal | int | float, cur: str,
|
|
196
|
+
async def check_in(
|
|
197
|
+
self, amount: Decimal | int | float, cur: str, dt: datetime = None, tid: str | int = None
|
|
102
198
|
) -> tuple[Decimal | None, int | None]:
|
|
103
|
-
history = self.api.history(type="incoming",
|
|
199
|
+
history = self.api.history(type="incoming", count=10)
|
|
104
200
|
if tid:
|
|
105
201
|
return (t := history.get(tid)) and Decimal(t["creditedAmount"])
|
|
106
|
-
|
|
202
|
+
ts: list[dict] = [
|
|
107
203
|
h
|
|
108
204
|
for h in history.values()
|
|
109
205
|
if (
|
|
110
206
|
amount <= Decimal(h["creditedAmount"]) <= ceil(amount)
|
|
111
207
|
and h["creditedCurrency"] == cur
|
|
112
|
-
|
|
208
|
+
# todo: wrong tz
|
|
209
|
+
and datetime.fromisoformat(h["date"]) > dt - timedelta(minutes=3) # +180(tz)-5
|
|
113
210
|
)
|
|
114
211
|
]
|
|
115
|
-
if not (t :=
|
|
212
|
+
if not (t := ts and ts[0]):
|
|
116
213
|
return None, None
|
|
117
214
|
return (
|
|
118
215
|
amount <= (am := Decimal(t["creditedAmount"])) <= ceil(amount) and t["creditedCurrency"] == cur
|
|
@@ -125,30 +222,37 @@ async def main(uid: int):
|
|
|
125
222
|
from x_model import init_db
|
|
126
223
|
|
|
127
224
|
_ = await init_db(TORM, True)
|
|
225
|
+
agent = await PmAgent.get_or_none(pm__norm="payeer", user__username_id=uid).prefetch_related(
|
|
226
|
+
"user__username__session", "pm"
|
|
227
|
+
)
|
|
228
|
+
if not agent:
|
|
229
|
+
raise Exception(f"No active user #{uid} with agent for volet!")
|
|
230
|
+
abot = Bot(PAY_TOKEN)
|
|
231
|
+
pyr = agent.client(abot)
|
|
128
232
|
playwright: Playwright = await async_playwright().start()
|
|
129
|
-
pyr = Client(uid)
|
|
130
233
|
try:
|
|
131
|
-
|
|
234
|
+
dest, amount, cur = "P79619335", 4, "RUB"
|
|
235
|
+
ta = await TopUpAble.get(pm__norm="payeer")
|
|
236
|
+
topup = await TopUp.create(amount=1001, cur_id=1, topupable=ta, user_id=1)
|
|
237
|
+
await topup.fetch_related("cur")
|
|
238
|
+
_url, _data = pyr.form_redirect(topup)
|
|
132
239
|
|
|
133
|
-
|
|
240
|
+
await pyr.start(playwright, False)
|
|
134
241
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
res = await pyr.send(dest, amount, cur)
|
|
138
|
-
res = await pyr.send(dest, 3, cur)
|
|
139
|
-
res = await pyr.send(dest, amount, cur)
|
|
242
|
+
_res = await pyr.send(dest, amount, cur)
|
|
243
|
+
_res = await pyr.send(dest, 3, cur)
|
|
140
244
|
|
|
141
|
-
res = pyr.check_in(
|
|
245
|
+
res = pyr.check_in(3, cur, datetime.now())
|
|
142
246
|
|
|
143
247
|
if len(res) > 1 and isinstance(res[1], bytes):
|
|
144
|
-
await pyr.
|
|
248
|
+
await pyr.receive(f"Transaction #{res[0]}", photo=res[1])
|
|
145
249
|
elif res[0] > 0:
|
|
146
|
-
await pyr.
|
|
250
|
+
await pyr.receive(f"Sreen of transaction #{res[0]} failed", photo=await pyr.page.screenshot())
|
|
147
251
|
else:
|
|
148
|
-
await pyr.
|
|
252
|
+
await pyr.receive(f"Sending {amount} {cur} to {dest} FAILED", photo=await pyr.page.screenshot())
|
|
149
253
|
|
|
150
254
|
except TimeoutError as te:
|
|
151
|
-
await pyr.
|
|
255
|
+
await pyr.receive(repr(te), photo=await pyr.page.screenshot())
|
|
152
256
|
raise te
|
|
153
257
|
# finally:
|
|
154
258
|
# await pyr.stop()
|
xync_client/Pms/Payeer/login.py
CHANGED
|
@@ -8,7 +8,31 @@ import time
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
async def login(agent: PmAgent):
|
|
11
|
-
|
|
11
|
+
options = uc.ChromeOptions()
|
|
12
|
+
options.add_argument("--disable-blink-features=AutomationControlled")
|
|
13
|
+
options.add_argument("--no-sandbox")
|
|
14
|
+
options.add_argument("--disable-dev-shm-usage")
|
|
15
|
+
# options.add_argument("--headless=new") # for Chrome >= 109
|
|
16
|
+
options.add_argument("--disable-renderer-backgrounding")
|
|
17
|
+
options.add_argument("--disable-background-timer-throttling")
|
|
18
|
+
options.add_argument("--disable-backgrounding-occluded-windows")
|
|
19
|
+
options.add_argument("--disable-client-side-phishing-detection")
|
|
20
|
+
options.add_argument("--disable-crash-reporter")
|
|
21
|
+
options.add_argument("--disable-oopr-debug-crash-dump")
|
|
22
|
+
options.add_argument("--no-crash-upload")
|
|
23
|
+
options.add_argument("--disable-gpu")
|
|
24
|
+
options.add_argument("--disable-extensions")
|
|
25
|
+
options.add_argument("--disable-low-res-tiling")
|
|
26
|
+
options.add_argument("--log-level=3")
|
|
27
|
+
options.add_argument("--silent")
|
|
28
|
+
options.add_argument("--window-size=1920,1080")
|
|
29
|
+
options.add_argument("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
|
|
30
|
+
|
|
31
|
+
driver = uc.Chrome(
|
|
32
|
+
options=options,
|
|
33
|
+
headless=False,
|
|
34
|
+
browser_executable_path="/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta",
|
|
35
|
+
)
|
|
12
36
|
wait = WebDriverWait(driver, timeout=10)
|
|
13
37
|
try:
|
|
14
38
|
driver.get("https://payeer.com/en/auth")
|
|
@@ -22,7 +46,10 @@ async def login(agent: PmAgent):
|
|
|
22
46
|
login_button = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "login-form__login-btn.step1")))
|
|
23
47
|
login_button.click()
|
|
24
48
|
time.sleep(4)
|
|
25
|
-
|
|
49
|
+
try:
|
|
50
|
+
login_button.click()
|
|
51
|
+
except Exception:
|
|
52
|
+
pass
|
|
26
53
|
time.sleep(1)
|
|
27
54
|
if (v := driver.find_elements(By.CLASS_NAME, "form-input-top")) and v[0].text == "Введите проверочный код":
|
|
28
55
|
code = input("Email code: ")
|