> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Your First Solana App with Helius

> Learn the fundamentals of building on Solana by creating your first application using Helius APIs. From setup to deployment in minutes.

export const Quickstart = () => {
  const [apiKey, setApiKey] = useState('');
  const [ownerAddress, setOwnerAddress] = useState('86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY');
  const [loading, setLoading] = useState(false);
  const [randomNft, setRandomNft] = useState(null);
  const [error, setError] = useState(null);
  const handleSubmit = async e => {
    e.preventDefault();
    setLoading(true);
    setError(null);
    setRandomNft(null);
    try {
      const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${apiKey}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: '1',
          method: 'getAssetsByOwner',
          params: {
            ownerAddress
          }
        })
      });
      const data = await response.json();
      if (data.error) {
        setError(data.error.message || 'Error calling API');
      } else if (data.result && data.result.items && data.result.items.length > 0) {
        const randomIndex = Math.floor(Math.random() * data.result.items.length);
        const selectedNft = data.result.items[randomIndex];
        setRandomNft(selectedNft);
      } else {
        setError('No NFTs found for this wallet');
      }
    } catch (err) {
      setError(err.message || 'Failed to fetch data');
    } finally {
      setLoading(false);
    }
  };
  return <div className="p-4 border dark:border-zinc-950/80 rounded-xl bg-white dark:bg-zinc-950/80 shadow-sm">      
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">Your API Key</label>
          <input type="text" value={apiKey} onChange={e => setApiKey(e.target.value)} placeholder="Enter your API key" className="w-full p-2 border rounded dark:bg-zinc-900 dark:border-zinc-700" required />
        </div>
        
        <div>
          <label className="block text-sm text-zinc-950/70 dark:text-white/70 mb-1">Owner Address</label>
          <input type="text" value={ownerAddress} onChange={e => setOwnerAddress(e.target.value)} placeholder="Solana wallet address" className="w-full p-2 border rounded dark:bg-zinc-900 dark:border-zinc-700" required />
        </div>
        
        <button type="submit" disabled={loading} className={`px-4 py-2 rounded font-medium rounded-full ${loading ? 'bg-gray-300 dark:bg-gray-700 cursor-not-allowed' : 'bg-primary hover:bg-primary/80 text-white'}`}>
          {loading ? 'Loading...' : 'Get Random NFT'}
        </button>
      </form>
      
      {error && <div className="mt-4 p-3 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded text-red-700 dark:text-red-300">
          <strong>Error:</strong> {error}
        </div>}
      
      {randomNft && <div className="mt-6">
          <div className="text-center mb-4">
            <h3 className="text-lg font-semibold mb-1 text-zinc-950 dark:text-white">
              {randomNft.content?.metadata?.name || 'Unnamed NFT'}
            </h3>
            <div className="flex items-center justify-center gap-2">
              <p className="text-sm text-zinc-600 dark:text-zinc-400">
                {randomNft.id}
              </p>
              <a href={`https://orbmarkets.io/address/${randomNft.id}?cluster=mainnet-beta`} target="_blank" rel="noopener noreferrer" className="text-primary hover:text-primary/80 transition-colors" title="View on Orb Explorer">
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
                </svg>
              </a>
            </div>
          </div>
          
          <div className="flex justify-center mb-4">
            {randomNft.content?.files && randomNft.content.files.length > 0 && randomNft.content.files[0].uri ? <img src={randomNft.content.files[0].uri} alt={randomNft.content?.metadata?.name || 'NFT'} className="rounded-lg max-h-64 border border-zinc-200 dark:border-zinc-800 shadow-sm" /> : <div className="bg-gray-200 dark:bg-zinc-800 rounded-lg w-64 h-64 flex items-center justify-center">
                <span className="text-zinc-500 dark:text-zinc-400">No image available</span>
              </div>}
          </div>
          
          
        </div>}
    </div>;
};

## What does Helius provide?

