DeFiPy 2.1.0__tar.gz → 2.2.0__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 (116) hide show
  1. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/PKG-INFO +58 -52
  2. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/requires.txt +3 -3
  3. {defipy-2.1.0 → defipy-2.2.0}/PKG-INFO +58 -52
  4. {defipy-2.1.0 → defipy-2.2.0}/README.md +54 -48
  5. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/_rpc.py +96 -0
  6. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/live_provider.py +193 -20
  7. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/snapshot.py +2 -3
  8. {defipy-2.1.0 → defipy-2.2.0}/setup.py +11 -10
  9. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/SOURCES.txt +0 -0
  10. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/dependency_links.txt +0 -0
  11. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/not-zip-safe +0 -0
  12. {defipy-2.1.0 → defipy-2.2.0}/DeFiPy.egg-info/top_level.txt +0 -0
  13. {defipy-2.1.0 → defipy-2.2.0}/LICENSE +0 -0
  14. {defipy-2.1.0 → defipy-2.2.0}/NOTICE +0 -0
  15. {defipy-2.1.0 → defipy-2.2.0}/python/prod/__init__.py +0 -0
  16. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/ImpermanentLossAgent.py +0 -0
  17. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/PriceThresholdSwapAgent.py +0 -0
  18. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/TVLBasedLiquidityExitAgent.py +0 -0
  19. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/VolumeSpikeNotifierAgent.py +0 -0
  20. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/__init__.py +0 -0
  21. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/config/ImpermanentLossConfig.py +0 -0
  22. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/config/PriceThresholdConfig.py +0 -0
  23. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/config/TVLExitConfig.py +0 -0
  24. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/config/VolumeSpikeConfig.py +0 -0
  25. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/config/__init__.py +0 -0
  26. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/data/UniswapPoolData.py +0 -0
  27. {defipy-2.1.0 → defipy-2.2.0}/python/prod/agents/data/__init__.py +0 -0
  28. {defipy-2.1.0 → defipy-2.2.0}/python/prod/analytics/risk/__init__.py +0 -0
  29. {defipy-2.1.0 → defipy-2.2.0}/python/prod/analytics/simulate/__init__.py +0 -0
  30. {defipy-2.1.0 → defipy-2.2.0}/python/prod/erc/__init__.py +0 -0
  31. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/basic/__init__.py +0 -0
  32. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/interest/__init__.py +0 -0
  33. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/interest/ips/__init__.py +0 -0
  34. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/interest/ips/aggregate/__init__.py +0 -0
  35. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/model/__init__.py +0 -0
  36. {defipy-2.1.0 → defipy-2.2.0}/python/prod/math/risk/__init__.py +0 -0
  37. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/__init__.py +0 -0
  38. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/comparison/CompareFeeTiers.py +0 -0
  39. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/comparison/CompareProtocols.py +0 -0
  40. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/comparison/__init__.py +0 -0
  41. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/execution/CalculateSlippage.py +0 -0
  42. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/execution/DetectMEV.py +0 -0
  43. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/execution/__init__.py +0 -0
  44. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/optimization/EvaluateRebalance.py +0 -0
  45. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/optimization/EvaluateTickRanges.py +0 -0
  46. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/optimization/OptimalDepositSplit.py +0 -0
  47. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/optimization/__init__.py +0 -0
  48. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/pool_health/CheckPoolHealth.py +0 -0
  49. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/pool_health/DetectFeeAnomaly.py +0 -0
  50. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/pool_health/DetectRugSignals.py +0 -0
  51. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/pool_health/__init__.py +0 -0
  52. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/portfolio/AggregatePortfolio.py +0 -0
  53. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/portfolio/__init__.py +0 -0
  54. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/AnalyzeBalancerPosition.py +0 -0
  55. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/AnalyzePosition.py +0 -0
  56. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/AnalyzeStableswapPosition.py +0 -0
  57. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/FindBreakEvenPrice.py +0 -0
  58. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/FindBreakEvenTime.py +0 -0
  59. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/SimulateBalancerPriceMove.py +0 -0
  60. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/SimulatePriceMove.py +0 -0
  61. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/SimulateStableswapPriceMove.py +0 -0
  62. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/position/__init__.py +0 -0
  63. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/risk/AssessDepegRisk.py +0 -0
  64. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/risk/CheckTickRangeStatus.py +0 -0
  65. {defipy-2.1.0 → defipy-2.2.0}/python/prod/primitives/risk/__init__.py +0 -0
  66. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/__init__.py +0 -0
  67. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/burn/__init__.py +0 -0
  68. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/deposit/__init__.py +0 -0
  69. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/join/Join.py +0 -0
  70. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/join/__init__.py +0 -0
  71. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/liquidity/AddLiquidity.py +0 -0
  72. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/liquidity/RemoveLiquidity.py +0 -0
  73. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/liquidity/__init__.py +0 -0
  74. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/mint/__init__.py +0 -0
  75. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/swap/Swap.py +0 -0
  76. {defipy-2.1.0 → defipy-2.2.0}/python/prod/process/swap/__init__.py +0 -0
  77. {defipy-2.1.0 → defipy-2.2.0}/python/prod/tools/__init__.py +0 -0
  78. {defipy-2.1.0 → defipy-2.2.0}/python/prod/tools/registry.py +0 -0
  79. {defipy-2.1.0 → defipy-2.2.0}/python/prod/tools/schemas.py +0 -0
  80. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/__init__.py +0 -0
  81. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/builder.py +0 -0
  82. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/mock_provider.py +0 -0
  83. {defipy-2.1.0 → defipy-2.2.0}/python/prod/twin/provider.py +0 -0
  84. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/client/__init__.py +0 -0
  85. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/client/contract/ExecuteScript.py +0 -0
  86. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/client/contract/__init__.py +0 -0
  87. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/BalancerPositionAnalysis.py +0 -0
  88. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/BalancerPriceMoveScenario.py +0 -0
  89. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/BreakEvenAlphas.py +0 -0
  90. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/BreakEvenTime.py +0 -0
  91. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/DepegRiskAssessment.py +0 -0
  92. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/DepositSplitResult.py +0 -0
  93. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/FeeAnomalyResult.py +0 -0
  94. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/FeeTierCandidate.py +0 -0
  95. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/FeeTierComparison.py +0 -0
  96. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/MEVDetectionResult.py +0 -0
  97. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/PoolHealth.py +0 -0
  98. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/PortfolioAnalysis.py +0 -0
  99. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/PortfolioPosition.py +0 -0
  100. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/PositionAnalysis.py +0 -0
  101. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/PriceMoveScenario.py +0 -0
  102. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/ProtocolComparison.py +0 -0
  103. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/RebalanceCostReport.py +0 -0
  104. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/RugSignalReport.py +0 -0
  105. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/SlippageAnalysis.py +0 -0
  106. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/StableswapPositionAnalysis.py +0 -0
  107. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/StableswapPriceMoveScenario.py +0 -0
  108. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/TickRangeCandidate.py +0 -0
  109. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/TickRangeEvaluation.py +0 -0
  110. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/TickRangeStatus.py +0 -0
  111. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/data/__init__.py +0 -0
  112. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/interfaces/__init__.py +0 -0
  113. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/tools/UniswapScriptHelper.py +0 -0
  114. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/tools/__init__.py +0 -0
  115. {defipy-2.1.0 → defipy-2.2.0}/python/prod/utils/tools/v3/__init__.py +0 -0
  116. {defipy-2.1.0 → defipy-2.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DeFiPy
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Python SDK for Agentic DeFi
5
5
  Home-page: http://github.com/defipy-devs/defipy
6
6
  Author: icmoore
@@ -21,17 +21,17 @@ Requires-Dist: uniswappy>=1.7.9
21
21
  Requires-Dist: balancerpy>=1.1.0
22
22
  Requires-Dist: stableswappy>=1.1.0
23
23
  Provides-Extra: chain
24
- Requires-Dist: web3scout>=0.2.0; extra == "chain"
24
+ Requires-Dist: web3scout>=1.0.0; extra == "chain"
25
25
  Requires-Dist: web3<7.0,>=6.0; extra == "chain"
26
26
  Provides-Extra: book
27
- Requires-Dist: web3scout>=0.2.0; extra == "book"
27
+ Requires-Dist: web3scout>=1.0.0; extra == "book"
28
28
  Requires-Dist: web3<7.0,>=6.0; extra == "book"
29
29
  Provides-Extra: anvil
30
30
  Requires-Dist: web3<7.0,>=6.0; extra == "anvil"
31
31
  Provides-Extra: mcp
32
32
  Requires-Dist: mcp>=1.27.0; extra == "mcp"
33
33
  Provides-Extra: agentic
34
- Requires-Dist: web3scout>=0.2.0; extra == "agentic"
34
+ Requires-Dist: web3scout>=1.0.0; extra == "agentic"
35
35
  Requires-Dist: web3<7.0,>=6.0; extra == "agentic"
36
36
  Requires-Dist: mcp>=1.27.0; extra == "agentic"
37
37
  Dynamic: author
@@ -55,13 +55,22 @@ Underneath, DeFiPy is modular by protocol:
55
55
  * [BalancerPy](https://github.com/defipy-devs/balancerpy)
56
56
  * [StableSwapPy](https://github.com/defipy-devs/stableswappy)
57
57
 
58
- For onchain event access and scripting, use [LiveProvider](https://defipy.org/live-provider/) as of v2.1 — it pulls live pool state into the same primitive surface that runs against synthetic recipes. Under the hood it's powered by [Web3Scout](https://github.com/defipy-devs/web3scout); install via the `[chain]` extra (see below).
58
+ For onchain event access and scripting, use [LiveProvider](https://defipy.org/live-provider/) as of v2.1 — it pulls live pool state into the same primitive surface that runs against synthetic recipes. Under the hood it's powered by [Web3Scout](https://github.com/defipy-devs/web3scout); install via the `[chain]` extra (see below). For details on architecture behind [State Twins](https://defipy.org/twin-concept/), see paper [![arXiv](https://img.shields.io/badge/arXiv-2605.11522-b31b1b.svg)](https://arxiv.org/abs/2605.11522)
59
59
 
60
- 🔗 SPDX-Anchor: [anchorregistry.ai/AR-2026-YdPXB5g](https://anchorregistry.ai/AR-2026-YdPXB5g)
60
+ ## 🆕 What's new in v2.2
61
+
62
+ v2.2 extends `LiveProvider` from Uniswap V2/V3 to **Balancer** and **Curve-style Stableswap** — chain reads now cover all four protocol families through the same `provider.snapshot(...)` → `StateTwinBuilder().build(...)` flow.
63
+
64
+ * **Balancer LiveProvider** — `provider.snapshot("balancer:0xADDR")` builds a `BalancerPoolSnapshot` from a real Balancer V2 weighted pool (2-asset). Two block-pinned round trips, since token balances live on the Vault keyed by `poolId`. Normalized weights read honestly; reserves decimal-adjusted.
65
+ * **Stableswap LiveProvider** — `provider.snapshot("stableswap:0xADDR")` builds an N-coin `StableswapPoolSnapshot` (N ∈ {2, 3}, e.g. the DAI/USDC/USDT 3pool) from a real Curve plain pool. Coin count comes from an `n_coins` hint or an automatic `coins(0..K)` probe; plain pools only.
66
+ * **`multicall_aggregate3_args`** — an argument-bearing Multicall3 batch (encodes calldata args, optional `allow_failure`) powering the Balancer/Curve reads alongside the no-arg getters, all block-pinned. The existing no-arg `multicall_aggregate3` and the V3 path are unchanged.
67
+ * **web3scout `>= 1.0.0`** — the `[chain]` / `[book]` / `[agentic]` extras now pin web3scout 1.0, which carries the Balancer/Curve read ABIs.
68
+
69
+ See the [CHANGELOG](./CHANGELOG.md) for the full v2.2 entry. v2.2 is a strict superset of v2.1.
61
70
 
62
71
  ## 🆕 What's new in v2.1
63
72
 
64
- v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real**. `LiveProvider` ships for Uniswap V2 and V3 — chain reads compose with every primitive in the library, the same way `MockProvider` recipes do. The "what would happen if?" loop is now local: pull state once, simulate forever, decide before executing.
73
+ v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real** — the substrate formalized in [our arXiv paper](https://arxiv.org/abs/2605.11522). `LiveProvider` ships for Uniswap V2 and V3 — chain reads compose with every primitive in the library, the same way `MockProvider` recipes do. The "what would happen if?" loop is now local: pull state once, simulate forever, decide before executing.
65
74
 
66
75
  * **`LiveProvider`** — `provider.snapshot("uniswap_v2:0xADDR")` and `provider.snapshot("uniswap_v3:0xADDR")` build `V2PoolSnapshot` and `V3PoolSnapshot` from real on-chain state. Block pinning is automatic — `"latest"` resolves once at the top of `.snapshot()` and every read inside that snapshot pins to the same block. Pass `block_number=N` for historical reads.
67
76
  * **Multicall3 batching for V3** — V3 snapshots batch `slot0`, `liquidity`, `fee`, `tickSpacing`, `token0`, `token1`, and block timestamp into one [Multicall3](https://github.com/mds1/multicall) `aggregate3` round trip. Hardcoded canonical Multicall3 address; works on every major EVM chain.
@@ -74,14 +83,14 @@ v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real**. `LivePro
74
83
 
75
84
  V2.1 is a strict superset of v2.0 — every v2.0 primitive, MockProvider recipe, and MCP server pattern works identically. What changes is that the same primitives now run against live chain state without changing call shape.
76
85
 
77
- **What's deferred to v2.2:** Balancer and Stableswap LiveProvider implementations raise `NotImplementedError` pointing at the planned version. V3 tick bitmap walking is also v2.2 work; in v2.1, V3 LiveProvider snapshots cover active-liquidity only primitives that depend on non-active-tick liquidity (e.g., `AssessLiquidityDepth`) ship in v2.2.
86
+ **What was deferred to v2.2 (now shipped):** Balancer and Stableswap LiveProvider reads landed in v2.2 (see above). Still open: V3 tick bitmap walking V3 LiveProvider snapshots cover active-liquidity only, so primitives that depend on non-active-tick liquidity (e.g., `AssessLiquidityDepth`) and N-asset Balancer / rate-bearing Curve pools remain future work.
78
87
 
79
88
  ## v2.0 foundations
80
89
 
81
90
  The State Twin abstraction, agentic primitives, and MCP server pattern shipped in v2.0. v2.1 builds on that surface without changing it:
82
91
 
83
92
  * **`defipy.tools`** — self-describing schemas for a curated set of 10 leaf primitives, in [Model Context Protocol](https://modelcontextprotocol.io) (MCP) format. Any MCP-compatible client can discover and invoke DeFiPy primitives as tools.
84
- * **`defipy.twin`** — the **State Twin** abstraction. `MockProvider` ships four canonical synthetic pools (V2, V3, Balancer, Stableswap) for notebooks and tests; `LiveProvider` ships chain reads for V2 and V3 in v2.1.
93
+ * **`defipy.twin`** — the **State Twin** abstraction. `MockProvider` ships four canonical synthetic pools (V2, V3, Balancer, Stableswap) for notebooks and tests; `LiveProvider` ships chain reads for all four families (V2/V3 in v2.1, Balancer/Stableswap in v2.2).
85
94
  * **MCP server demo** at [`python/mcp/`](./python/mcp/) — a stdio-transport server exposing DeFiPy's tools to Claude Desktop, Claude Code, or any MCP client. Install with `pip install defipy[mcp]` and see the [MCP server README](./python/mcp/README.md) for setup.
86
95
 
87
96
  ### What is MCP?
@@ -125,12 +134,14 @@ DeFiPy requires **Python 3.10 or later**. Install via pip:
125
134
 
126
135
  The core install is the pure analytics engine — AMM math, primitives, State Twin, and all 21 typed analytics functions. It has **zero web3 dependencies and zero LLM dependencies**. No chain reads, no RPC calls, no MCP. Chain reads come from [Web3Scout](https://github.com/defipy-devs/web3scout) (via the `[chain]` or `[book]` extras); MCP tool serving comes from the `[mcp]` extra. All optional.
127
136
 
137
+ > **Note for zsh users (default on macOS):** wrap any install spec with extras in single quotes — `pip install 'defipy[agentic]'` — so zsh doesn't try to glob the brackets. Without the quotes, you'll see `zsh: no matches found`. Bash users can use either form.
138
+
128
139
  ### Chain install (LiveProvider — v2.1+)
129
140
 
130
141
  To use `LiveProvider` for on-chain pool snapshots, install the `[chain]` extra:
131
142
 
132
143
  ```
133
- > pip install defipy[chain]
144
+ > pip install 'defipy[chain]'
134
145
  ```
135
146
 
136
147
  This pulls in `web3scout` (which `LiveProvider` uses internally for ABI loading, contract reads, and token-fetching) plus `web3.py`. With `[chain]` installed, you can construct twins from real chain state:
@@ -143,14 +154,14 @@ snapshot = provider.snapshot("uniswap_v2:0xB4e16d0168e52d35CaCD2c6185b44281Ec28C
143
154
  lp = StateTwinBuilder().build(snapshot)
144
155
  ```
145
156
 
146
- > **Note:** the `[chain]` extra pins `web3 < 7.0` because `web3scout 0.2.0` depends on `eth_utils.abi.get_abi_input_types`, which was removed in web3 7. If you have web3 7.x installed for other reasons, `pip install defipy[chain]` will downgrade it. Tracking upstream as v2.2 work.
157
+ > **Note:** the `[chain]` extra pins `web3 < 7.0` because `web3scout 0.2.0` depends on `eth_utils.abi.get_abi_input_types`, which was removed in web3 7. If you have web3 7.x installed for other reasons, `pip install 'defipy[chain]'` will downgrade it. Tracking upstream as v2.2 work.
147
158
 
148
159
  ### Agentic install (full LLM + chain stack)
149
160
 
150
161
  For users building LLM-driven systems against live chain state — the canonical *Python SDK for Agentic DeFi* use case — install the `[agentic]` extra:
151
162
 
152
163
  ```
153
- > pip install defipy[agentic]
164
+ > pip install 'defipy[agentic]'
154
165
  ```
155
166
 
156
167
  This composes `[chain]` and `[mcp]` in one step: `web3scout` and `web3.py` for `LiveProvider` chain reads, plus the `mcp` Python SDK for serving DeFiPy's primitives as tools to Claude Desktop, Claude Code, or any MCP-compatible client. Equivalent to `pip install defipy[chain,mcp]` but spelled with intent.
@@ -162,27 +173,17 @@ The same `web3 < 7.0` pin from the `[chain]` extra applies.
162
173
  To run the MCP server that exposes DeFiPy's primitives as tools to Claude Desktop, Claude Code, or any MCP-compatible client, install the `[mcp]` extra:
163
174
 
164
175
  ```
165
- > pip install defipy[mcp]
176
+ > pip install 'defipy[mcp]'
166
177
  ```
167
178
 
168
179
  This adds the [`mcp`](https://github.com/modelcontextprotocol/python-sdk) Python SDK on top of the core install. The MCP server itself lives at [`python/mcp/defipy_mcp_server.py`](./python/mcp/defipy_mcp_server.py); see [`python/mcp/README.md`](./python/mcp/README.md) for Claude Desktop and Claude Code configuration snippets.
169
180
 
170
- ### Book install (chapter 9 agents)
171
-
172
- Chapter 9 of *Hands-On AMMs with Python* — *Building Autonomous DeFi Agents* — uses live chain integration via `web3scout`. To run those examples, install the `[book]` extra:
173
-
174
- ```
175
- > pip install defipy[book]
176
- ```
177
-
178
- The `[book]` extra carries the same package set as `[chain]` (`web3scout` + `web3`). The split is intent-based — `[chain]` signals production live-state reads via LiveProvider; `[book]` signals textbook chapter 9 use. Either works for either purpose.
179
-
180
181
  ### Anvil install (local Foundry workflows)
181
182
 
182
183
  If you're using `ExecuteScript` or `UniswapScriptHelper` against a local [Anvil](https://book.getfoundry.sh/anvil/) node and don't need the full `web3scout` event-monitoring stack, the lighter `[anvil]` extra just adds `web3.py`:
183
184
 
184
185
  ```
185
- > pip install defipy[anvil]
186
+ > pip install 'defipy[anvil]'
186
187
  ```
187
188
 
188
189
  `[book]` and `[chain]` already include everything in `[anvil]`, so users on either of those don't need it separately.
@@ -218,13 +219,6 @@ See the [gmpy2 installation docs](https://gmpy2.readthedocs.io/en/latest/install
218
219
  DeFiPy is accompanied by educational resources for developers and researchers
219
220
  interested in on-chain analytics and DeFi modeling.
220
221
 
221
- ### 📘 Textbook
222
- **_DeFiPy: Python SDK for On-Chain Analytics_**
223
-
224
- A comprehensive guide to DeFi analytics, AMM modeling, and simulation.
225
-
226
- 🔗 **Buy on Amazon:** https://www.amazon.com/dp/B0G3RV5QRB
227
-
228
222
  ### 🎓 Course
229
223
  **On-Chain Analytics Foundations**
230
224
 
@@ -245,34 +239,27 @@ Topics include:
245
239
 
246
240
  The fastest way to see DeFiPy at work — pull a real Uniswap V2 pool's state from mainnet and run a primitive against it. Requires the `[chain]` install extra.
247
241
 
248
- from defipy import AnalyzePosition
242
+ from defipy import CheckPoolHealth
249
243
  from defipy.twin import LiveProvider, StateTwinBuilder
250
-
251
- # Pull live state from a real Uniswap V2 pool — WETH/USDC mainnet
252
- provider = LiveProvider("https://eth-mainnet.g.alchemy.com/v2/<key>")
244
+
245
+ # Pull live state from a real Uniswap V3 pool — USDC/WETH 500bps mainnet
246
+ provider = LiveProvider("https://mainnet.infura.io/v3/d2d6569915ec402b82c9379d033f8b9b")
253
247
  snapshot = provider.snapshot(
254
- "uniswap_v2:0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"
248
+ "uniswap_v3:0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"
255
249
  )
256
250
  lp = StateTwinBuilder().build(snapshot)
257
251
  lp.summary()
258
-
252
+
259
253
  # Snapshot carries chain context — block_number, timestamp, chain_id
260
- print(f"Block: {snapshot.block_number}")
261
- print(f"Reserves: {snapshot.token0_name}={snapshot.reserve0:.2f}, "
262
- f"{snapshot.token1_name}={snapshot.reserve1:.2f}")
263
-
254
+ print(f"Block: {snapshot.block_number}")
255
+
264
256
  # Run any primitive against the live twin — same call shape as MockProvider
265
- result = AnalyzePosition().apply(
266
- lp,
267
- lp_init_amt=1.0,
268
- entry_x_amt=1000,
269
- entry_y_amt=3_000_000,
270
- )
271
-
272
- print(f"Diagnosis: {result.diagnosis}")
273
- print(f"Net PnL: {result.net_pnl:.4f}")
274
- print(f"IL %: {result.il_percentage:.4f}")
275
- print(f"Current val: {result.current_value:.4f}")
257
+ health = CheckPoolHealth().apply(lp)
258
+ print(f"Fee tier: {health.fee_pips} pips")
259
+ print(f"TVL (USDC): {health.tvl_in_token0:,.2f}")
260
+ print(f"TVL (WETH): {health.tvl_in_token1:,.4f}")
261
+ print(f"Current tick: {health.tick_current}")
262
+ print(f"Spot price: {health.spot_price:.6f} WETH/USDC")
276
263
 
277
264
  The same shape works for V3 — swap `uniswap_v2:` for `uniswap_v3:` and the appropriate pool address (e.g. `0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640` for USDC/WETH 500bps). V3 snapshots default to full-range ticks; pass `lwr_tick=N, upr_tick=N` to override. See the [LiveProvider docs](https://defipy.org/live-provider/) for block pinning, the V3 tick-range surface, and the active-liquidity-only caveat.
278
265
 
@@ -344,7 +331,26 @@ To run the opt-in live-RPC tests, set `DEFIPY_LIVE_RPC` to a mainnet RPC URL:
344
331
 
345
332
  DEFIPY_LIVE_RPC=https://eth-mainnet.g.alchemy.com/v2/<key> pytest -m live_rpc -v
346
333
 
334
+ ## 📄 Citation
335
+
336
+ If you use DeFiPy in research, please cite the State Twin paper:
337
+
338
+ ```bibtex
339
+ @misc{moore2026statetwins,
340
+ title={State Twins: An Off-Chain Substrate for Agentic Reasoning over Decentralized Finance Protocols},
341
+ author={Moore, Ian C.},
342
+ year={2026},
343
+ eprint={2605.11522},
344
+ archivePrefix={arXiv},
345
+ primaryClass={cs.DC},
346
+ doi={10.48550/arXiv.2605.11522}
347
+ }
348
+ ```
349
+
347
350
  ## License
348
351
  Licensed under the Apache License, Version 2.0.
349
352
  See [LICENSE](./LICENSE) and [NOTICE](./NOTICE) for details.
350
353
  Portions of this project may include code from third-party projects under compatible open-source licenses.
354
+
355
+ <!-- Machine-readable provenance anchor -->
356
+ 🔗 SPDX-Anchor: [anchorregistry.ai/AR-2026-YdPXB5g](https://anchorregistry.ai/AR-2026-YdPXB5g)
@@ -11,7 +11,7 @@ balancerpy>=1.1.0
11
11
  stableswappy>=1.1.0
12
12
 
13
13
  [agentic]
14
- web3scout>=0.2.0
14
+ web3scout>=1.0.0
15
15
  web3<7.0,>=6.0
16
16
  mcp>=1.27.0
17
17
 
@@ -19,11 +19,11 @@ mcp>=1.27.0
19
19
  web3<7.0,>=6.0
20
20
 
21
21
  [book]
22
- web3scout>=0.2.0
22
+ web3scout>=1.0.0
23
23
  web3<7.0,>=6.0
24
24
 
25
25
  [chain]
26
- web3scout>=0.2.0
26
+ web3scout>=1.0.0
27
27
  web3<7.0,>=6.0
28
28
 
29
29
  [mcp]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DeFiPy
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Python SDK for Agentic DeFi
5
5
  Home-page: http://github.com/defipy-devs/defipy
6
6
  Author: icmoore
@@ -21,17 +21,17 @@ Requires-Dist: uniswappy>=1.7.9
21
21
  Requires-Dist: balancerpy>=1.1.0
22
22
  Requires-Dist: stableswappy>=1.1.0
23
23
  Provides-Extra: chain
24
- Requires-Dist: web3scout>=0.2.0; extra == "chain"
24
+ Requires-Dist: web3scout>=1.0.0; extra == "chain"
25
25
  Requires-Dist: web3<7.0,>=6.0; extra == "chain"
26
26
  Provides-Extra: book
27
- Requires-Dist: web3scout>=0.2.0; extra == "book"
27
+ Requires-Dist: web3scout>=1.0.0; extra == "book"
28
28
  Requires-Dist: web3<7.0,>=6.0; extra == "book"
29
29
  Provides-Extra: anvil
30
30
  Requires-Dist: web3<7.0,>=6.0; extra == "anvil"
31
31
  Provides-Extra: mcp
32
32
  Requires-Dist: mcp>=1.27.0; extra == "mcp"
33
33
  Provides-Extra: agentic
34
- Requires-Dist: web3scout>=0.2.0; extra == "agentic"
34
+ Requires-Dist: web3scout>=1.0.0; extra == "agentic"
35
35
  Requires-Dist: web3<7.0,>=6.0; extra == "agentic"
36
36
  Requires-Dist: mcp>=1.27.0; extra == "agentic"
37
37
  Dynamic: author
@@ -55,13 +55,22 @@ Underneath, DeFiPy is modular by protocol:
55
55
  * [BalancerPy](https://github.com/defipy-devs/balancerpy)
56
56
  * [StableSwapPy](https://github.com/defipy-devs/stableswappy)
57
57
 
58
- For onchain event access and scripting, use [LiveProvider](https://defipy.org/live-provider/) as of v2.1 — it pulls live pool state into the same primitive surface that runs against synthetic recipes. Under the hood it's powered by [Web3Scout](https://github.com/defipy-devs/web3scout); install via the `[chain]` extra (see below).
58
+ For onchain event access and scripting, use [LiveProvider](https://defipy.org/live-provider/) as of v2.1 — it pulls live pool state into the same primitive surface that runs against synthetic recipes. Under the hood it's powered by [Web3Scout](https://github.com/defipy-devs/web3scout); install via the `[chain]` extra (see below). For details on architecture behind [State Twins](https://defipy.org/twin-concept/), see paper [![arXiv](https://img.shields.io/badge/arXiv-2605.11522-b31b1b.svg)](https://arxiv.org/abs/2605.11522)
59
59
 
60
- 🔗 SPDX-Anchor: [anchorregistry.ai/AR-2026-YdPXB5g](https://anchorregistry.ai/AR-2026-YdPXB5g)
60
+ ## 🆕 What's new in v2.2
61
+
62
+ v2.2 extends `LiveProvider` from Uniswap V2/V3 to **Balancer** and **Curve-style Stableswap** — chain reads now cover all four protocol families through the same `provider.snapshot(...)` → `StateTwinBuilder().build(...)` flow.
63
+
64
+ * **Balancer LiveProvider** — `provider.snapshot("balancer:0xADDR")` builds a `BalancerPoolSnapshot` from a real Balancer V2 weighted pool (2-asset). Two block-pinned round trips, since token balances live on the Vault keyed by `poolId`. Normalized weights read honestly; reserves decimal-adjusted.
65
+ * **Stableswap LiveProvider** — `provider.snapshot("stableswap:0xADDR")` builds an N-coin `StableswapPoolSnapshot` (N ∈ {2, 3}, e.g. the DAI/USDC/USDT 3pool) from a real Curve plain pool. Coin count comes from an `n_coins` hint or an automatic `coins(0..K)` probe; plain pools only.
66
+ * **`multicall_aggregate3_args`** — an argument-bearing Multicall3 batch (encodes calldata args, optional `allow_failure`) powering the Balancer/Curve reads alongside the no-arg getters, all block-pinned. The existing no-arg `multicall_aggregate3` and the V3 path are unchanged.
67
+ * **web3scout `>= 1.0.0`** — the `[chain]` / `[book]` / `[agentic]` extras now pin web3scout 1.0, which carries the Balancer/Curve read ABIs.
68
+
69
+ See the [CHANGELOG](./CHANGELOG.md) for the full v2.2 entry. v2.2 is a strict superset of v2.1.
61
70
 
62
71
  ## 🆕 What's new in v2.1
63
72
 
64
- v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real**. `LiveProvider` ships for Uniswap V2 and V3 — chain reads compose with every primitive in the library, the same way `MockProvider` recipes do. The "what would happen if?" loop is now local: pull state once, simulate forever, decide before executing.
73
+ v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real** — the substrate formalized in [our arXiv paper](https://arxiv.org/abs/2605.11522). `LiveProvider` ships for Uniswap V2 and V3 — chain reads compose with every primitive in the library, the same way `MockProvider` recipes do. The "what would happen if?" loop is now local: pull state once, simulate forever, decide before executing.
65
74
 
66
75
  * **`LiveProvider`** — `provider.snapshot("uniswap_v2:0xADDR")` and `provider.snapshot("uniswap_v3:0xADDR")` build `V2PoolSnapshot` and `V3PoolSnapshot` from real on-chain state. Block pinning is automatic — `"latest"` resolves once at the top of `.snapshot()` and every read inside that snapshot pins to the same block. Pass `block_number=N` for historical reads.
67
76
  * **Multicall3 batching for V3** — V3 snapshots batch `slot0`, `liquidity`, `fee`, `tickSpacing`, `token0`, `token1`, and block timestamp into one [Multicall3](https://github.com/mds1/multicall) `aggregate3` round trip. Hardcoded canonical Multicall3 address; works on every major EVM chain.
@@ -74,14 +83,14 @@ v2.1 makes the [State Twin](https://defipy.org/twin-concept/) **real**. `LivePro
74
83
 
75
84
  V2.1 is a strict superset of v2.0 — every v2.0 primitive, MockProvider recipe, and MCP server pattern works identically. What changes is that the same primitives now run against live chain state without changing call shape.
76
85
 
77
- **What's deferred to v2.2:** Balancer and Stableswap LiveProvider implementations raise `NotImplementedError` pointing at the planned version. V3 tick bitmap walking is also v2.2 work; in v2.1, V3 LiveProvider snapshots cover active-liquidity only primitives that depend on non-active-tick liquidity (e.g., `AssessLiquidityDepth`) ship in v2.2.
86
+ **What was deferred to v2.2 (now shipped):** Balancer and Stableswap LiveProvider reads landed in v2.2 (see above). Still open: V3 tick bitmap walking V3 LiveProvider snapshots cover active-liquidity only, so primitives that depend on non-active-tick liquidity (e.g., `AssessLiquidityDepth`) and N-asset Balancer / rate-bearing Curve pools remain future work.
78
87
 
79
88
  ## v2.0 foundations
80
89
 
81
90
  The State Twin abstraction, agentic primitives, and MCP server pattern shipped in v2.0. v2.1 builds on that surface without changing it:
82
91
 
83
92
  * **`defipy.tools`** — self-describing schemas for a curated set of 10 leaf primitives, in [Model Context Protocol](https://modelcontextprotocol.io) (MCP) format. Any MCP-compatible client can discover and invoke DeFiPy primitives as tools.
84
- * **`defipy.twin`** — the **State Twin** abstraction. `MockProvider` ships four canonical synthetic pools (V2, V3, Balancer, Stableswap) for notebooks and tests; `LiveProvider` ships chain reads for V2 and V3 in v2.1.
93
+ * **`defipy.twin`** — the **State Twin** abstraction. `MockProvider` ships four canonical synthetic pools (V2, V3, Balancer, Stableswap) for notebooks and tests; `LiveProvider` ships chain reads for all four families (V2/V3 in v2.1, Balancer/Stableswap in v2.2).
85
94
  * **MCP server demo** at [`python/mcp/`](./python/mcp/) — a stdio-transport server exposing DeFiPy's tools to Claude Desktop, Claude Code, or any MCP client. Install with `pip install defipy[mcp]` and see the [MCP server README](./python/mcp/README.md) for setup.
86
95
 
87
96
  ### What is MCP?
@@ -125,12 +134,14 @@ DeFiPy requires **Python 3.10 or later**. Install via pip:
125
134
 
126
135
  The core install is the pure analytics engine — AMM math, primitives, State Twin, and all 21 typed analytics functions. It has **zero web3 dependencies and zero LLM dependencies**. No chain reads, no RPC calls, no MCP. Chain reads come from [Web3Scout](https://github.com/defipy-devs/web3scout) (via the `[chain]` or `[book]` extras); MCP tool serving comes from the `[mcp]` extra. All optional.
127
136
 
137
+ > **Note for zsh users (default on macOS):** wrap any install spec with extras in single quotes — `pip install 'defipy[agentic]'` — so zsh doesn't try to glob the brackets. Without the quotes, you'll see `zsh: no matches found`. Bash users can use either form.
138
+
128
139
  ### Chain install (LiveProvider — v2.1+)
129
140
 
130
141
  To use `LiveProvider` for on-chain pool snapshots, install the `[chain]` extra:
131
142
 
132
143
  ```
133
- > pip install defipy[chain]
144
+ > pip install 'defipy[chain]'
134
145
  ```
135
146
 
136
147
  This pulls in `web3scout` (which `LiveProvider` uses internally for ABI loading, contract reads, and token-fetching) plus `web3.py`. With `[chain]` installed, you can construct twins from real chain state:
@@ -143,14 +154,14 @@ snapshot = provider.snapshot("uniswap_v2:0xB4e16d0168e52d35CaCD2c6185b44281Ec28C
143
154
  lp = StateTwinBuilder().build(snapshot)
144
155
  ```
145
156
 
146
- > **Note:** the `[chain]` extra pins `web3 < 7.0` because `web3scout 0.2.0` depends on `eth_utils.abi.get_abi_input_types`, which was removed in web3 7. If you have web3 7.x installed for other reasons, `pip install defipy[chain]` will downgrade it. Tracking upstream as v2.2 work.
157
+ > **Note:** the `[chain]` extra pins `web3 < 7.0` because `web3scout 0.2.0` depends on `eth_utils.abi.get_abi_input_types`, which was removed in web3 7. If you have web3 7.x installed for other reasons, `pip install 'defipy[chain]'` will downgrade it. Tracking upstream as v2.2 work.
147
158
 
148
159
  ### Agentic install (full LLM + chain stack)
149
160
 
150
161
  For users building LLM-driven systems against live chain state — the canonical *Python SDK for Agentic DeFi* use case — install the `[agentic]` extra:
151
162
 
152
163
  ```
153
- > pip install defipy[agentic]
164
+ > pip install 'defipy[agentic]'
154
165
  ```
155
166
 
156
167
  This composes `[chain]` and `[mcp]` in one step: `web3scout` and `web3.py` for `LiveProvider` chain reads, plus the `mcp` Python SDK for serving DeFiPy's primitives as tools to Claude Desktop, Claude Code, or any MCP-compatible client. Equivalent to `pip install defipy[chain,mcp]` but spelled with intent.
@@ -162,27 +173,17 @@ The same `web3 < 7.0` pin from the `[chain]` extra applies.
162
173
  To run the MCP server that exposes DeFiPy's primitives as tools to Claude Desktop, Claude Code, or any MCP-compatible client, install the `[mcp]` extra:
163
174
 
164
175
  ```
165
- > pip install defipy[mcp]
176
+ > pip install 'defipy[mcp]'
166
177
  ```
167
178
 
168
179
  This adds the [`mcp`](https://github.com/modelcontextprotocol/python-sdk) Python SDK on top of the core install. The MCP server itself lives at [`python/mcp/defipy_mcp_server.py`](./python/mcp/defipy_mcp_server.py); see [`python/mcp/README.md`](./python/mcp/README.md) for Claude Desktop and Claude Code configuration snippets.
169
180
 
170
- ### Book install (chapter 9 agents)
171
-
172
- Chapter 9 of *Hands-On AMMs with Python* — *Building Autonomous DeFi Agents* — uses live chain integration via `web3scout`. To run those examples, install the `[book]` extra:
173
-
174
- ```
175
- > pip install defipy[book]
176
- ```
177
-
178
- The `[book]` extra carries the same package set as `[chain]` (`web3scout` + `web3`). The split is intent-based — `[chain]` signals production live-state reads via LiveProvider; `[book]` signals textbook chapter 9 use. Either works for either purpose.
179
-
180
181
  ### Anvil install (local Foundry workflows)
181
182
 
182
183
  If you're using `ExecuteScript` or `UniswapScriptHelper` against a local [Anvil](https://book.getfoundry.sh/anvil/) node and don't need the full `web3scout` event-monitoring stack, the lighter `[anvil]` extra just adds `web3.py`:
183
184
 
184
185
  ```
185
- > pip install defipy[anvil]
186
+ > pip install 'defipy[anvil]'
186
187
  ```
187
188
 
188
189
  `[book]` and `[chain]` already include everything in `[anvil]`, so users on either of those don't need it separately.
@@ -218,13 +219,6 @@ See the [gmpy2 installation docs](https://gmpy2.readthedocs.io/en/latest/install
218
219
  DeFiPy is accompanied by educational resources for developers and researchers
219
220
  interested in on-chain analytics and DeFi modeling.
220
221
 
221
- ### 📘 Textbook
222
- **_DeFiPy: Python SDK for On-Chain Analytics_**
223
-
224
- A comprehensive guide to DeFi analytics, AMM modeling, and simulation.
225
-
226
- 🔗 **Buy on Amazon:** https://www.amazon.com/dp/B0G3RV5QRB
227
-
228
222
  ### 🎓 Course
229
223
  **On-Chain Analytics Foundations**
230
224
 
@@ -245,34 +239,27 @@ Topics include:
245
239
 
246
240
  The fastest way to see DeFiPy at work — pull a real Uniswap V2 pool's state from mainnet and run a primitive against it. Requires the `[chain]` install extra.
247
241
 
248
- from defipy import AnalyzePosition
242
+ from defipy import CheckPoolHealth
249
243
  from defipy.twin import LiveProvider, StateTwinBuilder
250
-
251
- # Pull live state from a real Uniswap V2 pool — WETH/USDC mainnet
252
- provider = LiveProvider("https://eth-mainnet.g.alchemy.com/v2/<key>")
244
+
245
+ # Pull live state from a real Uniswap V3 pool — USDC/WETH 500bps mainnet
246
+ provider = LiveProvider("https://mainnet.infura.io/v3/d2d6569915ec402b82c9379d033f8b9b")
253
247
  snapshot = provider.snapshot(
254
- "uniswap_v2:0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"
248
+ "uniswap_v3:0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"
255
249
  )
256
250
  lp = StateTwinBuilder().build(snapshot)
257
251
  lp.summary()
258
-
252
+
259
253
  # Snapshot carries chain context — block_number, timestamp, chain_id
260
- print(f"Block: {snapshot.block_number}")
261
- print(f"Reserves: {snapshot.token0_name}={snapshot.reserve0:.2f}, "
262
- f"{snapshot.token1_name}={snapshot.reserve1:.2f}")
263
-
254
+ print(f"Block: {snapshot.block_number}")
255
+
264
256
  # Run any primitive against the live twin — same call shape as MockProvider
265
- result = AnalyzePosition().apply(
266
- lp,
267
- lp_init_amt=1.0,
268
- entry_x_amt=1000,
269
- entry_y_amt=3_000_000,
270
- )
271
-
272
- print(f"Diagnosis: {result.diagnosis}")
273
- print(f"Net PnL: {result.net_pnl:.4f}")
274
- print(f"IL %: {result.il_percentage:.4f}")
275
- print(f"Current val: {result.current_value:.4f}")
257
+ health = CheckPoolHealth().apply(lp)
258
+ print(f"Fee tier: {health.fee_pips} pips")
259
+ print(f"TVL (USDC): {health.tvl_in_token0:,.2f}")
260
+ print(f"TVL (WETH): {health.tvl_in_token1:,.4f}")
261
+ print(f"Current tick: {health.tick_current}")
262
+ print(f"Spot price: {health.spot_price:.6f} WETH/USDC")
276
263
 
277
264
  The same shape works for V3 — swap `uniswap_v2:` for `uniswap_v3:` and the appropriate pool address (e.g. `0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640` for USDC/WETH 500bps). V3 snapshots default to full-range ticks; pass `lwr_tick=N, upr_tick=N` to override. See the [LiveProvider docs](https://defipy.org/live-provider/) for block pinning, the V3 tick-range surface, and the active-liquidity-only caveat.
278
265
 
@@ -344,7 +331,26 @@ To run the opt-in live-RPC tests, set `DEFIPY_LIVE_RPC` to a mainnet RPC URL:
344
331
 
345
332
  DEFIPY_LIVE_RPC=https://eth-mainnet.g.alchemy.com/v2/<key> pytest -m live_rpc -v
346
333
 
334
+ ## 📄 Citation
335
+
336
+ If you use DeFiPy in research, please cite the State Twin paper:
337
+
338
+ ```bibtex
339
+ @misc{moore2026statetwins,
340
+ title={State Twins: An Off-Chain Substrate for Agentic Reasoning over Decentralized Finance Protocols},
341
+ author={Moore, Ian C.},
342
+ year={2026},
343
+ eprint={2605.11522},
344
+ archivePrefix={arXiv},
345
+ primaryClass={cs.DC},
346
+ doi={10.48550/arXiv.2605.11522}
347
+ }
348
+ ```
349
+
347
350
  ## License
348
351
  Licensed under the Apache License, Version 2.0.
349
352
  See [LICENSE](./LICENSE) and [NOTICE](./NOTICE) for details.
350
353
  Portions of this project may include code from third-party projects under compatible open-source licenses.
354
+
355
+ <!-- Machine-readable provenance anchor -->
356
+ 🔗 SPDX-Anchor: [anchorregistry.ai/AR-2026-YdPXB5g](https://anchorregistry.ai/AR-2026-YdPXB5g)