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

@erc7730/sdk

v0.3.0

Published

Decode blockchain transactions into human-readable format using ERC-7730 standard

Readme

@erc7730/sdk

TypeScript runtime for ERC-7730 clear signing.

npm version ERC-7730 License: MIT

This package is not a descriptor catalog. The source of truth is ethereum/clear-signing-erc7730-registry. Product direction: ROADMAP.md.

Why ERC-7730?

Wallets still show raw calldata like 0xa9059cbb000000.... ERC-7730 / clearsigning.org maps a call or typed-data payload to an intent and labeled fields.

Before:

Function: 0xa9059cbb
Param 1: 0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045
Param 2: 0x0000000000000000000000000000000000000000000000000000000005f5e100

After:

Send tokens
├── Amount: 100 USDC
└── Recipient: vitalik.eth

Trust model

Separate trusted metadata from ABI guesses. Sourcify and generateDescriptor are untrusted fallbacks — never confidence: "high".

| source | officialOnlyPolicy | officialOrLocalPolicy | confidence if accepted | | --- | --- | --- | --- | | Official registry (commit SHA pin) or attestation | accepted: true | accepted: true | "high" | | Local extend() override | false | true | "medium" | | Sourcify / generateDescriptor | false | false | never "high" | | Inferred / basic | false | false | "low" |

Clear signing is not ABI pretty-printing. Inject officialOnlyPolicy(), officialOrLocalPolicy(), or composePolicies(). Sourcify never returns trust.accepted: true under officialOnlyPolicy. When trust is omitted, decode uses a stub (policy: "unspecified") with the same accept/reject rows as officialOrLocalPolicy.

decodeTransaction, decodeTypedData, and the deprecated ClearSigner.decode alias follow the table above. Sourcify is never confidence: "high".

Features

  • Schema v1 + v2validateDescriptor() against official JSON Schema
  • Official registry client — pin ethereum/clear-signing-erc7730-registry by commit SHA
  • Resolve — merge includes and inline field $ref
  • decodeTransaction — apply official (or override) display.formats to calldata
  • Context matchersmatchContext() for deployments, factory.deployEvent, and EIP-1967 / EIP-1167 proxies
  • decodeTypedData — apply official EIP-712 descriptors (index.eip712.json)
  • createClearSigner — bind DecodeOptions (ClearSigner.decode is a deprecated alias of decodeTransaction)
  • TrustPolicyofficialOnlyPolicy / officialOrLocalPolicy / composePolicies
  • Untrusted fallback — Sourcify / generateDescriptor, labeled by source
  • Warnings — untrusted descriptors, infinite approvals, and similar risks
  • Tree-shakeable — minimal dependencies

Installation

npm install @erc7730/sdk

Quick Start

import {
  createOfficialRegistry,
  decodeTransaction,
  officialOnlyPolicy,
} from '@erc7730/sdk';

const registry = createOfficialRegistry({
  pin: '9f37816afde954ff6617fb5baa346133e5af26c5',
});

const result = await decodeTransaction(
  {
    to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    data: '0xa9059cbb000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa960450000000000000000000000000000000000000000000000000000000005f5e100',
    chainId: 1,
  },
  { registry, trust: officialOnlyPolicy(), useSourcifyFallback: false }
);

console.log(result.intent);
console.log(result.source);     // "official-registry" when the client matches
console.log(result.confidence); // "high" only when official-registry / attested is accepted
console.log(result.trust);      // { accepted, policy: "official-only", descriptorHash, reasons }
console.log(result.fields);

ClearSigner.decode is a deprecated alias of decodeTransaction (one minor). Prefer the functions, or createClearSigner(options) to bind registry / trust / provider.

Production lookups should use createOfficialRegistry({ pin }), not the v1 embedded snapshot.

Official registry

The product catalog is ethereum/clear-signing-erc7730-registry. Pin a commit SHA in production — never master.

import { createOfficialRegistry, decodeTypedData } from '@erc7730/sdk';

const registry = createOfficialRegistry({
  pin: '9f37816afde954ff6617fb5baa346133e5af26c5',
});

const weth = await registry.findCalldata({
  chainId: 1,
  address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
});

const usdcPermit = await registry.findEip712({
  chainId: 1,
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  signature: 'Permit',
});

const typedData = {
  chainId: 1,
  domain: {
    name: 'USD Coin',
    version: '2',
    chainId: 1,
    verifyingContract: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' as const,
  },
  types: {
    Permit: [
      { name: 'owner', type: 'address' },
      { name: 'spender', type: 'address' },
      { name: 'value', type: 'uint256' },
      { name: 'nonce', type: 'uint256' },
      { name: 'deadline', type: 'uint256' },
    ],
  },
  primaryType: 'Permit',
  message: {
    owner: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
    spender: '0x1111111254eeb25477b68fb85ed929f73a960582',
    value: 100000000n,
    nonce: 0n,
    deadline: 1_735_689_600n,
  },
};

const decoded = await decodeTypedData(typedData, { registry });

extend() is for local overrides only. Submit new protocol metadata to the official registry, not this repository.

The v1 ClearSigner still ships a small built-in fallback (ERC-20 / ERC-721 / WETH) plus a legacy embed; that embed is not the live catalog.

