kog-fee-gate-tests / tree / src/harness.ts ยท raw (this view has old GitHub links rewritten for the mirror; raw is byte-exact)
/**
 * The LAX registry handler harness, kit version 1: the registry's own request handler (registry/, copied unchanged
 * from Kognai's registry 0.10.0), in memory stores, a mocked x402 facilitator for the USDC listing payment, and the
 * KOG fee gate in front of POST /offers and POST /jobs/<id>/bids. No network, no database, no key of Kognai's.
 *
 *   const h = createHarness();
 *   const res = await h.handle(h.offerRequest({ agent: h.agents[0] }));   // 402 with a KOG quote
 */
import { randomBytes } from 'node:crypto';
import { verifyMessage } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { canonicalJson, createHandler, PAY_TO, sha256Hex } from '../registry/handler.ts';
import { bidMessage } from '../registry/bids.ts';
import type { Job } from '../registry/jobs.ts';
import { checkPayment, KOG_FEES, KOG_MINT, KOG_PAYEE, kogFeeGate, usedFees, type GatedRoute, type KogPayment, type KogQuote, type UsedFees, type Verify } from './kog-fee.ts';
import { memoryStores, type MemoryStores } from './memory-store.ts';

export const HARNESS_VERSION = 1;
export const BASE = 'https://lax.test/registry';
export const START = Date.parse('2026-10-22T12:00:00.000Z');
/** The well known public test keys of local Ethereum dev chains (anvil accounts 1 to 3): never funded. */
const TEST_KEYS = [
  '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',
  '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',
  '0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6',
] as const;
const B58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const base58 = (bytes: Uint8Array) => { let n = BigInt('0x' + Buffer.from(bytes).toString('hex')); let s = ''; while (n > 0n) { s = B58[Number(n % 58n)] + s; n /= 58n; } return s || '1'; };

export interface Agent { name: string; address: string; did: string; solana: string; signMessage(p: { message: string }): Promise<string> }
export interface HarnessOptions {
  /** the clock start, milliseconds since the epoch (2026-10-22T12:00:00Z by default) */
  now?: number;
  /** the payment check of the gate (default checkPayment); production uses verifyKogFee over the parsed transaction */
  verify?: Verify;
  /** where spent fees are kept (default in memory) */
  used?: UsedFees;
  /** the gated routes (default both) */
  gated?: GatedRoute[];
}
export interface Harness {
  version: number; base: string;
  /** the registry behind the KOG fee gate */
  handle(req: Request): Promise<Response>;
  /** the clock: set clock.now to move time */
  clock: { now: number };
  kog: { mint: string; payee: string; fees: { offer: string; bid: string }; decimals: number };
  stores: MemoryStores; chain: Map<string, KogPayment>; quotes: Map<string, KogQuote>; used: UsedFees;
  /** three test agents (public test keys) */
  agents: Agent[];
  /** a valid LAX offer for an agent */
  offer(agent: Agent, over?: Record<string, unknown>): Record<string, unknown>;
  /** POST /offers with a valid offer and a valid USDC listing payment; KOG headers only when given */
  offerRequest(o: { agent: Agent; body?: unknown; quote?: KogQuote | string; fee?: string }): Request;
  /** an open tender (a job with a bid window), straight into the store; returns its id */
  seedJob(over?: Partial<Job>): string;
  /** a listed outside offer for an agent, straight into the store (no fee); returns its id */
  seedListing(agent: Agent): string;
  /** POST /jobs/<id>/bids signed by the listing owner; KOG headers only when given */
  bidRequest(o: { agent: Agent; jobId: string; offerId: string; body?: Record<string, unknown>; quote?: KogQuote | string; fee?: string }): Promise<Request>;
  /** pays in KOG on the harness chain and returns the transaction signature (amount: the quote's by default) */
  payKog(o: { quote: KogQuote; amount?: string; mint?: string; payee?: string; from?: Agent; at?: number; ok?: boolean }): string;
  /** the quote of a 402 answer */
  quoteOf(res: Response): Promise<KogQuote>;
}

export function createHarness(opts: HarnessOptions = {}): Harness {
  const clock = { now: opts.now ?? START };
  const now = () => clock.now;
  let n = 0; const id = () => `t${++n}`;
  const stores = memoryStores(now);
  // the x402 facilitator of the USDC listing payment, mocked: it accepts every well formed payment
  const facilitator = (async (url: string) => {
    const path = new URL(String(url)).pathname;
    if (path === '/verify') return Response.json({ isValid: true });
    if (path === '/settle') return Response.json({ success: true, transaction: '0x' + 'ab'.repeat(32), network: 'base' });
    return new Response('not found', { status: 404 });
  }) as unknown as typeof fetch;
  const noAiax = (async () => new Response('not found', { status: 404 })) as unknown as typeof fetch;
  const inner = createHandler({
    store: stores.store, fetch: facilitator, aiaxFetch: noAiax, now, randomId: () => `lax-${id()}`, rpcUrl: 'https://rpc.invalid',
    jobs: { store: stores.jobStore, adminAddress: null, bids: stores.bidStore, pact: stores.pactStore },
    verifyMessage: ({ address, message, signature }) => verifyMessage({ address: address as `0x${string}`, message, signature: signature as `0x${string}` }),
  });
  const chain = new Map<string, KogPayment>(); const quotes = new Map<string, KogQuote>(); const used = opts.used || usedFees();
  const handle = kogFeeGate(inner, { now, newId: id, chain, quotes, used, verify: opts.verify || checkPayment, gated: opts.gated || ['offers', 'bids'], fees: { ...KOG_FEES }, mint: KOG_MINT, payee: KOG_PAYEE });

  const agents: Agent[] = TEST_KEYS.map((k, i) => {
    const a = privateKeyToAccount(k); const name = `agent-${'abc'[i]}`;
    return { name, address: a.address, did: `did:web:${name}.example`, solana: base58(new Uint8Array(32).fill(i + 7)), signMessage: (p) => a.signMessage(p) };
  });
  const offer = (agent: Agent, over: Record<string, unknown> = {}) => ({
    lax_version: '1.0', name: `Test ${agent.name}`, description: 'A test agent that translates short documents and answers in plain words.', category: 'Testing',
    agent_did: agent.did, capabilities: [{ skill_id: 'translate', description: 'Translate up to 2000 words', pricing: { model: 'per_call', amount: '0.05', currency: 'USDC', rail: 'x402' } }],
    constitutional_constraints: ['Solidarity Oath', 'Renewal Mandate', 'Treasury Equilibrium', 'Harm Shield', 'Transparency Covenant'],
    endpoint: `https://${agent.name}.example/api`, payment_rails: ['x402'], ...over,
  });
  const usdcPayment = (agent: Agent) => Buffer.from(JSON.stringify({ x402Version: 1, scheme: 'exact', network: 'base', payload: {
    signature: '0x' + 'ab'.repeat(65),
    authorization: { from: agent.address, to: PAY_TO, value: '10000', validAfter: '0', validBefore: String(Math.floor(now() / 1000) + 600), nonce: '0x' + randomBytes(32).toString('hex') },
  } })).toString('base64');
  const kogHeaders = (quote?: KogQuote | string, fee?: string): Record<string, string> => ({
    ...(quote ? { 'x-kog-quote': typeof quote === 'string' ? quote : quote.quote_id } : {}), ...(fee ? { 'x-kog-fee': fee } : {}),
  });

  return {
    version: HARNESS_VERSION, base: BASE, handle, clock, kog: { mint: KOG_MINT, payee: KOG_PAYEE, fees: { ...KOG_FEES }, decimals: 6 }, stores, chain, quotes, used, agents,
    offer,
    offerRequest: ({ agent, body, quote, fee }) => new Request(`${BASE}/offers`, { method: 'POST', headers: { 'content-type': 'application/json', 'x-payment': usdcPayment(agent), ...kogHeaders(quote, fee) }, body: JSON.stringify(body ?? offer(agent)) }),
    seedJob: (over = {}) => {
      const jid = `job-${id()}`; const iso = (ms: number) => new Date(ms).toISOString();
      stores.jobStore.jobs.set(jid, { id: jid, title: 'Test tender', track: 'seat', summary: 'A test tender with a bid window, for the harness.', spec_md: 'Build a test module with tests for every acceptance item.', skills: ['typescript'],
        bounty_usdc: 60, currency: 'USDC', chain: 'base', deadline: iso(now() + 14 * 86400_000), status: 'open', created_by: '0x' + '0'.repeat(40), created_at: iso(now()), bid_closes: iso(now() + 2 * 86400_000), ...over } as Job);
      return jid;
    },
    seedListing: (agent) => {
      const oid = `lax-ext-${id()}`;
      stores.store.agents.set(oid, { id: oid, name: `Test ${agent.name}`, slug: oid, listed: true, origin: 'outside', verified: false, owner_address: agent.address, agent_did: agent.did, offer: offer(agent) as any, created_at: new Date(now()).toISOString() });
      return oid;
    },
    bidRequest: async ({ agent, jobId, offerId, body, quote, fee }) => {
      const b = body ?? { offer_id: offerId, price_usdc: 50, delivery_by: new Date(now() + 5 * 86400_000).toISOString(), approach_md: 'A TypeScript module with node:test tests for every acceptance item, delivered at an exact commit.', settlement: { chain: 'base', payee: agent.address } };
      const path = `/jobs/${jobId}/bids`; const time = new Date(now()).toISOString();
      const signature = await agent.signMessage({ message: bidMessage('POST', path, time, await sha256Hex(canonicalJson(b))) });
      return new Request(BASE + path, { method: 'POST', headers: { 'content-type': 'application/json', 'x-lax-signature': signature, 'x-lax-time': time, ...kogHeaders(quote, fee) }, body: JSON.stringify(b) });
    },
    payKog: ({ quote, amount, mint, payee, from, at, ok }) => {
      const signature = base58(randomBytes(64));
      chain.set(signature, { signature, mint: mint ?? quote.mint, payee: payee ?? quote.payee, amount: amount ?? quote.amount, from: (from || agents[0]).solana, block_time: new Date(at ?? now()).toISOString(), ok: ok ?? true });
      return signature;
    },
    quoteOf: async (res) => { const j: any = await res.clone().json(); if (!j?.kog_fee?.quote_id) throw new Error(`no KOG quote in this answer (${res.status})`); return j.kog_fee as KogQuote; },
  };
}

agentgate-source: code mirror on Cloudflare Pages. All repos