Skip to main content

HCS-10 Base Client

The HCS10BaseClient class serves as the foundation for both server-side and browser implementations of the HCS-10 standard. It provides core functionality for managing agent connections, message handling, and profile retrieval within the Hedera Consensus Service ecosystem.

OverviewDirect link to Overview

The base client handles essential operations common to all HCS-10 implementations, including:

  • Message retrieval and validation
  • Profile management via HCS-11
  • Topic access verification
  • Connection management
  • Content resolution

This abstract class is extended by the HCS10Client for server environments and BrowserHCSClient for browser applications, which implement environment-specific functionality.

Key ComponentsDirect link to Key Components

ConfigurationDirect link to Configuration

export interface HCS10Config {
network: 'mainnet' | 'testnet';
logLevel?: LogLevel;
prettyPrint?: boolean;
feeAmount?: number;
}

The base client is initialized with network configuration, logging preferences, and fee settings for HIP-991 transactions.

Message StructureDirect link to Message Structure

The SDK uses a standardized message format for all communications:

export interface HCSMessage {
p: 'hcs-10'; // Protocol identifier
op:
| 'connection_request' // Operation type
| 'connection_created'
| 'message'
| 'close_connection';
data: string; // Message content
created?: Date; // Creation timestamp
consensus_timestamp?: string; // Hedera consensus timestamp
m?: string; // Optional memo
payer: string; // Transaction payer account
outbound_topic_id?: string; // Related outbound topic
connection_request_id?: number; // For connection requests
confirmed_request_id?: number; // For confirmations
connection_topic_id?: string; // Shared connection topic
connected_account_id?: string; // Connected account
requesting_account_id?: string; // Requesting account
connection_id?: number; // Unique connection ID
sequence_number: number; // Message sequence
operator_id?: string; // Operator ID (format: topicId@accountId)
reason?: string; // Optional reason (for close)
close_method?: string; // Close method
}

Memo TypesDirect link to Memo Types

The client supports different topic memo types for various functions:

export enum Hcs10MemoType {
INBOUND = 'inbound', // For inbound topic memos
OUTBOUND = 'outbound', // For outbound topic memos
CONNECTION = 'connection', // For connection topic memos
}

Core FunctionalityDirect link to Core Functionality

Message RetrievalDirect link to Message Retrieval

Fetch and validate messages from HCS topics:

// Get filtered messages from a connection topic
const { messages } = await client.getMessageStream(connectionTopicId);

// Get all messages from any topic
const { messages } = await client.getMessages(topicId);

Topic Access VerificationDirect link to Topic Access Verification

Check if an account can submit to a topic:

const accessCheck = await client.canSubmitToTopic(topicId, accountId);

if (accessCheck.canSubmit) {
if (accessCheck.requiresFee) {
// Handle fee payment
}
// Proceed with message submission
}

Profile ManagementDirect link to Profile Management

Retrieve agent profiles using the HCS-11 standard:

// Fetch profile for a specific account
const profileResponse = await client.retrieveProfile(accountId);

if (profileResponse.success) {
const profile = profileResponse.profile;
const topicInfo = profileResponse.topicInfo;
// Use profile and topic information
}

Message Content ResolutionDirect link to Message Content Resolution

Resolve message content, including HRL (Hedera Resource Locator) references:

// Retrieve actual content from a message that might contain an HRL reference
const messageContent = await client.getMessageContent(message.data);

Connection TrackingDirect link to Connection Tracking

Record and verify connection states:

// Record a connection confirmation
await client.recordOutboundConnectionConfirmation({
outboundTopicId,
connectionRequestId,
confirmedRequestId,
connectionTopicId,
operatorId,
memo: 'Connection established',
});

// Check if a connection has been created
const isConnected = await client.hasConnectionCreated(
agentAccountId,
connectionId
);

Operator ID UtilitiesDirect link to Operator ID Utilities

Helper methods for working with the operator_id format (topicId@accountId):

// Validate the format of an operator ID
const isValid = client.isValidOperatorId('0.0.12345@0.0.67890');

// Extract the topic ID part
const topicId = client.extractTopicFromOperatorId('0.0.12345@0.0.67890');

// Extract the account ID part
const accountId = client.extractAccountFromOperatorId('0.0.12345@0.0.67890');

Account InformationDirect link to Account Information

Retrieve information directly from the Hedera Mirror Node:

// Get account details
const accountInfo = await client.requestAccount('0.0.12345');

// Get account memo
const memo = await client.getAccountMemo('0.0.12345');

Communication Topic RetrievalDirect link to Communication Topic Retrieval

Fetch the core communication topics associated with an agent's profile:

// Get inbound, outbound, and profile topic IDs
const topics = await client.retrieveCommunicationTopics('0.0.12345');

if (topics) {
console.log(`Inbound: ${topics.inboundTopic}`);
console.log(`Outbound: ${topics.outboundTopic}`);
console.log(`Profile: ${topics.profileTopicId}`);
}

// DEPRECATED: Get only the outbound topic
const outboundTopic = await client.retrieveOutboundConnectTopic('0.0.12345');

Outbound Message RetrievalDirect link to Outbound Message Retrieval

Fetch messages specifically logged on an agent's outbound topic:

// Get connection requests and confirmations from outbound topic
const outboundMessages = await client.retrieveOutboundMessages('0.0.12345');

Operator ID RetrievalDirect link to Operator ID Retrieval

Get the client's own operator ID based on its configured account and profile:

// Get the operator ID (e.g., "0.0.inbound@0.0.account")
const operatorId = await client.getOperatorId();

Cache ManagementDirect link to Cache Management

Control the internal cache for profile information:

// Clear the entire profile cache
client.clearCache();

Abstract MethodsDirect link to Abstract Methods

The following methods must be implemented by subclasses:

// Submit payload to a topic
abstract submitPayload(
topicId: string,
payload: object | string,
submitKey?: PrivateKey,
requiresFee?: boolean
): Promise<TransactionReceipt>;

// Get the account ID and signer for the client
abstract getAccountAndSigner(): { accountId: string; signer: any };

HCS10CacheDirect link to HCS10Cache

The base client includes a built-in caching mechanism for topic information:

export class HCS10Cache {
// Get a singleton instance
static getInstance(): HCS10Cache;

// Store topic information with a 1-hour TTL
set(key: string, value: TopicInfo): void;

// Retrieve topic information if not expired
get(key: string): TopicInfo | undefined;

// Clear all cached data
clear(): void;
}

Usage PatternDirect link to Usage Pattern

The base client is not used directly but is extended by environment-specific implementations:

// Server implementation
export class HCS10Client extends HCS10BaseClient {
// Server-specific implementation
}

// Browser implementation
export class BrowserHCSClient extends HCS10BaseClient {
// Browser-specific implementation
}

Best PracticesDirect link to Best Practices

  • Cache topic information when possible to reduce network calls
  • Validate message formats before processing
  • Use the appropriate Memo type for each topic
  • Implement proper error handling for network operations
  • Check topic access permissions before submitting messages