fere-sdk 0.5.0.dev35__tar.gz → 0.5.0.dev39__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.
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/PKG-INFO +1 -1
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/pyproject.toml +1 -1
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/client.py +95 -1
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/low_level.py +63 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/models.py +12 -0
- fere_sdk-0.5.0.dev39/src/fere_sdk/spot_models.py +103 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/.gitignore +0 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/README.md +0 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/__init__.py +0 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/auth.py +0 -0
- {fere_sdk-0.5.0.dev35 → fere_sdk-0.5.0.dev39}/src/fere_sdk/perp_models.py +0 -0
|
@@ -28,6 +28,10 @@ from .models import (
|
|
|
28
28
|
PerpOpenRequest,
|
|
29
29
|
PerpWithdrawRequest,
|
|
30
30
|
SecurityCheckResponse,
|
|
31
|
+
SpotBuyRequest,
|
|
32
|
+
SpotCancelRequest,
|
|
33
|
+
SpotSellRequest,
|
|
34
|
+
SpotTpSlRequest,
|
|
31
35
|
SwapRequest,
|
|
32
36
|
TokenToCheck,
|
|
33
37
|
WithdrawRequest,
|
|
@@ -169,7 +173,12 @@ class FereClient:
|
|
|
169
173
|
timeout: int = DEFAULT_TIMEOUT,
|
|
170
174
|
**kwargs,
|
|
171
175
|
) -> dict:
|
|
172
|
-
"""Execute a swap and wait for completion.
|
|
176
|
+
"""Execute a swap and wait for completion.
|
|
177
|
+
|
|
178
|
+
Fully gasless for the user (no native gas token needed on any
|
|
179
|
+
chain). One call handles same-chain, cross-chain, and
|
|
180
|
+
EVM↔Solana bridge swaps, with bridging built in.
|
|
181
|
+
"""
|
|
173
182
|
req = SwapRequest(
|
|
174
183
|
chain_id_in=chain_id_in,
|
|
175
184
|
chain_id_out=chain_id_out,
|
|
@@ -384,10 +393,95 @@ class FereClient:
|
|
|
384
393
|
)
|
|
385
394
|
return await self._api.perp_withdraw(req, wait=True, timeout=timeout)
|
|
386
395
|
|
|
396
|
+
# ----------------------------------------------------------
|
|
397
|
+
# Spot (venue-neutral HyperCore spot)
|
|
398
|
+
# ----------------------------------------------------------
|
|
399
|
+
|
|
400
|
+
async def spot_hl_buy(
|
|
401
|
+
self,
|
|
402
|
+
asset: str,
|
|
403
|
+
size: float,
|
|
404
|
+
order_type: str = "market",
|
|
405
|
+
limit_price: float | None = None,
|
|
406
|
+
slippage_pct: float = 0.5,
|
|
407
|
+
tp_price: float | None = None,
|
|
408
|
+
sl_price: float | None = None,
|
|
409
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
410
|
+
) -> dict:
|
|
411
|
+
"""Buy a spot asset with USDC and wait for completion.
|
|
412
|
+
|
|
413
|
+
``asset`` is a base symbol (USDC-quoted); ``size`` is the base-token
|
|
414
|
+
amount.
|
|
415
|
+
"""
|
|
416
|
+
req = SpotBuyRequest(
|
|
417
|
+
asset=asset,
|
|
418
|
+
size=size,
|
|
419
|
+
order_type=order_type,
|
|
420
|
+
limit_price=limit_price,
|
|
421
|
+
slippage_pct=slippage_pct,
|
|
422
|
+
tp_price=tp_price,
|
|
423
|
+
sl_price=sl_price,
|
|
424
|
+
)
|
|
425
|
+
return await self._api.spot_hl_buy(req, wait=True, timeout=timeout)
|
|
426
|
+
|
|
427
|
+
async def spot_hl_sell(
|
|
428
|
+
self,
|
|
429
|
+
asset: str,
|
|
430
|
+
size: float | None = None,
|
|
431
|
+
order_type: str = "market",
|
|
432
|
+
limit_price: float | None = None,
|
|
433
|
+
slippage_pct: float = 0.5,
|
|
434
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
435
|
+
) -> dict:
|
|
436
|
+
"""Sell a held spot asset (omit size for full balance) and wait."""
|
|
437
|
+
req = SpotSellRequest(
|
|
438
|
+
asset=asset,
|
|
439
|
+
size=size,
|
|
440
|
+
order_type=order_type,
|
|
441
|
+
limit_price=limit_price,
|
|
442
|
+
slippage_pct=slippage_pct,
|
|
443
|
+
)
|
|
444
|
+
return await self._api.spot_hl_sell(req, wait=True, timeout=timeout)
|
|
445
|
+
|
|
446
|
+
async def spot_hl_set_tp_sl(
|
|
447
|
+
self,
|
|
448
|
+
asset: str,
|
|
449
|
+
tp_price: float | None = None,
|
|
450
|
+
sl_price: float | None = None,
|
|
451
|
+
size: float | None = None,
|
|
452
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
453
|
+
) -> dict:
|
|
454
|
+
"""Attach TP/SL sell triggers to a held spot asset and wait."""
|
|
455
|
+
req = SpotTpSlRequest(
|
|
456
|
+
asset=asset,
|
|
457
|
+
tp_price=tp_price,
|
|
458
|
+
sl_price=sl_price,
|
|
459
|
+
size=size,
|
|
460
|
+
)
|
|
461
|
+
return await self._api.spot_hl_set_tp_sl(req, wait=True, timeout=timeout)
|
|
462
|
+
|
|
463
|
+
async def spot_hl_cancel_order(
|
|
464
|
+
self,
|
|
465
|
+
asset: str,
|
|
466
|
+
order_id: int,
|
|
467
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
468
|
+
) -> dict:
|
|
469
|
+
"""Cancel an open spot order and wait for completion."""
|
|
470
|
+
req = SpotCancelRequest(asset=asset, order_id=order_id)
|
|
471
|
+
return await self._api.spot_hl_cancel_order(
|
|
472
|
+
req, wait=True, timeout=timeout
|
|
473
|
+
)
|
|
474
|
+
|
|
387
475
|
# ----------------------------------------------------------
|
|
388
476
|
# Read-only (pass-through)
|
|
389
477
|
# ----------------------------------------------------------
|
|
390
478
|
|
|
479
|
+
async def get_spot_hl_markets(self, search_text: str | None = None) -> dict:
|
|
480
|
+
return await self._api.get_spot_hl_markets(search_text=search_text)
|
|
481
|
+
|
|
482
|
+
async def get_spot_hl_orders(self) -> dict:
|
|
483
|
+
return await self._api.get_spot_hl_orders()
|
|
484
|
+
|
|
391
485
|
async def get_perp_markets(self, search_text: str | None = None) -> dict:
|
|
392
486
|
return await self._api.get_perp_markets(search_text=search_text)
|
|
393
487
|
|
|
@@ -23,6 +23,10 @@ from .models import (
|
|
|
23
23
|
PerpWithdrawRequest,
|
|
24
24
|
SecurityCheckResponse,
|
|
25
25
|
SecurityCheckSummary,
|
|
26
|
+
SpotBuyRequest,
|
|
27
|
+
SpotCancelRequest,
|
|
28
|
+
SpotSellRequest,
|
|
29
|
+
SpotTpSlRequest,
|
|
26
30
|
SwapRequest,
|
|
27
31
|
TaskResponse,
|
|
28
32
|
TaskStatusResponse,
|
|
@@ -510,6 +514,65 @@ class FereAPI:
|
|
|
510
514
|
"/v1/perp/withdraw", request.to_dict(), wait, timeout
|
|
511
515
|
)
|
|
512
516
|
|
|
517
|
+
# ----------------------------------------------------------
|
|
518
|
+
# Spot (venue-neutral HyperCore spot)
|
|
519
|
+
# ----------------------------------------------------------
|
|
520
|
+
|
|
521
|
+
async def get_spot_hl_markets(self, search_text: str | None = None) -> dict:
|
|
522
|
+
"""GET /v1/spot/markets"""
|
|
523
|
+
params = {}
|
|
524
|
+
if search_text:
|
|
525
|
+
params["search_text"] = search_text
|
|
526
|
+
return await self._authed_get("/v1/spot/markets", params=params)
|
|
527
|
+
|
|
528
|
+
async def get_spot_hl_orders(self) -> dict:
|
|
529
|
+
"""GET /v1/spot/orders"""
|
|
530
|
+
return await self._authed_get("/v1/spot/orders")
|
|
531
|
+
|
|
532
|
+
async def spot_hl_buy(
|
|
533
|
+
self,
|
|
534
|
+
request: SpotBuyRequest,
|
|
535
|
+
wait: bool = False,
|
|
536
|
+
timeout: int = 120,
|
|
537
|
+
) -> TaskResponse | dict:
|
|
538
|
+
"""POST /v1/spot/buy"""
|
|
539
|
+
return await self._perp_task(
|
|
540
|
+
"/v1/spot/buy", request.to_dict(), wait, timeout
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
async def spot_hl_sell(
|
|
544
|
+
self,
|
|
545
|
+
request: SpotSellRequest,
|
|
546
|
+
wait: bool = False,
|
|
547
|
+
timeout: int = 120,
|
|
548
|
+
) -> TaskResponse | dict:
|
|
549
|
+
"""POST /v1/spot/sell"""
|
|
550
|
+
return await self._perp_task(
|
|
551
|
+
"/v1/spot/sell", request.to_dict(), wait, timeout
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
async def spot_hl_set_tp_sl(
|
|
555
|
+
self,
|
|
556
|
+
request: SpotTpSlRequest,
|
|
557
|
+
wait: bool = False,
|
|
558
|
+
timeout: int = 120,
|
|
559
|
+
) -> TaskResponse | dict:
|
|
560
|
+
"""POST /v1/spot/tp-sl"""
|
|
561
|
+
return await self._perp_task(
|
|
562
|
+
"/v1/spot/tp-sl", request.to_dict(), wait, timeout
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
async def spot_hl_cancel_order(
|
|
566
|
+
self,
|
|
567
|
+
request: SpotCancelRequest,
|
|
568
|
+
wait: bool = False,
|
|
569
|
+
timeout: int = 120,
|
|
570
|
+
) -> TaskResponse | dict:
|
|
571
|
+
"""POST /v1/spot/orders/cancel"""
|
|
572
|
+
return await self._perp_task(
|
|
573
|
+
"/v1/spot/orders/cancel", request.to_dict(), wait, timeout
|
|
574
|
+
)
|
|
575
|
+
|
|
513
576
|
async def _perp_task(
|
|
514
577
|
self,
|
|
515
578
|
path: str,
|
|
@@ -14,6 +14,14 @@ from .perp_models import ( # noqa: E402,F401
|
|
|
14
14
|
PerpWithdrawRequest,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
# Spot models live in their own module; re-exported here for back-compat.
|
|
18
|
+
from .spot_models import ( # noqa: E402,F401
|
|
19
|
+
SpotBuyRequest,
|
|
20
|
+
SpotCancelRequest,
|
|
21
|
+
SpotSellRequest,
|
|
22
|
+
SpotTpSlRequest,
|
|
23
|
+
)
|
|
24
|
+
|
|
17
25
|
__all__ = [
|
|
18
26
|
"TaskResponse",
|
|
19
27
|
"TaskStatusResponse",
|
|
@@ -32,6 +40,10 @@ __all__ = [
|
|
|
32
40
|
"PerpCancelRequest",
|
|
33
41
|
"PerpFundRequest",
|
|
34
42
|
"PerpWithdrawRequest",
|
|
43
|
+
"SpotBuyRequest",
|
|
44
|
+
"SpotSellRequest",
|
|
45
|
+
"SpotTpSlRequest",
|
|
46
|
+
"SpotCancelRequest",
|
|
35
47
|
"TokenToCheck",
|
|
36
48
|
"TokenSecurityResult",
|
|
37
49
|
"SecurityCheckSummary",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Venue-neutral HyperCore spot request models.
|
|
2
|
+
|
|
3
|
+
Kept in a dedicated module (per the team convention of giving new model groups
|
|
4
|
+
their own file) and re-exported from ``models.py``. Assets are base symbol only
|
|
5
|
+
and always USDC-quoted; ``size`` is the base-token amount.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"SpotBuyRequest",
|
|
14
|
+
"SpotSellRequest",
|
|
15
|
+
"SpotTpSlRequest",
|
|
16
|
+
"SpotCancelRequest",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class SpotBuyRequest:
|
|
22
|
+
"""Buy a spot asset with USDC. size is the base-token amount."""
|
|
23
|
+
|
|
24
|
+
asset: str
|
|
25
|
+
size: float
|
|
26
|
+
order_type: str = "market"
|
|
27
|
+
limit_price: float | None = None
|
|
28
|
+
slippage_pct: float = 0.5
|
|
29
|
+
tp_price: float | None = None
|
|
30
|
+
sl_price: float | None = None
|
|
31
|
+
tp_is_market: bool = True
|
|
32
|
+
sl_is_market: bool = True
|
|
33
|
+
|
|
34
|
+
def to_dict(self) -> dict:
|
|
35
|
+
d: dict = {
|
|
36
|
+
"asset": self.asset,
|
|
37
|
+
"size": self.size,
|
|
38
|
+
"order_type": self.order_type,
|
|
39
|
+
"slippage_pct": self.slippage_pct,
|
|
40
|
+
"tp_is_market": self.tp_is_market,
|
|
41
|
+
"sl_is_market": self.sl_is_market,
|
|
42
|
+
}
|
|
43
|
+
if self.limit_price is not None:
|
|
44
|
+
d["limit_price"] = self.limit_price
|
|
45
|
+
if self.tp_price is not None:
|
|
46
|
+
d["tp_price"] = self.tp_price
|
|
47
|
+
if self.sl_price is not None:
|
|
48
|
+
d["sl_price"] = self.sl_price
|
|
49
|
+
return d
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass
|
|
53
|
+
class SpotSellRequest:
|
|
54
|
+
asset: str
|
|
55
|
+
size: float | None = None
|
|
56
|
+
order_type: str = "market"
|
|
57
|
+
limit_price: float | None = None
|
|
58
|
+
slippage_pct: float = 0.5
|
|
59
|
+
|
|
60
|
+
def to_dict(self) -> dict:
|
|
61
|
+
d: dict = {
|
|
62
|
+
"asset": self.asset,
|
|
63
|
+
"order_type": self.order_type,
|
|
64
|
+
"slippage_pct": self.slippage_pct,
|
|
65
|
+
}
|
|
66
|
+
if self.size is not None:
|
|
67
|
+
d["size"] = self.size
|
|
68
|
+
if self.limit_price is not None:
|
|
69
|
+
d["limit_price"] = self.limit_price
|
|
70
|
+
return d
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass
|
|
74
|
+
class SpotTpSlRequest:
|
|
75
|
+
asset: str
|
|
76
|
+
tp_price: float | None = None
|
|
77
|
+
sl_price: float | None = None
|
|
78
|
+
size: float | None = None
|
|
79
|
+
tp_is_market: bool = True
|
|
80
|
+
sl_is_market: bool = True
|
|
81
|
+
|
|
82
|
+
def to_dict(self) -> dict:
|
|
83
|
+
d: dict = {
|
|
84
|
+
"asset": self.asset,
|
|
85
|
+
"tp_is_market": self.tp_is_market,
|
|
86
|
+
"sl_is_market": self.sl_is_market,
|
|
87
|
+
}
|
|
88
|
+
if self.tp_price is not None:
|
|
89
|
+
d["tp_price"] = self.tp_price
|
|
90
|
+
if self.sl_price is not None:
|
|
91
|
+
d["sl_price"] = self.sl_price
|
|
92
|
+
if self.size is not None:
|
|
93
|
+
d["size"] = self.size
|
|
94
|
+
return d
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass
|
|
98
|
+
class SpotCancelRequest:
|
|
99
|
+
asset: str
|
|
100
|
+
order_id: int
|
|
101
|
+
|
|
102
|
+
def to_dict(self) -> dict:
|
|
103
|
+
return {"asset": self.asset, "order_id": self.order_id}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|