wayfinder-paths 0.1.13__py3-none-any.whl → 0.1.14__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 wayfinder-paths might be problematic. Click here for more details.

Files changed (47) hide show
  1. wayfinder_paths/adapters/balance_adapter/README.md +13 -14
  2. wayfinder_paths/adapters/balance_adapter/adapter.py +33 -32
  3. wayfinder_paths/adapters/balance_adapter/test_adapter.py +123 -0
  4. wayfinder_paths/adapters/brap_adapter/README.md +11 -16
  5. wayfinder_paths/adapters/brap_adapter/adapter.py +78 -63
  6. wayfinder_paths/adapters/brap_adapter/examples.json +63 -52
  7. wayfinder_paths/adapters/brap_adapter/test_adapter.py +121 -59
  8. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +16 -14
  9. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +114 -60
  10. wayfinder_paths/adapters/pool_adapter/README.md +9 -10
  11. wayfinder_paths/adapters/pool_adapter/adapter.py +9 -10
  12. wayfinder_paths/adapters/token_adapter/README.md +2 -14
  13. wayfinder_paths/adapters/token_adapter/adapter.py +16 -10
  14. wayfinder_paths/adapters/token_adapter/examples.json +4 -8
  15. wayfinder_paths/adapters/token_adapter/test_adapter.py +5 -3
  16. wayfinder_paths/core/clients/BRAPClient.py +102 -61
  17. wayfinder_paths/core/clients/ClientManager.py +1 -68
  18. wayfinder_paths/core/clients/HyperlendClient.py +125 -64
  19. wayfinder_paths/core/clients/LedgerClient.py +1 -4
  20. wayfinder_paths/core/clients/PoolClient.py +122 -48
  21. wayfinder_paths/core/clients/TokenClient.py +91 -36
  22. wayfinder_paths/core/clients/WalletClient.py +26 -56
  23. wayfinder_paths/core/clients/WayfinderClient.py +28 -160
  24. wayfinder_paths/core/clients/__init__.py +0 -2
  25. wayfinder_paths/core/clients/protocols.py +35 -46
  26. wayfinder_paths/core/clients/sdk_example.py +37 -22
  27. wayfinder_paths/core/engine/StrategyJob.py +7 -55
  28. wayfinder_paths/core/services/local_evm_txn.py +6 -6
  29. wayfinder_paths/core/services/local_token_txn.py +1 -1
  30. wayfinder_paths/core/strategies/Strategy.py +0 -2
  31. wayfinder_paths/core/utils/evm_helpers.py +2 -2
  32. wayfinder_paths/run_strategy.py +8 -19
  33. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +10 -11
  34. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +40 -25
  35. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +54 -9
  36. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +3 -3
  37. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +12 -6
  38. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +1 -1
  39. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +88 -56
  40. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +16 -12
  41. wayfinder_paths/templates/strategy/README.md +3 -3
  42. wayfinder_paths/templates/strategy/test_strategy.py +3 -2
  43. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.14.dist-info}/METADATA +14 -49
  44. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.14.dist-info}/RECORD +46 -47
  45. wayfinder_paths/core/clients/AuthClient.py +0 -83
  46. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.14.dist-info}/LICENSE +0 -0
  47. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.14.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  """
2
2
  BRAP (Bridge/Router/Adapter Protocol) Client
3
- Provides access to quote operations via the public quote endpoint.
3
+ Provides access to quote operations via the blockchain quote endpoint.
4
4
  """
5
5
 
6
6
  from __future__ import annotations
@@ -10,100 +10,141 @@ from typing import Any, NotRequired, Required, TypedDict
10
10
 
11
11
  from loguru import logger
12
12
 
13
- from wayfinder_paths.core.clients.AuthClient import AuthClient
14
13
  from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
15
14
  from wayfinder_paths.core.config import get_api_base_url
16
15
 
17
16
 
