wayfinder-paths 0.1.8__py3-none-any.whl → 0.1.10__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 (80) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +6 -15
  2. wayfinder_paths/adapters/balance_adapter/README.md +1 -2
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +4 -4
  4. wayfinder_paths/adapters/brap_adapter/README.md +1 -1
  5. wayfinder_paths/adapters/brap_adapter/adapter.py +139 -74
  6. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +0 -7
  7. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +0 -54
  8. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +1 -1
  9. wayfinder_paths/adapters/ledger_adapter/README.md +1 -1
  10. wayfinder_paths/adapters/moonwell_adapter/README.md +174 -0
  11. wayfinder_paths/adapters/moonwell_adapter/__init__.py +7 -0
  12. wayfinder_paths/adapters/moonwell_adapter/adapter.py +1226 -0
  13. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +635 -0
  14. wayfinder_paths/adapters/pool_adapter/README.md +1 -77
  15. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -122
  16. wayfinder_paths/adapters/pool_adapter/examples.json +0 -57
  17. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -86
  18. wayfinder_paths/adapters/token_adapter/README.md +1 -1
  19. wayfinder_paths/core/clients/ClientManager.py +1 -22
  20. wayfinder_paths/core/clients/WalletClient.py +0 -8
  21. wayfinder_paths/core/clients/WayfinderClient.py +7 -12
  22. wayfinder_paths/core/clients/__init__.py +0 -8
  23. wayfinder_paths/core/clients/protocols.py +0 -60
  24. wayfinder_paths/core/config.py +5 -45
  25. wayfinder_paths/core/constants/__init__.py +0 -2
  26. wayfinder_paths/core/constants/base.py +6 -2
  27. wayfinder_paths/core/constants/moonwell_abi.py +411 -0
  28. wayfinder_paths/core/services/base.py +7 -1
  29. wayfinder_paths/core/services/local_evm_txn.py +223 -222
  30. wayfinder_paths/core/services/local_token_txn.py +103 -92
  31. wayfinder_paths/core/services/web3_service.py +0 -2
  32. wayfinder_paths/core/settings.py +8 -8
  33. wayfinder_paths/core/strategies/Strategy.py +1 -5
  34. wayfinder_paths/core/strategies/descriptors.py +1 -1
  35. wayfinder_paths/core/utils/evm_helpers.py +7 -12
  36. wayfinder_paths/core/wallets/README.md +3 -6
  37. wayfinder_paths/run_strategy.py +62 -105
  38. wayfinder_paths/scripts/create_strategy.py +2 -27
  39. wayfinder_paths/scripts/make_wallets.py +1 -25
  40. wayfinder_paths/scripts/run_strategy.py +37 -9
  41. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -3
  42. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +87 -138
  43. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +96 -58
  44. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -17
  45. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +4 -1
  46. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +107 -29
  47. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +53 -14
  48. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +108 -0
  49. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +11 -0
  50. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2975 -0
  51. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +886 -0
  52. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -7
  53. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +2 -7
  54. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -4
  55. wayfinder_paths/templates/adapter/README.md +5 -21
  56. wayfinder_paths/templates/adapter/adapter.py +1 -2
  57. wayfinder_paths/templates/adapter/test_adapter.py +1 -1
  58. wayfinder_paths/templates/strategy/README.md +4 -21
  59. wayfinder_paths/templates/strategy/test_strategy.py +0 -4
  60. wayfinder_paths/tests/test_smoke_manifest.py +17 -2
  61. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/METADATA +64 -201
  62. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/RECORD +64 -71
  63. wayfinder_paths/adapters/balance_adapter/manifest.yaml +0 -8
  64. wayfinder_paths/adapters/brap_adapter/manifest.yaml +0 -11
  65. wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +0 -10
  66. wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +0 -8
  67. wayfinder_paths/adapters/ledger_adapter/manifest.yaml +0 -11
  68. wayfinder_paths/adapters/pool_adapter/manifest.yaml +0 -10
  69. wayfinder_paths/adapters/token_adapter/manifest.yaml +0 -6
  70. wayfinder_paths/core/clients/SimulationClient.py +0 -192
  71. wayfinder_paths/core/clients/TransactionClient.py +0 -63
  72. wayfinder_paths/core/engine/manifest.py +0 -97
  73. wayfinder_paths/scripts/validate_manifests.py +0 -213
  74. wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml +0 -23
  75. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/manifest.yaml +0 -7
  76. wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml +0 -17
  77. wayfinder_paths/templates/adapter/manifest.yaml +0 -6
  78. wayfinder_paths/templates/strategy/manifest.yaml +0 -8
  79. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/LICENSE +0 -0
  80. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/WHEEL +0 -0
