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:
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:
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:
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:
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:
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:
// 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
// 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
// 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
// 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
// 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
// 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:
// SDK handles this automatically
// Don't manually process postMessage events
Transaction Security
User Approval
All transactions require explicit user approval in the wallet:
// 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:
// 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:
- Do not open a public issue
- Email security@arcadia.com
- 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