# AI-Optimized Docs Source: https://docs.b3.fun/ai-optimized Learn how B3's documentation is optimized for AI tools and how to leverage these features for better development experience ### Contextual Menu Integration Every page in our documentation includes a contextual menu that provides one-click access to AI tools. Look for the menu icon on any page to access these features: Copies the current page as optimized Markdown that you can paste directly into any AI tool as context. Opens the current page in Markdown format, perfect for understanding the raw structure or copying specific sections. Creates a new ChatGPT conversation with the current page already loaded as context. Starts a Claude conversation with the documentation page pre-loaded for immediate assistance. Opens Perplexity with the current page as context for research and fact-checking. Provides Model Context Protocol (MCP) server URLs for advanced AI tool integrations. Direct integration with Cursor and VSCode through MCP for seamless coding assistance. ### Automatic LLM Indexing Our documentation automatically generates and maintains industry-standard files that help AI tools understand and index our content: #### llms.txt * **Automatic Generation**: Available at [/llms.txt](/llms.txt) * **Structured Content**: Lists all pages with descriptions for efficient AI navigation * **Always Up-to-Date**: Automatically updated when content changes * **Zero Maintenance**: No manual updates required #### llms-full.txt * **Complete Context**: Available at [/llms-full.txt](/llms-full.txt) * **Single File**: Combines entire documentation into one file * **AI-Ready Format**: Optimized for use as context in AI conversations * **Comprehensive**: Includes all content from across the documentation ## How to Use These Features ### For Quick Questions 1. **Navigate** to any relevant documentation page 2. **Click** the contextual menu icon 3. **Select** "Open in ChatGPT" or "Open in Claude" 4. **Ask** your question - the AI already has the page context ### For Code Development 1. **Open** your preferred code editor (Cursor or VSCode) 2. **Use** the MCP integration from our contextual menu 3. **Access** B3 documentation directly within your coding environment 4. **Get** contextual help while writing code ### For Deep Research 1. **Copy** the relevant page using "Copy Page" feature 2. **Paste** into your preferred AI tool 3. **Combine** with additional context or questions 4. **Get** comprehensive answers with full documentation context ## AI-Optimized Content Structure Our documentation is structured to work exceptionally well with AI tools: ### Clear Hierarchies * **Logical organization** that AI tools can easily parse * **Consistent formatting** across all pages * **Descriptive headings** that provide context ### Rich Metadata * **Comprehensive titles** and descriptions * **Structured frontmatter** for better AI understanding * **Semantic markup** that enhances AI comprehension ### Code Examples * **Complete, runnable examples** that AI can explain and modify * **Well-commented code** for better AI interpretation * **Multiple implementation approaches** for different use cases ## Benefits for Developers Get instant access to relevant documentation within your AI conversation, eliminating the need to switch between tools and manually copy content. AI tools receive properly formatted, comprehensive context about B3 features, leading to more accurate and helpful responses. Direct integration with development tools like Cursor and VSCode means you can get help without leaving your coding environment. Our AI-optimized files are automatically updated, ensuring AI tools always have access to the latest information. ## Example Use Cases ### Smart Contract Development ``` 1. Open the AnySpend SDK documentation 2. Use "Open in Cursor" to load context into your editor 3. Ask questions about implementation while coding 4. Get contextual code suggestions and explanations ``` ### Integration Planning ``` 1. Navigate to the relevant protocol documentation 2. Use "Copy Page" to get formatted content 3. Paste into Claude or ChatGPT 4. Ask for integration strategies and best practices ``` ### Debugging and Troubleshooting ``` 1. Find the error handling documentation 2. Use contextual menu to open in your preferred AI tool 3. Describe your specific issue 4. Get targeted solutions with documentation context ``` ## Technical Implementation Our AI optimization is powered by: * **Mintlify's AI features**: Built-in contextual menu and LLM file generation * **Structured content**: Consistent markdown formatting optimized for AI parsing * **Model Context Protocol (MCP)**: Standard for AI tool integration * **Automatic updates**: CI/CD pipeline ensures AI files stay current ## Get Started Ready to leverage these AI features? Here's how: 1. **Browse** to any page in our documentation 2. **Look** for the contextual menu icon (usually in the top-right area) 3. **Try** copying a page or opening it in your favorite AI tool 4. **Experience** the enhanced development workflow The AI optimization features are available on every page of our documentation and require no setup - they're ready to use immediately. *** These AI features are designed to enhance your development experience with B3. They work best when combined with a clear understanding of your specific use case and goals. # Get tokens for a chain Source: https://docs.b3.fun/anyspend/api-reference/chains/get-tokens-for-a-chain https://mainnet.anyspend.com/openapi.json get /chains/{chainId}/tokens Retrieves available tokens for a specific blockchain # Check Stripe support Source: https://docs.b3.fun/anyspend/api-reference/onramp/check-stripe-support https://mainnet.anyspend.com/openapi.json get /onramp/stripe/supported Checks if Stripe onramp and Stripe Web2 are supported based on IP address location and optional transaction amount # Get Coinbase onramp options Source: https://docs.b3.fun/anyspend/api-reference/onramp/get-coinbase-onramp-options https://mainnet.anyspend.com/openapi.json get /onramp/coinbase/options Retrieves available Coinbase onramp configuration options. # Create a new order Source: https://docs.b3.fun/anyspend/api-reference/orders/create-a-new-order https://mainnet.anyspend.com/openapi.json post /orders Creates a new order for token transactions across chains # Get anyspend quote Source: https://docs.b3.fun/anyspend/api-reference/orders/get-anyspend-quote https://mainnet.anyspend.com/openapi.json post /orders/quote Retrieves a quote to swap or execute contract # Get order and transactions Source: https://docs.b3.fun/anyspend/api-reference/orders/get-order-and-transactions https://mainnet.anyspend.com/openapi.json get /orders/{orderId} Retrieves order details along with associated transactions # Get orders by creator Source: https://docs.b3.fun/anyspend/api-reference/orders/get-orders-by-creator https://mainnet.anyspend.com/openapi.json get /orders Retrieves all orders created by a specific address # Get Stripe client secret Source: https://docs.b3.fun/anyspend/api-reference/stripe/get-stripe-client-secret https://mainnet.anyspend.com/openapi.json get /stripe/clientSecret Retrieves a Stripe client secret for payment processing using a payment intent ID # Components Source: https://docs.b3.fun/anyspend/components React components for seamless crypto payments, NFT purchases, and custom smart contract interactions ## Core Components ### `` The primary interface component for token-to-token exchanges and fiat onramps. ```tsx title="Basic Usage" icon="react" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpend.tsx import { AnySpend } from "@b3dotfun/sdk/anyspend/react"; ; ``` #### Props Use mainnet or testnet environment Display as modal overlay or full page Initial payment method tab Target token address for buy mode Chain ID of destination token Recipient wallet address Hide transaction history access Load specific order by ID #### Usage Examples ```tsx ``` ```tsx ``` *** ### `` A streamlined button component for NFT purchases with built-in payment handling. ```tsx title="NFT Purchase Button" icon="shopping-cart" import { AnySpendNFTButton } from "@b3dotfun/sdk/anyspend/react"; ; ``` #### Props NFT contract configuration object Wallet address to receive the NFT #### NFTContract Interface ```typescript title="Type Definition" icon="code" interface NFTContract { chainId: number; // Blockchain network ID contractAddress: string; // NFT contract address price: string; // Price in wei priceFormatted: string; // Human-readable price currency: { chainId: number; address: string; // Token contract (0x0 for native ETH) name: string; symbol: string; decimals: number; metadata: { logoURI: string; }; }; name: string; // NFT collection name description: string; // NFT description imageUrl: string; // Preview image URL tokenId: number | null; // Token ID (null for ERC721, specific ID for ERC1155) type: "erc721" | "erc1155"; // NFT contract type } ``` #### Usage Example ```tsx title="Complete NFT Integration" icon="image" lines const coolNFT = { chainId: 8333, contractAddress: "0x9c275ff1634519E9B5449ec79cd939B5F900564d", price: "500000000000000000", // 0.5 ETH priceFormatted: "0.5", currency: { chainId: 8333, address: "0x0000000000000000000000000000000000000000", name: "Ether", symbol: "ETH", decimals: 18, metadata: { logoURI: "https://assets.coingecko.com/coins/images/279/standard/ethereum.png?1696501628", }, }, name: "Cool Art Collection", description: "Unique digital artwork", imageUrl: "https://example.com/nft-preview.png", tokenId: null, type: "erc721", }; ; ``` *** ### `` The most flexible component for custom smart contract interactions, including gaming, staking, and DeFi operations. ```tsx title="Custom Contract Interaction" icon="code" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpendCustom.tsx import { AnySpendCustom } from "@b3dotfun/sdk/anyspend/react"; console.log("Custom action completed", txHash)} />; ``` #### Props Order type identifier Target blockchain network Token being used for payment Amount in wei/smallest unit Target smart contract address Encoded function call data Optional token spender address Custom metadata for tracking Custom header component Success callback with transaction hash #### Usage Example - Staking ```tsx title="Staking Integration" icon="coins" lines // Encode staking function call const stakeAmount = "1000000000000000000"; // 1 token const stakingCalldata = encodeFunctionData({ abi: stakingABI, functionName: "stake", args: [stakeAmount, 30], // 30 days }); (

