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.

Files changed (156) hide show
  1. wayfinder_paths/__init__.py +0 -4
  2. wayfinder_paths/adapters/balance_adapter/README.md +0 -1
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +313 -167
  4. wayfinder_paths/adapters/balance_adapter/manifest.yaml +8 -0
  5. wayfinder_paths/adapters/balance_adapter/test_adapter.py +41 -124
  6. wayfinder_paths/adapters/boros_adapter/__init__.py +17 -0
  7. wayfinder_paths/adapters/boros_adapter/adapter.py +1574 -0
  8. wayfinder_paths/adapters/boros_adapter/client.py +476 -0
  9. wayfinder_paths/adapters/boros_adapter/manifest.yaml +10 -0
  10. wayfinder_paths/adapters/boros_adapter/parsers.py +88 -0
  11. wayfinder_paths/adapters/boros_adapter/test_adapter.py +460 -0
  12. wayfinder_paths/adapters/boros_adapter/test_golden.py +156 -0
  13. wayfinder_paths/adapters/boros_adapter/types.py +70 -0
  14. wayfinder_paths/adapters/boros_adapter/utils.py +85 -0
  15. wayfinder_paths/adapters/brap_adapter/README.md +22 -75
  16. wayfinder_paths/adapters/brap_adapter/adapter.py +187 -576
  17. wayfinder_paths/adapters/brap_adapter/examples.json +21 -140
  18. wayfinder_paths/adapters/brap_adapter/manifest.yaml +9 -0
  19. wayfinder_paths/adapters/brap_adapter/test_adapter.py +6 -234
  20. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +180 -92
  21. wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +9 -0
  22. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +82 -14
  23. wayfinder_paths/adapters/hyperliquid_adapter/__init__.py +2 -9
  24. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +586 -61
  25. wayfinder_paths/adapters/hyperliquid_adapter/executor.py +47 -68
  26. wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +14 -0
  27. wayfinder_paths/adapters/hyperliquid_adapter/paired_filler.py +2 -3
  28. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +17 -21
  29. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +3 -6
  30. wayfinder_paths/adapters/hyperliquid_adapter/test_executor.py +4 -8
  31. wayfinder_paths/adapters/hyperliquid_adapter/test_utils.py +2 -2
  32. wayfinder_paths/adapters/ledger_adapter/README.md +4 -1
  33. wayfinder_paths/adapters/ledger_adapter/adapter.py +3 -3
  34. wayfinder_paths/adapters/ledger_adapter/manifest.yaml +7 -0
  35. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +1 -2
  36. wayfinder_paths/adapters/moonwell_adapter/adapter.py +649 -547
  37. wayfinder_paths/adapters/moonwell_adapter/manifest.yaml +14 -0
  38. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +160 -239
  39. wayfinder_paths/adapters/multicall_adapter/__init__.py +7 -0
  40. wayfinder_paths/adapters/multicall_adapter/adapter.py +166 -0
  41. wayfinder_paths/adapters/multicall_adapter/manifest.yaml +5 -0
  42. wayfinder_paths/adapters/multicall_adapter/test_adapter.py +97 -0
  43. wayfinder_paths/adapters/pendle_adapter/README.md +102 -0
  44. wayfinder_paths/adapters/pendle_adapter/__init__.py +7 -0
  45. wayfinder_paths/adapters/pendle_adapter/adapter.py +1992 -0
  46. wayfinder_paths/adapters/pendle_adapter/examples.json +11 -0
  47. wayfinder_paths/adapters/pendle_adapter/manifest.yaml +21 -0
  48. wayfinder_paths/adapters/pendle_adapter/test_adapter.py +666 -0
  49. wayfinder_paths/adapters/pool_adapter/manifest.yaml +6 -0
  50. wayfinder_paths/adapters/token_adapter/adapter.py +14 -0
  51. wayfinder_paths/adapters/token_adapter/examples.json +0 -4
  52. wayfinder_paths/adapters/token_adapter/manifest.yaml +7 -0
  53. wayfinder_paths/conftest.py +24 -17
  54. wayfinder_paths/core/__init__.py +0 -3
  55. wayfinder_paths/core/adapters/BaseAdapter.py +0 -25
  56. wayfinder_paths/core/adapters/models.py +17 -7
  57. wayfinder_paths/core/clients/BRAPClient.py +4 -1
  58. wayfinder_paths/core/clients/ClientManager.py +0 -7
  59. wayfinder_paths/core/clients/LedgerClient.py +196 -172
  60. wayfinder_paths/core/clients/TokenClient.py +47 -1
  61. wayfinder_paths/core/clients/WayfinderClient.py +1 -3
  62. wayfinder_paths/core/clients/__init__.py +0 -5
  63. wayfinder_paths/core/clients/protocols.py +21 -35
  64. wayfinder_paths/core/clients/test_ledger_client.py +448 -0
  65. wayfinder_paths/core/config.py +10 -162
  66. wayfinder_paths/core/constants/__init__.py +73 -2
  67. wayfinder_paths/core/constants/base.py +8 -17
  68. wayfinder_paths/core/constants/chains.py +36 -0
  69. wayfinder_paths/core/constants/contracts.py +52 -0
  70. wayfinder_paths/core/constants/erc20_abi.py +0 -1
  71. wayfinder_paths/core/constants/hyperlend_abi.py +0 -4
  72. wayfinder_paths/core/constants/hyperliquid.py +16 -0
  73. wayfinder_paths/core/constants/moonwell_abi.py +0 -15
  74. wayfinder_paths/core/constants/tokens.py +9 -0
  75. wayfinder_paths/core/engine/manifest.py +66 -0
  76. wayfinder_paths/core/strategies/Strategy.py +0 -71
  77. wayfinder_paths/core/strategies/__init__.py +10 -1
  78. wayfinder_paths/core/strategies/opa_loop.py +167 -0
  79. wayfinder_paths/core/utils/evm_helpers.py +5 -15
  80. wayfinder_paths/core/utils/test_transaction.py +289 -0
  81. wayfinder_paths/core/utils/tokens.py +28 -0
  82. wayfinder_paths/core/utils/transaction.py +57 -8
  83. wayfinder_paths/core/utils/web3.py +8 -3
  84. wayfinder_paths/mcp/__init__.py +5 -0
  85. wayfinder_paths/mcp/preview.py +185 -0
  86. wayfinder_paths/mcp/scripting.py +84 -0
  87. wayfinder_paths/mcp/server.py +52 -0
  88. wayfinder_paths/mcp/state/profile_store.py +195 -0
  89. wayfinder_paths/mcp/state/store.py +89 -0
  90. wayfinder_paths/mcp/test_scripting.py +267 -0
  91. wayfinder_paths/mcp/tools/__init__.py +0 -0
  92. wayfinder_paths/mcp/tools/balances.py +290 -0
  93. wayfinder_paths/mcp/tools/discovery.py +158 -0
  94. wayfinder_paths/mcp/tools/execute.py +770 -0
  95. wayfinder_paths/mcp/tools/hyperliquid.py +931 -0
  96. wayfinder_paths/mcp/tools/quotes.py +288 -0
  97. wayfinder_paths/mcp/tools/run_script.py +286 -0
  98. wayfinder_paths/mcp/tools/strategies.py +188 -0
  99. wayfinder_paths/mcp/tools/tokens.py +46 -0
  100. wayfinder_paths/mcp/tools/wallets.py +354 -0
  101. wayfinder_paths/mcp/utils.py +129 -0
  102. wayfinder_paths/policies/enso.py +1 -2
  103. wayfinder_paths/policies/hyper_evm.py +6 -3
  104. wayfinder_paths/policies/hyperlend.py +1 -2
  105. wayfinder_paths/policies/hyperliquid.py +1 -1
  106. wayfinder_paths/policies/lifi.py +18 -0
  107. wayfinder_paths/policies/moonwell.py +12 -7
  108. wayfinder_paths/policies/prjx.py +1 -3
  109. wayfinder_paths/policies/util.py +8 -2
  110. wayfinder_paths/run_strategy.py +97 -300
  111. wayfinder_paths/strategies/basis_trading_strategy/constants.py +3 -1
  112. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +47 -133
  113. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +24 -53
  114. wayfinder_paths/strategies/boros_hype_strategy/__init__.py +3 -0
  115. wayfinder_paths/strategies/boros_hype_strategy/boros_ops_mixin.py +450 -0
  116. wayfinder_paths/strategies/boros_hype_strategy/constants.py +255 -0
  117. wayfinder_paths/strategies/boros_hype_strategy/examples.json +37 -0
  118. wayfinder_paths/strategies/boros_hype_strategy/hyperevm_ops_mixin.py +114 -0
  119. wayfinder_paths/strategies/boros_hype_strategy/hyperliquid_ops_mixin.py +642 -0
  120. wayfinder_paths/strategies/boros_hype_strategy/manifest.yaml +36 -0
  121. wayfinder_paths/strategies/boros_hype_strategy/planner.py +460 -0
  122. wayfinder_paths/strategies/boros_hype_strategy/risk_ops_mixin.py +886 -0
  123. wayfinder_paths/strategies/boros_hype_strategy/snapshot_mixin.py +494 -0
  124. wayfinder_paths/strategies/boros_hype_strategy/strategy.py +1194 -0
  125. wayfinder_paths/strategies/boros_hype_strategy/test_planner_golden.py +374 -0
  126. wayfinder_paths/{templates/strategy → strategies/boros_hype_strategy}/test_strategy.py +99 -63
  127. wayfinder_paths/strategies/boros_hype_strategy/types.py +365 -0
  128. wayfinder_paths/strategies/boros_hype_strategy/withdraw_mixin.py +997 -0
  129. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +15 -23
  130. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +27 -62
  131. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +84 -58
  132. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +5 -15
  133. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +69 -164
  134. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +43 -76
  135. wayfinder_paths/tests/test_mcp_quote_swap.py +165 -0
  136. wayfinder_paths/tests/test_test_coverage.py +1 -4
  137. wayfinder_paths-0.1.24.dist-info/METADATA +378 -0
  138. wayfinder_paths-0.1.24.dist-info/RECORD +185 -0
  139. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/WHEEL +1 -1
  140. wayfinder_paths/core/clients/WalletClient.py +0 -41
  141. wayfinder_paths/core/engine/StrategyJob.py +0 -110
  142. wayfinder_paths/core/services/test_local_evm_txn.py +0 -145
  143. wayfinder_paths/scripts/create_strategy.py +0 -139
  144. wayfinder_paths/scripts/make_wallets.py +0 -142
  145. wayfinder_paths/templates/adapter/README.md +0 -150
  146. wayfinder_paths/templates/adapter/adapter.py +0 -16
  147. wayfinder_paths/templates/adapter/examples.json +0 -8
  148. wayfinder_paths/templates/adapter/test_adapter.py +0 -30
  149. wayfinder_paths/templates/strategy/README.md +0 -186
  150. wayfinder_paths/templates/strategy/examples.json +0 -11
  151. wayfinder_paths/templates/strategy/strategy.py +0 -35
  152. wayfinder_paths/tests/test_smoke_manifest.py +0 -63
  153. wayfinder_paths-0.1.22.dist-info/METADATA +0 -355
  154. wayfinder_paths-0.1.22.dist-info/RECORD +0 -129
  155. /wayfinder_paths/{scripts → mcp/state}/__init__.py +0 -0
  156. {wayfinder_paths-0.1.22.dist-info → wayfinder_paths-0.1.24.dist-info}/LICENSE +0 -0
