Registry Broker Client
The Registry Broker client in @hashgraphonline/standards-sdk provides a typed, batteries-included wrapper around the Hashgraph Online Registry Broker. It covers discovery, registration, chat relay, UAID utilities, metrics, and protocol detection in a single interface with rich Zod-backed response validation.
Getting Started
Installation
pnpm
1pnpm add @hashgraphonline/standards-sdk
Credentials & Credits
The production broker is pay-as-you-go. Before invoking any authenticated endpoints you must top up credits for your account at https://hol.org/registry/billing. Without credits, registration, chat relays, UAID utilities, and other metered APIs will fail with 402 responses.
Keyword and vector search remain credit-free but they are governed by a shared rate limiter.
Once credits are loaded you can generate an API key (or use session tokens) and create a client:
💡 The Registry Broker production API is available at
https://hol.org/registry/api/v1. OverridebaseUrlonly if you’ve been provisioned a private deployment.
Creating a client
client.ts
1import { RegistryBrokerClient } from '@hashgraphonline/standards-sdk';23const client = new RegistryBrokerClient({4// Optional: override the default https://hol.org/registry/api/v15baseUrl: process.env.REGISTRY_BROKER_API_URL,6// Optional: supply an API key issued by your Registry Broker instance7apiKey: process.env.REGISTRY_BROKER_API_KEY,8});
baseUrl– defaults to the production broker (https://hol.org/registry/api/v1). Trailing slashes and missing/api/v1segments are normalized automatically.apiKey– when provided, the client sets anx-api-keyheader on every request. You can update it later withclient.setApiKey(newKey).defaultHeaders– useclient.setDefaultHeader(name, value)to add or remove headers after instantiation (values are trimmed; falsy values remove the header).fetchImplementation– pass a custom fetch (for Cloudflare Workers, Node polyfills, testing, etc.).
Quickstart: OpenRouter chat relay
openrouter-chat.ts
1import { RegistryBrokerClient } from '@hashgraphonline/standards-sdk';23const client = new RegistryBrokerClient({4baseUrl: 'https://hol.org/registry/api/v1',5apiKey: process.env.REGISTRY_BROKER_API_KEY,6});78const session = await client.chat.createSession({9uaid: 'uaid:aid:2bnewJwP95isoCUkT5mee5gm212WS76tphHwBQvbWoquRa9kt89UanrBqHXpaSh4AN;uid=anthropic/claude-3.5-sonnet;registry=openrouter;proto=openrouter;nativeId=anthropic/claude-3.5-sonnet',10});1112const reply = await client.chat.sendMessage({13sessionId: session.sessionId,14message: 'Give me a one-line summary of your pricing.',15});1617console.log(reply.message);
For the hosted Registry Broker, the OpenRouter adapter is configured with its own API key and uses your credit balance, so you do not need to pass an OpenRouter token from the client for standard flows. You only need the auth block for custom deployments or when you explicitly proxy end‑user credentials through the broker.
Architecture Overview
The SDK mediates every request, ensuring headers and schemas are applied consistently.
✅ Free discovery: keyword search, vector search, adapter catalog, and public stats are available to everyone without credits or authentication (subject to the rate limit described above).
Use the billing portal only when you need metered functionality such as agent registration, chat relay, UAID inscription, or history compaction. These endpoints require an active credit balance; otherwise the broker returns 402 responses.
Searching the Registry
Keyword Search
1import type { SearchResult } from '@hashgraphonline/standards-sdk';23const result: SearchResult = await client.search({4q: 'custody agent',5registry: 'hashgraph-online',6capabilities: ['messaging'],7minTrust: 70,8page: 1,9limit: 25,10});1112console.log(`Found ${result.total} agents`);13for (const hit of result.hits) {14console.log(hit.name, hit.registry, hit.capabilities);15}
SearchParams supports q, page, limit, registry, minTrust, and capability filtering (capabilities can be AIAgentCapability enum values or arbitrary strings).
⚠️ Vector search obeys the broker’s rate limiter. Each response includes
x-rate-limit-limitandx-rate-limit-remainingheaders plusRetry-Afteron 429s. Provide an API key to move the limiter from a shared IP bucket to a per-key bucket.
Discovery Insights
Registries
1const registries = await client.registries(); // { registries: string[] }2const popular = await client.popularSearches(); // { searches: string[] }
These responses are strongly typed and validated, making them safe to expose in dashboards without additional schema definitions.
Working With UAIDs
uaid.ts
1const resolved = await client.resolveUaid('uaid:aid:123...');2console.log(resolved.agent.name);34const validation = await client.validateUaid('uaid:aid:123...');5console.log(validation.valid, validation.formats);67const status = await client.getUaidConnectionStatus('uaid:aid:123...');8if (!status.connected) {9console.log('Agent offline');10}1112await client.closeUaidConnection('uaid:aid:123...');
Each method returns the appropriate schema-backed response (UaidValidationResponse, UaidConnectionStatus).
Chat Sessions
Basic Chat
1const session = await client.chat.createSession({ uaid: 'uaid:aid:123...' });23const reply = await client.chat.sendMessage({4sessionId: session.sessionId,5message: 'Hello from the SDK!',6streaming: false,7});89console.log(reply.content);1011await client.chat.endSession(session.sessionId);
You can also seed the chat by agent URL instead of UAID ({ agentUrl: 'https://...' }) when talking to local or unregistered endpoints. The streaming flag is passed through to the broker; if the backend supports streaming, you can adapt the response accordingly.
Passing downstream auth (paid OpenRouter models)
AgentAuthConfig supports four schemes:
type | Fields used | Example |
|---|---|---|
bearer | token | { type: 'bearer', token: 'sk-or-...' } |
basic | username, password | { type: 'basic', username, password } |
apiKey | headerName, headerValue | { type: 'apiKey', headerName: 'x-api-key', headerValue: '...' } |
header | headerName, headerValue, optional headers map | Use for bespoke header names or multi-header payloads |
Cross-protocol chat playbook
The Standards SDK ships end-to-end demos that bridge Registry Broker chat to both AgentVerse mailbox/proxy agents and ERC-8004 HTTP agents:
standards-sdk/demo/registry-broker-agentverse-demo.tsstandards-sdk/demo/registry-broker-erc8004-demo.ts
Chat history and compaction
The history demo (standards-sdk/demo/registry-broker-history-demo.ts) illustrates how to persist, audit, and eventually compact chat transcripts.
Agent Registration
Simple Register
1import type { HCS11Profile } from '@hashgraphonline/standards-sdk';23const profile: HCS11Profile = {4version: '1.0.0',5type: 1,6display_name: 'Ledger Guard',7bio: 'Monitoring transactions for anomalies',8aiAgent: {9 type: 'openai',10 model: 'gpt-4o-mini',11 capabilities: ['monitoring', 'compliance'],12},13};1415const registration = await client.registerAgent({16profile,17registry: 'hashgraph-online',18protocol: 'aid',19endpoint: 'https://ledger-guard.example.com',20metadata: {21 trustScore: 92,22 uptime: 99.95,23},24});2526console.log(registration.uaid, registration.agent.nativeId);
Handling asynchronous responses & progress tracking
When a registration includes additional registries (for example ERC-8004) the broker returns 202 Accepted with a status: "pending" payload. The primary Hashgraph inscription is committed immediately, while downstream registrars are processed in the background via a work queue.
All progress tracking endpoints are protected by account ownership checks.
Protocol Discovery
Detect Protocol
1const protocols = await client.listProtocols(); // { protocols: string[] }23const detected = await client.detectProtocol({4message: {5 headers: { 'content-type': 'application/json' },6 body: '{"hello":"world"}',7},8});910console.log(detected.protocol); // e.g. "aid"
Example: Discover and Chat
discover-chat.ts
1const client = new RegistryBrokerClient({ apiKey: process.env.RB_API_KEY });23// 1. Find high-trust audit agents4const auditAgents = await client.search({ q: 'audit', minTrust: 80, limit: 5 });56// 2. Ask the top result a question7const topAgent = auditAgents.hits[0];8const session = await client.chat.createSession({ uaid: topAgent.uaid });9await client.chat.sendMessage({ sessionId: session.sessionId, message: 'Summarize your capabilities.' });