wayfinder-paths 0.1.8__py3-none-any.whl → 0.1.10__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 (80) hide show
  1. wayfinder_paths/CONFIG_GUIDE.md +6 -15
  2. wayfinder_paths/adapters/balance_adapter/README.md +1 -2
  3. wayfinder_paths/adapters/balance_adapter/adapter.py +4 -4
  4. wayfinder_paths/adapters/brap_adapter/README.md +1 -1
  5. wayfinder_paths/adapters/brap_adapter/adapter.py +139 -74
  6. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +0 -7
  7. wayfinder_paths/adapters/hyperliquid_adapter/adapter.py +0 -54
  8. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +1 -1
  9. wayfinder_paths/adapters/ledger_adapter/README.md +1 -1
  10. wayfinder_paths/adapters/moonwell_adapter/README.md +174 -0
  11. wayfinder_paths/adapters/moonwell_adapter/__init__.py +7 -0
  12. wayfinder_paths/adapters/moonwell_adapter/adapter.py +1226 -0
  13. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +635 -0
  14. wayfinder_paths/adapters/pool_adapter/README.md +1 -77
  15. wayfinder_paths/adapters/pool_adapter/adapter.py +0 -122
  16. wayfinder_paths/adapters/pool_adapter/examples.json +0 -57
  17. wayfinder_paths/adapters/pool_adapter/test_adapter.py +0 -86
  18. wayfinder_paths/adapters/token_adapter/README.md +1 -1
  19. wayfinder_paths/core/clients/ClientManager.py +1 -22
  20. wayfinder_paths/core/clients/WalletClient.py +0 -8
  21. wayfinder_paths/core/clients/WayfinderClient.py +7 -12
  22. wayfinder_paths/core/clients/__init__.py +0 -8
  23. wayfinder_paths/core/clients/protocols.py +0 -60
  24. wayfinder_paths/core/config.py +5 -45
  25. wayfinder_paths/core/constants/__init__.py +0 -2
  26. wayfinder_paths/core/constants/base.py +6 -2
  27. wayfinder_paths/core/constants/moonwell_abi.py +411 -0
  28. wayfinder_paths/core/services/base.py +7 -1
  29. wayfinder_paths/core/services/local_evm_txn.py +223 -222
  30. wayfinder_paths/core/services/local_token_txn.py +103 -92
  31. wayfinder_paths/core/services/web3_service.py +0 -2
  32. wayfinder_paths/core/settings.py +8 -8
  33. wayfinder_paths/core/strategies/Strategy.py +1 -5
  34. wayfinder_paths/core/strategies/descriptors.py +1 -1
  35. wayfinder_paths/core/utils/evm_helpers.py +7 -12
  36. wayfinder_paths/core/wallets/README.md +3 -6
  37. wayfinder_paths/run_strategy.py +62 -105
  38. wayfinder_paths/scripts/create_strategy.py +2 -27
  39. wayfinder_paths/scripts/make_wallets.py +1 -25
  40. wayfinder_paths/scripts/run_strategy.py +37 -9
  41. wayfinder_paths/strategies/basis_trading_strategy/snapshot_mixin.py +1 -3
  42. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +87 -138
  43. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +96 -58
  44. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/README.md +2 -17
  45. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/examples.json +4 -1
  46. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +107 -29
  47. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +53 -14
  48. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +108 -0
  49. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/examples.json +11 -0
  50. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2975 -0
  51. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +886 -0
  52. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +0 -7
  53. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +2 -7
  54. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +0 -4
  55. wayfinder_paths/templates/adapter/README.md +5 -21
  56. wayfinder_paths/templates/adapter/adapter.py +1 -2
  57. wayfinder_paths/templates/adapter/test_adapter.py +1 -1
  58. wayfinder_paths/templates/strategy/README.md +4 -21
  59. wayfinder_paths/templates/strategy/test_strategy.py +0 -4
  60. wayfinder_paths/tests/test_smoke_manifest.py +17 -2
  61. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/METADATA +64 -201
  62. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/RECORD +64 -71
  63. wayfinder_paths/adapters/balance_adapter/manifest.yaml +0 -8
  64. wayfinder_paths/adapters/brap_adapter/manifest.yaml +0 -11
  65. wayfinder_paths/adapters/hyperlend_adapter/manifest.yaml +0 -10
  66. wayfinder_paths/adapters/hyperliquid_adapter/manifest.yaml +0 -8
  67. wayfinder_paths/adapters/ledger_adapter/manifest.yaml +0 -11
  68. wayfinder_paths/adapters/pool_adapter/manifest.yaml +0 -10
  69. wayfinder_paths/adapters/token_adapter/manifest.yaml +0 -6
  70. wayfinder_paths/core/clients/SimulationClient.py +0 -192
  71. wayfinder_paths/core/clients/TransactionClient.py +0 -63
  72. wayfinder_paths/core/engine/manifest.py +0 -97
  73. wayfinder_paths/scripts/validate_manifests.py +0 -213
  74. wayfinder_paths/strategies/basis_trading_strategy/manifest.yaml +0 -23
  75. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/manifest.yaml +0 -7
  76. wayfinder_paths/strategies/stablecoin_yield_strategy/manifest.yaml +0 -17
  77. wayfinder_paths/templates/adapter/manifest.yaml +0 -6
  78. wayfinder_paths/templates/strategy/manifest.yaml +0 -8
  79. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/LICENSE +0 -0
  80. {wayfinder_paths-0.1.8.dist-info → wayfinder_paths-0.1.10.dist-info}/WHEEL +0 -0
@@ -4,7 +4,6 @@ Separates user-provided configuration from system configuration
4
4
  """
5
5
 
6
6
  import json
7
- import os
8
7
  from dataclasses import dataclass, field
9
8
  from pathlib import Path
10
9
  from typing import Any
@@ -72,12 +71,8 @@ class SystemConfig:
72
71
  These are values managed by the Wayfinder system
73
72
  """
74
73
 
75
- # API endpoints (populated from environment or defaults)
76
- api_base_url: str = field(
77
- default_factory=lambda: os.getenv(
78
- "WAYFINDER_API_URL", "https://api.wayfinder.ai"
79
- )
80
- )
74
+ # API endpoints (populated from config.json or defaults)
75
+ api_base_url: str = field(default="https://api.wayfinder.ai")
81
76
 
82
77
  # Job configuration
83
78
  job_id: str | None = None
@@ -102,10 +97,7 @@ class SystemConfig:
102
97
  def from_dict(cls, data: dict[str, Any]) -> "SystemConfig":
103
98
  """Create SystemConfig from dictionary"""
104
99
  return cls(
105
- api_base_url=data.get(
106
- "api_base_url",
107
- os.getenv("WAYFINDER_API_URL", "https://api.wayfinder.ai"),
108
- ),
100
+ api_base_url=data.get("api_base_url", "https://api.wayfinder.ai"),
109
101
  job_id=data.get("job_id"),
110
102
  job_type=data.get("job_type", "strategy"),
111
103
  update_interval=data.get("update_interval", 60),
@@ -113,10 +105,8 @@ class SystemConfig:
113
105
  retry_delay=data.get("retry_delay", 5),
114
106
  log_path=data.get("log_path"),
115
107
  data_path=data.get("data_path"),
116
- wallets_path=data.get(
117
- "wallets_path", os.getenv("WALLETS_PATH", "wallets.json")
118
- ),
119
- wallet_id=data.get("wallet_id") or os.getenv("WALLET_ID"),
108
+ wallets_path=data.get("wallets_path", "wallets.json"),
109
+ wallet_id=data.get("wallet_id"),
120
110
  )
121
111
 
122
112
  def to_dict(self) -> dict[str, Any]:
@@ -386,36 +376,6 @@ class StrategyJobConfig:
386
376
  return config
387
377
 
388
378
 
