primecli 0.11.3__tar.gz → 0.11.4__tar.gz

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 (33) hide show
  1. {primecli-0.11.3 → primecli-0.11.4}/PKG-INFO +2 -2
  2. {primecli-0.11.3 → primecli-0.11.4}/README.md +1 -1
  3. {primecli-0.11.3 → primecli-0.11.4}/primecli/degenprime.py +45 -4
  4. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/PKG-INFO +2 -2
  5. {primecli-0.11.3 → primecli-0.11.4}/pyproject.toml +1 -1
  6. {primecli-0.11.3 → primecli-0.11.4}/LICENSE +0 -0
  7. {primecli-0.11.3 → primecli-0.11.4}/primecli/__init__.py +0 -0
  8. {primecli-0.11.3 → primecli-0.11.4}/primecli/_flowledger.py +0 -0
  9. {primecli-0.11.3 → primecli-0.11.4}/primecli/_wallets.py +0 -0
  10. {primecli-0.11.3 → primecli-0.11.4}/primecli/arbprime.py +0 -0
  11. {primecli-0.11.3 → primecli-0.11.4}/primecli/bridge.py +0 -0
  12. {primecli-0.11.3 → primecli-0.11.4}/primecli/deltaprime.py +0 -0
  13. {primecli-0.11.3 → primecli-0.11.4}/primecli/health_monitor.py +0 -0
  14. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/SOURCES.txt +0 -0
  15. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/dependency_links.txt +0 -0
  16. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/entry_points.txt +0 -0
  17. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/requires.txt +0 -0
  18. {primecli-0.11.3 → primecli-0.11.4}/primecli.egg-info/top_level.txt +0 -0
  19. {primecli-0.11.3 → primecli-0.11.4}/setup.cfg +0 -0
  20. {primecli-0.11.3 → primecli-0.11.4}/tests/test_aero_range_and_swap_fallback.py +0 -0
  21. {primecli-0.11.3 → primecli-0.11.4}/tests/test_aero_rebalance.py +0 -0
  22. {primecli-0.11.3 → primecli-0.11.4}/tests/test_aero_v3_collision_fixes.py +0 -0
  23. {primecli-0.11.3 → primecli-0.11.4}/tests/test_bridge.py +0 -0
  24. {primecli-0.11.3 → primecli-0.11.4}/tests/test_cross_file_identity.py +0 -0
  25. {primecli-0.11.3 → primecli-0.11.4}/tests/test_flowledger_transferred_amount.py +0 -0
  26. {primecli-0.11.3 → primecli-0.11.4}/tests/test_gas_limit.py +0 -0
  27. {primecli-0.11.3 → primecli-0.11.4}/tests/test_gas_pricing.py +0 -0
  28. {primecli-0.11.3 → primecli-0.11.4}/tests/test_health_meter.py +0 -0
  29. {primecli-0.11.3 → primecli-0.11.4}/tests/test_health_monitor.py +0 -0
  30. {primecli-0.11.3 → primecli-0.11.4}/tests/test_paraswap_requote.py +0 -0
  31. {primecli-0.11.3 → primecli-0.11.4}/tests/test_paraswap_validator.py +0 -0
  32. {primecli-0.11.3 → primecli-0.11.4}/tests/test_redstone_encoding.py +0 -0
  33. {primecli-0.11.3 → primecli-0.11.4}/tests/test_to_wei_units.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: primecli
3
- Version: 0.11.3
3
+ Version: 0.11.4
4
4
  Summary: Agent-friendly CLI tools for the DeltaPrime (Avalanche + Arbitrum) and DegenPrime (Base) lending and leverage protocols. Preview-by-default; no Etherscan key required.
5
5
  Author: Mnemosyne-quest contributors
6
6
  License: MIT
@@ -47,7 +47,7 @@ Built for agent use:
47
47
  - RedStone-signed solvency math handled internally, with a regression test pinning the half-boundary `toFixed(8)` encoding.
48
48
  - ParaSwap calldata validated client-side against the on-chain executor allowlist before broadcast.
49
49
 
50
- **Current version:** 0.11.3 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
50
+ **Current version:** 0.11.4 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
51
51
 
