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,227 @@
|
|
|
1
|
+
from asyncio import run
|
|
2
|
+
from time import time
|
|
3
|
+
|
|
4
|
+
from xync_schema.models import Agent
|
|
5
|
+
|
|
6
|
+
gap = 0.01
|
|
7
|
+
HOST = 'https://c2c.binance.com/'
|
|
8
|
+
ADS = 'bapi/c2c/v2/friendly/c2c/adv/search'
|
|
9
|
+
AD = 'bapi/c2c/v2/public/c2c/adv/selected-adv/'
|
|
10
|
+
FIAT_NEW = 'bapi/c2c/v2/private/c2c/pay-method/add'
|
|
11
|
+
AD_NEW = 'bapi/c2c/v3/private/c2c/adv/publish'
|
|
12
|
+
AD_UPD = 'bapi/c2c/v3/private/c2c/adv/update'
|
|
13
|
+
AD_UPD_ST = 'bapi/c2c/v2/private/c2c/adv/update-status'
|
|
14
|
+
MY_ADS = 'bapi/c2c/v2/private/c2c/adv/list-by-page'
|
|
15
|
+
PTS = 'bapi/c2c/v2/private/c2c/pay-method/user-paymethods'
|
|
16
|
+
ORD = 'bapi/c2c/v2/private/c2c/order-match/order-list'
|
|
17
|
+
ORD_ARCH = 'bapi/c2c/v1/private/c2c/order-match/order-list-archived-involved'
|
|
18
|
+
CUR_MIN_AMT = 'bapi/c2c/v1/private/c2c/sys-config/adv-trans-amount-limit'
|
|
19
|
+
RATES = 'bapi/c2c/v1/private/c2c/merchant/get-exchange-rate-list'
|
|
20
|
+
RATE = 'bapi/c2c/v2/public/c2c/adv/quoted-price'
|
|
21
|
+
BLNC_URL = 'https://www.binance.com/bapi/asset/v2/private/asset-service/wallet/balance?needBalanceDetail=true'
|
|
22
|
+
|
|
23
|
+
# class C2cWeb(Private):
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def breq(path: str, user: Agent = None, data=None, is_post=True):
|
|
27
|
+
headers = {
|
|
28
|
+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36',
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
'clienttype': 'web',
|
|
31
|
+
}
|
|
32
|
+
if user:
|
|
33
|
+
headers.update({
|
|
34
|
+
'csrftoken': user.auth['tok'],
|
|
35
|
+
'cookie': f'p20t=web.{user.id}.{user.auth["cook"]}',
|
|
36
|
+
})
|
|
37
|
+
async with aiohttp.ClientSession() as session:
|
|
38
|
+
reqf = session.post if is_post else session.get
|
|
39
|
+
# noinspection PyArgumentList
|
|
40
|
+
async with reqf(('' if path.startswith('https://') else HOST) + path, headers=headers, json=data) as response:
|
|
41
|
+
# if response.status == 401:
|
|
42
|
+
# await hc(user)
|
|
43
|
+
if response.status != 200:
|
|
44
|
+
print(response)
|
|
45
|
+
return (await response.json()) or response.status
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
async def ping(user: Agent):
|
|
49
|
+
res = await breq('bapi/accounts/v1/public/authcenter/auth', user)
|
|
50
|
+
return res['success']
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# async def hc(user: {}):
|
|
54
|
+
# if not await ping(user):
|
|
55
|
+
# msg = 'You need to log in binance.com'
|
|
56
|
+
# await bot.send_message(user['tg_id'], msg)
|
|
57
|
+
# users_db.update({'ran': False}, user['key'])
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def get_my_pts(user: Agent = None): # payment methods
|
|
61
|
+
user = user or await Agent.get(nickName='Deals')
|
|
62
|
+
res = await breq(PTS, user, {})
|
|
63
|
+
return res['data']
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async def get_my_ads(user: Agent):
|
|
67
|
+
res = await breq(MY_ADS, user, {"inDeal": 1, "rows": 50, "page": 1})
|
|
68
|
+
return res['data']
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def act_orders(user: Agent): # payment methods
|
|
72
|
+
res = await breq(ORD, user, {"page": 1, "rows": 20, "orderStatusList": [0, 1, 2, 3, 5]})
|
|
73
|
+
return res['data'], res['total']
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async def get_arch_orders(user: Agent, part: int = 0, page: int = 1): # payment methods
|
|
77
|
+
res = await breq(ORD_ARCH, user,
|
|
78
|
+
{"page": page or 1, "rows": 50, "startDate": int((time() - m6 * (part + 1)) * 1000),
|
|
79
|
+
"endDate": int((time() - m6 * part) * 1000)})
|
|
80
|
+
return res['data'], res['total']
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
m6 = 60 * 60 * 24 * 30 * 6
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def balance(user: Agent, spot0fond1: 0 | 1 = 1): # payment methods
|
|
87
|
+
res = await breq(
|
|
88
|
+
BLNC_URL,
|
|
89
|
+
user,
|
|
90
|
+
is_post=False
|
|
91
|
+
)
|
|
92
|
+
return res['data'][spot0fond1]['assetBalances'] if res.get('data') else None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
async def get_ads(asset: str, cur: str, sell: int = 0, pts: [str] = None, rows: int = 20, page: int = 1):
|
|
96
|
+
payload = {"page": page,
|
|
97
|
+
"rows": rows,
|
|
98
|
+
"payTypes": pts,
|
|
99
|
+
"asset": asset,
|
|
100
|
+
"tradeType": "SELL" if sell else "BUY",
|
|
101
|
+
"fiat": cur,
|
|
102
|
+
# "transAmount": amount
|
|
103
|
+
}
|
|
104
|
+
return await breq(ADS, None, payload)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def get_ad(aid: str):
|
|
108
|
+
res = await breq(AD + aid, is_post=False)
|
|
109
|
+
return res.get('data')
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
async def ad_fiat(coin: str, cur: str, sell: bool, price_type: int, price: float, amount: float): # user
|
|
113
|
+
user = await Agent.get(nickName='Deals')
|
|
114
|
+
data = {"fields": [{"fieldId": "0000000000000000010", "fieldValue": "SHAINA CABANDO ABEJAR"},
|
|
115
|
+
{"fieldId": "0000000000000000021", "fieldValue": "Meet in Cebu City"}],
|
|
116
|
+
"identifier": "CashInPerson",
|
|
117
|
+
"payStatus": "ACTIVE",
|
|
118
|
+
"googleVerifyCode": "465802"
|
|
119
|
+
}
|
|
120
|
+
data = {"fields": [{"fieldId": "30129764664654118912", "fieldValue": "SHAINA CABANDO ABEJAR"}, # real name
|
|
121
|
+
{"fieldId": "30129764812512600064", "fieldValue": ""}, # nick in advcash
|
|
122
|
+
{"fieldId": "30129764931661045760", "fieldValue": "mixartemev@gmail.com"}, # advcash email
|
|
123
|
+
{"fieldId": "30129765053537591296", "fieldValue": "L 1808 3788 4260"}], # wallet ID
|
|
124
|
+
"identifier": "Advcash",
|
|
125
|
+
"payStatus": "ACTIVE",
|
|
126
|
+
"googleVerifyCode": "836384"
|
|
127
|
+
}
|
|
128
|
+
res = await breq(FIAT_NEW, user, data)
|
|
129
|
+
return res.get('data', False)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
async def ad_new(coin: str, cur: str, sell: bool, price_type: int, price: float, amount: float): # user
|
|
133
|
+
user = await Agent.get(nickName='Deals')
|
|
134
|
+
data = {"classify": "mass",
|
|
135
|
+
"autoReplyMsg": "Если не отвечаю дольше 5 минут, напишите пожалуйста сообщение, не всегда приходят уведомления о новых заявках",
|
|
136
|
+
"tradeType": "SELL" if sell else "BUY",
|
|
137
|
+
"onlineNow": True,
|
|
138
|
+
"fiatUnit": cur,
|
|
139
|
+
"asset": coin,
|
|
140
|
+
"initAmount": amount, # todo take amount from found wallet
|
|
141
|
+
"maxSingleTransAmount": 50000, # default
|
|
142
|
+
"minSingleTransAmount": 50, # default
|
|
143
|
+
"payTimeLimit": 15 if sell else 60,
|
|
144
|
+
"priceType": price_type,
|
|
145
|
+
"priceFloatingRatio" if price_type-1 else "price": price, # 1: stable, 2: float
|
|
146
|
+
"remarks": "Взаимный отзыв приветствуется:)",
|
|
147
|
+
"buyerKycLimit": 1,
|
|
148
|
+
"onlineDelayTime": 2,
|
|
149
|
+
"tradeMethods": [{"identifier": "BANK", "payId": 27973858, "payType": "BANK", "payAccount": "766-0-193538"}]
|
|
150
|
+
# "tradeMethods": [{"identifier": "YandexMoneyNew", "payId": 24956898},
|
|
151
|
+
# {"identifier": "TinkoffNew", "payId": 24956617},
|
|
152
|
+
# {"identifier": "RosBankNew", "payId": 24951855},
|
|
153
|
+
# {"identifier": "QIWI", "payId": 20023779, "payType": "QIWI", "payAccount": "79536515700"},
|
|
154
|
+
# {"identifier": "RUBfiatbalance", "payId": 16026051}]
|
|
155
|
+
}
|
|
156
|
+
res = await breq(AD_NEW, user, data)
|
|
157
|
+
return res.get('data', False)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def ad_upd(): # user, data: {}
|
|
161
|
+
user = await Agent.get(nickName='Deals')
|
|
162
|
+
data = {"asset": "RUB",
|
|
163
|
+
"fiatUnit": "RUB",
|
|
164
|
+
"priceType": 1,
|
|
165
|
+
# "priceScale": 2,
|
|
166
|
+
"advNo": 11419177391185489920,
|
|
167
|
+
"autoReplyMsg": "Взаимный лайк приветствуется:)\nЕсли усну, напишите сюда плиз или в tg: @ex212",
|
|
168
|
+
"initAmount": 50000,
|
|
169
|
+
"payTimeLimit": 30,
|
|
170
|
+
"price": 1.00,
|
|
171
|
+
"priceFloatingRatio": 100.12,
|
|
172
|
+
"minSingleTransAmount": 500,
|
|
173
|
+
"maxSingleTransAmount": 870000,
|
|
174
|
+
"remarks": "Оплачиваю быстро.\n",
|
|
175
|
+
"tradeMethods": [
|
|
176
|
+
{"identifier": "RaiffeisenBank"},
|
|
177
|
+
{"identifier": "RosBankNew"},
|
|
178
|
+
{"identifier": "TinkoffNew"},
|
|
179
|
+
{"identifier": "QIWI"},
|
|
180
|
+
{"identifier": "YandexMoneyNew"}
|
|
181
|
+
],
|
|
182
|
+
"tradeType": "BUY",
|
|
183
|
+
"launchCountry": [] # "AE", "TR"
|
|
184
|
+
}
|
|
185
|
+
res = await breq(AD_UPD, user, data)
|
|
186
|
+
return res.get('data')
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def ad_status_upd(aid: int, pub: bool = True): # user, data: {}
|
|
190
|
+
user = await Agent.get(nickName='Deals')
|
|
191
|
+
data = {"advNos": [f"1{aid}"], "advStatus": int(pub)}
|
|
192
|
+
res = await breq(AD_UPD_ST, user, data)
|
|
193
|
+
return res.get('data')
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
async def cur_min_amount(cur: str = 'RUB', coin: str = 'USDT'): # user, data: {}
|
|
197
|
+
user = await Agent.get(nickName='Deals')
|
|
198
|
+
data = {"asset": coin, "fiatCurrency": cur, "tradeType": "BUY", "limitScene": "mass"}
|
|
199
|
+
res = await breq(CUR_MIN_AMT, user, data)
|
|
200
|
+
return res.get('data')
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
async def get_rates(): # user, data: {}
|
|
204
|
+
user = await Agent.get(nickName='Deals')
|
|
205
|
+
res = await breq(RATES, user, is_post=False)
|
|
206
|
+
return {rate['fiatCurrency']: float(rate['exchangeRate']) for rate in res.get('data')}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
async def get_cur_rate(cur_id: str):
|
|
210
|
+
user = await Agent.get(nickName='Deals')
|
|
211
|
+
res = await breq(RATE, user, {"assets": ["USDT"], "fiatCurrency": cur_id, "tradeType": "BUY", "fromUserRole": "USER"})
|
|
212
|
+
return res['data'][0]['referencePrice']
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
async def get_cur_pms(cur: str):
|
|
216
|
+
data = {"fiat": cur, "classifies": ["mass", "profession"]}
|
|
217
|
+
res = await post('https://p2p.binance.com/bapi/c2c/v2/public/c2c/adv/filter-conditions', user, {"assets": ["USDT"], "fiatCurrency": cur_id, "tradeType": "BUY", "fromUserRole": "USER"})
|
|
218
|
+
return res['data'][0]['referencePrice']
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if __name__ == "__main__":
|
|
222
|
+
try:
|
|
223
|
+
# pts = run(get_my_pts())
|
|
224
|
+
res = run(ad_new('DOGE', 'RUB', False, 2, 95.5, 1000))
|
|
225
|
+
print(res)
|
|
226
|
+
except KeyboardInterrupt:
|
|
227
|
+
print('Stopped.')
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
|
|
3
|
+
from xync_schema.models import DepType
|
|
4
|
+
from http_client import Client, repeat_on_fault
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ProductType(IntEnum):
|
|
8
|
+
dual_assets = 2
|
|
9
|
+
flexible_saving_products = 4
|
|
10
|
+
liquidity_mining = 5
|
|
11
|
+
fixed_term_saving_products = 6
|
|
12
|
+
pos_staking_products = 8
|
|
13
|
+
fund_pool = 9
|
|
14
|
+
|
|
15
|
+
type_map = {
|
|
16
|
+
ProductType.flexible_saving_products: DepType.earn,
|
|
17
|
+
ProductType.fixed_term_saving_products: DepType.earn,
|
|
18
|
+
ProductType.pos_staking_products: DepType.stake,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BybitEarn(Client): # Bybit async client
|
|
23
|
+
base_url = 'https://api2.bybit.com'
|
|
24
|
+
middle_url = '/'
|
|
25
|
+
|
|
26
|
+
def __init__(self, token: str = None):
|
|
27
|
+
self.headers = {
|
|
28
|
+
'content-type': 'application/json',
|
|
29
|
+
# 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
|
|
30
|
+
# 'Accept': '*/*',
|
|
31
|
+
# 'Accept-Encoding': 'gzip, deflate, br',
|
|
32
|
+
'origin': 'https://www.bybit.com',
|
|
33
|
+
'usertoken': token,
|
|
34
|
+
}
|
|
35
|
+
super().__init__()
|
|
36
|
+
|
|
37
|
+
""" PUBLIC METHS """
|
|
38
|
+
@repeat_on_fault()
|
|
39
|
+
async def get_coins(self) -> dict:
|
|
40
|
+
res = await self.post('s1/byfi/list-coins')
|
|
41
|
+
return {c['coin_enum']: c['coin_name'] for c in res['result']['coins']}
|
|
42
|
+
|
|
43
|
+
@repeat_on_fault()
|
|
44
|
+
async def get_home_earn_products(self, typ: ProductType = ProductType.flexible_saving_products):
|
|
45
|
+
res = await self.post('s1/byfi/get-homepage-product-cards', {'product_type': typ})
|
|
46
|
+
return res['result']
|
|
47
|
+
|
|
48
|
+
@repeat_on_fault()
|
|
49
|
+
async def get_lend_products(self):
|
|
50
|
+
res = await self.post('spot/api/lending/v1/token/list')
|
|
51
|
+
res = [{
|
|
52
|
+
'pid': f'{r["token"]}_lend',
|
|
53
|
+
'coin': r["token"],
|
|
54
|
+
'apr': r["apr"],
|
|
55
|
+
'duration': r["period"],
|
|
56
|
+
'min_limit': r["minPurchaseLimit"],
|
|
57
|
+
'max_limit': r["depositLimit"],
|
|
58
|
+
'type': 4,
|
|
59
|
+
'ex_id': 4,
|
|
60
|
+
} for r in res['result']]
|
|
61
|
+
|
|
62
|
+
# async def get_earn_products(self):
|
|
63
|
+
# res = await self.post('s1/byfi/api/v1/get-overview-products')
|
|
64
|
+
# coins = await self.get_coins()
|
|
65
|
+
# eps = [{
|
|
66
|
+
# 'coin': await _ccoin(coins[coin]),
|
|
67
|
+
# 'pid': f"{coins[coin]}-{(pt:=ProductType(ep['product_type'])).name}",
|
|
68
|
+
# 'apr': tal[0]['apy_min_e8'] if (tal:=ep['tiered_apy_list']) and tal['apy_min_e8']==tal['apy_min_e8'] else 2,
|
|
69
|
+
# 'type': ProductType(ep['product_type']),
|
|
70
|
+
# 'duration': '',
|
|
71
|
+
# } for coin, ep in {grp['coin']: grp['product_types'] for grp in res['result']['coin_products']}.items()]
|
|
72
|
+
# return eps
|
|
73
|
+
|
|
74
|
+
@repeat_on_fault()
|
|
75
|
+
async def get_product_detail(self, typ: ProductType = ProductType.pos_staking_products, pid: str = "1"):
|
|
76
|
+
res = await self.post('s1/byfi/get-product-detail', {'product_id': pid, 'product_type': typ})
|
|
77
|
+
return res['result']
|
|
78
|
+
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
from time import sleep
|
|
3
|
+
|
|
4
|
+
import pyotp
|
|
5
|
+
|
|
6
|
+
from cex_clients.loader import BYT2FA
|
|
7
|
+
from cex_clients.rs import RsClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NoMakerException(Exception):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AdsStatus(IntEnum):
|
|
15
|
+
REST = 0
|
|
16
|
+
WORKING = 1
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BybitP2P(RsClient): # Bybit client
|
|
20
|
+
host = 'api2.bybit.com'
|
|
21
|
+
|
|
22
|
+
pub_header = {"cookie": ";"} # rewrite token for public methods
|
|
23
|
+
|
|
24
|
+
last_ad_id: list[str] = []
|
|
25
|
+
create_ad_body = {
|
|
26
|
+
"priceType": "1",
|
|
27
|
+
"premium": "119",
|
|
28
|
+
"quantity": "0.01",
|
|
29
|
+
"minAmount": "500",
|
|
30
|
+
"maxAmount": "3500",
|
|
31
|
+
"paymentPeriod": "15",
|
|
32
|
+
"remark": "",
|
|
33
|
+
"price": "",
|
|
34
|
+
"paymentIds": [
|
|
35
|
+
"3162981"
|
|
36
|
+
],
|
|
37
|
+
"tradingPreferenceSet": {
|
|
38
|
+
"isKyc": "1",
|
|
39
|
+
"hasCompleteRateDay30": "0",
|
|
40
|
+
"completeRateDay30": "",
|
|
41
|
+
"hasOrderFinishNumberDay30": "0",
|
|
42
|
+
"orderFinishNumberDay30": "",
|
|
43
|
+
"isMobile": "0",
|
|
44
|
+
"isEmail": "0",
|
|
45
|
+
"hasUnPostAd": "0",
|
|
46
|
+
"hasRegisterTime": "0",
|
|
47
|
+
"registerTimeThreshold": "",
|
|
48
|
+
"hasNationalLimit": "0",
|
|
49
|
+
"nationalLimit": ""
|
|
50
|
+
},
|
|
51
|
+
"tokenId": "ETH",
|
|
52
|
+
"currencyId": "RUB",
|
|
53
|
+
"side": "1",
|
|
54
|
+
"securityRiskToken": ""
|
|
55
|
+
}
|
|
56
|
+
update_ad_body = {
|
|
57
|
+
"priceType": "1",
|
|
58
|
+
"premium": "118",
|
|
59
|
+
"quantity": "0.01",
|
|
60
|
+
"minAmount": "500",
|
|
61
|
+
"maxAmount": "3500000",
|
|
62
|
+
"paymentPeriod": "30",
|
|
63
|
+
"remark": "",
|
|
64
|
+
"price": "398244.84",
|
|
65
|
+
"paymentIds": [
|
|
66
|
+
"3162931"
|
|
67
|
+
],
|
|
68
|
+
"tradingPreferenceSet": {
|
|
69
|
+
"isKyc": "1",
|
|
70
|
+
"hasCompleteRateDay30": "0",
|
|
71
|
+
"completeRateDay30": "",
|
|
72
|
+
"hasOrderFinishNumberDay30": "0",
|
|
73
|
+
"orderFinishNumberDay30": "0",
|
|
74
|
+
"isMobile": "0",
|
|
75
|
+
"isEmail": "0",
|
|
76
|
+
"hasUnPostAd": "0",
|
|
77
|
+
"hasRegisterTime": "0",
|
|
78
|
+
"registerTimeThreshold": "0",
|
|
79
|
+
"hasNationalLimit": "0",
|
|
80
|
+
"nationalLimit": ""
|
|
81
|
+
},
|
|
82
|
+
"actionType": "MODIFY",
|
|
83
|
+
"securityRiskToken": ""
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
""" PUBLIC METHS """
|
|
87
|
+
def get_ads(self, coin: str, cur: str, sell: bool = False, amount: int = None, payment: list[str] = None) -> list:
|
|
88
|
+
data = {
|
|
89
|
+
"userId": "",
|
|
90
|
+
"tokenId": coin,
|
|
91
|
+
"currencyId": cur,
|
|
92
|
+
"payment": payment or [],
|
|
93
|
+
"side": '0' if sell else '1',
|
|
94
|
+
"size": "10",
|
|
95
|
+
"page": "1",
|
|
96
|
+
"amount": str(amount) if amount else '',
|
|
97
|
+
"authMaker": False,
|
|
98
|
+
"canTrade": False
|
|
99
|
+
}
|
|
100
|
+
ads = self.post('/fiat/otc/item/online/', data, self.pub_header)
|
|
101
|
+
return ads['result']['items']
|
|
102
|
+
|
|
103
|
+
def get_config(self):
|
|
104
|
+
resp = self.get('/fiat/p2p/config/initial', self.pub_header)
|
|
105
|
+
return resp['result'] # todo: tokens, pairs, ...
|
|
106
|
+
|
|
107
|
+
def get_currencies(self):
|
|
108
|
+
config = self.get_config()
|
|
109
|
+
return config['symbols']
|
|
110
|
+
|
|
111
|
+
def get_coins(self):
|
|
112
|
+
coins = self.get('/spot/api/basic/symbol_list', self.pub_header)
|
|
113
|
+
return coins
|
|
114
|
+
|
|
115
|
+
def get_payment_methods(self):
|
|
116
|
+
pms = self.post('/fiat/otc/configuration/queryAllPaymentList/', headers=self.pub_header)
|
|
117
|
+
return pms
|
|
118
|
+
|
|
119
|
+
""" Private METHs"""
|
|
120
|
+
def create_payment_method(self, payment_type: int, real_name: str, account_number: str) -> dict:
|
|
121
|
+
method1 = self.post('/fiat/otc/user/payment/new_create', {
|
|
122
|
+
'paymentType': payment_type,
|
|
123
|
+
'realName': real_name,
|
|
124
|
+
'accountNo': account_number,
|
|
125
|
+
'securityRiskToken': ''
|
|
126
|
+
})
|
|
127
|
+
if srt := method1["result"]["securityRiskToken"]:
|
|
128
|
+
self.check_2fa(srt)
|
|
129
|
+
method2 = self.post('/fiat/otc/user/payment/new_create', {
|
|
130
|
+
'paymentType': payment_type,
|
|
131
|
+
'realName': real_name,
|
|
132
|
+
'accountNo': account_number,
|
|
133
|
+
'securityRiskToken': srt
|
|
134
|
+
})
|
|
135
|
+
return method2
|
|
136
|
+
else:
|
|
137
|
+
print(method1)
|
|
138
|
+
|
|
139
|
+
def get_payment_method(self, fiat_id: int = None) -> dict:
|
|
140
|
+
list_methods = self.get_user_pay_methods()
|
|
141
|
+
if fiat_id:
|
|
142
|
+
fiat = [m for m in list_methods if m['id'] == fiat_id][0]
|
|
143
|
+
return fiat
|
|
144
|
+
return list_methods[1]
|
|
145
|
+
|
|
146
|
+
def update_payment_method(self, real_name: str, account_number: str, fiat_id: int = None) -> dict:
|
|
147
|
+
fiat = self.get_payment_method(fiat_id)
|
|
148
|
+
fiat['realName'] = real_name
|
|
149
|
+
fiat['accountNo'] = account_number
|
|
150
|
+
result = self.post('/fiat/otc/user/payment/new_update', fiat)
|
|
151
|
+
srt = result["result"]["securityRiskToken"]
|
|
152
|
+
self.check_2fa(srt)
|
|
153
|
+
fiat['securityRiskToken'] = srt
|
|
154
|
+
result2 = self.post('/fiat/otc/user/payment/new_update', fiat)
|
|
155
|
+
return result2
|
|
156
|
+
|
|
157
|
+
def delete_payment_method(self, ids: str) -> dict:
|
|
158
|
+
data = {
|
|
159
|
+
'id': ids,
|
|
160
|
+
'securityRiskToken': ''
|
|
161
|
+
}
|
|
162
|
+
method = self.post('/fiat/otc/user/payment/new_delete', data)
|
|
163
|
+
srt = method["result"]["securityRiskToken"]
|
|
164
|
+
self.check_2fa(srt)
|
|
165
|
+
data['securityRiskToken'] = srt
|
|
166
|
+
delete = self.post('/fiat/otc/user/payment/new_delete', data)
|
|
167
|
+
return delete
|
|
168
|
+
|
|
169
|
+
def switch_ads(self, new_status: AdsStatus) -> dict:
|
|
170
|
+
data = {'workStatus': new_status.name}
|
|
171
|
+
res = self.post('/fiat/otc/maker/work-config/switch', data)
|
|
172
|
+
return res
|
|
173
|
+
|
|
174
|
+
def online_ads(self) -> str:
|
|
175
|
+
online = self.get('/fiat/otc/maker/work-config/get')
|
|
176
|
+
return online['result']['workStatus']
|
|
177
|
+
|
|
178
|
+
@staticmethod
|
|
179
|
+
def get_rate(list_ads: list) -> float:
|
|
180
|
+
ads = [ad for ad in list_ads if set(ad['payments']) - {'5', '51'}]
|
|
181
|
+
return float(ads[0]['price'])
|
|
182
|
+
|
|
183
|
+
def get_user_pay_methods(self):
|
|
184
|
+
upm = self.post('/fiat/otc/user/payment/list')
|
|
185
|
+
return upm['result']
|
|
186
|
+
|
|
187
|
+
def get_user_ads(self, active: bool = True) -> list:
|
|
188
|
+
uo = self.post('/fiat/otc/item/personal/list', {
|
|
189
|
+
"page": "1",
|
|
190
|
+
"size": "10",
|
|
191
|
+
"status": '2' if active else '0'
|
|
192
|
+
})
|
|
193
|
+
return uo['result']['items']
|
|
194
|
+
|
|
195
|
+
def get_security_token_create(self):
|
|
196
|
+
data = self.post('/fiat/otc/item/create', self.create_ad_body)
|
|
197
|
+
if data['ret_code'] == 912120019: # Current user can not to create add as maker
|
|
198
|
+
raise NoMakerException(data)
|
|
199
|
+
security_risk_token = data["result"]["securityRiskToken"]
|
|
200
|
+
return security_risk_token
|
|
201
|
+
|
|
202
|
+
def check_2fa(self, risk_token):
|
|
203
|
+
# 2fa code
|
|
204
|
+
bybit_secret = BYT2FA
|
|
205
|
+
totp = pyotp.TOTP(bybit_secret)
|
|
206
|
+
totp_code = totp.now()
|
|
207
|
+
|
|
208
|
+
res = self.post('/user/public/risk/verify', {
|
|
209
|
+
"risk_token": risk_token,
|
|
210
|
+
"component_list": {
|
|
211
|
+
"google2fa": totp_code
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
if res['ret_msg'] != "success":
|
|
215
|
+
print('Wrong 2fa, wait 5 secs and retry..')
|
|
216
|
+
sleep(5)
|
|
217
|
+
self.check_2fa(risk_token)
|
|
218
|
+
return res
|
|
219
|
+
|
|
220
|
+
def post_ad(self, risk_token: str):
|
|
221
|
+
self.create_ad_body.update({'securityRiskToken': risk_token})
|
|
222
|
+
data = self.post('/fiat/otc/item/create', self.create_ad_body)
|
|
223
|
+
return data
|
|
224
|
+
|
|
225
|
+
# создание объявлений
|
|
226
|
+
def post_create_ad(self, token: str):
|
|
227
|
+
result_check_2fa = self.check_2fa(token)
|
|
228
|
+
assert result_check_2fa['ret_msg'] == 'success', '2FA code wrong'
|
|
229
|
+
|
|
230
|
+
result_add_ad = self.post_ad(token)
|
|
231
|
+
if result_add_ad['ret_msg'] != 'SUCCESS':
|
|
232
|
+
print('Wrong 2fa on Ad creating, wait 9 secs and retry..')
|
|
233
|
+
sleep(9)
|
|
234
|
+
return self.post_create_ad(token)
|
|
235
|
+
self.last_ad_id.append(result_add_ad['result']['itemId'])
|
|
236
|
+
|
|
237
|
+
def get_security_token_update(self) -> str:
|
|
238
|
+
self.update_ad_body['id'] = self.last_ad_id
|
|
239
|
+
data = self.post('/fiat/otc/item/update', self.update_ad_body)
|
|
240
|
+
security_risk_token = data["result"]["securityRiskToken"]
|
|
241
|
+
return security_risk_token
|
|
242
|
+
|
|
243
|
+
def post_update_ad(self, token):
|
|
244
|
+
result_check_2fa = self.check_2fa(token)
|
|
245
|
+
assert result_check_2fa['ret_msg'] == 'success', '2FA code wrong'
|
|
246
|
+
|
|
247
|
+
result_update_ad = self.update_ad(token)
|
|
248
|
+
if result_update_ad['ret_msg'] != 'SUCCESS':
|
|
249
|
+
print('Wrong 2fa on Ad updating, wait 10 secs and retry..')
|
|
250
|
+
sleep(10)
|
|
251
|
+
return self.post_update_ad(token)
|
|
252
|
+
# assert result_update_ad['ret_msg'] == 'SUCCESS', "Ad isn't updated"
|
|
253
|
+
|
|
254
|
+
def update_ad(self, risk_token: str):
|
|
255
|
+
self.update_ad_body.update({'securityRiskToken': risk_token})
|
|
256
|
+
data = self.post('/fiat/otc/item/update', self.update_ad_body)
|
|
257
|
+
return data
|
|
258
|
+
|
|
259
|
+
def delete_ad(self, ad_id: str):
|
|
260
|
+
data = self.post('/fiat/otc/item/cancel', {"itemId": ad_id})
|
|
261
|
+
return data
|
|
262
|
+
|
|
263
|
+
def create_order_taker(self, item_id: str, coin: str, cur: str, sell: bool, quantity: str, amount: float, cur_price: str):
|
|
264
|
+
data = self.post('/fiat/otc/order/create', json={
|
|
265
|
+
"itemId": item_id,
|
|
266
|
+
"tokenId": coin,
|
|
267
|
+
"currencyId": cur,
|
|
268
|
+
"side": '0' if sell else '1',
|
|
269
|
+
"quantity": quantity,
|
|
270
|
+
"amount": amount,
|
|
271
|
+
"curPrice": cur_price,
|
|
272
|
+
"flag": "amount",
|
|
273
|
+
"version": "1.0",
|
|
274
|
+
"securityRiskToken": ""
|
|
275
|
+
})
|
|
276
|
+
return data["result"]["securityRiskToken"]
|
|
277
|
+
|
|
278
|
+
def get_order_info(self, order_id: str) -> dict:
|
|
279
|
+
data = self.post('/fiat/otc/order/info', json={
|
|
280
|
+
"orderId": order_id
|
|
281
|
+
})
|
|
282
|
+
return data['result']
|
|
283
|
+
|
|
284
|
+
def get_chat_msg(self, order_id):
|
|
285
|
+
data = self.post('/fiat/otc/order/message/listpage', json={
|
|
286
|
+
"orderId": order_id,
|
|
287
|
+
"size": 100
|
|
288
|
+
})
|
|
289
|
+
msgs = [{'text': msg['message'], 'type': msg['contentType'], 'role': msg['roleType'], 'user_id': msg['userId']} for msg in data['result']['result'] if msg['roleType'] not in ('sys', 'alarm')]
|
|
290
|
+
return msgs
|
|
291
|
+
|
|
292
|
+
def block_user(self, user_id: str):
|
|
293
|
+
return self.post('/fiat/p2p/user/add_block_user', {
|
|
294
|
+
"blockedUserId": user_id
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
def unblock_user(self, user_id: str):
|
|
298
|
+
return self.post('/fiat/p2p/user/delete_block_user', {"blockedUserId": user_id})
|
|
299
|
+
|
|
300
|
+
def user_review_post(self, order_id: str):
|
|
301
|
+
return self.post('/fiat/otc/order/appraise/modify', {
|
|
302
|
+
"orderId": order_id,
|
|
303
|
+
"anonymous": "0",
|
|
304
|
+
"appraiseType": "1", # тип оценки 1 - хорошо, 0 - плохо. При 0 - обязательно указывать appraiseContent
|
|
305
|
+
"appraiseContent": "",
|
|
306
|
+
"operateType": "ADD" # при повторном отправлять не 'ADD' -> а 'EDIT'
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
def get_orders_active(self, begin_time: int, end_time: int, status: int, side: int, token_id: str):
|
|
310
|
+
return self.post('/fiat/otc/order/pending/simplifyList', {
|
|
311
|
+
"status": status,
|
|
312
|
+
"tokenId": token_id,
|
|
313
|
+
"beginTime": begin_time,
|
|
314
|
+
"endTime": end_time,
|
|
315
|
+
"side": side, # 1 - продажа, 0 - покупка
|
|
316
|
+
"page": 1,
|
|
317
|
+
"size": 10
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
def get_orders_done(self, begin_time: int, end_time: int, status: int, side: int, token_id: str):
|
|
321
|
+
return self.post('/fiat/otc/order/simplifyList', {
|
|
322
|
+
"status": status, # 50 - завершено
|
|
323
|
+
"tokenId": token_id,
|
|
324
|
+
"beginTime": begin_time,
|
|
325
|
+
"endTime": end_time,
|
|
326
|
+
"side": side, # 1 - продажа, 0 - покупка
|
|
327
|
+
"page": 1,
|
|
328
|
+
"size": 10
|
|
329
|
+
})
|