npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@0xio/sdk

v2.8.1

Published

Official TypeScript SDK for 0xio Wallet - Secure Octra blockchain integration for dApps

Readme

0xio Wallet SDK

Version 2.8.0

The official TypeScript SDK for building dapps on the 0xio Wallet and the Octra Network. It works with the browser extension, inside the 0xio Desktop browser and inside the 0xio App, and picks the right transport on its own.

What changed in each release is in CHANGELOG.md. The full API is in DOCUMENTATION.md.

Install

npm install @0xio/sdk

Quick start

import { ZeroXIOWallet } from '@0xio/sdk';

const wallet = new ZeroXIOWallet({
  appName: 'My DApp',
  requiredPermissions: ['accounts', 'public_transactions'],
});

await wallet.initialize();

// Connect. The wallet shows an approval the first time.
const connection = await wallet.connect();
console.log(connection.address);
console.log(connection.publicKey); // base64 Ed25519 key

// Balance, in OCT.
const balance = await wallet.getBalance();
console.log(balance.public, balance.private, balance.total);

// Sign a message. The wallet frames it (see Message signing below).
const signature = await wallet.signMessage('Hello, 0xio!');

// Send 10.5 OCT.
const result = await wallet.sendTransaction({
  to: 'oct1recipient...',
  amountOct: '10.5',
  message: 'Payment',
});
console.log(result.hash);

Amounts and units

The wallet counts in raw micro-OCT: one OCT is 1000000 units. Every raw field is passed to the wallet exactly as you give it, so existing integrations keep working. Where you would rather write OCT, use the OCT field and the SDK converts it with exact decimal arithmetic.

| Method | Raw field (sent as is) | OCT field (converted by the SDK) | |--------|------------------------|----------------------------------| | sendTransaction, signTransaction | amount | amountOct | | callContract | amount | amountOct | | sendPrivateTransfer | amountRaw | amount | | getBalance | | returns OCT |

Pass one field or the other, not both. A number that cannot be written in six decimals (such as 0.1 + 0.2) is rejected; pass a string.

Permissions

Ask for what the dapp uses. The wallet enforces these names:

| Scope | Grants | |-------|--------| | accounts | address, balance, public key | | public_transactions | sends and message signing | | contract_calls | state-changing contract calls | | contract_views | read-only contract calls | | private_balance_read | private balance, decrypting values, pending transfers | | private_proofs | encrypting values, zero and range proofs | | private_transfers | sending private transfers | | private_claims | claiming private transfers |

The private scopes show a warning in the connection dialog. Older names such as read_balance or stealth_claim still work: the SDK translates them, and they come back in the granted list as aliases.

API map

Connection: initialize(), connect(options?), disconnect(), isConnected(), getConnectionStatus(), getAddress(), getPublicKey().

Balance and network: getBalance(forceRefresh?), getNetworkInfo(), getNetworkId(), switchNetwork(id) (connected dapps only; the wallet asks the user first).

Transactions: sendTransaction(data), signTransaction(data) then submitTransaction(signedTx), getTransactionHistory(page?, limit?).

Contracts: callContract(data) (signed, approval shown), contractCallView(data) (read-only, no approval), getContractStorage(contract, key), sendContractTransactionSequence(data) (several calls under one approval; every step is listed in it).

Messages: signMessage(message), signAuthMessage(service, nonce), and the verifiers verifyMessage, getSignedMessageBytes, buildAuthMessage.

Private: sendPrivateTransfer(data), getPendingPrivateTransfers(), claimPrivateTransfer(id) (approval shown), getPrivateBalanceInfo(), registerPrivateViewKey({ address }).

Private primitives (2.8.0): getPrivateCapabilities(), encryptValue(), decryptValue(), makeZeroProof(), makeRangeProof(), getPrivateBalance(). Keys never leave the wallet; the dapp receives ciphertexts, proofs and hashes.

Passthrough: request(method, params) sends any wallet method; rpcCall(method, params) reaches the wallet's read-only node RPC allow-list, such as octra_balance.

encryptBalance and decryptBalance remain for other wallets; the 0xio extension answers NOT_AVAILABLE, and users encrypt from its Privacy screen.

Message signing

