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

@vaultfire/vns

v1.0.0

Published

Vaultfire Name Service (VNS) — on-chain name resolution for AI agents. Maps human-readable .vns names to wallet addresses.

Readme

Vaultfire Name Service (VNS)

npm version License: MIT Base Solidity

On-chain name service mapping human-readable .vns names to wallet addresses for the Vaultfire AI accountability ecosystem.

VNS is to Vaultfire what ENS is to Ethereum — a human-readable identity layer for AI agents, humans, and AI companions operating in the Vaultfire Protocol. Names like vaultfire-sentinel.vns resolve to verifiable on-chain wallet addresses, enabling trust-based interactions across the ecosystem.

Hub: theloopbreaker.com
Contract: 0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25 on Base mainnet


Table of Contents


Overview

VNS provides a permissionless, on-chain registry for Vaultfire ecosystem identities. Every identity — human, AI companion, or AI agent — maps to a verifiable wallet address. The service is:

  • Free to register — users only pay gas
  • Permissionless — no admin functions, no KYC
  • Multi-chain — Base (primary), Avalanche, and Ethereum
  • Anti-gaming — enforced rules prevent name squatting and Sybil attacks
  • Privacy-first — wallet addresses only, no personal data stored on-chain

Resolution Order

When you resolve a .vns name, the client queries in this order:

  1. VaultfireNameService (0x1437c...) on Base mainnet — the primary on-chain registry
  2. ERC8004IdentityRegistry on Base and Avalanche — the legacy identity registry
  3. Local registry (localStorage cache) — for names registered in the current session

Name Format

[name].vns

Rules:

  • 3–32 characters
  • Lowercase alphanumeric characters (a-z, 0-9) and hyphens only
  • Cannot start or end with a hyphen
  • No consecutive hyphens (--)
  • Case-insensitive (always stored as lowercase)

Examples:

ghostkey316.vns          ✓ valid
vaultfire-sentinel.vns   ✓ valid
my-ai-agent-v2.vns       ✓ valid
-invalid.vns             ✗ starts with hyphen
my--name.vns             ✗ consecutive hyphens
toolong-toolong-toolong-toolong-toolong.vns ✗ exceeds 32 chars

Reserved names: vaultfire, embris, admin, root, system, protocol, vns, null, undefined, ghostkey


Identity Types

VNS supports three identity types, each with different rules and requirements:

Human ("human")

  • Represents a real person
  • One per wallet address — enforced at registration
  • No bond required — only gas
  • Sets the user's primary identity in the ecosystem

AI Companion ("companion")

  • An AI companion paired with a human identity
  • One per human identity — you must register a human name first
  • No bond required — only gas
  • Tied on-chain to the human's wallet address

AI Agent ("agent")

  • AI agents deployed by developers, companies, or protocols
  • Unlimited per wallet — deploy as many agents as needed
  • Accountability bond required — minimum 0.01 ETH
  • Bond amount determines trust tier (bronze / silver / gold / platinum)

The identity type is encoded in the on-chain description field as JSON:

{"type":"agent","spec":["research"],"caps":["nlp"],"v":1}

This is readable by any indexer without requiring a custom ABI.


Anti-Gaming Rules

VNS enforces six anti-gaming rules to maintain ecosystem integrity:

| Rule | Description | |------|-------------| | One human per wallet | Each address can hold exactly one human type VNS name | | One companion per human | Each human identity gets exactly one AI companion | | Bond-backed agents | All agent registrations require a minimum 0.01 ETH bond | | No name squatting | Names must be backed by a real on-chain transaction | | Duplicate prevention | Case-insensitive uniqueness enforced across the registry | | Bot prevention | Registration requires gas — bots cannot register freely |


Quick Start

Install

# From npm (when published)
npm install @vaultfire/vns ethers

# From GitHub (works now)
npm install github:Ghostkey316/vaultfire-vns ethers

Resolve a .vns name

import { resolver } from '@vaultfire/vns';

const profile = await resolver.resolve('vaultfire-sentinel');
if (profile) {
  console.log(profile.address);     // "0xc48e2fD9D51b94eBF4965711DD1caa25070c95dB"
  console.log(profile.identityType); // "agent"
  console.log(profile.bondTier);    // "gold"
}

Reverse resolve an address to its name

import { reverseResolveVNS } from '@vaultfire/vns';

const name = await reverseResolveVNS('0xA054f831B562e729F8D268291EBde1B2EDcFb84F');
console.log(name); // "vaultfire-sentinel.vns"

Check name availability

import { checkVNSAvailability } from '@vaultfire/vns';

const avail = await checkVNSAvailability('my-new-agent');
if (avail.available) {
  console.log('Name is free — register it!');
} else {
  console.log(`Taken by ${avail.takenBy}`);
}

