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

# Learn by building

> Browse tutorials, demo apps, and projects from the onchain community.

export const BuilderTiles = ({img, href, title, description, bgColor}) => {
  return <a href={href} target="_blank" rel="noopener noreferrer" className="group" style={{
    textDecoration: 'none',
    borderBottom: 'none'
  }}>
      <div className="flex flex-col gap-4 rounded-2xl p-6 min-h-[290px] h-full" style={{
    background: bgColor
  }}>
        <div className="w-full h-[120px] overflow-hidden rounded-xl">
          <img src={img} className="w-full h-full object-cover" alt={title} />
        </div>
        <div className="flex flex-col gap-3">
          <h2 className="text-md font-semibold text-white dark:text-white group-hover:underline group-hover:decoration-blue-500 group-hover:underline-offset-4 transition-all">
            {title}
          </h2>
          <p className="text-white dark:text-white text-sm font-medium" style={{
    textDecoration: 'none',
    borderBottom: 'none',
    boxShadow: 'none'
  }}>
            {description}
          </p>
        </div>
      </div>
    </a>;
};

export const ProductCard = ({img, href, title, description}) => {
  return <a href={href} target="_blank" rel="noopener noreferrer" className="group" style={{
    textDecoration: 'none',
    borderBottom: 'none'
  }}>
      <div className="flex flex-col gap-4 rounded-xl">
        <div className="w-full h-30 overflow-hidden rounded-xl">
          <img src={img} className="w-full h-full object-cover" alt={title} />
        </div>
        <div className="flex flex-col gap-3">
          <h2 className="text-md font-semibold text-gray-900 dark:text-gray-200 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors mb-[-8px]">
            {title}
          </h2>
          <p className="text-gray-500 dark:text-gray-400 text-sm font-medium" style={{
    textDecoration: 'none',
    borderBottom: 'none',
    boxShadow: 'none'
  }}>
            {description}
          </p>
        </div>
      </div>
    </a>;
};

export const coinbaseVideosCategories = [{
  id: "agentkit",
  title: "AgentKit",
  desc: "Build autonomous crypto agents with AgentKit.",
  links: [{
    label: "GitHub",
    href: "https://github.com/coinbase/agentkit"
  }, {
    label: "Replit",
    href: "https://replit.com/@CoinbaseDev/CDP-AgentKit?v=1"
  }, {
    label: "Guide",
    href: "/agent-kit/getting-started/quickstart"
  }],
  videoCode: `<iframe width="560" height="500" src="https://www.youtube.com/embed/hw-PuogqLR0?si=Z8ibXW600F_zwNue" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>`
}, {
  id: "mass-payments",
  title: "Mass Payments",
  desc: "Build a scalable mass payments application using CDP Non-custodial Wallets",
  links: [{
    label: "Demo",
    href: "https://masspayoutsdemo.xyz/"
  }, {
    label: "GitHub",
    href: "https://github.com/coinbase-samples/cdp-sdk-mass-payments-ts"
  }, {
    label: "Guide",
    href: "/get-started/demo-apps/app-examples/automated-mass-payouts"
  }],
  videoCode: `<iframe width="560" height="500" src="https://www.youtube.com/embed/wfyB-nq1btI?si=ymSABVZU_HnAa_eV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>`
}];

export const Tags = ({tags, className}) => {
  if (!tags || !Array.isArray(tags)) {
    return null;
  }
  return <div className={`mt-5 mb-5 flex flex-row flex-wrap gap-2 ${className}`}>
      {tags.map((tag, index) => <span key={index} className="text-sm text-[#733E00] dark:text-yellow-500 bg-[#FFFCF1] dark:bg-yellow-500/10 font-semibold px-2 py-1 rounded-lg">{tag}</span>)}
    </div>;
};

