Official Demo
XSWD Connection Pattern

XSWD Connection Pattern

Complete analysis of the XSWD connection implementation from tela_tests/app1 - the verified working pattern.

Verified Pattern: This is the exact connection pattern from the official app1 demo that has been tested and proven to work with Engram and CLI wallets.

Complete Connection Code

// From tela_tests/app1 - VERIFIED WORKING PATTERN
let socket = null;
let isConnected = false;
 
function connect() {
    if (socket && socket.readyState === WebSocket.OPEN) {
        console.log('Already connected');
        return;
    }
    
    // ✅ CRITICAL: Use localhost (not 127.0.0.1) - matches app1 pattern
    socket = new WebSocket("ws://localhost:44326/xswd");
    
    socket.onopen = function(event) {
        console.log('✅ WebSocket opened');
        
        // ✅ CRITICAL: Send immediately after onopen - no delay!
        // ✅ CRITICAL: ID must be exactly 64 hexadecimal characters (static)
        const appData = {
            id: "71605a32e3b0c44298fc1c549afbf4c8496fb92427ae41e4649b934ca495991b",  // Static 64-char hex
            name: "Application Name",
            description: "Description",
            url: "http://localhost:" + location.port
        };
        
        socket.send(JSON.stringify(appData));
        console.log('📤 Sent application data');
    };
    
    socket.onmessage = function(event) {
        try {
            const response = JSON.parse(event.data);
            
            // ✅ CRITICAL: Check accepted FIRST before making API calls
            if (response.accepted) {
                console.log('✅ Connection accepted!');
                isConnected = true;
                // Now safe to make API calls
            } else if (response.rejected) {
                console.error('❌ Connection rejected');
                isConnected = false;
            } else if (response.jsonrpc && response.id) {
                // Handle RPC responses
                handleRPCResponse(response);
            }
        } catch (error) {
            console.error('Parse error:', error);
        }
    };
    
    socket.onerror = function(error) {
        console.error('🚨 WebSocket error:', error);
    };
    
    socket.onclose = function(event) {
        console.log('🔌 Connection closed:', event.code);
        isConnected = false;
        
        if (event.code === 1006) {
            console.error('❌ Wallet not running or XSWD disabled');
        }
    };
}

Critical Points

1. ✅ Use localhost (Not 127.0.0.1)

// ✅ CORRECT (matches app1)
socket = new WebSocket("ws://localhost:44326/xswd");
 
// ❌ WRONG (may work but doesn't match verified pattern)
socket = new WebSocket("ws://127.0.0.1:44326/xswd");

2. ✅ Send Application Data Immediately

socket.onopen = function(event) {
    // ✅ CORRECT: Send immediately, no delay
    socket.send(JSON.stringify(appData));
    
    // ❌ WRONG: Delaying causes connection to close
    setTimeout(() => {
        socket.send(JSON.stringify(appData));  // Too late!
    }, 1000);
};

3. ✅ Wait for response.accepted

// ✅ CORRECT: Check accepted first
if (response.accepted) {
    isConnected = true;
    makeAPICall();  // Now safe
}
 
// ❌ WRONG: Making calls too early
socket.onopen = function() {
    socket.send(JSON.stringify(appData));
    makeAPICall();  // Not accepted yet!
};

4. ✅ Handle All Events

// All four event handlers required:
socket.onopen    // Send app data immediately
socket.onmessage // Handle responses and acceptance
socket.onerror   // Log errors
socket.onclose   // Clean up and reconnect if needed

Common Mistakes

MistakeWhy It FailsCorrect Pattern
Invalid ID size/format"Invalid ID size" error - wallet requires exactly 64 hex charsUse static 64-character hex string
Generating new ID each connectionBreaks permission continuity - user must approve repeatedlyGenerate once and store in localStorage
Using 127.0.0.1May work but doesn't match verified demoUse localhost
Delaying send()Connection closes before handshakeSend immediately in onopen
Not checking acceptedAPI calls rejected or fail silentlyWait for response.accepted
Missing event handlersErrors go unnoticedHandle all 4 events

Related Pages