wayfinder-paths 0.1.8__py3-none-any.whl → 0.1.10__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/CONFIG_GUIDE.md +6 -15
- wayfinder_paths/adapters/balance_adapter/README.md +1 -2
- wayfinder_paths/adapters/balance_adapter/adapter.py +4 -4
- wayfinder_paths/adapters/brap_adapter/README.md +1 -1
- wayfinder_paths/adapters/brap_adapter/adapter.py +139 -74
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +0 -7
- wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +0 -54
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +1 -1
- wayfinder_paths/adapters/ledger_adapter/README.md +1 -1
- wayfinder_paths/adapters/moonwell_adapter/README.md +174 -0
- wayfinder_paths/adapters/moonwell_adapter/__init__.py +7 -0
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +1226 -0
- wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +635 -0
- wayfinder_paths/adapters/pool_adapter/README.md +1 -77
- wayfinder_paths/adapters/pool_adapter/adapter.py +0 -122
- wayfinder_paths/adapters/pool_adapter/examples.json +0 -57
- wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -86
- wayfinder_paths/adapters/token_adapter/README.md +1 -1
- wayfinder_paths/core/clients/ClientManager.py +1 -22
- wayfinder_paths/core/clients/WalletClient.py +0 -8
- wayfinder_paths/core/clients/WayfinderClient.py +7 -12
- wayfinder_paths/core/clients/__init__.py +0 -8
- wayfinder_paths/core/clients/protocols.py +0 -60
- wayfinder_paths/core/config.py +5 -45
- wayfinder_paths/core/constants/__init__.py +0 -2
- wayfinder_paths/core/constants/base.py +6 -2
- wayfinder_paths/core/constants/moonwell_abi.py +411 -0
- wayfinder_paths/core/services/base.py +7 -1
- wayfinder_paths/core/services/local_evm_txn.py +223 -222
- wayfinder_paths/core/services/local_token_txn.py +103 -92
- wayfinder_paths/core/services/web3_service.py +0 -2
- wayfinder_paths/core/settings.py +8 -8
- wayfinder_paths/core/strategies/Strategy.py +1 -5
- wayfinder_paths/core/strategies/descriptors.py +1 -1
- wayfinder_paths/core/utils/evm_helpers.py +7 -12
- wayfinder_paths/core/wallets/README.md +3 -6
- wayfinder_paths/run_strategy.py +62 -105
- wayfinder_paths/scripts/create_strategy.py +2 -27
- wayfinder_paths/scripts/make_wallets.py +1 -25
- wayfinder_paths/scripts/run_strategy.py +37 -9
- wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -3
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +87 -138
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +96 -58
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -17
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +4 -1
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +107 -29
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +53 -14
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +108 -0
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +11 -0
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2975 -0
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +886 -0
- wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -7
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +2 -7
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -4
- wayfinder_paths/templates/adapter/README.md +5 -21
- wayfinder_paths/templates/adapter/adapter.py +1 -2
- wayfinder_paths/templates/adapter/test_adapter.py +1 -1
- wayfinder_paths/templates/strategy/README.md +4 -21
- wayfinder_paths/templates/strategy/test_strategy.py +0 -4
- wayfinder_paths/tests/test_smoke_manifest.py +17 -2
- {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/METADATA +64 -201
- {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/RECORD +64 -71
- wayfinder_paths/adapters/balance_adapter/manifest.yaml +0 -8
- wayfinder_paths/adapters/brap_adapter/manifest.yaml +0 -11
- wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +0 -10
- wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +0 -8
- wayfinder_paths/adapters/ledger_adapter/manifest.yaml +0 -11
- wayfinder_paths/adapters/pool_adapter/manifest.yaml +0 -10
- wayfinder_paths/adapters/token_adapter/manifest.yaml +0 -6
- wayfinder_paths/core/clients/SimulationClient.py +0 -192
- wayfinder_paths/core/clients/TransactionClient.py +0 -63
- wayfinder_paths/core/engine/manifest.py +0 -97
- wayfinder_paths/scripts/validate_manifests.py +0 -213
- wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml +0 -23
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/manifest.yaml +0 -7
- wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml +0 -17
- wayfinder_paths/templates/adapter/manifest.yaml +0 -6
- wayfinder_paths/templates/strategy/manifest.yaml +0 -8
- {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/LICENSE +0 -0
- {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/WHEEL +0 -0
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Manifest Validator
|
|
4
|
-
|
|
5
|
-
Validates all adapter and strategy manifests in the repository.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import sys
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
|
|
11
|
-
from loguru import logger
|
|
12
|
-
|
|
13
|
-
# Add parent to path for imports
|
|
14
|
-
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
15
|
-
|
|
16
|
-
from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
|
|
17
|
-
from wayfinder_paths.core.engine.manifest import (
|
|
18
|
-
load_adapter_manifest,
|
|
19
|
-
load_strategy_manifest,
|
|
20
|
-
)
|
|
21
|
-
from wayfinder_paths.core.strategies.Strategy import Strategy
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def verify_entrypoint(entrypoint: str) -> tuple[bool, str | None]:
|
|
25
|
-
"""Verify entrypoint is importable. Returns (success, error_message)."""
|
|
26
|
-
try:
|
|
27
|
-
module_path, class_name = entrypoint.rsplit(".", 1)
|
|
28
|
-
module = __import__(module_path, fromlist=[class_name], level=0)
|
|
29
|
-
getattr(module, class_name) # Verify class exists
|
|
30
|
-
return True, None
|
|
31
|
-
except ImportError as e:
|
|
32
|
-
return False, f"Import error: {str(e)}"
|
|
33
|
-
except AttributeError as e:
|
|
34
|
-
return False, f"Class not found: {str(e)}"
|
|
35
|
-
except Exception as e:
|
|
36
|
-
return False, f"Unexpected error: {str(e)}"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def verify_adapter_class(entrypoint: str) -> tuple[bool, str | None]:
|
|
40
|
-
"""Verify entrypoint is an adapter class."""
|
|
41
|
-
valid, error = verify_entrypoint(entrypoint)
|
|
42
|
-
if not valid:
|
|
43
|
-
return False, error
|
|
44
|
-
|
|
45
|
-
try:
|
|
46
|
-
module_path, class_name = entrypoint.rsplit(".", 1)
|
|
47
|
-
module = __import__(module_path, fromlist=[class_name], level=0)
|
|
48
|
-
adapter_class = getattr(module, class_name)
|
|
49
|
-
|
|
50
|
-
if not issubclass(adapter_class, BaseAdapter):
|
|
51
|
-
return False, f"{class_name} is not a BaseAdapter"
|
|
52
|
-
return True, None
|
|
53
|
-
except Exception as e:
|
|
54
|
-
return False, f"Error verifying adapter: {str(e)}"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def verify_strategy_class(entrypoint: str) -> tuple[bool, str | None]:
|
|
58
|
-
"""Verify entrypoint is a strategy class."""
|
|
59
|
-
valid, error = verify_entrypoint(entrypoint)
|
|
60
|
-
if not valid:
|
|
61
|
-
return False, error
|
|
62
|
-
|
|
63
|
-
try:
|
|
64
|
-
module_path, class_name = entrypoint.rsplit(".", 1)
|
|
65
|
-
module = __import__(module_path, fromlist=[class_name], level=0)
|
|
66
|
-
strategy_class = getattr(module, class_name)
|
|
67
|
-
|
|
68
|
-
if not issubclass(strategy_class, Strategy):
|
|
69
|
-
return False, f"{class_name} is not a Strategy"
|
|
70
|
-
return True, None
|
|
71
|
-
except Exception as e:
|
|
72
|
-
return False, f"Error verifying strategy: {str(e)}"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
# Capabilities are only declared in manifest - no code validation needed
|
|
76
|
-
# Manifest is the single source of truth for capabilities
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def verify_dependencies(dependencies: list[str]) -> tuple[bool, list[str]]:
|
|
80
|
-
"""Verify dependencies are importable. Returns (valid, error_messages)."""
|
|
81
|
-
errors = []
|
|
82
|
-
|
|
83
|
-
for dep in dependencies:
|
|
84
|
-
# Try to import from core.clients
|
|
85
|
-
try:
|
|
86
|
-
__import__(f"core.clients.{dep}", fromlist=[dep], level=0)
|
|
87
|
-
except ImportError:
|
|
88
|
-
errors.append(f"Dependency '{dep}' not found in core.clients")
|
|
89
|
-
except Exception as e:
|
|
90
|
-
errors.append(f"Error importing dependency '{dep}': {str(e)}")
|
|
91
|
-
|
|
92
|
-
return len(errors) == 0, errors
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def validate_adapter_manifest(manifest_path: str) -> tuple[bool, list[str]]:
|
|
96
|
-
"""Validate adapter manifest. Returns (valid, error_messages)."""
|
|
97
|
-
errors = []
|
|
98
|
-
|
|
99
|
-
try:
|
|
100
|
-
manifest = load_adapter_manifest(manifest_path)
|
|
101
|
-
except Exception as e:
|
|
102
|
-
return False, [f"Schema error: {str(e)}"]
|
|
103
|
-
|
|
104
|
-
# Verify entrypoint
|
|
105
|
-
valid, error = verify_adapter_class(manifest.entrypoint)
|
|
106
|
-
if not valid:
|
|
107
|
-
errors.append(f"Entrypoint validation failed: {error}")
|
|
108
|
-
return False, errors
|
|
109
|
-
|
|
110
|
-
# Verify dependencies
|
|
111
|
-
valid, dep_errors = verify_dependencies(manifest.dependencies)
|
|
112
|
-
if not valid:
|
|
113
|
-
errors.extend(dep_errors)
|
|
114
|
-
|
|
115
|
-
return len(errors) == 0, errors
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def validate_strategy_manifest(manifest_path: str) -> tuple[bool, list[str]]:
|
|
119
|
-
"""Validate strategy manifest. Returns (valid, error_messages)."""
|
|
120
|
-
errors = []
|
|
121
|
-
|
|
122
|
-
try:
|
|
123
|
-
manifest = load_strategy_manifest(manifest_path)
|
|
124
|
-
except Exception as e:
|
|
125
|
-
return False, [f"Schema error: {str(e)}"]
|
|
126
|
-
|
|
127
|
-
# Verify entrypoint
|
|
128
|
-
valid, error = verify_strategy_class(manifest.entrypoint)
|
|
129
|
-
if not valid:
|
|
130
|
-
errors.append(f"Entrypoint validation failed: {error}")
|
|
131
|
-
return False, errors
|
|
132
|
-
|
|
133
|
-
# Permissions are already validated by Pydantic model
|
|
134
|
-
|
|
135
|
-
return len(errors) == 0, errors
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def find_adapter_manifests() -> list[Path]:
|
|
139
|
-
"""Find all adapter manifest files."""
|
|
140
|
-
manifests = []
|
|
141
|
-
adapter_dir = Path(__file__).parent.parent / "adapters"
|
|
142
|
-
if adapter_dir.exists():
|
|
143
|
-
for adapter_path in adapter_dir.iterdir():
|
|
144
|
-
manifest_path = adapter_path / "manifest.yaml"
|
|
145
|
-
if manifest_path.exists():
|
|
146
|
-
manifests.append(manifest_path)
|
|
147
|
-
return manifests
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def find_strategy_manifests() -> list[Path]:
|
|
151
|
-
"""Find all strategy manifest files."""
|
|
152
|
-
manifests = []
|
|
153
|
-
strategy_dir = Path(__file__).parent.parent / "strategies"
|
|
154
|
-
if strategy_dir.exists():
|
|
155
|
-
for strategy_path in strategy_dir.iterdir():
|
|
156
|
-
manifest_path = strategy_path / "manifest.yaml"
|
|
157
|
-
if manifest_path.exists():
|
|
158
|
-
manifests.append(manifest_path)
|
|
159
|
-
return manifests
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def main() -> int:
|
|
163
|
-
"""Main validation function. Returns 0 on success, 1 on failure."""
|
|
164
|
-
logger.info("Validating all manifests...")
|
|
165
|
-
|
|
166
|
-
all_valid = True
|
|
167
|
-
error_count = 0
|
|
168
|
-
|
|
169
|
-
# Validate adapter manifests
|
|
170
|
-
logger.info("\n=== Validating Adapter Manifests ===")
|
|
171
|
-
adapter_manifests = find_adapter_manifests()
|
|
172
|
-
for manifest_path in sorted(adapter_manifests):
|
|
173
|
-
logger.info(f"Validating {manifest_path}...")
|
|
174
|
-
valid, errors = validate_adapter_manifest(str(manifest_path))
|
|
175
|
-
if valid:
|
|
176
|
-
logger.success(f"✅ {manifest_path.name} - Valid")
|
|
177
|
-
else:
|
|
178
|
-
logger.error(f"❌ {manifest_path.name} - Invalid")
|
|
179
|
-
for error in errors:
|
|
180
|
-
logger.error(f" {error}")
|
|
181
|
-
all_valid = False
|
|
182
|
-
error_count += len(errors)
|
|
183
|
-
|
|
184
|
-
# Validate strategy manifests
|
|
185
|
-
logger.info("\n=== Validating Strategy Manifests ===")
|
|
186
|
-
strategy_manifests = find_strategy_manifests()
|
|
187
|
-
for manifest_path in sorted(strategy_manifests):
|
|
188
|
-
logger.info(f"Validating {manifest_path}...")
|
|
189
|
-
valid, errors = validate_strategy_manifest(str(manifest_path))
|
|
190
|
-
if valid:
|
|
191
|
-
logger.success(f"✅ {manifest_path.name} - Valid")
|
|
192
|
-
else:
|
|
193
|
-
logger.error(f"❌ {manifest_path.name} - Invalid")
|
|
194
|
-
for error in errors:
|
|
195
|
-
logger.error(f" {error}")
|
|
196
|
-
all_valid = False
|
|
197
|
-
error_count += len(errors)
|
|
198
|
-
|
|
199
|
-
# Summary
|
|
200
|
-
logger.info("\n=== Summary ===")
|
|
201
|
-
if all_valid:
|
|
202
|
-
logger.success(
|
|
203
|
-
f"✅ All manifests valid! ({len(adapter_manifests)} adapters, "
|
|
204
|
-
f"{len(strategy_manifests)} strategies)"
|
|
205
|
-
)
|
|
206
|
-
return 0
|
|
207
|
-
else:
|
|
208
|
-
logger.error(f"❌ Validation failed with {error_count} error(s)")
|
|
209
|
-
return 1
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if __name__ == "__main__":
|
|
213
|
-
sys.exit(main())
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
schema_version: "0.1"
|
|
2
|
-
entrypoint: "wayfinder_paths.strategies.basis_trading_strategy.strategy.BasisTradingStrategy"
|
|
3
|
-
permissions:
|
|
4
|
-
policy: |
|
|
5
|
-
(wallet.id == 'FORMAT_WALLET_ID') AND (
|
|
6
|
-
# Allow Hyperliquid EIP-712 order actions
|
|
7
|
-
(action.type == 'hyperliquid_order') OR
|
|
8
|
-
(action.type == 'hyperliquid_cancel') OR
|
|
9
|
-
(action.type == 'hyperliquid_transfer') OR
|
|
10
|
-
# Allow USDC transfers to Hyperliquid bridge
|
|
11
|
-
(action.type == 'erc20_transfer' AND action.to == '0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7') OR
|
|
12
|
-
# Allow USDC withdraw to main wallet
|
|
13
|
-
(action.type == 'erc20_transfer' AND action.to == main_wallet.address)
|
|
14
|
-
)
|
|
15
|
-
adapters:
|
|
16
|
-
- name: "BALANCE"
|
|
17
|
-
capabilities: ["wallet_read", "wallet_transfer"]
|
|
18
|
-
- name: "LEDGER"
|
|
19
|
-
capabilities: ["ledger.read", "ledger.write", "strategy.transactions"]
|
|
20
|
-
- name: "TOKEN"
|
|
21
|
-
capabilities: ["token.read"]
|
|
22
|
-
- name: "HYPERLIQUID"
|
|
23
|
-
capabilities: ["market.read", "market.meta", "market.funding", "market.candles", "market.orderbook", "order.execute", "order.cancel", "position.manage", "transfer"]
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
schema_version: "0.1"
|
|
2
|
-
entrypoint: "strategies.stablecoin_yield_strategy.strategy.StablecoinYieldStrategy"
|
|
3
|
-
permissions:
|
|
4
|
-
policy: "(wallet.id == 'FORMAT_WALLET_ID') && ((eth.tx.data[0..10] == '0x095ea7b3' && eth.tx.data[34..74] == 'f75584ef6673ad213a685a1b58cc0330b8ea22cf') || (eth.tx.to == '0xF75584eF6673aD213a685a1B58Cc0330B8eA22Cf'))"
|
|
5
|
-
adapters:
|
|
6
|
-
- name: "BALANCE"
|
|
7
|
-
capabilities: ["wallet_read", "wallet_transfer"]
|
|
8
|
-
- name: "POOL"
|
|
9
|
-
capabilities: ["pool.read", "pool.analytics"]
|
|
10
|
-
- name: "BRAP"
|
|
11
|
-
capabilities: ["swap.quote", "swap.execute"]
|
|
12
|
-
- name: "TOKEN"
|
|
13
|
-
capabilities: ["token.read"]
|
|
14
|
-
- name: "LEDGER"
|
|
15
|
-
capabilities: ["ledger.read", "strategy.transactions"]
|
|
16
|
-
- name: "EVM_TRANSACTION"
|
|
17
|
-
capabilities: ["wallet_transfer"]
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
schema_version: "0.1"
|
|
2
|
-
entrypoint: "strategies.my_strategy.strategy.MyStrategy"
|
|
3
|
-
name: "my_strategy" # Unique name for this strategy instance (used for wallet lookup)
|
|
4
|
-
permissions:
|
|
5
|
-
policy: "(wallet.id == 'FORMAT_WALLET_ID')"
|
|
6
|
-
adapters:
|
|
7
|
-
- name: "BALANCE"
|
|
8
|
-
capabilities: ["wallet_read"]
|
|
File without changes
|
|
File without changes
|