Add some debug methods for pairing workflow
Some checks failed
Build and Push to Registry / build-and-push (push) Failing after 44s
Some checks failed
Build and Push to Registry / build-and-push (push) Failing after 44s
This commit is contained in:
parent
79633ed923
commit
7ea4ef1920
@ -401,13 +401,13 @@ export async function registerAllListeners() {
|
||||
// Retrieve the state for the process
|
||||
const process = await services.getProcess(processId);
|
||||
if (!process) {
|
||||
throw new Error('Can\'t find process');
|
||||
throw new Error("Can't find process");
|
||||
}
|
||||
const state = services.getStateFromId(process, stateId);
|
||||
|
||||
await services.checkConnections(process, stateId);
|
||||
|
||||
let res: Record<string, any> = {};
|
||||
const res: Record<string, any> = {};
|
||||
if (state) {
|
||||
// Decrypt all the data we have the key for
|
||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||
@ -424,10 +424,10 @@ export async function registerAllListeners() {
|
||||
}
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
{
|
||||
type: MessageType.DATA_RETRIEVED,
|
||||
data: res,
|
||||
messageId: event.data.messageId
|
||||
messageId: event.data.messageId,
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
@ -500,6 +500,8 @@ export async function registerAllListeners() {
|
||||
|
||||
if (!services.isPaired()) {
|
||||
const errorMsg = 'Device not paired';
|
||||
console.log('Device not paired - running diagnosis...');
|
||||
await services.diagnosePairingState();
|
||||
errorResponse(errorMsg, event.origin, event.data.messageId);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -123,6 +123,7 @@ export default class Services {
|
||||
this.relayReadyResolver = null;
|
||||
this.relayReadyPromise = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async addWebsocketConnection(url: string): Promise<void> {
|
||||
console.log('Opening new websocket connection');
|
||||
@ -171,7 +172,21 @@ export default class Services {
|
||||
|
||||
public isPaired(): boolean {
|
||||
try {
|
||||
return this.sdkClient.is_paired();
|
||||
const result = this.sdkClient.is_paired();
|
||||
console.log('isPaired() called, result:', result);
|
||||
|
||||
// Additional debugging: check device state
|
||||
try {
|
||||
const device = this.dumpDeviceFromMemory();
|
||||
console.log('Current device state:', {
|
||||
pairing_process_commitment: device.pairing_process_commitment,
|
||||
paired_member: device.paired_member
|
||||
});
|
||||
} catch (deviceError) {
|
||||
console.error('Failed to dump device for debugging:', deviceError);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
throw new Error(`isPaired ~ Error: ${e}`);
|
||||
}
|
||||
@ -230,7 +245,7 @@ export default class Services {
|
||||
// We will take the roles from the last state, wheter it's commited or not
|
||||
public async checkConnections(process: Process, stateId: string | null = null): Promise<void> {
|
||||
if (process.states.length < 2) {
|
||||
throw new Error('Process doesn\'t have any state yet');
|
||||
throw new Error("Process doesn't have any state yet");
|
||||
}
|
||||
let roles: Record<string, RoleDefinition> | null = null;
|
||||
if (!stateId) {
|
||||
@ -251,12 +266,29 @@ export default class Services {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (members.size === 0) {
|
||||
// This must be a pairing process
|
||||
// Check if we have a pairedAddresses in the public data
|
||||
const publicData = process.states[0]?.public_data;
|
||||
if (!publicData || !publicData['pairedAddresses']) {
|
||||
let publicData: Record<string, any> | null = null;
|
||||
if (!stateId) {
|
||||
publicData = process.states[process.states.length - 2]?.public_data;
|
||||
} else {
|
||||
publicData = process.states.find(state => state.state_id === stateId)?.public_data || null;
|
||||
}
|
||||
|
||||
// If pairedAddresses is not in the current state, look in previous states
|
||||
if (!publicData?.['pairedAddresses']) {
|
||||
// Look for pairedAddresses in previous states
|
||||
for (let i = process.states.length - 1; i >= 0; i--) {
|
||||
const state = process.states[i];
|
||||
if (state.public_data && state.public_data['pairedAddresses']) {
|
||||
publicData = state.public_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!publicData?.['pairedAddresses']) {
|
||||
throw new Error('Not a pairing process');
|
||||
}
|
||||
const decodedAddresses = this.decodeValue(publicData['pairedAddresses']);
|
||||
@ -268,15 +300,19 @@ export default class Services {
|
||||
|
||||
// Ensure the amount is available before proceeding
|
||||
await this.getTokensFromFaucet();
|
||||
let unconnectedAddresses = new Set<string>();
|
||||
const myAddress = this.getDeviceAddress();
|
||||
const unconnectedAddresses = new Set<string>();
|
||||
const myAddress = await this.getDeviceAddress();
|
||||
for (const member of Array.from(members)) {
|
||||
const sp_addresses = member.sp_addresses;
|
||||
if (!sp_addresses || sp_addresses.length === 0) continue;
|
||||
if (!sp_addresses || sp_addresses.length === 0) {
|
||||
continue;
|
||||
}
|
||||
for (const address of sp_addresses) {
|
||||
// For now, we ignore our own device address, although there might be use cases for having a secret with ourselves
|
||||
if (address === myAddress) continue;
|
||||
if (await this.getSecretForAddress(address) === null) {
|
||||
if (address === myAddress) {
|
||||
continue;
|
||||
}
|
||||
if ((await this.getSecretForAddress(address)) === null) {
|
||||
unconnectedAddresses.add(address);
|
||||
}
|
||||
}
|
||||
@ -623,10 +659,17 @@ export default class Services {
|
||||
|
||||
try {
|
||||
const parsedTx = this.sdkClient.parse_new_tx(newTxMsg, 0, membersList);
|
||||
if (parsedTx) {
|
||||
if (parsedTx && (parsedTx.partial_tx || parsedTx.new_tx_to_send || parsedTx.secrets || parsedTx.updated_process)) {
|
||||
try {
|
||||
await this.handleApiReturn(parsedTx);
|
||||
const newDevice = this.dumpDeviceFromMemory();
|
||||
|
||||
// Preserve pairing_process_commitment from existing device
|
||||
const existingDevice = await this.getDeviceFromDatabase();
|
||||
if (existingDevice && existingDevice.pairing_process_commitment) {
|
||||
newDevice.pairing_process_commitment = existingDevice.pairing_process_commitment;
|
||||
}
|
||||
|
||||
await this.saveDeviceInDatabase(newDevice);
|
||||
} catch (e) {
|
||||
console.error('Failed to update device with new tx');
|
||||
@ -639,6 +682,19 @@ export default class Services {
|
||||
|
||||
public async handleApiReturn(apiReturn: ApiReturn) {
|
||||
console.log(apiReturn);
|
||||
|
||||
// Skip processing if apiReturn is empty or contains only null values
|
||||
if (!apiReturn || Object.keys(apiReturn).length === 0) {
|
||||
console.log('Skipping empty apiReturn');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if all values are null
|
||||
const hasValidData = Object.values(apiReturn).some(value => value !== null && value !== undefined);
|
||||
if (!hasValidData) {
|
||||
console.log('Skipping apiReturn with only null values');
|
||||
return;
|
||||
}
|
||||
if (apiReturn.partial_tx) {
|
||||
try {
|
||||
const res = this.sdkClient.sign_transaction(apiReturn.partial_tx);
|
||||
@ -708,6 +764,21 @@ export default class Services {
|
||||
console.error('Failed to save diffs to db:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a pairing process that's ready for confirmation
|
||||
const existingDevice = await this.getDeviceFromDatabase();
|
||||
if (existingDevice && existingDevice.pairing_process_commitment === processId) {
|
||||
// This is our pairing process, check if it has paired addresses
|
||||
const lastState = updatedProcess.current_process.states[updatedProcess.current_process.states.length - 1];
|
||||
if (lastState && lastState.public_data && lastState.public_data['pairedAddresses']) {
|
||||
console.log('Pairing process updated with paired addresses, confirming pairing...');
|
||||
try {
|
||||
await this.confirmPairing();
|
||||
} catch (e) {
|
||||
console.error('Failed to auto-confirm pairing:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (apiReturn.push_to_storage && apiReturn.push_to_storage.length != 0) {
|
||||
@ -756,13 +827,100 @@ export default class Services {
|
||||
|
||||
public async confirmPairing() {
|
||||
try {
|
||||
// Is the wasm paired?
|
||||
const pairingId = this.getPairingProcessId();
|
||||
// TODO confirm that the pairing process id is known, commited
|
||||
// Get the pairing process ID from database
|
||||
const existingDevice = await this.getDeviceFromDatabase();
|
||||
if (!existingDevice || !existingDevice.pairing_process_commitment) {
|
||||
console.error('No pairing process commitment found');
|
||||
return;
|
||||
}
|
||||
|
||||
const pairingProcessId = existingDevice.pairing_process_commitment;
|
||||
|
||||
// Get the pairing process to extract paired addresses
|
||||
const myPairingProcess = await this.getProcess(pairingProcessId);
|
||||
if (!myPairingProcess) {
|
||||
console.error('Unknown pairing process');
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get committed state first, fallback to current state
|
||||
let myPairingState = this.getLastCommitedState(myPairingProcess);
|
||||
if (!myPairingState && myPairingProcess.states.length > 0) {
|
||||
// If no committed state, use the current state
|
||||
myPairingState = myPairingProcess.states[myPairingProcess.states.length - 1];
|
||||
console.log('Using current state instead of committed state');
|
||||
}
|
||||
|
||||
if (!myPairingState) {
|
||||
console.error('No state found in pairing process');
|
||||
return;
|
||||
}
|
||||
|
||||
const encodedSpAddressList = myPairingState.public_data['pairedAddresses'];
|
||||
if (!encodedSpAddressList) {
|
||||
console.error('No paired addresses found in state');
|
||||
return;
|
||||
}
|
||||
|
||||
const spAddressList = this.decodeValue(encodedSpAddressList);
|
||||
if (spAddressList.length === 0) {
|
||||
console.error('Empty pairedAddresses');
|
||||
return;
|
||||
}
|
||||
|
||||
// Test parsing côté Rust
|
||||
console.log('Checking if test_process_id_parsing is available:', typeof this.sdkClient.test_process_id_parsing);
|
||||
try {
|
||||
if (this.sdkClient.test_process_id_parsing) {
|
||||
const rustParseResult = this.sdkClient.test_process_id_parsing(pairingProcessId);
|
||||
console.log('Rust parsing test result:', rustParseResult);
|
||||
} else {
|
||||
console.error('test_process_id_parsing function not found in sdkClient');
|
||||
console.log('Available functions:', Object.keys(this.sdkClient).filter(key => typeof this.sdkClient[key] === 'function'));
|
||||
}
|
||||
} catch (rustParseError) {
|
||||
console.error('Rust parsing test failed:', rustParseError);
|
||||
}
|
||||
|
||||
this.sdkClient.unpair_device(); // Clear any existing pairing
|
||||
|
||||
try {
|
||||
this.sdkClient.pair_device(pairingProcessId, spAddressList);
|
||||
console.log('pair_device() call succeeded');
|
||||
} catch (pairError) {
|
||||
console.error('pair_device() failed:', pairError);
|
||||
throw pairError;
|
||||
}
|
||||
|
||||
// Verify pairing was successful
|
||||
const isPairedAfterPairing = this.sdkClient.is_paired();
|
||||
console.log('Is paired after pair_device call:', isPairedAfterPairing);
|
||||
|
||||
// Save the updated device
|
||||
const newDevice = this.dumpDeviceFromMemory();
|
||||
console.log('Device from memory after pairing:', {
|
||||
pairing_process_commitment: newDevice.pairing_process_commitment,
|
||||
paired_member: newDevice.paired_member
|
||||
});
|
||||
|
||||
// IMPORTANT: Only set pairing_process_commitment if WASM pairing succeeded
|
||||
if (isPairedAfterPairing) {
|
||||
console.log('WASM pairing succeeded, keeping WASM commitment');
|
||||
// Don't override - use what WASM set
|
||||
} else {
|
||||
console.log('WASM pairing failed, manually setting commitment');
|
||||
newDevice.pairing_process_commitment = pairingProcessId;
|
||||
}
|
||||
|
||||
await this.saveDeviceInDatabase(newDevice);
|
||||
|
||||
// Final verification
|
||||
const finalIsPaired = this.sdkClient.is_paired();
|
||||
console.log('Final is_paired status:', finalIsPaired);
|
||||
console.log('Device successfully paired with process:', pairingProcessId);
|
||||
|
||||
} catch (e) {
|
||||
console.error('Failed to confirm pairing');
|
||||
console.error('Failed to confirm pairing:', e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -852,17 +1010,34 @@ export default class Services {
|
||||
const db = await Database.getInstance();
|
||||
const walletStore = 'wallet';
|
||||
try {
|
||||
console.log('Saving device to database:', {
|
||||
pairing_process_commitment: device.pairing_process_commitment,
|
||||
paired_member: device.paired_member
|
||||
});
|
||||
|
||||
const prevDevice = await this.getDeviceFromDatabase();
|
||||
if (prevDevice) {
|
||||
console.log('Previous device found, deleting...');
|
||||
await db.deleteObject(walletStore, "1");
|
||||
}
|
||||
|
||||
await db.addObject({
|
||||
storeName: walletStore,
|
||||
object: { pre_id: '1', device },
|
||||
key: null,
|
||||
});
|
||||
|
||||
console.log('Device saved successfully');
|
||||
|
||||
// Verify save
|
||||
const savedDevice = await this.getDeviceFromDatabase();
|
||||
console.log('Verification - saved device:', {
|
||||
pairing_process_commitment: savedDevice?.pairing_process_commitment,
|
||||
paired_member: savedDevice?.paired_member
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error('Error saving device to database:', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,216 +1,227 @@
|
||||
import Services from '../services/service';
|
||||
import { getCorrectDOM } from './html.utils';
|
||||
import { addSubscription } from './subscription.utils';
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
//Copy Address
|
||||
export async function copyToClipboard(fullAddress: string) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(fullAddress);
|
||||
alert('Adresse copiée dans le presse-papiers !');
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the address: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
//Generate emojis list
|
||||
export function generateEmojiList(): string[] {
|
||||
const emojiRanges = [
|
||||
[0x1f600, 0x1f64f],
|
||||
[0x1f300, 0x1f5ff],
|
||||
[0x1f680, 0x1f6ff],
|
||||
[0x1f700, 0x1f77f],
|
||||
];
|
||||
|
||||
const emojiList: string[] = [];
|
||||
for (const range of emojiRanges) {
|
||||
const [start, end] = range;
|
||||
for (let i = start; i <= end && emojiList.length < 256; i++) {
|
||||
emojiList.push(String.fromCodePoint(i));
|
||||
}
|
||||
if (emojiList.length >= 256) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return emojiList.slice(0, 256);
|
||||
}
|
||||
|
||||
//Adress to emojis
|
||||
export async function addressToEmoji(text: string): Promise<string> {
|
||||
//Adress to Hash
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(text);
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||
|
||||
const hash = new Uint8Array(hashBuffer);
|
||||
const bytes = hash.slice(-4);
|
||||
|
||||
//Hash slice to emojis
|
||||
const emojiList = generateEmojiList();
|
||||
const emojis = Array.from(bytes)
|
||||
.map((byte) => emojiList[byte])
|
||||
.join('');
|
||||
return emojis;
|
||||
}
|
||||
|
||||
//Get emojis from other device
|
||||
async function emojisPairingRequest() {
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||
|
||||
const urlParams: URLSearchParams = new URLSearchParams(window.location.search);
|
||||
const sp_adress: string | null = urlParams.get('sp_address');
|
||||
|
||||
if (!sp_adress) {
|
||||
// console.error("No 'sp_adress' parameter found in the URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = await addressToEmoji(sp_adress);
|
||||
const emojiDisplay = container?.querySelector('.pairing-request');
|
||||
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.textContent = '(Request from: ' + emojis + ')';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Display address emojis and other device emojis
|
||||
export async function displayEmojis(text: string) {
|
||||
console.log('🚀 ~ Services ~ adressToEmoji');
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||
const emojis = await addressToEmoji(text);
|
||||
const emojiDisplay = container?.querySelector('.emoji-display');
|
||||
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.textContent = emojis;
|
||||
}
|
||||
|
||||
emojisPairingRequest();
|
||||
|
||||
initAddressInput();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify Other address
|
||||
export function initAddressInput() {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
|
||||
const emojiDisplay = container.querySelector('#emoji-display-2');
|
||||
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
|
||||
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
|
||||
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
|
||||
addSubscription(addressInput, 'input', async () => {
|
||||
let address = addressInput.value;
|
||||
|
||||
// Vérifie si l'adresse est une URL
|
||||
try {
|
||||
const url = new URL(address);
|
||||
// Si c'est une URL valide, extraire le paramètre sp_address
|
||||
const urlParams = new URLSearchParams(url.search);
|
||||
const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide
|
||||
|
||||
if (extractedAddress) {
|
||||
address = extractedAddress;
|
||||
addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite
|
||||
}
|
||||
} catch (e) {
|
||||
// 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.");
|
||||
}
|
||||
if (address) {
|
||||
const emojis = await addressToEmoji(address);
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.innerHTML = emojis;
|
||||
}
|
||||
if (okButton) {
|
||||
okButton.style.display = 'inline-block';
|
||||
}
|
||||
} else {
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.innerHTML = '';
|
||||
}
|
||||
if (okButton) {
|
||||
okButton.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (createButton) {
|
||||
addSubscription(createButton, 'click', () => {
|
||||
onCreateButtonClick();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function onCreateButtonClick() {
|
||||
try {
|
||||
await prepareAndSendPairingTx();
|
||||
const service = await Services.getInstance();
|
||||
await service.confirmPairing();
|
||||
} catch (e) {
|
||||
console.error(`onCreateButtonClick error: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function prepareAndSendPairingTx(): Promise<void> {
|
||||
const service = await Services.getInstance();
|
||||
|
||||
try {
|
||||
await service.checkConnections([]);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
const relayAddress = service.getAllRelays();
|
||||
const createPairingProcessReturn = await service.createPairingProcess(
|
||||
"",
|
||||
[],
|
||||
);
|
||||
|
||||
if (!createPairingProcessReturn.updated_process) {
|
||||
throw new Error('createPairingProcess returned an empty new process');
|
||||
}
|
||||
|
||||
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
||||
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||
|
||||
await service.handleApiReturn(createPairingProcessReturn);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateQRCode(spAddress: string) {
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const currentUrl = 'https://' + window.location.host;
|
||||
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
|
||||
const qrCode = container?.querySelector('.qr-code img');
|
||||
qrCode?.setAttribute('src', url);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateCreateBtn() {
|
||||
try{
|
||||
//Generate CreateBtn
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const createBtn = container?.querySelector('.create-btn');
|
||||
if (createBtn) {
|
||||
createBtn.textContent = 'CREATE';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
import Services from '../services/service';
|
||||
import { getCorrectDOM } from './html.utils';
|
||||
import { addSubscription } from './subscription.utils';
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
//Copy Address
|
||||
export async function copyToClipboard(fullAddress: string) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(fullAddress);
|
||||
alert('Adresse copiée dans le presse-papiers !');
|
||||
} catch (err) {
|
||||
console.error('Failed to copy the address: ', err);
|
||||
}
|
||||
}
|
||||
|
||||
//Generate emojis list
|
||||
export function generateEmojiList(): string[] {
|
||||
const emojiRanges = [
|
||||
[0x1f600, 0x1f64f],
|
||||
[0x1f300, 0x1f5ff],
|
||||
[0x1f680, 0x1f6ff],
|
||||
[0x1f700, 0x1f77f],
|
||||
];
|
||||
|
||||
const emojiList: string[] = [];
|
||||
for (const range of emojiRanges) {
|
||||
const [start, end] = range;
|
||||
for (let i = start; i <= end && emojiList.length < 256; i++) {
|
||||
emojiList.push(String.fromCodePoint(i));
|
||||
}
|
||||
if (emojiList.length >= 256) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return emojiList.slice(0, 256);
|
||||
}
|
||||
|
||||
//Adress to emojis
|
||||
export async function addressToEmoji(text: string): Promise<string> {
|
||||
//Adress to Hash
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(text);
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||
|
||||
const hash = new Uint8Array(hashBuffer);
|
||||
const bytes = hash.slice(-4);
|
||||
|
||||
//Hash slice to emojis
|
||||
const emojiList = generateEmojiList();
|
||||
const emojis = Array.from(bytes)
|
||||
.map((byte) => emojiList[byte])
|
||||
.join('');
|
||||
return emojis;
|
||||
}
|
||||
|
||||
//Get emojis from other device
|
||||
async function emojisPairingRequest() {
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||
|
||||
const urlParams: URLSearchParams = new URLSearchParams(window.location.search);
|
||||
const sp_adress: string | null = urlParams.get('sp_address');
|
||||
|
||||
if (!sp_adress) {
|
||||
// console.error("No 'sp_adress' parameter found in the URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = await addressToEmoji(sp_adress);
|
||||
const emojiDisplay = container?.querySelector('.pairing-request');
|
||||
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.textContent = '(Request from: ' + emojis + ')';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Display address emojis and other device emojis
|
||||
export async function displayEmojis(text: string) {
|
||||
console.log('🚀 ~ Services ~ adressToEmoji');
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||
const emojis = await addressToEmoji(text);
|
||||
const emojiDisplay = container?.querySelector('.emoji-display');
|
||||
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.textContent = emojis;
|
||||
}
|
||||
|
||||
emojisPairingRequest();
|
||||
|
||||
initAddressInput();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify Other address
|
||||
export function initAddressInput() {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
|
||||
const emojiDisplay = container.querySelector('#emoji-display-2');
|
||||
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
|
||||
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
|
||||
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
|
||||
addSubscription(addressInput, 'input', async () => {
|
||||
let address = addressInput.value;
|
||||
|
||||
// Vérifie si l'adresse est une URL
|
||||
try {
|
||||
const url = new URL(address);
|
||||
// Si c'est une URL valide, extraire le paramètre sp_address
|
||||
const urlParams = new URLSearchParams(url.search);
|
||||
const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide
|
||||
|
||||
if (extractedAddress) {
|
||||
address = extractedAddress;
|
||||
addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite
|
||||
}
|
||||
} catch (e) {
|
||||
// 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.");
|
||||
}
|
||||
if (address) {
|
||||
const emojis = await addressToEmoji(address);
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.innerHTML = emojis;
|
||||
}
|
||||
if (okButton) {
|
||||
okButton.style.display = 'inline-block';
|
||||
}
|
||||
} else {
|
||||
if (emojiDisplay) {
|
||||
emojiDisplay.innerHTML = '';
|
||||
}
|
||||
if (okButton) {
|
||||
okButton.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (createButton) {
|
||||
addSubscription(createButton, 'click', () => {
|
||||
onCreateButtonClick();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function onCreateButtonClick() {
|
||||
try {
|
||||
await prepareAndSendPairingTx();
|
||||
// Don't call confirmPairing immediately - it will be called when the pairing process is complete
|
||||
console.log('Pairing process initiated. Waiting for completion...');
|
||||
} catch (e) {
|
||||
console.error(`onCreateButtonClick error: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function prepareAndSendPairingTx(): Promise<void> {
|
||||
const service = await Services.getInstance();
|
||||
|
||||
try {
|
||||
const relayAddress = service.getAllRelays();
|
||||
const createPairingProcessReturn = await service.createPairingProcess(
|
||||
"",
|
||||
[],
|
||||
);
|
||||
|
||||
if (!createPairingProcessReturn.updated_process) {
|
||||
throw new Error('createPairingProcess returned an empty new process');
|
||||
}
|
||||
|
||||
try {
|
||||
await service.checkConnections(createPairingProcessReturn.updated_process.current_process, createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
||||
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||
|
||||
// Update device.pairing_process_commitment with the process_id
|
||||
try {
|
||||
const currentDevice = await service.getDeviceFromDatabase();
|
||||
if (currentDevice) {
|
||||
currentDevice.pairing_process_commitment = createPairingProcessReturn.updated_process.process_id;
|
||||
await service.saveDeviceInDatabase(currentDevice);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to update device pairing_process_commitment:', err);
|
||||
}
|
||||
|
||||
await service.handleApiReturn(createPairingProcessReturn);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateQRCode(spAddress: string) {
|
||||
try {
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const currentUrl = 'https://' + window.location.host;
|
||||
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
|
||||
const qrCode = container?.querySelector('.qr-code img');
|
||||
qrCode?.setAttribute('src', url);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateCreateBtn() {
|
||||
try{
|
||||
//Generate CreateBtn
|
||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||
const createBtn = container?.querySelector('.create-btn');
|
||||
if (createBtn) {
|
||||
createBtn.textContent = 'CREATE';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user