wayfinder-paths 0.1.4__py3-none-any.whl → 0.1.6__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 (61) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +14 -14
  2. wayfinder_paths/__init__.py +4 -3
  3. wayfinder_paths/adapters/balance_adapter/README.md +10 -10
  4. wayfinder_paths/adapters/balance_adapter/adapter.py +10 -9
  5. wayfinder_paths/adapters/balance_adapter/examples.json +1 -1
  6. wayfinder_paths/adapters/brap_adapter/README.md +1 -1
  7. wayfinder_paths/adapters/brap_adapter/adapter.py +28 -21
  8. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +33 -26
  9. wayfinder_paths/adapters/ledger_adapter/README.md +26 -39
  10. wayfinder_paths/adapters/ledger_adapter/adapter.py +78 -75
  11. wayfinder_paths/adapters/ledger_adapter/examples.json +10 -4
  12. wayfinder_paths/adapters/ledger_adapter/manifest.yaml +4 -4
  13. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +31 -26
  14. wayfinder_paths/adapters/pool_adapter/README.md +1 -13
  15. wayfinder_paths/adapters/pool_adapter/adapter.py +12 -19
  16. wayfinder_paths/adapters/token_adapter/adapter.py +8 -4
  17. wayfinder_paths/core/__init__.py +9 -4
  18. wayfinder_paths/core/adapters/BaseAdapter.py +20 -3
  19. wayfinder_paths/core/adapters/models.py +41 -0
  20. wayfinder_paths/core/clients/BRAPClient.py +21 -2
  21. wayfinder_paths/core/clients/ClientManager.py +42 -63
  22. wayfinder_paths/core/clients/HyperlendClient.py +46 -5
  23. wayfinder_paths/core/clients/LedgerClient.py +350 -124
  24. wayfinder_paths/core/clients/PoolClient.py +51 -19
  25. wayfinder_paths/core/clients/SimulationClient.py +16 -4
  26. wayfinder_paths/core/clients/TokenClient.py +34 -18
  27. wayfinder_paths/core/clients/TransactionClient.py +18 -2
  28. wayfinder_paths/core/clients/WalletClient.py +35 -4
  29. wayfinder_paths/core/clients/WayfinderClient.py +16 -5
  30. wayfinder_paths/core/clients/protocols.py +69 -62
  31. wayfinder_paths/core/clients/sdk_example.py +0 -5
  32. wayfinder_paths/core/config.py +192 -103
  33. wayfinder_paths/core/constants/base.py +17 -0
  34. wayfinder_paths/core/engine/{VaultJob.py → StrategyJob.py} +25 -19
  35. wayfinder_paths/core/engine/__init__.py +2 -2
  36. wayfinder_paths/core/services/base.py +6 -4
  37. wayfinder_paths/core/services/local_evm_txn.py +3 -2
  38. wayfinder_paths/core/settings.py +2 -2
  39. wayfinder_paths/core/strategies/Strategy.py +135 -38
  40. wayfinder_paths/core/strategies/descriptors.py +1 -0
  41. wayfinder_paths/core/utils/evm_helpers.py +12 -10
  42. wayfinder_paths/core/wallets/README.md +3 -3
  43. wayfinder_paths/core/wallets/WalletManager.py +3 -3
  44. wayfinder_paths/run_strategy.py +26 -24
  45. wayfinder_paths/scripts/make_wallets.py +6 -6
  46. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +6 -6
  47. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +36 -156
  48. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +6 -6
  49. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +11 -11
  50. wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml +1 -1
  51. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +92 -92
  52. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +6 -6
  53. wayfinder_paths/templates/adapter/README.md +1 -1
  54. wayfinder_paths/templates/adapter/test_adapter.py +1 -1
  55. wayfinder_paths/templates/strategy/README.md +4 -4
  56. wayfinder_paths/templates/strategy/test_strategy.py +7 -7
  57. wayfinder_paths/tests/test_test_coverage.py +5 -5
  58. {wayfinder_paths-0.1.4.dist-info → wayfinder_paths-0.1.6.dist-info}/METADATA +46 -47
  59. {wayfinder_paths-0.1.4.dist-info → wayfinder_paths-0.1.6.dist-info}/RECORD +61 -60
  60. {wayfinder_paths-0.1.4.dist-info → wayfinder_paths-0.1.6.dist-info}/LICENSE +0 -0
  61. {wayfinder_paths-0.1.4.dist-info → wayfinder_paths-0.1.6.dist-info}/WHEEL +0 -0
