wayfinder-paths 0.1.19__py3-none-any.whl → 0.1.20__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 +0 -21
  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 +0 -147
  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 +0 -9
  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 +9 -121
  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/erc20_service.py +0 -1
  65. wayfinder_paths/core/utils/evm_helpers.py +0 -50
  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.20.dist-info/METADATA +355 -0
  93. wayfinder_paths-0.1.20.dist-info/RECORD +129 -0
  94. wayfinder_paths/core/adapters/base.py +0 -5
  95. wayfinder_paths-0.1.19.dist-info/METADATA +0 -592
  96. wayfinder_paths-0.1.19.dist-info/RECORD +0 -130
  97. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.20.dist-info}/LICENSE +0 -0
  98. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.20.dist-info}/WHEEL +0 -0
@@ -1,12 +1,9 @@
1
- """Test to ensure all adapters and strategies have corresponding test files."""
2
-
3
1
  from pathlib import Path
4
2
 
5
3
  import pytest
6
4
 
7
5
 
8
6
  def test_all_adapters_have_tests():
9
- """Verify that all adapters have a test_adapter.py file."""
10
7
  adapters_dir = Path(__file__).parent.parent / "adapters"
11
8
 
12
9
  if not adapters_dir.exists():
@@ -35,7 +32,6 @@ def test_all_adapters_have_tests():
35
32
 
36
33
 
37
34
  def test_all_strategies_have_tests():
38
- """Verify that all strategies have a test_strategy.py file."""
39
35
  strategies_dir = Path(__file__).parent.parent / "strategies"
40
36
 
41
37
  if not strategies_dir.exists():
@@ -64,7 +60,6 @@ def test_all_strategies_have_tests():
64
60
 
65
61
 
66
62
  def test_all_strategies_have_examples_json():
67
- """Verify that all strategies have an examples.json file (REQUIRED)."""
68
63
  strategies_dir = Path(__file__).parent.parent / "strategies"
69
64
 
70
65
  if not strategies_dir.exists():
@@ -94,7 +89,6 @@ def test_all_strategies_have_examples_json():
94
89
 
95
90
 
96
91
  def test_strategy_tests_use_examples_json():
97
- """Verify that strategy test files load examples.json using the shared utility."""
98
92
  strategies_dir = Path(__file__).parent.parent / "strategies"
99
93
 
100
94
  if not strategies_dir.exists():
@@ -115,26 +109,23 @@ def test_strategy_tests_use_examples_json():
115
109
  try:
116
110
  content = test_file.read_text()
117
111
 
118
- # Check if it imports load_strategy_examples from tests.test_utils
119
112
  # (wayfinder_paths/ is added to path by conftest.py or inline)
120
113
  has_import = (
121
114
  "from tests.test_utils import load_strategy_examples" in content
122
115
  or "from wayfinder_paths.tests.test_utils import load_strategy_examples"
123
- in content # alternative
116
+ in content
124
117
  or "import tests.test_utils" in content
125
- or "import wayfinder_paths.tests.test_utils" in content # alternative
118
+ or "import wayfinder_paths.tests.test_utils" in content
126
119
  or (
127
120
  "tests.test_utils" in content
128
121
  and "load_strategy_examples" in content
129
122
  ) # fallback importlib pattern
130
123
  )
131
124
 
132
- # Check if it calls load_strategy_examples
133
125
  has_usage = "load_strategy_examples" in content
134
126
 
135
127
  # If it doesn't use the shared utility, check for alternative patterns
136
128
  if not (has_import and has_usage):