Stake Tokens

Duration: 30 days

Expected APY: 5.2%

{!isLoadingAnyspendPrice &&

Total Cost: ${anyspendPrice?.usdPrice}

}
)} />; ``` ## Specialized Components ### `` Enhanced NFT component with additional marketplace features. ```tsx title="Enhanced NFT Component" icon="store" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpendNFT.tsx ``` ### `` Pre-configured component for B3 token staking. ```tsx title="B3 Staking" icon="coins" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpendStakeB3.tsx ``` ### `` Gaming-specific component for purchasing spin wheels or lottery tickets. ```tsx title="Gaming Spin Wheel" icon="gamepad" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpendBuySpin.tsx ``` ### `` Tournament entry payment component. ```tsx title="Tournament Entry" icon="trophy" // https://github.com/b3-fun/b3/blob/main/packages/sdk/src/anyspend/react/components/AnySpendTournament.tsx ``` ## Component Styling All components come with default styling that can be customized using CSS variables: ```css title="Custom Styling" icon="palette" /* Override default styles */ .anyspend-modal { --anyspend-primary: #6366f1; --anyspend-secondary: #f3f4f6; --anyspend-border-radius: 12px; } ``` ## Platform Support
Component React Web React Native
`AnySpend`
`AnySpendNFTButton`
`AnySpendCustom`
`AnySpendNFT`
Fiat onramp features
## Next Steps Discover React hooks for custom payment flows Browse real-world implementation examples Learn how to handle errors gracefully # Error Handling & Troubleshooting Source: https://docs.b3.fun/anyspend/error-handling Comprehensive guide to handling errors gracefully and debugging common issues with AnySpend # Error Handling & Troubleshooting Comprehensive guide to handling errors gracefully and debugging common issues with AnySpend to provide the best user experience. ## 📊 Order Status Lifecycle Understanding order states is crucial for proper error handling and user experience. ### Order Status Types ```typescript title="Order Status Enum" icon="list" enum OrderStatus { // Initial States SCANNING_DEPOSIT_TRANSACTION = "scanning_deposit_transaction", WAITING_STRIPE_PAYMENT = "waiting_stripe_payment", EXPIRED = "expired", // Processing States SENDING_TOKEN_FROM_VAULT = "sending_token_from_vault", RELAY = "relay", // Success States EXECUTED = "executed", // Failure States REFUNDING = "refunding", REFUNDED = "refunded", FAILURE = "failure", } ``` ### Status Descriptions
Status Description User Action Required
`scanning_deposit_transaction` Waiting for payment confirmation None - wait for blockchain confirmation
`waiting_stripe_payment` Processing credit card payment May need to complete 3D Secure
`sending_token_from_vault` Sending tokens for swap None - automatic process
`relay` Cross-chain transaction in progress None - wait for completion
`executed` Transaction completed successfully None - success!
`expired` Order expired before completion Create new order
`refunding` Automatic refund in progress None - wait for refund
`refunded` Refund completed Check wallet for refunded tokens
`failure` Transaction failed Review error details, retry
## ⚠️ Common Error Codes ### Payment Errors **Description**: User doesn't have enough tokens for the transaction **Solution**: Request user to add funds to their wallet or choose a different payment token **Example**: ```typescript if (error.message === "INSUFFICIENT_BALANCE") { toast.error("Insufficient balance. Please add funds to your wallet."); // Optionally redirect to fiat onramp openFiatOnramp(); } ``` **Description**: Token contract not supported on the target chain **Solution**: Verify token is supported and provide alternative options **Example**: ```typescript if (error.message === "INVALID_TOKEN_ADDRESS") { toast.error("This token is not supported. Please choose another."); showSupportedTokens(); } ``` **Description**: Transaction amount is below the minimum threshold **Solution**: Increase transaction amount or inform user of minimum requirements **Example**: ```typescript if (error.message === "MINIMUM_AMOUNT_NOT_MET") { toast.error(`Minimum amount is $${minimumAmount}. Please increase your amount.`); } ``` **Description**: Transaction amount exceeds maximum limit **Solution**: Reduce amount or split into multiple transactions **Example**: ```typescript if (error.message === "MAXIMUM_AMOUNT_EXCEEDED") { toast.error(`Maximum amount is $${maximumAmount}. Please reduce your amount.`); } ``` ### Network Errors **Description**: Price moved beyond acceptable tolerance during execution **Solution**: Retry with higher slippage tolerance or wait for price stability **Example**: ```typescript if (error.message === "SLIPPAGE") { toast.warning("Price moved unfavorably. Retrying with adjusted settings..."); retryWithHigherSlippage(); } ``` **Description**: RPC connection issues or blockchain congestion **Solution**: Retry after delay or switch to alternative RPC **Example**: ```typescript if (error.message === "NETWORK_ERROR") { toast.error("Network issue detected. Please check connection and try again."); scheduleRetry(); } ``` **Description**: Price quote is no longer valid **Solution**: Get fresh quote and retry transaction **Example**: ```typescript if (error.message === "QUOTE_EXPIRED") { toast.info("Price quote expired. Getting fresh quote..."); refreshQuoteAndRetry(); } ``` **Description**: Requested blockchain is not supported **Solution**: Use supported chains or implement fallback **Example**: ```typescript if (error.message === "CHAIN_NOT_SUPPORTED") { toast.error("This blockchain is not supported. Please choose another."); showSupportedChains(); } ``` ### Contract Errors **Description**: Smart contract execution failed **Solution**: Check contract parameters and state **Example**: ```typescript if (error.message === "CONTRACT_CALL_FAILED") { toast.error("Contract interaction failed. Please verify parameters."); logContractError(error); } ``` **Description**: Gas limit set too low for transaction **Solution**: Increase gas limit or suggest gas optimization **Example**: ```typescript if (error.message === "INSUFFICIENT_GAS") { toast.error("Transaction requires more gas. Increasing gas limit..."); retryWithHigherGas(); } ``` **Description**: Transaction nonce conflict **Solution**: Wait for pending transactions to complete **Example**: ```typescript if (error.message === "NONCE_TOO_LOW") { toast.info("Please wait for pending transactions to complete."); waitAndRetry(); } ``` **Description**: Contract reverted the transaction **Solution**: Check contract state and parameters **Example**: ```typescript if (error.message === "TRANSACTION_REVERTED") { toast.error("Transaction was rejected by the contract. Please check requirements."); showTransactionDetails(); } ``` ## 🛠️ Error Handling Patterns ### Component-Level Error Handling ```tsx title="Payment Component with Error Handling" icon="shield-exclamation" lines import { useAnyspendCreateOrder } from "@b3dotfun/sdk/anyspend"; function PaymentComponent() { const [error, setError] = useState(null); const [retryCount, setRetryCount] = useState(0); const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({ onError: error => { console.error("Payment failed:", error); // Handle specific errors switch (error.message) { case "INSUFFICIENT_BALANCE": setError("Insufficient balance. Please add funds to your wallet."); break; case "SLIPPAGE": if (retryCount < 3) { setError("Price moved unfavorably. Retrying..."); setTimeout(() => { setRetryCount(prev => prev + 1); retryPayment(); }, 2000); } else { setError("Price too volatile. Please try again later."); } break; case "NETWORK_ERROR": setError("Network issue. Please check your connection and try again."); break; case "QUOTE_EXPIRED": setError("Price quote expired. Getting fresh quote..."); refreshQuote(); break; default: setError("Payment failed. Please try again or contact support."); } // Track errors for monitoring analytics.track("payment_error", { error: error.message, retryCount, timestamp: new Date().toISOString(), }); }, onSuccess: () => { setError(null); setRetryCount(0); }, }); return (
{error && (
⚠️ {error}
)}
); } ``` ### Order Status Monitoring ```tsx title="Order Status Monitor" icon="eye" lines import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend"; function OrderStatusMonitor({ orderId }: { orderId: string }) { const { orderAndTransactions, getOrderAndTransactionsError } = useAnyspendOrderAndTransactions(true, orderId); if (getOrderAndTransactionsError) { return (

