Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
096c34f
Initial plan
Copilot Mar 7, 2026
016599c
feat: add get_balance action to TypeScript WalletActionProvider
Copilot Mar 7, 2026
d35f953
Initial plan
Copilot Mar 7, 2026
b3ae45b
Fix yarn install in next template by adding packageManager field
Copilot Mar 7, 2026
71c620b
Merge pull request #1 from Kushmanmb/copilot/fetch-wallet-data
Kushmanmb Mar 7, 2026
01b8628
Initial plan
Copilot Mar 7, 2026
29e4400
Merge pull request #2 from Kushmanmb/copilot/install-yarn-dependencies
Kushmanmb Mar 7, 2026
215dbda
Initial plan
Copilot Mar 7, 2026
d5a6cb3
feat(typescript): migrate from pnpm to yarn for running tests
Copilot Mar 7, 2026
a305a79
Add return_native_balance action to wallet action providers (TypeScri…
Copilot Mar 7, 2026
369d871
Update return_native_balance to deduct gas fees before transfer
Copilot Mar 7, 2026
79afa71
Merge pull request #4 from Kushmanmb/copilot/return-native-token-balance
Kushmanmb Mar 7, 2026
327d979
Merge pull request #3 from Kushmanmb/copilot/run-tests-with-yarn
Kushmanmb Mar 7, 2026
76fc547
Initial plan
Copilot Mar 7, 2026
cdd83fd
Add zero address protection to wallet transfer actions (TypeScript + …
Copilot Mar 7, 2026
87025d2
Security audit fixes: zero address validation, remove debug statement…
Copilot Mar 11, 2026
c29ea42
Address code review feedback: fix BigInt precision literal, restore s…
Copilot Mar 11, 2026
31f3195
Merge branch 'main' into copilot/audit-zero-address-vulnerabilities
Kushmanmb Mar 11, 2026
67e0084
Update typescript/agentkit/src/action-providers/wallet/walletActionPr…
Kushmanmb Mar 11, 2026
bfeb7ea
Update python/coinbase-agentkit/coinbase_agentkit/action_providers/wa…
Kushmanmb Mar 11, 2026
1c4ead4
Fix review feedback: align Python test constants/messages and fix TS …
Copilot Mar 11, 2026
4cd4e52
Initial plan
Copilot Mar 11, 2026
eb995ea
Add Etherscan action provider for smart contract verification
Copilot Mar 11, 2026
62b4214
Merge pull request #10 from Kushmanmb/copilot/verify-publish-ethersca…
Kushmanmb Mar 11, 2026
ec858b4
Merge pull request #5 from Kushmanmb/copilot/audit-zero-address-vulne…
Kushmanmb Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,14 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda
with:
version: 10

- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
cache-dependency-path: ./typescript
cache: "yarn"
cache-dependency-path: ./typescript/yarn.lock

- name: Install and test AgentKit.js
working-directory: ./typescript
run: |
pnpm install --frozen-lockfile
pnpm run test
yarn install --frozen-lockfile
yarn test
2 changes: 2 additions & 0 deletions python/coinbase-agentkit/coinbase_agentkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
create_action,
erc20_action_provider,
erc721_action_provider,
etherscan_action_provider,
hyperbolic_action_provider,
morpho_action_provider,
nillion_action_provider,
Expand Down Expand Up @@ -64,6 +65,7 @@
"compound_action_provider",
"erc20_action_provider",
"erc721_action_provider",
"etherscan_action_provider",
"hyperbolic_action_provider",
"morpho_action_provider",
"nillion_action_provider",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
)
from .compound.compound_action_provider import CompoundActionProvider, compound_action_provider
from .erc20.erc20_action_provider import ERC20ActionProvider, erc20_action_provider
from .etherscan.etherscan_action_provider import (
EtherscanActionProvider,
etherscan_action_provider,
)
from .erc721.erc721_action_provider import Erc721ActionProvider, erc721_action_provider
from .hyperboliclabs.hyperbolic_action_provider import (
HyperbolicActionProvider,
Expand Down Expand Up @@ -57,6 +61,8 @@
"compound_action_provider",
"ERC20ActionProvider",
"erc20_action_provider",
"EtherscanActionProvider",
"etherscan_action_provider",
"Erc721ActionProvider",
"erc721_action_provider",
"HyperbolicActionProvider",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pydantic import BaseModel, Field, field_validator
from pydantic_core import PydanticCustomError

from ...validators.eth import validate_not_zero_address


class GetBalanceSchema(BaseModel):
"""Schema for getting the balance of an ERC20 token."""
Expand All @@ -29,6 +31,12 @@ class TransferSchema(BaseModel):
contract_address: str = Field(description="The contract address of the token to transfer")
destination_address: str = Field(description="The destination to transfer the funds")

@field_validator("destination_address")
@classmethod
def validate_destination_address(cls, v: str) -> str:
"""Validate destination address is a valid non-zero Ethereum address."""
return validate_not_zero_address(v)

@field_validator("amount")
@classmethod
def validate_amount(cls, v: str) -> str:
Expand Down Expand Up @@ -90,6 +98,12 @@ class ApproveSchema(BaseModel):
contract_address: str = Field(description="The contract address of the token")
spender_address: str = Field(description="The address to approve for spending tokens")

@field_validator("spender_address")
@classmethod
def validate_spender_address(cls, v: str) -> str:
"""Validate spender address is a valid non-zero Ethereum address."""
return validate_not_zero_address(v)

@field_validator("amount")
@classmethod
def validate_amount(cls, v: str) -> str:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Etherscan Action Provider

The Etherscan action provider enables AI agents to verify and publish smart contract source code on [Etherscan](https://etherscan.io) and compatible block explorers (Basescan, Arbiscan, Optimism Explorer, PolygonScan).

## Actions

### `verify_smart_contract`

Submits a deployed contract's Solidity source code for on-chain verification.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `contract_address` | `str` | ✅ | The on-chain address of the deployed contract |
| `source_code` | `str` | ✅ | Full Solidity source code (or Standard JSON input) |
| `contract_name` | `str` | ✅ | Contract name (e.g. `MyToken`); for Standard JSON include the file path (e.g. `contracts/MyToken.sol:MyToken`) |
| `compiler_version` | `str` | ✅ | Exact compiler version string (e.g. `v0.8.20+commit.a1b79de6`) |
| `optimization_used` | `bool` | ❌ | Whether the optimizer was enabled (default: `False`) |
| `runs` | `int` | ❌ | Optimizer runs — only relevant when `optimization_used` is `True` (default: `200`) |
| `constructor_arguments` | `str` | ❌ | ABI-encoded constructor arguments without `0x` prefix (default: `""`) |
| `evm_version` | `str` | ❌ | Target EVM version, e.g. `london` or `paris` (default: compiler default) |
| `license_type` | `int` | ❌ | SPDX license type 1–14 (default: `1` = No License) |
| `code_format` | `str` | ❌ | `solidity-single-file` or `solidity-standard-json-input` (default: `solidity-single-file`) |

On success the action returns the **GUID** issued by Etherscan which you can pass to `get_verification_status` to poll for the result.

---

### `get_verification_status`

Polls for the result of a previously submitted verification request.

**Parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `guid` | `str` | ✅ | The GUID returned by `verify_smart_contract` |

Common status values returned by Etherscan:

- **"Pending in queue"** — queued, not yet processed
- **"Pass - Verified"** — source code verified successfully ✅
- **"Fail - Unable to verify"** — verification failed; check compiler settings
- **"Already Verified"** — contract is already verified on this explorer

---

## Setup

### API Key

An Etherscan (or compatible explorer) API key is required. Obtain one at [https://etherscan.io/myapikey](https://etherscan.io/myapikey).

Set it as an environment variable:

```bash
export ETHERSCAN_API_KEY="your_api_key_here"
```

Or pass it explicitly when initialising the provider:

```python
from coinbase_agentkit import etherscan_action_provider

provider = etherscan_action_provider(api_key="your_api_key_here")
```

### Supported Networks

All EVM-compatible networks configured in AgentKit are supported, including:

- Ethereum Mainnet & Sepolia
- Base & Base Sepolia
- Arbitrum One & Arbitrum Sepolia
- Optimism Mainnet & OP Sepolia
- Polygon & Polygon Amoy

---

## Usage Example

```python
from coinbase_agentkit import AgentKit, AgentKitConfig, etherscan_action_provider
from coinbase_agentkit.wallet_providers import EthAccountWalletProvider, EthAccountWalletProviderConfig

wallet_provider = EthAccountWalletProvider(
EthAccountWalletProviderConfig(private_key="0x...", chain_id="1")
)

agentkit = AgentKit(
AgentKitConfig(
wallet_provider=wallet_provider,
action_providers=[etherscan_action_provider()],
)
)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Etherscan action provider for smart contract verification."""
Loading
Loading