Skip to main content
The @turtleclub/earn-provider package provides a complete, zero-configuration solution for integrating the Earn Widget with Web3 functionality. It includes all the required providers and a hook that returns a ready-to-use adapter.

Overview

This package provides:
  • EVM Client: Pre-configured Wagmi setup
  • Wallet Provider: RainbowKit integration for wallet connections
  • Adapter Hook: useEarnDefaultAdapter that returns all methods the widget needs

Installation

bun add @turtleclub/earn-provider

Quick Start

The simplest way to use the Earn Widget:
app/earn-widget.tsx
import { EarnWidget } from '@turtleclub/earn-widget';
import { TurtleDefaultProvider, useEarnDefaultAdapter } from '@turtleclub/earn-provider';

function EarnWidgetContent() {
  // This hook provides everything the widget needs
  const adapter = useEarnDefaultAdapter();
  
  return (
    <EarnWidget
      config={{ /* Your widget configuration from https://dashboard.turtle.xyz/ */ }}
      adapter={adapter}
      distributorId={{ /* Your unique distributor ID from https://dashboard.turtle.xyz/ */ }}
    />
  );
}

export function MyApp() {
  return (
    <TurtleDefaultProvider>
      <EarnWidgetContent />
    </TurtleDefaultProvider>
  );
}

The useEarnDefaultAdapter Hook

The useEarnDefaultAdapter hook provides a complete adapter implementation that includes:
  • user: Current connected wallet address
  • network: Current network & chain ID
  • openConnectionModal: Opens the wallet connection modal
  • signMessage: Signs messages for authentication
  • sendTransaction: Sends transactions and waits for confirmation
  • changeNetwork: Switches between different networks
const adapter = useEarnDefaultAdapter();

// adapter = {
//   user: "0x123...",                       // Connected wallet address (reactive value)
//   network: 1,                             // Current chain ID (reactive value)
//   openConnectionModal: () => {},
//   signMessage: async (msg) => "0x...",
//   sendTransaction: async (tx) => "0x...",
//   changeNetwork: async (chainId) => {}
// }

Provider Configuration

Basic Usage

For most use cases, the default configuration works out of the box:
<TurtleDefaultProvider>
  {/* Your app content */}
</TurtleDefaultProvider>

Custom Configuration

You can customize the provider with your own configuration or your providers already configured on your app:
import { TurtleDefaultProvider } from '@turtleclub/earn-provider';
import { QueryClient } from '@tanstack/react-query';

// Create your own query client
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000, // 1 minute
    }
  }
});

// Custom Wagmi configuration
const wagmiOptions = {
  appName: "My DeFi App",
  projectId: "your-walletconnect-project-id", // Get from https://cloud.reown.com
  appUrl: "https://myapp.com",
  appDescription: "My awesome DeFi application",
  appIcon: "https://myapp.com/icon.png"
};

export function App() {
  return (
    <TurtleDefaultProvider 
      queryClient={queryClient}
      wagmiOptions={wagmiOptions}
    >
      {/* Your app content */}
    </TurtleDefaultProvider>
  );
}

Provider Props

queryClient
QueryClient
Optional custom QueryClient instance from @tanstack/react-query. If not provided, a default one is created.
wagmiOptions
object
Optional Wagmi configuration options. If not provided, a default one is created.

Complete Example

Here’s a complete example with custom styling and configuration:
app/page.tsx
"use client"; // For Next.js

import { EarnWidget } from '@turtleclub/earn-widget';
import { TurtleDefaultProvider, useEarnDefaultAdapter } from '@turtleclub/earn-provider';
import type { WidgetStyleConfig } from '@turtleclub/earn-widget';

// Widget styling configuration
const widgetConfig: WidgetStyleConfig = {
  theme: "dark",
  widgetWidth: "default",
  showNavigation: true,
  padding: "lg",
  rounding: "xl",
  fontFamily: "Inter, sans-serif",
  
  // Custom branding
  logo: {
    light: "/logo-light.svg",
    dark: "/logo-dark.svg",
    fallback: "MyApp"
  },
  
  // Custom colors
  styles: {
    background: "#0f0f0f",
    background_dark: "#000000",
    foreground: "#ffffff", 
    foreground_dark: "#f0f0f0",
    primary: "#00dc82",
    primary_dark: "#00f092"
  }
};

// Wagmi configuration
const wagmiOptions = {
  appName: "MyApp Earn",
  projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
  appUrl: "https://myapp.com",
  appDescription: "Earn rewards with MyApp"
};

function EarnWidgetWithAdapter() {
  const adapter = useEarnDefaultAdapter();
  
  return (
    <div className="min-h-screen bg-black p-4">
      <EarnWidget
        config={widgetConfig}
        adapter={adapter}
        distributorId={process.env.NEXT_PUBLIC_DISTRIBUTOR_ID!}
      />
    </div>
  );
}

export default function EarnPage() {
  return (
    <TurtleDefaultProvider wagmiOptions={wagmiOptions}>
      <EarnWidgetWithAdapter />
    </TurtleDefaultProvider>
  );
}

Next.js Integration

For Next.js applications, remember to:
  1. Add the "use client" directive at the top of files using the provider
  2. Import RainbowKit styles in your component or _app.tsx:
import '@rainbow-me/rainbowkit/styles.css';
  1. Use environment variables for sensitive data:
.env.local
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-project-id
NEXT_PUBLIC_DISTRIBUTOR_ID=your-distributor-id

Comparison with Manual Setup

Using @turtleclub/earn-provider vs manual setup:
// ✅ Simple: 3 imports, 10 lines of code
import { EarnWidget } from '@turtleclub/earn-widget';
import { TurtleDefaultProvider, useEarnDefaultAdapter } from '@turtleclub/earn-provider';

function App() {
  return (
    <TurtleDefaultProvider>
      <WidgetContent />
    </TurtleDefaultProvider>
  );
}

Without earn-provider

// ❌ Complex: 15+ imports, 100+ lines of configuration
import { WagmiProvider, createConfig } from 'wagmi';
import { RainbowKitProvider, getDefaultConfig } from '@rainbow-me/rainbowkit';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
// ... many more imports and configuration

Troubleshooting

This error occurs when you try to use the useEarnDefaultAdapter hook outside of the provider. Make sure your component is wrapped:
// ❌ Wrong
function App() {
  const adapter = useEarnDefaultAdapter(); // Error!
  return <EarnWidget adapter={adapter} />;
}

// ✅ Correct
function WidgetContent() {
  const adapter = useEarnDefaultAdapter(); // Works!
  return <EarnWidget adapter={adapter} />;
}

function App() {
  return (
    <TurtleDefaultProvider>
      <WidgetContent />
    </TurtleDefaultProvider>
  );
}
You need to get your own project ID from https://cloud.reown.com:
  1. Create an account or sign in
  2. Create a new project
  3. Copy your project ID
  4. Pass it in the wagmiOptions:
<TurtleDefaultProvider 
  wagmiOptions={{
    appName: "MyApp",
    projectId: "your-actual-project-id-here"
  }}
>

Summary

The @turtleclub/earn-provider package is the recommended way to integrate the Earn Widget. It provides:
  • ✅ Zero-configuration setup
  • ✅ All required providers pre-configured
  • ✅ Simple adapter hook for the widget
  • ✅ TypeScript support out of the box
  • ✅ Optimized for performance
  • ✅ Regular updates and maintenance
For most applications, this package eliminates the complexity of Web3 provider setup and lets you focus on your application logic.