wayfinder-paths 0.1.6__tar.gz → 0.1.8__tar.gz
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.
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/PKG-INFO +32 -3
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/README.md +30 -2
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/pyproject.toml +2 -1
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/README.md +0 -10
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/adapter.py +0 -20
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -30
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/adapter.py +3 -2
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/test_adapter.py +9 -13
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +14 -7
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +18 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +1093 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/executor.py +549 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +8 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +1050 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +126 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +219 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +220 -0
- wayfinder_paths-0.1.8/wayfinder_paths/adapters/hyperliquid_adapter/utils.py +134 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/test_adapter.py +7 -6
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/README.md +3 -28
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/adapter.py +0 -72
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/examples.json +0 -43
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/test_adapter.py +4 -54
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/test_adapter.py +4 -14
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/adapters/models.py +9 -4
- wayfinder_paths-0.1.8/wayfinder_paths/core/analytics/__init__.py +11 -0
- wayfinder_paths-0.1.8/wayfinder_paths/core/analytics/bootstrap.py +57 -0
- wayfinder_paths-0.1.8/wayfinder_paths/core/analytics/stats.py +48 -0
- wayfinder_paths-0.1.8/wayfinder_paths/core/analytics/test_analytics.py +170 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/BRAPClient.py +1 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/LedgerClient.py +2 -7
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/PoolClient.py +0 -16
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/WalletClient.py +0 -27
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/protocols.py +104 -18
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/scripts/make_wallets.py +9 -0
- wayfinder_paths-0.1.8/wayfinder_paths/scripts/run_strategy.py +124 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/README.md +213 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/__init__.py +3 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/constants.py +1 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/examples.json +16 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml +23 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1011 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/strategy.py +4522 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +727 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/basis_trading_strategy/types.py +39 -0
- wayfinder_paths-0.1.8/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +8 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +36 -5
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +367 -278
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +204 -7
- wayfinder_paths-0.1.6/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +0 -16
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/LICENSE +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/CONFIG_GUIDE.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/abis/generic/erc20.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/hyperlend_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/ledger_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/pool_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/token_adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/config.example.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/conftest.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/adapters/BaseAdapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/adapters/base.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/AuthClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/ClientManager.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/HyperlendClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/SimulationClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/TokenClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/TransactionClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/WayfinderClient.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/clients/sdk_example.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/config.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/constants/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/constants/base.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/constants/erc20_abi.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/constants/hyperlend_abi.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/engine/StrategyJob.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/engine/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/engine/manifest.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/services/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/services/base.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/services/local_evm_txn.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/services/local_token_txn.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/services/web3_service.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/settings.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/strategies/Strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/strategies/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/strategies/base.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/strategies/descriptors.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/utils/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/utils/evm_helpers.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/utils/wallets.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/wallets/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/wallets/WalletManager.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/core/wallets/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/enso.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/erc20.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/evm.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/hyper_evm.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/hyperlend.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/hyperliquid.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/moonwell.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/prjx.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/policies/util.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/run_strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/scripts/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/scripts/create_strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/scripts/validate_manifests.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/config.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/adapter/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/adapter/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/adapter/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/strategy/README.md +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/strategy/examples.json +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/strategy/manifest.yaml +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/strategy/strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/templates/strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/tests/__init__.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/tests/test_smoke_manifest.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/tests/test_test_coverage.py +0 -0
- {wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wayfinder-paths
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Wayfinder Path: strategies and adapters
|
|
5
5
|
Author: Wayfinder
|
|
6
6
|
Author-email: dev@wayfinder.ai
|
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
10
10
|
Requires-Dist: aiohttp (>=3.13.0,<4.0.0)
|
|
11
11
|
Requires-Dist: eth-account (>=0.13.7,<0.14.0)
|
|
12
12
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
13
|
+
Requires-Dist: hyperliquid-python-sdk (>=0.21.0,<0.22.0)
|
|
13
14
|
Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
|
14
15
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
15
16
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
|
@@ -124,6 +125,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
124
125
|
### Contributor Guidelines
|
|
125
126
|
|
|
126
127
|
#### For Adapters
|
|
128
|
+
|
|
127
129
|
- **Start from the template**: Copy `wayfinder_paths/templates/adapter/` as a starting point
|
|
128
130
|
- Extend `BaseAdapter` from `wayfinder_paths/core/adapters/BaseAdapter.py`
|
|
129
131
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/adapter/manifest.yaml`) with:
|
|
@@ -137,6 +139,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
137
139
|
- Validate your manifest: `just validate-manifests`
|
|
138
140
|
|
|
139
141
|
#### For Strategies
|
|
142
|
+
|
|
140
143
|
- **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
|
|
141
144
|
- Extend `Strategy` from `wayfinder_paths/core/strategies/Strategy.py`
|
|
142
145
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/strategy/manifest.yaml`) with:
|
|
@@ -150,6 +153,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
150
153
|
- Validate your manifest: `just validate-manifests`
|
|
151
154
|
|
|
152
155
|
#### General Guidelines
|
|
156
|
+
|
|
153
157
|
- **Code Quality**: Follow existing patterns and use type hints
|
|
154
158
|
- **Testing**: See [TESTING.md](TESTING.md) - minimum: smoke test for strategies, basic tests for adapters
|
|
155
159
|
- **Documentation**: Update README files and add docstrings
|
|
@@ -204,6 +208,7 @@ poetry run python wayfinder_paths/run_strategy.py your_strategy --action status
|
|
|
204
208
|
## 🏗️ Architecture
|
|
205
209
|
|
|
206
210
|
### Client System
|
|
211
|
+
|
|
207
212
|
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.
|
|
208
213
|
|
|
209
214
|
### Clients vs Adapters
|
|
@@ -230,6 +235,7 @@ Adapter manifests declare the capabilities an adapter provides and the clients i
|
|
|
230
235
|
**Template:** Copy `wayfinder_paths/templates/adapter/manifest.yaml` as a starting point.
|
|
231
236
|
|
|
232
237
|
**Schema:**
|
|
238
|
+
|
|
233
239
|
```yaml
|
|
234
240
|
schema_version: "0.1"
|
|
235
241
|
entrypoint: "adapters.my_adapter.adapter.MyAdapter"
|
|
@@ -242,12 +248,14 @@ dependencies:
|
|
|
242
248
|
```
|
|
243
249
|
|
|
244
250
|
**Fields:**
|
|
251
|
+
|
|
245
252
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
246
253
|
- `entrypoint`: Full Python import path to the adapter class (required)
|
|
247
254
|
- `capabilities`: List of abstract capabilities this adapter provides (required, non-empty)
|
|
248
255
|
- `dependencies`: List of client class names from `core.clients` that this adapter requires (required, non-empty)
|
|
249
256
|
|
|
250
257
|
**Example** (`wayfinder_paths/adapters/pool_adapter/manifest.yaml`):
|
|
258
|
+
|
|
251
259
|
```yaml
|
|
252
260
|
schema_version: "0.1"
|
|
253
261
|
entrypoint: "adapters.pool_adapter.adapter.PoolAdapter"
|
|
@@ -268,6 +276,7 @@ Strategy manifests declare permissions and required adapters with their capabili
|
|
|
268
276
|
**Template:** Copy `wayfinder_paths/templates/strategy/manifest.yaml` as a starting point.
|
|
269
277
|
|
|
270
278
|
**Schema:**
|
|
279
|
+
|
|
271
280
|
```yaml
|
|
272
281
|
schema_version: "0.1"
|
|
273
282
|
entrypoint: "strategies.my_strategy.strategy.MyStrategy"
|
|
@@ -281,6 +290,7 @@ adapters:
|
|
|
281
290
|
```
|
|
282
291
|
|
|
283
292
|
**Fields:**
|
|
293
|
+
|
|
284
294
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
285
295
|
- `entrypoint`: Full Python import path to the strategy class (required)
|
|
286
296
|
- `name`: Strategy directory name (optional, used for wallet lookup - defaults to directory name)
|
|
@@ -290,6 +300,7 @@ adapters:
|
|
|
290
300
|
- `capabilities`: List of capabilities required from this adapter
|
|
291
301
|
|
|
292
302
|
**Example** (`wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml`):
|
|
303
|
+
|
|
293
304
|
```yaml
|
|
294
305
|
schema_version: "0.1"
|
|
295
306
|
entrypoint: "strategies.stablecoin_yield_strategy.strategy.StablecoinYieldStrategy"
|
|
@@ -307,12 +318,14 @@ adapters:
|
|
|
307
318
|
#### Manifest Validation
|
|
308
319
|
|
|
309
320
|
Manifests are automatically validated to ensure:
|
|
321
|
+
|
|
310
322
|
- Schema compliance (all required fields present, correct types)
|
|
311
323
|
- Entrypoint classes exist and are importable
|
|
312
324
|
- Dependencies are valid client classes
|
|
313
325
|
- Permissions policies are non-empty
|
|
314
326
|
|
|
315
327
|
**Validate locally:**
|
|
328
|
+
|
|
316
329
|
```bash
|
|
317
330
|
# Validate all manifests
|
|
318
331
|
just validate-manifests
|
|
@@ -347,6 +360,7 @@ The `validate_manifests.py` script performs multi-stage validation:
|
|
|
347
360
|
- Policy syntax is not parsed/validated (assumed to be valid at runtime)
|
|
348
361
|
|
|
349
362
|
**Validation Flow:**
|
|
363
|
+
|
|
350
364
|
```
|
|
351
365
|
For each manifest file:
|
|
352
366
|
1. Load YAML → Parse with Pydantic (schema validation)
|
|
@@ -356,6 +370,7 @@ For each manifest file:
|
|
|
356
370
|
```
|
|
357
371
|
|
|
358
372
|
The script automatically discovers all manifests by scanning:
|
|
373
|
+
|
|
359
374
|
- `wayfinder_paths/adapters/*/manifest.yaml` for adapter manifests
|
|
360
375
|
- `wayfinder_paths/strategies/*/manifest.yaml` for strategy manifests
|
|
361
376
|
|
|
@@ -366,12 +381,15 @@ All errors are collected and reported at the end, with the script exiting with c
|
|
|
366
381
|
Capabilities are abstract operation identifiers (e.g., `"pool.read"`, `"swap.execute"`) declared in manifests. They represent what operations an adapter can perform, not specific method names. The manifest is the **single source of truth** for capabilities—they are not duplicated in code.
|
|
367
382
|
|
|
368
383
|
When creating an adapter:
|
|
384
|
+
|
|
369
385
|
1. Declare capabilities in your `manifest.yaml`
|
|
370
386
|
2. Implement methods that fulfill those capabilities
|
|
371
387
|
3. Capabilities are validated at manifest validation time (entrypoint must be importable)
|
|
372
388
|
|
|
373
389
|
### Configuration
|
|
390
|
+
|
|
374
391
|
Configuration is split between:
|
|
392
|
+
|
|
375
393
|
- **User Config**: Your credentials and preferences
|
|
376
394
|
- **System Config**: Platform settings
|
|
377
395
|
- **Strategy Config**: Strategy-specific parameters
|
|
@@ -383,9 +401,11 @@ See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
|
|
|
383
401
|
Wayfinder Paths supports two authentication methods:
|
|
384
402
|
|
|
385
403
|
#### 1. Service Account Authentication (API Key)
|
|
404
|
+
|
|
386
405
|
For backend services and automated systems with higher rate limits:
|
|
387
406
|
|
|
388
407
|
**Option A: Pass to Strategy Constructor**
|
|
408
|
+
|
|
389
409
|
```python
|
|
390
410
|
from wayfinder_paths.strategies.stablecoin_yield_strategy.strategy import StablecoinYieldStrategy
|
|
391
411
|
|
|
@@ -396,19 +416,21 @@ strategy = StablecoinYieldStrategy(
|
|
|
396
416
|
```
|
|
397
417
|
|
|
398
418
|
**Option B: Set Environment Variable**
|
|
419
|
+
|
|
399
420
|
```bash
|
|
400
421
|
export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
401
422
|
# All clients will automatically discover and use this
|
|
402
423
|
```
|
|
403
424
|
|
|
404
425
|
**Option C: Add to config.json**
|
|
426
|
+
|
|
405
427
|
```json
|
|
406
428
|
{
|
|
407
429
|
"user": {
|
|
408
430
|
"api_key": "sk_live_abc123..."
|
|
409
431
|
},
|
|
410
432
|
"system": {
|
|
411
|
-
"api_key": "sk_live_abc123..."
|
|
433
|
+
"api_key": "sk_live_abc123..." // Alternative: system-level API key
|
|
412
434
|
}
|
|
413
435
|
}
|
|
414
436
|
```
|
|
@@ -418,6 +440,7 @@ export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
|
418
440
|
**Note:** API keys in `config.json` are loaded directly by `WayfinderClient` via `_load_config_credentials()`, not through the `UserConfig` or `SystemConfig` dataclasses. This allows flexible credential loading.
|
|
419
441
|
|
|
420
442
|
#### 2. Personal Access Authentication (OAuth)
|
|
443
|
+
|
|
421
444
|
For standalone SDK users with username/password:
|
|
422
445
|
|
|
423
446
|
```json
|
|
@@ -425,12 +448,13 @@ For standalone SDK users with username/password:
|
|
|
425
448
|
"user": {
|
|
426
449
|
"username": "your_username",
|
|
427
450
|
"password": "your_password",
|
|
428
|
-
"refresh_token": null
|
|
451
|
+
"refresh_token": null // Optional: use refresh token instead
|
|
429
452
|
}
|
|
430
453
|
}
|
|
431
454
|
```
|
|
432
455
|
|
|
433
456
|
**How It Works:**
|
|
457
|
+
|
|
434
458
|
- API keys are automatically discovered by all clients (no need to pass explicitly)
|
|
435
459
|
- When an API key is available, it's used for all API requests (including public endpoints) for rate limiting
|
|
436
460
|
- If no API key is found, the system falls back to OAuth authentication
|
|
@@ -613,6 +637,7 @@ just create-wallets
|
|
|
613
637
|
```
|
|
614
638
|
|
|
615
639
|
This creates:
|
|
640
|
+
|
|
616
641
|
- `main` wallet - your main wallet for testing (labeled "main" in wallets.json)
|
|
617
642
|
- `wallets.json` - wallet addresses and private keys for local testing
|
|
618
643
|
|
|
@@ -688,12 +713,14 @@ This package follows [Semantic Versioning](https://semver.org/) (SemVer) and is
|
|
|
688
713
|
3. **Dependent changes**: Only after publishing can dependent changes be merged in other applications
|
|
689
714
|
|
|
690
715
|
**Why this order matters:**
|
|
716
|
+
|
|
691
717
|
- Other applications depend on this package from PyPI
|
|
692
718
|
- They cannot merge changes that depend on new versions until those versions are available on PyPI
|
|
693
719
|
- Publishing from `main` ensures the published version matches what's in the repository
|
|
694
720
|
- This prevents dependency resolution failures in downstream applications
|
|
695
721
|
|
|
696
722
|
**Example workflow:**
|
|
723
|
+
|
|
697
724
|
```bash
|
|
698
725
|
# 1. Make changes in a feature branch
|
|
699
726
|
git checkout -b feature/new-adapter
|
|
@@ -726,6 +753,7 @@ just publish
|
|
|
726
753
|
```
|
|
727
754
|
|
|
728
755
|
**Important:**
|
|
756
|
+
|
|
729
757
|
- ⚠️ **Publishing is only allowed from the `main` branch** - the publish command will fail if run from any other branch
|
|
730
758
|
- ⚠️ **Versions must be unique** - ensure the version in `pyproject.toml` has been bumped and is unique
|
|
731
759
|
- ⚠️ **Follow the order of operations** - see [Versioning](#-versioning) section above for the required workflow
|
|
@@ -748,6 +776,7 @@ pip install git+https://github.com/wayfinder-ai/wayfinder-paths.git
|
|
|
748
776
|
### Managing Package Access
|
|
749
777
|
|
|
750
778
|
To add collaborators who can publish updates:
|
|
779
|
+
|
|
751
780
|
1. Go to https://pypi.org/project/wayfinder-paths/
|
|
752
781
|
2. Click "Manage" → "Collaborators"
|
|
753
782
|
3. Add users as "Maintainers" (can publish) or "Owners" (full control)
|
|
@@ -102,6 +102,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
102
102
|
### Contributor Guidelines
|
|
103
103
|
|
|
104
104
|
#### For Adapters
|
|
105
|
+
|
|
105
106
|
- **Start from the template**: Copy `wayfinder_paths/templates/adapter/` as a starting point
|
|
106
107
|
- Extend `BaseAdapter` from `wayfinder_paths/core/adapters/BaseAdapter.py`
|
|
107
108
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/adapter/manifest.yaml`) with:
|
|
@@ -115,6 +116,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
115
116
|
- Validate your manifest: `just validate-manifests`
|
|
116
117
|
|
|
117
118
|
#### For Strategies
|
|
119
|
+
|
|
118
120
|
- **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
|
|
119
121
|
- Extend `Strategy` from `wayfinder_paths/core/strategies/Strategy.py`
|
|
120
122
|
- Create a `manifest.yaml` (template at `wayfinder_paths/templates/strategy/manifest.yaml`) with:
|
|
@@ -128,6 +130,7 @@ We welcome contributions! This is an open-source project where community members
|
|
|
128
130
|
- Validate your manifest: `just validate-manifests`
|
|
129
131
|
|
|
130
132
|
#### General Guidelines
|
|
133
|
+
|
|
131
134
|
- **Code Quality**: Follow existing patterns and use type hints
|
|
132
135
|
- **Testing**: See [TESTING.md](TESTING.md) - minimum: smoke test for strategies, basic tests for adapters
|
|
133
136
|
- **Documentation**: Update README files and add docstrings
|
|
@@ -182,6 +185,7 @@ poetry run python wayfinder_paths/run_strategy.py your_strategy --action status
|
|
|
182
185
|
## 🏗️ Architecture
|
|
183
186
|
|
|
184
187
|
### Client System
|
|
188
|
+
|
|
185
189
|
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.
|
|
186
190
|
|
|
187
191
|
### Clients vs Adapters
|
|
@@ -208,6 +212,7 @@ Adapter manifests declare the capabilities an adapter provides and the clients i
|
|
|
208
212
|
**Template:** Copy `wayfinder_paths/templates/adapter/manifest.yaml` as a starting point.
|
|
209
213
|
|
|
210
214
|
**Schema:**
|
|
215
|
+
|
|
211
216
|
```yaml
|
|
212
217
|
schema_version: "0.1"
|
|
213
218
|
entrypoint: "adapters.my_adapter.adapter.MyAdapter"
|
|
@@ -220,12 +225,14 @@ dependencies:
|
|
|
220
225
|
```
|
|
221
226
|
|
|
222
227
|
**Fields:**
|
|
228
|
+
|
|
223
229
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
224
230
|
- `entrypoint`: Full Python import path to the adapter class (required)
|
|
225
231
|
- `capabilities`: List of abstract capabilities this adapter provides (required, non-empty)
|
|
226
232
|
- `dependencies`: List of client class names from `core.clients` that this adapter requires (required, non-empty)
|
|
227
233
|
|
|
228
234
|
**Example** (`wayfinder_paths/adapters/pool_adapter/manifest.yaml`):
|
|
235
|
+
|
|
229
236
|
```yaml
|
|
230
237
|
schema_version: "0.1"
|
|
231
238
|
entrypoint: "adapters.pool_adapter.adapter.PoolAdapter"
|
|
@@ -246,6 +253,7 @@ Strategy manifests declare permissions and required adapters with their capabili
|
|
|
246
253
|
**Template:** Copy `wayfinder_paths/templates/strategy/manifest.yaml` as a starting point.
|
|
247
254
|
|
|
248
255
|
**Schema:**
|
|
256
|
+
|
|
249
257
|
```yaml
|
|
250
258
|
schema_version: "0.1"
|
|
251
259
|
entrypoint: "strategies.my_strategy.strategy.MyStrategy"
|
|
@@ -259,6 +267,7 @@ adapters:
|
|
|
259
267
|
```
|
|
260
268
|
|
|
261
269
|
**Fields:**
|
|
270
|
+
|
|
262
271
|
- `schema_version`: Manifest schema version (currently `"0.1"`)
|
|
263
272
|
- `entrypoint`: Full Python import path to the strategy class (required)
|
|
264
273
|
- `name`: Strategy directory name (optional, used for wallet lookup - defaults to directory name)
|
|
@@ -268,6 +277,7 @@ adapters:
|
|
|
268
277
|
- `capabilities`: List of capabilities required from this adapter
|
|
269
278
|
|
|
270
279
|
**Example** (`wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml`):
|
|
280
|
+
|
|
271
281
|
```yaml
|
|
272
282
|
schema_version: "0.1"
|
|
273
283
|
entrypoint: "strategies.stablecoin_yield_strategy.strategy.StablecoinYieldStrategy"
|
|
@@ -285,12 +295,14 @@ adapters:
|
|
|
285
295
|
#### Manifest Validation
|
|
286
296
|
|
|
287
297
|
Manifests are automatically validated to ensure:
|
|
298
|
+
|
|
288
299
|
- Schema compliance (all required fields present, correct types)
|
|
289
300
|
- Entrypoint classes exist and are importable
|
|
290
301
|
- Dependencies are valid client classes
|
|
291
302
|
- Permissions policies are non-empty
|
|
292
303
|
|
|
293
304
|
**Validate locally:**
|
|
305
|
+
|
|
294
306
|
```bash
|
|
295
307
|
# Validate all manifests
|
|
296
308
|
just validate-manifests
|
|
@@ -325,6 +337,7 @@ The `validate_manifests.py` script performs multi-stage validation:
|
|
|
325
337
|
- Policy syntax is not parsed/validated (assumed to be valid at runtime)
|
|
326
338
|
|
|
327
339
|
**Validation Flow:**
|
|
340
|
+
|
|
328
341
|
```
|
|
329
342
|
For each manifest file:
|
|
330
343
|
1. Load YAML → Parse with Pydantic (schema validation)
|
|
@@ -334,6 +347,7 @@ For each manifest file:
|
|
|
334
347
|
```
|
|
335
348
|
|
|
336
349
|
The script automatically discovers all manifests by scanning:
|
|
350
|
+
|
|
337
351
|
- `wayfinder_paths/adapters/*/manifest.yaml` for adapter manifests
|
|
338
352
|
- `wayfinder_paths/strategies/*/manifest.yaml` for strategy manifests
|
|
339
353
|
|
|
@@ -344,12 +358,15 @@ All errors are collected and reported at the end, with the script exiting with c
|
|
|
344
358
|
Capabilities are abstract operation identifiers (e.g., `"pool.read"`, `"swap.execute"`) declared in manifests. They represent what operations an adapter can perform, not specific method names. The manifest is the **single source of truth** for capabilities—they are not duplicated in code.
|
|
345
359
|
|
|
346
360
|
When creating an adapter:
|
|
361
|
+
|
|
347
362
|
1. Declare capabilities in your `manifest.yaml`
|
|
348
363
|
2. Implement methods that fulfill those capabilities
|
|
349
364
|
3. Capabilities are validated at manifest validation time (entrypoint must be importable)
|
|
350
365
|
|
|
351
366
|
### Configuration
|
|
367
|
+
|
|
352
368
|
Configuration is split between:
|
|
369
|
+
|
|
353
370
|
- **User Config**: Your credentials and preferences
|
|
354
371
|
- **System Config**: Platform settings
|
|
355
372
|
- **Strategy Config**: Strategy-specific parameters
|
|
@@ -361,9 +378,11 @@ See [CONFIG_GUIDE.md](wayfinder_paths/CONFIG_GUIDE.md) for details.
|
|
|
361
378
|
Wayfinder Paths supports two authentication methods:
|
|
362
379
|
|
|
363
380
|
#### 1. Service Account Authentication (API Key)
|
|
381
|
+
|
|
364
382
|
For backend services and automated systems with higher rate limits:
|
|
365
383
|
|
|
366
384
|
**Option A: Pass to Strategy Constructor**
|
|
385
|
+
|
|
367
386
|
```python
|
|
368
387
|
from wayfinder_paths.strategies.stablecoin_yield_strategy.strategy import StablecoinYieldStrategy
|
|
369
388
|
|
|
@@ -374,19 +393,21 @@ strategy = StablecoinYieldStrategy(
|
|
|
374
393
|
```
|
|
375
394
|
|
|
376
395
|
**Option B: Set Environment Variable**
|
|
396
|
+
|
|
377
397
|
```bash
|
|
378
398
|
export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
379
399
|
# All clients will automatically discover and use this
|
|
380
400
|
```
|
|
381
401
|
|
|
382
402
|
**Option C: Add to config.json**
|
|
403
|
+
|
|
383
404
|
```json
|
|
384
405
|
{
|
|
385
406
|
"user": {
|
|
386
407
|
"api_key": "sk_live_abc123..."
|
|
387
408
|
},
|
|
388
409
|
"system": {
|
|
389
|
-
"api_key": "sk_live_abc123..."
|
|
410
|
+
"api_key": "sk_live_abc123..." // Alternative: system-level API key
|
|
390
411
|
}
|
|
391
412
|
}
|
|
392
413
|
```
|
|
@@ -396,6 +417,7 @@ export WAYFINDER_API_KEY="sk_live_abc123..."
|
|
|
396
417
|
**Note:** API keys in `config.json` are loaded directly by `WayfinderClient` via `_load_config_credentials()`, not through the `UserConfig` or `SystemConfig` dataclasses. This allows flexible credential loading.
|
|
397
418
|
|
|
398
419
|
#### 2. Personal Access Authentication (OAuth)
|
|
420
|
+
|
|
399
421
|
For standalone SDK users with username/password:
|
|
400
422
|
|
|
401
423
|
```json
|
|
@@ -403,12 +425,13 @@ For standalone SDK users with username/password:
|
|
|
403
425
|
"user": {
|
|
404
426
|
"username": "your_username",
|
|
405
427
|
"password": "your_password",
|
|
406
|
-
"refresh_token": null
|
|
428
|
+
"refresh_token": null // Optional: use refresh token instead
|
|
407
429
|
}
|
|
408
430
|
}
|
|
409
431
|
```
|
|
410
432
|
|
|
411
433
|
**How It Works:**
|
|
434
|
+
|
|
412
435
|
- API keys are automatically discovered by all clients (no need to pass explicitly)
|
|
413
436
|
- When an API key is available, it's used for all API requests (including public endpoints) for rate limiting
|
|
414
437
|
- If no API key is found, the system falls back to OAuth authentication
|
|
@@ -591,6 +614,7 @@ just create-wallets
|
|
|
591
614
|
```
|
|
592
615
|
|
|
593
616
|
This creates:
|
|
617
|
+
|
|
594
618
|
- `main` wallet - your main wallet for testing (labeled "main" in wallets.json)
|
|
595
619
|
- `wallets.json` - wallet addresses and private keys for local testing
|
|
596
620
|
|
|
@@ -666,12 +690,14 @@ This package follows [Semantic Versioning](https://semver.org/) (SemVer) and is
|
|
|
666
690
|
3. **Dependent changes**: Only after publishing can dependent changes be merged in other applications
|
|
667
691
|
|
|
668
692
|
**Why this order matters:**
|
|
693
|
+
|
|
669
694
|
- Other applications depend on this package from PyPI
|
|
670
695
|
- They cannot merge changes that depend on new versions until those versions are available on PyPI
|
|
671
696
|
- Publishing from `main` ensures the published version matches what's in the repository
|
|
672
697
|
- This prevents dependency resolution failures in downstream applications
|
|
673
698
|
|
|
674
699
|
**Example workflow:**
|
|
700
|
+
|
|
675
701
|
```bash
|
|
676
702
|
# 1. Make changes in a feature branch
|
|
677
703
|
git checkout -b feature/new-adapter
|
|
@@ -704,6 +730,7 @@ just publish
|
|
|
704
730
|
```
|
|
705
731
|
|
|
706
732
|
**Important:**
|
|
733
|
+
|
|
707
734
|
- ⚠️ **Publishing is only allowed from the `main` branch** - the publish command will fail if run from any other branch
|
|
708
735
|
- ⚠️ **Versions must be unique** - ensure the version in `pyproject.toml` has been bumped and is unique
|
|
709
736
|
- ⚠️ **Follow the order of operations** - see [Versioning](#-versioning) section above for the required workflow
|
|
@@ -726,6 +753,7 @@ pip install git+https://github.com/wayfinder-ai/wayfinder-paths.git
|
|
|
726
753
|
### Managing Package Access
|
|
727
754
|
|
|
728
755
|
To add collaborators who can publish updates:
|
|
756
|
+
|
|
729
757
|
1. Go to https://pypi.org/project/wayfinder-paths/
|
|
730
758
|
2. Click "Manage" → "Collaborators"
|
|
731
759
|
3. Add users as "Maintainers" (can publish) or "Owners" (full control)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "wayfinder-paths"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.8"
|
|
4
4
|
description = "Wayfinder Path: strategies and adapters"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = ["Wayfinder <dev@wayfinder.ai>"]
|
|
@@ -21,6 +21,7 @@ python-dotenv = "^1.1.1"
|
|
|
21
21
|
aiohttp = "^3.13.0"
|
|
22
22
|
numpy = "^1.26.0"
|
|
23
23
|
pandas = "^2.2.0"
|
|
24
|
+
hyperliquid-python-sdk = "^0.21.0"
|
|
24
25
|
|
|
25
26
|
[tool.poetry.group.dev.dependencies]
|
|
26
27
|
pytest = "^8.4.2"
|
{wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/README.md
RENAMED
|
@@ -45,16 +45,6 @@ success, amount = await balance.get_pool_balance(
|
|
|
45
45
|
)
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
### `get_all_balances(wallet_address: str, enrich=True, from_cache=False, add_llama=True)`
|
|
49
|
-
Returns the enriched token balance payload Wayfinder exposes (including USD value, metadata, and optional DeFi Llama overlays).
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
success, snapshot = await balance.get_all_balances(
|
|
53
|
-
wallet_address=config["strategy_wallet"]["address"],
|
|
54
|
-
enrich=True,
|
|
55
|
-
)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
48
|
### `move_from_main_wallet_to_strategy_wallet(token_id: str, amount: float, strategy_name="unknown", skip_ledger=False)`
|
|
59
49
|
Sends the specified token from the configured `main_wallet` to the strategy wallet, records the ledger deposit (unless `skip_ledger=True`), and returns the `(success, tx_result)` tuple from the underlying send helper.
|
|
60
50
|
|
{wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/balance_adapter/adapter.py
RENAMED
|
@@ -236,23 +236,3 @@ class BalanceAdapter(BaseAdapter):
|
|
|
236
236
|
return (True, self._parse_balance(raw))
|
|
237
237
|
except Exception as e:
|
|
238
238
|
return (False, str(e))
|
|
239
|
-
|
|
240
|
-
async def get_all_balances(
|
|
241
|
-
self,
|
|
242
|
-
*,
|
|
243
|
-
wallet_address: str,
|
|
244
|
-
enrich: bool = True,
|
|
245
|
-
from_cache: bool = False,
|
|
246
|
-
add_llama: bool = True,
|
|
247
|
-
) -> tuple[bool, Any]:
|
|
248
|
-
"""Get all enriched token balances for a wallet."""
|
|
249
|
-
try:
|
|
250
|
-
data = await self.wallet_client.get_all_enriched_token_balances_for_wallet(
|
|
251
|
-
wallet_address=wallet_address,
|
|
252
|
-
enrich=enrich,
|
|
253
|
-
from_cache=from_cache,
|
|
254
|
-
add_llama=add_llama,
|
|
255
|
-
)
|
|
256
|
-
return (True, data)
|
|
257
|
-
except Exception as e:
|
|
258
|
-
return (False, str(e))
|
|
@@ -54,36 +54,6 @@ class TestBalanceAdapter:
|
|
|
54
54
|
ok = await adapter.connect()
|
|
55
55
|
assert isinstance(ok, bool)
|
|
56
56
|
|
|
57
|
-
@pytest.mark.asyncio
|
|
58
|
-
async def test_get_all_enriched_token_balances_for_wallet_success(
|
|
59
|
-
self, adapter, mock_wallet_client
|
|
60
|
-
):
|
|
61
|
-
"""Test successful retrieval of enriched token balances"""
|
|
62
|
-
mock_response = {
|
|
63
|
-
"balances": [
|
|
64
|
-
{
|
|
65
|
-
"token_id": "usd-coin-base",
|
|
66
|
-
"symbol": "USDC",
|
|
67
|
-
"balance": "1000000000",
|
|
68
|
-
"usd_value": 1000.0,
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
"total_usd_value": 1000.0,
|
|
72
|
-
}
|
|
73
|
-
mock_wallet_client.get_all_enriched_token_balances_for_wallet = AsyncMock(
|
|
74
|
-
return_value=(True, mock_response)
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
success, data = await adapter.get_all_balances(
|
|
78
|
-
wallet_address="0x1234567890123456789012345678901234567890",
|
|
79
|
-
enrich=True,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
assert success is True
|
|
83
|
-
assert isinstance(data, (dict, tuple))
|
|
84
|
-
if isinstance(data, dict):
|
|
85
|
-
assert "balances" in data
|
|
86
|
-
|
|
87
57
|
def test_adapter_type(self, adapter):
|
|
88
58
|
"""Test adapter has adapter_type"""
|
|
89
59
|
assert adapter.adapter_type == "BALANCE"
|
{wayfinder_paths-0.1.6 → wayfinder_paths-0.1.8}/wayfinder_paths/adapters/brap_adapter/adapter.py
RENAMED
|
@@ -147,8 +147,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
147
147
|
)
|
|
148
148
|
|
|
149
149
|
# Extract best quote from response
|
|
150
|
-
|
|
151
|
-
best_quote = quotes.get("best_quote")
|
|
150
|
+
best_quote = data["best_route"]
|
|
152
151
|
|
|
153
152
|
if not best_quote:
|
|
154
153
|
return (False, "No quotes available")
|
|
@@ -631,6 +630,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
631
630
|
|
|
632
631
|
response = broadcast_response if isinstance(broadcast_response, dict) else {}
|
|
633
632
|
operation_data = SWAP(
|
|
633
|
+
adapter=self.adapter_type,
|
|
634
634
|
from_token_id=from_token.get("id"),
|
|
635
635
|
to_token_id=to_token.get("id"),
|
|
636
636
|
from_amount=quote.get("input_amount"),
|
|
@@ -638,6 +638,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
638
638
|
from_amount_usd=from_amount_usd or 0,
|
|
639
639
|
to_amount_usd=to_amount_usd or 0,
|
|
640
640
|
transaction_hash=response.get("transaction_hash"),
|
|
641
|
+
transaction_chain_id=from_token.get("chain_id"),
|
|
641
642
|
transaction_status=response.get("transaction_status"),
|
|
642
643
|
transaction_receipt=response.get("transaction_receipt"),
|
|
643
644
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from types import SimpleNamespace
|
|
2
|
-
from unittest.mock import AsyncMock
|
|
2
|
+
from unittest.mock import AsyncMock
|
|
3
3
|
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
@@ -33,11 +33,9 @@ class TestBRAPAdapter:
|
|
|
33
33
|
@pytest.fixture
|
|
34
34
|
def adapter(self, mock_brap_client, mock_web3_service):
|
|
35
35
|
"""Create a BRAPAdapter instance with mocked client for testing"""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
):
|
|
40
|
-
return BRAPAdapter(web3_service=mock_web3_service)
|
|
36
|
+
adapter = BRAPAdapter(web3_service=mock_web3_service)
|
|
37
|
+
adapter.brap_client = mock_brap_client
|
|
38
|
+
return adapter
|
|
41
39
|
|
|
42
40
|
@pytest.mark.asyncio
|
|
43
41
|
async def test_get_swap_quote_success(self, adapter, mock_brap_client):
|
|
@@ -83,12 +81,10 @@ class TestBRAPAdapter:
|
|
|
83
81
|
async def test_get_best_quote_success(self, adapter, mock_brap_client):
|
|
84
82
|
"""Test successful best quote retrieval"""
|
|
85
83
|
mock_response = {
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"total_fee": "8000000000000000",
|
|
91
|
-
}
|
|
84
|
+
"best_route": {
|
|
85
|
+
"input_amount": "1000000000000000000",
|
|
86
|
+
"output_amount": "995000000000000000",
|
|
87
|
+
"total_fee": "8000000000000000",
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
mock_brap_client.get_quote = AsyncMock(return_value=mock_response)
|
|
@@ -110,7 +106,7 @@ class TestBRAPAdapter:
|
|
|
110
106
|
@pytest.mark.asyncio
|
|
111
107
|
async def test_get_best_quote_no_quotes(self, adapter, mock_brap_client):
|
|
112
108
|
"""Test best quote retrieval when no quotes available"""
|
|
113
|
-
mock_response = {"
|
|
109
|
+
mock_response = {"best_route": None}
|
|
114
110
|
mock_brap_client.get_quote = AsyncMock(return_value=mock_response)
|
|
115
111
|
|
|
116
112
|
success, data = await adapter.get_best_quote(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
from
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
from unittest.mock import AsyncMock
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
|
|
@@ -15,13 +16,19 @@ class TestHyperlendAdapter:
|
|
|
15
16
|
return mock_client
|
|
16
17
|
|
|
17
18
|
@pytest.fixture
|
|
18
|
-
def
|
|
19
|
+
def mock_web3_service(self):
|
|
20
|
+
"""Minimal Web3Service stub for adapter construction."""
|
|
21
|
+
return SimpleNamespace(token_transactions=SimpleNamespace())
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def adapter(self, mock_hyperlend_client, mock_web3_service):
|
|
19
25
|
"""Create a HyperlendAdapter instance with mocked client for testing"""
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
|
|
26
|
+
adapter = HyperlendAdapter(
|
|
27
|
+
config={},
|
|
28
|
+
web3_service=mock_web3_service,
|
|
29
|
+
)
|
|
30
|
+
adapter.hyperlend_client = mock_hyperlend_client
|
|
31
|
+
return adapter
|
|
25
32
|
|
|
26
33
|
@pytest.mark.asyncio
|
|
27
34
|
async def test_get_stable_markets_success(self, adapter, mock_hyperlend_client):
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .adapter import (
|
|
2
|
+
ARBITRUM_USDC_ADDRESS,
|
|
3
|
+
HYPERLIQUID_BRIDGE_ADDRESS,
|
|
4
|
+
HyperliquidAdapter,
|
|
5
|
+
)
|
|
6
|
+
from .executor import HyperliquidExecutor, LocalHyperliquidExecutor
|
|
7
|
+
from .paired_filler import FillConfig, FillConfirmCfg, PairedFiller
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"HyperliquidAdapter",
|
|
11
|
+
"HyperliquidExecutor",
|
|
12
|
+
"LocalHyperliquidExecutor",
|
|
13
|
+
"PairedFiller",
|
|
14
|
+
"FillConfig",
|
|
15
|
+
"FillConfirmCfg",
|
|
16
|
+
"HYPERLIQUID_BRIDGE_ADDRESS",
|
|
17
|
+
"ARBITRUM_USDC_ADDRESS",
|
|
18
|
+
]
|