18
- class BRAPQuote(TypedDict):
17
+ class QuoteTx(TypedDict, total=False):
18
+ """Quote transaction data structure"""
19
+
20
+ data: str
21
+ to: str
22
+ value: str
23
+ chainId: int
24
+
25
+
26
+ class QuoteData(TypedDict):
27
+ """Quote data structure"""
28
+
29
+ gas: Required[str]
30
+ amountOut: Required[str]
31
+ priceImpact: Required[int]
32
+ feeAmount: Required[list[str]]
33
+ minAmountOut: Required[str]
34
+ createdAt: Required[int]
35
+ tx: Required[QuoteTx]
36
+ route: Required[list[dict[str, Any]]]
37
+
38
+
39
+ class FeeBreakdown(TypedDict):
40
+ """Fee breakdown structure"""
41
+
42
+ name: Required[str]
43
+ amount: Required[int]
44
+ amount_usd: Required[float]
45
+ token: Required[str]
46
+ token_chain: Required[int]
47
+
48
+
49
+ class FeeEstimate(TypedDict):
50
+ """Fee estimate structure"""
51
+
52
+ fee_total_usd: Required[float]
53
+ fee_breakdown: Required[list[FeeBreakdown]]
54
+
55
+
56
+ class Calldata(TypedDict, total=False):
57
+ """Calldata structure"""
58
+
59
+ data: str
60
+ to: str
61
+ value: str
62
+ chainId: int
63
+
64
+
65
+ class BRAPQuoteEntry(TypedDict):
66
+ """BRAP quote entry structure"""
67
+
68
+ provider: Required[str]
69
+ quote: Required[QuoteData]
70
+ calldata: Required[Calldata]
71
+ output_amount: Required[int]
72
+ input_amount: Required[int]
73
+ gas_estimate: NotRequired[int | None]
74
+ error: NotRequired[str | None]
75
+ input_amount_usd: Required[float]
76
+ output_amount_usd: Required[float]
77
+ fee_estimate: Required[FeeEstimate]
78
+ wrap_transaction: NotRequired[dict[str, Any] | None]
79
+ unwrap_transaction: NotRequired[dict[str, Any] | None]
80
+ native_input: Required[bool]
81
+ native_output: Required[bool]
82
+
83
+
84
+ class BRAPQuoteResponse(TypedDict):
19
85
  """BRAP quote response structure"""
20
86
 
21
- from_token_address: Required[str]
22
- to_token_address: Required[str]
23
- from_chain_id: Required[int]
24
- to_chain_id: Required[int]
25
- from_address: Required[str]
26
- to_address: Required[str]
27
- amount1: Required[str]
28
- amount2: NotRequired[str]
29
- routes: NotRequired[list[dict[str, Any]]]
30
- best_route: NotRequired[dict[str, Any]]
31
- fees: NotRequired[dict[str, Any] | None]
32
- slippage: NotRequired[float | None]
33
- wayfinder_fee: NotRequired[float | None]
87
+ quotes: Required[list[BRAPQuoteEntry]]
88
+ best_quote: Required[BRAPQuoteEntry]
34
89
 
35
90
 
36
91
  class BRAPClient(WayfinderClient):
37
92
  """Client for BRAP quote operations"""
38
93
 
39
- def __init__(self, api_key: str | None = None):
40
- super().__init__(api_key=api_key)
41
- self.api_base_url = get_api_base_url()
42
- self._auth_client: AuthClient | None = AuthClient(api_key=api_key)
94
+ def __init__(self):
95
+ super().__init__()
96
+ self.api_base_url = f"{get_api_base_url()}/v1/blockchain/braps"
43
97
 
44
98
  async def get_quote(
45
99
  self,
46
100
  *,
47
- from_token_address: str,
48
- to_token_address: str,
49
- from_chain_id: int,
50
- to_chain_id: int,
51
- from_address: str,
52
- to_address: str,
53
- amount1: str,
54
- slippage: float | None = None,
55
- wayfinder_fee: float | None = None,
56
- ) -> BRAPQuote:
101
+ from_token: str,
102
+ to_token: str,
103
+ from_chain: int,
104
+ to_chain: int,
105
+ from_wallet: str,
106
+ from_amount: str,
107
+ ) -> BRAPQuoteResponse: # type: ignore # noqa: E501
57
108
  """
58
109
  Get a quote for a bridge/swap operation.
59
110
 
60
111
  Args:
61
- from_token_address: Source token contract address
62
- to_token_address: Destination token contract address
63
- from_chain_id: Source chain ID
64
- to_chain_id: Destination chain ID
65
- from_address: Source wallet address
66
- to_address: Destination wallet address
67
- amount1: Amount to swap (in smallest units)
68
- slippage: Maximum slippage tolerance (optional)
69
- wayfinder_fee: Wayfinder fee (optional)
112
+ from_token: Source token contract address
113
+ to_token: Destination token contract address
114
+ from_chain: Source chain ID
115
+ to_chain: Destination chain ID
116
+ from_wallet: Source wallet address
117
+ from_amount: Amount to swap (in smallest units)
70
118
 
71
119
  Returns:
72
- Quote data including routes, amounts, fees, etc.
120
+ Quote response including quotes array and best_quote
73
121
  """
