Claude-code-plugins-plus alchemy-core-workflow-b
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-b" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-alchemy-core-workflow-b && rm -rf "$T"
manifest:
plugins/saas-packs/alchemy-pack/skills/alchemy-core-workflow-b/SKILL.mdsource content
Alchemy Core Workflow B — NFT & Smart Contract Interaction
Overview
Build NFT collection explorers and smart contract read operations using Alchemy's NFT API and core JSON-RPC methods.
Prerequisites
- Completed
setupalchemy-install-auth - 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
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Wrong address or chain | Verify contract on correct network |
| ABI mismatch | Verify contract implements the interface |
| Rate limit on batch | Too many requests | Reduce batch size; add delay |
| Empty NFT images | IPFS timeout | Use Alchemy's field |
Resources
Next Steps
For common errors and debugging, see
alchemy-common-errors.