Register a human identity (free, gas only)

import { registerVNSName } from '@vaultfire/vns';

const result = await registerVNSName(
  '0xYourWalletAddress',
  '0xYourPrivateKey',      // Never hardcode in production — use env vars
  'my-human-identity',
  'human',
  'base'
);

if (result.success) {
  console.log(`Registered! Tx: ${result.txHash}`);
  console.log(`Explorer: ${result.explorerUrl}`);
}

Register an AI agent with accountability bond

import { registerVNSName, stakeAgentBond } from '@vaultfire/vns';

// Step 1: Register identity
const identity = await registerVNSName(
  walletAddress,
  privateKey,
  'my-research-agent',
  'agent',
  'base',
  {
    description: 'AI research agent for blockchain data analysis',
    specializations: ['research', 'data-analysis'],
    capabilities: ['nlp', 'code-review'],
    bondAmountEth: 0.05,  // Silver tier
  }
);

// Step 2: Stake accountability bond
if (identity.success) {
  const bond = await stakeAgentBond(
    walletAddress,
    privateKey,
    'my-research-agent',
    0.05,  // ETH
    'base'
  );
  console.log(`Bond staked: ${bond.txHash}`);
}

Resolve to payment address (for x402 integrations)

import { resolvePaymentAddress } from '@vaultfire/vns';

// Accepts .vns name or raw address
const result = await resolvePaymentAddress('vaultfire-sentinel.vns');
if (result) {
  console.log(result.address);  // payment address (may differ from identity address)
  console.log(result.vnsName);  // "vaultfire-sentinel.vns"
}

API Reference

Core Functions

| Function | Description | |----------|-------------| | resolveVNSName(name) | Resolve a .vns name to a full profile | | getProfileByAddress(address) | Get profile by wallet address | | checkVNSAvailability(name) | Check if a name is available | | reverseResolveVNS(address) | Get .vns name for an address | | resolvePaymentAddress(nameOrAddr) | Resolve to payment address | | registerVNSName(...) | Register a new name on-chain | | stakeAgentBond(...) | Stake accountability bond for agent | | estimateVNSRegistrationGas(...) | Estimate gas before registering |

Validation Functions

| Function | Description | |----------|-------------| | validateVNSName(input) | Validate name format — returns { valid, error?, normalized? } | | formatVNSName(name) | Add .vns suffix and normalize | | stripVNSSuffix(name) | Remove .vns suffix | | validateRegistrationRules(wallet, type, name, bond?) | Check anti-gaming rules | | parseIdentityType(description) | Parse identity type from on-chain description | | getBondTier(ethAmount) | Get tier for a bond amount |

Anti-Gaming Functions

| Function | Description | |----------|-------------| | getHumanVNSForAddress(address) | Get human name for a wallet | | getCompanionVNSForAddress(address) | Get companion name for a wallet | | getAgentVNSNamesForAddress(address) | Get all agent names for a wallet | | isRegisteredAgent(address) | Check if address has bonded agent identity |

User Identity Helpers

| Function | Description | |----------|-------------| | getMyVNSName() | Get current user's stored name | | setMyVNSName(name) | Set current user's primary name | | getMyVNSFullName() | Get full .vns name | | getMyIdentityType() | Get current user's identity type |

Payment Preferences

| Function | Description | |----------|-------------| | setPaymentPreferences(name, prefs) | Set payment address and currency | | getPaymentCapableAgents() | List agents that accept payments |

VNSResolver Class

A clean, stateless resolution API:

import { VNSResolver, resolver } from '@vaultfire/vns';

// Use the singleton
const profile = await resolver.resolve('ghostkey316');
const name = await resolver.reverseResolve('0x...');
const addr = await resolver.resolveToAddress('ghostkey316');
const payment = await resolver.resolveToPayment('ghostkey316.vns');
const avail = await resolver.checkAvailability('my-name');

// Batch operations
const profiles = await resolver.batchResolve(['name1', 'name2', 'name3']);
const names = await resolver.batchReverseResolve(['0x...', '0x...']);

// Synchronous helpers (no network)
const valid = resolver.isValidName('my-agent');
const full = resolver.normalize('MY-AGENT'); // → 'my-agent.vns'
const bare = resolver.strip('my-agent.vns'); // → 'my-agent'

ABI Encoding Helpers

For direct contract interaction:

import { encodeAddress, encodeUint256, encodeString, abiEncodeStringCall } from '@vaultfire/vns';

// Encode calldata for isNameAvailable(string)
const calldata = abiEncodeStringCall('0x8cf44d21', 'my-agent');

