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

@ethlimo/ens-hooks

v0.1.15

Published

TypeScript library for encoding, decoding, and executing EIP-8121 hooks with ERC-7930 interoperable addresses.

Readme

ENS Hooks - EIP-8121 Implementation

TypeScript library for encoding, decoding, and executing EIP-8121 hooks with ERC-7930 interoperable addresses. Enables cross-chain function calls for ENS contenthash resolution with optional trust verification.

Overview

This library implements EIP-8121 hooks, a specification for cross-chain function calls. A hook fully specifies what function to call, with what parameters, on which contract, on which chain using ERC-7930 interoperable addresses.

Key Features:

  • EIP-8121 hook encoding (selector 0x6113bfa3)
  • ERC-7930 interoperable addresses
  • Multi-chain execution (EIP-155)
  • 0-2 fixed-size primitive parameters
  • Optional trust verification
  • Contenthash encoding/decoding

Scope

This is a focused implementation for contenthash resolution. See LIMITATIONS.md for scope restrictions:

  • 0-2 parameters of fixed-size primitives and strings (bool, address, uintN, intN, bytesN, string)
  • String parameters limited to 512 characters
  • EIP-155 chains only (EVM)
  • Bytes return type only
  • No recursive resolution
  • No struct or dynamic type support (dynamic bytes, arrays)
  • Requires ERC-3668 (CCIP-Read) enabled provider

Installation

npm install @ethlimo/ens-hooks

Usage

Encoding a Hook

import { encodeHook, EIP8121Target } from '@ethlimo/ens-hooks';

const target: EIP8121Target = {
    chainId: 1,  // Ethereum mainnet
    address: "0x1234567890123456789012345678901234567890"
};

const hookData = await encodeHook(
    "data(bytes32)",                    // function signature
    "data(0x1234...)",                  // function call with values
    "(bytes)",                          // return type
    target
);

Decoding and Executing a Hook

import { decodeHook, executeHook, ProviderMap } from '@ethlimo/ens-hooks';
import { ethers, namehash } from 'ethers';

// Decode the hook
const hook = await decodeHook(hookData);

// Set up provider map for cross-chain calls
const providerMap: ProviderMap = new Map([
    [1, new ethers.JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/...")]
]);

// Execute the hook
const result = await executeHook(hook!, {
    params: [namehash("example.eth")],
    providerMap
});

if (result._tag === "HookExecutionResult") {
    console.log("Result:", result.data);
} else {
    console.error("Error:", result.message);
}

Parameter Support

Hooks support functions with 0-2 parameters of fixed-size Solidity primitives:

  • 0 parameters: getData() - Global data
  • 1 parameter: data(bytes32) - Node-specific data
  • 2 parameters: data(bytes32,bytes32) - Node with additional context

Recommended Parameter Patterns:

  • () - Zero parameters for global data
  • (nodehash: bytes32) - Single nodehash parameter for node-specific data
  • (nodehash: bytes32, hashOfContent: bytes32) - Two parameters for cache-busting
    • hashOfContent should be either:
      • A hash of the expected content (for integrity verification)
      • An autoincrement value (for cache invalidation in web gateways)

Supported Types: bool, address, uint8-256, int8-256, bytes1-32, string (max 512 chars)

import { executeHook } from '@ethlimo/ens-hooks';
import { namehash } from 'ethers';

// 0-parameter hook
const globalHook = await encodeHook(
    "getData()",
    "getData()",
    "(bytes)",
    { chainId: 1, address: "0x..." }
);

const globalResult = await executeHook(await decodeHook(globalHook)!, {
    providerMap  // No params
});

// 1-parameter hook (node-specific data)
const node = namehash("example.eth");
const nodeHook = await encodeHook(
    "data(bytes32)",
    `data(${node})`,
    "(bytes)",
    { chainId: 1, address: "0x..." }
);

const nodeResult = await executeHook(await decodeHook(nodeHook)!, {
    params: [node],  // Single parameter array
    providerMap
});

// 2-parameter hook (with cache-busting)
const hashOfContent = "0xabcd..."; // Hash or autoincrement
const twoParamHook = await encodeHook(
    "data(bytes32,bytes32)",
    `data(${node},${hashOfContent})`,
    "(bytes)",
    { chainId: 1, address: "0x..." }
);

const twoParamResult = await executeHook(await decodeHook(twoParamHook)!, {
    params: [node, hashOfContent],  // Two parameter array
    providerMap
});

Trust Verification

Optionally verify hook targets against a trusted list:

import { executeHook, createTrustedTargets } from '@ethlimo/ens-hooks';

// Create trusted targets set
const trustedTargets = createTrustedTargets([
    { 
        chainId: 1, 
        address: "0x1234567890123456789012345678901234567890",
        description: "ENS Public Resolver"
    }
]);

// Execute with trust verification
const result = await executeHook(hook!, {
    params: [namehash("example.eth")],
    providerMap,
    trustedTargets
});

Three verification modes supported:

  1. Array: TrustedTarget[] - Verified via array iteration
  2. Set: Set<string> - Fast lookup with "chainId:address" keys
  3. Function: (target: EIP8121Target) => boolean - Custom logic

API Reference

Hook Encoding/Decoding

  • encodeHook() - Encode EIP-8121 hook (bytes format, 5 parameters)
  • decodeHook() - Decode EIP-8121 hook (bytes format)
  • computeSelector() - Compute 4-byte function selector from signature
  • parseParameterTypes() - Parse and validate parameter types (0-2 fixed-size primitives)
  • validateFunctionCallMatchesSignature() - Strict validation of call vs signature

Hook Execution

  • executeHook(hook, options) - Execute hook on target chain with type-safe options:
    • For 0-parameter hooks: { providerMap, trustedTargets?, throwOnUntrusted? }
    • For 1-parameter hooks: { params: [string], providerMap, trustedTargets?, throwOnUntrusted? }
    • For 2-parameter hooks: { params: [string, string], providerMap, trustedTargets?, throwOnUntrusted? }
  • validateHook() - Validate parameter count (0-2) and types (fixed-size primitives)
  • detectAndDecodeHook() - Detect and decode hooks from bytes format

Contenthash Support

  • encodeEIP8121HookForContenthash() - Wrap hook for contenthash storage
  • tryDecodeEIP8121HookFromContenthash() - Extract hook from contenthash
  • encodeDataUri() - Encode plain URI for contenthash
  • tryDecodeDataUri() - Decode plain URI from contenthash

Trust Verification

  • verifyTrustedTarget() - Check if target is trusted
  • createTrustedTargets() - Create fast-lookup Set from array
  • createTargetKey() - Generate "chainId:address" key

Testing

npm test

69 tests covering encoding, decoding, execution, and trust verification.

Specification

See notes/EIP-8121.md for the full EIP-8121 specification and notes/LIMITATIONS.md for implementation scope.

License

MIT