Skip to content

leaderboards.topProviders()

Get content creators ranked by total revenue earned.

Signature

leaderboards.topProviders(query?: LeaderboardPeriodQuery): Promise<LeaderboardResponse<TopProvider>>

Parameters

query (optional)

  • Type: LeaderboardPeriodQuery
interface LeaderboardPeriodQuery {
  page_size?: number;                    // Results per page (default: 20)
  period?: '1d' | '7d' | '30d' | 'all';  // Time period (default: 'all')
}

Returns

  • Type: Promise<LeaderboardResponse<TopProvider>>
interface TopProvider {
  rank: string;
  user_id: string;
  username?: string | null;
  wallet_address: string;
  total_feeds: string;
  total_entries: string;
  total_purchases: string;
  total_revenue: string;
  unique_buyers: string;
  joined_at: number;
}

Usage

Basic Example

const topProviders = await grapevine.leaderboards.topProviders();
 
topProviders.data.forEach(provider => {
  console.log(`#${provider.rank}: ${provider.username || provider.wallet_address}`);
  console.log(`   Revenue: ${formatUSDC(provider.total_revenue)}`);
  console.log(`   Feeds: ${provider.total_feeds}, Entries: ${provider.total_entries}`);
});
 
function formatUSDC(weiAmount: string): string {
  const usdc = Number(BigInt(weiAmount)) / 1e6;
  return `${usdc.toLocaleString('en-US', { minimumFractionDigits: 2 })}`;
}

Top Earners This Week

const weeklyTop = await grapevine.leaderboards.topProviders({ 
  period: '7d',
  page_size: 10 
});
 
console.log('Top earners this week:');
weeklyTop.data.forEach((p, i) => {
  const name = p.username || `${p.wallet_address.slice(0, 8)}...`;
  console.log(`${i + 1}. ${name}: ${formatUSDC(p.total_revenue)}`);
});

Provider Profile Card

function TopProviderCard({ provider }: { provider: TopProvider }) {
  return (
    <div className="provider-card">
      <div className="rank-badge">#{provider.rank}</div>
      
      <h3>{provider.username || 'Anonymous'}</h3>
      <p className="wallet">{provider.wallet_address.slice(0, 8)}...{provider.wallet_address.slice(-6)}</p>
      
      <div className="stats-grid">
        <div className="stat">
          <span className="value">{formatUSDC(provider.total_revenue)}</span>
          <span className="label">Revenue</span>
        </div>
        <div className="stat">
          <span className="value">{provider.total_feeds}</span>
          <span className="label">Feeds</span>
        </div>
        <div className="stat">
          <span className="value">{provider.total_entries}</span>
          <span className="label">Entries</span>
        </div>
        <div className="stat">
          <span className="value">{provider.unique_buyers}</span>
          <span className="label">Buyers</span>
        </div>
      </div>
      
      <p className="joined">
        Member since {new Date(provider.joined_at * 1000).toLocaleDateString()}
      </p>
    </div>
  );
}

Compare Periods

async function getProviderTrends(walletAddress: string) {
  const [daily, weekly, monthly, allTime] = await Promise.all([
    grapevine.leaderboards.topProviders({ period: '1d', page_size: 100 }),
    grapevine.leaderboards.topProviders({ period: '7d', page_size: 100 }),
    grapevine.leaderboards.topProviders({ period: '30d', page_size: 100 }),
    grapevine.leaderboards.topProviders({ period: 'all', page_size: 100 })
  ]);
  
  const findRank = (providers: TopProvider[]) => {
    const found = providers.find(p => p.wallet_address === walletAddress);
    return found ? parseInt(found.rank) : null;
  };
  
  return {
    dailyRank: findRank(daily.data),
    weeklyRank: findRank(weekly.data),
    monthlyRank: findRank(monthly.data),
    allTimeRank: findRank(allTime.data)
  };
}

Platform Statistics

async function getPlatformCreatorStats() {
  const providers = await grapevine.leaderboards.topProviders({ page_size: 100 });
  
  const totalRevenue = providers.data.reduce(
    (sum, p) => sum + BigInt(p.total_revenue),
    BigInt(0)
  );
  
  const totalFeeds = providers.data.reduce(
    (sum, p) => sum + parseInt(p.total_feeds),
    0
  );
  
  const totalEntries = providers.data.reduce(
    (sum, p) => sum + parseInt(p.total_entries),
    0
  );
  
  return {
    topCreatorsCount: providers.data.length,
    totalRevenue: formatUSDC(totalRevenue.toString()),
    avgRevenuePerCreator: formatUSDC((totalRevenue / BigInt(providers.data.length)).toString()),
    totalFeeds,
    totalEntries
  };
}

Leaderboard Table

function ProviderLeaderboard() {
  const [providers, setProviders] = useState<TopProvider[]>([]);
  const [period, setPeriod] = useState<LeaderboardPeriod>('all');
  
  useEffect(() => {
    grapevine.leaderboards.topProviders({ period, page_size: 20 })
      .then(result => setProviders(result.data));
  }, [period]);
  
  return (
    <div>
      <div className="period-selector">
        {(['1d', '7d', '30d', 'all'] as const).map(p => (
          <button 
            key={p} 
            onClick={() => setPeriod(p)}
            className={period === p ? 'active' : ''}
          >
            {p === '1d' ? 'Today' : p === '7d' ? 'Week' : p === '30d' ? 'Month' : 'All Time'}
          </button>
        ))}
      </div>
      
      <table className="leaderboard">
        <thead>
          <tr>
            <th>Rank</th>
            <th>Creator</th>
            <th>Revenue</th>
            <th>Feeds</th>
            <th>Entries</th>
            <th>Buyers</th>
          </tr>
        </thead>
        <tbody>
          {providers.map(p => (
            <tr key={p.user_id}>
              <td>#{p.rank}</td>
              <td>{p.username || `${p.wallet_address.slice(0, 8)}...`}</td>
              <td>{formatUSDC(p.total_revenue)}</td>
              <td>{p.total_feeds}</td>
              <td>{p.total_entries}</td>
              <td>{p.unique_buyers}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Notes

  • Authentication: Not required - public endpoint
  • Ranking: Ordered by total revenue (highest first)
  • Period: Filters revenue earned within the specified timeframe

Related