163 lines
5.6 KiB
TypeScript
Executable File
163 lines
5.6 KiB
TypeScript
Executable File
import modalHtml from '../components/login-modal/login-modal.html?raw';
|
|
import modalScript from '../components/login-modal/login-modal.js?raw';
|
|
import Services from './service';
|
|
import { U32_MAX } from './service';
|
|
import { navigate } from '../router';
|
|
import { addressToEmoji } from '../utils/sp-address.utils';
|
|
import { RoleDefinition } from 'dist/pkg/sdk_client';
|
|
|
|
export default class ModalService {
|
|
private static instance: ModalService;
|
|
private currentPcdCommitment: string | null = null;
|
|
private currentOutpoint: string | null = null;
|
|
private constructor() {}
|
|
private paired_addresses: string[] = [];
|
|
|
|
// Method to access the singleton instance of Services
|
|
public static async getInstance(): Promise<ModalService> {
|
|
if (!ModalService.instance) {
|
|
ModalService.instance = new ModalService();
|
|
}
|
|
return ModalService.instance;
|
|
}
|
|
|
|
public openLoginModal(myAddress: string, receiverAddress: string) {
|
|
const container = document.querySelector('.page-container');
|
|
let html = modalHtml;
|
|
html = html.replace('{{device1}}', myAddress);
|
|
html = html.replace('{{device2}}', receiverAddress);
|
|
if (container) container.innerHTML += html;
|
|
const modal = document.getElementById('login-modal');
|
|
if (modal) modal.style.display = 'flex';
|
|
const newScript = document.createElement('script');
|
|
|
|
newScript.setAttribute('type', 'module');
|
|
newScript.textContent = modalScript;
|
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
|
}
|
|
|
|
async injectModal(members: any[]) {
|
|
const container = document.querySelector('.page-container');
|
|
if (container) {
|
|
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('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1]));
|
|
container.innerHTML += html;
|
|
|
|
// Dynamically load the header JS
|
|
const script = document.createElement('script');
|
|
script.src = '/src/components/modal/confirmation-modal.ts';
|
|
script.type = 'module';
|
|
document.head.appendChild(script);
|
|
}
|
|
}
|
|
|
|
// this is kind of too specific for pairing though
|
|
public async openConfirmationModal(pcd: any, commitmentTx: string, merkleRoot: string) {
|
|
let map: Record<string, RoleDefinition>;
|
|
if (pcd['roles']) {
|
|
const roles = pcd['roles'];
|
|
try {
|
|
map = JSON.parse(roles);
|
|
} catch (e) {
|
|
throw new Error(`Failed to parse roles: ${e}`);
|
|
}
|
|
} else {
|
|
throw new Error('Pcd doesn\'t have a \"roles\" field');
|
|
}
|
|
|
|
// pairing specifics
|
|
let members;
|
|
if (map['owner']) {
|
|
const owner = map['owner'];
|
|
members = owner.members;
|
|
} else {
|
|
throw new Error('No \"owner\" role');
|
|
}
|
|
|
|
// pairing specifics
|
|
if (members.length != 1) {
|
|
throw new Error('Must have exactly 1 member');
|
|
}
|
|
|
|
// We take all the addresses except our own
|
|
const service = await Services.getInstance();
|
|
const localAddress = await service.getDeviceAddress();
|
|
console.log('🚀 ~ Routing ~ openConfirmationModal ~ pcd:', pcd);
|
|
for (const member of members) {
|
|
for (const address of member['sp_addresses']) {
|
|
if (address !== localAddress) {
|
|
this.paired_addresses.push(address);
|
|
}
|
|
}
|
|
}
|
|
this.currentOutpoint = commitmentTx;
|
|
this.currentPcdCommitment = merkleRoot;
|
|
await this.injectModal(members);
|
|
const modal = document.getElementById('modal');
|
|
if (modal) modal.style.display = 'flex';
|
|
// const newScript = document.createElement('script');
|
|
// newScript.setAttribute('type', 'module');
|
|
// newScript.textContent = confirmationModalScript;
|
|
// document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
|
|
|
// Add correct text
|
|
|
|
// Close modal when clicking outside of it
|
|
window.onclick = (event) => {
|
|
const modal = document.getElementById('modal');
|
|
if (event.target === modal) {
|
|
this.closeConfirmationModal();
|
|
}
|
|
};
|
|
}
|
|
confirmLogin() {
|
|
console.log('=============> Confirm Login');
|
|
}
|
|
async closeLoginModal() {
|
|
const modal = document.getElementById('login-modal');
|
|
if (modal) modal.style.display = 'none';
|
|
}
|
|
|
|
async confirmPairing() {
|
|
const service = await Services.getInstance();
|
|
const modal = document.getElementById('modal');
|
|
if (modal) modal.style.display = 'none';
|
|
|
|
// We send the prd update
|
|
if (this.currentPcdCommitment) {
|
|
try {
|
|
const createPrdUpdateReturn = await service.createPrdUpdate(this.currentPcdCommitment);
|
|
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.currentPcdCommitment!);
|
|
await service.handleApiReturn(approveChangeReturn);
|
|
} catch (e) {
|
|
throw e
|
|
}
|
|
|
|
service.pairDevice(this.paired_addresses);
|
|
this.paired_addresses = [];
|
|
this.currentOutpoint = null;
|
|
this.currentPcdCommitment = null;
|
|
const newDevice = service.dumpDevice();
|
|
await service.saveDevice(newDevice);
|
|
navigate('process');
|
|
}
|
|
|
|
async closeConfirmationModal() {
|
|
const service = await Services.getInstance();
|
|
await service.unpairDevice();
|
|
const modal = document.getElementById('modal');
|
|
if (modal) modal.style.display = 'none';
|
|
}
|
|
}
|