The NFT module provides comprehensive functionality for interacting with Non-Fungible Tokens (NFTs) on the Solana blockchain. It integrates with the Tensor API for fetching NFT data, collection information, and performing buy/sell operations.

Core Functionalities

NFT Portfolio

View and manage all NFTs owned by a user with detailed metadata and pricing information

Collection Discovery

Search and browse NFT collections with floor price tracking and collection analytics

Buy NFTs

Purchase individual NFTs or floor NFTs from collections with integrated Tensor trading

Sell & List

List owned NFTs for sale with custom pricing and duration settings

Installation & Setup

1

API Configuration

Configure your Tensor API access in .env.local:

TENSOR_API_KEY=your_tensor_api_key_here
HELIUS_API_KEY=your_helius_api_key_here  # Optional for compressed NFTs
2

Import Module

Import the components and hooks you need:

import { 
  NftScreen,
  useFetchNFTs,
  NftDetailsSection,
  nftService 
} from '@/modules/nft';
3

Wallet Integration

Ensure wallet providers are configured for transaction signing:

import { useWallet } from '@/modules/wallet-providers';

Tensor API: This module primarily uses Tensor’s API for NFT data and trading. Ensure you have appropriate API access and rate limits configured.

Module Architecture

src/modules/nft/
├── components/             # Reusable NFT UI components
├── hooks/                  # Custom React hooks for NFT data
├── screens/               # Complete NFT trading screens
├── services/              # Tensor API integration
├── types/                 # TypeScript definitions
└── utils/                 # NFT-specific utilities

Core Components

NftScreen - Main NFT trading interface with buy/sell tabs

import { NftScreen } from '@/modules/nft';

function NFTMarketplace() {
  return (
    <NftScreen
      defaultTab="buy" // or "sell"
      showHeader={true}
      enableSearch={true}
    />
  );
}

Features:

  • Tabbed interface for buying and selling
  • Collection search and discovery
  • User’s NFT portfolio display
  • Integrated trading functionality

Core Hook: useFetchNFTs

The primary hook for fetching user’s NFT portfolio:

import { useFetchNFTs } from '@/modules/nft';
import { useWallet } from '@/modules/wallet-providers';

function UserNFTPortfolio() {
  const { wallet } = useWallet();
  const { nfts, loading, error, refetch } = useFetchNFTs(wallet?.address, {
    includeCompressed: true,
    includeMetadata: true,
    sortBy: 'floorPrice'
  });

  if (loading) return <LoadingSpinner />;
  if (error) return <ErrorDisplay message={error} onRetry={refetch} />;

  return (
    <View>
      <Text style={styles.title}>Your NFTs ({nfts.length})</Text>
      <FlatList
        data={nfts}
        keyExtractor={(item) => item.mint}
        renderItem={({ item }) => (
          <NFTCard 
            nft={item} 
            onPress={() => openNFTDetails(item)}
          />
        )}
        onRefresh={refetch}
        refreshing={loading}
      />
    </View>
  );
}

Hook Parameters:

  • walletAddress - User’s wallet address
  • options - Configuration object with:
    • includeCompressed - Include compressed NFTs
    • includeMetadata - Fetch full metadata
    • sortBy - Sort order preference

Returns:

  • nfts - Array of NFT items
  • loading - Loading state
  • error - Error message if any
  • refetch - Function to refresh data

NFT Service Functions

The nftService.ts provides comprehensive Tensor API integration:

nft_service
object

Quick Start Examples

import { useFetchNFTs, NftDetailsSection } from '@/modules/nft';
import { useWallet } from '@/modules/wallet-providers';

function MyNFTCollection() {
  const { wallet } = useWallet();
  const { nfts, loading, error } = useFetchNFTs(wallet?.address);
  const [selectedNFT, setSelectedNFT] = useState(null);

  if (!wallet) {
    return <ConnectWalletPrompt />;
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>My NFT Collection</Text>
      
      {loading && <LoadingSpinner />}
      
      {error && (
        <ErrorCard 
          message={error}
          onRetry={() => window.location.reload()}
        />
      )}
      
      <FlatList
        data={nfts}
        numColumns={2}
        keyExtractor={(item) => item.mint}
        renderItem={({ item }) => (
          <TouchableOpacity 
            style={styles.nftCard}
            onPress={() => setSelectedNFT(item)}
          >
            <Image 
              source={{ uri: item.image }} 
              style={styles.nftImage}
            />
            <Text style={styles.nftName}>{item.name}</Text>
            <Text style={styles.nftPrice}>
              {item.price ? `${item.price} SOL` : 'Not Listed'}
            </Text>
          </TouchableOpacity>
        )}
      />
      
      {selectedNFT && (
        <Modal visible={!!selectedNFT}>
          <NftDetailsSection
            mint={selectedNFT.mint}
            onClose={() => setSelectedNFT(null)}
          />
        </Modal>
      )}
    </View>
  );
}

