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

@fenine/fns-avatar

v1.0.4

Published

Avatar resolver library for Node.js, browsers, and edge runtimes (Cloudflare Workers etc.).

Readme

fns-avatar

Avatar resolver library for Node.js, browsers, and edge runtimes (Cloudflare Workers etc.).

Important Notes

  • FNS-Avatar >= 1.0.0 is only compatible with ethers v6. If your project is using v5, keep your fns-avatar on latest 0.x version.
  • Version 1.0.4+ uses the native Fetch API for maximum compatibility across platforms including Cloudflare Workers and other edge runtimes.

Platform Support

This library works seamlessly across:

  • Node.js 18+ (uses native fetch or http adapter)
  • Browsers (all modern browsers)
  • Cloudflare Workers
  • Other edge runtimes that support standard Fetch API

Getting started

Prerequisites

  • Have your web3 provider ready (web3.js, ethers.js)
  • [Only for node env] Have jsdom installed.

And good to go!

Installation

# npm
npm i @fenine/fns-avatar
# yarn
yarn add @fenine/fns-avatar

Usage

import { StaticJsonRpcProvider } from '@ethersproject/providers';
import { AvatarResolver, resolveMediaRecord, utils as avtUtils } from '@fenine/fns-avatar';

// const { JSDOM } = require('jsdom'); on nodejs
// const jsdom = new JSDOM().window; on nodejs

const provider = new StaticJsonRpcProvider(
    ...
  );
...
async function getAvatar() {
    const resolver = new AvatarResolver(provider);
    const avatarURI = await resolver.getAvatar('tanrikulu.fen', { /* jsdomWindow: jsdom (on nodejs) */ });
    // avatarURI = https://ipfs.io/ipfs/QmUShgfoZQSHK3TQyuTfUpsc8UfeNfD8KwPUvDBUdZ4nmR
}

async function getHeader() {
    const resolver = new AvatarResolver(provider);
    const headerURI = await resolver.getHeader('tanrikulu.fen', { /* jsdomWindow: jsdom (on nodejs) */ });
    // headerURI = https://ipfs.io/ipfs/QmRFnn6c9rj6NuHenFVyKXb6tuKxynAvGiw7yszQJ2EsjN
}

async function getAvatarMetadata() {
    const resolver = new AvatarResolver(provider);
    const avatarMetadata = await resolver.getMetadata('tanrikulu.fen');
    // avatarMetadata = { image: ... , uri: ... , name: ... , description: ... }
    const headerMetadata = await resolver.getMetadata('tanrikulu.fen', 'header');
    // headerMetadata = { image: ... , uri: ... , name: ... , description: ... }
    const avatarURI = avtUtils.getImageURI({ metadata: avatarMetadata /*, jsdomWindow: jsdom (on nodejs) */ });
    // avatarURI = https://ipfs.io/ipfs/QmUShgfoZQSHK3TQyuTfUpsc8UfeNfD8KwPUvDBUdZ4nmR
}

async function resolveDirectRecord() {
    const avatarURI = await resolveMediaRecord('ipfs://QmHash...', {
      ipfs: 'https://cloudflare-ipfs.com',
    });
}

Supported avatar specs

NFTs

  • ERC721
  • ERC1155

URIs

  • HTTP
  • Base64
  • IPFS

Options

Cache (Default: Disabled)

const avt = new AvatarResolver(provider, { cache: 300 }); // 5 min response cache in memory

Custom IPFS Gateway (Default: https://ipfs.io)

const avt = new AvatarResolver(provider, { ipfs: 'https://dweb.link' });

Custom Arweave Gateway (Default: https://arweave.net)

const avt = new AvatarResolver(provider, { arweave: 'https://arweave.net' });

Marketplace Api Keys (Default: {})

const avt = new AvatarResolver(provider, {
  apiKey: {
    opensea: 'YOUR_API_KEY',
  },
});

URL DenyList (Default: [])

const avt = new AvatarResolver(provider, {
  urlDenyList: ['https://maliciouswebsite.com'],
});

Custom Agents (Node.js only)

You can provide custom HTTP/HTTPS agents for advanced use cases:

import http from 'http';
import https from 'https';

const avt = new AvatarResolver(provider, {
  agents: {
    httpAgent: new http.Agent({ keepAlive: true }),
    httpsAgent: new https.Agent({ keepAlive: true }),
  },
});

⚠️ SECURITY WARNING: When you provide custom agents, ens-avatar will use them as-is without applying SSRF protection. You are responsible for ensuring your custom agents have appropriate security measures to prevent Server-Side Request Forgery attacks.

If you need SSRF protection with custom agents, wrap them with ssrf-req-filter:

import http from 'http';
import https from 'https';
const { requestFilterHandler } = require('ssrf-req-filter');

const avt = new AvatarResolver(provider, {
  agents: {
    httpAgent: requestFilterHandler(new http.Agent({ keepAlive: true })),
    httpsAgent: requestFilterHandler(new https.Agent({ keepAlive: true })),
  },
});

Allow Private IPs (Default: false) - Development Only

For local development when you need to access localhost or private network services:

const avt = new AvatarResolver(provider, {
  allowPrivateIPs: true, // Allows localhost, 127.0.0.1, 10.x.x.x, 192.168.x.x, etc.
});

⚠️ WARNING: This disables SSRF protection. Only use for local development (e.g., local IPFS nodes, test servers). NEVER enable this in production.

Common local development scenarios:

  • Local IPFS node: http://127.0.0.1:5001
  • Local Ethereum node: http://localhost:8545
  • Docker containers on private networks

Note: This flag is ignored if you provide custom agents (you control security in that case).

Security

XSS Protection

All user-generated SVG content is automatically sanitized to prevent XSS attacks:

  • Browser/Node.js: Uses DOMPurify (8.74 KB, battle-tested)
  • Cloudflare Workers: Uses sanitize-html (parser-based, no DOM dependency)

Both sanitizers are production-ready, actively maintained, and specifically configured for secure SVG handling.

SSRF Protection

By default, ens-avatar includes built-in protection against Server-Side Request Forgery (SSRF) attacks in Node.js environments. This prevents malicious actors from using avatar URLs to probe internal networks.

Default behavior (recommended for production):

  • ✅ Blocks requests to localhost, 127.0.0.1
  • ✅ Blocks private IP ranges: 10.x.x.x, 192.168.x.x, 172.16.x.x-172.31.x.x
  • ✅ Blocks link-local and other internal addresses

Custom agents: If you provide your own HTTP/HTTPS agents, ens-avatar will use them as-is without applying SSRF protection. You are responsible for securing your custom agents.

Local development: Set allowPrivateIPs: true to disable SSRF protection when you need to access local services (e.g., local IPFS nodes). Never use this in production.

See the Custom Agents section for more details.


⚠️ SECURITY DISCLAIMER

While ens-avatar implements security measures to help protect against XSS and SSRF attacks, you are ultimately responsible for the security of your application. We strongly recommend:

  • Conducting your own security audits before deploying to production
  • Implementing additional security layers appropriate for your use case
  • Keeping the library updated to receive security patches
  • Following security best practices when handling user-generated content
  • Properly configuring all security-related options for your environment

This library is provided "as-is" without warranty. The maintainers are not liable for any security vulnerabilities in applications using this library.

Demo

  • Create .env file with INFURA_KEY env variable

  • Build the library

  • Node example

node example/node.js ENS_NAME
  • Browser example
yarn build:demo
http-server example