wayfinder-paths 0.1.19__py3-none-any.whl → 0.1.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wayfinder-paths might be problematic. Click here for more details.

Files changed (98) hide show
  1. wayfinder_paths/__init__.py +0 -2
  2. wayfinder_paths/adapters/balance_adapter/README.md +59 -45
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +1 -22
  4. wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -14
  5. wayfinder_paths/adapters/brap_adapter/README.md +61 -184
  6. wayfinder_paths/adapters/brap_adapter/__init__.py +0 -4
  7. wayfinder_paths/adapters/brap_adapter/adapter.py +1 -148
  8. wayfinder_paths/adapters/brap_adapter/test_adapter.py +0 -15
  9. wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -4
  10. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +1 -10
  11. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +0 -17
  12. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +3 -312
  13. wayfinder_paths/adapters/hyperliquid_adapter/executor.py +1 -71
  14. wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -57
  15. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -17
  16. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +2 -42
  17. wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +1 -9
  18. wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +15 -47
  19. wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -7
  20. wayfinder_paths/adapters/ledger_adapter/README.md +54 -74
  21. wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -4
  22. wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -106
  23. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -12
  24. wayfinder_paths/adapters/moonwell_adapter/README.md +67 -106
  25. wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -4
  26. wayfinder_paths/adapters/moonwell_adapter/adapter.py +10 -122
  27. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +84 -83
  28. wayfinder_paths/adapters/pool_adapter/README.md +30 -51
  29. wayfinder_paths/adapters/pool_adapter/__init__.py +0 -4
  30. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -19
  31. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -8
  32. wayfinder_paths/adapters/token_adapter/README.md +41 -49
  33. wayfinder_paths/adapters/token_adapter/adapter.py +0 -32
  34. wayfinder_paths/adapters/token_adapter/test_adapter.py +1 -12
  35. wayfinder_paths/conftest.py +0 -8
  36. wayfinder_paths/core/__init__.py +0 -2
  37. wayfinder_paths/core/adapters/BaseAdapter.py +0 -22
  38. wayfinder_paths/core/adapters/__init__.py +0 -5
  39. wayfinder_paths/core/adapters/models.py +0 -5
  40. wayfinder_paths/core/analytics/__init__.py +0 -2
  41. wayfinder_paths/core/analytics/bootstrap.py +0 -16
  42. wayfinder_paths/core/analytics/stats.py +0 -7
  43. wayfinder_paths/core/analytics/test_analytics.py +5 -34
  44. wayfinder_paths/core/clients/BRAPClient.py +0 -35
  45. wayfinder_paths/core/clients/ClientManager.py +0 -51
  46. wayfinder_paths/core/clients/HyperlendClient.py +0 -77
  47. wayfinder_paths/core/clients/LedgerClient.py +2 -122
  48. wayfinder_paths/core/clients/PoolClient.py +0 -2
  49. wayfinder_paths/core/clients/TokenClient.py +0 -39
  50. wayfinder_paths/core/clients/WalletClient.py +0 -15
  51. wayfinder_paths/core/clients/WayfinderClient.py +0 -24
  52. wayfinder_paths/core/clients/__init__.py +0 -4
  53. wayfinder_paths/core/clients/protocols.py +25 -98
  54. wayfinder_paths/core/config.py +0 -24
  55. wayfinder_paths/core/constants/__init__.py +0 -7
  56. wayfinder_paths/core/constants/base.py +2 -9
  57. wayfinder_paths/core/constants/erc20_abi.py +0 -5
  58. wayfinder_paths/core/constants/hyperlend_abi.py +0 -7
  59. wayfinder_paths/core/constants/moonwell_abi.py +0 -35
  60. wayfinder_paths/core/engine/StrategyJob.py +0 -32
  61. wayfinder_paths/core/strategies/Strategy.py +0 -99
  62. wayfinder_paths/core/strategies/__init__.py +0 -2
  63. wayfinder_paths/core/utils/__init__.py +0 -1
  64. wayfinder_paths/core/utils/evm_helpers.py +0 -50
  65. wayfinder_paths/core/utils/{erc20_service.py → tokens.py} +25 -21
  66. wayfinder_paths/core/utils/transaction.py +0 -1
  67. wayfinder_paths/run_strategy.py +0 -46
  68. wayfinder_paths/scripts/create_strategy.py +0 -17
  69. wayfinder_paths/scripts/make_wallets.py +1 -4
  70. wayfinder_paths/strategies/basis_trading_strategy/README.md +71 -163
  71. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +0 -24
  72. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +36 -400
  73. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +15 -64
  74. wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -4
  75. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +65 -56
  76. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +4 -27
  77. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -10
  78. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +71 -72
  79. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +23 -227
  80. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +120 -113
  81. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +64 -59
  82. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +4 -44
  83. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +2 -35
  84. wayfinder_paths/templates/adapter/README.md +107 -46
  85. wayfinder_paths/templates/adapter/adapter.py +0 -9
  86. wayfinder_paths/templates/adapter/test_adapter.py +0 -19
  87. wayfinder_paths/templates/strategy/README.md +113 -59
  88. wayfinder_paths/templates/strategy/strategy.py +0 -22
  89. wayfinder_paths/templates/strategy/test_strategy.py +0 -28
  90. wayfinder_paths/tests/test_test_coverage.py +2 -12
  91. wayfinder_paths/tests/test_utils.py +1 -31
  92. wayfinder_paths-0.1.21.dist-info/METADATA +355 -0
  93. wayfinder_paths-0.1.21.dist-info/RECORD +129 -0
  94. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/WHEEL +1 -1
  95. wayfinder_paths/core/adapters/base.py +0 -5
  96. wayfinder_paths-0.1.19.dist-info/METADATA +0 -592
  97. wayfinder_paths-0.1.19.dist-info/RECORD +0 -130
  98. {wayfinder_paths-0.1.19.dist-info → wayfinder_paths-0.1.21.dist-info}/LICENSE +0 -0
