npm package: @gemini-wallet/rainbow
Description: RainbowKit connector for Gemini Wallet integration
Author: Gemini
Latest version: 0.2.0

# @gemini-wallet/rainbow

RainbowKit connector for seamless Gemini Wallet integration with beautiful UI components.

## Overview

`@gemini-wallet/rainbow` provides a RainbowKit wallet adapter that enables easy integration of Gemini Wallet into applications using RainbowKit. It offers a polished, customizable wallet connection experience with minimal setup.

## Features

- 🎨 **Beautiful UI**: Leverages RainbowKit's polished interface
- 🔌 **Simple Integration**: Drop-in replacement for wallet connectors
- 🎯 **Type Safe**: Full TypeScript support
- 📱 **Responsive**: Works seamlessly on desktop and mobile
- 🔐 **Secure**: Built on @gemini-wallet/wagmi and @gemini-wallet/core

## Installation

```bash
npm install @gemini-wallet/rainbow
# or
yarn add @gemini-wallet/rainbow
# or
pnpm add @gemini-wallet/rainbow
# or
bun add @gemini-wallet/rainbow
```

## 🚀 Try the Example App

We've included a complete working example that you can run immediately:

```bash
cd example
bun install
bun run dev
# Open http://localhost:3000
```

The example demonstrates:
- ✅ Proper connector setup (wrapped in a function)
- ✅ Multi-chain configuration
- ✅ Beautiful RainbowKit UI
- ✅ Zero configuration - works out of the box!

## Quick Start

### ⚠️ Important: Correct Usage

The Gemini wallet connector **MUST** be wrapped in a function when used with `connectorsForWallets`:

```typescript
// ✅ CORRECT - Wrapped in a function
wallets: [
  () => geminiRainbowKitConnector({ ... }),
]

// ❌ WRONG - Will cause "createWallet is not a function" error
wallets: [
  geminiRainbowKitConnector({ ... }),
]
```

### Basic Setup

```typescript
import '@rainbow-me/rainbowkit/styles.css';

import { connectorsForWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { WagmiProvider, createConfig, http } from 'wagmi';
import { mainnet, polygon, optimism, arbitrum } from 'wagmi/chains';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { geminiRainbowKitConnector } from '@gemini-wallet/rainbow';
import {
  rainbowWallet,
  metaMaskWallet,
  coinbaseWallet,
  walletConnectWallet,
} from '@rainbow-me/rainbowkit/wallets';

const projectId = 'YOUR_PROJECT_ID'; // Get from https://cloud.walletconnect.com/

const connectors = connectorsForWallets(
  [
    {
      groupName: 'Recommended',
      wallets: [
        // 🌟 Gemini Wallet - No API key needed!
        // IMPORTANT: Must wrap in a function () => ...
        () => geminiRainbowKitConnector({
          appName: 'My DApp', // Required
          appLogoUrl: 'https://mydapp.com/logo.png', // Optional
        }),
        // Other wallets
        rainbowWallet,
        metaMaskWallet,
        coinbaseWallet,
        walletConnectWallet,
      ],
    },
  ],
  {
    appName: 'My DApp',
    projectId,
  }
);

const config = createConfig({
  connectors,
  chains: [mainnet, polygon, optimism, arbitrum],
  transports: {
    [mainnet.id]: http(),
    [polygon.id]: http(),
    [optimism.id]: http(),
    [arbitrum.id]: http(),
  },
  ssr: true,
});

const queryClient = new QueryClient();

function App() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider>
          <YourApp />
        </RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
}
```

### With ConnectButton

```tsx
import { ConnectButton } from '@rainbow-me/rainbowkit';

function YourApp() {
  return (
    <div>
      <ConnectButton />
      {/* Your app content */}
    </div>
  );
}
```

## Advanced Usage

### Custom Wallet Groups