@@ -1,6 +1,6 @@
1
1
  # Configuration Guide
2
2
 
3
- This guide explains how to configure your vault strategies for local testing.
3
+ This guide explains how to configure your strategies for local testing.
4
4
 
5
5
  ## Quick Setup
6
6
 
@@ -64,7 +64,7 @@ cp wayfinder_paths/config.example.json config.json
64
64
 
65
65
  **Other Optional fields:**
66
66
  - `user.main_wallet_address` - Override auto-loaded main wallet
67
- - `user.vault_wallet_address` - Override auto-loaded vault wallet
67
+ - `user.strategy_wallet_address` - Override auto-loaded strategy wallet
68
68
 
69
69
  **Security Note:** Never commit `config.json` to version control. Add it to `.gitignore`.
70
70
 
@@ -74,7 +74,7 @@ These are managed automatically by Wayfinder:
74
74
  - `api_base_url` - Wayfinder backend API endpoint
75
75
  - `wallets_path` - Location of generated wallets.json
76
76
  - `job_id` - Auto-generated by Wayfinder
77
- - `job_type` - Set to "vault"
77
+ - `job_type` - Set to "strategy"
78
78
 
79
79
  ## Strategy Configuration
80
80
 
@@ -125,8 +125,8 @@ Each strategy should have its own dedicated wallet for isolation and security. T
125
125
  When you run a strategy:
126
126
  1. The system uses the strategy directory name (e.g., `hyperlend_stable_yield_strategy`) to look up a wallet
127
127
  2. It searches `wallets.json` for a wallet with a matching `label`
128
- 3. If found, that wallet is used as the strategy's `vault_wallet`
129
- 4. Falls back to `vault_wallet_address` from config if explicitly provided
128
+ 3. If found, that wallet is used as the strategy's dedicated wallet
129
+ 4. Falls back to `strategy_wallet_address` from config if explicitly provided
130
130
 
131
131
  ### Creating a Strategy with Wallet
132
132
 
@@ -188,11 +188,11 @@ Strategies access wallets the same way as before:
188
188
 
189
189
  ```python
190
190
  # In strategy code
191
- vault_address = self.config.get("vault_wallet").get("address")
191
+ strategy_address = self.config.get("strategy_wallet").get("address")
192
192
  main_address = self.config.get("main_wallet").get("address")
193
193
  ```
194
194
 
195
- The `vault_wallet` is automatically populated from the wallet with label matching the strategy directory name.
195
+ The strategy wallet is automatically populated from the wallet with label matching the strategy directory name.
196
196
 
197
197
  ## Loading Configuration
198
198
 
@@ -206,14 +206,14 @@ For programmatic use:
206
206
 
