Earn Page is a ready-made component that allows users to earn rewards by connecting their wallets and interacting with DeFi partners.

Overview

The EarnPage component uses provided APIs to fetch partners and display them. You need to provide user so that the component can fetch the user’s join status. If the user has not joined, it prompts them to sign up for Turtle. If no user is provided, it will prompt a login modal.

Installation

If you haven’t already, install the dependencies using the following guide:

Get Started

Get Started with the Typescript SDK

Usage Example

MyEarnPage.tsx
import { ConnectButton, useConnectModal } from "@rainbow-me/rainbowkit";
import {
	defaultThemeConfig,
	EarnPage,
	TurtleLogo,
	TurtleProvider,
	useWagmiAdapter,
} from "@turtledev/react";
import { useAccount } from "wagmi";

export function MyEarnPage(): React.ReactElement {
	const { address } = useAccount();
	const { openConnectModal } = useConnectModal();
	const adapter = useWagmiAdapter();

	return (
		<TurtleProvider
			themeConfig={{
				...defaultThemeConfig,
				theme: "dark",
			}}
		>
			<EarnPage
				referral="YOUR_REFERRAL_CODE" // You can get one at https://app.turtle.club/
				user={address}
				header={{
					logo: <TurtleLogo fill="hsl(117, 85%, 69%)" className="w-10 h-10" />,
					text: "Turtle Earn",
					extra: <ConnectButton />,
				}}
				openConnectionModal={openConnectModal ?? (() => {})}
				{...adapter}
			/>
		</TurtleProvider>
	);
}

Adapter

We provide an adapter for Wagmi, since it’s the most popular React-based library for interacting with the blockchain. We use Wagmi at Turtle.club, so we can also recommend it as the best choice for your project.

If you want to use a different library, you can implement your own adapter. You will still have to plumb in your own wallet connection modal, as is shown in the example above.

MyEarnPage.tsx
import { useWagmiAdapter } from "@turtledev/react";

// Contains `signMessage`, `sendTransaction`, `changeNetwork`, and `network`
const adapter = useWagmiAdapter();

Props

user
string

User’s wallet address (undefined if not connected)

referral
string
required

Referral code

campaignId
string

Optional campaign identifier for tracking specific campaigns

network
Network
required

Network to use (extends number)

header
object

Header configuration object

openConnectionModal
function
required

Function to open the wallet connection modal

changeNetwork
function
required

Function to change the network: (network: Network) => Promise<void>

signMessage
function
required

Function to sign the message for wallet authentication: (message: string) => Promise<string>

sendTransaction
function
required

Function to send a transaction: (transaction: Transaction<Network>) => Promise<string>

startSigning
function

Optional callback triggered when signing process starts

onError
function

Optional error handler: (error: Error) => void

onSuccess
function

Optional success callback

Types

Transaction Interface

types.ts
import type { Address, Hex } from "viem";

export interface Transaction<Network> {
	from: Address;
	to: Address;
	data: Hex;
	chainId: Network;
	value?: bigint;
}

EarnPageProps Interface

types.ts
export interface EarnPageProps<Network extends number> {
	user: string | undefined;
	referral: string;
	campaignId?: string;
	network: Network;
	header?: {
		logo?: React.ReactNode;
		text?: React.ReactNode;
		extra?: React.ReactNode;
	};
	openConnectionModal: () => void;
	changeNetwork: (network: Network) => Promise<void>;
	signMessage: (message: string) => Promise<string>;
	sendTransaction: (transaction: Transaction<Network>) => Promise<string>;
	startSigning?: () => void;
	onError?: (error: Error) => void;
	onSuccess?: () => void;
}

Theming

Using the TurtleProvider

The EarnPage component must be wrapped in a TurtleProvider to apply theming. We recommend wrapping somewhere in your app, like in App.tsx, but you can wrap it in any component.

ThemedEarnPage.tsx
import { TurtleProvider, EarnPage, defaultThemeConfig } from "@turtledev/react";

function ThemedEarnPage() {
	// ...

	return (
		<TurtleProvider
			themeConfig={{
				...defaultThemeConfig,
				theme: "dark", // or 'light'
			}}
		>
			<EarnPage
				referral="TURTLE"
				user={address}
				network={1} // Ethereum mainnet
				header={{
					text: "Turtle Earn",
				}}
				openConnectionModal={openConnectModal}
				changeNetwork={changeNetwork}
				signMessage={signMessage}
				sendTransaction={sendTransaction}
			/>
		</TurtleProvider>
	);
}

Theme Configuration

The themeConfig prop accepts a TurtleThemeConfig object with the following structure:

types.ts
export interface TurtleThemeConfig {
	// Theme selection
	theme: "light" | "dark";

	// Shared variables (apply to both themes)
	shared: {
		borderRadius: string;
		gap: string;
		padding: string;
		fontFamily: string;
		fontSize: string;
		fontWeight: string;
	};

	// Theme-specific colors
	light: ThemeColors;
	dark: ThemeColors;
}

export interface ThemeColors {
	// Background colors
	bgPrimary: string;
	bgSecondary: string;
	bgAccent: string;
	bgTranslucent: string;

	// Text colors
	textPrimary: string;
	textSecondary: string;

	// Border color
	borderColor: string;

	// Button colors
	buttonBgColor: string;
	buttonTextColor: string;

	// Error color
	errorColor: string;
}

Default Theme

The default theme configuration is as follows:

default.ts
{
  theme: "dark",
  shared: {
    borderRadius: "0.5rem",
    gap: "0.75rem",
    padding: "1rem",
    fontFamily: "Inter, system-ui, -apple-system, sans-serif",
    fontSize: "1rem",
    fontWeight: "400",
  },
  light: {
    bgPrimary: "rgb(245, 245, 245)",
    bgSecondary: "rgba(220, 220, 220)",
    bgAccent: "rgba(200, 200, 200)",
    bgTranslucent: "hsl(0 0% 10% / 0.25)",
    borderColor: "rgb(220, 220, 225)",
    textPrimary: "rgba(10, 10, 10)",
    textSecondary: "rgba(30, 30, 30)",
    buttonBgColor: "hsl(117, 85%, 69%)",
    buttonTextColor: "rgb(10, 10, 10)",
    errorColor: "rgb(247, 23, 53)",
  },
  dark: {
    bgPrimary: "rgb(32, 32, 34)",
    bgSecondary: "rgba(20, 20, 20)",
    bgAccent: "rgba(60, 60, 60)",
    bgTranslucent: "hsl(0 0% 90% / 0.25)",
    borderColor: "rgb(53, 53, 59)",
    textPrimary: "rgba(255, 255, 255)",
    textSecondary: "rgba(225, 225, 225)",
    buttonBgColor: "hsl(117, 85%, 69%)",
    buttonTextColor: "rgb(10, 10, 10)",
    errorColor: "rgb(246, 56, 85)",
  },
}

How it Works

  1. The EarnPage component fetches available partners and deals
  2. It checks if the user has joined Turtle using the provided wallet address
  3. If not joined, it prompts the user to sign a message to join
  4. Once joined, users can access partner deals with boosted rewards
  5. The component handles all states: loading, empty results, and listing deals

By providing the necessary authentication functions, the EarnPage component handles the entire flow from wallet connection to deal redemption.