xync-client 0.1.3__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.
Potentially problematic release.
This version of xync-client might be problematic. Click here for more details.
- xync_client/Binance/binance_async.py +83 -0
- xync_client/Binance/earn_api.py +83 -0
- xync_client/Binance/sapi.py +267 -0
- xync_client/Binance/web.py +30 -0
- xync_client/Binance/web_c2c.py +227 -0
- xync_client/Bybit/web_earn.py +78 -0
- xync_client/Bybit/web_p2p.py +329 -0
- xync_client/Gate/premarket.py +65 -0
- xync_client/Htx/watchdog/Ad.py +0 -0
- xync_client/Htx/watchdog/init.py +0 -0
- xync_client/Htx/watchdog/lib.py +0 -0
- xync_client/Htx/watchdog/main.py +0 -0
- xync_client/Htx/web.py +76 -0
- xync_client/Htx/web_c2c.py +18 -0
- xync_client/KuCoin/web.py +30 -0
- xync_client/Okx/web.py +6 -0
- xync_client/Proto.py +168 -0
- xync_client/TgWallet/pyro.py +29 -0
- xync_client/TgWallet/web.py +70 -0
- xync_client/TgWallet/web_p2p.py +182 -0
- xync_client/__init__.py +0 -0
- xync_client/exceptions.py +27 -0
- xync_client/loader.py +23 -0
- xync_client/rs.py +38 -0
- xync_client-0.1.3.dist-info/METADATA +21 -0
- xync_client-0.1.3.dist-info/RECORD +28 -0
- xync_client-0.1.3.dist-info/WHEEL +5 -0
- xync_client-0.1.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from http_client import Client
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Priv(Client):
|
|
5
|
+
base_url = 'https://www.gate.io'
|
|
6
|
+
middle_url = '/apiw/v2/'
|
|
7
|
+
|
|
8
|
+
def __init__(self, uid: str, pver: str):
|
|
9
|
+
self.headers = {
|
|
10
|
+
# 'content-type': 'application/json',
|
|
11
|
+
'cookie': f'uid={uid};pver={pver}'
|
|
12
|
+
}
|
|
13
|
+
super().__init__()
|
|
14
|
+
|
|
15
|
+
# 1: Get ads for taker
|
|
16
|
+
async def get_premarket_ads(self, cur: str = 'HMSTR', sell: bool = True, done: bool = False, limit: int = 100) -> list[dict]:
|
|
17
|
+
params = {
|
|
18
|
+
'page': 1,
|
|
19
|
+
'limit': limit,
|
|
20
|
+
'currency': cur,
|
|
21
|
+
'side': 'sell' if sell else 'buy',
|
|
22
|
+
'status': 'transaction_completed' if done else 'no_transaction'
|
|
23
|
+
}
|
|
24
|
+
res = await self.get('pre_market/market_orders', params)
|
|
25
|
+
return res['data']['list']
|
|
26
|
+
|
|
27
|
+
# 2: Get my ads
|
|
28
|
+
async def get_my_premarket_ads(self) -> list[dict]:
|
|
29
|
+
params = {
|
|
30
|
+
'type': 'current_orders',
|
|
31
|
+
'page': 1,
|
|
32
|
+
'limit': 100
|
|
33
|
+
}
|
|
34
|
+
res = await self.get('pre_market/orders', params)
|
|
35
|
+
return res['data']['list']
|
|
36
|
+
|
|
37
|
+
# 3: New ad
|
|
38
|
+
async def post_premarket_ad(self, price: float, amount: int, sell: bool = True, cur: str = 'HMSTR') -> int:
|
|
39
|
+
data = {
|
|
40
|
+
"fundpass":"",
|
|
41
|
+
"currency": cur,
|
|
42
|
+
'side': 'sell' if sell else 'buy',
|
|
43
|
+
"amount": str(amount),
|
|
44
|
+
"price": str(price)
|
|
45
|
+
}
|
|
46
|
+
res = await self.post('pre_market/orders', data)
|
|
47
|
+
return res['data']['order_id']
|
|
48
|
+
|
|
49
|
+
# 4: Del ad
|
|
50
|
+
async def del_premarket_ad(self, order_id: int) -> bool:
|
|
51
|
+
res = await self.delete(f'pre_market/orders/{order_id}')
|
|
52
|
+
return not res['code']
|
|
53
|
+
|
|
54
|
+
# 5: Execute deal
|
|
55
|
+
async def deal(self, order_id: int, price: float, amount: int, sell: bool = True, cur: str = 'HMSTR') -> bool:
|
|
56
|
+
data = {
|
|
57
|
+
"fundpass": "",
|
|
58
|
+
"currency": cur,
|
|
59
|
+
'side': 'sell' if sell else 'buy',
|
|
60
|
+
"amount": amount,
|
|
61
|
+
"price": price,
|
|
62
|
+
"deal_order_id": order_id
|
|
63
|
+
}
|
|
64
|
+
res = await self.post('pre_market/deal_order')
|
|
65
|
+
return not res['code']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
xync_client/Htx/web.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
from json import loads
|
|
2
|
+
from http_client import Client, repeat_on_fault
|
|
3
|
+
|
|
4
|
+
from cex_clients.loader import HT
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Public(Client):
|
|
8
|
+
base_url = 'https://www.htx.com'
|
|
9
|
+
middle_url = '/-/x'
|
|
10
|
+
|
|
11
|
+
# 1: Get all: currency,pay,allCountry,coin
|
|
12
|
+
@repeat_on_fault()
|
|
13
|
+
async def get_all(self) -> (dict, dict, dict, dict):
|
|
14
|
+
res = await self.get('/otc/v1/data/config-list?type=currency,pay,allCountry,coin')
|
|
15
|
+
return res['data'].values()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Earn(Client):
|
|
19
|
+
base_url = 'https://www.htx.com'
|
|
20
|
+
middle_url = '/-/x/hbg/'
|
|
21
|
+
|
|
22
|
+
# 1: Get BETH staking details
|
|
23
|
+
@repeat_on_fault()
|
|
24
|
+
async def get_staking_products(self):
|
|
25
|
+
res = await self.get('v1/hbps/vote/product/list')
|
|
26
|
+
return res['data']
|
|
27
|
+
|
|
28
|
+
# 2: Get ongoing earn products
|
|
29
|
+
@repeat_on_fault()
|
|
30
|
+
async def get_recommend_products(self):
|
|
31
|
+
res = await self.get('v1/saving/mining/prime_earn/activity/onGoing')
|
|
32
|
+
return res['data']
|
|
33
|
+
|
|
34
|
+
# 3: Get newList earn products
|
|
35
|
+
@repeat_on_fault()
|
|
36
|
+
async def get_new_products(self, page: int = 1):
|
|
37
|
+
res = (await self.get('v4/saving/mining/project/queryLimitList', {'page': page}))['data']
|
|
38
|
+
if len(res) == 6:
|
|
39
|
+
res += await self.get_new_products(page+1)
|
|
40
|
+
return res
|
|
41
|
+
|
|
42
|
+
# 4: Get fixed earn products
|
|
43
|
+
@repeat_on_fault()
|
|
44
|
+
async def get_lock_products(self, page: int = 1):
|
|
45
|
+
res = (await self.get('v4/saving/mining/project/queryFixedList', {'page': page}))['data']
|
|
46
|
+
if len(res) == 6:
|
|
47
|
+
res += await self.get_lock_products(page+1)
|
|
48
|
+
return res
|
|
49
|
+
|
|
50
|
+
# 5: Get flexible earn products
|
|
51
|
+
@repeat_on_fault()
|
|
52
|
+
async def get_flex_products(self, page: int = 1):
|
|
53
|
+
res = (await self.get('v4/saving/mining/project/queryYbbList', {'page': page}))['data']
|
|
54
|
+
if len(res) == 10:
|
|
55
|
+
res += await self.get_flex_products(page+1)
|
|
56
|
+
return res
|
|
57
|
+
|
|
58
|
+
# 6: Get ongoing earn products
|
|
59
|
+
@repeat_on_fault()
|
|
60
|
+
async def get_large_products(self):
|
|
61
|
+
res = await self.get('v4/saving/mining/project/largeAmtList')
|
|
62
|
+
return res['data']
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Private(Client): # Huobi async client
|
|
66
|
+
base_url = 'https://www.htx.com'
|
|
67
|
+
middle_url = '/'
|
|
68
|
+
headers = loads(HT)
|
|
69
|
+
|
|
70
|
+
""" PUBLIC METHS """
|
|
71
|
+
# 1: Get BETH staking details
|
|
72
|
+
@repeat_on_fault()
|
|
73
|
+
async def get_beth_rate(self):
|
|
74
|
+
# pool token required
|
|
75
|
+
res = await self.get('hbp/eth2/v1/staking/eth2/profit')
|
|
76
|
+
return res['data']['mr']
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from http_client import Client
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Public(Client):
|
|
5
|
+
url_ads_web = 'https://www.huobi.com/en-us/fiat-crypto/trade/'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Private(Client):
|
|
9
|
+
base_url = ''
|
|
10
|
+
middle_url = ''
|
|
11
|
+
|
|
12
|
+
htok: str = 'Ev5lFfAvxDU2MA9BJ-Mc4U6zZG3Wb6qsp3Tx2fz6GIoY-uOP2m0-gvjE57ad1qDF'
|
|
13
|
+
|
|
14
|
+
url_ads_req = 'https://otc-cf.huobi.com/v1/data/trade-market'
|
|
15
|
+
url_my_ads = 'https://otc-api.trygofast.com/v1/data/trade-list?pageSize=50'
|
|
16
|
+
url_my_ad = 'https://www.huobi.com/-/x/otc/v1/otc/trade/' # + id
|
|
17
|
+
url_my_bals = 'https://www.huobi.com/-/x/otc/v1/capital/balance'
|
|
18
|
+
url_paccs = 'https://www.huobi.com/-/x/otc/v1/user/receipt-account'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from http_client import Client, repeat_on_fault
|
|
2
|
+
from http_client.client import HttpNotFound
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Earn(Client):
|
|
6
|
+
base_url = 'https://www.kucoin.com'
|
|
7
|
+
middle_url = '/'
|
|
8
|
+
|
|
9
|
+
# 1: Get BETH staking details
|
|
10
|
+
@repeat_on_fault()
|
|
11
|
+
async def get_earn_products(self) -> dict:
|
|
12
|
+
res = await self.get('_pxapi/pool-staking/v3/products/currencies')
|
|
13
|
+
return res['data']
|
|
14
|
+
|
|
15
|
+
# 2: Get ongoing earn products
|
|
16
|
+
@repeat_on_fault()
|
|
17
|
+
async def get_onchain_products(self) -> dict:
|
|
18
|
+
res = await self.get('_api/loan-b2c/outer/condition-currencies')
|
|
19
|
+
return res['data']
|
|
20
|
+
|
|
21
|
+
# 3: Get product detail
|
|
22
|
+
@repeat_on_fault()
|
|
23
|
+
async def get_product_detail(self, pid: int) -> dict:
|
|
24
|
+
try:
|
|
25
|
+
res = await self.get('_pxapi/pool-staking/v3/products/'+str(pid))
|
|
26
|
+
except HttpNotFound:
|
|
27
|
+
return {}
|
|
28
|
+
if not res['success']:
|
|
29
|
+
pass
|
|
30
|
+
return res['data'] or {}
|
xync_client/Okx/web.py
ADDED
xync_client/Proto.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from xync_schema.model import Agent, Ex, User, OrderStatus, Coin, Cur, Order, Fiat, Pm, PmType, Ad, AdStatus
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AgentProto(Protocol):
|
|
7
|
+
def __init__(self, agent: Agent):
|
|
8
|
+
self.agent: Agent = agent
|
|
9
|
+
self.public: AgentProto.PublicProto = AgentProto.PublicProto(agent.ex)
|
|
10
|
+
self.pre_url: str = agent.ex.host
|
|
11
|
+
|
|
12
|
+
# 0: Получшение ордеров в статусе status, по монете coin, в валюте coin, продаже(is_sell=True)/покупке(is_sell=False)
|
|
13
|
+
def get_orders(
|
|
14
|
+
self, stauts=OrderStatus.active, coin: Coin = None, cur: Cur = None, is_sell: bool = None
|
|
15
|
+
) -> list[Order]:
|
|
16
|
+
...
|
|
17
|
+
|
|
18
|
+
class OrderProto(Protocol):
|
|
19
|
+
def __init__(self, order: Order):
|
|
20
|
+
self.order: Order = order
|
|
21
|
+
|
|
22
|
+
# 1: [T] Получшение ордеров в статусе status, по монете coin, в валюте coin, продаже(is_sell=True)/покупке(is_sell=False)
|
|
23
|
+
def order_request(self, ad_id: int, amount: float) -> Order:
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
# 2: [T] Отмена запроса на сделку
|
|
27
|
+
def cancel_request(self, ad_id: int, amount: float) -> Order:
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
# 3: [M] Одобрить запрос на сделку
|
|
31
|
+
def accept_request(self) -> bool:
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
# 4: [M] Отклонить запрос на сделку
|
|
35
|
+
def reject_request(self) -> bool:
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
# 5: [B] Перевод сделки в состояние "оплачено", c отправкой чека
|
|
39
|
+
def mark_payed(self, receipt):
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
# 6: [B] Отмена сделки
|
|
43
|
+
def cancel_order(self) -> bool:
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
# 7: [S] Подтвердить получение оплаты
|
|
47
|
+
def confirm(self) -> bool:
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
# 9, 10: [S, B] Подать аппеляцию cо скриншотом / видео / файлом
|
|
51
|
+
def start_appeal(self, file) -> bool:
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
# 11, 12: [S, B] Встречное оспаривание полученной аппеляции cо скриншотом / видео / файлом
|
|
55
|
+
def dispute_appeal(self, file) -> bool:
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
# 15: [B, S] Отмена аппеляции
|
|
59
|
+
def cancel_appeal(self) -> bool:
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
# 16: Отправка сообщения юзеру в чат по ордеру с приложенным файлом
|
|
63
|
+
def send_order_msg(self, msg: str, file=None) -> bool:
|
|
64
|
+
...
|
|
65
|
+
|
|
66
|
+
# 17: Отправка сообщения по апелляции
|
|
67
|
+
def send_appeal_msg(self, file, msg: str = None) -> bool:
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
class PublicProto(Protocol):
|
|
71
|
+
def __init__(self, ex: Ex):
|
|
72
|
+
self.ex: Ex = ex
|
|
73
|
+
|
|
74
|
+
# 21: Список поддерживаемых валют
|
|
75
|
+
def curs(self) -> list[Cur]:
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
# 22: Список торгуемых монет (с ограничениям по валютам, если есть)
|
|
79
|
+
def coins(self, cur: Cur = None) -> list[Coin]:
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
# 23: Список платежных методов по каждой валюте
|
|
83
|
+
def pms(self, cur: Cur) -> list[Pm]:
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
# 24: Список объяв по (buy/sell, cur, coin, pm)
|
|
87
|
+
def ads(self, coin: Coin, cur: Cur, is_sell: bool, pms: list[Pm] = None) -> list[Ad]:
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
# # # Fiat
|
|
91
|
+
# 25: Список реквизитов моих платежных методов
|
|
92
|
+
def my_fiats(self, cur: Cur = None) -> list[Fiat]:
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
# 26: Создание
|
|
96
|
+
def fiat_new(self, cur: Cur, pm: Pm, detail: str, type_: PmType = None) -> Fiat:
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
# 27: Редактирование
|
|
100
|
+
def fiat_upd(self, detail: str = None, type_: PmType = None) -> bool:
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
# 28: Удаление
|
|
104
|
+
def fiat_del(self, fiat_id:int) -> bool:
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
# # # Ad
|
|
108
|
+
# 29: Список моих ad
|
|
109
|
+
def my_ads(self) -> list[Ad]:
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
# 30: Создание ad:
|
|
113
|
+
def ad_new(
|
|
114
|
+
self,
|
|
115
|
+
coin: Coin,
|
|
116
|
+
cur: Cur,
|
|
117
|
+
is_sell: bool,
|
|
118
|
+
pms: list[Pm],
|
|
119
|
+
price: float,
|
|
120
|
+
is_float: bool = True,
|
|
121
|
+
min_fiat: int = None,
|
|
122
|
+
details: str = None,
|
|
123
|
+
autoreply: str = None,
|
|
124
|
+
status: AdStatus = AdStatus.active
|
|
125
|
+
) -> Ad:
|
|
126
|
+
...
|
|
127
|
+
|
|
128
|
+
# 31: Редактирование
|
|
129
|
+
def ad_upd(
|
|
130
|
+
self,
|
|
131
|
+
pms: [Pm] = None,
|
|
132
|
+
price: float = None,
|
|
133
|
+
is_float: bool = None,
|
|
134
|
+
min_fiat: int = None,
|
|
135
|
+
details: str = None,
|
|
136
|
+
autoreply: str = None,
|
|
137
|
+
status: AdStatus = None
|
|
138
|
+
) -> bool:
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
# 32: Удаление
|
|
142
|
+
def ad_del(self) -> bool:
|
|
143
|
+
...
|
|
144
|
+
|
|
145
|
+
# 33: Вкл/выкл объявления
|
|
146
|
+
def ad_switch(self) -> bool:
|
|
147
|
+
...
|
|
148
|
+
|
|
149
|
+
# 34: Вкл/выкл всех объявлений
|
|
150
|
+
def ads_switch(self) -> bool:
|
|
151
|
+
...
|
|
152
|
+
|
|
153
|
+
# # # User
|
|
154
|
+
# 35: Получить объект юзера по его ид
|
|
155
|
+
def get_user(self, user_id) -> User:
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
# 36: Отправка сообщения юзеру с приложенным файло
|
|
159
|
+
def send_user_msg(self, msg:str, file=None) -> bool:
|
|
160
|
+
...
|
|
161
|
+
|
|
162
|
+
# 37: (Раз)Блокировать юзера
|
|
163
|
+
def block_user(self, is_blocked: bool = True) -> bool:
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
# 38: Поставить отзыв юзеру
|
|
167
|
+
def rate_user(self, positive: bool) -> bool:
|
|
168
|
+
...
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from urllib.parse import parse_qs
|
|
2
|
+
from pyrogram import Client
|
|
3
|
+
from pyrogram.raw import functions
|
|
4
|
+
from xync_schema.model import Agent
|
|
5
|
+
|
|
6
|
+
api_id = 20276309
|
|
7
|
+
api_hash = "077f4a2aa1debc0768c582c818d20f64"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def get_init_data(agent: Agent):
|
|
11
|
+
async with Client(str(agent.user_id), api_id, api_hash, session_string=agent.auth['sess']) as app:
|
|
12
|
+
app: Client
|
|
13
|
+
await app.send_message("me", "Greetings from **Pyrogram**!")
|
|
14
|
+
bot = await app.resolve_peer('wallet')
|
|
15
|
+
me = await app.resolve_peer(agent.user_id)
|
|
16
|
+
res = await app.invoke(functions.messages.RequestWebView(peer=me, bot=bot, platform='chatparse'))
|
|
17
|
+
raw = parse_qs(res.url)['tgWebAppUserId'][0].split('#tgWebAppData=')[1]
|
|
18
|
+
j = parse_qs(raw)
|
|
19
|
+
dct = {
|
|
20
|
+
"web_view_init_data": {
|
|
21
|
+
"query_id": j['query_id'][0],
|
|
22
|
+
"user": j['user'][0],
|
|
23
|
+
"auth_date": j['auth_date'][0],
|
|
24
|
+
"hash": j['hash'][0]
|
|
25
|
+
},
|
|
26
|
+
"web_view_init_data_raw": raw,
|
|
27
|
+
"ep": "menu"
|
|
28
|
+
}
|
|
29
|
+
return dct
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from aiohttp import ClientResponse
|
|
4
|
+
from aiohttp.http_exceptions import HttpProcessingError
|
|
5
|
+
from http_client import Client
|
|
6
|
+
|
|
7
|
+
from xync_schema.model import Agent
|
|
8
|
+
|
|
9
|
+
from cex_clients.rs import RsClient
|
|
10
|
+
from cex_clients.TgWallet.pyro import get_init_data
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Private(Client):
|
|
14
|
+
base_url = 'https://walletbot.me'
|
|
15
|
+
middle_url = '/'
|
|
16
|
+
headers = {'Content-Type': 'application/json'}
|
|
17
|
+
agent: Agent
|
|
18
|
+
|
|
19
|
+
def __init__(self, agent: Agent):
|
|
20
|
+
self.agent = agent
|
|
21
|
+
super().__init__()
|
|
22
|
+
self.meth = {
|
|
23
|
+
"GET": self.get,
|
|
24
|
+
"POST": self.post,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Get JWT Tokens
|
|
28
|
+
async def _get_tokens(self) -> dict[str, str]:
|
|
29
|
+
init_data = await get_init_data(self.agent)
|
|
30
|
+
tokens = RsClient('walletbot.me').post('/api/v1/users/auth/', init_data)
|
|
31
|
+
return {'Wallet-Authorization': tokens['jwt'], 'Authorization': 'Bearer ' + tokens['value']}
|
|
32
|
+
|
|
33
|
+
# Set JWT Tokens
|
|
34
|
+
async def set_tokens(self) -> None:
|
|
35
|
+
self.session.headers.update(await self._get_tokens())
|
|
36
|
+
|
|
37
|
+
async def proc(self, resp: ClientResponse, data: dict = None) -> dict | str:
|
|
38
|
+
try:
|
|
39
|
+
return await super().proc(resp)
|
|
40
|
+
except HttpProcessingError as e:
|
|
41
|
+
if e.code == 401:
|
|
42
|
+
logging.warning('')
|
|
43
|
+
await self.set_tokens()
|
|
44
|
+
url = resp.url.path.replace(self.middle_url, '', 1)
|
|
45
|
+
res = await self.meth[resp.method](url, data)
|
|
46
|
+
return res
|
|
47
|
+
|
|
48
|
+
# Get Status
|
|
49
|
+
async def get_status(self) -> dict:
|
|
50
|
+
status = await self.get('users/public-api/v2/region-verification/status/')
|
|
51
|
+
return status
|
|
52
|
+
|
|
53
|
+
# Get Transaction
|
|
54
|
+
async def get_transactions(self, limit: int = 20) -> dict:
|
|
55
|
+
transactions = await self.get('api/v1/transactions/', params={'limit': limit})
|
|
56
|
+
return transactions
|
|
57
|
+
|
|
58
|
+
# Get Campaigns
|
|
59
|
+
async def get_campaigns(self) -> dict:
|
|
60
|
+
campaigns = await self.get('v2api/earn/campaigns/')
|
|
61
|
+
return campaigns
|
|
62
|
+
|
|
63
|
+
# Get KYC
|
|
64
|
+
async def get_kyc(self) -> dict:
|
|
65
|
+
kyc = await self.post('users/public-api/v2/user/get-kyc')
|
|
66
|
+
return kyc['data']['userId']
|
|
67
|
+
|
|
68
|
+
# async def main():
|
|
69
|
+
# c = Private()
|
|
70
|
+
# await c.get_token()
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
from enum import IntEnum, StrEnum
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
from cex_clients.wallet.web import Private
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Exceptions(StrEnum):
|
|
8
|
+
PM_KYC = 'OFFER_FIAT_COUNTRY_NOT_SUPPORTED_BY_USER_KYC_COUNTRY'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PrivateP2P(Private):
|
|
12
|
+
base_url = 'https://p2p.walletbot.me'
|
|
13
|
+
middle_url = '/p2p/'
|
|
14
|
+
|
|
15
|
+
# 1: all_curs
|
|
16
|
+
async def all_curs(self):
|
|
17
|
+
coins_curs = await self.post('public-api/v2/currency/all-supported')
|
|
18
|
+
curs = [c['code'] for c in coins_curs['data']['fiat']]
|
|
19
|
+
return curs
|
|
20
|
+
|
|
21
|
+
# 2: all_coins
|
|
22
|
+
async def all_coins(self):
|
|
23
|
+
coins_curs = await self.post('public-api/v2/currency/all-supported')
|
|
24
|
+
coins = [c['code'] for c in coins_curs['data']['crypto']]
|
|
25
|
+
return coins
|
|
26
|
+
|
|
27
|
+
# 3: all_coins
|
|
28
|
+
async def all_pms(self):
|
|
29
|
+
pms = await self.post('public-api/v3/payment-details/get-methods/by-currency-code', {"currencyCode": "RUB"})
|
|
30
|
+
return pms['data']
|
|
31
|
+
|
|
32
|
+
# 4: all_ads
|
|
33
|
+
async def get_ads(self, coin: str = "TON", cur: str = "RUB", tt: str = "SALE", offset: int = 0, limit: int = 100) -> dict:
|
|
34
|
+
params = {"baseCurrencyCode": coin, "quoteCurrencyCode": cur, "offerType": tt, "offset": offset, "limit": limit} # ,"merchantVerified":"TRUSTED"
|
|
35
|
+
ads = await self.post('public-api/v2/offer/depth-of-market/', params)
|
|
36
|
+
return ads
|
|
37
|
+
|
|
38
|
+
# 5: fiats
|
|
39
|
+
async def fiats(self):
|
|
40
|
+
pms = await self.post('public-api/v3/payment-details/get/by-user-id')
|
|
41
|
+
return pms
|
|
42
|
+
|
|
43
|
+
# 6: fiat_new
|
|
44
|
+
async def fiat_new(self, code_pms: str, cur: str, name_pms: str, number: str):
|
|
45
|
+
add_fiat = await self.post('public-api/v3/payment-details/create', {
|
|
46
|
+
"paymentMethodCode": code_pms,
|
|
47
|
+
"currencyCode": cur,
|
|
48
|
+
"name": name_pms,
|
|
49
|
+
"attributes": {
|
|
50
|
+
"version": "V1",
|
|
51
|
+
"values": [
|
|
52
|
+
{
|
|
53
|
+
"name": "PAYMENT_DETAILS_NUMBER",
|
|
54
|
+
"value": number
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
return add_fiat
|
|
60
|
+
|
|
61
|
+
# 7 - fiat_edit
|
|
62
|
+
async def fiat_edit(self, fiat_id: int, code_pms: str, cur: str, name_pms: str, number: str):
|
|
63
|
+
edit_fiat = await self.post('public-api/v3/payment-details/edit', {
|
|
64
|
+
"id": fiat_id,
|
|
65
|
+
"paymentMethodCode": code_pms,
|
|
66
|
+
"currencyCode": cur,
|
|
67
|
+
"name": name_pms,
|
|
68
|
+
"attributes": {
|
|
69
|
+
"version": "V1",
|
|
70
|
+
"values": [
|
|
71
|
+
{
|
|
72
|
+
"name": "PAYMENT_DETAILS_NUMBER",
|
|
73
|
+
"value": number
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
return edit_fiat
|
|
79
|
+
|
|
80
|
+
# 8 - fiat_del
|
|
81
|
+
async def fiat_del(self, fiat_id: int):
|
|
82
|
+
del_fiat = await self.post('public-api/v3/payment-details/delete', {"id": fiat_id})
|
|
83
|
+
return del_fiat
|
|
84
|
+
|
|
85
|
+
# 9 - my_ads
|
|
86
|
+
async def my_ads(self, status: Literal["INACTIVE", "ACTIVE"] = None):
|
|
87
|
+
ads = await self.post('public-api/v2/offer/user-own/list', {"offset": 0, "limit": 20, "offerType": "SALE"})
|
|
88
|
+
return [ad for ad in ads['data'] if ad['status'] == status] if status else ads
|
|
89
|
+
|
|
90
|
+
async def my_orders(self):
|
|
91
|
+
orders = await self.post('public-api/v2/offer/order/history/get-by-user-id', {"offset": 0, "limit": 20, "filter": {"status": "ALL_ACTIVE"}})
|
|
92
|
+
return orders
|
|
93
|
+
|
|
94
|
+
# 10 - ad_new
|
|
95
|
+
async def ad_new(self, fiats: list[int], amount: int, coin: str = "TON", cur: str = "RUB", tt: str = "SALE"):
|
|
96
|
+
create = await self.post('public-api/v2/offer/create', {
|
|
97
|
+
"type": tt,
|
|
98
|
+
"initVolume": {
|
|
99
|
+
"currencyCode": coin,
|
|
100
|
+
"amount": f"{amount}"
|
|
101
|
+
},
|
|
102
|
+
"orderRoundingRequired": False,
|
|
103
|
+
"price": {
|
|
104
|
+
"type": "FLOATING",
|
|
105
|
+
"baseCurrencyCode": coin,
|
|
106
|
+
"quoteCurrencyCode": cur,
|
|
107
|
+
"value": "120"
|
|
108
|
+
},
|
|
109
|
+
"orderAmountLimits": {
|
|
110
|
+
"min": "500",
|
|
111
|
+
"max": "2000"
|
|
112
|
+
},
|
|
113
|
+
"paymentConfirmTimeout": "PT15M",
|
|
114
|
+
"comment": "",
|
|
115
|
+
"paymentDetailsIds": fiats
|
|
116
|
+
})
|
|
117
|
+
return create
|
|
118
|
+
|
|
119
|
+
# 11 - ad_upd
|
|
120
|
+
async def ad_upd(self, typ: str, offer_id: int, fiats: list[int], amount: int):
|
|
121
|
+
upd = await self.post('public-api/v2/offer/edit', {
|
|
122
|
+
"offerId": offer_id,
|
|
123
|
+
"paymentConfirmTimeout": "PT15M",
|
|
124
|
+
"type": typ,
|
|
125
|
+
"orderRoundingRequired": False,
|
|
126
|
+
"price": {
|
|
127
|
+
"type": "FLOATING",
|
|
128
|
+
"value": "120"
|
|
129
|
+
},
|
|
130
|
+
"orderAmountLimits": {
|
|
131
|
+
"min": "500",
|
|
132
|
+
"max": "2000"
|
|
133
|
+
},
|
|
134
|
+
"comment": "",
|
|
135
|
+
"volume": f"{amount}",
|
|
136
|
+
"paymentDetailsIds": fiats
|
|
137
|
+
})
|
|
138
|
+
return upd
|
|
139
|
+
|
|
140
|
+
# 12 - ad_del
|
|
141
|
+
async def ad_del(self, typ: str, offer_id: int):
|
|
142
|
+
ad_del = await self.post('public-api/v2/offer/delete', {"type": typ, "offerId": offer_id})
|
|
143
|
+
return ad_del
|
|
144
|
+
|
|
145
|
+
# 13 - ad_on
|
|
146
|
+
async def ad_on(self, typ: str, offer_id: int):
|
|
147
|
+
active = await self.post('public-api/v2/offer/activate', {"type": typ, "offerId": offer_id})
|
|
148
|
+
return active
|
|
149
|
+
|
|
150
|
+
# 14 - ad_off
|
|
151
|
+
async def ad_off(self, typ: str, offer_id: int) -> dict[str, str]:
|
|
152
|
+
off = await self.post('public-api/v2/offer/deactivate', {"type": typ, "offerId": offer_id})
|
|
153
|
+
return off
|
|
154
|
+
|
|
155
|
+
# 15 - order_approve
|
|
156
|
+
async def order_approve(self, order_id: int, typ: str):
|
|
157
|
+
approve = await self.post('public-api/v2/offer/order/accept', {'orderId': order_id, 'type': typ})
|
|
158
|
+
return approve
|
|
159
|
+
|
|
160
|
+
# 16 - order_reject
|
|
161
|
+
async def order_reject(self, order_id: str):
|
|
162
|
+
reject = await self.post('public-api/v2/offer/order/cancel/by-seller', {'orderId': order_id})
|
|
163
|
+
return reject
|
|
164
|
+
|
|
165
|
+
async def upload_file(self, order_id: int, path_to_file: str):
|
|
166
|
+
url = f'public-api/v2/file-storage/file/upload?orderId={order_id}&uploadType=UPLOAD_BUYER_PAYMENT_RECEIPT'
|
|
167
|
+
data = {'file': open(path_to_file, 'rb')}
|
|
168
|
+
upload_file = await self.post(url, data)
|
|
169
|
+
return upload_file
|
|
170
|
+
|
|
171
|
+
# 19 - order_paid
|
|
172
|
+
async def order_paid(self, order_id: str, file: dict):
|
|
173
|
+
paid = await self.post('public-api/v2/offer/order/confirm-sending-payment', {
|
|
174
|
+
'orderId': order_id,
|
|
175
|
+
'paymentReceipt': file
|
|
176
|
+
})
|
|
177
|
+
return paid
|
|
178
|
+
|
|
179
|
+
# 20 - order_payment_confirm
|
|
180
|
+
async def order_payment_confirm(self, order_id: str):
|
|
181
|
+
payment_confirm = await self.post('public-api/v2/payment-details/confirm', {'orderId': order_id})
|
|
182
|
+
return payment_confirm
|
xync_client/__init__.py
ADDED
|
File without changes
|