Skip to content

yearn/yPartners

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

441 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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
    • Price data is fetched from DefiLlama (no API key required) 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> = {
  yearn: { ... },  // 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 = {
  yearn: { ... },  // 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.

About

Partners website

Resources

License

Stars

Watchers

Forks

Contributors

Generated from yearn/web-template