Alchemy Core Workflow B — NFT & Smart Contract Interaction

SkillDev tools

Lets your agent explore NFT collections and interact with smart contracts using Alchemy.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Alchemy Core Workflow B — NFT & Smart Contract Interaction skill

About this capability

Build an NFT discovery workflow with Alchemy NFT API v3 and isolate typed on-chain reads through viem. Use when creating collection explorers or ownership checks. Trigger with "Alchemy NFT API", "NFT collection explorer", or "read an NFT contract".

What this skill tells your AI

The instructions your AI receives, as published by jeremylongshore/tons-of-skills-marketplace in skills/.curated/alchemy-core-workflow-b/SKILL.md and read by ahel’s review.

Overview

Build NFT collection explorers and smart contract read operations using Alchemy's NFT API and core JSON-RPC methods.

Prerequisites

  • Completed alchemy-install-auth setup
  • Familiarity with alchemy-core-workflow-a
  • Understanding of ERC-721 and ERC-1155 standards

Instructions

Step 1: NFT Collection Explorer

// src/nft/collection-explorer.ts
import { Alchemy, Network } from 'alchemy-sdk';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

async function exploreCollection(contractAddress: string) {
  const metadata = await alchemy.nft.getContractMetadata(contractAddress);

  return {
    address: contractAddress,
    name: metadata.name || 'Unknown',
    symbol: metadata.symbol || '',
    totalSupply: metadata.totalSupply || '0',
    tokenType: metadata.tokenType,
    floorPrice: metadata.openSeaMetadata?.floorPrice || null,
    description: metadata.openSeaMetadata?.description || '',
    imageUrl: metadata.openSeaMetadata?.imageUrl || null,
  };
}

async function getCollectionNfts(contractAddress: string, limit: number = 20) {
  const response = await alchemy.nft.getNftsForContract(contractAddress, { limit });
  return response.nfts.map(nft => ({
    tokenId: nft.tokenId,
    name: nft.name || `#${nft.tokenId}`,
    description: nft.description,
    image: nft.image?.cachedUrl || nft.image?.originalUrl,
    attributes: nft.raw?.metadata?.attributes || [],
  }));
}

// Example: Bored Ape Yacht Club
const BAYC = '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D';
exploreCollection(BAYC).then(console.log).catch(console.error);

Step 2: Batch NFT Metadata

// src/nft/batch-metadata.ts
import { Alchemy, Network } from 'alchemy-sdk';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

async function batchGetNftMetadata(
  tokens: Array<{ contractAddress: string; tokenId: string }>
) {
  const results = await alchemy.nft.getNftMetadataBatch(
    tokens.map(t => ({ contractAddress: t.contractAddress, tokenId: t.tokenId }))
  );
  return results.map(nft => ({
    contract: nft.contract.address,
    tokenId: nft.tokenId,
    name: nft.name,
    image: nft.image?.cachedUrl,
    tokenType: nft.tokenType,
    collection: nft.contract.name,
  }));
}

Step 3: Smart Contract Read via Ethers + Alchemy Provider

// src/contracts/read-contract.ts
import { Alchemy, Network } from 'alchemy-sdk';
import { ethers } from 'ethers';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

async function readErc20Contract(contractAddress: string) {
  const provider = await alchemy.config.getProvider();
  const erc20Abi = [
    'function name() view returns (string)',
    'function symbol() view returns (string)',
    'function decimals() view returns (uint8)',
    'function totalSupply() view returns (uint256)',
    'function balanceOf(address) view returns (uint256)',
  ];

  const contract = new ethers.Contract(contractAddress, erc20Abi, provider);
  const [name, symbol, decimals, totalSupply] = await Promise.all([
    contract.name(), contract.symbol(), contract.decimals(), contract.totalSupply(),
  ]);

  return { address: contractAddress, name, symbol, decimals, totalSupply: ethers.formatUnits(totalSupply, decimals) };
}

// Example: Read USDC contract
readErc20Contract('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48').then(console.log);

Step 4: NFT Ownership Verification

// src/nft/verify-ownership.ts
import { Alchemy, Network } from 'alchemy-sdk';

const alchemy = new Alchemy({
  apiKey: process.env.ALCHEMY_API_KEY,
  network: Network.ETH_MAINNET,
});

async function verifyNftOwnership(
  ownerAddress: string,
  contractAddress: string,
  tokenId?: string,
): Promise<boolean> {
  if (tokenId) {
    const owners = await alchemy.nft.getOwnersForNft(contractAddress, tokenId);
    return owners.owners.some(o => o.toLowerCase() === ownerAddress.toLowerCase());
  }
  const nfts = await alchemy.nft.getNftsForOwner(ownerAddress, {
    contractAddresses: [contractAddress],
  });
  return nfts.totalCount > 0;
}

Output

  • NFT collection explorer with OpenSea metadata and floor price
  • Batch metadata fetching for gallery views
  • Smart contract read operations via Ethers.js provider
  • NFT ownership verification for token-gating

Examples

Use a known public testnet collection or a contract you control to fetch a small page of metadata, then render the collection address, token IDs, and cached-image fallback without treating metadata as verified financial or ownership advice. For token gating, call verifyNftOwnership only after the user has proved control of the wallet through your application’s own signed challenge; an address submitted in a form is not authentication. If an RPC call reverts, metadata is absent, or image retrieval times out, preserve the valid fields, label the unavailable item, and retry only within the configured rate-limit budget.

Error Handling

ErrorCauseSolution
Contract not foundWrong address or chainVerify contract on correct network
call revert exceptionABI mismatchVerify contract implements the interface
Rate limit on batchToo many requestsReduce batch size; add delay
Empty NFT imagesIPFS timeoutUse Alchemy's cachedUrl field

Resources

Next Steps

For common errors and debugging, see alchemy-common-errors.

Signals

GitHub stars
3k
Forks
396
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
alchemy-core-workflow-b
Source
github.com/jeremylongshore/tons-of-skills-marketplace