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

@openlabels/oli-sdk

v0.2.4

Published

TypeScript/JavaScript SDK for querying Open Labels Initiative (OLI) address labels on-chain and off-chain

Downloads

109

Readme

OLI SDK

Type-safe TypeScript/JavaScript client for reading OLI address labels and submitting onchain attestations.

Install

npm install @openlabels/oli-sdk

Modules

| Subpath | Description | |---------|-------------| | @openlabels/oli-sdk | OLIClient, read APIs (oli.api.*), helpers, proxy middleware | | @openlabels/oli-sdk/attest | AttestClient, createDynamicWalletAdapter, write profiles | | @openlabels/oli-sdk/attest-ui | React hooks and unstyled components for attestation UIs | | @openlabels/oli-sdk/projects | Project lookup, typo suggestions, and similarity matching | | @openlabels/oli-sdk/contributions | GitHub PR automation for OSS Directory project onboarding | | @openlabels/oli-sdk/react | Re-export of attest-ui for React-centric import paths |

Getting an API Key

To use protected endpoints in the SDK, you need an API key.

  1. Go to the Open Labels developer portal and click Sign in.
  2. Approve the short GitHub OAuth authorization.
  3. Complete the registration form with your contact email, project name, and intended use. This usually takes less than a minute.
  4. After submitting, your API key is generated instantly and displayed in the portal (shown only once).
  5. Store it securely in your secrets manager or .env file (e.g. OLI_API_KEY=...), then provide it to the SDK via api.apiKey or use the proxy helper for browser apps.

Need full API endpoint documentation? See the OLI API Reference.

Trust & Label Pool Disclaimer

  • The SDK reads from the open OLI label pool (mirrored through the OLI Live REST API, public GitHub exports, and the growthepie API). All records are community-generated and should be considered untrusted data until weighted by your own allow-lists.
  • oli.api.getBestLabelForAddress() removes revoked/expired labels, applies optional filters, sorts by recency, and returns the first hit. There is no attester weighting or trust scoring.
  • oli.api.getValidLabelsForAddress() / helpers.isLabelValid() only check revocation and expiration. "Valid" does not mean "verified" or "safe."
  • Trust algorithms (attester weighting, consensus scoring, label provenance checks) are not yet implemented. Keep humans in the loop or apply your own policy layer before surfacing data to end users. See docs/TRUST.md for details.

Quick Start — Read APIs

Display name for an address

const name = await oli.api.getDisplayName('0x1234...');
console.log(name); // "Uniswap Router" (or fallback short address)

UI-ready address summary

const summary = await oli.api.getAddressSummary('0x1234...', { limit: 50 });

if (!summary) {
  console.log('No labels yet');
} else {
  console.log(summary.displayName, summary.primaryCategory, summary.latestActivity);
}

Bulk labels and search

const bulk = await oli.api.getLabelsBulk({
  addresses: ['0x1234...', '0xABCD...'],
  limit_per_address: 10
});

const paymasters = await oli.api.searchAddressesByTag({
  tag_id: 'is_paymaster',
  tag_value: 'true',
  limit: 20
});

Latest attestations

const feed = await oli.api.getLatestAttestations({ limit: 25 });
feed.forEach(att => {
  console.log(att.recipient, att.contract_name, att.timeCreated);
});

Quick Start — Attest (Write)

Single form flow

import { OLIClient } from '@openlabels/oli-sdk';
import { createDynamicWalletAdapter } from '@openlabels/oli-sdk/attest';

const oli = new OLIClient({ api: { apiKey: process.env.OLI_API_KEY! } });
await oli.init();

const adapter = createDynamicWalletAdapter(primaryWallet, {
  paymasterUrl: process.env.NEXT_PUBLIC_COINBASE_PAYMASTER_URL
});

const input = {
  chain_id: 'eip155:8453',
  address: '0x1234567890123456789012345678901234567890',
  usage_category: 'dex',
  owner_project: 'uniswap'
};