74
122
  logger.info(
75
- f"Getting BRAP quote: {from_token_address} -> {to_token_address} (chain {from_chain_id} -> {to_chain_id})"
76
- )
77
- logger.debug(
78
- f"Quote params: amount={amount1}, slippage={slippage}, wayfinder_fee={wayfinder_fee}"
123
+ f"Getting BRAP quote: {from_token} -> {to_token} (chain {from_chain} -> {to_chain})"
79
124
  )
125
+ logger.debug(f"Quote params: amount={from_amount}")
80
126
  start_time = time.time()
81
127
 
82
- url = f"{self.api_base_url}/public/quotes/"
128
+ url = f"{self.api_base_url}/quote/"
83
129
 
84
- payload = {
85
- "from_token_address": from_token_address,
86
- "to_token_address": to_token_address,
87
- "from_chain_id": from_chain_id,
88
- "to_chain_id": to_chain_id,
89
- "from_address": from_address,
90
- "to_address": to_address,
91
- "amount1": amount1,
130
+ params: dict[str, Any] = {
131
+ "from_token": from_token,
132
+ "to_token": to_token,
133
+ "from_chain": from_chain,
134
+ "to_chain": to_chain,
135
+ "from_wallet": from_wallet,
136
+ "from_amount": from_amount,
92
137
  }
93
138
 
94
- # Only add optional parameters if they're provided
95
- if slippage is not None:
96
- payload["slippage"] = slippage
97
- if wayfinder_fee is not None:
98
- payload["wayfinder_fee"] = wayfinder_fee
99
-
100
139
  try:
101
- response = await self._request("POST", url, json=payload, headers={})
140
+ response = await self._authed_request("GET", url, params=params, headers={})
102
141
  response.raise_for_status()
103
142
  data = response.json()
143
+ result = data.get("data", data)
144
+
104
145
  elapsed = time.time() - start_time
105
146
  logger.info(f"BRAP quote request completed successfully in {elapsed:.2f}s")
106
- return data.get("data", data)
147
+ return result
107
148
  except Exception as e:
108
149
  elapsed = time.time() - start_time
109
150
  logger.error(f"BRAP quote request failed after {elapsed:.2f}s: {e}")
@@ -5,7 +5,6 @@ Consolidated client management for all API interactions
5
5
 
6
6
  from typing import Any
7
7
 
8
- from wayfinder_paths.core.clients.AuthClient import AuthClient
9
8
  from wayfinder_paths.core.clients.BRAPClient import BRAPClient
10
9
  from wayfinder_paths.core.clients.HyperlendClient import HyperlendClient
11
10
  from wayfinder_paths.core.clients.LedgerClient import LedgerClient
@@ -37,7 +36,6 @@ class ClientManager:
37
36
  self,
38
37
  clients: dict[str, Any] | None = None,
39
38
  skip_auth: bool = False,
40
- api_key: str | None = None,
41
39
  ):
42
40
  """
43
41
  Initialize ClientManager.
@@ -45,14 +43,10 @@ class ClientManager:
45
43
  Args:
46
44
  clients: Optional dict of pre-instantiated clients to inject directly.
47
45
  skip_auth: If True, skips authentication (for SDK usage).
48
- api_key: Optional API key for service account authentication.
49
46
  """
50
47
  self._injected_clients = clients or {}
51
48
  self._skip_auth = skip_auth
52
- self._api_key = api_key
53
- self._access_token: str | None = None
54
49
 
55
- self._auth_client: AuthClient | None = None
56
50
  self._token_client: TokenClientProtocol | None = None
57
51
  self._wallet_client: WalletClientProtocol | None = None
58
52
  self._ledger_client: LedgerClientProtocol | None = None