207
207
  ```python
208
208
  from pathlib import Path
209
- from core.config import VaultConfig
209
+ from core.config import StrategyJobConfig
210
210
  import json
211
211
 
212
212
  # Load from file
213
213
  with open("config.json") as f:
214
214
  config_data = json.load(f)
215
215
 
216
- config = VaultConfig.from_dict(config_data)
216
+ config = StrategyJobConfig.from_dict(config_data)
217
217
 
218
218
  # Configuration now has:
219
219
  # - config.user.username & password (for Wayfinder backend)
@@ -223,13 +223,13 @@ config = VaultConfig.from_dict(config_data)
223
223
 
224
224
  ## Wallet Abstraction
225
225
 
226
- The vault system supports multiple wallet types through a wallet abstraction layer. By default, adapters use local private keys (self-custodial wallets), but you can inject custom wallet providers for custodial wallets like Privy or Turnkey.
226
+ The strategy system supports multiple wallet types through a wallet abstraction layer. By default, adapters use local private keys (self-custodial wallets), but you can inject custom wallet providers for custodial wallets like Privy or Turnkey.
227
227
 
228
228
  ### Default Behavior (Local Wallets)
229
229
 
230
230
  By default, adapters use `LocalWalletProvider` which resolves private keys from:
231
231
  - `wallets.json` (matched by address)
232
- - Environment variables (`PRIVATE_KEY`, `PRIVATE_KEY_VAULT`)
232
+ - Environment variables (`PRIVATE_KEY`, `PRIVATE_KEY_STRATEGY`)
233
233
  - Wallet config in `config.json`
234
234
 
235
235
  No code changes are required - existing strategies continue to work.
@@ -264,7 +264,7 @@ See `core/wallets/README.md` for details on implementing custom wallet providers
264
264
 
265
265
  ## Authentication with Wayfinder Backend
266
266
 
267
- Wayfinder Vaults supports **dual authentication** for different use cases:
267
+ Wayfinder Paths supports **dual authentication** for different use cases:
268
268
 
269
269
  ### 1. Service Account Authentication (API Key)
270
270
 
@@ -318,7 +318,7 @@ export WAYFINDER_API_KEY="sk_live_abc123..."
318
318
  The `username` and `password` in your config authenticate with the Wayfinder backend to access:
319
319
  - Wallet management
320
320
  - Transaction signing services
321
- - Vault execution services
321
+ - Strategy execution services
322
322
 
323
323
  ```json
