UNPKG

@gemini-wallet/rainbow

Version:

RainbowKit connector for Gemini Wallet integration

494 lines (411 loc) 11.9 kB
# @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.