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

@leashmarket/sdk

v0.3.3

Published

Typed Leash API client for app developers. Discover services, vet counterparties, manage agent webhooks, and ingest receipts in any TypeScript runtime.

Downloads

154

Readme

@leashmarket/sdk

Typed TypeScript client for the public Leash API. Use it from any JavaScript runtime — browsers, Bun, Deno, Node, edge — to:

  • Search the agent marketplace (leash.discover)
  • Resolve and verify agent identities (leash.resolveIdentity, leash.verifyIdentity)
  • Ask for trust verdicts before agent-to-agent calls (leash.verifyIdentityDecision, leash.verifyCapabilitySeller)
  • Read shareable selective-disclosure links (leash.readIdentityDisclosure)
  • Update the active agent's handle, capability cards, claims, domains, and selective disclosures with X-Leash-Sig
  • Vet a counterparty's reputation (leash.reputation)
  • Record a client-minted agent on the platform (leash.recordAgent)
  • Create/list/revoke agent-owned API keys with X-Leash-Sig
  • Manage agent-scoped webhooks signed with X-Leash-Sig
  • Pull receipts for an agent (legacy API-key auth)
  • Create + manage x402/MPP payment links, including upstream API paywalls with expected POST body metadata (legacy API-key auth)

Provisioning agents (generating keypairs, minting MPL Core assets, setting USDC delegation) is not in the SDK — use @leashmarket/mcp (mintAgentLocally()) or the leash agent create CLI for that. The SDK is for "remote control" of agents that already exist; the MCP is the engine that creates them.

Install

pnpm add @leashmarket/sdk
# or
npm install @leashmarket/sdk

Quickstart

import { LeashClient } from '@leashmarket/sdk';

const leash = new LeashClient({ baseUrl: 'https://api.leash.market' });

// 1. Marketplace browse — public, no auth.
const services = await leash.discover({ capability: 'ocr', max_price_usdc: 0.1 });
const first = services.items[0];
if (first.seller_identity) {
  console.log('seller identity', first.seller_identity.mint, first.seller_identity.reputation);
}

// 2. Reputation lookup before paying — public, no auth.
const rep = await leash.reputation({
  agentMint: services.items[0].seller_agent_mint!,
});
if (rep.rating < 0.5) throw new Error('seller has too low a rating');

// 3. Resolve or verify identity selectors — public, no auth.
const profile = await leash.resolveIdentity({ handle: 'payce-demo' });
const verdict = await leash.verifyIdentity({ mint: profile.mint });
if (!verdict.verified) throw new Error('identity did not verify');

const decision = await leash.verifyIdentityDecision({
  selector: { mint: profile.mint },
  intent: 'pay',
  capability: { slug: 'agentmail/email', protocol: 'x402' },
  thresholds: { require_verified_domain: true },
});
if (decision.verdict === 'deny') throw new Error('seller did not pass trust checks');

const sellerDecision = await leash.verifyCapabilitySeller({
  selector: { mint: profile.mint },
  capability: { slug: 'agentmail/email', protocol: 'x402' },
});
if (sellerDecision.verdict === 'deny') throw new Error('capability seller did not verify');

// Disclosure links reveal only resources the identity owner shared.
const disclosed = await leash.readIdentityDisclosure('lsh_disclosure_token');
console.log(disclosed.resources.capability_cards);

// 4. Record a client-minted agent — public, no auth (idempotent on
//    `mint`). Mint + delegate the asset locally with `@leashmarket/mcp`'s
//    `mintAgentLocally` first, then hand the result here.
const recorded = await leash.recordAgent({
  mint: 'BcN4ToBs8jE3dbYNhYqDJqGnKPjH3zRX8gsDUDH72JQp',
  executive_pubkey: '947dU4Nk8HsdkFcrVip5Zt9XLnfFF5iJSvepEArdr5Ma',
  name: 'my-experimental-bot',
  network: 'solana-devnet',
});
console.log('recorded', recorded.mint, 'treasury', recorded.treasury);

Payment links and expected POST bodies

