@moongate/sdk
v0.2.4
Published
React UI components for Solana wallet adapter with modern shadcn/ui design and MoonGate integration
Readme
MoonGate SDK
A beautiful, customizable Solana wallet adapter built with React and vanilla CSS - zero UI library dependencies.
Features
- 🎨 Fully Customizable - Brand colors, logo, and wallet selection
- 🚀 Easy Integration - Single provider component
- 🔌 Comprehensive Wallet Support - 30+ wallet adapters included
- 💼 TypeScript First - Full type safety
- 🎯 Modern UI - Built from scratch with vanilla React and CSS
- ⚡ Optimized - Tree-shakable and performant
- 🔒 Style Isolation - Complete CSS isolation prevents conflicts with your app
- 🎭 Zero UI Dependencies - No Radix UI, no Tailwind, just pure CSS
Architecture
What We Built From Scratch
The SDK is built with vanilla React and CSS - no external UI libraries:
- UI Components: Dialog, Sheet, DropdownMenu, Button, ScrollArea all built from scratch
- Accessibility: Custom focus trap, keyboard navigation, ARIA attributes
- Interactions: Click outside, escape key, body scroll locking
- Animations: Pure CSS animations for smooth transitions
- Styling: 100% vanilla CSS with scoped Preflight-style reset
What We Don't Use
- ❌ No Radix UI
- ❌ No shadcn/ui
- ❌ No Tailwind CSS
- ❌ No class-variance-authority
- ❌ No tailwind-merge
- ❌ No CSS-in-JS libraries
Dependencies
The SDK only depends on:
- ✅ React (peer dependency)
- ✅ Solana wallet adapter libraries
- ✅ Lucide React (icons)
- ✅ clsx (utility for conditional classes)
Installation
npm install moongate-sdk
# or
yarn add moongate-sdk
# or
pnpm add moongate-sdkCSS Styles
The SDK includes 100% vanilla CSS with zero external dependencies. Import the CSS file in your app:
import 'moongate-sdk/styles.css';Style Isolation: The SDK implements a comprehensive scoped reset (similar to Tailwind's Preflight) that prevents parent application CSS from affecting the SDK's UI. All styles are scoped to .moongate-wallet-sdk containers, ensuring complete isolation from your app's global CSS, including Tailwind CSS if you use it.
Quick Start
1. Wrap your app with MoonGateProvider
import { MoongateConnectButton, MoonGateProvider } from 'moongate-sdk';
const config = {
primaryColor: '#9945FF',
secondaryColor: '#14F195',
logo: '/your-logo.svg',
wallets: {
primary: [
{ name: 'Phantom', order: 1 },
{ name: 'Solflare', order: 2 },
],
secondary: [
{ name: 'WalletConnect', order: 1 },
{ name: 'Coinbase Wallet', order: 2 },
{ name: 'Ledger', order: 3 },
],
},
};
function App() {
return (
<MoonGateProvider config={config}>
<div>
<h1>My Solana App</h1>
<MoongateConnectButton />
</div>
</MoonGateProvider>
);
}2. Use wallet functionality in your components
import { useWallet, useWalletModal } from 'moongate-sdk';
function MyComponent() {
const { connected, publicKey, disconnect } = useWallet();
const { setVisible, config } = useWalletModal();
if (!connected) {
return <button onClick={() => setVisible(true)}>Connect Wallet</button>;
}
return (
<div>
<p>Connected: {publicKey?.toString()}</p>
<button onClick={disconnect}>Disconnect</button>
</div>
);
}Configuration
AdapterConfig
interface AdapterConfig {
primaryColor: string; // Main brand color
secondaryColor: string; // Accent color
logo: string; // Path to your logo
wallets: WalletConfig; // Wallet configuration
}WalletConfig
interface WalletConfig {
primary: WalletItem[]; // Main wallets (always visible)
secondary?: WalletItem[]; // Additional wallets (collapsible)
}
interface WalletItem {
name: string; // Wallet name (must match supported wallets)
order: number; // Display order
}Supported Wallets
- Phantom
- Solflare
- WalletConnect
- Coinbase Wallet
- Ledger
- Burner Wallet
- And 25+ more...
MoonGateProvider Props
interface MoonGateProviderProps {
children: ReactNode;
config: AdapterConfig;
network?: WalletAdapterNetwork; // Default: Devnet
endpoint?: string; // Custom RPC endpoint
autoConnect?: boolean; // Default: true
apiKey?: string; // MoonGate API key
apiUrl?: string; // MoonGate API URL (default: https://wallet.moongate.one)
// MoonGate adapter customization
displayState?: 'fullscreen' | 'minimized' | 'hidden'; // Default: 'minimized'
position?: string; // Wallet modal position (default: 'top-right')
logoDataUri?: string; // Custom logo data URI
buttonLogoUri?: string; // Custom button logo URI
environment?: string; // Environment (e.g., 'production', 'staging')
}MoonGate Adapter Options
The provider accepts additional props to customize the MoonGate wallet adapter:
| Prop | Type | Default | Description |
| --------------- | ----------------------------------------- | -------------- | ------------------------------------------------ |
| displayState | 'fullscreen' \| 'minimized' \| 'hidden' | 'minimized' | Controls how the MoonGate wallet iframe displays |
| position | string | 'top-right' | Position of the wallet modal |
| logoDataUri | string | - | Custom logo as a data URI |
| buttonLogoUri | string | - | Custom button logo URL |
| environment | string | 'production' | Environment setting |
Example Configurations
Minimal Setup
const minimalConfig = {
primaryColor: '#000000',
secondaryColor: '#666666',
logo: '/logo.svg',
wallets: {
primary: [{ name: 'Phantom', order: 1 }],
},
};Custom Branding
const customConfig = {
primaryColor: '#FF6B6B',
secondaryColor: '#4ECDC4',
logo: '/custom-logo.svg',
wallets: {
primary: [
{ name: 'Phantom', order: 1 },
{ name: 'Solflare', order: 2 },
],
secondary: [
{ name: 'WalletConnect', order: 1 },
{ name: 'Ledger', order: 2 },
],
},
};Components
MoongateConnectButton
The main wallet connection button with built-in state management.
import { MoongateConnectButton } from 'moongate-sdk';
<MoongateConnectButton />;Hooks
useWalletModal
Access wallet modal state and configuration.
const { visible, setVisible, config } = useWalletModal();useWallet (re-exported)
Standard Solana wallet adapter hook.
const { connected, publicKey, disconnect, sendTransaction } = useWallet();useConnection (re-exported)
Access the Solana connection.
const { connection } = useConnection();Advanced Usage
Custom Network
import { WalletAdapterNetwork } from 'moongate-sdk';
<MoonGateProvider config={config} network={WalletAdapterNetwork.Mainnet}>
{children}
</MoonGateProvider>;Custom RPC Endpoint
<MoonGateProvider config={config} endpoint="https://your-rpc-endpoint.com">
{children}
</MoonGateProvider>Full MoonGate Configuration
<MoonGateProvider
config={config}
apiKey="your-api-key"
endpoint="https://your-rpc-endpoint.com"
network={WalletAdapterNetwork.Mainnet}
displayState="minimized"
position="top-right"
environment="production">
{children}
</MoonGateProvider>TypeScript Support
The SDK is built with TypeScript and provides full type safety:
import type { AdapterConfig, WalletConfig, WalletName } from 'moongate-sdk';CSS Scoping & Style Isolation
The MoonGate SDK uses vanilla CSS with advanced scoping techniques to ensure complete style isolation from your application. This prevents any conflicts between the SDK's styles and your existing CSS, including Tailwind CSS, Bootstrap, or any other framework.
How It Works
- Scoped Container: All SDK components are automatically wrapped in a
.moongate-wallet-sdkcontainer - Scoped Preflight Reset: A comprehensive CSS reset (similar to Tailwind's Preflight) scoped to
.moongate-wallet-sdkprevents parent app styles from leaking in - Prefixed Class Names: All component classes use the
mg-prefix (e.g.,.mg-button,.mg-dialog-content) - Custom Variables: CSS custom properties are namespaced with
--moongate-prefix - Portal Scoping: Modals, dropdowns, and overlays rendered via portals maintain the scoped container
- Complete Isolation: Your app's global CSS (including Tailwind Preflight) won't affect the SDK
Implementation Details
The SDK uses pure vanilla CSS with no external UI dependencies:
// The SDK automatically wraps your components
<MoonGateProvider config={config}>
<YourApp /> {/* This gets wrapped in .moongate-wallet-sdk */}
</MoonGateProvider>
// Modals and overlays use portals with scoped containers
<Portal>
<div className="moongate-wallet-sdk">
<WalletModal /> {/* Maintains scoped isolation */}
</div>
</Portal>Scoped Preflight Reset
The SDK includes a comprehensive reset scoped to .moongate-wallet-sdk:
/* Resets all elements within the SDK scope */
.moongate-wallet-sdk *,
.moongate-wallet-sdk *::before,
.moongate-wallet-sdk *::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
border-color: currentColor;
}
/* Removes default margins, resets headings, lists, forms, etc. */
.moongate-wallet-sdk h1,
.moongate-wallet-sdk h2,
.moongate-wallet-sdk h3 {
font-size: inherit;
font-weight: inherit;
margin: 0;
}
/* ... and 50+ more reset rules */CSS Variables
The SDK uses scoped CSS variables that won't conflict with your app:
.moongate-wallet-sdk {
--moongate-background: 0 0% 100%;
--moongate-foreground: 240 10% 3.9%;
--moongate-primary: 240 5.9% 10%;
/* ... other scoped variables */
}Component Classes
All CSS classes are prefixed with mg-:
.mg-button {
/* Button component */
}
.mg-dialog-content {
/* Dialog modal */
}
.mg-dropdown-menu-item {
/* Dropdown items */
}
.mg-wallet-list-item {
/* Wallet list items */
}
/* ... all other components */Benefits
- ✅ Zero Style Conflicts: Your app's styles remain untouched, SDK styles are isolated
- ✅ No UI Library Dependencies: No Radix UI, no Tailwind CSS, no external UI libs
- ✅ Works with Tailwind: SDK remains unaffected by parent app's Tailwind Preflight
- ✅ Small Bundle Size: Pure CSS means no extra JavaScript for UI libraries
- ✅ Framework Agnostic: Works with any CSS framework (Tailwind, Bootstrap, etc.)
- ✅ Consistent Theming: SDK maintains its design system regardless of parent app styles
- ✅ Easy Integration: No need to modify your existing CSS or build setup
Built-in Components
All UI components are built from scratch with vanilla React and CSS:
- ✅ Dialog/Modal - Custom dialog with focus trap, escape key, click outside
- ✅ Sheet - Slide-in panels from 4 sides with animations
- ✅ DropdownMenu - Keyboard navigation, nested menus, radio/checkbox items
- ✅ Button - Variants, sizes, all without class-variance-authority
- ✅ ScrollArea - Custom scrollbar styling
- ✅ Portal - React portal wrapper for modals/overlays
Troubleshooting
If you experience style conflicts:
- Ensure you're importing the CSS:
import "moongate-sdk/styles.css" - Check that the
.moongate-wallet-sdkclass is present on SDK components - Verify your bundler is processing the CSS correctly
- If using Tailwind in your app, the SDK should be completely isolated
Custom Styling
While the SDK is fully scoped, you can still customize it by targeting the mg- prefixed classes:
/* Override SDK styles safely */
.moongate-wallet-sdk .mg-button {
/* Customize button styles */
border-radius: 12px;
}
.moongate-wallet-sdk .mg-dialog-content {
/* Customize dialog */
max-width: 500px;
}Tip: All dynamic theme colors are passed via inline styles, so you can fully control the SDK's appearance through the config prop.
Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
MIT License - see LICENSE for details.
