Merge commit 'd1132155a695fc280af395b8cc1610a5660510d0' into HEAD
This commit is contained in:
commit
7863404393
@ -8,7 +8,7 @@ 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 currentPcdCommitment: string | null = null;
|
||||||
private currentOutpoint: string | null = null;
|
private currentOutpoint: string | null = null;
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
private paired_addresses: string[] = [];
|
private paired_addresses: string[] = [];
|
||||||
@ -52,7 +52,8 @@ export default class ModalService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openConfirmationModal(pcd: any, commitmentTx: string) {
|
// this is kind of too specific for pairing though
|
||||||
|
public async openConfirmationModal(pcd: any, commitmentTx: string, merkleRoot: string) {
|
||||||
let map: Record<string, RoleDefinition>;
|
let map: Record<string, RoleDefinition>;
|
||||||
if (pcd['roles']) {
|
if (pcd['roles']) {
|
||||||
const roles = pcd['roles'];
|
const roles = pcd['roles'];
|
||||||
@ -65,6 +66,7 @@ export default class ModalService {
|
|||||||
throw new Error('Pcd doesn\'t have a \"roles\" field');
|
throw new Error('Pcd doesn\'t have a \"roles\" field');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pairing specifics
|
||||||
let members;
|
let members;
|
||||||
if (map['owner']) {
|
if (map['owner']) {
|
||||||
const owner = map['owner'];
|
const owner = map['owner'];
|
||||||
@ -73,6 +75,7 @@ export default class ModalService {
|
|||||||
throw new Error('No \"owner\" role');
|
throw new Error('No \"owner\" role');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pairing specifics
|
||||||
if (members.length != 1) {
|
if (members.length != 1) {
|
||||||
throw new Error('Must have exactly 1 member');
|
throw new Error('Must have exactly 1 member');
|
||||||
}
|
}
|
||||||
@ -81,12 +84,15 @@ export default class ModalService {
|
|||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
const localAddress = await service.getDeviceAddress();
|
const localAddress = await service.getDeviceAddress();
|
||||||
console.log('🚀 ~ Routing ~ openConfirmationModal ~ pcd:', pcd);
|
console.log('🚀 ~ Routing ~ openConfirmationModal ~ pcd:', pcd);
|
||||||
for (const address of members[0]['sp_addresses']) {
|
for (const member of members) {
|
||||||
if (address !== localAddress) {
|
for (const address of member['sp_addresses']) {
|
||||||
this.paired_addresses.push(address);
|
if (address !== localAddress) {
|
||||||
|
this.paired_addresses.push(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.currentOutpoint = commitmentTx;
|
this.currentOutpoint = commitmentTx;
|
||||||
|
this.currentPcdCommitment = merkleRoot;
|
||||||
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';
|
||||||
@ -116,18 +122,33 @@ export default class ModalService {
|
|||||||
async confirmPairing() {
|
async confirmPairing() {
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
const modal = document.getElementById('modal');
|
const modal = document.getElementById('modal');
|
||||||
// console.log("🚀 ~ Routing ~ confirm ~ prd:", prd)
|
|
||||||
if (modal) modal.style.display = 'none';
|
if (modal) modal.style.display = 'none';
|
||||||
|
|
||||||
if (this.currentOutpoint === null || this.paired_addresses.length === 0) {
|
// We send the prd update
|
||||||
throw new Error('Missing outpoint and/or paired addresses');
|
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 take the paired device(s) from the contract
|
// We send confirmation that we validate the change
|
||||||
await service.pairDevice(this.currentOutpoint, this.paired_addresses);
|
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.paired_addresses = [];
|
||||||
this.currentOutpoint = null;
|
this.currentOutpoint = null;
|
||||||
const newDevice = await service.dumpDevice();
|
this.currentPcdCommitment = null;
|
||||||
|
const newDevice = service.dumpDevice();
|
||||||
await service.saveDevice(newDevice);
|
await service.saveDevice(newDevice);
|
||||||
navigate('process');
|
navigate('process');
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,18 @@ import ModalService from './modal.service';
|
|||||||
import { navigate } from '../router';
|
import { navigate } from '../router';
|
||||||
import Database from './database.service';
|
import Database from './database.service';
|
||||||
|
|
||||||
type ProcessesCache = {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const U32_MAX = 4294967295;
|
export const U32_MAX = 4294967295;
|
||||||
|
const RELAY_ADDRESS = "sprt1qqdg4x69xdyhxpz4weuel0985qyswa0x9ycl4q6xc0fngf78jtj27gqj5vff4fvlt3fydx4g7vv0mh7vqv8jncgusp6n2zv860nufdzkyy59pqrdr";
|
||||||
const wsurl = `https://demo.4nkweb.com/ws/`;
|
const wsurl = `https://demo.4nkweb.com/ws/`;
|
||||||
|
|
||||||
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 current_process: string | null = null;
|
private currentProcess: string | null = null;
|
||||||
|
private pendingUpdates: Record<string, any> = {};
|
||||||
|
private currentUpdateMerkleRoot: string | null = null;
|
||||||
|
private localAddress: string | null = null;
|
||||||
|
private pairedAddresses: string[] = [];
|
||||||
private sdkClient: any;
|
private sdkClient: any;
|
||||||
private processes: IProcess[] | null = null;
|
private processes: IProcess[] | null = null;
|
||||||
private notifications: INotification[] | null = null;
|
private notifications: INotification[] | null = null;
|
||||||
@ -57,50 +58,31 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async addWebsocketConnection(url: string): Promise<void> {
|
public async addWebsocketConnection(url: string): Promise<void> {
|
||||||
// const services = await Services.getInstance();
|
|
||||||
console.log('Opening new websocket connection');
|
console.log('Opening new websocket connection');
|
||||||
const newClient = initWebsocket(url);
|
await initWebsocket(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public isPaired(): boolean | undefined {
|
public async getRelayAddresses(): Promise<string[]> {
|
||||||
|
// We just return one hardcoded address for now
|
||||||
|
return [RELAY_ADDRESS];
|
||||||
|
}
|
||||||
|
|
||||||
|
public isPaired(): boolean {
|
||||||
try {
|
try {
|
||||||
return this.sdkClient.is_linking();
|
return this.sdkClient.is_linking();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('isPaired ~ Error:', e);
|
throw new Error(`isPaired ~ Error: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async unpairDevice(): Promise<void> {
|
public async unpairDevice(): Promise<void> {
|
||||||
const service = await Services.getInstance();
|
try {
|
||||||
await service.sdkClient.unpair_device();
|
this.sdkClient.unpair_device();
|
||||||
const newDevice = await this.dumpDevice();
|
const newDevice = this.dumpDevice();
|
||||||
await this.saveDevice(newDevice);
|
await this.saveDevice(newDevice);
|
||||||
}
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to unpair device: ${e}`);
|
||||||
private prepareProcessTx(myAddress: string, recipientAddress: string) {
|
}
|
||||||
const initial_session_privkey = new Uint8Array(32);
|
|
||||||
const initial_session_pubkey = new Uint8Array(32);
|
|
||||||
const pairingTemplate = {
|
|
||||||
description: 'AliceBob',
|
|
||||||
roles: {
|
|
||||||
owner: {
|
|
||||||
members: [{ sp_addresses: [myAddress, recipientAddress] }],
|
|
||||||
validation_rules: [
|
|
||||||
{
|
|
||||||
quorum: 1.0,
|
|
||||||
fields: ['description', 'roles', 'session_privkey', 'session_pubkey', 'key_parity'],
|
|
||||||
min_sig_member: 1.0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
session_privkey: initial_session_privkey,
|
|
||||||
session_pubkey: initial_session_pubkey,
|
|
||||||
key_parity: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const apiReturn = this.sdkClient.create_update_transaction(undefined, JSON.stringify(pairingTemplate), 1);
|
|
||||||
return apiReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSecretForAddress(address: string): Promise<string | null> {
|
public async getSecretForAddress(address: string): Promise<string | null> {
|
||||||
@ -108,7 +90,7 @@ export default class Services {
|
|||||||
return await db.getObject('shared_secrets', address);
|
return await db.getObject('shared_secrets', address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connectMember(members: Member[]): Promise<void> {
|
public async connectMember(members: Member[]): Promise<ApiReturn> {
|
||||||
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');
|
||||||
}
|
}
|
||||||
@ -144,15 +126,13 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const apiReturn = this.sdkClient.create_connect_transaction(members_str, 1);
|
return this.sdkClient.create_connect_transaction(members_str, 1);
|
||||||
|
|
||||||
await this.handleApiReturn(apiReturn);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to connect:', e);
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createPairingProcess(pairWith: string[], relayAddress: string, feeRate: number): Promise<void> {
|
public async createPairingProcess(pairWith: string[], relayAddress: string, feeRate: number): Promise<ApiReturn> {
|
||||||
const myAddress: string = this.sdkClient.get_address();
|
const myAddress: string = this.sdkClient.get_address();
|
||||||
pairWith.push(myAddress);
|
pairWith.push(myAddress);
|
||||||
const newKey = this.sdkClient.get_new_keypair();
|
const newKey = this.sdkClient.get_new_keypair();
|
||||||
@ -175,14 +155,61 @@ export default class Services {
|
|||||||
key_parity: newKey['key_parity'],
|
key_parity: newKey['key_parity'],
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const newProcessReturn = this.sdkClient.create_new_process(JSON.stringify(pairingTemplate), relayAddress, feeRate);
|
return this.sdkClient.create_new_process(JSON.stringify(pairingTemplate), relayAddress, feeRate);
|
||||||
console.log('newProcessReturn:', newProcessReturn);
|
|
||||||
await this.handleApiReturn(newProcessReturn);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Creating process failed:, ${e}`);
|
throw new Error(`Creating process failed:, ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create prd update for current process and update
|
||||||
|
public createPrdUpdate(pcdMerkleRoot: string): ApiReturn {
|
||||||
|
if (!this.currentProcess) {
|
||||||
|
throw new Error('No current process defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this.sdkClient.create_update_message(this.currentProcess, pcdMerkleRoot);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to create prd update: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createPrdResponse(pcdMerkleRoot: string): ApiReturn {
|
||||||
|
if (!this.currentProcess) {
|
||||||
|
throw new Error('No current process defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this.sdkClient.create_response_prd(this.currentProcess, pcdMerkleRoot);
|
||||||
|
} catch (e) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public approveChange(currentPcdMerkleRoot: string): ApiReturn {
|
||||||
|
if (!this.currentProcess) {
|
||||||
|
throw new Error('No current process defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this.sdkClient.validate_state(this.currentProcess, currentPcdMerkleRoot);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to create prd response: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public rejectChange(): ApiReturn {
|
||||||
|
if (!this.currentProcess || !this.currentUpdateMerkleRoot) {
|
||||||
|
throw new Error('No current process and/or current update defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this.sdkClient.refuse_state(this.currentProcess, this.currentUpdateMerkleRoot);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to create prd response: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async resetDevice() {
|
async resetDevice() {
|
||||||
await this.sdkClient.reset_device();
|
await this.sdkClient.reset_device();
|
||||||
}
|
}
|
||||||
@ -209,11 +236,11 @@ export default class Services {
|
|||||||
async parseCipher(message: string) {
|
async parseCipher(message: string) {
|
||||||
try {
|
try {
|
||||||
console.log('parsing new cipher');
|
console.log('parsing new cipher');
|
||||||
const apiReturn = await this.sdkClient.parse_cipher(message, 0.00001);
|
const apiReturn = await this.sdkClient.parse_cipher(message);
|
||||||
console.log('🚀 ~ Services ~ parseCipher ~ apiReturn:', apiReturn);
|
console.log('🚀 ~ Services ~ parseCipher ~ apiReturn:', apiReturn);
|
||||||
await this.handleApiReturn(apiReturn);
|
await this.handleApiReturn(apiReturn);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Cipher isn't for us");
|
console.error(`Parsed cipher with error: ${e}`);
|
||||||
}
|
}
|
||||||
// await this.saveCipherTxToDb(parsedTx)
|
// await this.saveCipherTxToDb(parsedTx)
|
||||||
}
|
}
|
||||||
@ -236,7 +263,21 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleApiReturn(apiReturn: ApiReturn) {
|
public getUpdateProposals(commitmentOutpoint: string) {
|
||||||
|
try {
|
||||||
|
const proposals: ApiReturn = this.sdkClient.get_update_proposals(commitmentOutpoint);
|
||||||
|
if (proposals.decrypted_pcds && proposals.decrypted_pcds.length != 0) {
|
||||||
|
this.currentProcess = commitmentOutpoint;
|
||||||
|
this.pendingUpdates = proposals.decrypted_pcds;
|
||||||
|
} else {
|
||||||
|
throw new Error('No pending proposals');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to get proposal updates for process ${commitmentOutpoint}: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async handleApiReturn(apiReturn: ApiReturn) {
|
||||||
if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) {
|
if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) {
|
||||||
await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send));
|
await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send));
|
||||||
}
|
}
|
||||||
@ -245,7 +286,6 @@ export default class Services {
|
|||||||
const unconfirmedSecrets = apiReturn.secrets.unconfirmed_secrets;
|
const unconfirmedSecrets = apiReturn.secrets.unconfirmed_secrets;
|
||||||
const confirmedSecrets = apiReturn.secrets.shared_secrets;
|
const confirmedSecrets = apiReturn.secrets.shared_secrets;
|
||||||
|
|
||||||
console.log('confirmedSecrets:', confirmedSecrets);
|
|
||||||
const db = await Database.getInstance();
|
const db = await Database.getInstance();
|
||||||
for (const secret of unconfirmedSecrets) {
|
for (const secret of unconfirmedSecrets) {
|
||||||
db.addObject({
|
db.addObject({
|
||||||
@ -256,8 +296,6 @@ export default class Services {
|
|||||||
}
|
}
|
||||||
const entries = Object.entries(confirmedSecrets).map(([key, value]) => ({ key, value }));
|
const entries = Object.entries(confirmedSecrets).map(([key, value]) => ({ key, value }));
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
console.log('entry:', entry);
|
|
||||||
|
|
||||||
db.addObject({
|
db.addObject({
|
||||||
storeName: 'shared_secrets',
|
storeName: 'shared_secrets',
|
||||||
object: entry,
|
object: entry,
|
||||||
@ -277,18 +315,6 @@ export default class Services {
|
|||||||
object: { id: commitmentTx, process },
|
object: { id: commitmentTx, process },
|
||||||
key: null,
|
key: null,
|
||||||
});
|
});
|
||||||
// Check if the newly updated process reveals some new information
|
|
||||||
try {
|
|
||||||
const proposals: ApiReturn = this.sdkClient.get_update_proposals(commitmentTx);
|
|
||||||
const decrypted_pcds = proposals.decrypted_pcds;
|
|
||||||
if (decrypted_pcds && decrypted_pcds.length != 0) {
|
|
||||||
for (const actual_proposal of Object.values(decrypted_pcds)) {
|
|
||||||
await this.routingInstance.openConfirmationModal(actual_proposal, commitmentTx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiReturn.commit_to_send) {
|
if (apiReturn.commit_to_send) {
|
||||||
@ -296,62 +322,45 @@ export default class Services {
|
|||||||
await this.sendCommitMessage(JSON.stringify(commit));
|
await this.sendCommitMessage(JSON.stringify(commit));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiReturn.decrypted_pcds && apiReturn.decrypted_pcds.length != 0) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length != 0) {
|
if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length != 0) {
|
||||||
await this.sendCipherMessages(apiReturn.ciphers_to_send);
|
await this.sendCipherMessages(apiReturn.ciphers_to_send);
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async pairDevice(commitmentTx: string, spAddressList: string[]) {
|
public async evaluatePendingUpdates() {
|
||||||
await this.sdkClient.pair_device(commitmentTx, spAddressList);
|
if (!this.currentProcess) {
|
||||||
|
throw new Error('No current process');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.openConfirmationModal();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Error while evaluating pending updates for process ${this.currentProcess}: ${e}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async validatePairingDevice(prd: any, outpointCommitment: string) {
|
private async openConfirmationModal() {
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ prd:', prd);
|
if (this.pendingUpdates.length === 0) {
|
||||||
const spAddress = (await this.getDeviceAddress()) as any;
|
console.log('No pending updates');
|
||||||
const sender = JSON.parse(prd?.sender);
|
}
|
||||||
const senderAddress = sender?.sp_addresses?.find((address: string) => address !== spAddress);
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ senderAddress:', senderAddress);
|
|
||||||
if (senderAddress) {
|
|
||||||
const proposal = this.sdkClient.get_update_proposals(outpointCommitment);
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ proposal:', proposal);
|
|
||||||
// const pairingTx = proposal.pairing_tx.replace(/^\"+|\"+$/g, '')
|
|
||||||
const parsedProposal = JSON.parse(proposal[0]);
|
|
||||||
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ parsedProposal:', parsedProposal);
|
try {
|
||||||
const roles = JSON.parse(parsedProposal.roles);
|
for (const [merkleRoot, actual_proposal] of Object.entries(this.pendingUpdates)) {
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ roles:', roles, Array.isArray(roles), !roles.owner);
|
await this.routingInstance.openConfirmationModal(actual_proposal, this.currentProcess!, merkleRoot);
|
||||||
if (Array.isArray(roles) || !roles.owner) return;
|
}
|
||||||
const proposalMembers = roles?.owner?.members;
|
} catch (e) {
|
||||||
const isFirstDevice = proposalMembers.some((member: Member) => member.sp_addresses.some((address) => address === spAddress));
|
throw new Error(`${e}`);
|
||||||
const isSecondDevice = proposalMembers.some((member: Member) => member.sp_addresses.some((address) => address === senderAddress));
|
}
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ proposalMembers:', proposalMembers);
|
}
|
||||||
if (proposalMembers?.length !== 2 || !isFirstDevice || !isSecondDevice) return;
|
|
||||||
const pairingTx = parsedProposal?.pairing_tx?.replace(/^\"+|\"+$/g, '');
|
pairDevice(spAddressList: string[]) {
|
||||||
|
if (this.currentProcess) {
|
||||||
let txid = '0'.repeat(64);
|
try {
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ pairingTx:', pairingTx, `${txid}:4294967295`);
|
this.sdkClient.pair_device(this.currentProcess, spAddressList);
|
||||||
|
} catch (e) {
|
||||||
const pairing = await this.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress]);
|
throw new Error(`Failed to pair device: ${e}`);
|
||||||
const device = this.dumpDevice();
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ device:', device);
|
|
||||||
this.saveDevice(device);
|
|
||||||
// await service.sdkClient.pair_device(pairingTx, [senderAddress])
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ pairing:', pairing);
|
|
||||||
// const process = await this.prepareProcessTx(spAddress, senderAddress)
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ process:', outpointCommitment, prd, prd.payload);
|
|
||||||
const prdString = JSON.stringify(prd).trim();
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ prdString:', prdString);
|
|
||||||
let tx = await this.sdkClient.response_prd(outpointCommitment, prdString, true);
|
|
||||||
console.log('🚀 ~ Services ~ pairDevice ~ tx:', tx);
|
|
||||||
if (tx.ciphers_to_send) {
|
|
||||||
tx.ciphers_to_send.forEach((cipher: string) => sendMessage('Cipher', cipher));
|
|
||||||
}
|
}
|
||||||
navigate('process');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,12 +373,15 @@ export default class Services {
|
|||||||
return await this.sdkClient.get_address();
|
return await this.sdkClient.get_address();
|
||||||
}
|
}
|
||||||
|
|
||||||
async dumpDevice() {
|
public dumpDevice(): string {
|
||||||
const device = await this.sdkClient.dump_device();
|
try {
|
||||||
return device;
|
return this.sdkClient.dump_device();
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to dump device: ${e}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveDevice(device: any): Promise<any> {
|
async saveDevice(device: any): Promise<void> {
|
||||||
const db = await Database.getInstance();
|
const db = await Database.getInstance();
|
||||||
try {
|
try {
|
||||||
await db.addObject({
|
await db.addObject({
|
||||||
@ -506,47 +518,12 @@ export default class Services {
|
|||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getProcessesCache(): ProcessesCache {
|
private getProcessesCache() {
|
||||||
// Regular expression to match 64-character hexadecimal strings
|
console.log('TODO get processes from indexedDB')
|
||||||
const hexU32KeyRegex: RegExp = /^[0-9a-fA-F]{64}:\d+$/;
|
|
||||||
const hexObjects: ProcessesCache = {};
|
|
||||||
|
|
||||||
// Iterate over all keys in localStorage
|
|
||||||
for (let i = 0; i < localStorage.length; i++) {
|
|
||||||
const key = localStorage.key(i);
|
|
||||||
|
|
||||||
if (!key) {
|
|
||||||
return hexObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the key matches the 32-byte hex pattern
|
|
||||||
if (hexU32KeyRegex.test(key)) {
|
|
||||||
const value = localStorage.getItem(key);
|
|
||||||
if (!value) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hexObjects[key] = JSON.parse(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hexObjects;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async restoreProcesses() {
|
public async restoreProcesses() {
|
||||||
const processesCache = this.getProcessesCache();
|
console.log('TODO: restore processes from indexedDB');
|
||||||
console.log('🚀 ~ Services ~ restoreProcesses ~ processesCache:', processesCache);
|
|
||||||
|
|
||||||
if (processesCache.length == 0) {
|
|
||||||
console.debug('🚀 ~ Services ~ restoreProcesses ~ no processes in local storage');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.sdkClient.set_process_cache(JSON.stringify(processesCache));
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Services ~ restoreProcesses ~ Error:', e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNotifications(): INotification[] {
|
getNotifications(): INotification[] {
|
||||||
|
@ -149,14 +149,29 @@ 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 {
|
try {
|
||||||
|
// Connect to target, if necessary
|
||||||
const sharedSecret = await service.getSecretForAddress(addressInput);
|
const sharedSecret = await service.getSecretForAddress(addressInput);
|
||||||
if (!sharedSecret) {
|
if (!sharedSecret) {
|
||||||
const member = {
|
const member = {
|
||||||
sp_addresses: [addressInput],
|
sp_addresses: [addressInput],
|
||||||
}
|
}
|
||||||
await service.connectMember([member]);
|
const connectMemberResult = await service.connectMember([member]);
|
||||||
|
await service.handleApiReturn(connectMemberResult);
|
||||||
}
|
}
|
||||||
await service.createPairingProcess([addressInput], "sprt1qqdg4x69xdyhxpz4weuel0985qyswa0x9ycl4q6xc0fngf78jtj27gqj5vff4fvlt3fydx4g7vv0mh7vqv8jncgusp6n2zv860nufdzkyy59pqrdr", 1);
|
// Create the process
|
||||||
|
const relayAddress = await service.getRelayAddresses(); // Get one (or more?) relay addresses
|
||||||
|
const createPairingProcessReturn = await service.createPairingProcess([addressInput], relayAddress[0], 1);
|
||||||
|
await service.handleApiReturn(createPairingProcessReturn);
|
||||||
|
|
||||||
|
if (!createPairingProcessReturn.updated_process) {
|
||||||
|
throw new Error('createPairingProcess returned an empty new process'); // This should never happen
|
||||||
|
}
|
||||||
|
const [commitmentOutpoint, process] = createPairingProcessReturn.updated_process;
|
||||||
|
|
||||||
|
// We set the service to the process
|
||||||
|
service.getUpdateProposals(commitmentOutpoint);
|
||||||
|
|
||||||
|
await service.evaluatePendingUpdates();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('onOkButtonClick error:', e);
|
console.error('onOkButtonClick error:', e);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user