const prepared = await oli.attest.prepareSingleAttestation(input, { mode: 'simpleProfile' });
const result = await oli.attest.submitSingleOnchain(prepared, adapter);
console.log(result.status, result.txHash, result.sponsored);

Bulk CSV flow

const parsed = await oli.attest.parseCsv(csvText);
const validation = await oli.attest.validateBulk(parsed.rows, { mode: 'advancedProfile' });

if (validation.diagnostics.errors.length > 0) {
  console.log('Fix errors before submitting:', validation.diagnostics.errors);
  return;
}

const result = await oli.attest.submitBulkOnchain(validation.validRows, adapter);
console.log(result.status, result.uids);

Client Configuration

import { OLIClient } from '@openlabels/oli-sdk';

const oli = new OLIClient({
  api: {
    apiKey: process.env.OLI_API_KEY!,
    enableCache: true,
    cacheTtl: 30_000
  },
  filters: {
    allowedCategories: ['dex', 'bridge'],
    maxAge: 86_400
  },
  display: {
    addressFormat: 'short',
    dateFormat: 'relative'
  }
});

await oli.init(); // pulls latest tag definitions and value sets

Notable configuration fields

| Path | Description | |------|-------------| | api.apiKey | Required for protected endpoints (/labels, /addresses/search, /analytics). | | filters.allowedCategories / excludedCategories / allowedProjects | Include or exclude categories/projects globally. | | filters.minAge / maxAge | Filter labels by age in seconds. | | display.nameFields / addressFormat / dateFormat | Customize formatting defaults for helper outputs. |

Proxy Helper

Use createProxyHandler in a Next.js API route to forward browser requests to the OLI API while keeping your API key server-side.

// pages/api/oli/[...path].ts
import { createProxyHandler } from '@openlabels/oli-sdk';

export default createProxyHandler({
  apiKey: process.env.OLI_API_KEY!,
  forwardHeaders: ['authorization']
});

Helper Overview

| Helper | Purpose | |--------|---------| | oli.api.getLabels, getLabelsBulk, getAttestations, getAttestationsExpanded | Raw REST payloads. Requires API key for /labels. | | oli.api.getDisplayName, getAddressSummary, getBestLabelForAddress, getValidLabelsForAddress | Higher-level helpers with filtering, ranking, and formatting. | | oli.api.getLatestAttestations, searchAttestations, getAttesterLeaderboard, getAttesterAnalytics, getTagBreakdown | Feed and analytics helpers for dashboards. | | helpers.* | Pure utility helpers (formatting, ranking, REST response expansion) that power oli.api methods. | | oli.fetcher.getOLITags, getOLIValueSets, getFullRawExport | Access raw schema/value-set data and open label pool exports. | | createProxyHandler | Express/Next.js middleware that forwards requests to the OLI API while injecting x-api-key. |

Documentation

| File | Description | |------|-------------| | docs/index.md | Documentation landing page and navigation guide | | docs/ATTEST_QUICKSTART.md | End-to-end attestation walkthrough (single + bulk) | | docs/ATTEST_API.md | Full oli.attest.* method reference and type shapes | | docs/ATTEST_DYNAMIC_WALLET.md | Dynamic wallet adapter setup and sponsorship behavior | | docs/ATTEST_ENV.md | All environment variables with a complete .env template | | docs/ATTEST_UI_COMPONENTS.md | React hooks and unstyled component integration | | docs/PROJECTS_MODULE.md | Project lookup, validation, and similarity matching | | docs/CONTRIBUTIONS_MODULE.md | GitHub PR automation for OSS Directory contributions | | docs/ATTEST_MIGRATION.md | Migrating custom frontend logic to oli.attest.* | | docs/TRUST.md | Trust model, data provenance, and label pool disclaimer |

Development

npm run lint    # ESLint flat config
npm run build   # Bundle to dist/
npm test        # Integration tests (uses tsx)

Tests spin up local listeners. In restricted environments you may need to grant permission for IPC sockets.

License

MIT © Open Labels Initiative