Skip to main content

createKey0()

The createKey0() factory is the main entry point for assembling a Key0 instance. It takes your seller configuration, payment adapter, and storage backends, then returns a fully wired object containing the challenge engine, A2A executor, agent card, and request handler.

Signature

function createKey0(opts: Key0Config): Key0Instance

Parameters

Key0Config

config
SellerConfig
required
Seller configuration defining wallet address, network, pricing plans, and callbacks. See SellerConfig for details.
adapter
IPaymentAdapter
required
Payment adapter responsible for on-chain verification of ERC-20 transfers. Use X402Adapter for Base mainnet or Base Sepolia. See X402Adapter.
store
IChallengeStore
required
Persistent store for challenge state. Provides atomic state transitions to prevent race conditions. See Storage.
seenTxStore
ISeenTxStore
required
Store for tracking used transaction hashes. Prevents double-spend by atomically marking each txHash as consumed. See Storage.
type Key0Config = {
  readonly config: SellerConfig;
  readonly adapter: IPaymentAdapter;
  readonly store: IChallengeStore;
  readonly seenTxStore: ISeenTxStore;
};

Return value

Key0Instance

PropertyTypeDescription
requestHandlerDefaultRequestHandlerA2A request handler (from @a2a-js/sdk)
agentCardAgentCardAuto-generated A2A discovery card from config
engineChallengeEngineChallenge lifecycle engine for the payment flow
executorKey0ExecutorA2A executor implementing the x402 protocol flow
type Key0Instance = {
  requestHandler: DefaultRequestHandler;
  agentCard: AgentCard;
  engine: ChallengeEngine;
  executor: Key0Executor;
};

What it does

  1. Validates inputs — throws a descriptive error if store or seenTxStore is missing.
  2. Creates a ChallengeEngine — wires together config, store, seenTxStore, and adapter into the state machine that manages the full challenge lifecycle (PENDING, PAID, DELIVERED, EXPIRED, CANCELLED, REFUNDED).
  3. Creates a Key0Executor — builds the A2A protocol executor that handles AccessRequest and PaymentProof messages.
  4. Builds the agent card — generates an A2A-compliant discovery card from SellerConfig.
  5. Creates the request handler — returns a DefaultRequestHandler (from @a2a-js/sdk) bound to the agent card and executor.

Usage

import {
  createKey0,
  X402Adapter,
  RedisChallengeStore,
  RedisSeenTxStore,
} from "@key0ai/key0";

const { engine, agentCard, requestHandler, executor } = createKey0({
  config: sellerConfig,
  adapter: new X402Adapter({ network: "testnet" }),
  store: new RedisChallengeStore({ redis }),
  seenTxStore: new RedisSeenTxStore({ redis }),
});

When to use createKey0() directly

Most developers should use framework adapters instead of calling createKey0() directly:
  • Expresskey0Router() from @key0ai/key0/express
  • Honokey0App() from @key0ai/key0/hono
  • Fastifykey0Plugin() from @key0ai/key0/fastify
These adapters call createKey0() internally, mount the challenge and proof endpoints, and export validateAccessToken middleware for protecting routes. Use createKey0() directly when you need:
  • Access to the engine for custom challenge lifecycle management
  • Access to the executor for a non-standard A2A integration
  • Full control over how endpoints are mounted in your application