Crossmint NFT Minting App
Build a completely decentralized NFT minting app that leverages the power of Arweave for permanent storage and Crossmint for simplified NFT creation. Learn how to store NFT content permanently, create and mint NFTs, build a frontend with authentication and payment options, and deploy your application to Arweave.
What You'll Learn
- How to store NFT content permanently on Arweave
- How to create and mint NFTs using Crossmint's API
- How to build a frontend with authentication and payment options
- How to deploy your application to Arweave
- How to configure a human-readable ArNS domain
Example Project
- Live Demo: https://crossmint_zerotoarweave.arweave.net
- GitHub Repository: https://github.com/ar-io/crossmint-arweave-example
Prerequisites
- Node.js environment
- Arweave wallet with AR tokens
- Crossmint developer account
- Basic understanding of React and JavaScript
Quick Start
Storage Setup
Store your NFT image permanently on Arweave using ArDrive.io:
Generate AI Image
Create an AI-generated image for your NFT:
- Visit ChatGPT or another AI image generation tool
- Use a prompt to generate an interesting image for your NFT
- Download the generated image to your local machine
- Make sure to save it in a common format like PNG or JPG
Upload to Arweave
Store the image permanently on Arweave:
- Visit ArDrive.io and log in to your account
- Fund your ArDrive wallet if needed (requires AR tokens)
- Create a new folder for your NFT project
- Drag and drop your AI-generated image into this folder
- Wait for the upload to complete and for the transaction to be processed
Get Transaction ID
Retrieve the Arweave Transaction ID:
- Click on the uploaded image in your ArDrive folder
- Look for the "Transaction ID" or "TX ID" in the file details
- Copy this Transaction ID - it looks like
Abc123XYZ...
- Save this Transaction ID - you'll need it for creating your NFT metadata
Important: This Transaction ID is the permanent reference to your image on the Arweave network.
Collection and Template Creation
Create an ERC-1155 collection and template using Crossmint's API:
Create Account
Set up your Crossmint developer account:
- Visit the Crossmint Staging Console
- Sign in and accept the dialog to continue
- Note that Crossmint provides two environments:
- Staging: For development and testing (what we'll use first)
- Production: For your final, live application
Get API Key
Get a server-side API key:
- After logging in, navigate to the "Integrate" tab
- Click on "API Keys" at the top of the page
- In the "Server-side keys" section, click "Create new key"
- Select the following scopes under "Minting API":
collections.create
- Required for creating a new collectionnfts.create
- Required for minting NFTsnfts.read
- Needed to read NFT information
- Create and save this API key securely
Create Collection
Create an ERC-1155 collection:
const apiKey = "YOUR_API_KEY";
const env = "staging"; // Using staging environment for development
const url = `https://${env}.crossmint.com/api/2022-06-09/collections`;
const options = {
method: "POST",
headers: {
"accept": "application/json",
"content-type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify({
chain: "ethereum-sepolia", // Using Ethereum testnet for development
fungibility: "semi-fungible", // For ERC-1155 tokens
metadata: {
name: "lil dumdumz SFT Collection",
imageUrl: "https://arweave.net/YOUR_ARWEAVE_TX_ID", // Optional collection image
description: "A collection of semi-fungible tokens with images stored on Arweave"
}
}),
};
fetch(url, options)
.then((res) => res.json())
.then((json) => {
console.log("Collection created! Collection ID:", json.id);
console.log("Save this Collection ID for the next steps");
})
.catch((err) => console.error("Error:", err));
Create Template
Create an SFT template:
const apiKey = "YOUR_API_KEY";
const collectionId = "YOUR_COLLECTION_ID";
const env = "staging";
const url = `https://${env}.crossmint.com/apis/2022-06-09/collections/${collectionId}/templates`;
const options = {
method: "POST",
headers: {
"accept": "application/json",
"content-type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify({
name: "lil dumdumz SFT",
description: "A semi-fungible token with image stored on Arweave",
imageUrl: "https://arweave.net/YOUR_ARWEAVE_TX_ID",
attributes: [
{
trait_type: "Rarity",
value: "Common"
},
{
trait_type: "Storage",
value: "Arweave"
}
]
}),
};
fetch(url, options)
.then((res) => res.json())
.then((json) => {
console.log("Template created! Template ID:", json.id);
console.log("Save this Template ID for minting NFTs");
})
.catch((err) => console.error("Error:", err));
Frontend Development
Clone and set up the Zero-to-Arweave starter kit:
Clone Repository
Clone the starter kit:
git clone https://github.com/ar-io/crossmint-arweave-example.git
cd crossmint-arweave-example
Configure Environment
Set up your environment variables:
Create a .env
file in the root directory:
VITE_CROSSMINT_API_KEY=your_api_key_here
VITE_CROSSMINT_ENV=staging
VITE_COLLECTION_ID=your_collection_id_here
VITE_TEMPLATE_ID=your_template_id_here
Authentication Integration
Implement Crossmint's client-side authentication:
import { CrossmintAuth } from "@crossmint/client-sdk-react";
function App() {
const { user, login, logout, isLoading } = CrossmintAuth.useAuth();
return (
<div>
{user ? (
<div>
<p>Welcome, {user.email}!</p>
<button onClick={logout}>Logout</button>
</div>
) : (
<button onClick={login}>Login with Crossmint</button>
)}
</div>
);
}
Payment Integration
Add Crossmint's embedded checkout for NFT purchases:
import { CrossmintPaymentButton } from "@crossmint/client-sdk-react";
function NFTMinting() {
const handlePaymentSuccess = (result) => {
console.log("Payment successful:", result);
// Handle successful payment
};
return (
<CrossmintPaymentButton
collectionId={import.meta.env.VITE_COLLECTION_ID}
templateId={import.meta.env.VITE_TEMPLATE_ID}
environment={import.meta.env.VITE_CROSSMINT_ENV}
onPaymentSuccess={handlePaymentSuccess}
/>
);
}
Deploy to Arweave
Deploy your completed application to Arweave:
Deploy with ArDrive
Deploy using ArDrive:
- Visit ArDrive.io
- Create a new folder for your application
- Upload the contents of your
dist
folder - Wait for the upload to complete
Get Manifest ID
Retrieve the manifest ID:
- Click on your uploaded application folder
- Look for the "Manifest ID" in the folder details
- Copy this ID - you'll need it for domain configuration
Domain Configuration
Connect your application to a human-readable domain name using ArNS:
Purchase ARNS Name
Get an ARNS name (if needed):
- Visit arns.app
- Connect your Arweave wallet
- Search for an available name
- Purchase it with $ARIO tokens
Get Process ID
Get your Process ID:
- Visit arns.app
- Connect your Arweave wallet
- Click "Manage Assets" in the top-right
- Find your ARNS name and click on the settings icon
- Copy the Process ID displayed
Update Configuration
Update the configuration:
const ant = ANT.init({
signer: new ArweaveSigner(jwk),
processId: 'YOUR_PROCESS_ID_HERE' // Replace with your Process ID
});
const result = await ant.setRecord({
name: '@',
ttlSeconds: 900, // 15 minutes
dataLink: 'YOUR_MANIFEST_ID' // Replace with the manifest ID
});
Set Base Record
Set the base record:
# Using pnpm
pnpm run set-base
# Using yarn
yarn set-base
When successful, you'll see:
✅ Base record update successful!
🔗 Your application is now available at: https://YOUR-NAME.ar.io
Advanced Features
Custom NFT Metadata
const customMetadata = {
name: "Custom NFT Name",
description: "A unique NFT with custom attributes",
imageUrl: "https://arweave.net/YOUR_TX_ID",
attributes: [
{
trait_type: "Rarity",
value: "Legendary"
},
{
trait_type: "Power",
value: 95
},
{
trait_type: "Element",
value: "Fire"
}
]
};
Batch Minting NFTs
const batchMint = async (templateId, quantity) => {
const promises = Array(quantity).fill().map(() =>
mintNFT(templateId)
);
const results = await Promise.all(promises);
return results;
};
Track Sales and Engagement
const trackMint = (nftId, userEmail) => {
// Send analytics data
analytics.track('nft_minted', {
nftId,
userEmail,
timestamp: Date.now()
});
};
Comprehensive Error Handling
const mintWithErrorHandling = async (templateId) => {
try {
const result = await mintNFT(templateId);
return { success: true, data: result };
} catch (error) {
console.error('Minting failed:', error);
return {
success: false,
error: error.message
};
}
};
Benefits of This Approach
- True Permanence: NFT images are stored permanently on Arweave
- Accessibility: Credit card payments make NFTs accessible to mainstream users
- Complete Decentralization: Both application and assets are stored on decentralized networks
- User-Friendly Experience: Seamless experience for both creators and collectors
- No Server Maintenance: No need to manage servers or renew domains
Ready to Build?
Clone the Example
Get started with the complete example project
Crossmint Documentation
Learn more about Crossmint's APIs and features
ArFS Documentation
Understand Arweave's file system for advanced storage
How is this guide?