Files
self/sdk/qrcode/utils/websocket.ts
turnoffthiscomputer 36a29c9a21 chore: add redirect.self.xyz to app link domains (#415)
* chore: add redirect.self.xyz to app link domains

* chore: add redirect.self.xyz to android manifest

* add self in the universal link path

* set gestureEnabled false on Launch screen

* improve ProveScreen UX

* improve ProveScreen UX

* implement deeplinking in mobile app and sdk

* start app listener in ViewFinder

* support WS connexion with complex qrcodes

* remove /self path from android deeplink support

---------

Co-authored-by: turboblitz <florent.tavernier@gmail.com>
2025-03-21 13:55:11 -07:00

117 lines
3.7 KiB
TypeScript

import io, { Socket } from 'socket.io-client';
import { QRcodeSteps } from './utils';
import { SelfApp } from '../../../common/src/utils/appType';
export interface WebAppInfo {
appName: string;
userId: string;
logoBase64: string;
};
// Log once when this module loads
console.log('[WebSocket] Initializing websocket module.');
const newSocket = (websocketUrl: string, sessionId: string) => {
const fullUrl = `${websocketUrl}/websocket`;
console.log(`[WebSocket] Creating new socket. URL: ${fullUrl}, sessionId: ${sessionId}`);
return io(fullUrl, {
path: '/',
query: { sessionId, clientType: 'web' },
transports: ['websocket'],
});
};
const handleWebSocketMessage =
(
socket: Socket,
sessionId: string,
selfApp: SelfApp,
type: 'websocket' | 'deeplink',
setProofStep: (step: number) => void,
setProofVerified: (proofVerified: boolean) => void,
onSuccess: () => void
) =>
async (data: any) => {
console.log('[WebSocket] Received mobile status:', data.status, 'for session:', sessionId);
switch (data.status) {
case 'mobile_connected':
console.log('[WebSocket] Mobile device connected. Emitting self_app event with payload:', selfApp);
setProofStep(QRcodeSteps.MOBILE_CONNECTED);
if (type === 'websocket') {
socket.emit('self_app', { ...selfApp, sessionId });
}
break;
case 'mobile_disconnected':
console.log('[WebSocket] Mobile device disconnected.');
setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
break;
case 'proof_generation_started':
console.log('[WebSocket] Proof generation started.');
setProofStep(QRcodeSteps.PROOF_GENERATION_STARTED);
break;
case 'proof_generated':
console.log('[WebSocket] Proof generated.');
setProofStep(QRcodeSteps.PROOF_GENERATED);
break;
case 'proof_generation_failed':
console.log('[WebSocket] Proof generation failed.');
setProofVerified(false);
setProofStep(QRcodeSteps.PROOF_VERIFIED);
break;
case 'proof_verified':
console.log('[WebSocket] Proof verified.');
setProofVerified(true);
setProofStep(QRcodeSteps.PROOF_VERIFIED);
onSuccess();
break;
default:
console.log('[WebSocket] Unhandled mobile status:', data.status);
break;
}
};
export function initWebSocket(
websocketUrl: string,
selfApp: SelfApp,
type: 'websocket' | 'deeplink',
setProofStep: (step: number) => void,
setProofVerified: (proofVerified: boolean) => void,
onSuccess: () => void
) {
const sessionId = selfApp.sessionId;
console.log(`[WebSocket] Initializing WebSocket connection for sessionId: ${sessionId}`);
const socket = newSocket(websocketUrl, sessionId);
socket.on('connect', () => {
console.log(`[WebSocket] Connected with id: ${socket.id}, transport: ${socket.io.engine.transport.name}`);
});
socket.on('connect_error', (error) => {
console.error('[WebSocket] Connection error:', error);
});
socket.on('mobile_status', (data) => {
console.log('[WebSocket] Raw mobile_status event received:', data);
handleWebSocketMessage(
socket,
sessionId,
selfApp,
type,
setProofStep,
setProofVerified,
onSuccess
)(data);
});
socket.on('disconnect', (reason: string) => {
console.log(`[WebSocket] Disconnected. Reason: ${reason}, Last transport: ${socket.io.engine.transport?.name}`);
});
return () => {
console.log(`[WebSocket] Cleaning up connection for sessionId: ${sessionId}`);
if (socket) {
socket.disconnect();
}
};
}