wayfinder-paths 0.1.14__py3-none-any.whl → 0.1.16__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 (58) hide show
  1. wayfinder_paths/adapters/balance_adapter/README.md +19 -20
  2. wayfinder_paths/adapters/balance_adapter/adapter.py +91 -22
  3. wayfinder_paths/adapters/balance_adapter/test_adapter.py +5 -11
  4. wayfinder_paths/adapters/brap_adapter/README.md +22 -19
  5. wayfinder_paths/adapters/brap_adapter/adapter.py +95 -45
  6. wayfinder_paths/adapters/brap_adapter/test_adapter.py +8 -24
  7. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +40 -42
  8. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +8 -15
  9. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +6 -6
  10. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +12 -12
  11. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +6 -6
  12. wayfinder_paths/adapters/moonwell_adapter/README.md +29 -31
  13. wayfinder_paths/adapters/moonwell_adapter/adapter.py +326 -364
  14. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +285 -189
  15. wayfinder_paths/adapters/pool_adapter/test_adapter.py +2 -2
  16. wayfinder_paths/adapters/token_adapter/test_adapter.py +4 -4
  17. wayfinder_paths/core/config.py +8 -47
  18. wayfinder_paths/core/constants/base.py +0 -1
  19. wayfinder_paths/core/constants/erc20_abi.py +13 -24
  20. wayfinder_paths/core/engine/StrategyJob.py +3 -1
  21. wayfinder_paths/core/services/test_local_evm_txn.py +145 -0
  22. wayfinder_paths/core/strategies/Strategy.py +22 -4
  23. wayfinder_paths/core/utils/erc20_service.py +100 -0
  24. wayfinder_paths/core/utils/evm_helpers.py +1 -8
  25. wayfinder_paths/core/utils/transaction.py +191 -0
  26. wayfinder_paths/core/utils/web3.py +66 -0
  27. wayfinder_paths/policies/erc20.py +1 -1
  28. wayfinder_paths/run_strategy.py +42 -6
  29. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +263 -220
  30. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +132 -155
  31. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +0 -1
  32. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +123 -80
  33. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +0 -12
  34. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +6 -6
  35. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2270 -1328
  36. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +282 -121
  37. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -1
  38. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +107 -85
  39. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -8
  40. wayfinder_paths/templates/adapter/README.md +1 -1
  41. wayfinder_paths/templates/strategy/README.md +1 -5
  42. {wayfinder_paths-0.1.14.dist-info → wayfinder_paths-0.1.16.dist-info}/METADATA +3 -41
  43. {wayfinder_paths-0.1.14.dist-info → wayfinder_paths-0.1.16.dist-info}/RECORD +45 -54
  44. {wayfinder_paths-0.1.14.dist-info → wayfinder_paths-0.1.16.dist-info}/WHEEL +1 -1
  45. wayfinder_paths/abis/generic/erc20.json +0 -383
  46. wayfinder_paths/core/clients/sdk_example.py +0 -125
  47. wayfinder_paths/core/engine/__init__.py +0 -5
  48. wayfinder_paths/core/services/__init__.py +0 -0
  49. wayfinder_paths/core/services/base.py +0 -130
  50. wayfinder_paths/core/services/local_evm_txn.py +0 -334
  51. wayfinder_paths/core/services/local_token_txn.py +0 -242
  52. wayfinder_paths/core/services/web3_service.py +0 -43
  53. wayfinder_paths/core/wallets/README.md +0 -88
  54. wayfinder_paths/core/wallets/WalletManager.py +0 -56
  55. wayfinder_paths/core/wallets/__init__.py +0 -7
  56. wayfinder_paths/scripts/run_strategy.py +0 -152
  57. wayfinder_paths/strategies/config.py +0 -85
  58. {wayfinder_paths-0.1.14.dist-info → wayfinder_paths-0.1.16.dist-info}/LICENSE +0 -0
