feat: Integrate injected wallet support in PhoneVerificationModal and ProfileView components - #623
Conversation
… ProfileView components - Added `useInjectedWallet` context to both PhoneVerificationModal and ProfileView components to handle wallet address selection. - Updated logic to use the injected wallet address when in injected mode, ensuring a seamless user experience across wallet types. - Enhanced code clarity by differentiating between embedded and injected wallet addresses in both components.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughInjected-wallet authentication now flows through OTP, KYC, bridge quoting, execution, and status tracking. Wallet UI selects injected addresses where available, while Scroll is removed from chain configuration, metadata, mocks, and fallback tokens. ChangesInjected wallet support
Scroll support removal
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant WalletUser
participant BridgeForm
participant BridgeHooks
participant InjectedProvider
participant BridgeAPI
WalletUser->>BridgeForm: Connect injected wallet
BridgeForm->>BridgeAPI: Request quote with injected address
BridgeAPI->>BridgeForm: Return bridge quote
BridgeForm->>BridgeHooks: Execute injected bridge flow
BridgeHooks->>InjectedProvider: Switch chain and submit transactions
InjectedProvider->>BridgeHooks: Return transaction receipts
BridgeHooks->>BridgeAPI: Poll bridge status with injected authentication
BridgeAPI->>BridgeForm: Return updated status
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/components/PhoneVerificationModal.tsx`:
- Around line 96-103: Update the walletAddress selection near isInjectedWallet
so injected mode does not fall back to embeddedWallet when injectedAddress is
unavailable or the injected account is disconnected. Use the
InjectedWalletContext readiness/connection state to fail closed or apply the
established consistent fallback, while preserving embeddedWallet usage only for
non-injected mode.
- Around line 96-103: The wallet readiness policy is inconsistent between
PhoneVerificationModal and ProfileView when injected mode is enabled without an
injectedAddress. Update walletAddress selection in
app/components/PhoneVerificationModal.tsx at lines 96-103 and the corresponding
address handling in app/components/ProfileView.tsx at lines 47-58 to use the
same approved policy: require a ready injected address, otherwise consistently
preserve kycWalletAddress or hide/block the address; do not silently fall back
in only one component.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 348ac598-1373-4fda-ac82-331b8c84f2cc
📒 Files selected for processing (2)
app/components/PhoneVerificationModal.tsxapp/components/ProfileView.tsx
- Updated authorizationMiddleware to support both Privy JWT and injected wallet authentication, improving error handling and analytics tracking. - Removed references to the Scroll chain across multiple components, including layout, mocks, and utils, to streamline the codebase. - Enhanced KycModal, PhoneVerificationModal, and BridgeForm components to handle injected wallet logic, ensuring seamless user experience across wallet types. - Refactored bridge-related hooks and API calls to accommodate injected wallet authentication, improving overall functionality and maintainability.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
app/components/PhoneVerificationModal.tsx (2)
204-260: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
handlePhoneSubmit's deps omitisInjectedWallet/injectedAddress.Both are read inside the callback (lines 215, 227-229) but missing from the dependency array (line 260).
injectedAddresschanging withoutisInjectedWallettoggling (e.g. the injected wallet switches account) would not recreate the callback, sending a stale address inx-injected-wallet.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/PhoneVerificationModal.tsx` around lines 204 - 260, Update the dependency array of handlePhoneSubmit to include both isInjectedWallet and injectedAddress, ensuring the callback uses the current injected-wallet state and address when sending the OTP request.
262-307: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winOTP verification and resend are unreachable for injected wallets.
resolveAccessToken()intentionally returnsnullfor injected wallets (lines 90-92), buthandleOtpSubmitandhandleResendOtpwere not updated to match — they still doif (!accessToken) { return; }and only ever sendAuthorization: Bearer …. For injected-wallet users this means every OTP submit/resend call silently no-ops: they can request an OTP viahandlePhoneSubmit(which was correctly updated) but can never complete verification, since these two handlers always bail out before hittingfetch.Apply the same pattern used in
handlePhoneSubmit: allowaccessTokento be null whenisInjectedWallet, and add thex-injected-walletheader.🐛 Proposed fix
const handleOtpSubmit = useCallback(async () => { if (!otpCode.trim() || otpCode.length !== 6) { toast.error("Please enter the 6-digit OTP code"); return; } const accessToken = await resolveAccessToken(); - if (!accessToken) { + if (!accessToken && !isInjectedWallet) { return; } setIsLoading(true); try { + const headers: Record<string, string> = { "Content-Type": "application/json" }; + if (accessToken) headers.Authorization = `Bearer ${accessToken}`; + if (isInjectedWallet && injectedAddress) headers["x-injected-wallet"] = injectedAddress; const response = await fetch("/api/phone/verify-otp", { method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${accessToken}`, - }, + headers, body: JSON.stringify({ phoneNumber: formattedPhone, otpCode }), });The same change applies to
handleResendOtp.Also applies to: 309-344
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/PhoneVerificationModal.tsx` around lines 262 - 307, Update handleOtpSubmit and handleResendOtp to support injected wallets like handlePhoneSubmit: permit a null accessToken when isInjectedWallet is true, still require a token otherwise, and include the x-injected-wallet header in their fetch requests for injected-wallet flows while preserving the existing Authorization header behavior.app/components/KycModal.tsx (1)
120-129: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMissing
injectedReadygate — inconsistent with the fix applied to sibling components.
PhoneVerificationModal.tsxandProfileView.tsxwere fixed (per past review) to requireinjectedReadybefore treatinginjectedAddressas valid. This component doesn't destructure or checkinjectedReadyat all, sowalletAddress(and everything downstream: SmileID capture context, Tier 3 upload headers,fetchStatus) can use an injected address before the wallet is actually ready.🛡️ Suggested fix
- const { isInjectedWallet, injectedAddress } = useInjectedWallet(); + const { isInjectedWallet, injectedAddress, injectedReady } = useInjectedWallet(); const embeddedWallet = wallets.find( (wallet) => wallet.walletClientType === "privy", ); const walletAddress = isInjectedWallet - ? injectedAddress + ? (injectedReady ? injectedAddress : null) : embeddedWallet?.address;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/KycModal.tsx` around lines 120 - 129, Update the useInjectedWallet destructuring and walletAddress selection in KycModal so injectedAddress is used only when injectedReady is true; otherwise preserve the embedded wallet fallback behavior. Ensure all downstream consumers of walletAddress, including SmileID context, Tier 3 upload headers, and fetchStatus, receive only a ready injected address.
🧹 Nitpick comments (1)
app/components/WalletDetails.tsx (1)
537-579: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant
!isInjectedWalletcheck on the Convert button.Line 565 adds
&& !isInjectedWallet, but this button is already inside the{!isInjectedWallet && (...)}block opened at line 537 — the added check is dead code and can't change behavior. Separately, since the whole Fund/Transfer/Convert row (and the modals rendered at line 906, includingBridgeForm) is gated out for injected wallets here, worth confirming the new injected-wallet bridge quoting/execution work added toBridgeForm.tsx/app/hooks/bridge.tsis actually reachable from some other UI entry point.🧹 Suggested cleanup
- {isBridgeUiVisible() && !isInjectedWallet && ( + {isBridgeUiVisible() && (🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/WalletDetails.tsx` around lines 537 - 579, Remove the redundant !isInjectedWallet condition from the Convert button’s isBridgeUiVisible() guard in WalletDetails, since it is already nested inside the outer !isInjectedWallet block. Separately verify that injected-wallet bridge quoting and execution remain reachable through an appropriate UI entry point outside this gated Fund/Transfer/Convert row, including BridgeForm usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/context/KYCContext.tsx`:
- Around line 104-121: The KYC fetch flow in KYCProvider must wait for the
injected wallet context’s injectedReady flag before using walletAddress or
requesting KYC status and transaction-summary data. Include injectedReady from
useInjectedWallet and gate the relevant refresh effects/requests, while
preserving the existing Privy authentication path and normal behavior once the
wallet is ready.
In `@app/mocks.ts`:
- Around line 158-167: Update the documentation comment above
migrationChecklistNetworks to accurately describe that the checklist excludes
Celo, Starknet, and Tron, or use a generic description that does not enumerate
exclusions. Keep the filtering logic and MIGRATION_EXCLUDED_CHAIN_IDS unchanged.
In `@middleware.ts`:
- Around line 172-183: The injected-wallet branch in middleware must not trust
x-injected-wallet alone. Before assigning walletAddress or privyUserId, validate
a signed nonce/challenge proving control of the claimed wallet, and reject the
request when proof is missing or invalid; preserve the existing token-based
authentication path and only derive downstream headers after successful
verification.
---
Outside diff comments:
In `@app/components/KycModal.tsx`:
- Around line 120-129: Update the useInjectedWallet destructuring and
walletAddress selection in KycModal so injectedAddress is used only when
injectedReady is true; otherwise preserve the embedded wallet fallback behavior.
Ensure all downstream consumers of walletAddress, including SmileID context,
Tier 3 upload headers, and fetchStatus, receive only a ready injected address.
In `@app/components/PhoneVerificationModal.tsx`:
- Around line 204-260: Update the dependency array of handlePhoneSubmit to
include both isInjectedWallet and injectedAddress, ensuring the callback uses
the current injected-wallet state and address when sending the OTP request.
- Around line 262-307: Update handleOtpSubmit and handleResendOtp to support
injected wallets like handlePhoneSubmit: permit a null accessToken when
isInjectedWallet is true, still require a token otherwise, and include the
x-injected-wallet header in their fetch requests for injected-wallet flows while
preserving the existing Authorization header behavior.
---
Nitpick comments:
In `@app/components/WalletDetails.tsx`:
- Around line 537-579: Remove the redundant !isInjectedWallet condition from the
Convert button’s isBridgeUiVisible() guard in WalletDetails, since it is already
nested inside the outer !isInjectedWallet block. Separately verify that
injected-wallet bridge quoting and execution remain reachable through an
appropriate UI entry point outside this gated Fund/Transfer/Convert row,
including BridgeForm usage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fdfebd9c-01f4-4c1f-8fd7-52d80bff717d
📒 Files selected for processing (17)
app/api/aggregator.tsapp/components/KycModal.tsxapp/components/PhoneVerificationModal.tsxapp/components/ProfileView.tsxapp/components/WalletDetails.tsxapp/components/bridge/BridgeForm.tsxapp/context/BalanceContext.tsxapp/context/KYCContext.tsxapp/hooks/bridge.tsapp/hooks/useBridgeStatusTracker.tsapp/layout.tsxapp/lib/bridge.tsapp/lib/bundler/chains.tsapp/lib/privy-config.tsapp/mocks.tsapp/utils.tsmiddleware.ts
💤 Files with no reviewable changes (3)
- app/utils.ts
- app/layout.tsx
- app/lib/privy-config.ts
…let readiness - Enhanced KycModal and PhoneVerificationModal to ensure injected wallet address is only used when the wallet is ready, preventing premature KYC requests. - Updated PhoneVerificationModal to include injected wallet details in API calls, improving authentication handling. - Refactored WalletDetails and KYCContext to streamline injected wallet logic and improve code clarity. - Adjusted migrationChecklistNetworks documentation to reflect the exclusion of additional networks.
…allet support - Updated rendering logic in WalletDetails and WalletView to conditionally display fund and transfer buttons based on wallet type, enhancing user experience for both injected and non-injected wallets. - Moved the Convert modal outside the injected wallet condition to ensure accessibility for all wallet types. - Improved code clarity by adding comments to explain the rendering conditions for wallet actions.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
app/components/PhoneVerificationModal.tsx (1)
77-99: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winRequire a ready injected wallet for every OTP request.
resolveAccessToken()returnsnullfor any injected mode, while OTP verification and resend treat that as authenticated solely becauseisInjectedWalletis true. If the wallet is disconnected or still initializing, these requests send neitherAuthorizationnorx-injected-wallet. Gate all handlers oninjectedReady && injectedAddress, and include readiness in the callback dependencies. Move the injected-wallet branch before the Privyreadycheck to avoid misleading Privy-loading errors.Based on the supplied authentication contract, injected requests must authenticate through
x-injected-walletwhen no bearer token exists.Also applies to: 204-229, 260-260, 262-288, 314-336, 358-358
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/PhoneVerificationModal.tsx` around lines 77 - 99, Update resolveAccessToken and every OTP request handler to require injectedReady and injectedAddress when isInjectedWallet is true, returning early with the existing authentication error if the wallet is unavailable. Move the injected-wallet branch before the Privy ready check so injected flows do not show Privy-loading errors, include injectedReady and injectedAddress in callback dependencies, and ensure injected requests authenticate via x-injected-wallet when no bearer token is returned.app/components/WalletDetails.tsx (1)
14-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMake the bridge visibility change effective for injected wallets.
The Convert button at Line 565 is still nested under the outer
!isInjectedWalletblock at Line 537, so injected users never see it. Removing the inner restriction is a no-op. Move only Fund/Transfer/Earn behind the embedded-wallet guard, render Convert separately according to the intended embed policy, and either use or removeisEmbed.Based on the PR objective for injected bridge execution, injected users need an accessible Convert entry point.
Also applies to: 169-169, 565-579
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/components/WalletDetails.tsx` at line 14, Update the WalletDetails component so the Convert entry point is rendered independently of the outer !isInjectedWallet guard, allowing injected wallets to access bridge execution. Keep only Fund, Transfer, and Earn behind the embedded-wallet restriction, and use isEmbed in the resulting visibility logic or remove it if no longer needed.
🧹 Nitpick comments (1)
app/mocks.ts (1)
145-146: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd regression coverage for the network-list contract.
Please test that Scroll is absent from
networks, while Celo, Starknet, and Tron remain excluded frommigrationChecklistNetworks. These assertions will prevent future chain/configuration edits from silently changing the migration scope.Also applies to: 158-166
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/mocks.ts` around lines 145 - 146, Add regression tests for the network-list configuration in app/mocks.ts: assert that Scroll is absent from networks, and that Celo, Starknet, and Tron remain absent from migrationChecklistNetworks. Keep the assertions focused on preserving these existing migration-scope exclusions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@app/components/PhoneVerificationModal.tsx`:
- Around line 77-99: Update resolveAccessToken and every OTP request handler to
require injectedReady and injectedAddress when isInjectedWallet is true,
returning early with the existing authentication error if the wallet is
unavailable. Move the injected-wallet branch before the Privy ready check so
injected flows do not show Privy-loading errors, include injectedReady and
injectedAddress in callback dependencies, and ensure injected requests
authenticate via x-injected-wallet when no bearer token is returned.
In `@app/components/WalletDetails.tsx`:
- Line 14: Update the WalletDetails component so the Convert entry point is
rendered independently of the outer !isInjectedWallet guard, allowing injected
wallets to access bridge execution. Keep only Fund, Transfer, and Earn behind
the embedded-wallet restriction, and use isEmbed in the resulting visibility
logic or remove it if no longer needed.
---
Nitpick comments:
In `@app/mocks.ts`:
- Around line 145-146: Add regression tests for the network-list configuration
in app/mocks.ts: assert that Scroll is absent from networks, and that Celo,
Starknet, and Tron remain absent from migrationChecklistNetworks. Keep the
assertions focused on preserving these existing migration-scope exclusions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: df20c8e8-3954-4224-8aa4-a95a594b1038
📒 Files selected for processing (5)
app/components/KycModal.tsxapp/components/PhoneVerificationModal.tsxapp/components/WalletDetails.tsxapp/context/KYCContext.tsxapp/mocks.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- app/components/KycModal.tsx
- app/context/KYCContext.tsx
* fix(status): poll order status with injected-wallet auth and harden polling TransactionStatus was the only status surface still using Privy-only auth (getAccessToken), so in injected/embed mode the poll interval was never created and the UI stayed on pending/processing forever while the order settled server-side. Migrate to useApiAuth and pass the SIWE token to the order fetchers and the transaction update, and persist status rows for injected wallets too. Also harden the poll loop: - a missing token now skips the cycle instead of permanently clearing the interval (session-expired toast only after several consecutive misses) - the interval is created synchronously so an effect re-run can no longer orphan an in-flight bootstrap - envelope fallbacks surfacing "success"/"error" are rejected by a status whitelist instead of leaking into UI state and DB writes - status writes are pinned to the order's own DB row, so a later transfer overwriting the global currentTransactionId key can't redirect them Resolve chained forwarding terminally instead of spinning: injected mode skips immediately (leg 1 already paid the user's wallet), a not-yet-hydrated embedded wallet schedules a recheck, and an unsupported token resolves as skipped once the token list is loaded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * fix(preview): derive isOnramp from form mode, not walletAddress A Buy reaching the preview with an empty wallet address was misclassified as an offramp (isOnramp was derived from !!walletAddress), rendering the offramp row set with a blank recipient and "Account: undefined", and building offramp order params from empty bank fields. Derive the flow from the form's own swapMode/isSwapped instead, and never render "undefined" when an institution code has no display name. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * fix(kyc): identity-scoped phone flag and honest status staleness Two causes of repeated phone-verification prompts for already-verified users: 1. A wallet that inherited tier >= 2 through the ID triple holds no phone of its own, so the tier-2 phone gate fired on every swap — and re-verifying the same number is rejected as already in use by the sibling wallet, an unsatisfiable loop. /api/kyc/status now reports identityHasVerifiedPhone (any wallet in the identity pool with an OTP-verified phone), fail-soft to the per-wallet answer. 2. KYCContext stamped the staleness window even when the status fetch failed, serving the reset tier-0 snapshot for 30s — verified users transiently read as unverified. Only a successful fetch now counts as fresh, a forced refresh no longer piggybacks on an older in-flight fetch (post-OTP refresh must observe post-promotion data), and a new hasLoadedStatus flag lets gating UIs distinguish "unknown" from "unverified". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * fix(form): require a recipient before submit; don't skip it after phone OTP After phone verification handlePhoneVerified continued straight into handleSwap, which submitted with empty recipient fields — the recipient section only mounts once the user is verified, so it was never shown. The empty onramp wallet address passed validation (empty is "valid" for the field validator; the required rule lives on a field that never registered) and the preview rendered a blank recipient. handleSwap now requires a recipient for both directions before proceeding; the post-OTP continuation lands back on the form with the freshly unlocked recipient section and an informational prompt instead of auto-submitting. Also use the KYC identity's phone (identityHasVerifiedPhone) for the tier-2 gate, and load real status once before deciding between the phone modal and the limit modal when the snapshot hasn't loaded yet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * fix(profile): hide Privy email linking for injected wallets; honest link errors ProfileView offered "Connect my email" to injected (external) wallet users, who have no Privy session — Privy linkEmail always failed and the hardcoded error claimed the email was already linked. Gate the email block on !isInjectedWallet, matching SettingsDropdown and the mobile SettingsView (missed when injected support was retrofitted in #623). Both link handlers now read the Privy error code: closing the modal shows no error, linked_to_another_user keeps the "already linked" copy, and everything else gets a truthful generic message. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * feat(reconciler): reconcile stuck onramp orders server-side The reconcile-pending-orders cron was offramp-only, so an onramp row whose tab closed before settlement stayed pending forever even though the crypto was delivered — the same failure the offramp scan exists to fix, and one the client poll alone cannot cover. Scan onramp rows too, against /v2/sender/orders/{uuid} with the sender API key. Onramp terminal semantics match the app exactly: only settled completes an order, validated stays pending. The app's validUntil expiry inference is ported as well, so unfunded orders become expired and leave the scan set instead of being re-fetched on every run. Operational details: - offramp is capped at half the wall-clock budget so a backlog there can never starve the onramp scan; if it finishes early onramp gets the rest - a missing AGGREGATOR_SENDER_API_KEY_ID skips only the onramp scan and is reported as onrampSkippedReason, so offramp keeps reconciling - a 404 carrying an "api key not found" message is surfaced as an error rather than counted as "not indexed yet", which would silently no-op every onramp row - companion partial index mirrors the onramp scan predicate Also adds tests pinning the mapping semantics the Edge Function ports. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov * fix: address review findings on gating, status casing and reconciler reporting - handleSwap consumed the post-OTP continuation flag only inside the tier-2 branch, so verifying a phone below tier 2 with a recipient already filled left the flag set permanently — later waving an ungated wallet past the tier-2 phone gate. Consume it exactly once per invocation instead. - TransactionStatus accepted an order status case-insensitively but every comparison and the persisted value are lowercase, so a mixed-case terminal status would poll forever and store a non-canonical value. Canonicalize right after the guard. - KYCContext left a previous wallet's in-flight refresh attached across a wallet switch; the forced refresh chains onto it, so the new wallet's status waited on an unrelated untimed fetch. Detach it on reset — the run's ownership check already prevents cross-clobbering. - Reconciler: bound summary.details (non-reconcilable rows never leave the scan set and re-emitted an entry every run) and stop reporting the offramp half-budget cap as a run timeout; truncation is now per scan. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FVH15Dsqay4qpRfwTeyov --------- Co-authored-by: Claude <noreply@anthropic.com>
Description
useInjectedWalletcontext to both PhoneVerificationModal and ProfileView components to handle wallet address selection.This pull request adds comprehensive support for "injected wallet" authentication across the app, enabling users to authenticate and perform actions using an injected wallet (e.g., MetaMask) instead of only Privy-embedded wallets. The main changes involve updating API calls and UI logic to conditionally use an injected wallet's address and custom headers for authentication, rather than always requiring a Privy access token. This improves compatibility and user experience for users with browser wallets.
Injected Wallet Authentication Support:
saveTransaction,updateBridgeTransactionStatus,submitSmileIDData) inapp/api/aggregator.tsto accept anisInjectedWalletparameter and set the appropriate headers (x-injected-walletorAuthorization) based on wallet type. [1] [2] [3] [4]KycModal.tsxandPhoneVerificationModal.tsxto allow authentication with injected wallets by handling cases where the Privy access token is not required, and setting headers accordingly. [1] [2] [3] [4] [5] [6] [7] [8]UI & Context Integration:
ProfileView.tsx,WalletDetails.tsx,BridgeForm.tsx) to use the injected wallet context, ensuring the correct wallet address and authentication method are used throughout the UI and when making API calls. [1] [2] [3] [4] [5] [6] [7] [8] [9]Bridge and Transaction Handling:
Conditional UI Elements:
These changes collectively enable seamless operation for users with injected wallets, improving flexibility and compatibility across the app.
References
Testing
Checklist
mainBy submitting a PR, I agree to Paycrest's Contributor Code of Conduct and Contribution Guide.
Summary by CodeRabbit