```typescript
import { connectorsForWallets } from '@rainbow-me/rainbowkit';
import { geminiRainbowKitConnector } from '@gemini-wallet/rainbow';
import { 
  metaMaskWallet, 
  walletConnectWallet,
  coinbaseWallet 
} from '@rainbow-me/rainbowkit/wallets';

const connectors = connectorsForWallets(
  [
    {
      groupName: 'Recommended',
      wallets: [
        // Remember: Gemini must be wrapped in a function!
        () => geminiRainbowKitConnector({
          appName: 'My DApp',
          appLogoUrl: 'https://mydapp.com/logo.png',
        }),
        metaMaskWallet,
      ],
    },
    {
      groupName: 'Other',
      wallets: [
        walletConnectWallet,
        coinbaseWallet,
      ],
    },
  ],
  {
    appName: 'My DApp',
    projectId: 'YOUR_PROJECT_ID',
  }
);
```

### Custom Theme

```typescript
import { RainbowKitProvider, darkTheme } from '@rainbow-me/rainbowkit';

function App() {
  return (
    <RainbowKitProvider 
      theme={darkTheme({
        accentColor: '#7b3ff2',
        accentColorForeground: 'white',
        borderRadius: 'large',
        fontStack: 'system',
      })}
    >
      <YourApp />
    </RainbowKitProvider>
  );
}
```

### Custom Connect Button

```tsx
import { ConnectButton } from '@rainbow-me/rainbowkit';

export const CustomConnectButton = () => {
  return (
    <ConnectButton.Custom>
      {({
        account,
        chain,
        openAccountModal,
        openChainModal,
        openConnectModal,
        authenticationStatus,
        mounted,
      }) => {
        const ready = mounted && authenticationStatus !== 'loading';
        const connected =
          ready &&
          account &&
          chain &&
          (!authenticationStatus ||
            authenticationStatus === 'authenticated');

        return (
          <div
            {...(!ready && {
              'aria-hidden': true,
              'style': {
                opacity: 0,
                pointerEvents: 'none',
                userSelect: 'none',
              },
            })}
          >
            {(() => {
              if (!connected) {
                return (
                  <button onClick={openConnectModal} type="button">
                    Connect Wallet
                  </button>
                );
              }

              if (chain.unsupported) {
                return (
                  <button onClick={openChainModal} type="button">
                    Wrong network
                  </button>
                );
              }

              return (
                <div style={{ display: 'flex', gap: 12 }}>
                  <button
                    onClick={openChainModal}
                    style={{ display: 'flex', alignItems: 'center' }}
                    type="button"
                  >
                    {chain.hasIcon && (
                      <div
                        style={{
                          background: chain.iconBackground,
                          width: 12,
                          height: 12,
                          borderRadius: 999,
                          overflow: 'hidden',
                          marginRight: 4,
                        }}
                      >
                        {chain.iconUrl && (
                          <img
                            alt={chain.name ?? 'Chain icon'}
                            src={chain.iconUrl}
                            style={{ width: 12, height: 12 }}
                          />
                        )}
                      </div>
                    )}
                    {chain.name}
                  </button>

                  <button onClick={openAccountModal} type="button">
                    {account.displayName}
                    {account.displayBalance
                      ? ` (${account.displayBalance})`
                      : ''}
                  </button>
                </div>
              );
            })()}
          </div>
        );
      }}
    </ConnectButton.Custom>
  );
};
```

## API Reference

### `geminiRainbowKitConnector(appMetadata?)`

Creates a RainbowKit wallet configuration for Gemini Wallet.

#### Parameters

- `appMetadata` (optional): Application metadata
  - `appName`: Your application name (required)
  - `appLogo`: Your application logo URL (optional)

#### Returns

A RainbowKit `Wallet` object with:
- `id`: `"gemini"`
- `name`: `"Gemini"`
- `iconUrl`: Gemini logo URL
- `iconAccent`: `"#000"`
- `iconBackground`: `"#000"`

### Configuration Object

The default configuration can be accessed via `geminiRainbowKitConfig`:

