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