The wallet never signs a raw message. It signs a framed payload, so a signed message can never be a transaction (a transaction is JSON and starts with {):

"Octra Signed Message:\n" + utf8ByteLength(message) + "\n" + message

The signature is an Ed25519 detached signature over the UTF-8 bytes of that string. Verify it with the SDK:

import { verifyMessage } from '@0xio/sdk';

const publicKey = await wallet.getPublicKey();
const ok = await verifyMessage(message, signature, publicKey);

Or with any Ed25519 library, over the exact bytes from getSignedMessageBytes(message). For signAuthMessage(service, nonce), rebuild the signed string with buildAuthMessage(service, nonce, origin) first.

Events

wallet.on('connect', (event) => console.log('Connected:', event.data.address));
wallet.on('disconnect', (event) => console.log('Disconnected:', event.data.reason));
wallet.on('accountChanged', (event) => console.log('Account:', event.data.newAddress));
wallet.on('balanceChanged', (event) => console.log('Balance:', event.data.newBalance.total));
wallet.on('networkChanged', (event) => console.log('Network:', event.data.newNetwork.name));
wallet.on('transactionConfirmed', (event) => console.log('Confirmed:', event.data.txHash));
wallet.on('transactionFailed', (event) => console.log('Failed:', event.data.error));
wallet.on('extensionLocked', () => console.log('Locked'));

Errors

Every failure is a ZeroXIOWalletError with a code.

import { ZeroXIOWalletError, ErrorCode } from '@0xio/sdk';

try {
  await wallet.sendTransaction({ to: 'oct1...', amountOct: '10' });
} catch (error) {
  if (error instanceof ZeroXIOWalletError) {
    switch (error.code) {
      case ErrorCode.NOT_CONNECTED:   // connect() first
      case ErrorCode.WALLET_LOCKED:   // the user has to unlock the wallet
      case ErrorCode.USER_REJECTED:   // the user declined the approval
      case ErrorCode.INVALID_AMOUNT:  // bad unit or precision
      case ErrorCode.NONCE_TOO_FAR:   // node rejected the transaction
        console.log(error.code, error.message);
    }
  }
}

The wallet refuses anything that signs, submits or changes state until the page has connected, and opens its unlock screen at most once a minute for a page that is not connected.

Networks

import { getNetworkConfig } from '@0xio/sdk';

const devnet = getNetworkConfig('devnet');
console.log(devnet.rpcUrl);          // https://devnet.octrascan.io
console.log(devnet.isTestnet);       // true

| Network | RPC | Explorer | Privacy | |---------|-----|----------|---------| | Mainnet | https://octra.network | octrascan.io | yes | | Devnet | https://devnet.octrascan.io | devnet.octrascan.io | yes |

connect() returns the wallet's active network in networkInfo; the SDK never assumes one.

Where it runs

  • Browser extension. The page talks to the extension over a private message channel that page scripts cannot read or forge.
  • 0xio Desktop. The dapp runs in an iframe and the SDK relays requests to the desktop wallet. Set trustedParentOrigins in production; localhost is trusted by default for development.
  • 0xio App. The dapp runs in a WebView and the SDK uses the app's bridge.

No code changes are needed; the SDK detects the environment.

Wallet adapters

Transport is pluggable, so another wallet can be supported without touching the core.

import { detectWalletAdapter, ZeroXIOWallet, OctraProviderAdapter } from '@0xio/sdk';

// Detect: the 0xio bridge first, then any RFC-O-1 provider on window.octra.
const adapter = detectWalletAdapter();
const wallet = new ZeroXIOWallet({ appName: 'My DApp', adapter });

// Or choose one explicitly.
const rfc = new ZeroXIOWallet({ appName: 'My DApp', adapter: OctraProviderAdapter });

The 0xio bridge carries every SDK method. The RFC-O-1 provider carries what the RFC names, so getBalance, getPublicKey, getTransactionHistory, getContractStorage, getPendingPrivateTransfers and rpcCall have no equivalent there. The table in DOCUMENTATION.md lists coverage per method.

To add a wallet, copy src/supports/template.ts, fill in its constants and message mapping, register it in src/supports/index.ts, and export it from src/index.ts if it belongs in the public API.

Timeouts

Approvals wait up to three minutes. A private transfer waits up to ten, because the wallet builds proofs after the approval. Interactive methods are never retried, so a slow approval never produces a second popup.

Requirements

  • 0xio Wallet Extension 2.5.5 or newer for the 2.8.0 private primitives and framed message signing; 2.4.0 or newer for private transfers and claims
  • 0xio Desktop 1.0 or newer for the iframe bridge, 0xio App 1.0 or newer for the WebView bridge
  • A current Chromium-based browser (Chrome, Edge, Brave) or Firefox

License

MIT License. Copyright 2026 0xio Labs.