// Encode individual types
const addr32 = encodeAddress('0x...');   // 64-char hex (32 bytes, left-padded)
const uint32 = encodeUint256(42);        // 64-char hex
const str = encodeString('hello');       // length-prefixed, padded to 32 bytes

Bond Tiers

AI agents must stake an accountability bond. The bond amount determines the agent's trust tier and visibility in the Vaultfire Hub.

| Tier | Min ETH | Color | Description | |------|---------|-------|-------------| | Bronze | 0.01 ETH | #CD7F32 | Entry-level. Required minimum. Basic trust signal. | | Silver | 0.05 ETH | #C0C0C0 | Mid-tier. Stronger accountability commitment. | | Gold | 0.10 ETH | #FFD700 | High tier. Serious operator signal. Priority listing. | | Platinum | 0.50 ETH | #E5E4E2 | Elite tier. Maximum trust and Hub visibility. |

Bond amounts are sent as ETH value to the AIPartnershipBondsV2 contract. Bonds are recoverable under the Vaultfire dispute resolution process.

import { getBondTier, getBondTierInfo, BOND_TIERS } from '@vaultfire/vns';

getBondTier(0.05);  // → 'silver'
getBondTier(0.5);   // → 'platinum'

const info = getBondTierInfo('gold');
// → { label: 'Gold', minEth: 0.1, color: '#FFD700', accent: '#5B21B6' }

Contract Addresses

VaultfireNameService

| Network | Address | |---------|---------| | Base (primary) | 0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25 |

ERC8004IdentityRegistry

| Network | Address | |---------|---------| | Base | 0x35978DB675576598F0781dA2133E94cdCf4858bC | | Avalanche | 0x57741F4116925341d8f7Eb3F381d98e07C73B4a3 | | Ethereum | 0x1A80F77e12f1bd04538027aed6d056f5DCcDCD3C |

AIAccountabilityBondsV2

| Network | Address | |---------|---------| | Base | 0xf92baef9523BC264144F80F9c31D5c5C017c6Da8 | | Avalanche | 0xaeFEa985E0C52f92F73606657B9dA60db2798af3 | | Ethereum | 0x11C267C8A75B13A4D95357CEF6027c42F8e7bA24 |

AIPartnershipBondsV2

| Network | Address | |---------|---------| | Base | 0xC574CF2a09B0B470933f0c6a3ef422e3fb25b4b4 | | Avalanche | 0xea6B504827a746d781f867441364C7A732AA4b07 | | Ethereum | 0x247F31bB2b5a0d28E68bf24865AA242965FF99cd |

PrivacyGuard

| Network | Address | |---------|---------| | Base | 0xE2f75A4B14ffFc1f9C2b1ca22Fdd6877E5BD5045 | | Avalanche | 0xc09F0e06690332eD9b490E1040BdE642f11F3937 | | Ethereum | 0x8aceF0Bc7e07B2dE35E9069663953f41B5422218 |


Smart Contract

The VaultfireNameService contract (contracts/VaultfireNameService.sol) is a simple, permissionless registry with no admin functions.

Key Properties

  • No admin functions — fully permissionless
  • One name per address — enforced on-chain
  • Case-sensitive storage — client normalizes to lowercase before calling
  • Gas-only — registration costs no ETH beyond gas

Interface

// Register a .vns name for msg.sender
function registerName(string calldata name) external;

// Resolve name → address
function resolveNameToAddress(string calldata name)
    external view returns (address owner, uint256 registeredAt, bool exists);

// Reverse resolve address → name
function resolveAddressToName(address addr)
    external view returns (string memory name, bool hasRegistered);

// Check availability
function isNameAvailable(string calldata name)
    external view returns (bool available);

// Check if address has a name
function hasRegisteredName(address addr)
    external view returns (bool);

// Transfer name to new address
function transferName(address newOwner) external;

// Release name (makes it available again)
function releaseName() external;

Function Selectors

For direct RPC calls without ABI files:

| Function | Selector | |----------|----------| | isNameAvailable(string) | 0x8cf44d21 | | resolveNameToAddress(string) | 0xabf600cc | | resolveAddressToName(address) | 0x13fee8d3 | | registerName(string) | 0x0830602b |

Events

event NameRegistered(string indexed nameIndexed, string name, address indexed owner, uint256 timestamp);
event NameTransferred(string indexed nameIndexed, string name, address indexed previousOwner, address indexed newOwner, uint256 timestamp);
event NameReleased(string indexed nameIndexed, string name, address indexed previousOwner, uint256 timestamp);

Direct Contract Interaction (no SDK)

// Check availability via eth_call
const calldata = abiEncodeStringCall('0x8cf44d21', 'my-agent');
const response = await fetch('https://mainnet.base.org', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'eth_call',
    params: [
      { to: '0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25', data: calldata },
      'latest',
    ],
  }),
});
const { result } = await response.json();
const available = result.slice(-1) === '1'; // true if available

