wayfinder-paths 0.1.10__tar.gz → 0.1.13__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.
Potentially problematic release.
This version of wayfinder-paths might be problematic. Click here for more details.
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/PKG-INFO +15 -18
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/README.md +14 -15
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/pyproject.toml +2 -3
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/balance_adapter/adapter.py +3 -7
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/adapter.py +10 -13
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperlend_adapter/adapter.py +6 -9
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +1 -1
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/executor.py +44 -5
- wayfinder_paths-0.1.13/wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +104 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/moonwell_adapter/adapter.py +0 -3
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/README.md +4 -19
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/adapter.py +4 -29
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/examples.json +6 -7
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/test_adapter.py +8 -8
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/AuthClient.py +2 -2
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/BRAPClient.py +2 -2
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/HyperlendClient.py +2 -2
- wayfinder_paths-0.1.13/wayfinder_paths/core/clients/PoolClient.py +76 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/TokenClient.py +3 -3
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/WalletClient.py +2 -2
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/WayfinderClient.py +9 -10
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/protocols.py +1 -7
- wayfinder_paths-0.1.13/wayfinder_paths/core/config.py +254 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/services/base.py +0 -55
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/services/local_evm_txn.py +37 -134
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/strategies/Strategy.py +3 -3
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/strategies/descriptors.py +7 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/utils/evm_helpers.py +5 -28
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/utils/wallets.py +12 -19
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/wallets/README.md +1 -1
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/run_strategy.py +10 -8
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/scripts/create_strategy.py +5 -5
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/scripts/make_wallets.py +5 -5
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/scripts/run_strategy.py +3 -3
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -1
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/strategy.py +196 -515
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +228 -11
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -2
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +1 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +1 -1
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +8 -7
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +2 -2
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +25 -25
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +28 -9
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/adapter/README.md +1 -1
- wayfinder_paths-0.1.10/wayfinder_paths/CONFIG_GUIDE.md +0 -390
- wayfinder_paths-0.1.10/wayfinder_paths/config.example.json +0 -22
- wayfinder_paths-0.1.10/wayfinder_paths/core/clients/PoolClient.py +0 -112
- wayfinder_paths-0.1.10/wayfinder_paths/core/config.py +0 -418
- wayfinder_paths-0.1.10/wayfinder_paths/core/settings.py +0 -61
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/LICENSE +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/abis/generic/erc20.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/balance_adapter/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/balance_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/balance_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperlend_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/hyperliquid_adapter/utils.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/ledger_adapter/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/ledger_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/ledger_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/ledger_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/ledger_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/moonwell_adapter/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/moonwell_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/token_adapter/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/token_adapter/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/token_adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/token_adapter/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/token_adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/conftest.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/adapters/BaseAdapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/adapters/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/adapters/base.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/adapters/models.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/analytics/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/analytics/bootstrap.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/analytics/stats.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/analytics/test_analytics.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/ClientManager.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/LedgerClient.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/clients/sdk_example.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/constants/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/constants/base.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/constants/erc20_abi.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/constants/hyperlend_abi.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/constants/moonwell_abi.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/engine/StrategyJob.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/engine/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/services/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/services/local_token_txn.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/services/web3_service.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/strategies/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/strategies/base.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/utils/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/wallets/WalletManager.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/core/wallets/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/enso.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/erc20.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/evm.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/hyper_evm.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/hyperlend.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/hyperliquid.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/moonwell.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/prjx.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/policies/util.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/scripts/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/constants.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/basis_trading_strategy/types.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/config.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/strategies/stablecoin_yield_strategy/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/adapter/adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/adapter/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/adapter/test_adapter.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/strategy/README.md +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/strategy/examples.json +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/strategy/strategy.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/templates/strategy/test_strategy.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/tests/__init__.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/tests/test_smoke_manifest.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/tests/test_test_coverage.py +0 -0
- {wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/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.13
|
|
4
4
|
Summary: Wayfinder Path: strategies and adapters
|
|
5
5
|
Author: Wayfinder
|
|
6
6
|
Author-email: dev@wayfinder.ai
|
|
@@ -15,8 +15,6 @@ Requires-Dist: loguru (>=0.7.3,<0.8.0)
|
|
|
15
15
|
Requires-Dist: numpy (>=1.26.0,<2.0.0)
|
|
16
16
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
|
17
17
|
Requires-Dist: pydantic (>=2.11.9,<3.0.0)
|
|
18
|
-
Requires-Dist: pydantic-settings (>=2.7.0,<3.0.0)
|
|
19
|
-
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
20
18
|
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
21
19
|
Requires-Dist: web3 (>=7.13.0,<8.0.0)
|
|
22
20
|
Description-Content-Type: text/markdown
|
|
@@ -43,12 +41,12 @@ curl -sSL https://install.python-poetry.org | python3 -
|
|
|
43
41
|
poetry install
|
|
44
42
|
|
|
45
43
|
# ⚠️ Generate test wallets FIRST (required!)
|
|
46
|
-
# This creates
|
|
44
|
+
# This creates config.json with a main wallet for local testing
|
|
47
45
|
just create-wallets
|
|
48
46
|
# Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
|
|
49
47
|
|
|
50
48
|
# To test a specific strategy
|
|
51
|
-
just
|
|
49
|
+
just create-wallet stablecoin_yield_strategy
|
|
52
50
|
|
|
53
51
|
# Copy and configure
|
|
54
52
|
cp wayfinder_paths/config.example.json config.json
|
|
@@ -92,8 +90,7 @@ wayfinder_paths/
|
|
|
92
90
|
│ ├── config.example.json # Example configuration
|
|
93
91
|
│ ├── scripts/ # Utility scripts
|
|
94
92
|
│ └── run_strategy.py # Strategy runner script
|
|
95
|
-
├── config.json # Your local config
|
|
96
|
-
├── wallets.json # Generated dev wallets
|
|
93
|
+
├── config.json # Your local config with credentials and wallets
|
|
97
94
|
├── pyproject.toml # Poetry configuration
|
|
98
95
|
└── README.md # This file
|
|
99
96
|
```
|
|
@@ -302,7 +299,7 @@ class MyAdapter(BaseAdapter):
|
|
|
302
299
|
|
|
303
300
|
async def get_pools(self, pool_ids: list[str]):
|
|
304
301
|
data = await self.pool_client.get_pools_by_ids(
|
|
305
|
-
pool_ids=",".join(pool_ids)
|
|
302
|
+
pool_ids=",".join(pool_ids)
|
|
306
303
|
)
|
|
307
304
|
return (True, data)
|
|
308
305
|
```
|
|
@@ -374,11 +371,11 @@ class MyStrategy(Strategy):
|
|
|
374
371
|
|
|
375
372
|
The following strategies are available and can be run using the CLI:
|
|
376
373
|
|
|
377
|
-
| Strategy
|
|
378
|
-
|
|
379
|
-
| `basis_trading_strategy`
|
|
380
|
-
| `hyperlend_stable_yield_strategy` | Stable yield on HyperLend
|
|
381
|
-
| `moonwell_wsteth_loop_strategy`
|
|
374
|
+
| Strategy | Description | Chain |
|
|
375
|
+
| --------------------------------- | --------------------------- | -------- |
|
|
376
|
+
| `basis_trading_strategy` | Delta-neutral basis trading | - |
|
|
377
|
+
| `hyperlend_stable_yield_strategy` | Stable yield on HyperLend | HyperEVM |
|
|
378
|
+
| `moonwell_wsteth_loop_strategy` | Leveraged wstETH yield loop | Base |
|
|
382
379
|
|
|
383
380
|
#### Running Strategies
|
|
384
381
|
|
|
@@ -491,7 +488,7 @@ poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --de
|
|
|
491
488
|
|
|
492
489
|
### Wallet Generation for Testing
|
|
493
490
|
|
|
494
|
-
**Before running any strategies, generate test wallets.** This creates `
|
|
491
|
+
**Before running any strategies, generate test wallets.** This creates `config.json` in the repository root with throwaway wallets for local testing:
|
|
495
492
|
|
|
496
493
|
```bash
|
|
497
494
|
# Essential: Create main wallet for testing
|
|
@@ -501,8 +498,8 @@ just create-wallets
|
|
|
501
498
|
|
|
502
499
|
This creates:
|
|
503
500
|
|
|
504
|
-
- `main` wallet - your main wallet for testing (labeled "main" in
|
|
505
|
-
- `
|
|
501
|
+
- `main` wallet - your main wallet for testing (labeled "main" in config.json)
|
|
502
|
+
- `config.json` - wallet addresses and private keys for local testing
|
|
506
503
|
|
|
507
504
|
**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"`.
|
|
508
505
|
|
|
@@ -538,9 +535,9 @@ cp wayfinder_paths/config.example.json config.json
|
|
|
538
535
|
# - user.username: Your Wayfinder username
|
|
539
536
|
# - user.password: Your Wayfinder password
|
|
540
537
|
# - OR user.refresh_token: Your refresh token
|
|
541
|
-
# - system.wallets_path: Path to
|
|
538
|
+
# - system.wallets_path: Path to config.json (default: "config.json")
|
|
542
539
|
#
|
|
543
|
-
# Wallet addresses are auto-loaded from
|
|
540
|
+
# Wallet addresses are auto-loaded from config.json by default.
|
|
544
541
|
# Then run with:
|
|
545
542
|
poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config config.json
|
|
546
543
|
```
|
|
@@ -20,12 +20,12 @@ curl -sSL https://install.python-poetry.org | python3 -
|
|
|
20
20
|
poetry install
|
|
21
21
|
|
|
22
22
|
# ⚠️ Generate test wallets FIRST (required!)
|
|
23
|
-
# This creates
|
|
23
|
+
# This creates config.json with a main wallet for local testing
|
|
24
24
|
just create-wallets
|
|
25
25
|
# Or manually: poetry run python wayfinder_paths/scripts/make_wallets.py -n 1
|
|
26
26
|
|
|
27
27
|
# To test a specific strategy
|
|
28
|
-
just
|
|
28
|
+
just create-wallet stablecoin_yield_strategy
|
|
29
29
|
|
|
30
30
|
# Copy and configure
|
|
31
31
|
cp wayfinder_paths/config.example.json config.json
|
|
@@ -69,8 +69,7 @@ wayfinder_paths/
|
|
|
69
69
|
│ ├── config.example.json # Example configuration
|
|
70
70
|
│ ├── scripts/ # Utility scripts
|
|
71
71
|
│ └── run_strategy.py # Strategy runner script
|
|
72
|
-
├── config.json # Your local config
|
|
73
|
-
├── wallets.json # Generated dev wallets
|
|
72
|
+
├── config.json # Your local config with credentials and wallets
|
|
74
73
|
├── pyproject.toml # Poetry configuration
|
|
75
74
|
└── README.md # This file
|
|
76
75
|
```
|
|
@@ -279,7 +278,7 @@ class MyAdapter(BaseAdapter):
|
|
|
279
278
|
|
|
280
279
|
async def get_pools(self, pool_ids: list[str]):
|
|
281
280
|
data = await self.pool_client.get_pools_by_ids(
|
|
282
|
-
pool_ids=",".join(pool_ids)
|
|
281
|
+
pool_ids=",".join(pool_ids)
|
|
283
282
|
)
|
|
284
283
|
return (True, data)
|
|
285
284
|
```
|
|
@@ -351,11 +350,11 @@ class MyStrategy(Strategy):
|
|
|
351
350
|
|
|
352
351
|
The following strategies are available and can be run using the CLI:
|
|
353
352
|
|
|
354
|
-
| Strategy
|
|
355
|
-
|
|
356
|
-
| `basis_trading_strategy`
|
|
357
|
-
| `hyperlend_stable_yield_strategy` | Stable yield on HyperLend
|
|
358
|
-
| `moonwell_wsteth_loop_strategy`
|
|
353
|
+
| Strategy | Description | Chain |
|
|
354
|
+
| --------------------------------- | --------------------------- | -------- |
|
|
355
|
+
| `basis_trading_strategy` | Delta-neutral basis trading | - |
|
|
356
|
+
| `hyperlend_stable_yield_strategy` | Stable yield on HyperLend | HyperEVM |
|
|
357
|
+
| `moonwell_wsteth_loop_strategy` | Leveraged wstETH yield loop | Base |
|
|
359
358
|
|
|
360
359
|
#### Running Strategies
|
|
361
360
|
|
|
@@ -468,7 +467,7 @@ poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --de
|
|
|
468
467
|
|
|
469
468
|
### Wallet Generation for Testing
|
|
470
469
|
|
|
471
|
-
**Before running any strategies, generate test wallets.** This creates `
|
|
470
|
+
**Before running any strategies, generate test wallets.** This creates `config.json` in the repository root with throwaway wallets for local testing:
|
|
472
471
|
|
|
473
472
|
```bash
|
|
474
473
|
# Essential: Create main wallet for testing
|
|
@@ -478,8 +477,8 @@ just create-wallets
|
|
|
478
477
|
|
|
479
478
|
This creates:
|
|
480
479
|
|
|
481
|
-
- `main` wallet - your main wallet for testing (labeled "main" in
|
|
482
|
-
- `
|
|
480
|
+
- `main` wallet - your main wallet for testing (labeled "main" in config.json)
|
|
481
|
+
- `config.json` - wallet addresses and private keys for local testing
|
|
483
482
|
|
|
484
483
|
**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"`.
|
|
485
484
|
|
|
@@ -515,9 +514,9 @@ cp wayfinder_paths/config.example.json config.json
|
|
|
515
514
|
# - user.username: Your Wayfinder username
|
|
516
515
|
# - user.password: Your Wayfinder password
|
|
517
516
|
# - OR user.refresh_token: Your refresh token
|
|
518
|
-
# - system.wallets_path: Path to
|
|
517
|
+
# - system.wallets_path: Path to config.json (default: "config.json")
|
|
519
518
|
#
|
|
520
|
-
# Wallet addresses are auto-loaded from
|
|
519
|
+
# Wallet addresses are auto-loaded from config.json by default.
|
|
521
520
|
# Then run with:
|
|
522
521
|
poetry run python wayfinder_paths/run_strategy.py stablecoin_yield_strategy --config config.json
|
|
523
522
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "wayfinder-paths"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.13"
|
|
4
4
|
description = "Wayfinder Path: strategies and adapters"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = ["Wayfinder <dev@wayfinder.ai>"]
|
|
@@ -14,10 +14,8 @@ loguru = "^0.7.3"
|
|
|
14
14
|
httpx = "^0.28.1"
|
|
15
15
|
pyyaml = "^6.0.1"
|
|
16
16
|
pydantic = "^2.11.9"
|
|
17
|
-
pydantic-settings = "^2.7.0"
|
|
18
17
|
web3 = "^7.13.0"
|
|
19
18
|
eth-account = "^0.13.7"
|
|
20
|
-
python-dotenv = "^1.1.1"
|
|
21
19
|
aiohttp = "^3.13.0"
|
|
22
20
|
numpy = "^1.26.0"
|
|
23
21
|
pandas = "^2.2.0"
|
|
@@ -34,6 +32,7 @@ ruff = "^0.13.2"
|
|
|
34
32
|
bandit = "^1.7.5"
|
|
35
33
|
safety = "^2.3.5"
|
|
36
34
|
twine = "^6.2.0"
|
|
35
|
+
vulture = "^2.14"
|
|
37
36
|
|
|
38
37
|
[tool.ruff]
|
|
39
38
|
target-version = "py312"
|
|
@@ -7,7 +7,6 @@ from wayfinder_paths.core.clients.TokenClient import TokenClient
|
|
|
7
7
|
from wayfinder_paths.core.clients.WalletClient import WalletClient
|
|
8
8
|
from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
|
|
9
9
|
from wayfinder_paths.core.services.base import Web3Service
|
|
10
|
-
from wayfinder_paths.core.settings import settings
|
|
11
10
|
from wayfinder_paths.core.utils.evm_helpers import resolve_chain_id
|
|
12
11
|
|
|
13
12
|
|
|
@@ -129,12 +128,9 @@ class BalanceAdapter(BaseAdapter):
|
|
|
129
128
|
return False, tx_data
|
|
130
129
|
|
|
131
130
|
tx = tx_data
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
broadcast_result = await self.wallet_provider.broadcast_transaction(
|
|
136
|
-
tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
|
|
137
|
-
)
|
|
131
|
+
broadcast_result = await self.wallet_provider.broadcast_transaction(
|
|
132
|
+
tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
|
|
133
|
+
)
|
|
138
134
|
|
|
139
135
|
if broadcast_result[0] and not skip_ledger and ledger_method is not None:
|
|
140
136
|
wallet_for_ledger = from_address if ledger_wallet == "from" else to_address
|
{wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/brap_adapter/adapter.py
RENAMED
|
@@ -14,7 +14,6 @@ from wayfinder_paths.core.clients.TokenClient import TokenClient
|
|
|
14
14
|
from wayfinder_paths.core.constants import DEFAULT_SLIPPAGE, ZERO_ADDRESS
|
|
15
15
|
from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
|
|
16
16
|
from wayfinder_paths.core.services.base import Web3Service
|
|
17
|
-
from wayfinder_paths.core.settings import settings
|
|
18
17
|
|
|
19
18
|
_NEEDS_CLEAR_APPROVAL = {
|
|
20
19
|
(1, "0xdac17f958d2ee523a2206206994597c13d831ec7"),
|
|
@@ -339,16 +338,16 @@ class BRAPAdapter(BaseAdapter):
|
|
|
339
338
|
"all_routes": sorted_quotes,
|
|
340
339
|
"route_analysis": {
|
|
341
340
|
"highest_output": sorted_quotes[0] if sorted_quotes else None,
|
|
342
|
-
"lowest_fees":
|
|
343
|
-
all_quotes, key=lambda x: int(x.get("total_fee", 0))
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
"fastest":
|
|
348
|
-
all_quotes, key=lambda x: int(x.get("estimated_time", 0))
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
341
|
+
"lowest_fees": (
|
|
342
|
+
min(all_quotes, key=lambda x: int(x.get("total_fee", 0)))
|
|
343
|
+
if all_quotes
|
|
344
|
+
else None
|
|
345
|
+
),
|
|
346
|
+
"fastest": (
|
|
347
|
+
min(all_quotes, key=lambda x: int(x.get("estimated_time", 0)))
|
|
348
|
+
if all_quotes
|
|
349
|
+
else None
|
|
350
|
+
),
|
|
352
351
|
},
|
|
353
352
|
}
|
|
354
353
|
|
|
@@ -698,8 +697,6 @@ class BRAPAdapter(BaseAdapter):
|
|
|
698
697
|
async def _broadcast_transaction(
|
|
699
698
|
self, transaction: dict[str, Any], confirmations: int = 0
|
|
700
699
|
) -> tuple[bool, Any]:
|
|
701
|
-
if getattr(settings, "DRY_RUN", False):
|
|
702
|
-
return True, {"dry_run": True, "transaction": transaction}
|
|
703
700
|
return await self.wallet_provider.broadcast_transaction(
|
|
704
701
|
transaction,
|
|
705
702
|
wait_for_receipt=True,
|
|
@@ -18,7 +18,6 @@ from wayfinder_paths.core.constants.hyperlend_abi import (
|
|
|
18
18
|
WRAPPED_TOKEN_GATEWAY_ABI,
|
|
19
19
|
)
|
|
20
20
|
from wayfinder_paths.core.services.base import Web3Service
|
|
21
|
-
from wayfinder_paths.core.settings import settings
|
|
22
21
|
|
|
23
22
|
HYPERLEND_DEFAULTS = {
|
|
24
23
|
"pool": "0x00A89d7a5A02160f20150EbEA7a2b5E4879A1A8b",
|
|
@@ -136,7 +135,7 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
136
135
|
chain_id = int(chain_id)
|
|
137
136
|
|
|
138
137
|
if native:
|
|
139
|
-
tx = self._encode_call(
|
|
138
|
+
tx = await self._encode_call(
|
|
140
139
|
target=self.gateway_address,
|
|
141
140
|
abi=WRAPPED_TOKEN_GATEWAY_ABI,
|
|
142
141
|
fn_name="depositETH",
|
|
@@ -156,7 +155,7 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
156
155
|
)
|
|
157
156
|
if not approved[0]:
|
|
158
157
|
return approved
|
|
159
|
-
tx = self._encode_call(
|
|
158
|
+
tx = await self._encode_call(
|
|
160
159
|
target=self.pool_address,
|
|
161
160
|
abi=POOL_ABI,
|
|
162
161
|
fn_name="supply",
|
|
@@ -181,7 +180,7 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
181
180
|
chain_id = int(chain_id)
|
|
182
181
|
|
|
183
182
|
if native:
|
|
184
|
-
tx = self._encode_call(
|
|
183
|
+
tx = await self._encode_call(
|
|
185
184
|
target=self.gateway_address,
|
|
186
185
|
abi=WRAPPED_TOKEN_GATEWAY_ABI,
|
|
187
186
|
fn_name="withdrawETH",
|
|
@@ -191,7 +190,7 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
191
190
|
)
|
|
192
191
|
else:
|
|
193
192
|
token_addr = self._checksum(underlying_token)
|
|
194
|
-
tx = self._encode_call(
|
|
193
|
+
tx = await self._encode_call(
|
|
195
194
|
target=self.pool_address,
|
|
196
195
|
abi=POOL_ABI,
|
|
197
196
|
fn_name="withdraw",
|
|
@@ -237,13 +236,11 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
237
236
|
)
|
|
238
237
|
|
|
239
238
|
async def _broadcast_transaction(self, tx: dict[str, Any]) -> tuple[bool, Any]:
|
|
240
|
-
if getattr(settings, "DRY_RUN", False):
|
|
241
|
-
return True, {"dry_run": True, "transaction": tx}
|
|
242
239
|
return await self.web3.evm_transactions.broadcast_transaction(
|
|
243
240
|
tx, wait_for_receipt=True, timeout=DEFAULT_TRANSACTION_TIMEOUT
|
|
244
241
|
)
|
|
245
242
|
|
|
246
|
-
def _encode_call(
|
|
243
|
+
async def _encode_call(
|
|
247
244
|
self,
|
|
248
245
|
*,
|
|
249
246
|
target: str,
|
|
@@ -258,7 +255,7 @@ class HyperlendAdapter(BaseAdapter):
|
|
|
258
255
|
web3 = self.web3.get_web3(chain_id)
|
|
259
256
|
contract = web3.eth.contract(address=target, abi=abi)
|
|
260
257
|
try:
|
|
261
|
-
data = getattr(contract.functions, fn_name)(*args).build_transaction(
|
|
258
|
+
data = await getattr(contract.functions, fn_name)(*args).build_transaction(
|
|
262
259
|
{"from": from_address}
|
|
263
260
|
)["data"]
|
|
264
261
|
except ValueError as exc:
|
|
@@ -10,6 +10,7 @@ the protocol (for example, by delegating signing to a hosted signer).
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
12
|
import uuid
|
|
13
|
+
from collections.abc import Mapping
|
|
13
14
|
from typing import Any
|
|
14
15
|
|
|
15
16
|
from loguru import logger
|
|
@@ -86,11 +87,49 @@ class LocalHyperliquidExecutor:
|
|
|
86
87
|
)
|
|
87
88
|
self.info = Info(base_url, skip_ws=True)
|
|
88
89
|
self.exchange = Exchange(self._wallet, base_url)
|
|
90
|
+
self._asset_id_to_coin: dict[int, str] | None = None
|
|
89
91
|
|
|
90
92
|
logger.info(
|
|
91
93
|
f"LocalHyperliquidExecutor initialized for address: {self._wallet.address}"
|
|
92
94
|
)
|
|
93
95
|
|
|
96
|
+
def _get_perp_coin(self, asset_id: int) -> str | None:
|
|
97
|
+
"""
|
|
98
|
+
Resolve a perp coin name from a perp asset_id.
|
|
99
|
+
|
|
100
|
+
Note: newer versions of the hyperliquid SDK expose `coin_to_asset` but not
|
|
101
|
+
`asset_to_coin`, so we build the reverse mapping when needed.
|
|
102
|
+
"""
|
|
103
|
+
if self._asset_id_to_coin is None:
|
|
104
|
+
mapping: dict[int, str] = {}
|
|
105
|
+
|
|
106
|
+
asset_to_coin = getattr(self.info, "asset_to_coin", None)
|
|
107
|
+
if isinstance(asset_to_coin, Mapping):
|
|
108
|
+
for k, v in asset_to_coin.items():
|
|
109
|
+
try:
|
|
110
|
+
asset_int = int(k)
|
|
111
|
+
except (TypeError, ValueError):
|
|
112
|
+
continue
|
|
113
|
+
if v:
|
|
114
|
+
mapping[asset_int] = str(v)
|
|
115
|
+
|
|
116
|
+
coin_to_asset = getattr(self.info, "coin_to_asset", None)
|
|
117
|
+
try:
|
|
118
|
+
coin_to_asset_dict = dict(coin_to_asset) if coin_to_asset else {}
|
|
119
|
+
except Exception: # noqa: BLE001
|
|
120
|
+
coin_to_asset_dict = {}
|
|
121
|
+
for coin, aid in coin_to_asset_dict.items():
|
|
122
|
+
try:
|
|
123
|
+
asset_int = int(aid)
|
|
124
|
+
except (TypeError, ValueError):
|
|
125
|
+
continue
|
|
126
|
+
if coin and asset_int not in mapping:
|
|
127
|
+
mapping[asset_int] = str(coin)
|
|
128
|
+
|
|
129
|
+
self._asset_id_to_coin = mapping
|
|
130
|
+
|
|
131
|
+
return self._asset_id_to_coin.get(asset_id) if self._asset_id_to_coin else None
|
|
132
|
+
|
|
94
133
|
def _resolve_private_key(self, config: dict[str, Any]) -> str | None:
|
|
95
134
|
"""Extract private key from config."""
|
|
96
135
|
# Try strategy_wallet first
|
|
@@ -172,7 +211,7 @@ class LocalHyperliquidExecutor:
|
|
|
172
211
|
)
|
|
173
212
|
else:
|
|
174
213
|
# Perp market order
|
|
175
|
-
coin = self.
|
|
214
|
+
coin = self._get_perp_coin(asset_id)
|
|
176
215
|
if not coin:
|
|
177
216
|
return {
|
|
178
217
|
"status": "err",
|
|
@@ -231,7 +270,7 @@ class LocalHyperliquidExecutor:
|
|
|
231
270
|
spot_index = asset_id - 10000
|
|
232
271
|
coin = f"@{spot_index}"
|
|
233
272
|
else:
|
|
234
|
-
coin = self.
|
|
273
|
+
coin = self._get_perp_coin(asset_id)
|
|
235
274
|
if not coin:
|
|
236
275
|
return {
|
|
237
276
|
"status": "err",
|
|
@@ -268,7 +307,7 @@ class LocalHyperliquidExecutor:
|
|
|
268
307
|
}
|
|
269
308
|
|
|
270
309
|
try:
|
|
271
|
-
coin = self.
|
|
310
|
+
coin = self._get_perp_coin(asset_id)
|
|
272
311
|
if not coin:
|
|
273
312
|
return {
|
|
274
313
|
"status": "err",
|
|
@@ -366,7 +405,7 @@ class LocalHyperliquidExecutor:
|
|
|
366
405
|
}
|
|
367
406
|
|
|
368
407
|
try:
|
|
369
|
-
coin = self.
|
|
408
|
+
coin = self._get_perp_coin(asset_id)
|
|
370
409
|
if not coin:
|
|
371
410
|
return {
|
|
372
411
|
"status": "err",
|
|
@@ -439,7 +478,7 @@ class LocalHyperliquidExecutor:
|
|
|
439
478
|
spot_index = asset_id - 10000
|
|
440
479
|
coin = f"@{spot_index}"
|
|
441
480
|
else:
|
|
442
|
-
coin = self.
|
|
481
|
+
coin = self._get_perp_coin(asset_id)
|
|
443
482
|
if not coin:
|
|
444
483
|
return {
|
|
445
484
|
"status": "err",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Tests for LocalHyperliquidExecutor."""
|
|
2
|
+
|
|
3
|
+
from types import SimpleNamespace
|
|
4
|
+
from unittest.mock import MagicMock, patch
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestLocalHyperliquidExecutor:
|
|
10
|
+
"""Tests for LocalHyperliquidExecutor."""
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def mock_info_without_asset_to_coin(self):
|
|
14
|
+
"""Mock Info that only exposes coin_to_asset (no asset_to_coin)."""
|
|
15
|
+
return SimpleNamespace(coin_to_asset={"HYPE": 7})
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def mock_exchange(self):
|
|
19
|
+
"""Mock Exchange client."""
|
|
20
|
+
mock = MagicMock()
|
|
21
|
+
mock.update_leverage.return_value = {"status": "ok"}
|
|
22
|
+
mock.market_open.return_value = {"status": "ok"}
|
|
23
|
+
return mock
|
|
24
|
+
|
|
25
|
+
@pytest.mark.asyncio
|
|
26
|
+
async def test_update_leverage_works_without_asset_to_coin(
|
|
27
|
+
self, mock_info_without_asset_to_coin, mock_exchange
|
|
28
|
+
):
|
|
29
|
+
"""update_leverage should map asset_id->coin via coin_to_asset inversion."""
|
|
30
|
+
dummy_wallet = SimpleNamespace(address="0xabc")
|
|
31
|
+
|
|
32
|
+
with patch(
|
|
33
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Account"
|
|
34
|
+
) as mock_account:
|
|
35
|
+
mock_account.from_key.return_value = dummy_wallet
|
|
36
|
+
with patch(
|
|
37
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Info",
|
|
38
|
+
return_value=mock_info_without_asset_to_coin,
|
|
39
|
+
):
|
|
40
|
+
with patch(
|
|
41
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Exchange",
|
|
42
|
+
return_value=mock_exchange,
|
|
43
|
+
):
|
|
44
|
+
from wayfinder_paths.adapters.hyperliquid_adapter.executor import (
|
|
45
|
+
LocalHyperliquidExecutor,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
executor = LocalHyperliquidExecutor(
|
|
49
|
+
config={"strategy_wallet": {"private_key": "0x" + "11" * 32}}
|
|
50
|
+
)
|
|
51
|
+
resp = await executor.update_leverage(
|
|
52
|
+
asset_id=7,
|
|
53
|
+
leverage=1,
|
|
54
|
+
is_cross=True,
|
|
55
|
+
address="0xabc",
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
assert resp.get("status") == "ok"
|
|
59
|
+
mock_exchange.update_leverage.assert_called_once_with(
|
|
60
|
+
leverage=1,
|
|
61
|
+
name="HYPE",
|
|
62
|
+
is_cross=True,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
@pytest.mark.asyncio
|
|
66
|
+
async def test_place_market_order_perp_works_without_asset_to_coin(
|
|
67
|
+
self, mock_info_without_asset_to_coin, mock_exchange
|
|
68
|
+
):
|
|
69
|
+
"""place_market_order should map asset_id->coin via coin_to_asset inversion."""
|
|
70
|
+
dummy_wallet = SimpleNamespace(address="0xabc")
|
|
71
|
+
|
|
72
|
+
with patch(
|
|
73
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Account"
|
|
74
|
+
) as mock_account:
|
|
75
|
+
mock_account.from_key.return_value = dummy_wallet
|
|
76
|
+
with patch(
|
|
77
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Info",
|
|
78
|
+
return_value=mock_info_without_asset_to_coin,
|
|
79
|
+
):
|
|
80
|
+
with patch(
|
|
81
|
+
"wayfinder_paths.adapters.hyperliquid_adapter.executor.Exchange",
|
|
82
|
+
return_value=mock_exchange,
|
|
83
|
+
):
|
|
84
|
+
from wayfinder_paths.adapters.hyperliquid_adapter.executor import (
|
|
85
|
+
LocalHyperliquidExecutor,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
executor = LocalHyperliquidExecutor(
|
|
89
|
+
config={"strategy_wallet": {"private_key": "0x" + "11" * 32}}
|
|
90
|
+
)
|
|
91
|
+
resp = await executor.place_market_order(
|
|
92
|
+
asset_id=7,
|
|
93
|
+
is_buy=True,
|
|
94
|
+
slippage=0.01,
|
|
95
|
+
size=1.0,
|
|
96
|
+
address="0xabc",
|
|
97
|
+
reduce_only=False,
|
|
98
|
+
cloid=MagicMock(), # Avoid Cloid conversion
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
assert resp.get("status") == "ok"
|
|
102
|
+
mock_exchange.market_open.assert_called_once()
|
|
103
|
+
_, kwargs = mock_exchange.market_open.call_args
|
|
104
|
+
assert kwargs["name"] == "HYPE"
|
|
@@ -23,7 +23,6 @@ from wayfinder_paths.core.constants.moonwell_abi import (
|
|
|
23
23
|
WETH_ABI,
|
|
24
24
|
)
|
|
25
25
|
from wayfinder_paths.core.services.base import Web3Service
|
|
26
|
-
from wayfinder_paths.core.settings import settings
|
|
27
26
|
|
|
28
27
|
# Moonwell Base chain addresses
|
|
29
28
|
MOONWELL_DEFAULTS = {
|
|
@@ -1149,8 +1148,6 @@ class MoonwellAdapter(BaseAdapter):
|
|
|
1149
1148
|
|
|
1150
1149
|
Includes retry logic with exponential backoff for rate-limited RPCs.
|
|
1151
1150
|
"""
|
|
1152
|
-
if getattr(settings, "DRY_RUN", False):
|
|
1153
|
-
return True, {"dry_run": True, "transaction": tx}
|
|
1154
1151
|
if not self.web3:
|
|
1155
1152
|
return False, "web3 service not configured"
|
|
1156
1153
|
|
{wayfinder_paths-0.1.10 → wayfinder_paths-0.1.13}/wayfinder_paths/adapters/pool_adapter/README.md
RENAMED
|
@@ -35,8 +35,7 @@ adapter = PoolAdapter()
|
|
|
35
35
|
|
|
36
36
|
```python
|
|
37
37
|
success, data = await adapter.get_pools_by_ids(
|
|
38
|
-
pool_ids=["pool-123", "pool-456"]
|
|
39
|
-
merge_external=True
|
|
38
|
+
pool_ids=["pool-123", "pool-456"]
|
|
40
39
|
)
|
|
41
40
|
if success:
|
|
42
41
|
pools = data.get("pools", [])
|
|
@@ -48,27 +47,13 @@ else:
|
|
|
48
47
|
### Get Llama Matches
|
|
49
48
|
|
|
50
49
|
```python
|
|
51
|
-
success, data = await adapter.
|
|
50
|
+
success, data = await adapter.get_pools()
|
|
52
51
|
if success:
|
|
53
52
|
matches = data.get("matches", [])
|
|
54
53
|
print(f"Found {len(matches)} Llama matches")
|
|
55
54
|
for match in matches:
|
|
56
|
-
if match.get("
|
|
57
|
-
print(f"Stablecoin pool: {match.get('id')} - APY: {match.get('
|
|
58
|
-
else:
|
|
59
|
-
print(f"Error: {data}")
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Get Llama Reports
|
|
63
|
-
|
|
64
|
-
```python
|
|
65
|
-
success, data = await adapter.get_llama_reports(
|
|
66
|
-
identifiers=["pool-123", "usd-coin-base", "base_0x1234..."]
|
|
67
|
-
)
|
|
68
|
-
if success:
|
|
69
|
-
reports = data
|
|
70
|
-
for identifier, report in reports.items():
|
|
71
|
-
print(f"Report for {identifier}: APY {report.get('llama_apy_pct', 0)}%")
|
|
55
|
+
if match.get("stablecoin"):
|
|
56
|
+
print(f"Stablecoin pool: {match.get('id')} - APY: {match.get('apy')}%")
|
|
72
57
|
else:
|
|
73
58
|
print(f"Error: {data}")
|
|
74
59
|
```
|