export const VideoTiles = ({items}) => {
  const [activeSubTab, setActiveSubTab] = useState(items[0]?.id ?? null);
  const currentSub = items.find(item => item.id === activeSubTab);
  return <div className="not-prose space-y-6">
      <div className="flex flex-col lg:flex-row gap-6">
       
        <div className="flex flex-col w-full lg:w-1/3 space-y-2">
          {items.map(item => <button key={item.id} onClick={() => setActiveSubTab(item.id)} className={`flex items-start gap-1.5 text-left px-5 py-4 rounded-2xl transition-all ${activeSubTab === item.id ? 'bg-gray-100 dark:bg-white/5' : ''}`}>
              <div className="flex-1">
                <h3 className="font-semibold text-base text-black dark:text-white">
                  {item.title}
                </h3>
                {activeSubTab === item.id && <>
                    <p className="text-sm text-gray-600 dark:text-gray-400 font-medium">{item.desc}</p>
                    {item.links && <div className="flex flex-wrap gap-3 mt-2">
                        {item.links.map(link => <a key={link.label} href={link.href} target="_blank" rel="noopener noreferrer" className="flex items-center gap-1 text-blue-600 dark:text-blue-600 font-semibold text-sm hover:underline hover:text-blue-700 dark:hover:text-blue-500">
                            {link.label}
                          </a>)}
                      </div>}
                  </>}
              </div>
            </button>)}
        </div>
        <div className="group w-full h-fit lg:w-2/3 bg-[#F5F8FF] dark:bg-[#001033] rounded-2xl flex items-center justify-center border border-[#D3E1FF] dark:border-[#011D5B] p-4">
          {currentSub?.videoCode ? <div className="w-full aspect-video rounded-xl overflow-hidden">
              <div className="w-full h-full" style={{
    position: 'relative',
    paddingBottom: '56.25%',
    height: 0
  }}>
                <div style={{
    position: 'absolute',
    top: 0,
    left: 0,
    width: '100%',
    height: '100%'
  }} dangerouslySetInnerHTML={{
    __html: currentSub.videoCode.replace(/<iframe ([^>]*)width="[0-9]+" height="[0-9]+"/, '<iframe $1width="100%" height="100%" style="width:100%;height:100%;"')
  }} />
              </div>
            </div> : <p className="text-gray-400 dark:text-gray-500">No video available</p>}
        </div>
      </div>
    </div>;
};

export const VideoLink = ({children, href}) => {
  return <a href={href} className="text-[#0955FE] dark:text-blue-400 font-bold flex items-center gap-1">
      {children} <Icon icon="arrow-up-right" size="14" />
    </a>;
};

export const LearnTitle = ({children}) => {
  return <div className="text-gray-900 dark:text-gray-200 text-2xl font-bold">
      {children}
    </div>;
};

export const QuickstartItem = ({title, description, icon, href}) => {
  return <a className="group flex items-start gap-4 hover:bg-gray-100 dark:hover:bg-white/5 p-3 rounded-xl" href={href}>
      <div className="flex-shrink-0 w-12 h-12 flex items-center justify-center rounded-lg border border-gray-200 dark:border-white/10 bg-background-light dark:bg-background-dark">
        {icon}
      </div>
      <div>
        <div className="font-semibold text-sm text-gray-900 dark:text-gray-200">{title}</div>
        <div className="mt-1 text-gray-500 text-sm dark:text-gray-400">{description}</div>
      </div>
    </a>;
};

export const TitleLink = ({children, href}) => {
  return <a href={href} className="text-[#0955FE] dark:text-blue-400 font-bold flex items-center gap-1">
      {children} <Icon icon="arrow-right" size="14" color="currentColor" />
    </a>;
};

export const Title = ({children}) => {
  return <div className="text-gray-900 dark:text-gray-200 text-3xl tracking-tight">
      {children}
    </div>;
};

export const Container = ({children}) => {
  return <div className="px-4 lg:px-10 py-14">
      {children}
    </div>;
};

export const CandleSticksIcon = ({className}) => {
  return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
      <path d="M10.9888 -0.00482178H12.9888V2.99518H13.9888V14.9952H12.9888V17.9952H10.9888V14.9952H9.98877V2.99518H10.9888V-0.00482178Z" fill="currentColor" />
      <path d="M3.98877 8.99518H2.98877V20.9952H3.98877V23.9952H5.98877V20.9952H6.98877V8.99518H5.98877V5.99518H3.98877V8.99518Z" fill="currentColor" />
      <path d="M19.9888 8.99518H20.9888V20.9952H19.9888V23.9952H17.9888V20.9952H16.9888V8.99518H17.9888V5.99518H19.9888V8.99518Z" fill="currentColor" />
    </svg>;
};

