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

@dailydrop/shield

v1.3.0

Published

Proof of Presence verification SDK — verify real humans by their on-chain streak

Readme

@dailydrop/shield

Proof of Presence — verify real humans by their on-chain streak.

npm License: MIT

What's new in v1.3.0

  • Security fix (server-side, no SDK code change needed): /api/relayer — the endpoint that propagates check-ins across chains — previously accepted any successful transaction hash as proof of a check-in without verifying it was sent by the claimed user to the real DailyDrop contract. This let anyone fabricate cross-chain streaks. It's now fixed to validate the transaction sender, recipient, and emitted event before accepting it. This directly affects the accuracy of the streak data this SDK reads, so an upgrade is recommended even though the client API is unchanged.
  • getUserData ABI updated to match the latest DailyDrop.sol (totalCheckIns removed from contract storage — it's now derived off-chain from confirmed transactions)
  • Behavior change: in onChain: true mode, checkins.total is always 0 (no contract storage to read it from). Use the default API mode for an accurate count, or read it yourself from /api/verify.

What's new in v1.2.0

  • Fix: removed broken "import": "dist/index.mjs" from exports (file never existed — ESM consumers failed silently)
  • New exports: STREAK_MASTER_ADDRESS (Base) and STREAK_NFT_ADDRESS (Base) — deployed contract addresses
  • All 5 contract addresses now exported as named constants

What was in v1.1.0

  • verifyBatch() — verify multiple addresses in parallel
  • getProfile() — alias for verify(address, 1) with full data
  • Automatic retry on network errors
  • Configurable timeout (timeout option)
  • Address validation before any network call

Why?

Airdrops get sybil-attacked. DAOs get fake votes. NFT mints get botted.

A streak on-chain can't be faked retroactively. If a wallet showed up every day for 7+ days, it's a real human.

DailyDrop Shield gives any project a one-line sybil check powered by behavioral proof-of-humanity.

Install

npm install @dailydrop/shield

Quick Start

import DailyDropShield from "@dailydrop/shield"

const shield = new DailyDropShield()

// Verify a wallet has 7+ day streak
const result = await shield.verify("0xABC...", 7)
if (result.passed) {
  console.log("✅ Real human — allow airdrop")
} else {
  console.log("❌ Streak too low — reject")
}

// Quick boolean check
const isHuman = await shield.isHuman("0xABC...", 7)

// Get streak number
const streak = await shield.getStreak("0xABC...")

// Get badge level (0=none, 1=weekly, 2=monthly, 3=century)
const badge = await shield.getBadge("0xABC...")

// Verify multiple wallets at once (airdrop filtering)
const results = await shield.verifyBatch([
  "0xABC...",
  "0xDEF...",
  "0x123...",
], 7)

const eligible = Object.entries(results)
  .filter(([, r]) => r.passed)
  .map(([addr]) => addr)

console.log(`${eligible.length} eligible wallets`)

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiUrl | string | https://dailydrop-five.vercel.app | Custom API endpoint | | onChain | boolean | false | Read directly from blockchain | | celoRpc | string | https://forno.celo.org | Custom Celo RPC | | baseRpc | string | https://mainnet.base.org | Custom Base RPC | | timeout | number | 10000 | Fetch timeout in ms |

Response

{
  address: "0xABC...",
  passed: true,           // meets minStreak requirement
  minStreak: 7,

  streak: {
    current: 12,          // highest streak across all chains
    bestChain: "celo",
    celo: 12,
    base: 0,
  },

  badges: {
    level: 1,             // 0=none 1=weekly 2=monthly 3=century
    label: "🥉 Weekly",
    weekly: true,         // 7+ days
    monthly: false,       // 30+ days
    century: false,       // 100+ days
  },

  checkins: {
    total: 36,
    canCheckIn: false,
    canClaim: false,
    nextCheckIn: 1780613801,
  },

  shield: "0x24eFf9bdE979D6dccC869178F353D663bC8A6983",
  meta: {
    verifiedAt: "2026-06-04T08:11:01.983Z",
    celoscan: "https://celoscan.io/address/0xABC...",
    basescan: "https://basescan.org/address/0xABC...",
  }
}

Error handling

try {
  const result = await shield.verify("0xABC...", 7)
} catch (err) {
  if (err.message.includes("invalid Ethereum address")) {
    // Bad address format
  } else if (err.message.includes("timeout")) {
    // Network timeout — retry or use onChain: true
  } else {
    // API error
  }
}

Use Cases

| Use Case | minStreak | |----------|-----------| | Airdrop sybil filter | 7 | | DAO voting weight | 30 | | NFT allowlist | 7 | | DeFi APY boost | 14 | | Exclusive access | 100 |

On-Chain Mode

For maximum trust, verify directly on-chain without the API:

const shield = new DailyDropShield({ onChain: true })
const result = await shield.verify("0xABC...", 7)

Note: checkins.total is always 0 in on-chain mode — total check-in count isn't stored on-chain (gas optimization) and is only derived in the default API mode. Streak, badges, canCheckIn, canClaim, and nextCheckIn are unaffected.

REST API

Free public API — no auth required:

GET https://dailydrop-five.vercel.app/api/verify?address=0xABC&minStreak=7

Contracts

| Contract | Network | Address | |----------|---------|---------| | DailyDrop | Celo Mainnet | 0xd8Cc2a639a8D4e7A75a5B41C28606712e4fDf70b | | DailyDrop | Base Mainnet | 0x974fB504172f2aABbecc698Ebf137202a5E4e495 | | DailyDropShield | Celo Mainnet | 0x24eFf9bdE979D6dccC869178F353D663bC8A6983 | | StreakMaster | Base Mainnet | 0x038F496eCf99ecA5959A40493C96670Ea8a14345 | | StreakNFT | Base Mainnet | 0xbBa5865b3E3A5033730f851d555cc922B74B25Fa |

All 5 addresses are exported as named constants:

import {
  CELO_DAILYDROP,
  BASE_DAILYDROP,
  SHIELD_ADDRESS,
  STREAK_MASTER_ADDRESS,
  STREAK_NFT_ADDRESS,
} from "@dailydrop/shield"

License

MIT © 2026 @wkalidev

Built on Celo & Base · Behavioral Proof of Humanity