Alchemy core workflow b
Build NFT collection explorer and smart contract interaction with Alchemy. Use when fetching NFT metadata, building galleries, reading contract state, or implementing NFT marketplace features. Trigger: "alchemy NFT", "alchemy smart contract", "alchemy collection", "alchemy NFT metadata", "alchemy contract read".From its SKILL.md
npx -y skills add ComeOnOliver/skillshub --skill alchemy-core-workflow-bAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.7 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
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
alchemy-install-authsetup - 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 |
|---|---|---|
Contract not found | Wrong address or chain | Verify contract on correct network |
call revert exception | 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 cachedUrl field |
Resources
Next Steps
For common errors and debugging, see alchemy-common-errors.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.