Unable to load order status

Please check your connection and try again.

); } if (!orderAndTransactions) { return
Loading order status...
; } const { order, depositTxs, executeTx, refundTxs } = orderAndTransactions.data; const renderStatusMessage = () => { switch (order.status) { case "scanning_deposit_transaction": return (

⏳ Waiting for payment confirmation

This usually takes 1-2 minutes. Please don't close this window.

{depositTxs.length > 0 && ( View payment transaction )}
); case "relay": return (

🔄 Processing cross-chain transaction

Your payment is being processed. This may take a few minutes.

); case "executed": return (

Transaction completed successfully!

Your order has been processed.

{executeTx && ( View transaction )}
); case "failure": case "obtain_failed": return (

Transaction failed

{order.errorDetails || "An error occurred while processing your order."}

); case "refunded": return (
↩️

Refund processed

Your payment has been refunded automatically.

{refundTxs.length > 0 && ( View refund transaction )}
); case "expired": return (

Order expired

This order expired before payment was received.

); default: return (

Processing...

Order status: {order.status}

); } }; return (

Order #{orderId.slice(0, 8)}

Created: {new Date(order.createdAt).toLocaleString()} Status: {order.status}
{renderStatusMessage()} {/* Debug information in development */} {process.env.NODE_ENV === "development" && (
Debug Information
{JSON.stringify(order, null, 2)}
)}
); } ``` ### Global Error Boundary ```tsx title="Error Boundary Component" icon="shield" lines import React, { Component, ErrorInfo } from "react"; interface Props { children: React.ReactNode; fallback?: React.ComponentType<{ error: Error; resetError: () => void }>; } interface State { hasError: boolean; error?: Error; } class AnySpendErrorBoundary extends Component { constructor(props: Props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error: Error): State { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: ErrorInfo) { console.error("AnySpend Error Boundary caught an error:", error, errorInfo); // Report to error tracking service if (typeof window !== "undefined") { // Example: Sentry.captureException(error, { contexts: { errorInfo } }); } } resetError = () => { this.setState({ hasError: false, error: undefined }); }; render() { if (this.state.hasError) { const FallbackComponent = this.props.fallback || DefaultErrorFallback; return ; } return this.props.children; } } function DefaultErrorFallback({ error, resetError }: { error: Error; resetError: () => void }) { return (

Something went wrong

An unexpected error occurred in the payment component.

Error details
{error.message}
); } // Usage function App() { return ( ); } ``` ## 📊 Error Monitoring & Analytics ### Error Tracking Setup ```tsx title="Error Analytics" icon="chart-bar" lines // Track errors for monitoring and improvement function trackPaymentError(error: Error, context: any) { // Analytics tracking analytics.track("payment_error", { error_message: error.message, error_stack: error.stack, user_agent: navigator.userAgent, timestamp: new Date().toISOString(), context, }); // Error reporting service (e.g., Sentry) if (window.Sentry) { window.Sentry.captureException(error, { tags: { component: "anyspend", error_type: "payment_error", }, extra: context, }); } // Custom error logging console.error("AnySpend Payment Error:", { message: error.message, context, timestamp: new Date().toISOString(), }); } ``` ### User-Friendly Error Messages ```tsx title="Error Message Helper" icon="comment" lines function getErrorMessage(error: Error): { title: string; message: string; action?: string } { switch (error.message) { case "INSUFFICIENT_BALANCE": return { title: "Insufficient Balance", message: "You don't have enough funds for this transaction.", action: "Add funds to your wallet or choose a different payment method.", }; case "SLIPPAGE": return { title: "Price Changed", message: "The price moved while processing your transaction.", action: "We'll retry automatically with updated pricing.", }; case "NETWORK_ERROR": return { title: "Connection Issue", message: "Unable to connect to the blockchain network.", action: "Please check your internet connection and try again.", }; case "QUOTE_EXPIRED": return { title: "Quote Expired", message: "The price quote is no longer valid.", action: "Getting a fresh quote automatically...", }; default: return { title: "Transaction Failed", message: "An unexpected error occurred.", action: "Please try again or contact support if the problem persists.", }; } } // Usage in component function ErrorDisplay({ error }: { error: Error }) { const errorInfo = getErrorMessage(error); return (

{errorInfo.title}

{errorInfo.message}

{errorInfo.action &&

{errorInfo.action}

}
); } ``` ## 🔧 Debugging Tools ### Debug Mode ```tsx title="Debug Helper" icon="bug" lines // Enable debug mode for detailed logging function useAnyspendDebug() { const isDebug = process.env.NODE_ENV === "development" || localStorage.getItem("anyspend_debug") === "true"; const log = (message: string, data?: any) => { if (isDebug) { console.log(`[AnySpend Debug] ${message}`, data); } }; const error = (message: string, error?: Error) => { if (isDebug) { console.error(`[AnySpend Debug] ${message}`, error); } }; return { log, error, isDebug }; } // Usage function PaymentComponent() { const debug = useAnyspendDebug(); const { createOrder } = useAnyspendCreateOrder({ onSuccess: data => { debug.log("Order created successfully", data); }, onError: error => { debug.error("Order creation failed", error); }, }); // ... rest of component } ``` ### Network Status Checker ```tsx title="Network Status" icon="wifi" lines function useNetworkStatus() { const [isOnline, setIsOnline] = useState(navigator.onLine); const [networkSpeed, setNetworkSpeed] = useState<"slow" | "fast" | "unknown">("unknown"); useEffect(() => { const handleOnline = () => setIsOnline(true); const handleOffline = () => setIsOnline(false); window.addEventListener("online", handleOnline); window.addEventListener("offline", handleOffline); // Check network speed const connection = (navigator as any).connection; if (connection) { const speed = connection.effectiveType; setNetworkSpeed(speed === "4g" ? "fast" : "slow"); } return () => { window.removeEventListener("online", handleOnline); window.removeEventListener("offline", handleOffline); }; }, []); return { isOnline, networkSpeed }; } // Usage in component function PaymentComponent() { const { isOnline, networkSpeed } = useNetworkStatus(); if (!isOnline) { return (

