Official Demo
Application Data Handshake

Application Data Handshake

Complete analysis of the application data format from tela_tests/app1 - the verified handshake pattern.

Verified Format: This is the exact application data structure from app1 that successfully connects to Engram and CLI wallets.

Application Data Format

// From tela_tests/app1 - VERIFIED FORMAT (EXACT from main.js line 5-10)
const applicationData = {
    "id": "71605a32e3b0c44298fc1c549afbf4c8496fb92427ae41e4649b934ca495991b",  // 64-character hex string (static)
    "name": "TELA Demo Application",
    "description": "Basic WS connection parts for TELA application",
    "url": "http://localhost:" + location.port  // CRITICAL: Must include port!
};
⚠️

Critical ID Requirement: The id field must be exactly 64 hexadecimal characters (0-9, a-f). IDs that are shorter, longer, or contain invalid characters will cause "Invalid ID size" errors.

Field Requirements

id (Required)

  • Type: String
  • Format: Exactly 64 hexadecimal characters (0-9, a-f)
  • Example: "71605a32e3b0c44298fc1c549afbf4c8496fb92427ae41e4649b934ca495991b" (from app1)
  • Purpose: Application identifier for connection and permission management
  • Important: Use a static ID (generate once and store in localStorage). The wallet tracks permissions by ID, so reusing the same ID maintains permission continuity across sessions. This matches the app1 demo pattern.

name (Required)

  • Type: String
  • Purpose: Display name shown in wallet approval dialog
  • Example: "My TELA Application"

description (Required)

  • Type: String
  • Purpose: Explanation of what your app does
  • Example: "Connecting to wallet for DERO operations"

url (Required)

  • Type: String
  • Format: Must be full URL including port
  • ✅ CORRECT: "http://localhost:" + location.port
  • ❌ WRONG: window.location.origin (missing port)
  • Purpose: Origin verification for security

Complete Handshake Flow

// Step 1: Create application data
// Generate and store ID for reuse (matches app1 pattern - maintains permission continuity)
function getOrCreateAppId() {
    let appId = localStorage.getItem('xswd_app_id');
    if (!appId) {
        // Generate 64-character hex string
        appId = Array.from({length: 64}, () => 
            Math.floor(Math.random() * 16).toString(16)
        ).join('');
        localStorage.setItem('xswd_app_id', appId);
    }
    return appId;
}
 
const appData = {
    id: getOrCreateAppId(),  // Static ID - maintains permission continuity across connections
    name: "My TELA App",
    description: "App description",
    url: "http://localhost:" + location.port  // Include port!
};
 
// Step 2: Connect to WebSocket
socket = new WebSocket("ws://localhost:44326/xswd");
 
// Step 3: Send data immediately when connection opens
socket.onopen = function(event) {
    socket.send(JSON.stringify(appData));  // Immediate send!
};
 
// Step 4: Wait for wallet response
socket.onmessage = function(event) {
    const response = JSON.parse(event.data);
    
    if (response.accepted) {
        // ✅ Connection approved - can make API calls
        console.log("Connection accepted:", response.message);
    } else if (response.rejected) {
        // ❌ User denied or error
        console.error("Connection rejected:", response.message);
    }
};

Wallet Response Format

Accepted Response

{
  "accepted": true,
  "message": "Connection established"
}

Rejected Response

{
  "rejected": true,
  "message": "Connection rejected by user"
}

Common Mistakes

MistakeIssueFix
Variable-length or wrong-size ID"Invalid ID size" errorUse exactly 64 hexadecimal characters
Missing url fieldWallet rejects connectionAlways include url: "http://localhost:" + location.port
url without portConnection may failUse location.port not just origin
Delaying send()Connection closesSend immediately in onopen
Invalid JSONParse errorUse JSON.stringify()

Related Pages