Complete examples and integration patterns for B3 Global Accounts
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;
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;
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;
// 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;
// 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>
);
}
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>
);
}
/* 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;
}