324
324
  {
@@ -343,7 +343,7 @@ The `username` and `password` in your config authenticate with the Wayfinder bac
343
343
 
344
344
  ## Configuration in Strategies
345
345
 
346
- Strategies receive configuration automatically through VaultJob:
346
+ Strategies receive configuration automatically through StrategyJob:
347
347
 
348
348
  ```python
349
349
  from core.strategies.Strategy import Strategy
@@ -1,14 +1,15 @@
1
- """Wayfinder Path - Trading strategies and adapters for automated vault management"""
1
+ """Wayfinder Path - Trading strategies and adapters for automated strategy management"""
2
2
 
3
3
  __version__ = "0.1.0"
4
4
 
5
5
  # Re-export commonly used items for convenience
6
6
  from wayfinder_paths.core import (
7
7
  BaseAdapter,
8
+ LiquidationResult,
8
9
  StatusDict,
9
10
  StatusTuple,
10
11
  Strategy,
11
- VaultJob,
12
+ StrategyJob,
12
13
  )
13
14
 
14
15
  __all__ = [
@@ -17,5 +18,5 @@ __all__ = [
17
18
  "Strategy",
18
19
  "StatusDict",
19
20
  "StatusTuple",
20
- "VaultJob",
21
+ "StrategyJob",
21
22
  ]
@@ -1,6 +1,6 @@
1
1
  # Balance Adapter
2
2
 
3
- Adapter that exposes wallet, token, and pool balances backed by `WalletClient`/`TokenClient` and now orchestrates transfers between the configured main/vault wallets (with ledger bookkeeping).
3
+ Adapter that exposes wallet, token, and pool balances backed by `WalletClient`/`TokenClient` and now orchestrates transfers between the configured main/strategy wallets (with ledger bookkeeping).
4
4
 
5
5
  - Entrypoint: `adapters.balance_adapter.adapter.BalanceAdapter`
6
6
  - Manifest: `manifest.yaml`
@@ -41,7 +41,7 @@ Fetches the amount supplied to a specific pool, using the `/wallets/pool-balance
41
41
  success, amount = await balance.get_pool_balance(
42
42
  pool_address="0xPool",
43
43
  chain_id=8453,
44
- user_address=config["vault_wallet"]["address"],
44
+ user_address=config["strategy_wallet"]["address"],
45
45
  )
46
46
  ```
47
47
 
@@ -50,27 +50,27 @@ Returns the enriched token balance payload Wayfinder exposes (including USD valu
50
50
 
51
51
  ```python
52
52
  success, snapshot = await balance.get_all_balances(
53
- wallet_address=config["vault_wallet"]["address"],
53
+ wallet_address=config["strategy_wallet"]["address"],
54
54
  enrich=True,
55
55
  )
56
56
  ```
57
57
 
58
- ### `move_from_main_wallet_to_vault_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
59
- Sends the specified token from the configured `main_wallet` to the `vault_wallet`, records the ledger deposit (unless `skip_ledger=True`), and returns the `(success, tx_result)` tuple from the underlying send helper.
58
+ ### `move_from_main_wallet_to_strategy_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
59
+ Sends the specified token from the configured `main_wallet` to the strategy wallet, records the ledger deposit (unless `skip_ledger=True`), and returns the `(success, tx_result)` tuple from the underlying send helper.
60
60
 
61
61
  ```python
62
- success, tx = await balance.move_from_main_wallet_to_vault_wallet(
62
+ success, tx = await balance.move_from_main_wallet_to_strategy_wallet(
63
63
  token_id="usd-coin-base",
64
64
  amount=1.5,
65
65
  strategy_name="MyStrategy",
66
66
  )
67
67
  ```
68
68
 
69
- ### `move_from_vault_wallet_to_main_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
70
- Mirrors the previous method but withdraws from the vault wallet back to the main wallet while recording a ledger withdrawal entry.
69
+ ### `move_from_strategy_wallet_to_main_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
70
+ Mirrors the previous method but withdraws from the strategy wallet back to the main wallet while recording a ledger withdrawal entry.
71
71
 
72
72
  ```python
73
- await balance.move_from_vault_wallet_to_main_wallet(
73
+ await balance.move_from_strategy_wallet_to_main_wallet(
74
74
  token_id="usd-coin-base",
75
75
  amount=0.75,
76
76
  strategy_name="MyStrategy",
@@ -94,7 +94,7 @@ class MyStrategy(Strategy):
94
94
  success, pool_balance = await self.balance_adapter.get_pool_balance(
95
95
  pool_address=self.current_pool["address"],
96
96
  chain_id=self.current_pool["chain"]["id"],
97
- user_address=self.config["vault_wallet"]["address"],
97
+ user_address=self.config["strategy_wallet"]["address"],
98
98
  )
99
99
  return {"portfolio_value": float(pool_balance or 0), ...}
100
100
  ```
@@ -5,6 +5,7 @@ from wayfinder_paths.adapters.token_adapter.adapter import TokenAdapter
5
5
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
6
6
  from wayfinder_paths.core.clients.TokenClient import TokenClient
7
7
  from wayfinder_paths.core.clients.WalletClient import WalletClient
8
+ from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
8
9
  from wayfinder_paths.core.services.base import Web3Service
9
10
  from wayfinder_paths.core.settings import settings
10
11
  from wayfinder_paths.core.utils.evm_helpers import resolve_chain_id
@@ -44,7 +45,7 @@ class BalanceAdapter(BaseAdapter):
44
45
  *,
45
46
  token_id: str,
46
47
  wallet_address: str,
47
- ) -> tuple[bool, Any]:
48
+ ) -> tuple[bool, str | int]:
48
49
  """Get token balance for a wallet."""
49
50
  try:
