Nockchain Wallet WASM
WebAssembly bindings for the Nockchain 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
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):
Linux (apt):
Docker:
Run Envoy
From the repository root:
# Using local installation
# Using Docker
Envoy will:
- Listen on
http://localhost:8080for 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
4. Run the Example
Serve the example HTML file with a local HTTP server:
# Using Python
# Using Node.js
# Using Rust
Then open your browser to:
http://localhost:8000/crates/rose-wasm/examples/grpc-web-demo.html
Usage Examples
JavaScript
import init from './pkg/rose_wasm.js';
// Initialize the WASM module
await ;
// Create a client pointing to your Envoy proxy
const client = ;
// Get balance by wallet address
const balance = await client.;
console.log;
// Get balance by first name (note hash)
const balanceByName = await client.;
console.log;
// ============================================================================
// Building and signing transactions
// ============================================================================
// Derive keys from mnemonic
const mnemonic = "dice domain inspire horse time...";
const masterKey = ;
// Create notes from balance query (protobuf -> wasm types)
const notes = balance..;
// Create spend condition
const pubkeyHash = "your_pubkey_hash_here"; // base58 digest string
const spendCondition = ;
const spendConditions = notes.;
// Build transaction (simple spend)
const feePerWord = 2850816n;
const builder = ;
builder.;
// Sign and submit
const signingKey = masterKey.;
if throw ;
builder.;
builder.;
const nockchainTx = builder.;
const rawTx = nockchainTx.;
const txProtobuf = rawTx.;
await client.;
// Check if a transaction was accepted
const accepted = await client.;
console.log;
API Reference
GrpcClient
Constructor
Creates a new gRPC-Web client.
endpoint: URL of the Envoy proxy (e.g.,http://localhost:8080)
Methods
getBalanceByAddress(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
getBalanceByFirstName(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
sendTransaction(rawTx: RawTransaction): Promise<string>
Send a signed transaction to the network.
rawTx: RawTransaction object (must include tx_id)- Returns: Acknowledgment message
transactionAccepted(txId: string): Promise<boolean>
Check if a transaction has been accepted.
txId: Base58-encoded transaction ID- Returns:
trueif accepted,falseotherwise
Cryptography
The WASM package also exposes key-derivation and signing helpers (backed by rose-crypto).
Key derivation (browser)
import init from './pkg/rose_wasm.js';
await ;
const mnemonic =
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
const masterKey = ;
// `ExtendedKey` properties are camelCase in JS
console.log; // 97
console.log; // 32
const child0 = masterKey.;
// Important: free wasm-bindgen objects when you're done
masterKey.;
child0.;
Signing
import init from './pkg/rose_wasm.js';
await ;
// privateKeyBytes: Uint8Array(32)
// publicKeyBytes: Uint8Array(97)
const sig = ;
const ok = ;
console.log;
API surface (selected)
- Functions:
deriveMasterKey(seed: Uint8Array): ExtendedKeyderiveMasterKeyFromMnemonic(mnemonic: string, passphrase?: string): ExtendedKeyhashPublicKey(publicKeyBytes: Uint8Array): stringhashU64(value: number | bigint): stringhashNoun(jamBytes: Uint8Array): stringsignMessage(privateKeyBytes: Uint8Array, message: string): SignatureverifySignature(publicKeyBytes: Uint8Array, signature: Signature, message: string): boolean
- Classes:
ExtendedKey- Properties:
privateKey?: Uint8Array,publicKey: Uint8Array,chainCode: Uint8Array - Methods:
deriveChild(index: number): ExtendedKey,free(): void
- Properties:
Architecture
Browser (WASM) → gRPC-Web (HTTP) → Envoy Proxy → gRPC Server (HTTP/2)
- Browser/WASM: Your web application uses the WASM module to call gRPC methods
- gRPC-Web: The
tonic-web-wasm-clienttranslates calls to HTTP requests with gRPC-Web protocol - Envoy Proxy: Envoy translates gRPC-Web requests to native gRPC and handles CORS
- 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
Development
Rebuild WASM
After making changes to the Rust code:
Update Protobuf Definitions
If you modify .proto files, rebuild the project to regenerate the code:
License
See the main repository LICENSE file.