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

nft-rescue

v1.2.2

Published

CLI tool to backup NFT assets stored on centralized/at-risk infrastructure

Downloads

337

Readme

NFT Rescue

npm version License: MIT Node.js Version

A CLI tool to backup NFT assets stored on centralized/at-risk infrastructure. The tool analyzes all NFTs in a wallet, classifies their storage as "safe" (IPFS/Arweave) or "at-risk" (centralized CDNs, APIs), and downloads at-risk assets locally.

Features

  • Multi-chain support: Ethereum, Base, Zora, Optimism, Arbitrum, Polygon, Tezos
  • Accepts ENS names (e.g., artbot.eth), Tezos domains (e.g., alice.tez), or wallet addresses
  • Discovers all NFTs owned by the wallet
  • Classifies storage as safe (IPFS, Arweave, data URIs) or at-risk (centralized)
  • Downloads at-risk assets locally
  • Falls back to Alchemy's cached data when original servers are offline
  • Progress bars and detailed reporting
  • Supports IPFS and HTTP URLs with retry logic

Prerequisites

  • Node.js 18+
  • Alchemy API key for EVM chains (free tier works fine); not required for Tezos

Installation

From npm (recommended)

npm install -g nft-rescue

From source

git clone https://github.com/artbot-dev/nft-rescue.git
cd nft-rescue
npm install
npm run build
npm link  # Makes 'nft-rescue' available globally

Setup

Alchemy API keys are required for EVM chains (Ethereum, Base, Zora, Optimism, Arbitrum, Polygon). If you're only using Tezos, you can skip this section.

  1. Get an Alchemy API key:

    • Go to https://dashboard.alchemy.com/signup
    • Create a free account
    • Create a new app (select "Ethereum" and "Mainnet")
    • Copy your API key
  2. Set the environment variable:

export ALCHEMY_API_KEY=your-api-key-here

Usage

Analyze Storage

Analyze a wallet to see the storage breakdown of all NFTs:

# Basic analysis (Ethereum by default)
nft-rescue analyze artbot.eth

# Analyze on a specific chain
nft-rescue analyze 0x1234...abcd --chain base
nft-rescue analyze 0x1234...abcd --chain zora
nft-rescue analyze alice.tez --chain tezos

# Verbose output (shows details of at-risk NFTs)
nft-rescue analyze artbot.eth --verbose

Backup At-Risk NFTs

Backup NFTs stored on centralized infrastructure:

# Backup at-risk NFTs (default behavior)
nft-rescue backup artbot.eth

# Backup from a specific chain
nft-rescue backup 0x1234...abcd --chain base
nft-rescue backup alice.tez --chain tezos

# Specify output directory
nft-rescue backup artbot.eth --output ./my-backup

# Dry run (show what would be backed up)
nft-rescue backup artbot.eth --dry-run

# Backup ALL NFTs, not just at-risk
nft-rescue backup artbot.eth --all

Supported Chains

| Chain | Flag | Chain ID | |-------|------|----------| | Ethereum | --chain ethereum (default) | 1 | | Base | --chain base | 8453 | | Zora | --chain zora | 7777777 | | Optimism | --chain optimism | 10 | | Arbitrum | --chain arbitrum | 42161 | | Polygon | --chain polygon | 137 | | Tezos | --chain tezos | n/a (non-EVM) |

Note: ENS names (e.g., artbot.eth) are supported on Ethereum. Tezos domains (e.g., alice.tez) are supported on Tezos. Use wallet addresses for other chains.

CLI Options

nft-rescue analyze <wallet>

| Option | Description | Default | |--------|-------------|---------| | -c, --chain <chain> | Blockchain to query | ethereum | | -v, --verbose | Show detailed output including at-risk NFT details | false |

nft-rescue backup <wallet>

| Option | Description | Default | |--------|-------------|---------| | -c, --chain <chain> | Blockchain to query | ethereum | | -o, --output <dir> | Output directory | ./nft-rescue-backup | | -a, --all | Backup all NFTs, not just at-risk | false | | -d, --dry-run | Show what would be backed up | false | | -v, --verbose | Detailed output | false |

Storage Classification

Safe (Decentralized) Storage

The following are considered safe and won't be backed up by default:

  • IPFS: ipfs://..., /ipfs/Qm..., raw CIDs
  • IPFS Gateways: ipfs.io, cloudflare-ipfs.com, gateway.pinata.cloud, dweb.link, w3s.link, nftstorage.link
  • Arweave: ar://..., arweave.net, arweave.dev
  • Data URIs: data:... (content embedded directly)

At-Risk (Centralized) Storage

Everything else is considered at-risk, including:

  • api.niftygateway.com
  • *.cloudinary.com
  • *.amazonaws.com / S3
  • Custom domains (artist websites, etc.)
  • opensea.io metadata API

Output Structure

nft-rescue-backup/
├── index.html                     # Offline gallery entrypoint
├── app.js                         # Gallery logic
├── styles.css                     # Gallery styles
├── gallery-data.js                # Embedded gallery data for file:// use
├── manifests/
│   ├── index.json                  # Gallery manifest index
│   ├── manifest.<chain>.<wallet>.json          # Summary with storage analysis
│   ├── history/
│   │   └── manifest.<chain>.<wallet>.<ts>.json # Snapshots before overwrite
│   └── runs/
│       └── run.<ts>.<chain>.<wallet>.json      # Per-run delta summary
└── nfts/
    └── <contract-address>/
        └── <token-id>/
            ├── metadata.json        # Original metadata
            ├── image.<ext>          # Primary image
            ├── animation.<ext>      # Animation if present
            └── storage-report.json  # Classification details

Gallery

Open index.html inside the backup folder to browse your NFTs. The gallery works offline and includes filters for wallet, chain, collection, traits, and storage status. If you want to fetch remote media when local assets are missing, enable the remote fallback toggle. If you see a blank gallery when opening via file://, re-run the backup so gallery-data.js is regenerated.

Manifest Format

Manifests are stored per wallet+chain at manifests/manifest.<chain>.<wallet>.json. Per-run delta files are stored at manifests/runs/run.<ts>.<chain>.<wallet>.json.

{
  "walletAddress": "0x...",
  "ensName": "artbot.eth",
  "chainName": "ethereum",
  "chainId": 1,
  "backupDate": "2025-01-27T...",
  "summary": {
    "totalNFTs": 50,
    "fullyDecentralized": 30,
    "atRisk": 20,
    "backedUp": 18,
    "failed": 2
  },
  "nfts": [...]
}

Notes

  • Only at-risk assets are backed up by default; use --all to backup everything
  • The tool includes rate limiting to avoid API throttling (100ms between requests)
  • IPFS content is accessed through multiple gateways with fallback
  • When original metadata servers are offline, the tool falls back to Alchemy's cached data
  • ENS resolution only works on Ethereum; use wallet addresses for other chains

Gallery Refresh

If you update manifests manually or copy a backup to another machine, you can regenerate the gallery assets:

nft-rescue gallery refresh ./nft-rescue-backup

API Rate Limits

The free Alchemy tier has generous rate limits for most use cases. If you're backing up a wallet with thousands of NFTs, consider:

  • Using --dry-run first to see the scope
  • Running during off-peak hours
  • Upgrading to a paid Alchemy plan for higher limits

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT - see LICENSE file for details.