@@ -17,7 +17,7 @@ The adapter uses the PoolClient which automatically handles authentication and A
17
17
  The PoolClient will automatically:
18
18
 
19
19
  - Use the WAYFINDER_API_URL from settings
20
- - Handle authentication via environment variables or config.json
20
+ - Handle authentication via config.json
21
21
  - Manage token refresh and retry logic
22
22
 
23
23
  ## Usage
@@ -45,41 +45,6 @@ else:
45
45
  print(f"Error: {data}")
46
46
  ```
47
47
 
48
- ### Find High Yield Pools
49
-
50
- ```python
51
- success, data = await adapter.find_high_yield_pools(
52
- min_apy=0.03, # 3% minimum APY
53
- min_tvl=500000, # $500k minimum TVL
54
- stablecoin_only=True,
55
- network_codes=["base", "ethereum"]
56
- )
57
- if success:
58
- pools = data.get("pools", [])
59
- print(f"Found {len(pools)} high-yield pools")
60
- for pool in pools:
61
- print(f"Pool: {pool.get('id')} - APY: {pool.get('llama_apy_pct')}%")
62
- else:
63
- print(f"Error: {data}")
64
- ```
65
-
66
- ### Get Pool Analytics
67
-
68
- ```python
69
- success, data = await adapter.get_pool_analytics(
70
- pool_ids=["pool-123", "pool-456"]
71
- )
72
- if success:
73
- analytics = data.get("analytics", [])
74
- for pool_analytics in analytics:
75
- pool = pool_analytics.get("pool", {})
76
- combined_apy = pool_analytics.get("combined_apy", 0)
77
- tvl_usd = pool_analytics.get("tvl_usd", 0)
78
- print(f"Pool: {pool.get('name')} - APY: {combined_apy:.2%} - TVL: ${tvl_usd:,.0f}")
79
- else:
80
- print(f"Error: {data}")
81
- ```
82
-
83
48
  ### Get Llama Matches
84
49
 
85
50
  ```python
@@ -110,47 +75,6 @@ else:
110
75
 
111
76
  ## Advanced Usage
112
77
 
113
- ### Filtering High Yield Pools
114
-
115
- The `find_high_yield_pools` method provides powerful filtering capabilities:
116
-
117
- ```python
118
- # Find stablecoin pools with high yield on specific networks
119
- success, data = await adapter.find_high_yield_pools(
120
- min_apy=0.05, # 5% minimum APY
121
- min_tvl=1000000, # $1M minimum TVL
122
- stablecoin_only=True, # Only stablecoin pools
123
- network_codes=["base", "arbitrum"] # Specific networks
124
- )
125
-
126
- if success:
127
- pools = data.get("pools", [])
128
- # Pools are automatically sorted by APY (highest first)
129
- best_pool = pools[0] if pools else None
130
- if best_pool:
131
- print(f"Best pool: {best_pool.get('id')} - APY: {best_pool.get('llama_apy_pct')}%")
132
- ```
133
-
134
- ### Comprehensive Pool Analysis
135
-
136
- ```python
137
- # Get detailed analytics for specific pools
138
- success, data = await adapter.get_pool_analytics(["pool-123"])
139
-
140
- if success:
141
- analytics = data.get("analytics", [])
142
- for pool_analytics in analytics:
143
- pool = pool_analytics.get("pool", {})
144
- llama_data = pool_analytics.get("llama_data", {})
145
-
146
- print(f"Pool: {pool.get('name')}")
147
- print(f" Combined APY: {pool_analytics.get('combined_apy', 0):.2%}")
148
- print(f" TVL: ${pool_analytics.get('tvl_usd', 0):,.0f}")
149
- print(f" Llama APY: {llama_data.get('llama_apy_pct', 0)}%")
150
- print(f" Stablecoin: {llama_data.get('llama_stablecoin', False)}")
151
- print(f" IL Risk: {llama_data.get('llama_il_risk', 'unknown')}")
152
- ```
153
-
154
78
  ## API Endpoints
155
79
 
156
80
  The adapter uses the following Wayfinder API endpoints:
