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.
- wayfinder_paths/CONFIG_GUIDE.md +5 -14
- wayfinder_paths/adapters/brap_adapter/README.md +1 -1
- wayfinder_paths/adapters/brap_adapter/adapter.py +1 -53
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +5 -7
- 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/ledger_adapter/test_adapter.py +3 -0
- wayfinder_paths/adapters/pool_adapter/README.md +3 -104
- wayfinder_paths/adapters/pool_adapter/adapter.py +0 -194
- wayfinder_paths/adapters/pool_adapter/examples.json +0 -100
- wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -134
- wayfinder_paths/adapters/token_adapter/README.md +1 -1
- wayfinder_paths/core/clients/AuthClient.py +0 -3
- wayfinder_paths/core/clients/BRAPClient.py +1 -0
- wayfinder_paths/core/clients/ClientManager.py +1 -22
- wayfinder_paths/core/clients/PoolClient.py +0 -16
- wayfinder_paths/core/clients/WalletClient.py +0 -8
- wayfinder_paths/core/clients/WayfinderClient.py +9 -14
- wayfinder_paths/core/clients/__init__.py +0 -8
- wayfinder_paths/core/clients/protocols.py +0 -64
- wayfinder_paths/core/config.py +5 -45
- wayfinder_paths/core/engine/StrategyJob.py +0 -3
- wayfinder_paths/core/services/base.py +0 -49
- wayfinder_paths/core/services/local_evm_txn.py +3 -82
- wayfinder_paths/core/services/local_token_txn.py +61 -70
- 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/utils/evm_helpers.py +7 -12
- wayfinder_paths/core/wallets/README.md +3 -6
- wayfinder_paths/run_strategy.py +29 -32
- wayfinder_paths/scripts/make_wallets.py +1 -25
- wayfinder_paths/scripts/run_strategy.py +0 -2
- wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -3
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +86 -137
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +96 -58
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -2
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +4 -1
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +106 -28
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +53 -14
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +1 -6
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +40 -17
- wayfinder_paths/templates/strategy/test_strategy.py +0 -4
- {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/METADATA +33 -15
- {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/RECORD +49 -51
- wayfinder_paths/core/clients/SimulationClient.py +0 -192
- wayfinder_paths/core/clients/TransactionClient.py +0 -63
- {wayfinder_paths-0.1.7.dist-info → wayfinder_paths-0.1.9.dist-info}/LICENSE +0 -0
- {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)
|
|
File without changes
|
|
File without changes
|