389
- def load_config_from_env() -> StrategyJobConfig:
390
- """
391
- Load configuration from environment variables
392
- This is the simplest way for users to provide configuration
393
- """
394
- user_config = UserConfig(
395
- username=os.getenv("WAYFINDER_USERNAME"),
396
- password=os.getenv("WAYFINDER_PASSWORD"),
397
- refresh_token=os.getenv("WAYFINDER_REFRESH_TOKEN"),
398
- main_wallet_address=os.getenv("MAIN_WALLET_ADDRESS"),
399
- strategy_wallet_address=os.getenv("STRATEGY_WALLET_ADDRESS"),
400
- default_slippage=float(os.getenv("DEFAULT_SLIPPAGE", "0.005")),
401
- gas_multiplier=float(os.getenv("GAS_MULTIPLIER", "1.2")),
402
- )
403
-
404
- system_config = SystemConfig(
405
- api_base_url=os.getenv("WAYFINDER_API_URL", "https://api.wayfinder.ai"),
406
- job_id=os.getenv("JOB_ID"),
407
- update_interval=int(os.getenv("UPDATE_INTERVAL", "60")),
408
- max_retries=int(os.getenv("MAX_RETRIES", "3")),
409
- retry_delay=int(os.getenv("RETRY_DELAY", "5")),
410
- wallets_path=os.getenv("WALLETS_PATH", "wallets.json"),
411
- wallet_id=os.getenv("WALLET_ID"),
412
- )
413
-
414
- # No auto-population - wallets must be explicitly set in environment or matched by label
415
-
416
- return StrategyJobConfig(user=user_config, system=system_config)
417
-
418
-
419
379
  # --- Internal helpers -------------------------------------------------------
420
380
 
421
381
 
@@ -7,7 +7,6 @@ This package contains all constants used across the system, organized by categor
7
7
 
