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

merit-attest

v1.0.14

Published

Create, sign, and anchor WorkAttestations on Base. Drop-in helpers for CodeGrid, EVO, CTRL and similar tools.

Readme

merit-attest

Create, sign, and anchor WorkAttestations on Base.

A WorkAttestation is a JSON record of work done by an agent or hybrid team. The SDK produces a stable canonical hash of the record. Submit only the hash, producer address, and one metric value to the on-chain contract. The full payload and proofs stay off-chain.

Version 1.0.14 is now live on npm. The core model has been validated with real mainnet transactions, including direct use by Bankr-powered agents. We've got a solid build process, tests, and docs covering the changes.

Install

npm install merit-attest

Basic flow

import {
  createAttestation,
  hashAttestation,
  signAttestation,
  submitAttestation,
  getBaseWalletClient,
  MERIT_ATTEST_ADDRESS,
  MERIT_ATTEST_ABI
} from 'merit-attest';

// 1. Build from your agent output
const att = createAttestation({
  producer: {
    type: 'agent',
    id: 'agent-42',
    pubkey: '0xYourEvmAddress',
    framework: 'my-system'
  },
  context: {
    prompt_hash: 'sha256 of the task prompt',
    repo: 'owner/repo',
    files: ['src/foo.ts']
  },
  output: {
    type: 'code_patch',
    payload: 'the diff or result here',
    metrics_claimed: { coverage: 87 }
  }
});

// 2. Hash (sorted keys + sha256)
const hash = hashAttestation(att);

// 3. Sign (attach signature to the attestation object)
const signed = await signAttestation(att, {
  address: '0xYourEvmAddress',
  sign: async (h) => { /* return signature bytes for the hash */ }
});

// 4. Anchor on Base (real tx)
const walletClient = getBaseWalletClient(); // injected wallet on Base mainnet (after user switches chain in wallet)
const tx = await submitAttestation(signed, walletClient);

Only the hash + producer + metric are written on-chain. Anyone can later call isAnchored(hash) to confirm it was anchored.

How the SDK proves an agent did what it said it did

Here's the core flow, kept straightforward:

An agent produces some output (a code change, a strategy, an analysis, etc.). The SDK wraps that into a structured record called a WorkAttestation. This record captures the context (the prompt or task details), the actual output or payload, and any metrics or proofs the agent claims.

The SDK then creates a unique, canonical hash of that entire record. The agent signs this hash with its private key. The signature is attached to the record, proving the agent is the one making the claim about that exact output.

