From 726652521ebc8dcb72d3bd81c0c0b8f9b6eccbf0 Mon Sep 17 00:00:00 2001
From: Yashovardhan Agrawal <21066442+yashovardhan@users.noreply.github.com>
Date: Tue, 30 Sep 2025 10:20:09 +0800
Subject: [PATCH 1/3] Update dashboard docs
---
embedded-wallets/dashboard/README.mdx | 8 +-
.../dashboard/advanced/key-export.mdx | 452 +++++++++++++
.../dashboard/advanced/session-management.mdx | 360 ++++++++++
.../dashboard/advanced/test-accounts.mdx | 102 +++
.../dashboard/advanced/user-details.mdx | 618 ++++++++++++++++++
.../dashboard/project-settings.mdx | 267 ++++++--
embedded-wallets/dashboard/whitelist.mdx | 307 +++++++++
ew-sidebar.js | 13 +
.../project-settings-advanced.png | Bin 228473 -> 434613 bytes
.../w3a-dashboard/project-settings-domain.png | Bin 169462 -> 325154 bytes
.../project-settings-general.png | Bin 352681 -> 558277 bytes
.../w3a-dashboard/test-accounts-settings.png | Bin 0 -> 128896 bytes
12 files changed, 2070 insertions(+), 57 deletions(-)
create mode 100644 embedded-wallets/dashboard/advanced/key-export.mdx
create mode 100644 embedded-wallets/dashboard/advanced/session-management.mdx
create mode 100644 embedded-wallets/dashboard/advanced/test-accounts.mdx
create mode 100644 embedded-wallets/dashboard/advanced/user-details.mdx
create mode 100644 embedded-wallets/dashboard/whitelist.mdx
create mode 100644 static/img/embedded-wallets/w3a-dashboard/test-accounts-settings.png
diff --git a/embedded-wallets/dashboard/README.mdx b/embedded-wallets/dashboard/README.mdx
index b4721dc8414..bbe58f65152 100644
--- a/embedded-wallets/dashboard/README.mdx
+++ b/embedded-wallets/dashboard/README.mdx
@@ -49,7 +49,13 @@ The project comes pre-configured with default connections, chains and networks t
Once your project is created, you can configure various aspects of your integration through the dashboard:
-- **[Project Settings](./project-settings)** - Configure general settings, domain whitelisting, and advanced options
+- **[Project Settings](./project-settings)** - Basic project information, credentials, and token verification
+- **[Whitelist Settings](./whitelist)** - Domain and URL authorization for enhanced security
+- **[Advanced Project Settings](./advanced/session-management)** - Advanced configuration options
+ - **[Session Management](./advanced/session-management)** - Session duration and behavior
+ - **[Test Accounts](./advanced/test-accounts)** - Development testing environment
+ - **[User Details in ID Token](./advanced/user-details)** - JWT token user data configuration
+ - **[Key Export Settings](./advanced/key-export)** - Private key export permissions
- **[Chains and Networks](./chains-and-networks)** - Manage blockchain networks and custom chain configurations
- **[Authentication](./authentication)** - Configure login methods, social connections, and custom authentication
- **[Wallet Services](./wallet-services)** - Customize wallet UI and configure wallet features
diff --git a/embedded-wallets/dashboard/advanced/key-export.mdx b/embedded-wallets/dashboard/advanced/key-export.mdx
new file mode 100644
index 00000000000..96c7377fde3
--- /dev/null
+++ b/embedded-wallets/dashboard/advanced/key-export.mdx
@@ -0,0 +1,452 @@
+---
+title: Key Export Settings
+sidebar_label: Key Export
+image: 'img/metamaskog.jpg'
+description: 'Configure private key export permissions in Web3Auth Dashboard | Embedded Wallets'
+---
+
+import ProjectSettingsAdvanced from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png'
+
+The **Key Export Settings** allow you to control whether users can programmatically export their private keys using the Web3Auth SDK. This setting provides flexibility for advanced use cases while maintaining security control over sensitive cryptographic material.
+
+
+

