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

@newtype-ai/nit-sdk

v0.5.1

Published

Verify agent identity with one function call

Readme

@newtype-ai/nit-sdk

Verify AI agent identity with one function call. No crypto, no OAuth, no secrets needed.

Install

npm install @newtype-ai/nit-sdk

Usage

import { verifyAgent, NitSdkError } from '@newtype-ai/nit-sdk';

// The agent sends you a login payload (generated by `nit sign --login your-app.com`)
const result = await verifyAgent(payload, {
  policy: { max_identities_per_machine: 10, min_age_seconds: 3600 },
  timeoutMs: 5_000, // optional, default 10s
});

if (result.verified && result.admitted) {
  // result.agent_id — the agent's permanent UUID
  // result.card — the agent's card for your domain (skills, description, etc.)
  // result.wallet — { solana, evm } chain addresses
  // result.identity — registration time, machine/IP identity counts, login history
  // result.readToken — for fetching updated cards later
  console.log(`Welcome, ${result.card?.name}`);
} else if (result.verified && !result.admitted) {
  console.log('Identity verified but does not meet trust policy');
} else {
  console.log(`Verification failed: ${result.error}`);
}

How It Works

  1. The agent runs nit sign --login your-app.com to generate a signed login payload
  2. The agent sends the payload to your app
  3. Your app calls verifyAgent(payload, { policy }) — this hits api.newtype-ai.org/agent-card/verify
  4. You get back { verified, admitted, agent_id, card, identity, attestation, ... } or { verified: false, error }

The server acts as an identity registry — it stores identity metadata, evaluates your trust policy, and returns a decision alongside raw signals. Like Stripe Radar: evaluates rules server-side for convenience, returns metadata for transparency.

API

verifyAgent(payload, options?)

| Parameter | Type | Description | |-----------|------|-------------| | payload | LoginPayload | { agent_id, domain, timestamp, signature } from the agent | | options.apiUrl | string | Override API URL (default: https://api.newtype-ai.org) | | options.policy | VerifyPolicy | Trust rules the server evaluates (all optional) | | options.timeoutMs | number | Fetch timeout in milliseconds (default: 10000) |

Policy fields:

| Field | Type | Description | |-------|------|-------------| | max_identities_per_ip | number | Reject if too many identities from same registration IP | | max_identities_per_machine | number | Reject if too many identities from same machine | | min_age_seconds | number | Reject identities younger than this (e.g., 5) | | max_login_rate_per_hour | number | Reject if login rate is too high |

Returns Promise<VerifyResult>:

| Field | Type | Description | |-------|------|-------------| | verified | boolean | Ed25519 signature is valid | | admitted | boolean | Identity meets your policy (true if no policy specified) | | agent_id | string | Agent's permanent UUID | | card | AgentCard | Agent's card for your domain | | branch | string | Which branch the card came from (domain or "main") | | wallet | { solana, evm } | Chain addresses | | readToken | string | For fetching updated cards (30-day expiry) | | identity | IdentityMetadata | Registration time, machine/IP counts, login history | | attestation | ServerAttestation | Server's Ed25519 signature over the result |

NitSdkError

Typed error thrown by fetchAgentCard() on non-404 HTTP failures and malformed responses.

| Property | Type | Description | |----------|------|-------------| | message | string | Human-readable error description | | status | number | HTTP status code (0 for shape validation failures) |

import { fetchAgentCard, NitSdkError } from '@newtype-ai/nit-sdk';

try {
  const card = await fetchAgentCard(agentId, 'your-app.com', readToken);
} catch (err) {
  if (err instanceof NitSdkError) {
    console.error(`SDK error (HTTP ${err.status}): ${err.message}`);
  }
}

fetchAgentCard(agentId, domain, readToken, options?)

| Parameter | Type | Description | |-----------|------|-------------| | options.baseUrl | string | Override card hosting URL (default: https://agent-{id}.newtype-ai.org) | | options.timeoutMs | number | Fetch timeout in milliseconds (default: 10000) |

Returns Promise<AgentCard | null>null for 404, throws NitSdkError for other HTTP errors.

Runtime (LLM provider identity)

The identity object includes self-declared runtime fields — which LLM provider, model, and harness powers the agent. These are untrusted (the agent declares them), but useful for display and consistency checks:

if (result.verified && result.identity) {
  // Display which LLM powers this agent (self-declared)
  console.log(`Agent powered by ${result.identity.runtime_provider} / ${result.identity.runtime_model}`);

  // Consistency check — flag if the agent has changed providers over time
  if (result.identity.distinct_runtime_providers > 1) {
    console.warn('Agent has switched LLM providers over time');
  }
}

Phase 2 will add cryptographic attestation for some providers (Hugging Face, ChatGPT OAuth).

Security

  • HTTPS enforcement: Custom apiUrl and baseUrl must use https://. Localhost (127.0.0.1, localhost) is exempt for development. Non-HTTPS URLs throw TypeError.
  • Input validation: verifyAgent validates the payload before sending: agent_id must be a UUIDv5 nit agent id, domain must follow nit branch-name rules, timestamp must be a finite positive number, and signature must be a 64-byte standard base64 Ed25519 signature.
  • Response shape checks: After parsing JSON responses, the SDK verifies the expected shape (verified must be boolean, card must have name string) before returning. Malformed responses are returned as { verified: false, error: '...' }.

Full Integration Guide

See docs/app-integration.md for the complete flow, endpoint spec, code examples in multiple languages, fetching updated cards, and security notes.

License

MIT