wayfinder-paths 0.1.13__py3-none-any.whl → 0.1.15__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 (61) hide show
  1. wayfinder_paths/adapters/balance_adapter/README.md +13 -14
  2. wayfinder_paths/adapters/balance_adapter/adapter.py +73 -32
  3. wayfinder_paths/adapters/balance_adapter/test_adapter.py +123 -0
  4. wayfinder_paths/adapters/brap_adapter/README.md +11 -16
  5. wayfinder_paths/adapters/brap_adapter/adapter.py +144 -78
  6. wayfinder_paths/adapters/brap_adapter/examples.json +63 -52
  7. wayfinder_paths/adapters/brap_adapter/test_adapter.py +127 -65
  8. wayfinder_paths/adapters/hyperlend_adapter/adapter.py +30 -14
  9. wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +121 -67
  10. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +6 -6
  11. wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +12 -12
  12. wayfinder_paths/adapters/ledger_adapter/test_adapter.py +6 -6
  13. wayfinder_paths/adapters/moonwell_adapter/adapter.py +332 -9
  14. wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +13 -13
  15. wayfinder_paths/adapters/pool_adapter/README.md +9 -10
  16. wayfinder_paths/adapters/pool_adapter/adapter.py +9 -10
  17. wayfinder_paths/adapters/pool_adapter/test_adapter.py +2 -2
  18. wayfinder_paths/adapters/token_adapter/README.md +2 -14
  19. wayfinder_paths/adapters/token_adapter/adapter.py +16 -10
  20. wayfinder_paths/adapters/token_adapter/examples.json +4 -8
  21. wayfinder_paths/adapters/token_adapter/test_adapter.py +9 -7
  22. wayfinder_paths/core/clients/BRAPClient.py +102 -61
  23. wayfinder_paths/core/clients/ClientManager.py +1 -68
  24. wayfinder_paths/core/clients/HyperlendClient.py +125 -64
  25. wayfinder_paths/core/clients/LedgerClient.py +1 -4
  26. wayfinder_paths/core/clients/PoolClient.py +122 -48
  27. wayfinder_paths/core/clients/TokenClient.py +91 -36
  28. wayfinder_paths/core/clients/WalletClient.py +26 -56
  29. wayfinder_paths/core/clients/WayfinderClient.py +28 -160
  30. wayfinder_paths/core/clients/__init__.py +0 -2
  31. wayfinder_paths/core/clients/protocols.py +35 -46
  32. wayfinder_paths/core/clients/sdk_example.py +37 -22
  33. wayfinder_paths/core/constants/erc20_abi.py +0 -11
  34. wayfinder_paths/core/engine/StrategyJob.py +10 -56
  35. wayfinder_paths/core/services/base.py +1 -0
  36. wayfinder_paths/core/services/local_evm_txn.py +25 -9
  37. wayfinder_paths/core/services/local_token_txn.py +2 -6
  38. wayfinder_paths/core/services/test_local_evm_txn.py +145 -0
  39. wayfinder_paths/core/strategies/Strategy.py +16 -4
  40. wayfinder_paths/core/utils/evm_helpers.py +2 -9
  41. wayfinder_paths/policies/erc20.py +1 -1
  42. wayfinder_paths/run_strategy.py +13 -19
  43. wayfinder_paths/strategies/basis_trading_strategy/strategy.py +77 -11
  44. wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +6 -6
  45. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +107 -23
  46. wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +54 -9
  47. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +6 -5
  48. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2246 -1279
  49. wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +276 -109
  50. wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +1 -1
  51. wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +153 -56
  52. wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +16 -12
  53. wayfinder_paths/templates/adapter/README.md +1 -1
  54. wayfinder_paths/templates/strategy/README.md +3 -3
  55. wayfinder_paths/templates/strategy/test_strategy.py +3 -2
  56. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/METADATA +14 -49
  57. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/RECORD +59 -60
  58. wayfinder_paths/abis/generic/erc20.json +0 -383
  59. wayfinder_paths/core/clients/AuthClient.py +0 -83
  60. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/LICENSE +0 -0
  61. {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/WHEEL +0 -0
@@ -50,7 +50,10 @@ def strategy():
50
50
 
51
51
  if hasattr(s, "balance_adapter") and s.balance_adapter:
52
52
  # Mock balances: 1000 USDT0 (with 6 decimals) and 2 HYPE (with 18 decimals)
53
- def get_balance_side_effect(token_id, wallet_address, **kwargs):
53
+ def get_balance_side_effect(query, wallet_address, **kwargs):
54
+ token_id = (
55
+ query if isinstance(query, str) else (query or {}).get("token_id")
56
+ )
54
57
  token_id_str = str(token_id).lower() if token_id else ""
55
58
  if "usdt0" in token_id_str or token_id_str == "usdt0":
56
59
  # 1000 USDT0 with 6 decimals = 1000 * 10^6 = 1000000000
@@ -209,7 +212,31 @@ def strategy():
209
212
 
210
213
  if hasattr(s, "hyperlend_adapter") and s.hyperlend_adapter:
211
214
  s.hyperlend_adapter.get_assets_view = AsyncMock(
212
- return_value=(True, {"assets_view": {"assets": []}})
215
+ return_value=(
216
+ True,
217
+ {
218
+ "block_number": 12345,
219
+ "user": "0x0",
220
+ "native_balance_wei": 0,
221
+ "native_balance": 0.0,
222
+ "assets": [],
223
+ "account_data": {
224
+ "total_collateral_base": 0,
225
+ "total_debt_base": 0,
226
+ "available_borrows_base": 0,
227
+ "current_liquidation_threshold": 0,
228
+ "ltv": 0,
229
+ "health_factor_wad": 0,
230
+ "health_factor": 0.0,
231
+ },
232
+ "base_currency_info": {
233
+ "marketReferenceCurrencyUnit": 100000000,
234
+ "marketReferenceCurrencyPriceInUsd": 100000000,
235
+ "networkBaseTokenPriceInUsd": 0,
236
+ "networkBaseTokenPriceDecimals": 8,
237
+ },
238
+ },
239
+ )
213
240
  )
214
241
  s.hyperlend_adapter.get_stable_markets = AsyncMock(
215
242
  return_value=(
@@ -232,14 +259,24 @@ def strategy():
232
259
  },
233
260
  )
234
261
  )
