Get Started
Orbinum is a Substrate chain with an EVM and a shielded pool. A dApp, a script or a backend reads
the chain, calls precompiles from the EVM and checks what users show it, with the public package
@orbinum/protocol. This page installs it, connects to the testnet and reads the pool.
What you can build
| Task | How | Page |
|---|---|---|
| Read chain and pool state | OrbinumClient modules and the node's privacy_* RPC | Reading Pool State |
| Call precompiles from the EVM | Pay any AccountId32 through Balances; shield ORB through ShieldedPool | Calling a Precompile |
| Verify disclosure keys | decodeNoteDisclosureKey checks a key a user hands you, locally | Verifying Disclosure Keys |
| Index events | Read the shielded pool's Substrate events with polkadot-api | Indexing Events |
| Pass payment slips along | decodePaymentSlip checks that a slip is well formed; only the recipient's wallet can open it | Payment slips |
Everything in this table is public data or data a user chooses to show you. None of it needs a spending key.
What stays in the wallet
Three operations need the user's private keys, and only the wallet performs them, with the app's private custody library:
| Operation | Why it stays in the wallet |
|---|---|
| Note construction | A note is built from the recipient's keys and a secret blinding |
| Memo sealing | The 180-byte encrypted memo is what lets the recipient find the note |
Spending (private_transfer, unshield) | The proof uses the spending key and the note's secrets |
The public packages generate a shield proof and encode a commitment for the chain, but they do not seal memos,
do not parse orbpriv3 privacy addresses and never touch a spending key. A dApp that needs a
private payment asks the user to make it in their wallet. See
the custody boundary.
Install
npm install @orbinum/protocol polkadot-api @polkadot/util-crypto
polkadot-api and @polkadot/util-crypto are peer dependencies, and both are required: the ESM
and CommonJS builds import them when the package loads, so any import fails without them. npm
installs peers automatically; install them explicitly with other package managers.
Everything is imported from the package root; there are no subpath exports.
| Requirement | Detail |
|---|---|
| Runtime | Node 22 or later, a modern browser, a worker or React Native |
atob | Must exist when the module loads; a dependency decodes constants at import |
crypto.getRandomValues | Required; on React Native install a polyfill before importing the package |
Connect
import { OrbinumClient } from '@orbinum/protocol';
const client = await OrbinumClient.connect({
substrateWs: 'wss://rpc-1.testnet.orbinum.io',
evmRpc: 'https://rpc-1.testnet.orbinum.io',
});
| Option | Meaning |
|---|---|
substrateWs | WebSocket URL of the node; the client opens its own connection |
connectTimeoutMs | Handshake timeout with substrateWs; default 15 000 ms |
papi, substrateHttp | Adopt a polkadot-api client your app already holds, instead of substrateWs |
evmRpc | EVM JSON-RPC URL; without it client.evm, client.evmExplorer and client.precompiles are null |
evmRpcPeer | A second EVM endpoint, used only to tell a pending transaction from a stranded one |
connect throws if the node runs a runtime older than MIN_SPEC_VERSION (19). The client does
not reconnect; for a long-lived app, OrbinumClientProvider wraps it with a heartbeat and
backoff reconnection. Endpoints and chain IDs are in Network & Tooling.
First read
Save as first-read.mjs and run node first-read.mjs:
import { OrbinumClient, formatBalance } from '@orbinum/protocol';
const client = await OrbinumClient.connect({ substrateWs: 'wss://rpc-1.testnet.orbinum.io' });
const stats = await client.privacy.getPoolStats();
console.log('root:', stats.merkleRoot);
console.log('notes:', stats.commitmentCount, 'spent:', stats.nullifierCount);
console.log('pool holds:', formatBalance(stats.totalBalance, { decimals: 18, symbol: 'ORB' }));
client.destroy();
This reads the pool's current Merkle root, how many notes it holds, how many have been spent and the ORB it holds. It is public data and needs no keys or tokens. Writing needs test ORB from the faucet.
Where to go next
| You want to | Read |
|---|---|
| Configure a wallet, viem, ethers, Hardhat or Foundry | Network & Tooling |
| Read roots, proofs and nullifier status | Reading Pool State |
| Pay a Substrate account from Solidity | Calling a Precompile |
| Know how the EVM differs from Ethereum | EVM Compatibility |
| See the whole package API | @orbinum/protocol |
Related
- @orbinum/protocol — the package reference, the custody boundary and payment slips
- Network & Tooling — endpoints, chain IDs and tool configuration
- Calling a Precompile — Balances from Solidity and ethers
- Precompile Addresses — every registered address
- Transaction Lifecycle — what the wallet does at each step