137
- # Check for hardcoded examples.json loading (old pattern)
138
129
  has_hardcoded = (
139
130
  'Path(__file__).parent / "examples.json"' in content
140
131
  or "examples.json" in content
@@ -166,7 +157,6 @@ def test_strategy_tests_use_examples_json():
166
157
 
167
158
 
168
159
  def test_strategy_examples_have_smoke():
169
- """Verify that all strategy examples.json files have a 'smoke' entry."""
170
160
  strategies_dir = Path(__file__).parent.parent / "strategies"
171
161
 
172
162
  if not strategies_dir.exists():
@@ -1,26 +1,9 @@
1
- """Shared utilities for testing strategies and adapters."""
2
-
3
1
  import json
4
2
  from pathlib import Path
5
3
  from typing import Any
6
4
 
7
5
 
8
6
  def load_strategy_examples(strategy_test_file: Path) -> dict[str, Any]:
9
- """Load examples.json for a strategy test file.
10
-
11
- This is REQUIRED for all strategy tests. The examples.json file serves
12
- as both documentation and test data, ensuring tests stay in sync with examples.
13
-
14
- Args:
15
- strategy_test_file: Path to the test_strategy.py file
16
-
17
- Returns:
18
- Dictionary containing examples from examples.json
19
-
20
- Raises:
21
- FileNotFoundError: If examples.json does not exist
22
- json.JSONDecodeError: If examples.json is invalid JSON
23
- """
24
7
  examples_path = strategy_test_file.parent / "examples.json"
25
8
 
26
9
  if not examples_path.exists():
@@ -35,19 +18,6 @@ def load_strategy_examples(strategy_test_file: Path) -> dict[str, Any]:
35
18
 
36
19
 
37
20
  def get_canonical_examples(examples: dict[str, Any]) -> dict[str, Any]:
38
- """Extract canonical usage examples from examples.json.
39
-
40
- Canonical usage is defined as the primary, documented usage patterns
41
- that demonstrate how the strategy should be used. This includes:
42
- - 'smoke' example: The basic lifecycle test (deposit → update → status → withdraw)
43
- - Any examples without 'expect' fields (positive usage patterns)
44
-
45
- Args:
46
- examples: The full examples.json dictionary
47
-
48
- Returns:
49
- Dictionary of canonical examples keyed by their example name
50
- """
51
21
  canonical = {}
52
22
 
53
23
  # 'smoke' is always canonical
@@ -57,7 +27,7 @@ def get_canonical_examples(examples: dict[str, Any]) -> dict[str, Any]:
57
27
  # Any example without 'expect' is considered canonical usage
58
28
  for name, example_data in examples.items():
59
29
  if name == "smoke":
60
- continue # Already added
30
+ continue
61
31
  if isinstance(example_data, dict) and "expect" not in example_data:
62
32
  canonical[name] = example_data
63
33
 
@@ -0,0 +1,355 @@
1
+ Metadata-Version: 2.3
2
+ Name: wayfinder-paths
3
+ Version: 0.1.20
4
+ Summary: Wayfinder Path: strategies and adapters
5
+ Author: Wayfinder
6
+ Author-email: dev@wayfinder.ai
7
+ Requires-Python: >=3.12,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Requires-Dist: aiohttp (>=3.13.0,<4.0.0)
12
+ Requires-Dist: eth-account (>=0.13.7,<0.14.0)
13
+ Requires-Dist: httpx (>=0.28.1,<0.29.0)
14
+ Requires-Dist: hyperliquid-felix
15
+ Requires-Dist: loguru (>=0.7.3,<0.8.0)
16
+ Requires-Dist: numpy (>=1.26.0,<2.0.0)
17
+ Requires-Dist: pandas (>=2.2.0,<3.0.0)
18
+ Requires-Dist: pydantic (>=2.11.9,<3.0.0)
19
+ Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
20
+ Requires-Dist: web3 (>=7.13.0,<8.0.0)
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Wayfinder Paths
24
+
25
+ [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/)
26
+ [![PyPI](https://img.shields.io/pypi/v/wayfinder-paths.svg)](https://pypi.org/project/wayfinder-paths/)
27
+ [![Discord](https://img.shields.io/badge/discord-join-7289da.svg)](https://discord.gg/fUVwGMXjm3)
28
+
29
+ Open-source framework for building automated crypto trading strategies and protocol integrations. Develop, test, and deploy strategies with direct wallet integration across multiple chains.
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ # Clone the repository
35
+ git clone https://github.com/WayfinderFoundation/wayfinder-paths.git
36
+ cd wayfinder-paths
37
+
38
+ # Install Poetry if needed
39
+ curl -sSL https://install.python-poetry.org | python3 -
40
+
41
+ # Install dependencies
42
+ poetry install
43
+
44
+ # Generate test wallets (creates config.json with main wallet)
45
+ just create-wallets
46
+ # Or: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
47
+
48
+ # Create a strategy-specific wallet
49
+ just create-wallet stablecoin_yield_strategy
50
+ # Or: poetry run python wayfinder_paths/scripts/make_wallets.py --label stablecoin_yield_strategy
51
+
52
+ # Add your API key to config.json under system.api_key
53
+
54
+ # Run a strategy
55
+ poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --action status --config config.json
56
+ ```
57
+
58
+ ## Repository Structure
59
+
60
+ ```
61
+ wayfinder-paths/
62
+ ├── wayfinder_paths/
63
+ │ ├── core/ # Core framework (maintained by team)
64
+ │ │ ├── adapters/ # BaseAdapter class
65
+ │ │ ├── clients/ # API clients (Token, Wallet, Pool, BRAP, Ledger, etc.)
66
+ │ │ ├── engine/ # StrategyJob execution engine
67
+ │ │ ├── strategies/ # Strategy base class and descriptors
68
+ │ │ ├── utils/ # Web3, EVM helpers, transaction utilities
69
+ │ │ └── config.py # Configuration system
70
+ │ ├── adapters/ # Protocol integrations (community contributions)
71
+ │ │ ├── balance_adapter/ # Wallet/token balances and transfers
72
+ │ │ ├── brap_adapter/ # Cross-chain swaps and bridges
73
+ │ │ ├── ledger_adapter/ # Transaction recording
74
+ │ │ ├── moonwell_adapter/ # Moonwell lending protocol
75
+ │ │ ├── pool_adapter/ # DeFi pool data
76
+ │ │ └── token_adapter/ # Token metadata and prices
77
+ │ ├── strategies/ # Trading strategies (community contributions)
78
+ │ │ ├── basis_trading_strategy/
79
+ │ │ ├── hyperlend_stable_yield_strategy/
80
+ │ │ ├── moonwell_wsteth_loop_strategy/
81
+ │ │ └── stablecoin_yield_strategy/
82
+ │ ├── templates/ # Starter templates
83
+ │ │ ├── adapter/
84
+ │ │ └── strategy/
85
+ │ ├── scripts/ # Utility scripts
86
+ │ └── run_strategy.py # CLI entry point
87
+ ├── config.json # Local config (not committed)
88
+ ├── pyproject.toml # Project dependencies
89
+ └── README.md
90
+ ```
91
+
92
+ ## Architecture
93
+
94
+ ### Layered Design
95
+
96
+ ```
97
+ Strategy Layer - Trading logic (deposit, update, withdraw, exit)
98
+
99
+ Adapter Layer - Protocol integrations (BalanceAdapter, PoolAdapter, etc.)
100
+
101
+ Client Layer - API wrappers (TokenClient, WalletClient, PoolClient, etc.)
102
+
103
+ Network - RPCs, Wayfinder API, external services
104
+ ```
105
+
106
+ **Key principle**: Strategies call adapters, adapters compose clients, clients handle network communication.
107
+
108
+ ### Strategies
109
+
110
+ Strategies implement trading logic by extending the `Strategy` base class:
111
+
112
+ ```python
113
+ from wayfinder_paths.core.strategies.Strategy import Strategy, StatusDict, StatusTuple
114
+
115
+ class MyStrategy(Strategy):
116
+ name = "My Strategy"
117
+
118
+ def __init__(self, config=None, **kwargs):
119
+ super().__init__(config, **kwargs)
120
+ # Register adapters
121
+ balance_adapter = BalanceAdapter(config, **kwargs)
122
+ self.register_adapters([balance_adapter])
123
+ self.balance_adapter = balance_adapter
124
+
125
+ async def deposit(self, main_token_amount=0.0, gas_token_amount=0.0) -> StatusTuple:
126
+ """Move funds from main wallet into strategy wallet."""
127
+ return (True, "Deposited successfully")
128
+
129
+ async def update(self) -> StatusTuple:
130
+ """Rebalance or optimize positions."""
131
+ return (True, "Updated successfully")
132
+
133
+ async def exit(self, **kwargs) -> StatusTuple:
134
+ """Transfer funds from strategy wallet back to main wallet."""
135
+ return (True, "Exited successfully")
136
+
137
+ async def _status(self) -> StatusDict:
138
+ """Report current state."""
139
+ return {
140
+ "portfolio_value": 0.0,
141
+ "net_deposit": 0.0,
142
+ "strategy_status": {"message": "healthy"},
143
+ "gas_available": 0.0,
144
+ "gassed_up": True,
145
+ }
146
+ ```
147
+
148
+ **Required methods**: `deposit`, `update`, `exit`, `_status`
149
+
150
+ **Optional methods**: `withdraw` (has default implementation), `partial_liquidate`, `setup`, `health_check`
151
+
152
+ ### Adapters
153
+
154
+ Adapters wrap protocol-specific logic and expose capabilities to strategies:
155
+
156
+ ```python
157
+ from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
158
+
159
+ class MyAdapter(BaseAdapter):
160
+ adapter_type = "MY_ADAPTER"
161
+
162
+ def __init__(self, config=None):
163
+ super().__init__("my_adapter", config)
164
+ self.client = SomeClient()
165
+
166
+ async def connect(self) -> bool:
167
+ return True
168
+
169
+ async def do_something(self, param: str) -> tuple[bool, Any]:
170
+ try:
171
+ result = await self.client.call(param)
172
+ return (True, result)
173
+ except Exception as e:
174
+ return (False, str(e))
175
+ ```
176
+
177
+ All adapter methods return `(success: bool, data: Any)` tuples.
178
+
179
+ ### Built-in Adapters
180
+
181
+ | Adapter | Type | Purpose |
182
+ |---------|------|---------|
183
+ | BalanceAdapter | BALANCE | Wallet/token balances, cross-wallet transfers with ledger tracking |
184
+ | PoolAdapter | POOL | DeFi pool metadata and yield analytics |
185
+ | BRAPAdapter | BRAP | Cross-chain swap quotes and execution |
186
+ | LedgerAdapter | LEDGER | Transaction recording and net deposit tracking |
187
+ | TokenAdapter | TOKEN | Token metadata and price feeds |
188
+ | MoonwellAdapter | MOONWELL | Moonwell lending/borrowing on Base |
189
+
190
+ ### Built-in Strategies
191
+
192
+ | Strategy | Description | Chain |
193
+ |----------|-------------|-------|
194
+ | stablecoin_yield_strategy | USDC yield optimization on Base | Base |
195
+ | hyperlend_stable_yield_strategy | Stablecoin yield on HyperLend | HyperEVM |
196
+ | moonwell_wsteth_loop_strategy | Leveraged wstETH carry trade | Base |
197
+ | basis_trading_strategy | Delta-neutral funding rate capture | Hyperliquid |
198
+
199
+ ## Configuration
200
+
201
+ Configuration lives in `config.json`:
202
+
203
+ ```json
204
+ {
205
+ "system": {
206
+ "api_base_url": "https://api.wayfinder.ai",
207
+ "api_key": "sk_live_..."
208
+ },
209
+ "strategy": {
210
+ "rpc_urls": {
211
+ "1": "https://eth.llamarpc.com",
212
+ "8453": "https://mainnet.base.org",
213
+ "42161": "https://arb1.arbitrum.io/rpc"
214
+ }
215
+ },
216
+ "wallets": [
217
+ {
218
+ "label": "main",
219
+ "address": "0x...",
220
+ "private_key_hex": "0x..."
221
+ },
222
+ {
223
+ "label": "stablecoin_yield_strategy",
224
+ "address": "0x...",
225
+ "private_key_hex": "0x..."
226
+ }
227
+ ]
228
+ }
229
+ ```
230
+
231
+ - **system.api_key**: Required for Wayfinder API authentication (sent as `X-API-KEY` header)
232
+ - **wallets**: Array of wallets with labels; strategies look up wallets by label matching their directory name
233
+ - **strategy.rpc_urls**: Custom RPC endpoints by chain ID
234
+
235
+ See [CONFIG_GUIDE.md](CONFIG_GUIDE.md) for detailed configuration documentation.
236
+
237
+ ## CLI Usage
238
+
239
+ ```bash
240
+ # Check strategy status
241
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action status --config config.json
242
+
243
+ # Deposit funds
244
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action deposit \
245
+ --main-token-amount 100 --gas-token-amount 0.01 --config config.json
246
+
247
+ # Run update cycle
248
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action update --config config.json
249
+
250
+ # Withdraw funds
251
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action withdraw --config config.json
252
+
253
+ # Exit (return funds to main wallet)
254
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action exit --config config.json
255
+
256
+ # Run continuously
257
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action run --config config.json
258
+
259
+ # Partial liquidation
260
+ poetry run python wayfinder_paths/run_strategy.py <strategy_name> --action partial-liquidate \
261
+ --amount 50 --config config.json
262
+ ```
263
+
264
+ **Available actions**: `status`, `deposit`, `update`, `withdraw`, `exit`, `run`, `partial-liquidate`, `policy`, `script`
265
+
266
+ ## Testing
267
+
268
+ ```bash
269
+ # Generate test wallets first
270
+ just create-wallets
271
+
272
+ # Run all smoke tests
273
+ poetry run pytest -k smoke -v
274
+
275
+ # Test specific strategy
276
+ poetry run pytest wayfinder_paths/strategies/my_strategy/ -v
277
+
278
+ # Test specific adapter
279
+ poetry run pytest wayfinder_paths/adapters/my_adapter/ -v
280
+
281
+ # Run with coverage
282
+ poetry run pytest --cov=wayfinder_paths -v
283
+ ```
284
+
285
+ See [TESTING.md](TESTING.md) for detailed testing guidance.
286
+
287
+ ## Contributing
288
+
289
+ ### Creating a New Strategy
290
+
291
+ ```bash
292
+ # Use the convenience command (creates wallet automatically)
293
+ just create-strategy "My Strategy Name"
294
+
295
+ # Or manually copy the template
296
+ cp -r wayfinder_paths/templates/strategy wayfinder_paths/strategies/my_strategy
297
+ ```
298
+
299
+ Then:
300
+ 1. Rename the class in `strategy.py`
301
+ 2. Implement `deposit`, `update`, `exit`, and `_status` methods
302
+ 3. Add tests in `test_strategy.py`
303
+ 4. Create `examples.json` with test data
304
+ 5. Update the README
305
+
306
+ ### Creating a New Adapter
307
+
308
+ ```bash
309
+ cp -r wayfinder_paths/templates/adapter wayfinder_paths/adapters/my_adapter
310
+ ```
311
+
312
+ Then:
313
+ 1. Rename the class in `adapter.py`
314
+ 2. Implement protocol-specific methods
315
+ 3. Add tests in `test_adapter.py`
316
+ 4. Update the README
317
+
318
+ ### Guidelines
319
+
320
+ - Strategies call adapters, not clients directly
321
+ - All adapter methods return `(success, data)` tuples
322
+ - Use `examples.json` for strategy test data
323
+ - Never hardcode API keys or private keys
324
+ - Add tests before submitting PRs
325
+
326
+ ## Publishing
327
+
328
+ ```bash
329
+ # Must be on main branch
330
+ export PUBLISH_TOKEN="your_pypi_token"
331
+ just publish
332
+ ```
333
+
334
+ **Version bumping**: Update `version` in `pyproject.toml` before publishing. Follow [SemVer](https://semver.org/):
335
+ - PATCH: Bug fixes
336
+ - MINOR: New features (backward compatible)
337
+ - MAJOR: Breaking changes
338
+
339
+ ## Security
340
+
341
+ - Never commit `config.json` (contains private keys)
342
+ - Use test wallets for development
343
+ - Test on testnets when available
344
+ - Validate all inputs
345
+ - Set appropriate gas limits
346
+
347
+ ## Community
348
+
349
+ - [Discord](https://discord.gg/fUVwGMXjm3)
350
+ - [GitHub Issues](https://github.com/WayfinderFoundation/wayfinder-paths/issues)
351
+
352
+ ## License
353
+
354
+ MIT License - see [LICENSE](LICENSE) for details.
355
+
@@ -0,0 +1,129 @@
1
+ wayfinder_paths/__init__.py,sha256=xKU94QbtPMmpY-Y3ktZfHwC7Rgaspl69GE8a8LQdAHs,337
2
+ wayfinder_paths/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ wayfinder_paths/adapters/balance_adapter/README.md,sha256=mq4cSYrrW5TNcXKnGBg9PwQcjCYZtXFNzEAfNGYumb8,2402
4
+ wayfinder_paths/adapters/balance_adapter/adapter.py,sha256=bOPWOr11IfDPnTg5J6hQQ1wI2gyRlxJ_-qTn6o48aBg,10091
5
+ wayfinder_paths/adapters/balance_adapter/examples.json,sha256=3R1M4B_VsIy29viAuFT9nQbnQShWl8ZbU-rnSNWUW9U,129
6
+ wayfinder_paths/adapters/balance_adapter/test_adapter.py,sha256=gf7WlA-RkMmSDP1jIYi0hUXkMfqfGTjzUZjQa9H07nU,5334
7
+ wayfinder_paths/adapters/brap_adapter/README.md,sha256=u_UZNB3RBLAHrwklgd-ZPftNiIpIutzfH1FulJ4QB-Y,2673
8
+ wayfinder_paths/adapters/brap_adapter/__init__.py,sha256=Hx4JW1tDijXS5YQhVliE0syw1RD1YKO2MM37wN_to9M,60
9
+ wayfinder_paths/adapters/brap_adapter/adapter.py,sha256=yhiP54TjcS1cbbAH1Is6yQtFe9Esw1ZfxoXMa_5TBjw,26217
10
+ wayfinder_paths/adapters/brap_adapter/examples.json,sha256=FGZhNaMCAQ56KhovEGSsV1BHOcMd_QqQBNmCU6m8zfQ,5389
11
+ wayfinder_paths/adapters/brap_adapter/test_adapter.py,sha256=CmK8TUxmnf4IzExToJ68FgUyE4FB7B2IOeB6GF5-B0E,11361
12
+ wayfinder_paths/adapters/hyperlend_adapter/__init__.py,sha256=IDgYOx5rF2Zd8DjZ_VzmZc6EUGS34SfIVQ_M1PdZ0YQ,112
13
+ wayfinder_paths/adapters/hyperlend_adapter/adapter.py,sha256=MCQcp8m_-Wp6702B9BxSXNnT8lkPaZc95bAFDCxnnys,9632
14
+ wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py,sha256=f7YEJTT8o8FdN8OmDFuNYcIZRZ99kCAWcDHEFsgYFIQ,10884
15
+ wayfinder_paths/adapters/hyperliquid_adapter/__init__.py,sha256=QpA258RzVbxzsha86HQduAuNVG0g0qvsI5OcZunQ8DQ,467
16
+ wayfinder_paths/adapters/hyperliquid_adapter/adapter.py,sha256=GCI4up7fGuyiiYd_5zw00y497UdggjDSJ_G-ZhU_tgA,25217
17
+ wayfinder_paths/adapters/hyperliquid_adapter/executor.py,sha256=h7Kwcj1R6udb-m_ckw8LHdNZ_gsfvBTSCosY-4tWjSk,16277
18
+ wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py,sha256=FFRZJVkZMvcIfzvyttNcAdvAAdpMoiz1oBMPcfpQ1TU,35193
19
+ wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py,sha256=3533NANBEAGYpisXWF7u6lxF8e3LyqLmlL-C3HIWZ1Q,3847
20
+ wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py,sha256=7hWBW2yNj8a1_R4cBVnvXQ70ENS4FTVaqq3BC7SlxWQ,5871
21
+ wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py,sha256=w3iXOx7JfS54E05Zr-hxzKSe3mr5dtLloUrQ6LyJyao,3746
22
+ wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py,sha256=BhsymEuDfaRlRhEX1qcWAZmmgnJPno84dupV1Q2aX-A,5604
23
+ wayfinder_paths/adapters/hyperliquid_adapter/utils.py,sha256=J0UcXR60BHLj147qMZHocrcvIQ71GhGx90u3JDZ3gg8,3838
24
+ wayfinder_paths/adapters/ledger_adapter/README.md,sha256=qdKwZTiLyjD21zI_LTipiT44tNTPA-N7YEklQD8laoQ,2482
25
+ wayfinder_paths/adapters/ledger_adapter/__init__.py,sha256=CrFEf6_7I27g5CQPPOAFYzQvm33IpdkbQHCKiDdwiWk,64
26
+ wayfinder_paths/adapters/ledger_adapter/adapter.py,sha256=6K6N0Xjjw_ZxnraJ30NijaNlnD1HQQ5lDCHzsy8Pzvg,6628
27
+ wayfinder_paths/adapters/ledger_adapter/examples.json,sha256=DdqTSe4vnBrfIycQVQQ_JZom7fBGHbL7MR4ppK9ljCY,3936
28
+ wayfinder_paths/adapters/ledger_adapter/test_adapter.py,sha256=haPVZQGL0f-vZPvNMUcfoq63Bu7F4FumVBuAJKiRmwg,6827
29
+ wayfinder_paths/adapters/moonwell_adapter/README.md,sha256=A-xKZo4ssLh1-uJqlp9ihMrnlZ8hB-KW2e0MRH4pnhU,3036
30
+ wayfinder_paths/adapters/moonwell_adapter/__init__.py,sha256=5wMDRIM6z0QbSqKEqaV8tUGkpwrAABqz1T0hP4YJbMg,109
31
+ wayfinder_paths/adapters/moonwell_adapter/adapter.py,sha256=SdVA4_wXjL3NR3yql8jWOrm5zBuFGSrJA62PmCKLTD4,39525
32
+ wayfinder_paths/adapters/moonwell_adapter/test_adapter.py,sha256=Uv9jtHJEifAZ_IUafo5e5tsNkjslAhFhnZqRkwmxXQ0,25391
33
+ wayfinder_paths/adapters/pool_adapter/README.md,sha256=qxXNcTgxQ4-YEDC-ZHiQ5wTpV_76t-vK58vyDh0IBgU,1282
34
+ wayfinder_paths/adapters/pool_adapter/__init__.py,sha256=LTbty0SuACoj3X5yeGESDUdtJQt8zyB2Loq8BuEp7rE,60
35
+ wayfinder_paths/adapters/pool_adapter/adapter.py,sha256=NHxtFOt10l320AClQUWchUVrQp0ivST25UOczS7aYeQ,1298
36
+ wayfinder_paths/adapters/pool_adapter/examples.json,sha256=NW-7J6_zXxky8uMDRym3jJaPP8hZLEiytQ3WKoZEP54,855
37
+ wayfinder_paths/adapters/pool_adapter/test_adapter.py,sha256=GGocdzXbeZMYXeVy7SOkY_ifC719rwYdqTIwQoxRJSo,2262
38
+ wayfinder_paths/adapters/token_adapter/README.md,sha256=JlZhT6MK3gYQ73uJU-DOrEx5eMZXvqceqrawJqNdygI,1623
39
+ wayfinder_paths/adapters/token_adapter/__init__.py,sha256=nEmxrvffEygn3iKH3cZTNLkhnUUhlUAEtshmrFRAjq8,62
40
+ wayfinder_paths/adapters/token_adapter/adapter.py,sha256=3qZ9vHdCEMeMzbcFCh4ZE3VYTQ0OWKsRihNilop8wyI,2751
41
+ wayfinder_paths/adapters/token_adapter/examples.json,sha256=bvwP9XL9c_endFlMQgkavXh_IzNEEUyJd4gh5QjrcqY,2944
42
+ wayfinder_paths/adapters/token_adapter/test_adapter.py,sha256=jDenD0BYbbb_xE3jKrA84io8iVEcvjk5SExf6UjQ410,3980
43
+ wayfinder_paths/conftest.py,sha256=1KWNevxGIsnZfgUntkF2qo2fqfE7Wr-lM5km01gMcHo,816
44
+ wayfinder_paths/core/__init__.py,sha256=nwf9NigPlXUDAqXpYNOQGBdjwMyvj40RdNTMEklqBH0,363
45
+ wayfinder_paths/core/adapters/BaseAdapter.py,sha256=PnzwbUOyHDrmBlUeJWO4KHYDxpkLiGK_TWCAsJ-7Vg0,1326
46
+ wayfinder_paths/core/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
+ wayfinder_paths/core/adapters/models.py,sha256=bopGe59hFtvMqFdMfI4M04Nh5-f1O8orGzJyA7qfY64,891
48
+ wayfinder_paths/core/analytics/__init__.py,sha256=d_upri6nw5-oUdhOCb45P-ojAqpb0JBGFMBdqFGBI8s,209
49
+ wayfinder_paths/core/analytics/bootstrap.py,sha256=npbLf9Jzx0tl4fHVumeUID5NnBwyHnjbQdIg7Ol-s-Y,1194
50
+ wayfinder_paths/core/analytics/stats.py,sha256=5JzhHEHivXuK5xvQa9BWgkpRD7WwVvQdJDGuILlS7Pc,1161
51
+ wayfinder_paths/core/analytics/test_analytics.py,sha256=COyUP9UBhE6471z9lQA2yM51SNKXZz0i3bkBztcilbs,4193
52
+ wayfinder_paths/core/clients/BRAPClient.py,sha256=tlB0DpoTfWPBHfH_UcXgxU3jH6M3CAenbw4Isfq1GJM,3229
53
+ wayfinder_paths/core/clients/ClientManager.py,sha256=J86ENEXaPt92LOa9WbZMjJCX5RCwqGRxjwSMmydeq3M,2481
54
+ wayfinder_paths/core/clients/HyperlendClient.py,sha256=_10Hrbo3M4VbW3Nwlt1_rJMrz955u_AIanQotG0fwE8,5508
55
+ wayfinder_paths/core/clients/LedgerClient.py,sha256=IHjJtKXYMgCdIhykyCTDwrrVOCucafLFBJOQtoe3Bz0,10230
56
+ wayfinder_paths/core/clients/PoolClient.py,sha256=ij0aVwV73UiUndOmBrtpg1BhalSIr_Ab78pP7xQQHzY,4266
57
+ wayfinder_paths/core/clients/TokenClient.py,sha256=5yZiVcuGV4FTEUIRhjaSxGU8CChf3Qf1H5rLkviVLCY,3141
58
+ wayfinder_paths/core/clients/WalletClient.py,sha256=sjPLmzuAnY_NOSsDIoIViPRXKeHvp1s1uOf1W4E6bpk,1215
59
+ wayfinder_paths/core/clients/WayfinderClient.py,sha256=OKMuKKxfg3O2tNlZeywIZHpDQX7RWgKjiN0hy8BT_rI,3555
60
+ wayfinder_paths/core/clients/__init__.py,sha256=wrQQ4_Lfgc3kHiqO-jDCVFqtZxeOpDvth73GMhakC0E,1122
61
+ wayfinder_paths/core/clients/protocols.py,sha256=97VCgOq5Z9IoVrmzMS4aR3WfbaNfSuiNG2ikNO7lz2o,5604
62
+ wayfinder_paths/core/config.py,sha256=GUKtDpS7-jlb-KxVT_1l4XuO93pu2qr4IgUKWbnYRs8,7007
63
+ wayfinder_paths/core/constants/__init__.py,sha256=k_PUZFCfCsPkUOcpDCniKKbJhomTnOFrVVRW6qyNzuU,315
64
+ wayfinder_paths/core/constants/base.py,sha256=lV2oSIuqXZfCXQcgIlwBcNNcShsZrkHwuQ-Fx61kiQI,1178
65
+ wayfinder_paths/core/constants/erc20_abi.py,sha256=-eN5Or7J2K9PoGrvLpNd0fDIGdcC5_XCHfzaOZyNaUE,2733
66
+ wayfinder_paths/core/constants/hyperlend_abi.py,sha256=999Y2lKM35gMvYbiHVa0i8HK7e5Th6Q-DD5kB9nrFS4,4110
67
+ wayfinder_paths/core/constants/moonwell_abi.py,sha256=DFpM3_6j0n6-zu2M5qdCAD3Ss2sMZEXOHyHEPjG1tjY,11634
68
+ wayfinder_paths/core/engine/StrategyJob.py,sha256=zR02cV4DXuw4RU8_GE_VOmyuQRH5fxt7xzxpai6qRf8,4042
69
+ wayfinder_paths/core/services/test_local_evm_txn.py,sha256=tmP3pt4QBihA6T3PgCSd8hjBkVh4ImNtKGFiFKOkWWA,4829
70
+ wayfinder_paths/core/strategies/Strategy.py,sha256=5fB1eLsy1hNqQ7_l4GrtS2wD90UooDNYSlRL3aiKgGA,6449
71
+ wayfinder_paths/core/strategies/__init__.py,sha256=r3v5Eriz5mb7vurIGxB-2Hzo4ZApGt8dZ8OFf0lwCWk,105
72
+ wayfinder_paths/core/strategies/base.py,sha256=-s0qeiGZl5CHTUL2PavGXM7ACkNlaa0c4jeZR_4DuBM,155
73
+ wayfinder_paths/core/strategies/descriptors.py,sha256=2Olef0VWols1CWb-TWcb5pil2rztC0jP6F_Trpv2hIw,1958
74
+ wayfinder_paths/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ wayfinder_paths/core/utils/erc20_service.py,sha256=0epXzo2vUWwb6AXNyP0RLhQTwiwoDvlkuHd8wKL_a3g,3376
76
+ wayfinder_paths/core/utils/evm_helpers.py,sha256=VIXDd_4uDrnttqqapoPGd1PCfmWzX1T_CsMZ1bPe77w,4147
77
+ wayfinder_paths/core/utils/transaction.py,sha256=OC-hig-H9IeCLFh64Hal2y-Du7RCK2ka7KjBohEV17c,6729
78
+ wayfinder_paths/core/utils/wallets.py,sha256=ccCQ128lDShO265AFMOCdijzPLucWe-Neg5wjLrOsnk,1948
79
+ wayfinder_paths/core/utils/web3.py,sha256=r0vHvKvFC167MygHhmxr2nfYtLYN0ttSUEI--hPetO0,1877
80
+ wayfinder_paths/policies/enso.py,sha256=oytco04eeGjiRbZPGFE1YpH4NxvV0tfVM14QmlyzjkY,428
81
+ wayfinder_paths/policies/erc20.py,sha256=K5PQCUivBrU2nYmIdsIARzRiFy36Rijver-RJnaxNT8,960
82
+ wayfinder_paths/policies/evm.py,sha256=8fJpjAl6XVxr51sVMw_VkWmIaI_lj2T7qrLcR8_sWgs,713
83
+ wayfinder_paths/policies/hyper_evm.py,sha256=wLkrE158rPaDjfU5q-PyRXuQ6KA67VcqWo484UHsLb8,649
84
+ wayfinder_paths/policies/hyperlend.py,sha256=4u0NP80t7rpHlw_nvParUN90sIXypWyXACfE0OPqFys,370
85
+ wayfinder_paths/policies/hyperliquid.py,sha256=hAxNtWdxavwf_a-AnlXMOmEYakkNBkrPTrvprIQqBDQ,796
86
+ wayfinder_paths/policies/moonwell.py,sha256=sKWLbruMKiW7Yh1DhXdVPRe0JBP-nooNybRz0G9PgvA,1605
87
+ wayfinder_paths/policies/prjx.py,sha256=6kfZ6OQFroFHYJl4vSWT-svwwfvoHlS_ZrcHt8nmZMU,743
88
+ wayfinder_paths/policies/util.py,sha256=r8xQLPvE3kU21_LG6VbkFI9sUSYltcsKunryZdHOUDA,912
89
+ wayfinder_paths/run_strategy.py,sha256=C0uwRlq2Xy1ASgC8Z8SjQZvHY8t4-Y8b0T_5UxEdJ2Y,11858
90
+ wayfinder_paths/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
+ wayfinder_paths/scripts/create_strategy.py,sha256=s9rQd880VbSSwOJdwjtOLfdW5evZqes69f5tm6VsrhQ,4688
92
+ wayfinder_paths/scripts/make_wallets.py,sha256=vKcf7g0QX9pCpQGVImoychzV70hvHpfMo7d0_wxd-js,4980
93
+ wayfinder_paths/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
+ wayfinder_paths/strategies/basis_trading_strategy/README.md,sha256=kZtG5NVVZwWsuz65n2SrwPMUGow9xsfIRplbHI0ARgE,3540
95
+ wayfinder_paths/strategies/basis_trading_strategy/__init__.py,sha256=kVcehFjBUtoi5xzSHI56jtDghsy0nYl6XIE6BI1l6aI,79
96
+ wayfinder_paths/strategies/basis_trading_strategy/constants.py,sha256=PJ1WtSALxiuW1FXx-BF30ciFISEhO5VBfrSZyfhPuz0,45
97
+ wayfinder_paths/strategies/basis_trading_strategy/examples.json,sha256=q2wlAH8Gr-LUJeamKzWL1EtChL3TBWe0HQ4_P-VCdqQ,429
98
+ wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py,sha256=F324ILz9w6uT7fkOVUa7gltp2LMEyGBlw3tz-ANcff8,37634
99
+ wayfinder_paths/strategies/basis_trading_strategy/strategy.py,sha256=g51mw8iSjW4p21XF3QWNzbN1ksMShS4tGllfAkzhIbc,146949
100
+ wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py,sha256=SJoCR9PcyXzdd8--6LCySc27B5rjgUeQrbALMouFOLU,35306
101
+ wayfinder_paths/strategies/basis_trading_strategy/types.py,sha256=xTkLYqwvS0meMdlRAvIKNH9AANRyz63bQSYFSxLI6n4,740
102
+ wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md,sha256=cqCmcWIPiOpCwt-82dnOgHnN64ZUITITR3jqIUYDXmA,2906
103
+ wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json,sha256=GbVo2p6QiG6M7Ma5s671lw8G9JwnMl1h0n9mrtt-ZS8,164
104
+ wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py,sha256=8qwYmREVq-CDBS91pZfCxgBTKYr7ePfXbakHCkmX3Fw,92955
105
+ wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py,sha256=5DZiu1Sc2AVHnKEhP5lBlXbGYfuznXeK8vVh_mysBWQ,15907
106
+ wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md,sha256=PZVbRXfoMNNrZUZY3YOWBW9A-6By7vi-IBBDIfvcdNc,3594
107
+ wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json,sha256=kgNRdZcqne8XTm-Y8Hv1a1pdajRQsey4Qhd5La-iWss,164
108
+ wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py,sha256=uW_Vef9eNFOSMmWYeE68LDxyVwHyWYje4B817-CQDZk,151446
109
+ wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py,sha256=U6_vaCzYRfu6k2vlOQhVXhPexvPNOfv8e6s8OiIySiw,37466
110
+ wayfinder_paths/strategies/stablecoin_yield_strategy/README.md,sha256=efyLd2AJHL_JtHF3eZsnHk2wF4NWzEnuLKRA2vOpLtE,2844
111
+ wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json,sha256=pL1DNFEvYvXKK7xXD5oQYFPQj3Cm1ocKnk6r_iZk0IY,423
112
+ wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py,sha256=qETYPjCocCxOk_WX9C4sUgYPq1tZOSBx2F9Sih5zhvE,75816
113
+ wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py,sha256=ITM-JmRfrT1MKW1iVN3VlFs2CwZK2AXx9JYdMVQHLcQ,18881
114
+ wayfinder_paths/templates/adapter/README.md,sha256=z0ULmM-vkyrZ0Y-a8iJzfLdrRgOuWaj9FqwE7xOZrwU,4179
115
+ wayfinder_paths/templates/adapter/adapter.py,sha256=o7ZY6q-42zl6AnQFmDWbYoRJCZwjuUbiK8GT7bs0Nds,442
116
+ wayfinder_paths/templates/adapter/examples.json,sha256=KLHy3AgPIplAaZN0qY2A-HBMa1xXkMhIyusORovTD9w,79
117
+ wayfinder_paths/templates/adapter/test_adapter.py,sha256=iuth05S9Twz5_ALh-rbPrQHoIEyxRy30X9fxELXnPWc,839
118
+ wayfinder_paths/templates/strategy/README.md,sha256=r7v4VcpO5Abz6q-mmjNmBcuagYM-Q-0H78CzMwwQksg,5298
119
+ wayfinder_paths/templates/strategy/examples.json,sha256=s8UdlD5uxLITQrRMCqgiaAP0IE0tdnnLfX-Zn-OChIc,135
120
+ wayfinder_paths/templates/strategy/strategy.py,sha256=Mw23A4yYoUqQ4sh4wdID0EypE9jo_RY0u_Qs2tMzGjY,968
121
+ wayfinder_paths/templates/strategy/test_strategy.py,sha256=72Wtft_SEykxKVlVq3eZzE4ZdzIxwkeM8Sb_aaXof9E,6335
122
+ wayfinder_paths/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
+ wayfinder_paths/tests/test_smoke_manifest.py,sha256=kTcIa4qikcspVh2ohQIk0aHUdIvBvcQBfNbm3PNiVvg,1636
124
+ wayfinder_paths/tests/test_test_coverage.py,sha256=paZd0U-J7oVDtkJ-DCBBEOHdupMRLsvs7WG5NrpAPRA,7203
125
+ wayfinder_paths/tests/test_utils.py,sha256=VzweYVaO20deZOwR8RKGYFrDnKTW0gZLm3dBwZiMK28,1015
126
+ wayfinder_paths-0.1.20.dist-info/LICENSE,sha256=dYKnlkC_xosBAEQNUvB6cHMuhFgcUtN0oBR7E8_aR2Y,1066
127
+ wayfinder_paths-0.1.20.dist-info/METADATA,sha256=UOXIWLq5N7RxpkrvETfbIpa7oV3pY9vZY2UHDINLwVQ,11638
128
+ wayfinder_paths-0.1.20.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
129
+ wayfinder_paths-0.1.20.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
2
-
3
- __all__ = [
4
- "BaseAdapter",
5
- ]