@@ -86,125 +86,3 @@ class PoolAdapter(BaseAdapter):
86
86
  except Exception as e:
87
87
  self.logger.error(f"Error fetching Llama reports: {e}")
88
88
  return (False, str(e))
89
-
90
- async def find_high_yield_pools(
91
- self,
92
- min_apy: float = 0.01,
93
- min_tvl: float = 1000000,
94
- stablecoin_only: bool = True,
95
- network_codes: list[str] | None = None,
96
- ) -> tuple[bool, Any]:
97
- """
98
- Find high-yield pools based on criteria.
99
-
100
- Args:
101
- min_apy: Minimum APY threshold (as decimal, e.g., 0.01 for 1%)
102
- min_tvl: Minimum TVL threshold in USD
103
- stablecoin_only: Whether to filter for stablecoin pools only
104
- network_codes: List of network codes to filter by
105
-
106
- Returns:
107
- Tuple of (success, data) where data is filtered pools or error message
108
- """
109
- try:
110
- # Get Llama matches for yield data
111
- success, llama_data = await self.get_llama_matches()
112
- if not success:
113
- return (False, f"Failed to fetch Llama data: {llama_data}")
114
-
115
- matches = llama_data.get("matches", [])
116
- filtered_pools = []
117
-
118
- for pool in matches:
119
- # Apply filters
120
- if stablecoin_only and not pool.get("llama_stablecoin", False):
121
- continue
122
-
123
- if pool.get("llama_tvl_usd", 0) < min_tvl:
124
- continue
125
-
126
- if (
127
- pool.get("llama_apy_pct", 0) < min_apy * 100
128
- ): # Convert to percentage
129
- continue
130
-
131
- if network_codes and pool.get("network", "").lower() not in [
132
- nc.lower() for nc in network_codes
133
- ]:
134
- continue
135
-
136
- filtered_pools.append(pool)
137
-
138
- # Sort by APY descending
139
- filtered_pools.sort(key=lambda x: x.get("llama_apy_pct", 0), reverse=True)
140
-
141
- return (
142
- True,
143
- {
144
- "pools": filtered_pools,
145
- "total_found": len(filtered_pools),
146
- "filters_applied": {
147
- "min_apy": min_apy,
148
- "min_tvl": min_tvl,
149
- "stablecoin_only": stablecoin_only,
150
- "network_codes": network_codes,
151
- },
152
- },
153
- )
154
- except Exception as e:
155
- self.logger.error(f"Error finding high yield pools: {e}")
156
- return (False, str(e))
157
-
158
- async def get_pool_analytics(self, pool_ids: list[str]) -> tuple[bool, Any]:
159
- """
160
- Get comprehensive analytics for specific pools.
161
-
162
- Args:
163
- pool_ids: List of pool identifiers
164
-
165
- Returns:
166
- Tuple of (success, data) where data is pool analytics or error message
167
- """
168
- try:
169
- # Get pool data
170
- success, pool_data = await self.get_pools_by_ids(pool_ids)
171
- if not success:
172
- return (False, f"Failed to fetch pool data: {pool_data}")
173
-
174
- # Get Llama reports
175
- success, llama_data = await self.get_llama_reports(pool_ids)
176
- if not success:
177
- self.logger.warning(f"Failed to fetch Llama data: {llama_data}")
178
- llama_data = {}
179
-
180
- pools = pool_data.get("pools", [])
181
- llama_reports = llama_data
182
-
183
- # Combine data
184
- analytics = []
185
- for pool in pools:
186
- pool_id = pool.get("id")
187
- llama_report = llama_reports.get(pool_id.lower()) if pool_id else None
188
-
189
- analytics.append(
190
- {
191
- "pool": pool,
192
- "llama_data": llama_report,
193
- "combined_apy": (
194
- llama_report.get("llama_combined_apy_pct", 0) / 100
195
- if llama_report
196
- and llama_report.get("llama_combined_apy_pct") is not None
197
- else pool.get("apy", 0)
198
- ),
199
- "tvl_usd": (
200
- llama_report.get("llama_tvl_usd", 0)
201
- if llama_report and llama_report.get("llama_tvl_usd")
202
- else pool.get("tvl", 0)
203
- ),
204
- }
205
- )
206
-
207
- return (True, {"analytics": analytics, "total_pools": len(analytics)})
208
- except Exception as e:
209
- self.logger.error(f"Error getting pool analytics: {e}")
210
- return (False, str(e))
@@ -39,62 +39,5 @@
39
39
  ]
