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

@zga/shielded-sdk

v0.1.1

Published

The client library for the shielded pool. It holds what a wallet, a relayer or a test needs and nothing that touches a chain.

Readme

@zga/shielded-sdk

The client library for the shielded pool. It holds what a wallet, a relayer or a test needs and nothing that touches a chain.

What is in it

| Module | Contents | |---|---| | field | The BN254 scalar field, 32-byte big-endian encoding, 64-bit little-endian encoding, field reduction of a hash | | hasher | Poseidon over BN254, the hash the circuit and the pool use | | tree | The pool's incremental Merkle tree (depth 20), paths, and root recomputation from a path | | notes | A note (asset, value, owner key, blinding), its commitment and its nullifier | | keys | Spending key, owner key and encryption key pair derived from one seed; the shielded address format | | encryption | Encryption of a note's secrets to its owner, 88 bytes against the pool's limit of 96 | | extdata | The external data hashes a proof binds: shield, transfer and unshield | | circuit | A transaction's circuit input, padding, and the choice of notes to spend | | prover | The byte layouts of a proof and a key, proving, and checking a proof in JavaScript | | builders | A shield, a private transfer and an unshield, each returning the program's arguments | | events, scanner, chain | Decoding the pool's events, a wallet's view of the pool, and a reader that gets the events from a chain |

Artifacts

The circuit's WebAssembly (transact_main.wasm), the proving key (transact_main_final.zkey) and the verification key (vk.bin, vkey.json) come from the ceremony's publication, which lists each file's SHA-256, its size and the addresses it is served from (ArtifactManifest). loadArtifact tries each address in order and returns only bytes that match the manifest, so no host is trusted; loadVerifyingKey also checks that vk.bin hashes to the key hash the pool records.

Relaying an unshield

A wallet that does not pay for an exit itself sends a relayer a RelayerUnshieldRequest. GET /v1/info gives the relayer's address, its lookup tables and its fee for each asset (a minimum, and a share of the amount in basis points); POST /v1/unshield takes the request and answers with the transaction's signature, or with a refusal and a code. checkUnshieldRequest is what a relayer runs before it spends anything: the shape of every field, that it takes the asset, that the nullifiers differ, and that the fee is enough and not more than the amount. The relayer sees the recipient and the nullifiers, and nothing that links the exit to a note.

Sending the transactions

A shield, an unshield and a transfer carry a proof, two encrypted notes and about a dozen accounts, which is close to the 1,232-byte limit of a legacy transaction. Measured with the encrypted notes a wallet sends: a shield is 1,191 bytes, an unshield 1,203, and an unshield that names a target pool (1,235), that a NOP relays by passing its NOP and fee accounts (1,267), or both (1,299, and 1,331 when the NOP also holds a bond) is over. They are sent as versioned transactions with the lookup table the deployment records, which brings the largest of them to 1,119 bytes. Every transaction type is measured both ways by scripts/test-shielded-real.ts in the contracts repository.

Finding a wallet's notes

const scanner = new WalletScanner(hasher, keys);
await scanner.sync(new ChainEventSource(connection, async () => poolAddresses()));  // every pool's address
scanner.tree(poolIndex);    // the tree of one pool: a spend is proved against the tree of the pool its note is in
scanner.balance(assetId);   // what the wallet can spend
scanner.unspent(assetId);   // the notes, with their places in the tree
save(scanner.serialize());  // and WalletScanner.restore(...) to carry on later

The scanner takes its events from anything that implements PoolEventSource. The chain reader goes back as far as the node keeps history; a gap shows up as a ScanGapError, and then the events have to come from a source that has all of them.

Facts a client depends on

  • A shield, an unshield and a transfer consume between 220,000 and 242,000 compute units on chain. The default limit is 200,000, so a transaction must request more. COMPUTE_UNIT_LIMIT is 400,000.
  • A proof is bound to what the transaction does outside the circuit. A shield binds the depositor and the amount, a transfer binds the submitter, and an unshield binds the recipient's token account, the relayer's token account, the fee and the amount. A proof submitted for other accounts or amounts is refused by the program.
  • The pool's verification key cannot change once it is installed.
  • A note is announced by an event carrying its commitment and its encrypted secrets. A wallet finds its notes by trying to decrypt each event with its encryption secret and checking that the commitment matches.

Building and testing

npm install
npm run build
npm test

The tests in reference.test.mjs compare the library with values made by the circuit library, which the circuit's tests and the program were checked against. Make those values once, from a checkout of the contracts repository whose circuit library has its dependencies installed:

npm run reference -- <path to the contracts repository>