52
52
  > **Breaking change in 0.5.0:** there is no longer a default signing key. Earlier versions silently fell back to a baked-in agent when no key was configured; that fallback has been removed. With no key configured, every command now fails closed with `No signing key found...`. Set a key explicitly (see [Configuration](#configuration)).
53
53
 
@@ -16,7 +16,7 @@ Built for agent use:
16
16
  - RedStone-signed solvency math handled internally, with a regression test pinning the half-boundary `toFixed(8)` encoding.
17
17
  - ParaSwap calldata validated client-side against the on-chain executor allowlist before broadcast.
18
18
 
19
- **Current version:** 0.11.3 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
19
+ **Current version:** 0.11.4 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
20
20
 
21
21
  > **Breaking change in 0.5.0:** there is no longer a default signing key. Earlier versions silently fell back to a baked-in agent when no key was configured; that fallback has been removed. With no key configured, every command now fails closed with `No signing key found...`. Set a key explicitly (see [Configuration](#configuration)).
22
22
 
@@ -3398,6 +3398,43 @@ def _paraswap_requote_until_clean(src_token, src_dec, dest_token, dest_dec, amou
3398
3398
  print(f" ✗ All {_PARASWAP_REQUOTE_ATTEMPTS} ParaSwap quotes reverted in simulation.")
3399
3399
  return last
3400
3400
 
3401
+ # Bounded slippage escalation: re-quoting at a FIXED slippage_pct only helps when
3402
+ # ParaSwap rotates to a different (whitelisted) executor/route. It does nothing when
3403
+ # ParaSwap's own off-chain quote is itself measurably rich vs the pool's live price -
3404
+ # confirmed on a WETH/EURC Aerodrome Slipstream pool where the quote sat ~3.2% above
3405
+ # the pool's own slot0 price, so every requote at 1% slippage reverted identically with
3406
+ # SwapFailed() (0x81ceff30, the facet's wrapper around ParaSwap's own
3407
+ # InsufficientReturnAmount()). Widening slippage (not re-quoting) is what actually
3408
+ # clears that case. Steps up only on that exact failure signature - a different error
3409
+ # (e.g. insufficient balance) won't be fixed by more slippage room, so we stop
3410
+ # immediately rather than burning extra RPC round-trips.
3411
+ _SLIPPAGE_ESCALATION_STEP_PCT = 1.5
3412
+ _SLIPPAGE_ESCALATION_MAX_PCT = 4.5 # stays clear of the facet's hard 5% ceiling
3413
+
3414
+ def _paraswap_swap_with_escalation(src_token, src_dec, dest_token, dest_dec, amount_in_wei,
3415
+ slippage_pct, pa_cs, sim_fn):
3416
+ """Wraps _paraswap_requote_until_clean with bounded slippage escalation (see above).
3417
+ Starts at the caller's slippage_pct (unchanged behavior if that already clears).
3418
+ On an all-attempts-failed SwapFailed() result, steps slippage_pct up by
3419
+ _SLIPPAGE_ESCALATION_STEP_PCT and re-runs the full requote loop, capped at
3420
+ _SLIPPAGE_ESCALATION_MAX_PCT. Returns the same shape as
3421
+ _paraswap_requote_until_clean (the last attempted route, sim_ok reflecting whether
3422
+ it ultimately cleared)."""
3423
+ slip = slippage_pct
3424
+ while True:
3425
+ route = _paraswap_requote_until_clean(src_token, src_dec, dest_token, dest_dec,
3426
+ amount_in_wei, slip, pa_cs, sim_fn)
3427
+ route["slippage_pct_used"] = slip
3428
+ if route["sim_ok"] or slip >= _SLIPPAGE_ESCALATION_MAX_PCT:
3429
+ return route
3430
+ if not route["last_err"] or "81ceff30" not in str(route["last_err"]):
3431
+ return route # different failure mode - more slippage room won't fix it
3432
+ next_slip = min(slip + _SLIPPAGE_ESCALATION_STEP_PCT, _SLIPPAGE_ESCALATION_MAX_PCT)
3433
+ print(f" All quotes failed with SwapFailed() at {slip:.2f}% slippage - the "
3434
+ f"ParaSwap quote may be stale vs the live pool price. Retrying at "
3435
+ f"{next_slip:.2f}%...")
3436
+ slip = next_slip
3437
+
3401
3438
  def cmd_swap(from_sym: str, to_sym: str, amount: float, slippage_pct: float = 1.0,
3402
3439
  execute: bool = False):
3403
3440
  """Swap one in-account asset for another via the Degen Account on ParaSwap v6.
@@ -3464,19 +3501,22 @@ def cmd_swap(from_sym: str, to_sym: str, amount: float, slippage_pct: float = 1.
3464
3501
  return True, None
3465
3502
  except Exception as e:
3466
3503
  return False, str(e)
3467
- route = _paraswap_requote_until_clean(
3504
+ route = _paraswap_swap_with_escalation(
3468
3505
  from_cfg["token"], from_cfg["decimals"], to_cfg["token"], to_cfg["decimals"],
3469
3506
  amount_in, slippage_pct, pa_cs, _sim_paraswap)
3470
3507
  price_route, tx_built, full = route["price_route"], route["tx_built"], route["full"]
3471
3508
  selector_hex, data_bytes = route["selector_hex"], route["data_bytes"]
3472
3509
  quoted_out, min_out, sim_ok = route["quoted_out"], route["min_out"], route["sim_ok"]
3510
+ slippage_used = route.get("slippage_pct_used", slippage_pct)
3473
3511
 
3474
3512
  print(f"Swap {amount} {from_asset_sym} -> {to_asset_sym} on Degen Account {pa_cs} (via ParaSwap/Velora)")
3475
3513
  print(f" Router method: {price_route['contractMethod']} ({selector_hex})")
3476
3514
  print(f" Augustus router: {tx_built['to']}")
3477
3515
  print(f" Expected out: {quoted_out / 10**to_cfg['decimals']:.6f} {to_asset_sym}")
3478
3516
  if min_out is not None:
3479
- print(f" Min out (@{slippage_pct}% slippage): {min_out / 10**to_cfg['decimals']:.6f} {to_asset_sym}")
3517
+ print(f" Min out (@{slippage_used:.2f}% slippage): {min_out / 10**to_cfg['decimals']:.6f} {to_asset_sym}")
3518
+ if slippage_used != slippage_pct:
3519
+ print(f" (requested {slippage_pct}% was not routable - escalated to {slippage_used:.2f}% to clear SwapFailed())")
3480
3520
  print(f" ParaSwap srcUSD ${price_route.get('srcUSD','?')} -> destUSD ${price_route.get('destUSD','?')}")
3481
3521
  print(" Facet enforces a 5% hard slippage cap (RedStone-priced) on top of this.")
3482
3522
 
@@ -3485,8 +3525,9 @@ def cmd_swap(from_sym: str, to_sym: str, amount: float, slippage_pct: float = 1.
3485
3525
  return
3486
3526
 
3487
3527
  if not sim_ok:
3488
- print(f"✗ Refusing to broadcast: every ParaSwap quote reverted in simulation "
3489
- f"({_PARASWAP_REQUOTE_ATTEMPTS} attempts). Try again shortly.")
3528
+ print(f"✗ Refusing to broadcast: every ParaSwap quote reverted in simulation, "
3529
+ f"even after escalating slippage tolerance up to {slippage_used:.2f}%. "
3530
+ "Try again shortly.")
3490
3531
  return
3491
3532
 
3492
3533
  # Rebuild the payload fresh for broadcast (the sim payload may be near the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: primecli
3
- Version: 0.11.3
3
+ Version: 0.11.4
4
4
  Summary: Agent-friendly CLI tools for the DeltaPrime (Avalanche + Arbitrum) and DegenPrime (Base) lending and leverage protocols. Preview-by-default; no Etherscan key required.
5
5
  Author: Mnemosyne-quest contributors
6
6
  License: MIT
@@ -47,7 +47,7 @@ Built for agent use:
47
47
  - RedStone-signed solvency math handled internally, with a regression test pinning the half-boundary `toFixed(8)` encoding.
48
48
  - ParaSwap calldata validated client-side against the on-chain executor allowlist before broadcast.
49
49
 
50
- **Current version:** 0.11.3 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
50
+ **Current version:** 0.11.4 The 0.x line is pre-1.0, so breaking changes are possible. See [Releases](https://github.com/Mnemosyne-quest/primecli/releases).
51
51
 
52
52
  > **Breaking change in 0.5.0:** there is no longer a default signing key. Earlier versions silently fell back to a baked-in agent when no key was configured; that fallback has been removed. With no key configured, every command now fails closed with `No signing key found...`. Set a key explicitly (see [Configuration](#configuration)).
53
53
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "primecli"
7
- version = "0.11.3"
7
+ version = "0.11.4"
8
8
  description = "Agent-friendly CLI tools for the DeltaPrime (Avalanche + Arbitrum) and DegenPrime (Base) lending and leverage protocols. Preview-by-default; no Etherscan key required."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes