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

@obscura-fhe/sdk

v1.0.4

Published

Official TypeScript SDK for Obscura Pay, Credit, and Vote on Arbitrum Sepolia

Downloads

634

Readme

@obscura-fhe/sdk

Official TypeScript SDK for Obscura Pay, Credit, and Vote on Arbitrum Sepolia.

Privacy-first DeFi with FHE (Fully Homomorphic Encryption). Framework-agnostic — works in Node.js, browsers, Vite, Next.js, and automation scripts.

Install

npm install @obscura-fhe/sdk viem

viem is a peer dependency (v2+). You must install it alongside the SDK.

Requirements at a glance

| Module | Wallet | RPC / chain | Supabase | FHE provider | |--------|--------|-------------|----------|--------------| | reputation | No | No | No | No | | notifications | No | No | No | No | | activity | No | No | Yes (URL + anon key) | No | | pay / credit / vote reads | No | Yes (default RPC) | No | No | | Encrypted writes (buildShield, etc.) | Optional* | Yes | No | Yes (or pre-encrypted input) | | sendCall() | Yes (walletClient) | Yes | No | If write needs FHE |

*Use encodeCall() and sign externally if you do not inject walletClient.

Network: Arbitrum Sepolia (chainId 421614) by default.

Quick start

import { ObscuraSDK } from "@obscura-fhe/sdk";

const sdk = ObscuraSDK.create({
  // Required for activity feed only:
  supabaseAnonKey: process.env.OBSCURA_SUPABASE_ANON_KEY,
  // supabaseUrl defaults to Obscura production project
});

// Reputation — no wallet, no Supabase
const summary = await sdk.reputation.getSummary("0xYourWallet...");
console.log(summary.tier, summary.totalCappedWeight);

// Activity — requires supabaseAnonKey
if (sdk.activity.isConfigured()) {
  const { items } = await sdk.activity.listForWallet("0xYourWallet...", { filter: "credit" });
  console.log(items.length);
}

// On-chain read — uses default Arbitrum Sepolia RPC
const proposalCount = await sdk.vote.getProposalCount(); // reads nextProposalId()
const balanceCt = await sdk.pay.getShieldedBalance("0xYourWallet...");

viem integration (recommended)

Pass an explicit RPC URL and viem clients when you need custom transport, account abstraction, or sendCall():

import { ObscuraSDK } from "@obscura-fhe/sdk";
import { createPublicClient, createWalletClient, http, custom } from "viem";
import { arbitrumSepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";

const rpcUrl = process.env.ARB_SEPOLIA_RPC_URL ?? "https://sepolia-rollup.arbitrum.io/rpc";

const publicClient = createPublicClient({
  chain: arbitrumSepolia,
  transport: http(rpcUrl),
});

// Browser wallet (MetaMask, etc.)
const walletClient = createWalletClient({
  chain: arbitrumSepolia,
  transport: custom(window.ethereum),
});

// Or Node with private key
// const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// const walletClient = createWalletClient({ account, chain: arbitrumSepolia, transport: http(rpcUrl) });

const sdk = ObscuraSDK.create({
  chainId: 421614,
  rpcUrl,
  publicClient,
  walletClient,
  supabaseUrl: process.env.OBSCURA_SUPABASE_URL,
  supabaseAnonKey: process.env.OBSCURA_SUPABASE_ANON_KEY,
});

// Shorthand — SDK creates publicClient from rpcUrl when publicClient omitted:
const sdkMinimal = ObscuraSDK.create({ rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc" });

Activity module — Supabase setup

The activity feed reads indexed on-chain events from Supabase (obscura_activity). Both credentials are required:

import { ObscuraSDK, DEFAULT_SUPABASE_URL } from "@obscura-fhe/sdk";

const sdk = ObscuraSDK.create({
  supabaseUrl: process.env.OBSCURA_SUPABASE_URL ?? DEFAULT_SUPABASE_URL,
  supabaseAnonKey: process.env.OBSCURA_SUPABASE_ANON_KEY!, // required
});

if (!sdk.activity.isConfigured()) {
  throw new Error("Set OBSCURA_SUPABASE_ANON_KEY for activity queries");
}

const { items, hasMore } = await sdk.activity.listForWallet(wallet, {
  filter: "vote", // all | pay | credit | vote | stream | ...
  page: 0,
  pageSize: 20,
});

Environment variables:

OBSCURA_SUPABASE_URL=https://quoovjkjwgtdqwdofubh.supabase.co   # optional — this is the default
OBSCURA_SUPABASE_ANON_KEY=eyJ...                                 # required for activity

Get the anon key from Supabase → Project Settings → API → anon public key.

TypeScript setup

The SDK ships ESM + CJS with .d.ts types. Recommended tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "verbatimModuleSyntax": true
  }
}

verbatimModuleSyntax

With verbatimModuleSyntax: true, TypeScript requires type-only imports for types:

// Correct
import { ObscuraSDK } from "@obscura-fhe/sdk";
import type { FheProvider, ReputationSummary, ContractCall } from "@obscura-fhe/sdk";

// Wrong — TS1363 error under verbatimModuleSyntax
import { FheProvider, ReputationSummary } from "@obscura-fhe/sdk";

If you cannot use type-only imports, set "verbatimModuleSyntax": false or use "isolatedModules": true without verbatim (Vite/Next default).

Module examples

See examples/ for runnable scripts:

| File | Module | |------|--------| | examples/reputation.ts | Reputation summary | | examples/activity.ts | Activity feed (Supabase) | | examples/notifications.ts | VAPID + prefs | | examples/pay.ts | Shielded balance + transfer builder | | examples/credit.ts | Market address + borrow builder | | examples/vote.ts | Proposal count + delegate | | examples/basic-usage.ts | Combined smoke test |

Run: npm run example:basic or npx tsx examples/reputation.ts

Configuration reference

ObscuraSDK.create({
  chainId: 421614,                    // default: Arbitrum Sepolia
  rpcUrl: "https://...",              // default: Arbitrum Sepolia public RPC
  apiUrl: "https://...",              // default: obscura-api production
  supabaseUrl: "https://...",         // default: Obscura Supabase project
  supabaseAnonKey: "...",             // required for activity module
  addresses: { ocUSDC_Pay: "0x..." }, // override deployment registry
  publicClient,                       // inject viem PublicClient
  walletClient,                       // optional — for sdk.sendCall()
  fhe: myFheAdapter,                   // optional — for encrypted writes
});

FHE (encrypted writes)

Encrypted contract inputs require a host-supplied FheProvider (typically wrapping @fhenixprotocol/cofhe-sdk):

import type { FheProvider } from "@obscura-fhe/sdk";

const fhe: FheProvider = {
  async encryptUint64(value, { contractAddress }) {
    // wrap CoFHE encrypt — user-triggered only
    return { ctHash, securityZone, utype, signature };
  },
};

const sdk = ObscuraSDK.create({ fhe });
await sdk.pay.buildShield(1000n); // encrypts via adapter

// Or pass pre-encrypted input directly:
await sdk.pay.buildShield(1000n, preEncryptedInEuint64);

Sending transactions

const call = sdk.vote.buildDelegate("0xDelegatee...");
const hash = await sdk.sendCall(call, account); // requires walletClient

Modules

| Module | Methods | Backend | |--------|---------|---------| | pay | getShieldedBalance, buildShield, buildUnshield, buildTransfer | On-chain (ocUSDC_Pay) | | credit | getMarketAddress, buildSupplyCollateral, buildBorrow, buildRepay | On-chain (credit market) | | vote | getProposalCount, getProposal, buildCastVote, buildDelegate | On-chain (ObscuraVote) | | reputation | getSummary | obscura-api REST | | activity | listForWallet, getEventFilters, isConfigured | Supabase | | notifications | getVapidPublicKey, getPrefs, savePrefs, subscribe, unsubscribe | obscura-api REST |

Defaults (Arbitrum Sepolia)

| Setting | Value | |---------|-------| | Chain ID | 421614 | | RPC | https://sepolia-rollup.arbitrum.io/rpc | | Supabase URL | https://quoovjkjwgtdqwdofubh.supabase.co | | ocUSDC_Pay | 0xEd46020Df8abe7BB1E096f27d089F4326D223a53 | | Vote | 0xe358776AfdbA95d7c9F040e6ef1f5A021aF91730 | | Credit market | 0x1Ec113297c7F9516A6604aa3b18C180559a6f551 | | API | https://obscura-api-n62v.onrender.com |

Exports

Core: ObscuraSDK, ObscuraSDKConfig, ContractCall, InEuint64, FheProvider, FheRequiredError

Types: ReputationSummary, ActivityItem, NotificationPrefs, ProposalState, …

Constants: DEFAULT_ADDRESSES, DEFAULT_SUPABASE_URL, ARBITRUM_SEPOLIA_CHAIN_ID, ACTIVITY_EVENT_FILTERS

Utilities: encodeCall, normalizeWallet, toContractInEuint64, HttpError

License

MIT — see LICENSE.