Basic Authentication Example

A simple authentication flow with error handling and loading states.
import { 
  B3Provider, 
  SignInWithB3, 
  useB3 
} from "@b3dotfun/sdk/global-account/react";

function AuthExample() {
  return (
    <B3Provider environment="production">
      <AuthComponent />
    </B3Provider>
  );
}

function AuthComponent() {
  const { account, isAuthenticated, isLoading, signOut } = useB3();
  const [authError, setAuthError] = useState<string | null>(null);

  if (isLoading) {
    return (
      <div className="loading-container">
        <div className="spinner" />
        <p>Loading your account...</p>
      </div>
    );
  }

  return (
    <div className="auth-container">
      {isAuthenticated ? (
        <div className="user-profile">
          <img 
            src={account?.avatarUrl} 
            alt="Profile" 
            className="avatar"
          />
          <h2>Welcome, {account?.displayName}!</h2>
          <p>Email: {account?.email}</p>
          <button onClick={signOut} className="sign-out-btn">
            Sign Out
          </button>
        </div>
      ) : (
        <div className="sign-in-container">
          <h2>Sign in to B3</h2>
          
          <SignInWithB3
            provider={{ strategy: "google" }}
            partnerId="your-partner-id"
            onLoginSuccess={(globalAccount) => {
              setAuthError(null);
              console.log("Authentication successful:", globalAccount);
            }}
            onLoginError={(error) => {
              setAuthError(error.message);
              console.error("Authentication failed:", error);
            }}
          />

          <SignInWithB3
            provider={{ strategy: "discord" }}
            partnerId="your-partner-id"
            onLoginSuccess={(globalAccount) => {
              setAuthError(null);
              console.log("Discord auth successful:", globalAccount);
            }}
            onLoginError={(error) => {
              setAuthError(error.message);
            }}
          />

          {authError && (
            <div className="error-message">
              <p>Authentication failed: {authError}</p>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export default AuthExample;

Gaming Application Example

Complete example for a gaming application with session keys and permissions.
import {
  B3Provider,
  SignInWithB3,
  RequestPermissionsButton,
  useB3,
  usePermissions,
  useAccountWallet
} from "@b3dotfun/sdk/global-account/react";

const b3Chain = {
  id: 8333,
  name: "B3",
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
  rpc: "https://mainnet-rpc.b3.fun",
};

const gameContracts = [
  "0x9c275ff1634519E9B5449ec79cd939B5F900564d", // Game contract
  "0x...", // NFT marketplace
  "0x...", // Token contract
];

function GameApp() {
  return (
    <B3Provider environment="production">
      <GameContainer />
    </B3Provider>
  );
}

function GameContainer() {
  const { account, isAuthenticated } = useB3();
  const { hasPermissions, isExpired } = usePermissions();
  const { wallet, isConnected } = useAccountWallet();

  const isGameReady = isAuthenticated && hasPermissions && !isExpired && isConnected;

  return (
    <div className="game-container">
      <header className="game-header">
        <h1>🎮 Epic B3 Game</h1>
        {isAuthenticated && (
          <div className="user-info">
            <img src={account?.avatarUrl} alt="Avatar" className="small-avatar" />
            <span>{account?.displayName}</span>
          </div>
        )}
      </header>

      <main className="game-content">
        {!isAuthenticated ? (
          <AuthenticationStep />
        ) : !isConnected ? (
          <WalletConnectionStep />
        ) : !hasPermissions || isExpired ? (
          <PermissionStep />
        ) : (
          <GameReadyState />
        )}
      </main>
    </div>
  );
}

function AuthenticationStep() {
  return (
    <div className="setup-step">
      <h2>🔐 Sign In</h2>
      <p>Connect your B3 Global Account to start playing</p>
      
      <div className="auth-options">
        <SignInWithB3
          provider={{ strategy: "google" }}
          partnerId="epic-game-studio"
          onLoginSuccess={(account) => {
            console.log("Welcome to the game:", account.displayName);
          }}
        />
        
        <SignInWithB3
          provider={{ strategy: "discord" }}
          partnerId="epic-game-studio"
          onLoginSuccess={(account) => {
            console.log("Discord player joined:", account.displayName);
          }}
        />
      </div>
    </div>
  );
}

function WalletConnectionStep() {
  const { connect } = useAccountWallet();

  return (
    <div className="setup-step">
      <h2>👛 Connect Wallet</h2>
      <p>Connect your wallet to interact with the game</p>
      <button onClick={connect} className="connect-wallet-btn">
        Connect Wallet
      </button>
    </div>
  );
}

function PermissionStep() {
  const gamePermissions = {
    approvedTargets: gameContracts,
    startDate: new Date(),
    endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
    nativeTokenLimitPerTransaction: 0.001, // Small ETH limit for gas
  };

  return (
    <div className="setup-step">
      <h2>🛡️ Grant Game Permissions</h2>
      <p>Allow the game to perform actions on your behalf</p>
      
      <div className="permission-details">
        <h3>This will allow the game to:</h3>
        <ul>
          <li>✅ Interact with game contracts</li>
          <li>✅ Trade NFTs on your behalf</li>
          <li>✅ Spend up to 0.001 ETH per transaction</li>
          <li>✅ Valid for 7 days</li>
        </ul>
      </div>

      <RequestPermissionsButton
        chain={b3Chain}
        sessionKeyAddress="0x..." // Your session key address
        permissions={gamePermissions}
        onSuccess={() => {
          console.log("Game permissions granted! Starting game...");
        }}
        onError={(error) => {
          console.error("Permission grant failed:", error);
        }}
      />
    </div>
  );
}

function GameReadyState() {
  const { account } = useB3();
  const { wallet } = useAccountWallet();
  
  return (
    <div className="game-ready">
      <h2>🎯 Game Ready!</h2>
      <div className="player-stats">
        <div className="stat">
          <label>Player:</label>
          <span>{account?.displayName}</span>
        </div>
        <div className="stat">
          <label>Wallet:</label>
          <span>{wallet?.address?.substring(0, 6)}...{wallet?.address?.substring(-4)}</span>
        </div>
        <div className="stat">
          <label>Balance:</label>
          <span>{wallet?.balance} ETH</span>
        </div>
      </div>
      
      <div className="game-actions">
        <button className="play-btn">Start Playing</button>
        <button className="inventory-btn">View Inventory</button>
        <button className="marketplace-btn">Marketplace</button>
      </div>
    </div>
  );
}

export default GameApp;

E-commerce Application Example

Example showing B3 Global Accounts integration in an e-commerce context.
import {
  B3Provider,
  SignInWithB3,
  useB3,
  useAccountAssets
} from "@b3dotfun/sdk/global-account/react";

function EcommerceApp() {
  return (
    <B3Provider environment="production">
      <ShopContainer />
    </B3Provider>
  );
}

function ShopContainer() {
  const { isAuthenticated } = useB3();

  return (
    <div className="shop-container">
      <header className="shop-header">
        <h1>🛍️ B3 NFT Marketplace</h1>
        <UserSection />
      </header>

      <main>
        {isAuthenticated ? (
          <AuthenticatedShop />
        ) : (
          <GuestShop />
        )}
      </main>
    </div>
  );
}

function UserSection() {
  const { account, isAuthenticated, signOut } = useB3();

  return (
    <div className="user-section">
      {isAuthenticated ? (
        <div className="user-menu">
          <img src={account?.avatarUrl} alt="Profile" className="avatar" />
          <div className="dropdown">
            <span>{account?.displayName}</span>
            <div className="dropdown-content">
              <button>My Collection</button>
              <button>Purchase History</button>
              <button onClick={signOut}>Sign Out</button>
            </div>
          </div>
        </div>
      ) : (
        <div className="auth-buttons">
          <SignInWithB3
            provider={{ strategy: "google" }}
            partnerId="nft-marketplace"
            onLoginSuccess={(account) => {
              console.log("Welcome to the marketplace:", account.displayName);
            }}
          />
        </div>
      )}
    </div>
  );
}

function AuthenticatedShop() {
  const { assets } = useAccountAssets();

  return (
    <div className="authenticated-shop">
      <section className="user-collection">
        <h2>Your Collection</h2>
        <div className="asset-grid">
          {assets?.map((asset) => (
            <div key={asset.id} className="asset-card">
              <img src={asset.imageUrl} alt={asset.name} />
              <h3>{asset.name}</h3>
              <p className="price">{asset.value} {asset.currency}</p>
            </div>
          ))}
        </div>
      </section>

      <section className="marketplace">
        <h2>Marketplace</h2>
        <MarketplaceGrid />
      </section>
    </div>
  );
}

function GuestShop() {
  return (
    <div className="guest-shop">
      <section className="hero">
        <h2>Discover Amazing NFTs</h2>
        <p>Sign in to start collecting and trading</p>
        
        <SignInWithB3
          provider={{ strategy: "google" }}
          partnerId="nft-marketplace"
          onLoginSuccess={() => {
            console.log("User joined the marketplace!");
          }}
        />
      </section>

      <section className="featured">
        <h2>Featured Collections</h2>
        <MarketplaceGrid />
      </section>
    </div>
  );
}

function MarketplaceGrid() {
  // Mock marketplace items
  const items = [
    { id: 1, name: "Cool NFT #1", price: "0.1 ETH", image: "/nft1.jpg" },
    { id: 2, name: "Rare Item #42", price: "0.5 ETH", image: "/nft2.jpg" },
    // ... more items
  ];

  return (
    <div className="marketplace-grid">
      {items.map((item) => (
        <div key={item.id} className="marketplace-item">
          <img src={item.image} alt={item.name} />
          <h3>{item.name}</h3>
          <p className="price">{item.price}</p>
          <button className="buy-btn">Buy Now</button>
        </div>
      ))}
    </div>
  );
}

export default EcommerceApp;

React Native Example

Example for React Native applications.
// App.tsx (React Native)
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { B3Provider, useB3 } from '@b3dotfun/sdk/global-account/react';

function App() {
  return (
    <B3Provider environment="production">
      <MainScreen />
    </B3Provider>
  );
}

function MainScreen() {
  const { account, isAuthenticated, isLoading } = useB3();

  if (isLoading) {
    return (
      <View style={styles.container}>
        <Text>Loading...</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      {isAuthenticated ? (
        <AuthenticatedView account={account} />
      ) : (
        <SignInView />
      )}
    </View>
  );
}

function SignInView() {
  return (
    <View style={styles.signInContainer}>
      <Text style={styles.title}>Welcome to B3 Mobile</Text>
      
      {/* React Native implementation would use native auth flows */}
      <TouchableOpacity style={styles.signInButton}>
        <Text style={styles.buttonText}>Sign In with Google</Text>
      </TouchableOpacity>
      
      <TouchableOpacity style={styles.signInButton}>
        <Text style={styles.buttonText}>Sign In with Discord</Text>
      </TouchableOpacity>
    </View>
  );
}

function AuthenticatedView({ account }) {
  const { signOut } = useB3();

  return (
    <View style={styles.authenticatedContainer}>
      <Text style={styles.welcomeText}>
        Welcome, {account?.displayName}!
      </Text>
      
      <TouchableOpacity 
        style={styles.signOutButton}
        onPress={signOut}
      >
        <Text style={styles.buttonText}>Sign Out</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f5f5f5',
  },
  signInContainer: {
    padding: 20,
    alignItems: 'center',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 30,
  },
  signInButton: {
    backgroundColor: '#007AFF',
    padding: 15,
    borderRadius: 10,
    marginVertical: 10,
    minWidth: 200,
  },
  signOutButton: {
    backgroundColor: '#FF3B30',
    padding: 15,
    borderRadius: 10,
    marginTop: 20,
  },
  buttonText: {
    color: 'white',
    textAlign: 'center',
    fontSize: 16,
    fontWeight: '600',
  },
  authenticatedContainer: {
    alignItems: 'center',
  },
  welcomeText: {
    fontSize: 20,
    marginBottom: 20,
  },
});

export default App;

Next.js App Router Example

Example for Next.js 13+ App Router.
// app/layout.tsx
import { B3Provider } from '@b3dotfun/sdk/global-account/react';
import '@b3dotfun/sdk/index.css';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <B3Provider environment="production">
          {children}
        </B3Provider>
      </body>
    </html>
  );
}

// app/page.tsx
'use client';

import { useB3 } from '@b3dotfun/sdk/global-account/react';
import AuthComponent from './components/AuthComponent';
import Dashboard from './components/Dashboard';

export default function HomePage() {
  const { isAuthenticated, isLoading } = useB3();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  return (
    <main>
      {isAuthenticated ? <Dashboard /> : <AuthComponent />}
    </main>
  );
}

// app/components/AuthComponent.tsx
'use client';

import { SignInWithB3 } from '@b3dotfun/sdk/global-account/react';

export default function AuthComponent() {
  return (
    <div className="auth-container">
      <h1>Welcome to B3 App</h1>
      
      <SignInWithB3
        provider={{ strategy: "google" }}
        partnerId="nextjs-app"
        onLoginSuccess={(account) => {
          console.log("Next.js auth success:", account);
        }}
      />
    </div>
  );
}

Advanced Custom Hook Example

Custom hook that combines multiple B3 features:
import { 
  useB3, 
  usePermissions, 
  useAccountWallet,
  useAccountAssets 
} from "@b3dotfun/sdk/global-account/react";

function useB3GameState() {
  const { account, isAuthenticated } = useB3();
  const { hasPermissions, isExpired, permissions } = usePermissions();
  const { wallet, isConnected } = useAccountWallet();
  const { assets } = useAccountAssets();

  // Calculate game readiness
  const isGameReady = isAuthenticated && hasPermissions && !isExpired && isConnected;
  
  // Get game-specific assets (NFTs, tokens)
  const gameAssets = assets?.filter(asset => 
    asset.contractAddress && 
    permissions?.approvedTargets.includes(asset.contractAddress)
  ) || [];

  // Calculate total game value
  const totalGameValue = gameAssets.reduce((sum, asset) => sum + asset.value, 0);

  // Game state object
  const gameState = {
    player: {
      id: account?.id,
      name: account?.displayName,
      avatar: account?.avatarUrl,
      email: account?.email,
    },
    wallet: {
      address: wallet?.address,
      balance: wallet?.balance,
      chainId: wallet?.chainId,
    },
    permissions: {
      active: hasPermissions && !isExpired,
      expires: permissions?.endDate,
      contracts: permissions?.approvedTargets || [],
    },
    assets: {
      items: gameAssets,
      count: gameAssets.length,
      totalValue: totalGameValue,
    },
    status: {
      authenticated: isAuthenticated,
      connected: isConnected,
      authorized: hasPermissions && !isExpired,
      ready: isGameReady,
    }
  };

  return {
    gameState,
    isGameReady,
    gameAssets,
    totalGameValue,
  };
}

// Usage in a game component
function GameDashboard() {
  const { gameState, isGameReady } = useB3GameState();

  if (!isGameReady) {
    return <GameSetup gameState={gameState} />;
  }

  return (
    <div className="game-dashboard">
      <PlayerInfo player={gameState.player} />
      <WalletInfo wallet={gameState.wallet} />
      <AssetInventory assets={gameState.assets} />
      <GameActions />
    </div>
  );
}

CSS Styling Examples

Example CSS for styling B3 components:
/* Custom B3 component styles */
.b3-auth-container {
  max-width: 400px;
  margin: 0 auto;
  padding: 2rem;
  border-radius: 12px;
  background: linear-gradient(135deg, #007AFF 0%, #4DA6FF 100%);
  color: white;
}

.b3-sign-in-button {
  width: 100%;
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.2);
  color: white;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.b3-sign-in-button:hover {
  background: rgba(255, 255, 255, 0.3);
  transform: translateY(-2px);
}

.b3-user-profile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 1rem;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.b3-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
}

.b3-permission-card {
  padding: 1.5rem;
  border: 2px solid #007AFF;
  border-radius: 12px;
  background: #f8f9ff;
}

.b3-game-ready {
  text-align: center;
  padding: 2rem;
  background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
  color: white;
  border-radius: 12px;
}
These examples provide comprehensive patterns for integrating B3 Global Accounts into various types of applications. Each example includes proper error handling, loading states, and follows React best practices.

Next Steps