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
| Mistake | Issue | Fix |
|---|---|---|
| Variable-length or wrong-size ID | "Invalid ID size" error | Use exactly 64 hexadecimal characters |
Missing url field | Wallet rejects connection | Always include url: "http://localhost:" + location.port |
url without port | Connection may fail | Use location.port not just origin |
Delaying send() | Connection closes | Send immediately in onopen |
| Invalid JSON | Parse error | Use JSON.stringify() |
Related Pages
- Official Demo - Complete app1 source code
- XSWD Connection Pattern - Connection code
- API Call Patterns - Making RPC calls after connection