CLI later (#15): ERC7730_REGISTRY_PATH for a local clone, and an update helper in the Cyfrin clearsig update style.

Divergences vs Ledger python-erc7730 resolved form (justified, golden-tested):

  • Format keys stay ABI fragments (not 4-byte selectors).
  • Constants are not inlined; nested field groups are not flattened; ABI HTTP URLs are not fetched.
  • fields arrays merge by path as in EIP-7730 (python-erc7730 overwrites the array).

See docs/divergences.md for the comparable slice, lint policy, and pnpm golden:python.

Schema v2

import { validateDescriptor, resolveDescriptor, createMemoryIncludeLoader } from '@erc7730/sdk';

const validated = validateDescriptor(input);
if (!validated.ok) {
  console.error(validated.errors);
}

const loader = createMemoryIncludeLoader({ 'common-Safe.json': commonSafe });
const resolved = await resolveDescriptor(input, loader);
// resolved.merged — includes merged, field $ref inlined, addresses lowercased
// resolved.hash   — keccak256 of canonical JSON (sorted keys, no extra whitespace)

Official descriptors often split shared formats into common-*.json and point fields at $.display.definitions.*. Inject an IncludeLoader for filesystem (CLI) or fetch (runtime).

Untrusted fallback (Sourcify / generate)

Sourcify is on by default so unknown verified contracts still render something. That output is not curated metadata.

const result = await decodeTransaction(
  {
    to: '0x6590cBBCCbE6B83eF3774Ef1904D86A7B02c2fCC',
    data: '0x2e17de78...',
    chainId: 1,
  },
  { useSourcifyFallback: true }
);

console.log(result.source);      // "sourcify" — untrusted
console.log(result.confidence);  // do not treat as "high"

Pass useSourcifyFallback: false to disable.

import { createClearSigner, generateDescriptor, officialOrLocalPolicy } from '@erc7730/sdk';

const draft = generateDescriptor({
  chainId: 1,
  address: '0x...',
  abi: contractABI,
  owner: 'My Protocol'
});
// Starting point for an upstream registry PR — never confidence: "high"

const signer = createClearSigner({ trust: officialOrLocalPolicy(), useSourcifyFallback: false });
signer.extend([draft]);

Security Warnings

const result = await decodeTransaction({
  to: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  data: '0x095ea7b3...ffffffffffffffffffffffffffffffffffffffff', // Infinite approval
  chainId: 1
});

console.log(result.warnings);
// [{
//   type: 'infinite_approval',
//   severity: 'high',
//   message: 'This approval grants unlimited spending access to your tokens'
// }]

Local overrides

import { createClearSigner, officialOrLocalPolicy } from '@erc7730/sdk';

const signer = createClearSigner({ trust: officialOrLocalPolicy() });

signer.extend([{
  context: {
    contract: {
      deployments: [{ chainId: 1, address: '0x...' }]
    }
  },
  metadata: {
    owner: 'My Protocol'
  },
  display: {
    formats: {
      'stake(uint256)': {
        intent: 'Stake tokens',
        fields: [
          { path: '[0]', label: 'Amount', format: 'tokenAmount' }
        ]
      }
    }
  }
}]);

API Reference

createClearSigner / decodeTransaction / decodeTypedData

import {
  createClearSigner,
  decodeTransaction,
  decodeTypedData,
  officialOnlyPolicy,
} from '@erc7730/sdk';

export function createClearSigner(options?: DecodeOptions): ClearSigner;
export function decodeTransaction(tx: TransactionInput, options?: DecodeOptions): Promise<DecodedOperation>;
export function decodeTypedData(data: TypedDataInput, options?: DecodeOptions): Promise<DecodedOperation>;

const signer = createClearSigner({
  registry,
  trust: officialOnlyPolicy(),
  provider: null,
  useSourcifyFallback: false,
});

await signer.decodeTransaction(tx);
await signer.decodeTypedData(typedData);
// signer.decode(tx) — @deprecated alias of decodeTransaction (one minor)

Also exported: matchContext, officialOnlyPolicy, officialOrLocalPolicy, composePolicies, createOfficialRegistry, validateDescriptor, resolveDescriptor, generateDescriptor.

Response Types

interface DecodedOperation {
  confidence: 'high' | 'medium' | 'low';
  source:
    | 'official-registry'
    | 'attested'
    | 'local-override'
    | 'sourcify'
    | 'generated'
    | 'inferred'
    | 'basic';
  intent: string;
  functionName?: string;
  signature?: string;
  fields: DecodedField[];
  excluded: string[];
  warnings: SecurityWarning[];
  trust: {
    accepted: boolean;
    policy: string;
    descriptorHash?: string;
    reasons: string[];
  };
  metadata: {
    chainId: number;
    contractAddress?: string;
    descriptorId?: string;
  };
  raw: {
    selector?: string;
    args?: readonly unknown[];
    message?: Record<string, unknown>;
  };
}

vs Ledger python-erc7730

| | @erc7730/sdk | Ledger python-erc7730 | | --- | --- | --- | | Language | TypeScript / JavaScript | Python | | Role | Runtime for wallets and dApps (validate, resolve, decode) | Authoring and firmware tooling (lint, convert, device clear-signing) | | Catalog | Consumes the official registry, pin by commit SHA | Same official catalog | | Schema | v1 read + v2 validate | v1 / v2 |

Supported Chains

Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche, and more.

Web Demo

Try it online: miltontulli.github.io/ERC-7730

The demo shows source, warnings, and trust.accepted on every decode. Prefer decodeTransaction with officialOnlyPolicy() in production.

Contributing

Protocol descriptors belong in ethereum/clear-signing-erc7730-registry.

SDK issues and features: MiltonTulli/ERC-7730.

License

MIT