BigBlocks Docs
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

PropTypeRequiredDefaultDescription
tokenPartial<BSV21Token>No-Pre-filled token data
buttonTextstringNo"Deploy BSV-21 Token"Button text
dialogTitlestringNo"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
classNamestringNo-Custom CSS classes
disabledbooleanNofalseWhether button is disabled
showFeeEstimatebooleanNofalseShow transaction fee estimate
onSuccess(txid: string, token: BSV21Token) => voidNo-Success callback with transaction ID
onError(error: Error) => voidNo-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 }]
  });
};

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