@@ -79,25 +73,10 @@ class ClientManager:
79
73
  """
80
74
  client = getattr(self, client_attr)
81
75
  if not client:
82
- client = self._injected_clients.get(injected_key) or client_class(
83
- api_key=self._api_key
84
- )
76
+ client = self._injected_clients.get(injected_key) or client_class()
85
77
  setattr(self, client_attr, client)
86
- if self._access_token and hasattr(client, "set_bearer_token"):
87
- client.set_bearer_token(self._access_token)
88
78
  return client
89
79
 
90
- @property
91
- def auth(self) -> AuthClient | None:
92
- """Get or create auth client. Returns None if skip_auth=True."""
93
- if self._skip_auth:
94
- return None
95
- if not self._auth_client:
96
- self._auth_client = AuthClient(api_key=self._api_key)
97
- if self._access_token:
98
- self._auth_client.set_bearer_token(self._access_token)
99
- return self._auth_client
100
-
101
80
  @property
102
81
  def token(self) -> TokenClientProtocol:
103
82
  """Get or create token client"""
@@ -130,55 +109,9 @@ class ClientManager:
130
109
  """Get or create BRAP client"""
131
110
  return self._get_or_create_client("_brap_client", "brap", BRAPClient)
132
111
 
133
- async def authenticate(
134
- self,
135
- username: str | None = None,
136
- password: str | None = None,
137
- *,
138
- refresh_token: str | None = None,
139
- ) -> dict[str, Any]:
140
- """Authenticate with the API. Raises ValueError if skip_auth=True."""
141
- if self._skip_auth:
142
- raise ValueError(
143
- "Authentication is disabled in SDK mode. SDK users handle their own authentication."
144
- )
145
- auth_client = self.auth
146
- if auth_client is None:
147
- raise ValueError("Auth client is not available")
148
- data = await auth_client.authenticate(
149
- username, password, refresh_token=refresh_token
150
- )
151
- access = data.get("access") or data.get("access_token")
152
- if access:
153
- self.set_access_token(access)
154
- return data
155
-
156
- def set_access_token(self, access_token: str) -> None:
157
- """Set and propagate access token to all initialized clients."""
158
- self._access_token = access_token
159
- if self._auth_client:
160
- self._auth_client.set_bearer_token(access_token)
161
- if self._token_client and hasattr(self._token_client, "set_bearer_token"):
162
- self._token_client.set_bearer_token(access_token)
163
- if self._transaction_client and hasattr(
164
- self._transaction_client, "set_bearer_token"
165
- ):
166
- self._transaction_client.set_bearer_token(access_token)
167
- if self._ledger_client and hasattr(self._ledger_client, "set_bearer_token"):
168
- self._ledger_client.set_bearer_token(access_token)
169
- if self._pool_client and hasattr(self._pool_client, "set_bearer_token"):
170
- self._pool_client.set_bearer_token(access_token)
171
- if self._hyperlend_client and hasattr(
172
- self._hyperlend_client, "set_bearer_token"
173
- ):
174
- self._hyperlend_client.set_bearer_token(access_token)
175
- if self._wallet_client and hasattr(self._wallet_client, "set_bearer_token"):
176
- self._wallet_client.set_bearer_token(access_token)
177
-
178
112
  def get_all_clients(self) -> dict[str, Any]:
179
113
  """Get all initialized clients for direct access"""
180
114
  return {
181
- "auth": self._auth_client,
182
115
  "token": self._token_client,
183
116
  "transaction": self._transaction_client,
184
117
  "ledger": self._ledger_client,
@@ -1,97 +1,163 @@
1
1
  """
2
2
  Hyperlend Client
