Exemplo de Autenticação Básica

Um fluxo de autenticação simples com tratamento de erro e estados de carregamento.
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>Carregando sua conta...</p>
      </div>
    );
  }

  return (
    <div className="auth-container">
      {isAuthenticated ? (
        <div className="user-profile">
          <img 
            src={account?.avatarUrl} 
            alt="Perfil" 
            className="avatar"
          />
          <h2>Bem-vindo(a), {account?.displayName}!</h2>
          <p>Email: {account?.email}</p>
          <button onClick={signOut} className="sign-out-btn">
            Sair
          </button>
        </div>
      ) : (
        <div className="sign-in-container">
          <h2>Entrar no B3</h2>
          
          <SignInWithB3
            provider={{ strategy: "google" }}
            partnerId="your-partner-id"
            onLoginSuccess={(globalAccount) => {
              setAuthError(null);
              console.log("Autenticação bem-sucedida:", globalAccount);
            }}
            onLoginError={(error) => {
              setAuthError(error.message);
              console.error("Falha na autenticação:", error);
            }}
          />

          <SignInWithB3
            provider={{ strategy: "discord" }}
            partnerId="your-partner-id"
            onLoginSuccess={(globalAccount) => {
              setAuthError(null);
              console.log("Autenticação pelo Discord bem-sucedida:", globalAccount);
            }}
            onLoginError={(error) => {
              setAuthError(error.message);
            }}
          />

          {authError && (
            <div className="error-message">
              <p>Falha na autenticação: {authError}</p>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export default AuthExample;

Exemplo de Aplicação de Jogos

Exemplo completo para uma aplicação de jogos com chaves de sessão e permissões.
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", // Contrato do jogo
  "0x...", // Mercado de NFT
  "0x...", // Contrato de token
];

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>🎮 Jogo Épico B3</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>🔐 Entrar</h2>
      <p>Conecte sua Conta Global B3 para começar a jogar</p>
      
      <div className="auth-options">
        <SignInWithB3
          provider={{ strategy: "google" }}
          partnerId="epic-game-studio"
          onLoginSuccess={(account) => {
            console.log("Bem-vindo ao jogo:", account.displayName);
          }}
        />
        
        <SignInWithB3
          provider={{ strategy: "discord" }}
          partnerId="epic-game-studio"
          onLoginSuccess={(account) => {
            console.log("Jogador do Discord entrou:", account.displayName);
          }}
        />
      </div>
    </div>
  );
}

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

  return (
    <div className="setup-step">
      <h2>👛 Conectar Carteira</h2>
      <p>Conecte sua carteira para interagir com o jogo</p>
      <button onClick={connect} className="connect-wallet-btn">
        Conectar Carteira
      </button>
    </div>
  );
}

function PermissionStep() {
  const gamePermissions = {
    approvedTargets: gameContracts,
    startDate: new Date(),
    endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 dias
    nativeTokenLimitPerTransaction: 0.001, // Limite pequeno de ETH para gás
  };

  return (
    <div className="setup-step">
      <h2>🛡️ Conceder Permissões ao Jogo</h2>
      <p>Permita que o jogo realize ações em seu nome</p>
      
      <div className="permission-details">
        <h3>Isso permitirá ao jogo:</h3>
        <ul>
          <li>✅ Interagir com contratos do jogo</li>
          <li>✅ Negociar NFTs em seu nome</li>
          <li>✅ Gastar até 0.001 ETH por transação</li>
          <li>✅ Válido por 7 dias</li>
        </ul>
      </div>

      <RequestPermissionsButton
        chain={b3Chain}
        sessionKeyAddress="0x..." // Seu endereço de chave de sessão
        permissions={gamePermissions}
        onSuccess={() => {
          console.log("Permissões do jogo concedidas! Iniciando jogo...");
        }}
        onError={(error) => {
          console.error("Falha ao conceder permissões:", error);
        }}
      />
    </div>
  );
}

function GameReadyState() {
  const { account } = useB3();
  const { wallet } = useAccountWallet();
  
  return (
    <div className="game-ready">
      <h2>🎯 Jogo Pronto!</h2>
      <div className="player-stats">
        <div className="stat">
          <label>Jogador:</label>
          <span>{account?.displayName}</span>
        </div>
        <div className="stat">
          <label>Carteira:</label>
          <span>{wallet?.address?.substring(0, 6)}...{wallet?.address?.substring(-4)}</span>
        </div>
        <div className="stat">
          <label>Saldo:</label>
          <span>{wallet?.balance} ETH</span>
        </div>
      </div>
      
      <div className="game-actions">
        <button className="play-btn">Começar a Jogar</button>
        <button className="inventory-btn">Ver Inventário</button>
        <button className="marketplace-btn">Mercado</button>
      </div>
    </div>
  );
}

export default GameApp;

Exemplo de Aplicação de E-commerce

Exemplo mostrando a integração de Contas Globais B3 em um contexto de e-commerce.
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>🛍️ Mercado de NFT B3</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="Perfil" className="avatar" />
          <div className="dropdown">
            <span>{account?.displayName}</span>
            <div className="dropdown-content">
              <button>Minha Coleção</button>
              <button>Histórico de Compra</button>
              <button onClick={signOut}>Sair</button>
            </div>
          </div>
        </div>
      ) : (
        <div className="auth-buttons">
          <SignInWithB3
            provider={{ strategy: "google" }}
            partnerId="nft-marketplace"
            onLoginSuccess={(account) => {
              console.log("Bem-vindo ao marketplace:", account.displayName);
            }}
          />
        </div>
      )}
    </div>
  );
}

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

  return (
    <div className="authenticated-shop">
      <section className="user-collection">
        <h2>Sua Coleção</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>Mercado</h2>
        <MarketplaceGrid />
      </section>
    </div>
  );
}

