Skip to content

CdpEvmWalletProvider fails with misleading ETIMEDOUT when asyncio event loop exists #967

@darrylsj

Description

@darrylsj

Problem

The CdpEvmWalletProvider.__init__ method fails with a misleading error message when an asyncio event loop is already running, which is common in:

  • Jupyter notebooks
  • Web frameworks (FastAPI, Flask with async)
  • Agent orchestration systems (like OpenClaw)
  • Any environment where asyncio is already running

Current Error Message

ValueError: Failed to initialize CDP wallet: NetworkError(ETIMEDOUT, "Request timed out")

Root Cause

In coinbase_agentkit/wallet_providers/cdp_evm_wallet_provider.py lines 62-66:

if config.address:
    account = asyncio.run(self._get_account(client, config.address))
else:
    account = asyncio.run(self._create_account(client))

The asyncio.run() calls fail when there's already an event loop running, causing a RuntimeError: cannot be called from a running event loop. This gets caught by the exception handler in __init__ and misleadingly wrapped as a network timeout error.

The _run_async helper method also has issues with event loop detection and handling on Python 3.14+.

Reproduction

import asyncio
from coinbase_agentkit.wallet_providers import CdpEvmWalletProvider, CdpEvmWalletProviderConfig

# This simulates Jupyter/web framework environment
async def test_in_existing_loop():
    config = CdpEvmWalletProviderConfig(
        api_key_id="your-key-id",
        api_key_secret="your-key-secret", 
        wallet_secret="your-wallet-secret"
    )
    # This will fail with misleading ETIMEDOUT error
    wallet = CdpEvmWalletProvider(config)

# Run in existing event loop context
asyncio.run(test_in_existing_loop())

Expected Behavior

  • Should work seamlessly in environments with existing asyncio event loops
  • Error messages should accurately reflect the root cause (asyncio conflicts, not network timeouts)

Workaround

Currently requires using nest_asyncio.apply() but this doesn't fully resolve the issue on Python 3.14+.

Secondary Issues

While fixing this, also noting:

  1. get_or_create_account() doesn't accept address= kwarg, making it impossible to reconnect to existing accounts via the raw CDP client
  2. When address is not specified in config, it silently creates a NEW account instead of raising an error or listing existing ones

Environment

  • Python 3.14+
  • Any environment with existing asyncio event loops
  • nest_asyncio package present but insufficient

Files Affected

  • coinbase_agentkit/wallet_providers/cdp_evm_wallet_provider.py

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions