From 325d2cbf13b5d8291df0d4f48d722a8f8f0d40cb Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Thu, 22 May 2025 14:36:19 +0200 Subject: [PATCH] Upodate processes creation and minor fixes --- src/services/service.ts | 325 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 305 insertions(+), 20 deletions(-) diff --git a/src/services/service.ts b/src/services/service.ts index 1fd2191..660b329 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -415,15 +415,16 @@ export default class Services { } } - public async createNotaryProcess(notaryTokens: string[]): Promise { + public async createNotaryProcess(notaryTokens: string[] | null): Promise { const notaryProcess = await this.lookForNotaryProcess(); if (notaryProcess) { + console.log('NOTARY PROCESS:', notaryProcess); throw new Error('There is already a notary process'); } const myProcessId: string = this.getPairingProcessId(); const roles: Record = { notary: { - members: [{ process_id: myProcessId }], + members: [myProcessId], validation_rules: [ { quorum: 0, @@ -444,69 +445,222 @@ export default class Services { const relayAddress = this.getAllRelays()[0]['spAddress']; const feeRate = 1; + await this.getTokensFromFaucet(); + try { return this.sdkClient.create_new_process( pairingTemplate, roles, publicData, relayAddress, - feeRate + feeRate, + this.getAllMembers() ); } catch (e) { throw new Error(`Creating process failed:, ${e}`); } } - public async createProfileProcess(): Promise { + public async createProfileProcess(userData: any): Promise { const myProcessId: string = this.getPairingProcessId(); + if (!myProcessId) { + throw new Error('Missing pairing id'); + } + + const validator = userData['validator']; + + delete userData.validator; // We don't want that in the final pcd + + const userDataKeys = Object.keys(userData); + const roles: Record = { + demiurge: { + members: [myProcessId], + validation_rules: [], + storages: [STORAGEURL] + }, owner: { - members: [{ process_id: myProcessId }], + members: [myProcessId], validation_rules: [ { quorum: 0.01, - fields: ['description', 'relayDomaine', 'serviceDomaine'], + fields: [ + 'description', + 'roles', + ...userDataKeys + ], min_sig_member: 0.01, }, ], storages: [STORAGEURL] }, + idCertificator: { + members: [validator], + validation_rules: [ + { + quorum: 1.0, + fields: ['identityCertified'], + min_sig_member: 1.0 + }, + { + quorum: 0.0, + fields: [ + 'description', + ...userDataKeys + ], + min_sig_member: 0.0 + } + ], + storages: [STORAGEURL] + }, blm: { - members: [{}], + members: [], validation_rules: [ { quorum: 0.0, - fields: ['description', 'ourDomaine', 'serviceDomaine'], - min_sig_member: 0.0, - }, + fields: [ + 'description', + 'name', + 'lastName', + ], + min_sig_member: 0.0 + } ], storages: [STORAGEURL] }, }; const profileTemplate = { description: 'profile', + ...userData, }; - const publicData = {} + const publicData = { + identityCertified: false, + }; + + // Add name and lastName if profile_idn (notary profile) + // if (userDataKeys.includes('profile_idn')) { + // publicData.identityCertified = true; + // publicData.name = userData.name; + // publicData.lastName = userData.lastName; + // } else { + // publicData.identityCertified = false; + // } + const relayAddress = this.getAllRelays()[0]['spAddress']; const feeRate = 1; + + await this.getTokensFromFaucet(); + try { return this.sdkClient.create_new_process( profileTemplate, roles, publicData, relayAddress, - feeRate + feeRate, + this.getAllMembers() ); } catch (e) { throw new Error(`Creating process failed:, ${e}`); } } - private async lookForNotaryProcess(): Promise { - const processes = await this.getMyProcesses(); - if (processes === null) { - return null; + // create a process for folder + public async createFolderProcess(folderData: any): Promise { + const myProcessId: string = this.getPairingProcessId(); + if (!myProcessId) { + throw new Error('Missing pairing id'); } + + const folderDataKeys = Object.keys(folderData); + + const roles: Record = { + owner: { + members: [myProcessId], + validation_rules: [ + { + quorum: 0.01, + fields: [ + 'description', + 'roles', + ...folderDataKeys + ], + min_sig_member: 0.01, + }, + ], + storages: [STORAGEURL] + }, + stakeholder: { + members: folderData.stakeholders, + validation_rules: [ + { + quorum: 0.01, + fields: ['documents', 'notes'], + min_sig_member: 0.01, + }, + ], + storages: [STORAGEURL] + }, + customer: { + members: [], + validation_rules: [ + { + quorum: 0.0, + fields: ['documents', 'notes'], + min_sig_member: 0.0, + }, + ], + storages: [STORAGEURL] + } + }; + + const folderTemplate = { + description: 'folder', + ...folderData, + }; + + console.log('🚀 ~ Services ~ createFolderProcess ~ folderTemplate:', folderTemplate); + + const publicData = { + + }; + + const relayAddress = this.getAllRelays()[0]['spAddress']; + const feeRate = 1; + + await this.getTokensFromFaucet(); + + try { + return this.sdkClient.create_new_process( + folderTemplate, + roles, + publicData, + relayAddress, + feeRate, + this.getAllMembers() + ); + } catch (e) { + throw new Error(`Creating folder process failed: ${e}`); + } + } + + public MOCK_NOTARY = { + at_hash: "DQLI1_Wg0853tf0qf8BYxghzIXaMBaQu4UWz07iG7o", + sub: "IDN26889949I", + profile_id: "IDN26889949I_IDN009850", + arm: "1", + iss: "https://connexion.idnot.fr/idPOAuth2/idnot_idp_v1", + given_name: "Marie", + aud: "BB715912AFEEC6D1", + nbf: "1669713096", + auth_time: "1669713195", + entity_id: "IDN009850", + name: "DUPONT", + exp: "1669720396", + iat: "1669713196", + email: "marie.dupont@notaires.fr" + }; + // This look for the process that holds all the notaries // private async lookForNotaryProcess(): Promise { // const processes = await this.getProcesses(); @@ -733,6 +887,7 @@ export default class Services { if (apiReturn.partial_tx) { try { const res = this.sdkClient.sign_transaction(apiReturn.partial_tx); + console.log('Adding tx to new_tx_to_send'); apiReturn.new_tx_to_send = res.new_tx_to_send; } catch (e) { console.error('Failed to sign transaction:', e); @@ -1003,7 +1158,7 @@ export default class Services { // Get the addresses for the member const otherMemberAddresses: string[] | null = this.getAddressesForMemberId(otherMember); if (!otherMemberAddresses) { - console.error('Failed to get addresses for member', otherMember); + // console.error('Failed to get addresses for member', otherMember); continue; } res = this.compareMembers(member, otherMemberAddresses); @@ -1240,10 +1395,14 @@ export default class Services { async decryptAttribute(processId: string, state: ProcessState, attribute: string): Promise { let hash = state.pcd_commitment[attribute]; + if (!hash) { + // attribute doesn't exist + return null; + } let key = state.keys[attribute]; - // If hash or key is missing, request an update and then retry - if (!hash || !key) { + // If key is missing, request an update and then retry + if (!key) { await this.requestDataFromPeers(processId, [state.state_id], [state.roles]); const maxRetries = 5; @@ -1448,7 +1607,11 @@ export default class Services { } public getAddressesForMemberId(memberId: string): string[] | null { - return this.membersList[memberId].sp_addresses; + try { + return this.membersList[memberId].sp_addresses; + } catch (e) { + return null; + } } public compareMembers(memberA: string[], memberB: string[]): boolean { @@ -1580,6 +1743,16 @@ export default class Services { } } + public getStateFromId(process: Process, stateId: string): ProcessState | null { + if (process.states.length === 0) return null; + const state = process.states.find(state => state.commited_in === stateId); + if (state) { + return state; + } else { + return null; + } + } + public isPairingProcess(roles: Record): boolean { if (Object.keys(roles).length != 1) { return false } const pairingRole = roles['pairing']; @@ -1598,6 +1771,118 @@ export default class Services { return await this.updateProcess(process, {}, publicData, null); } + + public async createAndSendNotaryTx(): Promise { + try { + await this.checkConnections([]); + } catch (e) { + throw e; + } + + try { + const createNotaryProcessReturn = await this.createNotaryProcess( + [], + ); + if (!createNotaryProcessReturn.updated_process) { + throw new Error('createNotaryProcessReturn returned an empty new process'); + } + await this.handleApiReturn(createNotaryProcessReturn); + + this.setProcessId(createNotaryProcessReturn.updated_process.process_id); + console.log('PROCESS NOTARY:', createNotaryProcessReturn.updated_process.process_id); + this.setStateId(createNotaryProcessReturn.updated_process.current_process.states[0].state_id); + } catch (e) { + console.error(e); + } + + try { + const createPrdUpdateReturn = await this.createPrdUpdate(this.processId!, this.stateId!); + await this.handleApiReturn(createPrdUpdateReturn); + } catch (e) { + throw new Error(`createPrdUpdate failed: ${e}`); + } + + try { + const approveChangeReturn = await this.approveChange(this.processId!, this.stateId!); + await this.handleApiReturn(approveChangeReturn); + } catch (e) { + throw new Error(`approveChange failed: ${e}`); + } + + this.processId = null; + this.stateId = null; + } + + public async createAndSendProfileTx(userData: any): Promise { + try { + const createProfileProcessReturn = await this.createProfileProcess( + userData, + ); + await this.handleApiReturn(createProfileProcessReturn); + + this.setProcessId(createProfileProcessReturn.updated_process!.process_id); + this.setStateId(createProfileProcessReturn.updated_process!.current_process.states[0].state_id); + } catch (e) { + throw new Error(`creatProfileProcess failed: ${e}`); + } + + try { + const createPrdUpdateReturn = await this.createPrdUpdate(this.processId!, this.stateId!); + await this.handleApiReturn(createPrdUpdateReturn); + } catch (e) { + throw new Error(`createPrdUpdate failed: ${e}`); + } + + try { + const approveChangeReturn = await this.approveChange(this.processId!, this.stateId!); + await this.handleApiReturn(approveChangeReturn); + this.processId = null; + this.stateId = null; + } catch (e) { + throw new Error(`approveChange failed: ${e}`); + } + + } + + + public async createAndSendFolderTx(folderData: any): Promise { + try { + await this.checkConnections([]); + } catch (e) { + throw e; + } + + try { + console.log("folderData", folderData); + const createFolderProcessReturn = await this.createFolderProcess( + folderData, + ); + await this.handleApiReturn(createFolderProcessReturn); + + this.setProcessId(createFolderProcessReturn.updated_process!.process_id); + this.setStateId(createFolderProcessReturn.updated_process!.current_process.states[0].state_id); + } catch (e) { + throw new Error(`createFolderProcess failed: ${e}`); + } + + try { + const createPrdUpdateReturn = await this.createPrdUpdate(this.processId!, this.stateId!); + await this.handleApiReturn(createPrdUpdateReturn); + } catch (e) { + throw new Error(`createPrdUpdate failed: ${e}`); + } + + try { + const approveChangeReturn = await this.approveChange(this.processId!, this.stateId!); + await this.handleApiReturn(approveChangeReturn); + this.processId = null; + this.stateId = null; + } catch (e) { + throw new Error(`approveChange failed: ${e}`); + } + + } + // public async getProfilesAttributes(): Promise>> { // const processes = await this.getProcesses(); // const profilesAttributes: Record> = {};