262
+ # Block bootstrap needs at least BLOCK_LEN (6) rows; provide enough history
263
+ _history_base = {
264
+ "timestamp_ms": 1700000000000,
265
+ "timestamp": 1700000000.0,
266
+ "supply_apr": 0.05,
267
+ "supply_apy": 0.05,
268
+ "borrow_apr": 0.07,
269
+ "borrow_apy": 0.07,
270
+ "token": "0x1234567890123456789012345678901234567890",
271
+ "symbol": "usdt0",
272
+ "display_symbol": "USDT0",
273
+ }
274
+ history_rows = [
275
+ {**_history_base, "timestamp_ms": 1700000000000 + i * 3600000}
276
+ for i in range(24)
277
+ ]
235
278
  s.hyperlend_adapter.get_lend_rate_history = AsyncMock(
236
- return_value=(
237
- True,
238
- {
239
- "rates": [{"rate": 5.0, "timestamp": 1700000000}],
240
- "avg_rate": 5.0,
241
- },
242
- )
279
+ return_value=(True, {"history": history_rows})
243
280
  )
244
281
 
245
282
  s.usdt_token_info = {
@@ -259,6 +296,14 @@ def strategy():
259
296
  "chain": {"code": "hyperevm", "id": 9999, "name": "HyperEVM"},
260
297
  }
261
298
  s.current_token = None
299
+ # Attributes normally set in setup()
300
+ s.rotation_policy = "hysteresis"
301
+ s.hys_dwell_hours = 168
302
+ s.hys_z = 1.15
303
+ s.rotation_tx_cost = 0.002
304
+ s.last_summary = None
305
+ s.last_dominance = None
306
+ s.last_samples = None
262
307
 
263
308
  if hasattr(s, "token_adapter") and s.token_adapter:
264
309
  if not hasattr(s.token_adapter, "get_token_price"):
@@ -31,9 +31,10 @@ The position is **delta-neutral**: WETH debt offsets wstETH collateral, so PnL i
31
31
  ## Safety features
32
32
 
33
33
  - **Depeg guard**: `_max_safe_F()` calculates leverage ceiling based on wstETH collateral factor and max depeg tolerance.
34
- - **Delta-neutrality**: `_balance_weth_debt()` rebalances when WETH debt exceeds wstETH collateral value.
34
+ - **Delta-neutrality**: `_post_run_guard()` enforces wstETH collateral ≥ WETH debt (within tolerance) via `_reconcile_wallet_into_position()` and `_settle_weth_debt_to_target_usd()`.
35
35
  - **Swap retries**: `_swap_with_retries()` uses progressive slippage (0.5% → 1% → 1.5%) with exponential backoff.
36
36
  - **Health monitoring**: Automatic deleveraging when health factor drops below `MIN_HEALTH_FACTOR`.
37
+ - **Deterministic Base reads**: waits 2 blocks after receipts by default and pins ETH/ERC20 balance reads to the confirmed block to avoid stale RPC reads on Base.
37
38
  - **Rollback protection**: Checks actual balances before rollback swaps to prevent failed transactions.
38
39
 
39
40
  ## Adapters used
@@ -58,9 +59,9 @@ The position is **delta-neutral**: WETH debt offsets wstETH collateral, so PnL i
58
59
  ### Update
59
60
 
60
61
  - Checks gas balance meets maintenance threshold.
61
- - Balances WETH debt against wstETH collateral for delta-neutrality.
62
- - Computes health factor from aggregated positions.
63
- - If HF < MIN: triggers deleveraging via `_repay_debt_loop()`.
62
+ - Reconciles wallet leftovers into the intended position (`_reconcile_wallet_into_position()`).
63
+ - Computes HF/LTV/delta from a single accounting snapshot.
64
+ - If HF < MIN: triggers deleveraging via `_settle_weth_debt_to_target_usd()`.
64
65
  - If HF > MAX: executes additional leverage loops to optimize yield.
65
66
  - Claims WELL rewards if above minimum threshold.
66
67
 
@@ -75,7 +76,7 @@ The position is **delta-neutral**: WETH debt offsets wstETH collateral, so PnL i
75
76
  ### Withdraw
76
77
 
77
78
  - Sweeps miscellaneous token balances to WETH.
78
- - Repays all WETH debt via `_repay_debt_loop()`.
79
+ - Repays all WETH debt via `_settle_weth_debt_to_target_usd(target_debt_usd=0.0, mode="exit")`.
79
80
  - Unlends wstETH, swaps to USDC.
80
81
  - Unlends USDC collateral.
81
82
  - Returns USDC and remaining ETH to main wallet.