Only the hash (plus the agent's address and one key metric) gets sent to the smart contract on Base. The contract records it as anchored, with a blockchain timestamp. The full details of the work stay off-chain.

To verify later:

  • Take the full record.
  • Recompute the hash from it.
  • Check that the attached signature matches the agent's public key.
  • Confirm on-chain (via the contract or Basescan) that this exact hash is recorded as anchored by that agent.

If everything matches, it proves the agent committed to precisely that work at that time. Any alteration to the record would change the hash, breaking the proof. The on-chain anchor adds immutability and a public timestamp without exposing the full work.

This is the "gossip first, anchor later" model: full data can be shared privately or via other channels, but the cryptographic root is permanently verifiable on Base.

Helpers for existing tools

import {
  fromCodeGridSession,
  fromEvoExperiment,
  fromCtrlStrategy,
  fromAi2HumanReview,
  createMcpSubmitMeritTool
} from 'merit-attest';
  • fromCodeGridSession(session) - turns a CodeGrid export into attestation input
  • fromEvoExperiment(exp) - turns an EVO run result into attestation input
  • fromCtrlStrategy(strat) - turns a CTRL / strategy output into attestation input
  • fromAi2HumanReview(review) - turns a human review into attestation input
  • createMcpSubmitMeritTool(submitFn) - returns an MCP tool definition named submit_merit for use in CTRL, Hermes, etc.

Example:

const partial = fromCodeGridSession(mySession);
const att = createAttestation({
  producer: { type: 'agent', id: '...', pubkey: '0x...' },
  ...partial
});

Contract

Live on Base mainnet:

0x9bE80d727cea67504a58eF5F7ADa0B92339BE163

https://basescan.org/address/0x9bE80d727cea67504a58eF5F7ADa0B92339BE163

The contract exposes:

  • submitAttestation(bytes32 hash, address producer, int256 metricValue, string metric)
  • isAnchored(bytes32) view returns (bool)
  • AttestationAnchored event

The helpers default to Base mainnet (base chain from viem, live contract at 0x9bE80d727cea67504a58eF5F7ADa0B92339BE163 ). Pass your own clients if you need a custom RPC.

Verify an anchor

import { createPublicClient, http, parseAbi } from 'viem';
import { base } from 'viem/chains';

const client = createPublicClient({
  chain: base,
  transport: http()
});

const anchored = await client.readContract({
  address: MERIT_ATTEST_ADDRESS,
  abi: MERIT_ATTEST_ABI,
  functionName: 'isAnchored',
  args: [hashAsBytes32]
});

Types

See WorkAttestation, Producer, and the exported functions in the package for the exact shape.

Full design and schema notes are in the repo docs. The on-chain record is intentionally minimal: only the cryptographic root is anchored.

Using with private keys (CLI / agent runtimes / Bankr)

Many agent systems (including Bankr launch identities) manage a plain EVM private key. You can use it directly:

import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import { createAttestation, signAttestation, submitAttestation, hashAttestation } from 'merit-attest';

const account = privateKeyToAccount('0x...your key...');
const walletClient = createWalletClient({
  account,
  chain: base,
  transport: http('https://mainnet.base.org'),
});

const att = createAttestation({ /* ... */ });
const signed = await signAttestation(att, {
  address: account.address,
  sign: async (hash) => hexToBytes(await account.sign({ hash })),
});

const tx = await submitAttestation(signed, walletClient);

The same pattern works for Bankr's launch wallet JSON.

Bankr + Agentic Usage

Bankr maintains a persistent EVM launch identity (see ~/.grok/skills/bankr/state/launch_wallet.json). The Merit SDK works natively with it for agents to attest their work (launches, optimizations, reviews, etc.):

import { createWalletClient, http, hexToBytes } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import { createAttestation, signAttestation, submitAttestation } from 'merit-attest';
import fs from 'node:fs';

const bankrWallet = JSON.parse(
  fs.readFileSync(process.env.HOME + '/.grok/skills/bankr/state/launch_wallet.json', 'utf8')
);

const account = privateKeyToAccount(bankrWallet.private_key);
const walletClient = createWalletClient({
  account,
  chain: base,
  transport: http(process.env.BASE_RPC || 'https://mainnet.base.org'),
});

const attestation = createAttestation({
  producer: {
    type: 'agent',
    id: 'grok-bankr-launcher',
    pubkey: account.address,
    framework: 'bankr',
  },
  context: {
    prompt_hash: 'bankr-launch-' + Date.now(),
    extra: { action: 'token-launch' },
  },
  output: {
    type: 'strategy_config',
    payload: JSON.stringify({ token: 'Example', narrative: '...' }),
    metrics_claimed: { launches: 1 },
  },
});

const signed = await signAttestation(attestation, {
  address: account.address,
  sign: async (hash) => hexToBytes(await account.sign({ hash })),
});

const tx = await submitAttestation(signed, walletClient);
console.log('Anchored tx:', tx);

This enables "gossip first, anchor later": agents produce full records that can be shared privately, while the cryptographic root is permanently verifiable on Base.

Status

Version 1.0.14 is the current release. It is ready for use by agents and platforms.

The core model has been validated with real Base mainnet transactions, including direct integration with Bankr.

Check the CHANGELOG for the 1.0 updates like the build, tests, and Bankr docs.

Full design notes are in the project repository.

(Note: the hexToBytes import from viem is needed in the examples above.)