merge_code

This commit is contained in:
Pascal 2024-11-26 13:50:52 +01:00
commit a190221e32
5 changed files with 94 additions and 47 deletions

View File

@ -56,10 +56,13 @@ async function onScanSuccess(decodedText: any, decodedResult: any) {
const service = await Services.getInstance(); const service = await Services.getInstance();
// Call the sendPairingTx function with the extracted sp_address // Call the sendPairingTx function with the extracted sp_address
try { try {
const sharedSecret = await service.getSecretForAddress(spAddress);
if (!sharedSecret) {
const member = { const member = {
sp_addresses: [spAddress], sp_addresses: [spAddress],
} }
await service.connectMember([member]); await service.connectMember([member]);
}
// await service.sendPairingTx(spAddress); // await service.sendPairingTx(spAddress);
} catch (e) { } catch (e) {
console.error('Failed to pair:', e); console.error('Failed to pair:', e);

View File

@ -113,9 +113,12 @@ async function init(): Promise<void> {
const pairingAddress = urlParams.get('sp_address'); const pairingAddress = urlParams.get('sp_address');
if (pairingAddress) { if (pairingAddress) {
setTimeout(async () => { setTimeout(async () => {
// await services.sendPairingTx(pairingAddress)
try { try {
// check if we have a shared secret with that address
const sharedSecret = await services.getSecretForAddress(pairingAddress);
if (!sharedSecret) {
await services.connectMember([{sp_addresses: [pairingAddress]}]); await services.connectMember([{sp_addresses: [pairingAddress]}]);
}
} catch (e) { } catch (e) {
console.error('Failed to pair:', e); console.error('Failed to pair:', e);
} }

View File

@ -4,11 +4,12 @@ import Services from './service';
import { U32_MAX } from './service'; import { U32_MAX } from './service';
import { navigate } from '../router'; import { navigate } from '../router';
import { addressToEmoji } from '../utils/sp-address.utils'; import { addressToEmoji } from '../utils/sp-address.utils';
import { RoleDefinition } from 'dist/pkg/sdk_client';
export default class ModalService { export default class ModalService {
private static instance: ModalService; private static instance: ModalService;
private currentPrd: any; private currentPrd: any;
private currentOutpoint?: string; private currentOutpoint: string | null = null;
private constructor() {} private constructor() {}
private paired_addresses: string[] = []; private paired_addresses: string[] = [];
@ -51,11 +52,31 @@ export default class ModalService {
} }
} }
public async openConfirmationModal(pcd: any, outpointCommitment: string) { public async openConfirmationModal(pcd: any, commitmentTx: string) {
let roles = JSON.parse(pcd['roles']); // ['members'][0]; let map: Record<string, RoleDefinition>;
console.log(roles); if (pcd['roles']) {
let members = roles['owner']['members']; const roles = pcd['roles'];
console.log(members); 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');
}
let members;
if (map['owner']) {
const owner = map['owner'];
members = owner.members;
} else {
throw new Error('No \"owner\" role');
}
if (members.length != 1) {
throw new Error('Must have exactly 1 member');
}
// 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 = await service.getDeviceAddress(); const localAddress = await service.getDeviceAddress();
@ -65,6 +86,7 @@ export default class ModalService {
this.paired_addresses.push(address); this.paired_addresses.push(address);
} }
} }
this.currentOutpoint = commitmentTx;
await this.injectModal(members); await this.injectModal(members);
const modal = document.getElementById('modal'); const modal = document.getElementById('modal');
if (modal) modal.style.display = 'flex'; if (modal) modal.style.display = 'flex';
@ -96,13 +118,15 @@ export default class ModalService {
const modal = document.getElementById('modal'); const modal = document.getElementById('modal');
// console.log("🚀 ~ Routing ~ confirm ~ prd:", prd) // console.log("🚀 ~ Routing ~ confirm ~ prd:", prd)
if (modal) modal.style.display = 'none'; if (modal) modal.style.display = 'none';
// Just make an empty commitment for now
const emptyTxid = '0'.repeat(64); if (this.currentOutpoint === null || this.paired_addresses.length === 0) {
const commitmentOutpoint = `${emptyTxid}:${U32_MAX}`; throw new Error('Missing outpoint and/or paired addresses');
}
// We take the paired device(s) from the contract // We take the paired device(s) from the contract
await service.pairDevice(commitmentOutpoint, this.paired_addresses); await service.pairDevice(this.currentOutpoint, this.paired_addresses);
this.paired_addresses = []; this.paired_addresses = [];
this.currentOutpoint = null;
const newDevice = await service.dumpDevice(); const newDevice = await service.dumpDevice();
await service.saveDevice(newDevice); await service.saveDevice(newDevice);
navigate('process'); navigate('process');

View File

@ -103,6 +103,11 @@ export default class Services {
return apiReturn; return apiReturn;
} }
public async getSecretForAddress(address: string): Promise<string | null> {
const db = await Database.getInstance();
return await db.getObject('shared_secrets', address);
}
public async connectMember(members: Member[]): Promise<void> { public async connectMember(members: Member[]): Promise<void> {
if (members.length === 0) { if (members.length === 0) {
throw new Error('Trying to connect to empty members list'); throw new Error('Trying to connect to empty members list');
@ -147,24 +152,35 @@ export default class Services {
} }
} }
public async sendPairingTx(spAddress: string): Promise<void> { public async createPairingProcess(pairWith: string[], relayAddress: string, feeRate: number): Promise<void> {
const localAddress = this.sdkClient.get_address(); const myAddress: string = this.sdkClient.get_address();
const emptyTxid = '0'.repeat(64); pairWith.push(myAddress);
const newKey = this.sdkClient.get_new_keypair();
const pairingTemplate = {
description: 'pairing',
roles: {
owner: {
members: [{ sp_addresses: pairWith }],
validation_rules: [
{
quorum: 1.0,
fields: ['description', 'roles', 'session_privkey', 'session_pubkey', 'key_parity'],
min_sig_member: 1.0,
},
],
},
},
session_privkey: newKey['private_key'],
session_pubkey: newKey['x_only_public_key'],
key_parity: newKey['key_parity'],
};
try { try {
let commitmentOutpoint = `${emptyTxid}:${U32_MAX}`; const newProcessReturn = this.sdkClient.create_new_process(JSON.stringify(pairingTemplate), relayAddress, feeRate);
this.sdkClient.pair_device(commitmentOutpoint, [spAddress]); console.log('newProcessReturn:', newProcessReturn);
await this.handleApiReturn(newProcessReturn);
} catch (e) { } catch (e) {
console.error('Services ~ Error:', e); throw new Error(`Creating process failed:, ${e}`);
return;
} }
setTimeout(async () => {
const apiReturn = this.prepareProcessTx(localAddress, spAddress);
await this.handleApiReturn(apiReturn);
}, 1500);
return;
} }
async resetDevice() { async resetDevice() {
@ -252,25 +268,23 @@ export default class Services {
setTimeout(async () => { setTimeout(async () => {
if (apiReturn.updated_process && apiReturn.updated_process.length) { if (apiReturn.updated_process && apiReturn.updated_process.length) {
const [processCommitment, process] = apiReturn.updated_process; const [commitmentTx, process] = apiReturn.updated_process;
console.debug('Updated Process Commitment:', processCommitment);
console.debug('Process Details:', process);
// Save process to storage // Save process to storage
localStorage.setItem(processCommitment, JSON.stringify(process));
const db = await Database.getInstance(); const db = await Database.getInstance();
db.addObject({ db.addObject({
storeName: 'process', storeName: 'process',
object: { id: processCommitment, process }, object: { id: commitmentTx, process },
key: processCommitment, key: null,
}); });
// Check if the newly updated process reveals some new information // Check if the newly updated process reveals some new information
try { try {
const proposals: string[] = this.sdkClient.get_update_proposals(processCommitment); const proposals: ApiReturn = this.sdkClient.get_update_proposals(commitmentTx);
if (proposals && proposals.length != 0) { const decrypted_pcds = proposals.decrypted_pcds;
const actual_proposal = JSON.parse(proposals[0]); // We just don't acknowledge concurrent proposals for now if (decrypted_pcds && decrypted_pcds.length != 0) {
console.info(actual_proposal); for (const actual_proposal of Object.values(decrypted_pcds)) {
await this.routingInstance.openConfirmationModal(actual_proposal, processCommitment); await this.routingInstance.openConfirmationModal(actual_proposal, commitmentTx);
}
} }
} catch (e) { } catch (e) {
console.error(e); console.error(e);

View File

@ -148,12 +148,15 @@ export function initAddressInput() {
async function onOkButtonClick() { async function onOkButtonClick() {
const service = await Services.getInstance(); const service = await Services.getInstance();
const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value; const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value;
try {
const sharedSecret = await service.getSecretForAddress(addressInput);
if (!sharedSecret) {
const member = { const member = {
sp_addresses: [addressInput], sp_addresses: [addressInput],
} }
try {
await service.connectMember([member]); await service.connectMember([member]);
// await service.sendPairingTx(addressInput); }
await service.createPairingProcess([addressInput], "sprt1qqdg4x69xdyhxpz4weuel0985qyswa0x9ycl4q6xc0fngf78jtj27gqj5vff4fvlt3fydx4g7vv0mh7vqv8jncgusp6n2zv860nufdzkyy59pqrdr", 1);
} catch (e) { } catch (e) {
console.error('onOkButtonClick error:', e); console.error('onOkButtonClick error:', e);
} }