ChallengeEngine class orchestrates the full challenge lifecycle: creating challenges, verifying payments, transitioning state, and issuing credentials. It is instantiated internally by createKey0() and shared across all transports (Express, Hono, Fastify, MCP).
You rarely construct a ChallengeEngine directly. Use the factory unless you need full control over wiring.
Constructor
Methods
requestAccess
Creates aPENDING challenge for the A2A protocol flow. Idempotent — if a challenge with the same requestId already exists, the existing challenge is returned.
Returns:
Promise<X402Challenge> — the challenge object containing challengeId, payment amount, destination wallet, and chainId.
requestHttpAccess
Creates aPENDING challenge for the x402 HTTP flow. Auto-generates a requestId if one is not provided.
Returns:
Promise<{ challengeId: string }> — the ID of the created challenge.
submitProof
Verifies a payment on-chain viaadapter.verifyProof(), transitions the challenge from PENDING to PAID to DELIVERED, and issues credentials. Used by the A2A protocol flow.
Returns:
Promise<AccessGrant> — the grant containing the issued credential (JWT, API key, etc.) from fetchResourceCredentials.
processHttpPayment
Handles payment for the x402 HTTP flow. UnlikesubmitProof, this method skips on-chain verification because the x402 settlement layer has already verified the payment. Creates a challenge if one does not yet exist, then transitions through PAID to DELIVERED.
Returns:
Promise<AccessGrant> — the grant containing the issued credential.
preSettlementCheck
Returns a cachedAccessGrant if the challenge has already been delivered. Returns null otherwise. Use this to avoid duplicate settlement when a client retries a request that was already fulfilled.
Returns:
Promise<AccessGrant | null> — the existing grant, or null if no delivered grant exists.
cancelChallenge
Transitions a challenge fromPENDING to CANCELLED. Only pending challenges can be cancelled.
Returns:
Promise<void>
State Machine
ChallengeEngine enforces a strict state machine for every challenge. Only valid transitions are permitted; invalid transitions throw a Key0Error.
IChallengeStore.transition() to prevent race conditions under concurrent access. For the full state machine specification, see the State Machine page.
Error Handling
All methods throwKey0Error with typed error codes when a failure occurs. Common scenarios include:
See the full list of error codes at Error Codes.
Usage Example
In most applications, you interact withChallengeEngine indirectly through the framework integration. For direct usage:
Related
- SellerConfig — configuration that drives engine behavior
- Storage — challenge and seen-tx store implementations
- X402Adapter — on-chain payment verification
- State Machine — full state transition diagram
- Error Codes — typed error codes reference

