Skip to content

test(python/evm): add unit tests for FacilitatorWeb3Signer methods#148

Open
0xAxiom wants to merge 1 commit intocoinbase:mainfrom
0xAxiom:test/python-evm-facilitator-web3-signer-methods
Open

test(python/evm): add unit tests for FacilitatorWeb3Signer methods#148
0xAxiom wants to merge 1 commit intocoinbase:mainfrom
0xAxiom:test/python-evm-facilitator-web3-signer-methods

Conversation

@0xAxiom
Copy link
Copy Markdown

@0xAxiom 0xAxiom commented May 4, 2026

Summary

tests/unit/mechanisms/evm/test_signer.py previously covered only the constructor, address property, and protocol surface of FacilitatorWeb3Signer in python/x402/x402/mechanisms/evm/signers.py. The actual on-chain methods were untested. This PR adds 17 unit tests that exercise every method's behavior with a mocked Web3 client.

Coverage Added

  • get_chain_id — RPC call + caching (mutating the mock after the first call still returns the cached value)
  • read_contract — contract-address checksumming, function invocation, and {\"from\": signer.address} propagation in .call(...)
  • verify_typed_data
    • EOA happy path against the matching account
    • EOA mismatch with no contract code (EIP-1271 path skipped)
    • bytes nonce normalized to hex without mutating the caller's message dict
    • Raw dict domain (Permit2-style, no version) accepted as-is
    • Internal exception swallowed → returns False
  • write_contract — build → sign → send-raw flow with checksummed contract address and propagated nonce/gas/gasPrice
  • send_transaction — raw tx build with checksummed to, account signing, hex tx-hash return
  • wait_for_transaction_receiptstatus=1 → TX_STATUS_SUCCESS, non-1 → 0, and a tx_hash without 0x prefix normalized in both the web3 call and the returned receipt
  • get_balance — zero-address routes to native eth.get_balance, empty-string token routes to native, real token address routes through ERC20 contract path with checksummed addresses
  • get_code — address checksumming and bytes() wrapping for both contract and EOA cases

Test plan

  • uv run pytest tests/unit/mechanisms/evm/test_signer.py → 27 passed (10 existing + 17 new)
  • uv run pytest tests/unit/mechanisms/evm/ → 271 passed (no regressions)
  • uvx ruff format applied
  • uvx ruff check clean
  • GPG-signed commit
  • Changeset fragment in python/x402/changelog.d/

🤖 Generated with Claude Code

The existing test_signer.py only covered the constructor, address
property, and protocol surface of FacilitatorWeb3Signer in
python/x402/x402/mechanisms/evm/signers.py. The actual on-chain
methods were not exercised. This commit fills that gap.

Tests cover:
- get_chain_id: RPC call + caching (mutating the underlying mock after
  first call still returns the cached value).
- read_contract: address checksumming on the contract address, function
  invocation, and {"from": signer.address} propagation in call().
- verify_typed_data: EOA happy path against the matching account, EOA
  mismatch with no contract code (EIP-1271 path skipped), bytes nonce
  normalized to hex without mutating the caller's message dict, raw
  dict domain (Permit2-style, no version) accepted as-is, and any
  internal exception swallowed to return False.
- write_contract: build → sign → send raw flow with checksummed
  contract address and propagated nonce/gas/gasPrice.
- send_transaction: raw tx build with checksummed `to`, account
  signing, and hex tx-hash return.
- wait_for_transaction_receipt: status=1 maps to TX_STATUS_SUCCESS,
  non-1 maps to 0, and a tx_hash without 0x prefix is normalized in
  both the web3 call and the returned receipt.
- get_balance: zero-address routes to native eth.get_balance, empty
  string also routes to native, and a real token address goes through
  the ERC20 contract path with checksummed addresses.
- get_code: address checksumming and bytes() wrapping for both
  contract and EOA cases.

17 new tests, 27 total in the file. All tests in
tests/unit/mechanisms/evm/ continue to pass (271 total).

Signed-off-by: Axiom Bot <0xAxiom@users.noreply.github.com>
@cb-heimdall
Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants