xync-client 0.0.155__py3-none-any.whl → 0.0.162__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 +0 -294
- xync_client/Abc/Agent.py +326 -51
- xync_client/Abc/Ex.py +421 -12
- xync_client/Abc/Order.py +7 -14
- xync_client/Abc/xtype.py +35 -3
- xync_client/Bybit/InAgent.py +18 -447
- xync_client/Bybit/agent.py +531 -431
- xync_client/Bybit/etype/__init__.py +0 -0
- xync_client/Bybit/etype/ad.py +47 -34
- xync_client/Bybit/etype/order.py +34 -49
- xync_client/Bybit/ex.py +20 -46
- xync_client/Bybit/order.py +14 -12
- xync_client/Htx/agent.py +82 -40
- xync_client/Htx/etype/ad.py +22 -5
- xync_client/Htx/etype/order.py +194 -0
- xync_client/Htx/ex.py +16 -16
- xync_client/Mexc/agent.py +196 -13
- xync_client/Mexc/api.py +955 -336
- xync_client/Mexc/etype/ad.py +52 -1
- xync_client/Mexc/etype/order.py +131 -416
- xync_client/Mexc/ex.py +29 -19
- xync_client/Okx/1.py +14 -0
- xync_client/Okx/agent.py +39 -0
- xync_client/Okx/ex.py +8 -8
- xync_client/Pms/Payeer/agent.py +396 -0
- xync_client/Pms/Payeer/login.py +1 -63
- xync_client/Pms/Payeer/trade.py +58 -0
- xync_client/Pms/Volet/{__init__.py → agent.py} +1 -2
- xync_client/loader.py +1 -0
- {xync_client-0.0.155.dist-info → xync_client-0.0.162.dist-info}/METADATA +2 -1
- {xync_client-0.0.155.dist-info → xync_client-0.0.162.dist-info}/RECORD +33 -29
- xync_client/Pms/Payeer/__init__.py +0 -262
- xync_client/Pms/Payeer/api.py +0 -25
- {xync_client-0.0.155.dist-info → xync_client-0.0.162.dist-info}/WHEEL +0 -0
- {xync_client-0.0.155.dist-info → xync_client-0.0.162.dist-info}/top_level.txt +0 -0
|
File without changes
|
xync_client/Bybit/etype/ad.py
CHANGED
|
@@ -13,9 +13,21 @@ class AdStatus(StrEnum):
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class AdsReq(BaseModel):
|
|
16
|
-
tokenId: str
|
|
17
|
-
currencyId: str
|
|
18
|
-
side: Literal["0", "1"] # 0 покупка, # 1 продажа
|
|
16
|
+
tokenId: str = Field(validation_alias="coin_id")
|
|
17
|
+
currencyId: str = Field(validation_alias="cur_id")
|
|
18
|
+
side: Literal["0", "1"] = Field(validation_alias="is_sell") # 0 покупка, # 1 продажа
|
|
19
|
+
payment: list[str] = Field([], validation_alias="pm_ids") # int
|
|
20
|
+
size: str = Field("20", validation_alias="limit") # int
|
|
21
|
+
page: str = "1" # int
|
|
22
|
+
amount: str = "" # float
|
|
23
|
+
vaMaker: bool = Field(False, validation_alias="vm_only")
|
|
24
|
+
canTrade: bool = False
|
|
25
|
+
userId: str = "" # int
|
|
26
|
+
verificationFilter: Literal[0, 1, 2] = 0
|
|
27
|
+
sortType: Literal["OVERALL_RANKING", "TRADE_VOLUME", "TRADE_COMPLETION_RATE", "TRADE_PRICE"] = "OVERALL_RANKING"
|
|
28
|
+
paymentPeriod: Literal[[], [15], [30], [60]] = []
|
|
29
|
+
itemRegion: int = 1
|
|
30
|
+
bulkMaker: bool = False
|
|
19
31
|
|
|
20
32
|
|
|
21
33
|
class Currency(BaseModel):
|
|
@@ -79,7 +91,39 @@ class TradingPreferenceSet(BaseModel):
|
|
|
79
91
|
registerTimeThreshold: int
|
|
80
92
|
|
|
81
93
|
|
|
94
|
+
class AdPostRequest(BaseModel):
|
|
95
|
+
tokenId: str
|
|
96
|
+
currencyId: str
|
|
97
|
+
side: Literal[0, 1] # 0 - покупка, 1 - продажа
|
|
98
|
+
priceType: Literal[0, 1] # 0 - fix rate, 1 - floating
|
|
99
|
+
premium: str
|
|
100
|
+
price: str
|
|
101
|
+
minAmount: str
|
|
102
|
+
maxAmount: str
|
|
103
|
+
remark: str
|
|
104
|
+
tradingPreferenceSet: TradingPreferenceSet
|
|
105
|
+
paymentIds: list[str] # list[int]
|
|
106
|
+
quantity: str # float
|
|
107
|
+
paymentPeriod: int = 15
|
|
108
|
+
itemType: Literal["ORIGIN", "BULK"] = "ORIGIN"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class AdUpdateRequest(AdPostRequest, BaseAdUpdate):
|
|
112
|
+
actionType: Literal["MODIFY", "ACTIVE"] = "MODIFY"
|
|
113
|
+
|
|
114
|
+
|
|
82
115
|
class Ad(BaseAd):
|
|
116
|
+
tokenId: str = None # for initial actualize
|
|
117
|
+
currencyId: str = None # for initial actualize
|
|
118
|
+
side: Literal[0, 1] = None # for initial actualize # 0 - покупка, 1 - продажа (для мейкера, т.е КАКАЯ объява)
|
|
119
|
+
priceType: Literal[0, 1] = None # for initial actualize # 0 - fix rate, 1 - floating
|
|
120
|
+
premium: str = None # for initial actualize
|
|
121
|
+
price: str = None # for initial actualize
|
|
122
|
+
maxAmount: str = Field(serialization_alias="max_fiat")
|
|
123
|
+
minAmount: str = Field(serialization_alias="min_fiat")
|
|
124
|
+
remark: str = Field(serialization_alias="auto_msg")
|
|
125
|
+
tradingPreferenceSet: TradingPreferenceSet | None = None # for initial actualize
|
|
126
|
+
|
|
83
127
|
accountId: str = None # for initial actualize
|
|
84
128
|
authStatus: int = None # for initial actualize
|
|
85
129
|
authTag: List[str] = None # for initial actualize
|
|
@@ -87,7 +131,6 @@ class Ad(BaseAd):
|
|
|
87
131
|
baned: bool = None # for initial actualize
|
|
88
132
|
blocked: str = None # for initial actualize
|
|
89
133
|
createDate: str = None # for initial actualize
|
|
90
|
-
currencyId: str = None # for initial actualize
|
|
91
134
|
executedQuantity: str = None # for initial actualize
|
|
92
135
|
fee: str = None # for initial actualize
|
|
93
136
|
finishNum: int = None # for initial actualize
|
|
@@ -98,27 +141,18 @@ class Ad(BaseAd):
|
|
|
98
141
|
lastLogoutTime: str = None # for initial actualize
|
|
99
142
|
lastQuantity: str = Field(serialization_alias="quantity")
|
|
100
143
|
makerContact: bool = None # for initial actualize
|
|
101
|
-
maxAmount: str = Field(serialization_alias="max_fiat")
|
|
102
|
-
minAmount: str = Field(serialization_alias="min_fiat")
|
|
103
144
|
nickName: str = None # for initial actualize
|
|
104
145
|
orderNum: int = None # for initial actualize
|
|
105
146
|
paymentPeriod: int = None # for initial actualize
|
|
106
147
|
payments: List[str] = None # for initial actualize
|
|
107
|
-
premium: str = None # for initial actualize
|
|
108
|
-
price: str = None # for initial actualize
|
|
109
|
-
priceType: Literal[0, 1] = None # for initial actualize # 0 - fix rate, 1 - floating
|
|
110
148
|
quantity: str = Field(serialization_alias="allQuantity") # for initial actualize
|
|
111
149
|
recentExecuteRate: int = None # for initial actualize
|
|
112
150
|
recentOrderNum: int = None # for initial actualize
|
|
113
151
|
recommend: bool = None # for initial actualize
|
|
114
152
|
recommendTag: str = None # for initial actualize
|
|
115
|
-
remark: str = Field(serialization_alias="auto_msg")
|
|
116
|
-
side: Literal[0, 1] = None # for initial actualize # 0 - покупка, 1 - продажа (для мейкера, т.е КАКАЯ объява)
|
|
117
153
|
status: Literal[10, 20, 30] # 10: online; 20: offline; 30: completed
|
|
118
154
|
symbolInfo: SymbolInfo = None # for initial actualize
|
|
119
|
-
tokenId: str = None # for initial actualize
|
|
120
155
|
tokenName: str = None # for initial actualize
|
|
121
|
-
tradingPreferenceSet: TradingPreferenceSet | None = None # for initial actualize
|
|
122
156
|
userId: str
|
|
123
157
|
userMaskId: str = None # for initial actualize
|
|
124
158
|
userType: str = None # for initial actualize
|
|
@@ -134,24 +168,3 @@ class Ad(BaseAd):
|
|
|
134
168
|
|
|
135
169
|
class MyAd(Ad):
|
|
136
170
|
paymentTerms: List[MyPaymentTerm]
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
class AdPostRequest(BaseModel):
|
|
140
|
-
tokenId: str
|
|
141
|
-
currencyId: str
|
|
142
|
-
side: Literal[0, 1] # 0 - покупка, 1 - продажа
|
|
143
|
-
priceType: Literal[0, 1] # 0 - fix rate, 1 - floating
|
|
144
|
-
premium: str
|
|
145
|
-
price: str
|
|
146
|
-
minAmount: str
|
|
147
|
-
maxAmount: str
|
|
148
|
-
remark: str
|
|
149
|
-
tradingPreferenceSet: TradingPreferenceSet
|
|
150
|
-
paymentIds: list[str]
|
|
151
|
-
quantity: str
|
|
152
|
-
paymentPeriod: int
|
|
153
|
-
itemType: str
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
class AdUpdateRequest(AdPostRequest, BaseAdUpdate):
|
|
157
|
-
actionType: Literal["MODIFY", "ACTIVE"] = "MODIFY"
|
xync_client/Bybit/etype/order.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from enum import IntEnum
|
|
2
|
-
from typing import Literal
|
|
2
|
+
from typing import Literal, ClassVar
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel
|
|
5
5
|
|
|
6
|
+
from xync_client.Abc.xtype import RemapBase
|
|
6
7
|
from xync_client.Bybit.etype.cred import CredEpyd, PaymentTerm as CredPaymentTerm, PaymentConfigVo
|
|
7
8
|
|
|
8
9
|
|
|
@@ -14,34 +15,20 @@ class Topic(IntEnum):
|
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class Status(IntEnum):
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
ws_new = 1
|
|
19
|
+
# chain = 5 # waiting for chain (only web3)
|
|
20
|
+
created = 10 # waiting for buyer to pay
|
|
21
|
+
paid = 20 # waiting for seller to release
|
|
22
|
+
appealed_by_seller = 30 # appealing
|
|
23
|
+
# appealed_by_buyer = 30 # the same appealing
|
|
24
|
+
canceled = 40 # order cancelled
|
|
21
25
|
completed = 50 # order finished
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
seller_appeal_disputed_by_buyer = 30
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class StatusApi(IntEnum):
|
|
32
|
-
created = 1
|
|
33
|
-
_web3 = 5
|
|
34
|
-
wait_for_buyer = 10 # ws_canceled
|
|
35
|
-
wait_for_seller = 20
|
|
36
|
-
appealed = 30
|
|
37
|
-
canceled = 40
|
|
38
|
-
completed = 50
|
|
39
|
-
_paying_online = 60
|
|
40
|
-
_pay_fail_online = 70
|
|
41
|
-
hotswap_cancelled = 80
|
|
42
|
-
_buyer_sel_tokenId = 90
|
|
43
|
-
objectioning = 100
|
|
44
|
-
waiting_for_objection = 110
|
|
26
|
+
# a = 60 # paying (only when paying online)
|
|
27
|
+
# a = 70 # pay fail (only when paying online)
|
|
28
|
+
# a = 80 # exception cancelled (the coin convert to other coin only hotswap)
|
|
29
|
+
# a = 90 # waiting for buyer to select tokenId
|
|
30
|
+
appeal_disputed = 100 # objectioning
|
|
31
|
+
appeal_dispute_disputed = 110 # waiting for the user to raise an objection
|
|
45
32
|
|
|
46
33
|
|
|
47
34
|
class TakeAdReq(BaseModel):
|
|
@@ -149,9 +136,23 @@ class PaymentTerm(CredPaymentTerm):
|
|
|
149
136
|
ruPaymentPrompt: bool
|
|
150
137
|
|
|
151
138
|
|
|
152
|
-
class
|
|
153
|
-
|
|
139
|
+
class _BaseOrder(RemapBase):
|
|
140
|
+
_remap: ClassVar[dict[str, dict]] = {"status": {}}
|
|
141
|
+
|
|
142
|
+
id: int
|
|
143
|
+
userId: int
|
|
144
|
+
createDate: int
|
|
154
145
|
side: Literal[0, 1] # int: 0 покупка, 1 продажа (именно для меня - апи агента, и пох мейкер я или тейкер)
|
|
146
|
+
status: Literal[*[s.value for s in Status]]
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class _BaseChange(_BaseOrder):
|
|
150
|
+
makerUserId: int
|
|
151
|
+
appealedTimes: int
|
|
152
|
+
totalAppealedTimes: int
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class OrderItem(_BaseOrder):
|
|
155
156
|
tokenId: str
|
|
156
157
|
orderType: Literal[
|
|
157
158
|
"ORIGIN", "SMALL_COIN", "WEB3"
|
|
@@ -164,14 +165,9 @@ class OrderItem(BaseModel):
|
|
|
164
165
|
fee: str
|
|
165
166
|
targetNickName: str
|
|
166
167
|
targetUserId: str # не я
|
|
167
|
-
status: Literal[
|
|
168
|
-
5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110
|
|
169
|
-
] # 5: waiting for chain (only web3), 10: waiting for buyer to pay, 20: waiting for seller to release, 30: appealing, 40: order cancelled, 50: order finished, 60: paying (only when paying online), 70: pay fail (only when paying online), 80: exception cancelled (the coin convert to other coin, only hotswap), 90: waiting for buyer to select tokenId, 100: objectioning, 110: waiting for the user to raise an objection
|
|
170
168
|
selfUnreadMsgCount: str
|
|
171
|
-
createDate: str
|
|
172
169
|
transferLastSeconds: str
|
|
173
170
|
appealLastSeconds: str
|
|
174
|
-
userId: str # я
|
|
175
171
|
sellerRealName: str
|
|
176
172
|
buyerRealName: str
|
|
177
173
|
judgeInfo: JudgeInfo
|
|
@@ -181,7 +177,7 @@ class OrderItem(BaseModel):
|
|
|
181
177
|
|
|
182
178
|
|
|
183
179
|
class OrderFull(OrderItem):
|
|
184
|
-
itemId:
|
|
180
|
+
itemId: int
|
|
185
181
|
makerUserId: str
|
|
186
182
|
targetAccountId: str
|
|
187
183
|
targetFirstName: str
|
|
@@ -284,17 +280,6 @@ class Message(BaseModel):
|
|
|
284
280
|
onlyForCustomer: int | None = None
|
|
285
281
|
|
|
286
282
|
|
|
287
|
-
class _BaseChange(BaseModel):
|
|
288
|
-
userId: int
|
|
289
|
-
makerUserId: int
|
|
290
|
-
id: str
|
|
291
|
-
createDate: int
|
|
292
|
-
side: int
|
|
293
|
-
appealedTimes: int
|
|
294
|
-
totalAppealedTimes: int
|
|
295
|
-
status: StatusApi | None = None
|
|
296
|
-
|
|
297
|
-
|
|
298
283
|
class StatusChange(_BaseChange):
|
|
299
284
|
appealVersion: int = None
|
|
300
285
|
|
|
@@ -305,7 +290,7 @@ class CountDown(_BaseChange):
|
|
|
305
290
|
|
|
306
291
|
class _BaseMsg(BaseModel):
|
|
307
292
|
userId: int
|
|
308
|
-
orderId:
|
|
293
|
+
orderId: int
|
|
309
294
|
message: str = None
|
|
310
295
|
msgUuid: str
|
|
311
296
|
msgUuId: str
|
|
@@ -323,7 +308,7 @@ class Receive(_BaseMsg):
|
|
|
323
308
|
class Read(_BaseMsg):
|
|
324
309
|
readAmount: int
|
|
325
310
|
read: Literal["101", "110", "11", "111"]
|
|
326
|
-
orderStatus:
|
|
311
|
+
orderStatus: Status
|
|
327
312
|
|
|
328
313
|
|
|
329
314
|
class SellerCancelChange(BaseModel):
|
xync_client/Bybit/ex.py
CHANGED
|
@@ -11,7 +11,7 @@ from xync_schema.models import Ex, Agent
|
|
|
11
11
|
from xync_client.Abc.Ex import BaseExClient
|
|
12
12
|
from xync_client.loader import NET_TOKEN
|
|
13
13
|
from xync_client.Bybit.etype import ad
|
|
14
|
-
from xync_client.Abc.xtype import PmEx, MapOfIdsList
|
|
14
|
+
from xync_client.Abc.xtype import PmEx, MapOfIdsList, GetAds
|
|
15
15
|
from xync_client.loader import TORM
|
|
16
16
|
|
|
17
17
|
|
|
@@ -81,47 +81,20 @@ class ExClient(BaseExClient): # Bybit client
|
|
|
81
81
|
return cc, cc
|
|
82
82
|
|
|
83
83
|
# 24: Список объяв по (buy/sell, cur, coin, pm)
|
|
84
|
-
async def
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"payment": pm_exids or [],
|
|
99
|
-
"side": "0" if is_sell else "1",
|
|
100
|
-
"size": str(lim) if lim else "20",
|
|
101
|
-
"page": "1",
|
|
102
|
-
"amount": str(amount) if amount else "",
|
|
103
|
-
"vaMaker": vm_filter,
|
|
104
|
-
"bulkMaker": False,
|
|
105
|
-
"canTrade": False,
|
|
106
|
-
"verificationFilter": 0,
|
|
107
|
-
"sortType": "OVERALL_RANKING",
|
|
108
|
-
"paymentPeriod": [],
|
|
109
|
-
"itemRegion": 1,
|
|
110
|
-
}
|
|
111
|
-
# {
|
|
112
|
-
# "userId": "",
|
|
113
|
-
# "tokenId": coin_exid,
|
|
114
|
-
# "currencyId": cur_exid,
|
|
115
|
-
# "payment": pm_exids or [],
|
|
116
|
-
# "side": "0" if is_sell else "1",
|
|
117
|
-
# "size": lim and str(lim) or "200",
|
|
118
|
-
# "page": "1",
|
|
119
|
-
# "amount": str(amount) if amount else "",
|
|
120
|
-
# "authMaker": False,
|
|
121
|
-
# "canTrade": False,
|
|
122
|
-
# }
|
|
123
|
-
ads = await self._post("/fiat/otc/item/online/", data)
|
|
124
|
-
return [ad.Ad(**_ad) for _ad in ads["result"]["items"]]
|
|
84
|
+
async def _ads(self, req: ad.AdsReq, post_pmexs: set[models.PmEx] = None) -> list[ad.Ad]:
|
|
85
|
+
if post_pmexs:
|
|
86
|
+
req.payment = []
|
|
87
|
+
req.size = str(min(1000, int(req.size) * 25))
|
|
88
|
+
res = await self._post("/fiat/otc/item/online/", req.model_dump())
|
|
89
|
+
ads = [ad.Ad(**_ad) for _ad in res["result"]["items"]]
|
|
90
|
+
if post_pmexs:
|
|
91
|
+
post_pmexids = {p.exid for p in post_pmexs}
|
|
92
|
+
ads = [
|
|
93
|
+
ad
|
|
94
|
+
for ad in ads
|
|
95
|
+
if (set(ad.payments) & post_pmexids or [True for px in post_pmexs if px.pm.norm in ad.remark.lower()])
|
|
96
|
+
]
|
|
97
|
+
return ads
|
|
125
98
|
|
|
126
99
|
|
|
127
100
|
async def main():
|
|
@@ -130,10 +103,11 @@ async def main():
|
|
|
130
103
|
bot: FileClient = FileClient(NET_TOKEN)
|
|
131
104
|
# await bot.start()
|
|
132
105
|
cl = ExClient(ex, bot)
|
|
133
|
-
await cl.set_pms()
|
|
134
|
-
await cl.set_coins()
|
|
135
|
-
await cl.set_pairs()
|
|
136
|
-
|
|
106
|
+
# await cl.set_pms()
|
|
107
|
+
# await cl.set_coins()
|
|
108
|
+
# await cl.set_pairs()
|
|
109
|
+
x_ads_req = GetAds(coin_id=1, cur_id=1, is_sell=True, pm_ids=[330, 366, 1853], amount=1000)
|
|
110
|
+
_ads = await cl.ads(x_ads_req)
|
|
137
111
|
# await bot.stop()
|
|
138
112
|
await cl.close()
|
|
139
113
|
|
xync_client/Bybit/order.py
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
from
|
|
1
|
+
from xync_client.Bybit.etype.cred import PaymentTerm
|
|
2
|
+
from xync_schema.models import CredEx, PmEx
|
|
2
3
|
|
|
3
4
|
from xync_client.Abc.Order import BaseOrderClient
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class OrderClient(BaseOrderClient):
|
|
7
|
-
# 2: Отмена своего запроса на сделку
|
|
8
|
-
async def cancel_request(self) -> Order: ...
|
|
9
|
-
|
|
10
|
-
# 3: Одобрить запрос на сделку
|
|
11
|
-
async def accept_request(self) -> bool: ...
|
|
12
|
-
|
|
13
|
-
# 4: Отклонить чужой запрос на сделку
|
|
14
|
-
async def reject_request(self) -> bool: ...
|
|
15
|
-
|
|
16
8
|
# 5: Перевод сделки в состояние "оплачено", c отправкой чека
|
|
17
|
-
async def mark_payed(self, receipt):
|
|
9
|
+
async def mark_payed(self, payterm: PaymentTerm = None, receipt: bytes = None):
|
|
10
|
+
if payterm:
|
|
11
|
+
pt = str(payterm.paymentType)
|
|
12
|
+
pid = payterm.id
|
|
13
|
+
else:
|
|
14
|
+
pmx = await PmEx.get(pm__pmcurs__id=self.order.cred.pmcur_id, ex=self.agent_client.ex_client.ex)
|
|
15
|
+
pt = pmx.exid
|
|
16
|
+
cdx = await CredEx.get(cred_id=self.order.cred_id, ex=self.agent_client.ex_client.ex)
|
|
17
|
+
pid = str(cdx.exid)
|
|
18
|
+
self.agent_client.api.mark_as_paid(orderId=str(self.order.exid), paymentType=pt, paymentId=pid)
|
|
18
19
|
|
|
19
20
|
# 6: Отмена одобренной сделки
|
|
20
21
|
async def cancel_order(self) -> bool: ...
|
|
21
22
|
|
|
22
23
|
# 7: Подтвердить получение оплаты
|
|
23
|
-
async def confirm(self)
|
|
24
|
+
async def confirm(self):
|
|
25
|
+
self.agent_client.api.release_assets(orderId=str(self.order.exid))
|
|
24
26
|
|
|
25
27
|
# 9, 10: Подать аппеляцию cо скриншотом/видео/файлом
|
|
26
28
|
async def start_appeal(self, file) -> bool: ...
|
xync_client/Htx/agent.py
CHANGED
|
@@ -10,11 +10,10 @@ from x_client.aiohttp import Client
|
|
|
10
10
|
from xync_bot import XyncBot
|
|
11
11
|
|
|
12
12
|
from xync_client.Abc.xtype import AdUpd, GetAds
|
|
13
|
+
from xync_client.Htx.etype.order import OrderItem, OrderFull
|
|
13
14
|
from xync_client.loader import NET_TOKEN, PAY_TOKEN, TORM
|
|
14
15
|
|
|
15
|
-
from xync_client.Htx.etype.ad import Req, TradeRule, TradeRulesV2
|
|
16
16
|
from xync_schema.enums import AdStatus, PmType, OrderStatus
|
|
17
|
-
from xync_schema.models import Pm, Coin, Cur, Ad, Order
|
|
18
17
|
from xync_schema import models
|
|
19
18
|
from xync_client.Abc.Agent import BaseAgentClient
|
|
20
19
|
from xync_client.Htx.etype import test, ad
|
|
@@ -39,6 +38,8 @@ class AgentClient(BaseAgentClient):
|
|
|
39
38
|
async def login(self):
|
|
40
39
|
t = int(time() * 1000)
|
|
41
40
|
resp = await self._get("/-/x/uc/uc/open/ticket/get", {"t": t})
|
|
41
|
+
if resp.get("data") is None:
|
|
42
|
+
...
|
|
42
43
|
if ticket := resp["data"].get("ticket"):
|
|
43
44
|
resp = await self._post("/-/x/otc/v1/user/login", form_data={"ticket": ticket, "type": "WEB"})
|
|
44
45
|
if resp["success"]:
|
|
@@ -115,14 +116,40 @@ class AgentClient(BaseAgentClient):
|
|
|
115
116
|
|
|
116
117
|
# 0
|
|
117
118
|
async def get_orders(
|
|
118
|
-
self,
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
self,
|
|
120
|
+
stauts: OrderStatus = OrderStatus.created,
|
|
121
|
+
coin: models.Coin = None,
|
|
122
|
+
cur: models.Cur = None,
|
|
123
|
+
is_sell: bool = None,
|
|
124
|
+
) -> list[OrderItem]:
|
|
125
|
+
resp = await self._get("/-/x/otc/v1/trade/order/process", {"needTradeCount": "true"})
|
|
126
|
+
if resp["success"]:
|
|
127
|
+
return [OrderItem(**o) for o in resp["data"]]
|
|
128
|
+
return []
|
|
129
|
+
|
|
130
|
+
async def get_order(self, oid: int) -> OrderFull | None:
|
|
131
|
+
resp = await self._get("/-/x/otc/v1/trade/order", {"orderId": oid})
|
|
132
|
+
if resp["success"]:
|
|
133
|
+
o = OrderFull(**resp["data"])
|
|
134
|
+
return o
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
async def recv(self, order: OrderItem):
|
|
138
|
+
if order.orderStatus:
|
|
139
|
+
...
|
|
140
|
+
else:
|
|
141
|
+
...
|
|
142
|
+
|
|
143
|
+
async def start_listen(self):
|
|
144
|
+
"""Фоновая задача для ловли входящих ордеров"""
|
|
145
|
+
while True:
|
|
146
|
+
[await self.recv(o) for o in await self.get_orders()]
|
|
147
|
+
await sleep(9)
|
|
121
148
|
|
|
122
149
|
async def order_request(self, ad_id: int, amount: float) -> dict:
|
|
123
150
|
pass
|
|
124
151
|
|
|
125
|
-
async def my_fiats(self, cur: Cur = None) -> list[dict]:
|
|
152
|
+
async def my_fiats(self, cur: models.Cur = None) -> list[dict]:
|
|
126
153
|
pass
|
|
127
154
|
|
|
128
155
|
# async def fiat_new(self, fiat: FiatNew) -> Fiat.pyd():
|
|
@@ -144,22 +171,22 @@ class AgentClient(BaseAgentClient):
|
|
|
144
171
|
|
|
145
172
|
async def ad_new(
|
|
146
173
|
self,
|
|
147
|
-
coin: Coin,
|
|
148
|
-
cur: Cur,
|
|
174
|
+
coin: models.Coin,
|
|
175
|
+
cur: models.Cur,
|
|
149
176
|
is_sell: bool,
|
|
150
|
-
pms: list[Pm],
|
|
177
|
+
pms: list[models.Pm],
|
|
151
178
|
price: float,
|
|
152
179
|
is_float: bool = True,
|
|
153
180
|
min_fiat: int = None,
|
|
154
181
|
details: str = None,
|
|
155
182
|
autoreply: str = None,
|
|
156
183
|
status: AdStatus = AdStatus.active,
|
|
157
|
-
) -> Ad:
|
|
184
|
+
) -> models.Ad:
|
|
158
185
|
pass
|
|
159
186
|
|
|
160
|
-
async def
|
|
187
|
+
async def x2e_req_ad_upd(self, xreq: AdUpd) -> ad.AdsUpd:
|
|
161
188
|
creds = [
|
|
162
|
-
TradeRule(
|
|
189
|
+
ad.TradeRule(
|
|
163
190
|
content="Payment method-%s",
|
|
164
191
|
contentCode="PAY",
|
|
165
192
|
hint="Please enter",
|
|
@@ -167,16 +194,14 @@ class AgentClient(BaseAgentClient):
|
|
|
167
194
|
inputValue=cx.cred.detail,
|
|
168
195
|
sort=1,
|
|
169
196
|
title="【Payment related】",
|
|
170
|
-
titleValue=await models.PmEx.get(pm_id=cx.cred.pmcur.pm_id, ex=self.ex_client.ex).
|
|
171
|
-
"name", flat=True
|
|
172
|
-
),
|
|
197
|
+
titleValue=(await models.PmEx.get(pm_id=cx.cred.pmcur.pm_id, ex=self.ex_client.ex)).name,
|
|
173
198
|
)
|
|
174
|
-
for cx in
|
|
199
|
+
for cx in xreq.credexs
|
|
175
200
|
]
|
|
176
|
-
|
|
201
|
+
trade_rules = ad.TradeRulesV2(
|
|
177
202
|
[
|
|
178
203
|
*creds,
|
|
179
|
-
TradeRule(
|
|
204
|
+
ad.TradeRule(
|
|
180
205
|
content="",
|
|
181
206
|
contentCode="MERCHANT",
|
|
182
207
|
hint="Please enter",
|
|
@@ -187,22 +212,25 @@ class AgentClient(BaseAgentClient):
|
|
|
187
212
|
),
|
|
188
213
|
]
|
|
189
214
|
).model_dump_json(exclude_none=True)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
215
|
+
coin_id, coin_scale = await self.ex_client.x2e_coin(xreq.coin_id)
|
|
216
|
+
cur_id, cur_scale, minimum = await self.ex_client.x2e_cur(xreq.cur_id)
|
|
217
|
+
return ad.AdsUpd(
|
|
218
|
+
id=xreq.id,
|
|
219
|
+
tradeType=int(xreq.is_sell),
|
|
220
|
+
coinId=int(coin_id),
|
|
221
|
+
currency=int(cur_id),
|
|
222
|
+
minTradeLimit=minimum,
|
|
223
|
+
maxTradeLimit=round(xreq.amount - 10**-cur_scale, cur_scale),
|
|
224
|
+
tradeCount=round(xreq.quantity or xreq.amount / xreq.price, coin_scale),
|
|
197
225
|
password=self.agent.auth["pass"],
|
|
198
226
|
payTerm=15,
|
|
199
227
|
premium=0.00,
|
|
200
228
|
isFixed="on",
|
|
201
|
-
fixedPrice=
|
|
229
|
+
fixedPrice=round(xreq.price, cur_scale),
|
|
202
230
|
isAutoReply="off",
|
|
203
231
|
takerAcceptOrder=0,
|
|
204
232
|
isPayCode="off",
|
|
205
|
-
receiveAccounts=
|
|
233
|
+
receiveAccounts=",".join([str(cx.exid) for cx in xreq.credexs]),
|
|
206
234
|
deviation=0,
|
|
207
235
|
isTakerLimit="on",
|
|
208
236
|
takerIsMerchant="on",
|
|
@@ -214,19 +242,20 @@ class AgentClient(BaseAgentClient):
|
|
|
214
242
|
chargeType=False,
|
|
215
243
|
apiVersion=4,
|
|
216
244
|
channel="web",
|
|
217
|
-
tradeRulesV2=quote(
|
|
245
|
+
tradeRulesV2=quote(trade_rules),
|
|
218
246
|
)
|
|
219
|
-
|
|
247
|
+
|
|
248
|
+
async def _ad_upd(self, req: ad.AdsUpd, hdrs: dict[str, str] = None) -> dict:
|
|
249
|
+
res = await self._post(self.url_my_ad + str(req.id), form_data=req.model_dump(exclude_none=True), hdrs=hdrs)
|
|
220
250
|
if res["code"] == 200:
|
|
221
251
|
return res["data"]
|
|
222
252
|
elif res["code"] == 605:
|
|
223
253
|
hdrs = {"x-dialog-trace-id": res["extend"]["traceId"]}
|
|
224
|
-
return await self._ad_upd(
|
|
254
|
+
return await self._ad_upd(req, hdrs)
|
|
225
255
|
elif res["code"] == 1010:
|
|
226
256
|
if (match := re.search(r"Available amount ([\d.]+)", res["message"])) and (qty := match.group(1)):
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
return await self._ad_upd(ad_upd, hdrs)
|
|
257
|
+
req.tradeCount = float(qty)
|
|
258
|
+
return await self._ad_upd(req, hdrs)
|
|
230
259
|
elif res["code"] == 401:
|
|
231
260
|
raise Exception(res)
|
|
232
261
|
raise BaseException(res)
|
|
@@ -304,36 +333,49 @@ async def _test():
|
|
|
304
333
|
while True:
|
|
305
334
|
breq = GetAds(coin_id=1, cur_id=1, is_sell=False, pm_ids=[366])
|
|
306
335
|
sreq = GetAds(coin_id=1, cur_id=1, is_sell=True, pm_ids=[366])
|
|
307
|
-
breq_upd = AdUpd(id=1185713, price=87.01, **{**breq.model_dump(), "amount":
|
|
308
|
-
sreq_upd = AdUpd(id=1188929, price=
|
|
336
|
+
breq_upd = AdUpd(id=1185713, price=87.01, **{**breq.model_dump(), "amount": 100000.01})
|
|
337
|
+
sreq_upd = AdUpd(id=1188929, price=98.99, **{**sreq.model_dump(), "amount": 200000.01})
|
|
309
338
|
|
|
310
339
|
bads: list[ad.Resp] = await cl.ex_client.ads(breq)
|
|
311
340
|
sads: list[ad.Resp] = await cl.ex_client.ads(sreq)
|
|
341
|
+
bceil = 101.11
|
|
342
|
+
sceil = 151
|
|
343
|
+
bads = [a for a in bads if a.price < bceil and a.tradeCount > 10 and (a.maxTradeLimit - a.minTradeLimit > 800)]
|
|
344
|
+
sads = [a for a in sads if a.price > sceil and a.tradeCount > 10 and (a.maxTradeLimit - a.minTradeLimit > 800)]
|
|
312
345
|
|
|
313
|
-
if bads:
|
|
346
|
+
if len(bads) > 1:
|
|
314
347
|
if bads[0].uid == cl.actor.exid:
|
|
315
348
|
if round(bads[0].price - bads[1].price, 2) > 0.01:
|
|
316
349
|
breq_upd.price = bads[1].price + 0.01
|
|
317
350
|
await cl.ad_upd(breq_upd)
|
|
318
351
|
print(end="!", flush=True)
|
|
319
|
-
elif bads[0].price <
|
|
352
|
+
elif bads[0].price < bceil:
|
|
320
353
|
breq_upd.price = bads[0].price + 0.01
|
|
321
354
|
await cl.ad_upd(breq_upd)
|
|
322
355
|
print(end="!", flush=True)
|
|
323
356
|
|
|
324
|
-
if sads:
|
|
357
|
+
if len(sads) > 1:
|
|
325
358
|
if sads[0].uid == cl.actor.exid:
|
|
326
359
|
if round(sads[1].price - sads[0].price, 2) > 0.01:
|
|
327
360
|
sreq_upd.price = sads[1].price - 0.01
|
|
328
361
|
await cl.ad_upd(sreq_upd)
|
|
329
362
|
print(end="!", flush=True)
|
|
330
|
-
elif sads[0].price >
|
|
363
|
+
elif sads[0].price > sceil:
|
|
331
364
|
sreq_upd.price = sads[0].price - 0.01
|
|
332
365
|
await cl.ad_upd(sreq_upd)
|
|
333
366
|
print(end="!", flush=True)
|
|
334
367
|
|
|
368
|
+
if (pos := await cl.get_orders()) and (po := pos.pop(0)):
|
|
369
|
+
if po.side: # is_sell
|
|
370
|
+
po.amount # check
|
|
371
|
+
else: # buy
|
|
372
|
+
order: OrderFull = await cl.get_order(po.orderId)
|
|
373
|
+
if ps := [pm.bankNumber for pm in order.paymentMethod if pm.bankType in [24]]:
|
|
374
|
+
if match := re.search(r"^[PpРр]\d{7,10}\b", ps[0]):
|
|
375
|
+
match.group()
|
|
376
|
+
|
|
335
377
|
print(end=".", flush=True)
|
|
336
|
-
await sleep(
|
|
378
|
+
await sleep(9)
|
|
337
379
|
|
|
338
380
|
await cl.stop()
|
|
339
381
|
|