Frontend Configuration

Below is an example of how to configure the QR code for on-chain verification using our SDK.

const selfApp = new SelfAppBuilder({
        appName: "Self Example App V2",
        scope: "Self-Example-App-V2",
        endpoint: "YOUR_DEPLOYED_CONTRACT_ADDRESS", // Your SelfVerificationRoot contract
        endpointType: "staging_celo", // "staging_celo" for testnet, "celo" for mainnet
        logoBase64: logo,
        userId: address, // User's wallet address (required)
        userIdType: "hex", // "uuid" or "hex"
        version: 2, // V2 configuration
        disclosures: { 
            // Passport data fields
            date_of_birth: true,
            nationality: true,
            name: true,
            issuing_state: true,
            passport_number: true, // Passport number field
            gender: true,
            expiry_date: true,
            
            // Verification rules (integrated in disclosures for V2)
            minimumAge: 18, // Age requirement (10-100)
            excludedCountries: [], // Array of 3-letter country codes (e.g., ["USA", "RUS"])
            ofac: true // OFAC compliance checking (boolean)
        },
        devMode: true, // Set to true for development/testing, false for production
        userDefinedData: "", // Optional: custom data passed to contract
}).build();

Configuration Parameters

Required Parameters:

  • appName: Name of your application

  • scope: Application identifier (max 31 ASCII characters)

  • endpoint: Your deployed SelfVerificationRoot contract address

  • userId: User's unique identifier (wallet address or UUID)

Optional Parameters:

  • endpointType: "celo" (mainnet) or "staging_celo" (testnet)

  • userIdType: "uuid" or "hex" (default: "uuid")

  • version: SDK version (default: 2 for V2)

  • logoBase64: Base64-encoded logo for the Self app

  • devMode: Development/testing mode flag - set to true during development, false for production (default: false)

  • disclosures: Identity attributes and verification rules

  • userDefinedData: Custom string data passed to your contract (default: "")

V2 Disclosures:

  • Passport data fields: name, nationality, date_of_birth, issuing_state, passport_number, gender, expiry_date

  • Verification rules: minimumAge, excludedCountries, ofac

Important: Your verification configuration in the SDK should match the configuration set in your contract.

Available Disclosures

disclosures: {
    // Passport data fields (boolean)
    name?: boolean,                 // Full name
    date_of_birth?: boolean,        // Date of birth
    nationality?: boolean,          // Nationality/citizenship
    gender?: boolean,               // Gender
    issuing_state?: boolean,        // Document issuing country
    passport_number?: boolean,      // Passport number
    expiry_date?: boolean,         // Document expiration date
    
    // Verification rules
    minimumAge?: number,           // Minimum age requirement (10-100)
    excludedCountries?: string[],  // Array of 3-letter country codes (max 40)
    ofac?: boolean,               // OFAC compliance checking
}

For detailed passport attribute usage, see Identity Attributes.

User Defined Data

The userDefinedData parameter allows you to pass arbitrary string data through the verification flow to your contract. This data is cryptographically included in the verification process and cannot be tampered with.

Common Use Cases:

  • Dynamic Configuration: Select different verification configs based on user context

  • Business Logic: Include application-specific data for custom verification logic

Data Flow:

  1. Frontend sets userDefinedData in SelfAppBuilder

  2. Data flows through mobile app and TEE processing

  3. Contract receives data in both getConfigId() and customVerificationHook() functions

Contract Access:

// In getConfigId - used for configuration selection
function getConfigId(
    bytes32 destinationChainId,
    bytes32 userIdentifier,
    bytes memory userDefinedData  // ← Your custom data here
) public view override returns (bytes32) {
    // Return your configuration ID
    return YOUR_CONFIG_ID;
}

// In customVerificationHook - userData contains full context including userDefinedData
function customVerificationHook(
    ISelfVerificationRoot.GenericDiscloseOutputV2 memory output,
    bytes memory userData  // ← First 64 bytes are destChainId+userIdentifier, rest is userDefinedData
) internal override {
    bytes memory userDefinedData = userData[64:];  // Extract custom data
    // Implement your business logic based on userDefinedData
}

Configuration Examples

Age Verification (21+):

const selfApp = new SelfAppBuilder({
    appName: "Age Verification App",
    scope: "Age-Verification-App",
    endpoint: "YOUR_CONTRACT_ADDRESS",
    userId: userAddress,
    endpointType: "staging_celo",
    disclosures: { 
        date_of_birth: true,
        minimumAge: 21
    }
}).build();

Geographic Restrictions:

const selfApp = new SelfAppBuilder({
    appName: "Geographic Restricted App",
    scope: "Geographic-App",
    endpoint: "YOUR_CONTRACT_ADDRESS", 
    userId: userAddress,
    disclosures: { 
        nationality: true, 
        issuing_state: true,
        excludedCountries: ["USA", "RUS", "CHN"]
    }
}).build();

OFAC Compliance:

const selfApp = new SelfAppBuilder({
    appName: "OFAC Compliant App",
    scope: "OFAC-App",
    endpoint: "YOUR_CONTRACT_ADDRESS",
    userId: userAddress,
    disclosures: { 
        name: true, 
        date_of_birth: true, 
        ofac: true
    }
}).build();

Development vs Production Setup:

// Development configuration
const devSelfApp = new SelfAppBuilder({
    appName: "My App (Dev)",
    scope: "My-App-Dev",
    endpoint: "YOUR_TESTNET_CONTRACT_ADDRESS",
    endpointType: "staging_celo", // Use testnet
    userId: userAddress,
    devMode: true, // Enable for development
    disclosures: { 
        name: true,
        minimumAge: 18
    }
}).build();

// Production configuration
const prodSelfApp = new SelfAppBuilder({
    appName: "My App",
    scope: "My-App",
    endpoint: "YOUR_MAINNET_CONTRACT_ADDRESS",
    endpointType: "celo", // Use mainnet
    userId: userAddress,
    devMode: false, // Disable for production
    disclosures: { 
        name: true,
        minimumAge: 18
    }
}).build();

Last updated