-
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 implementation of 1inch plugin (#218)
* feat: Add Python implementation of 1inch plugin - Create Python plugin structure mirroring coingecko plugin - Implement get_balances functionality from TypeScript version - Add proper parameter validation and error handling - Include documentation and configuration details Co-Authored-By: Agus Armellini Fischer <[email protected]> * Update pyproject.toml * refactor: rename package to goat-plugin-1inch and update plugin structure - Rename package from goat-plugin-oneinch to goat-plugin-1inch - Update directory structure from oneinch to inch1 - Update __init__.py to match coingecko plugin structure - Add OneInchPluginOptions and OneInchPlugin classes Co-Authored-By: Agus Armellini Fischer <[email protected]> * Update __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
e5c84ec
commit 7d63e9e
Showing
5 changed files
with
164 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,52 @@ | ||
# 1inch Plugin for GOAT | ||
|
||
This plugin provides integration with the 1inch API for the GOAT SDK. | ||
|
||
## Features | ||
|
||
- Get token balances and allowances for a wallet address on a specific chain | ||
|
||
## Installation | ||
|
||
```bash | ||
pip install goat-plugin-1inch | ||
``` | ||
|
||
## Usage | ||
|
||
```python | ||
from goat_plugins.inch1 import OneInchService | ||
|
||
# Initialize the service with your API key | ||
service = OneInchService(api_key="your_api_key") | ||
|
||
# Get balances for a wallet | ||
balances = await service.get_aggregated_balances({ | ||
"wallet_address": "0x...", | ||
"chain_id": 1 # Ethereum mainnet | ||
}) | ||
``` | ||
|
||
## Configuration | ||
|
||
The plugin requires a 1inch API key to function. You can obtain one from the [1inch Developer Portal](https://portal.1inch.dev/). | ||
|
||
Set your API key when initializing the service: | ||
|
||
```python | ||
service = OneInchService(api_key="your_api_key") | ||
``` | ||
|
||
## Development | ||
|
||
To set up the development environment: | ||
|
||
1. Clone the repository | ||
2. Install dependencies with Poetry: | ||
```bash | ||
poetry install | ||
``` | ||
3. Run tests: | ||
```bash | ||
poetry run pytest | ||
``` |
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 OneInchService | ||
|
||
|
||
@dataclass | ||
class OneInchPluginOptions: | ||
api_key: str | ||
|
||
|
||
class OneInchPlugin(PluginBase): | ||
def __init__(self, options: OneInchPluginOptions): | ||
super().__init__("1inch", [OneInchService(options.api_key)]) | ||
|
||
def supports_chain(self, chain) -> bool: | ||
return True | ||
|
||
|
||
def inch1(options: OneInchPluginOptions) -> OneInchPlugin: | ||
return OneInchPlugin(options) |
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,12 @@ | ||
from pydantic import BaseModel, Field | ||
from typing import Optional | ||
|
||
class GetBalancesParameters(BaseModel): | ||
wallet_address: str = Field( | ||
..., | ||
description="The wallet address to check balances for" | ||
) | ||
chain_id: int = Field( | ||
1, # Default to Ethereum mainnet | ||
description="The chain ID to query balances on (e.g., 1 for Ethereum mainnet)" | ||
) |
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,36 @@ | ||
import aiohttp | ||
from typing import Optional | ||
from goat.decorators.tool import Tool | ||
from .parameters import GetBalancesParameters | ||
|
||
class OneInchService: | ||
def __init__(self, api_key: Optional[str] = None): | ||
self.api_key = api_key | ||
self.base_url = "https://api.1inch.dev" | ||
|
||
@Tool({ | ||
"name": "1inch.get_balances", | ||
"description": "Get the balances of a wallet address on a specific chain", | ||
"parameters_schema": GetBalancesParameters | ||
}) | ||
async def get_aggregated_balances(self, parameters: dict): | ||
"""Get token balances and allowances for a wallet address on a specific chain.""" | ||
wallet_address = parameters.get("wallet_address") | ||
if not wallet_address: | ||
raise ValueError("wallet_address is required") | ||
|
||
chain_id = parameters.get("chain_id", 1) # Default to Ethereum mainnet | ||
|
||
url = f"{self.base_url}/balance/v1.2/{chain_id}/balances/{wallet_address}" | ||
|
||
headers = { | ||
"Accept": "application/json" | ||
} | ||
if self.api_key: | ||
headers["Authorization"] = f"Bearer {self.api_key}" | ||
|
||
async with aiohttp.ClientSession() as session: | ||
async with session.get(url, headers=headers) as response: | ||
if not response.ok: | ||
raise Exception(f"Failed to fetch balances: {response.status} {await response.text()}") | ||
return await response.json() |
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-plugin-1inch" | ||
version = "0.1.0" | ||
description = "1inch plugin for GOAT SDK" | ||
authors = ["GOAT SDK Team"] | ||
readme = "README.md" | ||
keywords = ["goat", "sdk", "web3", "agents", "ai", "1inch"] | ||
homepage = "https://ohmygoat.dev/" | ||
repository = "https://github.com/goat-sdk/goat" | ||
packages = [ | ||
{ include = "goat_plugins/inch1" }, | ||
] | ||
|
||
[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" |