Integration Guide

Integration with vaultfire-x402 (Pay by .vns name)

VNS enables x402 micropayments using human-readable names instead of raw addresses:

import { resolvePaymentAddress } from '@vaultfire/vns';

// In your x402 payment flow:
async function payByVNS(vnsName: string, amountUsdc: number) {
  const resolved = await resolvePaymentAddress(vnsName);
  if (!resolved) throw new Error(`Cannot resolve ${vnsName}`);

  // resolved.address is the payment address
  // resolved.vnsProfile?.preferredCurrency is the preferred token
  await x402.pay({
    to: resolved.address,
    amount: amountUsdc,
    currency: resolved.vnsProfile?.preferredCurrency ?? 'USDC',
  });
}

Integration with vaultfire-xmtp (Identity in Messages)

VNS provides named identities for XMTP message threads:

import { reverseResolveVNS, getProfileByAddress } from '@vaultfire/vns';

// Show .vns name in message UI instead of raw address
async function getSenderDisplay(senderAddress: string) {
  const vnsName = await reverseResolveVNS(senderAddress);
  if (vnsName) {
    const profile = await getProfileByAddress(senderAddress);
    return {
      displayName: vnsName,
      identityType: profile?.identityType ?? 'agent',
      bondTier: profile?.bondTier,
      isVerified: !!profile?.hasBond,
    };
  }
  return { displayName: `${senderAddress.slice(0, 6)}...${senderAddress.slice(-4)}` };
}

On-Chain Hub Stats

import { getOnChainHubStats, getOnChainAgents } from '@vaultfire/vns';

// Live stats from Base and Avalanche (no hardcoded values)
const stats = await getOnChainHubStats();
console.log(`Total identities: ${stats.totalIdentities}`);
console.log(`Active bonds: ${stats.activeBonds}`);
console.log(`ETH bonded: ${stats.totalBondedEth} ETH`);

// All on-chain agents
const agents = await getOnChainAgents();
agents.forEach(a => console.log(`${a.fullName} — ${a.identityType}`));

Verify Contract Liveness

import { verifyContractAlive, VNS_CONTRACT_ADDRESS } from '@vaultfire/vns';

const alive = await verifyContractAlive('base', VNS_CONTRACT_ADDRESS);
console.log(`VNS contract alive: ${alive}`);

Examples

The examples/ directory contains runnable examples:

| File | Description | |------|-------------| | resolve-name.ts | Resolve .vns names to profiles | | reverse-lookup.ts | Address → .vns name reverse resolution | | check-availability.ts | Check name availability | | register-name.ts | Register a human or companion name | | agent-registration.ts | Full agent registration with bond |

Run any example:

# Check availability (no wallet needed)
npx ts-node examples/check-availability.ts

# Resolve names (no wallet needed)
npx ts-node examples/resolve-name.ts

# Register (requires wallet + ETH for gas)
PRIVATE_KEY=0x... WALLET=0x... npx ts-node examples/register-name.ts

Development

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

# Type check
npm run typecheck

# Watch mode
npm run dev

Architecture Notes

Why Two Registries?

VNS runs on top of two contracts:

  1. VaultfireNameService (0x1437c...) — Simple, dedicated name registry for .vns names. Primary on-chain source of truth. Base mainnet only.

  2. ERC8004IdentityRegistry — Multi-chain identity registry used by the broader Vaultfire Protocol. Supports Base, Avalanche, and Ethereum. Stores richer metadata (description, specializations, capabilities) as JSON in the description field.

The SDK queries both, with VaultfireNameService taking precedence.

localStorage Cache

The SDK uses a 5-minute localStorage cache to avoid redundant RPC calls. The cache stores up to 50 entries and evicts the oldest when full. The cache key format is vns_{normalizedName}.

Identity Type Encoding

Identity types are not stored as a separate on-chain field — they are encoded in the description JSON:

{"type":"agent","spec":["research"],"caps":["nlp"],"v":1,"desc":"Optional description"}

Any indexer or client can decode this without a custom ABI or contract upgrade. The v field is a schema version for forward compatibility.


Ecosystem

| Package | Description | |---|---| | @vaultfire/x402 | x402 payment protocol — pay agents by .vns name via USDC | | @vaultfire/xmtp | Trust-gated encrypted agent messaging with VNS identity | | @vaultfire/sdk | Core SDK — belief verification, attestations, agent reputation | | vaultfire-contracts | Canonical contract registry — all deployed ABIs and addresses |


License

MIT — see LICENSE


Vaultfire Protocol · theloopbreaker.com
AI accountability infrastructure on Base and Avalanche mainnet.