Skip to content

leaderboards.topFeeds()

Get feeds ranked by total number of entries (most content).

Signature

leaderboards.topFeeds(query?: LeaderboardBaseQuery): Promise<LeaderboardResponse<TopFeed>>

Parameters

query (optional)

  • Type: LeaderboardBaseQuery
interface LeaderboardBaseQuery {
  page_size?: number;  // Results per page (default: 20)
}

Returns

  • Type: Promise<LeaderboardResponse<TopFeed>>
interface TopFeed {
  id: string;
  owner_id: string;
  category_id: string | null;
  name: string;
  description: string | null;
  image_cid: string | null;
  is_active: boolean;
  total_entries: number;
  total_purchases: number;
  total_revenue: string;
  tags: string[] | null;
  created_at: number;
  updated_at: number;
  owner_wallet: string;
  owner_username: string | null;
  category_name: string | null;
}

Usage

Basic Example

const topFeeds = await grapevine.leaderboards.topFeeds();
 
topFeeds.data.forEach((feed, index) => {
  console.log(`#${index + 1}: ${feed.name}`);
  console.log(`   Entries: ${feed.total_entries}`);
  console.log(`   by: ${feed.owner_username || feed.owner_wallet}`);
});

Most Content-Rich Feeds

const top10 = await grapevine.leaderboards.topFeeds({ page_size: 10 });
 
console.log('Feeds with most content:');
top10.data.forEach((feed, i) => {
  console.log(`${i + 1}. ${feed.name} - ${feed.total_entries} entries`);
});

Content Discovery

async function getContentRichFeeds() {
  const topFeeds = await grapevine.leaderboards.topFeeds({ page_size: 20 });
  
  // Only feeds with meaningful content
  const substantial = topFeeds.data.filter(f => f.total_entries >= 10);
  
  // Group by category
  const byCategory = substantial.reduce((acc, feed) => {
    const cat = feed.category_name || 'Uncategorized';
    if (!acc[cat]) acc[cat] = [];
    acc[cat].push(feed);
    return acc;
  }, {} as Record<string, TopFeed[]>);
  
  return byCategory;
}

Calculate Content Statistics

async function getPlatformContentStats() {
  const topFeeds = await grapevine.leaderboards.topFeeds({ page_size: 100 });
  
  const totalEntries = topFeeds.data.reduce(
    (sum, feed) => sum + feed.total_entries,
    0
  );
  
  const avgEntriesPerFeed = totalEntries / topFeeds.data.length;
  
  const mostProlific = topFeeds.data[0];
  
  return {
    totalFeedsAnalyzed: topFeeds.data.length,
    totalEntries,
    avgEntriesPerFeed: avgEntriesPerFeed.toFixed(1),
    mostProlificFeed: {
      name: mostProlific.name,
      entries: mostProlific.total_entries,
      creator: mostProlific.owner_username
    }
  };
}

Feed Grid Component

function TopFeedsGrid() {
  const [feeds, setFeeds] = useState<TopFeed[]>([]);
  
  useEffect(() => {
    grapevine.leaderboards.topFeeds({ page_size: 12 })
      .then(result => setFeeds(result.data));
  }, []);
  
  return (
    <div className="feed-grid">
      {feeds.map(feed => (
        <div key={feed.id} className="feed-card">
          {feed.image_cid && (
            <img 
              src={`https://gateway.pinata.cloud/ipfs/${feed.image_cid}`} 
              alt={feed.name}
            />
          )}
          
          <h3>{feed.name}</h3>
          <p className="creator">
            by {feed.owner_username || feed.owner_wallet.slice(0, 8)}...
          </p>
          
          <div className="stats">
            <span className="entries">{feed.total_entries} entries</span>
            <span className="revenue">{formatUSDC(feed.total_revenue)}</span>
          </div>
          
          {feed.category_name && (
            <span className="category">{feed.category_name}</span>
          )}
          
          {feed.description && (
            <p className="description">{feed.description}</p>
          )}
        </div>
      ))}
    </div>
  );
}

Notes

  • Authentication: Not required - public endpoint
  • Ranking: Ordered by total_entries (highest first)
  • Includes: Owner and category information for display

Related