Skip to content

[Python] ExactEvmScheme silently accepts raw LocalAccount but fails at sign time #1121

@endcycles

Description

@endcycles

Bug

ExactEvmScheme(signer=account) accepts an eth_account.signers.local.LocalAccount without error, but fails later during create_payment_payload with a confusing ValueError from encode_typed_data.

The issue is that LocalAccount.sign_typed_data has a different signature than the ClientEvmSigner protocol:

# ClientEvmSigner protocol (what ExactEvmScheme calls):
sign_typed_data(domain, types, primary_type, message) -> bytes

# LocalAccount.sign_typed_data (what gets called):
sign_typed_data(domain_data=None, message_types=None, message_data=None, full_message=None)

When called positionally, primary_type (a string) lands in the message_data parameter, and message (a dict) lands in full_message. This triggers:

ValueError: You may supply either `full_message` as a single argument or
`domain_data`, `message_types`, and `message_data` as three arguments, but not both.

Steps to Reproduce

from eth_account import Account
from x402 import PaymentRequired, x402ClientSync
from x402.mechanisms.evm.exact import ExactEvmScheme

account = Account.from_key("0x...")

# This is accepted without error but will fail later:
scheme = ExactEvmScheme(signer=account)

client = x402ClientSync()
client.register("eip155:*", scheme)

# Fails here with ValueError from encode_typed_data
payload = client.create_payment_payload(payment_required)

Workaround

Wrap the account in EthAccountSigner:

from x402.mechanisms.evm.signers import EthAccountSigner

signer = EthAccountSigner(account)
scheme = ExactEvmScheme(signer=signer)

Suggestion

Either:

  1. Add a type check / runtime validation in ExactEvmScheme.__init__ that rejects LocalAccount with a helpful error pointing to EthAccountSigner
  2. Auto-wrap LocalAccount instances in EthAccountSigner when detected
  3. Document the requirement prominently in the README

Environment

  • x402 Python SDK v2.0.0
  • eth-account 0.13.7
  • Python 3.12

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