wayfinder-paths 0.1.19__py3-none-any.whl → 0.1.21__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 (98) hide show
  1. wayfinder_paths/__init__.py +0 -2
  2. wayfinder_paths/adapters/balance_adapter/README.md +59 -45
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +1 -22
  4. wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -14
  5. wayfinder_paths/adapters/brap_adapter/README.md +61 -184
  6. wayfinder_paths/adapters/brap_adapter/__init__.py +0 -4
  7. wayfinder_paths/adapters/brap_adapter/adapter.py +1 -148
  8. wayfinder_paths/adapters/brap_adapter/test_adapter.py +0 -15
  9. wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -4
  10. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +1 -10
  11. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +0 -17
  12. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +3 -312
  13. wayfinder_paths/adapters/hyperliquid_adapter/executor.py +1 -71
  14. wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -57
  15. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -17
  16. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +2 -42
  17. wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +1 -9
  18. wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +15 -47
  19. wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -7
  20. wayfinder_paths/adapters/ledger_adapter/README.md +54 -74
  21. wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -4
  22. wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -106
  23. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -12
  24. wayfinder_paths/adapters/moonwell_adapter/README.md +67 -106
  25. wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -4
  26. wayfinder_paths/adapters/moonwell_adapter/adapter.py +10 -122
  27. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +84 -83
  28. wayfinder_paths/adapters/pool_adapter/README.md +30 -51
  29. wayfinder_paths/adapters/pool_adapter/__init__.py +0 -4
  30. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -19
  31. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -8
  32. wayfinder_paths/adapters/token_adapter/README.md +41 -49
  33. wayfinder_paths/adapters/token_adapter/adapter.py +0 -32
  34. wayfinder_paths/adapters/token_adapter/test_adapter.py +1 -12
  35. wayfinder_paths/conftest.py +0 -8
  36. wayfinder_paths/core/__init__.py +0 -2
  37. wayfinder_paths/core/adapters/BaseAdapter.py +0 -22
  38. wayfinder_paths/core/adapters/__init__.py +0 -5
  39. wayfinder_paths/core/adapters/models.py +0 -5
  40. wayfinder_paths/core/analytics/__init__.py +0 -2
  41. wayfinder_paths/core/analytics/bootstrap.py +0 -16
  42. wayfinder_paths/core/analytics/stats.py +0 -7
  43. wayfinder_paths/core/analytics/test_analytics.py +5 -34
  44. wayfinder_paths/core/clients/BRAPClient.py +0 -35
  45. wayfinder_paths/core/clients/ClientManager.py +0 -51
  46. wayfinder_paths/core/clients/HyperlendClient.py +0 -77
  47. wayfinder_paths/core/clients/LedgerClient.py +2 -122
  48. wayfinder_paths/core/clients/PoolClient.py +0 -2
  49. wayfinder_paths/core/clients/TokenClient.py +0 -39
  50. wayfinder_paths/core/clients/WalletClient.py +0 -15
  51. wayfinder_paths/core/clients/WayfinderClient.py +0 -24
  52. wayfinder_paths/core/clients/__init__.py +0 -4
  53. wayfinder_paths/core/clients/protocols.py +25 -98
  54. wayfinder_paths/core/config.py +0 -24
  55. wayfinder_paths/core/constants/__init__.py +0 -7
  56. wayfinder_paths/core/constants/base.py +2 -9
  57. wayfinder_paths/core/constants/erc20_abi.py +0 -5
  58. wayfinder_paths/core/constants/hyperlend_abi.py +0 -7
  59. wayfinder_paths/core/constants/moonwell_abi.py +0 -35
  60. wayfinder_paths/core/engine/StrategyJob.py +0 -32
  61. wayfinder_paths/core/strategies/Strategy.py +0 -99
  62. wayfinder_paths/core/strategies/__init__.py +0 -2
  63. wayfinder_paths/core/utils/__init__.py +0 -1
  64. wayfinder_paths/core/utils/evm_helpers.py +0 -50
  65. wayfinder_paths/core/utils/{erc20_service.py → tokens.py} +25 -21
  66. wayfinder_paths/core/utils/transaction.py +0 -1
  67. wayfinder_paths/run_strategy.py +0 -46
  68. wayfinder_paths/scripts/create_strategy.py +0 -17
  69. wayfinder_paths/scripts/make_wallets.py +1 -4
  70. wayfinder_paths/strategies/basis_trading_strategy/README.md +71 -163
  71. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +0 -24
  72. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +36 -400
  73. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +15 -64
  74. wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -4
  75. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +65 -56
  76. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +4 -27
  77. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -10
  78. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +71 -72
  79. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +23 -227
  80. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +120 -113
  81. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +64 -59
  82. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +4 -44
  83. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +2 -35
  84. wayfinder_paths/templates/adapter/README.md +107 -46
  85. wayfinder_paths/templates/adapter/adapter.py +0 -9
  86. wayfinder_paths/templates/adapter/test_adapter.py +0 -19
  87. wayfinder_paths/templates/strategy/README.md +113 -59
  88. wayfinder_paths/templates/strategy/strategy.py +0 -22
  89. wayfinder_paths/templates/strategy/test_strategy.py +0 -28
  90. wayfinder_paths/tests/test_test_coverage.py +2 -12
  91. wayfinder_paths/tests/test_utils.py +1 -31
  92. wayfinder_paths-0.1.21.dist-info/METADATA +355 -0
  93. wayfinder_paths-0.1.21.dist-info/RECORD +129 -0
  94. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/WHEEL +1 -1
  95. wayfinder_paths/core/adapters/base.py +0 -5
  96. wayfinder_paths-0.1.19.dist-info/METADATA +0 -592
  97. wayfinder_paths-0.1.19.dist-info/RECORD +0 -130
  98. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/LICENSE +0 -0
@@ -15,7 +15,7 @@ from wayfinder_paths.core.clients.BRAPClient import (
15
15
  from wayfinder_paths.core.clients.LedgerClient import TransactionRecord
16
16
  from wayfinder_paths.core.clients.TokenClient import TokenClient
17
17
  from wayfinder_paths.core.constants import DEFAULT_SLIPPAGE, ZERO_ADDRESS
18
- from wayfinder_paths.core.utils.erc20_service import (
18
+ from wayfinder_paths.core.utils.tokens import (
19
19
  build_approve_transaction,
20
20
  get_token_allowance,
21
21
  )
@@ -29,26 +29,14 @@ _NEEDS_CLEAR_APPROVAL = {
29
29
 
30
30
 
31
31
  class BRAPAdapter(BaseAdapter):
32
- """
33
- BRAP (Bridge/Router/Adapter Protocol) adapter for cross-chain swaps and quotes.
34
-
35
- Provides high-level operations for:
36
- - Getting swap quotes across chains
37
- - Executing cross-chain transactions
38
- - Route optimization and fee calculation
39
- - Bridge operations
40
- """
41
-
42
32
  adapter_type: str = "BRAP"
43
33
 
44
34
  def __init__(
45
35
  self,
46
36
  config: dict[str, Any] | None = None,
47
- simulation: bool = False,
48
37
  strategy_wallet_signing_callback=None,
49
38
  ):
50
39
  super().__init__("brap_adapter", config)
51
- self.simulation = simulation
52
40
  self.strategy_wallet_signing_callback = strategy_wallet_signing_callback
53
41
  self.brap_client = BRAPClient()
54
42
  self.token_client = TokenClient()
@@ -67,23 +55,6 @@ class BRAPAdapter(BaseAdapter):
67
55
  slippage: float | None = None,
68
56
  wayfinder_fee: float | None = None,
69
57
  ) -> tuple[bool, BRAPQuoteResponse | str]:
70
- """
71
- Get a quote for a cross-chain swap operation.
72
-
73
- Args:
74
- from_token_address: Source token contract address
75
- to_token_address: Destination token contract address
76
- from_chain_id: Source chain ID
77
- to_chain_id: Destination chain ID
78
- from_address: Source wallet address
79
- to_address: Destination wallet address
80
- amount: Amount to swap (in smallest units)
81
- slippage: Maximum slippage tolerance (optional)
82
- wayfinder_fee: Wayfinder fee (optional)
83
-
84
- Returns:
85
- Tuple of (success, data) where data is quote response or error message
86
- """
87
58
  try:
88
59
  data = await self.brap_client.get_quote(
89
60
  from_token=from_token_address,
@@ -111,25 +82,6 @@ class BRAPAdapter(BaseAdapter):
111
82
  wayfinder_fee: float | None = None,
112
83
  preferred_providers: list[str] | None = None,
113
84
  ) -> tuple[bool, dict[str, Any] | str]:
114
- """
115
- Get the best available quote for a swap operation.
116
-
117
- Args:
118
- from_token_address: Source token contract address
119
- to_token_address: Destination token contract address
120
- from_chain_id: Source chain ID
121
- to_chain_id: Destination chain ID
122
- from_address: Source wallet address
123
- to_address: Destination wallet address
124
- amount: Amount to swap (in smallest units)
125
- slippage: Maximum slippage tolerance (optional)
126
- wayfinder_fee: Wayfinder fee (optional)
127
- preferred_providers: List of provider names in order of preference (optional).
128
- If provided, selects first matching provider instead of "best".
129
-
130
- Returns:
131
- Tuple of (success, data) where data is best quote or error message
132
- """
133
85
  try:
134
86
  data = await self.brap_client.get_quote(
135
87
  from_token=from_token_address,
@@ -177,20 +129,9 @@ class BRAPAdapter(BaseAdapter):
177
129
  quotes: list[dict[str, Any]],
178
130
  preferred_providers: list[str],
179
131
  ) -> dict[str, Any] | None:
180
- """
181
- Select a quote from the list based on provider preference order.
182
-
183
- Args:
184
- quotes: List of quote objects from BRAP API
185
- preferred_providers: List of provider names in order of preference (case-insensitive)
186
-
187
- Returns:
188
- The first matching quote, or None if no preferred provider found
189
- """
190
132
  # Normalize preferred providers to lowercase for case-insensitive matching
191
133
  preferred_lower = [p.lower() for p in preferred_providers]
192
134
 
193
- # Build a map of provider name -> quotes
194
135
  provider_quotes: dict[str, list[dict[str, Any]]] = {}
195
136
  for quote in quotes:
196
137
  # Provider name might be in different fields depending on BRAP response structure
@@ -209,7 +150,6 @@ class BRAPAdapter(BaseAdapter):
209
150
  # Select first matching provider in preference order
210
151
  for pref in preferred_lower:
211
152
  if pref in provider_quotes:
212
- # Return the quote with highest output for this provider
213
153
  provider_list = provider_quotes[pref]
214
154
  best_for_provider = max(
215
155
  provider_list, key=lambda q: int(q.get("output_amount", 0) or 0)
@@ -233,22 +173,7 @@ class BRAPAdapter(BaseAdapter):
233
173
  amount: str,
234
174
  slippage: float | None = None,
235
175
  ) -> tuple[bool, Any]:
236
- """
237
- Calculate fees for a swap operation.
238
-
239
- Args:
240
- from_token_address: Source token contract address
241
- to_token_address: Destination token contract address
242
- from_chain_id: Source chain ID
243
- to_chain_id: Destination chain ID
244
- amount: Amount to swap (in smallest units)
245
- slippage: Maximum slippage tolerance (optional)
246
-
247
- Returns:
248
- Tuple of (success, data) where data is fee breakdown or error message
249
- """
250
176
  try:
251
- # Get quote to extract fee information
252
177
  success, quote_data = await self.get_swap_quote(
253
178
  from_token_address=from_token_address,
254
179
  to_token_address=to_token_address,
@@ -268,7 +193,6 @@ class BRAPAdapter(BaseAdapter):
268
193
  if not best_quote:
269
194
  return (False, "No quote available for fee calculation")
270
195
 
271
- # Extract fee information
272
196
  fee_estimate = best_quote.get("fee_estimate", {})
273
197
  fees = {
274
198
  "input_amount": best_quote.get("input_amount", 0),
@@ -295,20 +219,6 @@ class BRAPAdapter(BaseAdapter):
295
219
  amount: str,
296
220
  slippage: float | None = None,
297
221
  ) -> tuple[bool, Any]:
298
- """
299
- Compare multiple routes for a swap operation.
300
-
301
- Args:
302
- from_token_address: Source token contract address
303
- to_token_address: Destination token contract address
304
- from_chain_id: Source chain ID
305
- to_chain_id: Destination chain ID
306
- amount: Amount to swap (in smallest units)
307
- slippage: Maximum slippage tolerance (optional)
308
-
309
- Returns:
310
- Tuple of (success, data) where data is route comparison or error message
311
- """
312
222
  try:
313
223
  data = await self.brap_client.get_quote(
314
224
  from_token=from_token_address,
@@ -379,19 +289,6 @@ class BRAPAdapter(BaseAdapter):
379
289
  strategy_name: str | None = None,
380
290
  preferred_providers: list[str] | None = None,
381
291
  ) -> tuple[bool, Any]:
382
- """
383
- Execute a swap by looking up token metadata via token IDs.
384
-
385
- Args:
386
- from_token_id: Source token ID
387
- to_token_id: Destination token ID
388
- from_address: Wallet address
389
- amount: Amount to swap (in smallest units)
390
- slippage: Maximum slippage tolerance
391
- strategy_name: Strategy name for ledger recording
392
- preferred_providers: List of provider names in order of preference (e.g., ["enso", "aerodrome"]).
393
- If provided, selects first matching provider instead of "best".
394
- """
395
292
  from_token = await self.token_client.get_token_details(from_token_id)
396
293
  if not from_token:
397
294
  return (False, f"From token not found: {from_token_id}")
@@ -429,9 +326,6 @@ class BRAPAdapter(BaseAdapter):
429
326
  quote: dict[str, Any],
430
327
  strategy_name: str | None = None,
431
328
  ) -> tuple[bool, Any]:
432
- """
433
- Execute a swap using a previously retrieved BRAP quote.
434
- """
435
329
  chain = from_token.get("chain") or {}
436
330
  chain_id = self._chain_id(chain)
437
331
 
@@ -556,20 +450,6 @@ class BRAPAdapter(BaseAdapter):
556
450
  amount: str,
557
451
  slippage: float | None = None,
558
452
  ) -> tuple[bool, Any]:
559
- """
560
- Get a quote for a bridge operation (same as swap for BRAP).
561
-
562
- Args:
563
- from_token_address: Source token contract address
564
- to_token_address: Destination token contract address
565
- from_chain_id: Source chain ID
566
- to_chain_id: Destination chain ID
567
- amount: Amount to bridge (in smallest units)
568
- slippage: Maximum slippage tolerance (optional)
569
-
570
- Returns:
571
- Tuple of (success, data) where data is bridge quote or error message
572
- """
573
453
  # For BRAP, bridge operations are the same as swap operations
574
454
  return await self.get_swap_quote(
575
455
  from_token_address=from_token_address,
@@ -585,17 +465,6 @@ class BRAPAdapter(BaseAdapter):
585
465
  async def estimate_gas_cost(
586
466
  self, from_chain_id: int, to_chain_id: int, operation_type: str = "swap"
587
467
  ) -> tuple[bool, Any]:
588
- """
589
- Estimate gas costs for a cross-chain operation.
590
-
591
- Args:
592
- from_chain_id: Source chain ID
593
- to_chain_id: Destination chain ID
594
- operation_type: Type of operation ("swap", "bridge")
595
-
596
- Returns:
597
- Tuple of (success, data) where data is gas cost estimate or error message
598
- """
599
468
  try:
600
469
  # This is a simplified estimation - in practice, you'd want to
601
470
  # query actual gas prices from the chains
@@ -643,19 +512,6 @@ class BRAPAdapter(BaseAdapter):
643
512
  to_chain_id: int,
644
513
  amount: str,
645
514
  ) -> tuple[bool, Any]:
646
- """
647
- Validate swap parameters before executing.
648
-
649
- Args:
650
- from_token_address: Source token contract address
651
- to_token_address: Destination token contract address
652
- from_chain_id: Source chain ID
653
- to_chain_id: Destination chain ID
654
- amount: Amount to swap (in smallest units)
655
-
656
- Returns:
657
- Tuple of (success, data) where data is validation result or error message
658
- """
659
515
  try:
660
516
  validation_errors = []
661
517
 
@@ -752,9 +608,6 @@ class BRAPAdapter(BaseAdapter):
752
608
  return await self._send_tx(approve_tx)
753
609
 
754
610
  async def _send_tx(self, tx: dict[str, Any]) -> tuple[bool, Any]:
755
- """Send transaction with simulation check."""
756
- if self.simulation:
757
- return True, {"simulation": tx}
758
611
  txn_hash = await send_transaction(tx, self.strategy_wallet_signing_callback)
759
612
  return True, txn_hash
760
613
 
@@ -6,24 +6,19 @@ from wayfinder_paths.adapters.brap_adapter.adapter import BRAPAdapter
6
6
 
7
7
 
8
8
  class TestBRAPAdapter:
9
- """Test cases for BRAPAdapter"""
10
-
11
9
  @pytest.fixture
12
10
  def mock_brap_client(self):
13
- """Mock BRAPClient for testing"""
14
11
  mock_client = AsyncMock()
15
12
  return mock_client
16
13
 
17
14
  @pytest.fixture
18
15
  def adapter(self, mock_brap_client):
19
- """Create a BRAPAdapter instance with mocked client for testing"""
20
16
  adapter = BRAPAdapter()
21
17
  adapter.brap_client = mock_brap_client
22
18
  return adapter
23
19
 
24
20
  @pytest.mark.asyncio
25
21
  async def test_get_swap_quote_success(self, adapter, mock_brap_client):
26
- """Test successful swap quote retrieval"""
27
22
  mock_response = {
28
23
  "quotes": [
29
24
  {
@@ -80,7 +75,6 @@ class TestBRAPAdapter:
80
75
 
81
76
  @pytest.mark.asyncio
82
77
  async def test_get_best_quote_success(self, adapter, mock_brap_client):
83
- """Test successful best quote retrieval"""
84
78
  mock_response = {
85
79
  "quotes": [],
86
80
  "best_quote": {
@@ -115,7 +109,6 @@ class TestBRAPAdapter:
115
109
 
116
110
  @pytest.mark.asyncio
117
111
  async def test_get_best_quote_no_quotes(self, adapter, mock_brap_client):
118
- """Test best quote retrieval when no quotes available"""
119
112
  mock_response = {"quotes": [], "best_quote": None}
120
113
  mock_brap_client.get_quote = AsyncMock(return_value=mock_response)
121
114
 
@@ -134,7 +127,6 @@ class TestBRAPAdapter:
134
127
 
135
128
  @pytest.mark.asyncio
136
129
  async def test_calculate_swap_fees_success(self, adapter, mock_brap_client):
137
- """Test successful swap fee calculation"""
138
130
  mock_quote_response = {
139
131
  "quotes": [],
140
132
  "best_quote": {
@@ -175,7 +167,6 @@ class TestBRAPAdapter:
175
167
 
176
168
  @pytest.mark.asyncio
177
169
  async def test_compare_routes_success(self, adapter, mock_brap_client):
178
- """Test successful route comparison"""
179
170
  mock_response = {
180
171
  "quotes": [
181
172
  {
@@ -233,7 +224,6 @@ class TestBRAPAdapter:
233
224
 
234
225
  @pytest.mark.asyncio
235
226
  async def test_estimate_gas_cost_success(self, adapter):
236
- """Test successful gas cost estimation"""
237
227
  success, data = await adapter.estimate_gas_cost(
238
228
  from_chain_id=8453, to_chain_id=1, operation_type="swap"
239
229
  )
@@ -247,7 +237,6 @@ class TestBRAPAdapter:
247
237
 
248
238
  @pytest.mark.asyncio
249
239
  async def test_validate_swap_parameters_success(self, adapter, mock_brap_client):
250
- """Test successful swap parameter validation"""
251
240
  mock_quote_response = {
252
241
  "quotes": [],
253
242
  "best_quote": {
@@ -279,7 +268,6 @@ class TestBRAPAdapter:
279
268
 
280
269
  @pytest.mark.asyncio
281
270
  async def test_validate_swap_parameters_invalid_address(self, adapter):
282
- """Test swap parameter validation with invalid address"""
283
271
  success, data = await adapter.validate_swap_parameters(
284
272
  from_token_address="invalid_address",
285
273
  to_token_address="0xB1c97a44F7552d9Dd5e5e5e5e5e5e5e5e5e5e5e5e5e",
@@ -294,7 +282,6 @@ class TestBRAPAdapter:
294
282
 
295
283
  @pytest.mark.asyncio
296
284
  async def test_validate_swap_parameters_invalid_amount(self, adapter):
297
- """Test swap parameter validation with invalid amount"""
298
285
  success, data = await adapter.validate_swap_parameters(
299
286
  from_token_address="0x" + "a" * 40,
300
287
  to_token_address="0x" + "b" * 40,
@@ -309,7 +296,6 @@ class TestBRAPAdapter:
309
296
 
310
297
  @pytest.mark.asyncio
311
298
  async def test_get_swap_quote_failure(self, adapter, mock_brap_client):
312
- """Test swap quote retrieval failure"""
313
299
  mock_brap_client.get_quote = AsyncMock(side_effect=Exception("API Error"))
314
300
 
315
301
  success, data = await adapter.get_swap_quote(
@@ -326,5 +312,4 @@ class TestBRAPAdapter:
326
312
  assert "API Error" in data
327
313
 
328
314
  def test_adapter_type(self, adapter):
329
- """Test adapter has adapter_type"""
330
315
  assert adapter.adapter_type == "BRAP"
@@ -1,7 +1,3 @@
1
- """
2
- Hyperlend Adapter
3
- """
4
-
5
1
  from wayfinder_paths.adapters.hyperlend_adapter.adapter import HyperlendAdapter
6
2
 
7
3
  __all__ = ["HyperlendAdapter"]
@@ -16,7 +16,7 @@ from wayfinder_paths.core.constants.hyperlend_abi import (
16
16
  POOL_ABI,
17
17
  WRAPPED_TOKEN_GATEWAY_ABI,
18
18
  )
19
- from wayfinder_paths.core.utils.erc20_service import (
19
+ from wayfinder_paths.core.utils.tokens import (
20
20
  build_approve_transaction,
21
21
  get_token_allowance,
22
22
  )
@@ -31,21 +31,17 @@ HYPERLEND_DEFAULTS = {
31
31
 
32
32
 
33
33
  class HyperlendAdapter(BaseAdapter):
34
- """Thin HyperLend adapter that only builds tx data and lets the provider send it."""
35
-
36
34
  adapter_type = "HYPERLEND"
37
35
 
38
36
  def __init__(
39
37
  self,
40
38
  config: dict[str, Any],
41
- simulation: bool = False,
42
39
  strategy_wallet_signing_callback=None,
43
40
  ) -> None:
44
41
  super().__init__("hyperlend_adapter", config)
45
42
  cfg = config or {}
46
43
  adapter_cfg = cfg.get("hyperlend_adapter") or {}
47
44
 
48
- self.simulation = simulation
49
45
  self.strategy_wallet_signing_callback = strategy_wallet_signing_callback
50
46
  self.hyperlend_client = HyperlendClient()
51
47
 
@@ -212,9 +208,6 @@ class HyperlendAdapter(BaseAdapter):
212
208
  # ------------------------------------------------------------------ #
213
209
 
214
210
  async def _send_tx(self, tx: dict[str, Any]) -> tuple[bool, Any]:
215
- """Send transaction with simulation check."""
216
- if self.simulation:
217
- return True, {"simulation": tx}
218
211
  txn_hash = await send_transaction(tx, self.strategy_wallet_signing_callback)
219
212
  return True, txn_hash
220
213
 
@@ -250,8 +243,6 @@ class HyperlendAdapter(BaseAdapter):
250
243
  chain_id: int,
251
244
  value: int = 0,
252
245
  ) -> dict[str, Any]:
253
- """Encode calldata without touching network."""
254
-
255
246
  async with web3_from_chain_id(chain_id) as web3:
256
247
  contract = web3.eth.contract(address=target, abi=abi)
257
248
  try:
@@ -6,17 +6,13 @@ from wayfinder_paths.adapters.hyperlend_adapter.adapter import HyperlendAdapter
6
6
 
7
7
 
8
8
  class TestHyperlendAdapter:
9
- """Test cases for HyperlendAdapter"""
10
-
11
9
  @pytest.fixture
12
10
  def mock_hyperlend_client(self):
13
- """Mock HyperlendClient for testing"""
14
11
  mock_client = AsyncMock()
15
12
  return mock_client
16
13
 
17
14
  @pytest.fixture
18
15
  def adapter(self, mock_hyperlend_client):
19
- """Create a HyperlendAdapter instance with mocked client for testing"""
20
16
  adapter = HyperlendAdapter(
21
17
  config={},
22
18
  )
@@ -25,7 +21,6 @@ class TestHyperlendAdapter:
25
21
 
26
22
  @pytest.mark.asyncio
27
23
  async def test_get_stable_markets_success(self, adapter, mock_hyperlend_client):
28
- """Test successful stable markets retrieval"""
29
24
  mock_response = {
30
25
  "markets": {
31
26
  "0x1234...": {
@@ -69,7 +64,6 @@ class TestHyperlendAdapter:
69
64
  async def test_get_stable_markets_minimal_params(
70
65
  self, adapter, mock_hyperlend_client
71
66
  ):
72
- """Test stable markets retrieval with only required chain_id"""
73
67
  mock_response = {
74
68
  "markets": {
75
69
  "0x1234...": {
@@ -100,7 +94,6 @@ class TestHyperlendAdapter:
100
94
  async def test_get_stable_markets_partial_params(
101
95
  self, adapter, mock_hyperlend_client
102
96
  ):
103
- """Test stable markets retrieval with partial optional parameters"""
104
97
  mock_response = {"markets": {}, "notes": []}
105
98
  mock_hyperlend_client.get_stable_markets = AsyncMock(return_value=mock_response)
106
99
 
@@ -118,7 +111,6 @@ class TestHyperlendAdapter:
118
111
 
119
112
  @pytest.mark.asyncio
120
113
  async def test_get_stable_markets_failure(self, adapter, mock_hyperlend_client):
121
- """Test stable markets retrieval failure"""
122
114
  mock_hyperlend_client.get_stable_markets = AsyncMock(
123
115
  side_effect=Exception("API Error: Connection timeout")
124
116
  )
@@ -130,7 +122,6 @@ class TestHyperlendAdapter:
130
122
 
131
123
  @pytest.mark.asyncio
132
124
  async def test_get_stable_markets_http_error(self, adapter, mock_hyperlend_client):
133
- """Test stable markets retrieval with HTTP error"""
134
125
  mock_hyperlend_client.get_stable_markets = AsyncMock(
135
126
  side_effect=Exception("HTTP 404 Not Found")
136
127
  )
@@ -144,7 +135,6 @@ class TestHyperlendAdapter:
144
135
  async def test_get_stable_markets_empty_response(
145
136
  self, adapter, mock_hyperlend_client
146
137
  ):
147
- """Test stable markets retrieval with empty response"""
148
138
  mock_response = {"markets": {}, "notes": []}
149
139
  mock_hyperlend_client.get_stable_markets = AsyncMock(return_value=mock_response)
150
140
 
@@ -155,12 +145,10 @@ class TestHyperlendAdapter:
155
145
  assert len(data.get("markets", {})) == 0
156
146
 
157
147
  def test_adapter_type(self, adapter):
158
- """Test adapter has adapter_type"""
159
148
  assert adapter.adapter_type == "HYPERLEND"
160
149
 
161
150
  @pytest.mark.asyncio
162
151
  async def test_health_check(self, adapter):
163
- """Test adapter health check"""
164
152
  health = await adapter.health_check()
165
153
  assert isinstance(health, dict)
166
154
  assert health.get("status") in {"healthy", "unhealthy", "error"}
@@ -168,7 +156,6 @@ class TestHyperlendAdapter:
168
156
 
169
157
  @pytest.mark.asyncio
170
158
  async def test_connect(self, adapter):
171
- """Test adapter connection"""
172
159
  ok = await adapter.connect()
173
160
  assert isinstance(ok, bool)
174
161
  assert ok is True
@@ -177,7 +164,6 @@ class TestHyperlendAdapter:
177
164
  async def test_get_stable_markets_with_is_stable_symbol(
178
165
  self, adapter, mock_hyperlend_client
179
166
  ):
180
- """Test stable markets retrieval with is_stable_symbol parameter (ignored by API)"""
181
167
  mock_response = {
182
168
  "markets": {
183
169
  "0x1234...": {
@@ -206,7 +192,6 @@ class TestHyperlendAdapter:
206
192
 
207
193
  @pytest.mark.asyncio
208
194
  async def test_get_assets_view_success(self, adapter, mock_hyperlend_client):
209
- """Test successful assets view retrieval"""
210
195
  mock_response = {
211
196
  "block_number": 12345,
212
197
  "user": "0x0c737cB5934afCb5B01965141F865F795B324080",
@@ -271,7 +256,6 @@ class TestHyperlendAdapter:
271
256
 
272
257
  @pytest.mark.asyncio
273
258
  async def test_get_assets_view_failure(self, adapter, mock_hyperlend_client):
274
- """Test assets view retrieval failure"""
275
259
  mock_hyperlend_client.get_assets_view = AsyncMock(
276
260
  side_effect=Exception("API Error: Invalid address")
277
261
  )
@@ -285,7 +269,6 @@ class TestHyperlendAdapter:
285
269
 
286
270
  @pytest.mark.asyncio
287
271
  async def test_get_assets_view_empty_response(self, adapter, mock_hyperlend_client):
288
- """Test assets view retrieval with empty response"""
289
272
  mock_response = {
290
273
  "block_number": 12345,
291
274
  "user": "0x0c737cB5934afCb5B01965141F865F795B324080",