No Internet Connection

Please check your connection and try again.

); } if (networkSpeed === "slow") { return (

⚠️ Slow network detected. Transactions may take longer than usual.

); } // ... rest of component } ``` ## 📋 Best Practices Keep users informed about what's happening, especially during longer operations like cross-chain transactions. ```tsx // Good: Clear status messages

Processing your payment... This may take 2-3 minutes.

// Bad: No feedback during long operations
{isLoading && }
```
Many errors are transient and can be resolved by retrying the operation. ```tsx // Good: Automatic retry with exponential backoff const retryWithBackoff = (attempt: number) => { const delay = Math.min(1000 * Math.pow(2, attempt), 10000); setTimeout(() => retry(), delay); }; // Bad: No retry mechanism if (error) { throw error; } ``` Comprehensive error logging helps identify and fix issues quickly. ```tsx // Good: Detailed error logging console.error("Payment failed", { error: error.message, orderData, userAddress, timestamp: Date.now(), }); // Bad: Generic error logging console.error("Error occurred"); ``` Provide alternative options when primary functionality fails. ```tsx // Good: Fallback options if (crossChainFailed) { return ; } // Bad: Complete failure with no alternatives if (crossChainFailed) { throw new Error("Transaction failed"); } ```
## 🆘 Getting Help Get real-time help from our community and support team Report bugs and request features on our GitHub repository When reporting issues, please include: - Error messages and codes - Steps to reproduce the issue - Browser and device information - Network conditions (if relevant) - Order IDs (if applicable) Remember: Good error handling is about more than just catching errors—it's about providing a smooth, understandable experience for your users even when things go wrong. # Examples & Use Cases Source: https://docs.b3.fun/anyspend/examples Real-world implementation examples for common AnySpend integration patterns # Examples & Use Cases Real-world implementation examples for common AnySpend integration patterns, from simple swaps to complex DeFi and gaming applications. ## 🔄 Cross-Chain Token Swaps ### Basic Swap Interface Perfect for DeFi applications, portfolio managers, or any app that needs token exchange functionality. ```tsx title="Simple Swap Page" icon="exchange-alt" import { AnySpend } from "@b3dotfun/sdk/anyspend/react"; function TokenSwapPage() { const [userAddress] = useWallet(); // Your wallet hook return (

Swap Tokens