40
40
  }
41
41
  }
42
- },
43
- "find_high_yield_pools": {
44
- "description": "Find high-yield pools based on criteria",
45
- "input": {
46
- "min_apy": 0.03,
47
- "min_tvl": 500000,
48
- "stablecoin_only": true,
49
- "network_codes": ["base", "ethereum"]
50
- },
51
- "output": {
52
- "success": true,
53
- "data": {
54
- "pools": [
55
- {
56
- "id": "pool-123",
57
- "llama_apy_pct": 5.2,
58
- "llama_tvl_usd": 1000000,
59
- "llama_stablecoin": true,
60
- "network": "base"
61
- }
62
- ],
63
- "total_found": 1,
64
- "filters_applied": {
65
- "min_apy": 0.03,
66
- "min_tvl": 500000,
67
- "stablecoin_only": true,
68
- "network_codes": ["base", "ethereum"]
69
- }
70
- }
71
- }
72
- },
73
- "get_pool_analytics": {
74
- "description": "Get comprehensive analytics for specific pools",
75
- "input": {
76
- "pool_ids": ["pool-123"]
77
- },
78
- "output": {
79
- "success": true,
80
- "data": {
81
- "analytics": [
82
- {
83
- "pool": {
84
- "id": "pool-123",
85
- "name": "USDC/USDT Pool",
86
- "symbol": "USDC-USDT"
87
- },
88
- "llama_data": {
89
- "llama_apy_pct": 5.2,
90
- "llama_tvl_usd": 1000000
91
- },
92
- "combined_apy": 0.052,
93
- "tvl_usd": 1000000
94
- }
95
- ],
96
- "total_pools": 1
97
- }
98
- }
99
42
  }
100
43
  }
@@ -69,77 +69,6 @@ class TestPoolAdapter:
69
69
  assert success is True
70
70
  assert data == mock_response
71
71
 
72
- @pytest.mark.asyncio
73
- async def test_find_high_yield_pools_success(self, adapter, mock_pool_client):
74
- """Test successful high yield pool discovery"""
75
- mock_llama_response = {
76
- "matches": [
77
- {
78
- "pool_id": "pool-123",
79
- "llama_apy_pct": 5.2,
80
- "llama_tvl_usd": 1000000,
81
- "llama_stablecoin": True,
82
- "network": "base",
83
- },
84
- {
85
- "pool_id": "pool-456",
86
- "llama_apy_pct": 2.0,
87
- "llama_tvl_usd": 500000,
88
- "llama_stablecoin": True,
89
- "network": "ethereum",
90
- },
91
- {
92
- "pool_id": "pool-789",
93
- "llama_apy_pct": 6.0,
94
- "llama_tvl_usd": 2000000,
95
- "llama_stablecoin": False,
96
- "network": "base",
97
- },
98
- ]
99
- }
100
- mock_pool_client.get_llama_matches = AsyncMock(return_value=mock_llama_response)
101
-
102
- success, data = await adapter.find_high_yield_pools(
103
- min_apy=0.03, min_tvl=500000, stablecoin_only=True, network_codes=["base"]
104
- )
105
-
106
- assert success is True
107
- assert len(data["pools"]) == 1 # Only pool-123 meets criteria
108
- assert (
109
- data["pools"][0].get("pool_id") == "pool-123"
110
- or data["pools"][0].get("id") == "pool-123"
111
- )
112
- assert data["total_found"] == 1
113
- assert data["filters_applied"]["min_apy"] == 0.03
114
- assert data["filters_applied"]["stablecoin_only"] is True
115
-
116
- @pytest.mark.asyncio
117
- async def test_get_pool_analytics_success(self, adapter, mock_pool_client):
118
- """Test successful pool analytics generation"""
119
- mock_pool_data = {
120
- "pools": [
121
- {"id": "pool-123", "name": "USDC/USDT Pool", "symbol": "USDC-USDT"}
122
- ]
123
- }
124
- mock_pool_client.get_pools_by_ids = AsyncMock(return_value=mock_pool_data)
125
-
126
- mock_llama_data = {
127
- "pool-123": {
128
- "llama_apy_pct": 5.2,
129
- "llama_combined_apy_pct": 5.2,
130
- "llama_tvl_usd": 1000000,
131
- }
132
- }
133
- mock_pool_client.get_llama_reports = AsyncMock(return_value=mock_llama_data)
134
-
135
- success, data = await adapter.get_pool_analytics(["pool-123"])
136
-
137
- assert success is True
138
- assert len(data["analytics"]) == 1
139
- assert data["analytics"][0]["pool"]["id"] == "pool-123"
140
- assert round(data["analytics"][0]["combined_apy"], 6) == round(0.052, 6)
141
- assert data["analytics"][0]["tvl_usd"] == 1000000
142
-
143
72
  @pytest.mark.asyncio
