
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@nockbox/iris-wasm
Advanced tools
WebAssembly bindings for the Nockbox Wallet, including cryptographic operations, transaction building, and gRPC-Web client for communicating with the Nockchain server.
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.
Since browsers can't directly communicate with gRPC servers, you need to run an Envoy proxy that translates gRPC-Web requests to native gRPC.
macOS (Homebrew):
brew install envoy
Linux (apt):
sudo apt-get install envoy
Docker:
docker pull envoyproxy/envoy:v1.28-latest
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:
http://localhost:8080 for gRPC-Web requestslocalhost:6666Make sure your Nockchain gRPC server is running on port 6666:
# From your server directory
./your-grpc-server
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
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);
GrpcClientnew GrpcClient(endpoint: string)
Creates a new gRPC-Web client.
endpoint: URL of the Envoy proxy (e.g., http://localhost:8080)get_balance_by_address(address: string): Promise<Balance>Get the balance for a wallet address.
address: Base58-encoded wallet addressget_balance_by_first_name(firstName: string): Promise<Balance>Get the balance for a note first name.
firstName: Base58-encoded first name hashsend_transaction(rawTx: RawTransaction): Promise<string>Send a signed transaction to the network.
rawTx: RawTransaction object (must include tx_id)transaction_accepted(txId: string): Promise<boolean>Check if a transaction has been accepted.
txId: Base58-encoded transaction IDtrue if accepted, false otherwiseBrowser (WASM) → gRPC-Web (HTTP) → Envoy Proxy → gRPC Server (HTTP/2)
tonic-web-wasm-client translates calls to HTTP requests with gRPC-Web protocolMake sure Envoy is running and properly configured. The envoy.yaml file includes CORS headers.
file://)pkg/ directory contains the built WASM filesIf you encounter build errors:
# Clean and rebuild
cargo clean
wasm-pack build --target web --out-dir pkg --scope nockbox
After making changes to the Rust code:
wasm-pack build --target web --out-dir pkg --scope nockbox
If you modify .proto files, rebuild the project to regenerate the code:
cargo build
See the main repository LICENSE file.
FAQs
WASM bindings for Iris wallet
We found that @nockbox/iris-wasm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.