═══════════════════════════════════════════════════════════════════════════════ ARCADIA GAME SDK - DEVELOPER DOCUMENTATION ═══════════════════════════════════════════════════════════════════════════════ Document: Security Generated: 2/13/2026, 7:31:40 PM Version: 1.0.0 ═══════════════════════════════════════════════════════════════════════════════ Security Guide ══════════════════════════════════════════════════════════════════════ This guide covers security best practices when using the Arcadia Game SDK. Overview ════════════════════════════════════════════════════════════ The Arcadia Game SDK is designed with security in mind. It uses secure communication patterns and never exposes sensitive data like private keys. Security Features ════════════════════════════════════════════════════════════ Wallet Security ══════════════════════════════════════════════════ • No Private Keys - The SDK never accesses or transmits private keys • Wallet Address Only - Only public wallet addresses are used • Parent Window Signing - All transactions are signed in the secure parent window • No Wallet Access - Games cannot directly access wallet functionality Communication Security ══════════════════════════════════════════════════ • postMessage API - Secure cross-origin communication • Origin Validation - Optional origin validation for messages • Request Timeouts - Prevents hanging requests • Message Validation - All messages are validated before processing Transaction Security ══════════════════════════════════════════════════ • User Approval Required - All transactions require explicit user approval • No Automatic Transactions - Games cannot send transactions without user consent • Transaction Details - Users see full transaction details before approval • Immediate Return - Payments return after transaction is sent (not confirmed) Best Practices ════════════════════════════════════════════════════════════ 1. Origin Validation ══════════════════════════════════════════════════ Always validate the parent origin when possible: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ const arcadia = new ArcadiaSDK({ gameId: 'your-game-id', parentOrigin: 'https://arcadia.com', // Restrict to specific origin }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Note: Using ['*'] allows any origin. Only use this for development. 2. Validate Payment Results ══════════════════════════════════════════════════ Always verify payment results before granting access or items: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ const result = await arcadia.payment.payToPlay(0.5, 'SOL'); // Verify payment details if (result.success && result.amount === 0.5 && result.token === 'SOL') { // Payment verified - proceed grantAccess(); } else { // Payment verification failed rejectPayment(); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3. Store Transaction Signatures ══════════════════════════════════════════════════ Keep transaction signatures for record-keeping and verification: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ const result = await arcadia.payment.payToPlay(0.5, 'SOL'); // Store transaction signature await savePaymentRecord({ walletAddress: walletAddress, txSignature: result.txSignature, amount: result.amount, timestamp: result.timestamp, }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4. Handle Errors Securely ══════════════════════════════════════════════════ Don't expose sensitive information in error messages: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ try { await arcadia.payment.payToPlay(0.5, 'SOL'); } catch (error) { // Don't expose internal error details if (error instanceof PaymentFailedError) { showError('Payment failed. Please try again.'); // Log full error details server-side logError(error); } } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5. Validate Wallet Addresses ══════════════════════════════════════════════════ Always validate wallet addresses before using them: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ function isValidSolanaAddress(address: string): boolean { // Basic validation - check length and format return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address); } const walletAddress = await arcadia.getWalletAddress(); if (walletAddress && isValidSolanaAddress(walletAddress)) { // Use wallet address } else { // Invalid address showError('Invalid wallet address'); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6. Secure Save Data ══════════════════════════════════════════════════ Use wallet addresses securely when storing player data: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Good: Use wallet address as identifier await savePlayerData({ walletAddress: walletAddress, // Public key - safe to store gameData: gameData, }); // Bad: Never store private keys or sensitive wallet data // await savePlayerData({ // privateKey: privateKey, // NEVER DO THIS // }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Common Security Pitfalls ════════════════════════════════════════════════════════════ ❌ Don't Trust Client-Side Validation Alone ══════════════════════════════════════════════════ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Bad: Only client-side validation const amount = parseFloat(userInput); if (amount > 0) { await arcadia.payment.payToPlay(amount, 'SOL'); } // Good: Validate server-side too const amount = parseFloat(userInput); if (amount > 0 && amount <= MAX_PAYMENT) { // Also validate on server await arcadia.payment.payToPlay(amount, 'SOL'); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ❌ Don't Expose Internal Errors ══════════════════════════════════════════════════ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Bad: Expose internal error details catch (error) { showError([Payment failed: ${error.message}]); // May expose sensitive information } // Good: Show user-friendly messages catch (error) { showError('Payment failed. Please try again.'); // Log full error server-side logError(error); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ❌ Don't Skip Payment Verification ══════════════════════════════════════════════════ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Bad: Trust payment without verification const result = await arcadia.payment.payToPlay(0.5, 'SOL'); grantAccess(); // No verification! // Good: Verify payment details const result = await arcadia.payment.payToPlay(0.5, 'SOL'); if (result.success && result.amount === 0.5) { grantAccess(); } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ❌ Don't Store Sensitive Data ══════════════════════════════════════════════════ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // Bad: Store sensitive data localStorage.setItem('privateKey', privateKey); // NEVER! // Good: Only store public data localStorage.setItem('walletAddress', walletAddress); // OK ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ postMessage Security ════════════════════════════════════════════════════════════ The SDK uses [postMessage] for communication. Follow these practices: Validate Message Origin ══════════════════════════════════════════════════ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // SDK automatically validates origin if parentOrigin is set const arcadia = new ArcadiaSDK({ gameId: 'your-game-id', parentOrigin: 'https://arcadia.com', // Validates origin }); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Don't Trust External Messages ══════════════════════════════════════════════════ The SDK handles message validation internally. Don't process messages from unknown sources: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // SDK handles this automatically // Don't manually process postMessage events ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Transaction Security ════════════════════════════════════════════════════════════ User Approval ══════════════════════════════════════════════════ All transactions require explicit user approval in the wallet: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // User must approve in wallet popup const result = await arcadia.payment.payToPlay(0.5, 'SOL'); // Transaction is only sent after user approval ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Transaction Details ══════════════════════════════════════════════════ Users see full transaction details before approval: • Amount • Token type • Recipient address • Transaction fee No Automatic Transactions ══════════════════════════════════════════════════ Games cannot send transactions automatically: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CODE BLOCK [TYPESCRIPT] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ // This requires user approval - cannot be automated const result = await arcadia.payment.payToPlay(0.5, 'SOL'); ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Data Privacy ════════════════════════════════════════════════════════════ Wallet Address Privacy ══════════════════════════════════════════════════ Wallet addresses are public information, but: • Don't share wallet addresses unnecessarily • Don't link wallet addresses to real-world identities without consent • Respect user privacy preferences Payment Data ══════════════════════════════════════════════════ Payment data includes: • Transaction signatures (public) • Amounts (public) • Timestamps (public) • Purchase IDs (internal) All payment data is safe to store and share for analytics. Reporting Security Issues ════════════════════════════════════════════════════════════ If you discover a security vulnerability: 1. Do not open a public issue 2. Email security@arcadia.com 3. Include: - Description of the vulnerability - Steps to reproduce - Potential impact - Suggested fix (if any) Security Checklist ════════════════════════════════════════════════════════════ Before deploying your game: • [ ] Origin validation configured (if applicable) • [ ] Payment results are verified • [ ] Transaction signatures are stored • [ ] Error messages don't expose sensitive data • [ ] Wallet addresses are validated • [ ] No sensitive data in client-side code • [ ] Server-side validation for critical operations • [ ] Security best practices followed Next Steps ════════════════════════════════════════════════════════════ • Review Error Handling for secure error handling • Check API Reference for security-related methods • See Examples for secure implementation patterns ═══════════════════════════════════════════════════════════════════════════════ For the latest documentation, visit: https://arcadia.obeliskprotocol.io/developer For support, email: support@arcadia.com ═══════════════════════════════════════════════════════════════════════════════