{ // Update user's portfolio toast.success("Swap completed successfully!"); // Optional: Track analytics analytics.track("swap_completed", { txHash, userAddress, }); // Refresh user balances queryClient.invalidateQueries(['user-balances', userAddress]); }} />
); } ``` ### Advanced Swap with Quote Preview ```tsx title="Advanced Swap Interface" icon="chart-line" lines import { useAnyspendQuote, AnySpend } from "@b3dotfun/sdk/anyspend/react"; function AdvancedSwapInterface() { const [fromToken, setFromToken] = useState(USDC_ETHEREUM); const [toToken, setToToken] = useState(ETH_B3); const [amount, setAmount] = useState("100"); const [isSwapOpen, setIsSwapOpen] = useState(false); const quoteRequest = useMemo(() => ({ srcChain: fromToken.chainId, dstChain: toToken.chainId, srcTokenAddress: fromToken.address, dstTokenAddress: toToken.address, type: "swap" as const, tradeType: "EXACT_INPUT" as const, amount: parseUnits(amount || "0", fromToken.decimals).toString(), }), [fromToken, toToken, amount]); const { anyspendQuote, isLoadingAnyspendQuote } = useAnyspendQuote(true, quoteRequest); return (
{ setFromToken(toToken); setToToken(fromToken); }} /> {anyspendQuote && (
Rate: 1 {fromToken.symbol} = {anyspendQuote.rate} {toToken.symbol}
Network Fee: ${anyspendQuote.networkFeeUsd}
Service Fee: ${anyspendQuote.serviceFeeUsd}
Total: ${anyspendQuote.totalUsdCost}
)}
{isSwapOpen && ( { setIsSwapOpen(false); toast.success("Swap completed!"); }} /> )}
); } ``` ## 🖼️ NFT Marketplace Integration ### Simple NFT Purchase ```tsx title="NFT Card Component" icon="image" lines import { AnySpendNFTButton } from "@b3dotfun/sdk/anyspend/react"; function NFTCard({ nft }: { nft: NFTListing }) { const [userAddress] = useWallet(); const [isOwned, setIsOwned] = useState(false); const nftContract = { chainId: nft.chainId, contractAddress: nft.contractAddress, price: nft.priceWei, priceFormatted: nft.priceFormatted, currency: nft.currency, name: nft.name, description: nft.description, imageUrl: nft.imageUrl, }; return (
{nft.name}

{nft.name}

{nft.description}

{nft.priceFormatted} {nft.currency.symbol}
{isOwned ? (
✅ Owned
) : ( { setIsOwned(true); // Update user's NFT collection queryClient.invalidateQueries(['user-nfts', userAddress]); // Show success message with explorer link toast.success(
NFT purchased successfully! View Transaction
); }} /> )}
); } ``` ### NFT Marketplace with Bulk Purchase ```tsx title="Bulk NFT Purchase" icon="shopping-cart" lines function NFTMarketplace() { const [selectedNFTs, setSelectedNFTs] = useState([]); const [userAddress] = useWallet(); const handleBulkPurchase = () => { // For bulk purchases, create multiple orders or use batch contract selectedNFTs.forEach((nft, index) => { setTimeout(() => { // Stagger purchases to avoid rate limiting createSingleNFTPurchase(nft); }, index * 1000); }); }; return (
{nfts.map((nft) => ( { if (selected) { setSelectedNFTs([...selectedNFTs, nft]); } else { setSelectedNFTs(selectedNFTs.filter(n => n.id !== nft.id)); } }} /> ))}
{selectedNFTs.length > 0 && (

Selected: {selectedNFTs.length} NFTs

Total: {calculateTotal(selectedNFTs)} ETH

)}
); } ``` ## 🎮 Gaming & DeFi Applications ### Staking Interface ```tsx title="Staking Pool Component" icon="coins" lines import { AnySpendCustom } from "@b3dotfun/sdk/anyspend/react"; import { encodeFunctionData } from "viem"; function StakingPool({ pool }: { pool: StakingPool }) { const [stakeAmount, setStakeAmount] = useState(""); const [stakingDuration, setStakingDuration] = useState(30); const [userAddress] = useWallet(); const stakingCalldata = useMemo(() => { if (!stakeAmount) return "0x"; const amountWei = parseUnits(stakeAmount, pool.token.decimals); return encodeFunctionData({ abi: stakingPoolABI, functionName: "stake", args: [amountWei, stakingDuration * 24 * 60 * 60], // duration in seconds }); }, [stakeAmount, stakingDuration]); const expectedRewards = useMemo(() => { if (!stakeAmount) return "0"; const amount = parseFloat(stakeAmount); const apy = pool.apy / 100; const durationInYears = stakingDuration / 365; return (amount * apy * durationInYears).toFixed(4); }, [stakeAmount, stakingDuration, pool.apy]); return (

{pool.name}

APY: {pool.apy}%

TVL: ${pool.totalValueLocked.toLocaleString()}

setStakeAmount(e.target.value)} placeholder="0.0" /> {pool.token.symbol}

Expected rewards: {expectedRewards} {pool.token.symbol}

(

Stake {pool.token.symbol}

Amount: {stakeAmount} {pool.token.symbol}
Duration: {stakingDuration} days
Expected rewards: {expectedRewards} {pool.token.symbol}
{anyspendPrice && (
Total cost: ${anyspendPrice.totalUsdCost}
)}
)} onSuccess={(txHash) => { toast.success("Staking successful!"); // Update user's staking positions queryClient.invalidateQueries(['staking-positions', userAddress]); // Reset form setStakeAmount(""); }} />
); } ``` ### Gaming Spin Wheel ```tsx title="Spin Wheel Game" icon="gamepad" lines import { AnySpendBuySpin } from "@b3dotfun/sdk/anyspend/react"; function SpinWheel({ game }: { game: GameConfig }) { const [userAddress] = useWallet(); const [spinHistory, setSpinHistory] = useState([]); return (

{game.name}

Cost per spin: {game.spinCost} {game.currency.symbol}

Possible Prizes:

{game.prizes.map((prize, index) => (
{prize.name} {prize.probability}% chance
))}
{ // Handle spin result fetchSpinResult(txHash).then((result) => { setSpinHistory([result, ...spinHistory]); if (result.isWinner) { toast.success(`You won ${result.prize}! 🎉`); } else { toast.info("Better luck next time!"); } }); }} />

Recent Spins

{spinHistory.map((spin, index) => (
{spin.prize || "No prize"} {new Date(spin.timestamp).toLocaleTimeString()}
))}
); } ``` ### Tournament Entry ```tsx title="Tournament Entry" icon="trophy" lines import { AnySpendTournament } from "@b3dotfun/sdk/anyspend/react"; function TournamentEntry({ tournament }: { tournament: Tournament }) { const [userAddress] = useWallet(); const [isRegistered, setIsRegistered] = useState(false); return (

{tournament.name}

Prize Pool: ${tournament.prizePool.toLocaleString()}

Entry Fee: {tournament.entryFee} {tournament.currency.symbol}

Players: {tournament.currentPlayers}/{tournament.maxPlayers}

Starts: {new Date(tournament.startTime).toLocaleString()}

{isRegistered ? (
You're registered!

Tournament starts {formatTimeUntil(tournament.startTime)}

) : ( { setIsRegistered(true); // Update tournament player count queryClient.invalidateQueries(['tournament', tournament.id]); toast.success("Successfully registered for tournament!"); }} /> )}

Rules

    {tournament.rules.map((rule, index) => (
  • {rule}
  • ))}
); } ``` ## 💰 Fiat-to-Crypto Onramp ### Simple Onboarding Flow ```tsx title="User Onboarding" icon="credit-card" lines function UserOnboarding() { const [step, setStep] = useState(1); const [userAddress] = useWallet(); return (
= 1 ? 'active' : ''}`}>1. Connect Wallet
= 2 ? 'active' : ''}`}>2. Buy Crypto
= 3 ? 'active' : ''}`}>3. Start Using
{step === 1 && (

Welcome! Let's get you started

First, connect your wallet to continue.

setStep(2)} />
)} {step === 2 && (

Buy your first crypto

Purchase tokens with your credit card to get started.

{ setStep(3); toast.success("Purchase successful! Welcome to the ecosystem!"); }} />
)} {step === 3 && (

You're all set! 🎉

Your crypto purchase is complete. Here's what you can do next:

)}
); } ``` ## 🛒 E-commerce Integration ### Crypto Checkout ```tsx title="Checkout Process" icon="shopping-cart" lines function CryptoCheckout({ cart }: { cart: CartItem[] }) { const [paymentMethod, setPaymentMethod] = useState<'crypto' | 'fiat'>('crypto'); const [userAddress] = useWallet(); const total = cart.reduce((sum, item) => sum + item.price, 0); return (

Order Summary

{cart.map((item) => (
{item.name} ${item.price}
))}
Total: ${total}

Payment Method

{ // Create order record createOrder({ items: cart, total, paymentTxHash: txHash, customerAddress: userAddress, }); // Clear cart and redirect clearCart(); router.push(`/order-confirmation?tx=${txHash}`); }} />
); } ``` ## 🎯 Advanced Patterns ### Multi-Chain Portfolio Rebalancing ```tsx title="Portfolio Rebalancing" icon="balance-scale" lines function PortfolioRebalancer() { const [userAddress] = useWallet(); const [targetAllocations, setTargetAllocations] = useState({ ETH: 40, USDC: 30, BTC: 20, OTHER: 10, }); const { data: portfolio } = usePortfolioData(userAddress); const rebalancingPlan = calculateRebalancing(portfolio, targetAllocations); return (

Portfolio Rebalancing

Current Allocation

Target Allocation

Rebalancing Plan

{rebalancingPlan.map((action, index) => (
{action.type} {action.amount} {action.fromToken} {action.expectedOutput} {action.toToken} { queryClient.invalidateQueries(['portfolio', userAddress]); toast.success(`Rebalanced ${action.fromToken} to ${action.toToken}`); }} />
))}
); } ``` ## Getting Help Learn how to handle errors gracefully and provide great UX Get help from our community and team members These examples showcase the flexibility and power of AnySpend for building seamless payment experiences across different types of applications. Each example can be customized to fit your specific use case and design requirements. # Hooks Source: https://docs.b3.fun/anyspend/hooks React hooks for building custom payment flows and managing order lifecycles ## Core Hooks ### `useAnyspendQuote` Get real-time pricing information for token swaps and cross-chain transactions. ```tsx title="Basic Usage" icon="quote-left" import { useAnyspendQuote } from "@b3dotfun/sdk/anyspend"; const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError, refetchAnyspendQuote } = useAnyspendQuote(isMainnet, quoteRequest); ``` #### Parameters Use mainnet or testnet environment Quote configuration object #### QuoteRequest Interface ```typescript title="Type Definition" icon="code" interface QuoteRequest { srcChain: number; // Source chain ID dstChain: number; // Destination chain ID srcTokenAddress: string; // Source token contract address dstTokenAddress: string; // Destination token contract address type: "swap" | "custom"; // Order type tradeType: "EXACT_INPUT" | "EXACT_OUTPUT"; amount: string; // Amount in smallest unit (wei) } ``` #### Return Values Quote data with pricing and fees Loading state indicator Error object if quote failed Function to manually refresh quote #### Usage Example ```tsx title="Swap Quote Component" icon="exchange-alt" lines function SwapQuote() { const quoteRequest = { srcChain: 1, // Ethereum dstChain: 8333, // B3 srcTokenAddress: "0xA0b86a33E6Fb6Dd9a9B3d8B5FEb2b3C8e7D9Ff1E", // USDC dstTokenAddress: "0x0000000000000000000000000000000000000000", // ETH type: "swap", tradeType: "EXACT_INPUT", amount: "1000000", // 1 USDC (6 decimals) }; const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote(true, quoteRequest); if (isLoadingAnyspendQuote) return
Getting best price...
; if (getAnyspendQuoteError) return
Failed to get quote
; return (

You'll receive: {anyspendQuote?.expectedOutput} ETH

Network fee: ${anyspendQuote?.networkFeeUsd}

Service fee: ${anyspendQuote?.serviceFeeUsd}

Total cost: ${anyspendQuote?.totalUsdCost}

); } ``` *** ### `useAnyspendCreateOrder` Create and execute AnySpend orders with comprehensive error handling. ```tsx title="Basic Usage" icon="plus-circle" import { useAnyspendCreateOrder } from "@b3dotfun/sdk/anyspend"; const { createOrder, isCreatingOrder, createOrderError } = useAnyspendCreateOrder(options); ``` #### Parameters Configuration object with callback functions #### CreateOrderOptions Interface ```typescript title="Type Definition" icon="settings" interface CreateOrderOptions { onSuccess?: (data: OrderResponse) => void; onError?: (error: Error) => void; onSettled?: () => void; } ``` #### Return Values Function to create and execute an order Loading state indicator Error object if order creation failed #### Usage Example ```tsx title="Payment Form" icon="credit-card" lines function PaymentForm() { const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({ onSuccess: (data) => { console.log("Order created:", data.data.id); // Redirect to payment or show success router.push(`/payment/${data.data.id}`); }, onError: (error) => { console.error("Order failed:", error.message); toast.error("Payment failed. Please try again."); }, }); const handlePayment = () => { createOrder({ isMainnet: true, recipientAddress: userWalletAddress, orderType: "swap", srcChain: 1, dstChain: 8333, srcToken: { chainId: 1, address: "0xA0b86a33E6Fb6Dd9a9B3d8B5FEb2b3C8e7D9Ff1E", name: "USD Coin", symbol: "USDC", decimals: 6, }, dstToken: { chainId: 8333, address: "0x0000000000000000000000000000000000000000", name: "Ether", symbol: "ETH", decimals: 18, }, srcAmount: "1000000", // 1 USDC expectedDstAmount: "500000000000000000", // ~0.5 ETH creatorAddress: userWalletAddress, }); }; return ( ); } ``` *** ### `useAnyspendOrderAndTransactions` Monitor order status and track associated blockchain transactions in real-time. ```tsx title="Basic Usage" icon="search" import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend"; const { orderAndTransactions, isLoadingOrderAndTransactions, getOrderAndTransactionsError } = useAnyspendOrderAndTransactions(isMainnet, orderId); ``` #### Parameters Environment selection (mainnet or testnet) Order ID to track and monitor #### Return Values Complete order data with transaction details Loading state indicator Error object if fetch failed #### OrderWithTransactions Interface ```typescript title="Type Definition" icon="database" interface OrderWithTransactions { data: { order: Order; // Order details and status depositTxs: Transaction[]; // User deposit transactions relayTx?: Transaction; // Cross-chain relay transaction executeTx?: Transaction; // Final execution transaction refundTxs: Transaction[]; // Refund transactions (if any) }; } ``` #### Usage Example ```tsx title="Order Tracker" icon="eye" lines function OrderTracker({ orderId }: { orderId: string }) { const { orderAndTransactions, isLoadingOrderAndTransactions } = useAnyspendOrderAndTransactions(true, orderId); if (isLoadingOrderAndTransactions) { return
Loading order status...
; } if (!orderAndTransactions) { return
Order not found
; } const { order, depositTxs, executeTx, refundTxs } = orderAndTransactions.data; const getStatusMessage = (status: string) => { switch (status) { case "scanning_deposit_transaction": return "⏳ Waiting for payment confirmation..."; case "relay": return "🔄 Processing cross-chain transaction..."; case "executed": return "✅ Transaction completed successfully!"; case "refunded": return "↩️ Refund processed"; default: return "🔄 Processing..."; } }; return (

Order #{orderId.slice(0, 8)}

{getStatusMessage(order.status)}

{depositTxs.length > 0 && (

Payment Transaction

View on Etherscan
)} {executeTx && (

Execution Transaction

View on B3 Explorer
)} {order.errorDetails && (
Error: {order.errorDetails}
)}
); } ``` *** ### `useAnyspendOrderHistory` Retrieve paginated order history for a user address. ```tsx title="Basic Usage" icon="history" import { useAnyspendOrderHistory } from "@b3dotfun/sdk/anyspend"; const { orderHistory, isLoadingOrderHistory, getOrderHistoryError } = useAnyspendOrderHistory(isMainnet, creatorAddress, limit, offset); ``` #### Parameters Environment selection User wallet address Number of orders to fetch (max 100) Pagination offset #### Usage Example ```tsx title="Order History Component" icon="list" lines function OrderHistory({ userAddress }: { userAddress: string }) { const [page, setPage] = useState(0); const pageSize = 10; const { orderHistory, isLoadingOrderHistory } = useAnyspendOrderHistory( true, userAddress, pageSize, page * pageSize ); if (isLoadingOrderHistory) { return
Loading order history...
; } return (

Your Orders

{orderHistory?.data.map((order) => (

Type: {order.type}

Status: {order.status}

Amount: {order.srcAmount} {order.srcToken.symbol}

Date: {new Date(order.createdAt).toLocaleDateString()}

))}
); } ``` ## Additional Hooks ### `useAnyspendTokens` Get available tokens for a specific chain. ```tsx title="Token List" icon="coins" const { tokens, isLoadingTokens } = useAnyspendTokens(true, 1, "USDC"); ``` ### `useCoinbaseOnrampOptions` Get Coinbase onramp configuration for fiat payments. ```tsx title="Coinbase Onramp" icon="credit-card" const { coinbaseOptions, isLoadingCoinbaseOptions } = useCoinbaseOnrampOptions(); ``` ### `useStripeClientSecret` Get Stripe payment intent for credit card payments. ```tsx title="Stripe Integration" icon="stripe" const { clientSecret, isLoadingClientSecret } = useStripeClientSecret(orderData); ``` ## Hook Patterns ### Error Handling Pattern ```tsx title="Error Handling" icon="shield-exclamation" lines function PaymentComponent() { const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({ onError: (error) => { // Log error for debugging console.error("Payment failed:", error); // Show user-friendly message switch (error.message) { case "INSUFFICIENT_BALANCE": toast.error("Insufficient balance. Please add funds."); break; case "SLIPPAGE": toast.error("Price moved unfavorably. Please try again."); break; default: toast.error("Payment failed. Please try again."); } }, }); // Component implementation... } ``` ### Loading State Pattern ```tsx title="Loading States" icon="spinner" lines function SwapInterface() { const { anyspendQuote, isLoadingAnyspendQuote } = useAnyspendQuote(true, quoteRequest); const { createOrder, isCreatingOrder } = useAnyspendCreateOrder(); const isLoading = isLoadingAnyspendQuote || isCreatingOrder; return (
{isLoading && } {/* Rest of component */}
); } ``` ### Real-time Updates Pattern ```tsx title="Real-time Updates" icon="sync-alt" lines function OrderStatus({ orderId }: { orderId: string }) { const { orderAndTransactions } = useAnyspendOrderAndTransactions(true, orderId); // Auto-refresh every 5 seconds for pending orders useEffect(() => { if (orderAndTransactions?.data.order.status === "relay") { const interval = setInterval(() => { // Refetch is handled automatically by the hook }, 5000); return () => clearInterval(interval); } }, [orderAndTransactions?.data.order.status]); // Component implementation... } ``` ## Next Steps Browse real-world implementation examples Learn comprehensive error handling strategies Explore pre-built components # Installation & Setup Source: https://docs.b3.fun/anyspend/installation Get started with AnySpend - installation, basic setup, and verification ## Prerequisites v20.15.0 or higher Version 18 or 19 Recommended for better DX ## Installation Choose your preferred package manager: ```bash npm install @b3dotfun/sdk ``` `bash yarn add @b3dotfun/sdk ` ```bash pnpm add @b3dotfun/sdk ``` ## Basic Setup ### 1. Provider Setup Wrap your app with the `B3Provider` and `AnyspendProvider` to enable AnySpend functionality: ```tsx title="App.tsx" icon="react" import { AnyspendProvider } from "@b3dotfun/sdk/anyspend/react"; import { B3Provider } from "@b3dotfun/sdk/global-account/react"; import "@b3dotfun/sdk/index.css"; function App() { return ( {/* Your app components */} ); } export default App; ``` ### 2. Environment Configuration AnySpend automatically configures API endpoints based on the `isMainnet` parameter: **Endpoint**: `https://mainnet.anyspend.com` Use this for production applications with real transactions. **Endpoint**: `http://testnet.anyspend.com` Use this for development and testing with test tokens. ### 3. TypeScript Configuration (Optional but Recommended) If you're using TypeScript, ensure your `tsconfig.json` includes these settings for optimal compatibility: ```json title="tsconfig.json" icon="settings" { "compilerOptions": { "moduleResolution": "node", "allowSyntheticDefaultImports": true, "esModuleInterop": true } } ``` ## Verification Create a simple test component to verify your setup works correctly: ```tsx title="TestComponent.tsx" icon="test-tube" lines import { AnySpend } from "@b3dotfun/sdk/anyspend/react"; function TestComponent() { return ; } ``` ## Next Steps Learn about available components for different payment scenarios Discover React hooks for building custom payment flows Browse real-world implementation examples ## Troubleshooting Make sure you've installed the SDK correctly and imported the CSS file. The SDK requires React 18+ and may have compatibility issues with older versions. Ensure you have `B3Provider` and `AnyspendProvider` placed high in your component tree, typically in your main App component. If you're seeing TypeScript errors, verify your `tsconfig.json` includes the recommended settings above. # AnySpend Introduction Source: https://docs.b3.fun/anyspend/introduction Cross-chain crypto payments made simple - swap tokens, buy NFTs, and integrate fiat onramps AnySpend Banner ## What is AnySpend? AnySpend is B3's comprehensive payment infrastructure that enables seamless crypto transactions across multiple blockchains. Whether you're building a DeFi application, NFT marketplace, or gaming platform, AnySpend provides the components and APIs you need to accept payments in any token. [Try AnySpend in your browser](https://anyspend.com/swap) ## Use Cases

Cross-Chain Swaps

Enable users to swap tokens between different blockchains with automatic routing and best price discovery.

Checkout

One-click checkout buttons that accept any token as payment, with automatic conversion.

DeFi

Execute any onchain contract call, with usage for staking, prediction markets, bonding curves, and more.

Games

Embeddable in native iOS/Android, Unity, & other surfaces.
## Features User clicks a payment button or interacts with your interface, choosing their preferred token Our routing engine finds the best path to convert their token to the required destination token If needed, tokens are bridged across chains using secure, battle-tested infrastructure Tokens arrive at the destination address, execute any custom logic, and trigger your success callbacks ## Use Cases AnySpend Banner Enable token swaps, provide liquidity, and facilitate yield farming across multiple chains with automatic routing and competitive rates. Allow users to buy NFTs with any token they own, removing barriers and increasing conversion rates by supporting their preferred payment methods. Accept payments for in-game assets, tournament entries, and premium features using any cryptocurrency or fiat payment methods. Integrate crypto payments into traditional e-commerce platforms with automatic fiat conversion and settlement. Accept recurring payments in crypto with automatic conversion to your preferred settlement currency. ## Quick Start Get started with AnySpend in just a few steps: ```tsx import { AnySpend, AnyspendProvider } from "@b3dotfun/sdk/anyspend/react"; import { B3Provider } from "@b3dotfun/sdk/global-account/react"; import "@b3dotfun/sdk/index.css"; function App() { return ( ); } export default App ``` ## What's Next? Set up AnySpend in your project with npm, yarn, or pnpm Explore pre-built components for common payment scenarios See real-world implementation examples and best practices ## Getting Help * **Discord**: Join our [Discord community](https://discord.gg/b3dotfun) for support * **Documentation**: Comprehensive guides and API references * **Examples**: Ready-to-use code samples and integrations # ArenaKit Introduction Source: https://docs.b3.fun/arenakit/introduction Host tournaments, enable onchain wagering, & create onchain leaderboards. ## What is ArenaKit? More documentation is coming soon. # B3AR Introduction Source: https://docs.b3.fun/b3ar/introduction Host IRL drops with augmented reality. ## What is B3AR? More documentation is coming soon. # Check Channel Status Source: https://docs.b3.fun/basement/api-reference/check-channel-status basement/basement-swagger.json post /launcher/channel-status Check the status of a user's channel session # Create Message Channel Source: https://docs.b3.fun/basement/api-reference/create-message-channel basement/basement-swagger.json post /launcher/create-message-channel Create a new message channel with specified participants # Create Unverified Channel Source: https://docs.b3.fun/basement/api-reference/create-unverified-channel basement/basement-swagger.json post /launcher/create-unverified-channel Create a new unverified channel session for external games # Edit Channel Message Source: https://docs.b3.fun/basement/api-reference/edit-channel-message basement/basement-swagger.json post /launcher/edit-channel-message Edit an existing message in a channel # Get Channel Messages Source: https://docs.b3.fun/basement/api-reference/get-channel-messages basement/basement-swagger.json post /launcher/get-channel-messages Retrieve messages from a specific channel # Get Game Leaderboard Source: https://docs.b3.fun/basement/api-reference/get-game-leaderboard basement/basement-swagger.json post /scores Retrieves data from the game leaderboard, providing you with information on player rankings and scores. It helps you monitor and display competitive standings within the game. # Get Message Channels Source: https://docs.b3.fun/basement/api-reference/get-message-channels basement/basement-swagger.json post /launcher/get-message-channels Retrieve all message channels for the user # Get User Activities Source: https://docs.b3.fun/basement/api-reference/get-user-activities basement/basement-swagger.json get /activities Retrieves user activities that were previously set using the SendCustomActivity function. It's particularly useful for tracking and displaying in-game events, achievements, or custom leaderboards. # Get User Leaderboard Position Source: https://docs.b3.fun/basement/api-reference/get-user-leaderboard-position basement/basement-swagger.json post /launcher Retrieves data from the game leaderboard via wallet address, providing you with information on player rankings and scores. # Get User Scores Source: https://docs.b3.fun/basement/api-reference/get-user-scores basement/basement-swagger.json post /launcher/get-user-scores Retrieve user scores for the game # Get User States Source: https://docs.b3.fun/basement/api-reference/get-user-states basement/basement-swagger.json post /launcher/get-states Retrieve user states for the game # Renew Channel Heartbeat Source: https://docs.b3.fun/basement/api-reference/renew-channel-heartbeat basement/basement-swagger.json post /launcher/channel-heartbeat Keep the user session alive by renewing the heartbeat # Send Channel Message Source: https://docs.b3.fun/basement/api-reference/send-channel-message basement/basement-swagger.json post /launcher/send-channel-message Send a message to a specific channel # Send Custom Activity Source: https://docs.b3.fun/basement/api-reference/send-custom-activity basement/basement-swagger.json post /launcher/send-custom-activity Send a custom activity event for the user # Send Notification Source: https://docs.b3.fun/basement/api-reference/send-notification basement/basement-swagger.json post /launcher/send-notification Send a notification to the user # Set User Score Source: https://docs.b3.fun/basement/api-reference/set-user-score basement/basement-swagger.json post /launcher/set-user-score Set or update user score for the game # Set User State Source: https://docs.b3.fun/basement/api-reference/set-user-state basement/basement-swagger.json post /launcher/set-state Set or update user state for the game # Track Game Sessions Source: https://docs.b3.fun/basement/api-reference/track-game-sessions basement/basement-swagger.json post /launcher/track-game-sessions Track and update game session data # Trigger Rules Engine Source: https://docs.b3.fun/basement/api-reference/trigger-rules-engine basement/basement-swagger.json post /launcher/trigger-rules-engine Trigger the rules engine with specific event data # Unsend Channel Message Source: https://docs.b3.fun/basement/api-reference/unsend-channel-message basement/basement-swagger.json post /launcher/unsend-channel-message Delete/unsend a message from a channel # Verify Unverified Channel Source: https://docs.b3.fun/basement/api-reference/verify-unverified-channel basement/basement-swagger.json post /launcher/verify-unverified-channel Verify an unverified channel with user's wallet signature # BSMNT Brand Kit Source: https://docs.b3.fun/basement/brand-kit Follow these guidelines to use our brand correctly when contributing to the BSMNT community.
✦ DISCOVER GAMES ✦ FUN ✦ B3 ✦ PLAY TO EARN ✦
## Primary Logo BSMNT Purple Logo BSMNT Wordmark Dark BSMNT Wordmark Light ## Colors Don't limit yourself to just this common brand colors. B3 invites you to be expressive with different fun, vibrant color palletes.
``` #8B5CF6 ```
``` #6B7280 ```
``` #FFFFFF ```
``` #1F2937 ```
``` #E5E7EB ```
``` #F97316 ``` ## Brand Guidelines **Make it nostalgia.** Invoke a sense of childlike-play. **Make it fun.** Keep things light, friendly, and engaging. ## Fonts We recommend using the Apple San Francisco. [Download from Apple](https://developer.apple.com/fonts/) [Download from Github](https://github.com/AppleDesignResources/SanFranciscoFont) But have fun with other fonts... ## Fun Assets BSMNT Cursor BSMNT Rainbow Glitch BSMNT Icon BSMNT Alternative Logo
SVG
BSMNT Alternative Logo
SVG
BSMNT Alternative Logo
SVG
BSMNT Abstract Glitch BSMNT Clouds BSMNT Interruption
## Contribute to BSMNT brand Let's build B3 together - we welcome creators, artists, developers, gamers, players & everyone to contribute & be rewarded. Reach out if you've built something cool for the B3 community. # Construct Guide Source: https://docs.b3.fun/basement/construct-guide This guide will walk you through integrating your Construct game with the Basement.fun platform using web APIs ## Events Construct has a great GUI that enables developers to create games with minimal to no code. The following docs will review how to connect your game to Basement.fun using Construct's event sheet. ### Key Components You will need to add a few objects to your project to enable your Construct game to interact with the Basement.fun platform. To add objects to your project go to the **Layout View**, right-click in the layout, select **Insert New Object**, and then choose the object you want to insert into your project. After adding the object, it will be available in your event sheet. The Browser object enables you to write to the console. It's not necessary, but it will come in handy when verifying data and debugging your code. The AJAX object enables your game to interact with B3 APIs. * **POST requests** require you to create separate actions for each header parameter and one post to URL action for all the body parameters * **GET requests** require you to combine all the parameters and values you need into a single URL to send the request to the API * The **API responses** can be referenced using `AJAX.LastData` The JSON object enables your game to handle JSON responses. You will need to parse the JSON strings to make use of the response data. ## Sample Event This sample event will cover the POST Set Scores request detailed in the BSMNT API Specs. ### Sample Request Right-click anywhere on the event sheet, create a function, and name it **SetScore**. Click add action, select **AJAX**, select **Set request header**. * **Header field**: `X-Service-Method` * **Value field**: `setUserScore` Add another AJAX action and select **Set request header** again. * **Header field**: `Authorization` * **Value field**: `Bearer ` Replace `` with your actual game secret token. Add another AJAX action but this time, select **Post to URL**. Enter the following: * **Tag**: `setUserScore` * **URL**: `https://api.basement.fun/launcher` * **Data**: `{"launcherJwt": "string", "nonce": "string", "score": 0}` * **Method**: `POST` This is a sample request - be sure to replace your values with variables that are set by events in your game. ### Sample Response The sample response will look something like this: ```json API Response { "success": true | false, "error"?: "error string", "newScore"?: { "_id": "unique id", "nonce": "nonce", "updatedAt": 23151264, // unix timestamp "score": 100.235, "gameId": "game uuid", "normalizedAddress": "user lowercase address" } } ``` ## Retrieving Data In Construct, let's retrieve the nonce from the response, so we can use it to retrieve the score at a later time. Right-click anywhere on the event sheet and add a global variable named **Nonce**. Add an event that is triggered by your game. **Example**: To capture the user's score when they crash their bike into another bike, add an **on collision with another object** condition to the biker and set the object to biker. Add the action, select **functions**, and select **SetScore**. Add a **JSON** action, select **parse**, and enter `AJAX.LastData` in the JSON string field. This will grab the response from our SetScore request. Add a **system** action, select **set value**, choose the **Nonce** variable, and enter `JSON.Get("newScore.nonce")`. Now your Nonce variable is set to the nonce returned by the API response! ## Complete Integration Following the same steps, you can create events for each API endpoint by reviewing all the parameters and responses. ### Available API Endpoints Update or set a user's score for leaderboards. **Endpoint**: `POST /launcher`\ **Headers**: `X-Service-Method: setUserScore` ```json { "launcherJwt": "string", "nonce": "string", "score": 0 } ``` Retrieve a user's current score. **Endpoint**: `GET /launcher`\ **Headers**: `X-Service-Method: getUserScore` Trigger onchain actions based on game events. **Endpoint**: `POST /launcher`\ **Headers**: `X-Service-Method: triggerRulesEngine` ```json { "launcherJwt": "string", "trigger": "string", "nonce": "string" } ``` ## Best Practices Always check the `success` field in API responses and handle errors gracefully. Use Construct's global variables to store important data like JWT tokens and user scores. Use the Browser object to log important information to the console during development. Be mindful of API rate limits and avoid making too many requests in quick succession. ## Next Steps Complete API reference for all available endpoints Learn how to integrate with the BSMNT game launcher Official Construct 3 documentation and tutorials Sample projects using BSMNT integration ## Troubleshooting * Ensure you've added the AJAX object to your project * Check that all required headers are set correctly * Verify your game secret is valid * Make sure the API endpoint URL is correct * Confirm the JSON object is added to your project * Check that `AJAX.LastData` contains valid JSON * Use the Browser object to log the raw response for debugging * Verify your launcher JWT token is valid * Check that the Authorization header is properly formatted * Ensure your game secret hasn't expired # Game Launcher Source: https://docs.b3.fun/basement/game-launcher Launch games natively inside the BSMNT (basement.fun) platform and build addicting onchain experiences without having to worry about the crypto components