wayfinder-paths 0.1.7__py3-none-any.whl → 0.1.9__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.
Files changed (51) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +5 -14
  2. wayfinder_paths/adapters/brap_adapter/README.md +1 -1
  3. wayfinder_paths/adapters/brap_adapter/adapter.py +1 -53
  4. wayfinder_paths/adapters/brap_adapter/test_adapter.py +5 -7
  5. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +0 -7
  6. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +0 -54
  7. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +1 -1
  8. wayfinder_paths/adapters/ledger_adapter/README.md +1 -1
  9. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +3 -0
  10. wayfinder_paths/adapters/pool_adapter/README.md +3 -104
  11. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -194
  12. wayfinder_paths/adapters/pool_adapter/examples.json +0 -100
  13. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -134
  14. wayfinder_paths/adapters/token_adapter/README.md +1 -1
  15. wayfinder_paths/core/clients/AuthClient.py +0 -3
  16. wayfinder_paths/core/clients/BRAPClient.py +1 -0
  17. wayfinder_paths/core/clients/ClientManager.py +1 -22
  18. wayfinder_paths/core/clients/PoolClient.py +0 -16
  19. wayfinder_paths/core/clients/WalletClient.py +0 -8
  20. wayfinder_paths/core/clients/WayfinderClient.py +9 -14
  21. wayfinder_paths/core/clients/__init__.py +0 -8
  22. wayfinder_paths/core/clients/protocols.py +0 -64
  23. wayfinder_paths/core/config.py +5 -45
  24. wayfinder_paths/core/engine/StrategyJob.py +0 -3
  25. wayfinder_paths/core/services/base.py +0 -49
  26. wayfinder_paths/core/services/local_evm_txn.py +3 -82
  27. wayfinder_paths/core/services/local_token_txn.py +61 -70
  28. wayfinder_paths/core/services/web3_service.py +0 -2
  29. wayfinder_paths/core/settings.py +8 -8
  30. wayfinder_paths/core/strategies/Strategy.py +1 -5
  31. wayfinder_paths/core/utils/evm_helpers.py +7 -12
  32. wayfinder_paths/core/wallets/README.md +3 -6
  33. wayfinder_paths/run_strategy.py +29 -32
  34. wayfinder_paths/scripts/make_wallets.py +1 -25
  35. wayfinder_paths/scripts/run_strategy.py +0 -2
  36. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -3
  37. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +86 -137
  38. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +96 -58
  39. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -2
  40. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +4 -1
  41. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +106 -28
  42. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +53 -14
  43. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +1 -6
  44. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +40 -17
  45. wayfinder_paths/templates/strategy/test_strategy.py +0 -4
  46. {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/METADATA +33 -15
  47. {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/RECORD +49 -51
  48. wayfinder_paths/core/clients/SimulationClient.py +0 -192
  49. wayfinder_paths/core/clients/TransactionClient.py +0 -63
  50. {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/LICENSE +0 -0
  51. {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/WHEEL +0 -0
@@ -1,192 +0,0 @@
1
- """
2
- Simulation Client
3
- Handles blockchain transaction simulations via Gorlami/Tenderly
4
- """
5
-
6
- from __future__ import annotations
7
-
8
- import time
9
- from typing import NotRequired, Required, TypedDict
10
-
11
- from loguru import logger
12
-
13
- from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
14
-
15
-
16
- class SimulationResult(TypedDict):
17
- """Simulation result structure"""
18
-
19
- success: Required[bool]
20
- gas_used: NotRequired[str | None]
21
- gas_price: NotRequired[str | None]
22
- balances: NotRequired[dict[str, str]]
23
- error: NotRequired[str | None]
24
-
25
-
26
- class SimulationClient(WayfinderClient):
27
- """Client for blockchain transaction simulations"""
28
-
29
- def __init__(self, api_key: str | None = None):
30
- super().__init__(api_key=api_key)
31
-
32
- async def simulate_send(
33
- self,
34
- from_address: str,
35
- to_address: str,
36
- token_address: str,
37
- amount: str,
38
- chain_id: int,
39
- initial_balances: dict[str, str],
40
- ) -> SimulationResult:
41
- """
42
- Simulate sending native ETH or ERC20 tokens.
43
-
44
- Args:
45
- from_address: Source wallet address
46
- to_address: Destination wallet address
47
- token_address: Token contract address (use 0x0 for native ETH)
48
- amount: Amount to send
49
- chain_id: Blockchain chain ID
50
- initial_balances: Initial token balances for simulation
51
-
52
- Returns:
53
- Simulation result data
54
- """
55
- logger.info(
56
- f"Simulating send: {amount} from {from_address} to {to_address} (chain {chain_id})"
57
- )
58
- start_time = time.time()
59
-
60
- url = f"{self.api_base_url}public/simulate/send/"
61
-
62
- payload = {
63
- "from_address": from_address,
64
- "to_address": to_address,
65
- "token_address": token_address,
66
- "amount": amount,
67
- "chain_id": chain_id,
68
- "initial_balances": initial_balances,
69
- }
70
-
71
- try:
72
- response = await self._request("POST", url, json=payload, headers={})
73
- response.raise_for_status()
74
- data = response.json()
75
- elapsed = time.time() - start_time
76
- logger.info(f"Simulation request completed successfully in {elapsed:.2f}s")
77
- return data.get("data", data)
78
- except Exception as e:
79
- elapsed = time.time() - start_time
80
- logger.error(f"Simulation request failed after {elapsed:.2f}s: {e}")
81
- raise
82
-
83
- async def simulate_approve(
84
- self,
85
- from_address: str,
86
- to_address: str,
87
- token_address: str,
88
- amount: str,
89
- chain_id: int,
90
- initial_balances: dict[str, str],
91
- clear_approval_first: bool = False,
92
- ) -> SimulationResult:
93
- """
94
- Simulate ERC20 token approval.
95
-
96
- Args:
97
- from_address: Address approving the tokens
98
- to_address: Address being approved to spend tokens
99
- token_address: ERC20 token contract address
100
- amount: Amount to approve
101
- chain_id: Blockchain chain ID
102
- initial_balances: Initial token balances for simulation
103
- clear_approval_first: Whether to clear existing approval before setting new one
104
-
105
- Returns:
106
- Simulation result data
107
- """
108
- logger.info(
109
- f"Simulating approval: {amount} from {from_address} to {to_address} (chain {chain_id})"
110
- )
111
- start_time = time.time()
112
-
113
- url = f"{self.api_base_url}public/simulate/approve/"
114
-
115
- payload = {
116
- "from_address": from_address,
117
- "to_address": to_address,
118
- "token_address": token_address,
119
- "amount": amount,
120
- "chain_id": chain_id,
121
- "initial_balances": initial_balances,
122
- "clear_approval_first": clear_approval_first,
123
- }
124
-
125
- try:
126
- response = await self._request("POST", url, json=payload, headers={})
127
- response.raise_for_status()
128
- data = response.json()
129
- elapsed = time.time() - start_time
130
- logger.info(f"Simulation request completed successfully in {elapsed:.2f}s")
131
- return data.get("data", data)
132
- except Exception as e:
133
- elapsed = time.time() - start_time
134
- logger.error(f"Simulation request failed after {elapsed:.2f}s: {e}")
135
- raise
136
-
137
- async def simulate_swap(
138
- self,
139
- from_token_address: str,
140
- to_token_address: str,
141
- from_chain_id: int,
142
- to_chain_id: int,
143
- amount: str,
144
- from_address: str,
145
- slippage: float,
146
- initial_balances: dict[str, str],
147
- ) -> SimulationResult:
148
- """
149
- Simulate token swap operation.
150
-
151
- Args:
152
- from_token_address: Source token contract address
153
- to_token_address: Destination token contract address
154
- from_chain_id: Source chain ID
155
- to_chain_id: Destination chain ID
156
- amount: Amount to swap
157
- from_address: Wallet address initiating swap
158
- slippage: Maximum slippage tolerance
159
- initial_balances: Initial token balances for simulation
160
-
161
- Returns:
162
- Simulation result data
163
- """
164
- logger.info(
165
- f"Simulating swap: {from_token_address} -> {to_token_address} (chain {from_chain_id} -> {to_chain_id})"
166
- )
167
- start_time = time.time()
168
-
169
- url = f"{self.api_base_url}public/simulate/swap/"
170
-
171
- payload = {
172
- "from_token_address": from_token_address,
173
- "to_token_address": to_token_address,
174
- "from_chain_id": from_chain_id,
175
- "to_chain_id": to_chain_id,
176
- "amount": amount,
177
- "from_address": from_address,
178
- "slippage": slippage,
179
- "initial_balances": initial_balances,
180
- }
181
-
182
- try:
183
- response = await self._request("POST", url, json=payload, headers={})
184
- response.raise_for_status()
185
- data = response.json()
186
- elapsed = time.time() - start_time
187
- logger.info(f"Simulation request completed successfully in {elapsed:.2f}s")
188
- return data.get("data", data)
189
- except Exception as e:
190
- elapsed = time.time() - start_time
191
- logger.error(f"Simulation request failed after {elapsed:.2f}s: {e}")
192
- raise
@@ -1,63 +0,0 @@
1
- """
2
- Transaction Client
3
- Handles transaction building, gas estimation, and monitoring
4
- """
5
-
6
- from __future__ import annotations
7
-
8
- from typing import NotRequired, Required, TypedDict
9
-
10
- from wayfinder_paths.core.clients.AuthClient import AuthClient
11
- from wayfinder_paths.core.clients.WayfinderClient import WayfinderClient
12
- from wayfinder_paths.core.settings import settings
13
-
14
-
15
- class TransactionPayload(TypedDict):
16
- """Transaction payload structure"""
17
-
18
- from_address: Required[str]
19
- to_address: Required[str]
20
- token_address: Required[str]
21
- amount: Required[str]
22
- chain_id: Required[int]
23
- data: NotRequired[str | None]
24
- value: NotRequired[str | None]
25
- gas_limit: NotRequired[str | None]
26
- gas_price: NotRequired[str | None]
27
-
28
-
29
- class TransactionClient(WayfinderClient):
30
- """Client for transaction operations"""
31
-
32
- def __init__(self, api_key: str | None = None):
33
- super().__init__(api_key=api_key)
34
- self.api_base_url = f"{self.api_base_url}/transactions"
35
- self._auth_client: AuthClient | None = AuthClient(api_key=api_key)
36
-
37
- # ============== Protected (Auth Required) Endpoints ==============
38
-
39
- async def build_send(
40
- self,
41
- from_address: str,
42
- to_address: str,
43
- token_address: str,
44
- amount: float,
45
- chain_id: int,
46
- ) -> TransactionPayload:
47
- """
48
- Build a send transaction payload for EVM tokens/native transfers.
49
-
50
- GET /api/v1/public/transactions/build-send/?from_address=...&to_address=...&token_address=...&amount=...&chain_id=...
51
- """
52
- url = f"{settings.WAYFINDER_API_URL}/public/transactions/build-send/"
53
- params = {
54
- "from_address": from_address,
55
- "to_address": to_address,
56
- "token_address": token_address,
57
- "amount": str(amount),
58
- "chain_id": str(chain_id),
59
- }
60
- response = await self._authed_request("GET", url, params=params)
61
- response.raise_for_status()
62
- data = response.json()
63
- return data.get("data", data)