3
- Provides access to Hyperlend stable markets data via public endpoints.
3
+ Provides access to Hyperlend stable markets data via blockchain endpoints.
4
4
  """
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
- from typing import Any, NotRequired, Required, TypedDict
8
+ from typing import Any, Required, TypedDict
9
9
 
10
10
  from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
11
11
  from wayfinder_paths.core.config import get_api_base_url
12
12
 
13
13
 
14
- class StableMarket(TypedDict):
15
- """Stable market data structure"""
16
-
17
- chain_id: Required[int]
18
- token_address: Required[str]
19
- symbol: Required[str]
20
- name: Required[str]
21
- underlying_tokens: Required[float]
22
- buffer_bps: Required[int]
23
- min_buffer_tokens: Required[float]
24
- is_stable_symbol: Required[bool]
25
-
26
-
27
14
  class AssetsView(TypedDict):
28
15
  """Assets view response structure"""
29
16
 
30
- chain_id: Required[int]
31
- user_address: Required[str]
32
- assets: Required[list[dict[str, Any]]]
33
- total_value: NotRequired[float | None]
17
+ block_number: Required[int]
18
+ user: Required[str]
19
+ native_balance_wei: Required[int]
20
+ native_balance: Required[float]
21
+ assets: Required[list[AssetInfo]]
22
+ account_data: Required[AccountData]
23
+ base_currency_info: Required[BaseCurrencyInfo]
34
24
 
35
25
 
36
26
  class MarketEntry(TypedDict):
37
27
  """Market entry data structure"""
38
28
 
39
- chain_id: Required[int]
40
- token_address: Required[str]
41
- market_data: Required[dict[str, Any]]
29
+ symbol: Required[str]
30
+ symbol_canonical: Required[str]
31
+ display_symbol: Required[str]
32
+ reserve: Required[dict[str, Any]]
42
33
 
43
34
 
44
35
  class LendRateHistory(TypedDict):
45
36
  """Lend rate history response structure"""
46
37
 
47
- chain_id: Required[int]
48
- token_address: Required[str]
49
- lookback_hours: Required[int]
50
- rates: Required[list[dict[str, Any]]]
38
+ history: Required[list[RateHistoryEntry]]
39
+
40
+
41
+ class MarketHeadroom(TypedDict):
42
+ """Market headroom data structure"""
43
+
44
+ symbol: Required[str]
45
+ symbol_canonical: Required[str]
46
+ display_symbol: Required[str]
47
+ reserve: Required[dict[str, Any]]
48
+ decimals: Required[int]
49
+ headroom: Required[int]
50
+ supply_cap: Required[int]
51
+
52
+
53
+ class StableMarketsHeadroomResponse(TypedDict):
54
+ """Stable markets headroom response structure"""
55
+
56
+ markets: Required[dict[str, MarketHeadroom]]
57
+ notes: Required[list[str]]
58
+
59
+
60
+ class RateHistoryEntry(TypedDict):
61
+ """Rate history entry data structure"""
62
+
63
+ timestamp_ms: Required[int]
64
+ timestamp: Required[float]
65
+ supply_apr: Required[float]
66
+ supply_apy: Required[float]
67
+ borrow_apr: Required[float]
68
+ borrow_apy: Required[float]
69
+ token: Required[str]
70
+ symbol: Required[str]
71
+ display_symbol: Required[str]
72
+
73
+
74
+ class AssetInfo(TypedDict):
75
+ """Asset information structure"""
76
+
77
+ underlying: Required[str]
78
+ symbol: Required[str]
79
+ symbol_canonical: Required[str]
80
+ symbol_display: Required[str]
81
+ decimals: Required[int]
82
+ a_token: Required[str]
83
+ variable_debt_token: Required[str]
84
+ usage_as_collateral_enabled: Required[bool]
85
+ borrowing_enabled: Required[bool]
86
+ is_active: Required[bool]
87
+ is_frozen: Required[bool]
88
+ is_paused: Required[bool]
89
+ is_siloed_borrowing: Required[bool]
90
+ is_stablecoin: Required[bool]
91
+ underlying_wallet_balance: Required[float]
92
+ underlying_wallet_balance_wei: Required[int]
93
+ price_usd: Required[float]
94
+ supply: Required[float]
95
+ variable_borrow: Required[float]
96
+ supply_usd: Required[float]
97
+ variable_borrow_usd: Required[float]
98
+ supply_apr: Required[float]
99
+ supply_apy: Required[float]
100
+ variable_borrow_apr: Required[float]
101
+ variable_borrow_apy: Required[float]
102
+
103
+
104
+ class AccountData(TypedDict):
105
+ """Account data structure"""
106
+
107
+ total_collateral_base: Required[int | float]
108
+ total_debt_base: Required[int | float]
109
+ available_borrows_base: Required[int | float]
110
+ current_liquidation_threshold: Required[int | float]
111
+ ltv: Required[int | float]
112
+ health_factor_wad: Required[int]
113
+ health_factor: Required[float]
114
+
115
+
116
+ class BaseCurrencyInfo(TypedDict):
117
+ """Base currency information structure"""
118
+
119
+ marketReferenceCurrencyUnit: Required[int]
120
+ marketReferenceCurrencyPriceInUsd: Required[int]
121
+ networkBaseTokenPriceInUsd: Required[int]
122
+ networkBaseTokenPriceDecimals: Required[int]
51
123
 
52
124
 
53
125
  class HyperlendClient(WayfinderClient):
54
126
  """Client for Hyperlend-related operations"""
55
127
 
56
- def __init__(self, api_key: str | None = None):
57
- super().__init__(api_key=api_key)
128
+ def __init__(self):
129
+ super().__init__()
58
130
  self.api_base_url = get_api_base_url()
59
131
 
60
132
  async def get_stable_markets(
61
133
  self,
62
134
  *,
63
- chain_id: int,
64
135
  required_underlying_tokens: float | None = None,
65
136
  buffer_bps: int | None = None,
66
137
  min_buffer_tokens: float | None = None,
67
- is_stable_symbol: bool | None = None,
68
- ) -> list[StableMarket]:
138
+ ) -> StableMarketsHeadroomResponse:
69
139
  """
