-
Notifications
You must be signed in to change notification settings - Fork 76
feat: adds fallbackChainApiClient #2009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughRoute chain API calls through a fallbackable Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant C as Component / Hook
participant S as ServicesProvider
participant API as chainApiHttpClient
participant B as TopBannerProvider
rect #f3f6f9
note over S,API: Services initialization
S->>API: create via withInterceptors(createFallbackableHttpClient(...))
API-->>S: exposes isFallbackEnabled
end
U->>C: open page or trigger fetch
C->>API: request (e.g., /blocks/latest, balances)
alt API ready (baseURL && !isFallbackEnabled)
API-->>C: 200 OK (data)
C->>U: normal UI
else fallback active or no baseURL
API-->>S: onUnavailableError / fallback trigger
S-->>B: set isBlockchainDown = true
C->>U: render read-only UI / fallback messages
end
sequenceDiagram
autonumber
participant WS as WalletStatus
participant STORE as walletStore (Jotai)
participant POP as WalletPopup
participant U as User
WS->>STORE: read balance
alt balance present
WS->>POP: pass walletBalance
POP-->>U: show AKT/USDC and credits
else balance null
WS->>POP: walletBalance = null
POP-->>U: "Wallet Balance is unknown because the blockchain is down"
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is ❌ Your patch status has failed because the patch coverage (39.32%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #2009 +/- ##
==========================================
- Coverage 45.95% 45.58% -0.37%
==========================================
Files 1013 1003 -10
Lines 28605 28276 -329
Branches 7477 7459 -18
==========================================
- Hits 13144 12889 -255
+ Misses 14244 14180 -64
+ Partials 1217 1207 -10
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this 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/deploy-web/src/hooks/useWalletBalance.ts (1)
58-69
: Fix wrong USDC grants aggregation
totalDeploymentGrantsUUSDC
now pulls fromdeploymentEscrowUAKT
, so the grants total in USD/USDC is completely wrong in the UI. Restore the correct source.totalDeploymentGrantsUAKT: balances.deploymentGrantsUAKT, - totalDeploymentGrantsUUSDC: balances.deploymentEscrowUAKT, + totalDeploymentGrantsUUSDC: balances.deploymentGrantsUUSDC, totalDeploymentGrantsUSD: totalDeploymentGrantsUSD
🧹 Nitpick comments (1)
apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx (1)
24-24
: Initialize banner state from feature flag to prevent flicker
The banner is hidden on mount (useState(false)) and only shown post-mount viauseWhen
(useEffect), causing a brief flash. Consider:- const [isMaintenanceBannerOpen, setIsMaintenanceBannerOpen] = useState(false); + const [isMaintenanceBannerOpen, setIsMaintenanceBannerOpen] = useState(maintenanceBannerFlag.enabled);If you intentionally want the banner closed on first paint, document that and/or switch to
useLayoutEffect
inuseWhen
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (25)
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
(4 hunks)apps/deploy-web/src/components/home/YourAccount.tsx
(1 hunks)apps/deploy-web/src/components/layout/TopBanner.tsx
(2 hunks)apps/deploy-web/src/components/layout/WalletStatus.tsx
(4 hunks)apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
(4 hunks)apps/deploy-web/src/components/sdl/RentGpusForm.tsx
(4 hunks)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
(2 hunks)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
(2 hunks)apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
(4 hunks)apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
(1 hunks)apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
(3 hunks)apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
(1 hunks)apps/deploy-web/src/hooks/useWalletBalance.ts
(2 hunks)apps/deploy-web/src/pages/payment.tsx
(3 hunks)apps/deploy-web/src/queries/useBalancesQuery.ts
(1 hunks)apps/deploy-web/src/queries/useBidQuery.ts
(2 hunks)apps/deploy-web/src/queries/useBlocksQuery.ts
(1 hunks)apps/deploy-web/src/queries/useGrantsQuery.ts
(3 hunks)apps/deploy-web/src/queries/useSaveSettings.ts
(2 hunks)apps/deploy-web/src/services/app-di-container/browser-di-container.ts
(1 hunks)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
(2 hunks)apps/deploy-web/src/store/walletStore.ts
(1 hunks)apps/deploy-web/src/utils/deploymentData/helpers.ts
(0 hunks)apps/deploy-web/src/utils/deploymentData/v1beta2.ts
(3 hunks)apps/deploy-web/src/utils/deploymentData/v1beta3.ts
(3 hunks)
💤 Files with no reviewable changes (1)
- apps/deploy-web/src/utils/deploymentData/helpers.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
apps/deploy-web/src/components/home/YourAccount.tsx
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
apps/deploy-web/src/pages/payment.tsx
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/queries/useSaveSettings.ts
apps/deploy-web/src/hooks/useWalletBalance.ts
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/queries/useBlocksQuery.ts
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}
: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
apps/deploy-web/src/components/home/YourAccount.tsx
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
apps/deploy-web/src/pages/payment.tsx
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/queries/useSaveSettings.ts
apps/deploy-web/src/hooks/useWalletBalance.ts
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/queries/useBlocksQuery.ts
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
🧬 Code graph analysis (14)
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (1)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)
apps/deploy-web/src/store/walletStore.ts (2)
apps/deploy-web/src/utils/apiUtils.ts (1)
balance
(44-46)apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)
apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/components/home/YourAccount.tsx (1)
apps/deploy-web/src/utils/urlUtils.ts (1)
UrlService
(16-81)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (6)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
services
(23-55)packages/http-sdk/src/authz/authz-http.service.ts (1)
AuthzHttpService
(56-219)apps/deploy-web/src/services/wallet-balances/wallet-balances.service.ts (1)
WalletBalancesService
(12-61)packages/http-sdk/src/certificates/certificates.service.ts (1)
CertificatesService
(22-48)apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)
withInterceptors
(151-155)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
createFallbackableHttpClient
(8-46)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
services
(23-34)
apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx (2)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)apps/deploy-web/src/components/shared/PriceValue.tsx (1)
PriceValue
(18-38)
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx (2)
apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx (1)
useSettings
(333-335)apps/deploy-web/src/queries/useSaveSettings.ts (1)
useDepositParams
(37-45)
apps/deploy-web/src/queries/useGrantsQuery.ts (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)
apps/deploy-web/src/components/layout/WalletStatus.tsx (3)
apps/deploy-web/src/hooks/useShortText.ts (1)
getSplitText
(6-10)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx (1)
CustodialWalletPopup
(28-95)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (1)
ManagedWalletPopup
(19-88)
apps/deploy-web/src/queries/useSaveSettings.ts (1)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/components/sdl/RentGpusForm.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/queries/useBidQuery.ts (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: validate / validate-app
- GitHub Check: test-build
🔇 Additional comments (34)
apps/deploy-web/src/pages/payment.tsx (3)
14-14
: LGTM!The import statement is correctly formatted and the hook is used within the component.
58-58
: LGTM!The hook initialization and destructuring are correct.
263-272
: No change needed: payment UI remains consistent with current pattern.There is no existing usage of
chainApiHttpClient.isFallbackEnabled
; the project’s blockchain availability gating uniformly relies onsettings.isBlockchainDown
. The suggested change is premature.Likely an incorrect or invalid review comment.
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx (1)
24-24
: LGTM!Extracting
settings
fromuseSettings()
is necessary for accessing theisBlockchainDown
flag in the subsequent guard.apps/deploy-web/src/components/layout/TopBanner.tsx (2)
25-25
: LGTM! Improved banner message clarity.The updated message "The blockchain is down. Console is in read-only mode." clearly communicates the state and user impact, which is more informative than the previous "Unable to change deployments" wording.
56-58
: LGTM! Explicit precedence improves clarity.The explicit
if (isMaintenanceBannerOpen)
block makes the banner precedence order clear (blockchain-down > maintenance > credit card), improving code readability without changing the logic.apps/deploy-web/src/components/deployments/ManifestUpdate.tsx (3)
44-44
: LGTM!The expansion of
useServices
to includeanalyticsService
andchainApiHttpClient
aligns with the PR objective to route chain API calls through a fallback-capable client.
85-85
: LGTM!Both calls to
deploymentData.NewDeploymentData
now correctly usechainApiHttpClient
instead ofsettings.apiEndpoint
, ensuring consistent API client usage throughout the deployment flow.Also applies to: 143-143
107-107
: LGTM!The dependency array correctly tracks
chainApiHttpClient
instead ofsettings.apiEndpoint
, ensuring the validation effect re-runs when the client changes.apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx (4)
76-76
: LGTM!The expanded
useServices
hook consumption to includechainApiHttpClient
andappConfig
aligns with the centralized ServicesProvider pattern introduced in this PR.
89-89
: LGTM!The default deposit value now correctly sources from
appConfig.NEXT_PUBLIC_DEFAULT_INITIAL_DEPOSIT
instead ofbrowserEnvConfig.NEXT_PUBLIC_DEFAULT_DEPOSIT
, centralizing configuration management.
168-168
: LGTM!The deployment data creation call now uses
chainApiHttpClient
for API interactions, consistent with the fallback-capable client pattern introduced in this PR.
219-219
: LGTM!The master wallet address reference correctly uses
appConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS
, aligning with the centralized configuration approach.apps/deploy-web/src/queries/useSaveSettings.ts (1)
37-44
: LGTM!The enhanced type safety with
UseQueryOptions
and the addition of fallback gating logic (!chainApiHttpClient.isFallbackEnabled
) correctly prevent the query from running when the chain API is in fallback mode, aligning with the broader fallback mechanism introduced in this PR.apps/deploy-web/src/queries/useGrantsQuery.ts (4)
17-25
: LGTM!The
useGranterGrants
hook now correctly gates the query with!chainApiHttpClient.isFallbackEnabled
, preventing execution when the chain API is in fallback mode.
29-36
: LGTM!The
useGranteeGrants
hook applies consistent fallback gating logic, aligning with the broader pattern introduced in this PR.
45-53
: LGTM!The
useAllowancesIssued
hook correctly implements the fallback gating mechanism.
60-68
: LGTM!The
useAllowancesGranted
hook consistently applies the fallback gating pattern, completing the migration away from settings-based blockchain-down checks.apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
40-51
: LGTM with the caveat above.The fallback chain API client creation correctly wraps the
createFallbackableHttpClient
with interceptors and wires in the fallback logic usingshouldFallback
andonFailure
/onSuccess
callbacks. The approach aligns with the PR objective to introduce a fallback-capable HTTP client.However, ensure the request gating strategy (comment above) is appropriate for your use case.
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (2)
16-16
: LGTM!The prop type change to
walletBalance?: WalletBalance | null
correctly supports optional balance data, enabling graceful handling when the blockchain is down.
32-60
: LGTM!The conditional rendering provides clear user feedback when wallet balance is unavailable, with a descriptive fallback message explaining that the blockchain is down. This aligns with the broader pattern of handling blockchain unavailability introduced in this PR.
apps/deploy-web/src/utils/deploymentData/v1beta3.ts (1)
85-91
: LGTM!The migration from
apiEndpoint
string parameter tochainApiHttpClient: HttpClient
correctly enables on-demand block height resolution via the fallback-capable HTTP client. The pattern of fetching the latest block height whendseq
is not provided aligns with the PR objective.Also applies to: 101-106, 114-114
apps/deploy-web/src/components/layout/WalletStatus.tsx (3)
30-32
: LGTM!The
useCallback
hook is correctly used to memoize theopenDropdown
function, preventing unnecessary re-renders.
63-74
: LGTM!The conditional rendering of the divider and balance block based on
walletBalance
presence provides graceful handling when balance data is unavailable, consistent with the broader pattern introduced in this PR.
93-94
: LGTM!The simplified popup rendering logic with direct conditional checks improves code clarity while maintaining the correct visibility behavior.
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (4)
7-7
: LGTM!The type definition clearly extends
HttpClient
with the fallback flag, making the API self-documenting.
8-12
: LGTM!The function signature correctly reflects the enhanced return type with the fallback flag.
41-43
: LGTM!The getter pattern for
isFallbackEnabled
correctly delegates tooptions.shouldFallback
, allowing dynamic evaluation of the fallback state.
45-45
: LGTM!The type assertion is safe here since
isFallbackEnabled
is correctly defined viaObject.defineProperty
above.apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx (1)
23-23
: LGTM!The optional and nullable
walletBalance
prop correctly supports the fallback scenario when blockchain data is unavailable.apps/deploy-web/src/queries/useBidQuery.ts (2)
33-42
: LGTM!The query gating logic correctly prevents execution when the chain API client is in fallback mode, while still respecting explicit
enabled: false
from callers.
52-67
: LGTM!The expanded signature and query gating logic align with the
useBidList
pattern, correctly preventing execution during fallback mode.apps/deploy-web/src/utils/deploymentData/v1beta2.ts (1)
184-191
: All NewDeploymentData call sites updated. Calls now passchainApiHttpClient
as the first argument.apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
43-51
: Error handling verified:getBaseApiUrlFor
defaults to MAINNET URL for undefined or invalid networks and never throws.
0a9ec15
to
89adcc5
Compare
There was a problem hiding this 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 (4)
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx (1)
32-35
: Past review concern remains unaddressed.The synchronization issue between
settings.isBlockchainDown
andchainApiHttpClient.isFallbackEnabled
flagged in the previous review has not been resolved. Without coordination between these two flags, there is a risk of inconsistent behavior where one allows fetching while the other prevents it.apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
41-54
: Avoid hanging requests whenbaseURL
is missingReturning
neverResolvedPromise
from the request interceptor means any call made beforeconfig.baseURL
is set will wait forever and never retry, leaving downstream queries permanently stuck. Fail fast instead so callers can surface an actionable error (or implement a real retry queue if needed).- { - request: [config => (config.baseURL ? config : neverResolvedPromise)] - } + { + request: [ + config => { + if (config.baseURL) return config; + return Promise.reject(new Error("chainApiHttpClient missing baseURL")); + } + ] + }apps/deploy-web/src/utils/deploymentData/v1beta3.ts (1)
101-107
: Remove debug console.log and ensure dseq is string.The stack trace log is debug noise and was flagged previously. Cast height to string to keep types consistent.
- if (!finalDseq) { - console.log("Getting current height", new Error().stack); - const response = await chainApiHttpClient.get("/blocks/latest"); - finalDseq = response.data.block.header.height; - } + if (!finalDseq) { + const response = await chainApiHttpClient.get("/blocks/latest"); + finalDseq = String(response.data.block.header.height); + }Also applies to: 114-114
apps/deploy-web/src/utils/deploymentData/v1beta2.ts (1)
211-215
: Remove debug console.log (repeat).Same as earlier feedback: drop the stack trace log and keep the height fetch; cast to string for consistency.
- if (!id.dseq) { - console.log("Getting current height", new Error().stack); - - const response = await chainApiHttpClient.get("/blocks/latest"); - id.dseq = response.data.block.header.height; - } + if (!id.dseq) { + const response = await chainApiHttpClient.get("/blocks/latest"); + id.dseq = String(response.data.block.header.height); + }
🧹 Nitpick comments (3)
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx (2)
145-148
: Gate bid fetching when blockchain is down.Add settings.isBlockchainDown to the query's enabled flag to avoid unnecessary requests and reduce noise while the chain is down.
Apply:
} = d.useBidList(address, dseq, { initialData: [], refetchInterval: REFRESH_BIDS_INTERVAL, - enabled: !maxRequestsReached && !isSendingManifest + enabled: !settings.isBlockchainDown && !maxRequestsReached && !isSendingManifest });
454-458
: Gating UI on blockchain-down looks good.Consistent, user-friendly blocking with clear messaging; buttons are properly disabled or hidden. Consider removing redundant disabled={settings.isBlockchainDown} on Line 461 since the block doesn’t render when down. Optional.
Also applies to: 460-465, 466-473, 474-483, 485-491
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx (1)
76-76
: HardenloadValidCertificates
with fallback check
- In apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx, prepend to
loadValidCertificates
:if (chainApiHttpClient.isFallbackEnabled) { setIsLoadingCertificates(false); return []; }- Add
chainApiHttpClient.isFallbackEnabled
to itsuseCallback
deps to avoid capturing a stale flag.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
(4 hunks)apps/deploy-web/src/components/home/YourAccount.tsx
(1 hunks)apps/deploy-web/src/components/layout/TopBanner.tsx
(2 hunks)apps/deploy-web/src/components/layout/WalletStatus.tsx
(4 hunks)apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
(2 hunks)apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
(1 hunks)apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
(4 hunks)apps/deploy-web/src/components/sdl/RentGpusForm.tsx
(4 hunks)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
(2 hunks)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
(2 hunks)apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
(4 hunks)apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
(1 hunks)apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
(3 hunks)apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
(1 hunks)apps/deploy-web/src/hooks/useWalletBalance.ts
(2 hunks)apps/deploy-web/src/pages/payment.tsx
(3 hunks)apps/deploy-web/src/queries/useBalancesQuery.ts
(1 hunks)apps/deploy-web/src/queries/useBidQuery.ts
(2 hunks)apps/deploy-web/src/queries/useBlocksQuery.ts
(1 hunks)apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
(3 hunks)apps/deploy-web/src/queries/useGrantsQuery.ts
(3 hunks)apps/deploy-web/src/queries/useSaveSettings.spec.tsx
(3 hunks)apps/deploy-web/src/queries/useSaveSettings.ts
(2 hunks)apps/deploy-web/src/services/app-di-container/browser-di-container.ts
(1 hunks)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
(2 hunks)apps/deploy-web/src/store/walletStore.ts
(1 hunks)apps/deploy-web/src/utils/deploymentData/helpers.ts
(0 hunks)apps/deploy-web/src/utils/deploymentData/v1beta2.ts
(3 hunks)apps/deploy-web/src/utils/deploymentData/v1beta3.ts
(3 hunks)
💤 Files with no reviewable changes (1)
- apps/deploy-web/src/utils/deploymentData/helpers.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
- apps/deploy-web/src/components/home/YourAccount.tsx
- apps/deploy-web/src/pages/payment.tsx
- apps/deploy-web/src/queries/useBlocksQuery.ts
- apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
- apps/deploy-web/src/queries/useSaveSettings.ts
- apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
- apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/queries/useSaveSettings.spec.tsx
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/hooks/useWalletBalance.ts
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}
: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/queries/useSaveSettings.spec.tsx
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/hooks/useWalletBalance.ts
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
**/*.spec.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)
Don't use
jest.mock()
to mock dependencies in test files. Instead, usejest-mock-extended
to create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}
: Usesetup
function instead ofbeforeEach
in test files
setup
function must be at the bottom of the rootdescribe
block in test files
setup
function creates an object under test and returns it
setup
function should accept a single parameter with inline type definition
Don't use shared state insetup
function
Don't specify return type ofsetup
function
Files:
apps/deploy-web/src/queries/useSaveSettings.spec.tsx
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
apps/{deploy-web,provider-console}/**/*.spec.tsx
📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)
Use
queryBy
methods instead ofgetBy
methods in test expectations in.spec.tsx
files
Files:
apps/deploy-web/src/queries/useSaveSettings.spec.tsx
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
🧬 Code graph analysis (11)
apps/deploy-web/src/queries/useSaveSettings.spec.tsx (1)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
FallbackableHttpClient
(7-7)
apps/deploy-web/src/store/walletStore.ts (2)
apps/deploy-web/src/utils/apiUtils.ts (1)
balance
(44-46)apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)
apps/deploy-web/src/components/sdl/RentGpusForm.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx (3)
apps/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx (1)
useSettings
(333-335)apps/deploy-web/src/queries/useSaveSettings.ts (1)
useDepositParams
(37-45)apps/deploy-web/src/hooks/useDenom.ts (1)
useUsdcDenom
(4-6)
apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (1)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)
apps/deploy-web/src/queries/useGrantsQuery.ts (3)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)packages/http-sdk/src/authz/authz-http.service.ts (1)
DepositDeploymentGrant
(31-34)
apps/deploy-web/src/components/layout/WalletStatus.tsx (3)
apps/deploy-web/src/hooks/useShortText.ts (1)
getSplitText
(6-10)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx (1)
CustodialWalletPopup
(28-95)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (1)
ManagedWalletPopup
(19-88)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (3)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
services
(23-55)apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)
withInterceptors
(151-155)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
createFallbackableHttpClient
(8-46)
apps/deploy-web/src/queries/useBidQuery.ts (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
services
(23-34)
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx (1)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
FallbackableHttpClient
(7-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: validate / validate-app
- GitHub Check: test-build
🔇 Additional comments (14)
apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx (1)
24-24
: LGTM!Destructuring
settings
to accessisBlockchainDown
is correct and necessary for the new guard condition.apps/deploy-web/src/components/layout/TopBanner.tsx (2)
25-25
: LGTM!The updated banner message clearly communicates the read-only state to users.
56-58
: LGTM!The reordered gating logic correctly prioritizes the blockchain-down banner over the maintenance banner, ensuring users see the most critical information first.
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
2-2
: LGTM!The migration from local
useState
to the globalwalletStore.balance
atom is implemented correctly, maintaining the same API while enabling cross-component state sharing.Also applies to: 9-9, 40-40
apps/deploy-web/src/queries/useBalancesQuery.ts (1)
13-14
: LGTM!The added
isFallbackEnabled
gate correctly prevents balance queries when the blockchain is down, consistent with the fallback behavior introduced across the codebase.apps/deploy-web/src/store/walletStore.ts (1)
4-4
: LGTM!The new
balance
atom is correctly typed and integrated into thewalletStore
, enabling centralized wallet balance state management.Also applies to: 9-9, 15-15
apps/deploy-web/src/queries/useSaveSettings.spec.tsx (1)
7-7
: LGTM!The test correctly adapts to the new
FallbackableHttpClient
abstraction, withisFallbackEnabled: false
properly simulating normal (non-fallback) operation.Also applies to: 77-79, 106-108
apps/deploy-web/src/components/sdl/RentGpusForm.tsx (1)
13-13
: LGTM!The migration from
browserEnvConfig
/SettingsProvider
touseServices
correctly centralizes dependency access through the DI container, consistent with the broader architectural shift in this PR.Also applies to: 50-50, 78-78, 136-136
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx (1)
7-7
: LGTM!The test mocks correctly adopt the
FallbackableHttpClient
type withisFallbackEnabled: false
, aligning with the new HTTP client abstraction.Also applies to: 178-179, 205-206
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx (1)
179-179
: LGTM!The test correctly validates the blockchain-down UI behavior by checking for the expected indicator text, and the mock properly simulates fallback mode via
isFallbackEnabled
.Also applies to: 431-431
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
43-51
: fallbackChainApiHttpClient flag exposure verified
applyAxiosInterceptors/withInterceptors preserveisFallbackEnabled
on the client wrapper, so downstream guards remain functional.apps/deploy-web/src/queries/useBidQuery.ts (3)
39-40
: LGTM! Correct fallback gating implementation.The enabled gate correctly prevents the query from running when the chain API client is in fallback mode, while respecting any explicit
enabled: false
from the caller. The order of spreading...options
before definingenabled
ensures the fallback check cannot be overridden.
52-59
: LGTM! Improved type safety.The signature refactoring provides explicit, strongly-typed optional options parameter, replacing the previous generic default. This improves type safety and aligns with
useBidList
's signature pattern.
64-65
: LGTM! Consistent fallback gating.The enabled gate implementation matches the pattern in
useBidList
, correctly preventing the query from running when the chain API is in fallback mode while respecting explicit caller preferences.
There was a problem hiding this 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
🧹 Nitpick comments (2)
apps/deploy-web/src/utils/deploymentData/v1beta2.ts (2)
211-212
: Consider extracting duplicated height-fetching logic.The height-fetching logic is duplicated between v1beta2.ts and v1beta3.ts. Consider extracting it into a shared helper function in
helpers.ts
to improve maintainability.Example helper function:
// In helpers.ts export async function fetchLatestBlockHeight(chainApiHttpClient: HttpClient): Promise<string> { try { const response = await chainApiHttpClient.get("/blocks/latest"); return response.data.block.header.height; } catch (error) { throw new CustomValidationError(`Failed to fetch latest block height: ${error instanceof Error ? error.message : String(error)}`); } }Then use in both files:
if (!id.dseq) { id.dseq = await fetchLatestBlockHeight(chainApiHttpClient); }
211-212
: Enforce type safety and wrap the block-height fetch in explicit error handling
- Specify the response type on the API call (e.g.
get<{block:{header:{height:string}}}>
) or assertresponse.data.block.header.height
is a string before assigning toid.dseq
.- Add a localized
try/catch
to throw a clearCustomValidationError
on failures:if (!id.dseq) { + try { const response = await chainApiHttpClient.get<{block:{header:{height:string}}}>("/blocks/latest"); id.dseq = response.data.block.header.height; + } catch (error) { + throw new CustomValidationError(`Failed to fetch latest block height: ${error instanceof Error ? error.message : String(error)}`); + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/deploy-web/src/components/layout/WalletStatus.tsx
(2 hunks)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
(2 hunks)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
(2 hunks)apps/deploy-web/src/utils/deploymentData/v1beta2.ts
(3 hunks)apps/deploy-web/src/utils/deploymentData/v1beta3.ts
(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
- apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}
: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/deploy-web/src/components/layout/WalletStatus.tsx
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
🧬 Code graph analysis (1)
apps/deploy-web/src/components/layout/WalletStatus.tsx (4)
apps/provider-console/src/utils/styleUtils.ts (1)
cn
(4-6)apps/deploy-web/src/hooks/useShortText.ts (1)
getSplitText
(6-10)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx (1)
CustodialWalletPopup
(28-95)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx (1)
ManagedWalletPopup
(19-88)
🔇 Additional comments (5)
apps/deploy-web/src/utils/deploymentData/v1beta3.ts (3)
2-2
: LGTM: HttpClient import added.The import of
HttpClient
type from@akashnetwork/http-sdk
is correctly added to support the new parameter type.
85-85
: LGTM: Function signature updated to use HttpClient.The signature change from
apiEndpoint: string
tochainApiHttpClient: HttpClient
aligns with the broader PR objective to route chain API calls through a fallbackable client.
101-105
: No action required: block.header.height is defined as string in the SDK, so assigning it tofinalDseq: string
is type-safe.apps/deploy-web/src/utils/deploymentData/v1beta2.ts (2)
4-4
: LGTM: HttpClient import added.The import of
HttpClient
type from@akashnetwork/http-sdk
correctly supports the new parameter type.
185-185
: LGTM: Function signature updated consistently.The signature change mirrors the v1beta3 implementation, maintaining consistency across SDL versions.
<DropdownMenu modal={false} open={open}> | ||
<DropdownMenuTrigger asChild> | ||
{!!walletBalance && ( | ||
<div | ||
className={cn("flex items-center justify-center rounded-md border px-4 py-2 text-sm", { | ||
"border-primary bg-primary/10 text-primary dark:bg-primary dark:text-primary-foreground": isManaged, | ||
"bg-background text-foreground": !isManaged | ||
})} | ||
onMouseOver={() => setOpen(true)} | ||
> | ||
<div className="flex items-center space-x-2" aria-label="Connected wallet name and balance"> | ||
{isManaged && isTrialing && <span className="text-xs">Trial</span>} | ||
{!isManaged && ( | ||
<> | ||
<Wallet className="text-xs" /> | ||
{walletName?.length > 20 ? ( | ||
<span className="text-xs">{getSplitText(walletName, 4, 4)}</span> | ||
) : ( | ||
<span className="text-xs">{walletName}</span> | ||
)} | ||
</> | ||
)} | ||
</div> | ||
<div | ||
className={cn("flex items-center justify-center rounded-md border px-4 py-2 text-sm", { | ||
"border-primary bg-primary/10 text-primary dark:bg-primary dark:text-primary-foreground": isManaged, | ||
"bg-background text-foreground": !isManaged | ||
})} | ||
onMouseOver={() => setOpen(true)} | ||
> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore click/touch-open behavior for the wallet menu
By switching the trigger to onMouseOver
only, the dropdown never opens on touch devices or via keyboard (no hover). Because the menu is controlled (open={open}
) without onOpenChange
, Radix can’t toggle it either, so wallet actions become inaccessible on mobile—this is a regression. Please reintroduce a click/pointer toggle (or wire onOpenChange={setOpen}
) so the menu still opens outside of hover contexts.
a8fe690
to
edfdb21
Compare
There was a problem hiding this 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/deploy-web/src/components/sdl/RentGpusForm.tsx (1)
127-137
: Normalize deposit before calling NewDeploymentData.createAndValidateDeploymentData forwards deposit which can be number | DepositParams[]. NewDeploymentData uses deposit.toString(), so arrays will stringify incorrectly.
Apply:
- async function createAndValidateDeploymentData( - yamlStr: string, - dseq: string | null = null, - deposit = defaultDeposit, - depositorAddress: string | null = null - ) { + async function createAndValidateDeploymentData( + yamlStr: string, + dseq: string | null = null, + depositArg: number | DepositParams[] = defaultDeposit, + depositorAddress: string | null = null + ) { try { if (!yamlStr) return null; - const dd = await deploymentData.NewDeploymentData(chainApiHttpClient, yamlStr, dseq, address, deposit, depositorAddress); + const normalizedDeposit = + Array.isArray(depositArg) + ? Number(depositArg.find(d => d.denom === "uakt")?.amount ?? appConfig.NEXT_PUBLIC_DEFAULT_INITIAL_DEPOSIT) + : depositArg; + const dd = await deploymentData.NewDeploymentData(chainApiHttpClient, yamlStr, dseq, address, normalizedDeposit, depositorAddress);As per coding guidelines
apps/deploy-web/src/utils/deploymentData/v1beta2.ts (1)
184-191
: Catch block height fetch failures and tighten deposit parameter typing
- Wrap the
chainApiHttpClient.get("/blocks/latest")
call in a try/catch, rethrowing a clearCustomValidationError("Unable to retrieve block height; try again later")
on error.- Update the signature to:
export async function NewDeploymentData( chainApiHttpClient: HttpClient, yamlStr: string, dseq: string, fromAddress: string, deposit: string | number = browserEnvConfig.NEXT_PUBLIC_DEFAULT_INITIAL_DEPOSIT, depositorAddress: string | null = null )and validate
deposit
to reject non-string/number values (e.g., arrays).
♻️ Duplicate comments (1)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
40-55
: Avoid never-resolving promises in request interceptorReturning
neverResolvedPromise
causes requests to hang indefinitely until the client is recreated. Prefer failing fast or canceling for clearer behavior and reduced resource usage.-const neverResolvedPromise = new Promise<never>(() => {}); @@ - request: [config => (config.baseURL ? config : neverResolvedPromise)] + request: [ + config => (config.baseURL ? config : Promise.reject(new Error("chainApiHttpClient: missing baseURL"))) + ]
🧹 Nitpick comments (7)
apps/deploy-web/src/components/home/YourAccount.tsx (1)
224-224
: Good defensive guard, but consider filtering invalid providers upstream.The conditional check prevents malformed URLs when
owner
is empty, which is an improvement. However, there are better alternatives to consider:
- Filter out providers without valid owners in the
useEffect
(lines 133-139) to prevent them from being added touserProviders
in the first place.- Duplicate key concern: If multiple providers have empty
owner
values, thekey={p.owner}
will cause React duplicate key warnings.Consider this refactor to filter out invalid providers earlier:
const _userProviders = activeLeases .map(x => x.provider) .filter((value, index, array) => array.indexOf(value) === index) .map(x => { const provider = providers.find(p => p.owner === x); return { owner: provider?.owner || "", name: provider?.name || "Unknown" }; }) + .filter(p => p.owner !== ""); setCostPerMonth(getAvgCostPerMonth(totalCostPerBlock)); setUserProviders(_userProviders);
This eliminates the need for the conditional in the href and prevents potential duplicate key warnings.
apps/deploy-web/src/services/createFetchAdapter/createFetchAdapter.ts (1)
63-67
: Coerce boolean and consider retrying 408 (Request Timeout).
- Make isNetworkError a strict boolean and cast for type safety.
- Many clients retry 408 along with 5xx/429 for idempotent methods.
Apply:
-export function isNetworkOrIdempotentRequestError(error: unknown): boolean { - const isNetworkError = error && !axios.isAxiosError(error) && error instanceof Error && "code" in error && error.code; - if (isNetworkError) return isRetriableError(error); - return axios.isAxiosError(error) && isIdempotentRequestError(error); -} +export function isNetworkOrIdempotentRequestError(error: unknown): boolean { + const isNetworkError = !!( + error && + !axios.isAxiosError(error) && + error instanceof Error && + "code" in error && + (error as ErrorWithCode).code + ); + if (isNetworkError) return isRetriableError(error as ErrorWithCode); + return axios.isAxiosError(error) && (isIdempotentRequestError(error) || error.response?.status === 408); +}apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx (1)
178-181
: Use queryBy in expectations (repo guideline).*Replace getByText with queryByText in this .spec.tsx file.
- expect(screen.getByText(/Blockchain is down/i)).toBeInTheDocument(); + expect(screen.queryByText(/Blockchain is down/i)).toBeInTheDocument();As per coding guidelines
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx (1)
76-77
: Solid fallback behavior; add dep to avoid stale closure.
- Returning [] on fallback avoids noisy errors. Early exit in useEffect is good.
- Minor: loadValidCertificates captures chainApiHttpClient.isFallbackEnabled but it’s not in the useCallback deps, risking a stale value after a fallback toggle. Add it to the dependency array.
Add to deps of loadValidCertificates:
// ...existing deps [address, certificatesService, localCert, selectedCertificate, chainApiHttpClient.isFallbackEnabled]Also applies to: 94-97, 141-142, 152-152
apps/deploy-web/src/queries/useGrantsQuery.ts (1)
17-25
: Gate by fallback: good; align queryKey behavior when address is falsyGating via
!chainApiHttpClient.isFallbackEnabled
is solid and the spread order preserves gating precedence. To avoid caching under placeholder keys and be consistent withuseAllowancesGranted
, use an empty queryKey whenaddress
is falsy.@@ - return useQuery({ - queryKey: QueryKeys.getGranterGrants(address, page, offset), + return useQuery({ + queryKey: address ? QueryKeys.getGranterGrants(address, page, offset) : [], @@ - return useQuery({ - queryKey: QueryKeys.getGranteeGrants(address || "UNDEFINED"), + return useQuery({ + queryKey: address ? QueryKeys.getGranteeGrants(address) : [], @@ - return useQuery({ - queryKey: QueryKeys.getAllowancesIssued(address, page, offset), + return useQuery({ + queryKey: address ? QueryKeys.getAllowancesIssued(address, page, offset) : [],Also applies to: 29-36, 45-53, 60-68
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx (1)
454-458
: UI gating looks good; also pause polling when blockchain is downWhile the UI is gated on
settings.isBlockchainDown
, consider pausinguseBidList
polling to save bandwidth and noise.Example change (outside this hunk) where
useBidList
is called:// current d.useBidList(address, dseq, { initialData: [], refetchInterval: REFRESH_BIDS_INTERVAL, enabled: !maxRequestsReached && !isSendingManifest }); // suggested d.useBidList(address, dseq, { initialData: [], refetchInterval: REFRESH_BIDS_INTERVAL, enabled: !maxRequestsReached && !isSendingManifest && !settings.isBlockchainDown });Please confirm if
useBidList
already gates internally viachainApiHttpClient.isFallbackEnabled
; if so, this can be skipped.Also applies to: 460-464, 466-472, 474-483, 485-491
apps/deploy-web/src/utils/deploymentData/v1beta3.ts (1)
101-106
: Type the /blocks/latest response for safetyAdd a response type to avoid untyped property access and catch regressions at compile time.
- const response = await chainApiHttpClient.get("/blocks/latest"); - finalDseq = response.data.block.header.height; + const response = await chainApiHttpClient.get<{ block: { header: { height: string } } }>("/blocks/latest"); + finalDseq = response.data.block.header.height;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (31)
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
(4 hunks)apps/deploy-web/src/components/home/YourAccount.tsx
(1 hunks)apps/deploy-web/src/components/layout/TopBanner.tsx
(2 hunks)apps/deploy-web/src/components/layout/WalletStatus.tsx
(2 hunks)apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
(2 hunks)apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
(1 hunks)apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
(4 hunks)apps/deploy-web/src/components/sdl/RentGpusForm.tsx
(4 hunks)apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
(2 hunks)apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
(2 hunks)apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
(4 hunks)apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
(1 hunks)apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
(2 hunks)apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
(1 hunks)apps/deploy-web/src/hooks/useWalletBalance.ts
(2 hunks)apps/deploy-web/src/pages/payment.tsx
(3 hunks)apps/deploy-web/src/queries/useBalancesQuery.ts
(1 hunks)apps/deploy-web/src/queries/useBidQuery.ts
(2 hunks)apps/deploy-web/src/queries/useBlocksQuery.ts
(1 hunks)apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
(3 hunks)apps/deploy-web/src/queries/useGrantsQuery.ts
(3 hunks)apps/deploy-web/src/queries/useSaveSettings.spec.tsx
(3 hunks)apps/deploy-web/src/queries/useSaveSettings.ts
(2 hunks)apps/deploy-web/src/services/app-di-container/browser-di-container.ts
(1 hunks)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts
(4 hunks)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
(3 hunks)apps/deploy-web/src/services/createFetchAdapter/createFetchAdapter.ts
(1 hunks)apps/deploy-web/src/store/walletStore.ts
(1 hunks)apps/deploy-web/src/utils/deploymentData/helpers.ts
(0 hunks)apps/deploy-web/src/utils/deploymentData/v1beta2.ts
(3 hunks)apps/deploy-web/src/utils/deploymentData/v1beta3.ts
(3 hunks)
💤 Files with no reviewable changes (1)
- apps/deploy-web/src/utils/deploymentData/helpers.ts
🚧 Files skipped from review as they are similar to previous changes (11)
- apps/deploy-web/src/pages/payment.tsx
- apps/deploy-web/src/queries/useBlocksQuery.ts
- apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx
- apps/deploy-web/src/queries/useSaveSettings.spec.tsx
- apps/deploy-web/src/components/layout/WalletStatus.tsx
- apps/deploy-web/src/hooks/useWalletBalance.ts
- apps/deploy-web/src/components/wallet/CustodialWalletPopup.tsx
- apps/deploy-web/src/context/TopBannerProvider/TopBannerProvider.tsx
- apps/deploy-web/src/context/ChainParamProvider/ChainParamProvider.tsx
- apps/deploy-web/src/components/wallet/ManagedWalletPopup.tsx
- apps/deploy-web/src/queries/useSaveSettings.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/deploy-web/src/services/createFetchAdapter/createFetchAdapter.ts
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/components/home/YourAccount.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}
: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/deploy-web/src/services/createFetchAdapter/createFetchAdapter.ts
apps/deploy-web/src/services/app-di-container/browser-di-container.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx
apps/deploy-web/src/context/CertificateProvider/CertificateProviderContext.tsx
apps/deploy-web/src/queries/useBalancesQuery.ts
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.tsx
apps/deploy-web/src/components/layout/TopBanner.tsx
apps/deploy-web/src/utils/deploymentData/v1beta3.ts
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
apps/deploy-web/src/store/walletStore.ts
apps/deploy-web/src/components/sdl/RentGpusForm.tsx
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx
apps/deploy-web/src/utils/deploymentData/v1beta2.ts
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts
apps/deploy-web/src/queries/useBidQuery.ts
apps/deploy-web/src/components/home/YourAccount.tsx
apps/deploy-web/src/queries/useGrantsQuery.ts
**/*.spec.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)
Don't use
jest.mock()
to mock dependencies in test files. Instead, usejest-mock-extended
to create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}
: Usesetup
function instead ofbeforeEach
in test files
setup
function must be at the bottom of the rootdescribe
block in test files
setup
function creates an object under test and returns it
setup
function should accept a single parameter with inline type definition
Don't use shared state insetup
function
Don't specify return type ofsetup
function
Files:
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts
apps/{deploy-web,provider-console}/**/*.spec.tsx
📄 CodeRabbit inference engine (.cursor/rules/query-by-in-tests.mdc)
Use
queryBy
methods instead ofgetBy
methods in test expectations in.spec.tsx
files
Files:
apps/deploy-web/src/components/new-deployment/CreateLease/CreateLease.spec.tsx
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx
🧬 Code graph analysis (11)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
apps/deploy-web/src/services/app-di-container/server-di-container.service.ts (1)
services
(23-34)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (3)
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
services
(23-55)apps/deploy-web/src/services/app-di-container/app-di-container.ts (1)
withInterceptors
(151-155)apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
createFallbackableHttpClient
(7-44)
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx (1)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
FallbackableHttpClient
(6-6)
apps/deploy-web/src/store/walletStore.ts (1)
apps/deploy-web/src/hooks/useWalletBalance.ts (1)
WalletBalance
(16-28)
apps/deploy-web/src/components/sdl/RentGpusForm.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/utils/deploymentData/index.ts (1)
deploymentData
(14-14)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
apps/deploy-web/src/services/createFetchAdapter/createFetchAdapter.ts (1)
isNetworkOrIdempotentRequestError
(63-67)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts (1)
apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (1)
ChainApiHttpClientOptions
(46-51)
apps/deploy-web/src/queries/useBidQuery.ts (2)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)
apps/deploy-web/src/components/home/YourAccount.tsx (1)
apps/deploy-web/src/utils/urlUtils.ts (1)
UrlService
(16-81)
apps/deploy-web/src/queries/useGrantsQuery.ts (3)
apps/deploy-web/src/context/ServicesProvider/ServicesProvider.tsx (1)
useServices
(29-31)apps/deploy-web/src/queries/queryKeys.ts (1)
QueryKeys
(1-122)packages/http-sdk/src/authz/authz-http.service.ts (1)
DepositDeploymentGrant
(31-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: validate / validate-app
- GitHub Check: test-build
🔇 Additional comments (19)
apps/deploy-web/src/store/walletStore.ts (1)
4-15
: LGTM!The implementation correctly introduces a global balance state atom:
- Type-only import follows best practices
balance
atom usesWalletBalance | null
type, appropriately reflecting optional balance data- Regular
atom
(notatomWithStorage
) is the right choice for transient balance data that should be fetched fresh- Follows the existing Jotai state management pattern
apps/deploy-web/src/components/layout/TopBanner.tsx (2)
25-25
: LGTM! Clear and informative message.The updated message effectively communicates both the problem (blockchain is down) and the consequence (read-only mode) to users. This aligns well with the broader blockchain-down gating feature being implemented across the codebase.
56-58
: LGTM! Correct banner precedence.The maintenance banner now renders only after the blockchain-down check, which is the appropriate priority order. Critical blockchain outages should take precedence over scheduled maintenance messaging.
apps/deploy-web/src/queries/useBidQuery.ts (3)
39-40
: LGTM! Query gating logic is correct.The enabled condition properly combines the caller's intent with the fallback mode check. The spread order (
...options
beforeenabled
) ensures the calculated enabled value takes precedence, which is the correct behavior to prevent queries from running when the chain API is in fallback mode.
52-59
: LGTM! Improved type safety.The signature change from
options = {}
to a strongly-typed optional parameter improves type safety. TheOmit
utility type correctly prevents callers from overridingqueryKey
orqueryFn
.
64-65
: LGTM! Consistent with useBidList.The enabled gating logic matches the pattern in
useBidList
, ensuring consistent behavior across both hooks when the chain API is in fallback mode.apps/deploy-web/src/queries/useBalancesQuery.ts (1)
13-14
: LGTM! Correctly gates balance queries when chain API is in fallback mode.The enabled logic now properly disables the query when
chainApiHttpClient.isFallbackEnabled
is true, preventing balance fetches when the blockchain is unreachable. The spread operator placement on line 13 is correct—placing it before the explicitenabled
ensures the computed conditions always apply while still respectingoptions?.enabled !== false
to allow explicit disables.apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.spec.ts (1)
16-37
: Renamed callback and expectations look correct.Fallback triggers after retries and when breaker is open; onUnavailableError is asserted properly.
Also applies to: 55-71
apps/deploy-web/src/components/deployments/ManifestUpdate.tsx (1)
44-45
: Migration to chainApiHttpClient looks good.Passing dseq avoids extra height fetch; deps updated appropriately.
Also applies to: 85-86, 107-108, 143-144
apps/deploy-web/src/queries/useGrantsQuery.spec.tsx (1)
7-8
: Aligned tests with FallbackableHttpClient and fallback flag.Mocks and expectations match the new abstraction.
Also applies to: 178-187, 205-213
apps/deploy-web/src/services/app-di-container/browser-di-container.ts (1)
43-51
: Fallback client wiring LGTMSetting
baseURL
per-request viaApiUrlService
is clean and resilient across network switch. No issues spotted.apps/deploy-web/src/services/createFallbackableHttpClient/createFallbackableHttpClient.ts (8)
4-4
: LGTM!The new import correctly brings in the error checking function used in the updated fallback logic.
6-6
: LGTM!The type definition appropriately extends
HttpClient
with the fallback status property, making the enhanced API surface explicit.
11-12
: LGTM!The more specific return type improves type safety, and storing the client in a variable enables the dynamic property addition.
27-27
: LGTM!The callback rename from
onFailure
toonUnavailableError
improves clarity by being more specific about the error type. This is consistent with the interface update.
39-41
: LGTM!The
Object.defineProperty
pattern correctly exposesisFallbackEnabled
as a computed read-only property that delegates tooptions.shouldFallback()
, ensuring it always reflects the current fallback state.
43-43
: LGTM!The type assertion to
FallbackableHttpClient
is necessary and safe since theisFallbackEnabled
property was just added viaObject.defineProperty
.
48-48
: LGTM!The interface property rename from
onFailure
toonUnavailableError
is consistent with the updated callback usage and provides better semantic clarity.
26-26
: Validate refined fallback conditions
Fallback now triggers only for network/idempotent or broken-circuit errors instead of all HTTP errors—confirm this narrower behavior is intentional.
Why
#1947
Summary by CodeRabbit
New Features
Bug Fixes
Refactor