144
73
  async def test_get_pools_by_ids_failure(self, adapter, mock_pool_client):
145
74
  """Test pool retrieval failure"""
@@ -152,21 +81,6 @@ class TestPoolAdapter:
152
81
  assert success is False
153
82
  assert "API Error" in data
154
83
 
155
- @pytest.mark.asyncio
156
- async def test_find_high_yield_pools_no_matches(self, adapter, mock_pool_client):
157
- """Test high yield pool discovery with no matches"""
158
- mock_llama_response = {"matches": []}
159
- mock_pool_client.get_llama_matches.return_value = mock_llama_response
160
-
161
- success, data = await adapter.find_high_yield_pools(
162
- min_apy=0.10,
163
- min_tvl=10000000,
164
- )
165
-
166
- assert success is True
167
- assert len(data["pools"]) == 0
168
- assert data["total_found"] == 0
169
-
170
84
  def test_adapter_type(self, adapter):
171
85
  """Test adapter has adapter_type"""
172
86
  assert adapter.adapter_type == "POOL"
@@ -12,7 +12,7 @@ The adapter uses the TokenClient which automatically handles authentication and
12
12
 
13
13
  The TokenClient will automatically:
14
14
  - Use the WAYFINDER_API_URL from settings
15
- - Handle authentication via environment variables or config.json
15
+ - Handle authentication via config.json
16
16
  - Manage token refresh and retry logic
17
17
 
18
18
  ## Usage
@@ -15,14 +15,10 @@ from wayfinder_paths.core.clients.protocols import (
15
15
  HyperlendClientProtocol,
16
16
  LedgerClientProtocol,
17
17
  PoolClientProtocol,
18
- SimulationClientProtocol,
19
18
  TokenClientProtocol,
20
- TransactionClientProtocol,
21
19
  WalletClientProtocol,
22
20
  )
23
- from wayfinder_paths.core.clients.SimulationClient import SimulationClient
24
21
  from wayfinder_paths.core.clients.TokenClient import TokenClient
25
- from wayfinder_paths.core.clients.TransactionClient import TransactionClient
26
22
  from wayfinder_paths.core.clients.WalletClient import WalletClient
27
23
 
28
24
 
@@ -32,7 +28,7 @@ class ClientManager:
32
28
 
33
29
  Args:
34
30
  clients: Optional dict of pre-instantiated clients to inject directly.
35
- Keys: 'token', 'hyperlend', 'ledger', 'wallet', 'transaction', 'pool', 'brap', 'simulation'.
31
+ Keys: 'token', 'hyperlend', 'ledger', 'wallet', 'transaction', 'pool', 'brap'.
36
32
  If not provided, defaults to HTTP-based clients.
37
33
  skip_auth: If True, skips authentication (for SDK usage).
