Skip to content

Conversation

@pranalidhanavade
Copy link
Contributor

@pranalidhanavade pranalidhanavade commented Nov 26, 2025

Summary by CodeRabbit

  • New Features

    • Organization ID is now tracked and returned across provisioning and tenant creation flows.
    • Tenant creation now returns richer organization and agent details.
  • Bug Fixes

    • Wallet provisioning status values updated to WALLET_CREATED and DID_CREATED for clearer state reporting.
  • Improvements

    • Success text changed to "Organization wallet created successfully" for clearer user feedback.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

Threaded orgId through provisioning, service, and repository layers; createTenant now returns richer IStoreOrgAgentDetails; wallet provisioning and agent spin-up statuses renamed to WALLET_CREATED/DID_CREATED; repository adds updateAgentSpinupStatus; DTO validation and success message text updated.

Changes

Cohort / File(s) Summary
Agent Provisioning Module
apps/agent-provisioning/src/agent-provisioning.service.ts
Import reordering, added exec from child_process, and dotenv placement adjusted; no runtime/control-flow changes.
Agent Service Controller
apps/agent-service/src/agent-service.controller.ts
createTenant return type changed from IAgentSpinUpSatus to IStoreOrgAgentDetails; imports reorganized.
Agent Service Business Logic
apps/agent-service/src/agent-service.service.ts
Propagated orgId into createOrgAgent; createTenant/_createTenant now return IStoreOrgAgentDetails; wallet provisioning/status flows renamed to WALLET_CREATED/DID_CREATED; DID/socket notification steps adjusted; createDid now updates spin-up status when applicable.
Agent Service Repository
apps/agent-service/src/repositories/agent-service.repository.ts
createOrgAgent signature now includes orgId; storeOrgAgentDetails returns richer object (orgId, agentSpinUpStatus, agentEndPoint, tenantId, walletName, id); added updateAgentSpinupStatus(orgId: string).
API Gateway DTO
apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts
CreateTenantDto no longer extends CreateDidDto; validation decorators applied directly; properties preserved (label, did, clientSocketId, orgId).
Common Response Messages
libs/common/src/response-messages/index.ts
ResponseMessages.agent.success.create text changed to "Organization wallet created successfully".
Enums
libs/enum/src/enum.ts
AgentSpinUpStatus enum values renamed: PROCESSEDWALLET_CREATED, COMPLETEDDID_CREATED (numeric mappings preserved).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant API as API Gateway
    participant Controller as AgentServiceController
    participant Service as AgentServiceService
    participant Repo as AgentServiceRepository
    participant Provision as AgentProvisioning

    Client->>API: POST /create-tenant (CreateTenantDto)
    API->>Controller: createTenant(payload)
    Controller->>Service: createTenant(payload, user)
    Service->>Repo: createOrgAgent(WALLET_CREATED?, userId, orgId)
    Repo-->>Service: orgAgentRecord (orgId, tenantId, walletName)
    Service->>Provision: provisionWallet(orgAgentRecord, user)
    Provision-->>Service: walletProvisionResult (walletName, agentEndPoint)
    Service->>Repo: storeOrgAgentDetails({orgId, tenantId, walletName, agentEndPoint})
    Repo-->>Service: storedOrgAgentDetails (IStoreOrgAgentDetails)
    Service->>Repo: updateAgentSpinupStatus(orgId)
    Service-->>Controller: IStoreOrgAgentDetails
    Controller-->>Client: 200 OK (IStoreOrgAgentDetails)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus:
    • apps/agent-service/src/agent-service.service.ts — orgId propagation, updated return types, renamed enum values, and wallet/DID flow changes.
    • apps/agent-service/src/repositories/agent-service.repository.ts — new return shape, updateAgentSpinupStatus, and data mapping (orgDid/didDocument).
    • Call sites, tests, and consumers expecting the old IAgentSpinUpSatus type or PROCESSED/COMPLETED enum names.

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • tipusinghaw
  • GHkrishna
  • RinkalBhojani

Poem

🐰
I nibbled through the service trail,
I threaded orgId without fail,
Wallets wake and statuses sing,
Tidier flows hop in a ring,
Hooray — carrots for this small tale! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: simplify wallet provisioning flow (detach did creation)' directly describes the main objective and primary changes visible across the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/create-wallet-api-changes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pranalidhanavade pranalidhanavade force-pushed the feat/create-wallet-api-changes branch from b0a232f to 7314f1f Compare November 27, 2025 06:44
@pranalidhanavade pranalidhanavade marked this pull request as ready for review November 27, 2025 06:57
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/agent-service/src/agent-service.service.ts (1)

746-770: <!-- [scratchpad_start]
[task verify_review_comment_1/1 COMPLETE]

[observations]

  • No explanatory comments for why COMPLETED check was commented out
  • The code is identical between createTenant and processWalletProvision except for this missing check
  • Both methods get agent details and check status
  • processWalletProvision has BOTH checks, createTenant only has PROCESSED check
  • No indication this is intentional architectural difference

[analysis]
FINAL VERIFICATION RESULTS:

  1. ✓ CONFIRMED: agentStatusResponse is unused - it's created but never returned or used
  2. ✓ CONFIRMED: COMPLETED check was removed from createTenant but exists in processWalletProvision
  3. ✓ CONFIRMED: Removal creates a gap - allows createTenant to proceed even if wallet already COMPLETED
  4. ✓ CONFIRMED: No comment or documentation explaining why this check was removed
  5. ✓ CONFIRMED: This is a real issue - potential duplicate wallet creation vulnerability

Review comment is ACCURATE and VALID.
Original severity:
Final verdict: Issues are confirmed and still need to be fixed.
Final tag:

[done]
Ready to generate final rewritten review comment with confirmed findings.
</scratchpad_start>

Based on my verification, I've confirmed both issues raised in the review comment. Here's the final rewritten review:


