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

fangorn-fhe-sdk

v2026.3.8

Published

A zero-knowledge conditional access control framework

Readme

Fangorn

Programmable data.

Overview

Fangorn is a programmable data framework that lets you register datasources and publish encrypted data under public conditions, or predicates, such that it can only be decrypted if you meet the condition(s).

Supported Networks

Fangorn can be deployed on any EVM chain that has a brige to Lit protocol. Currently, contracts are deployed to both Arbitrum Sepolia and Base Sepolia. See the contracts section for more info.

Usage

Fangorn is a programmable data framework. It provides tools to register data sources that can be accessed based on owner-defined conditions, like payment.

CLI/Quickstart

To install the fangorn-sdk from NPM, run:

npm i -g fangorn-sdk

Register a Datasource

First register a datasource

fangorn register name-of-your-datasource-agent

Upload Data

On upload, data is encrypted under a user-specified gadget. For now, the CLI only supports the payment gadget, which is used by specifying the argument -g "Payment(amount)". The minimum amount is 0.000001.

For -c, the CLI supports both arbitrumSepolia and baseSepolia.

fangorn upload name-of-your-datasource-agent file-to-upload.ext -c arbitrumSepolia -g "Payment(0.0001)"

Decrypt and Download

fangorn decrypt [owner] [datasourceName] [tag] -c arbitrumSepolia

Full Guide

Build

pnpm i

Setup

// provide the account, rpcurl, and chain externally
// Initalize a wallet client
const walletClient = createWalletClient({
  account,
  transport: http(rpcUrl),
  chain,
});
// For ArbSep, also supports BaseSepolia (wallet client must match)
const config: AppConfig = FangornConfig.ArbitrumSepolia;
// and the encryption service
const encryptionService = new LitEncryptionService(chain);

// setup the storage client
const pinata = new PinataSDK({
  pinataJwt: jwt,
  pinataGateway: gateway,
});
// we only support pinata right now, more to come
const storage = new PinataStorage(pinata);

// the domain/webserver where Fangorn is used
const domain = "localhost";

const fangorn = await Fangorn.init(
  walletClient,
  storage,
  encryptionService,
  domain,
  config,
);

Datasource Registration

Now that you have a Fangorn client, you can create a datasource. A datasource is an on-chain asset that stores a commitment to its storage root along with an optional agentId field for associating the datasource with an ERC-8004 identity.

const name = "demo";
// id = sha256(name || owner), agentId = ""
const id = await this.delegatorFangorn.registerDataSource(name, "");

Encryption

Once a datasource exists, the owner can update its storage root to point it to data. Fangorn leverages Lit protocol for encryption and access control.

Encryption works by specifying a gadget, code that represents a logical statement that you want to encrypt under. The gadgets framework is extensible and customizable, allowing for easy custom implementations. For now, we have three gadgets:

  • empty wallet: must have an empty wallet to decrypt
  • identity: must have a specific identity to decrypt
  • payment: must submit a specific payment to decrypt
// configure data using a json array, note that all data in this array will be encrypted under the same condition
// each entry has as (tag, data, extension, fileTpe)
let filedata = [
	{
		tag: "test0",
		data: "content0",
		extension: ".txt",
		fileType: "text/plain",
	},
	{
		tag: "test1",
		data: "content1",
		extension: ".png",
		fileType: "image/png",
	},
];

// this encrypts the file under a USDC payment condition, useful for x402
await fangorn.upload(datasourceName, filedata, async (file) => {
	const commitment = await computeTagCommitment(
		this.delegatorAddress,
		datasourceName,
		file.tag,
		usdcPrice,
	);
	return new PaymentGadget({
		commitment: fieldToHex(commitment),
		chainName: this.config.chainName,
		settlementTrackerContractAddress,
		usdcPrice,
	});
});

Decryption

Decryption mandates that the caller has met the condition specified by the ciphertext. If unknown, the condition can be decoded by fetching the entry from storage (pinata) in which we store a gadgetDescriptor, providing pertinent information about the gadget used to encrypt the plaintext and how to satisfy it.

// the address of the owner of the datasource
const owner = "0xabc123...";
// the name of the datasource
const name = "demo";
// the tag of the data we want to fetch
const tag = "test0";

const plaintext = await fangorn.decryptFile(owner, name, tag);
const outputAsString = new TextDecoder().decode(output);
console.log("we got the plaintext " + outputAsString);

Testing

Unit Tests

Run the tests with:

pnpm test

E2E tests

Setup

The e2e test suite requires various environment variables that must be manually configured. In addition, it must be executed on an actual testnet in order to establish comms with Lit protocol.

