Skip to content

yearn/yPartners

Repository files navigation

Yearn B2B Partners Dashboard

Marketing site and analytics dashboard for Yearn’s partner program. The landing page highlights fees and vault counts, the Team Up form pings a Telegram bot, and partner dashboards (e.g. /dashboard/0x...treasury) display balances and payouts pulled via the local API routes.

  • Live site: https://partners.yearn.fi
  • Tech: Next.js 15 + TypeScript, TailwindCSS, SWR, Yearn Web Lib components
  • Token/chain icons: loaded from https://token-assets-one.vercel.app (see lib/crypto/tokenLogos.ts and next.config.js)

Quick start

  1. Copy environment defaults: cp .env.example .env
  2. Install dependencies (pnpm recommended because the lockfile is present): pnpm install
  3. Run the dev server: pnpm dev then open http://localhost:3000
  4. Use address 0x93A62dA5a14C80f265DAbC077fCEE437B1a0Efde for login testing

Other scripts:

  • pnpm lint – run ESLint
  • pnpm build – type-check and build for production
  • pnpm start – start the built app
  • pnpm export – generate a static export (if needed)

Configuration

  • Public metadata is set in pages/_app.tsx (site name, description, theme color, OG image). Update those values to rebrand the site.
  • Runtime environment variables live in .env:
    • YVISION_BASE_URI – legacy (currently unused; historical Yearn Vision base)
    • ENVIO_GRAPHQL_URL – required Envio GraphQL endpoint used by /api/partner-fees
    • KONG_GRAPHQL_URL – optional Kong GraphQL endpoint for vault metadata (defaults to https://kong.yearn.fi/api/gql)
    • RPC_URL_MAINNET_PUBLIC, RPC_URL_MAINNET_PRIVATE – preferred public/latest and private/archive RPCs
    • RPC_URL_BASE_PUBLIC, RPC_URL_BASE_PRIVATE – preferred public/latest and private/archive RPCs
    • RPC_URL_ARBITRUM_PUBLIC, RPC_URL_ARBITRUM_PRIVATE – preferred public/latest and private/archive RPCs
    • RPC_URL_POLYGON_PUBLIC, RPC_URL_POLYGON_PRIVATE – preferred public/latest and private/archive RPCs
    • RPC_URL_MAINNET, RPC_URL_BASE, RPC_URL_ARBITRUM, RPC_URL_POLYGON – legacy fallback RPCs if the split envs are unset
    • NEXTAUTH_SECRET – secret for NextAuth usage
    • COINGECKO_API_KEY – optional API key for Coingecko price lookups (used to convert non-USD vault values to USD)
    • TELEGRAM_BOT, TELEGRAM_RECIPIENT_USERID – required by pages/api/telegram.ts to deliver Team Up form submissions
    • IP_TO_BLOCK – optional comma-separated IPs to deny from the contact form

Partner dashboards

Partner metadata (name, treasury address, logo) is defined in utils/Partners.tsx. The login modal expects a treasury address that maps to an entry in PARTNERS; successful login routes to /dashboard/[partnerID] where vault balances and payouts are fetched via:

  • /api/partner-tvl
  • /api/partner-fees (with/without snapshots)

These endpoints aggregate over the vault + depositor configuration in PARTNER_VAULT_CONFIG and return normalized totals, asset metadata, and per-account breakdowns.

Adding a new partner

To add a new partner to the dashboard, edit utils/Partners.tsx and add entries to two objects:

1. Add partner metadata to PARTNERS

const PARTNERS: TDict<TPartner> = {
  sturdy: { ... },  // existing partner

  // Add your new partner here
  yourpartner: {
    name: 'Your Partner Name',           // Display name
    shortName: 'yourpartner',            // URL-safe identifier (lowercase, no spaces)
    treasury: [toAddress('0xYourPartnerTreasuryAddress')],  // Partner's treasury address(es)
    logo: <LogoYourPartner className={'text-900'} />        // Partner logo component
  }
};

The treasury address will be used for authentication and URL routing (e.g., /dashboard/0xYourPartnerTreasuryAddress).

Note: SHAREABLE_ADDRESSES is auto-generated from PARTNERS, so you don't need to add anything there.

2. Configure vault data in PARTNER_VAULT_CONFIG

const PARTNER_VAULT_CONFIG: TPartnerVaultConfig = {
  sturdy: { ... },  // existing partner

  // Add your new partner's vault configuration
  yourpartner: {
    1: {  // Chain ID (1 = Ethereum mainnet, 8453 = Base, 137 = Polygon, etc.)
      [toAddress('0xVaultAddress1')]: [  // Yearn V3 vault address
        // List of depositor addresses to track for this vault
        toAddress('0xDepositorAddress1'),
        toAddress('0xDepositorAddress2'),
        toAddress('0xDepositorAddress3')
      ],
      // Add more vaults on the same chain
      [toAddress('0xVaultAddress2')]: [
        toAddress('0xDepositorAddress4'),
        toAddress('0xDepositorAddress5')
      ]
    },
    // Add vaults on other chains
    8453: {  // Base chain
      [toAddress('0xBaseVaultAddress')]: [
        toAddress('0xDepositorAddress6')
      ]
    }
  }
};

The dashboard will automatically:

  • Query balances and fees for all depositor addresses across all vaults and chains
  • Aggregate total TVL and fees across all chains and vaults
  • Display the combined metrics on the partner's dashboard

3. Add partner logo component

Create a logo component in components/icons/partners/ following the existing pattern:

// components/icons/partners/LogoYourPartner.tsx
import type {ReactElement} from 'react';

export default function LogoYourPartner({className, isColored}: {className?: string, isColored?: boolean}): ReactElement {
  return (
    <svg className={className} viewBox="0 0 100 100">
      {/* Your SVG logo here */}
    </svg>
  );
}

Then import it in utils/Partners.tsx:

import LogoYourPartner from 'components/icons/partners/LogoYourPartner';

And add it to the LOGOS object (keyed by shortName):

const LOGOS: TPartnerLogo = {
  yourpartner: <LogoYourPartner className={'text-900 h-3/4 w-3/4'} />
};

Example: Complete partner configuration

// 1. Add to PARTNERS
const PARTNERS: TDict<TPartner> = {
  acme: {
    name: 'Acme Protocol',
    shortName: 'acme',
    treasury: [toAddress('0x1234567890123456789012345678901234567890')],
    logo: <LogoAcme className={'text-900'} />
  }
};

// 2. Add to PARTNER_VAULT_CONFIG
const PARTNER_VAULT_CONFIG: TPartnerVaultConfig = {
  acme: {
    1: {  // Ethereum mainnet
      [toAddress('0xBe53A109B494E5c9f97b9Cd39Fe969BE68BF6204')]: [  // USDC vault
        toAddress('0xAcmeDepositor1'),
        toAddress('0xAcmeDepositor2')
      ]
    }
  }
};

After adding your partner, rebuild the app with pnpm build and the new dashboard will be available at:

  • /dashboard/0x1234567890123456789012345678901234567890 (using treasury address)
  • Or via the login modal using the treasury address

Known limitations

  • Yearn Vision-driven chart aggregation is currently disabled; the large historical chart fetch block in components/dashboard/DashboardTabsWrapper.tsx is commented out.
  • usePartner currently returns an empty vaults object (legacy Yearn Vision data path disabled), so per-vault tabs and charts are not populated from that source.
  • The dashboard currently relies on the local /api/partner-tvl and /api/partner-fees routes for totals; these endpoints are the supported path while the legacy flow is commented out.