50
51
  data = await self.wallet_client.get_token_balance_for_wallet(
@@ -55,37 +56,37 @@ class BalanceAdapter(BaseAdapter):
55
56
  except Exception as e:
56
57
  return (False, str(e))
57
58
 
58
- async def move_from_main_wallet_to_vault_wallet(
59
+ async def move_from_main_wallet_to_strategy_wallet(
59
60
  self,
60
61
  token_id: str,
61
62
  amount: float,
62
63
  strategy_name: str = "unknown",
63
64
  skip_ledger: bool = False,
64
65
  ) -> tuple[bool, Any]:
65
- """Move funds from the configured main wallet into the vault wallet."""
66
+ """Move funds from the configured main wallet into the strategy wallet."""
66
67
  return await self._move_between_wallets(
67
68
  token_id=token_id,
68
69
  amount=amount,
69
70
  from_wallet=self.config.get("main_wallet"),
70
- to_wallet=self.config.get("vault_wallet"),
71
+ to_wallet=self.config.get("strategy_wallet"),
71
72
  ledger_method=self.ledger_adapter.record_deposit,
72
73
  ledger_wallet="to",
73
74
  strategy_name=strategy_name,
74
75
  skip_ledger=skip_ledger,
75
76
  )
76
77
 
77
- async def move_from_vault_wallet_to_main_wallet(
78
+ async def move_from_strategy_wallet_to_main_wallet(
78
79
  self,
79
80
  token_id: str,
80
81
  amount: float,
81
82
  strategy_name: str = "unknown",
82
83
  skip_ledger: bool = False,
83
84
  ) -> tuple[bool, Any]:
84
- """Move funds from the vault wallet back into the main wallet."""
85
+ """Move funds from the strategy wallet back into the main wallet."""
85
86
  return await self._move_between_wallets(
86
87
  token_id=token_id,
87
88
  amount=amount,
88
- from_wallet=self.config.get("vault_wallet"),
89
+ from_wallet=self.config.get("strategy_wallet"),
89
90
  to_wallet=self.config.get("main_wallet"),
90
91
  ledger_method=self.ledger_adapter.record_withdrawal,
91
92
  ledger_wallet="from",
@@ -111,7 +112,7 @@ class BalanceAdapter(BaseAdapter):
111
112
  from_address = self._wallet_address(from_wallet)
112
113
  to_address = self._wallet_address(to_wallet)
113
114
  if not from_address or not to_address:
114
- return False, "main_wallet or vault_wallet missing"
115
+ return False, "main_wallet or strategy_wallet missing"
115
116
 
116
117
  token_info = await self.token_client.get_token_details(token_id)
117
118
  if not token_info:
@@ -132,7 +133,7 @@ class BalanceAdapter(BaseAdapter):
132
133
  broadcast_result = (True, {"dry_run": True, "transaction": tx})
133
134
  else:
134
135
  broadcast_result = await self.wallet_provider.broadcast_transaction(
135
- tx, wait_for_receipt=True, timeout=120
136
+ tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
136
137
  )
137
138
 
138
139
  if broadcast_result[0] and not skip_ledger and ledger_method is not None:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "smoke": {
3
- "get_balance": {"asset": "base_0x0000000000000000000000000000000000000000", "wallet_type": "vault"}
3
+ "get_balance": {"asset": "base_0x0000000000000000000000000000000000000000", "wallet_type": "strategy"}
4
4
  }
5
5
  }
6
6
 
@@ -240,7 +240,7 @@ All methods return a tuple of `(success: bool, data: Any)` where:
240
240
  Run the adapter tests:
241
241
 
242
242
  ```bash
243
- pytest wayfinder_paths/vaults/adapters/brap_adapter/test_adapter.py -v
243
+ pytest wayfinder_paths/adapters/brap_adapter/test_adapter.py -v
244
244
  ```
245
245
 
246
246
  ## Dependencies
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from typing import Any
2
4
 
3
5
  from eth_utils import to_checksum_address
@@ -5,10 +7,16 @@ from eth_utils import to_checksum_address
5
7
  from wayfinder_paths.adapters.ledger_adapter.adapter import LedgerAdapter
6
8
  from wayfinder_paths.adapters.token_adapter.adapter import TokenAdapter
7
9
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
8
- from wayfinder_paths.core.clients.BRAPClient import BRAPClient
9
- from wayfinder_paths.core.clients.SimulationClient import SimulationClient
10
+ from wayfinder_paths.core.adapters.models import SWAP
11
+ from wayfinder_paths.core.clients.BRAPClient import BRAPClient, BRAPQuote
12
+ from wayfinder_paths.core.clients.LedgerClient import TransactionRecord
13
+ from wayfinder_paths.core.clients.SimulationClient import (
14
+ SimulationClient,
15
+ SimulationResult,
16
+ )
10
17
  from wayfinder_paths.core.clients.TokenClient import TokenClient
11
18
  from wayfinder_paths.core.constants import DEFAULT_SLIPPAGE
19
+ from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
12
20
  from wayfinder_paths.core.services.base import Web3Service
13
21
  from wayfinder_paths.core.settings import settings
14
22
 
@@ -61,7 +69,7 @@ class BRAPAdapter(BaseAdapter):
61
69
  amount: str,
62
70
  slippage: float | None = None,
63
71
  wayfinder_fee: float | None = None,
64
- ) -> tuple[bool, Any]:
72
+ ) -> tuple[bool, BRAPQuote | str]:
65
73
  """
66
74
  Get a quote for a cross-chain swap operation.
67
75
 
@@ -107,7 +115,7 @@ class BRAPAdapter(BaseAdapter):
107
115
  amount: str,
108
116
  slippage: float | None = None,
109
117
  wayfinder_fee: float | None = None,
110
- ) -> tuple[bool, Any]:
118
+ ) -> tuple[bool, dict[str, Any] | str]:
111
119
  """
112
120
  Get the best available quote for a swap operation.
113
121
 
@@ -597,7 +605,7 @@ class BRAPAdapter(BaseAdapter):
597
605
  return await self.wallet_provider.broadcast_transaction(
598
606
  transaction,
599
607
  wait_for_receipt=True,
600
- timeout=120,
608
+ timeout=DEFAULT_TRANSACTION_TIMEOUT,
601
609
  )
602
610
 
603
611
  async def _record_swap_operation(
@@ -608,7 +616,7 @@ class BRAPAdapter(BaseAdapter):
608
616
  quote: dict[str, Any],
609
617
  broadcast_response: dict[str, Any] | Any,
610
618
  strategy_name: str | None = None,
611
- ) -> Any:
619
+ ) -> TransactionRecord | dict[str, Any]:
612
620
  from_amount_usd = quote.get("from_amount_usd")
