wayfinder-paths 0.1.15__py3-none-any.whl → 0.1.16__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.
- wayfinder_paths/adapters/balance_adapter/README.md +19 -20
- wayfinder_paths/adapters/balance_adapter/adapter.py +66 -37
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +2 -8
- wayfinder_paths/adapters/brap_adapter/README.md +22 -19
- wayfinder_paths/adapters/brap_adapter/adapter.py +33 -34
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +2 -18
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +40 -56
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +1 -8
- wayfinder_paths/adapters/moonwell_adapter/README.md +29 -31
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +301 -662
- wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +275 -179
- wayfinder_paths/core/config.py +8 -47
- wayfinder_paths/core/constants/base.py +0 -1
- wayfinder_paths/core/constants/erc20_abi.py +13 -13
- wayfinder_paths/core/strategies/Strategy.py +6 -2
- wayfinder_paths/core/utils/erc20_service.py +100 -0
- wayfinder_paths/core/utils/evm_helpers.py +1 -1
- wayfinder_paths/core/utils/transaction.py +191 -0
- wayfinder_paths/core/utils/web3.py +66 -0
- wayfinder_paths/run_strategy.py +37 -6
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +200 -224
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +128 -151
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +0 -1
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +52 -78
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -12
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +0 -1
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +39 -64
- wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -1
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +42 -85
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -8
- wayfinder_paths/templates/strategy/README.md +1 -5
- {wayfinder_paths-0.1.15.dist-info → wayfinder_paths-0.1.16.dist-info}/METADATA +3 -41
- {wayfinder_paths-0.1.15.dist-info → wayfinder_paths-0.1.16.dist-info}/RECORD +35 -44
- {wayfinder_paths-0.1.15.dist-info → wayfinder_paths-0.1.16.dist-info}/WHEEL +1 -1
- wayfinder_paths/core/clients/sdk_example.py +0 -125
- wayfinder_paths/core/engine/__init__.py +0 -5
- wayfinder_paths/core/services/__init__.py +0 -0
- wayfinder_paths/core/services/base.py +0 -131
- wayfinder_paths/core/services/local_evm_txn.py +0 -350
- wayfinder_paths/core/services/local_token_txn.py +0 -238
- wayfinder_paths/core/services/web3_service.py +0 -43
- wayfinder_paths/core/wallets/README.md +0 -88
- wayfinder_paths/core/wallets/WalletManager.py +0 -56
- wayfinder_paths/core/wallets/__init__.py +0 -7
- wayfinder_paths/scripts/run_strategy.py +0 -152
- wayfinder_paths/strategies/config.py +0 -85
- {wayfinder_paths-0.1.15.dist-info → wayfinder_paths-0.1.16.dist-info}/LICENSE +0 -0
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Wallet Abstraction Layer
|
|
2
|
-
|
|
3
|
-
Wayfinder strategies interact with blockchains through a single abstraction: the `EvmTxn` interface defined in `wayfinder_paths/core/services/base.py`. The default implementation (`LocalEvmTxn`) signs transactions with private keys pulled from config.json or config.json, while `WalletManager` resolves which provider to use at runtime.
|
|
4
|
-
|
|
5
|
-
## Pieces
|
|
6
|
-
|
|
7
|
-
1. **`EvmTxn` (interface)** – describes balance lookups, ERC-20 approvals, raw transaction broadcasting, and AsyncWeb3 access.
|
|
8
|
-
2. **`LocalEvmTxn`** – the built-in provider that signs transactions locally via `eth_account`. It handles RPC resolution, nonce management, gas estimation, and status checks.
|
|
9
|
-
3. **`WalletManager`** – light factory that reads `wallet_type` from strategy config and returns the appropriate `EvmTxn`. Today it always returns `LocalEvmTxn` unless you inject your own provider.
|
|
10
|
-
4. **`DefaultWeb3Service`** – convenience wrapper that bundles an `EvmTxn` (wallet provider) with a `LocalTokenTxnService` (transaction builders used by adapters).
|
|
11
|
-
|
|
12
|
-
## Using the defaults
|
|
13
|
-
|
|
14
|
-
```python
|
|
15
|
-
from wayfinder_paths.core.services.web3_service import DefaultWeb3Service
|
|
16
|
-
from wayfinder_paths.core.wallets.WalletManager import WalletManager
|
|
17
|
-
|
|
18
|
-
config = {...} # contains main_wallet / strategy_wallet entries
|
|
19
|
-
wallet_provider = WalletManager.get_provider(config)
|
|
20
|
-
web3_service = DefaultWeb3Service(config, wallet_provider=wallet_provider)
|
|
21
|
-
|
|
22
|
-
# Strategies typically pass web3_service.evm_transactions into adapters that require wallet access.
|
|
23
|
-
balance_adapter = BalanceAdapter(config, web3_service=web3_service)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
If you want to provide a custom wallet provider (e.g., Privy, Turnkey, Fireblocks), implement the `EvmTxn` interface and hand it to `DefaultWeb3Service`/adapters directly—`WalletManager` is purely a helper.
|
|
27
|
-
|
|
28
|
-
## Implementing a custom provider
|
|
29
|
-
|
|
30
|
-
Subclass `EvmTxn` and implement every abstract method:
|
|
31
|
-
|
|
32
|
-
```python
|
|
33
|
-
from typing import Any
|
|
34
|
-
from web3 import AsyncWeb3
|
|
35
|
-
|
|
36
|
-
from wayfinder_paths.core.services.base import EvmTxn
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class PrivyWallet(EvmTxn):
|
|
40
|
-
def __init__(self, privy_client):
|
|
41
|
-
self._client = privy_client
|
|
42
|
-
|
|
43
|
-
async def get_balance(self, address: str, token_address: str | None, chain_id: int) -> tuple[bool, Any]:
|
|
44
|
-
...
|
|
45
|
-
|
|
46
|
-
async def read_erc20_allowance(self, chain_id: int, token_address: str, owner_address: str, spender_address: str) -> tuple[bool, Any]:
|
|
47
|
-
...
|
|
48
|
-
|
|
49
|
-
async def broadcast_transaction(...):
|
|
50
|
-
...
|
|
51
|
-
|
|
52
|
-
async def transaction_succeeded(self, tx_hash: str, chain_id: int, timeout: int = 120) -> bool:
|
|
53
|
-
...
|
|
54
|
-
|
|
55
|
-
def get_web3(self, chain_id: int) -> AsyncWeb3:
|
|
56
|
-
...
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Methods should mirror `LocalEvmTxn`’s behavior: return `(True, payload)` on success, `(False, "reason")` on failure, and expose AsyncWeb3 instances tied to the requested chain.
|
|
60
|
-
|
|
61
|
-
Once implemented:
|
|
62
|
-
|
|
63
|
-
```python
|
|
64
|
-
custom_wallet = PrivyWallet(privy_client)
|
|
65
|
-
web3_service = DefaultWeb3Service(config, wallet_provider=custom_wallet)
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Configuration hints
|
|
69
|
-
|
|
70
|
-
`WalletManager.get_provider` looks for `wallet_type` on the top-level config, `main_wallet`, and `strategy_wallet`. Example:
|
|
71
|
-
|
|
72
|
-
```json
|
|
73
|
-
{
|
|
74
|
-
"strategy": {
|
|
75
|
-
"wallet_type": "local",
|
|
76
|
-
"main_wallet": { "address": "0x...", "wallet_type": "local" },
|
|
77
|
-
"strategy_wallet": { "address": "0x..." }
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Currently only `"local"` is supported through configuration—the custom path is injection.
|
|
83
|
-
|
|
84
|
-
## Why this layer?
|
|
85
|
-
|
|
86
|
-
- Strategies never touch raw `AsyncWeb3`; they call adapters, which call clients, which call a wallet provider.
|
|
87
|
-
- Alternate signing backends can be plugged in without modifying strategy code.
|
|
88
|
-
- Tests can patch `WalletManager.get_provider` or inject stub `EvmTxn` implementations to avoid real RPC calls.
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Wallet Manager
|
|
3
|
-
|
|
4
|
-
Factory class for resolving and instantiating wallet providers based on configuration.
|
|
5
|
-
Provides convenience methods for config-based wallet provider resolution.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
from loguru import logger
|
|
11
|
-
|
|
12
|
-
from wayfinder_paths.core.services.base import EvmTxn
|
|
13
|
-
from wayfinder_paths.core.services.local_evm_txn import LocalEvmTxn
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class WalletManager:
|
|
17
|
-
"""
|
|
18
|
-
Factory class for wallet providers.
|
|
19
|
-
|
|
20
|
-
Resolves appropriate wallet provider based on config, defaulting to LocalWalletProvider.
|
|
21
|
-
This is a convenience helper - adapters support direct injection, making this optional.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
@staticmethod
|
|
25
|
-
def get_provider(config: dict[str, Any] | None = None) -> EvmTxn:
|
|
26
|
-
"""
|
|
27
|
-
Get wallet provider based on configuration.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
config: Configuration dictionary. May contain wallet_type in wallet configs.
|
|
31
|
-
|
|
32
|
-
Returns:
|
|
33
|
-
WalletProvider instance. Defaults to LocalWalletProvider if no type specified.
|
|
34
|
-
"""
|
|
35
|
-
config = config or {}
|
|
36
|
-
wallet_type = config.get("wallet_type")
|
|
37
|
-
|
|
38
|
-
if not wallet_type:
|
|
39
|
-
main_wallet = config.get("main_wallet")
|
|
40
|
-
if isinstance(main_wallet, dict):
|
|
41
|
-
wallet_type = main_wallet.get("wallet_type")
|
|
42
|
-
|
|
43
|
-
if not wallet_type:
|
|
44
|
-
strategy_wallet = config.get("strategy_wallet")
|
|
45
|
-
if isinstance(strategy_wallet, dict):
|
|
46
|
-
wallet_type = strategy_wallet.get("wallet_type")
|
|
47
|
-
|
|
48
|
-
if not wallet_type or wallet_type == "local":
|
|
49
|
-
logger.debug("Using LocalWalletProvider (default)")
|
|
50
|
-
return LocalEvmTxn(config)
|
|
51
|
-
|
|
52
|
-
logger.warning(
|
|
53
|
-
f"Unknown wallet_type '{wallet_type}', defaulting to LocalWalletProvider. "
|
|
54
|
-
"To use custom wallet providers, inject them directly into adapters."
|
|
55
|
-
)
|
|
56
|
-
return LocalEvmTxn(config)
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"""Wallet abstraction layer for supporting multiple wallet types."""
|
|
2
|
-
|
|
3
|
-
from wayfinder_paths.core.services.base import EvmTxn
|
|
4
|
-
from wayfinder_paths.core.services.local_evm_txn import LocalEvmTxn
|
|
5
|
-
from wayfinder_paths.core.wallets.WalletManager import WalletManager
|
|
6
|
-
|
|
7
|
-
__all__ = ["EvmTxn", "LocalEvmTxn", "WalletManager"]
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import argparse
|
|
4
|
-
import asyncio
|
|
5
|
-
import json
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def _load_wallets(path: Path) -> list[dict[str, Any]]:
|
|
11
|
-
data = json.loads(path.read_text(encoding="utf-8"))
|
|
12
|
-
if not isinstance(data, list):
|
|
13
|
-
raise ValueError(f"Expected a list in {path}")
|
|
14
|
-
return [w for w in data if isinstance(w, dict)]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _load_config(path: Path) -> dict[str, Any]:
|
|
18
|
-
if not path.exists():
|
|
19
|
-
return {}
|
|
20
|
-
data = json.loads(path.read_text(encoding="utf-8"))
|
|
21
|
-
if not isinstance(data, dict):
|
|
22
|
-
raise ValueError(f"Expected a dict in {path}")
|
|
23
|
-
return data
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _find_wallet(wallets: list[dict[str, Any]], label: str) -> dict[str, Any]:
|
|
27
|
-
for w in wallets:
|
|
28
|
-
if w.get("label") == label:
|
|
29
|
-
return w
|
|
30
|
-
raise ValueError(f"Wallet label not found in config.json: {label}")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _get_strategy_class(strategy: str):
|
|
34
|
-
if strategy == "basis_trading_strategy":
|
|
35
|
-
from wayfinder_paths.strategies.basis_trading_strategy.strategy import (
|
|
36
|
-
BasisTradingStrategy,
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
return BasisTradingStrategy
|
|
40
|
-
|
|
41
|
-
if strategy == "hyperlend_stable_yield_strategy":
|
|
42
|
-
from wayfinder_paths.strategies.hyperlend_stable_yield_strategy.strategy import (
|
|
43
|
-
HyperlendStableYieldStrategy,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
return HyperlendStableYieldStrategy
|
|
47
|
-
|
|
48
|
-
if strategy == "moonwell_wsteth_loop_strategy":
|
|
49
|
-
from wayfinder_paths.strategies.moonwell_wsteth_loop_strategy.strategy import (
|
|
50
|
-
MoonwellWstethLoopStrategy,
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
return MoonwellWstethLoopStrategy
|
|
54
|
-
|
|
55
|
-
raise ValueError(f"Unknown strategy: {strategy}")
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
async def _run(args: argparse.Namespace) -> int:
|
|
59
|
-
repo_root = Path(__file__).resolve().parents[2]
|
|
60
|
-
wallets_path = (
|
|
61
|
-
Path(args.wallets).resolve() if args.wallets else repo_root / "config.json"
|
|
62
|
-
)
|
|
63
|
-
config_path = (
|
|
64
|
-
Path(args.config).resolve() if args.config else repo_root / "config.json"
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
wallets = _load_wallets(wallets_path)
|
|
68
|
-
config = _load_config(config_path)
|
|
69
|
-
|
|
70
|
-
main_wallet = _find_wallet(wallets, args.main_wallet_label)
|
|
71
|
-
strategy_wallet = _find_wallet(wallets, args.strategy_wallet_label)
|
|
72
|
-
|
|
73
|
-
# Merge config with wallet info
|
|
74
|
-
strategy_config = {
|
|
75
|
-
"main_wallet": main_wallet,
|
|
76
|
-
"strategy_wallet": strategy_wallet,
|
|
77
|
-
**config.get("strategy", {}),
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
strategy_class = _get_strategy_class(args.strategy)
|
|
81
|
-
s = strategy_class(strategy_config)
|
|
82
|
-
|
|
83
|
-
await s.setup()
|
|
84
|
-
|
|
85
|
-
if args.command == "deposit":
|
|
86
|
-
ok, msg = await s.deposit(
|
|
87
|
-
main_token_amount=float(args.usdc), gas_token_amount=float(args.eth)
|
|
88
|
-
)
|
|
89
|
-
print(msg)
|
|
90
|
-
return 0 if ok else 1
|
|
91
|
-
|
|
92
|
-
if args.command == "update":
|
|
93
|
-
ok, msg = await s.update()
|
|
94
|
-
print(msg)
|
|
95
|
-
return 0 if ok else 1
|
|
96
|
-
|
|
97
|
-
if args.command == "withdraw":
|
|
98
|
-
ok, msg = await s.withdraw(
|
|
99
|
-
amount=float(args.amount) if args.amount is not None else None
|
|
100
|
-
)
|
|
101
|
-
print(msg)
|
|
102
|
-
return 0 if ok else 1
|
|
103
|
-
|
|
104
|
-
if args.command == "status":
|
|
105
|
-
st = await s.status()
|
|
106
|
-
print(json.dumps(st, indent=2, sort_keys=True))
|
|
107
|
-
return 0
|
|
108
|
-
|
|
109
|
-
raise ValueError(f"Unknown command: {args.command}")
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def main() -> int:
|
|
113
|
-
p = argparse.ArgumentParser(
|
|
114
|
-
description="Run a strategy locally (deposit/update/withdraw/status)."
|
|
115
|
-
)
|
|
116
|
-
p.add_argument(
|
|
117
|
-
"--strategy",
|
|
118
|
-
default="basis_trading_strategy",
|
|
119
|
-
choices=[
|
|
120
|
-
"basis_trading_strategy",
|
|
121
|
-
"hyperlend_stable_yield_strategy",
|
|
122
|
-
"moonwell_wsteth_loop_strategy",
|
|
123
|
-
],
|
|
124
|
-
)
|
|
125
|
-
p.add_argument(
|
|
126
|
-
"--wallets", default=None, help="Path to config.json (default: repo root)"
|
|
127
|
-
)
|
|
128
|
-
p.add_argument(
|
|
129
|
-
"--config", default=None, help="Path to config.json (default: repo root)"
|
|
130
|
-
)
|
|
131
|
-
p.add_argument("--main-wallet-label", default="main")
|
|
132
|
-
p.add_argument("--strategy-wallet-label", default="basis_trading_strategy")
|
|
133
|
-
|
|
134
|
-
sub = p.add_subparsers(dest="command", required=True)
|
|
135
|
-
|
|
136
|
-
dep = sub.add_parser("deposit")
|
|
137
|
-
dep.add_argument("--usdc", required=True, type=float)
|
|
138
|
-
dep.add_argument("--eth", default=0.0, type=float)
|
|
139
|
-
|
|
140
|
-
sub.add_parser("update")
|
|
141
|
-
|
|
142
|
-
wd = sub.add_parser("withdraw")
|
|
143
|
-
wd.add_argument("--amount", default=None, type=float)
|
|
144
|
-
|
|
145
|
-
sub.add_parser("status")
|
|
146
|
-
|
|
147
|
-
args = p.parse_args()
|
|
148
|
-
return asyncio.run(_run(args))
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if __name__ == "__main__":
|
|
152
|
-
raise SystemExit(main())
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Configuration for community strategies
|
|
3
|
-
Each strategy can define its own configuration parameters
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
# Funding Rate Strategy Configuration
|
|
9
|
-
FUNDING_RATE_CONFIG = {
|
|
10
|
-
"min_deposit": 30, # USDC
|
|
11
|
-
"lookback_days": 90,
|
|
12
|
-
"confidence": 0.9999,
|
|
13
|
-
"min_open_interest": 50_000,
|
|
14
|
-
"min_daily_volume": 100_000,
|
|
15
|
-
"max_leverage": 3,
|
|
16
|
-
"liquidation_threshold": 0.75,
|
|
17
|
-
"rebalance_threshold": 0.05,
|
|
18
|
-
"hyperliquid_system_address": "0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7",
|
|
19
|
-
"supported_chains": ["arbitrum"],
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Stablecoin Yield Strategy Configuration
|
|
24
|
-
STABLECOIN_YIELD_CONFIG = {
|
|
25
|
-
"min_deposit": 50, # USDC
|
|
26
|
-
"min_tvl": 1_000_000, # $1M minimum TVL for safety
|
|
27
|
-
"min_apy": 0.01, # 1% minimum APY
|
|
28
|
-
"rebalance_days": 7, # Days until rebalance is profitable
|
|
29
|
-
"search_depth": 10, # Number of pools to evaluate
|
|
30
|
-
"gas_buffer": 0.001, # ETH for gas
|
|
31
|
-
"supported_chains": ["base", "arbitrum"],
|
|
32
|
-
"supported_tokens": ["USDC", "DAI", "USDT"],
|
|
33
|
-
"excluded_protocols": [], # Protocols to avoid
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
# Moonwell wstETH Loop Strategy Configuration (example for advanced strategies)
|
|
38
|
-
MOONWELL_LOOP_CONFIG = {
|
|
39
|
-
"min_deposit": 200, # USDC
|
|
40
|
-
"max_loops": 30,
|
|
41
|
-
"leverage_limit": 10,
|
|
42
|
-
"contracts": {
|
|
43
|
-
"m_usdc": "0xedc817a28e8b93b03976fbd4a3ddbc9f7d176c22",
|
|
44
|
-
"m_weth": "0x628ff693426583D9a7FB391E54366292F509D457",
|
|
45
|
-
"m_wsteth": "0x627fe393bc6edda28e99ae648fd6ff362514304b",
|
|
46
|
-
"reward_distributor": "0xe9005b078701e2a0948d2eac43010d35870ad9d2",
|
|
47
|
-
"comptroller": "0xfbb21d0380bee3312b33c4353c8936a0f13ef26c",
|
|
48
|
-
},
|
|
49
|
-
"supported_chains": ["base"],
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# Global adapter configurations
|
|
54
|
-
ADAPTER_CONFIGS = {
|
|
55
|
-
"hyperliquid": {
|
|
56
|
-
"api_url": "https://api.hyperliquid.xyz",
|
|
57
|
-
"testnet_url": "https://api.hyperliquid-testnet.xyz",
|
|
58
|
-
"rate_limit": 10, # requests per second
|
|
59
|
-
"timeout": 30, # seconds
|
|
60
|
-
"slippage": 0.05, # 5% default slippage for market orders
|
|
61
|
-
},
|
|
62
|
-
"enso": {
|
|
63
|
-
"router_address": "0xF75584eF6673aD213a685a1B58Cc0330B8eA22Cf",
|
|
64
|
-
"supported_chains": ["ethereum", "base", "arbitrum", "polygon"],
|
|
65
|
-
},
|
|
66
|
-
"moonwell": {
|
|
67
|
-
"supported_chains": ["base"],
|
|
68
|
-
"protocol_fee": 0.001, # 0.1%
|
|
69
|
-
},
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def get_strategy_config(strategy_name: str) -> dict[str, Any]:
|
|
74
|
-
"""Get configuration for a specific strategy"""
|
|
75
|
-
configs = {
|
|
76
|
-
"funding_rate": FUNDING_RATE_CONFIG,
|
|
77
|
-
"stablecoin_yield": STABLECOIN_YIELD_CONFIG,
|
|
78
|
-
"moonwell_loop": MOONWELL_LOOP_CONFIG,
|
|
79
|
-
}
|
|
80
|
-
return configs.get(strategy_name.lower(), {})
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def get_adapter_config(adapter_name: str) -> dict[str, Any]:
|
|
84
|
-
"""Get configuration for a specific adapter"""
|
|
85
|
-
return ADAPTER_CONFIGS.get(adapter_name.lower(), {})
|
|
File without changes
|