@@ -1,383 +0,0 @@
1
- [
2
- {
3
- "constant": true,
4
- "inputs": [
5
- {
6
- "name": "owner",
7
- "type": "address"
8
- },
9
- {
10
- "name": "spender",
11
- "type": "address"
12
- }
13
- ],
14
- "name": "allowance",
15
- "outputs": [
16
- {
17
- "name": "",
18
- "type": "uint256"
19
- }
20
- ],
21
- "type": "function"
22
- },
23
- {
24
- "constant": true,
25
- "inputs": [
26
- {
27
- "name": "account",
28
- "type": "address"
29
- }
30
- ],
31
- "name": "balanceOf",
32
- "outputs": [
33
- {
34
- "name": "",
35
- "type": "uint256"
36
- }
37
- ],
38
- "type": "function"
39
- },
40
- {
41
- "constant": true,
42
- "inputs": [],
43
- "name": "decimals",
44
- "outputs": [
45
- {
46
- "name": "",
47
- "type": "uint8"
48
- }
49
- ],
50
- "type": "function"
51
- },
52
- {
53
- "constant": true,
54
- "inputs": [],
55
- "name": "name",
56
- "outputs": [
57
- {
58
- "name": "",
59
- "type": "string"
60
- }
61
- ],
62
- "type": "function"
63
- },
64
- {
65
- "constant": true,
66
- "inputs": [],
67
- "name": "symbol",
68
- "outputs": [
69
- {
70
- "name": "",
71
- "type": "string"
72
- }
73
- ],
74
- "type": "function"
75
- },
76
- {
77
- "constant": false,
78
- "inputs": [
79
- {
80
- "name": "recipient",
81
- "type": "address"
82
- },
83
- {
84
- "name": "amount",
85
- "type": "uint256"
86
- }
87
- ],
88
- "name": "transfer",
89
- "outputs": [
90
- {
91
- "name": "",
92
- "type": "bool"
93
- }
94
- ],
95
- "type": "function"
96
- },
97
- {
98
- "constant": false,
99
- "inputs": [
100
- {
101
- "name": "spender",
102
- "type": "address"
103
- },
104
- {
105
- "name": "amount",
106
- "type": "uint256"
107
- }
108
- ],
109
- "name": "approve",
110
- "outputs": [
111
- {
112
- "name": "",
113
- "type": "bool"
114
- }
115
- ],
116
- "type": "function"
117
- },
118
- {
119
- "inputs": [
120
- {
121
- "internalType": "address",
122
- "name": "tokenA",
123
- "type": "address"
124
- },
125
- {
126
- "internalType": "address",
127
- "name": "tokenB",
128
- "type": "address"
129
- },
130
- {
131
- "internalType": "bool",
132
- "name": "stable",
133
- "type": "bool"
134
- },
135
- {
136
- "internalType": "uint256",
137
- "name": "amountADesired",
138
- "type": "uint256"
139
- },
140
- {
141
- "internalType": "uint256",
142
- "name": "amountBDesired",
143
- "type": "uint256"
144
- },
145
- {
146
- "internalType": "uint256",
147
- "name": "amountAMin",
148
- "type": "uint256"
149
- },
150
- {
151
- "internalType": "uint256",
152
- "name": "amountBMin",
153
- "type": "uint256"
154
- },
155
- {
156
- "internalType": "address",
157
- "name": "to",
158
- "type": "address"
159
- },
160
- {
161
- "internalType": "uint256",
162
- "name": "deadline",
163
- "type": "uint256"
164
- }
165
- ],
166
- "name": "addLiquidity",
167
- "outputs": [
168
- {
169
- "internalType": "uint256",
170
- "name": "amountA",
171
- "type": "uint256"
172
- },
173
- {
174
- "internalType": "uint256",
175
- "name": "amountB",
176
- "type": "uint256"
177
- },
178
- {
179
- "internalType": "uint256",
180
- "name": "liquidity",
181
- "type": "uint256"
182
- }
183
- ],
184
- "stateMutability": "nonpayable",
185
- "type": "function"
186
- },
187
- {
188
- "inputs": [
189
- {
190
- "internalType": "address",
191
- "name": "tokenA",
192
- "type": "address"
193
- },
194
- {
195
- "internalType": "address",
196
- "name": "tokenB",
197
- "type": "address"
198
- },
199
- {
200
- "internalType": "bool",
201
- "name": "stable",
202
- "type": "bool"
203
- },
204
- {
205
- "internalType": "address",
206
- "name": "_factory",
207
- "type": "address"
208
- },
209
- {
210
- "internalType": "uint256",
211
- "name": "amountADesired",
212
- "type": "uint256"
213
- },
214
- {
215
- "internalType": "uint256",
216
- "name": "amountBDesired",
217
- "type": "uint256"
218
- }
219
- ],
220
- "name": "quoteAddLiquidity",
221
- "outputs": [
222
- {
223
- "internalType": "uint256",
224
- "name": "amountA",
225
- "type": "uint256"
226
- },
227
- {
228
- "internalType": "uint256",
229
- "name": "amountB",
230
- "type": "uint256"
231
- },
232
- {
233
- "internalType": "uint256",
234
- "name": "liquidity",
235
- "type": "uint256"
236
- }
237
- ],
238
- "stateMutability": "view",
239
- "type": "function"
240
- },
241
- {
242
- "inputs": [],
243
- "name": "defaultFactory",
244
- "outputs": [
245
- {
246
- "internalType": "address",
247
- "name": "",
248
- "type": "address"
249
- }
250
- ],
251
- "stateMutability": "view",
252
- "type": "function"
253
- },
254
- {
255
- "inputs": [
256
- {
257
- "internalType": "address",
258
- "name": "tokenA",
259
- "type": "address"
260
- },
261
- {
262
- "internalType": "address",
263
- "name": "tokenB",
264
- "type": "address"
265
- },
266
- {
267
- "internalType": "bool",
268
- "name": "stable",
269
- "type": "bool"
270
- },
271
- {
272
- "internalType": "address",
273
- "name": "_factory",
274
- "type": "address"
275
- },
276
- {
277
- "internalType": "uint256",
278
- "name": "liquidity",
279
- "type": "uint256"
280
- }
281
- ],
282
- "name": "quoteRemoveLiquidity",
283
- "outputs": [
284
- {
285
- "internalType": "uint256",
286
- "name": "amountA",
287
- "type": "uint256"
288
- },
289
- {
290
- "internalType": "uint256",
291
- "name": "amountB",
292
- "type": "uint256"
293
- }
294
- ],
295
- "stateMutability": "view",
296
- "type": "function"
297
- },
298
- {
299
- "inputs": [
300
- {
301
- "internalType": "address",
302
- "name": "tokenA",
303
- "type": "address"
304
- },
305
- {
306
- "internalType": "address",
307
- "name": "tokenB",
308
- "type": "address"
309
- },
310
- {
311
- "internalType": "bool",
312
- "name": "stable",
313
- "type": "bool"
314
- },
315
- {
316
- "internalType": "uint256",
317
- "name": "liquidity",
318
- "type": "uint256"
319
- },
320
- {
321
- "internalType": "uint256",
322
- "name": "amountAMin",
323
- "type": "uint256"
324
- },
325
- {
326
- "internalType": "uint256",
327
- "name": "amountBMin",
328
- "type": "uint256"
329
- },
330
- {
331
- "internalType": "address",
332
- "name": "to",
333
- "type": "address"
334
- },
335
- {
336
- "internalType": "uint256",
337
- "name": "deadline",
338
- "type": "uint256"
339
- }
340
- ],
341
- "name": "removeLiquidity",
342
- "outputs": [
343
- {
344
- "internalType": "uint256",
345
- "name": "amountA",
346
- "type": "uint256"
347
- },
348
- {
349
- "internalType": "uint256",
350
- "name": "amountB",
351
- "type": "uint256"
352
- }
353
- ],
354
- "stateMutability": "nonpayable",
355
- "type": "function"
356
- },
357
- {
358
- "inputs": [
359
- {
360
- "internalType": "uint256",
361
- "name": "_amount",
362
- "type": "uint256"
363
- }
364
- ],
365
- "name": "deposit",
366
- "outputs": [],
367
- "stateMutability": "nonpayable",
368
- "type": "function"
369
- },
370
- {
371
- "inputs": [
372
- {
373
- "internalType": "uint256",
374
- "name": "_shares",
375
- "type": "uint256"
376
- }
377
- ],
378
- "name": "withdraw",
379
- "outputs": [],
380
- "stateMutability": "nonpayable",
381
- "type": "function"
382
- }
383
- ]
@@ -1,125 +0,0 @@
1
- """
2
- SDK Usage Examples
3
-
4
- Demonstrates how to use the SDK with custom client implementations.
5
- Use cases: mocks for testing, caching layers, alternative endpoints, rate limiting.
6
- """
7
-
8
- from typing import Any
9
-
10
- from wayfinder_paths.core.clients.ClientManager import ClientManager
11
- from wayfinder_paths.core.clients.TokenClient import TokenClient
12
-
13
-
14
- class CachedTokenClient:
15
- """Token client with in-memory caching"""
16
-
17
- def __init__(self):
18
- self._cache: dict[str, dict[str, Any]] = {}
19
- self._default_client = TokenClient()
20
-
21
- async def get_token_details(
22
- self, token_id: str, force_refresh: bool = False
23
- ) -> dict[str, Any]:
24
- cache_key = f"token_{token_id}"
25
- if not force_refresh and cache_key in self._cache:
26
- return self._cache[cache_key]
27
- data = await self._default_client.get_token_details(token_id, force_refresh)
28
- self._cache[cache_key] = data
29
- return data
30
-
31
- async def get_gas_token(self, chain_code: str) -> dict[str, Any]:
32
- return await self._default_client.get_gas_token(chain_code)
33
-
34
-
35
- class MockHyperlendClient:
36
- """Mock client for testing"""
37
-
38
- async def get_stable_markets(
39
- self,
40
- *,
41
- required_underlying_tokens: float | None = None,
42
- buffer_bps: int | None = None,
43
- min_buffer_tokens: float | None = None,
44
- ) -> dict[str, Any]:
45
- return {
46
- "markets": {
47
- "0xMockToken": {
48
- "symbol": "USDC",
49
- "symbol_canonical": "usdc",
50
- "display_symbol": "USDC",
51
- "reserve": {},
52
- "decimals": 6,
53
- "headroom": 1000000000000,
54
- "supply_cap": 5000000000000,
55
- }
56
- },
57
- "notes": [],
58
- }
59
-
60
- async def get_assets_view(
61
- self,
62
- *,
63
- user_address: str,
64
- ) -> dict[str, Any]:
65
- return {
66
- "block_number": 12345,
67
- "user": user_address,
68
- "native_balance_wei": 0,
69
- "native_balance": 0.0,
70
- "assets": [],
71
- "account_data": {
72
- "total_collateral_base": 0,
73
- "total_debt_base": 0,
74
- "available_borrows_base": 0,
75
- "current_liquidation_threshold": 0,
76
- "ltv": 0,
77
- "health_factor_wad": 0,
78
- "health_factor": 0.0,
79
- },
80
- "base_currency_info": {
81
- "marketReferenceCurrencyUnit": 100000000,
82
- "marketReferenceCurrencyPriceInUsd": 100000000,
83
- "networkBaseTokenPriceInUsd": 0,
84
- "networkBaseTokenPriceDecimals": 8,
85
- },
86
- }
87
-
88
- async def get_market_entry(
89
- self,
90
- *,
91
- token: str,
92
- ) -> dict[str, Any]:
93
- return {
94
- "symbol": "USDC",
95
- "symbol_canonical": "usdc",
96
- "display_symbol": "USDC",
97
- "reserve": {},
98
- }
99
-
100
- async def get_lend_rate_history(
101
- self,
102
- *,
103
- token: str,
104
- lookback_hours: int,
105
- force_refresh: bool | None = None,
106
- ) -> dict[str, Any]:
107
- return {
108
- "history": [],
109
- }
110
-
111
-
112
- async def example_sdk_usage():
113
- """Direct client injection - inject only what you customize"""
114
-
115
- custom_token_client = CachedTokenClient()
116
- custom_hyperlend_client = MockHyperlendClient()
117
-
118
- ClientManager(
119
- clients={
120
- "token": custom_token_client,
121
- "hyperlend": custom_hyperlend_client,
122
- },
123
- skip_auth=True,
124
- )
125
- pass
@@ -1,5 +0,0 @@
1
- """Core Engine Module"""
2
-
3
- from .StrategyJob import StrategyJob
4
-
5
- __all__ = ["StrategyJob", "GLOBAL_IMPORTS"]
File without changes
@@ -1,130 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Any
3
-
4
- from web3 import AsyncWeb3
5
-
6
- from wayfinder_paths.core.constants.base import DEFAULT_TRANSACTION_TIMEOUT
7
-
8
-
9
- class TokenTxn(ABC):
10
- """Interface describing high-level EVM transaction builders."""
11
-
12
- @abstractmethod
13
- async def build_send(
14
- self,
15
- *,
16
- token_id: str,
17
- amount: float,
18
- from_address: str,
19
- to_address: str,
20
- token_info: dict[str, Any] | None = None,
21
- ) -> tuple[bool, dict[str, Any] | str]:
22
- """Build raw transaction data for sending tokens."""
23
-
24
- @abstractmethod
25
- def build_erc20_approve(
26
- self,
27
- *,
28
- chain_id: int,
29
- token_address: str,
30
- from_address: str,
31
- spender: str,
32
- amount: int,
33
- ) -> tuple[bool, dict[str, Any] | str]:
34
- """Build raw ERC20 approve transaction data."""
35
-
36
- @abstractmethod
37
- async def read_erc20_allowance(
38
- self, chain: Any, token_address: str, from_address: str, spender_address: str
39
- ) -> dict[str, Any]:
40
- """Read allowance granted for a spender."""
41
-
42
-
43
- class EvmTxn(ABC):
44
- """
45
- Abstract base class for wallet providers.
46
-
47
- This interface abstracts all blockchain interactions needed by adapters so the
48
- rest of the codebase never touches raw web3 primitives. Implementations
49
- are responsible for RPC resolution, gas estimation, signing, broadcasting and
50
- transaction confirmations.
51
- """
52
-
53
- @abstractmethod
54
- async def broadcast_transaction(
55
- self,
56
- transaction: dict[str, Any],
57
- *,
58
- wait_for_receipt: bool = True,
59
- timeout: int = DEFAULT_TRANSACTION_TIMEOUT,
60
- ) -> tuple[bool, Any]:
61
- """
62
- Sign and broadcast a transaction dict.
63
-
64
- Providers must handle gas estimation, gas pricing, nonce selection, signing
65
- and submission internally so callers can simply pass the transaction data.
66
-
67
- Args:
68
- transaction: Dictionary describing the transaction (to, data, value, etc.)
69
- wait_for_receipt: Whether to wait for the transaction receipt
70
- timeout: Receipt timeout in seconds
71
- """
72
- pass
73
-
74
- @abstractmethod
75
- async def transaction_succeeded(
76
- self, tx_hash: str, chain_id: int, timeout: int = 120
77
- ) -> bool:
78
- """
79
- Check if a transaction hash succeeded on-chain.
80
-
81
- Args:
82
- tx_hash: Transaction hash to inspect
83
- chain_id: Chain ID where the transaction was broadcast
84
- timeout: Maximum seconds to wait for a receipt
85
-
86
- Returns:
87
- Boolean indicating whether the transaction completed successfully.
88
- """
89
- pass
90
-
91
- @abstractmethod
92
- def get_web3(self, chain_id: int) -> AsyncWeb3:
93
- """
94
- Return an AsyncWeb3 instance configured for the given chain.
95
-
96
- Implementations may create new instances per call or pull from an internal
97
- cache, but they must document whether the caller is responsible for closing
98
- the underlying HTTP session.
99
- """
100
- pass
101
-
102
-
103
- class Web3Service(ABC):
104
- """Facade that exposes low-level wallet access and higher-level EVM helpers."""
105
-
106
- @property
107
- @abstractmethod
108
- def evm_transactions(self) -> EvmTxn:
109
- """Return the wallet provider responsible for RPC, signing, and broadcasting."""
110
-
111
- @property
112
- @abstractmethod
113
- def token_transactions(self) -> TokenTxn:
114
- """Returns TokenTxn, for sends and swaps of any token"""
115
-
116
- async def broadcast_transaction(
117
- self,
118
- transaction: dict[str, Any],
119
- *,
120
- wait_for_receipt: bool = True,
121
- timeout: int = DEFAULT_TRANSACTION_TIMEOUT,
122
- ) -> tuple[bool, Any]:
123
- """Proxy convenience wrapper to underlying wallet provider."""
124
- return await self.evm_transactions.broadcast_transaction(
125
- transaction, wait_for_receipt=wait_for_receipt, timeout=timeout
126
- )
127
-
128
- def get_web3(self, chain_id: int):
129
- """Expose underlying web3 provider for ABI encoding helpers."""
130
- return self.evm_transactions.get_web3(chain_id)