Helius provides REST and JSON-RPC APIs for building any Solana application — from analytic platforms and DeFi dashboards to trading bots and compliance tools. Query token balances, fetch NFT metadata, stream real-time blockchain events, send optimized transactions, and monitor wallets with a single API key. This guide walks you through your first API call and a working application in minutes.

<Steps titleSize="h2">
  <Step title="Create Your Free Helius Account">
    Start by creating your free account at the [Helius Dashboard](https://dashboard.helius.dev/dashboard). Your free tier includes 100,000 DAS API calls per month; perfect for getting started and building prototypes.

    Agents looking to programmatically create a Helius account should use the [Helius CLI](/agents/cli) and reference the [Agent signup instructions](https://dashboard.helius.dev/agents.md).
  </Step>

  <Step title="Get Your API Key">
    Navigate to the [API Keys](https://dashboard.helius.dev/api-keys) section and copy your key. This key gives you access to all Helius APIs, including RPC nodes, DAS API, and enhanced transaction data.

    <Tip>
      **Performance Tip**: Use our Gatekeeper (Beta) endpoint: `https://beta.helius-rpc.com` instead of `https://mainnet.helius-rpc.com` for lower latency. Your API key works on both. [Learn more →](/gatekeeper/overview)
    </Tip>
  </Step>

  <Step title="Make Your First API Call">
    Let's start with a practical example: fetching NFTs from a wallet. We'll use the [getAssetsByOwner](/api-reference/das/getassetsbyowner) method to query assets owned by `86xCn…o2MMY` (Anatoly Yakovenko's wallet, co-founder of Solana).

    <Quickstart />

    **What's happening here?** The DAS API allows you to query compressed and standard NFTs with a single call. Notice how the response includes metadata, image URLs, and ownership information - all the data you need to build rich user experiences.
  </Step>

  <Step title="Understanding the Response">
    Great! You've successfully fetched NFT data. The response includes:

    * **Asset ID**: Unique identifier for each NFT
    * **Metadata**: Name, symbol, description, and attributes
    * **Content**: Image URLs and file information
    * **Ownership**: Current owner and authority information
  </Step>
</Steps>

## Build It with Code

Now let's implement this in a real application. We'll create a simple NFT portfolio viewer that you can expand upon.

<Note>
  We'll use Node.js for this example. Make sure you have it installed from [nodejs.org](https://nodejs.org/en/download).
</Note>

<Steps titleSize="h3">
  <Step title="Set up your project">
    ```bash theme={"system"}
    mkdir solana-nft-viewer
    cd solana-nft-viewer
    npm init -y
    npm install node-fetch
    ```
  </Step>

  <Step title="Create the NFT portfolio viewer">
    ```javascript nft-portfolio.js theme={"system"}
    const fetch = require('node-fetch');

    class NFTPortfolioViewer {
      constructor(apiKey) {
        this.apiKey = apiKey;
        this.baseUrl = 'https://mainnet.helius-rpc.com';
      }

      async fetchNFTsByOwner(ownerAddress, limit = 10) {
        try {
          const response = await fetch(`${this.baseUrl}/?api-key=${this.apiKey}`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              jsonrpc: '2.0',
              id: '1',
              method: 'getAssetsByOwner',
              params: {
                ownerAddress,
                page: 1,
                limit,
                displayOptions: {
                  showFungible: false,
                  showNativeBalance: false,
                },
              },
            }),
          });

          const data = await response.json();

          if (data.error) {
            throw new Error(data.error.message);
          }

          return data.result;
        } catch (error) {
          console.error('Error fetching NFTs:', error.message);
          throw error;
        }
      }

      displayNFTPortfolio(nfts) {
        console.log('\n🖼️  NFT Portfolio Summary');
        console.log('========================');
        console.log(`Total NFTs: ${nfts.total}`);
        console.log(`Showing: ${nfts.items.length} items\n`);

        nfts.items.forEach((nft, index) => {
          console.log(`${index + 1}. ${nft.content?.metadata?.name || 'Unnamed NFT'}`);
          console.log(`   Collection: ${nft.grouping?.[0]?.group_value || 'Individual'}`);
          console.log(`   Compressed: ${nft.compression?.compressed ? 'Yes' : 'No'}`);
          console.log(`   Image: ${nft.content?.files?.[0]?.uri || 'No image'}`);
          console.log(`   ID: ${nft.id}\n`);
        });
      }

      async getRandomNFT(ownerAddress) {
        const portfolio = await this.fetchNFTsByOwner(ownerAddress, 50);
        
        if (portfolio.items.length === 0) {
          console.log('No NFTs found for this address.');
          return null;
        }

        const randomIndex = Math.floor(Math.random() * portfolio.items.length);
        return portfolio.items[randomIndex];
      }
    }

    // Usage example
    async function main() {
      const viewer = new NFTPortfolioViewer('YOUR_API_KEY');
      
      // Anatoly's wallet address
      const walletAddress = '86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY';
      
      console.log('🚀 Fetching NFT portfolio...');
      
      try {
        // Get full portfolio overview
        const portfolio = await viewer.fetchNFTsByOwner(walletAddress);
        viewer.displayNFTPortfolio(portfolio);
        
        // Get a random NFT for featured display
        console.log('🎲 Featured Random NFT:');
        console.log('=====================');
        const randomNFT = await viewer.getRandomNFT(walletAddress);
        
        if (randomNFT) {
          console.log(`Name: ${randomNFT.content?.metadata?.name}`);
          console.log(`Description: ${randomNFT.content?.metadata?.description || 'No description'}`);
          console.log(`Image: ${randomNFT.content?.files?.[0]?.uri}`);
        }
        
      } catch (error) {
        console.error('Failed to fetch NFT data:', error.message);
      }
    }

    main();
    ```
  </Step>

  <Step title="Add your API key">
    Replace `YOUR_API_KEY` with your actual API key from the Helius dashboard.
  </Step>

  <Step title="Run your NFT portfolio viewer">
    ```bash theme={"system"}
    node nft-portfolio.js
    ```
  </Step>

  <Step title="Success! 🎉">
    You've built your first Solana application! The output shows:

    * Total NFT count in the wallet
    * Individual NFT details including compression status
    * Collection information
    * A featured random NFT

    **What you've learned:**

    * How to structure API calls to Helius
    * Working with the DAS API response format
    * Handling compressed vs standard NFTs
    * Building reusable code for NFT operations
  </Step>
</Steps>

## Take It Further

Now that you understand the basics, explore these advanced features:

<CardGroup cols={2}>
  <Card title="Send Transactions" icon="paper-plane" href="/sending-transactions/overview">
    Learn transaction optimization, priority fees, and smart routing for reliable execution.
  </Card>

  <Card title="Advanced NFT Operations" icon="images" href="/das/get-nfts">
    Search NFTs by traits, fetch collection stats, and work with token metadata at scale.
  </Card>

  <Card title="Real-Time Data Streaming" icon="bolt" href="/data-streaming/quickstart">
    Stream live blockchain data with sub-second latency using gRPC or enhanced WebSockets.
  </Card>

  <Card title="Automate with Webhooks" icon="bell" href="/webhooks">
    Set up intelligent notifications for wallet activity, NFT sales, and custom on-chain events.
  </Card>
</CardGroup>

## What's Next?

You've successfully built your first Solana application with Helius! Here are some ideas to expand your project:

* **Add wallet connection**: Integrate with wallets
* **Build a UI**: Create a React/Vue frontend to display the portfolio
* **Add filtering**: Search by collection, traits, or mint date
* **Real-time updates**: Use WebSockets to show live portfolio changes
* **Analytics**: Track portfolio value and NFT price history