8
8
  from .base import (
9
9
  CHAIN_CODE_TO_ID,
10
- DEFAULT_GAS_ESTIMATE_FALLBACK,
11
10
  DEFAULT_NATIVE_GAS_UNITS,
12
11
  DEFAULT_SLIPPAGE,
13
12
  GAS_BUFFER_MULTIPLIER,
@@ -19,7 +18,6 @@ __all__ = [
19
18
  "ZERO_ADDRESS",
20
19
  "CHAIN_CODE_TO_ID",
21
20
  "DEFAULT_NATIVE_GAS_UNITS",
22
- "DEFAULT_GAS_ESTIMATE_FALLBACK",
23
21
  "GAS_BUFFER_MULTIPLIER",
24
22
  "ONE_GWEI",
25
23
  "DEFAULT_SLIPPAGE",
@@ -19,13 +19,17 @@ CHAIN_CODE_TO_ID = {
19
19
 
20
20
  # Gas/defaults
21
21
  DEFAULT_NATIVE_GAS_UNITS = 21000
22
- DEFAULT_GAS_ESTIMATE_FALLBACK = 100000
22
+ # Fallback gas limit used only when RPC gas estimation fails for non-revert reasons.
23
+ # Must be high enough for typical DeFi interactions (lending, swaps, etc.).
23
24
  GAS_BUFFER_MULTIPLIER = 1.1 # 10% buffer for native sends
24
25
  ONE_GWEI = 1_000_000_000
25
26
  DEFAULT_SLIPPAGE = 0.005
26
27
 
27
28
  # Timeout constants (seconds)
28
- DEFAULT_TRANSACTION_TIMEOUT = 120 # Transaction receipt wait timeout
29
+ # Base L2 (and some RPC providers) can occasionally take >2 minutes to index/return receipts,
30
+ # even if the transaction is eventually mined. A longer timeout reduces false negatives that
31
+ # can lead to unsafe retry behavior (nonce gaps, duplicate swaps, etc.).
32
+ DEFAULT_TRANSACTION_TIMEOUT = 300 # Transaction receipt wait timeout
29
33
  DEFAULT_HTTP_TIMEOUT = 30.0 # HTTP client timeout
30
34
 
31
35
  # Adapter type identifiers
@@ -0,0 +1,411 @@
1
+ """
2
+ Moonwell ABI constants for smart contract interactions.
3
+
4
+ This module contains ABI definitions for Moonwell protocol contracts,
5
+ including mToken (ERC20 Delegator), Comptroller, and Reward Distributor contracts.
6
+ """
7
+
8
+ # mToken (CErc20Delegator) ABI - for lending, borrowing, and position management
9
+ MTOKEN_ABI = [
10
+ # Lend (supply) tokens by minting mTokens
11
+ {
12
+ "name": "mint",
13
+ "type": "function",
14
+ "stateMutability": "nonpayable",
15
+ "inputs": [{"name": "mintAmount", "type": "uint256"}],
16
+ "outputs": [{"name": "", "type": "uint256"}],
17
+ },
18
+ # Withdraw (redeem) underlying by burning mTokens
19
+ {
20
+ "name": "redeem",
21
+ "type": "function",
22
+ "stateMutability": "nonpayable",
23
+ "inputs": [{"name": "redeemTokens", "type": "uint256"}],
24
+ "outputs": [{"name": "", "type": "uint256"}],
25
+ },
26
+ # Withdraw exact underlying amount
27
+ {
28
+ "name": "redeemUnderlying",
29
+ "type": "function",
30
+ "stateMutability": "nonpayable",
31
+ "inputs": [{"name": "redeemAmount", "type": "uint256"}],
32
+ "outputs": [{"name": "", "type": "uint256"}],
33
+ },
34
+ # Borrow underlying tokens
35
+ {
36
+ "name": "borrow",
37
+ "type": "function",
38
+ "stateMutability": "nonpayable",
39
+ "inputs": [{"name": "borrowAmount", "type": "uint256"}],
40
+ "outputs": [{"name": "", "type": "uint256"}],
41
+ },
42
+ # Repay borrowed tokens
43
+ {
44
+ "name": "repayBorrow",
45
+ "type": "function",
46
+ "stateMutability": "nonpayable",
47
+ "inputs": [{"name": "repayAmount", "type": "uint256"}],
48
+ "outputs": [{"name": "", "type": "uint256"}],
49
+ },
50
+ # Get mToken balance
51
+ {
52
+ "name": "balanceOf",
53
+ "type": "function",
54
+ "stateMutability": "view",
55
+ "inputs": [{"name": "owner", "type": "address"}],
56
+ "outputs": [{"name": "", "type": "uint256"}],
57
+ },
58
+ # Get underlying balance (including accrued interest)
59
+ {
60
+ "name": "balanceOfUnderlying",
61
+ "type": "function",
62
+ "stateMutability": "nonpayable",
63
+ "inputs": [{"name": "owner", "type": "address"}],
64
+ "outputs": [{"name": "", "type": "uint256"}],
65
+ },
66
+ # Get current borrow balance (including interest)
67
+ {
68
+ "name": "borrowBalanceCurrent",
69
+ "type": "function",
70
+ "stateMutability": "nonpayable",
71
+ "inputs": [{"name": "account", "type": "address"}],
72
+ "outputs": [{"name": "", "type": "uint256"}],
73
+ },
74
+ # Get stored borrow balance (without accruing interest first)
75
+ {
76
+ "name": "borrowBalanceStored",
77
+ "type": "function",
78
+ "stateMutability": "view",
79
+ "inputs": [{"name": "account", "type": "address"}],
80
+ "outputs": [{"name": "", "type": "uint256"}],
81
+ },
82
+ # Get exchange rate between mToken and underlying
83
+ {
84
+ "name": "exchangeRateCurrent",
85
+ "type": "function",
86
+ "stateMutability": "nonpayable",
87
+ "inputs": [],
88
+ "outputs": [{"name": "", "type": "uint256"}],
89
+ },
90
+ # Get stored exchange rate
91
+ {
92
+ "name": "exchangeRateStored",
93
+ "type": "function",
94
+ "stateMutability": "view",
95
+ "inputs": [],
96
+ "outputs": [{"name": "", "type": "uint256"}],
97
+ },
98
+ # Get underlying token address
99
+ {
100
+ "name": "underlying",
101
+ "type": "function",
102
+ "stateMutability": "view",
103
+ "inputs": [],
104
+ "outputs": [{"name": "", "type": "address"}],
105
+ },
106
+ # Get supply rate per timestamp
107
+ {
108
+ "name": "supplyRatePerTimestamp",
109
+ "type": "function",
110
+ "stateMutability": "view",
111
+ "inputs": [],
112
+ "outputs": [{"name": "", "type": "uint256"}],
113
+ },
114
+ # Get borrow rate per timestamp
115
+ {
116
+ "name": "borrowRatePerTimestamp",
117
+ "type": "function",
118
+ "stateMutability": "view",
119
+ "inputs": [],
120
+ "outputs": [{"name": "", "type": "uint256"}],
121
+ },
122
+ # Get total borrows
123
+ {
124
+ "name": "totalBorrows",
125
+ "type": "function",
126
+ "stateMutability": "view",
127
+ "inputs": [],
128
+ "outputs": [{"name": "", "type": "uint256"}],
129
+ },
130
+ # Get total supply of mTokens
131
+ {
132
+ "name": "totalSupply",
133
+ "type": "function",
134
+ "stateMutability": "view",
135
+ "inputs": [],
136
+ "outputs": [{"name": "", "type": "uint256"}],
137
+ },
138
+ # Get cash (available liquidity)
139
+ {
140
+ "name": "getCash",
141
+ "type": "function",
142
+ "stateMutability": "view",
143
+ "inputs": [],
144
+ "outputs": [{"name": "", "type": "uint256"}],
145
+ },
146
+ # Accrue interest
147
+ {
148
+ "name": "accrueInterest",
149
+ "type": "function",
150
+ "stateMutability": "nonpayable",
151
+ "inputs": [],
152
+ "outputs": [{"name": "", "type": "uint256"}],
153
+ },
154
+ # Get decimals
155
+ {
156
+ "name": "decimals",
157
+ "type": "function",
158
+ "stateMutability": "view",
159
+ "inputs": [],
160
+ "outputs": [{"name": "", "type": "uint8"}],
161
+ },
162
+ ]
163
+
164
+ # Comptroller ABI - for collateral management and account liquidity
165
+ COMPTROLLER_ABI = [
166
+ # Enable a market as collateral
167
+ {
168
+ "name": "enterMarkets",
169
+ "type": "function",
170
+ "stateMutability": "nonpayable",
171
+ "inputs": [{"name": "mTokens", "type": "address[]"}],
172
+ "outputs": [{"name": "", "type": "uint256[]"}],
173
+ },
174
+ # Disable a market as collateral
175
+ {
176
+ "name": "exitMarket",
177
+ "type": "function",
178
+ "stateMutability": "nonpayable",
179
+ "inputs": [{"name": "mTokenAddress", "type": "address"}],
180
+ "outputs": [{"name": "", "type": "uint256"}],
181
+ },
182
+ # Get account liquidity (error, liquidity, shortfall)
183
+ {
184
+ "name": "getAccountLiquidity",
185
+ "type": "function",
186
+ "stateMutability": "view",
187
+ "inputs": [{"name": "account", "type": "address"}],
188
+ "outputs": [
189
+ {"name": "error", "type": "uint256"},
190
+ {"name": "liquidity", "type": "uint256"},
191
+ {"name": "shortfall", "type": "uint256"},
192
+ ],
193
+ },
194
+ # Get market info (isListed, collateralFactorMantissa)
195
+ {
196
+ "name": "markets",
197
+ "type": "function",
198
+ "stateMutability": "view",
199
+ "inputs": [{"name": "mToken", "type": "address"}],
200
+ "outputs": [
201
+ {"name": "isListed", "type": "bool"},
202
+ {"name": "collateralFactorMantissa", "type": "uint256"},
203
+ ],
204
+ },
205
+ # Check if account has entered a market
206
+ {
207
+ "name": "checkMembership",
208
+ "type": "function",
209
+ "stateMutability": "view",
210
+ "inputs": [
211
+ {"name": "account", "type": "address"},
212
+ {"name": "mToken", "type": "address"},
213
+ ],
214
+ "outputs": [{"name": "", "type": "bool"}],
215
+ },
216
+ # Get all markets an account has entered
217
+ {
218
+ "name": "getAssetsIn",
219
+ "type": "function",
220
+ "stateMutability": "view",
221
+ "inputs": [{"name": "account", "type": "address"}],
222
+ "outputs": [{"name": "", "type": "address[]"}],
223
+ },
224
+ # Get all listed markets
225
+ {
226
+ "name": "getAllMarkets",
227
+ "type": "function",
228
+ "stateMutability": "view",
229
+ "inputs": [],
230
+ "outputs": [{"name": "", "type": "address[]"}],
231
+ },
232
+ # Get hypothetical account liquidity
233
+ {
234
+ "name": "getHypotheticalAccountLiquidity",
235
+ "type": "function",
236
+ "stateMutability": "view",
237
+ "inputs": [
238
+ {"name": "account", "type": "address"},
239
+ {"name": "mTokenModify", "type": "address"},
240
+ {"name": "redeemTokens", "type": "uint256"},
241
+ {"name": "borrowAmount", "type": "uint256"},
242
+ ],
243
+ "outputs": [
244
+ {"name": "error", "type": "uint256"},
245
+ {"name": "liquidity", "type": "uint256"},
246
+ {"name": "shortfall", "type": "uint256"},
247
+ ],
248
+ },
249
+ # Get close factor
250
+ {
251
+ "name": "closeFactorMantissa",
252
+ "type": "function",
253
+ "stateMutability": "view",
254
+ "inputs": [],
255
+ "outputs": [{"name": "", "type": "uint256"}],
256
+ },
257
+ # Get liquidation incentive
258
+ {
259
+ "name": "liquidationIncentiveMantissa",
260
+ "type": "function",
261
+ "stateMutability": "view",
262
+ "inputs": [],
263
+ "outputs": [{"name": "", "type": "uint256"}],
264
+ },
265
+ # Claim rewards for a user (called on comptroller in some versions)
266
+ {
267
+ "name": "claimReward",
268
+ "type": "function",
269
+ "stateMutability": "nonpayable",
270
+ "inputs": [{"name": "holder", "type": "address"}],
271
+ "outputs": [],
272
+ },
273
+ ]
274
+
275
+ # Reward Distributor ABI - for claiming WELL rewards
276
+ REWARD_DISTRIBUTOR_ABI = [
277
+ # Claim rewards for all markets
278
+ {
279
+ "name": "claimReward",
280
+ "type": "function",
281
+ "stateMutability": "nonpayable",
282
+ "inputs": [],
283
+ "outputs": [],
284
+ },
285
+ # Claim rewards for specific holder and markets
286
+ {
287
+ "name": "claimReward",
288
+ "type": "function",
289
+ "stateMutability": "nonpayable",
290
+ "inputs": [
291
+ {"name": "holder", "type": "address"},
292
+ {"name": "mTokens", "type": "address[]"},
293
+ ],
294
+ "outputs": [],
295
+ },
296
+ # Get reward token address
297
+ {
298
+ "name": "rewardToken",
299
+ "type": "function",
300
+ "stateMutability": "view",
301
+ "inputs": [],
302
+ "outputs": [{"name": "", "type": "address"}],
303
+ },
304
+ # Get pending rewards (accrued but not yet claimed)
305
+ {
306
+ "name": "rewardAccrued",
307
+ "type": "function",
308
+ "stateMutability": "view",
309
+ "inputs": [{"name": "holder", "type": "address"}],
310
+ "outputs": [{"name": "", "type": "uint256"}],
311
+ },
312
+ # Get outstanding rewards for a user across all markets
313
+ # Returns array of (mToken, [(rewardToken, totalReward, supplySide, borrowSide)])
314
+ {
315
+ "name": "getOutstandingRewardsForUser",
316
+ "type": "function",
317
+ "stateMutability": "view",
318
+ "inputs": [{"name": "user", "type": "address"}],
319
+ "outputs": [
320
+ {
321
+ "name": "",
322
+ "type": "tuple[]",
323
+ "components": [
324
+ {"name": "mToken", "type": "address"},
325
+ {
326
+ "name": "rewards",
327
+ "type": "tuple[]",
328
+ "components": [
329
+ {"name": "rewardToken", "type": "address"},
330
+ {"name": "totalReward", "type": "uint256"},
331
+ {"name": "supplySide", "type": "uint256"},
332
+ {"name": "borrowSide", "type": "uint256"},
333
+ ],
334
+ },
335
+ ],
336
+ }
337
+ ],
338
+ },
339
+ # Get outstanding rewards for a user for a specific mToken
340
+ {
341
+ "name": "getOutstandingRewardsForUser",
342
+ "type": "function",
343
+ "stateMutability": "view",
344
+ "inputs": [
345
+ {"name": "mToken", "type": "address"},
346
+ {"name": "user", "type": "address"},
347
+ ],
348
+ "outputs": [
349
+ {
350
+ "name": "",
351
+ "type": "tuple[]",
352
+ "components": [
353
+ {"name": "rewardToken", "type": "address"},
354
+ {"name": "totalReward", "type": "uint256"},
355
+ {"name": "supplySide", "type": "uint256"},
356
+ {"name": "borrowSide", "type": "uint256"},
357
+ ],
358
+ }
359
+ ],
360
+ },
361
+ # Get all market configurations for an mToken
362
+ # Returns array of (mToken, rewardToken, supplyEmissionsPerSec, borrowEmissionsPerSec, ...)
363
+ {
364
+ "name": "getAllMarketConfigs",
365
+ "type": "function",
366
+ "stateMutability": "view",
367
+ "inputs": [{"name": "mToken", "type": "address"}],
368
+ "outputs": [
369
+ {
370
+ "name": "",
371
+ "type": "tuple[]",
372
+ "components": [
373
+ {"name": "mToken", "type": "address"},
374
+ {"name": "rewardToken", "type": "address"},
375
+ {"name": "owner", "type": "address"},
376
+ {"name": "emissionCap", "type": "uint256"},
377
+ {"name": "supplyEmissionsPerSec", "type": "uint256"},
378
+ {"name": "borrowEmissionsPerSec", "type": "uint256"},
379
+ {"name": "supplyGlobalIndex", "type": "uint256"},
380
+ {"name": "borrowGlobalIndex", "type": "uint256"},
381
+ {"name": "endTime", "type": "uint256"},
382
+ ],
383
+ }
384
+ ],
385
+ },
386
+ ]
387
+
388
+ # WETH ABI for wrapping/unwrapping ETH
389
+ WETH_ABI = [
390
+ {
391
+ "name": "deposit",
392
+ "type": "function",
393
+ "stateMutability": "payable",
394
+ "inputs": [],
395
+ "outputs": [],
396
+ },
397
+ {
398
+ "name": "withdraw",
399
+ "type": "function",
400
+ "stateMutability": "nonpayable",
401
+ "inputs": [{"name": "wad", "type": "uint256"}],
402
+ "outputs": [],
403
+ },
404
+ {
405
+ "name": "balanceOf",
406
+ "type": "function",
407
+ "stateMutability": "view",
408
+ "inputs": [{"name": "account", "type": "address"}],
409
+ "outputs": [{"name": "", "type": "uint256"}],
410
+ },
411
+ ]
@@ -56,14 +56,20 @@ class EvmTxn(ABC):
56
56
  address: str,
57
57
  token_address: str | None,
58
58
  chain_id: int,
59
+ block_identifier: int | str | None = None,
59
60
  ) -> tuple[bool, Any]:
60
61
  """
61
- Get balance for an address.
62
+ Get balance for an address at a specific block.
62
63
 
63
64
  Args:
64
65
  address: Address to query balance for
65
66
  token_address: ERC20 token address, or None for native token
66
67
  chain_id: Chain ID
68
+ block_identifier: Block to query at. Can be:
69
+ - int: specific block number (for pinning to tx block)
70
+ - "safe": OP Stack safe block (data posted to L1)
71
+ - "finalized": fully finalized block
72
+ - None/"latest": current head (default, but avoid after txs)
67
73
 
68
74
  Returns:
69
75
  Tuple of (success, balance_integer_or_error_message)