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

marc-protocol-sdk

v4.3.0

Published

MARC Protocol SDK — FHE-powered confidential payments for AI agents (ERC-7984, ERC-8004, ERC-8183, x402)

Readme

fhe-x402-sdk

TypeScript SDK for the FHE x402 payment protocol. Encrypts payment amounts with Fully Homomorphic Encryption (FHE) via Zama's fhevmjs, so on-chain balances and transfer amounts remain confidential.

Install

npm install fhe-x402-sdk

Peer dependency:

npm install fhevmjs

Quick Start

Client: Pay for a 402 resource

import { fheFetch } from "fhe-x402-sdk";
import { Wallet, JsonRpcProvider } from "ethers";
import { initFhevm, createInstance } from "fhevmjs";

await initFhevm();
const fhevmInstance = await createInstance({ chainId: 11155111 });
const provider = new JsonRpcProvider("https://ethereum-sepolia-rpc.publicnode.com");
const signer = new Wallet(process.env.PRIVATE_KEY!, provider);

const response = await fheFetch("https://api.example.com/premium", {
  poolAddress: "0xfF87ec6cb07D8Aa26ABc81037e353A28c7752d73",
  rpcUrl: "https://ethereum-sepolia-rpc.publicnode.com",
  signer,
  fhevmInstance,
  maxPayment: 5_000_000n, // 5 USDC max
  timeoutMs: 30_000,
  maxRetries: 2,
  retryDelayMs: 1_000,
});

const data = await response.json();

Server: Paywall middleware (Express)

import express from "express";
import { fhePaywall } from "fhe-x402-sdk";

const app = express();

app.use(
  "/api/premium",
  fhePaywall({
    price: "1000000", // 1 USDC
    asset: "USDC",
    poolAddress: "0xfF87ec6cb07D8Aa26ABc81037e353A28c7752d73",
    recipientAddress: "0xYourAddress",
    rpcUrl: "https://ethereum-sepolia-rpc.publicnode.com",
  })
);

app.get("/api/premium", (req, res) => {
  res.json({ data: "premium content", paidBy: req.paymentInfo?.from });
});

API

fheFetch(url, options): Promise<Response>

x402-aware fetch. Automatically handles 402 responses by encrypting payment via fhevmjs, calling pool.pay() on-chain, and retrying with the Payment header.

| Option | Type | Default | Description | |--------|------|---------|-------------| | poolAddress | string | required | ConfidentialPaymentPool address | | rpcUrl | string | required | Ethereum RPC URL | | signer | ethers.Signer | required | Wallet for signing transactions | | fhevmInstance | FhevmInstance | required | fhevmjs instance for FHE encryption | | maxPayment | bigint | - | Maximum payment amount (6 decimals) | | allowedNetworks | string[] | - | CAIP-2 network filter (e.g. ["eip155:11155111"]) | | dryRun | boolean | false | Return 402 without paying | | timeoutMs | number | 30000 | HTTP request timeout (ms) | | maxRetries | number | 0 | Retry attempts after payment | | retryDelayMs | number | 1000 | Base delay between retries (linear backoff) | | memo | string | 0x0...0 | Optional bytes32 memo attached to payment |

createFheFetch(options): (url, init?) => Promise<Response>

Creates a bound fetch function with pre-configured options.

const secureFetch = createFheFetch({ poolAddress, rpcUrl, signer, fhevmInstance });
const res = await secureFetch("https://api.example.com/data");

FhePaymentHandler

Low-level handler for parsing 402 responses and creating payments.

import { FhePaymentHandler } from "fhe-x402-sdk";

const handler = new FhePaymentHandler(signer, fhevmInstance, {
  maxPayment: 10_000_000n,
  allowedNetworks: ["eip155:11155111"],
  memo: "0x" + "ab".repeat(32),
});

// Parse 402 response
const requirements = await handler.parsePaymentRequired(response);

// Select matching requirement
const selected = handler.selectRequirement(requirements.accepts);

// Create payment (encrypts + sends tx)
const result = await handler.createPayment(selected);
// result.txHash, result.nonce, result.paymentHeader

fhePaywall(config): express.RequestHandler

Express middleware that returns 402 with FHE payment requirements, then verifies PaymentExecuted events on-chain.

| Config | Type | Default | Description | |--------|------|---------|-------------| | price | number \| string | required | USDC amount (6 decimals) | | asset | string | required | Token symbol | | poolAddress | string | required | Pool contract address | | recipientAddress | string | required | Payment recipient | | rpcUrl | string | required | Ethereum RPC URL | | chainId | number | 11155111 | Chain ID | | maxTimeoutSeconds | number | 300 | Payment timeout | | maxRateLimit | number | 60 | Requests per window | | rateLimitWindowMs | number | 60000 | Rate limit window | | minConfirmations | number | 1 | Block confirmations required | | nonceStore | NonceStore | in-memory | Nonce persistence backend |

createFacilitatorServer(config): Promise<express.Application>

Creates a standalone facilitator server with /info, /verify, and /health endpoints.

import { createFacilitatorServer } from "fhe-x402-sdk";

const app = await createFacilitatorServer({
  poolAddress: "0xfF87ec6cb07D8Aa26ABc81037e353A28c7752d73",
  rpcUrl: "https://ethereum-sepolia-rpc.publicnode.com",
  apiKey: process.env.API_KEY,
});

app.listen(3001);

ERC-8004 Helpers

import { fhePaymentMethod, fhePaymentProof } from "fhe-x402-sdk";

// For agent registration files
const method = fhePaymentMethod({
  poolAddress: "0xfF87ec6cb07D8Aa26ABc81037e353A28c7752d73",
  facilitatorUrl: "https://facilitator.example.com",
});

// For feedback proof-of-payment
const proof = fhePaymentProof(nonce, poolAddress);

Error Handling

The SDK provides structured error classes for programmatic error handling:

import {
  FheX402Error,
  PaymentError,
  EncryptionError,
  TimeoutError,
  NetworkError,
  FheErrorCode,
} from "fhe-x402-sdk";

try {
  await fheFetch(url, options);
} catch (err) {
  if (err instanceof PaymentError) {
    console.error("Payment failed:", err.code, err.details);
  } else if (err instanceof EncryptionError) {
    console.error("FHE encryption failed:", err.message);
  } else if (err instanceof TimeoutError) {
    console.error("Request timed out:", err.details?.timeoutMs);
  } else if (err instanceof NetworkError) {
    console.error("Network error after retries:", err.details?.retries);
  }
}

| Error Class | Code | When | |-------------|------|------| | PaymentError | PAYMENT_FAILED | On-chain payment TX reverted | | EncryptionError | ENCRYPTION_FAILED | fhevmjs encryption failed | | VerificationError | VERIFICATION_FAILED | Event verification failed | | TimeoutError | TIMEOUT | HTTP request timeout | | NetworkError | NETWORK_ERROR | All retry attempts exhausted |

Custom Nonce Store

The default in-memory nonce store doesn't survive server restarts. For production, implement the NonceStore interface:

import type { NonceStore } from "fhe-x402-sdk";

class RedisNonceStore implements NonceStore {
  constructor(private redis: Redis) {}

  async check(nonce: string): Promise<boolean> {
    return !(await this.redis.exists(`nonce:${nonce}`));
  }

  async add(nonce: string): Promise<void> {
    await this.redis.set(`nonce:${nonce}`, "1", "EX", 86400);
  }

  async checkAndAdd(nonce: string): Promise<boolean> {
    const result = await this.redis.set(`nonce:${nonce}`, "1", "EX", 86400, "NX");
    return result === "OK";
  }
}

Contract ABI

The SDK exports POOL_ABI with the full ConfidentialPaymentPool V1.2 interface:

import { POOL_ABI } from "fhe-x402-sdk";

Tests

cd sdk && npx vitest run

85 tests covering handler, middleware, fetch, facilitator, ERC-8004, and error classes.

License

BUSL-1.1