xync-client 0.0.25.dev22__tar.gz → 0.0.25.dev38__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {xync_client-0.0.25.dev22/xync_client.egg-info → xync_client-0.0.25.dev38}/PKG-INFO +1 -1
  2. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/TestEx.py +2 -2
  3. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Bybit/test_bybit_p2p.py +2 -2
  4. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/Ex.py +1 -1
  5. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/sapi.py +1 -1
  6. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/ex.py +11 -10
  7. xync_client-0.0.25.dev38/xync_client/BingX/pyd.py +90 -0
  8. xync_client-0.0.25.dev38/xync_client/Htx/ex.py +90 -0
  9. xync_client-0.0.25.dev38/xync_client/Htx/pyd/actor.py +4 -0
  10. xync_client-0.0.25.dev38/xync_client/Htx/pyd/ad.py +92 -0
  11. xync_client-0.0.25.dev38/xync_client/Htx/pyd/cred.py +59 -0
  12. xync_client-0.0.25.dev38/xync_client/Htx/pyd/pm.py +12 -0
  13. xync_client-0.0.25.dev38/xync_client/Htx/pyd/types.py +9 -0
  14. xync_client-0.0.25.dev38/xync_client/Okx/ex.py +90 -0
  15. xync_client-0.0.25.dev38/xync_client/Okx/pyd.py +161 -0
  16. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/pyro.py +8 -5
  17. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38/xync_client.egg-info}/PKG-INFO +1 -1
  18. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client.egg-info/SOURCES.txt +6 -0
  19. xync_client-0.0.25.dev22/xync_client/BingX/pyd.py +0 -32
  20. xync_client-0.0.25.dev22/xync_client/Htx/ex.py +0 -77
  21. xync_client-0.0.25.dev22/xync_client/Okx/ex.py +0 -45
  22. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/.env.sample +0 -0
  23. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/.gitignore +0 -0
  24. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/.pre-commit-config.yaml +0 -0
  25. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/README.md +0 -0
  26. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/makefile +0 -0
  27. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/pyproject.toml +0 -0
  28. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/setup.cfg +0 -0
  29. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/TestAgent.py +0 -0
  30. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/TestAsset.py +0 -0
  31. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/TestOrder.py +0 -0
  32. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Binance/test_binance.py +0 -0
  33. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  34. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Gate/test_gate.py +0 -0
  35. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
  36. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  37. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  38. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/__init__.py +0 -0
  39. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/tests/_todo_refact/_test_ex.py +0 -0
  40. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/Agent.py +0 -0
  41. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/Asset.py +0 -0
  42. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/AuthTrait.py +0 -0
  43. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/Base.py +0 -0
  44. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/BaseTest.py +0 -0
  45. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/InAgent.py +0 -0
  46. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Abc/Order.py +0 -0
  47. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/__init__.py +0 -0
  48. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/binance_async.py +0 -0
  49. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/earn_api.py +0 -0
  50. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/ex.py +0 -0
  51. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/exceptions.py +0 -0
  52. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Binance/web_c2c.py +0 -0
  53. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/__init__.py +0 -0
  54. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/agent.py +0 -0
  55. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/base.py +0 -0
  56. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/req.mjs +0 -0
  57. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/sign.js +0 -0
  58. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BingX/test/main.py +0 -0
  59. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BitGet/__init__.py +0 -0
  60. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BitGet/agent.py +0 -0
  61. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BitGet/ex.py +0 -0
  62. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/BitGet/req.mjs +0 -0
  63. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Bybit/agent.py +0 -0
  64. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Bybit/ex.py +0 -0
  65. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Bybit/web_earn.py +0 -0
  66. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Bybit/web_p2p.py +0 -0
  67. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Gate/ex.py +0 -0
  68. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Gate/premarket.py +0 -0
  69. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Htx/agent.py +0 -0
  70. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/Htx/earn.py +0 -0
  71. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/KuCoin/pub.py +0 -0
  72. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/KuCoin/web.py +0 -0
  73. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/agent.py +0 -0
  74. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/asset.py +0 -0
  75. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/auth.py +0 -0
  76. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/ex.py +0 -0
  77. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/inAgent.py +0 -0
  78. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/order.py +0 -0
  79. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/pyd.py +0 -0
  80. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/pyro.py +0 -0
  81. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/TgWallet/web.py +0 -0
  82. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/__init__.py +0 -0
  83. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client/loader.py +0 -0
  84. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client.egg-info/dependency_links.txt +0 -0
  85. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client.egg-info/requires.txt +0 -0
  86. {xync_client-0.0.25.dev22 → xync_client-0.0.25.dev38}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: xync-client
3
- Version: 0.0.25.dev22
3
+ Version: 0.0.25.dev38
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -71,7 +71,7 @@ class TestEx(BaseTest):
71
71
  # 24
72
72
  async def test_ads(self, clients: list[BaseExClient]):
73
73
  for client in clients:
74
- ads: list[BaseAd] = await client.ads("USDT", "RUB", False)
74
+ ads: list[BaseAd] = await client.ads("USDT", "USD", False)
75
75
  ok = self.is_list_of_objects(ads, BaseAd)