```typescript
import { geminiRainbowKitConfig } from '@gemini-wallet/rainbow';

console.log(geminiRainbowKitConfig);
// {
//   desktop: {},
//   downloadUrls: {},
//   iconAccent: "#000",
//   iconBackground: "#000",
//   iconUrl: "https://cdn.worldvectorlogo.com/logos/gemini-4.svg",
//   id: "gemini",
//   mobile: {},
//   name: "Gemini",
// }
```

## Styling

### Using RainbowKit Themes

```typescript
import { 
  RainbowKitProvider, 
  lightTheme,
  darkTheme,
  midnightTheme
} from '@rainbow-me/rainbowkit';

// Light theme
<RainbowKitProvider theme={lightTheme()}>

// Dark theme
<RainbowKitProvider theme={darkTheme()}>

// Custom theme
<RainbowKitProvider 
  theme={lightTheme({
    accentColor: '#00D4AA',
    accentColorForeground: 'white',
    borderRadius: 'medium',
  })}
>
```

### CSS Variables

RainbowKit provides CSS variables that can be customized:

```css
:root {
  --rk-blurs-modalOverlay: blur(0px);
  --rk-fonts-body: -apple-system, BlinkMacSystemFont, 'Segoe UI';
  --rk-radii-connectButton: 12px;
}
```

## Best Practices

1. **Always include styles**: Import RainbowKit styles at the app's root
2. **Provide app metadata**: Helps users identify your application
3. **Use project ID**: Required for WalletConnect functionality
4. **Handle chain switching**: Implement proper UX for unsupported chains
5. **Mobile optimization**: Test thoroughly on mobile devices

## Examples

### Multi-Chain Configuration

```typescript
import { createConfig, http } from 'wagmi';
import { connectorsForWallets } from '@rainbow-me/rainbowkit';
import { geminiRainbowKitConnector } from '@gemini-wallet/rainbow';
import { 
  mainnet, 
  polygon, 
  optimism, 
  arbitrum,
  base,
  zora 
} from 'wagmi/chains';

const connectors = connectorsForWallets(
  [
    {
      groupName: 'Recommended',
      wallets: [
        () => geminiRainbowKitConnector({
          appName: 'Multi-Chain App',
        }),
        // Add other wallets as needed
      ],
    },
  ],
  {
    appName: 'Multi-Chain App',
    projectId: 'YOUR_PROJECT_ID',
  }
);

const config = createConfig({
  connectors,
  chains: [mainnet, polygon, optimism, arbitrum, base, zora],
  transports: {
    [mainnet.id]: http(),
    [polygon.id]: http(),
    [optimism.id]: http(),
    [arbitrum.id]: http(),
    [base.id]: http(),
    [zora.id]: http(),
  },
});
```

### With Authentication

```typescript
import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { RainbowKitAuthenticationProvider } from '@rainbow-me/rainbowkit';

function App() {
  const [authStatus, setAuthStatus] = useState('unauthenticated');

  return (
    <RainbowKitAuthenticationProvider
      adapter={authenticationAdapter}
      status={authStatus}
    >
      <RainbowKitProvider>
        <YourApp />
      </RainbowKitProvider>
    </RainbowKitAuthenticationProvider>
  );
}
```

## Troubleshooting

### Common Issues

1. **"createWallet is not a function" Error**
   - **Cause**: Not wrapping the Gemini connector in a function
   - **Solution**: Always use `() => geminiRainbowKitConnector({ ... })` not just `geminiRainbowKitConnector({ ... })`

2. **Styles not loading**: Ensure `@rainbow-me/rainbowkit/styles.css` is imported at the top of your app

3. **Wallet not appearing**: Check that you're using `connectorsForWallets` and not the deprecated `getDefaultWallets`

4. **Chain not supported**: Add required chains to the configuration and their corresponding transports

5. **Popup blocked**: Ensure browser allows popups for wallet connection

## Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## License

MIT License - see [LICENSE](LICENSE) for details.