export const NftIcon = ({className}) => {
  return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
      <path d="M11.4888 7.99518L12.7616 11.2224L15.9888 12.4952L12.7616 13.768L11.4888 16.9952L10.216 13.768L6.98877 12.4952L10.216 11.2224L11.4888 7.99518Z" fill="currentColor" />
      <path d="M16.1252 7.85878L15.4888 6.49518L14.8524 7.85878L13.4888 8.49518L14.8524 9.13157L15.4888 10.4952L16.1252 9.13157L17.4888 8.49518L16.1252 7.85878Z" fill="currentColor" />
      <path d="M4.9177 19.0662C3.10806 17.2566 1.98877 14.7566 1.98877 11.9952C1.98877 6.47233 6.46592 1.99518 11.9888 1.99518C17.5116 1.99518 21.9888 6.47233 21.9888 11.9952C21.9888 14.7566 20.8695 17.2566 19.0598 19.0662L21.9888 21.9952H1.98877L4.9177 19.0662ZM15.8648 18.9952C18.3242 17.6304 19.9888 15.0072 19.9888 11.9952C19.9888 7.5769 16.407 3.99518 11.9888 3.99518C7.57049 3.99518 3.98877 7.5769 3.98877 11.9952C3.98877 15.0072 5.65334 17.6304 8.11276 18.9952H15.8648Z" fill="currentColor" />
    </svg>;
};

export const CurrenciesIcon = ({className}) => {
  return <svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
      <path d="M10.4523 10.669L9.48873 8.35236L8.52518 10.669L6.02417 10.8695L7.92968 12.5018L7.34752 14.9423L9.48873 13.6345L11.63 14.9423L11.0478 12.5018L12.9533 10.8695L10.4523 10.669Z" fill="currentColor" />
      <path d="M9.48877 20.4952C14.1832 20.4952 17.9888 16.6896 17.9888 11.9952C17.9888 7.30076 14.1832 3.49518 9.48877 3.49518C4.79435 3.49518 0.98877 7.30076 0.98877 11.9952C0.98877 16.6896 4.79435 20.4952 9.48877 20.4952ZM9.48877 18.4952C5.89892 18.4952 2.98877 15.585 2.98877 11.9952C2.98877 8.40533 5.89892 5.49518 9.48877 5.49518C13.0786 5.49518 15.9888 8.40533 15.9888 11.9952C15.9888 15.585 13.0786 18.4952 9.48877 18.4952Z" fill="currentColor" />
      <path d="M18.9888 20.1215C22.4631 19.0539 24.9888 15.8195 24.9888 11.9951C24.9888 8.17075 22.4631 4.93628 18.9888 3.86871V5.99328C21.3377 6.97284 22.9888 9.29117 22.9888 11.9951C22.9888 14.6991 21.3377 17.0174 18.9888 17.997V20.1215Z" fill="currentColor" />
    </svg>;
};

export const WalletIcon = ({className}) => {
  return <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
      <path d="M16.9888 15.9952C17.5411 15.9952 17.9888 15.5475 17.9888 14.9952C17.9888 14.4429 17.5411 13.9952 16.9888 13.9952C16.4365 13.9952 15.9888 14.4429 15.9888 14.9952C15.9888 15.5475 16.4365 15.9952 16.9888 15.9952Z" fill="currentColor" />
      <path d="M18.9888 8.99518V1.99518L1.98877 8.54063V21.9952H21.9888V8.99518H18.9888ZM19.9888 10.9952V19.9952H3.98877V10.9952H19.9888ZM16.9888 4.90836V8.99518H6.37438L16.9888 4.90836Z" fill="currentColor" />
    </svg>;
};

<div className="flex flex-col w-full mt-10">
  <div className="flex items-center justify-between w-full mb-6">
    <LearnTitle>Video tutorials</LearnTitle>
    <VideoLink href="https://www.youtube.com/playlist?list=PL0zEUTVaoPOyNCos7rpiaQjjl7ZOuesF5" className="border-none">See all videos</VideoLink>
  </div>
</div>

<VideoTiles items={coinbaseVideosCategories} />

<div className="flex flex-col w-full mt-20">
  <div className="flex items-center justify-between w-full">
    <LearnTitle>Demo apps</LearnTitle>
    <TitleLink href="/get-started/demo-apps/explore" className="border-none">See all demo apps</TitleLink>
  </div>

  <p className="text-[#3D4045] dark:text-gray-300 font-medium text-md">
    Jumpstart your building journey with ready-to-use demo apps.
  </p>
</div>

