Context
Cold-agent dogfood test: an AI agent with no x402r context was given a merchant URL and a private key, and asked to get a paid response. It found @x402r/evm via the SDK hint in the 402 payload, followed the README, and stumbled on one specific friction point:
The README imports CommerceEvmScheme on line 16:
import { CommerceEvmScheme, registerCommerceEvmScheme } from '@x402r/evm/commerce/client'
…but every example only shows the registerCommerceEvmScheme(client, { signer }) call. The direct class is in scope and never used. By analogy to the register function, the agent tried:
const scheme = new CommerceEvmScheme({ signer: account })
The constructor actually wants the bare account: new CommerceEvmScheme(account). The mismatch throws a misleading error deep inside viem (Address \"undefined\" is invalid), with no indication that the offending parameter is the constructor shape.
What to change
Pick one of:
Option A (preferred): Show the direct constructor form in the README alongside the register helper, so agents who want to skip the register pattern have a correct template:
import { CommerceEvmScheme } from '@x402r/evm/commerce/client'
const scheme = new CommerceEvmScheme(signer)
// pass to whichever client you're using
Option B: Don't import CommerceEvmScheme in README examples if users shouldn't construct it directly. Remove from line 16 import, remove from "Exports" section's top-level @x402r/evm line. Keep it as an internal type.
Option C (mechanical): Make the constructor accept both shapes (new CommerceEvmScheme(signer) and new CommerceEvmScheme({ signer })) and throw a clear error (Expected Account or { signer: Account }, got {signer: undefined}) when neither matches.
Why
This is the only real stumble a cold agent hits on the happy path. Fixing it compresses time-to-first-paid-request materially.
Acceptance criteria
Context
Cold-agent dogfood test: an AI agent with no x402r context was given a merchant URL and a private key, and asked to get a paid response. It found
@x402r/evmvia the SDK hint in the 402 payload, followed the README, and stumbled on one specific friction point:The README imports
CommerceEvmSchemeon line 16:…but every example only shows the
registerCommerceEvmScheme(client, { signer })call. The direct class is in scope and never used. By analogy to the register function, the agent tried:The constructor actually wants the bare account:
new CommerceEvmScheme(account). The mismatch throws a misleading error deep inside viem (Address \"undefined\" is invalid), with no indication that the offending parameter is the constructor shape.What to change
Pick one of:
Option A (preferred): Show the direct constructor form in the README alongside the register helper, so agents who want to skip the register pattern have a correct template:
Option B: Don't import
CommerceEvmSchemein README examples if users shouldn't construct it directly. Remove from line 16 import, remove from "Exports" section's top-level@x402r/evmline. Keep it as an internal type.Option C (mechanical): Make the constructor accept both shapes (
new CommerceEvmScheme(signer)andnew CommerceEvmScheme({ signer })) and throw a clear error (Expected Account or { signer: Account }, got {signer: undefined}) when neither matches.Why
This is the only real stumble a cold agent hits on the happy path. Fixing it compresses time-to-first-paid-request materially.
Acceptance criteria