One device pairing
This commit is contained in:
parent
2855365851
commit
f2e2aeaa9a
@ -135,37 +135,63 @@ export async function init(): Promise<void> {
|
||||
const services = await Services.getInstance();
|
||||
(window as any).myService = services;
|
||||
await Database.getInstance();
|
||||
setTimeout(async () => {
|
||||
let device = await services.getDeviceFromDatabase();
|
||||
console.log('🚀 ~ setTimeout ~ device:', device);
|
||||
let device = await services.getDeviceFromDatabase();
|
||||
console.log('🚀 ~ setTimeout ~ device:', device);
|
||||
|
||||
if (!device) {
|
||||
device = await services.createNewDevice();
|
||||
} else {
|
||||
services.restoreDevice(device);
|
||||
if (!device) {
|
||||
device = await services.createNewDevice();
|
||||
} else {
|
||||
services.restoreDevice(device);
|
||||
}
|
||||
await services.restoreProcessesFromDB();
|
||||
await services.restoreSecretsFromDB();
|
||||
|
||||
// If we have a service redirection flag, we intercept it here
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const source = urlParams.get('source');
|
||||
|
||||
if (source === "lecoffre") {
|
||||
console.log('Detected source \'lecoffre\'')
|
||||
// We pair first if necessary
|
||||
if (!services.isPaired()) {
|
||||
await prepareAndSendPairingTx(false);
|
||||
await services.confirmPairing();
|
||||
}
|
||||
await services.restoreProcessesFromDB();
|
||||
await services.restoreSecretsFromDB();
|
||||
|
||||
if (services.isPaired()) {
|
||||
await navigate('chat');
|
||||
} else {
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const pairingAddress = urlParams.get('sp_address');
|
||||
if (pairingAddress) {
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
// check if we have a shared secret with that address
|
||||
await prepareAndSendPairingTx(pairingAddress);
|
||||
} catch (e) {
|
||||
console.error('Failed to pair:', e);
|
||||
}
|
||||
}, 2000);
|
||||
// pop up to inform user that they will be redirected to lecoffre with their 4nk identity
|
||||
alert("User successfully created, you will be redirected to lecoffre.io");
|
||||
// Once paired we get a copy of the device without the spend key
|
||||
const neuteredDevice = services.dumpNeuteredDevice();
|
||||
if (!neuteredDevice) {
|
||||
console.error('Failed to get a neutered device');
|
||||
return;
|
||||
}
|
||||
await navigate('home');
|
||||
// We send the neutered device to the main frame
|
||||
window.parent.postMessage({ type: 'RESPONSE', payload: JSON.stringify(neuteredDevice) }, 'https://lecoffreio.4nkweb.com');
|
||||
}
|
||||
}, 200);
|
||||
} else {
|
||||
console.log('No source provided');
|
||||
}
|
||||
|
||||
if (services.isPaired()) {
|
||||
await navigate('account');
|
||||
} else {
|
||||
const pairingAddress = urlParams.get('sp_address');
|
||||
if (pairingAddress) {
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
// check if we have a shared secret with that address
|
||||
await prepareAndSendPairingTx(pairingAddress);
|
||||
} catch (e) {
|
||||
console.error('Failed to pair:', e);
|
||||
}
|
||||
await navigate('account');
|
||||
}, 2000);
|
||||
}
|
||||
console.log('here');
|
||||
await navigate('home');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
await navigate('home');
|
||||
|
@ -164,93 +164,37 @@ export default class ModalService {
|
||||
if (this.modal) this.modal.style.display = 'none';
|
||||
}
|
||||
|
||||
async confirmPairing() {
|
||||
const service = await Services.getInstance();
|
||||
if (this.modal) this.modal.style.display = 'none';
|
||||
// async confirmPairing() {
|
||||
// const service = await Services.getInstance();
|
||||
// if (this.modal) this.modal.style.display = 'none';
|
||||
|
||||
if (service.device1) {
|
||||
console.log("Device 1 detected");
|
||||
// We send the prd update
|
||||
if (this.stateId && this.processId) {
|
||||
try {
|
||||
// Device B shouldn't do this again
|
||||
const createPrdUpdateReturn = service.createPrdUpdate(this.processId, this.stateId);
|
||||
await service.handleApiReturn(createPrdUpdateReturn);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
throw new Error('No currentPcdCommitment');
|
||||
}
|
||||
// // We send the prd update
|
||||
// if (this.stateId && this.processId) {
|
||||
// try {
|
||||
// const createPrdUpdateReturn = service.createPrdUpdate(this.processId, this.stateId);
|
||||
// await service.handleApiReturn(createPrdUpdateReturn);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// }
|
||||
// } else {
|
||||
// throw new Error('No currentPcdCommitment');
|
||||
// }
|
||||
|
||||
// We send confirmation that we validate the change
|
||||
try {
|
||||
const approveChangeReturn = await service.approveChange(this.processId!, this.stateId!);
|
||||
await service.handleApiReturn(approveChangeReturn);
|
||||
// try {
|
||||
// const approveChangeReturn = await service.approveChange(this.processId!, this.stateId!);
|
||||
// await service.handleApiReturn(approveChangeReturn);
|
||||
|
||||
await this.injectWaitingModal();
|
||||
const waitingModal = document.getElementById('waiting-modal');
|
||||
if (waitingModal) waitingModal.style.display = 'flex';
|
||||
|
||||
if (!service.device2Ready) {
|
||||
while (!service.device2Ready) {
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
console.log("Device 2 is ready - Device 1 can now proceed");
|
||||
}
|
||||
service.pairDevice(this.paired_addresses, this.processId);
|
||||
this.paired_addresses = [];
|
||||
this.processId = null;
|
||||
this.stateId = null;
|
||||
const newDevice = service.dumpDeviceFromMemory();
|
||||
console.log(newDevice);
|
||||
await service.saveDeviceInDatabase(newDevice);
|
||||
navigate('chat');
|
||||
service.resetState();
|
||||
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
// try {
|
||||
// service.pairDevice(this.paired_addresses);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// }
|
||||
} else {
|
||||
console.log("Device 2 detected");
|
||||
|
||||
// if (this.stateId && this.processId) {
|
||||
// try {
|
||||
// // Device B shouldn't do this again
|
||||
// const createPrdUpdateReturn = service.createPrdUpdate(this.processId, this.stateId);
|
||||
// await service.handleApiReturn(createPrdUpdateReturn);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// }
|
||||
// } else {
|
||||
// throw new Error('No currentPcdCommitment');
|
||||
// }
|
||||
|
||||
// We send confirmation that we validate the change
|
||||
try {
|
||||
const approveChangeReturn = await service.approveChange(this.processId!, this.stateId!);
|
||||
await service.handleApiReturn(approveChangeReturn);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
service.pairDevice(this.paired_addresses, this.processId!);
|
||||
|
||||
this.paired_addresses = [];
|
||||
this.processId = null;
|
||||
this.stateId = null;
|
||||
const newDevice = service.dumpDeviceFromMemory();
|
||||
console.log(newDevice);
|
||||
await service.saveDeviceInDatabase(newDevice);
|
||||
navigate('chat');
|
||||
}
|
||||
}
|
||||
// service.pairDevice(this.paired_addresses, this.processId);
|
||||
// this.paired_addresses = [];
|
||||
// this.processId = null;
|
||||
// this.stateId = null;
|
||||
// const newDevice = service.dumpDeviceFromMemory();
|
||||
// console.log(newDevice);
|
||||
// await service.saveDeviceInDatabase(newDevice);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// }
|
||||
// }
|
||||
|
||||
async closeConfirmationModal() {
|
||||
const service = await Services.getInstance();
|
||||
|
@ -20,8 +20,8 @@ const EMPTY32BYTES = String('').padStart(64, '0');
|
||||
export default class Services {
|
||||
private static initializing: Promise<Services> | null = null;
|
||||
private static instance: Services;
|
||||
private currentProcess: string | null = null;
|
||||
private currentUpdateMerkleRoot: string | null = null;
|
||||
private processId: string | null = null;
|
||||
private stateId: string | null = null;
|
||||
private sdkClient: any;
|
||||
private myProcesses: Set = new Set();
|
||||
private notifications: any[] | null = null;
|
||||
@ -64,6 +64,24 @@ export default class Services {
|
||||
await this.connectAllRelays();
|
||||
}
|
||||
|
||||
public setProcessId(processId: string | null) {
|
||||
console.log('this.processId', this.processId);
|
||||
this.processId = processId;
|
||||
}
|
||||
|
||||
public setStateId(stateId: string | null) {
|
||||
console.log('this.stateId', this.stateId);
|
||||
this.stateId = stateId;
|
||||
}
|
||||
|
||||
public getProcessId(): string | null {
|
||||
return this.processId;
|
||||
}
|
||||
|
||||
public getStateId(): string | null {
|
||||
return this.stateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `this.addWebsocketConnection` for each `wsurl` in relayAddresses.
|
||||
*/
|
||||
@ -246,11 +264,11 @@ export default class Services {
|
||||
pairWith.push(myAddress);
|
||||
const roles: Record<string, RoleDefinition> = {
|
||||
pairing: {
|
||||
members: [{ sp_addresses: pairWith }],
|
||||
members: [],
|
||||
validation_rules: [
|
||||
{
|
||||
quorum: 1.0,
|
||||
fields: ['description', 'counter', 'roles', 'memberPublicName'],
|
||||
fields: ['description', 'counter', 'roles', 'memberPublicName', 'pairedAddresses'],
|
||||
min_sig_member: 1.0,
|
||||
},
|
||||
],
|
||||
@ -262,15 +280,17 @@ export default class Services {
|
||||
counter: 0,
|
||||
};
|
||||
const publicData = {
|
||||
memberPublicName: userName
|
||||
}
|
||||
memberPublicName: userName,
|
||||
pairedAddresses: pairWith,
|
||||
};
|
||||
try {
|
||||
return this.sdkClient.create_new_process(
|
||||
pairingTemplate,
|
||||
roles,
|
||||
publicData,
|
||||
relayAddress,
|
||||
feeRate
|
||||
feeRate,
|
||||
this.getAllMembers()
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(`Creating process failed:, ${e}`);
|
||||
@ -719,9 +739,51 @@ export default class Services {
|
||||
}
|
||||
}
|
||||
|
||||
pairDevice(spAddressList: string[], pairingProcess: string) {
|
||||
public async confirmPairing() {
|
||||
if (!this.processId || !this.stateId) {
|
||||
console.error('Missing process and/or state ID');
|
||||
return;
|
||||
}
|
||||
let createPrdUpdateReturn;
|
||||
try {
|
||||
this.sdkClient.pair_device(pairingProcess, spAddressList);
|
||||
createPrdUpdateReturn = await this.createPrdUpdate(this.processId, this.stateId);
|
||||
} catch (e) {
|
||||
throw new Error(`createPrdUpdate failed: ${e}`);
|
||||
}
|
||||
await this.handleApiReturn(createPrdUpdateReturn);
|
||||
|
||||
let approveChangeReturn;
|
||||
try {
|
||||
approveChangeReturn = await this.approveChange(this.processId, this.stateId);
|
||||
} catch (e) {
|
||||
throw new Error(`approveChange failed: ${e}`);
|
||||
}
|
||||
await this.handleApiReturn(approveChangeReturn);
|
||||
|
||||
await this.pairDevice();
|
||||
|
||||
this.processId = null;
|
||||
this.stateId = null;
|
||||
const newDevice = this.dumpDeviceFromMemory();
|
||||
console.log(newDevice);
|
||||
await this.saveDeviceInDatabase(newDevice);
|
||||
navigate('account');
|
||||
}
|
||||
|
||||
public async pairDevice() {
|
||||
if (!this.processId) {
|
||||
console.error('No processId set');
|
||||
return;
|
||||
}
|
||||
const process = await this.getProcess(this.processId);
|
||||
if (!process) {
|
||||
console.error('Unknown process');
|
||||
return;
|
||||
}
|
||||
const spAddressList = process.states[0].public_data['pairedAddresses'];
|
||||
console.log(spAddressList);
|
||||
try {
|
||||
this.sdkClient.pair_device(this.processId, spAddressList);
|
||||
} catch (e) {
|
||||
throw new Error(`Failed to pair device: ${e}`);
|
||||
}
|
||||
|
@ -168,17 +168,16 @@ async function onOkButtonClick() {
|
||||
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(promptName: boolean = false) {
|
||||
export async function prepareAndSendPairingTx(promptName: boolean = false): Promise<void> {
|
||||
const service = await Services.getInstance();
|
||||
|
||||
// Device 1 wait Device 2
|
||||
// service.device1 = true;
|
||||
|
||||
try {
|
||||
await service.checkConnections([]);
|
||||
} catch (e) {
|
||||
@ -193,11 +192,8 @@ export async function prepareAndSendPairingTx(promptName: boolean = false) {
|
||||
userName = "";
|
||||
}
|
||||
|
||||
// Create the process after a delay.
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const relayAddress = service.getAllRelays();
|
||||
|
||||
// Pass the userName as an additional parameter.
|
||||
const createPairingProcessReturn = await service.createPairingProcess(
|
||||
userName,
|
||||
[],
|
||||
@ -207,11 +203,17 @@ export async function prepareAndSendPairingTx(promptName: boolean = false) {
|
||||
);
|
||||
|
||||
if (!createPairingProcessReturn.updated_process) {
|
||||
throw new Error('createPairingProcess returned an empty new process'); // This should never happen
|
||||
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);
|
||||
}, 1000);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateQRCode(spAddress: string) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user