hiero-react
v0.2.0
Published
React hooks for reading data from the Hiero/Hedera network via the Mirror Node REST API
Maintainers
Readme
hiero-react
React hooks for reading data from the Hiero / Hedera network via the Mirror Node REST API.
Features
- React hooks — accounts, transactions, tokens, NFTs, files, smart contracts, and HCS topics
- TypeScript — full type safety and autocompletion on every hook
- Mirror Node — read Hiero data without running a node or holding a private key
- Lightweight — zero production dependencies
How it works
Hedera runs a public read API called the Mirror Node. It indexes everything on the network — every transaction, token transfer, and HCS message — and exposes it over REST.
This library wraps those endpoints in React hooks so you can display blockchain data without writing any fetch logic yourself. It is read-only: you can display balances, transactions, and token data, but cannot send transactions or sign anything.
Your component
└── calls useAccount('0.0.1234')
└── reads mirror URL from HieroProvider
└── GET https://testnet.mirrornode.hedera.com/api/v1/accounts/0.0.1234
└── returns { balance, loading, error }Installation
npm install hiero-reactReact 18 or higher is required as a peer dependency.
Quick start
1. Wrap your app with HieroProvider
import { HieroProvider } from 'hiero-react';
export default function App() {
return (
<HieroProvider network="testnet">
<YourApp />
</HieroProvider>
);
}2. Use a hook in your component
import { useAccount } from 'hiero-react';
function Wallet({ accountId }: { accountId: string }) {
const { balance, loading, error } = useAccount(accountId);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return <p>Balance: {balance} HBAR</p>;
}Configuration
Networks
<HieroProvider network="testnet"> // Testnet (development)
<HieroProvider network="mainnet"> // Mainnet (production)
<HieroProvider network="previewnet"> // Previewnet (experimental)Custom Mirror Node URL
<HieroProvider network="mainnet" mirrorNodeUrl="https://your-mirror-node.com">Available hooks
useHiero()
Access the current network configuration. Must be inside HieroProvider.
const { network, mirrorNodeUrl } = useHiero();useAccount(accountId)
Fetch the HBAR balance for an account.
const { accountId, balance, loading, error } = useAccount('0.0.1234');useTransactions(accountId, limit?)
Fetch recent transactions for an account.
const { transactions, loading, error, refetch } = useTransactions('0.0.1234', 20);Each Transaction has: transactionId, type, result, consensusTimestamp, transfers[].
useTokens(accountId)
Fetch fungible tokens held by an account.
const { tokens, loading, error } = useTokens('0.0.1234');
// tokens: Array<{ tokenId, symbol, balance, decimals }>useNFTs(accountId)
Fetch NFTs held by an account. Metadata is automatically decoded from base64.
const { nfts, loading, error } = useNFTs('0.0.1234');
// nfts: Array<{ tokenId, serialNumber, metadata }>useFile(fileId) and useFileContents(fileId)
Fetch metadata and raw contents of a file stored on the Hedera file service.
const { file, loading, error, refetch } = useFile('0.0.101');
// file: { fileId, size, expirationTimestamp, deleted, memo, keys[] }
const { contents, loading, error } = useFileContents('0.0.101');
// contents: { fileId, content (base64), encoding }useContract(contractId), useContractCalls(contractId), useContractLogs(contractId)
Fetch metadata, historical call results, and emitted event logs for a smart contract.
const { contract, loading, error } = useContract('0.0.2001');
// contract: { contractId, evmAddress, fileId, memo, adminKey, deleted, bytecodeHash, ... }
const { calls, loading, error } = useContractCalls('0.0.2001');
// calls: Array<{ result, gasUsed, errorMessage }>
const { logs, loading, error } = useContractLogs('0.0.2001');
// logs: Array<{ address, blockHash, blockNumber, data, topics[], transactionHash }>useTopic(topicId) and useTopicMessages(topicId, options?)
Fetch metadata and messages for a Hedera Consensus Service (HCS) topic. Messages are automatically decoded from base64.
const { topic, loading, error } = useTopic('0.0.2');
// topic: { topicId, memo, runningHash, sequenceNumber, adminKey, submitKey, deleted, ... }
const { messages, loading, error } = useTopicMessages('0.0.2', {
limit: 25,
sequenceNumberGte: 100,
sequenceNumberLte: 200,
});
// messages: Array<{ consensusTimestamp, message, sequenceNumber, runningHash, topicId }>Full example
This example demonstrates all available hooks against real testnet data. Topic 0.0.2 and file 0.0.101 are Hedera system resources that always exist on testnet — no setup required.
import {
HieroProvider,
useAccount,
useTopic,
useTopicMessages,
useFile,
useFileContents,
useContract,
useContractLogs,
} from 'hiero-react';
function HookTests() {
const { balance, loading: accountLoading } = useAccount('0.0.8241384');
const { topic } = useTopic('0.0.2');
const { messages } = useTopicMessages('0.0.2', { limit: 3 });
const { file } = useFile('0.0.101');
const { contents } = useFileContents('0.0.101');
const { contract } = useContract('0.0.8071440');
const { logs } = useContractLogs('0.0.8071440');
return (
<div style={{ padding: 32, fontFamily: 'monospace', display: 'flex', flexDirection: 'column', gap: 24 }}>
<section>
<h2>useAccount</h2>
{accountLoading ? <p>Loading...</p> : <p>Balance: {balance} HBAR</p>}
</section>
<section>
<h2>useTopic (0.0.2)</h2>
{topic ? (
<p>Sequence number: {topic.sequenceNumber} | Memo: {topic.memo}</p>
) : <p>Loading...</p>}
</section>
<section>
<h2>useTopicMessages (0.0.2)</h2>
{messages.length === 0 ? <p>Loading...</p> : messages.map(m => (
<div key={m.sequenceNumber}>
#{m.sequenceNumber} — {m.consensusTimestamp}
</div>
))}
</section>
<section>
<h2>useFile (0.0.101)</h2>
{file ? (
<p>Size: {file.size} bytes | Deleted: {String(file.deleted)}</p>
) : <p>Loading...</p>}
</section>
<section>
<h2>useFileContents (0.0.101)</h2>
{contents ? (
<p>Content length: {contents.content.length} chars (base64)</p>
) : <p>Loading...</p>}
</section>
<section>
<h2>useContract</h2>
{contract ? (
<p>EVM address: {contract.evmAddress} | Deleted: {String(contract.deleted)}</p>
) : <p>Loading...</p>}
</section>
<section>
<h2>useContractLogs</h2>
{logs.length === 0 ? <p>No logs</p> : logs.map((log, i) => (
<div key={i}>
Block {log.blockNumber} — {log.address}
</div>
))}
</section>
</div>
);
}
export default function App() {
return (
<HieroProvider network="testnet">
<HookTests />
</HieroProvider>
);
}Development
npm install # install dependencies
npm run build # compile TypeScript → dist/
npm test # run test suite
npm run lint # check code style
npm run typecheck # check types without building
npm run dev # build and watch for changesContributing
See CONTRIBUTING.md for the full guide.
All commits must be:
- GPG signed (
git config commit.gpgsign true) - Include a DCO sign-off (
git commit -s)
License
Apache-2.0 — see LICENSE for details.
