Components/Inscriptions
BSV21MintButton
Deploy BSV-21 NFT tokens with icon validation and on-chain deployment
Deploy BSV-21 NFT tokens with icon inscriptions. BSV-21 is the NFT standard that requires an icon image, supporting square images up to 400x400px and 100KB in size.
Demo
Basic NFT Token
Game Token
Collectible
Custom Token
Features Demonstrated:
Icon UploadSymbol ValidationSupply ManagementDecimal ConfigurationFee EstimationTransaction Tracking
Demo Note: This demonstrates BSV-21 NFT token deployment. Icons must be square images (max 400x400px, 100KB). In production, tokens are deployed to Bitcoin SV blockchain with real transaction fees.
API Reference
This component extends the Button and Dialog primitives from Radix and uses DropZone for icon file upload.
Installation
npx bigblocks add bsv21-mint-button
Import
import { BSV21MintButton } from 'bigblocks';
Props
Prop | Type | Required | Default | Description |
---|---|---|---|---|
token | Partial<BSV21Token> | No | - | Pre-filled token data |
buttonText | string | No | "Deploy BSV-21 Token" | Button text |
dialogTitle | string | No | "Deploy BSV-21 NFT Token" | Dialog title |
variant | 'solid' | 'soft' | 'outline' | 'ghost' | No | 'solid' | Button variant |
size | '1' | '2' | '3' | '4' | No | '2' | Button size |
color | 'blue' | 'green' | 'red' | 'gray' | No | 'blue' | Button color |
className | string | No | - | Custom CSS classes |
disabled | boolean | No | false | Whether button is disabled |
showFeeEstimate | boolean | No | false | Show transaction fee estimate |
onSuccess | (txid: string, token: BSV21Token) => void | No | - | Success callback with transaction ID |
onError | (error: Error) => void | No | - | Error callback |
Types
BSV21Token
interface BSV21Token {
/** Token symbol/ticker */
symbol: string;
/** Icon image file */
icon: File | null;
/** Maximum supply */
maxSupply: string;
/** Number of decimal places */
decimals?: number;
}
Basic Usage
import { BSV21MintButton } from 'bigblocks';
export default function TokenCreator() {
const handleSuccess = (txid: string, token: BSV21Token) => {
console.log('Token deployed!', { txid, token });
// Redirect or show success message
};
const handleError = (error: Error) => {
console.error('Deployment failed:', error);
// Show error message to user
};
return (
<div className="p-6">
<h2>Create Your NFT Token</h2>
<BSV21MintButton
onSuccess={handleSuccess}
onError={handleError}
showFeeEstimate={true}
/>
</div>
);
}
Advanced Usage
Pre-filled Token Data
import { BSV21MintButton } from 'bigblocks';
export default function GameTokens() {
const gameTokenDefaults = {
symbol: 'HERO',
maxSupply: '1000',
decimals: 0
};
return (
<BSV21MintButton
token={gameTokenDefaults}
buttonText="Create Game Token"
dialogTitle="Deploy Game Hero Token"
color="green"
onSuccess={(txid, token) => {
// Save to game database
saveGameToken({ txid, ...token });
// Navigate to token management
router.push(`/game/tokens/${txid}`);
}}
/>
);
}
Collection Integration
import { BSV21MintButton } from 'bigblocks';
import { useState } from 'react';
export default function CollectionManager() {
const [deployedTokens, setDeployedTokens] = useState([]);
const handleTokenDeployment = (txid: string, token: BSV21Token) => {
setDeployedTokens(prev => [...prev, { txid, ...token }]);
// Update collection metadata
updateCollectionMetadata({
tokenCount: deployedTokens.length + 1,
latestToken: txid
});
};
return (
<div className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<BSV21MintButton
token={{ symbol: 'ART', decimals: 0 }}
buttonText="Deploy Art Token"
onSuccess={handleTokenDeployment}
/>
<BSV21MintButton
token={{ symbol: 'MUSIC', decimals: 0 }}
buttonText="Deploy Music Token"
onSuccess={handleTokenDeployment}
/>
</div>
{deployedTokens.length > 0 && (
<div>
<h3>Deployed Tokens</h3>
<ul>
{deployedTokens.map(token => (
<li key={token.txid}>
{token.symbol} - Supply: {token.maxSupply}
</li>
))}
</ul>
</div>
)}
</div>
);
}
Icon Requirements
Image Validation
- Format: PNG, JPEG, GIF, or WebP
- Size: Maximum 100KB file size
- Dimensions: Must be square (same width and height)
- Maximum Resolution: 400x400 pixels
Best Practices
// Example icon preparation
const prepareIcon = async (file: File): Promise<boolean> => {
// Check file type
const validTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'];
if (!validTypes.includes(file.type)) {
throw new Error('Invalid image type');
}
// Check file size
if (file.size > 100 * 1024) {
throw new Error('Image too large (max 100KB)');
}
// Check dimensions
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
if (img.width !== img.height) {
reject(new Error('Image must be square'));
} else if (img.width > 400) {
reject(new Error('Image too large (max 400x400)'));
} else {
resolve(true);
}
};
img.src = URL.createObjectURL(file);
});
};
BSV-21 Standard
BSV-21 tokens are NFTs on Bitcoin SV that include:
- Unique symbol/ticker
- Icon inscription on-chain
- Fixed or unlimited supply
- Decimal places for fractional ownership
- Ordinal-based ownership tracking
Token Economics
// Example token configurations
const limitedEdition = {
symbol: 'RARE',
maxSupply: '100', // Limited to 100 tokens
decimals: 0 // Whole tokens only
};
const fractionalArt = {
symbol: 'ARTPIECE',
maxSupply: '1', // Single piece
decimals: 8 // Allows fractional ownership
};
const gameItems = {
symbol: 'SWORD',
maxSupply: '10000', // Game economy
decimals: 0 // Discrete items
};
Error Handling
Common error scenarios:
- Wallet not connected
- Insufficient UTXOs
- Invalid icon format/size
- Network connectivity issues
- Transaction broadcast failures
const handleError = (error: Error) => {
switch (error.message) {
case 'Wallet not connected':
// Prompt user to connect wallet
setShowConnectDialog(true);
break;
case 'No UTXOs available':
// Suggest funding wallet
setShowFundingDialog(true);
break;
default:
// Generic error handling
toast.error(`Deployment failed: ${error.message}`);
}
};
Integration Examples
Marketplace Integration
import { BSV21MintButton } from 'bigblocks';
export default function MarketplaceCreator() {
return (
<BSV21MintButton
onSuccess={(txid, token) => {
// Auto-list on marketplace
createMarketplaceListing({
tokenTxid: txid,
symbol: token.symbol,
price: 1000, // sats
description: `BSV-21 token: ${token.symbol}`
});
}}
/>
);
}
Social Media Integration
const handleTokenCreation = (txid: string, token: BSV21Token) => {
// Share on social media
const message = `🎨 Just created ${token.symbol} NFT token on Bitcoin SV! Supply: ${token.maxSupply}`;
// Post to social feed
socialPost({
message,
attachments: [{ type: 'token', txid }]
});
};
Related Components
- CollectionMintButton - Deploy NFT collections
- BSV20MintButton - Deploy fungible tokens
- InscriptionButton - General inscription creation
Best Practices
Token Symbol Guidelines
- Use uppercase letters (automatically converted)
- Keep symbols short and memorable (1-10 characters)
- Avoid using existing popular symbols
- Consider namespace conflicts
Icon Design
- Use high contrast for visibility at small sizes
- Avoid complex details that don't scale down well
- Consider using SVG format for crisp scaling
- Test icon visibility on different backgrounds
Supply Economics
// Consider your token's use case
const collectible = { maxSupply: '1' }; // Unique item
const limitedSeries = { maxSupply: '100' }; // Limited edition
const gameAsset = { maxSupply: '10000' }; // Game economy
const fractional = { maxSupply: '1', decimals: 8 }; // Shared ownership