+
+
+## Key Export Overview
+
+Private key export functionality allows applications to retrieve users' private keys programmatically through the Web3Auth SDK. This capability enables advanced use cases such as wallet migration, multi-platform support, and integration with external services, while requiring careful consideration of security implications.
+
+### Export Methods
+
+**Programmatic Export (Configurable):**
+
+- Access via `eth_private_key` JSON-RPC method
+- Requires explicit user consent
+- Can be enabled/disabled per project
+- Controlled through dashboard settings
+
+**Manual Export (Always Available):**
+
+- Built-in Web3Auth wallet interface
+- User-initiated through wallet UI
+- Cannot be disabled
+- Provides user autonomy over their keys
+
+## Configuring Key Export
+
+### Enabling Programmatic Export
+
+1. **Navigate to Project Settings** → **Advanced** → **Key Export**
+2. **Locate "Enable Key Export"** toggle
+3. **Enable the setting** to allow programmatic access
+4. **Save configuration** to apply changes
+
+### Disabling Programmatic Export
+
+When disabled:
+
+- Applications cannot retrieve private keys via SDK
+- Users can still export manually through wallet interface
+- Enhanced security for applications that don't require key access
+- Recommended for most consumer applications
+
+## Implementation Guide
+
+### Programmatic Key Retrieval
+
+**Basic Implementation:**
+
+```javascript
+// Ensure user is authenticated
+if ((await web3auth.status) !== 'connected') {
+ throw new Error('User not authenticated')
+}
+
+// Request private key (requires user consent)
+try {
+ const privateKey = await web3auth.provider.request({
+ method: 'eth_private_key',
+ })
+
+ // Handle the private key securely
+ console.log('Private key retrieved successfully')
+ return privateKey
+} catch (error) {
+ // Handle export rejection or failure
+ console.error('Key export failed:', error)
+ throw error
+}
+```
+
+**Secure Implementation Pattern:**
+
+```javascript
+class SecureKeyManager {
+ async exportKey() {
+ // Validate authentication state
+ await this.validateAuthentication()
+
+ // Show user confirmation dialog
+ const userConsent = await this.getUserConsent()
+ if (!userConsent) {
+ throw new Error('User declined key export')
+ }
+
+ // Retrieve private key
+ const privateKey = await web3auth.provider.request({
+ method: 'eth_private_key',
+ })
+
+ // Process key securely (encrypt, transmit, etc.)
+ return await this.processKeySecurely(privateKey)
+ }
+
+ async processKeySecurely(privateKey) {
+ // Implement your secure processing logic
+ // Examples: encryption, secure transmission, temporary storage
+
+ // Always clear sensitive data from memory
+ setTimeout(() => {
+ privateKey = null
+ }, 0)
+ }
+}
+```
+
+### User Consent Flow
+
+**Best Practices for User Consent:**
+
+```javascript
+async function requestKeyExport() {
+ // Show clear explanation to user
+ const consent = await showConsentDialog({
+ title: 'Export Private Key',
+ message:
+ 'Your private key will be exported for wallet migration. ' +
+ 'Keep this key secure and never share it with others.',
+ risks: [
+ 'Anyone with your private key can access your funds',
+ 'Store the key in a secure location',
+ 'Consider using a hardware wallet for long-term storage',
+ ],
+ confirmText: 'I understand the risks and want to export my key',
+ cancelText: 'Cancel',
+ })
+
+ if (consent) {
+ return await exportPrivateKey()
+ }
+
+ throw new Error('User declined key export')
+}
+```
+
+## Use Cases for Key Export
+
+### Wallet Migration
+
+**Cross-Platform Migration:**
+
+```javascript
+// Export from Web3Auth for import into other wallets
+async function migrateToExternalWallet() {
+ try {
+ const privateKey = await exportPrivateKey()
+
+ // Generate wallet formats for different platforms
+ const walletFormats = {
+ metamask: generateMetaMaskFormat(privateKey),
+ trustwallet: generateTrustWalletFormat(privateKey),
+ hardware: generateHardwareWalletFormat(privateKey),
+ }
+
+ return walletFormats
+ } catch (error) {
+ console.error('Migration failed:', error)
+ throw error
+ }
+}
+```
+
+### Multi-Chain Support
+
+**Cross-Chain Key Derivation:**
+
+```javascript
+async function deriveKeysForMultipleChains() {
+ const basePrivateKey = await exportPrivateKey()
+
+ // Derive keys for different blockchain networks
+ const chainKeys = {
+ ethereum: deriveEthereumKey(basePrivateKey),
+ polygon: derivePolygonKey(basePrivateKey),
+ solana: deriveSolanaKey(basePrivateKey),
+ bitcoin: deriveBitcoinKey(basePrivateKey),
+ }
+
+ return chainKeys
+}
+```
+
+### Advanced Integrations
+
+**DeFi Protocol Integration:**
+
+```javascript
+async function integrateDeFiProtocol() {
+ // Export key for direct protocol interaction
+ const privateKey = await exportPrivateKey()
+
+ // Create wallet instance for advanced operations
+ const wallet = new ethers.Wallet(privateKey, provider)
+
+ // Perform complex DeFi operations
+ await performAdvancedDeFiOperations(wallet)
+
+ // Clear sensitive data
+ wallet.privateKey = null
+}
+```
+
+### Backup and Recovery
+
+**Secure Backup Creation:**
+
+```javascript
+async function createSecureBackup() {
+ const privateKey = await exportPrivateKey()
+
+ // Encrypt private key for backup
+ const encryptedBackup = await encryptKey(privateKey, userPassword)
+
+ // Store encrypted backup securely
+ await storeEncryptedBackup(encryptedBackup)
+
+ // Provide recovery instructions to user
+ showBackupInstructions(encryptedBackup)
+}
+```
+
+## Security Considerations
+
+### Application Security
+
+**Key Handling Best Practices:**
+
+- **Minimize Exposure**: Retrieve keys only when necessary
+- **Secure Transmission**: Use HTTPS and encrypted channels
+- **Memory Management**: Clear private keys from memory immediately after use
+- **No Persistent Storage**: Never store private keys in databases or local storage
+- **Audit Logging**: Log key export events for security monitoring
+
+**Implementation Security:**
+
+```javascript
+class SecureKeyHandler {
+ constructor() {
+ this.keyBuffer = null
+ }
+
+ async handleKeyExport() {
+ try {
+ // Secure key retrieval
+ this.keyBuffer = await this.getPrivateKey()
+
+ // Process immediately
+ const result = await this.processKey(this.keyBuffer)
+
+ return result
+ } finally {
+ // Always clear sensitive data
+ this.clearKeyBuffer()
+ }
+ }
+
+ clearKeyBuffer() {
+ if (this.keyBuffer) {
+ // Overwrite memory with random data
+ crypto.getRandomValues(new Uint8Array(this.keyBuffer.length))
+ this.keyBuffer = null
+ }
+ }
+}
+```
+
+### User Education
+
+**Security Awareness:**
+
+- Educate users about private key security
+- Explain the implications of key export
+- Provide secure storage recommendations
+- Warn against sharing private keys
+
+**User Interface Guidelines:**
+
+```javascript
+const securityWarnings = {
+ beforeExport: [
+ 'Your private key controls access to your wallet and funds',
+ 'Never share your private key with anyone',
+ 'Store your key in a secure, offline location',
+ 'Consider using a hardware wallet for long-term storage',
+ ],
+
+ afterExport: [
+ 'Your private key has been exported',
+ 'Ensure it is stored securely and never shared',
+ 'Delete any temporary copies or screenshots',
+ 'Consider this key compromised if viewed by others',
+ ],
+}
+```
+
+### Regulatory Compliance
+
+**Compliance Considerations:**
+
+- **Data Protection**: Ensure key export complies with privacy regulations
+- **Audit Requirements**: Maintain records of key export events
+- **User Consent**: Obtain explicit consent for key export operations
+- **Jurisdictional Laws**: Consider local regulations regarding cryptographic material
+
+## Monitoring and Analytics
+
+### Export Event Tracking
+
+**Analytics Implementation:**
+
+```javascript
+async function trackKeyExport(userId, exportReason) {
+ await analytics.track('private_key_exported', {
+ user_id: userId,
+ timestamp: new Date().toISOString(),
+ reason: exportReason,
+ user_agent: navigator.userAgent,
+ ip_address: await getUserIP(),
+ session_id: getSessionId(),
+ })
+}
+```
+
+**Security Monitoring:**
+
+```javascript
+class KeyExportMonitor {
+ constructor() {
+ this.exportAttempts = new Map()
+ }
+
+ async monitorExport(userId) {
+ const attempts = this.exportAttempts.get(userId) || 0
+
+ // Flag suspicious activity
+ if (attempts > 5) {
+ await this.flagSuspiciousActivity(userId)
+ }
+
+ // Track export attempt
+ this.exportAttempts.set(userId, attempts + 1)
+
+ // Reset counter after 24 hours
+ setTimeout(
+ () => {
+ this.exportAttempts.delete(userId)
+ },
+ 24 * 60 * 60 * 1000
+ )
+ }
+}
+```
+
+## Alternative Approaches
+
+### When to Disable Key Export
+
+**Recommended for:**
+
+- Consumer-facing applications
+- Applications handling high-value assets
+- Regulated financial services
+- Applications with strict security requirements
+
+**Alternative Solutions:**
+
+- Use Web3Auth's built-in wallet interface
+- Implement transaction signing without key exposure
+- Use multi-signature schemes
+- Leverage Web3Auth's session-based authentication
+
+### Transaction-Only Access
+
+**Secure Transaction Pattern:**
+
+```javascript
+// Sign transactions without exposing private key
+async function signTransaction(transactionData) {
+ // Use Web3Auth's provider directly
+ const signedTransaction = await web3auth.provider.request({
+ method: 'eth_signTransaction',
+ params: [transactionData],
+ })
+
+ return signedTransaction
+}
+```
+
+## Troubleshooting
+
+### Common Issues
+
+**Key Export Disabled:**
+
+- Verify setting is enabled in dashboard
+- Check project configuration
+- Confirm user permissions
+
+**Export Method Not Available:**
+
+- Ensure Web3Auth SDK is properly initialized
+- Verify user is authenticated
+- Check for browser compatibility issues
+
+**User Consent Failures:**
+
+- Implement proper consent flow
+- Provide clear security information
+- Handle user rejection gracefully
+
+### Error Handling
+
+**Robust Error Management:**
+
+```javascript
+async function safeKeyExport() {
+ try {
+ await validateExportPermissions()
+ const key = await exportPrivateKey()
+ return key
+ } catch (error) {
+ if (error.code === 'EXPORT_DISABLED') {
+ throw new Error('Key export is disabled for this project')
+ } else if (error.code === 'USER_REJECTED') {
+ throw new Error('User declined key export')
+ } else {
+ console.error('Unexpected error:', error)
+ throw new Error('Key export failed')
+ }
+ }
+}
+```
+
+## Next Steps
+
+- **[User Details in ID Token](./user-details)** - Configure user data in JWT tokens
+- **[Session Management](./session-management)** - Control session duration and behavior
+- **[Project Settings](../project-settings)** - Configure basic project information
diff --git a/embedded-wallets/dashboard/advanced/session-management.mdx b/embedded-wallets/dashboard/advanced/session-management.mdx
new file mode 100644
index 00000000000..555dae7275d
--- /dev/null
+++ b/embedded-wallets/dashboard/advanced/session-management.mdx
@@ -0,0 +1,360 @@
+---
+title: Session Management
+sidebar_label: Session Management
+image: 'img/metamaskog.jpg'
+description: 'Configure session duration and behavior in Web3Auth Dashboard | Embedded Wallets'
+---
+
+import ProjectSettingsAdvanced from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png'
+
+The **Session Management** settings allow you to customize session lifetime and behavior for your Web3Auth integration. These settings determine how long user sessions remain active before requiring re-authentication, providing flexibility to balance security requirements with user experience.
+
+
+

+
+
+## Session Duration Overview
+
+Session duration controls how long a user's authentication session remains valid before automatic expiration. This setting directly impacts both security posture and user convenience, making it a critical configuration for production applications.
+
+### Default Configuration
+
+- **Default Duration**: 1 day (24 hours)
+- **Minimum Duration**: 1 second
+- **Maximum Duration**: 30 days (720 hours)
+- **Granularity**: Configurable down to the second
+
+## Configuring Session Duration
+
+### Setting Session Lifetime
+
+1. **Navigate to Project Settings** → **Advanced** → **Session Management**
+2. **Locate Session Duration** setting
+3. **Enter desired duration** in the provided format
+4. **Save configuration** to apply changes
+
+### Duration Format Options
+
+**Time Units Supported:**
+
+- **Seconds**: 1s, 30s, 60s
+- **Minutes**: 1m, 30m, 60m
+- **Hours**: 1h, 12h, 24h
+- **Days**: 1d, 7d, 30d
+
+**Example Configurations:**
+
+```
+30m # 30 minutes
+2h # 2 hours
+1d # 1 day (default)
+7d # 7 days
+30d # 30 days (maximum)
+```
+
+## Security Considerations
+
+### Short Session Durations
+
+**Benefits:**
+
+- **Enhanced Security**: Reduced exposure window if credentials are compromised
+- **Compliance**: Meets strict security requirements for sensitive applications
+- **Risk Mitigation**: Limits potential damage from unauthorized access
+- **Regular Validation**: Ensures users are actively using the application
+
+**Use Cases:**
+
+- Financial applications
+- Healthcare systems
+- Administrative interfaces
+- High-security environments
+
+**Recommended Durations:**
+
+- **High Security**: 30m - 2h
+- **Financial Apps**: 1h - 4h
+- **Admin Panels**: 2h - 8h
+
+### Long Session Durations
+
+**Benefits:**
+
+- **Improved UX**: Reduces authentication friction for users
+- **Productivity**: Minimizes workflow interruptions
+- **User Retention**: Decreases abandonment due to re-authentication
+- **Convenience**: Better for applications with frequent usage
+
+**Use Cases:**
+
+- Consumer applications
+- Gaming platforms
+- Content consumption apps
+- Productivity tools
+
+**Recommended Durations:**
+
+- **Consumer Apps**: 7d - 30d
+- **Gaming**: 14d - 30d
+- **Content Apps**: 7d - 30d
+
+## Application-Specific Recommendations
+
+### Web Applications
+
+**Standard Web Apps:**
+
+```
+Session Duration: 1d - 7d
+Rationale: Balance between security and convenience
+```
+
+**Single Page Applications (SPAs):**
+
+```
+Session Duration: 4h - 1d
+Rationale: Active browsing sessions with automatic renewal
+```
+
+**Progressive Web Apps (PWAs):**
+
+```
+Session Duration: 7d - 30d
+Rationale: App-like experience with persistent sessions
+```
+
+### Mobile Applications
+
+**Native Mobile Apps:**
+
+```
+Session Duration: 14d - 30d
+Rationale: Device-based security with biometric re-authentication
+```
+
+**Mobile Games:**
+
+```
+Session Duration: 30d
+Rationale: Seamless gaming experience with maximum convenience
+```
+
+**Financial Mobile Apps:**
+
+```
+Session Duration: 1h - 4h
+Rationale: High security requirements with biometric backup
+```
+
+### Gaming Applications
+
+**Casual Games:**
+
+```
+Session Duration: 30d
+Rationale: Minimal friction for entertainment applications
+```
+
+**Competitive Games:**
+
+```
+Session Duration: 14d - 30d
+Rationale: Balance between convenience and account security
+```
+
+**Gaming Platforms:**
+
+```
+Session Duration: 7d - 30d
+Rationale: Platform-level access with game-specific security
+```
+
+## Advanced Session Behaviors
+
+### Session Renewal
+
+Web3Auth sessions can be renewed through various mechanisms:
+
+**Automatic Renewal:**
+
+- Sessions automatically extend on user activity
+- Background refresh maintains active sessions
+- Seamless experience without user intervention
+
+**Manual Renewal:**
+
+- Explicit user action required for session extension
+- Greater control over session lifecycle
+- Suitable for high-security environments
+
+### Session Termination
+
+**Automatic Termination Events:**
+
+- Session duration expiry
+- Extended inactivity periods
+- Security-triggered logout
+- Device/browser changes
+
+**Manual Termination:**
+
+- User-initiated logout
+- Administrative session termination
+- Forced logout from dashboard
+
+## Implementation Considerations
+
+### Frontend Integration
+
+**Session Status Monitoring:**
+
+```javascript
+// Check session status
+const isAuthenticated = await web3auth.status
+
+// Handle session expiry
+web3auth.on('session_expired', () => {
+ // Redirect to login or show re-authentication modal
+ handleSessionExpiry()
+})
+```
+
+**Graceful Session Handling:**
+
+```javascript
+// Monitor session state
+setInterval(async () => {
+ const sessionValid = await web3auth.isLoggedIn()
+ if (!sessionValid) {
+ // Handle session expiry gracefully
+ await handleSessionExpiry()
+ }
+}, 60000) // Check every minute
+```
+
+### Backend Validation
+
+**Token Validation:**
+
+```javascript
+import jwt from 'jsonwebtoken'
+
+// Validate session token
+function validateSession(token) {
+ try {
+ const decoded = jwt.verify(token, publicKey)
+ const now = Math.floor(Date.now() / 1000)
+
+ if (decoded.exp < now) {
+ throw new Error('Session expired')
+ }
+
+ return decoded
+ } catch (error) {
+ // Handle session validation failure
+ throw new Error('Invalid session')
+ }
+}
+```
+
+## Security Best Practices
+
+### Session Security Guidelines
+
+**Token Management:**
+
+- Store session tokens securely (HttpOnly cookies for web)
+- Implement proper token rotation
+- Use secure transmission (HTTPS only)
+- Clear tokens on logout
+
+**Monitoring and Alerting:**
+
+- Track unusual session patterns
+- Monitor concurrent sessions
+- Alert on suspicious activity
+- Log session events for audit
+
+**Multi-Device Considerations:**
+
+- Limit concurrent sessions per user
+- Implement device fingerprinting
+- Provide session management UI
+- Enable remote session termination
+
+### Compliance Requirements
+
+**Industry Standards:**
+
+- **PCI DSS**: Maximum 15-minute idle timeout for payment systems
+- **HIPAA**: Regular session timeouts for healthcare data
+- **SOX**: Documented session management for financial systems
+- **GDPR**: User control over session data and duration
+
+**Risk Assessment Matrix:**
+
+| Risk Level | Max Session Duration | Re-auth Frequency |
+| ---------- | -------------------- | ----------------- |
+| Critical | 1-2 hours | Every action |
+| High | 2-8 hours | Daily |
+| Medium | 1-7 days | Weekly |
+| Low | 7-30 days | Monthly |
+
+## Troubleshooting Session Issues
+
+### Common Session Problems
+
+**Premature Session Expiry:**
+
+- Check system clock synchronization
+- Verify session duration configuration
+- Review token validation logic
+- Check for timezone issues
+
+**Sessions Not Expiring:**
+
+- Confirm session duration settings
+- Check automatic renewal behavior
+- Verify backend token validation
+- Review frontend session monitoring
+
+**Inconsistent Session Behavior:**
+
+- Check cross-device synchronization
+- Verify token storage mechanisms
+- Review session renewal logic
+- Test different browser/app configurations
+
+### Debugging Tools
+
+**Session Inspection:**
+
+```javascript
+// Debug session information
+console.log('Session Duration:', web3auth.sessionDuration)
+console.log('Session Start:', web3auth.sessionStartTime)
+console.log('Session Expires:', web3auth.sessionExpiryTime)
+console.log('Time Remaining:', web3auth.sessionTimeRemaining)
+```
+
+**Token Analysis:**
+
+```javascript
+// Decode and inspect session token
+const jwt = require('jsonwebtoken')
+const decoded = jwt.decode(sessionToken, { complete: true })
+console.log('Token Header:', decoded.header)
+console.log('Token Payload:', decoded.payload)
+console.log('Issued At:', new Date(decoded.payload.iat * 1000))
+console.log('Expires At:', new Date(decoded.payload.exp * 1000))
+```
+
+## Next Steps
+
+- **[Key Export Settings](./key-export)** - Configure private key export permissions
+- **[User Details in ID Token](./user-details)** - Manage user data in JWT tokens
+- **[Project Settings](../project-settings)** - Configure basic project information
diff --git a/embedded-wallets/dashboard/advanced/test-accounts.mdx b/embedded-wallets/dashboard/advanced/test-accounts.mdx
new file mode 100644
index 00000000000..b1e047f9e33
--- /dev/null
+++ b/embedded-wallets/dashboard/advanced/test-accounts.mdx
@@ -0,0 +1,102 @@
+---
+title: Test Accounts
+sidebar_label: Test Accounts
+image: 'img/metamaskog.jpg'
+description: 'Configure test accounts for development and testing | Embedded Wallets'
+---
+
+import TestAccountsSettings from '@site/static/img/embedded-wallets/w3a-dashboard/test-accounts-settings.png'
+
+Test Accounts allow you to log in with static verification codes during development and testing phases. This feature simplifies the authentication flow when testing your application by providing predictable OTP codes and designated test credentials.
+
+Enabling this option permits login through the provided email, OTP code, or phone number. Note that these accounts are designated for testing only and should not be used in production/ storing funds.
+
+
+

+
+
+## Enabling Test Accounts
+
+Test Accounts can be enabled through the Web3Auth Dashboard:
+
+1. Navigate to your project in the [Web3Auth Dashboard](https://dashboard.web3auth.io)
+2. Go to **Project Settings** > **Advanced**
+3. Locate the **Test Accounts** section
+4. Toggle the **Enable Test Accounts** option
+
+## Test Account Types
+
+### Email Authentication
+
+When Test Accounts are enabled, each test account is assigned a unique email address in the format `test_account_XXXX@example.com`, where `XXXX` represents a randomly generated number. You can use these test email addresses to authenticate using email passwordless OTP login.
+
+### Phone Number Authentication
+
+When Test Accounts are enabled, each test account is assigned a unique phone number in the format `+1 (555) XXX-XXXX`, where `XXX-XXXX` represents a randomly generated number. You can use these test phone numbers to authenticate using SMS OTP login.
+
+### Static OTP Code
+
+When using Test Accounts, a static OTP verification code is generated and displayed in your project dashboard. This code remains constant for both email and phone number test accounts.
+
+## Usage in Development
+
+### Email + OTP Flow
+
+1. Enter a test email (e.g., `test_account_XXXX@example.com`)
+2. Click "Send Code" or equivalent button
+3. Enter the static OTP: `XXXXXX`
+4. Complete the authentication flow
+
+### SMS + OTP Flow
+
+1. Enter a test phone number (e.g., `+1 (555) XXX-XXXX`)
+2. Click "Send Code" or equivalent button
+3. Enter the static OTP: `XXXXXX`
+4. Complete the authentication flow
+
+## Benefits for Development
+
+### Consistent Testing Experience
+
+- **Predictable Credentials**: Same OTP code (`XXXXXX`) works every time
+- **No External Dependencies**: No need to access email or SMS during testing
+- **Faster Iteration**: Streamlined testing without waiting for delivery of verification codes
+
+### Team Collaboration
+
+- **Shared Test Accounts**: Team members can use the same test credentials
+- **Standardized Testing**: Consistent testing experience across the development team
+- **Demo-Friendly**: Reliable for demonstrations and presentations
+
+### CI/CD Integration
+
+- **Automated Testing**: Enables automated tests that require authentication flows
+- **E2E Testing**: Facilitates end-to-end testing scenarios
+- **Staging Validation**: Supports testing in staging environments
+
+## Security Considerations
+
+### Best Practices
+
+- **Never use Test Accounts in production** - they are designed for testing only and could expose your application to security vulnerabilities if used in production
+- **Disable before going live** - ensure Test Accounts are turned off before production deployment
+- **Use separate projects** - maintain separate projects for development and production environments
+- **Document test credentials** - clearly document which credentials are for testing only
+
+### Troubleshooting
+
+If Test Accounts are not functioning as expected:
+
+1. **Verify Environment**: Ensure you're using your particular Sapphire Devnet or Sapphire Mainnet environment where test accounts are enabled.
+2. **Check Project Settings**: Confirm Test Accounts are enabled in Project Settings > Advanced
+3. **Email or Phone**: Ensure test email or phone number is correct as mentioned in the dashboard, you can refresh the credentials by clicking on the refresh button.
+4. **OTP Code**: Always use `XXXXXX` as the verification code as mentioned in the dashboard
diff --git a/embedded-wallets/dashboard/advanced/user-details.mdx b/embedded-wallets/dashboard/advanced/user-details.mdx
new file mode 100644
index 00000000000..96d623fb97a
--- /dev/null
+++ b/embedded-wallets/dashboard/advanced/user-details.mdx
@@ -0,0 +1,618 @@
+---
+title: User Details in ID Token
+sidebar_label: User Details
+image: 'img/metamaskog.jpg'
+description: 'Configure user data in JWT identity tokens | Embedded Wallets'
+---
+
+import ProjectSettingsAdvanced from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png'
+
+The **User Details in ID Token** setting determines whether Personally Identifiable Information (PII)—such as the user's email, profile picture, and name—is returned in the JWT identity token issued by Web3Auth. This configuration allows you to control the level of user information available directly within the authentication token.
+
+
+

+
+
+## User Data Overview
+
+JWT identity tokens can include various types of user information, ranging from minimal identifiers to comprehensive profile data. The configuration of this setting impacts both functionality and privacy considerations for your application.
+
+### Available User Data Types
+
+**Basic Identifier Information:**
+
+- User ID (always included)
+- Wallet address (always included)
+- Authentication timestamp (always included)
+
+**Optional Profile Information:**
+
+- Email address
+- Full name
+- Profile picture URL
+- Social login provider data
+- Custom user metadata
+
+## Configuration Options
+
+### Enable User Data in Tokens
+
+When **enabled**, the identity token includes comprehensive user profile information:
+
+```json
+{
+ "iss": "https://api.web3auth.io",
+ "sub": "user_unique_identifier",
+ "aud": "your_client_id",
+ "exp": 1640995200,
+ "iat": 1640908800,
+ "email": "user@example.com",
+ "name": "John Doe",
+ "picture": "https://profile-pics.com/user.jpg",
+ "provider": "google",
+ "wallet_address": "0x1234567890abcdef...",
+ "custom_data": {
+ "user_tier": "premium",
+ "registration_date": "2023-01-15"
+ }
+}
+```
+
+### Disable User Data in Tokens
+
+When **disabled**, the identity token contains only essential identification information:
+
+```json
+{
+ "iss": "https://api.web3auth.io",
+ "sub": "user_unique_identifier",
+ "aud": "your_client_id",
+ "exp": 1640995200,
+ "iat": 1640908800,
+ "wallet_address": "0x1234567890abcdef..."
+}
+```
+
+### Email-Only Mode
+
+When **userIdentifier is set to email**, only the user's email is included in the token:
+
+```json
+{
+ "iss": "https://api.web3auth.io",
+ "sub": "user_unique_identifier",
+ "aud": "your_client_id",
+ "exp": 1640995200,
+ "iat": 1640908800,
+ "email": "user@example.com",
+ "wallet_address": "0x1234567890abcdef..."
+}
+```
+
+## Implementation Patterns
+
+### Token Parsing and Validation
+
+**Complete Token Processing:**
+
+```javascript
+import jwt from 'jsonwebtoken'
+
+async function processUserToken(idToken) {
+ try {
+ // Verify and decode the token
+ const decoded = jwt.verify(idToken, publicKey, {
+ issuer: 'https://api.web3auth.io',
+ audience: 'your_client_id',
+ })
+
+ // Extract user information
+ const userProfile = {
+ id: decoded.sub,
+ walletAddress: decoded.wallet_address,
+ email: decoded.email || null,
+ name: decoded.name || null,
+ picture: decoded.picture || null,
+ provider: decoded.provider || null,
+ customData: decoded.custom_data || {},
+ }
+
+ return userProfile
+ } catch (error) {
+ console.error('Token validation failed:', error)
+ throw new Error('Invalid user token')
+ }
+}
+```
+
+**Conditional Data Handling:**
+
+```javascript
+function extractUserData(decodedToken) {
+ const baseData = {
+ userId: decodedToken.sub,
+ walletAddress: decodedToken.wallet_address,
+ issuedAt: new Date(decodedToken.iat * 1000),
+ expiresAt: new Date(decodedToken.exp * 1000),
+ }
+
+ // Handle optional profile data
+ if (decodedToken.email) {
+ baseData.email = decodedToken.email
+ }
+
+ if (decodedToken.name) {
+ baseData.displayName = decodedToken.name
+ }
+
+ if (decodedToken.picture) {
+ baseData.profilePicture = decodedToken.picture
+ }
+
+ if (decodedToken.custom_data) {
+ baseData.metadata = decodedToken.custom_data
+ }
+
+ return baseData
+}
+```
+
+### Frontend Integration
+
+**React Implementation:**
+
+```jsx
+import { useEffect, useState } from 'react'
+import { Web3Auth } from '@web3auth/modal'
+
+function UserProfile() {
+ const [userInfo, setUserInfo] = useState(null)
+
+ useEffect(() => {
+ const loadUserData = async () => {
+ if (web3auth.status === 'connected') {
+ // Get ID token with user data
+ const idToken = await web3auth.authenticateUser()
+
+ // Parse user information from token
+ const userProfile = parseUserToken(idToken.idToken)
+ setUserInfo(userProfile)
+ }
+ }
+
+ loadUserData()
+ }, [])
+
+ if (!userInfo) {
+ return Loading user profile...
+ }
+
+ return (
+
+ {userInfo.picture &&

}
+ {userInfo.name &&
{userInfo.name}
}
+ {userInfo.email &&
Email: {userInfo.email}
}
+
Wallet: {userInfo.walletAddress}
+
+ )
+}
+```
+
+**Vue Implementation:**
+
+```vue
+
+
+
![Profile]()
+
{{ userInfo.name }}
+
Email: {{ userInfo.email }}
+
Wallet: {{ userInfo.walletAddress }}
+
+
+
+
+```
+
+## Use Cases and Benefits
+
+### Streamlined User Onboarding
+
+**Profile Pre-population:**
+
+```javascript
+async function setupUserAccount(idToken) {
+ const userProfile = parseUserToken(idToken)
+
+ // Pre-populate user profile from token data
+ const accountData = {
+ email: userProfile.email,
+ displayName: userProfile.name,
+ avatarUrl: userProfile.picture,
+ authProvider: userProfile.provider,
+ walletAddress: userProfile.walletAddress,
+ }
+
+ // Create user account with pre-filled information
+ await createUserAccount(accountData)
+
+ // Skip additional profile setup steps
+ redirectToMainApplication()
+}
+```
+
+### Personalized User Experience
+
+**Dynamic UI Customization:**
+
+```javascript
+function personalizeInterface(userProfile) {
+ // Customize greeting based on available name
+ const greeting = userProfile.name ? `Welcome back, ${userProfile.name}!` : `Welcome back!`
+
+ // Update profile avatar
+ if (userProfile.picture) {
+ updateUserAvatar(userProfile.picture)
+ }
+
+ // Apply user-specific settings
+ if (userProfile.customData?.theme) {
+ applyUserTheme(userProfile.customData.theme)
+ }
+
+ // Show personalized content
+ displayPersonalizedContent(userProfile)
+}
+```
+
+### Session Management
+
+**Enhanced Session Context:**
+
+```javascript
+class SessionManager {
+ constructor(idToken) {
+ this.userProfile = parseUserToken(idToken)
+ this.sessionData = this.initializeSession()
+ }
+
+ initializeSession() {
+ return {
+ userId: this.userProfile.id,
+ email: this.userProfile.email,
+ displayName: this.userProfile.name,
+ walletAddress: this.userProfile.walletAddress,
+ loginProvider: this.userProfile.provider,
+ sessionStart: new Date(),
+ lastActivity: new Date(),
+ }
+ }
+
+ updateActivity() {
+ this.sessionData.lastActivity = new Date()
+
+ // Log activity with user context
+ this.logUserActivity({
+ userId: this.sessionData.userId,
+ email: this.sessionData.email,
+ action: 'page_view',
+ timestamp: new Date(),
+ })
+ }
+}
+```
+
+## Privacy and Compliance Considerations
+
+### Data Minimization Principles
+
+**GDPR Compliance:**
+
+- Only include necessary user data in tokens
+- Obtain explicit consent for PII inclusion
+- Provide clear privacy notices
+- Enable data portability and deletion
+
+**Implementation Example:**
+
+```javascript
+class PrivacyCompliantTokenHandler {
+ constructor(privacySettings) {
+ this.allowedFields = privacySettings.allowedTokenFields
+ this.userConsent = privacySettings.userConsent
+ }
+
+ processUserToken(rawToken) {
+ const decodedToken = jwt.decode(rawToken)
+ const filteredData = {}
+
+ // Only include fields user consented to
+ this.allowedFields.forEach(field => {
+ if (decodedToken[field] && this.userConsent[field]) {
+ filteredData[field] = decodedToken[field]
+ }
+ })
+
+ return filteredData
+ }
+}
+```
+
+### Regional Compliance
+
+**Multi-Jurisdictional Considerations:**
+
+```javascript
+function getRegionSpecificTokenHandling(userRegion) {
+ const regionPolicies = {
+ EU: {
+ requireExplicitConsent: true,
+ dataRetentionDays: 90,
+ allowProfilePictures: false,
+ requireDataProcessingNotice: true,
+ },
+ US: {
+ requireExplicitConsent: false,
+ dataRetentionDays: 365,
+ allowProfilePictures: true,
+ requireDataProcessingNotice: false,
+ },
+ APAC: {
+ requireExplicitConsent: true,
+ dataRetentionDays: 180,
+ allowProfilePictures: true,
+ requireDataProcessingNotice: true,
+ },
+ }
+
+ return regionPolicies[userRegion] || regionPolicies['EU'] // Default to strictest
+}
+```
+
+## Security Considerations
+
+### Token Security Best Practices
+
+**Secure Token Handling:**
+
+```javascript
+class SecureTokenProcessor {
+ constructor() {
+ this.tokenCache = new Map()
+ this.encryptionKey = process.env.TOKEN_ENCRYPTION_KEY
+ }
+
+ async processToken(idToken) {
+ // Validate token signature
+ const isValid = await this.validateTokenSignature(idToken)
+ if (!isValid) {
+ throw new Error('Invalid token signature')
+ }
+
+ // Check for token replay attacks
+ if (this.isTokenReplayed(idToken)) {
+ throw new Error('Token replay detected')
+ }
+
+ // Extract and sanitize user data
+ const userData = this.extractUserData(idToken)
+ return this.sanitizeUserData(userData)
+ }
+
+ sanitizeUserData(userData) {
+ // Remove potentially dangerous content
+ const sanitized = { ...userData }
+
+ if (sanitized.name) {
+ sanitized.name = this.sanitizeString(sanitized.name)
+ }
+
+ if (sanitized.email) {
+ sanitized.email = this.validateEmail(sanitized.email)
+ }
+
+ if (sanitized.picture) {
+ sanitized.picture = this.validateImageUrl(sanitized.picture)
+ }
+
+ return sanitized
+ }
+}
+```
+
+### Data Validation
+
+**Input Validation and Sanitization:**
+
+```javascript
+function validateUserData(userData) {
+ const validators = {
+ email: email => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email),
+ name: name => name.length <= 100 && !/[<>]/.test(name),
+ picture: url => {
+ try {
+ const parsed = new URL(url)
+ return ['https:'].includes(parsed.protocol)
+ } catch {
+ return false
+ }
+ },
+ }
+
+ const validatedData = {}
+
+ Object.keys(userData).forEach(key => {
+ if (validators[key]) {
+ if (validators[key](userData[key])) {
+ validatedData[key] = userData[key]
+ } else {
+ console.warn(`Invalid ${key} data:`, userData[key])
+ }
+ } else {
+ validatedData[key] = userData[key]
+ }
+ })
+
+ return validatedData
+}
+```
+
+## Performance Considerations
+
+### Token Size Management
+
+**Optimizing Token Size:**
+
+- Include only necessary user fields
+- Avoid large profile pictures (use URLs instead)
+- Limit custom metadata size
+- Consider token size impact on network performance
+
+**Token Size Monitoring:**
+
+```javascript
+function analyzeTokenSize(idToken) {
+ const tokenSize = new Blob([idToken]).size
+ const decoded = jwt.decode(idToken)
+
+ const analysis = {
+ totalSize: tokenSize,
+ headerSize: JSON.stringify(decoded.header).length,
+ payloadSize: JSON.stringify(decoded.payload).length,
+ signatureSize: idToken.split('.')[2].length,
+ userDataSize: JSON.stringify({
+ email: decoded.email,
+ name: decoded.name,
+ picture: decoded.picture,
+ custom_data: decoded.custom_data,
+ }).length,
+ }
+
+ // Log warning for large tokens
+ if (tokenSize > 8192) {
+ // 8KB threshold
+ console.warn('Large JWT token detected:', analysis)
+ }
+
+ return analysis
+}
+```
+
+### Caching Strategies
+
+**Efficient User Data Caching:**
+
+```javascript
+class UserDataCache {
+ constructor() {
+ this.cache = new Map()
+ this.ttl = 5 * 60 * 1000 // 5 minutes
+ }
+
+ getUserData(userId, idToken) {
+ const cached = this.cache.get(userId)
+
+ if (cached && Date.now() - cached.timestamp < this.ttl) {
+ return cached.data
+ }
+
+ // Parse fresh token data
+ const userData = parseUserToken(idToken)
+
+ // Cache with timestamp
+ this.cache.set(userId, {
+ data: userData,
+ timestamp: Date.now(),
+ })
+
+ return userData
+ }
+
+ invalidateUser(userId) {
+ this.cache.delete(userId)
+ }
+
+ clearExpired() {
+ const now = Date.now()
+ for (const [userId, cached] of this.cache.entries()) {
+ if (now - cached.timestamp >= this.ttl) {
+ this.cache.delete(userId)
+ }
+ }
+ }
+}
+```
+
+## Decision Framework
+
+### When to Enable User Data in Tokens
+
+**Recommended for:**
+
+- Applications requiring immediate user context
+- Single-page applications with limited backend calls
+- Personalization-heavy interfaces
+- Offline-capable applications
+
+**Consider enabling when:**
+
+- User onboarding needs profile pre-population
+- UI personalization improves user experience
+- Session management benefits from user context
+- Reduced API calls for user data improve performance
+
+### When to Disable User Data in Tokens
+
+**Recommended for:**
+
+- High-security applications
+- Compliance-heavy environments
+- Applications with separate user management systems
+- Minimal data exposure requirements
+
+**Consider disabling when:**
+
+- Privacy regulations are strict
+- Token size is a concern
+- User data is managed separately
+- Security requirements prefer minimal token content
+
+### Email-Only Configuration
+
+**Optimal for:**
+
+- Applications needing user identification only
+- Email-based user management systems
+- Privacy-focused applications
+- Minimal PII exposure scenarios
+
+## Next Steps
+
+- **[Session Management](./session-management)** - Configure session duration and behavior
+- **[Key Export Settings](./key-export)** - Control private key export permissions
+- **[Project Settings](../project-settings)** - Configure basic project information
diff --git a/embedded-wallets/dashboard/project-settings.mdx b/embedded-wallets/dashboard/project-settings.mdx
index a7843930ea2..760cdf29305 100644
--- a/embedded-wallets/dashboard/project-settings.mdx
+++ b/embedded-wallets/dashboard/project-settings.mdx
@@ -6,13 +6,9 @@ description: 'Configure project settings in Web3Auth Dashboard | Embedded Wallet
---
import ProjectSettingsGeneral from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-general.png'
-import ProjectSettingsDomain from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-domain.png'
-import ProjectSettingsAdvanced from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png'
The **Project Settings** section of the Web3Auth Dashboard allows developers to manage core configuration options for each project. These settings determine how the project integrates with the Web3Auth SDK and how it behaves across different environments.
-## General
-
-The **General tab** provides an overview of key project-specific parameters:
+## Project Information
-- **Project Name**: This is the name of the project that will be displayed to users during the Web3Auth login flow and in any related email communication. The name can be updated post-creation at any time.
-- **Environment**: This indicates the Web3Auth environment (devnet or mainnet) selected during project creation. These environments are globally distributed and highly scalable. Once set, the environment cannot be modified.
-- **Client ID**: A unique identifier automatically generated for each project. This value is required for SDK integration and is safe to expose publicly.
-- **Client Secret**: A confidential key used for authenticating server-side API requests. It should never be exposed to the frontend or any client-side environment to maintain security.
-- **JWKS Endpoint**: A public endpoint that exposes the JSON Web Key Set (JWKS) used by Web3Auth to sign JWTs. Developers can use this endpoint to verify identity tokens. [Learn more](#).
-- **Project Verification Key**: An alternative to using the JWKS endpoint. This static key allows for token verification without depending on the JWKS URL. [Learn more](#).
-- **Project Platform**: Developers can select from a wide range of platform options such as Web, Mobile, or Gaming, depending on the nature of the application.
+### Project Name
-### Archive Project
+This is the name of the project that will be displayed to users during the Web3Auth login flow and in any related email communication. The project name serves as your application's identity in the Web3Auth ecosystem.
-The Archive Project button allows developers to archive a project. Once archived, the project becomes read-only and cannot be modified unless explicitly restored.
+**Key Features:**
-## Whitelist Domains
+- **User-Facing Display**: Appears in login modals and authentication flows
+- **Email Communications**: Used in Web3Auth-generated emails to users
+- **Dashboard Identification**: Helps you identify projects in your dashboard
+- **Updateable**: Can be modified at any time after project creation
-To enhance security, Web3Auth enables domain whitelisting for both web and mobile applications.
+**Best Practices:**
-- Domain Authorization Developers must add and verify URLs that are authorized to use the Web3Auth SDK.
+- Use a clear, recognizable name that matches your application
+- Keep it concise but descriptive
+- Avoid special characters that might cause display issues
+- Consider how it will appear to end users
- > For mainnet projects, at least one domain or URL must be whitelisted before the SDK can be used in production.
+### Environment
- {" "}
+This indicates the Web3Auth environment selected during project creation. The environment determines the infrastructure tier and security level of your project.
-
-

-
+**Available Environments:**
-## Advanced
+- **Sapphire Devnet**: Development environment for testing and integration
+- **Sapphire Mainnet**: Production environment for live applications
-The Advanced tab provides developers with additional configuration options to fine-tune authentication behavior, session control, and data privacy.
+**Important Notes:**
-
-

-
+- Environments are globally distributed and highly scalable
+- **Cannot be modified** after project creation
+- Each environment has separate user bases and data isolation
+- Production applications should use Sapphire Mainnet
+
+### Project Platform
+
+Developers can select from a wide range of platform options depending on the nature of their application. This setting helps optimize the SDK behavior and available features for your specific platform.
-### Session Duration
+**Platform Options:**
-Web3Auth allows customization of session lifetime:
+- **Web**: Browser-based applications (React, Vue, JavaScript)
+- **Mobile**: Native mobile applications (Android, iOS, React Native, Flutter)
+- **Gaming**: Game development platforms (Unity, Unreal Engine)
-- Developers can configure how long a user session remains active before requiring re-authentication.
-- The default session duration is 1 day.
-- Minimum configurable duration is 1 second, while the maximum is 30 days.
+**Platform-Specific Features:**
-This setting is particularly useful for balancing security and user experience. Shorter durations increase security by reducing exposure, while longer durations improve usability for trusted applications.
+- Different SDK packages and integration methods
+- Platform-optimized authentication flows
+- Tailored documentation and examples
+- Specific security considerations
-### Return User Data in Identity Token
+## Authentication Credentials
-This option determines whether Personally Identifiable Information (PII)—such as the user's email, profile picture, and name—is returned in the JWT identity token issued by Web3Auth.
+### Client ID
+
+A unique identifier automatically generated for each project. This is the primary credential used to authenticate your application with Web3Auth services.
+
+**Characteristics:**
+
+- **Publicly Safe**: Can be exposed in client-side code
+- **Required for Integration**: Essential for all SDK implementations
+- **Unique per Project**: Each project receives a distinct Client ID
+- **Immutable**: Cannot be changed after generation
+
+**Usage Example:**
+
+```javascript
+import { Web3Auth } from '@web3auth/modal'
+
+const web3auth = new Web3Auth({
+ clientId: 'YOUR_CLIENT_ID_HERE', // Safe to expose publicly
+ web3AuthNetwork: 'sapphire_mainnet',
+})
+```
-- Enabling this setting allows applications to access additional user metadata directly from the identity token.
-- If userIdentifier is set to email, only the user's email will be returned in the token. This provides a privacy-centric approach to user identity management.
+### Client Secret
-> Why this matters: Including user PII in the JWT can streamline user onboarding, personalization, and session management in your application. However, developers must consider user consent, data minimization, and jurisdictional privacy regulations (such as GDPR or CCPA) before enabling this option. Only request what is essential for your application's functionality.
+A confidential key used for authenticating server-side API requests and advanced integrations. This credential provides elevated access to Web3Auth services.
-### Enable Key Export
+**Security Requirements:**
-This setting allows developers to control whether users can programmatically export their private keys using the Web3Auth SDK.
+- **Never expose** in frontend code or client-side environments
+- **Server-side only**: Use exclusively in backend services
+- **Secure storage**: Store in environment variables or secure vaults
+- **Rotation capability**: Can be regenerated if compromised
-- When enabled, the application can allow users to retrieve their private key. For this, the dApp must use the `eth_private_key` JSON-RPC method.
-- When disabled, users will only be able to export their keys manually via Web3Auth's built-in wallet interface.
+**Use Cases:**
-This functionality is crucial for advanced use cases such as migration, backup, or interoperability with non-EVM-compatible blockchains.
+- Server-side user verification
+- Administrative operations
+- Webhook signature verification
+- Advanced API integrations
-> Example: Programmatically retrieving the private key after login:
+:::danger Security Warning
+
+The Client Secret must never be exposed in client-side code, mobile applications, or any publicly accessible environment. Exposure could compromise your project's security.
+
+:::
+
+## Token Verification
+
+### JWKS Endpoint
+
+A public endpoint that exposes the JSON Web Key Set (JWKS) used by Web3Auth to sign JWTs. This endpoint enables you to verify the authenticity of identity tokens issued by Web3Auth.
+
+**Endpoint Format:**
+
+```
+https://api.web3auth.io/jwks?project_id=YOUR_PROJECT_ID
+```
+
+**Benefits:**
+
+- **Dynamic Key Rotation**: Automatically receives updated signing keys
+- **Industry Standard**: JWKS is a widely adopted standard for JWT verification
+- **High Availability**: Backed by Web3Auth's global infrastructure
+- **Real-time Updates**: Always provides current verification keys
+
+**Implementation Example:**
```javascript
-// Assuming user is already logged in
-async function getPrivateKey() {
- const privateKey = await web3auth.provider.request({
- method: 'eth_private_key',
+import jwt from 'jsonwebtoken'
+import jwksClient from 'jwks-rsa'
+
+const client = jwksClient({
+ jwksUri: 'https://api.web3auth.io/jwks?project_id=YOUR_PROJECT_ID',
+})
+
+function getKey(header, callback) {
+ client.getSigningKey(header.kid, (err, key) => {
+ const signingKey = key.publicKey || key.rsaPublicKey
+ callback(null, signingKey)
})
}
+
+// Verify token
+jwt.verify(token, getKey, options, (err, decoded) => {
+ if (err) {
+ console.error('Token verification failed:', err)
+ } else {
+ console.log('Token verified:', decoded)
+ }
+})
```
+
+### Project Verification Key
+
+An alternative to using the JWKS endpoint, this static key allows for token verification without depending on external JWKS URL calls.
+
+**Advantages:**
+
+- **Offline Verification**: No external API calls required
+- **Reduced Latency**: Faster token verification process
+- **Network Independence**: Works in environments with limited connectivity
+- **Simplified Implementation**: Single key verification logic
+
+**When to Use:**
+
+- Applications with strict latency requirements
+- Environments with limited internet access
+- Simplified verification workflows
+- Backup verification method
+
+**Implementation Example:**
+
+```javascript
+import jwt from 'jsonwebtoken'
+
+const PROJECT_VERIFICATION_KEY = `-----BEGIN PUBLIC KEY-----
+YOUR_PROJECT_VERIFICATION_KEY_HERE
+-----END PUBLIC KEY-----`
+
+// Verify token with static key
+jwt.verify(token, PROJECT_VERIFICATION_KEY, { algorithms: ['RS256'] }, (err, decoded) => {
+ if (err) {
+ console.error('Token verification failed:', err)
+ } else {
+ console.log('Token verified:', decoded)
+ }
+})
+```
+
+## Project Management
+
+### Archive Project
+
+The Archive Project feature allows you to deactivate a project while preserving its configuration and data. This is useful for temporarily disabling projects or maintaining historical records.
+
+**Archive Effects:**
+
+- **Read-Only Mode**: Project becomes non-functional but viewable
+- **Authentication Disabled**: Users cannot log in to archived projects
+- **Data Preservation**: All configuration and user data is retained
+- **Reversible**: Projects can be restored from archived state
+
+**When to Archive:**
+
+- Temporary project suspension
+- End-of-life applications
+- Testing environment cleanup
+- Compliance requirements
+
+**Restoration Process:**
+
+- Archived projects can be restored through the dashboard
+- All settings and configurations are preserved
+- User data and authentication flows resume normally
+- No data loss occurs during archive/restore cycles
+
+:::info Archive vs Delete
+
+Archiving preserves all project data and allows for restoration. If you need to permanently remove a project, contact Web3Auth support for assistance with proper data deletion procedures.
+
+:::
+
+## Next Steps
+
+For comprehensive project configuration, explore these related settings:
+
+- **[Whitelist Settings](./whitelist)** - Configure domain and URL authorization for enhanced security
+- **[Advanced Project Settings](./advanced/session-management)** - Access session management, key export, user data, and testing configurations
+
+### Quick Start Guide
+
+**Essential Configuration Steps:**
+
+1. Set up your project name and verify environment
+2. Obtain your Client ID for SDK integration
+3. Configure domain whitelisting for security
+4. Set up token verification method
+5. Review advanced settings as needed
+
+### Production Deployment Checklist
+
+- ✅ All production domains whitelisted
+- ✅ Token verification configured
+- ✅ Advanced settings reviewed
+- ✅ Test accounts disabled
+- ✅ Security settings verified
diff --git a/embedded-wallets/dashboard/whitelist.mdx b/embedded-wallets/dashboard/whitelist.mdx
new file mode 100644
index 00000000000..3b8f718db37
--- /dev/null
+++ b/embedded-wallets/dashboard/whitelist.mdx
@@ -0,0 +1,307 @@
+---
+title: Whitelist Settings
+sidebar_label: Whitelist
+image: 'img/metamaskog.jpg'
+description: 'Configure domain whitelisting in Web3Auth Dashboard | Embedded Wallets'
+---
+
+import ProjectSettingsDomain from '@site/static/img/embedded-wallets/w3a-dashboard/project-settings-domain.png'
+
+The **Whitelist Settings** section allows you to configure domain and URL authorization for enhanced security. Web3Auth requires explicit whitelisting of domains and URLs that are authorized to use your project's Web3Auth SDK, providing protection against unauthorized usage and potential security threats.
+
+
+

+
+
+## Domain Authorization Overview
+
+Domain whitelisting is a critical security feature that prevents unauthorized applications from using your Web3Auth project credentials. Only domains and URLs explicitly added to your whitelist can successfully authenticate users through your Web3Auth configuration.
+
+### Security Benefits
+
+- **Prevents Credential Theft**: Unauthorized sites cannot use your Client ID
+- **Protects User Data**: Ensures authentication flows only occur on approved domains
+- **Compliance Ready**: Meets security standards for production applications
+- **Fraud Prevention**: Blocks malicious sites from impersonating your application
+
+## Web Application Whitelisting
+
+### Supported URL Formats
+
+Web3Auth supports various URL formats for comprehensive domain coverage:
+
+**Standard Domains:**
+
+```
+https://myapp.com
+https://www.myapp.com
+https://app.mycompany.com
+```
+
+**Development Environments:**
+
+```
+http://localhost:3000
+http://localhost:8080
+https://dev.myapp.com
+https://staging.myapp.com
+```
+
+**Subdomain Patterns:**
+
+```
+https://*.myapp.com (covers all subdomains)
+https://feature-*.myapp.com (wildcard patterns)
+```
+
+**Port-Specific URLs:**
+
+```
+https://myapp.com:8443
+http://localhost:3000
+http://127.0.0.1:8080
+```
+
+### Adding Web Domains
+
+1. **Navigate to Project Settings** → **Whitelist**
+2. **Click "Add Domain"** or similar button
+3. **Enter the complete URL** including protocol (http:// or https://)
+4. **Verify the domain** if required
+5. **Save the configuration**
+
+**Best Practices:**
+
+- Always use HTTPS for production domains
+- Include all necessary subdomains
+- Add development and staging environments
+- Test authentication after adding domains
+
+## Mobile Application Whitelisting
+
+### Bundle Identifiers
+
+For mobile applications, whitelist the app's bundle identifier or package name:
+
+**iOS Bundle IDs:**
+
+```
+com.yourcompany.yourapp
+com.yourcompany.yourapp.staging
+```
+
+**Android Package Names:**
+
+```
+com.yourcompany.yourapp
+com.yourcompany.yourapp.debug
+```
+
+### Deep Link Schemes
+
+Mobile applications using deep links should whitelist their custom URL schemes:
+
+**Custom Schemes:**
+
+```
+yourapp://auth
+com.yourcompany.yourapp://callback
+```
+
+**Universal Links (iOS):**
+
+```
+https://yourapp.com/auth/callback
+```
+
+**App Links (Android):**
+
+```
+https://yourapp.com/auth/callback
+```
+
+## Environment-Specific Configuration
+
+### Development Environment
+
+For development and testing:
+
+```
+http://localhost:3000
+http://localhost:8080
+http://127.0.0.1:3000
+https://dev.yourapp.com
+https://staging.yourapp.com
+```
+
+**Development Tips:**
+
+- Whitelist common development ports
+- Include both localhost and 127.0.0.1
+- Add staging and testing environments
+- Use HTTP for local development (HTTPS for staging)
+
+### Production Environment
+
+:::warning Production Requirements
+
+For Sapphire Mainnet projects, **at least one domain must be whitelisted** before the SDK can be used in production. This is a mandatory security requirement.
+
+:::
+
+**Production Checklist:**
+
+- ✅ All production domains whitelisted
+- ✅ HTTPS enforced for all domains
+- ✅ Subdomain coverage complete
+- ✅ Mobile bundle IDs added
+- ✅ Deep link schemes configured
+- ✅ Remove development URLs
+
+## Wildcard Domains
+
+### Subdomain Wildcards
+
+Use wildcard patterns to cover multiple subdomains efficiently:
+
+**Single-level wildcard:**
+
+```
+https://*.myapp.com
+```
+
+Covers: `https://api.myapp.com`, `https://admin.myapp.com`, `https://user.myapp.com`
+
+**Multi-level wildcards:**
+
+```
+https://*.*.myapp.com
+```
+
+Covers: `https://api.v1.myapp.com`, `https://admin.staging.myapp.com`
+
+### Dynamic Subdomains
+
+For applications with dynamic subdomains (multi-tenant apps):
+
+```
+https://*.myapp.com
+https://tenant-*.myapp.com
+https://*.saas.myapp.com
+```
+
+## Verification Process
+
+### Domain Verification
+
+Some domains may require verification to ensure ownership:
+
+1. **DNS Verification**: Add a TXT record to your domain's DNS
+2. **File Upload**: Upload a verification file to your web server
+3. **HTML Meta Tag**: Add a meta tag to your website's homepage
+
+### Verification Status
+
+Monitor the verification status in your dashboard:
+
+- ✅ **Verified**: Domain is confirmed and active
+- ⏳ **Pending**: Verification in progress
+- ❌ **Failed**: Verification unsuccessful, requires attention
+
+## Common Issues and Solutions
+
+### Authentication Failures
+
+**Problem**: Users cannot authenticate on your domain
+**Solutions:**
+
+- Verify the domain is in your whitelist
+- Check for typos in the domain name
+- Ensure protocol (http/https) matches exactly
+- Confirm subdomain patterns are correct
+
+### Development Environment Issues
+
+**Problem**: Local development not working
+**Solutions:**
+
+- Add `http://localhost:PORT` to whitelist
+- Include `http://127.0.0.1:PORT` as alternative
+- Check if your development server uses a different port
+- Verify protocol matches (http vs https)
+
+### Mobile App Issues
+
+**Problem**: Mobile authentication failing
+**Solutions:**
+
+- Verify bundle ID matches exactly
+- Check deep link scheme configuration
+- Ensure URL schemes are properly whitelisted
+- Test with both debug and release builds
+
+## Security Best Practices
+
+### Regular Audits
+
+- **Monthly Reviews**: Check whitelist for unused domains
+- **Remove Stale Entries**: Delete old development or staging URLs
+- **Monitor Access**: Review authentication patterns for anomalies
+- **Update Documentation**: Keep domain lists current for your team
+
+### Principle of Least Privilege
+
+- **Minimal Domains**: Only whitelist necessary domains
+- **Specific Patterns**: Avoid overly broad wildcard patterns
+- **Environment Separation**: Use different projects for dev/staging/prod
+- **Regular Cleanup**: Remove domains when no longer needed
+
+### Compliance Considerations
+
+- **Data Residency**: Consider where authentication occurs
+- **Privacy Regulations**: Ensure whitelisted domains comply with privacy laws
+- **Security Standards**: Meet industry requirements for domain authorization
+- **Audit Trails**: Maintain records of domain modifications
+
+## Advanced Configuration
+
+### CDN and Load Balancer Support
+
+For applications using CDNs or load balancers:
+
+```
+https://cdn.myapp.com
+https://lb.myapp.com
+https://edge-*.myapp.com
+```
+
+### Multi-Region Deployments
+
+For global applications with regional domains:
+
+```
+https://us.myapp.com
+https://eu.myapp.com
+https://asia.myapp.com
+https://*.global.myapp.com
+```
+
+### API Gateway Integration
+
+For applications behind API gateways:
+
+```
+https://api.myapp.com
+https://gateway.myapp.com
+https://*.api.myapp.com
+```
+
+## Next Steps
+
+- **[Project Settings](./project-settings)** - Configure basic project information
+- **[Advanced Project Settings](./advanced/session-management)** - Access advanced configuration options
+- **[Session Management](./advanced/session-management)** - Control session duration and behavior
diff --git a/ew-sidebar.js b/ew-sidebar.js
index 30eabd456e2..e724be4c3e7 100644
--- a/ew-sidebar.js
+++ b/ew-sidebar.js
@@ -137,6 +137,19 @@ const sidebar = {
label: "Configuration",
items: [
"dashboard/project-settings",
+ "dashboard/whitelist",
+ {
+ type: "category",
+ label: "Advanced Settings",
+ collapsible: true,
+ collapsed: false,
+ items: [
+ "dashboard/advanced/session-management",
+ "dashboard/advanced/test-accounts",
+ "dashboard/advanced/user-details",
+ "dashboard/advanced/key-export",
+ ],
+ },
"dashboard/chains-and-networks",
"dashboard/authentication",
"dashboard/wallet-services",
diff --git a/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png b/static/img/embedded-wallets/w3a-dashboard/project-settings-advanced.png
index a38269bdbe97c8c3315c3d678d4704a6e93cb7c0..d37087663ec8e3d7e8da7b63420e8190540ab5a4 100644
GIT binary patch
literal 434613
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μkL=M(+!)cb-)|`ib
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