Incantory
Sign in
RulesCC0-1.0Not scanned

Hol Hedera Typescript

Cursor rules for Hashgraph Online development with TypeScript, building AI agents on Hedera with RegistryBrokerClient.

Awesome CursorRulesv10 stars · 0 forks · 0 makes≈1.8K tokens

Hashgraph Online (HOL) Development Rules

You are an expert TypeScript developer building applications with Hashgraph Online (HOL) - the open-source SDK for AI agents and decentralized applications on Hedera.

Technology Stack

Core:

  • Language: TypeScript (strict mode)
  • Runtime: Node.js 20+
  • Package Manager: pnpm
  • Testing: Jest with @swc/jest

HOL SDK:

  • @hashgraphonline/standards-sdk - Core SDK for HCS standards and Registry Broker
  • @hol-org/hashnet-mcp - MCP server for AI agent integration

Frontend (when applicable):

  • Framework: Next.js 14+ (App Router)
  • UI: shadcn/ui + Tailwind CSS
  • Icons: react-icons (Lucide preferred)

Coding Standards

TypeScript Requirements

  • NEVER use any - define proper interfaces
  • NEVER use as any casting - use type guards
  • ALWAYS define explicit return types
  • ALWAYS use generics for flexible code
  • Validate external data with type guards or zod

File Naming

  • Use kebab-case: registry-client.ts, topic-manager.ts
  • Test files: __tests__/registry-client.test.ts
  • Components: registry-browser.tsx

Code Style

  • Max 500 lines per file - split larger files
  • No nested ternaries
  • No inline comments - use JSDoc only
  • No console.log - use Logger from standards-sdk
  • Prettier formatting required

React Patterns (when applicable)

  • NO render functions like renderContent()
  • NO inline callbacks in JSX
  • NO hooks in loops/conditionals
  • ALWAYS use separate child components
  • ALWAYS define Props interfaces

HOL SDK Usage

RegistryBrokerClient - Initialization

import { RegistryBrokerClient } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient({
  baseUrl: 'https://api.hol.org',
  apiKey: process.env.HOL_API_KEY,
});

RegistryBrokerClient - Search Agents

import { RegistryBrokerClient, SearchParams, Logger } from '@hashgraphonline/standards-sdk';

const logger = new Logger({ module: 'AgentSearch', level: 'info' });
const client = new RegistryBrokerClient();

const searchParams: SearchParams = {
  q: 'weather',
  registry: 'hcs-10',
  limit: 10,
  page: 1,
};

const results = await client.search(searchParams);
logger.info('Search completed', { total: results.total });
results.hits.forEach(agent => {
  logger.debug('Agent found', { name: agent.name, description: agent.description });
});

RegistryBrokerClient - Resolve Agent (UAID)

import { RegistryBrokerClient, Logger } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient();
const logger = new Logger({ module: 'AgentResolver', level: 'info' });

const agent = await client.resolveUaid('hcs10://0.0.123456/agent-name');
logger.info('Agent resolved', { 
  name: agent.name, 
  protocols: agent.protocols, 
  capabilities: agent.capabilities 
});

RegistryBrokerClient - Register Agent

import { RegistryBrokerClient, AgentRegistrationRequest, Logger } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient();
const logger = new Logger({ module: 'AgentRegistration', level: 'info' });

const registration: AgentRegistrationRequest = {
  name: 'My Agent',
  description: 'A helpful AI agent',
  protocols: ['hcs-10'],
  capabilities: ['chat', 'search'],
  endpoint: 'https://my-agent.example.com',
};

const response = await client.registerAgent(registration, {
  autoTopUp: {
    accountId: process.env.HEDERA_OPERATOR_ID!,
    privateKey: process.env.HEDERA_OPERATOR_KEY!,
  },
});

if (response.success) {
  logger.info('Agent registered', { uaid: response.uaid });
}

RegistryBrokerClient - Chat with Agent

import { RegistryBrokerClient, StartChatOptions, Logger } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient();
const logger = new Logger({ module: 'AgentChat', level: 'info' });

const options: StartChatOptions = {
  uaid: 'hcs10://0.0.123456/agent-name',
  auth: {
    accountId: process.env.HEDERA_OPERATOR_ID!,
    privateKey: process.env.HEDERA_OPERATOR_KEY!,
  },
};

const conversation = await client.chat.start(options);

const response = await conversation.send({
  plaintext: 'Hello, can you help me?',
});

logger.info('Agent response received', { sessionId: conversation.sessionId });

RegistryBrokerClient - Get Stats

import { RegistryBrokerClient, Logger } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient();
const logger = new Logger({ module: 'RegistryStats', level: 'info' });

const stats = await client.stats();
logger.info('Registry stats', { totalAgents: stats.totalAgents, protocols: stats.protocols });

const registries = await client.registries();
registries.forEach(r => logger.debug('Registry', { name: r.name }));

RegistryBrokerClient - Vector Search

import { RegistryBrokerClient, VectorSearchRequest, Logger } from '@hashgraphonline/standards-sdk';

const client = new RegistryBrokerClient();
const logger = new Logger({ module: 'VectorSearch', level: 'info' });

const request: VectorSearchRequest = {
  query: 'find me an agent that can help with weather forecasts',
  limit: 5,
  filter: {
    registry: 'hcs-10',
    protocols: ['a2a'],
  },
};

const results = await client.vectorSearch(request);
results.hits.forEach(hit => {
  logger.info('Match found', { name: hit.agent.name, score: hit.score });
});

Testing Requirements

TDD Workflow

  1. RED: Write failing tests first
  2. GREEN: Implement minimum code to pass
  3. REFACTOR: Improve while keeping tests green

Test Structure

describe('RegistryBrokerClient', () => {
  let client: RegistryBrokerClient;

  beforeEach(() => {
    client = new RegistryBrokerClient();
  });

  describe('search', () => {
    it('should return agents matching query', async () => {
      const result = await client.search({ q: 'test' });
      
      expect(result.hits).toBeDefined();
      expect(Array.isArray(result.hits)).toBe(true);
    });
  });

  describe('resolveUaid', () => {
    it('should resolve valid UAID', async () => {
      const agent = await client.resolveUaid('hcs10://0.0.123456/test');
      
      expect(agent.name).toBeDefined();
    });
  });
});

Test Commands

pnpm test                    # Run all tests
pnpm test -- --watch         # Watch mode
pnpm test -- --coverage      # Coverage report
pnpm test -- -t "pattern"    # Run specific tests

Validation Checklist

Before completing any task:

  1. pnpm run lint - Zero violations
  2. pnpm run typecheck - Zero errors
  3. pnpm run build - Must compile
  4. pnpm test - All tests pass

Environment Configuration

import 'dotenv/config';

const config = {
  baseUrl: process.env.HOL_API_URL || 'https://api.hol.org',
  apiKey: process.env.HOL_API_KEY,
  network: process.env.HEDERA_NETWORK || 'testnet',
  operatorId: process.env.HEDERA_OPERATOR_ID,
  operatorKey: process.env.HEDERA_OPERATOR_KEY,
};

Resources