76
76
  t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.ads)
77
77
  assert t.ok, "No ads"
@@ -81,7 +81,7 @@ class TestEx(BaseTest):
81
81
  # 42
82
82
  async def test_ad(self, clients: list[BaseExClient]):
83
83
  for client in clients:
84
- ad: BaseAd = await client.ad(self.ad[client.ex.name].id)
84
+ ad: BaseAd = await client.ad(self.ad.get(client.ex.name, (await client.ads("USDT", "RUB", False))[0]).id)
85
85
  ok = isinstance(ad, BaseAd)
86
86
  t, _ = await ExTest.update_or_create({"ok": ok}, ex=client.ex, action=ExAction.ad)
87
87
  assert t.ok, "No ad"
@@ -135,10 +135,10 @@ async def test_on_off_ads(dbc):
135
135
  old_status = AdsStatus[bybit_p2p.online_ads()]
136
136
  new_status = AdsStatus(int(not bool(old_status.name)))
137
137
  ok = await _switch_ad(new_status)
138
- assert ok, "Ads no " + new_status.name
138
+ assert ok, "Ad no " + new_status.name
139
139
  # возвращаем как было:
140
140
  ok = await _switch_ad(old_status)
141
- assert ok, "Ads no " + old_status.name
141
+ assert ok, "Ad no " + old_status.name
142
142
 
143
143
 
144
144
  # старт заявки (тейкером 17)
@@ -50,7 +50,7 @@ class BaseExClient(BaseClient):
50
50
 
51
51
  # 23: Список пар валюта/монет
52
52
  @abstractmethod
53
- async def pairs(self) -> DictOfDicts: ...
53
+ async def pairs(self) -> MapOfIdsList: ...
54
54
 
55
55
  # 24: Список объяв по (buy/sell, cur, coin, pm)
56
56
  @abstractmethod
@@ -138,7 +138,7 @@ class Sapi(Client):
138
138
  }
139
139
  return await self._post(Ep.POST_AD, body)
140
140
 
141
- # 6. Search Ads
141
+ # 6. Search Ad
142
142
  async def search_ads(self, asset, fiat, trade_type, pms: [str] = None, amount: int = None, page=1, rows=20):
