Skip to content

test(python/evm): add unit tests for ExactEvmSchemeV1 client#145

Open
0xAxiom wants to merge 1 commit into
coinbase:mainfrom
0xAxiom:test/python-evm-exact-v1-client-unit-tests
Open

test(python/evm): add unit tests for ExactEvmSchemeV1 client#145
0xAxiom wants to merge 1 commit into
coinbase:mainfrom
0xAxiom:test/python-evm-exact-v1-client-unit-tests

Conversation

@0xAxiom
Copy link
Copy Markdown

@0xAxiom 0xAxiom commented May 4, 2026

Summary

Add 23 unit tests for python/x402/x402/mechanisms/evm/exact/v1/client.py — the last source file in mechanisms/evm/exact/ without a dedicated unit test module.

mechanisms/evm/exact/v1/client.py (ExactEvmSchemeV1) is the V1-legacy client counterpart of mechanisms/evm/exact/client.py (ExactEvmScheme). The V2 client has had dedicated coverage for a while; the V1 client only had partial integration coverage. This PR closes the gap so the V1 codepath is exercised at unit-test granularity.

What's covered

TestExactEvmSchemeV1Constructor (4 tests)

  • scheme attribute is "exact"
  • Stores signer reference on _signer
  • Auto-wraps a raw LocalAccount in EthAccountSigner
  • Does not double-wrap an existing EthAccountSigner

TestCreatePaymentPayloadV1 (9 tests)

  • Returns inner payload dict with authorization + signature
  • Signature is 0x-prefixed, 132 chars (65-byte ECDSA, hex-encoded)
  • V1 max_amount_required → authorization value
  • from is signer address, to is requirements.pay_to
  • valid_after = now - 600s (V1 buffer)
  • valid_before = now + max_timeout_seconds
  • Falsy max_timeout_seconds (e.g. 0) falls back to 600s
  • Nonce is freshly generated, 32 bytes / 0x + 64 hex

TestSignAuthorizationV1 (10 tests)

  • Legacy network name → chain ID lookup (base → 8453, base-sepolia → 84532)
  • Unknown legacy name raises ValueError("Unknown v1 network …")
  • CAIP-2 format (eip155:8453) is rejected (V2-only)
  • extra accepts a JSON string and is re-parsed (json.loads)
  • Missing name falls back to V1 get_asset_info lookup
  • Missing name + unregistered asset → ValueError("EIP-712 domain name required …")
  • Missing version defaults to "1"
  • Signer is invoked with TypedDataField lists (not raw dicts)
  • Bytes signature returned by signer is hex-encoded with 0x prefix

Verification

$ uv run pytest tests/unit/mechanisms/evm/test_exact_v1_client.py -v
23 passed in 3.86s

$ uv run pytest tests/unit/mechanisms/evm/ -q
277 passed in 1.39s

$ uvx ruff format tests/unit/mechanisms/evm/test_exact_v1_client.py
1 file left unchanged

$ uvx ruff check tests/unit/mechanisms/evm/test_exact_v1_client.py
All checks passed!

Notes

  • Pure test-only addition; no source files modified, no public API change.
  • Per CONTRIBUTING.md, no changelog fragment is added (test-only changes are excluded).
  • Commit is GPG-signed.

🤖 Generated with Claude Code

Add 23 unit tests for python/x402/x402/mechanisms/evm/exact/v1/client.py — the
last source file in mechanisms/evm/exact/ without a dedicated test module.

Coverage:
- Constructor: scheme attribute, signer storage, raw LocalAccount auto-wrap,
  pre-wrapped EthAccountSigner pass-through.
- create_payment_payload: returns inner dict with authorization+signature,
  hex-encoded 65-byte signature, V1 max_amount_required mapped to value,
  from/to address mapping, valid_after = now-600s, valid_before honors
  max_timeout_seconds, falsy timeout falls back to 600s, nonce is fresh
  per call and 32 bytes.
- _sign_authorization V1 specifics: legacy network names resolve to chain IDs
  (base→8453, base-sepolia→84532), unknown legacy names raise ValueError,
  CAIP-2 format is rejected (V2-only), JSON-string extra is parsed, missing
  name falls back to V1 asset_info, missing name + unregistered asset raises,
  missing version defaults to '1', signer receives TypedDataField objects,
  bytes signature is hex-encoded with 0x prefix.

All 23 tests pass; full mechanisms/evm suite still passes (277 tests).
@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