@lucid/client — API + A2A Hub Client
npm install @lucid-dreams/client@lucid/client — API + A2A Hub Client
Overview
- Typed helpers and schemas for the server API.
- Thin A2A hub client to interoperate with registered agents by agentRef.
A2A Hub Client
- Import: import { A2AHubClient } from '@lucid/client'.
- Construct with your API base URL and optional headers or API key.
Using x402-fetch for payments
- Install: x402-fetch
- Example:
import { createSigner, wrapFetchWithPayment } from 'x402-fetch';
const signer = await createSigner('base-sepolia', process.env.PRIVATE_KEY!);
const paidFetch = wrapFetchWithPayment(fetch, signer);
const client = new A2AHubClient('http://localhost:8787', { fetch: paidFetch });
// Headers added by x402-fetch are forwarded by the hub to target agents
Paid client helper
- Import: import { createPaidA2AHubClient } from '@lucid/client'.
- Example:
const client = await createPaidA2AHubClient({
hubUrl: 'http://localhost:8787',
privateKey: process.env.PRIVATE_KEY!,
network: process.env.PAYMENT_NETWORK || process.env.NETWORK || 'base-sepolia',
});
// Same API as A2AHubClient
await client.sendMessage({ agentRef: 'echo-agent', skillId: 'echo', input: { text: 'hi' } });
Examples
- Get agent card:
const client = new A2AHubClient('http://localhost:8787', { apiKey: process.env.API_KEY });
const card = await client.getCard('echo-agent');
- Send a non-streaming task:
const task = await client.sendMessage({ agentRef: 'echo-agent', skillId: 'echo', input: { text: 'hello' } });
// task.kind === 'task'; task.status.state in ['completed','failed','unknown']
- Stream a task:
const ac = new AbortController();
try {
for await (const evt of client.sendMessageStream({ agentRef: 'echo-agent', skillId: 'echo', input: { text: 'stream me' }, signal: ac.signal })) {
if (evt.kind === 'task') console.log('task opened', evt.id);
else if (evt.kind === 'status-update') console.log('status', evt.status.state, evt.status.message?.parts?.[0]?.text);
}
} finally {
ac.abort();
}
Notes
- skillId is optional if the agent only advertises a single entrypoint.
- Streaming yields a task first, then status-update events until a final update (final: true).
- Errors in the stream are thrown by the iterator; wrap in try/catch.
- Payments (x402): pass your x-402-* headers via the client constructor, e.g. new A2AHubClient(url, { headers: { 'x-402-token': '...', 'x-402-signature': '...' } }). The hub forwards these to the target agent.
Node paid demo
- A runnable script is included at apps/examples/a2a/paid-demo.ts that:
- Fetches an agent card via the hub
- Sends an A2A RPC task (non-stream)
- Invokes and streams via direct hub endpoints with x402 payments (headers auto-managed by x402-fetch)
Run (Bun):
```
HUB_URL=http://localhost:8787 \
AGENT_REF=echo-agent \
SKILL_ID=echo \
NETWORK=base-sepolia \
PRIVATE_KEY=0x... \
bun run apps/examples/a2a/paid-demo.ts
Notes:
- For paid flows, ensure the target agent is configured with x402 (payee address, network, facilitator).
- The demo prints x-payment-response` when present; 402 challenges are handled by x402-fetch when using the direct endpoints.