143
143
  """
144
144
  Search advertisements based on search criteria.
@@ -5,12 +5,11 @@ from xync_schema import models
5
5
  from xync_schema.models import Ex
6
6
  from xync_schema.pydantic import PmPyd, CurEpyd, CoinEpyd
7
7
 
8
- from xync_client.Abc.Base import FlatDict
9
8
  from xync_client.Abc.Ex import BaseExClient
10
9
  from xync_client.BingX.base import BaseBingXClient
11
10
  from xync_client.loader import PG_DSN
12
11
  from xync_client.Abc.Base import MapOfIdsList
13
- from xync_client.BingX.pyd import PmEpyd
12
+ from xync_client.BingX.pyd import PmEpyd, Ad
14
13
 
15
14
 
16
15
  class ExClient(BaseExClient, BaseBingXClient):
@@ -51,21 +50,23 @@ class ExClient(BaseExClient, BaseBingXClient):
51
50
  return [CurEpyd(exid=cur["id"], ticker=cur["name"]) for cur in curs["data"]["coins"]]
52
51
 
53
52
  # 21: cur_pms_map на BingX
54
- async def cur_pms_map(self):
55
- return {cur.exid: list(await self._pms(cur.exid)) for cur in await self.curs()}
53
+ async def cur_pms_map(self) -> MapOfIdsList:
54
+ return {cur.ticker: [pm.id for pm in await self._pms(cur.ticker)] for cur in await self.curs()}
56
55
 
57
56
  # 22: Монеты на BingX
58
- async def coins(self) -> FlatDict:
59
- return [CoinEpyd(exid="USDT", ticker="USDT")]
57
+ async def coins(self) -> list[CoinEpyd]:
58
+ return [CoinEpyd(exid="1", ticker="USDT")]
60
59
 
61
60
  # 23: Список пар валюта/монет
62
61
  async def pairs(self) -> MapOfIdsList:
63
62
  coins = await self.coins()
64
63
  curs = await self.curs()
65
- return {cur.exid: set(c.exid for c in coins) for cur in curs}
64
+ return {cur.ticker: set(c.ticker for c in coins) for cur in curs}
66
65
 
67
66
  # 24: ads
68
- async def ads(self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None):
67
+ async def ads(
68
+ self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None, amount: int = None
69
+ ) -> list[Ad]:
69
70
  params = {
70
71
  "type": 1,
71
72
  "fiat": cur_exid,
@@ -77,14 +78,14 @@ class ExClient(BaseExClient, BaseBingXClient):
77
78
  }
78
79
 
79
80
  ads = await self._get("/api/c2c/v1/advert/list", params=params)
80
- return ads["data"]["dataList"]
81
+ return [Ad(**ad) for ad in ads["data"]["dataList"]]
81
82
 
82
83
 
83
84
  async def main():
84
85
  _ = await init_db(PG_DSN, models, True)
85
86
  bg = await Ex.get(name="BingX")
86
87
  cl = ExClient(bg)
87
- await cl.pms()
88
+ _ads = await cl.ads("USDT", "RUB", False)
88
89
  await cl.close()
89
90
 
90
91
 
@@ -0,0 +1,90 @@
1
+ from pydantic import BaseModel
2
+ from typing import List
3
+ from xync_schema.pydantic import BaseAd
4
+
5
+ class User(BaseModel):
6
+ nickname: str
7
+ avatar: str
8
+ phone: bool
9
+ email: bool
10
+ # payMethods: dict
11
+
12
+
13
+ class AvailableVolume(BaseModel):
14
+ tradeUSDTNum30: float
15
+
16
+
17
+ class Price(BaseModel):
18
+ asset: str
19
+ fiat: str
20
+ value: str
21
+
22
+
23
+ class OrderLimitsIn(BaseModel):
24
+ minAmount: str
25
+ maxAmount: str
26
+
27
+
28
+ class PmEpyd(BaseModel):
29
+ id: int
30
+ name: str
31
+ mainColor: str
32
+ icon: str
33
+ number: int
34
+
35
+ class UserPaymentMethod(BaseModel):
36
+ id: int
37
+ paymentMethodId: int
38
+ paymentMethodName: str
39
+ paymentMethodIcon: str
40
+ mainColor: str
41
+
42
+ class PaymentMethod(BaseModel):
43
+ id: int
44
+ name: str
45
+ icon: str
46
+ mainColor: str
47
+ userPaymentMethodList: List[UserPaymentMethod]
48
+
49
+ class Ad(BaseAd):
50
+ orderNo: str
51
+ tradeRecent: int
52
+ type: int
53
+ asset: str
54
+ fiat: str
55
+ fiatSymbol: str
56
+ totalNumber: float
57
+ availableAmount: float
58
+ priceType: int
59
+ fixPrice: float
60
+ floatRatio: float
61
+ price: float
62
+ minAmount: float
63
+ maxAmount: float
64
+ assetPrecision: int
65
+ fiatPrecision: int
66
+ pricePrecision: int
67
+ paymentMethodList: List[PaymentMethod]
68
+ termsDesc: str
69
+ hidePaymentInfo: int
70
+ nickName: str
71
+ merchantUid: str
72
+ restStatus: int
73
+ onlineStatus: bool
74
+ merchantOnlineHint: str
75
+ avatarUrl: str
76
+ tradeNum30: int
77
+ expireMinute: int
78
+ status: int
79
+ autoReplyMsg: str
80
+ formatPrice: str
81
+ formatMinAmount: str
82
+ formatMaxAmount: str
83
+ promotionAdvert: bool
84
+ promotionAdvertOnline: bool
85
+ promotionAdvertEnableChange: bool
86
+ isCanBeSubsidized: bool
87
+ merchantKycType: int
88
+ merchantVerificationType: int
89
+ isUserMatchCondition: bool
90
+ notMatchConditionReason: str
@@ -0,0 +1,90 @@
1
+ from asyncio import run
2
+
3
+ from x_model import init_db
4
+ from xync_schema import models, types
5
+ from xync_schema.models import Ex, Cur
6
+ from xync_schema.enums import PmType
7
+
8
+ from xync_client.Abc.Ex import BaseExClient
9
+ from xync_client.Htx.pyd.types import Country
10
+ from xync_client.loader import PG_DSN
11
+
12
+
13
+ class ExClient(BaseExClient):
14
+ # 20: Get all pms
15
+ async def pms(self, _cur: Cur = None) -> dict[int, types.Pm]:
16
+ dist = {
17
+ 0: PmType.card,
18
+ 1: PmType.bank,
19
+ 2: PmType.cash,
20
+ 3: PmType.emoney,
21
+ 4: PmType.emoney,
22
+ 5: PmType.IFSC,
23
+ }
24
+
25
+ pms = (await self._coin_curs_pms())["payMethod"]
26
+
27
+ pmsd = {
28
+ pm["payMethodId"]: types.Pm(
29
+ id=pm["payMethodId"],
30
+ name=pm["name"],
31
+ type_=dist.get(pm["template"], pm["template"]),
32
+ logo=pm.get("bankImage", pm["bankImageWeb"]),
33
+ )
34
+ for pm in pms
35
+ }
36
+
37
+ return pmsd
38
+
39
+ # 21: Get all: currency,pay,allCountry,coin
40
+ async def curs(self) -> list[types.CurE]:
41
+ res = (await self._coin_curs_pms())["currency"]
42
+ return [
43
+ types.CurE(exid=c["currencyId"], ticker=c["nameShort"]) for c in res
44
+ ] # if c['showPtoP'] todo: wht "showPtoP" is means
45
+
46
+ # 22: Список платежных методов по каждой валюте
47
+ async def cur_pms_map(self) -> dict[int, set[int]]:
48
+ res = await self._coin_curs_pms()
49
+ wrong_pms = {4, 34, 498, 548, 20009, 20010} # , 212, 239, 363 # these ids not exist in pms
50
+ return {c["currencyId"]: set(c["supportPayments"]) - wrong_pms for c in res["currency"] if c["supportPayments"]}
51
+
52
+ # 23: Список торгуемых монет
53
+ async def coins(self) -> list[types.CoinE]:
54
+ coins: list[dict] = (await self._coin_curs_pms())["coin"]
55
+ return [types.CoinE(exid=c["coinId"], ticker=c["coinCode"]) for c in coins if c["coinType"] == 2]
56
+
57
+ # 99: Страны
58
+ async def countries(self) -> list[Country]:
59
+ res = await self._coin_curs_pms()
60
+ cts = [
61
+ Country(
62
+ id=c["countryId"],
63
+ code=c["code"],
64
+ name=c["name"],
65
+ short=c["appShort"],
66
+ cur_id=c["currencyId"],
67
+ )
68
+ for c in res["country"]
69
+ ]
70
+ return cts
71
+
72
+ # Get all: currency,pay,allCountry,coin
73
+ async def _coin_curs_pms(self) -> (dict, dict, dict, dict):
74
+ res = (await self._get("/-/x/otc/v1/data/config-list?type=currency,pay,coin,allCountry"))["data"]
75
+ res["currency"][0]["currencyId"] = 1
76
+ [c.update({"currencyId": 1, "name": ""}) for c in res["country"] if c["currencyId"] == 172]
77
+ return res
78
+
79
+
80
+ async def main():
81
+ _ = await init_db(PG_DSN, models, True)
82
+ ex = await Ex.get(name="Htx")
83
+ cl = ExClient(ex)
84
+ await cl.set_pmcurexs()
85
+ await cl.set_coinexs()
86
+ await cl.close()
87
+
88
+
89
+ if __name__ == "__main__":
90
+ run(main())
@@ -0,0 +1,4 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class Resp(BaseModel):
@@ -0,0 +1,92 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class TradeRule(BaseModel):
7
+ title: str
8
+ titleValue: str
9
+ content: str
10
+ inputType: int
11
+ inputValue: str
12
+ hint: str
13
+ contentCode: str
14
+ sort: int
15
+
16
+
17
+ class Req(BaseModel):
18
+ tradeType: int
19
+ coinId: int
20
+ currency: int
21
+ minTradeLimit: float
22
+ maxTradeLimit: float
23
+ tradeCount: float
24
+ password: str
25
+ securityToken: str | None = ""
26
+ payTerm: int
27
+ isFixed: Literal["off", "on"]
28
+ premium: int
29
+ fixedPrice: str | None = ""
30
+ autoReplyContent: str | None = ""
31
+ isAutoReply: Literal["off", "on"]
32
+ tradeRule: str | None = ""
33
+ takerAcceptOrder: int
34
+ isPayCode: Literal["off", "on"]
35
+ isVerifyCapital: bool
36
+ receiveAccounts: int
37
+ deviation: int
38
+ isTakerLimit: Literal["off", "on"]
39
+ blockType: int
40
+ session: int
41
+ chargeType: bool
42
+ apiVersion: int
43
+ channel: str
44
+ tradeRulesV2: list[TradeRule]
45
+
46
+
47
+ class PayMethod(BaseModel):
48
+ payMethodId: int
49
+ name: str
50
+ color: str
51
+ isRecommend: bool | None = None
52
+
53
+
54
+ class PayName(BaseModel):
55
+ bankType: int
56
+ id: int
57
+
58
+
59
+ class Resp(BaseModel):
60
+ blockType: int
61
+ chargeType: bool
62
+ coinId: int
63
+ currency: int
64
+ gmtSort: int
65
+ id: int
66
+ isCopyBlock: bool
67
+ isFollowed: bool
68
+ isOnline: bool
69
+ isTrade: bool
70
+ isVerifyCapital: bool
71
+ labelName: str | None = None
72
+ maxTradeLimit: str
73
+ merchantLevel: int
74
+ merchantTags: str | None = None
75
+ minTradeLimit: str
76
+ orderCompleteRate: str
77
+ payMethod: str
78
+ payMethods: list[PayMethod]
79
+ payName: list[PayName] # приходит массив объектов внутри строки
80
+ payTerm: int
81
+ price: str
82
+ seaViewRoom: str | None = None
83
+ takerAcceptAmount: str
84
+ takerAcceptOrder: int
85
+ takerLimit: int
86
+ thumbUp: int
87
+ totalTradeOrderCount: int
88
+ tradeCount: str
89
+ tradeMonthTimes: int
90
+ tradeType: int
91
+ uid: int
92
+ userName: str
@@ -0,0 +1,59 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel
4
+
5
+ field_ids = {
6
+ 926496571879587801: "payee",
7
+ 926496571879587802: "bank",
8
+ 926496571879587803: "sub_bank",
9
+ 926496571879587804: "pay_account"
10
+ }
11
+
12
+ field_types = {
13
+ "payee": "cred__name",
14
+ "bank": "pm__name",
15
+ "sub_bank": None,
16
+ "pay_account": "cred__detail"
17
+ }
18
+
19
+
20
+ class Cred(BaseModel):
21
+ fieldId: str
22
+ fieldType: Literal["payee", "bank", "sub_bank", "pay_account"]
23
+ value: str | None = None
24
+
25
+
26
+ class Req(BaseModel):
27
+ __root__: list[Cred]
28
+
29
+
30
+ class ModelField(BaseModel):
31
+ fieldId: str
32
+ name: str
33
+ fieldType: str
34
+ index: int
35
+ maxLength: int
36
+ required: bool
37
+ copyable: bool
38
+ remindWord: str
39
+ valueType: str
40
+ value: str | None = None
41
+
42
+
43
+ class Resp(BaseModel):
44
+ id: int
45
+ uid: int
46
+ userName: str
47
+ bankType: int
48
+ bankNumber: str
49
+ bankName: str
50
+ bankAddress: str | None = None
51
+ qrCode: str | None = None
52
+ isShow: int
53
+ buyingEnable: bool
54
+ sellingEnable: bool
55
+ disabledCurrencyList: list[int]
56
+ modelFields: str | None = ""
57
+ modelFieldsList: list[ModelField]
58
+ color: str
59
+ payMethodName: str
@@ -0,0 +1,12 @@
1
+ from pydantic import BaseModel, HttpUrl
2
+
3
+
4
+ class Resp(BaseModel):
5
+ payMethodId: int
6
+ name: str
7
+ defaultName: str | None = None
8
+ template: int
9
+ bankImage: HttpUrl
10
+ bankImageWeb: HttpUrl
11
+ bankType: int
12
+ color: str
@@ -0,0 +1,9 @@
1
+ from msgspec import Struct
2
+
3
+
4
+ class Country(Struct):
5
+ id: int
6
+ code: int
7
+ short: str
8
+ name: str
9
+ cur_id: str
@@ -0,0 +1,90 @@
1
+ from asyncio import run
2
+
3
+ from x_model import init_db
4
+ from xync_schema import models
5
+ from xync_schema import types
6
+
7
+ from xync_client.Abc.Base import MapOfIdsList
8
+ from xync_client.Abc.Ex import BaseExClient
9
+ from xync_client.loader import PG_DSN
10
+ from xync_client.Okx.pyd import PmE, Ads, Ad
11
+
12
+
13
+ class ExClient(BaseExClient):
14
+ async def _pms(self, cur) -> list[PmE]:
15
+ params = {
16
+ "quoteCurrency": f"{cur}",
17
+ "needField": "false",
18
+ }
19
+ pms = await self._get("/v3/c2c/configs/receipt/templates", params=params)
20
+ return [PmE(**pm) for pm in pms["data"]]
21
+
22
+ # 19: Список поддерживаемых валют тейкера
23
+ async def curs(self) -> list[types.CurE]: # {cur.exid: cur.ticker}
24
+ curs = await self._get("/v3/users/common/list/currencies")
25
+ return [types.CurE(exid=cur["currencyId"], ticker=cur["displayName"]) for cur in curs["data"]]
26
+
27
+ # 20: Список платежных методов
28
+ async def pms(self, cur: models.Cur = None) -> dict[int | str, types.Pm]: # {pm.exid: pm}
29
+ all_pms = {}
30
+ for cur in await self.curs():
31
+ pms = await self._pms(cur.ticker)
32
+ for pm in pms:
33
+ all_pms[pm.transferSpeed] = types.Pm(name=pm.paymentMethod)
34
+ return all_pms
35
+
36
+ # 21: Список платежных методов по каждой валюте
37
+ async def cur_pms_map(self) -> MapOfIdsList: # {cur.exid: [pm.exid]}
38
+ return {cur.ticker: [pm.paymentMethod for pm in await self._pms(cur.ticker)] for cur in await self.curs()}
39
+
40
+ # 22: Список торгуемых монет (с ограничениям по валютам, если есть)
41
+ async def coins(self) -> list[types.CoinE]: # {coin.exid: coin.ticker}
42
+ ...
43
+
44
+ # 23: Список пар валюта/монет
45
+ async def pairs(self) -> MapOfIdsList:
46
+ coins = await self.coins()
47
+ curs = await self.curs()
48
+ return {cur.ticker: set(c.ticker for c in coins) for cur in curs}
49
+
50
+ # 24: Список объяв по (buy/sell, cur, coin, pm)
51
+ async def ads(
52
+ self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None, amount: int = None
53
+ ) -> list[Ads]: # {ad.id: ad}
54
+ params = {
55
+ "side": "sell",
56
+ "paymentMethod": "all",
57
+ "userType": "all",
58
+ "hideOverseasVerificationAds": "true" if is_sell else "false",
59
+ "sortType": "price_asc",
60
+ "limit": "100",
61
+ "cryptoCurrency": f"{coin_exid}",
62
+ "fiatCurrency": f"{cur_exid}",
63
+ "currentPage": "1",
64
+ "numberPerPage": "5",
65
+ }
66
+ ads = await self._get("/v3/c2c/tradingOrders/getMarketplaceAdsPrelogin", params=params)
67
+ return [Ads(**ad) for ad in ads["data"]["sell"]]
68
+
69
+ # 42: Чужая объява по id
70
+ async def ad(self, ad_id: int) -> Ad:
71
+ params = {
72
+ "publicUserId": "f81434eb2a",
73
+ "t": f"{ad_id}",
74
+ }
75
+ ad = await self._get("/v3/c2c/merchant/liteProfile", params=params)
76
+ return Ad(**ad)
77
+
78
+
79
+ async def main():
80
+ _ = await init_db(PG_DSN, models, True)
81
+ bg = await models.Ex.get(name="Okx")
82
+ cl = ExClient(bg)
83
+ await cl.curs()
84
+ # await cl.coins()
85
+ # await cl.pms()
86
+ await cl.close()
87
+
88
+
89
+ if __name__ == "__main__":
90
+ run(main())
@@ -0,0 +1,161 @@
1
+ from pydantic import BaseModel
2
+ from typing import List, Optional
3
+ from xync_schema.types import BaseAd
4
+
5
+
6
+ class PmE(BaseModel):
7
+ fieldJson: list
8
+ instantSettlePayment: bool
9
+ mainColor: str
10
+ mostUsed: bool
11
+ needVerification: bool
12
+ paymentMethod: str
13
+ paymentMethodDescription: str
14
+ transferSpeed: int
15
+
16
+
17
+ class PromoBadgeInfoVo(BaseModel):
18
+ badgeList: List[str]
19
+
20
+
21
+ class LegacyMerchantInfo(BaseModel):
22
+ accountAssociationDate: int
23
+ avgPaidTime: int
24
+ avgReleasedTime: int
25
+ cancelledOrderQuantity: int
26
+ completedOrderQuantity: int
27
+ hasLegacyMerchant: bool
28
+ legacyMerchantRegisteredDate: int
29
+ nickname: str
30
+ totalCompletionRate: str
31
+
32
+
33
+ class MerchantInfo30DayOrderInfo(BaseModel):
34
+ completedBuyOrderQuantity30Day: int
35
+ completedOrderQuantity30Day: int
36
+ completedSellOrderQuantity30Day: int
37
+ completionRateBuyOrderQuantity30Day: float
38
+ completionRateOrderQuantity30Day: float
39
+ completionRateSellOrderQuantity30Day: float
40
+ servedUsersCompletedOrders30Day: int
41
+
42
+
43
+ class MerchantScoreInfo(BaseModel):
44
+ merchantScore: int
45
+ scorePercentileRank: int
46
+ showMerchantScoreInfo: bool
47
+
48
+
49
+ class UserActiveStatusVo(BaseModel):
50
+ userActiveStatus: int
51
+ userActiveStatusText: str
52
+
53
+
54
+ class VideoVerificationStatus(BaseModel):
55
+ failedReason: str
56
+ status: int
57
+
58
+
59
+ class Ads(BaseAd):
60
+ alreadyTraded: bool
61
+ availableAmount: str
62
+ avgCompletedTime: int
63
+ avgPaymentTime: int
64
+ baseCurrency: str
65
+ black: bool
66
+ cancelledOrderQuantity: int
67
+ completedOrderQuantity: int
68
+ completedRate: str
69
+ creatorType: str
70
+ guideUpgradeKyc: bool
71
+ id: str
72
+ intention: bool
73
+ isInstitution: int
74
+ maxCompletedOrderQuantity: int
75
+ maxUserCreatedDate: int
76
+ merchantId: str
77
+ minCompletedOrderQuantity: int
78
+ minCompletionRate: str
79
+ minKycLevel: int
80
+ minSellOrderQuantity: int
81
+ minSellOrders: int
82
+ minTradeVolume: int
83
+ mine: bool
84
+ nickName: str
85
+ paymentMethods: List[str]
86
+ paymentTimeoutMinutes: int
87
+ posReviewPercentage: str
88
+ price: str
89
+ promoBadgeInfoVo: PromoBadgeInfoVo
90
+ publicUserId: str
91
+ quoteCurrency: str
92
+ quoteMaxAmountPerOrder: str
93
+ quoteMinAmountPerOrder: str
94
+ quoteScale: int
95
+ quoteSymbol: str
96
+ receivingAds: bool
97
+ safetyLimit: bool
98
+ side: str
99
+ userActiveStatusVo: None
100
+ userType: str
101
+ verificationType: int
102
+ whitelistedCountries: List[str]
103
+
104
+
105
+ class Ad(BaseAd):
106
+ allowChat: bool
107
+ auditState: int
108
+ avatarImage: str
109
+ avgCompletedTime: str
110
+ avgPaidTime: str
111
+ blackState: str
112
+ blackUserCount: Optional[str] = None
113
+ businessHoursInfo: Optional[str] = None
114
+ canCurrentUserViewOrderReview: bool
115
+ commonOrderTotal: Optional[str] = None
116
+ completedBuyOrderQuantity: int
117
+ completedOrderQuantity: int
118
+ completedSellOrderQuantity: int
119
+ countryIcon: str
120
+ countryId: str
121
+ countryName: str
122
+ createdDate: int
123
+ description: str
124
+ disabled: bool
125
+ emailVerified: bool
126
+ finishRate: str
127
+ follow: bool
128
+ followerCount: int
129
+ fundsInfo: Optional[str] = None
130
+ isInstitution: int
131
+ kycDate: int
132
+ kycLevel: str
133
+ kycRedirect: int
134
+ kycVerified: bool
135
+ legacyMerchantInfo: LegacyMerchantInfo
136
+ merchantDeposit: int
137
+ merchantDepositCurrency: str
138
+ merchantInfo30DayOrderInfo: MerchantInfo30DayOrderInfo
139
+ merchantRegistrationDate: int
140
+ merchantScoreInfo: MerchantScoreInfo
141
+ negativeReviewNum: int
142
+ nickName: str
143
+ orderTotalCount: str
144
+ phoneVerified: bool
145
+ positiveReviewNum: int
146
+ positiveReviewPercentage: int
147
+ promoBadgeInfoVo: PromoBadgeInfoVo
148
+ publicMerchantId: Optional[str] = None
149
+ publicUserId: str
150
+ realName: str
151
+ self: bool
152
+ showAddNicknameButton: bool
153
+ showAddNicknameTooltip: bool
154
+ showReview: bool
155
+ showingVideoVerification: bool
156
+ totalReviewNum: int
157
+ tradeUserCount: str
158
+ userActiveStatusVo: UserActiveStatusVo
159
+ userType: str
160
+ videoVerificationStatus: VideoVerificationStatus
161
+ vip: bool
@@ -3,7 +3,7 @@ from pyrogram import Client
3
3
  from pyrogram.errors import UserNotParticipant
4
4
  from pyrogram.raw.functions.channels import ToggleForum
5
5
  from pyrogram.raw.types import InputChannel
6
- from pyrogram.types import ChatPrivileges
6
+ from pyrogram.types import ChatPrivileges, Chat
7
7
  from src.loader import PG_DSN
8
8
  from tg_auth import UserStatus
9
9
  from x_model import init_db
@@ -29,20 +29,23 @@ class PyroClient:
29
29
  def __init__(self, agent: Agent):
30
30
  self.app: Client = Client(str(agent.user_id), TG_API_ID, TG_API_HASH, session_string=agent.auth["sess"])
31
31
 
32
- async def create_orders_forum(self, uid: int | str) -> tuple[int, bool]:
32
+ async def create_orders_forum(self, uid: int) -> tuple[int, bool]:
33
33
  async with self.app as app:
34
34
  app: Client
35
- forum = await app.create_supergroup(f"xync{uid}", "Xync Orders")
35
+ forum: Chat = await app.create_supergroup(f"xync{uid}", "Xync Orders")
36
36
  if not (_ := await app.toggle_forum_topics(chat_id=forum.id, enabled=True)):
37
37
  r = await app.delete_channel(forum.id)
38
38
  r = await forum.leave()
39
39
  raise Exception(f"Chat {forum.id} for {app.me.username} not converted to forum")
40
- added = await forum.add_members([uid, "XyncNetBot"]) # , "xync_bot"
40
+ if added := await forum.add_members(["XyncNetBot"]): # , "xync_bot"
41
+ await forum.promote_member("XyncNetBot", max_privs)
42
+ added = await forum.add_members([uid])
43
+ else:
44
+ pass
41
45
  try:
42
46
  await forum.get_member(uid)
43
47
  except UserNotParticipant:
44
48
  added = False
45
- await forum.promote_member("XyncNetBot", max_privs)
46
49
  # await forum.leave()
47
50
  return forum.id, added
48
51
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: xync-client
3
- Version: 0.0.25.dev22
3
+ Version: 0.0.25.dev38
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -61,9 +61,15 @@ xync_client/Gate/premarket.py
61
61
  xync_client/Htx/agent.py
62
62
  xync_client/Htx/earn.py
63
63
  xync_client/Htx/ex.py
64
+ xync_client/Htx/pyd/actor.py
65
+ xync_client/Htx/pyd/ad.py
66
+ xync_client/Htx/pyd/cred.py
67
+ xync_client/Htx/pyd/pm.py
68
+ xync_client/Htx/pyd/types.py
64
69
  xync_client/KuCoin/pub.py
65
70
  xync_client/KuCoin/web.py
66
71
  xync_client/Okx/ex.py
72
+ xync_client/Okx/pyd.py
67
73
  xync_client/TgWallet/agent.py
68
74
  xync_client/TgWallet/asset.py
69
75
  xync_client/TgWallet/auth.py
@@ -1,32 +0,0 @@
1
- from pydantic import BaseModel
2
-
3
-
4
- class User(BaseModel):
5
- nickname: str
6
- avatar: str
7
- phone: bool
8
- email: bool
9
- # payMethods: dict
10
-
11
-
12
- class AvailableVolume(BaseModel):
13
- tradeUSDTNum30: float
14
-
15
-
16
- class Price(BaseModel):
17
- asset: str
18
- fiat: str
19
- value: str
20
-
21
-
22
- class OrderLimitsIn(BaseModel):
23
- minAmount: str
24
- maxAmount: str
25
-
26
-
27
- class PmEpyd(BaseModel):
28
- id: int
29
- name: str
30
- mainColor: str
31
- icon: str
32
- number: int
@@ -1,77 +0,0 @@
1
- from asyncio import run
2
-
3
- from x_model import init_db
4
- from xync_schema import models
5
- from xync_schema.models import Ex, Coin, Cur, Pm, Ad
6
- from xync_schema.enums import PmType
7
-
8
- from xync_client.Abc.Ex import BaseExClient
9
- from xync_client.loader import PG_DSN
10
-
11
-
12
- class ExClient(BaseExClient):
13
- # 20: Get all pms
14
- async def pms(self) -> dict[int, dict]:
15
- dist = {
16
- 0: PmType.credit_card,
17
- 1: PmType.bank,
18
- 2: PmType.cash,
19
- 3: PmType.web_wallet,
20
- 4: PmType.web_wallet,
21
- 5: PmType.IFSC,
22
- }
23
-
24
- pms = (await self._coin_curs_pms())["payMethod"]
25
-
26
- pmsd = {
27
- pm["payMethodId"]: {
28
- "name": pm["name"],
29
- "type_": dist.get(pm["template"], pm["template"]),
30
- "logo": pm.get("bankImage", pm["bankImageWeb"]),
31
- }
32
- for pm in pms
33
- }
34
-
35
- return pmsd
36
-
37
- # 21: Get all: currency,pay,allCountry,coin
38
- async def curs(self) -> dict[int, str]:
39
- res = await self._coin_curs_pms()
40
- return {
41
- c["currencyId"]: c["nameShort"] for c in res["currency"]
42
- } # if c['showPtoP'] todo: wht "showPtoP" is means
43
-
44
- # 22: Список платежных методов по каждой валюте
45
- async def cur_pms_map(self) -> dict[int, set[int]]:
46
- res = await self._coin_curs_pms()
47
- wrong_pms = {4, 34, 498, 548, 20009, 20010} # , 212, 239, 363 # these ids not exist in pms
48
- return {c["currencyId"]: set(c["supportPayments"]) - wrong_pms for c in res["currency"] if c["supportPayments"]}
49
-
50
- # 23: Список торгуемых монет
51
- async def coins(self) -> dict[int, str]:
52
- coins: list[dict] = (await self._coin_curs_pms())["coin"]
53
- return {c["coinId"]: c["coinCode"] for c in coins if c["coinType"] == 2}
54
-
55
- # 24: Список объяв
56
- async def ads(self, coin: Coin, cur: Cur, is_sell: bool, pms: list[Pm] = None) -> list[Ad]:
57
- res = await self._coin_curs_pms()
58
- return res["country"]
59
-
60
- # Get all: currency,pay,allCountry,coin
61
- async def _coin_curs_pms(self) -> (dict, dict, dict, dict):
62
- res = await self._get("/-/x/otc/v1/data/config-list?type=currency,pay,coin") # ,allCountry
63
- return res["data"]
64
-
65
-
66
- async def main():
67
- _ = await init_db(PG_DSN, models, True)
68
- ex = await Ex.get(name="Htx")
69
- cl = ExClient(ex)
70
- # await cl.cur_pms_map()
71
- await cl.set_pmcurexs()
72
- await cl.set_coinexs()
73
- await cl.close()
74
-
75
-
76
- if __name__ == "__main__":
77
- run(main())
@@ -1,45 +0,0 @@
1
- from asyncio import run
2
-
3
- from x_model import init_db
4
- from xync_schema import models
5
- from xync_schema.models import Coin, Cur, Pm, Ad, Ex
6
-
7
- from xync_client.Abc.Base import MapOfIdsList, ListOfDicts
8
- from xync_client.Abc.Ex import BaseExClient
9
- from xync_client.loader import PG_DSN
10
-
11
-
12
- class ExClient(BaseExClient):
13
- async def cur_pms_map(self) -> MapOfIdsList:
14
- pass
15
-
16
- async def curs(self) -> list[Cur]:
17
- curs = (await self._get("/v3/users/common/list/currencies"))["data"]
18
- return curs
19
-
20
- async def coins(self, cur: Cur = None) -> list[Coin]: ...
21
-
22
- async def pms(self, cur: Cur = None) -> ListOfDicts:
23
- pmcurs = {
24
- cur.ticker: (await self._get("/v3/c2c/configs/receipt/templates", {"quoteCurrency": cur.ticker}))["data"]
25
- for cur in await self.curs()
26
- }
27
- pp = {}
28
- [[pp.update({p["paymentMethod"]: p["paymentMethodDescription"]}) for p in ps] for ps in pmcurs.values()]
29
- pp = {k: v for k, v in sorted(pp.items(), key=lambda x: x[0])}
30
- return pp
31
-
32
- async def ads(self, coin: Coin, cur: Cur, is_sell: bool, pms: list[Pm] = None) -> list[Ad]:
33
- pass
34
-
35
-
36
- async def main():
37
- _ = await init_db(PG_DSN, models, True)
38
- bg = await Ex.get(name="Okx")
39
- cl = ExClient(bg)
40
- # await cl.curs()
41
- # await cl.coins()
42
- await cl.pms()
43
-
44
-
45
- run(main())