ci: docker_tag=ext - Update ihm_client configuration and dependencies

This commit is contained in:
4NK CI Bot 2025-09-21 13:07:47 +00:00
parent ae58d95e39
commit 30a3960b2e
5 changed files with 1531 additions and 1531 deletions

View File

@ -1,50 +1,50 @@
import { interpolate } from '../../utils/html.utils'; import { interpolate } from '../../utils/html.utils';
import Services from '../../services/service'; import Services from '../../services/service';
import { Process } from '../../pkg/sdk_client.js'; import { Process } from '../../pkg/sdk_client.js';
import { getCorrectDOM } from '~/utils/document.utils'; import { getCorrectDOM } from '~/utils/document.utils';
let currentPageStyle: HTMLStyleElement | null = null; let currentPageStyle: HTMLStyleElement | null = null;
export async function initProcessElement(id: string, zone: string) { export async function initProcessElement(id: string, zone: string) {
const processes = await getProcesses(); const processes = await getProcesses();
const container = getCorrectDOM('process-4nk-component'); const container = getCorrectDOM('process-4nk-component');
// const currentProcess = processes.find((process) => process[0] === id)[1]; // const currentProcess = processes.find((process) => process[0] === id)[1];
// const currentProcess = {title: 'Hello', html: '', css: ''}; // const currentProcess = {title: 'Hello', html: '', css: ''};
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' }); // await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
// const wrapper = document.querySelector('.process-container'); // const wrapper = document.querySelector('.process-container');
// if (wrapper) { // if (wrapper) {
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' }); // wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
// injectCss(currentProcess.css); // injectCss(currentProcess.css);
// } // }
} }
async function loadPage(data?: any) { async function loadPage(data?: any) {
const content = document.getElementById('containerId'); const content = document.getElementById('containerId');
if (content && data) { if (content && data) {
if (data) { if (data) {
content.innerHTML = interpolate(content.innerHTML, data); content.innerHTML = interpolate(content.innerHTML, data);
} }
} }
} }
function injectCss(cssContent: string) { function injectCss(cssContent: string) {
removeCss(); // Ensure that the previous CSS is removed removeCss(); // Ensure that the previous CSS is removed
currentPageStyle = document.createElement('style'); currentPageStyle = document.createElement('style');
currentPageStyle.type = 'text/css'; currentPageStyle.type = 'text/css';
currentPageStyle.appendChild(document.createTextNode(cssContent)); currentPageStyle.appendChild(document.createTextNode(cssContent));
document.head.appendChild(currentPageStyle); document.head.appendChild(currentPageStyle);
} }
function removeCss() { function removeCss() {
if (currentPageStyle) { if (currentPageStyle) {
document.head.removeChild(currentPageStyle); document.head.removeChild(currentPageStyle);
currentPageStyle = null; currentPageStyle = null;
} }
} }
async function getProcesses(): Promise<Record<string, Process>> { async function getProcesses(): Promise<Record<string, Process>> {
const service = await Services.getInstance(); const service = await Services.getInstance();
const processes = await service.getProcesses(); const processes = await service.getProcesses();
return processes; return processes;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,230 +1,230 @@
import modalHtml from '../components/login-modal/login-modal.html?raw'; import modalHtml from '../components/login-modal/login-modal.html?raw';
import modalScript from '../components/login-modal/login-modal.js?raw'; import modalScript from '../components/login-modal/login-modal.js?raw';
import validationModalStyle from '../components/validation-modal/validation-modal.css?raw'; import validationModalStyle from '../components/validation-modal/validation-modal.css?raw';
import Services from './service'; import Services from './service';
import { init, navigate } from '../router'; import { init, navigate } from '../router';
import { addressToEmoji } from '../utils/sp-address.utils'; import { addressToEmoji } from '../utils/sp-address.utils';
import { RoleDefinition } from '../../pkg/sdk_client.js'; import { RoleDefinition } from '../../pkg/sdk_client.js';
import { initValidationModal } from '~/components/validation-modal/validation-modal'; import { initValidationModal } from '~/components/validation-modal/validation-modal';
import { interpolate } from '~/utils/html.utils'; import { interpolate } from '~/utils/html.utils';
interface ConfirmationModalOptions { interface ConfirmationModalOptions {
title: string; title: string;
content: string; content: string;
confirmText?: string; confirmText?: string;
cancelText?: string; cancelText?: string;
} }
export default class ModalService { export default class ModalService {
private static instance: ModalService; private static instance: ModalService;
private stateId: string | null = null; private stateId: string | null = null;
private processId: string | null = null; private processId: string | null = null;
private constructor() {} private constructor() {}
private paired_addresses: string[] = []; private paired_addresses: string[] = [];
private modal: HTMLElement | null = null; private modal: HTMLElement | null = null;
// Method to access the singleton instance of Services // Method to access the singleton instance of Services
public static async getInstance(): Promise<ModalService> { public static async getInstance(): Promise<ModalService> {
if (!ModalService.instance) { if (!ModalService.instance) {
ModalService.instance = new ModalService(); ModalService.instance = new ModalService();
} }
return ModalService.instance; return ModalService.instance;
} }
public openLoginModal(myAddress: string, receiverAddress: string) { public openLoginModal(myAddress: string, receiverAddress: string) {
const container = document.querySelector('.page-container'); const container = document.querySelector('.page-container');
let html = modalHtml; let html = modalHtml;
html = html.replace('{{device1}}', myAddress); html = html.replace('{{device1}}', myAddress);
html = html.replace('{{device2}}', receiverAddress); html = html.replace('{{device2}}', receiverAddress);
if (container) container.innerHTML += html; if (container) container.innerHTML += html;
const modal = document.getElementById('login-modal'); const modal = document.getElementById('login-modal');
if (modal) modal.style.display = 'flex'; if (modal) modal.style.display = 'flex';
const newScript = document.createElement('script'); const newScript = document.createElement('script');
newScript.setAttribute('type', 'module'); newScript.setAttribute('type', 'module');
newScript.textContent = modalScript; newScript.textContent = modalScript;
document.head.appendChild(newScript).parentNode?.removeChild(newScript); document.head.appendChild(newScript).parentNode?.removeChild(newScript);
} }
async injectModal(members: any[]) { async injectModal(members: any[]) {
const container = document.querySelector('#containerId'); const container = document.querySelector('#containerId');
if (container) { if (container) {
let html = await fetch('/src/components/modal/confirmation-modal.html').then((res) => res.text()); let html = await fetch('/src/components/modal/confirmation-modal.html').then((res) => res.text());
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0])); html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1])); html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1]));
container.innerHTML += html; container.innerHTML += html;
// Dynamically load the header JS // Dynamically load the header JS
const script = document.createElement('script'); const script = document.createElement('script');
script.src = '/src/components/modal/confirmation-modal.ts'; script.src = '/src/components/modal/confirmation-modal.ts';
script.type = 'module'; script.type = 'module';
document.head.appendChild(script); document.head.appendChild(script);
} }
} }
async injectCreationModal(members: any[]) { async injectCreationModal(members: any[]) {
const container = document.querySelector('#containerId'); const container = document.querySelector('#containerId');
if (container) { if (container) {
let html = await fetch('/src/components/modal/creation-modal.html').then((res) => res.text()); let html = await fetch('/src/components/modal/creation-modal.html').then((res) => res.text());
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0])); html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
container.innerHTML += html; container.innerHTML += html;
// Dynamically load the header JS // Dynamically load the header JS
const script = document.createElement('script'); const script = document.createElement('script');
script.src = '/src/components/modal/confirmation-modal.ts'; script.src = '/src/components/modal/confirmation-modal.ts';
script.type = 'module'; script.type = 'module';
document.head.appendChild(script); document.head.appendChild(script);
} }
} }
// Device 1 wait Device 2 // Device 1 wait Device 2
async injectWaitingModal() { async injectWaitingModal() {
const container = document.querySelector('#containerId'); const container = document.querySelector('#containerId');
if (container) { if (container) {
let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text()); let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text());
container.innerHTML += html; container.innerHTML += html;
} }
} }
async injectValidationModal(processDiff: any) { async injectValidationModal(processDiff: any) {
const container = document.querySelector('#containerId'); const container = document.querySelector('#containerId');
if (container) { if (container) {
let html = await fetch('/src/components/validation-modal/validation-modal.html').then((res) => res.text()); let html = await fetch('/src/components/validation-modal/validation-modal.html').then((res) => res.text());
html = interpolate(html, {processId: processDiff.processId}) html = interpolate(html, {processId: processDiff.processId})
container.innerHTML += html; container.innerHTML += html;
// Dynamically load the header JS // Dynamically load the header JS
const script = document.createElement('script'); const script = document.createElement('script');
script.id = 'validation-modal-script'; script.id = 'validation-modal-script';
script.src = '/src/components/validation-modal/validation-modal.ts'; script.src = '/src/components/validation-modal/validation-modal.ts';
script.type = 'module'; script.type = 'module';
document.head.appendChild(script); document.head.appendChild(script);
const css = document.createElement('style'); const css = document.createElement('style');
css.id = 'validation-modal-css'; css.id = 'validation-modal-css';
css.innerText = validationModalStyle; css.innerText = validationModalStyle;
document.head.appendChild(css); document.head.appendChild(css);
initValidationModal(processDiff) initValidationModal(processDiff)
} }
} }
async closeValidationModal() { async closeValidationModal() {
const script = document.querySelector('#validation-modal-script'); const script = document.querySelector('#validation-modal-script');
const css = document.querySelector('#validation-modal-css'); const css = document.querySelector('#validation-modal-css');
const component = document.querySelector('#validation-modal'); const component = document.querySelector('#validation-modal');
script?.remove(); script?.remove();
css?.remove(); css?.remove();
component?.remove(); component?.remove();
} }
public async openPairingConfirmationModal(roleDefinition: Record<string, RoleDefinition>, processId: string, stateId: string) { public async openPairingConfirmationModal(roleDefinition: Record<string, RoleDefinition>, processId: string, stateId: string) {
let members; let members;
if (roleDefinition['pairing']) { if (roleDefinition['pairing']) {
const owner = roleDefinition['pairing']; const owner = roleDefinition['pairing'];
members = owner.members; members = owner.members;
} else { } else {
throw new Error('No "pairing" role'); throw new Error('No "pairing" role');
} }
if (members.length != 1) { if (members.length != 1) {
throw new Error('Must have exactly 1 member'); throw new Error('Must have exactly 1 member');
} }
console.log("MEMBERS:", members); console.log("MEMBERS:", members);
// We take all the addresses except our own // We take all the addresses except our own
const service = await Services.getInstance(); const service = await Services.getInstance();
const localAddress = service.getDeviceAddress(); const localAddress = service.getDeviceAddress();
for (const member of members) { for (const member of members) {
if (member.sp_addresses) { if (member.sp_addresses) {
for (const address of member.sp_addresses) { for (const address of member.sp_addresses) {
if (address !== localAddress) { if (address !== localAddress) {
this.paired_addresses.push(address); this.paired_addresses.push(address);
} }
} }
} }
} }
this.processId = processId; this.processId = processId;
this.stateId = stateId; this.stateId = stateId;
if (members[0].sp_addresses.length === 1) { if (members[0].sp_addresses.length === 1) {
await this.injectCreationModal(members); await this.injectCreationModal(members);
this.modal = document.getElementById('creation-modal'); this.modal = document.getElementById('creation-modal');
console.log("LENGTH:", members[0].sp_addresses.length); console.log("LENGTH:", members[0].sp_addresses.length);
} else { } else {
await this.injectModal(members); await this.injectModal(members);
this.modal = document.getElementById('modal'); this.modal = document.getElementById('modal');
console.log("LENGTH:", members[0].sp_addresses.length); console.log("LENGTH:", members[0].sp_addresses.length);
} }
if (this.modal) this.modal.style.display = 'flex'; if (this.modal) this.modal.style.display = 'flex';
// Close modal when clicking outside of it // Close modal when clicking outside of it
window.onclick = (event) => { window.onclick = (event) => {
if (event.target === this.modal) { if (event.target === this.modal) {
this.closeConfirmationModal(); this.closeConfirmationModal();
} }
}; };
} }
confirmLogin() { confirmLogin() {
console.log('=============> Confirm Login'); console.log('=============> Confirm Login');
} }
async closeLoginModal() { async closeLoginModal() {
if (this.modal) this.modal.style.display = 'none'; if (this.modal) this.modal.style.display = 'none';
} }
async showConfirmationModal(options: ConfirmationModalOptions, fullscreen: boolean = false): Promise<boolean> { async showConfirmationModal(options: ConfirmationModalOptions, fullscreen: boolean = false): Promise<boolean> {
// Create modal element // Create modal element
const modalElement = document.createElement('div'); const modalElement = document.createElement('div');
modalElement.id = 'confirmation-modal'; modalElement.id = 'confirmation-modal';
modalElement.innerHTML = ` modalElement.innerHTML = `
<div class="modal-overlay"> <div class="modal-overlay">
<div class="modal-content" ${fullscreen ? 'style="width: 100% !important; max-width: none !important; height: 100% !important; max-height: none !important; border-radius: 0 !important; margin: 0 !important;"' : ''}> <div class="modal-content" ${fullscreen ? 'style="width: 100% !important; max-width: none !important; height: 100% !important; max-height: none !important; border-radius: 0 !important; margin: 0 !important;"' : ''}>
<h2>${options.title}</h2> <h2>${options.title}</h2>
<div class="modal-body"> <div class="modal-body">
${options.content} ${options.content}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button> <button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button>
<button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button> <button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button>
</div> </div>
</div> </div>
</div> </div>
`; `;
// Add modal to document // Add modal to document
document.body.appendChild(modalElement); document.body.appendChild(modalElement);
// Return promise that resolves with user choice // Return promise that resolves with user choice
return new Promise((resolve) => { return new Promise((resolve) => {
const confirmButton = modalElement.querySelector('#confirm-button'); const confirmButton = modalElement.querySelector('#confirm-button');
const cancelButton = modalElement.querySelector('#cancel-button'); const cancelButton = modalElement.querySelector('#cancel-button');
const modalOverlay = modalElement.querySelector('.modal-overlay'); const modalOverlay = modalElement.querySelector('.modal-overlay');
const cleanup = () => { const cleanup = () => {
modalElement.remove(); modalElement.remove();
}; };
confirmButton?.addEventListener('click', () => { confirmButton?.addEventListener('click', () => {
cleanup(); cleanup();
resolve(true); resolve(true);
}); });
cancelButton?.addEventListener('click', () => { cancelButton?.addEventListener('click', () => {
cleanup(); cleanup();
resolve(false); resolve(false);
}); });
modalOverlay?.addEventListener('click', (e) => { modalOverlay?.addEventListener('click', (e) => {
if (e.target === modalOverlay) { if (e.target === modalOverlay) {
cleanup(); cleanup();
resolve(false); resolve(false);
} }
}); });
}); });
} }
async closeConfirmationModal() { async closeConfirmationModal() {
const service = await Services.getInstance(); const service = await Services.getInstance();
await service.unpairDevice(); await service.unpairDevice();
if (this.modal) this.modal.style.display = 'none'; if (this.modal) this.modal.style.display = 'none';
} }
} }