NFT Utilities

The module includes specialized utilities for handling NFT data:

nft_utilities
object

Advanced Features

NFT Sharing Integration

import { NftListingModal } from '@/modules/nft';
import { useThread } from '@/core/thread';

function ShareNFTFeature() {
  const { createPost } = useThread();
  const [showNFTModal, setShowNFTModal] = useState(false);

  const handleShareNFT = async (nftData) => {
    try {
      await createPost({
        content: `Check out this amazing NFT! 🎨`,
        type: 'nft_listing',
        sections: [
          {
            type: 'nft_listing',
            data: nftData
          }
        ]
      });
      
      setShowNFTModal(false);
      Alert.alert('Success', 'NFT shared to your feed!');
    } catch (error) {
      Alert.alert('Error', 'Failed to share NFT');
    }
  };

  return (
    <View>
      <Button 
        title="Share NFT" 
        onPress={() => setShowNFTModal(true)} 
      />
      
      <NftListingModal
        visible={showNFTModal}
        onClose={() => setShowNFTModal(false)}
        onSelect={handleShareNFT}
        selectionType="both" // 'nft', 'collection', or 'both'
      />
    </View>
  );
}

Real-time Floor Price Tracking

function useFloorPriceTracking(collectionId) {
  const [floorPrice, setFloorPrice] = useState(null);
  const [priceChange, setPriceChange] = useState(0);

  useEffect(() => {
    if (!collectionId) return;

    const trackFloorPrice = async () => {
      try {
        const floorNFT = await nftService.fetchFloorNFTForCollection(collectionId);
        const newPrice = floorNFT.price;
        
        if (floorPrice !== null) {
          const change = ((newPrice - floorPrice) / floorPrice) * 100;
          setPriceChange(change);
        }
        
        setFloorPrice(newPrice);
      } catch (error) {
        console.error('Floor price tracking error:', error);
      }
    };

    // Initial load
    trackFloorPrice();
    
    // Update every 30 seconds
    const interval = setInterval(trackFloorPrice, 30000);
    return () => clearInterval(interval);
  }, [collectionId, floorPrice]);

  return { floorPrice, priceChange };
}

Batch NFT Operations

function useBatchNFTOperations() {
  const { wallet, sendTransaction } = useWallet();

  const batchListNFTs = async (nfts, pricePerNFT) => {
    const results = [];
    
    for (const nft of nfts) {
      try {
        const result = await nftService.listNftForSale(
          wallet.publicKey,
          nft.mint,
          pricePerNFT,
          wallet,
          (status) => console.log(`${nft.name}: ${status}`)
        );
        results.push({ nft: nft.name, success: true, result });
      } catch (error) {
        results.push({ nft: nft.name, success: false, error: error.message });
      }
    }
    
    return results;
  };

  const batchBuyFloorNFTs = async (collectionIds) => {
    const results = [];
    
    for (const collectionId of collectionIds) {
      try {
        const result = await nftService.buyCollectionFloor(
          wallet.publicKey,
          collectionId,
          sendTransaction,
          (status) => console.log(`Collection ${collectionId}: ${status}`)
        );
        results.push({ collection: collectionId, success: true, result });
      } catch (error) {
        results.push({ collection: collectionId, success: false, error: error.message });
      }
    }
    
    return results;
  };

  return { batchListNFTs, batchBuyFloorNFTs };
}

Integration with Other Modules

Error Handling & Troubleshooting

common_issues
object
function RobustNFTOperation() {
  const [retryCount, setRetryCount] = useState(0);
  const maxRetries = 3;

  const safeNFTOperation = async (operation) => {
    try {
      return await operation();
    } catch (error) {
      if (retryCount < maxRetries && error.message.includes('rate limit')) {
        setRetryCount(prev => prev + 1);
        // Exponential backoff
        await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, retryCount)));
        return safeNFTOperation(operation);
      }
      throw error;
    }
  };

  return { safeNFTOperation };
}

Performance Considerations

Image Optimization: Use image caching and lazy loading for better performance when displaying large NFT collections.

API Limits: Be mindful of Tensor API rate limits, especially when fetching large collections or making frequent requests.

API Reference

For detailed API documentation, see:


The NFT module provides a complete digital collectibles trading platform, enabling users to discover, buy, sell, and manage NFTs with professional-grade tools and seamless Tensor integration.