@@ -1,592 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: wayfinder-paths
3
- Version: 0.1.19
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-python-sdk (>=0.21.0,<0.22.0)
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
- [![Docker](https://img.shields.io/badge/docker-ready-brightgreen.svg)](https://www.docker.com/)
27
- [![Discord](https://img.shields.io/badge/discord-join-7289da.svg)](https://discord.gg/fUVwGMXjm3)
28
-
29
- Open-source platform for community-contributed crypto trading strategies and adapters. Build, test, and deploy automated trading strategies with direct wallet integration.
30
-
31
- ## 🚀 Quick Start
32
-
33
- ```bash
34
- # Clone the repository
35
- git clone https://github.com/wayfinder-ai/wayfinder-paths.git
36
- cd wayfinder-paths
37
-
38
- # Install Poetry (if not already installed)
39
- curl -sSL https://install.python-poetry.org | python3 -
40
-
41
- # Install dependencies
42
- poetry install
43
-
44
- # ⚠️ Generate test wallets FIRST (required!)
45
- # This creates config.json with a main wallet for local testing
46
- just create-wallets
47
- # Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
48
-
49
- # To test a specific strategy
50
- just create-wallet stablecoin_yield_strategy
51
-
52
- # Copy and configure
53
- cp wayfinder_paths/config.example.json config.json
54
- # Edit config.json with your Wayfinder credentials
55
-
56
- # Run a strategy locally (one-shot status check)
57
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --action status --config config.json
58
-
59
- # Run continuously (production mode)
60
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config config.json
61
- ```
62
-
63
- ## 📁 Repository Structure
64
-
65
- ```
66
- wayfinder_paths/
67
- ├── wayfinder_paths/ # Main package directory
68
- │ ├── core/ # Core engine (maintained by team)
69
- │ │ ├── clients/ # API client managers
70
- │ │ ├── adapters/ # Base adapter interfaces
71
- │ │ ├── engine/ # Trading engine & StrategyJob
72
- │ │ ├── strategies/ # Base strategy classes
73
- │ │ └── config.py # Configuration system
74
- │ ├── adapters/ # Your exchange/protocol integrations (community contributions)
75
- │ │ ├── balance_adapter/
76
- │ │ │ ├── adapter.py # Adapter implementation
77
- │ │ │ ├── examples.json # Example inputs for smoke
78
- │ │ │ ├── README.md # Local notes
79
- │ │ │ └── test_adapter.py # Local smoke test
80
- │ │ ├── brap_adapter/
81
- │ │ └── ...
82
- │ ├── strategies/ # Your trading strategies (community contributions)
83
- │ │ ├── stablecoin_yield_strategy/
84
- │ │ │ ├── strategy.py # Strategy implementation
85
- │ │ │ ├── examples.json # Example inputs
86
- │ │ │ ├── README.md # Local notes
87
- │ │ │ └── test_strategy.py # Local smoke test
88
- │ │ └── ...
89
- │ ├── tests/ # Test suite
90
- │ ├── CONFIG_GUIDE.md # Configuration documentation
91
- │ ├── config.example.json # Example configuration
92
- │ ├── scripts/ # Utility scripts
93
- │ └── run_strategy.py # Strategy runner script
94
- ├── config.json # Your local config with credentials and wallets
95
- ├── pyproject.toml # Poetry configuration
96
- └── README.md # This file
97
- ```
98
-
99
- ## 🤝 Contributing
100
-
101
- We welcome contributions! This is an open-source project where community members can contribute adapters and strategies.
102
-
103
- ### Quick Contribution Guide
104
-
105
- 1. **Fork the repository** and clone your fork
106
- 2. **Create a feature branch**: `git checkout -b feature/my-strategy`
107
- 3. **Copy a template** to get started:
108
- - **For adapters**: Copy `wayfinder_paths/templates/adapter/` to `wayfinder_paths/adapters/my_adapter/`
109
- - **For strategies**: Copy `wayfinder_paths/templates/strategy/` to `wayfinder_paths/strategies/my_strategy/`
110
- 4. **Customize** the template (rename classes, implement methods)
111
- 5. **Test your code** thoroughly using the provided test framework
112
- 6. **Submit a Pull Request** with a clear description of your changes
113
-
114
- ### What You Can Contribute
115
-
116
- - **Adapters**: Exchange/protocol integrations (e.g., Uniswap, Aave, Compound)
117
- - **Strategies**: Trading algorithms and yield optimization strategies
118
- - **Improvements**: Bug fixes, documentation, or core system enhancements
119
-
120
- ### Contributor Guidelines
121
-
122
- #### For Adapters
123
-
124
- - **Start from the template**: Copy `wayfinder_paths/templates/adapter/` as a starting point
125
- - Extend `BaseAdapter` from `wayfinder_paths/core/adapters/BaseAdapter.py`
126
- - Implement your adapter methods
127
- - Add comprehensive tests in `test_adapter.py`
128
- - Include usage examples in `examples.json`
129
- - Document your adapter in `README.md`
130
-
131
- #### For Strategies
132
-
133
- - **Start from the template**: Use `just create-strategy "Strategy Name"` to create a new strategy with its own wallet, or copy `wayfinder_paths/templates/strategy/` manually
134
- - Extend `Strategy` from `wayfinder_paths/core/strategies/Strategy.py`
135
- - Implement required methods: `deposit()`, `update()`, `status()`, `withdraw()`
136
- - Include test cases in `test_strategy.py`
137
- - Add example configurations in `examples.json`
138
-
139
- #### General Guidelines
140
-
141
- - **Code Quality**: Follow existing patterns and use type hints
142
- - **Testing**: See [TESTING.md](TESTING.md) - minimum: smoke test for strategies, basic tests for adapters
143
- - **Documentation**: Update README files and add docstrings
144
- - **Security**: Never hardcode API keys or private keys
145
- - **Architecture**: Use adapters for external integrations, not direct API calls
146
-
147
- ### Development Setup
148
-
149
- ```bash
150
- # 1. Fork and clone the repository
151
- git clone https://github.com/yourusername/wayfinder-paths.git
152
- cd wayfinder-paths
153
-
154
- # 2. Install dependencies
155
- poetry install
156
-
157
- # 3. Generate test wallets (required before testing!)
158
- # Creates a main wallet (or use 'just create-strategy' which auto-creates wallets)
159
- just create-wallets
160
- # Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
161
-
162
- # 4. Create a new strategy (recommended - automatically creates wallet)
163
- just create-strategy "My Strategy Name"
164
-
165
- # Or manually copy a template:
166
- # For adapters:
167
- cp -r wayfinder_paths/templates/adapter wayfinder_paths/adapters/my_adapter
168
- # For strategies:
169
- cp -r wayfinder_paths/templates/strategy wayfinder_paths/strategies/my_strategy
170
-
171
- # 5. Customize the template (see template README.md files for details)
172
-
173
- # 6. Run tests
174
- poetry run pytest -k smoke -v
175
-
176
- # Or test your specific contribution
177
- poetry run pytest wayfinder_paths/strategies/your_strategy/ -v
178
- poetry run pytest wayfinder_paths/adapters/your_adapter/ -v
179
-
180
- # 8. Test your contribution locally
181
- poetry run python wayfinder_paths/run_strategy.py your_strategy --action status
182
- ```
183
-
184
- ### Getting Help
185
-
186
- - 📖 Check existing adapters/strategies for examples
187
- - 🐛 Open an issue for bugs or feature requests
188
-
189
- ## 🏗️ Architecture
190
-
191
- ### Client System
192
-
193
- The platform uses a unified client system for all API interactions. Clients are thin wrappers that handle low-level API calls, authentication, and network communication. **Strategies should not call clients directly** - use adapters instead for domain-specific operations.
194
-
195
- ### Clients vs Adapters
196
-
197
- - **Clients**: Low-level, reusable service wrappers that talk to networks and external APIs. They handle auth, headers, retries, and response parsing, and expose generic capabilities (e.g., token info, tx building). Examples: `TokenClient`, `WalletClient`.
198
- - **Adapters**: Strategy-facing integrations for a specific exchange/protocol. They compose one or more clients to implement a set of capabilities (e.g., `supply`, `borrow`, `place_order`). Adapters encapsulate protocol-specific semantics and raise `NotImplementedError` for unsupported ops.
199
-
200
- Recommended usage:
201
-
202
- - Strategies call adapters (not clients directly) for domain actions.
203
- - Add or change a client when you need a new low-level capability shared across adapters.
204
- - Add or change an adapter when integrating a new protocol/exchange or changing protocol-specific behavior.
205
-
206
- Data flow: `Strategy` → `Adapter` → `Client(s)` → network/API.
207
-
208
- ### Configuration
209
-
210
- Configuration is split between:
211
-
212
- - **User Config**: Your credentials and preferences
213
- - **System Config**: Platform settings
214
- - **Strategy Config**: Strategy-specific parameters
215
-
216
- See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
217
-
218
- ### Authentication
219
-
220
- Wayfinder Paths uses API key authentication via the `X-API-KEY` header.
221
-
222
- **Add API key to config.json:**
223
-
224
- ```json
225
- {
226
- "system": {
227
- "api_key": "sk_live_abc123...",
228
- "api_base_url": "https://wayfinder.ai/api/v1",
229
- "wallets_path": "wallets.json"
230
- }
231
- }
232
- ```
233
-
234
- **How It Works:**
235
-
236
- - API key is automatically loaded from `system.api_key` in config.json
237
- - The API key is sent as the `X-API-KEY` header on all API requests
238
- - All clients automatically include the API key header
239
- - No need to pass API keys explicitly to strategies or clients
240
-
241
- See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for detailed configuration documentation.
242
-
243
- ## 🔌 Creating Adapters
244
-
245
- Adapters connect to exchanges and DeFi protocols using the client system.
246
-
247
- ```python
248
- # wayfinder_paths/adapters/my_adapter/adapter.py
249
- from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
250
- from wayfinder_paths.core.clients.PoolClient import PoolClient
251
-
252
-
253
- class MyAdapter(BaseAdapter):
254
- """Thin wrapper around PoolClient that exposes pool metadata to strategies."""
255
-
256
- adapter_type = "POOL"
257
-
258
- def __init__(self, config: dict | None = None):
259
- super().__init__("my_adapter", config)
260
- self.pool_client = PoolClient()
261
-
262
- async def connect(self) -> bool:
263
- """No-op for read-only adapters, but kept for interface consistency."""
264
- return True
265
-
266
- async def get_pools(self, pool_ids: list[str]):
267
- data = await self.pool_client.get_pools_by_ids(
268
- pool_ids=pool_ids
269
- )
270
- return (True, data)
271
- ```
272
-
273
- ## 📈 Building Strategies
274
-
275
- Strategies implement trading logic using adapters and the unified client system.
276
-
277
- ```python
278
- # wayfinder_paths/strategies/my_strategy/strategy.py
279
- from wayfinder_paths.core.strategies.Strategy import StatusDict, StatusTuple, Strategy
280
- from wayfinder_paths.adapters.balance_adapter.adapter import BalanceAdapter
281
-
282
-
283
- class MyStrategy(Strategy):
284
- name = "Demo Strategy"
285
-
286
- def __init__(
287
- self,
288
- config: dict | None = None,
289
- *,
290
- api_key: str | None = None, # Optional: API key for service account auth
291
- ):
292
- super().__init__(api_key=api_key) # Pass to base class for auto-discovery
293
- self.config = config or {}
294
- # Adapters automatically discover API key from constructor or config.json
295
- balance_adapter = BalanceAdapter(self.config)
296
- self.register_adapters([balance_adapter])
297
- self.balance_adapter = balance_adapter
298
-
299
- async def deposit(
300
- self, main_token_amount: float = 0.0, gas_token_amount: float = 0.0
301
- ) -> StatusTuple:
302
- """Move funds from main wallet into the strategy wallet."""
303
- if main_token_amount <= 0:
304
- return (False, "Nothing to deposit")
305
-
306
- success, _ = await self.balance_adapter.get_balance(
307
- query=self.config.get("token_id"),
308
- wallet_address=self.config.get("main_wallet", {}).get("address"),
309
- )
310
- if not success:
311
- return (False, "Unable to fetch balances")
312
-
313
- self.last_deposit = main_token_amount
314
- return (True, f"Deposited {main_token_amount} tokens")
315
-
316
- async def update(self) -> StatusTuple:
317
- """Periodic strategy update"""
318
- return (True, "No-op update")
319
-
320
- async def _status(self) -> StatusDict:
321
- """Report balances back to the runner"""
322
- success, balance = await self.balance_adapter.get_balance(
323
- query=self.config.get("token_id"),
324
- wallet_address=self.config.get("strategy_wallet", {}).get("address"),
325
- )
326
- return {
327
- "portfolio_value": float(balance or 0),
328
- "net_deposit": float(getattr(self, "last_deposit", 0.0)),
329
- "strategy_status": {"message": "healthy" if success else "unknown"},
330
- }
331
- ```
332
-
333
- ### Built-in Strategies
334
-
335
- The following strategies are available and can be run using the CLI:
336
-
337
- | Strategy | Description | Chain |
338
- | --------------------------------- | --------------------------- | -------- |
339
- | `basis_trading_strategy` | Delta-neutral basis trading | - |
340
- | `hyperlend_stable_yield_strategy` | Stable yield on HyperLend | HyperEVM |
341
- | `moonwell_wsteth_loop_strategy` | Leveraged wstETH yield loop | Base |
342
-
343
- #### Running Strategies
344
-
345
- ### Built-in adapters
346
-
347
- - **BALANCE (BalanceAdapter)**: wraps `WalletClient`/`TokenClient` to read wallet, token, and pool balances and now orchestrates transfers between the main/strategy wallets with ledger bookkeeping. Requires a `Web3Service` so it can share the same wallet provider as the strategy.
348
- - **POOL (PoolAdapter)**: composes `PoolClient` to fetch pools, llama analytics, combined reports, high-yield searches, and search helpers.
349
- - **BRAP (BRAPAdapter)**: integrates the cross-chain quote service for swaps/bridges, including fee breakdowns, route comparisons, validation helpers, and swap execution/ledger recording when provided a `Web3Service`.
350
- - **LEDGER (LedgerAdapter)**: records deposits, withdrawals, custom operations, and cashflows via `LedgerClient`, and can read strategy transaction summaries.
351
- - **TOKEN (TokenAdapter)**: lightweight wrapper around `TokenClient` for token metadata, live price snapshots, and gas token lookups.
352
- - **HYPERLEND (HyperlendAdapter)**: connects to `HyperlendClient` for lending/supply caps inside the HyperLend strategy.
353
- - **MOONWELL (MoonwellAdapter)**: interfaces with Moonwell protocol on Base for lending, borrowing, collateral management, and WELL rewards.
354
-
355
- Strategies register the adapters they need in their `__init__` method. Adapters implement their specific capabilities and raise `NotImplementedError` for unsupported operations.
356
-
357
- ## 🧪 Testing
358
-
359
- **📖 For detailed testing guidance, see [TESTING.md](TESTING.md)**
360
-
361
- ### Quick Start
362
-
363
- ```bash
364
- # 1. Generate test wallets (required!)
365
- # Creates a main wallet (or use 'just create-strategy' which auto-creates wallets)
366
- just create-wallets
367
- # Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
368
-
369
- # 2. Run smoke tests
370
- poetry run pytest -k smoke -v
371
-
372
- # 3. Test your specific contribution
373
- poetry run pytest wayfinder_paths/strategies/my_strategy/ -v # Strategy
374
- poetry run pytest wayfinder_paths/adapters/my_adapter/ -v # Adapter
375
- ```
376
-
377
- ### Testing Your Contribution
378
-
379
- **Strategies**: Add a simple smoke test in `test_strategy.py` that exercises deposit → update → status → withdraw.
380
-
381
- **Adapters**: Add basic functionality tests with mocked dependencies. Use `examples.json` to drive your tests.
382
-
383
- See [TESTING.md](TESTING.md) for complete examples and best practices.
384
-
385
- ## 💻 Local Development
386
-
387
- ### Setup
388
-
389
- ```bash
390
- # Clone repo
391
- git clone https://github.com/wayfinder-ai/wayfinder-paths.git
392
- cd wayfinder-paths
393
-
394
- # Install dependencies
395
- poetry install
396
-
397
- # Generate test wallets (essential!)
398
- # Creates a main wallet (or use 'just create-strategy' which auto-creates wallets)
399
- just create-wallets
400
- # Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
401
-
402
- # Copy and configure
403
- cp wayfinder_paths/config.example.json config.json
404
- # Edit config.json with your Wayfinder credentials
405
-
406
- # Run a strategy (status check)
407
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --action status --config config.json
408
-
409
- # Run with custom config
410
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config my_config.json
411
-
412
- # Run continuously with debug output
413
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --debug --config config.json
414
- ```
415
-
416
- ### Wallet Generation for Testing
417
-
418
- **Before running any strategies, generate test wallets.** This creates `config.json` in the repository root with throwaway wallets for local testing:
419
-
420
- ```bash
421
- # Essential: Create main wallet for testing
422
- just create-wallets
423
- # Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
424
- ```
425
-
426
- This creates:
427
-
428
- - `main` wallet - your main wallet for testing (labeled "main" in config.json)
429
- - `config.json` - wallet addresses and private keys for local testing
430
-
431
- **Note:** Strategy-specific wallets are automatically created when you use `just create-strategy "Strategy Name"`. For manual creation, use `just create-wallet "strategy_name"` or `poetry run python wayfinder_paths/scripts/make_wallets.py --label "strategy_name"`.
432
-
433
- **Important:** These wallets are for testing only. Never use them with real funds or on mainnet.
434
-
435
- **Per-Strategy Wallets:** Each strategy should have its own dedicated wallet. When you create a new strategy using `just create-strategy`, a wallet is automatically generated with a label matching the strategy directory name. The system automatically uses this wallet when running the strategy. See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
436
-
437
- Additional options:
438
-
439
- ```bash
440
- # Add 3 extra wallets for multi-account testing
441
- poetry run python wayfinder_paths/scripts/make_wallets.py -n 3
442
-
443
- # Create a wallet with a specific label (e.g., for a strategy)
444
- poetry run python wayfinder_paths/scripts/make_wallets.py --label "my_strategy_name"
445
-
446
- # Generate keystore files (for geth/web3 compatibility)
447
- poetry run python wayfinder_paths/scripts/make_wallets.py -n 1 --keystore-password "my-password"
448
- ```
449
-
450
- ### Configuration
451
-
452
- See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for detailed configuration documentation.
453
-
454
- #### Setup Configuration
455
-
456
- ```bash
457
- # Copy example config
458
- cp wayfinder_paths/config.example.json config.json
459
-
460
- # Edit config.json with your settings
461
- # Required fields:
462
- # - user.username: Your Wayfinder username
463
- # - user.password: Your Wayfinder password
464
- # - OR user.refresh_token: Your refresh token
465
- # - system.wallets_path: Path to config.json (default: "config.json")
466
- #
467
- # Wallet addresses are auto-loaded from config.json by default.
468
- # Then run with:
469
- poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config config.json
470
- ```
471
-
472
- ## 📦 Versioning
473
-
474
- This package follows [Semantic Versioning](https://semver.org/) (SemVer) and is published to PyPI as a public package.
475
-
476
- ### Version Format: MAJOR.MINOR.PATCH
477
-
478
- - **MAJOR** (X.0.0): Breaking changes that require code updates
479
- - **MINOR** (0.X.0): New features, backward compatible
480
- - **PATCH** (0.0.X): Bug fixes, backward compatible
481
-
482
- ### Version Bumping Rules
483
-
484
- - **PATCH**: Bug fixes, security patches, documentation updates
485
- - **MINOR**: New adapters, new strategies, new features (backward compatible)
486
- - **MAJOR**: Breaking API changes, removed features, incompatible changes
487
-
488
- ### Important Notes
489
-
490
- - **Versions are immutable**: Once published to PyPI, a version cannot be changed or deleted
491
- - **Versions must be unique**: Each release must have a new, unique version number
492
- - **Publishing is restricted**: Only publish from the `main` branch to prevent accidental releases
493
-
494
- ### Publishing Workflow and Order of Operations
495
-
496
- **Critical**: Changes must follow this strict order:
497
-
498
- 1. **Merge to main**: All changes must be merged to the `main` branch first
499
- 2. **Publish to PyPI**: The new version must be published to PyPI from `main` branch
500
- 3. **Dependent changes**: Only after publishing can dependent changes be merged in other applications
501
-
502
- **Why this order matters:**
503
-
504
- - Other applications depend on this package from PyPI
505
- - They cannot merge changes that depend on new versions until those versions are available on PyPI
506
- - Publishing from `main` ensures the published version matches what's in the repository
507
- - This prevents dependency resolution failures in downstream applications
508
-
509
- **Example workflow:**
510
-
511
- ```bash
512
- # 1. Make changes in a feature branch
513
- git checkout -b feature/new-adapter
514
- # ... make changes ...
515
- git commit -m "Add new adapter"
516
-
517
- # 2. Merge to main
518
- git checkout main
519
- git merge feature/new-adapter
520
-
521
- # 3. Bump version in pyproject.toml (e.g., 0.1.3 → 0.2.0)
522
- # Edit pyproject.toml: version = "0.2.0"
523
- git commit -m "Bump version to 0.2.0"
524
- git push origin main
525
-
526
- # 4. Publish to PyPI (must be on main branch)
527
- just publish
528
-
529
- # 5. Now dependent applications can update their dependencies
530
- # pip install wayfinder-paths==0.2.0
531
- ```
532
-
533
- ## 📦 Publishing
534
-
535
- Publish to PyPI:
536
-
537
- ```bash
538
- export PUBLISH_TOKEN="your_pypi_token"
539
- just publish
540
- ```
541
-
542
- **Important:**
543
-
544
- - ⚠️ **Publishing is only allowed from the `main` branch** - the publish command will fail if run from any other branch
545
- - ⚠️ **Versions must be unique** - ensure the version in `pyproject.toml` has been bumped and is unique
546
- - ⚠️ **Follow the order of operations** - see [Versioning](#-versioning) section above for the required workflow
547
- - ⚠️ **Versions are immutable** - once published, a version cannot be changed or deleted from PyPI
548
-
549
- Install the published package:
550
-
551
- ```bash
552
- pip install wayfinder-paths
553
- # or
554
- poetry add wayfinder-paths
555
- ```
556
-
557
- Install from Git (development):
558
-
559
- ```bash
560
- pip install git+https://github.com/wayfinder-ai/wayfinder-paths.git
561
- ```
562
-
563
- ### Managing Package Access
564
-
565
- To add collaborators who can publish updates:
566
-
567
- 1. Go to https://pypi.org/project/wayfinder-paths/
568
- 2. Click "Manage" → "Collaborators"
569
- 3. Add users as "Maintainers" (can publish) or "Owners" (full control)
570
-
571
- ## 🔒 Security
572
-
573
- - **Never hardcode API keys or Private keys** - use config.json for credentials
574
- - **Never commit config.json** - add it to .gitignore
575
- - **Test on testnet first** - use test network when available
576
- - **Validate all inputs** - sanitize user data
577
- - **Set gas limits** - prevent excessive fees
578
-
579
- ## 📊 Backtesting
580
-
581
- Coming soon
582
-
583
- ## 🌟 Community
584
-
585
- Need help or want to discuss strategies? Join our [Discord](https://discord.gg/fUVwGMXjm3)!
586
-
587
- ## 📄 License
588
-
589
- MIT License - see [LICENSE](LICENSE) file for details
590
-
591
- 🚀 **Happy Wayfinding!**
592
-