Testnet tokens (ETH on Base Sepolia) can be obtained from Coinbase's official faucet https://portal.cdp.coinbase.com/

  1. cp .env.example .env
  2. Fill in the ENVs:
    • DELEGATOR_ETH_PRIVATE_KEY: The private key of the delegator account
      • Needs to have a balance of test ETH to send transactions
    • DELEGATEE_ETH_PRIVATE_KEY: The private key of the delegatee account
      • Needs to have a balance of test ETH to send transactions
  • PINATA_JWT: The JWT for Pinata
    • Can be obtained from: https://app.pinata.cloud/developers/api-keys
  • PINATA_GATEWAY: The gateway for Pinata
    • Can use your own gateway or the default 'https://gateway.pinata.cloud'
  • CHAIN_NAME: arbitrumSepolia or baseSepolia
  • CAIP2: The CAIP-2 identifier for the network.
    • 421614 for Arbitrum Sepolia, 84532 for Base Sepolia
  • CHAIN_RPC_URL: The RPC URL of the chain
    • Expected to be Base sepolia testnet: https://base-sepolia-public.nodies.app or Arbitrum Sepolia: https://sepolia-rollup.arbitrum.io/rpc
  • USDC_CONTRACT_ADDRESS: The address of the deployed USDC contract
    • 0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d for Arbitrum Sepolia 0x036CbD53842c5426634e7929541eC2318f3dCF7e for Base Sepolia
  • DS_REGISTRY_ADDR: The address of the deployed data registry contract
    • Can be deployed by the test script, else use 0x5bd547ce3b5964c2fc0325f523679f66de391d6f for Arbitrum Sepolia and 0x6fd0e50073dbd8169bcaf066bb4a4991bfa48eeb on Base Sepolia
  • SETTLEMENT_TRACKER_ADDR: The address of the deployed settlement tracker contract address. This is only needed if you plan to run tests using the payment gadget.
    • Can be deployed by the test script, else use 0x7c6ae9eb3398234eb69b2f3acfae69065505ff69 for Arbitrum Sepolia

Sample:

For Arbitrum Sepolia

CHAIN_NAME=arbitrumSepolia
CAIP2=421614
CHAIN_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
USDC_CONTRACT_ADDRESS=0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d
DS_REGISTRY_ADDR=0x602aedafe1096004d4db591b6537bc39d7ac71a6
SETTLEMENT_TRACKER_ADDR=0x7c6ae9eb3398234eb69b2f3acfae69065505ff69

For Base Sepolia

CHAIN_NAME=baseSepolia
CAIP2=84532
CHAIN_RPC_URL=https://base-sepolia-public.nodies.app
USDC_CONTRACT_ADDRESS=0x036CbD53842c5426634e7929541eC2318f3dCF7e
DS_REGISTRY_ADDR=0x6fd0e50073dbd8169bcaf066bb4a4991bfa48eeb
SETTLEMENT_TRACKER_ADDR=0x708751829f5f5f584da4142b62cd5cc9235c8a18

Running the tests

pnpm test:e2e

The tests will:

  1. Build and deploy the solidity verifier to base sepolia (unless it is defined in .env)
  2. Upload the Lit Action to IPFS (unless it is defined in .env)

Contracts

| | Arbitrum Sepolia | Base Sepolia | | -------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------- | | Datsource Registry Contract Deployment | 0x602aedafe1096004d4db591b6537bc39d7ac71a6 | 0x6fd0e50073dbd8169bcaf066bb4a4991bfa48eeb | | Datsource Registry Contract Code | lib.rs | DSRegistry.sol | | Settlement Tracker Contract Deployment | 0x7c6ae9eb3398234eb69b2f3acfae69065505ff69 | 0x708751829f5f5f584da4142b62cd5cc9235c8a18 | | Settlement Tracker Contract Code | lib.rs | SettlementTracker.sol |

CLI

To install locally:

chmod +x update_cli.sh
./update_cli.sh
Usage: Fangorn [options] [command]

CLI for Fangorn

Options:
  -V, --version                           output the version number
  -h, --help                              display help for command

Commands:
  init                                    Configure your Fangorn credentials
  register [options] <name>               Register a new datasource as an agent.
  upload [options] <name> <files...>      Upload file(s) to a data source
  list [options] <name>                   List contents (index) of a data source
  info [options] <name>                   Get data source info from contract
  entry [options] <name> <tag>            Get info about a specific entry
  decrypt [options] <owner> <name> <tag>  Decrypt a file from a vault
  help [command]                          display help for command

License

MIT