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

@ibxlab/mandate

v0.1.0

Published

Mandate: scoped, revocable, passkey-signed delegations for AI agents on Monad, with breaker-enforced risk limits and ERC-8004 reputation.

Readme

@ibxlab/mandate

Mandate is a delegation and trust primitive for the agent economy on Monad. Humans issue scoped, revocable, privately-executed mandates to ERC-8004 agents from a passkey. Agents accumulate portable onchain reputation for how they honour them. Any app that lets an AI agent touch a wallet integrates Mandate instead of rolling its own session keys.

  • Passkey-rooted. The principal is a P256 passkey verified on-chain through Monad's RIP-7212 precompile. No seed phrase, no browser wallet.
  • Scoped and enforced on-chain. Whitelisted targets and selectors, lifetime and per-block spend caps, expiry, and a hysteresis drawdown breaker. Real outflow is measured, not self-reported.
  • Revocable in one block. The passkey revokes; the agent is frozen in the same block.
  • Typed errors. Every Solidity custom error surfaces as a MandateError with the same name and arguments, and agent.execute throws it before sending a transaction.
  • Portable reputation. Compliance is attested by an authorised attestor into the ERC-8004 Reputation Registry. Agents cannot self-attest.

Live on Monad testnet (chain id 10143). Private execution runs in BTX mode (Monad's encrypted mempool); a commit-reveal mode ships in the same contract behind the same interface.

Install

pnpm add @ibxlab/mandate viem

10-minute quickstart (Monad testnet)

You need a funded testnet key. Get MON from https://faucet.monad.xyz. One key plays the gas payer and the agent.

git clone https://github.com/aliveevie/mandate && cd mandate/sdk
pnpm install
export PRIVATE_KEY=0x...      # funded testnet key
pnpm quickstart

The script prints an explorer link for each step. This is what it does, and what you would write in your own app:

import { createMandateClient, MandateError, testnetDemo } from "@ibxlab/mandate";
import { privateKeyToAccount } from "viem/accounts";
import { monadTestnet } from "viem/chains";

const client = createMandateClient({ chain: monadTestnet, signer: privateKeyToAccount(process.env.PRIVATE_KEY) });

// Principal side ------------------------------------------------------------
// In a browser this is Face ID / Touch ID. `software: true` uses a WebCrypto key for servers and CI.
const principal = await client.passkey.create({ rpId: "yourapp.xyz" });

const mandate = client.mandate.build({
  agentId: 1831n,                       // ERC-8004 id
  agentKey: "0xAgentExecutingKey",
  targets: [{ address: testnetDemo.venue, selectors: ["buy(address,uint256)"] }],
  asset: testnetDemo.asset,
  spendCap: 500n * 10n ** 18n,          // lifetime
  perBlockCap: 300n * 10n ** 18n,       // per block
  maxDrawdownBps: 2000,                 // breaker trips at 20% drawdown
  validUntil: new Date(Date.now() + 86_400_000),
});
const signed = await client.mandate.sign(mandate, principal);   // passkey prompt
await client.mandate.grant(signed);                            // one tx, anyone can pay gas
// ...later
await client.mandate.revoke(signed.hash, principal);           // immediate

// Agent side ----------------------------------------------------------------
const agent = client.agent.load({ mandateHash: signed.hash, executor: agentSigner });
try {
  await agent.execute({ target, data, amount });   // validate -> simulate -> send
} catch (e) {
  if (MandateError.is(e, "SpendCapExceeded")) { /* [requested, remaining] */ }
  if (MandateError.is(e, "Tripped"))          { /* breaker is engaged      */ }
}
const state = await agent.state();               // spent, remaining, remainingThisBlock, breaker, active

// Anyone --------------------------------------------------------------------
const rep = await client.reputation.get(1831n);  // { score, trips, executed, pnlBps, erc8004 }

API

createMandateClient({ chain?, rpcUrl?, transport?, signer?, addresses?, storage? })

| Namespace | Call | Does | |---|---|---| | passkey | create({ rpId, software? }) | Creates a passkey, deploys its PasskeyAccount, persists the principal | | | load() | Restores the persisted principal | | | attach(signer, address) | Binds an existing passkey to an existing account (another device) | | mandate | build(params) | Pure. Flattens targets into the on-chain parallel arrays | | | sign(draft, principal) | Fetches the nonce, hashes, signs the EIP-712 digest with the passkey | | | grant(signed) | Sends MandateRegistry.grant | | | revoke(hash, principal) | Passkey-authorised revoke through the account | | | get(hash) / state(hash) | Stored mandate / spend, caps, breaker phase, liveness | | | validate(hash, target, selector, amount) | Dry run. Throws the typed error the chain would | | agent | load({ mandateHash, executor }) | Binds the executing key | | | agent.execute({ target, data, amount }) | Validate, simulate, send, wait | | | agent.validate(...) / agent.state() | Pre-flight and live state | | reputation | get(agentId) / history(agentId) | Latest attestation plus the ERC-8004 aggregate / full history |

amount is the upper bound on asset outflow the call may cause. The executor measures the real outflow and reverts with SpendExceedsDeclared if it is higher.

Typed errors

MandateError.name is the Solidity error name and MandateError.args its decoded arguments:

TargetNotAllowed(target, selector) · SpendCapExceeded(requested, remaining) · PerBlockCapExceeded(requested, remaining) · MandateExpired(validUntil) · MandateNotYetValid(validAfter) · MandateRevoked(hash) · Tripped(hash) · NotAgentKey(caller, agentKey) · InvalidSignature() · InvalidNonce(expected, provided) · SpendExceedsDeclared(actual, declared) · NotAttestor() · StaleReport(agentId, windowEnd, last) and the rest of the protocol's errors, including the accounts and the CRE receiver.

Passkeys

  • Browser: client.passkey.create({ rpId }) uses WebAuthn with userVerification: "required". rpId must equal the page hostname. Only the public key and credential id are stored; the private key never leaves the authenticator.
  • Servers, CI, quickstart: create({ rpId, software: true }) uses a WebCrypto P-256 key and produces the same WebAuthn-shaped assertion, so the on-chain verification path is identical. The key is persisted in the configured storage as a JWK. Treat it like any other hot key.

Addresses

Defaults for Monad testnet are built in (deployments[10143]). Pass addresses to point at another deployment. All addresses and deployment transaction hashes are in contracts/deployments/monad-testnet.json.

Examples

| Script | What it shows | |---|---| | pnpm quickstart | The whole protocol in one run: passkey principal, grant, execute, typed refusal, revoke, reputation | | pnpm example:agent | The agent side only: load a mandate with the executing key, read the bounds, execute inside them, watch an out-of-bounds call refused before it is sent (--dry never sends) | | pnpm example:tool | Mandate as one tool for any LLM agent loop: the tool schema is generated from the mandate, the handler returns the protocol's typed refusal as the tool result |

Entry points

  • @ibxlab/mandate — client, typed errors, EIP-712 helpers, ABIs, addresses, policy-vault helpers.
  • @ibxlab/mandate/prf — Mera PRF: encrypted policy vaults and per-agent identities from the principal's passkey (browser).
  • @ibxlab/mandate/privy — Privy server wallets as agent keys, mandate-mirroring wallet policies, session signers (server).

Full signatures: SDK reference.

Test

pnpm test    # starts an Osaka-spec anvil (P256 precompile at 0x100), deploys the protocol, runs the full flow

Security model in one paragraph

The registry, not the agent, enforces caps, whitelist, expiry and revocation. The executor is the only path from an agent to a principal's account, and it measures real asset outflow. The breaker is a permissionless-checkpoint FSM: anyone can record a market-driven trip, only the principal can re-baseline. Reputation is written by one attestor role from on-chain evidence and mirrored into ERC-8004; the adapter rejects everyone else, including the agent and the contract owner. Full threat model: docs/security.md.

License

MIT · IBX Lab