<div className="learn-demo-cards">
  <CardGroup cols={3}>
    <Card title="Aave Lending" href="/get-started/demo-apps/app-examples/aave-lending" img="https://mintcdn.com/coinbase-prod/5EwRXPqmEZzhto_n/get-started/demo-apps/images/aave-lending.svg?fit=max&auto=format&n=5EwRXPqmEZzhto_n&q=85&s=82431fd74865cbd6cca1533493cfea38" width="262" height="111" data-path="get-started/demo-apps/images/aave-lending.svg">
      Enable users to earn yield by depositing into Aave with Non-custodial Wallets.

      <Tags tags={['DeFi', 'Non-custodial Wallet']} className="!mb-0 mt-2" />
    </Card>

    <Card title="Automated Mass Payouts" href="/get-started/demo-apps/app-examples/automated-mass-payouts" img="https://mintcdn.com/coinbase-prod/cCGVQ8zMGF76EFDn/get-started/demo-apps/images/mass-payments.svg?fit=max&auto=format&n=cCGVQ8zMGF76EFDn&q=85&s=fe8220b6f969419f0c13ab31c597b3eb" width="539" height="190" data-path="get-started/demo-apps/images/mass-payments.svg">
      Automate payroll, rewards, and bulk transfers at scale with Non-custodial Wallet.

      <Tags tags={['Payments', 'Non-custodial Wallet']} className="!mb-0 mt-2" />
    </Card>

    <Card title="Onramp Demo App" href="/get-started/demo-apps/starter/onramp-demo-app" img="https://mintlify-assets.b-cdn.net/onramp-demo.png">
      Enable users to easily fund their crypto wallet with fiat.

      <Tags tags={['Starter', 'Onramp']} className="!mb-0 mt-2" />
    </Card>
  </CardGroup>
</div>

<div className="mt-20">
  <h2 className="text-2xl font-bold mb-2">Product demos + AMAs</h2>

  <p className="text-[#3D4045] dark:text-gray-300 font-medium text-md mb-6">
    View the latest demos from the CDP team.
  </p>
</div>

<CardGroup cols={4} className="custom-card-group">
  <ProductCard title="Smart Wallet Demo + AMA" description="We cover everything from session keys, to a Mobile SDK demo, to live Q&A from Discord." href="https://youtu.be/EPdHV_Ex0XY" img="https://mintlify-assets.b-cdn.net/coinbase/demos-smart-wallet.svg" />

  <ProductCard title="Paymaster Demo + AMA" description="How Paymaster is enabling builders to create magical gasless experiences for users." href="https://youtu.be/vqKhGq3kshg" img="https://mintlify-assets.b-cdn.net/coinbase/demos-paymaster.svg" />

  <ProductCard title="Staking Demo + AMA" description="Hear about our latest developments, upcoming releases, and Q&A from Discord." href="https://youtu.be/NM-dutlwRFc" img="https://mintlify-assets.b-cdn.net/coinbase/demos-staking-api.svg" />

  <ProductCard title="Onramp Demo + AMA" description="Dive into the newest features of Onramp, exciting upcoming releases, and Q&A from Discord." href="https://youtu.be/Nw7keUjloL8" img="https://mintlify-assets.b-cdn.net/coinbase/demos-onramp.svg" />
</CardGroup>

<div className="mt-20">
  <h2 className="text-2xl font-bold mb-2">CDP builder apps and demos</h2>

  <p className="text-[#3D4045] dark:text-gray-300 font-medium text-md mb-6">
    See what great apps builders have created using CDP APIs.
  </p>
</div>

<CardGroup cols={3} className="custom-card-group">
  <BuilderTiles title="Blocklords" description="Blocklords Dynasty is a player-driven medieval grand strategy game with innovative gameplay mechanics and a player-powered economy." href="https://www.coinbase.com/developer-platform/discover/case-studies/blocklords" img="https://mintlify-assets.b-cdn.net/coinbase/builder-blocklords.png" bgColor="linear-gradient(0deg, rgb(24, 40, 31) 0%, rgb(106, 125, 97) 100%)" />

  <BuilderTiles title="Moshicam" description="Automatically earn royalties when people create or collect photos with your borders. No crypto expertise required." href="https://moshi.cam/" img="https://mintlify-assets.b-cdn.net/coinbase/moshicam.gif" bgColor="linear-gradient(0deg, rgb(179, 90, 8) 0%, rgb(250, 214, 140) 100%)" />

  <BuilderTiles title="Moonwell" description="Moonwell is an open and decentralized lending and borrowing protocol built on Base, Optimism, Moonbeam, and Moonriver." href="https://moonwell.fi/" img="https://mintlify-assets.b-cdn.net/coinbase/builder-moonwell.png" bgColor="linear-gradient(rgb(162, 207, 232) 0%, rgb(5, 90, 189) 100%)" />
</CardGroup>
