Uploading Assets
This guide explains how to upload your NFT assets to the blockchain using the storage contract.
Asset Pipeline
magical-nft provides a complete pipeline for preparing and uploading assets:
Source Files → Convert → Encode → Upload → VerifyPreparing Assets
1. Convert Images to AVIF
AVIF provides excellent compression for onchain storage:
bun run convert-to-avifThis converts images in assets/ to AVIF format.
2. Base64 Encode
Encode assets to base64 for embedding in metadata:
bun run base64-encode3. Extract HTML
If using HTML-based NFTs, extract and minify:
bun run extract-htmlConfigure Upload List
Edit config/filesToUpload.json to specify files to upload:
{
"files": [
{
"key": "image",
"path": "assets/image.avif"
},
{
"key": "animation",
"path": "html/output.html"
}
]
}Upload Files
Upload All Files
bun run upload-all-filesThis uploads all files listed in the config.
Upload Single File
bun run upload-file <key> <path>Verify & Extract
After uploading, verify the data was stored correctly and extract the final output.
Verify Uploads
Download files from the storage contract to the tmp/ directory and verify their integrity:
source .env && forge script script/VerifyUploads.s.sol --rpc-url $RPC_URLExtract HTML
Fetch the tokenURI for token #1, decode the metadata and HTML, and save it to tmp/final_check.html:
bun run extract-htmlOpen tmp/final_check.html in your browser to verify the NFT renders correctly.
Extract Metadata
Extract just the JSON metadata from the tokenURI:
bun run extract-metadataGas Considerations
Uploading large files can be expensive. Consider:
- Chunking - Split large files across multiple transactions
- Compression - Use AVIF for images, minify HTML/JS
- Timing - Upload during low gas periods
- L2s - Consider deploying on Layer 2 for lower costs
Storage Limits
SSTORE2 can store up to ~24KB per pointer. For larger files:
- Split into chunks
- Store each chunk separately
- Concatenate in the renderer
Troubleshooting
Transaction Reverts
- Check gas limit is sufficient
- Verify file size is under 24KB
- Ensure storage contract is deployed
Wrong Data Stored
- Verify file encoding (UTF-8 vs binary)
- Check base64 encoding is correct
- Re-upload with correct data