Skip to main content

Browser — HCS‑20BrowserClient

This guide shows how to wire up a wallet and run common HCS‑20 operations entirely in the browser.

Quick Flow

Setup

import { HCS20BrowserClient } from '@hashgraphonline/standards-sdk';
import { HashinalsWalletConnectSDK } from '@hashgraphonline/hashinal-wc';

const hwc = new HashinalsWalletConnectSDK();
await hwc.init();
await hwc.connect();

const client = new HCS20BrowserClient({
network: 'testnet',
hwc,
// Optional: configure a known public topic or registry directory
publicTopicId: '0.0.6124611', // shared, permissionless topic for public points
registryTopicId: '0.0.6124612', // optional directory of points
});

Tip

  • Use a shared “public topic” to deploy public points (no topic creation).
  • For private points, set usePrivateTopic: true in deployPoints to create a new topic where only your wallet can submit.

Deploy Points (private vs public)

Private topic (created and owned by the connected wallet):

const points = await client.deployPoints({
name: 'MyRewardPoints',
tick: 'MRP',
maxSupply: '1000000',
limitPerMint: '1000',
metadata: 'https://example.com/meta',
usePrivateTopic: true,
progressCallback: p => console.log(`${p.stage}: ${p.percentage}%`),
});
console.log(points.topicId);

Public topic (reuses a known, shared topic configured on the client):

const points = await client.deployPoints({
name: 'PublicPoints',
tick: 'pub',
maxSupply: '5000000',
limitPerMint: '2000',
usePrivateTopic: false,
});

Notes

  • Private topics: the browser client creates a registry topic using your wallet’s public key as both admin and submit key.
  • Public topics: no new topic is created; operations are posted to the configured publicTopicId.

Register in a Directory (optional)

await client.registerTopic({
name: 'MyRewardPoints',
topicId: points.topicId,
isPrivate: true, // or false for public points
metadata: 'https://example.com/meta',
progressCallback: p => console.log(`${p.stage}: ${p.percentage}%`),
});

Registering helps wallets and explorers discover points by name; pass your directory’s registryTopicId in the client config.

Mint / Transfer / Burn

All methods accept an optional progressCallback for simple UI updates.

await client.mintPoints({
tick: 'mrp',
amount: '50',
to: '0.0.12345',
memo: 'bonus',
progressCallback: p => console.log(p.stage),
});

await client.transferPoints({
tick: 'mrp',
amount: '10',
from: '0.0.12345',
to: '0.0.67890',
});

await client.burnPoints({
tick: 'mrp',
amount: '1',
from: '0.0.67890',
});

Query Balances (Indexer)

Use the optional indexer to aggregate balances from a topic’s message history.

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

const indexer = new HCS20PointsIndexer();
const state = await indexer.query(points.topicId);
console.log(state.balances);

UX Tips

  • Wallet approvals: each action prompts the user; hook progressCallback to show stages
  • Tickers: tick is normalized to lowercase; stay consistent in UI
  • Directories: display a “verified” badge for directory‑registered points
  • Errors: show wallet error messages verbatim; retry transient network failures

Advanced (builders + signer)

If you need raw transactions (custom signing or batching), build them and execute with the signer:

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

const tx = buildHcs20MintTx({ topicId: points.topicId, tick: 'mrp', amt: '5', to: '0.0.123' });
const signer = hwc.dAppConnector.signers[0];
const frozen = await (tx as any).freezeWithSigner(signer);
const res = await frozen.executeWithSigner(signer);
await res.getReceiptWithSigner(signer);

Notes

  • All wallet operations require explicit user approval via the connected signer.
  • Public topics may enforce fee settings; the client sets a max transaction fee when needed.