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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@specify-sh/sdk

v0.4.2

Published

JS SDK for Specify Publishers

Readme


Now in beta!

The Specify Publisher SDK enables publishers to serve targeted ad content to users based on their wallet addresses.

Installation

# Using bun
bun add @specify-sh/sdk

# Using npm
npm install @specify-sh/sdk

# Using yarn
yarn add @specify-sh/sdk

Basic Usage

import Specify, { AuthenticationError, ValidationError, NotFoundError, APIError, ImageFormat } from "@specify-sh/sdk";

// Initialize with your publisher key and enable wallet caching
const specify = new Specify({
  publisherKey: "your_publisher_key",
  cacheMostRecentAddress: true // Do not enable this in server environments
});

// Serve content based on wallet address
async function serveContent() {
  try {
    const walletAddress = "0x1234567890123456789012345678901234567890";

    // Serve content with a provided wallet address. The SDK will also use the wallet cache if available.
    const content = await specify.serve(walletAddress, {imageFormat: ImageFormat.LANDSCAPE, adUnitId: "header-banner-1"});

    // Or; serve content solely relying on the addresses cache (Only works if you have cacheAddressesInLocalSession enabled.)
    const content = await specify.serve(undefined, {imageFormat: ImageFormat.SHORT_BANNER, adUnitId: "sidebar-ad-1"});
  } catch (error) {
    if (error instanceof AuthenticationError) {
      // Handle authentication errors
    } else if (error instanceof ValidationError) {
      // Handle validation errors
    } else if (error instanceof NotFoundError) {
      // Handle no ad found error
    } else if (error instanceof APIError) {
      // Handle API errors
    } else {
      // Handle other errors
    }
  }
}

serveContent();

Advanced Usage

Serving content matching across ads multiple addresses

You can provide a list of wallet addresses and we will find the best ad across all of them. This is useful if your users have multiple wallets connected at a given time for example.

// Serve content matching across multiple wallet addresses (max 50).
const addresses = [
  "0x1234567890123456789012345678901234567890",
  "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
  "0x9876543210987654321098765432109876543210"
];

// Serve content with multiple provided addresses + SDK memory.
const content = await specify.serve(addresses, {imageFormat: ImageFormat.LONG_BANNER, adUnitId: "ad-unit-2"});

API Reference

new Specify(config)

Creates a new instance of the Specify client.

  • config.publisherKey - Your publisher API key (required, format: spk_ followed by 30 alphanumeric characters)
  • config.cacheMostRecentAddress - Optional boolean, defaults to false. Set to true to enable caching the most recent wallet data across requests in supported environments (e.g., browser localStorage).

specify.serve(addressOrAddresses, {imageFormat, adUnitId})

Serves content based on the provided wallet address(es).

  • addressOrAddresses - Optional. Single wallet address, array of wallet addresses (max 50), or undefined if relying solely on the cached wallet data. If cacheMostRecentAddress is true, the SDK will attempt to use the cached wallet data if available, either independently or in conjunction with provided addresses.
    • Format: Standard EVM address format: 0x123...
    • Automatically deduplicated by the SDK
  • imageFormat - Required image format from the ImageFormat enum
  • adUnitId - Optional arbitrary string identifier to identify where the ad is being displayed
  • Returns: Promise resolving to ad content object (returns null if no ad is found)

Response Object

interface SpecifyAd {
  walletAddress: string;
  campaignId: string;
  adId: string;
  headline: string;
  content: string;
  ctaUrl: string;
  ctaLabel: string;
  imageUrl: string;
  communityName: string;
  communityLogo: string;
  imageFormat: "LANDSCAPE" | "LONG_BANNER" | "SHORT_BANNER" | "NO_IMAGE";  
  adUnitId?: string;
}

ImageFormat Enum

The ImageFormat enum defines the available image format options:

  • ImageFormat.LANDSCAPE - 16:9 - Landscape-oriented images
  • ImageFormat.LONG_BANNER - 8:1 - Long banner format
  • ImageFormat.SHORT_BANNER - 16:5 - Short banner format
  • ImageFormat.NO_IMAGE - No image, text-only ads

adUnitId String

  • Optional
  • Arbitrary string identifier to identify where the ad is being displayed

Error Types

  • AuthenticationError - Invalid API key format or authentication failure
  • ValidationError - Invalid wallet address format, or too many addresses (>50)
  • NotFoundError - No ad found for the provided address(es)
  • APIError - Network errors or other HTTP errors

Build from Source

Requirements:

# Clone the repository
git clone https://github.com/internetcommunitycompany/specify-publisher-sdk.git
cd specify-publisher-sdk

# Install dependencies
bun install

# Run tests
bun test

# Build the library (output to dist directory)
bun run build

Examples

Check out our examples repository for complete implementation examples in different frameworks and environments.

License

MIT