function GuestShop() {
  return (
    <div className="guest-shop">
      <section className="hero">
        <h2>Descubra NFTs Incríveis</h2>
        <p>Entre para começar a coletar e negociar</p>
        
        <SignInWithB3
          provider={{ strategy: "google" }}
          partnerId="nft-marketplace"
          onLoginSuccess={() => {
            console.log("Usuário entrou no marketplace!");
          }}
        />
      </section>

      <section className="featured">
        <h2>Coleções em Destaque</h2>
        <MarketplaceGrid />
      </section>
    </div>
  );
}

function MarketplaceGrid() {
  // Itens fictícios do marketplace
  const items = [
    { id: 1, name: "NFT Legal #1", price: "0.1 ETH", image: "/nft1.jpg" },
    { id: 2, name: "Item Raro #42", price: "0.5 ETH", image: "/nft2.jpg" },
    // ... mais itens
  ];

  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">Comprar Agora</button>
        </div>
      ))}
    </div>
  );
}

export default EcommerceApp;

Exemplo para React Native

Exemplo para aplicações React Native.
// 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>Carregando...</Text>
      </View>
    );
  }

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

function SignInView() {
  return (
    <View style={styles.signInContainer}>
      <Text style={styles.title}>Bem-vindo ao B3 Mobile</Text>
      
      {/* A implementação para React Native usaria fluxos de autenticação nativos */}
      <TouchableOpacity style={styles.signInButton}>
        <Text style={styles.buttonText}>Entrar com Google</Text>
      </TouchableOpacity>
      
      <TouchableOpacity style={styles.signInButton}>
        <Text style={styles.buttonText}>Entrar com Discord</Text>
      </TouchableOpacity>
    </View>
  );
}

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

  return (
    <View style={styles.authenticatedContainer}>
      <Text style={styles.welcomeText}>
        Bem-vindo(a), {account?.displayName}!
      </Text>
      
      <TouchableOpacity 
        style={styles.signOutButton}
        onPress={signOut}
      >
        <Text style={styles.buttonText}>Sair</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;

Exemplo de App Router do Next.js

Exemplo para o App Router do Next.js 13+.
// 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>Carregando...</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>Bem-vindo ao App B3</h1>
      
      <SignInWithB3
        provider={{ strategy: "google" }}
        partnerId="nextjs-app"
        onLoginSuccess={(account) => {
          console.log("Sucesso na autenticação Next.js:", account);
        }}
      />
    </div>
  );
}

Exemplo de Hook Personalizado Avançado

Hook personalizado que combina múltiplas funcionalidades do B3:
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();

  // Calcular prontidão do jogo
  const isGameReady = isAuthenticated && hasPermissions && !isExpired && isConnected;
  
  // Obter ativos específicos do jogo (NFTs, tokens)
  const gameAssets = assets?.filter(asset => 
    asset.contractAddress && 
    permissions?.approvedTargets.includes(asset.contractAddress)
  ) || [];

  // Calcular valor total do jogo
  const totalGameValue = gameAssets.reduce((sum, asset) => sum + asset.value, 0);

  // Objeto de estado do jogo
  const gameState = {
    player: {
      id: account?.id,
      name: account?.displayName,
      avatar: account?.avatarUrl,
      email: account?.email,
    },
    wallet: {
      address: wallet?.address,
      balance: wallet?.balance,