Skip to content

Commit 364d283

Browse files
committed
feat(evm): add new tools
1 parent 713529c commit 364d283

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

src/servers/evm/common/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,15 @@ async def trace_replayBlockTransactions(chain, block_number, trace_types):
151151

152152
async def trace_block(chain, block_number):
153153
return await _adapter(chain).trace_block(block_number)
154+
155+
156+
async def eth_getProof(chain, address, storage_keys, block):
157+
return await _adapter(chain).eth_getProof(address, storage_keys, block)
158+
159+
160+
async def eth_simulateV1(chain, params, block):
161+
return await _adapter(chain).eth_simulateV1(params, block)
162+
163+
164+
async def eth_getBlockReceipts(chain, block):
165+
return await _adapter(chain).eth_getBlockReceipts(block)

src/servers/evm/common/interfaces.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,12 @@ async def trace_replayBlockTransactions(
114114

115115
@abstractmethod
116116
async def trace_block(self, block_number: str) -> str: ...
117+
118+
@abstractmethod
119+
async def eth_getProof(self, address: str, storage_keys: list[str], block: str) -> str: ...
120+
121+
@abstractmethod
122+
async def eth_simulateV1(self, params: dict, block: str) -> str: ...
123+
124+
@abstractmethod
125+
async def eth_getBlockReceipts(self, block: str) -> str: ...

src/servers/evm/evm.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,14 @@ async def trace_replayBlockTransactions(self, block_number: str, trace_types: li
152152

153153
async def trace_block(self, block_number: str) -> str:
154154
return await self.rpc_client.post("trace_block", [block_number], self.rpc_url)
155+
156+
async def eth_getProof(self, address: str, storage_keys: list[str], block: str) -> str:
157+
return await self.rpc_client.post(
158+
"eth_getProof", [address, storage_keys, block], self.rpc_url
159+
)
160+
161+
async def eth_simulateV1(self, params: dict, block: str) -> str:
162+
return await self.rpc_client.post("eth_simulateV1", [params, block], self.rpc_url)
163+
164+
async def eth_getBlockReceipts(self, block: str) -> str:
165+
return await self.rpc_client.post("eth_getBlockReceipts", [block], self.rpc_url)

src/servers/evm/tools/json_rpc_methods.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,3 +1441,115 @@ async def trace_block(chain: str, block_number: str) -> CallToolResult:
14411441
return _ok(await client.trace_block(chain.lower(), block_number))
14421442
except Exception as e:
14431443
return _err(str(e))
1444+
1445+
1446+
@mcp.tool(
1447+
name="eth_getProof",
1448+
description=(
1449+
"Call the eth_getProof JSON-RPC method to get Merkle proof for account and storage values.\n\n"
1450+
"Description: Returns the account and storage values of the specified account including the Merkle-proof.\n\n"
1451+
"Parameters:\n"
1452+
"- chain (str): Blockchain name. Run get_supported_blockchains tool to get the list of supported blockchains.\n"
1453+
"- address (str): The address of the account or contract.\n"
1454+
"- storage_keys (list[str]): Array of storage-keys to be proofed and included.\n"
1455+
"- block (str): Block number or keyword like 'latest', 'earliest', or 'pending'.\n\n"
1456+
"Returns: Account proof object with balance, codeHash, nonce, storageHash, accountProof, and storageProof.\n\n"
1457+
"Example:\n"
1458+
'curl -X POST https://nd-422-757-666.p2pify.com/key -H "Content-Type: application/json" -d \'\n'
1459+
"{\n"
1460+
' "jsonrpc": "2.0",\n'
1461+
' "method": "eth_getProof",\n'
1462+
' "params": ["0x...", ["0x0000000000000000000000000000000000000000000000000000000000000000"], "latest"],\n'
1463+
' "id": 1\n'
1464+
"}'"
1465+
),
1466+
annotations={"title": "eth_getProof", "readOnlyHint": True},
1467+
)
1468+
async def eth_getProof(
1469+
chain: str, address: str, storage_keys: list[str], block: str = "latest"
1470+
) -> CallToolResult:
1471+
try:
1472+
return _ok(await client.eth_getProof(chain.lower(), address, storage_keys, block))
1473+
except Exception as e:
1474+
return _err(str(e))
1475+
1476+
1477+
@mcp.tool(
1478+
name="eth_simulateV1",
1479+
description=(
1480+
"Call the eth_simulateV1 JSON-RPC method to simulate transaction execution with state overrides.\n\n"
1481+
"Description: Simulates a list of transactions on top of a block and returns trace data.\n\n"
1482+
"Parameters:\n"
1483+
"- chain (str): Blockchain name. Run get_supported_blockchains tool to get the list of supported blockchains.\n"
1484+
"- block_state_calls (dict): Object containing blockOverrides, stateOverrides, and calls arrays.\n"
1485+
"- block (str): Block number or keyword like 'latest'.\n"
1486+
"- validation (bool, optional): Enable validation. Default is True.\n"
1487+
"- trace_transfers (bool, optional): Include trace transfers. Default is False.\n\n"
1488+
"Returns: Simulation result with call results and traces.\n\n"
1489+
"Example:\n"
1490+
'curl -X POST https://ethereum-mainnet.core.chainstack.com/key -H "Content-Type: application/json" -d \'\n'
1491+
"{\n"
1492+
' "jsonrpc": "2.0",\n'
1493+
' "method": "eth_simulateV1",\n'
1494+
' "params": [\n'
1495+
" {\n"
1496+
' "blockStateCalls": [{\n'
1497+
' "calls": [{"from": "0x...", "to": "0x...", "value": "0x1"}]\n'
1498+
" }],\n"
1499+
' "validation": true\n'
1500+
" },\n"
1501+
' "latest"\n'
1502+
" ],\n"
1503+
' "id": 1\n'
1504+
"}'"
1505+
),
1506+
annotations={"title": "eth_simulateV1", "readOnlyHint": True},
1507+
)
1508+
async def eth_simulateV1(
1509+
chain: str,
1510+
block_state_calls: dict,
1511+
block: str = "latest",
1512+
validation: bool = True,
1513+
trace_transfers: bool = False,
1514+
) -> CallToolResult:
1515+
try:
1516+
params = {
1517+
"blockStateCalls": block_state_calls.get("blockStateCalls", []),
1518+
"validation": validation,
1519+
"traceTransfers": trace_transfers,
1520+
}
1521+
if "stateOverrides" in block_state_calls:
1522+
params["stateOverrides"] = block_state_calls["stateOverrides"]
1523+
if "blockOverrides" in block_state_calls:
1524+
params["blockOverrides"] = block_state_calls["blockOverrides"]
1525+
1526+
return _ok(await client.eth_simulateV1(chain.lower(), params, block))
1527+
except Exception as e:
1528+
return _err(str(e))
1529+
1530+
1531+
@mcp.tool(
1532+
name="eth_getBlockReceipts",
1533+
description=(
1534+
"Call the eth_getBlockReceipts JSON-RPC method to get all transaction receipts for a block.\n\n"
1535+
"Description: Returns all transaction receipts for a given block.\n\n"
1536+
"Parameters:\n"
1537+
"- chain (str): Blockchain name. Run get_supported_blockchains tool to get the list of supported blockchains.\n"
1538+
"- block (str): Block number (hex) or keyword like 'latest', 'earliest', or 'pending'.\n\n"
1539+
"Returns: Array of transaction receipt objects for all transactions in the block.\n\n"
1540+
"Example:\n"
1541+
'curl -X POST https://nd-422-757-666.p2pify.com/key -H "Content-Type: application/json" -d \'\n'
1542+
"{\n"
1543+
' "jsonrpc": "2.0",\n'
1544+
' "method": "eth_getBlockReceipts",\n'
1545+
' "params": ["latest"],\n'
1546+
' "id": 1\n'
1547+
"}'"
1548+
),
1549+
annotations={"title": "eth_getBlockReceipts", "readOnlyHint": True},
1550+
)
1551+
async def eth_getBlockReceipts(chain: str, block: str) -> CallToolResult:
1552+
try:
1553+
return _ok(await client.eth_getBlockReceipts(chain.lower(), block))
1554+
except Exception as e:
1555+
return _err(str(e))

0 commit comments

Comments
 (0)