38
34
  """
@@ -59,12 +55,10 @@ class ClientManager:
59
55
  self._auth_client: AuthClient | None = None
60
56
  self._token_client: TokenClientProtocol | None = None
61
57
  self._wallet_client: WalletClientProtocol | None = None
62
- self._transaction_client: TransactionClientProtocol | None = None
63
58
  self._ledger_client: LedgerClientProtocol | None = None
64
59
  self._pool_client: PoolClientProtocol | None = None
65
60
  self._hyperlend_client: HyperlendClientProtocol | None = None
66
61
  self._brap_client: BRAPClientProtocol | None = None
67
- self._simulation_client: SimulationClientProtocol | None = None
68
62
 
69
63
  def _get_or_create_client(
70
64
  self,
@@ -109,13 +103,6 @@ class ClientManager:
109
103
  """Get or create token client"""
110
104
  return self._get_or_create_client("_token_client", "token", TokenClient)
111
105
 
112
- @property
113
- def transaction(self) -> TransactionClientProtocol:
114
- """Get or create transaction client"""
115
- return self._get_or_create_client(
116
- "_transaction_client", "transaction", TransactionClient
117
- )
118
-
119
106
  @property
120
107
  def ledger(self) -> LedgerClientProtocol:
121
108
  """Get or create ledger client"""
@@ -143,13 +130,6 @@ class ClientManager:
143
130
  """Get or create BRAP client"""
144
131
  return self._get_or_create_client("_brap_client", "brap", BRAPClient)
145
132
 
146
- @property
147
- def simulation(self) -> SimulationClientProtocol:
148
- """Get or create simulation client"""
149
- return self._get_or_create_client(
150
- "_simulation_client", "simulation", SimulationClient
151
- )
152
-
153
133
  async def authenticate(
154
134
  self,
155
135
  username: str | None = None,
@@ -206,5 +186,4 @@ class ClientManager:
206
186
  "wallet": self._wallet_client,
207
187
  "hyperlend": self._hyperlend_client,
208
188
  "brap": self._brap_client,
209
- "simulation": self._simulation_client,
210
189
  }
@@ -33,14 +33,6 @@ class PoolBalance(TypedDict):
33
33
  usd_value: NotRequired[float | None]
34
34
 
35
35
 
36
- class EnrichedBalances(TypedDict):
37
- """Enriched token balances response structure"""
38
-
39
- wallet_address: Required[str]
40
- balances: Required[list[TokenBalance]]
41
- total_usd_value: NotRequired[float | None]
42
-
43
-
44
36
  class WalletClient(WayfinderClient):
45
37
  def __init__(self, api_key: str | None = None):
46
38
  super().__init__(api_key=api_key)
@@ -121,13 +121,13 @@ class WayfinderClient:
121
121
 
122
122
  async def _ensure_bearer_token(self) -> bool:
123
123
  """
124
- Ensure Authorization header is set. Priority: existing header > constructor api_key > config.json api_key > env api_key > config.json tokens > env tokens > username/password.
124
+ Ensure Authorization header is set. Priority: existing header > constructor api_key > config.json api_key > config.json tokens > username/password.
125
125
  Raises PermissionError if no credentials found.
