wayfinder-paths 0.1.22__py3-none-any.whl → 0.1.24__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/__init__.py +0 -4
- wayfinder_paths/adapters/balance_adapter/README.md +0 -1
- wayfinder_paths/adapters/balance_adapter/adapter.py +313 -167
- wayfinder_paths/adapters/balance_adapter/manifest.yaml +8 -0
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +41 -124
- wayfinder_paths/adapters/boros_adapter/__init__.py +17 -0
- wayfinder_paths/adapters/boros_adapter/adapter.py +1574 -0
- wayfinder_paths/adapters/boros_adapter/client.py +476 -0
- wayfinder_paths/adapters/boros_adapter/manifest.yaml +10 -0
- wayfinder_paths/adapters/boros_adapter/parsers.py +88 -0
- wayfinder_paths/adapters/boros_adapter/test_adapter.py +460 -0
- wayfinder_paths/adapters/boros_adapter/test_golden.py +156 -0
- wayfinder_paths/adapters/boros_adapter/types.py +70 -0
- wayfinder_paths/adapters/boros_adapter/utils.py +85 -0
- wayfinder_paths/adapters/brap_adapter/README.md +22 -75
- wayfinder_paths/adapters/brap_adapter/adapter.py +187 -576
- wayfinder_paths/adapters/brap_adapter/examples.json +21 -140
- wayfinder_paths/adapters/brap_adapter/manifest.yaml +9 -0
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +6 -234
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +180 -92
- wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +9 -0
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +82 -14
- wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +2 -9
- wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +586 -61
- wayfinder_paths/adapters/hyperliquid_adapter/executor.py +47 -68
- wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +14 -0
- wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +2 -3
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +17 -21
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +3 -6
- wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +4 -8
- wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +2 -2
- wayfinder_paths/adapters/ledger_adapter/README.md +4 -1
- wayfinder_paths/adapters/ledger_adapter/adapter.py +3 -3
- wayfinder_paths/adapters/ledger_adapter/manifest.yaml +7 -0
- wayfinder_paths/adapters/ledger_adapter/test_adapter.py +1 -2
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +649 -547
- wayfinder_paths/adapters/moonwell_adapter/manifest.yaml +14 -0
- wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +160 -239
- wayfinder_paths/adapters/multicall_adapter/__init__.py +7 -0
- wayfinder_paths/adapters/multicall_adapter/adapter.py +166 -0
- wayfinder_paths/adapters/multicall_adapter/manifest.yaml +5 -0
- wayfinder_paths/adapters/multicall_adapter/test_adapter.py +97 -0
- wayfinder_paths/adapters/pendle_adapter/README.md +102 -0
- wayfinder_paths/adapters/pendle_adapter/__init__.py +7 -0
- wayfinder_paths/adapters/pendle_adapter/adapter.py +1992 -0
- wayfinder_paths/adapters/pendle_adapter/examples.json +11 -0
- wayfinder_paths/adapters/pendle_adapter/manifest.yaml +21 -0
- wayfinder_paths/adapters/pendle_adapter/test_adapter.py +666 -0
- wayfinder_paths/adapters/pool_adapter/manifest.yaml +6 -0
- wayfinder_paths/adapters/token_adapter/adapter.py +14 -0
- wayfinder_paths/adapters/token_adapter/examples.json +0 -4
- wayfinder_paths/adapters/token_adapter/manifest.yaml +7 -0
- wayfinder_paths/conftest.py +24 -17
- wayfinder_paths/core/__init__.py +0 -3
- wayfinder_paths/core/adapters/BaseAdapter.py +0 -25
- wayfinder_paths/core/adapters/models.py +17 -7
- wayfinder_paths/core/clients/BRAPClient.py +4 -1
- wayfinder_paths/core/clients/ClientManager.py +0 -7
- wayfinder_paths/core/clients/LedgerClient.py +196 -172
- wayfinder_paths/core/clients/TokenClient.py +47 -1
- wayfinder_paths/core/clients/WayfinderClient.py +1 -3
- wayfinder_paths/core/clients/__init__.py +0 -5
- wayfinder_paths/core/clients/protocols.py +21 -35
- wayfinder_paths/core/clients/test_ledger_client.py +448 -0
- wayfinder_paths/core/config.py +10 -162
- wayfinder_paths/core/constants/__init__.py +73 -2
- wayfinder_paths/core/constants/base.py +8 -17
- wayfinder_paths/core/constants/chains.py +36 -0
- wayfinder_paths/core/constants/contracts.py +52 -0
- wayfinder_paths/core/constants/erc20_abi.py +0 -1
- wayfinder_paths/core/constants/hyperlend_abi.py +0 -4
- wayfinder_paths/core/constants/hyperliquid.py +16 -0
- wayfinder_paths/core/constants/moonwell_abi.py +0 -15
- wayfinder_paths/core/constants/tokens.py +9 -0
- wayfinder_paths/core/engine/manifest.py +66 -0
- wayfinder_paths/core/strategies/Strategy.py +0 -71
- wayfinder_paths/core/strategies/__init__.py +10 -1
- wayfinder_paths/core/strategies/opa_loop.py +167 -0
- wayfinder_paths/core/utils/evm_helpers.py +5 -15
- wayfinder_paths/core/utils/test_transaction.py +289 -0
- wayfinder_paths/core/utils/tokens.py +28 -0
- wayfinder_paths/core/utils/transaction.py +57 -8
- wayfinder_paths/core/utils/web3.py +8 -3
- wayfinder_paths/mcp/__init__.py +5 -0
- wayfinder_paths/mcp/preview.py +185 -0
- wayfinder_paths/mcp/scripting.py +84 -0
- wayfinder_paths/mcp/server.py +52 -0
- wayfinder_paths/mcp/state/profile_store.py +195 -0
- wayfinder_paths/mcp/state/store.py +89 -0
- wayfinder_paths/mcp/test_scripting.py +267 -0
- wayfinder_paths/mcp/tools/__init__.py +0 -0
- wayfinder_paths/mcp/tools/balances.py +290 -0
- wayfinder_paths/mcp/tools/discovery.py +158 -0
- wayfinder_paths/mcp/tools/execute.py +770 -0
- wayfinder_paths/mcp/tools/hyperliquid.py +931 -0
- wayfinder_paths/mcp/tools/quotes.py +288 -0
- wayfinder_paths/mcp/tools/run_script.py +286 -0
- wayfinder_paths/mcp/tools/strategies.py +188 -0
- wayfinder_paths/mcp/tools/tokens.py +46 -0
- wayfinder_paths/mcp/tools/wallets.py +354 -0
- wayfinder_paths/mcp/utils.py +129 -0
- wayfinder_paths/policies/enso.py +1 -2
- wayfinder_paths/policies/hyper_evm.py +6 -3
- wayfinder_paths/policies/hyperlend.py +1 -2
- wayfinder_paths/policies/hyperliquid.py +1 -1
- wayfinder_paths/policies/lifi.py +18 -0
- wayfinder_paths/policies/moonwell.py +12 -7
- wayfinder_paths/policies/prjx.py +1 -3
- wayfinder_paths/policies/util.py +8 -2
- wayfinder_paths/run_strategy.py +97 -300
- wayfinder_paths/strategies/basis_trading_strategy/constants.py +3 -1
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +47 -133
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +24 -53
- wayfinder_paths/strategies/boros_hype_strategy/__init__.py +3 -0
- wayfinder_paths/strategies/boros_hype_strategy/boros_ops_mixin.py +450 -0
- wayfinder_paths/strategies/boros_hype_strategy/constants.py +255 -0
- wayfinder_paths/strategies/boros_hype_strategy/examples.json +37 -0
- wayfinder_paths/strategies/boros_hype_strategy/hyperevm_ops_mixin.py +114 -0
- wayfinder_paths/strategies/boros_hype_strategy/hyperliquid_ops_mixin.py +642 -0
- wayfinder_paths/strategies/boros_hype_strategy/manifest.yaml +36 -0
- wayfinder_paths/strategies/boros_hype_strategy/planner.py +460 -0
- wayfinder_paths/strategies/boros_hype_strategy/risk_ops_mixin.py +886 -0
- wayfinder_paths/strategies/boros_hype_strategy/snapshot_mixin.py +494 -0
- wayfinder_paths/strategies/boros_hype_strategy/strategy.py +1194 -0
- wayfinder_paths/strategies/boros_hype_strategy/test_planner_golden.py +374 -0
- wayfinder_paths/{templates/strategy → strategies/boros_hype_strategy}/test_strategy.py +99 -63
- wayfinder_paths/strategies/boros_hype_strategy/types.py +365 -0
- wayfinder_paths/strategies/boros_hype_strategy/withdraw_mixin.py +997 -0
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +15 -23
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +27 -62
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +84 -58
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +5 -15
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +69 -164
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +43 -76
- wayfinder_paths/tests/test_mcp_quote_swap.py +165 -0
- wayfinder_paths/tests/test_test_coverage.py +1 -4
- wayfinder_paths-0.1.24.dist-info/METADATA +378 -0
- wayfinder_paths-0.1.24.dist-info/RECORD +185 -0
- {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/WHEEL +1 -1
- wayfinder_paths/core/clients/WalletClient.py +0 -41
- wayfinder_paths/core/engine/StrategyJob.py +0 -110
- wayfinder_paths/core/services/test_local_evm_txn.py +0 -145
- wayfinder_paths/scripts/create_strategy.py +0 -139
- wayfinder_paths/scripts/make_wallets.py +0 -142
- wayfinder_paths/templates/adapter/README.md +0 -150
- wayfinder_paths/templates/adapter/adapter.py +0 -16
- wayfinder_paths/templates/adapter/examples.json +0 -8
- wayfinder_paths/templates/adapter/test_adapter.py +0 -30
- wayfinder_paths/templates/strategy/README.md +0 -186
- wayfinder_paths/templates/strategy/examples.json +0 -11
- wayfinder_paths/templates/strategy/strategy.py +0 -35
- wayfinder_paths/tests/test_smoke_manifest.py +0 -63
- wayfinder_paths-0.1.22.dist-info/METADATA +0 -355
- wayfinder_paths-0.1.22.dist-info/RECORD +0 -129
- /wayfinder_paths/{scripts → mcp/state}/__init__.py +0 -0
- {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/LICENSE +0 -0
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
"description": "Proper error handling for various scenarios",
|
|
12
12
|
"code": "from adapters.token_adapter.adapter import TokenAdapter\n\n# Initialize adapter (no config needed)\nadapter = TokenAdapter()\n\n# Handle API errors\nsuccess, data = await adapter.get_token(\"invalid-address\")\nif not success:\n print(f\"API error: {data}\")\nelse:\n print(f\"Token found: {data}\")"
|
|
13
13
|
},
|
|
14
|
-
"health_check": {
|
|
15
|
-
"description": "Check adapter health and connectivity",
|
|
16
|
-
"code": "from adapters.token_adapter.adapter import TokenAdapter\n\n# Initialize adapter (no config needed)\nadapter = TokenAdapter()\n\n# Check health\nhealth = await adapter.health_check()\nprint(f\"Adapter status: {health['status']}\")\nprint(f\"Connected: {health['connected']}\")\nprint(f\"Adapter type: {health['adapter']}\")\n\nif health['status'] == 'healthy':\n print(\"Adapter is ready to use\")\nelse:\n print(f\"Adapter has issues: {health.get('error', 'Unknown error')}\")"
|
|
17
|
-
},
|
|
18
14
|
"batch_operations": {
|
|
19
15
|
"description": "Perform multiple token lookups efficiently",
|
|
20
16
|
"code": "from adapters.token_adapter.adapter import TokenAdapter\n\n# Initialize adapter (no config needed)\nadapter = TokenAdapter()\n\n# List of token addresses to lookup (Base chain)\ntoken_addresses = [\n \"0x1234567890abcdef1234567890abcdef12345678\",\n \"0xabcdef1234567890abcdef1234567890abcdef12\",\n \"0x9876543210fedcba9876543210fedcba98765432\"\n]\n\n# Batch lookup\ntoken_data = {}\nfor address in token_addresses:\n success, data = await adapter.get_token(address, chain_id=8453)\n if success:\n token_data[address] = data\n else:\n print(f\"Failed to get token for {address}: {data}\")\n\nprint(f\"Successfully retrieved {len(token_data)} tokens\")\nfor address, data in token_data.items():\n print(f\"{address}: {data.get('symbol', 'Unknown')} - {data.get('name', 'Unknown')}\")"
|
wayfinder_paths/conftest.py
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
# Add repo root to path so tests.test_utils can be imported
|
|
7
|
+
_repo_root = Path(__file__).parent.parent
|
|
8
|
+
_repo_root_str = str(_repo_root)
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
def pytest_configure(config):
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sys.path.remove(
|
|
15
|
-
sys.path.insert(0,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
config.addinivalue_line("markers", "smoke: mark test as a smoke test")
|
|
13
|
+
if _repo_root_str not in sys.path:
|
|
14
|
+
sys.path.insert(0, _repo_root_str)
|
|
15
|
+
elif sys.path.index(_repo_root_str) > 0:
|
|
16
|
+
sys.path.remove(_repo_root_str)
|
|
17
|
+
sys.path.insert(0, _repo_root_str)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def pytest_collection_modifyitems(config, items):
|
|
21
|
+
for item in items:
|
|
22
|
+
if "smoke" in item.nodeid:
|
|
23
|
+
item.add_marker(pytest.mark.smoke)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if _repo_root_str not in sys.path:
|
|
27
|
+
sys.path.insert(0, _repo_root_str)
|
|
28
|
+
elif sys.path.index(_repo_root_str) > 0:
|
|
29
|
+
sys.path.remove(_repo_root_str)
|
|
30
|
+
sys.path.insert(0, _repo_root_str)
|
wayfinder_paths/core/__init__.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
|
|
2
|
-
from wayfinder_paths.core.engine.StrategyJob import StrategyJob
|
|
3
2
|
from wayfinder_paths.core.strategies.Strategy import (
|
|
4
|
-
LiquidationResult,
|
|
5
3
|
StatusDict,
|
|
6
4
|
StatusTuple,
|
|
7
5
|
Strategy,
|
|
@@ -12,5 +10,4 @@ __all__ = [
|
|
|
12
10
|
"StatusDict",
|
|
13
11
|
"StatusTuple",
|
|
14
12
|
"BaseAdapter",
|
|
15
|
-
"StrategyJob",
|
|
16
13
|
]
|
|
@@ -14,30 +14,5 @@ class BaseAdapter(ABC):
|
|
|
14
14
|
self.config = config or {}
|
|
15
15
|
self.logger = logger.bind(adapter=self.__class__.__name__)
|
|
16
16
|
|
|
17
|
-
async def connect(self) -> bool:
|
|
18
|
-
return True
|
|
19
|
-
|
|
20
|
-
async def get_balance(self, asset: str) -> dict[str, Any]:
|
|
21
|
-
if not asset or not isinstance(asset, str) or not asset.strip():
|
|
22
|
-
raise ValueError("asset must be a non-empty string")
|
|
23
|
-
raise NotImplementedError(
|
|
24
|
-
f"get_balance not supported by {self.__class__.__name__}"
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
async def health_check(self) -> dict[str, Any]:
|
|
28
|
-
try:
|
|
29
|
-
connected = await self.connect()
|
|
30
|
-
return {
|
|
31
|
-
"status": "healthy" if connected else "unhealthy",
|
|
32
|
-
"connected": connected,
|
|
33
|
-
"adapter": self.adapter_type or self.__class__.__name__,
|
|
34
|
-
}
|
|
35
|
-
except Exception as e:
|
|
36
|
-
return {
|
|
37
|
-
"status": "error",
|
|
38
|
-
"error": str(e),
|
|
39
|
-
"adapter": self.adapter_type or self.__class__.__name__,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
17
|
async def close(self) -> None:
|
|
43
18
|
pass
|
|
@@ -4,9 +4,11 @@ from pydantic import BaseModel, Field
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class OperationBase(BaseModel):
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
# These are provided by adapters at execution time, but tests and callers may
|
|
8
|
+
# construct operations without them (e.g., for bookkeeping payloads).
|
|
9
|
+
adapter: str = "unknown"
|
|
10
|
+
transaction_hash: str | None = None
|
|
11
|
+
transaction_chain_id: int | None = None
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class SWAP(OperationBase):
|
|
@@ -23,14 +25,22 @@ class SWAP(OperationBase):
|
|
|
23
25
|
|
|
24
26
|
class LEND(OperationBase):
|
|
25
27
|
type: Literal["LEND"] = "LEND"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
token_address: str
|
|
29
|
+
pool_address: str
|
|
30
|
+
amount: str
|
|
31
|
+
amount_usd: float
|
|
32
|
+
transaction_status: str | None = None
|
|
33
|
+
transaction_receipt: dict[str, Any] | None = None
|
|
28
34
|
|
|
29
35
|
|
|
30
36
|
class UNLEND(OperationBase):
|
|
31
37
|
type: Literal["UNLEND"] = "UNLEND"
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
token_address: str
|
|
39
|
+
pool_address: str
|
|
40
|
+
amount: str
|
|
41
|
+
amount_usd: float
|
|
42
|
+
transaction_status: str | None = None
|
|
43
|
+
transaction_receipt: dict[str, Any] | None = None
|
|
34
44
|
|
|
35
45
|
|
|
36
46
|
# Type alias for operation types (currently only SWAP is used)
|
|
@@ -72,7 +72,7 @@ class BRAPQuoteResponse(TypedDict):
|
|
|
72
72
|
class BRAPClient(WayfinderClient):
|
|
73
73
|
def __init__(self):
|
|
74
74
|
super().__init__()
|
|
75
|
-
self.api_base_url = f"{get_api_base_url()}/
|
|
75
|
+
self.api_base_url = f"{get_api_base_url()}/blockchain/braps"
|
|
76
76
|
|
|
77
77
|
async def get_quote(
|
|
78
78
|
self,
|
|
@@ -83,6 +83,7 @@ class BRAPClient(WayfinderClient):
|
|
|
83
83
|
to_chain: int,
|
|
84
84
|
from_wallet: str,
|
|
85
85
|
from_amount: str,
|
|
86
|
+
slippage: float | None = None,
|
|
86
87
|
) -> BRAPQuoteResponse: # type: ignore # noqa: E501
|
|
87
88
|
logger.info(
|
|
88
89
|
f"Getting BRAP quote: {from_token} -> {to_token} (chain {from_chain} -> {to_chain})"
|
|
@@ -100,6 +101,8 @@ class BRAPClient(WayfinderClient):
|
|
|
100
101
|
"from_wallet": from_wallet,
|
|
101
102
|
"from_amount": from_amount,
|
|
102
103
|
}
|
|
104
|
+
if slippage is not None:
|
|
105
|
+
params["slippage"] = slippage
|
|
103
106
|
|
|
104
107
|
try:
|
|
105
108
|
response = await self._authed_request("GET", url, params=params, headers={})
|
|
@@ -10,10 +10,8 @@ from wayfinder_paths.core.clients.protocols import (
|
|
|
10
10
|
LedgerClientProtocol,
|
|
11
11
|
PoolClientProtocol,
|
|
12
12
|
TokenClientProtocol,
|
|
13
|
-
WalletClientProtocol,
|
|
14
13
|
)
|
|
15
14
|
from wayfinder_paths.core.clients.TokenClient import TokenClient
|
|
16
|
-
from wayfinder_paths.core.clients.WalletClient import WalletClient
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
class ClientManager:
|
|
@@ -26,7 +24,6 @@ class ClientManager:
|
|
|
26
24
|
self._skip_auth = skip_auth
|
|
27
25
|
|
|
28
26
|
self._token_client: TokenClientProtocol | None = None
|
|
29
|
-
self._wallet_client: WalletClientProtocol | None = None
|
|
30
27
|
self._ledger_client: LedgerClientProtocol | None = None
|
|
31
28
|
self._pool_client: PoolClientProtocol | None = None
|
|
32
29
|
self._hyperlend_client: HyperlendClientProtocol | None = None
|
|
@@ -62,10 +59,6 @@ class ClientManager:
|
|
|
62
59
|
"_hyperlend_client", "hyperlend", HyperlendClient
|
|
63
60
|
)
|
|
64
61
|
|
|
65
|
-
@property
|
|
66
|
-
def wallet(self) -> WalletClientProtocol:
|
|
67
|
-
return self._get_or_create_client("_wallet_client", "wallet", WalletClient)
|
|
68
|
-
|
|
69
62
|
@property
|
|
70
63
|
def brap(self) -> BRAPClientProtocol:
|
|
71
64
|
return self._get_or_create_client("_brap_client", "brap", BRAPClient)
|