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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@nockbox/iris-wasm

v0.1.2

Published

WASM bindings for Iris wallet

Readme

Nockbox Wallet WASM

WebAssembly bindings for the Nockbox Wallet, including cryptographic operations, transaction building, and gRPC-Web client for communicating with the Nockchain server.

Features

  • Cryptography: Key derivation, signing, address generation
  • Transaction Building: Create and sign transactions
  • gRPC-Web Client: Call Nockchain gRPC endpoints from the browser
    • Get wallet balance
    • Send transactions
    • Check transaction status

Setup

1. Build the WASM Package

cd crates/iris-wasm
wasm-pack build --target web --out-dir pkg --scope nockbox

This generates the WebAssembly module and JavaScript bindings in the pkg/ directory.

2. Set Up Envoy Proxy

Since browsers can't directly communicate with gRPC servers, you need to run an Envoy proxy that translates gRPC-Web requests to native gRPC.

Install Envoy

macOS (Homebrew):

brew install envoy

Linux (apt):

sudo apt-get install envoy

Docker:

docker pull envoyproxy/envoy:v1.28-latest

Run Envoy

From the repository root:

# Using local installation
envoy -c envoy.yaml

# Using Docker
docker run --rm -it \
  --network host \
  -v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml \
  envoyproxy/envoy:v1.28-latest

Envoy will:

  • Listen on http://localhost:8080 for gRPC-Web requests
  • Proxy to your gRPC server on localhost:6666
  • Handle CORS headers for browser requests

3. Start Your gRPC Server

Make sure your Nockchain gRPC server is running on port 6666:

# From your server directory
./your-grpc-server

4. Run the Example

Serve the example HTML file with a local HTTP server:

# Using Python
python3 -m http.server 8000

# Using Node.js
npx http-server -p 8000

# Using Rust
cargo install simple-http-server
simple-http-server -p 8000

Then open your browser to:

http://localhost:8000/crates/iris-wasm/examples/grpc-web-demo.html

Usage Examples

JavaScript

import init, {
  GrpcClient,
  deriveMasterKeyFromMnemonic,
  WasmTxBuilder,
  WasmNote,
  WasmVersion,
  WasmName,
  WasmDigest,
  WasmSpendCondition,
  WasmPkh,
  WasmLockPrimitive,
  WasmLockTim
} from './pkg/iris_wasm.js';

// Initialize the WASM module
await init();

// Create a client pointing to your Envoy proxy
const client = new GrpcClient('http://localhost:8080');

// Get balance by wallet address
const balance = await client.get_balance_by_address(
  '6psXufjYNRxffRx72w8FF9b5MYg8TEmWq2nEFkqYm51yfqsnkJu8XqX'
);
console.log('Balance:', balance);

// Get balance by first name (note hash)
const balanceByName = await client.get_balance_by_first_name(
  '2H7WHTE9dFXiGgx4J432DsCLuMovNkokfcnCGRg7utWGM9h13PgQvsH'
);
console.log('Balance by name:', balanceByName);

// ============================================================================
// Building and signing transactions
// ============================================================================

// Derive keys from mnemonic
const mnemonic = "dice domain inspire horse time...";
const masterKey = deriveMasterKeyFromMnemonic(mnemonic, "");

// Create notes from balance query
const notes = balance.notes.map(entry => new WasmNote(
  WasmVersion.V1(),
  entry.note.noteVersion.v1.originPage.value,
  new WasmName(entry.name.first, entry.name.last),
  new WasmDigest(entry.note.noteVersion.v1.noteData.hash),
  entry.note.noteVersion.v1.assets.value
));

// Create spend condition
const pubkeyHash = new WasmDigest("your_pubkey_hash_here");
const spendCondition = new WasmSpendCondition([
  WasmLockPrimitive.newPkh(WasmPkh.single(pubkeyHash)),
  WasmLockPrimitive.newTim(WasmLockTim.coinbase())
]);

// Build transaction
const builder = WasmTxBuilder.newSimple(
  notes,
  spendCondition,
  new WasmDigest("recipient_address"),
  1234567, // gift
  2850816, // fee
  new WasmDigest("refund_address")
);

// Sign and submit
const signedTx = builder.sign(masterKey.private_key);
const txProtobuf = signedTx.toProtobuf();
await client.send_transaction(txProtobuf);

// Check if a transaction was accepted
const accepted = await client.transaction_accepted(signedTx.id.value);
console.log('Transaction accepted:', accepted);

API Reference

GrpcClient

Constructor

new GrpcClient(endpoint: string)

Creates a new gRPC-Web client.

  • endpoint: URL of the Envoy proxy (e.g., http://localhost:8080)

Methods

get_balance_by_address(address: string): Promise<Balance>

Get the balance for a wallet address.

  • address: Base58-encoded wallet address
  • Returns: Balance object with notes, height, and block_id
get_balance_by_first_name(firstName: string): Promise<Balance>

Get the balance for a note first name.

  • firstName: Base58-encoded first name hash
  • Returns: Balance object with notes, height, and block_id
send_transaction(rawTx: RawTransaction): Promise<string>

Send a signed transaction to the network.

  • rawTx: RawTransaction object (must include tx_id)
  • Returns: Acknowledgment message
transaction_accepted(txId: string): Promise<boolean>

Check if a transaction has been accepted.

  • txId: Base58-encoded transaction ID
  • Returns: true if accepted, false otherwise

Architecture

Browser (WASM) → gRPC-Web (HTTP) → Envoy Proxy → gRPC Server (HTTP/2)
  1. Browser/WASM: Your web application uses the WASM module to call gRPC methods
  2. gRPC-Web: The tonic-web-wasm-client translates calls to HTTP requests with gRPC-Web protocol
  3. Envoy Proxy: Envoy translates gRPC-Web requests to native gRPC and handles CORS
  4. gRPC Server: Your Nockchain server receives native gRPC requests

Troubleshooting

CORS Errors

Make sure Envoy is running and properly configured. The envoy.yaml file includes CORS headers.

Connection Refused

  • Verify your gRPC server is running on port 6666
  • Verify Envoy is running on port 8080
  • Check that you're using the correct endpoint in the client

WASM Module Not Loading

  • Ensure you're serving files over HTTP (not file://)
  • Check browser console for detailed error messages
  • Verify the pkg/ directory contains the built WASM files

Build Errors

If you encounter build errors:

# Clean and rebuild
cargo clean
wasm-pack build --target web --out-dir pkg --scope nockbox

Development

Rebuild WASM

After making changes to the Rust code:

wasm-pack build --target web --out-dir pkg --scope nockbox

Update Protobuf Definitions

If you modify .proto files, rebuild the project to regenerate the code:

cargo build

License

See the main repository LICENSE file.