126
126
  """
127
127
  if self.headers.get("Authorization"):
128
128
  return True
129
129
 
130
- # Check for API key: constructor > config.json > environment
130
+ # Check for API key: constructor > config.json
131
131
  api_key = self._api_key
132
132
  if not api_key:
133
133
  creds = self._load_config_credentials()
@@ -142,12 +142,7 @@ class WayfinderClient:
142
142
 
143
143
  # Fall back to OAuth token-based auth
144
144
  creds = self._load_config_credentials()
145
- access = os.getenv("WAYFINDER_ACCESS_TOKEN")
146
- refresh = creds.get("refresh_token") or os.getenv("WAYFINDER_REFRESH_TOKEN")
147
-
148
- if access:
149
- self.set_tokens(access, refresh)
150
- return True
145
+ refresh = creds.get("refresh_token")
151
146
 
152
147
  if refresh:
153
148
  self._refresh_token = refresh
@@ -155,8 +150,8 @@ class WayfinderClient:
155
150
  if refreshed:
156
151
  return True
157
152
 
158
- username = creds.get("username") or os.getenv("WAYFINDER_USERNAME")
159
- password = creds.get("password") or os.getenv("WAYFINDER_PASSWORD")
153
+ username = creds.get("username")
154
+ password = creds.get("password")
160
155
 
161
156
  if username and password:
162
157
  try:
@@ -178,7 +173,7 @@ class WayfinderClient:
178
173
  pass
179
174
 
180
175
  raise PermissionError(
181
- "Not authenticated: provide api_key (via constructor, config.json, or WAYFINDER_API_KEY env var) for service account auth, "
176
+ "Not authenticated: provide api_key (via constructor or config.json) for service account auth, "
182
177
  "or username+password/refresh_token in config.json for personal access"
183
178
  )
184
179
 
@@ -201,7 +196,7 @@ class WayfinderClient:
201
196
  # Ensure API key or bearer token is set in headers if available and not already set
202
197
  # This ensures API keys are passed to all endpoints (including public ones) for rate limiting
203
198
  if not self.headers.get("Authorization"):
204
- # Try to get API key from constructor, config, or env
199
+ # Try to get API key from constructor or config
205
200
  api_key = self._api_key
206
201
  if not api_key:
207
202
  creds = self._load_config_credentials()
@@ -13,14 +13,10 @@ from wayfinder_paths.core.clients.protocols import (
13
13
  HyperlendClientProtocol,
14
14
  LedgerClientProtocol,
15
15
  PoolClientProtocol,
16
- SimulationClientProtocol,
17
16
  TokenClientProtocol,
18
- TransactionClientProtocol,
19
17
  WalletClientProtocol,
20
18
  )
21
- from wayfinder_paths.core.clients.SimulationClient import SimulationClient
22
19
  from wayfinder_paths.core.clients.TokenClient import TokenClient
23
- from wayfinder_paths.core.clients.TransactionClient import TransactionClient
24
20
  from wayfinder_paths.core.clients.WalletClient import WalletClient
25
21
  from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
26
22
 
@@ -30,19 +26,15 @@ __all__ = [
30
26
  "AuthClient",
31
27
  "TokenClient",
32
28
  "WalletClient",
33
- "TransactionClient",
34
29
  "LedgerClient",
35
30
  "PoolClient",
36
31
  "BRAPClient",
37
- "SimulationClient",
38
32
  "HyperlendClient",
39
33
  # Protocols for SDK usage
40
34
  "TokenClientProtocol",
41
35
  "HyperlendClientProtocol",
42
36
  "LedgerClientProtocol",
43
37
  "WalletClientProtocol",
44
- "TransactionClientProtocol",
45
38
  "PoolClientProtocol",
46
39
  "BRAPClientProtocol",
47
- "SimulationClientProtocol",
48
40
  ]
@@ -28,12 +28,10 @@ if TYPE_CHECKING:
28
28
  LlamaReport,
29
29
  PoolList,
30
30
  )
31
- from wayfinder_paths.core.clients.SimulationClient import SimulationResult
32
31
  from wayfinder_paths.core.clients.TokenClient import (
33
32
  GasToken,
34
33
  TokenDetails,
35
34
  )
36
- from wayfinder_paths.core.clients.TransactionClient import TransactionPayload
37
35
  from wayfinder_paths.core.clients.WalletClient import (
38
36
  PoolBalance,
39
37
  TokenBalance,
@@ -186,21 +184,6 @@ class WalletClientProtocol(Protocol):
186
184
  ...
187
185
 
188
186
 
189
- class TransactionClientProtocol(Protocol):
190
- """Protocol for transaction operations"""
191
-
192
- async def build_send(
193
- self,
194
- from_address: str,
195
- to_address: str,
196
- token_address: str,
197
- amount: float,
198
- chain_id: int,
199
- ) -> TransactionPayload:
200
- """Build a send transaction payload for EVM tokens/native transfers"""
201
- ...
202
-
203
-
204
187
  class PoolClientProtocol(Protocol):
205
188
  """Protocol for pool-related read operations"""
206
189
 
@@ -242,49 +225,6 @@ class BRAPClientProtocol(Protocol):
242
225
  ...
243
226
 
244
227
 
245
- class SimulationClientProtocol(Protocol):
246
- """Protocol for blockchain transaction simulations"""
247
-
248
- async def simulate_send(
249
- self,
250
- from_address: str,
251
- to_address: str,
252
- token_address: str,
253
- amount: str,
254
- chain_id: int,
255
- initial_balances: dict[str, str],
256
- ) -> SimulationResult:
257
- """Simulate sending native ETH or ERC20 tokens"""
258
- ...
259
-
260
- async def simulate_approve(
261
- self,
262
- from_address: str,
263
- to_address: str,
264
- token_address: str,
265
- amount: str,
266
- chain_id: int,
267
- initial_balances: dict[str, str],
268
- clear_approval_first: bool = False,
269
- ) -> SimulationResult:
270
- """Simulate ERC20 token approval"""
271
- ...
272
-
273
- async def simulate_swap(
274
- self,
275
- from_token_address: str,
276
- to_token_address: str,
277
- from_chain_id: int,
278
- to_chain_id: int,
279
- amount: str,
280
- from_address: str,
281
- slippage: float,
282
- initial_balances: dict[str, str],
283
- ) -> SimulationResult:
284
- """Simulate token swap operation"""
285
- ...
286
-
287
-
288
228
  class HyperliquidExecutorProtocol(Protocol):
289
229
  """Protocol for Hyperliquid order execution operations."""
290
230