-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Python jsonrpc plugin (#224)
* feat: Add Python jsonrpc plugin - Add jsonrpc plugin Python implementation - Match TypeScript plugin functionality - Include JSON-RPC 2.0 protocol support - Add async implementation using aiohttp - Add plugin documentation Co-Authored-By: Agus Armellini Fischer <[email protected]> * Delete python/src/plugins/jsonrpc/goat_plugins/__init__.py --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Agus Armellini Fischer <[email protected]> Co-authored-by: Agus <[email protected]>
- Loading branch information
1 parent
83c3500
commit 035fe58
Showing
5 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# GOAT SDK JSON-RPC Plugin | ||
|
||
A plugin for the GOAT SDK that enables making JSON-RPC calls to any compatible endpoint. | ||
|
||
## Features | ||
|
||
- Make JSON-RPC calls to any compatible endpoint | ||
- Supports standard JSON-RPC 2.0 protocol | ||
- Fully async implementation using aiohttp | ||
- Integrates seamlessly with GOAT SDK and LangChain | ||
|
||
## Installation | ||
|
||
```bash | ||
poetry add goat-sdk-plugin-jsonrpc | ||
``` | ||
|
||
## Usage | ||
|
||
```python | ||
from goat_plugins.jsonrpc import jsonrpc, JSONRpcPluginOptions | ||
|
||
# Initialize the plugin with your RPC endpoint | ||
tools = get_on_chain_tools( | ||
wallet=wallet_client, | ||
plugins=[ | ||
jsonrpc(options=JSONRpcPluginOptions(endpoint="your-rpc-endpoint")) | ||
], | ||
) | ||
|
||
# Example JSON-RPC call | ||
response = await tools.JSONRpcFunc({ | ||
"method": "eth_blockNumber", | ||
"params": [], | ||
"id": 1, | ||
"jsonrpc": "2.0" | ||
}) | ||
``` | ||
|
||
## License | ||
|
||
This project is licensed under the terms of the MIT license. |
21 changes: 21 additions & 0 deletions
21
python/src/plugins/jsonrpc/goat_plugins/jsonrpc/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from dataclasses import dataclass | ||
|
||
from goat.classes.plugin_base import PluginBase | ||
from .service import JSONRpcService | ||
|
||
|
||
@dataclass | ||
class JSONRpcPluginOptions: | ||
endpoint: str | ||
|
||
|
||
class JSONRpcPlugin(PluginBase): | ||
def __init__(self, options: JSONRpcPluginOptions): | ||
super().__init__("jsonrpc", [JSONRpcService(options.endpoint)]) | ||
|
||
def supports_chain(self, chain) -> bool: | ||
return True | ||
|
||
|
||
def jsonrpc(options: JSONRpcPluginOptions) -> JSONRpcPlugin: | ||
return JSONRpcPlugin(options) |
20 changes: 20 additions & 0 deletions
20
python/src/plugins/jsonrpc/goat_plugins/jsonrpc/parameters.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from pydantic import BaseModel, Field | ||
from typing import List | ||
|
||
class JSONRpcBodyParameters(BaseModel): | ||
method: str = Field( | ||
..., | ||
description="A string containing the name of the method to be invoked" | ||
) | ||
params: List[str] = Field( | ||
..., | ||
description="A structured value that holds the parameter value to be used during the invokation of the method" | ||
) | ||
id: int = Field( | ||
..., | ||
description="An identifier established by the client that must contain a string number or null" | ||
) | ||
jsonrpc: str = Field( | ||
..., | ||
description="A string that specifies the version of the JSON-RPC protocol must be exactly '2.0'" | ||
) |
22 changes: 22 additions & 0 deletions
22
python/src/plugins/jsonrpc/goat_plugins/jsonrpc/service.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import aiohttp | ||
from goat.decorators.tool import Tool | ||
from .parameters import JSONRpcBodyParameters | ||
|
||
class JSONRpcService: | ||
def __init__(self, endpoint: str): | ||
self.endpoint = endpoint | ||
|
||
@Tool({ | ||
"description": "Make a remote procedure call to a JSON RPC endpoint", | ||
"parameters_schema": JSONRpcBodyParameters | ||
}) | ||
async def JSONRpcFunc(self, parameters: dict): | ||
"""Makes a POST request to the configured endpoint with the required JSON-RPC parameters.""" | ||
try: | ||
async with aiohttp.ClientSession() as session: | ||
async with session.post(self.endpoint, json=parameters) as response: | ||
if not response.ok: | ||
raise Exception(f"HTTP error! status: {response.status}, body: {await response.text()}") | ||
return await response.json() | ||
except Exception as e: | ||
raise Exception(f"Failed to call {self.endpoint}: {e}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
[tool.poetry] | ||
name = "goat-sdk-plugin-jsonrpc" | ||
version = "0.1.1" | ||
description = "Goat plugin for JSON-RPC" | ||
authors = ["Andrea Villa <[email protected]>"] | ||
readme = "README.md" | ||
keywords = ["goat", "sdk", "web3", "agents", "ai"] | ||
homepage = "https://ohmygoat.dev/" | ||
repository = "https://github.com/goat-sdk/goat" | ||
packages = [ | ||
{ include = "goat_plugins" }, | ||
] | ||
|
||
[tool.poetry.dependencies] | ||
python = "^3.10" | ||
aiohttp = "^3.8.6" | ||
goat-sdk = "^0.1.1" | ||
|
||
[tool.poetry.group.test.dependencies] | ||
pytest = "^8.3.4" | ||
pytest-asyncio = "^0.25.0" | ||
|
||
[tool.poetry.urls] | ||
"Bug Tracker" = "https://github.com/goat-sdk/goat/issues" | ||
|
||
[tool.pytest.ini_options] | ||
addopts = [ | ||
"--import-mode=importlib", | ||
] | ||
pythonpath = "src" | ||
asyncio_default_fixture_loop_scope = "function" | ||
|
||
[build-system] | ||
requires = ["poetry-core"] | ||
build-backend = "poetry.core.masonry.api" | ||
|
||
[tool.poetry.group.dev.dependencies] | ||
ruff = "^0.8.6" | ||
goat-sdk = { path = "../../goat-sdk", develop = true } | ||
|
||
[tool.ruff] | ||
line-length = 120 | ||
target-version = "py312" |