70
- Fetch stable markets from Hyperlend.
140
+ Fetch stable markets headroom from Hyperlend.
71
141
 
72
142
  Args:
73
- chain_id: Chain ID to query markets for
74
143
  required_underlying_tokens: Required underlying tokens amount
75
144
  buffer_bps: Buffer in basis points
76
145
  min_buffer_tokens: Minimum buffer in tokens
77
- is_stable_symbol: Filter by stable symbol (optional)
78
146
 
79
147
  Example:
80
- GET /api/v1/public/hyperlend/stable-markets/?chain_id=999&required_underlying_tokens=1000.0&buffer_bps=100&min_buffer_tokens=100.0&is_stable_symbol=true
148
+ GET /api/v1/blockchain/hyperlend/stable_markets_headroom/?required_underlying_tokens=1000&buffer_bps=50&min_buffer_tokens=100
81
149
 
82
150
  Returns:
83
- Dictionary containing stable markets data
151
+ Dictionary containing stable markets headroom data with markets and notes
84
152
  """
85
- url = f"{self.api_base_url}/public/hyperlend/stable-markets/"
86
- params: dict[str, Any] = {"chain_id": chain_id}
153
+ url = f"{self.api_base_url}/v1/blockchain/hyperlend/stable_markets_headroom/"
154
+ params: dict[str, Any] = {}
87
155
  if required_underlying_tokens is not None:
88
156
  params["required_underlying_tokens"] = required_underlying_tokens
89
157
  if buffer_bps is not None:
90
158
  params["buffer_bps"] = buffer_bps
91
159
  if min_buffer_tokens is not None:
92
160
  params["min_buffer_tokens"] = min_buffer_tokens
93
- if is_stable_symbol is not None:
94
- params["is_stable_symbol"] = "true" if is_stable_symbol else "false"
95
161
 
96
162
  response = await self._authed_request("GET", url, params=params, headers={})
97
163
  response.raise_for_status()
@@ -101,25 +167,22 @@ class HyperlendClient(WayfinderClient):
101
167
  async def get_assets_view(
102
168
  self,
103
169
  *,
104
- chain_id: int,
105
170
  user_address: str,
106
171
  ) -> AssetsView:
107
172
  """
108
173
  Fetch assets view for a user address from Hyperlend.
109
174
 
110
175
  Args:
111
- chain_id: Chain ID to query assets for
112
176
  user_address: User wallet address to query assets for
113
177
 
114
178
  Example:
115
- GET /api/v1/public/hyperlend/assets-view/?chain_id=999&user_address=0x0c737cB5934afCb5B01965141F865F795B324080
179
+ GET /api/v1/blockchain/hyperlend/assets/?user_address=0x0c737cB5934afCb5B01965141F865F795B324080
116
180
 
117
181
  Returns:
118
- Dictionary containing assets view data
182
+ Dictionary containing assets view data with account information and base currency info
119
183
  """
120
- url = f"{self.api_base_url}/public/hyperlend/assets-view/"
184
+ url = f"{self.api_base_url}/v1/blockchain/hyperlend/assets/"
121
185
  params: dict[str, Any] = {
122
- "chain_id": chain_id,
123
186
  "user_address": user_address,
124
187
  }
125
188
 
@@ -131,26 +194,23 @@ class HyperlendClient(WayfinderClient):
131
194
  async def get_market_entry(
132
195
  self,
133
196
  *,
134
- chain_id: int,
135
- token_address: str,
197
+ token: str,
136
198
  ) -> MarketEntry:
137
199
  """
138
200
  Fetch market entry from Hyperlend.
139
201
 
140
202
  Args:
141
- chain_id: Chain ID to query market for
142
- token_address: Token address to query market for
203
+ token: Token address to query market for
143
204
 
144
205
  Example:
145
- GET /api/v1/public/hyperlend/market-entry/?chain_id=999&token_address=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
206
+ GET /api/v1/blockchain/hyperlend/market_entry/?token=0x5555555555555555555555555555555555555555
146
207
 
147
208
  Returns:
148
- Dictionary containing market entry data
209
+ Dictionary containing market entry data with symbol and reserve information
149
210
  """
150
- url = f"{self.api_base_url}/public/hyperlend/market-entry/"
211
+ url = f"{self.api_base_url}/v1/blockchain/hyperlend/market_entry/"
151
212
  params: dict[str, Any] = {
152
- "chain_id": chain_id,
153
- "token_address": token_address,
213
+ "token": token,
154
214
  }
155
215
 
156
216
  response = await self._authed_request("GET", url, params=params, headers={})
@@ -161,30 +221,31 @@ class HyperlendClient(WayfinderClient):
161
221
  async def get_lend_rate_history(
162
222
  self,
163
223
  *,
164
- chain_id: int,
165
- token_address: str,
224
+ token: str,
166
225
  lookback_hours: int,
226
+ force_refresh: bool | None = None,
167
227
  ) -> LendRateHistory:
168
228
  """
169
229
  Fetch lend rate history from Hyperlend.
170
230
 
171
231
  Args:
172
- chain_id: Chain ID to query rate history for
173
- token_address: Token address to query rate history for
232
+ token: Token address to query rate history for
174
233
  lookback_hours: Number of hours to look back for rate history
234
+ force_refresh: Whether to force refresh the data (optional)
175
235
 
176
236
  Example:
177
- GET /api/v1/public/hyperlend/lend-rate-history/?chain_id=999&token_address=0x5555555555555555555555555555555555555555&lookback_hours=24
237
+ GET /api/v1/blockchain/hyperlend/lend_rate_history/?token=0x5555555555555555555555555555555555555555&lookback_hours=24&force_refresh=false
178
238
 
179
239
  Returns:
180
- Dictionary containing lend rate history data
240
+ Dictionary containing lend rate history data with history array
181
241
  """
182
- url = f"{self.api_base_url}/public/hyperlend/lend-rate-history/"
242
+ url = f"{self.api_base_url}/v1/blockchain/hyperlend/lend_rate_history/"
183
243
  params: dict[str, Any] = {
184
- "chain_id": chain_id,
185
- "token_address": token_address,
244
+ "token": token,
186
245
  "lookback_hours": lookback_hours,
187
246
  }
247
+ if force_refresh is not None:
248
+ params["force_refresh"] = "true" if force_refresh else "false"
188
249
 
189
250
  response = await self._authed_request("GET", url, params=params, headers={})
190
251
  response.raise_for_status()
@@ -63,14 +63,11 @@ class LedgerClient:
63
63
  - POST record snapshot
64
64
  """
65
65
 
66
- def __init__(
67
- self, api_key: str | None = None, ledger_dir: Path | str | None = None
68
- ) -> None:
66
+ def __init__(self, ledger_dir: Path | str | None = None) -> None:
69
67
  """
70
68
  Initialize the ledger client.
71
69
 
72
70
  Args:
73
- api_key: Unused, kept for backward compatibility
74
71
  ledger_dir: Directory to store ledger JSON files. Defaults to .ledger in project root
75
72
  """
76
73
  if ledger_dir is None: