#!/usr/bin/env node /** * Test script to connect to @bas's chat service and send a "hello" message * * IMPORTANT: This script requires the 'wrtc' package which must be installed separately. * See TEST_README.md for detailed installation instructions. * * Quick start: * npm install wrtc * npm test * * Requirements: * - Node.js 19+ (or Node.js 18 with --experimental-global-webcrypto) * - wrtc package (requires native compilation) * - Build tools (python, make, g++) */ import { Rondevu, RondevuSignaler, NodeCryptoAdapter } from '@xtr-dev/rondevu-client' // Import wrtc let wrtc try { wrtc = await import('wrtc') } catch (error) { console.error('āŒ Error: wrtc package not found or failed to load') console.error('\nThe wrtc package is required for WebRTC support in Node.js.') console.error('Install it with:') console.error('\n npm install wrtc') console.error('\nNote: wrtc requires native compilation and may take a few minutes to install.') console.error('\nError details:', error.message) process.exit(1) } const { RTCPeerConnection } = wrtc // Configuration const API_URL = 'https://api.ronde.vu' const TARGET_USER = 'bas' const SERVICE_FQN = `chat:2.0.0@${TARGET_USER}` const MESSAGE = 'hello' // TURN server configuration const RTC_CONFIG = { iceServers: [ { urls: 'stun:stun.share.fish:3478' }, { urls: [ 'turns:turn.share.fish:5349?transport=tcp', 'turns:turn.share.fish:5349?transport=udp', 'turn:turn.share.fish:3478?transport=tcp', 'turn:turn.share.fish:3478?transport=udp', ], username: 'webrtcuser', credential: 'supersecretpassword' } ] } async function main() { console.log('šŸš€ Rondevu Test Script') console.log('='.repeat(50)) try { // 1. Initialize Rondevu with Node crypto adapter console.log('1. Initializing Rondevu client...') const rondevu = new Rondevu({ apiUrl: API_URL, username: `test-${Date.now()}`, // Anonymous test user cryptoAdapter: new NodeCryptoAdapter() }) await rondevu.initialize() console.log(` āœ“ Initialized as: ${rondevu.getUsername()}`) console.log(` āœ“ Public key: ${rondevu.getPublicKey()?.substring(0, 20)}...`) // 2. Discover service console.log(`\n2. Looking for service: ${SERVICE_FQN}`) const serviceData = await rondevu.getService(SERVICE_FQN) console.log(` āœ“ Found service from @${serviceData.username}`) console.log(` āœ“ Offer ID: ${serviceData.offerId}`) // 3. Create peer connection console.log('\n3. Creating WebRTC peer connection...') const pc = new RTCPeerConnection(RTC_CONFIG) // 4. Create data channel console.log('4. Creating data channel...') const dc = pc.createDataChannel('chat') // Set up data channel handlers dc.onopen = () => { console.log(' āœ“ Data channel opened!') console.log(`\nšŸ“¤ Sending message: "${MESSAGE}"`) dc.send(MESSAGE) // Close after sending setTimeout(() => { console.log('\nāœ… Test completed successfully!') dc.close() pc.close() process.exit(0) }, 1000) } dc.onmessage = (event) => { console.log(`šŸ“„ Received: ${event.data}`) } dc.onerror = (error) => { console.error('āŒ Data channel error:', error) process.exit(1) } // 5. Set remote offer console.log('5. Setting remote offer...') await pc.setRemoteDescription({ type: 'offer', sdp: serviceData.sdp }) console.log(' āœ“ Remote offer set') // 6. Create and set local answer console.log('6. Creating answer...') const answer = await pc.createAnswer() await pc.setLocalDescription(answer) console.log(' āœ“ Local answer set') // 7. Send answer to server console.log('7. Sending answer to signaling server...') await rondevu.postOfferAnswer( serviceData.serviceFqn, serviceData.offerId, answer.sdp ) console.log(' āœ“ Answer sent') // 8. Handle ICE candidates console.log('8. Setting up ICE candidate exchange...') const signaler = new RondevuSignaler(rondevu, SERVICE_FQN, TARGET_USER) // Send our ICE candidates pc.onicecandidate = async (event) => { if (event.candidate) { console.log(' šŸ“¤ Sending ICE candidate') await signaler.addIceCandidate(event.candidate) } } // Receive remote ICE candidates signaler.addListener((candidate) => { console.log(' šŸ“„ Received ICE candidate') pc.addIceCandidate(candidate) }) // Monitor connection state pc.onconnectionstatechange = () => { console.log(` Connection state: ${pc.connectionState}`) if (pc.connectionState === 'failed') { console.error('āŒ Connection failed') process.exit(1) } } pc.oniceconnectionstatechange = () => { console.log(` ICE state: ${pc.iceConnectionState}`) } console.log('\nā³ Waiting for connection...') // Timeout after 30 seconds setTimeout(() => { if (pc.connectionState !== 'connected') { console.error('āŒ Connection timeout') process.exit(1) } }, 30000) } catch (error) { console.error('\nāŒ Error:', error.message) console.error(error) process.exit(1) } } main()