@@ -0,0 +1,158 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Literal
4
+
5
+ from wayfinder_paths.mcp.utils import err, ok, read_text_excerpt, read_yaml, repo_root
6
+
7
+
8
+ async def discover(
9
+ kind: Literal["adapters", "strategies"],
10
+ detail: Literal["summary", "full"] = "summary",
11
+ ) -> dict[str, Any]:
12
+ root = repo_root()
13
+ base = (
14
+ root / "wayfinder_paths" / ("adapters" if kind == "adapters" else "strategies")
15
+ )
16
+ if not base.exists():
17
+ return err("not_found", f"Directory not found: {base}")
18
+
19
+ items: list[dict[str, Any]] = []
20
+ for child in sorted(base.iterdir()):
21
+ if not child.is_dir():
22
+ continue
23
+ manifest_path = child / "manifest.yaml"
24
+ if not manifest_path.exists():
25
+ continue
26
+ manifest = read_yaml(manifest_path)
27
+ rel_manifest = str(manifest_path.relative_to(root))
28
+
29
+ if kind == "adapters":
30
+ item = {
31
+ "name": child.name,
32
+ "entrypoint": manifest.get("entrypoint"),
33
+ "capabilities": manifest.get("capabilities", []),
34
+ "dependencies": manifest.get("dependencies", []),
35
+ "manifest_path": rel_manifest,
36
+ }
37
+ else:
38
+ adapters = manifest.get("adapters", [])
39
+ item = {
40
+ "name": child.name,
41
+ "entrypoint": manifest.get("entrypoint"),
42
+ "adapters": adapters if isinstance(adapters, list) else [],
43
+ "permissions_policy_present": bool(
44
+ isinstance(manifest.get("permissions"), dict)
45
+ and (manifest.get("permissions") or {}).get("policy")
46
+ ),
47
+ "manifest_path": rel_manifest,
48
+ }
49
+
50
+ if detail == "full":
51
+ readme = read_text_excerpt(child / "README.md")
52
+ if readme:
53
+ item["readme_excerpt"] = readme
54
+ item["manifest"] = manifest
55
+
56
+ items.append(item)
57
+
58
+ return ok({"kind": kind, "items": items})
59
+
60
+
61
+ def _default_claude_notes_for_adapter(name: str) -> dict[str, Any] | None:
62
+ # Keep this deliberately small; the real docs live in .claude/skills.
63
+ if name == "brap_adapter":
64
+ return {
65
+ "reads": [
66
+ {
67
+ "name": "quote_swap (via mcp__wayfinder__quote_swap)",
68
+ "summary": "Get best BRAP route + fees; no on-chain effects.",
69
+ }
70
+ ],
71
+ "writes": [
72
+ {
73
+ "name": "swap (via mcp__wayfinder__execute kind=swap)",
74
+ "risk": "funds",
75
+ "summary": "May submit ERC20 approvals and a swap/bridge tx.",
76
+ }
77
+ ],
78
+ "gotchas": [
79
+ "USDT-style tokens may require setting allowance to 0 before approve.",
80
+ "Cross-chain swaps still broadcast a tx on the source chain.",
81
+ ],
82
+ }
83
+ if name == "balance_adapter":
84
+ return {
85
+ "reads": [
86
+ {
87
+ "name": "balances (via mcp__wayfinder__balances)",
88
+ "summary": "Read token/pool balances via Wayfinder API.",
89
+ }
90
+ ],
91
+ "writes": [
92
+ {
93
+ "name": "send (via mcp__wayfinder__execute kind=send)",
94
+ "risk": "funds",
95
+ "summary": "Native/ERC20 sends from a local wallet.",
96
+ }
97
+ ],
98
+ "gotchas": ["Prefer DRY_RUN=1 until ready to broadcast."],
99
+ }
100
+ if name == "hyperliquid_adapter":
101
+ return {
102
+ "reads": [
103
+ {
104
+ "name": "hyperliquid (via mcp__wayfinder__hyperliquid)",
105
+ "summary": "User state + market reads (no signing).",
106
+ }
107
+ ],
108
+ "writes": [
109
+ {
110
+ "name": "hyperliquid_execute (via mcp__wayfinder__hyperliquid_execute)",
111
+ "risk": "funds",
112
+ "summary": "Perp orders/leverage/withdraw with local signing (gated by review prompt).",
113
+ }
114
+ ],
115
+ "gotchas": [
116
+ "Perp coins are mapped to asset_id (<10000).",
117
+ "Builder fees are attributed to 0xaA1D89f333857eD78F8434CC4f896A9293EFE65c and use tenths-of-bp units.",
118
+ "Prefer DRY_RUN=1 until ready to execute.",
119
+ ],
120
+ }
121
+ return None
122
+
123
+
124
+ async def describe(
125
+ kind: Literal["adapter", "strategy"],
126
+ name: str,
127
+ include_manifest: bool = True,
128
+ include_readme_excerpt: bool = True,
129
+ include_claude_notes: bool = True,
130
+ ) -> dict[str, Any]:
131
+ root = repo_root()
132
+ base = (
133
+ root / "wayfinder_paths" / ("adapters" if kind == "adapter" else "strategies")
134
+ )
135
+ target = base / name
136
+ if not target.exists():
137
+ return err("not_found", f"Unknown {kind}: {name}")
138
+
139
+ manifest_path = target / "manifest.yaml"
140
+ if not manifest_path.exists():
141
+ return err("not_found", f"Missing manifest.yaml for {kind}: {name}")
142
+
143
+ out: dict[str, Any] = {"kind": kind, "name": name}
144
+ if include_manifest:
145
+ out["manifest"] = read_yaml(manifest_path)
146
+ out["manifest_path"] = str(manifest_path.relative_to(root))
147
+
148
+ if include_readme_excerpt:
149
+ readme = read_text_excerpt(target / "README.md")
150
+ if readme:
151
+ out["readme_excerpt"] = readme
152
+
153
+ if include_claude_notes and kind == "adapter":
154
+ notes = _default_claude_notes_for_adapter(name)
155
+ if notes:
156
+ out["claude_notes"] = notes
157
+
158
+ return ok(out)