Payment links are hosted x402/MPP paywalls served at /x/{id}. Set metadata.upstream_url to monetize an API you already host. The settled request forwards to that upstream URL and returns the live upstream response. For POST endpoints, set metadata.expected_request_body to describe the JSON shape buyers should send to the hosted Leash URL.

const link = await leash.createPaymentLink({
  label: 'Design agent',
  owner_agent: 'AjfeyP...',
  method: 'POST',
  protocol: 'x402',
  price: '1 USDC',
  currency: 'USDC',
  response: {
    status: 200,
    mimeType: 'application/json',
    body: { ok: true, message: 'Payment accepted. Forwarding to upstream.' },
  },
  metadata: {
    upstream_url: 'https://api.example.com/design',
    provider_url: 'https://api.example.com',
    pricing_type: 'fixed',
    expected_request_body: {
      prompt: 'string',
      style: 'string',
      format: 'string',
    },
  },
});

console.log(link.share_url);

The SDK creates and reads the metadata. Paying requires Solana signing, so buyer agents should use @leashmarket/buyer-kit, leash pay --method POST --body ..., or leash_pay_payment_link to send the actual runtime body.

Authenticated calls

The webhook endpoints are agent-scoped — they verify a X-Leash-Sig header signed with the agent's executive ed25519 keypair. Pass the keypair and mint to the constructor; the SDK stamps a fresh signature per request.

import { LeashClient } from '@leashmarket/sdk';

const leash = new LeashClient({
  agentMint: 'AjfeyP...',
  executiveSecretBase58: process.env.LEASH_EXECUTIVE_KEY!,
});

const createdKey = await leash.createAgentApiKey({ label: 'local worker' });
console.log('STORE ONCE:', createdKey.plaintext);

const keys = await leash.listAgentApiKeys();
await leash.revokeAgentApiKey(keys.items[0].id);

const updatedProfile = await leash.updateAgentIdentityProfile({
  handle: 'plexpert',
  capability_cards: [
    {
      kind: 'seller_api',
      title: 'Tax summary API',
      source: 'manual',
      endpoint: 'https://api.plexpert.xyz/tax',
      protocols: ['x402'],
      visibility: 'public',
    },
  ],
});
console.log('identity handle:', updatedProfile.handle);

await leash.verifyAgentDomain('plexpert.xyz');

const claim = await leash.createIdentityClaim({
  issuer: 'Leash Labs',
  type: 'verified_builder',
  value: 'true',
  signature: 'sig_...',
});
const disclosure = await leash.createIdentityDisclosure({
  resources: [{ kind: 'claim', id: claim.id }],
});
console.log('share once:', disclosure.url);

const sub = await leash.createWebhook({
  url: 'https://my-app.example/leash-webhook',
  events: ['receipt.published', 'agent.treasury.withdraw'],
});
console.log('SAVE THIS SECRET:', sub.secret); // returned ONCE.

const subs = await leash.listWebhooks();
await leash.deleteWebhook(sub.id);

Agent-created keys are bound to the active agent mint, owned by the executive public key, and scoped as exactly agent. Use them as LEASH_API_KEY for legacy bearer-token surfaces such as receipt reads and payment-link CRUD.

Reputation cheat sheet

reputation.rating is a normalised score in [0, 1]:

rating = (1 - dispute_rate) * weight
weight = min(1, log10(settled_calls + 1) / 3)
  • A new agent with settled_calls: 0 has rating: 0 regardless of dispute rate. That's intentional — you don't have data yet.
  • An established agent with no disputes saturates at 1.0 around ~1000 settled calls.
  • dispute_rate = denied_calls / (settled_calls + denied_calls).

Errors

Network / non-2xx responses throw LeashError:

import { LeashError } from '@leashmarket/sdk';

try {
  await leash.discover();
} catch (err) {
  if (err instanceof LeashError) {
    console.log('status:', err.status, 'body:', err.body);
  }
}

OpenAPI

The full set of endpoints is documented at https://api.leash.market/openapi.json. The SDK is hand-rolled against that surface so the runtime stays dep-free; type drift is caught by integration tests.

Develop

pnpm --filter @leashmarket/sdk typecheck
pnpm --filter @leashmarket/sdk test
pnpm --filter @leashmarket/sdk build