defi-mcp 0.1.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.
- defi_mcp-0.1.0/LICENSE +21 -0
- defi_mcp-0.1.0/PKG-INFO +156 -0
- defi_mcp-0.1.0/README.md +141 -0
- defi_mcp-0.1.0/pyproject.toml +23 -0
- defi_mcp-0.1.0/setup.cfg +4 -0
- defi_mcp-0.1.0/src/defi_mcp/__init__.py +0 -0
- defi_mcp-0.1.0/src/defi_mcp/config.py +29 -0
- defi_mcp-0.1.0/src/defi_mcp/lib/__init__.py +0 -0
- defi_mcp-0.1.0/src/defi_mcp/lib/abis.py +63 -0
- defi_mcp-0.1.0/src/defi_mcp/lib/chains.py +21 -0
- defi_mcp-0.1.0/src/defi_mcp/tools/__init__.py +0 -0
- defi_mcp-0.1.0/src/defi_mcp/tools/aave_position.py +73 -0
- defi_mcp-0.1.0/src/defi_mcp/tools/balance.py +56 -0
- defi_mcp-0.1.0/src/defi_mcp/tools/price.py +51 -0
- defi_mcp-0.1.0/src/defi_mcp.egg-info/PKG-INFO +156 -0
- defi_mcp-0.1.0/src/defi_mcp.egg-info/SOURCES.txt +18 -0
- defi_mcp-0.1.0/src/defi_mcp.egg-info/dependency_links.txt +1 -0
- defi_mcp-0.1.0/src/defi_mcp.egg-info/requires.txt +3 -0
- defi_mcp-0.1.0/src/defi_mcp.egg-info/top_level.txt +1 -0
- defi_mcp-0.1.0/tests/test_connection.py +25 -0
defi_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matthieu Ratsitohery
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
defi_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: defi-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An MCP server giving AI agents access to DeFi data on EVM chains.
|
|
5
|
+
Author-email: Matthieu Ratsitohery <matiosera3@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/matiosera3-ops/defi-mcp
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: mcp>=1.0.0
|
|
12
|
+
Requires-Dist: web3>=7.0.0
|
|
13
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# defi-mcp
|
|
17
|
+
|
|
18
|
+
An MCP (Model Context Protocol) server that gives AI agents direct, on-chain access to DeFi data on EVM chains — wallet balances, Aave v3 lending positions, and live token prices, with no centralized API in the middle.
|
|
19
|
+
|
|
20
|
+
**Status:** Live and functional. 4 tools available today, more on the roadmap.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Most "DeFi + AI" integrations route through a centralized API that can rate-limit, paywall, or simply disappear. `defi-mcp` talks directly to the chain (via your own RPC provider) and to first-party oracles (Chainlink), so the data your AI agent gets is exactly what's on-chain — verifiable, and not dependent on a third-party API staying online.
|
|
25
|
+
|
|
26
|
+
## Tools
|
|
27
|
+
|
|
28
|
+
### `get_token_balance`
|
|
29
|
+
Reads the ERC-20 balance of any wallet address for a supported token.
|
|
30
|
+
|
|
31
|
+
Supported tokens on Polygon: `USDC`, `USDC.e`, `USDT`, `WETH`, `WMATIC`, `WBTC`, `DAI`, `AAVE`.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
// get_token_balance(address="0x...", token_symbol="USDC", chain="polygon")
|
|
35
|
+
{
|
|
36
|
+
"address": "0x...",
|
|
37
|
+
"token": "USDC",
|
|
38
|
+
"chain": "polygon",
|
|
39
|
+
"balance": 268.21,
|
|
40
|
+
"raw_balance": "268210000",
|
|
41
|
+
"decimals": 6
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `get_aave_position`
|
|
46
|
+
Reads a user's full Aave v3 lending/borrowing position: collateral, debt, available borrowing power, and health factor — straight from the Aave v3 Pool contract.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
// get_aave_position(address="0x...", chain="polygon")
|
|
50
|
+
{
|
|
51
|
+
"address": "0x...",
|
|
52
|
+
"chain": "polygon",
|
|
53
|
+
"total_collateral_usd": 969.78,
|
|
54
|
+
"total_debt_usd": 288.16,
|
|
55
|
+
"available_borrows_usd": 484.86,
|
|
56
|
+
"liquidation_threshold_pct": 82.79,
|
|
57
|
+
"ltv_pct": 79.71,
|
|
58
|
+
"health_factor": 2.79,
|
|
59
|
+
"has_active_position": true
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A `health_factor` below `1.0` means the position is at risk of liquidation. A `null` health factor means the user has no outstanding debt.
|
|
64
|
+
|
|
65
|
+
### `get_token_price`
|
|
66
|
+
Reads the current USD price of a token directly from a Chainlink price feed — the same oracle DeFi protocols use internally, so the price is consistent with what `get_aave_position` reports.
|
|
67
|
+
|
|
68
|
+
Supported on Polygon: `ETH`/`WETH`, `MATIC`/`WMATIC`, `WBTC`, `USDC`, `USDT`.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
// get_token_price(token_symbol="WBTC", chain="polygon")
|
|
72
|
+
{
|
|
73
|
+
"token": "WBTC",
|
|
74
|
+
"chain": "polygon",
|
|
75
|
+
"price_usd": 63835.77,
|
|
76
|
+
"decimals": 8,
|
|
77
|
+
"updated_at": 1782032816
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `hello`
|
|
82
|
+
Simple connectivity check — confirms the MCP server is reachable and responding.
|
|
83
|
+
|
|
84
|
+
## Supported chains
|
|
85
|
+
|
|
86
|
+
- Polygon
|
|
87
|
+
|
|
88
|
+
More EVM chains are on the roadmap (see below).
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
Requires Python 3.10+ and an RPC provider API key (e.g. [Alchemy](https://www.alchemy.com/), free tier works).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/matiosera3-ops/defi-mcp.git
|
|
96
|
+
cd defi-mcp
|
|
97
|
+
python -m venv venv
|
|
98
|
+
|
|
99
|
+
# Windows
|
|
100
|
+
.\venv\Scripts\Activate.ps1
|
|
101
|
+
# macOS/Linux
|
|
102
|
+
source venv/bin/activate
|
|
103
|
+
|
|
104
|
+
pip install -e .
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Create a `.env` file in the project root:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
POLYGON_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/YOUR_API_KEY
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Usage with Claude Desktop
|
|
114
|
+
|
|
115
|
+
Add this to your Claude Desktop MCP config (`claude_desktop_config.json`):
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"defi-mcp": {
|
|
121
|
+
"command": "python",
|
|
122
|
+
"args": ["/absolute/path/to/defi-mcp/server.py"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Restart Claude Desktop, and the tools above will be available to the model.
|
|
129
|
+
|
|
130
|
+
## Testing locally
|
|
131
|
+
|
|
132
|
+
You can test the server directly with the official [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npx @modelcontextprotocol/inspector python server.py
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Roadmap
|
|
139
|
+
|
|
140
|
+
- [ ] Track Uniswap v3 LP positions and impermanent loss
|
|
141
|
+
- [ ] Simulate swaps with realistic slippage estimates
|
|
142
|
+
- [ ] Monitor protocol TVLs
|
|
143
|
+
- [ ] Additional chains (Ethereum, Arbitrum, Base)
|
|
144
|
+
- [ ] `defi-mcp-cloud` — hosted tier with MEV-specific tools, caching, and higher rate limits
|
|
145
|
+
|
|
146
|
+
## Architecture
|
|
147
|
+
|
|
148
|
+
Open-core model: this repository (MIT licensed) covers standard on-chain read tools. A separate `defi-mcp-cloud` will offer a hosted version with MEV-related tools, request caching, and managed RPC access for users who don't want to run their own infrastructure.
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Issues and PRs welcome. This is an early-stage project — feedback on what tools would actually be useful to you is especially valuable.
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
defi_mcp-0.1.0/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# defi-mcp
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that gives AI agents direct, on-chain access to DeFi data on EVM chains — wallet balances, Aave v3 lending positions, and live token prices, with no centralized API in the middle.
|
|
4
|
+
|
|
5
|
+
**Status:** Live and functional. 4 tools available today, more on the roadmap.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Most "DeFi + AI" integrations route through a centralized API that can rate-limit, paywall, or simply disappear. `defi-mcp` talks directly to the chain (via your own RPC provider) and to first-party oracles (Chainlink), so the data your AI agent gets is exactly what's on-chain — verifiable, and not dependent on a third-party API staying online.
|
|
10
|
+
|
|
11
|
+
## Tools
|
|
12
|
+
|
|
13
|
+
### `get_token_balance`
|
|
14
|
+
Reads the ERC-20 balance of any wallet address for a supported token.
|
|
15
|
+
|
|
16
|
+
Supported tokens on Polygon: `USDC`, `USDC.e`, `USDT`, `WETH`, `WMATIC`, `WBTC`, `DAI`, `AAVE`.
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
// get_token_balance(address="0x...", token_symbol="USDC", chain="polygon")
|
|
20
|
+
{
|
|
21
|
+
"address": "0x...",
|
|
22
|
+
"token": "USDC",
|
|
23
|
+
"chain": "polygon",
|
|
24
|
+
"balance": 268.21,
|
|
25
|
+
"raw_balance": "268210000",
|
|
26
|
+
"decimals": 6
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### `get_aave_position`
|
|
31
|
+
Reads a user's full Aave v3 lending/borrowing position: collateral, debt, available borrowing power, and health factor — straight from the Aave v3 Pool contract.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
// get_aave_position(address="0x...", chain="polygon")
|
|
35
|
+
{
|
|
36
|
+
"address": "0x...",
|
|
37
|
+
"chain": "polygon",
|
|
38
|
+
"total_collateral_usd": 969.78,
|
|
39
|
+
"total_debt_usd": 288.16,
|
|
40
|
+
"available_borrows_usd": 484.86,
|
|
41
|
+
"liquidation_threshold_pct": 82.79,
|
|
42
|
+
"ltv_pct": 79.71,
|
|
43
|
+
"health_factor": 2.79,
|
|
44
|
+
"has_active_position": true
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A `health_factor` below `1.0` means the position is at risk of liquidation. A `null` health factor means the user has no outstanding debt.
|
|
49
|
+
|
|
50
|
+
### `get_token_price`
|
|
51
|
+
Reads the current USD price of a token directly from a Chainlink price feed — the same oracle DeFi protocols use internally, so the price is consistent with what `get_aave_position` reports.
|
|
52
|
+
|
|
53
|
+
Supported on Polygon: `ETH`/`WETH`, `MATIC`/`WMATIC`, `WBTC`, `USDC`, `USDT`.
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
// get_token_price(token_symbol="WBTC", chain="polygon")
|
|
57
|
+
{
|
|
58
|
+
"token": "WBTC",
|
|
59
|
+
"chain": "polygon",
|
|
60
|
+
"price_usd": 63835.77,
|
|
61
|
+
"decimals": 8,
|
|
62
|
+
"updated_at": 1782032816
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `hello`
|
|
67
|
+
Simple connectivity check — confirms the MCP server is reachable and responding.
|
|
68
|
+
|
|
69
|
+
## Supported chains
|
|
70
|
+
|
|
71
|
+
- Polygon
|
|
72
|
+
|
|
73
|
+
More EVM chains are on the roadmap (see below).
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
Requires Python 3.10+ and an RPC provider API key (e.g. [Alchemy](https://www.alchemy.com/), free tier works).
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/matiosera3-ops/defi-mcp.git
|
|
81
|
+
cd defi-mcp
|
|
82
|
+
python -m venv venv
|
|
83
|
+
|
|
84
|
+
# Windows
|
|
85
|
+
.\venv\Scripts\Activate.ps1
|
|
86
|
+
# macOS/Linux
|
|
87
|
+
source venv/bin/activate
|
|
88
|
+
|
|
89
|
+
pip install -e .
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Create a `.env` file in the project root:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
POLYGON_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/YOUR_API_KEY
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Usage with Claude Desktop
|
|
99
|
+
|
|
100
|
+
Add this to your Claude Desktop MCP config (`claude_desktop_config.json`):
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mcpServers": {
|
|
105
|
+
"defi-mcp": {
|
|
106
|
+
"command": "python",
|
|
107
|
+
"args": ["/absolute/path/to/defi-mcp/server.py"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Restart Claude Desktop, and the tools above will be available to the model.
|
|
114
|
+
|
|
115
|
+
## Testing locally
|
|
116
|
+
|
|
117
|
+
You can test the server directly with the official [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx @modelcontextprotocol/inspector python server.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Roadmap
|
|
124
|
+
|
|
125
|
+
- [ ] Track Uniswap v3 LP positions and impermanent loss
|
|
126
|
+
- [ ] Simulate swaps with realistic slippage estimates
|
|
127
|
+
- [ ] Monitor protocol TVLs
|
|
128
|
+
- [ ] Additional chains (Ethereum, Arbitrum, Base)
|
|
129
|
+
- [ ] `defi-mcp-cloud` — hosted tier with MEV-specific tools, caching, and higher rate limits
|
|
130
|
+
|
|
131
|
+
## Architecture
|
|
132
|
+
|
|
133
|
+
Open-core model: this repository (MIT licensed) covers standard on-chain read tools. A separate `defi-mcp-cloud` will offer a hosted version with MEV-related tools, request caching, and managed RPC access for users who don't want to run their own infrastructure.
|
|
134
|
+
|
|
135
|
+
## Contributing
|
|
136
|
+
|
|
137
|
+
Issues and PRs welcome. This is an early-stage project — feedback on what tools would actually be useful to you is especially valuable.
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "defi-mcp"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "An MCP server giving AI agents access to DeFi data on EVM chains."
|
|
5
|
+
authors = [{name = "Matthieu Ratsitohery", email = "matiosera3@gmail.com"}]
|
|
6
|
+
license = {text = "MIT"}
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"mcp>=1.0.0",
|
|
11
|
+
"web3>=7.0.0",
|
|
12
|
+
"python-dotenv>=1.0.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.urls]
|
|
16
|
+
Repository = "https://github.com/matiosera3-ops/defi-mcp"
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = ["setuptools>=61.0"]
|
|
20
|
+
build-backend = "setuptools.build_meta"
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.packages.find]
|
|
23
|
+
where = ["src"]
|
defi_mcp-0.1.0/setup.cfg
ADDED
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Token addresses and protocol configurations per chain."""
|
|
2
|
+
|
|
3
|
+
TOKEN_ADDRESSES = {
|
|
4
|
+
"polygon": {
|
|
5
|
+
"USDC": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
6
|
+
"USDC.e": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
|
|
7
|
+
"USDT": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
8
|
+
"WETH": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
|
|
9
|
+
"WMATIC": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
|
|
10
|
+
"WBTC": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
|
|
11
|
+
"DAI": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
|
|
12
|
+
"AAVE": "0xD6DF932A45C0f255f85145f286eA0b292B21C90B",
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
AAVE_POOL_ADDRESSES = {
|
|
16
|
+
"polygon": "0x794a61358D6845594F94dc1DB02A252b5b4814aD",
|
|
17
|
+
}
|
|
18
|
+
# Chainlink price feed addresses (token/USD), per chain.
|
|
19
|
+
CHAINLINK_PRICE_FEEDS = {
|
|
20
|
+
"polygon": {
|
|
21
|
+
"ETH": "0xF9680D99D6C9589e2a93a78A04A279e509205945",
|
|
22
|
+
"WETH": "0xF9680D99D6C9589e2a93a78A04A279e509205945",
|
|
23
|
+
"MATIC": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0",
|
|
24
|
+
"WMATIC": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0",
|
|
25
|
+
"WBTC": "0xDE31F8bFBD8c84b5360CFACCa3539B938dd78ae6",
|
|
26
|
+
"USDC": "0xfe4A8cc5b5B2366C1B58Bea3858e81843581b2F7",
|
|
27
|
+
"USDT": "0x0A6513e40db6EB1b165753AD52E80663aeA50545",
|
|
28
|
+
}
|
|
29
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""ABIs for common smart contract standards."""
|
|
2
|
+
|
|
3
|
+
ERC20_ABI = [
|
|
4
|
+
{
|
|
5
|
+
"constant": True,
|
|
6
|
+
"inputs": [{"name": "_owner", "type": "address"}],
|
|
7
|
+
"name": "balanceOf",
|
|
8
|
+
"outputs": [{"name": "balance", "type": "uint256"}],
|
|
9
|
+
"type": "function",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"constant": True,
|
|
13
|
+
"inputs": [],
|
|
14
|
+
"name": "decimals",
|
|
15
|
+
"outputs": [{"name": "", "type": "uint8"}],
|
|
16
|
+
"type": "function",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"constant": True,
|
|
20
|
+
"inputs": [],
|
|
21
|
+
"name": "symbol",
|
|
22
|
+
"outputs": [{"name": "", "type": "string"}],
|
|
23
|
+
"type": "function",
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
AAVE_POOL_ABI = [
|
|
27
|
+
{
|
|
28
|
+
"inputs": [{"name": "user", "type": "address"}],
|
|
29
|
+
"name": "getUserAccountData",
|
|
30
|
+
"outputs": [
|
|
31
|
+
{"name": "totalCollateralBase", "type": "uint256"},
|
|
32
|
+
{"name": "totalDebtBase", "type": "uint256"},
|
|
33
|
+
{"name": "availableBorrowsBase", "type": "uint256"},
|
|
34
|
+
{"name": "currentLiquidationThreshold", "type": "uint256"},
|
|
35
|
+
{"name": "ltv", "type": "uint256"},
|
|
36
|
+
{"name": "healthFactor", "type": "uint256"},
|
|
37
|
+
],
|
|
38
|
+
"stateMutability": "view",
|
|
39
|
+
"type": "function",
|
|
40
|
+
},
|
|
41
|
+
]
|
|
42
|
+
CHAINLINK_AGGREGATOR_ABI = [
|
|
43
|
+
{
|
|
44
|
+
"inputs": [],
|
|
45
|
+
"name": "latestRoundData",
|
|
46
|
+
"outputs": [
|
|
47
|
+
{"name": "roundId", "type": "uint80"},
|
|
48
|
+
{"name": "answer", "type": "int256"},
|
|
49
|
+
{"name": "startedAt", "type": "uint256"},
|
|
50
|
+
{"name": "updatedAt", "type": "uint256"},
|
|
51
|
+
{"name": "answeredInRound", "type": "uint80"},
|
|
52
|
+
],
|
|
53
|
+
"stateMutability": "view",
|
|
54
|
+
"type": "function",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"inputs": [],
|
|
58
|
+
"name": "decimals",
|
|
59
|
+
"outputs": [{"name": "", "type": "uint8"}],
|
|
60
|
+
"stateMutability": "view",
|
|
61
|
+
"type": "function",
|
|
62
|
+
},
|
|
63
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Web3 connection management per chain."""
|
|
2
|
+
import os
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
from web3 import Web3
|
|
5
|
+
|
|
6
|
+
load_dotenv()
|
|
7
|
+
|
|
8
|
+
RPC_URLS = {
|
|
9
|
+
"polygon": os.getenv("POLYGON_RPC_URL"),
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_web3(chain: str) -> Web3:
|
|
14
|
+
"""Return a Web3 instance connected to the given chain."""
|
|
15
|
+
rpc_url = RPC_URLS.get(chain.lower())
|
|
16
|
+
if not rpc_url:
|
|
17
|
+
raise ValueError(f"Chain '{chain}' not supported or RPC URL not configured")
|
|
18
|
+
return Web3(Web3.HTTPProvider(rpc_url))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
SUPPORTED_CHAINS = list(RPC_URLS.keys())
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Aave v3 user position tool."""
|
|
2
|
+
from web3 import Web3
|
|
3
|
+
from defi_mcp.lib.chains import get_web3
|
|
4
|
+
from defi_mcp.lib.abis import AAVE_POOL_ABI
|
|
5
|
+
from defi_mcp.config import AAVE_POOL_ADDRESSES
|
|
6
|
+
|
|
7
|
+
# Aave v3 base currency on Polygon is USD with 8 decimals (price feed precision).
|
|
8
|
+
BASE_CURRENCY_DECIMALS = 8
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_aave_position(address: str, chain: str = "polygon") -> dict:
|
|
12
|
+
"""Get a user's Aave v3 lending/borrowing position on a given chain.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
address: The wallet address to check
|
|
16
|
+
chain: The blockchain to query. Default: polygon.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
A dictionary with total collateral, total debt, available borrows,
|
|
20
|
+
liquidation threshold, LTV, and health factor (all in USD where applicable).
|
|
21
|
+
"""
|
|
22
|
+
chain = chain.lower()
|
|
23
|
+
|
|
24
|
+
if chain not in AAVE_POOL_ADDRESSES:
|
|
25
|
+
return {"error": f"Chain '{chain}' not supported. Supported: {list(AAVE_POOL_ADDRESSES.keys())}"}
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
w3 = get_web3(chain)
|
|
29
|
+
|
|
30
|
+
if not Web3.is_address(address):
|
|
31
|
+
return {"error": f"Invalid address: {address}"}
|
|
32
|
+
address = Web3.to_checksum_address(address)
|
|
33
|
+
|
|
34
|
+
pool_address = Web3.to_checksum_address(AAVE_POOL_ADDRESSES[chain])
|
|
35
|
+
contract = w3.eth.contract(address=pool_address, abi=AAVE_POOL_ABI)
|
|
36
|
+
|
|
37
|
+
result = contract.functions.getUserAccountData(address).call()
|
|
38
|
+
(
|
|
39
|
+
total_collateral_base,
|
|
40
|
+
total_debt_base,
|
|
41
|
+
available_borrows_base,
|
|
42
|
+
current_liquidation_threshold,
|
|
43
|
+
ltv,
|
|
44
|
+
health_factor_raw,
|
|
45
|
+
) = result
|
|
46
|
+
|
|
47
|
+
# Base amounts use the price feed's decimals (8 on Polygon's main market).
|
|
48
|
+
total_collateral_usd = total_collateral_base / (10 ** BASE_CURRENCY_DECIMALS)
|
|
49
|
+
total_debt_usd = total_debt_base / (10 ** BASE_CURRENCY_DECIMALS)
|
|
50
|
+
available_borrows_usd = available_borrows_base / (10 ** BASE_CURRENCY_DECIMALS)
|
|
51
|
+
|
|
52
|
+
# Health factor and LTV/liquidation threshold are 18-decimal fixed point.
|
|
53
|
+
# If there's no debt, Aave returns max uint256 for health factor -> treat as infinite.
|
|
54
|
+
max_uint256 = 2**256 - 1
|
|
55
|
+
if health_factor_raw == max_uint256:
|
|
56
|
+
health_factor = None # represents infinite / no debt
|
|
57
|
+
else:
|
|
58
|
+
health_factor = health_factor_raw / (10 ** 18)
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
"address": address,
|
|
62
|
+
"chain": chain,
|
|
63
|
+
"total_collateral_usd": total_collateral_usd,
|
|
64
|
+
"total_debt_usd": total_debt_usd,
|
|
65
|
+
"available_borrows_usd": available_borrows_usd,
|
|
66
|
+
"liquidation_threshold_pct": current_liquidation_threshold / 100,
|
|
67
|
+
"ltv_pct": ltv / 100,
|
|
68
|
+
"health_factor": health_factor,
|
|
69
|
+
"has_active_position": total_collateral_usd > 0 or total_debt_usd > 0,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
return {"error": f"Failed to fetch Aave position: {str(e)}"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Token balance tool."""
|
|
2
|
+
from web3 import Web3
|
|
3
|
+
from defi_mcp.lib.chains import get_web3
|
|
4
|
+
from defi_mcp.lib.abis import ERC20_ABI
|
|
5
|
+
from defi_mcp.config import TOKEN_ADDRESSES
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_token_balance(address: str, token_symbol: str, chain: str = "polygon") -> dict:
|
|
9
|
+
"""Get the balance of an ERC-20 token for a given wallet address.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
address: The wallet address to check
|
|
13
|
+
token_symbol: The token symbol (e.g. USDC, USDT, WETH, USDC.e)
|
|
14
|
+
chain: The blockchain to query. Default: polygon.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
A dictionary with the address, token symbol, balance, and raw balance.
|
|
18
|
+
"""
|
|
19
|
+
chain = chain.lower()
|
|
20
|
+
|
|
21
|
+
if chain not in TOKEN_ADDRESSES:
|
|
22
|
+
return {"error": f"Chain '{chain}' not supported. Supported: {list(TOKEN_ADDRESSES.keys())}"}
|
|
23
|
+
|
|
24
|
+
# Case-insensitive token symbol matching
|
|
25
|
+
token_map = {k.upper(): k for k in TOKEN_ADDRESSES[chain].keys()}
|
|
26
|
+
token_key = token_map.get(token_symbol.upper())
|
|
27
|
+
|
|
28
|
+
if not token_key:
|
|
29
|
+
supported = list(TOKEN_ADDRESSES[chain].keys())
|
|
30
|
+
return {"error": f"Token '{token_symbol}' not supported on {chain}. Supported: {supported}"}
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
w3 = get_web3(chain)
|
|
34
|
+
|
|
35
|
+
if not Web3.is_address(address):
|
|
36
|
+
return {"error": f"Invalid address: {address}"}
|
|
37
|
+
address = Web3.to_checksum_address(address)
|
|
38
|
+
|
|
39
|
+
token_address = Web3.to_checksum_address(TOKEN_ADDRESSES[chain][token_key])
|
|
40
|
+
contract = w3.eth.contract(address=token_address, abi=ERC20_ABI)
|
|
41
|
+
|
|
42
|
+
raw_balance = contract.functions.balanceOf(address).call()
|
|
43
|
+
decimals = contract.functions.decimals().call()
|
|
44
|
+
balance = raw_balance / (10 ** decimals)
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
"address": address,
|
|
48
|
+
"token": token_key,
|
|
49
|
+
"chain": chain,
|
|
50
|
+
"balance": balance,
|
|
51
|
+
"raw_balance": str(raw_balance),
|
|
52
|
+
"decimals": decimals,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
except Exception as e:
|
|
56
|
+
return {"error": f"Failed to fetch balance: {str(e)}"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Token price tool using Chainlink price feeds."""
|
|
2
|
+
from web3 import Web3
|
|
3
|
+
from defi_mcp.lib.chains import get_web3
|
|
4
|
+
from defi_mcp.lib.abis import CHAINLINK_AGGREGATOR_ABI
|
|
5
|
+
from defi_mcp.config import CHAINLINK_PRICE_FEEDS
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_token_price(token_symbol: str, chain: str = "polygon") -> dict:
|
|
9
|
+
"""Get the current USD price of a token from a Chainlink price feed.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
token_symbol: The token symbol (e.g. ETH, WETH, MATIC, WMATIC, WBTC, USDC, USDT)
|
|
13
|
+
chain: The blockchain to query. Default: polygon.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A dictionary with the token symbol, USD price, and feed update timestamp.
|
|
17
|
+
"""
|
|
18
|
+
chain = chain.lower()
|
|
19
|
+
|
|
20
|
+
if chain not in CHAINLINK_PRICE_FEEDS:
|
|
21
|
+
return {"error": f"Chain '{chain}' not supported. Supported: {list(CHAINLINK_PRICE_FEEDS.keys())}"}
|
|
22
|
+
|
|
23
|
+
# Case-insensitive token symbol matching
|
|
24
|
+
feed_map = {k.upper(): k for k in CHAINLINK_PRICE_FEEDS[chain].keys()}
|
|
25
|
+
feed_key = feed_map.get(token_symbol.upper())
|
|
26
|
+
|
|
27
|
+
if not feed_key:
|
|
28
|
+
supported = list(CHAINLINK_PRICE_FEEDS[chain].keys())
|
|
29
|
+
return {"error": f"Token '{token_symbol}' has no price feed on {chain}. Supported: {supported}"}
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
w3 = get_web3(chain)
|
|
33
|
+
feed_address = Web3.to_checksum_address(CHAINLINK_PRICE_FEEDS[chain][feed_key])
|
|
34
|
+
contract = w3.eth.contract(address=feed_address, abi=CHAINLINK_AGGREGATOR_ABI)
|
|
35
|
+
|
|
36
|
+
round_data = contract.functions.latestRoundData().call()
|
|
37
|
+
_, answer, _, updated_at, _ = round_data
|
|
38
|
+
|
|
39
|
+
decimals = contract.functions.decimals().call()
|
|
40
|
+
price_usd = answer / (10 ** decimals)
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
"token": feed_key,
|
|
44
|
+
"chain": chain,
|
|
45
|
+
"price_usd": price_usd,
|
|
46
|
+
"decimals": decimals,
|
|
47
|
+
"updated_at": updated_at,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
except Exception as e:
|
|
51
|
+
return {"error": f"Failed to fetch price: {str(e)}"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: defi-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An MCP server giving AI agents access to DeFi data on EVM chains.
|
|
5
|
+
Author-email: Matthieu Ratsitohery <matiosera3@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/matiosera3-ops/defi-mcp
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: mcp>=1.0.0
|
|
12
|
+
Requires-Dist: web3>=7.0.0
|
|
13
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# defi-mcp
|
|
17
|
+
|
|
18
|
+
An MCP (Model Context Protocol) server that gives AI agents direct, on-chain access to DeFi data on EVM chains — wallet balances, Aave v3 lending positions, and live token prices, with no centralized API in the middle.
|
|
19
|
+
|
|
20
|
+
**Status:** Live and functional. 4 tools available today, more on the roadmap.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Most "DeFi + AI" integrations route through a centralized API that can rate-limit, paywall, or simply disappear. `defi-mcp` talks directly to the chain (via your own RPC provider) and to first-party oracles (Chainlink), so the data your AI agent gets is exactly what's on-chain — verifiable, and not dependent on a third-party API staying online.
|
|
25
|
+
|
|
26
|
+
## Tools
|
|
27
|
+
|
|
28
|
+
### `get_token_balance`
|
|
29
|
+
Reads the ERC-20 balance of any wallet address for a supported token.
|
|
30
|
+
|
|
31
|
+
Supported tokens on Polygon: `USDC`, `USDC.e`, `USDT`, `WETH`, `WMATIC`, `WBTC`, `DAI`, `AAVE`.
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
// get_token_balance(address="0x...", token_symbol="USDC", chain="polygon")
|
|
35
|
+
{
|
|
36
|
+
"address": "0x...",
|
|
37
|
+
"token": "USDC",
|
|
38
|
+
"chain": "polygon",
|
|
39
|
+
"balance": 268.21,
|
|
40
|
+
"raw_balance": "268210000",
|
|
41
|
+
"decimals": 6
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `get_aave_position`
|
|
46
|
+
Reads a user's full Aave v3 lending/borrowing position: collateral, debt, available borrowing power, and health factor — straight from the Aave v3 Pool contract.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
// get_aave_position(address="0x...", chain="polygon")
|
|
50
|
+
{
|
|
51
|
+
"address": "0x...",
|
|
52
|
+
"chain": "polygon",
|
|
53
|
+
"total_collateral_usd": 969.78,
|
|
54
|
+
"total_debt_usd": 288.16,
|
|
55
|
+
"available_borrows_usd": 484.86,
|
|
56
|
+
"liquidation_threshold_pct": 82.79,
|
|
57
|
+
"ltv_pct": 79.71,
|
|
58
|
+
"health_factor": 2.79,
|
|
59
|
+
"has_active_position": true
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A `health_factor` below `1.0` means the position is at risk of liquidation. A `null` health factor means the user has no outstanding debt.
|
|
64
|
+
|
|
65
|
+
### `get_token_price`
|
|
66
|
+
Reads the current USD price of a token directly from a Chainlink price feed — the same oracle DeFi protocols use internally, so the price is consistent with what `get_aave_position` reports.
|
|
67
|
+
|
|
68
|
+
Supported on Polygon: `ETH`/`WETH`, `MATIC`/`WMATIC`, `WBTC`, `USDC`, `USDT`.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
// get_token_price(token_symbol="WBTC", chain="polygon")
|
|
72
|
+
{
|
|
73
|
+
"token": "WBTC",
|
|
74
|
+
"chain": "polygon",
|
|
75
|
+
"price_usd": 63835.77,
|
|
76
|
+
"decimals": 8,
|
|
77
|
+
"updated_at": 1782032816
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `hello`
|
|
82
|
+
Simple connectivity check — confirms the MCP server is reachable and responding.
|
|
83
|
+
|
|
84
|
+
## Supported chains
|
|
85
|
+
|
|
86
|
+
- Polygon
|
|
87
|
+
|
|
88
|
+
More EVM chains are on the roadmap (see below).
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
Requires Python 3.10+ and an RPC provider API key (e.g. [Alchemy](https://www.alchemy.com/), free tier works).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/matiosera3-ops/defi-mcp.git
|
|
96
|
+
cd defi-mcp
|
|
97
|
+
python -m venv venv
|
|
98
|
+
|
|
99
|
+
# Windows
|
|
100
|
+
.\venv\Scripts\Activate.ps1
|
|
101
|
+
# macOS/Linux
|
|
102
|
+
source venv/bin/activate
|
|
103
|
+
|
|
104
|
+
pip install -e .
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Create a `.env` file in the project root:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
POLYGON_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/YOUR_API_KEY
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Usage with Claude Desktop
|
|
114
|
+
|
|
115
|
+
Add this to your Claude Desktop MCP config (`claude_desktop_config.json`):
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"defi-mcp": {
|
|
121
|
+
"command": "python",
|
|
122
|
+
"args": ["/absolute/path/to/defi-mcp/server.py"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Restart Claude Desktop, and the tools above will be available to the model.
|
|
129
|
+
|
|
130
|
+
## Testing locally
|
|
131
|
+
|
|
132
|
+
You can test the server directly with the official [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npx @modelcontextprotocol/inspector python server.py
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Roadmap
|
|
139
|
+
|
|
140
|
+
- [ ] Track Uniswap v3 LP positions and impermanent loss
|
|
141
|
+
- [ ] Simulate swaps with realistic slippage estimates
|
|
142
|
+
- [ ] Monitor protocol TVLs
|
|
143
|
+
- [ ] Additional chains (Ethereum, Arbitrum, Base)
|
|
144
|
+
- [ ] `defi-mcp-cloud` — hosted tier with MEV-specific tools, caching, and higher rate limits
|
|
145
|
+
|
|
146
|
+
## Architecture
|
|
147
|
+
|
|
148
|
+
Open-core model: this repository (MIT licensed) covers standard on-chain read tools. A separate `defi-mcp-cloud` will offer a hosted version with MEV-related tools, request caching, and managed RPC access for users who don't want to run their own infrastructure.
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Issues and PRs welcome. This is an early-stage project — feedback on what tools would actually be useful to you is especially valuable.
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/defi_mcp/__init__.py
|
|
5
|
+
src/defi_mcp/config.py
|
|
6
|
+
src/defi_mcp.egg-info/PKG-INFO
|
|
7
|
+
src/defi_mcp.egg-info/SOURCES.txt
|
|
8
|
+
src/defi_mcp.egg-info/dependency_links.txt
|
|
9
|
+
src/defi_mcp.egg-info/requires.txt
|
|
10
|
+
src/defi_mcp.egg-info/top_level.txt
|
|
11
|
+
src/defi_mcp/lib/__init__.py
|
|
12
|
+
src/defi_mcp/lib/abis.py
|
|
13
|
+
src/defi_mcp/lib/chains.py
|
|
14
|
+
src/defi_mcp/tools/__init__.py
|
|
15
|
+
src/defi_mcp/tools/aave_position.py
|
|
16
|
+
src/defi_mcp/tools/balance.py
|
|
17
|
+
src/defi_mcp/tools/price.py
|
|
18
|
+
tests/test_connection.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
defi_mcp
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dotenv import load_dotenv
|
|
3
|
+
from web3 import Web3
|
|
4
|
+
|
|
5
|
+
# Charge le .env
|
|
6
|
+
load_dotenv()
|
|
7
|
+
|
|
8
|
+
# Récupère l'URL Alchemy
|
|
9
|
+
rpc_url = os.getenv("POLYGON_RPC_URL")
|
|
10
|
+
|
|
11
|
+
if not rpc_url:
|
|
12
|
+
print("ERREUR: POLYGON_RPC_URL non trouvée dans .env")
|
|
13
|
+
exit(1)
|
|
14
|
+
|
|
15
|
+
print(f"URL chargée: {rpc_url[:50]}...")
|
|
16
|
+
|
|
17
|
+
# Connexion à Polygon
|
|
18
|
+
w3 = Web3(Web3.HTTPProvider(rpc_url))
|
|
19
|
+
|
|
20
|
+
if w3.is_connected():
|
|
21
|
+
print("Connecte a Polygon")
|
|
22
|
+
print(f"Bloc actuel: {w3.eth.block_number}")
|
|
23
|
+
print(f"Chain ID: {w3.eth.chain_id}")
|
|
24
|
+
else:
|
|
25
|
+
print("Echec de la connexion")
|