613
621
  if from_amount_usd is None:
614
622
  from_amount_usd = await self._token_amount_usd(
@@ -622,23 +630,22 @@ class BRAPAdapter(BaseAdapter):
622
630
  )
623
631
 
624
632
  response = broadcast_response if isinstance(broadcast_response, dict) else {}
625
- operation_payload = {
626
- "type": "SWAP",
627
- "from_token_id": from_token.get("id"),
628
- "to_token_id": to_token.get("id"),
629
- "from_amount": quote.get("input_amount"),
630
- "to_amount": quote.get("output_amount"),
631
- "from_amount_usd": from_amount_usd or 0,
632
- "to_amount_usd": to_amount_usd or 0,
633
- "transaction_hash": response.get("transaction_hash"),
634
- "transaction_status": response.get("transaction_status"),
635
- "transaction_receipt": response.get("transaction_receipt"),
636
- }
633
+ operation_data = SWAP(
634
+ from_token_id=from_token.get("id"),
635
+ to_token_id=to_token.get("id"),
636
+ from_amount=quote.get("input_amount"),
637
+ to_amount=quote.get("output_amount"),
638
+ from_amount_usd=from_amount_usd or 0,
639
+ to_amount_usd=to_amount_usd or 0,
640
+ transaction_hash=response.get("transaction_hash"),
641
+ transaction_status=response.get("transaction_status"),
642
+ transaction_receipt=response.get("transaction_receipt"),
643
+ )
637
644
 
638
645
  try:
639
646
  success, ledger_response = await self.ledger_adapter.record_operation(
640
647
  wallet_address=wallet_address,
641
- operation_data=operation_payload,
648
+ operation_data=operation_data,
642
649
  usd_value=from_amount_usd or 0,
643
650
  strategy_name=strategy_name,
644
651
  )
@@ -650,7 +657,7 @@ class BRAPAdapter(BaseAdapter):
650
657
  except Exception as exc: # noqa: BLE001
651
658
  self.logger.warning(f"Ledger swap record raised: {exc}", quote=quote)
652
659
 
653
- return operation_payload
660
+ return operation_data.model_dump(mode="json")
654
661
 
655
662
  async def _token_amount_usd(
656
663
  self, token_info: dict[str, Any], raw_amount: Any
@@ -676,7 +683,7 @@ class BRAPAdapter(BaseAdapter):
676
683
  from_address: str,
677
684
  chain_id: int,
678
685
  quote: dict[str, Any],
679
- ) -> Any:
686
+ ) -> SimulationResult:
680
687
  client = await self._get_simulation_client()
681
688
  initial_balances = {"native": "5000000000000000000"}
682
689
  if from_token.get("address"):
@@ -5,8 +5,15 @@ from typing import Any
5
5
  from eth_utils import to_checksum_address
6
6
 
7
7
  from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
8
- from wayfinder_paths.core.clients.HyperlendClient import HyperlendClient
8
+ from wayfinder_paths.core.clients.HyperlendClient import (
9
+ AssetsView,
10
+ HyperlendClient,
11
+ LendRateHistory,
12
+ MarketEntry,
13
+ StableMarket,
14
+ )
9
15
  from wayfinder_paths.core.clients.SimulationClient import SimulationClient
16
+ from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
10
17
  from wayfinder_paths.core.constants.hyperlend_abi import (
11
18
  POOL_ABI,
12
19
  WRAPPED_TOKEN_GATEWAY_ABI,
@@ -43,7 +50,7 @@ class HyperlendAdapter(BaseAdapter):
43
50
  self.web3 = web3_service
44
51
  self.token_txn_service = web3_service.token_transactions
45
52
 
46
- self.vault_wallet = cfg.get("vault_wallet") or {}
53
+ self.strategy_wallet = cfg.get("strategy_wallet") or {}
47
54
  self.pool_address = self._checksum(
48
55
  adapter_cfg.get("pool_address") or HYPERLEND_DEFAULTS["pool"]
49
56
  )
@@ -70,7 +77,7 @@ class HyperlendAdapter(BaseAdapter):
70
77
  buffer_bps: int | None = None,
71
78
  min_buffer_tokens: float | None = None,
72
79
  is_stable_symbol: bool | None = None,
73
- ) -> tuple[bool, Any]:
80
+ ) -> tuple[bool, list[StableMarket] | str]:
74
81
  try:
75
82
  data = await self.hyperlend_client.get_stable_markets(
76
83
  chain_id=chain_id,
@@ -85,7 +92,7 @@ class HyperlendAdapter(BaseAdapter):
85
92
 
86
93
  async def get_assets_view(
87
94
  self, chain_id: int, user_address: str
88
- ) -> tuple[bool, Any]:
95
+ ) -> tuple[bool, AssetsView | str]:
89
96
  try:
90
97
  data = await self.hyperlend_client.get_assets_view(
91
98
  chain_id=chain_id, user_address=user_address
@@ -96,7 +103,7 @@ class HyperlendAdapter(BaseAdapter):
96
103
 
97
104
  async def get_market_entry(
98
105
  self, chain_id: int, underlying: str
99
- ) -> tuple[bool, Any]:
106
+ ) -> tuple[bool, MarketEntry | str]:
100
107
  try:
101
108
  data = await self.hyperlend_client.get_market_entry(chain_id, underlying)
102
109
  return True, data
@@ -108,7 +115,7 @@ class HyperlendAdapter(BaseAdapter):
108
115
  chain_id: int,
109
116
  token_address: str,
110
117
  lookback_hours: int,
111
- ) -> tuple[bool, Any]:
118
+ ) -> tuple[bool, LendRateHistory | str]:
112
119
  try:
113
120
  data = await self.hyperlend_client.get_lend_rate_history(
114
121
  chain_id=chain_id,
@@ -127,7 +134,7 @@ class HyperlendAdapter(BaseAdapter):
127
134
  chain_id: int,
128
135
  native: bool = False,
129
136
  ) -> tuple[bool, Any]:
130
- vault = self._vault_address()
137
+ strategy = self._strategy_address()
131
138
  qty = int(qty)
132
139
  if qty <= 0:
133
140
  return False, "qty must be positive"
@@ -138,8 +145,8 @@ class HyperlendAdapter(BaseAdapter):
138
145
  target=self.gateway_address,
139
146
  abi=WRAPPED_TOKEN_GATEWAY_ABI,
140
147
  fn_name="depositETH",
141
- args=[self._gateway_first_arg(underlying_token), vault, 0],
142
- from_address=vault,
148
+ args=[self._gateway_first_arg(underlying_token), strategy, 0],
149
+ from_address=strategy,
143
150
  chain_id=chain_id,
144
151
  value=qty,
145
152
  )
@@ -147,7 +154,7 @@ class HyperlendAdapter(BaseAdapter):
147
154
  token_addr = self._checksum(underlying_token)
148
155
  approved = await self._ensure_allowance(
149
156
  token_address=token_addr,
150
- owner=vault,
157
+ owner=strategy,
151
158
  spender=self.pool_address,
152
159
  amount=qty,
153
160
  chain_id=chain_id,
@@ -158,8 +165,8 @@ class HyperlendAdapter(BaseAdapter):
158
165
  target=self.pool_address,
159
166
  abi=POOL_ABI,
160
167
  fn_name="supply",
161
- args=[token_addr, qty, vault, 0],
162
- from_address=vault,
168
+ args=[token_addr, qty, strategy, 0],
169
+ from_address=strategy,
163
170
  chain_id=chain_id,
164
171
  )
165
172
  return await self._execute(tx)
@@ -172,7 +179,7 @@ class HyperlendAdapter(BaseAdapter):
172
179
  chain_id: int,
173
180
  native: bool = False,
174
181
  ) -> tuple[bool, Any]:
175
- vault = self._vault_address()
182
+ strategy = self._strategy_address()
176
183
  qty = int(qty)
177
184
  if qty <= 0:
178
185
  return False, "qty must be positive"
@@ -183,8 +190,8 @@ class HyperlendAdapter(BaseAdapter):
183
190
  target=self.gateway_address,
184
191
  abi=WRAPPED_TOKEN_GATEWAY_ABI,
185
192
  fn_name="withdrawETH",
186
- args=[self._gateway_first_arg(underlying_token), qty, vault],
187
- from_address=vault,
193
+ args=[self._gateway_first_arg(underlying_token), qty, strategy],
194
+ from_address=strategy,
188
195
  chain_id=chain_id,
189
196
  )
190
197
  else:
@@ -193,8 +200,8 @@ class HyperlendAdapter(BaseAdapter):
193
200
  target=self.pool_address,
194
201
  abi=POOL_ABI,
195
202
  fn_name="withdraw",
196
- args=[token_addr, qty, vault],
197
- from_address=vault,
203
+ args=[token_addr, qty, strategy],
204
+ from_address=strategy,
198
205
  chain_id=chain_id,
199
206
  )
200
207
  return await self._execute(tx)
@@ -233,14 +240,14 @@ class HyperlendAdapter(BaseAdapter):
233
240
  if self.simulation:
234
241
  return True, {"simulation": tx}
235
242
  return await self.web3.broadcast_transaction(
236
- tx, wait_for_receipt=True, timeout=120
243
+ tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
237
244
  )
238
245
 
239
246
  async def _broadcast_transaction(self, tx: dict[str, Any]) -> tuple[bool, Any]:
240
247
  if getattr(settings, "DRY_RUN", False):
241
248
  return True, {"dry_run": True, "transaction": tx}
242
249
  return await self.web3.evm_transactions.broadcast_transaction(
243
- tx, wait_for_receipt=True, timeout=120
250
+ tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
244
251
  )
245
252
 
246
253
  def _encode_call(
@@ -273,17 +280,17 @@ class HyperlendAdapter(BaseAdapter):
273
280
  }
274
281
  return tx
275
282
 
276
- def _vault_address(self) -> str:
283
+ def _strategy_address(self) -> str:
277
284
  addr = None
278
- if isinstance(self.vault_wallet, dict):
279
- addr = self.vault_wallet.get("address") or (
280
- (self.vault_wallet.get("evm") or {}).get("address")
285
+ if isinstance(self.strategy_wallet, dict):
286
+ addr = self.strategy_wallet.get("address") or (
287
+ (self.strategy_wallet.get("evm") or {}).get("address")
281
288
  )
282
- elif isinstance(self.vault_wallet, str):
283
- addr = self.vault_wallet
289
+ elif isinstance(self.strategy_wallet, str):
290
+ addr = self.strategy_wallet
284
291
  if not addr:
285
292
  raise ValueError(
286
- "vault_wallet address is required for HyperLend operations"
293
+ "strategy_wallet address is required for HyperLend operations"
287
294
  )
288
295
  return to_checksum_address(addr)
289
296