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 neededCommon Mistakes
| Mistake | Why It Fails | Correct Pattern |
|---|---|---|
| Invalid ID size/format | "Invalid ID size" error - wallet requires exactly 64 hex chars | Use static 64-character hex string |
| Generating new ID each connection | Breaks permission continuity - user must approve repeatedly | Generate once and store in localStorage |
Using 127.0.0.1 | May work but doesn't match verified demo | Use localhost |
Delaying send() | Connection closes before handshake | Send immediately in onopen |
Not checking accepted | API calls rejected or fail silently | Wait for response.accepted |
| Missing event handlers | Errors go unnoticed | Handle all 4 events |
Related Pages
- XSWD Protocol Overview - Complete protocol guide and reference
- Official Demo - Complete app1 source code
- Application Data Handshake - Handshake details
- API Call Patterns - Making RPC calls
- XSWD Tutorial - Step-by-step implementation