-
Notifications
You must be signed in to change notification settings - Fork 81
feat: simplify wallet provisioning flow (detach did creation) #1528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4efe78b
600f68e
c338186
a0918f4
90f8144
f664a18
8de4546
fbc2a1c
8d5aa2e
5d3c978
341d46c
96d8cbd
b05e0ac
6fb1b25
5b52f1b
e7fc1b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,6 @@ | |
| ISendProofRequestPayload, | ||
| IIssuanceCreateOffer, | ||
| IOutOfBandCredentialOffer, | ||
| IAgentSpinUpSatus, | ||
| ICreateTenant, | ||
| IAgentStatus, | ||
| ICreateOrgAgent, | ||
|
|
@@ -126,15 +125,15 @@ | |
| }> { | ||
| let agentProcess: ICreateOrgAgent; | ||
| try { | ||
| await this.processWalletProvision(agentSpinupDto, user); | ||
| return { agentSpinupStatus: AgentSpinUpStatus.PROCESSED }; | ||
| await this.provisionWallet(agentSpinupDto, user); | ||
| return { agentSpinupStatus: AgentSpinUpStatus.DID_CREATED }; | ||
| } catch (error) { | ||
| this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess); | ||
| throw new RpcException(error.response ?? error); | ||
| } | ||
| } | ||
|
|
||
| private async processWalletProvision(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise<void> { | ||
| private async provisionWallet(agentSpinupDto: IAgentSpinupDto, user: IUserRequestInterface): Promise<void> { | ||
| let platformAdminUser; | ||
| let userId: string; | ||
| let agentProcess: ICreateOrgAgent; | ||
|
|
@@ -144,6 +143,7 @@ | |
| this.agentServiceRepository.getPlatformConfigDetails(), | ||
| this.agentServiceRepository.getAgentTypeDetails(), | ||
| this.agentServiceRepository.getLedgerDetails( | ||
| // TODO: Do we want to get first element from ledgerName | ||
|
Check warning on line 146 in apps/agent-service/src/agent-service.service.ts
|
||
| agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet] | ||
| ) | ||
| ]); | ||
|
|
@@ -182,20 +182,13 @@ | |
| // Get genesis URL and ledger details | ||
| const ledgerDetails = await this.agentServiceRepository.getGenesisUrl(agentSpinupDto.ledgerId); | ||
|
|
||
| if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { | ||
| throw new BadRequestException(ResponseMessages.agent.error.walletAlreadyProcessing, { | ||
| if (AgentSpinUpStatus.WALLET_CREATED === getOrgAgent?.agentSpinUpStatus) { | ||
| throw new BadRequestException(ResponseMessages.agent.error.walletAlreadyCreated, { | ||
| cause: new Error(), | ||
| description: ResponseMessages.errorMessages.badRequest | ||
| }); | ||
| } | ||
|
|
||
| if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { | ||
| throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, { | ||
| cause: new Error(), | ||
| description: ResponseMessages.errorMessages.conflict | ||
| }); | ||
| } | ||
|
|
||
| if (!agentSpinupDto.orgId) { | ||
| if (platformAdminOrgDetails) { | ||
| agentSpinupDto.orgId = platformAdminOrgDetails; | ||
|
|
@@ -229,10 +222,10 @@ | |
| const socket: Socket = await this.initSocketConnection(`${process.env.SOCKET_HOST}`); | ||
| this.emitAgentSpinupInitiatedEvent(agentSpinupDto, socket); | ||
|
|
||
| const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; | ||
| agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId); | ||
| const agentSpinUpStatus = AgentSpinUpStatus.WALLET_CREATED; | ||
| agentProcess = await this.createOrgAgent(agentSpinUpStatus, userId, agentSpinupDto.orgId); | ||
|
|
||
| // AFJ agent spin-up | ||
| // Credo agent spin-up | ||
| this._agentSpinup( | ||
| walletProvisionPayload, | ||
| agentSpinupDto, | ||
|
|
@@ -298,7 +291,7 @@ | |
| const storeAgentConfig = await this.agentServiceRepository.storeOrgAgentDetails({ | ||
| did, | ||
| isDidPublic: true, | ||
| agentSpinUpStatus: AgentSpinUpStatus.COMPLETED, | ||
| agentSpinUpStatus: AgentSpinUpStatus.DID_CREATED, | ||
| walletName, | ||
| agentsTypeId, | ||
| orgId, | ||
|
|
@@ -441,9 +434,9 @@ | |
| return socket; | ||
| } | ||
|
|
||
| async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string): Promise<ICreateOrgAgent> { | ||
| async createOrgAgent(agentSpinUpStatus: AgentSpinUpStatus, userId: string, orgId: string): Promise<ICreateOrgAgent> { | ||
| try { | ||
| const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId); | ||
| const agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, userId, orgId); | ||
| this.logger.log(`Organization agent created with status: ${agentSpinUpStatus}`); | ||
| return agentProcess; | ||
| } catch (error) { | ||
|
|
@@ -488,7 +481,7 @@ | |
| ledgerId: string[], | ||
| agentProcess: ICreateOrgAgent | ||
| ): Promise<void> { | ||
| let ledgerIdData = []; | ||
| let ledgerIdData; | ||
|
|
||
| try { | ||
| if (agentSpinupDto.method !== DidMethod.KEY && agentSpinupDto.method !== DidMethod.WEB) { | ||
|
|
@@ -626,7 +619,7 @@ | |
| did: '', | ||
| verkey: '', | ||
| isDidPublic: true, | ||
| agentSpinUpStatus: AgentSpinUpStatus.COMPLETED, | ||
| agentSpinUpStatus: AgentSpinUpStatus.DID_CREATED, | ||
| walletName: payload.walletName, | ||
| agentsTypeId: payload.agentsTypeId, | ||
| orgId: payload.orgId, | ||
|
|
@@ -742,32 +735,20 @@ | |
| * @param user | ||
| * @returns Get agent status | ||
| */ | ||
| async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise<IAgentSpinUpSatus> { | ||
| async createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise<IStoreOrgAgentDetails> { | ||
| try { | ||
| const agentStatusResponse = { | ||
| agentSpinupStatus: AgentSpinUpStatus.PROCESSED | ||
| }; | ||
| const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId); | ||
|
|
||
| if (AgentSpinUpStatus.COMPLETED === getOrgAgent?.agentSpinUpStatus) { | ||
| this.logger.error(`Your wallet is already been created.`); | ||
| if (AgentSpinUpStatus.WALLET_CREATED === getOrgAgent?.agentSpinUpStatus) { | ||
| this.logger.error(`Your wallet is already created.`); | ||
| throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, { | ||
| cause: new Error(), | ||
| description: ResponseMessages.errorMessages.conflict | ||
| }); | ||
| } | ||
|
|
||
| if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) { | ||
| this.logger.error(`Your wallet is already processing.`); | ||
| throw new ConflictException(ResponseMessages.agent.error.walletAlreadyProcessing, { | ||
| cause: new Error(), | ||
| description: ResponseMessages.errorMessages.conflict | ||
| }); | ||
| } | ||
|
|
||
| // Create tenant | ||
| this._createTenant(payload, user); | ||
| return agentStatusResponse; | ||
| const createdTenant = await this._createTenant(payload, user); | ||
| return createdTenant; | ||
| } catch (error) { | ||
|
Comment on lines
+742
to
752
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent orphan Two related issues in the shared-agent tenant path:
In const agentSpinUpStatus = AgentSpinUpStatus.WALLET_CREATED;
agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user?.id, payload.orgId);
// ...
const orgAgentDetails = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData);
// ...
return orgAgentDetails;
} catch (error) {
this.handleError(error, payload.clientSocketId);
throw error;
}If any error occurs after You already handle cleanup correctly elsewhere ( } catch (error) {
- this.handleError(error, payload.clientSocketId);
- throw error;
+ this.handleError(error, payload.clientSocketId);
+
+ if (agentProcess?.id) {
+ try {
+ await this.agentServiceRepository.removeOrgAgent(agentProcess.id);
+ } catch (cleanupError) {
+ this.logger.error(
+ `[_createTenant] - Failed to cleanup org_agent ${agentProcess.id}: ${JSON.stringify(cleanupError)}`
+ );
+ }
+ }
+ throw error;
}
In const getOrgAgent = await this.agentServiceRepository.getAgentDetails(payload.orgId);
if (AgentSpinUpStatus.WALLET_CREATED === getOrgAgent?.agentSpinUpStatus) {
this.logger.error(`Your wallet is already created.`);
throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, ...);
}Once a DID is created and status is advanced to - if (AgentSpinUpStatus.WALLET_CREATED === getOrgAgent?.agentSpinUpStatus) {
+ if (
+ getOrgAgent &&
+ [AgentSpinUpStatus.WALLET_CREATED, AgentSpinUpStatus.DID_CREATED].includes(
+ getOrgAgent.agentSpinUpStatus
+ )
+ ) {
this.logger.error(`Your wallet is already created.`);
throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, {
cause: new Error(),
description: ResponseMessages.errorMessages.conflict
});
}This gives a consistent business rule and avoids leaking low-level DB uniqueness errors back to clients. Also applies to: 764-848 🤖 Prompt for AI Agents |
||
| this.logger.error(`error in create tenant : ${JSON.stringify(error)}`); | ||
| throw new RpcException(error.response ? error.response : error); | ||
|
|
@@ -780,7 +761,7 @@ | |
| * @param user | ||
| * @returns Get agent status | ||
| */ | ||
| async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise<void> { | ||
| async _createTenant(payload: ITenantDto, user: IUserRequestInterface): Promise<IStoreOrgAgentDetails> { | ||
| let agentProcess; | ||
| let ledgerIdData = []; | ||
| try { | ||
|
|
@@ -800,28 +781,29 @@ | |
| description: ResponseMessages.errorMessages.notFound | ||
| }); | ||
| } | ||
| ledgerIdData = await this.agentServiceRepository.getLedgerDetails(ledger); | ||
|
Check warning on line 784 in apps/agent-service/src/agent-service.service.ts
|
||
|
|
||
| const agentSpinUpStatus = AgentSpinUpStatus.PROCESSED; | ||
| const agentSpinUpStatus = AgentSpinUpStatus.WALLET_CREATED; | ||
|
|
||
| // Create and stored agent details | ||
| agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user?.id); | ||
| agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user?.id, payload.orgId); | ||
|
|
||
| // Get platform admin details | ||
| const platformAdminSpinnedUp = await this.getPlatformAdminAndNotify(payload.clientSocketId); | ||
|
|
||
| payload.endpoint = platformAdminSpinnedUp.org_agents[0].agentEndPoint; | ||
| // Create tenant wallet and DID | ||
| // Create tenant wallet | ||
| const tenantDetails = await this.createTenantAndNotify(payload, platformAdminSpinnedUp); | ||
| if (!tenantDetails?.walletResponseDetails?.id || !tenantDetails?.DIDCreationOption?.did) { | ||
|
|
||
| if (!tenantDetails?.walletResponseDetails?.id) { | ||
| this.logger.error(`Error in getting wallet id and wallet did`); | ||
| throw new NotFoundException(ResponseMessages.agent.error.notAbleToSpinUpAgent, { | ||
| cause: new Error(), | ||
| description: ResponseMessages.errorMessages.notFound | ||
| }); | ||
| } | ||
|
|
||
| if (AgentSpinUpStatus.COMPLETED !== platformAdminSpinnedUp.org_agents[0].agentSpinUpStatus) { | ||
| if (AgentSpinUpStatus.DID_CREATED !== platformAdminSpinnedUp.org_agents[0].agentSpinUpStatus) { | ||
| this.logger.error(`Platform-admin agent is not spun-up`); | ||
| throw new NotFoundException(ResponseMessages.agent.error.platformAdminNotAbleToSpinp, { | ||
| cause: new Error(), | ||
|
|
@@ -833,50 +815,34 @@ | |
| // Get agent type details | ||
| const agentTypeId = await this.agentServiceRepository.getAgentTypeId(AgentType.AFJ); | ||
| const storeOrgAgentData: IStoreOrgAgentDetails = { | ||
| did: tenantDetails.DIDCreationOption.did, | ||
| isDidPublic: true, | ||
| didDoc: tenantDetails.DIDCreationOption.didDocument || tenantDetails.DIDCreationOption.didDoc, //changed the didDoc into didDocument | ||
| agentSpinUpStatus: AgentSpinUpStatus.COMPLETED, | ||
| agentSpinUpStatus: AgentSpinUpStatus.WALLET_CREATED, | ||
| agentsTypeId: agentTypeId, | ||
| orgId: payload.orgId, | ||
| agentEndPoint: platformAdminSpinnedUp.org_agents[0].agentEndPoint, | ||
| orgAgentTypeId, | ||
| tenantId: tenantDetails.walletResponseDetails['id'], | ||
| walletName: payload.label, | ||
| ledgerId: ledgerIdData.map((item) => item.id), | ||
| id: agentProcess?.id, | ||
| apiKey: await this.commonService.dataEncryption(tenantDetails.walletResponseDetails['token']) | ||
| }; | ||
|
|
||
| // Get organization data | ||
| const getOrganization = await this.agentServiceRepository.getOrgDetails(payload.orgId); | ||
|
|
||
| this.notifyClientSocket('agent-spinup-process-completed', payload.clientSocketId); | ||
|
|
||
| const orgAgentDetails = await this.agentServiceRepository.storeOrgAgentDetails(storeOrgAgentData); | ||
|
|
||
| const createdDidDetails = { | ||
| orgId: payload.orgId, | ||
| did: tenantDetails.DIDCreationOption.did, | ||
| didDocument: tenantDetails.DIDCreationOption.didDocument || tenantDetails.DIDCreationOption.didDoc, | ||
| isPrimaryDid: true, | ||
| orgAgentId: orgAgentDetails.id, | ||
| userId: user.id | ||
| }; | ||
|
|
||
| await this.agentServiceRepository.storeDidDetails(createdDidDetails); | ||
|
|
||
| this.notifyClientSocket('invitation-url-creation-started', payload.clientSocketId); | ||
|
|
||
| // Create the legacy connection invitation | ||
| await this._createConnectionInvitation(payload.orgId, user, getOrganization.name); | ||
|
|
||
| this.notifyClientSocket('invitation-url-creation-success', payload.clientSocketId); | ||
|
|
||
| return orgAgentDetails; | ||
| } catch (error) { | ||
| this.handleError(error, payload.clientSocketId); | ||
|
|
||
| if (agentProcess && agentProcess?.id) { | ||
| this.agentServiceRepository.removeOrgAgent(agentProcess?.id); | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
|
|
@@ -930,7 +896,6 @@ | |
| } | ||
| } | ||
| } | ||
|
|
||
| const getApiKey = await this.getOrgAgentApiKey(orgId); | ||
| const url = this.constructUrl(agentDetails); | ||
|
|
||
|
|
@@ -961,6 +926,9 @@ | |
| if (isPrimaryDid) { | ||
| await this.setPrimaryDidAndLedger(orgId, storeDidDetails, createDidPayload.network, createDidPayload.method); | ||
| } | ||
| if (agentDetails.agentSpinUpStatus === AgentSpinUpStatus.WALLET_CREATED) { | ||
| await this.agentServiceRepository.updateAgentSpinupStatus(orgId); | ||
| } | ||
|
|
||
| return storeDidDetails; | ||
| } catch (error) { | ||
|
|
@@ -1119,20 +1087,12 @@ | |
| platformAdminSpinnedUp.org_agents[0].agentEndPoint, | ||
| getDcryptedToken | ||
| ); | ||
| if (!walletResponseDetails && !walletResponseDetails.id && !walletResponseDetails.token) { | ||
| if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) { | ||
|
Check warning on line 1090 in apps/agent-service/src/agent-service.service.ts
|
||
| throw new InternalServerErrorException('Error while creating the wallet'); | ||
| } | ||
| const didCreateOption = { | ||
| didPayload: WalletSetupPayload, | ||
| agentEndpoint: platformAdminSpinnedUp.org_agents[0].agentEndPoint, | ||
| apiKey: walletResponseDetails.token | ||
| return { | ||
| walletResponseDetails | ||
| }; | ||
| const DIDCreationOption = await this._createDID(didCreateOption); | ||
| if (!DIDCreationOption) { | ||
| throw new InternalServerErrorException('Error while creating the wallet'); | ||
| } | ||
|
|
||
| return { walletResponseDetails, DIDCreationOption }; | ||
| } | ||
| // | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.