View File

@ -1,213 +1,213 @@
import Services from '../services/service'; import Services from '../services/service';
import { getCorrectDOM } from './html.utils'; import { getCorrectDOM } from './html.utils';
import { addSubscription } from './subscription.utils'; import { addSubscription } from './subscription.utils';
import QRCode from 'qrcode'; import QRCode from 'qrcode';
//Copy Address //Copy Address
export async function copyToClipboard(fullAddress: string) { export async function copyToClipboard(fullAddress: string) {
try { try {
await navigator.clipboard.writeText(fullAddress); await navigator.clipboard.writeText(fullAddress);
alert('Adresse copiée dans le presse-papiers !'); alert('Adresse copiée dans le presse-papiers !');
} catch (err) { } catch (err) {
console.error('Failed to copy the address: ', err); console.error('Failed to copy the address: ', err);
} }
} }
//Generate emojis list //Generate emojis list
export function generateEmojiList(): string[] { export function generateEmojiList(): string[] {
const emojiRanges = [ const emojiRanges = [
[0x1f600, 0x1f64f], [0x1f600, 0x1f64f],
[0x1f300, 0x1f5ff], [0x1f300, 0x1f5ff],
[0x1f680, 0x1f6ff], [0x1f680, 0x1f6ff],
[0x1f700, 0x1f77f], [0x1f700, 0x1f77f],
]; ];
const emojiList: string[] = []; const emojiList: string[] = [];
for (const range of emojiRanges) { for (const range of emojiRanges) {
const [start, end] = range; const [start, end] = range;
for (let i = start; i <= end && emojiList.length < 256; i++) { for (let i = start; i <= end && emojiList.length < 256; i++) {
emojiList.push(String.fromCodePoint(i)); emojiList.push(String.fromCodePoint(i));
} }
if (emojiList.length >= 256) { if (emojiList.length >= 256) {
break; break;
} }
} }
return emojiList.slice(0, 256); return emojiList.slice(0, 256);
} }
//Adress to emojis //Adress to emojis
export async function addressToEmoji(text: string): Promise<string> { export async function addressToEmoji(text: string): Promise<string> {
//Adress to Hash //Adress to Hash
const encoder = new TextEncoder(); const encoder = new TextEncoder();
const data = encoder.encode(text); const data = encoder.encode(text);
const hashBuffer = await crypto.subtle.digest('SHA-256', data); const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hash = new Uint8Array(hashBuffer); const hash = new Uint8Array(hashBuffer);
const bytes = hash.slice(-4); const bytes = hash.slice(-4);
//Hash slice to emojis //Hash slice to emojis
const emojiList = generateEmojiList(); const emojiList = generateEmojiList();
const emojis = Array.from(bytes) const emojis = Array.from(bytes)
.map((byte) => emojiList[byte]) .map((byte) => emojiList[byte])
.join(''); .join('');
return emojis; return emojis;
} }
//Get emojis from other device //Get emojis from other device
async function emojisPairingRequest() { async function emojisPairingRequest() {
try { try {
const container = getCorrectDOM('login-4nk-component') as HTMLElement; const container = getCorrectDOM('login-4nk-component') as HTMLElement;
const urlParams: URLSearchParams = new URLSearchParams(window.location.search); const urlParams: URLSearchParams = new URLSearchParams(window.location.search);
const sp_adress: string | null = urlParams.get('sp_address'); const sp_adress: string | null = urlParams.get('sp_address');
if (!sp_adress) { if (!sp_adress) {
// console.error("No 'sp_adress' parameter found in the URL."); // console.error("No 'sp_adress' parameter found in the URL.");
return; return;
} }
const emojis = await addressToEmoji(sp_adress); const emojis = await addressToEmoji(sp_adress);
const emojiDisplay = container?.querySelector('.pairing-request'); const emojiDisplay = container?.querySelector('.pairing-request');
if (emojiDisplay) { if (emojiDisplay) {
emojiDisplay.textContent = '(Request from: ' + emojis + ')'; emojiDisplay.textContent = '(Request from: ' + emojis + ')';
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
} }
// Display address emojis and other device emojis // Display address emojis and other device emojis
export async function displayEmojis(text: string) { export async function displayEmojis(text: string) {
console.log('🚀 ~ Services ~ adressToEmoji'); console.log('🚀 ~ Services ~ adressToEmoji');
try { try {
const container = getCorrectDOM('login-4nk-component') as HTMLElement; const container = getCorrectDOM('login-4nk-component') as HTMLElement;
const emojis = await addressToEmoji(text); const emojis = await addressToEmoji(text);
const emojiDisplay = container?.querySelector('.emoji-display'); const emojiDisplay = container?.querySelector('.emoji-display');
if (emojiDisplay) { if (emojiDisplay) {
emojiDisplay.textContent = emojis; emojiDisplay.textContent = emojis;
} }
emojisPairingRequest(); emojisPairingRequest();
initAddressInput(); initAddressInput();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
} }
// Verify Other address // Verify Other address
export function initAddressInput() { export function initAddressInput() {
const container = getCorrectDOM('login-4nk-component') as HTMLElement const container = getCorrectDOM('login-4nk-component') as HTMLElement
const addressInput = container.querySelector('#addressInput') as HTMLInputElement; const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
const emojiDisplay = container.querySelector('#emoji-display-2'); const emojiDisplay = container.querySelector('#emoji-display-2');
const okButton = container.querySelector('#okButton') as HTMLButtonElement; const okButton = container.querySelector('#okButton') as HTMLButtonElement;
const createButton = container.querySelector('#createButton') as HTMLButtonElement; const createButton = container.querySelector('#createButton') as HTMLButtonElement;
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement; const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
addSubscription(addressInput, 'input', async () => { addSubscription(addressInput, 'input', async () => {
let address = addressInput.value; let address = addressInput.value;
// Vérifie si l'adresse est une URL // Vérifie si l'adresse est une URL
try { try {
const url = new URL(address); const url = new URL(address);
// Si c'est une URL valide, extraire le paramètre sp_address // Si c'est une URL valide, extraire le paramètre sp_address
const urlParams = new URLSearchParams(url.search); const urlParams = new URLSearchParams(url.search);
const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide
if (extractedAddress) { if (extractedAddress) {
address = extractedAddress; address = extractedAddress;
addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite
} }
} catch (e) { } catch (e) {
// Si ce n'est pas une URL valide, on garde l'adresse originale // Si ce n'est pas une URL valide, on garde l'adresse originale
console.log("Ce n'est pas une URL valide, on garde l'adresse originale."); console.log("Ce n'est pas une URL valide, on garde l'adresse originale.");
} }
if (address) { if (address) {
const emojis = await addressToEmoji(address); const emojis = await addressToEmoji(address);
if (emojiDisplay) { if (emojiDisplay) {
emojiDisplay.innerHTML = emojis; emojiDisplay.innerHTML = emojis;
} }
if (okButton) { if (okButton) {
okButton.style.display = 'inline-block'; okButton.style.display = 'inline-block';
} }
} else { } else {
if (emojiDisplay) { if (emojiDisplay) {
emojiDisplay.innerHTML = ''; emojiDisplay.innerHTML = '';
} }
if (okButton) { if (okButton) {
okButton.style.display = 'none'; okButton.style.display = 'none';
} }
} }
}); });
if (createButton) { if (createButton) {
addSubscription(createButton, 'click', () => { addSubscription(createButton, 'click', () => {
onCreateButtonClick(); onCreateButtonClick();
}); });
} }
} }
async function onCreateButtonClick() { async function onCreateButtonClick() {
try { try {
await prepareAndSendPairingTx(); await prepareAndSendPairingTx();
const service = await Services.getInstance(); const service = await Services.getInstance();
await service.confirmPairing(); await service.confirmPairing();
} catch (e) { } catch (e) {
console.error(`onCreateButtonClick error: ${e}`); console.error(`onCreateButtonClick error: ${e}`);
} }
} }
export async function prepareAndSendPairingTx(): Promise<void> { export async function prepareAndSendPairingTx(): Promise<void> {
const service = await Services.getInstance(); const service = await Services.getInstance();
// checkConnections requires a Process object, not an empty array // checkConnections requires a Process object, not an empty array
// This call has been removed as it was causing TypeScript errors // This call has been removed as it was causing TypeScript errors
try { try {
const relayAddress = service.getAllRelays(); const relayAddress = service.getAllRelays();
const createPairingProcessReturn = await service.createPairingProcess( const createPairingProcessReturn = await service.createPairingProcess(
"", "",
[], [],
); );
if (!createPairingProcessReturn.updated_process) { if (!createPairingProcessReturn.updated_process) {
throw new Error('createPairingProcess returned an empty new process'); throw new Error('createPairingProcess returned an empty new process');
} }
service.setProcessId(createPairingProcessReturn.updated_process.process_id); service.setProcessId(createPairingProcessReturn.updated_process.process_id);
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id); service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
await service.handleApiReturn(createPairingProcessReturn); await service.handleApiReturn(createPairingProcessReturn);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
} }
export async function generateQRCode(spAddress: string) { export async function generateQRCode(spAddress: string) {
try { try {
const container = getCorrectDOM('login-4nk-component') as HTMLElement const container = getCorrectDOM('login-4nk-component') as HTMLElement
const currentUrl = 'https://' + window.location.host; const currentUrl = 'https://' + window.location.host;
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress); const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
const qrCode = container?.querySelector('.qr-code img'); const qrCode = container?.querySelector('.qr-code img');
qrCode?.setAttribute('src', url); qrCode?.setAttribute('src', url);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
} }
export async function generateCreateBtn() { export async function generateCreateBtn() {
try{ try{
//Generate CreateBtn //Generate CreateBtn
const container = getCorrectDOM('login-4nk-component') as HTMLElement const container = getCorrectDOM('login-4nk-component') as HTMLElement
const createBtn = container?.querySelector('.create-btn'); const createBtn = container?.querySelector('.create-btn');
if (createBtn) { if (createBtn) {
createBtn.textContent = 'CREATE'; createBtn.textContent = 'CREATE';
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
} }

View File

@ -1,89 +1,89 @@
import { AnkFlag } from '../../pkg/sdk_client.js'; import { AnkFlag } from '../../pkg/sdk_client.js';
import Services from './services/service'; import Services from './services/service';
let ws: WebSocket; let ws: WebSocket;
let messageQueue: string[] = []; let messageQueue: string[] = [];
export async function initWebsocket(url: string) { export async function initWebsocket(url: string) {
ws = new WebSocket(url); ws = new WebSocket(url);
if (ws !== null) { if (ws !== null) {
ws.onopen = async (event) => { ws.onopen = async (event) => {
console.log('WebSocket connection established'); console.log('WebSocket connection established');
while (messageQueue.length > 0) { while (messageQueue.length > 0) {
const message = messageQueue.shift(); const message = messageQueue.shift();
if (message) { if (message) {
ws.send(message); ws.send(message);
} }
} }
}; };
// Listen for messages // Listen for messages
ws.onmessage = (event) => { ws.onmessage = (event) => {
const msgData = event.data; const msgData = event.data;
// console.log("Received text message: ", msgData); // console.log("Received text message: ", msgData);
(async () => { (async () => {
if (typeof msgData === 'string') { if (typeof msgData === 'string') {
try { try {
const parsedMessage = JSON.parse(msgData); const parsedMessage = JSON.parse(msgData);
const services = await Services.getInstance(); const services = await Services.getInstance();
switch (parsedMessage.flag) { switch (parsedMessage.flag) {
case 'Handshake': case 'Handshake':
await services.handleHandshakeMsg(url, parsedMessage.content); await services.handleHandshakeMsg(url, parsedMessage.content);
break; break;
case 'NewTx': case 'NewTx':
await services.parseNewTx(parsedMessage.content); await services.parseNewTx(parsedMessage.content);
break; break;
case 'Cipher': case 'Cipher':
await services.parseCipher(parsedMessage.content); await services.parseCipher(parsedMessage.content);
break; break;
case 'Commit': case 'Commit':
// Basically if we see this it means we have an error // Basically if we see this it means we have an error
await services.handleCommitError(parsedMessage.content); await services.handleCommitError(parsedMessage.content);
break; break;
} }
} catch (error) { } catch (error) {
console.error('Received an invalid message:', error); console.error('Received an invalid message:', error);
} }
} else { } else {
console.error('Received a non-string message'); console.error('Received a non-string message');
} }
})(); })();
}; };
// Listen for possible errors // Listen for possible errors
ws.onerror = (event) => { ws.onerror = (event) => {
console.error('WebSocket error:', event); console.error('WebSocket error:', event);
}; };
// Listen for when the connection is closed // Listen for when the connection is closed
ws.onclose = (event) => { ws.onclose = (event) => {
console.log('WebSocket is closed now.'); console.log('WebSocket is closed now.');
}; };
} }
} }
// Method to send messages // Method to send messages
export function sendMessage(flag: AnkFlag, message: string): void { export function sendMessage(flag: AnkFlag, message: string): void {
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
const networkMessage = { const networkMessage = {
flag: flag, flag: flag,
content: message, content: message,
}; };
console.log('Sending message of type:', flag); console.log('Sending message of type:', flag);
ws.send(JSON.stringify(networkMessage)); ws.send(JSON.stringify(networkMessage));
} else { } else {
console.error('WebSocket is not open. ReadyState:', ws.readyState); console.error('WebSocket is not open. ReadyState:', ws.readyState);
messageQueue.push(message); messageQueue.push(message);
} }
} }
export function getUrl(): string { export function getUrl(): string {
return ws.url; return ws.url;
} }
// Method to close the WebSocket connection // Method to close the WebSocket connection
export function close(): void { export function close(): void {
ws.close(); ws.close();
} }