Remove unused variable and restore duplicate-wallet prevention check.

  1. Unused variable: agentStatusResponse (lines 748-750) is assigned but never used—remove it.

  2. Missing COMPLETED status check: The check for AgentSpinUpStatus.COMPLETED (lines 753-759) has been commented out, but it exists and is active in the processWalletProvision() method (line 193). Without this check, createTenant() can proceed even if a wallet already exists in COMPLETED status, potentially allowing duplicate wallet creation or overwriting. Restore this check to match the validation logic in processWalletProvision():

   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.`);
+        throw new ConflictException(ResponseMessages.agent.error.walletAlreadyCreated, {
+          cause: new Error(),
+          description: ResponseMessages.errorMessages.conflict
+        });
+      }
 
       if (AgentSpinUpStatus.PROCESSED === getOrgAgent?.agentSpinUpStatus) {
♻️ Duplicate comments (1)
apps/agent-service/src/agent-service.service.ts (1)

836-850: Clean up commented-out code and verify the PROCESSED status workflow.

  1. Commented-out code: Multiple lines (837-840, 847) contain commented-out code that should be removed per the new workflow. This was flagged by static analysis.

  2. Status set to PROCESSED: Setting agentSpinUpStatus to AgentSpinUpStatus.PROCESSED (line 840) instead of COMPLETED indicates the wallet is not fully ready. This aligns with the new workflow where status updates to COMPLETED after DID creation (lines 965-967). Ensure downstream consumers handle the PROCESSED state correctly.

Apply this diff to clean up the commented-out code:

       const storeOrgAgentData: IStoreOrgAgentDetails = {
-        // did: tenantDetails.DIDCreationOption.did,
-        // isDidPublic: true,
-        // didDoc: tenantDetails.DIDCreationOption.didDocument || tenantDetails.DIDCreationOption.didDoc, //changed the didDoc into didDocument
         agentSpinUpStatus: AgentSpinUpStatus.PROCESSED,
         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'])
       };
🧹 Nitpick comments (1)
apps/agent-service/src/agent-service.service.ts (1)

147-148: Address or remove the TODO comment.

The TODO comment indicates uncertainty about whether to get the first element from ledgerName. The current implementation passes the full array to getLedgerDetails, which appears to be the intended behavior. Either clarify the logic and remove the TODO, or implement the necessary change.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ab4ac6 and 9644199.

📒 Files selected for processing (6)
  • apps/agent-provisioning/src/agent-provisioning.service.ts (1 hunks)
  • apps/agent-service/src/agent-service.controller.ts (2 hunks)
  • apps/agent-service/src/agent-service.service.ts (12 hunks)
  • apps/agent-service/src/repositories/agent-service.repository.ts (6 hunks)
  • apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts (1 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts (3)
libs/validations/maxLength.ts (1)
  • MaxLength (3-28)
libs/common/src/cast.helper.ts (1)
  • trim (39-43)
libs/validations/minLength.ts (1)
  • MinLength (3-28)
apps/agent-service/src/agent-service.controller.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (1)
  • IStoreOrgAgentDetails (177-201)
apps/agent-service/src/repositories/agent-service.repository.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (2)
  • ICreateOrgAgent (449-451)
  • IStoreOrgAgentDetails (177-201)
apps/agent-service/src/agent-service.service.ts (4)
apps/agent-service/src/interface/agent-service.interface.ts (4)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IUserRequestInterface (237-250)
  • IStoreOrgAgentDetails (177-201)
apps/ledger/src/schema/interfaces/schema.interface.ts (1)
  • IUserRequestInterface (5-18)
apps/connection/src/interfaces/connection.interfaces.ts (1)
  • IUserRequestInterface (21-33)
apps/api-gateway/src/connection/interfaces/index.ts (1)
  • IUserRequestInterface (3-15)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 147-147: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAfOZxHuU9wfKJF5oS&open=AZrAfOZxHuU9wfKJF5oS&pullRequest=1528


[warning] 748-748: Remove this useless assignment to variable "agentStatusResponse".

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiR&open=AZrAPdZjkOgkTFjvADiR&pullRequest=1528


[warning] 753-759: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiS&open=AZrAPdZjkOgkTFjvADiS&pullRequest=1528


[warning] 874-874: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiY&open=AZrAPdZjkOgkTFjvADiY&pullRequest=1528


[warning] 858-865: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiV&open=AZrAPdZjkOgkTFjvADiV&pullRequest=1528


[warning] 879-881: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiZ&open=AZrAPdZjkOgkTFjvADiZ&pullRequest=1528


[warning] 867-867: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiW&open=AZrAPdZjkOgkTFjvADiW&pullRequest=1528


[warning] 869-869: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADiX&open=AZrAPdZjkOgkTFjvADiX&pullRequest=1528


[warning] 1129-1137: Remove this commented out code.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrAPdZjkOgkTFjvADia&open=AZrAPdZjkOgkTFjvADia&pullRequest=1528

🔇 Additional comments (11)
apps/agent-provisioning/src/agent-provisioning.service.ts (1)

1-10: LGTM!

The import reorganization improves readability by grouping related imports together.

libs/common/src/response-messages/index.ts (1)

226-226: Appropriate message update for the new synchronous flow.

The change from an "initiated" message to "created successfully" aligns with the updated API behavior that now returns richer wallet details immediately rather than a pending status.

apps/agent-service/src/repositories/agent-service.repository.ts (4)

1-27: LGTM!

Import reorganization is clean. The addition of ICreateOrgAgent and IStoreOrgAgentDetails interfaces supports the updated method signatures.


103-120: LGTM!

The createOrgAgent method now correctly accepts and stores orgId, enabling proper organization context tracking from the initial agent creation.


159-211: Return type is narrower than IStoreOrgAgentDetails interface.

The method's explicit return type specifies only 6 fields (orgId, agentSpinUpStatus, agentEndPoint, tenantId, walletName, id), but the IStoreOrgAgentDetails interface (used in the service layer) has 24 optional fields. This is intentional narrowing for this specific flow, but ensure callers don't expect additional fields like apiKey, did, or verkey from this method's return value.


263-282: LGTM!

The new updateAgentSpinupStatus method correctly updates the agent status to COMPLETED using orgId as the unique identifier. Error handling follows the established pattern in this repository.

apps/agent-service/src/agent-service.controller.ts (2)

1-31: LGTM!

Import reorganization is clean and properly includes IStoreOrgAgentDetails to support the updated return type.


49-55: I'll help you verify this review comment about the breaking change in the createTenant method's return type. Let me search the codebase to understand the scope of this change and its impact on downstream consumers.
<function_calls>


#!/bin/bash

Search for create-tenant message pattern usage and callers

rg -n -A 10 "'create-tenant'" --type=ts

echo "---"
echo "Searching for alternative patterns:"
rg -n '"create-tenant"' --type=ts

echo "---"
echo "Searching for old response type references:"
rg -n "IAgentSpinUpSatus|IAgentSpinupStatus|agent.*status" --type=ts -i


</function_calls>

<function_calls>


#!/bin/bash

Find IStoreOrgAgentDetails definition

rg -n "interface IStoreOrgAgentDetails|type IStoreOrgAgentDetails|export.*IStoreOrgAgentDetails" --type=ts

echo "---"
echo "Search for any related agent details types:"
rg -n "interface.*Agent.*Details|type.*Agent.*Details" --type=ts


</function_calls>

<function_calls>


#!/bin/bash

Check the actual file to see the full context around the method

cat -n apps/agent-service/src/agent-service.controller.ts | head -100


</function_calls>

<function_calls>


#!/bin/bash

Find all message pattern usages in the codebase

rg -n "MessagePattern|send.*create-tenant|@MessagePattern" --type=ts | grep -i "create-tenant|send"

echo "---"
echo "Look for RPC client usage for agent-service:"
rg -n "agent-service|AgentService" --type=ts | head -30


</function_calls>

apps/agent-service/src/agent-service.service.ts (3)

130-130: LGTM!

The simplified return of AgentSpinUpStatus.COMPLETED after successful wallet provisioning is clean and appropriate.


445-447: LGTM!

The updated createOrgAgent signature now properly accepts orgId, enabling correct organization association during agent creation. The repository call is updated accordingly.


965-967: LGTM!

The conditional status update to COMPLETED after DID creation correctly implements the two-step workflow. The check for PROCESSED status ensures this only applies to the new wallet creation flow.

@pranalidhanavade
Copy link
Contributor Author

@coderabbitai

@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Tip

For best results, initiate chat on the files or code changes.

@pranalidhanavade, hello! How can I help you with this pull request?

I can assist you with:

  • Reviewing the changes in this PR
  • Answering questions about the code
  • Generating tests or documentation
  • Analyzing specific parts of the implementation
  • Checking for issues or potential improvements

Please let me know what you'd like me to do!

@pranalidhanavade
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pranalidhanavade pranalidhanavade self-assigned this Nov 27, 2025
@GHkrishna GHkrishna changed the title Feat/create wallet api changes feat: simplify wallet provisioning flow (detach did creation) Nov 27, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/agent-service/src/agent-service.service.ts (1)

805-811: Add validation for the wallet token.

The validation only checks for walletResponseDetails.id, but the wallet token is also critical. Line 1088 validates both id and token. For consistency, this validation should also check for the token.

Apply this diff:

-      if (!tenantDetails?.walletResponseDetails?.id) {
+      if (!tenantDetails?.walletResponseDetails?.id || !tenantDetails?.walletResponseDetails?.token) {
         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
         });
       }
♻️ Duplicate comments (1)
apps/agent-service/src/agent-service.service.ts (1)

1088-1090: Fix the validation logic error.

The condition uses && (AND) operators which is incorrect. If walletResponseDetails is falsy, accessing .id or .token will throw a TypeError. The validation should check if ANY of these are missing using || (OR).

Apply this diff:

-    if (!walletResponseDetails && !walletResponseDetails.id && !walletResponseDetails.token) {
+    if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
       throw new InternalServerErrorException('Error while creating the wallet');
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b805fb7 and 57f6e29.

📒 Files selected for processing (1)
  • apps/agent-service/src/agent-service.service.ts (10 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/agent-service.service.ts (2)
apps/agent-service/src/interface/agent-service.interface.ts (4)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IUserRequestInterface (237-250)
  • IStoreOrgAgentDetails (177-201)
apps/connection/src/interfaces/connection.interfaces.ts (1)
  • IUserRequestInterface (21-33)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Take the required action to fix the issue indicated by this comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrKiYWXHtm4cnk2M99i&open=AZrKiYWXHtm4cnk2M99i&pullRequest=1528

🔇 Additional comments (5)
apps/agent-service/src/agent-service.service.ts (5)

825-825: LGTM: Two-phase status flow.

Setting agentSpinUpStatus to PROCESSED here is correct. The status will be updated to COMPLETED when createDid is called (lines 927-929), which aligns with the separation of wallet and DID creation.


1091-1093: LGTM: Simplified return value.

The method now returns only walletResponseDetails without DID information, which correctly reflects the separation of wallet and DID creation flows as intended by this PR.


745-758: I'll verify that callers can handle the new return type for the createTenant method. Let me search for all usages of this method.
<function_calls>


#!/bin/bash

Find all call sites of createTenant method

rg -n -C3 'createTenant(' --type=ts --type=js


</function_calls>
<function_calls>


#!/bin/bash

Find files that contain createTenant references (controllers, gateways, etc.)

fd -e ts -e js | xargs rg -l 'createTenant' | head -20


</function_calls>


927-929: I'll help you verify the agent status update behavior. Let me search for the updateAgentSpinupStatus method implementation to understand what status it sets.
<function_calls>

#!/bin/bash

Search for the updateAgentSpinupStatus method definition

rg -n -A15 'updateAgentSpinupStatus' --type ts --type js


</function_calls>

I need to search for the method implementation to verify the status update behavior. Let me refine the search:
<function_calls>

#!/bin/bash

First, find files that contain updateAgentSpinupStatus

fd -e ts -e js | xargs rg -l 'updateAgentSpinupStatus'

Then search for the method definition with context

rg -n 'updateAgentSpinupStatus\s*(' -A20 --type ts


</function_calls>


444-446: Repository method signature verified and matches the service method call.

The repository method createOrgAgent at apps/agent-service/src/repositories/agent-service.repository.ts:103 has been correctly updated to accept the orgId parameter:

async createOrgAgent(agentSpinUpStatus: number, userId: string, orgId: string): Promise<ICreateOrgAgent>

This matches the service method call at line 446 which passes all three parameters in the correct order. The parameter passing is consistent across both call sites (lines 233 and 796).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/agent-service/src/agent-service.service.ts (2)

129-129: Status semantically misleading — async spinup not awaited.

The return of AgentSpinUpStatus.COMPLETED is misleading since _agentSpinup at line 236 runs asynchronously without await. The HTTP response claims completion before the actual spinup finishes. Consider returning IN_PROGRESS or PROCESSING instead.


146-148: Resolve the FIXME comment about ledgerName handling.

The FIXME indicates an unresolved decision about whether to use the first element or process all elements of the ledgerName array. Please clarify the intended behavior and remove the FIXME.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57f6e29 and 1d9b227.

📒 Files selected for processing (1)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/agent-service.service.ts (3)
apps/agent-service/src/interface/agent-service.interface.ts (4)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IUserRequestInterface (237-250)
  • IStoreOrgAgentDetails (177-201)
apps/ledger/src/schema/interfaces/schema.interface.ts (1)
  • IUserRequestInterface (5-18)
apps/connection/src/interfaces/connection.interfaces.ts (1)
  • IUserRequestInterface (21-33)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Take the required action to fix the issue indicated by this comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrKiYWXHtm4cnk2M99i&open=AZrKiYWXHtm4cnk2M99i&pullRequest=1528

🔇 Additional comments (5)
apps/agent-service/src/agent-service.service.ts (5)

444-446: LGTM!

The createOrgAgent signature correctly updated to accept orgId, and the repository call properly passes it through. This aligns with the flow changes to associate org agents with their organization from creation.


745-758: LGTM!

The return type change to IStoreOrgAgentDetails provides richer tenant/agent details to callers, aligning with the PR objective to simplify the wallet provisioning flow.


805-805: Good use of optional chaining.

The tenantDetails?.walletResponseDetails?.id safely handles potential null/undefined values in the response chain.


824-840: Verify the intentional PROCESSED status in the new flow.

The tenant is now stored with AgentSpinUpStatus.PROCESSED instead of COMPLETED. Based on lines 927-929, the status gets updated to COMPLETED when createDid is called and the agent is in PROCESSED state. This implements the new two-phase approach where wallet creation and DID creation are decoupled.

Ensure this flow is documented and that API consumers understand they need to call createDid to complete the provisioning.


927-929: Good addition for completing the provisioning flow.

This correctly updates the agent status to COMPLETED after DID creation when the agent was in PROCESSED state, completing the two-phase wallet provisioning flow.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
apps/agent-service/src/agent-service.service.ts (3)

120-134: walletProvision still returns COMPLETED while spin‑up runs asynchronously.

walletProvision awaits processWalletProvision but that method starts _agentSpinup without await, so the HTTP call can return before the agent is actually spun up, while you return AgentSpinUpStatus.COMPLETED (line 129). This can mislead API consumers who may assume the agent is ready.

Consider either:

  • returning a “PROCESSED/IN_PROGRESS”‑style status from walletProvision, or
  • awaiting _agentSpinup inside processWalletProvision so COMPLETED truly means done.

Also applies to: 232-247


142-210: Clarify and resolve the ledgerName TODO to avoid future ambiguity.

The TODO on line 146 about “get first element from ledgerName” is still unresolved while you pass agentSpinupDto.ledgerName (possibly an array) directly into getLedgerDetails. Please decide and encode the intended behavior (single ledger vs multi‑ledger) and remove the TODO, e.g.:

  • If only one ledger is supported here, explicitly use agentSpinupDto.ledgerName[0].
  • If multiple ledgers are valid, make that clear in the DTO and repository API and ensure downstream code handles multiple ledger IDs consistently.

745-763: Shared‑agent _createTenant can still leave orphaned orgAgent records on failure.

In _createTenant, you create an orgAgent record (line 796) and later persist final details (line 838). If anything after createOrgAgent fails (tenant wallet creation, encryption, storing details, etc.), the catch block only calls this.handleError(...) and rethrows (lines 842‑845). There is no call to removeOrgAgent(agentProcess.id), so failed attempts can leave a PROCESSED orgAgent row that blocks future spin‑ups with “walletAlreadyProcessing”.

Recommend restoring explicit cleanup in this catch:

    } catch (error) {
      this.handleError(error, payload.clientSocketId);
- 
-      throw error;
+      if (agentProcess && agentProcess.id) {
+        await this.agentServiceRepository.removeOrgAgent(agentProcess.id);
+      }
+      throw error;
    }

This matches the pattern you already use in _agentSpinup and avoids inconsistent state.

Also applies to: 771-846

🧹 Nitpick comments (2)
apps/agent-service/src/agent-service.service.ts (2)

481-491: Ledger handling in _agentSpinup is reasonable; null vs [] is a minor contract choice.

Initializing ledgerIdData lazily and then mapping to ledgerId: ledgerIdData ? ledgerIdData.map(...) : null is functionally fine. Just ensure callers and DB schema treat null and “no ledgers” consistently (previously this may have been []), otherwise consider standardizing on an empty array.

Also applies to: 542-557


1068-1094: Wallet response validation is now safe; optional chaining would further simplify it.

The updated check:

if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token)

fixes the earlier && bug and avoids accessing .id/.token on a nullish value; returning { walletResponseDetails } (lines 1091‑1093) matches how _createTenant now consumes it.

If you want to follow the Sonar suggestion and reduce verbosity, you can use optional chaining:

if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
  throw new InternalServerErrorException('Error while creating the wallet');
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d9b227 and 86d79f2.

📒 Files selected for processing (1)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/agent-service.service.ts (4)
apps/agent-service/src/interface/agent-service.interface.ts (4)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IUserRequestInterface (237-250)
  • IStoreOrgAgentDetails (177-201)
apps/ledger/src/schema/interfaces/schema.interface.ts (1)
  • IUserRequestInterface (5-18)
apps/connection/src/interfaces/connection.interfaces.ts (1)
  • IUserRequestInterface (21-33)
apps/api-gateway/src/connection/interfaces/index.ts (1)
  • IUserRequestInterface (3-15)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1088-1088: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (2)
apps/agent-service/src/agent-service.service.ts (2)

233-233: Org‑scoped createOrgAgent looks consistent with new flow.

Passing agentSpinupDto.orgId into createOrgAgent and threading orgId through to the repository aligns org‑agent records with their organization and supports later cleanup/status updates. The try/catch with logging around createOrgAgent is straightforward and fine.

Also applies to: 444-453


885-931: Updating agentSpinUpStatus to completed on successful DID creation is a good addition.

The new block that calls updateAgentSpinupStatus(orgId) when agentDetails.agentSpinUpStatus === AgentSpinUpStatus.PROCESSED (lines 927‑929) cleanly ties the state transition to successful DID creation, aligning with the “wallet provision first, DID later” design.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/agent-service/src/agent-service.service.ts (2)

136-150: Clarify ledgerName usage and tighten ledgerIdData typing.

  1. The TODO at Line 146 (// TODO: Do we want to get first element from ledgerName) leaves behavior ambiguous. Currently you're passing the entire ledgerName array (or [Ledgers.Indicio_Demonet]) into getLedgerDetails and later normalizing agentSpinupDto.ledgerName to an array. Please either:

    • Decide to support multiple ledgers and remove/replace the TODO with a clear comment that ledgerName is intentionally an array, or
    • If only one ledger is supported, change the call to something like:
      this.agentServiceRepository.getLedgerDetails(
        agentSpinupDto.ledgerName?.[0] ?? Ledgers.Indicio_Demonet
      );

    This will also address the Sonar TODO warning.

  2. In _agentSpinup, let ledgerIdData; (Line 491) is implicitly any. Since you later call ledgerIdData.map((item) => item.id), consider typing it explicitly, e.g.:

    let ledgerIdData: ledgers[] | undefined;

    This makes the intent and shape clearer and avoids implicit-any surprises.

Also applies to: 178-210, 491-491


771-846: Prevent tenant spin-up from getting stuck in PROCESSED and fix minor issues in _createTenant.

Two behaviors here are worth tightening:

  1. Orphaned org_agents row on failure (can permanently block tenant creation).

    _createTenant creates an org agent row with status PROCESSED:

    agentProcess = await this.agentServiceRepository.createOrgAgent(
      agentSpinUpStatus,
      user?.id,
      payload.orgId
    );

    but in the catch block you only call this.handleError(error, payload.clientSocketId); and rethrow. There is no cleanup of agentProcess. Because createTenant short-circuits when it sees AgentSpinUpStatus.PROCESSED for that org (Line 749), any failure after createOrgAgent (e.g., during platform admin lookup, tenant wallet creation, or storing details) will leave the org in a permanently “processing” state until manually fixed in the DB.

    Consider explicitly removing or resetting that orgAgent entry in the catch:

    } catch (error) {
  •  this.handleError(error, payload.clientSocketId);
    
  •  throw error;
    
  •  if (agentProcess?.id) {
    
  •    await this.agentServiceRepository.removeOrgAgent(agentProcess.id);
    
  •  }
    
  •  await this.handleError(error, payload.clientSocketId);
    
  •  throw error;
    
    }
    
    This aligns the shared-tenant path with the dedicated-wallet path, where failures clean up partial state.  
    
    
    
  1. Unused ledgerIdData in _createTenant.

    let ledgerIdData = []; is assigned from getLedgerDetails (Line 791) but never used afterwards. Either wire it into the stored data (if tenant records should track ledger IDs) or remove it to avoid confusion.

  2. Possibly invalid error key notAbleToSpinUpAgent.

    In the wallet-id check:

    throw new NotFoundException(ResponseMessages.agent.error.notAbleToSpinUpAgent, { ... });

    the key notAbleToSpinUpAgent does not appear in the provided ResponseMessages.agent.error snippet (there are notAbleToSpinUp, notAbleToSpinup, notAbleToSpinp, etc.). If this key isn’t defined, the exception will carry a generic/not-intended message. Please either add the key to libs/common/src/response-messages/index.ts or reuse one of the existing constants that best matches the intent.

🧹 Nitpick comments (3)
apps/agent-service/src/agent-service.service.ts (3)

120-133: Remove unused agentProcess in walletProvision and delegate cleanup to agentWalletProvision.

In walletProvision, agentProcess is declared but never assigned; the catch block calls handleErrorOnWalletProvision with agentProcess always undefined, so that method is effectively a no-op here. All real cleanup and socket error emission already happen inside agentWalletProvision / _agentSpinup.

You can simplify and avoid confusion by removing the local agentProcess and its use:

-  async walletProvision(
+  async walletProvision(
     agentSpinupDto: IAgentSpinupDto,
     user: IUserRequestInterface
   ): Promise<{
     agentSpinupStatus: AgentSpinUpStatus;
   }> {
-    let agentProcess: ICreateOrgAgent;
     try {
       await this.agentWalletProvision(agentSpinupDto, user);
       return { agentSpinupStatus: AgentSpinUpStatus.COMPLETED };
     } catch (error) {
-      this.handleErrorOnWalletProvision(agentSpinupDto, error, agentProcess);
       throw new RpcException(error.response ?? error);
     }
   }

444-447: Reuse createOrgAgent helper inside _createTenant for consistency.

You’ve introduced createOrgAgent as a centralized helper wrapping the repository call with logging and error handling (Lines 444-447), but _createTenant still calls this.agentServiceRepository.createOrgAgent(...) directly (Line 795).

For consistency and to avoid diverging behavior over time, consider reusing the helper:

-      agentProcess = await this.agentServiceRepository.createOrgAgent(agentSpinUpStatus, user?.id, payload.orgId);
+      agentProcess = await this.createOrgAgent(agentSpinUpStatus, user?.id, payload.orgId);

Also, typing agentProcess in _createTenant as ICreateOrgAgent | undefined would better document what this variable holds.

Also applies to: 771-797


1068-1094: Validation of walletResponseDetails is now safe; optional chaining can simplify per Sonar.

The new guard:

if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
  throw new InternalServerErrorException('Error while creating the wallet');
}

correctly protects against null/undefined walletResponseDetails and missing id/token, fixing the earlier bug where .id could be accessed on a nullish value.

To satisfy the Sonar suggestion and make it a bit more idiomatic, you could express the same logic with optional chaining:

-    if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
+    if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
       throw new InternalServerErrorException('Error while creating the wallet');
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 86d79f2 and 1c0daf6.

📒 Files selected for processing (1)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/agent-service.service.ts (3)
apps/agent-service/src/interface/agent-service.interface.ts (5)
  • IAgentSpinupDto (5-32)
  • IUserRequestInterface (237-250)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IStoreOrgAgentDetails (177-201)
apps/connection/src/interfaces/connection.interfaces.ts (1)
  • IUserRequestInterface (21-33)
apps/api-gateway/src/connection/interfaces/index.ts (1)
  • IUserRequestInterface (3-15)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1088-1088: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (1)
apps/agent-service/src/agent-service.service.ts (1)

885-931: Good alignment: advance agentSpinUpStatus to COMPLETED only after DID creation.

The new block in createDid:

if (agentDetails.agentSpinUpStatus === AgentSpinUpStatus.PROCESSED) {
  await this.agentServiceRepository.updateAgentSpinupStatus(orgId);
}

ensures the stored agentSpinUpStatus transitions from PROCESSED to COMPLETED only after a DID has actually been created and stored. This matches the goal of decoupling wallet provisioning from DID creation while still reflecting a final “completed” state once DID setup finishes.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/agent-service/src/agent-service.service.ts (2)

128-129: Return status COMPLETED remains semantically misleading.

The method awaits provisionWallet, but provisionWallet internally calls _agentSpinup without await (line 236). The actual agent spinup runs asynchronously and signals completion via WebSocket events, yet the HTTP response already claims AgentSpinUpStatus.COMPLETED. Consider returning AgentSpinUpStatus.PROCESSED or IN_PROGRESS to accurately reflect the asynchronous nature of the operation.


146-148: Resolve the TODO about ledgerName array handling.

The TODO comment indicates an unresolved decision about how to handle the ledgerName array. The current code passes the array directly to getLedgerDetails, but it's unclear whether:

  • Only the first element should be used
  • All elements should be processed
  • The array handling is intentionally correct

Please clarify the intended behavior and remove the TODO once resolved.

🧹 Nitpick comments (1)
apps/agent-service/src/agent-service.service.ts (1)

1088-1093: Consider using optional chaining for cleaner validation.

The validation logic is now correct. For improved readability, consider using optional chaining as suggested by static analysis:

-    if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
+    if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
       throw new InternalServerErrorException('Error while creating the wallet');
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c0daf6 and aefd1fe.

📒 Files selected for processing (1)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/agent-service.service.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (5)
  • IAgentSpinupDto (5-32)
  • IUserRequestInterface (237-250)
  • ICreateOrgAgent (449-451)
  • ITenantDto (56-73)
  • IStoreOrgAgentDetails (177-201)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1088-1088: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (5)
apps/agent-service/src/agent-service.service.ts (5)

444-446: LGTM!

The orgId parameter threading through createOrgAgent is correctly implemented. The method signature and repository call are consistent.


745-758: LGTM!

The return type change from IAgentSpinUpSatus to IStoreOrgAgentDetails is correctly propagated through createTenant and _createTenant. This provides richer tenant/agent details as intended by the PR.


802-811: LGTM!

The simplified tenant creation flow correctly:

  1. Creates the tenant wallet via createTenantAndNotify
  2. Uses optional chaining (tenantDetails?.walletResponseDetails?.id) for safe property access
  3. Throws appropriate error when wallet creation fails

824-840: LGTM!

Setting agentSpinUpStatus: AgentSpinUpStatus.PROCESSED correctly reflects the decoupled workflow where the wallet is created but DID creation is deferred. The status transitions to COMPLETED when createDid is subsequently called (lines 927-929). This aligns with the PR objective to detach DID creation from wallet provisioning.


927-929: Status transition to COMPLETED is correctly implemented.

The updateAgentSpinupStatus method properly updates the agent spinup status from PROCESSED to COMPLETED when DID creation is successful. The logic at lines 927-929 correctly completes the decoupled wallet/DID creation workflow.

* @param orgId
*/
// eslint-disable-next-line camelcase
async updateAgentSpinupStatus(orgId: string): Promise<org_agents> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think most of the update function can be combined like the: updateLedgerId, updateTenantToken

…out did for shared agent

Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
@pranalidhanavade pranalidhanavade force-pushed the feat/create-wallet-api-changes branch from aefd1fe to b05e0ac Compare December 1, 2025 12:52
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
apps/agent-service/src/agent-service.service.ts (2)

128-129: Status COMPLETED is misleading—wallet provisioning completes before async agent spinup finishes.

The method returns AgentSpinUpStatus.COMPLETED after calling provisionWallet, but the actual agent spinup process is initiated asynchronously at line 236 without await. This means the HTTP response claims completion while the background spinup is still in progress, potentially misleading API consumers.

Consider either:

  1. Return AgentSpinUpStatus.IN_PROGRESS or AgentSpinUpStatus.PROCESSING to reflect the asynchronous nature, OR
  2. Await the _agentSpinup call to ensure completion before returning COMPLETED status.

851-854: Missing cleanup for orphaned agent record on error.

If an error occurs in _createTenant after agentProcess is created at line 796, the catch block at lines 851-854 calls handleError but does not clean up the orphaned agent record. The handleError method (lines 1186-1193) only emits a socket event and doesn't remove the agent.

This could leave the database in an inconsistent state with a PROCESSED agent that never completed.

Apply this diff to add cleanup:

     } catch (error) {
       this.handleError(error, payload.clientSocketId);
+
+      if (agentProcess?.id) {
+        await this.agentServiceRepository.removeOrgAgent(agentProcess.id);
+      }
+
       throw error;
     }
apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts (1)

27-28: Add validation decorators or exclude orgId from client input.

The orgId property still lacks validation/serialization decorators. Based on past review comments, this remains unresolved:

  • If orgId is expected from the client request body, add @ApiProperty(), @IsString(), and @IsNotEmpty() decorators.
  • If orgId is set server-side (which seems likely based on the AI summary), use @Exclude() from class-transformer to prevent client injection.

Apply this diff if orgId should be excluded from client input:

+import { Exclude } from 'class-transformer';
+
 export class CreateTenantDto {
   ...
+  @Exclude()
   orgId: string;
 }

Or if orgId is client-provided:

+  @ApiProperty()
+  @IsString({ message: 'orgId must be in string format.' })
+  @IsNotEmpty({ message: 'orgId is required.' })
   orgId: string;
🧹 Nitpick comments (1)
apps/agent-service/src/agent-service.service.ts (1)

1097-1099: Consider optional chaining for cleaner validation.

The validation logic is now correct with OR operators. However, you can make it more concise using optional chaining:

Apply this diff:

-    if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
+    if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
       throw new InternalServerErrorException('Error while creating the wallet');
     }

As per static analysis hints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aefd1fe and b05e0ac.

📒 Files selected for processing (6)
  • apps/agent-provisioning/src/agent-provisioning.service.ts (1 hunks)
  • apps/agent-service/src/agent-service.controller.ts (2 hunks)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
  • apps/agent-service/src/repositories/agent-service.repository.ts (6 hunks)
  • apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts (1 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/agent-service/src/agent-service.controller.ts
  • apps/agent-provisioning/src/agent-provisioning.service.ts
🧰 Additional context used
🧬 Code graph analysis (2)
apps/api-gateway/src/agent-service/dto/create-tenant.dto.ts (3)
libs/validations/maxLength.ts (1)
  • MaxLength (3-28)
libs/common/src/cast.helper.ts (1)
  • trim (39-43)
libs/validations/minLength.ts (1)
  • MinLength (3-28)
apps/agent-service/src/agent-service.service.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (4)
  • IAgentSpinupDto (5-32)
  • IUserRequestInterface (237-250)
  • ICreateOrgAgent (449-451)
  • IStoreOrgAgentDetails (177-201)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1097-1097: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (7)
libs/common/src/response-messages/index.ts (1)

226-226: LGTM! Clear and user-friendly message.

The updated success message is more descriptive and aligns well with the simplified wallet provisioning flow described in the PR objectives.

apps/agent-service/src/repositories/agent-service.repository.ts (3)

103-120: LGTM! Threading orgId through agent creation.

The addition of the orgId parameter to createOrgAgent properly establishes the organization relationship at agent creation time, which aligns with the simplified wallet provisioning flow.


159-211: LGTM! Enriched return type provides better context.

The expanded return type from storeOrgAgentDetails now includes essential agent details (orgId, agentEndPoint, tenantId, walletName) in addition to the ID and status. This richer data shape supports the simplified wallet provisioning flow by allowing callers to access all necessary tenant/agent details without additional queries.

The consistent select clauses in both create and update paths ensure uniform behavior.


263-282: LGTM! Clean method for updating agent spinup status.

The new updateAgentSpinupStatus method provides a focused API for transitioning agents to COMPLETED status. The implementation is straightforward with appropriate error handling.

apps/agent-service/src/agent-service.service.ts (3)

745-763: LGTM! Enriched return type provides better tenant details.

The updated createTenant signature now returns IStoreOrgAgentDetails instead of a simple status object, providing callers with comprehensive tenant and agent information. This aligns well with the simplified wallet provisioning flow.


771-855: LGTM! Simplified tenant creation with richer response.

The _createTenant method now returns complete organization agent details, streamlining the tenant provisioning workflow. The removal of DID creation and related socket notifications from this flow aligns with the PR objective to decouple DID creation from wallet provisioning.


936-938: LGTM! Proper status transition after DID creation.

The logic to update agent spinup status to COMPLETED after DID creation (when status is PROCESSED) properly completes the agent provisioning lifecycle. This aligns with the decoupled DID creation workflow.

Signed-off-by: pranalidhanavade <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
apps/agent-service/src/agent-service.service.ts (3)

120-134: Status COMPLETED is misleading—agent spinup runs asynchronously.

The method returns AgentSpinUpStatus.COMPLETED after awaiting provisionWallet (line 128), but provisionWallet calls _agentSpinup without await (line 236). The actual agent spinup runs asynchronously and signals completion via websocket events. The HTTP response status should reflect IN_PROGRESS or PROCESSING instead of COMPLETED to accurately represent the asynchronous nature of the operation.


146-148: Resolve the TODO comment about ledgerName handling.

The TODO indicates uncertainty about whether to use the first element or the entire ledgerName array. The current implementation passes the full array (or a default array) to getLedgerDetails, which suggests multi-ledger support is intended. Either remove the TODO if the current approach is correct, or clarify and implement the intended behavior explicitly.

Based on static analysis.


851-854: Missing cleanup for orphaned agent record on error.

If an error occurs after creating the agentProcess record (line 796), the catch block (line 852) calls handleError but doesn't remove the orphaned agent record. This could leave the database in an inconsistent state with a PROCESSED agent that never completed.

Apply this diff to add cleanup:

     } catch (error) {
       this.handleError(error, payload.clientSocketId);
+
+      if (agentProcess?.id) {
+        await this.agentServiceRepository.removeOrgAgent(agentProcess.id);
+      }
+
       throw error;
     }
🧹 Nitpick comments (1)
apps/agent-service/src/agent-service.service.ts (1)

1097-1102: LGTM! Validation logic fixed and return simplified.

The validation at line 1097 now correctly uses || operators to short-circuit when walletResponseDetails or its required properties are missing. The return statement is also simplified to return only walletResponseDetails.

Optional improvement: Consider using optional chaining for even cleaner validation:

if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
  throw new InternalServerErrorException('Error while creating the wallet');
}

Based on static analysis.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b05e0ac and 6fb1b25.

📒 Files selected for processing (2)
  • apps/agent-service/src/agent-service.service.ts (11 hunks)
  • apps/agent-service/src/repositories/agent-service.repository.ts (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/repositories/agent-service.repository.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (2)
  • ICreateOrgAgent (449-451)
  • IStoreOrgAgentDetails (177-201)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1097-1097: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (6)
apps/agent-service/src/repositories/agent-service.repository.ts (3)

103-120: LGTM! Signature updated to include orgId.

The method now correctly accepts and persists orgId during agent creation, aligning with the PR objective to thread organization context through the provisioning flow.


159-211: LGTM! Return type expanded to provide richer tenant details.

The method now returns a comprehensive object containing orgId, agentSpinUpStatus, agentEndPoint, tenantId, walletName, and id instead of just the id. Both create and update paths consistently select the same fields, which aligns with the updated controller/service layer expectations.


263-282: LGTM! New method to mark agent spinup completion.

The updateAgentSpinupStatus method correctly updates the agent status to COMPLETED for a given organization. The implementation is straightforward with appropriate error logging.

apps/agent-service/src/agent-service.service.ts (3)

444-453: LGTM! Method signature updated to include orgId.

The createOrgAgent service method now correctly accepts and passes orgId to the repository layer, maintaining consistency across the provisioning flow.


936-938: LGTM! Agent spinup status updated upon DID creation.

When a DID is created and the agent status is still PROCESSED, this logic correctly updates it to COMPLETED. This aligns with the PR objective to detach DID creation from the wallet provisioning flow, allowing the agent status to be completed only after explicit DID creation.


824-834: LGTM! Tenant creation sets status to PROCESSED, awaiting DID creation.

The tenant creation flow correctly sets agentSpinUpStatus to PROCESSED rather than COMPLETED. This aligns with the PR objective to detach DID creation—the agent spinup will be marked COMPLETED only when a DID is explicitly created via createDid (lines 936-938).

Signed-off-by: pranalidhanavade <[email protected]>
Signed-off-by: pranalidhanavade <[email protected]>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2025

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/agent-service/src/repositories/agent-service.repository.ts (1)

159-178: Avoid wiping createdBy / lastChangedBy on updates in storeOrgAgentDetails.

On the update path (id present), userId is often not passed by callers (e.g. _storeOrgAgentDetails, _createTenant), so:

const { id, orgId, did, userId, ledgerId, didDoc, ...commonFields } = storeOrgAgentDetails;

const data = {
  ...commonFields,
  orgId,
  ledgerId: firstLedgerId,
  createdBy: userId,
  lastChangedBy: userId,
  didDocument: didDoc,
  orgDid: did
};

will overwrite existing createdBy and lastChangedBy with undefined/null, losing audit information whenever an existing agent row is updated.

Safer pattern: only set createdBy on create, and always set lastChangedBy when you actually have a userId:

-      const data = {
-        ...commonFields,
-        orgId,
-        ledgerId: firstLedgerId,
-        createdBy: userId,
-        lastChangedBy: userId,
-        didDocument: didDoc,
-        orgDid: did
-      };
+      const baseData = {
+        ...commonFields,
+        orgId,
+        ledgerId: firstLedgerId,
+        didDocument: didDoc,
+        orgDid: did
+      };
+
+      const data = id
+        ? {
+            ...baseData,
+            ...(userId && { lastChangedBy: userId })
+          }
+        : {
+            ...baseData,
+            createdBy: userId,
+            lastChangedBy: userId
+          };
@@
-      const query = id
-        ? this.prisma.org_agents.update({
-            where: { id },
-            data,
+      const query = id
+        ? this.prisma.org_agents.update({
+            where: { id },
+            data,
@@
-        : this.prisma.org_agents.create({
-            data,
+        : this.prisma.org_agents.create({
+            data,

This preserves original createdBy on updates while still tracking the latest modifier.

Also applies to: 181-207

apps/agent-service/src/agent-service.service.ts (1)

120-137: Agent spin-up/DID status is misleading vs actual flow; align AgentSpinUpStatus usage with detached DID creation.

Right now:

  • walletProvision returns { agentSpinupStatus: AgentSpinUpStatus.DID_CREATED } after await this.provisionWallet(...).
  • provisionWallet triggers _agentSpinup(...) without await, so the HTTP call completes before spin-up is actually done.
  • _agentSpinup stores org-agent details via _storeOrgAgentDetails, which hardcodes agentSpinUpStatus: AgentSpinUpStatus.DID_CREATED in _buildStoreOrgAgentData.
  • Actual DID creation is now handled by createDid, which also bumps status from WALLET_CREATEDDID_CREATED via updateAgentSpinupStatus.

This leads to two problems:

  1. The API reports DID_CREATED synchronously even though:

    • Agent spin-up is still in progress (fire-and-forget _agentSpinup).
    • No DID has been created yet (that’s now a separate createDid call).
  2. The DB status for dedicated wallets is set to DID_CREATED as soon as wallet provisioning finishes, so createDid can run while the status already claims DID is created, and updateAgentSpinupStatus is never used for that path.

To match the “detach DID creation” goal and keep statuses meaningful:

  • Treat AgentSpinUpStatus.WALLET_CREATED as “wallet provisioned/agent record created” and DID_CREATED as “at least one DID successfully written and stored”.
  • In that model:
    • _buildStoreOrgAgentData should set agentSpinUpStatus: AgentSpinUpStatus.WALLET_CREATED.
    • walletProvision should return { agentSpinupStatus: AgentSpinUpStatus.WALLET_CREATED } (or even PENDING) rather than DID_CREATED.
    • Only createDid should advance status to DID_CREATED via updateAgentSpinupStatus once DID persistence succeeds.

Concrete sketch:

// walletProvision
-      await this.provisionWallet(agentSpinupDto, user);
-      return { agentSpinupStatus: AgentSpinUpStatus.DID_CREATED };
+      await this.provisionWallet(agentSpinupDto, user);
+      return { agentSpinupStatus: AgentSpinUpStatus.WALLET_CREATED };

// _buildStoreOrgAgentData
-      isDidPublic: true,
-      agentSpinUpStatus: AgentSpinUpStatus.DID_CREATED,
+      isDidPublic: true,
+      agentSpinUpStatus: AgentSpinUpStatus.WALLET_CREATED,

With this, the lifecycle becomes:
PENDING → WALLET_CREATED (after wallet/agent provisioning) and only later → DID_CREATED via createDid, which keeps both API responses and DB state honest.

Also applies to: 225-227, 474-555, 617-623, 887-932

🧹 Nitpick comments (3)
apps/agent-service/src/repositories/agent-service.repository.ts (2)

102-111: Type agentSpinUpStatus as AgentSpinUpStatus instead of number.

createOrgAgent currently accepts agentSpinUpStatus: number even though the enum is imported. Tightening this to AgentSpinUpStatus will prevent accidental invalid values and better document the lifecycle.

-  async createOrgAgent(agentSpinUpStatus: number, userId: string, orgId: string): Promise<ICreateOrgAgent> {
+  async createOrgAgent(
+    agentSpinUpStatus: AgentSpinUpStatus,
+    userId: string,
+    orgId: string
+  ): Promise<ICreateOrgAgent> {

263-282: updateAgentSpinupStatus is fine; consider returning a narrowed projection.

The update-by-orgId to AgentSpinUpStatus.DID_CREATED matches the new enum and shared-wallet DID lifecycle. If callers only need status/orgId, you might return a narrowed select similar to storeOrgAgentDetails for consistency, but that’s an optional polish.

apps/agent-service/src/agent-service.service.ts (1)

146-148: Resolve ledgerName TODO and optionally simplify wallet-response validation.

A couple of small but worthwhile cleanups:

  1. Clarify ledgerName handling and remove the TODO
const [platformConfig, getAgentType, ledgerIdData] = await Promise.all([
  // ...
  this.agentServiceRepository.getLedgerDetails(
-    // TODO: Do we want to get first element from ledgerName
-    agentSpinupDto.ledgerName ? agentSpinupDto.ledgerName : [Ledgers.Indicio_Demonet]
+    agentSpinupDto.ledgerName && agentSpinupDto.ledgerName.length
+      ? agentSpinupDto.ledgerName
+      : [Ledgers.Indicio_Demonet]
  )
]);

Combined with:

agentSpinupDto.ledgerName = agentSpinupDto.ledgerName?.length
  ? agentSpinupDto.ledgerName
  : [Ledgers.Indicio_Demonet];

you’re already treating ledgerName as an array with sensible defaulting. I’d suggest:

  • Keeping the “array of ledger names” contract.
  • Removing the TODO comment.
  • Optionally adding a brief JSDoc on IAgentSpinupDto.ledgerName to state it’s an array and that all entries are resolved via getLedgerDetails.
  1. Optional: use optional chaining for tenant wallet validation

The validation in createTenantAndNotify is now logically correct:

if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
  throw new InternalServerErrorException('Error while creating the wallet');
}

To satisfy the static-analysis hint and improve readability, you could shrink it to:

-    if (!walletResponseDetails || !walletResponseDetails.id || !walletResponseDetails.token) {
+    if (!walletResponseDetails?.id || !walletResponseDetails?.token) {
       throw new InternalServerErrorException('Error while creating the wallet');
     }

Behavior is equivalent, just cleaner.

Also applies to: 185-190, 200-203, 394-421, 1090-1095

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fb1b25 and 5b52f1b.

📒 Files selected for processing (3)
  • apps/agent-service/src/agent-service.service.ts (14 hunks)
  • apps/agent-service/src/repositories/agent-service.repository.ts (6 hunks)
  • libs/enum/src/enum.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/agent-service/src/repositories/agent-service.repository.ts (1)
apps/agent-service/src/interface/agent-service.interface.ts (2)
  • ICreateOrgAgent (449-451)
  • IStoreOrgAgentDetails (177-201)
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/agent-service.service.ts

[warning] 146-146: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZv&open=AZrYqBck27eHY-4VIvZv&pullRequest=1528


[warning] 1090-1090: Prefer using an optional chain expression instead, as it's more concise and easier to read.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZrYqBck27eHY-4VIvZw&open=AZrYqBck27eHY-4VIvZw&pullRequest=1528

🔇 Additional comments (1)
libs/enum/src/enum.ts (1)

88-91: Enum rename keeps numeric contract; semantics look consistent.

Renaming to WALLET_CREATED / DID_CREATED while keeping values 1/2 preserves DB compatibility and clarifies intent around wallet vs DID lifecycle; callers just need to treat 1 as “wallet ready” and 2 as “DID created/agent fully ready”.

Comment on lines +742 to 752
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) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Prevent orphan org_agents on tenant creation errors and tighten “wallet already created” guard.

Two related issues in the shared-agent tenant path:

  1. Orphan org_agents records on failure

In _createTenant:

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 agentProcess is created (e.g. tenant creation fails, NATS issues, invitation failure), the catch block calls handleError, which only emits a socket event and logs. The partially created org_agents row is never cleaned up, leaving the DB in an inconsistent state.

You already handle cleanup correctly elsewhere (_agentSpinup and handleErrorOnWalletProvision remove the agent on error). Do the same here:

   } 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;
   }
  1. “Wallet already created” only checks WALLET_CREATED

In createTenant:

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 DID_CREATED, this guard no longer triggers, even though the org clearly already has a wallet. You probably want to block duplicate wallet creation for any non‑PENDING state, e.g.:

-    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
In apps/agent-service/src/agent-service.service.ts around lines 742 to 752, the
current logic throws a ConflictException only when agentSpinUpStatus ===
WALLET_CREATED and creates an org_agent before tenant creation without cleaning
it up on downstream failures; update two things: 1) tighten the pre-check to
treat any non-PENDING agentSpinUpStatus (e.g. DID_CREATED, WALLET_CREATED, or
any terminal state) as a conflict so duplicate wallet/tenant creation is blocked
consistently, and 2) ensure that any partial org_agent created during the
_createTenant path is removed on error — after creating the initial org_agent
record, wrap subsequent steps in try/catch and in the catch call the same
cleanup used elsewhere (remove/delete the org_agent record via the repository)
before rethrowing or handling the error and emitting socket events.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/agent-service/src/repositories/agent-service.repository.ts (2)

263-283: Acknowledge TODO and recommend tracking.

The new method correctly updates the agent status to DID_CREATED as part of the decoupled provisioning flow. The TODO comment (line 268) appropriately notes the opportunity to consolidate multiple single-field update methods (updateAgentSpinupStatus, updateLedgerId, updateTenantToken) into a generic update function.

Consider creating an issue to track this refactoring to prevent the TODO from becoming stale.


286-286: Duplicate TODO comment.

This TODO duplicates the one at line 268. Consider keeping a single TODO at the top of the related update methods or consolidating them into a single comment block to avoid redundancy.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b52f1b and e7fc1b2.

📒 Files selected for processing (1)
  • apps/agent-service/src/repositories/agent-service.repository.ts (6 hunks)
🧰 Additional context used
🪛 GitHub Check: SonarCloud Code Analysis
apps/agent-service/src/repositories/agent-service.repository.ts

[warning] 286-286: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZraHcc6uDLBMMjmXyuv&open=AZraHcc6uDLBMMjmXyuv&pullRequest=1528


[warning] 268-268: Complete the task associated to this "TODO" comment.

See more on https://sonarcloud.io/project/issues?id=credebl_platform&issues=AZraHcc6uDLBMMjmXyuu&open=AZraHcc6uDLBMMjmXyuu&pullRequest=1528

🔇 Additional comments (4)
apps/agent-service/src/repositories/agent-service.repository.ts (4)

1-27: LGTM!

Import changes appropriately add the new interfaces (ICreateOrgAgent, IStoreOrgAgentDetails, IStoreDidDetails) and enum values needed to support the updated method signatures throughout this repository.


103-120: LGTM!

The addition of orgId to the createOrgAgent signature and data payload correctly associates the agent record with the organization at creation time, aligning with the simplified wallet provisioning flow.


181-206: LGTM!

The conditional query construction cleanly handles both update and create paths with identical select clauses, ensuring a consistent return shape. Returning the Promise directly is appropriate.


168-178: No action needed. The ledgerId handling on line 169 is correct and aligns with the interface definition (ledgerId?: string[]). The code properly handles both array and falsy values as intended.

@pranalidhanavade pranalidhanavade merged commit 1d4c782 into main Dec 5, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants