Skip to content

feat: integrates child di container#1358

Merged
stalniy merged 1 commit intomainfrom
feat/child-di
May 23, 2025
Merged

feat: integrates child di container#1358
stalniy merged 1 commit intomainfrom
feat/child-di

Conversation

@stalniy
Copy link
Contributor

@stalniy stalniy commented May 23, 2025

Why

to have a single container source which can construct services that depend on values provided by React.Providers

What

  1. Integrates child DI container into ServicesProvider
  2. refactor useBalances to rely on DI container and extracts getBalances into a separate service with service level tests
  3. adjusted existing tests
  4. added additional check in _app.tsx to ensure that <Loading> is not shown if there is no injected config. Config only injected during e2e testing for now
  5. resolves settings <-> wallet cyclic dependency via external atom based state

Summary by CodeRabbit

  • New Features

    • Introduced a new WalletBalancesService to aggregate wallet balances, deployment grants, and escrow information.
    • Added a hook for calculating real-time balance metrics based on blockchain data.
    • Added a persistent settings ID atom for improved local storage key management.
    • Added a function to detect the presence of injected configuration.
    • Added a test data seeder for deployments.
  • Refactor

    • Switched to a dependency injection container for managing and providing services throughout the app.
    • Delegated wallet balance logic from the balances query hook to the new WalletBalancesService.
    • Updated local storage and wallet providers to use the new settings ID atom for namespacing.
    • Reorganized provider hierarchy for improved context management.
    • Moved the real-time metrics hook to a dedicated module and updated relevant imports.
    • Simplified test mocks to factory functions for better modularity.
    • Enhanced container creation logic with child container support and improved typing.
  • Bug Fixes

    • Improved handling of injected configuration to prevent unnecessary decoding and loading states.
  • Tests

    • Added comprehensive tests for the new WalletBalancesService.
    • Updated test mocks to use factory functions for improved flexibility.
  • Chores

    • Updated type annotations and import paths for improved consistency and clarity.
    • Removed ESLint disable comments related to import cycles for cleaner code.

@stalniy stalniy requested a review from a team as a code owner May 23, 2025 06:40
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 23, 2025

Walkthrough

This set of changes introduces a dependency injection (DI) container pattern for service management in the application, refactors balance retrieval logic into a new WalletBalancesService, and updates the use of localStorage to be namespaced by a new settingsIdAtom. Several hooks and utilities are restructured or moved, and new test data seeders and tests are added to support these changes.

Changes

File(s) Change Summary
src/context/ServicesProvider/ServicesProvider.tsx, src/services/container/createContainer.ts, src/pages/_app.tsx Refactored service provisioning to use a DI container pattern, introduced child containers, and updated provider nesting in the app.
src/queries/useBalancesQuery.ts, src/services/wallet-balances/wallet-balances.service.ts, src/services/wallet-balances/wallet-balances.service.spec.ts Moved balance fetching logic into a new WalletBalancesService, updated the hook to use DI, and added comprehensive tests for the new service.
src/hooks/useLocalStorage.ts, src/context/SettingsProvider/settingsStore.ts, src/context/WalletProvider/WalletProvider.tsx Introduced a persistent settingsIdAtom for namespacing localStorage, synchronized it with wallet address, and updated localStorage hooks to use this atom.
src/hooks/useRealTimeLeft.ts, src/utils/priceUtils.ts, src/components/deployments/DeploymentListRow.tsx, src/hooks/useDeploymentMetrics.tsx Moved the useRealTimeLeft hook to its own module, updated imports, and removed it from utility files.
src/services/decodeInjectedConfig/decodeInjectedConfig.ts, src/pages/_app.tsx Added a function to check for injected config and updated app initialization logic to use it.
src/utils/apiUtils.ts Updated the type for the HTTP client parameter in the pagination utility.
src/context/SettingsProvider/SettingsProviderContext.tsx Updated the import path for the query client.
tests/seeders/deployment.ts Added a new test data seeder for generating mock deployments.
src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx, src/components/providers/ProviderRawData/ProviderRawData.spec.tsx Updated test setup mocks to use factory functions instead of direct instances.
src/hooks/useAllowance.tsx, src/hooks/useAuthZService.tsx, src/queries/index.ts, src/queries/useApiKeysQuery.ts, src/queries/useBlocksQuery.ts, src/queries/useGrantsQuery.ts, src/utils/deploymentDetailUtils.ts, src/context/SettingsProvider/index.ts, src/context/WalletProvider/index.ts Removed ESLint disable comments related to import cycle warnings without functional changes.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant ServicesProvider
    participant DIContainer
    participant WalletBalancesService
    participant AuthzHttpService
    participant Axios
    participant API

    App->>ServicesProvider: Initialize
    ServicesProvider->>DIContainer: Create container with settings/services
    DIContainer->>WalletBalancesService: Instantiate with dependencies

    App->>useBalancesQuery: useBalances(address)
    useBalancesQuery->>DIContainer: Get walletBalancesService
    useBalancesQuery->>WalletBalancesService: getBalances(address)
    WalletBalancesService->>Axios: Fetch wallet balances
    WalletBalancesService->>AuthzHttpService: Fetch deployment grants
    WalletBalancesService->>Axios: Fetch active deployments
    WalletBalancesService->>useBalancesQuery: Return aggregated balances
Loading

Suggested reviewers

  • ygrishajev
  • baktun14

Poem

In the warren of code, a new pattern appears,
With containers for services, and tests for our peers.
Balances hop from the wallet with care,
While atoms and hooks keep state everywhere.
The rabbit approves, with a wiggle and cheer—
“Such tidy refactoring, spring is now here!”
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm warn config production Use --omit=dev instead.
npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-05-23T08_33_57_859Z-debug-0.log

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ff786b and e31090a.

📒 Files selected for processing (28)
  • apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/deployments/DeploymentListRow.tsx (1 hunks)
  • apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1 hunks)
  • apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx (1 hunks)
  • apps/deploy-web/src/context/SettingsProvider/index.ts (1 hunks)
  • apps/deploy-web/src/context/SettingsProvider/settingsStore.ts (1 hunks)
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (4 hunks)
  • apps/deploy-web/src/context/WalletProvider/index.ts (1 hunks)
  • apps/deploy-web/src/hooks/useAllowance.tsx (1 hunks)
  • apps/deploy-web/src/hooks/useAuthZService.tsx (1 hunks)
  • apps/deploy-web/src/hooks/useDeploymentMetrics.tsx (1 hunks)
  • apps/deploy-web/src/hooks/useLocalStorage.ts (1 hunks)
  • apps/deploy-web/src/hooks/useRealTimeLeft.ts (1 hunks)
  • apps/deploy-web/src/pages/_app.tsx (3 hunks)
  • apps/deploy-web/src/queries/index.ts (1 hunks)
  • apps/deploy-web/src/queries/useApiKeysQuery.ts (1 hunks)
  • apps/deploy-web/src/queries/useBalancesQuery.ts (1 hunks)
  • apps/deploy-web/src/queries/useBlocksQuery.ts (1 hunks)
  • apps/deploy-web/src/queries/useGrantsQuery.ts (1 hunks)
  • apps/deploy-web/src/services/container/createContainer.ts (3 hunks)
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts (1 hunks)
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.spec.ts (1 hunks)
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (1 hunks)
  • apps/deploy-web/src/utils/apiUtils.ts (2 hunks)
  • apps/deploy-web/src/utils/deploymentDetailUtils.ts (1 hunks)
  • apps/deploy-web/src/utils/priceUtils.ts (0 hunks)
  • apps/deploy-web/tests/seeders/deployment.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/deploy-web/src/utils/priceUtils.ts
✅ Files skipped from review due to trivial changes (10)
  • apps/deploy-web/src/utils/deploymentDetailUtils.ts
  • apps/deploy-web/src/context/SettingsProvider/index.ts
  • apps/deploy-web/src/queries/index.ts
  • apps/deploy-web/src/queries/useBlocksQuery.ts
  • apps/deploy-web/src/hooks/useAuthZService.tsx
  • apps/deploy-web/src/context/WalletProvider/index.ts
  • apps/deploy-web/src/queries/useGrantsQuery.ts
  • apps/deploy-web/src/hooks/useDeploymentMetrics.tsx
  • apps/deploy-web/src/hooks/useAllowance.tsx
  • apps/deploy-web/src/queries/useApiKeysQuery.ts
🚧 Files skipped from review as they are similar to previous changes (16)
  • apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/components/deployments/DeploymentListRow.tsx
  • apps/deploy-web/src/context/SettingsProvider/settingsStore.ts
  • apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx
  • apps/deploy-web/tests/seeders/deployment.ts
  • apps/deploy-web/src/utils/apiUtils.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.spec.ts
  • apps/deploy-web/src/hooks/useRealTimeLeft.ts
  • apps/deploy-web/src/services/container/createContainer.ts
  • apps/deploy-web/src/hooks/useLocalStorage.ts
  • apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
  • apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/deploy-web/src/queries/useBalancesQuery.ts (3)
apps/deploy-web/src/types/address.ts (1)
  • Balances (41-50)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (32-34)
apps/deploy-web/src/queries/queryKeys.ts (1)
  • QueryKeys (1-70)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test-deploy-web-build
🔇 Additional comments (3)
apps/deploy-web/src/queries/useBalancesQuery.ts (3)

12-13: Architectural improvement: Clean delegation to service layer.

The refactoring successfully moves complex balance aggregation logic into a dedicated service, improving separation of concerns and testability. The simplified query function is more maintainable.


9-9:

Details

✅ Verification successful

Verify DI container initialization and service availability.

The hook now depends on the walletBalancesService being available in the DI container. Ensure the service is properly registered and initialized.


🏁 Script executed:

#!/bin/bash
# Description: Verify that walletBalancesService is properly registered in the DI container

echo "=== Checking walletBalancesService registration ==="
# Look for service registration in ServicesProvider
rg -A 10 -B 5 "walletBalancesService" apps/deploy-web/src/context/ServicesProvider/

echo -e "\n=== Checking service implementation ==="
# Verify the service file exists and has getBalances method
fd "wallet-balances.service" --type f --exec grep -H "getBalances" {} \;

Length of output: 2178


✅ walletBalancesService registration and implementation verified

  • walletBalancesService is registered in apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx.
  • WalletBalancesService exists at apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts and defines the required getBalances(address: string): Promise<Balances> method.
  • Service tests cover getBalances, confirming its presence and behavior.

No further changes needed.


13-13:

Details

❓ Verification inconclusive

Simplified enabled condition may affect query behavior.

The enabled condition is now !!address instead of potentially checking for other dependencies like API settings. Ensure this doesn't cause queries to run when the service isn't properly configured.


🏁 Script executed:

#!/bin/bash
# Description: Check if the service handles missing configuration gracefully

echo "=== Checking service error handling ==="
# Look for error handling in the wallet balances service
rg -A 5 -B 5 "throw|error|catch" apps/deploy-web/src/services/wallet-balances/

echo -e "\n=== Checking previous enabled conditions ==="
# Look for previous git history to see what other conditions were checked
git log -p --follow -- apps/deploy-web/src/queries/useBalancesQuery.ts | head -50

Length of output: 274


Verify enabled condition for useBalancesQuery

The current enabled: !!address check only gates queries by wallet address. It doesn’t account for other prerequisites—such as API client or configuration readiness—which could lead to requests firing against an uninitialized service. Please confirm that all necessary dependencies are loaded before enabling the query.

• File: apps/deploy-web/src/queries/useBalancesQuery.ts (around line 13)
• Suggest including additional flags, for example:

enabled: !!address && apiClient.isReady && settings.hasLoaded

Ensure the service handles missing configs gracefully or add a guard so the query only runs when everything is properly configured.

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 4

🧹 Nitpick comments (1)
apps/deploy-web/src/services/balance/wallet-ballances.service.ts (1)

1-1: Fix the typo in the filename.

The filename "wallet-ballances.service.ts" contains a typo. It should be "wallet-balances.service.ts" (balances, not ballances).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dafe16a and 494d061.

📒 Files selected for processing (11)
  • apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1 hunks)
  • apps/deploy-web/src/pages/_app.tsx (3 hunks)
  • apps/deploy-web/src/queries/useBalancesQuery.ts (1 hunks)
  • apps/deploy-web/src/services/balance/wallet-ballances.service.spec.ts (1 hunks)
  • apps/deploy-web/src/services/balance/wallet-ballances.service.ts (1 hunks)
  • apps/deploy-web/src/services/container/createContainer.ts (3 hunks)
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts (1 hunks)
  • apps/deploy-web/src/utils/apiUtils.ts (2 hunks)
  • apps/deploy-web/tests/seeders/deployment.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Check: validate-deploy-web
apps/deploy-web/src/queries/useBalancesQuery.ts

[failure] 4-4:
Dependency cycle via "./ServicesProvider:1=>../SettingsProvider/SettingsProviderContext:14=>@src/hooks/useLocalStorage:5=>@src/context/WalletProvider:1=>./WalletProvider:1"

apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx

[failure] 9-9:
Dependency cycle via "@src/utils/deploymentDetailUtils:10=>./priceUtils:2=>@src/queries/useBlocksQuery:6=>@src/context/SettingsProvider:5=>./SettingsProviderContext:1=>@src/queries:7=>./useApiKeysQuery:5=>@src/context/ServicesProvider:5"

apps/deploy-web/src/services/balance/wallet-ballances.service.ts

[failure] 10-10:
Dependency cycle via "./priceUtils:2=>@src/queries/useBlocksQuery:6=>@src/context/SettingsProvider:5=>./SettingsProviderContext:1=>@src/queries:7=>./useApiKeysQuery:5=>@src/context/ServicesProvider:5=>./ServicesProvider:1"

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test-deploy-web-build
🔇 Additional comments (19)
apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts (1)

3-5: LGTM! Well-implemented utility function.

The hasInjectedConfig function correctly handles:

  • SSR compatibility by checking for window existence
  • Proper truthy evaluation of the injected config property
  • Clear return type and descriptive naming

This utility supports the conditional config checking pattern mentioned in the AI summary.

apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx (1)

27-44: LGTM! Proper alignment with DI container pattern.

The conversion of axios and providerProxy mocks from objects to factory functions correctly supports the dependency injection container approach. The mock behavior is preserved while enabling dynamic service instantiation.

Key benefits:

  • Consistent with the DI pattern introduced in ServicesProvider
  • Maintains existing test functionality
  • Proper type safety with casting
apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx (1)

92-97: LGTM! Consistent factory function pattern.

The conversion of notificationsApi to a factory function maintains the same createAPIClient instantiation while aligning with the dependency injection container pattern. This change preserves test functionality while supporting the new service architecture.

apps/deploy-web/src/utils/apiUtils.ts (1)

1-1: LGTM! Improved type consistency.

The change from AxiosInstance to Axios type improves consistency with the DI container pattern where Axios instances are passed to service constructors. This is a refinement that maintains functionality while aligning with the broader architectural changes.

Also applies to: 131-131

apps/deploy-web/src/services/balance/wallet-ballances.service.spec.ts (3)

17-54: Well-structured test with comprehensive balance verification.

The test effectively validates the service's ability to aggregate balance data from multiple sources. The assertions cover all expected balance properties including UAKT/USDC balances, deployment escrows, grants, and active deployments.


57-112: Excellent mock setup with flexible configuration.

The setup function provides a clean way to inject custom mock implementations for different service dependencies. The URL-based routing in the Axios mock (lines 64-104) effectively simulates different API endpoints.


114-121: Clean TypeScript interface for test configuration.

The TestInput interface provides good type safety for the test setup function parameters, making the tests more maintainable and self-documenting.

apps/deploy-web/src/pages/_app.tsx (3)

64-68: Improved config loading with proper conditional checks.

The addition of hasInjectedConfig() check prevents unnecessary decoding attempts when no config is injected, improving performance and avoiding potential errors.


71-71: Consistent loading state logic.

The loading condition correctly matches the config decoding logic, ensuring the loading indicator only appears when actually needed.


97-113: Well-positioned ServicesProvider in the hierarchy.

Moving ServicesProvider to wrap around other providers makes sense for the DI container pattern, ensuring services are available to all nested components that depend on them.

apps/deploy-web/tests/seeders/deployment.ts (1)

7-111: Comprehensive and well-structured test data seeder.

The buildRpcDeployment function provides excellent coverage of the deployment data structure with realistic defaults. The use of faker for randomization and merge for overrides makes it flexible for various test scenarios.

Key strengths:

  • Comprehensive default data covering all deployment properties
  • Flexible override system using DeepPartial<RpcDeployment>
  • Realistic resource specifications, pricing, and escrow data
  • Consistent wallet address and dseq usage throughout the structure
apps/deploy-web/src/services/container/createContainer.ts (4)

1-1: Simplified factory function signatures improve usability.

Removing the container parameter from factory functions simplifies the API while maintaining functionality. The direct factory call without parameters (line 17) is cleaner and more intuitive.

Also applies to: 17-17


13-13: Enhanced circular dependency error messaging.

Including the current key in the dependency path provides better debugging information when circular dependencies are detected.


30-34: Elegant child container implementation using prototype chaining.

The createChildContainer function cleverly uses prototype chaining to inherit from the parent container while adding new factories. This enables the hierarchical DI pattern mentioned in the PR objectives.


36-40: Improved type definitions for better type safety.

The updated DIContainer type using ReturnType<T[K]> and the new Factories type alias provide better type inference and constraint checking for the DI container system.

apps/deploy-web/src/queries/useBalancesQuery.ts (1)

9-18: Good refactoring to use dependency injection.

The hook has been cleanly refactored to use the injected service. The addition of settings?.apiEndpoint to the enabled condition ensures the query doesn't run without proper configuration.

apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (3)

16-30: Well-implemented dependency injection pattern.

The refactoring to use a typed DI container is a good architectural improvement. The ability to override services via props will make testing much easier.


46-48:

Details

❓ Verification inconclusive

Potential initialization issue with service dependencies.

The walletBalancesService factory references di.authzHttpService from the same container being created. This forward reference might cause initialization issues.

Consider refactoring to ensure proper initialization order:

-    walletBalancesService: () =>
-      new WalletBalancesService(di.authzHttpService, di.axios, browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS, settings.apiEndpoint),
+    walletBalancesService: (container) =>
+      new WalletBalancesService(container.authzHttpService, container.axios, browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS, settings.apiEndpoint),

🏁 Script executed:

#!/bin/bash
# Description: Check how createChildContainer handles forward references

# Find the createChildContainer implementation
echo "=== createChildContainer implementation ==="
ast-grep --pattern 'export function createChildContainer($$$) {
  $$$
}'

# Check if other services use similar patterns
echo -e "\n=== Other services using di references ==="
rg "di\.[a-zA-Z]+Service" --type ts -A 2 -B 2

Length of output: 1403


Verify service factory initialization ordering

I wasn’t able to locate how createChildContainer resolves service factories, so please confirm that forward references (i.e. one factory calling another via di.otherService) are handled lazily and won’t run into an uninitialized dependency.

• File: apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
Lines around:

    authzHttpService: () => new AuthzHttpService({ baseURL: settings.apiEndpoint }),
    walletBalancesService: () =>
      new WalletBalancesService(
        di.authzHttpService,
        di.axios,
        browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS,
        settings.apiEndpoint
      ),
    ...services

• If createChildContainer does not defer factory execution until after all services are registered, consider changing the factory signature to accept the container explicitly:

- walletBalancesService: () =>
-   new WalletBalancesService(di.authzHttpService, …),
+ walletBalancesService: (container) =>
+   new WalletBalancesService(container.authzHttpService, …),

Please verify the container implementation to ensure no runtime initialization errors.


9-9:

Details

❌ Incorrect review comment

Address the dependency cycle issue.

Static analysis indicates a complex dependency cycle involving this import. This needs to be resolved to prevent potential runtime issues.


🏁 Script executed:

#!/bin/bash
# Description: Analyze the dependency cycle in detail

# Find all files in the cycle path
echo "=== Files in the dependency cycle ==="
rg -l "deploymentDetailUtils|priceUtils|useBlocksQuery|SettingsProvider|useApiKeysQuery|ServicesProvider" --type ts | sort | uniq

# Check if there are any circular imports between services and providers
echo -e "\n=== Checking for circular imports between services and context ==="
fd --type f --extension ts --exec grep -l "import.*from.*@src/context" {} \; | xargs grep -l "import.*from.*@src/services" | head -10

Length of output: 5256


🏁 Script executed:

#!/bin/bash
# Verify that no service imports context, to rule out a true circular dependency

echo "=== Checking wallet-balances.service.ts for @src/context imports ==="
grep -n "import.*from.*@src/context" apps/deploy-web/src/services/balance/wallet-ballances.service.ts || echo "No context imports found in wallet-balances.service.ts"

echo -e "\n=== Scanning entire services directory for any @src/context imports ==="
grep -R -n "import.*from.*@src/context" apps/deploy-web/src/services || echo "No context imports found in services directory"

Length of output: 702


🏁 Script executed:

#!/bin/bash
# List all import statements in the wallet-balances service to trace dependencies
echo "=== Import lines in wallet-balances.service.ts ==="
grep -n '^import ' apps/deploy-web/src/services/balance/wallet-ballances.service.ts

Length of output: 738



---

🏁 Script executed:

```shell
#!/bin/bash
# Locate and inspect imports in useDenom, deploymentDetailUtils, and apiUtils

echo "=== Locate useDenom files ==="
fd --type f --extension ts --extension tsx -g "useDenom"

echo -e "\n=== Imports in useDenom files ==="
for f in $(fd --type f --extension ts --extension tsx -g "useDenom"); do
  echo "File: $f"
  grep -n '^import ' "$f"
done

echo -e "\n=== Imports in deploymentDetailUtils.ts ==="
grep -n '^import ' apps/deploy-web/src/utils/deploymentDetailUtils.ts

echo -e "\n=== Imports in apiUtils.ts ==="
grep -n '^import ' apps/deploy-web/src/utils/apiUtils.ts

Length of output: 1085


No circular dependency in WalletBalancesService import
Static analysis flagged a cycle on the import in wallet-balances.service.ts, but:

  • wallet-balances.service.ts does not import any context modules.
  • The only import cycle lives entirely between deploymentDetailUtils.tspriceUtils.ts, and is already suppressed via // eslint-disable-line import-x/no-cycle.
    No runtime or provider–service cycle exists here, so you can ignore this warning.

Likely an incorrect or invalid review comment.

🧰 Tools
🪛 GitHub Check: validate-deploy-web

[failure] 9-9:
Dependency cycle via "@src/utils/deploymentDetailUtils:10=>./priceUtils:2=>@src/queries/useBlocksQuery:6=>@src/context/SettingsProvider:5=>./SettingsProviderContext:1=>@src/queries:7=>./useApiKeysQuery:5=>@src/context/ServicesProvider:5"

@codecov
Copy link

codecov bot commented May 23, 2025

Codecov Report

Attention: Patch coverage is 60.36036% with 44 lines in your changes missing coverage. Please review.

Project coverage is 34.24%. Comparing base (dafe16a) to head (e31090a).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
apps/deploy-web/src/hooks/useRealTimeLeft.ts 0.00% 11 Missing and 1 partial ⚠️
apps/deploy-web/src/hooks/useLocalStorage.ts 25.00% 6 Missing and 3 partials ⚠️
apps/deploy-web/src/pages/_app.tsx 0.00% 3 Missing and 2 partials ⚠️
.../src/context/ServicesProvider/ServicesProvider.tsx 76.47% 4 Missing ⚠️
...-web/src/context/WalletProvider/WalletProvider.tsx 40.00% 2 Missing and 1 partial ⚠️
...b/src/components/deployments/DeploymentListRow.tsx 0.00% 2 Missing ⚠️
apps/deploy-web/src/queries/useBalancesQuery.ts 33.33% 2 Missing ⚠️
...vices/decodeInjectedConfig/decodeInjectedConfig.ts 0.00% 2 Missing ⚠️
...ervices/wallet-balances/wallet-balances.service.ts 93.33% 2 Missing ⚠️
apps/deploy-web/src/hooks/useDeploymentMetrics.tsx 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1358      +/-   ##
==========================================
+ Coverage   33.96%   34.24%   +0.28%     
==========================================
  Files         796      799       +3     
  Lines       19418    19451      +33     
  Branches     3604     3606       +2     
==========================================
+ Hits         6595     6661      +66     
+ Misses      12234    12205      -29     
+ Partials      589      585       -4     
Flag Coverage Δ *Carryforward flag
api 64.23% <ø> (ø) Carriedforward from dafe16a
deploy-web 13.90% <60.36%> (+0.50%) ⬆️
notifications 87.66% <ø> (ø) Carriedforward from dafe16a
provider-proxy 80.09% <ø> (ø) Carriedforward from dafe16a

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...ntext/SettingsProvider/SettingsProviderContext.tsx 11.01% <100.00%> (ø)
...s/deploy-web/src/context/SettingsProvider/index.ts 100.00% <100.00%> (ø)
...-web/src/context/SettingsProvider/settingsStore.ts 100.00% <100.00%> (ø)
...pps/deploy-web/src/context/WalletProvider/index.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/hooks/useAllowance.tsx 30.23% <100.00%> (ø)
apps/deploy-web/src/hooks/useAuthZService.tsx 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/index.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/useApiKeysQuery.ts 14.70% <100.00%> (ø)
apps/deploy-web/src/queries/useGrantsQuery.ts 100.00% <100.00%> (ø)
apps/deploy-web/src/utils/apiUtils.ts 35.71% <100.00%> (+17.34%) ⬆️
... and 14 more

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@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 (1)
apps/deploy-web/src/queries/useBalancesQuery.ts (1)

4-4: ⚠️ Potential issue

Critical: Resolve the circular dependency instead of suppressing it.

The eslint-disable comment indicates the circular dependency issue from previous reviews remains unresolved. Suppressing the warning doesn't fix the underlying architectural problem that can cause runtime errors and unpredictable initialization order.

Please implement the solution outlined in the previous review: refactor the localStorage logic in useLocalStorage.ts into a standalone utility without React hook dependencies, or invert the dependency by having WalletProvider accept settings via props/context instead of importing SettingsProvider directly.

🧹 Nitpick comments (2)
apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (2)

36-43: Consider simplifying balance calculation logic.

The conditional logic for determining balances could be simplified for better readability:

- const balanceUAKT =
-   balanceData.balances.some(b => b.denom === UAKT_DENOM) || deploymentGrantsUAKT > 0
-     ? parseFloat(balanceData.balances.find(b => b.denom === UAKT_DENOM)?.amount || "0")
-     : 0;
+ const uaktBalance = balanceData.balances.find(b => b.denom === UAKT_DENOM);
+ const balanceUAKT = parseFloat(uaktBalance?.amount || "0");

The same pattern applies to USDC balance calculation. The original condition checking for grants doesn't affect the balance calculation logic and might be confusing.


25-25: Consider extracting pagination limit as a constant.

The hardcoded value 1000 for pagination limit should be extracted as a named constant for better maintainability.

+ const MAX_DEPLOYMENTS_PER_REQUEST = 1000;
+
  async getBalances(address: string): Promise<Balances> {
    // ...
-   loadWithPagination<RpcDeployment[]>(ApiUrlService.deploymentList(this.apiEndpoint, address, true), "deployments", 1000, this.axios)
+   loadWithPagination<RpcDeployment[]>(ApiUrlService.deploymentList(this.apiEndpoint, address, true), "deployments", MAX_DEPLOYMENTS_PER_REQUEST, this.axios)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 494d061 and 8ff786b.

📒 Files selected for processing (19)
  • apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx (1 hunks)
  • apps/deploy-web/src/components/deployments/DeploymentListRow.tsx (1 hunks)
  • apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx (1 hunks)
  • apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1 hunks)
  • apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx (1 hunks)
  • apps/deploy-web/src/context/SettingsProvider/settingsStore.ts (1 hunks)
  • apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (3 hunks)
  • apps/deploy-web/src/hooks/useDeploymentMetrics.tsx (1 hunks)
  • apps/deploy-web/src/hooks/useLocalStorage.ts (1 hunks)
  • apps/deploy-web/src/hooks/useRealTimeLeft.ts (1 hunks)
  • apps/deploy-web/src/pages/_app.tsx (3 hunks)
  • apps/deploy-web/src/queries/useBalancesQuery.ts (1 hunks)
  • apps/deploy-web/src/services/container/createContainer.ts (3 hunks)
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts (1 hunks)
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.spec.ts (1 hunks)
  • apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (1 hunks)
  • apps/deploy-web/src/utils/apiUtils.ts (2 hunks)
  • apps/deploy-web/src/utils/priceUtils.ts (0 hunks)
  • apps/deploy-web/tests/seeders/deployment.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/deploy-web/src/utils/priceUtils.ts
✅ Files skipped from review due to trivial changes (3)
  • apps/deploy-web/src/hooks/useDeploymentMetrics.tsx
  • apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx
  • apps/deploy-web/src/context/SettingsProvider/settingsStore.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • apps/deploy-web/src/services/decodeInjectedConfig/decodeInjectedConfig.ts
  • apps/deploy-web/src/pages/_app.tsx
  • apps/deploy-web/src/components/alerts/ContactPointCreateContainer/ContactPointFormContainer.spec.tsx
  • apps/deploy-web/tests/seeders/deployment.ts
  • apps/deploy-web/src/utils/apiUtils.ts
  • apps/deploy-web/src/components/providers/ProviderRawData/ProviderRawData.spec.tsx
  • apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
  • apps/deploy-web/src/services/container/createContainer.ts
🧰 Additional context used
🧬 Code Graph Analysis (5)
apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (1)
apps/deploy-web/src/context/SettingsProvider/settingsStore.ts (1)
  • settingsIdAtom (5-7)
apps/deploy-web/src/hooks/useLocalStorage.ts (2)
apps/deploy-web/src/context/SettingsProvider/settingsStore.ts (1)
  • settingsIdAtom (5-7)
packages/network-store/src/network.store.ts (1)
  • selectedNetworkId (70-72)
apps/deploy-web/src/services/wallet-balances/wallet-balances.service.spec.ts (5)
apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (1)
  • WalletBalancesService (12-62)
apps/deploy-web/tests/seeders/deployment.ts (1)
  • buildRpcDeployment (7-111)
apps/deploy-web/src/utils/deploymentDetailUtils.ts (1)
  • deploymentToDto (19-44)
apps/deploy-web/src/types/balances.ts (1)
  • RestApiBalancesResponseType (13-19)
packages/http-sdk/src/authz/authz-http.service.ts (1)
  • AuthzHttpService (56-217)
apps/deploy-web/src/queries/useBalancesQuery.ts (3)
apps/deploy-web/src/types/address.ts (1)
  • Balances (41-50)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
  • useServices (32-34)
apps/deploy-web/src/queries/queryKeys.ts (1)
  • QueryKeys (1-70)
apps/deploy-web/src/hooks/useRealTimeLeft.ts (1)
apps/deploy-web/src/utils/priceUtils.ts (1)
  • averageBlockTime (9-9)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test-deploy-web-build
🔇 Additional comments (16)
apps/deploy-web/src/components/deployments/DeploymentListRow.tsx (1)

27-27: LGTM! Good separation of concerns.

Moving the useRealTimeLeft hook to its own dedicated file improves modularity and follows the single responsibility principle. The import change is clean and aligns with the broader refactoring effort.

apps/deploy-web/src/hooks/useRealTimeLeft.ts (2)

6-24: Verify block height calculation logic.

The hook implementation looks good overall, but there are potential issues with the block height calculations:

  1. Math.abs() usage (lines 13-14): Using absolute value for block differences may not be appropriate. Block heights should be monotonically increasing, so settledAt and createdAt should typically be less than latestBlockHeight. Consider whether negative values indicate an error condition that should be handled differently.

  2. Block height assumptions: The calculations assume that settledAt and createdAt represent block heights rather than timestamps, which should be verified.

Consider replacing the absolute value calculations with proper validation:

- const blocksPassed = Math.abs(settledAt - latestBlockHeight);
- const blocksSinceCreation = Math.abs(createdAt - latestBlockHeight);
+ const blocksPassed = Math.max(0, latestBlockHeight - settledAt);
+ const blocksSinceCreation = Math.max(0, latestBlockHeight - createdAt);

This ensures non-negative values while preserving the expected direction of time.


7-9: Good use of polling interval.

The 30-second refetch interval for block data is appropriate for real-time balance calculations, providing a good balance between accuracy and performance.

apps/deploy-web/src/services/wallet-balances/wallet-balances.service.spec.ts (2)

13-55: Excellent test coverage and structure.

The test suite demonstrates several best practices:

  1. Comprehensive mocking: Properly mocks external dependencies (AuthzHttpService, Axios)
  2. Realistic test data: Uses deployment seeders to generate realistic test scenarios
  3. Clear assertions: Verifies all returned fields from the getBalances method
  4. Flexible setup: The setup function allows easy customization for different test cases

The test effectively validates the service's core functionality of aggregating wallet balances, deployment escrow amounts, and deployment grants.


57-112: Well-designed test helper with good mocking strategy.

The setup function and mocking approach are well-implemented:

  1. URL-based routing: The Axios mock intelligently routes requests based on URL patterns
  2. Flexible input interface: The TestInput interface allows precise control over test scenarios
  3. Appropriate fallbacks: Provides sensible defaults when specific inputs aren't provided

The mock implementation correctly simulates the expected API responses for both balance and deployment endpoints.

apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (3)

12-18: Excellent dependency injection pattern.

The constructor properly implements dependency injection, making the service easily testable and flexible. The readonly modifiers ensure immutability of injected dependencies.


20-26: Good use of parallel execution.

Using Promise.all to execute the three API calls in parallel is an excellent performance optimization. The calls are independent and can safely run concurrently.


51-61: Clean and comprehensive return object.

The returned Balances object provides a comprehensive view of wallet state, including all relevant balance types, grants, and active deployments. The structure is well-organized and covers all the necessary data points.

apps/deploy-web/src/queries/useBalancesQuery.ts (3)

9-9: Good use of dependency injection pattern.

The use of the useServices hook to access the DI container is a solid architectural choice that improves testability and separation of concerns.


12-12: Excellent refactoring - delegating to service layer.

Moving the balance fetching logic to walletBalancesService improves modularity and makes the hook a clean interface over the service. This aligns well with the PR objective of leveraging the DI container pattern.


13-13: Good optimization - preventing unnecessary queries.

Adding enabled: !!address ensures the query only runs when an address is available, preventing unnecessary API calls and improving performance.

apps/deploy-web/src/context/WalletProvider/WalletProvider.tsx (2)

31-31: LGTM: Clean import of the centralized settings atom.

The import aligns with the architectural shift towards centralized state management using Jotai atoms.


72-72: LGTM: Proper atom usage for state synchronization.

The destructuring to get the setter function follows Jotai best practices for write-only atom access.

apps/deploy-web/src/hooks/useLocalStorage.ts (3)

1-4: LGTM: Imports properly updated for the refactoring.

The added imports support the architectural shift to Jotai-based state management and include the necessary performance optimization with useMemo.


8-8: LGTM: Clean dependency replacement.

The replacement of wallet address with settingsIdAtom successfully decouples the hook from the wallet context while maintaining the same namespacing functionality.


11-24: LGTM: Excellent performance optimization with useMemo.

The useMemo wrapper prevents unnecessary recreations of the localStorage functions when other parts of the component re-render, improving performance. The dependency array correctly includes both selectedNetworkId and settingsId.

The localStorage key format ${selectedNetworkId}${settingsId ? "/" + settingsId : ""}/${key} maintains the same structure as before, just using settingsId instead of the wallet address.

@stalniy stalniy merged commit 554ea1e into main May 23, 2025
27 checks passed
@stalniy stalniy deleted the feat/child-di branch May 23, 2025 08:54
stalniy added a commit that referenced this pull request Nov 20, 2025
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.

2 participants

Comments