HCS‑17 API Reference
Complete, literal reference for the HCS‑17 module in @hashgraphonline/standards-sdk. For conceptual guidance and flows, see the HCS‑17 SDK guide and standard.
Sources
- Module folder: GitHub
- types.ts: GitHub
- base-client.ts: GitHub
- sdk.ts: GitHub
- browser.ts: GitHub
- tx.ts: GitHub
Import PathsDirect link to Import Paths
- TypeScript
- Go
// Barrel export
import {
HCS17Client,
HCS17BrowserClient,
HCS17TopicType,
generateHCS17Memo,
parseHCS17Memo,
buildHcs17CreateTopicTx,
buildHcs17MessageTx,
type StateHashMessage,
type AccountStateInput,
type CompositeStateInput,
type StateHashResult,
type CompositeStateHashResult,
type HCS17ClientConfig,
type SDKHCS17ClientConfig,
type BrowserHCS17ClientConfig,
} from '@hashgraphonline/standards-sdk';
// Direct path (optional)
import * as HCS17 from '@hashgraphonline/standards-sdk';
NewClient(config ClientConfig) (*Client, error)
Client.CreateStateTopic(ctx, ...)
Client.SubmitMessage(ctx, ...)
Client.ComputeAndPublish(ctx, ...)
Client.ValidateTopic(ctx, topicID string) (bool, *TopicMemo, error)
Client.GetRecentMessages / GetLatestMessage
Client.CalculateAccountStateHash(AccountStateInput) (StateHashResult, error)
Client.CalculateCompositeStateHash(CompositeStateInput) (CompositeStateHashResult, error)
BuildCreateStateTopicTx(CreateTopicOptions) *hedera.TopicCreateTransaction
BuildStateHashMessageTx(topicID string, StateHashMessage, txMemo string) (*hedera.TopicMessageSubmitTransaction, error)
Topic MemoDirect link to Topic Memo
- Format:
hcs-17:<type>:<ttl>where<type>is numeric and<ttl>is a positive integer (seconds). - Enum:
HCS17TopicType.STATE = 0.
Helpers:
- TypeScript
- Go
function generateHCS17Memo(ttl: number): string;
function parseHCS17Memo(memo: string): { type: HCS17TopicType; ttl: number } | undefined;
// See standards-sdk-go for full Go API types and methods
TypesDirect link to Types
- TypeScript
- Go
type TopicState = { topicId: string; latestRunningHash: string };
interface AccountStateInput {
accountId: string;
publicKey: import('@hashgraph/sdk').PublicKey | string;
topics: TopicState[];
}
interface CompositeStateInput {
compositeAccountId: string;
compositePublicKeyFingerprint: string; // deterministic fingerprint of threshold key
memberStates: Array<{ accountId: string; stateHash: string }>;
compositeTopics: TopicState[];
}
interface StateHashMessage {
p: 'hcs-17';
op: 'state_hash';
state_hash: string;
topics: string[];
account_id: string;
timestamp?: string; // ISO8601
m?: string; // optional application memo
}
interface StateHashResult {
stateHash: string;
accountId: string;
timestamp: Date;
topicCount: number;
}
interface CompositeStateHashResult extends StateHashResult {
memberCount: number;
compositeTopicCount: number;
}
interface HCS17ClientConfig {
network: 'mainnet' | 'testnet';
logLevel?: 'debug' | 'info' | 'warn' | 'error';
silent?: boolean;
mirrorNodeUrl?: string; // override
logger?: any; // custom logger (ILogger compatible)
}
interface SDKHCS17ClientConfig extends HCS17ClientConfig {
operatorId: string;
operatorKey: string | import('@hashgraph/sdk').PrivateKey;
keyType?: 'ed25519' | 'ecdsa';
}
interface BrowserHCS17ClientConfig extends HCS17ClientConfig {
hwc?: import('@hashgraphonline/hashinal-wc').HashinalsWalletConnectSDK;
signer?: import('@hashgraph/hedera-wallet-connect').DAppSigner;
}
// See standards-sdk-go for full Go API types and methods
EnumDirect link to Enum
- TypeScript
- Go
enum HCS17TopicType {
STATE = 0,
}
// See standards-sdk-go for full Go API types and methods
Message Schema (canonical)Direct link to Message Schema (canonical)
{
"p": "hcs-17",
"op": "state_hash",
"state_hash": "<hex>",
"topics": ["0.0.123", "0.0.456"],
"account_id": "0.0.999",
"timestamp": "2025-09-14T10:00:00.000Z",
"m": "optional"
}
Base Client (selected)Direct link to Base Client (selected)
The following methods are inherited by both Node and Browser clients.
- TypeScript
- Go
// Constructed internally by concrete clients
// Validate an existing HCS‑17 topic by memo
validateHCS17Topic(topicId: string): Promise<{ valid: boolean; type?: HCS17TopicType; ttl?: number; error?: string }>;
// Mirror node helpers (validated parsing)
getRecentMessages(
topicId: string,
options?: { limit?: number; order?: 'asc' | 'desc' }
): Promise<Array<{ message: StateHashMessage; consensus_timestamp?: string; sequence_number: number; payer?: string }>>;
getLatestMessage(topicId: string): Promise<(StateHashMessage & { consensus_timestamp?: string; sequence_number: number }) | null>;
// Hashing utilities
calculateAccountStateHash(input: AccountStateInput): StateHashResult;
calculateCompositeStateHash(input: CompositeStateInput): CompositeStateHashResult;
calculateKeyFingerprint(keys: import('@hashgraph/sdk').PublicKey[], threshold: number): string;
verifyStateHash(input: AccountStateInput | CompositeStateInput, expectedHash: string): Promise<boolean>;
// Message helper
createStateHashMessage(stateHash: string, accountId: string, topicIds: string[], memo?: string): StateHashMessage;
// See standards-sdk-go for full Go API types and methods
Notes
- Account state hash sorts topics lexicographically by
topicIdand hashestopicId || runningHashvalues plus the public key (SHA‑384). - Composite state hash sorts members by
accountId, then composite topics bytopicId, and appends the threshold key fingerprint. verifyStateHashrecomputes with the same rules and compares toexpectedHash.
Server Client (HCS17Client)Direct link to Server Client (HCS17Client)
- TypeScript
- Go
constructor(config: SDKHCS17ClientConfig)
getKeyType(): 'ed25519' | 'ecdsa'
createStateTopic(options?: {
ttl?: number; // default 86400
adminKey?: boolean | string | import('@hashgraph/sdk').PublicKey | import('@hashgraph/sdk').KeyList;
submitKey?: boolean | string | import('@hashgraph/sdk').PublicKey | import('@hashgraph/sdk').KeyList;
}): Promise<string>
submitMessage(topicId: string, message: StateHashMessage): Promise<import('@hashgraph/sdk').TransactionReceipt>
computeAndPublish(params: {
accountId: string;
accountPublicKey: string | import('@hashgraph/sdk').PublicKey;
topics: string[]; // topics to include in hash
publishTopicId: string; // destination topic for the message
memo?: string;
}): Promise<{ stateHash: string; receipt: import('@hashgraph/sdk').TransactionReceipt }>
// See standards-sdk-go for full Go API types and methods
Throws
Invalid HCS-17 message: …(onsubmitMessagewhen schema validation fails)Failed to create topic: topicId empty(unexpected Mirror Node/SDK response)
Example
- TypeScript
- Go
const c = new HCS17Client({ network: 'testnet', operatorId, operatorKey });
const topicId = await c.createStateTopic({ ttl: 86400 });
const { stateHash } = await c.computeAndPublish({
accountId: '0.0.1234',
accountPublicKey: '302a30…',
topics: ['0.0.2001','0.0.2002'],
publishTopicId: topicId,
});
// See standards-sdk-go for full Go API types and methods
Browser Client (HCS17BrowserClient)Direct link to Browser Client (HCS17BrowserClient)
- TypeScript
- Go
constructor(config: BrowserHCS17ClientConfig)
createStateTopic(options?: {
ttl?: number; // default 86400
adminKey?: boolean | string; // string = hex/der of key; depends on wallet support
submitKey?: boolean | string;
}): Promise<string>
submitMessage(topicId: string, message: StateHashMessage): Promise<{ transactionId?: string }>
computeAndPublish(params: {
accountId: string;
accountPublicKey: string | import('@hashgraph/sdk').PublicKey;
topics: string[];
publishTopicId: string;
memo?: string;
}): Promise<{ stateHash: string }>
// See standards-sdk-go for full Go API types and methods
Throws
No active wallet connection(no account bound)No active wallet signer(connector has no signer)Invalid HCS-17 message: …(onsubmitMessagewhen schema validation fails)
Example
- TypeScript
- Go
const c = new HCS17BrowserClient({ network: 'testnet', signer });
const topicId = await c.createStateTopic({ ttl: 86400 });
const out = await c.computeAndPublish({
accountId: '0.0.1234',
accountPublicKey: '302a30…',
topics: ['0.0.2001','0.0.2002'],
publishTopicId: topicId,
});
// See standards-sdk-go for full Go API types and methods
Builders (tx.ts)Direct link to Builders (tx.ts)
- TypeScript
- Go
function buildHcs17CreateTopicTx(params: {
ttl: number;
adminKey?: boolean | string | import('@hashgraph/sdk').PublicKey | import('@hashgraph/sdk').KeyList;
submitKey?: boolean | string | import('@hashgraph/sdk').PublicKey | import('@hashgraph/sdk').KeyList;
operatorPublicKey?: import('@hashgraph/sdk').PublicKey; // Node helper defaulting
}): import('@hashgraph/sdk').TopicCreateTransaction;
function buildHcs17MessageTx(params: {
topicId: string;
stateHash: string;
accountId: string;
topics: string[];
memo?: string;
transactionMemo?: string;
}): import('@hashgraph/sdk').TopicMessageSubmitTransaction;
// See standards-sdk-go for full Go API types and methods
Notes
- The message builder includes an ISO timestamp automatically.
- Use
transactionMemoto set the Hedera transaction memo (separate fromm).
Reading MessagesDirect link to Reading Messages
- TypeScript
- Go
// Recent, validated messages (filtering non‑HCS‑17 entries)
const recent = await client.getRecentMessages('0.0.7777', { limit: 25, order: 'desc' });
// Latest only (or null)
const latest = await client.getLatestMessage('0.0.7777');
// See standards-sdk-go for full Go API types and methods
Validation RulesDirect link to Validation Rules
parseHCS17Memoaccepts onlyhcs-17:<number>:<positive integer>.- Message
pmust behcs-17andopmust bestate_hash. state_hashandaccount_idare required;topicsmust be an array of strings.
Error TypesDirect link to Error Types
- TypeScript
- Go
class StateHashError extends Error {
readonly code: string; // implementation-defined
}
// See standards-sdk-go for full Go API types and methods
Note: The clients throw standard Error with codes in messages; StateHashError is available for users who prefer explicit typing in their apps.