feat: qr login flow#30442
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
|
Not sure if we allowed to modify SDKConnectV2 |
433728b to
9d3db7f
Compare
9d3db7f to
4e4964a
Compare
14f25ce to
2297a60
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2297a60. Configure here.
2297a60 to
f6c70a7
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #30442 +/- ##
==========================================
- Coverage 82.28% 82.27% -0.01%
==========================================
Files 5522 5531 +9
Lines 148790 149276 +486
Branches 34280 34387 +107
==========================================
+ Hits 122430 122824 +394
- Misses 18030 18071 +41
- Partials 8330 8381 +51 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
Tag selection rationale:
Performance Test Selection: |
|
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Adds end-to-end support for linking **MetaMask Agent CLI** via QR scan on mobile, and refactors that flow out of generic SDK Connect V2 handling into a dedicated `AgenticCli` module. **Why:** Agentic CLI connections differ from standard dApp MWP sessions—they are short-lived, use an OTP pairing step, require dashboard project selection, and must return an auth token to the CLI rather than persisting a wallet session in the connection registry. This pr is based on the pr MetaMask#30442 done by @tylerc-consensys **What changed:** 1. **`app/core/AgenticCli/`** — New module that owns agentic CLI deeplink parsing (`connectionType: { name: 'agentic-cli' }`), MWP connection lifecycle (untrusted mode, no persistent save), OTP UI hooks, loading toasts, and the QR login pipeline: - Wait for keyring unlock - Fetch Hydra bearer token → exchange for dashboard access token via `/api/v2/mm-qr-login/token` - Open allowlisted dashboard WebView for project approval - Send `auth-token` message back to the CLI over MWP - Clean up the temporary connection 2. **Dashboard WebView** (`AgenticCliDashboardWebview`) — Modal screen + service with build-type origin allowlists, auth token in URL hash + `Authorization` header, strict `mm-agentic-cli` postMessage parsing, pending-request resolve/reject with 5-minute timeout, and token redaction in logs. QR-supplied `dashboardUrl` / `dashboardAuthUrl` overrides are ignored in favor of configured endpoints. 3. **OTP modal** (`SDKConnectV2OtpModal`) — Bottom sheet shown during MWP pairing with formatted OTP, countdown (1-minute display cap), and auto-dismiss on connect. 4. **SDK Connect V2 refactor** — `ConnectionRegistry` routes agentic deeplinks to the new handler; MWP payload parsing and analytics move to shared utils (`parseMwpConnectDeeplink`, `trackMwpEvent`); relay URL respects dev vs prod; failed connects use `cleanupConnection` instead of always calling `disconnect`. ## **Changelog** CHANGELOG entry: Added QR login flow for MetaMask Agent CLI, including OTP pairing and dashboard project selection in a WebView. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: MetaMask Agent CLI QR login Scenario: user links CLI via QR scan (dev build) Given the app is unlocked on a dev build (main_dev / flask_dev) And MetaMask Agent CLI is running and displays a QR code When the user scans the QR code with MetaMask Mobile Then an OTP bottom sheet appears with a pairing code And a "Connecting to dApp" loading toast is shown When the user enters the OTP in the CLI and the MWP session connects Then the OTP sheet dismisses And a "Select project" dashboard WebView modal opens (test-dashboard host) When the user approves a project on the dashboard Then the WebView closes And a "MetaMask Agent CLI link successful" notification appears And the CLI receives the auth token and can continue Scenario: user closes dashboard WebView before approving Given the dashboard WebView is open after OTP pairing When the user taps Close or navigates back Then the connection fails gracefully with "Dashboard approval closed." And the temporary MWP connection is cleaned up Scenario: user on prod build uses prod dashboard Given the app is a prod build (main_prod / flask_prod) When the user completes the agentic CLI QR flow Then the dashboard WebView loads the prod dashboard origin (dashboard.w3a.io / dashboard.web3auth.io) And test-dashboard / dev-dashboard hosts are not allowlisted ``` **Build-type dashboard URLs** | Build type | Dashboard WebView URL | |---|---| | `*_dev` | `https://test-dashboard.web3auth.io/agentic/login` | | `*_uat` | `https://dev-dashboard.web3auth.io/agentic/login` | | `*_prod` | `https://dashboard.w3a.io/agentic/login` | ## **Screenshots/Recordings** ### **Before** <!-- N/A — new flow --> ### **After** <!-- OTP modal → dashboard WebView → success notification --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. **Test coverage added/updated** - `AgenticCliMwpConnectionService.test.ts` — deeplink handling, event wiring, error/cleanup paths - `AgenticCliQrLoginService.test.ts` — Hydra token → dashboard token → WebView → send auth token - `AgenticCliDashboardWebviewService.test.ts` — origin allowlists, URL building, postMessage parsing, pending requests - `AgenticCliDashboardWebview/index.test.tsx` — WebView rendering, message handling, external link policy - `SDKConnectV2OtpModal.test.tsx` — OTP display and countdown - `connection-registry.test.ts` — agentic deeplink routing delegation **Security notes for reviewers** - Dashboard WebView uses build-type origin allowlists; external top-frame navigations open in the system browser. - postMessage events require `source: "mm-agentic-cli"` and canonical result types (`approved`, `rejected`, `close`, `error`). - Auth tokens are redacted from error logs; QR-provided dashboard URLs are not trusted. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **High Risk** > Touches authentication (Hydra bearer, dashboard tokens), WebView origin allowlists and postMessage handling, and MWP deeplink routing—security-sensitive paths with a large new surface area. > > **Overview** > Adds **MetaMask Agent CLI** QR linking as a dedicated flow separate from normal SDK Connect V2 sessions: agentic MWP deeplinks (`connectionType: agentic-cli`) are handled in a new `app/core/AgenticCli` module instead of persisting through the generic connection registry. > > The flow shows an **OTP bottom sheet** during pairing, runs a short **untrusted** MWP connect, then **Hydra → dashboard token → allowlisted dashboard WebView** for project approval, and returns an **`auth-token`** to the CLI before tearing down the temporary connection. QR-supplied dashboard URLs are ignored in favor of build-type config. > > New UI includes **`SDKConnectV2OtpModal`**, **`AgenticCliDashboardWebview`** (origin allowlists, `mm-agentic-cli` postMessage contract, pending promise + timeout), and navigation routes. **SDK Connect V2** now delegates agentic deeplinks, extracts **`parseMwpConnectPayload`** / **`trackMwpEvent`**, and uses **`cleanupConnection`** on failed connects. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 53522dd. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: hung <hung@tor.us> Co-authored-by: Tyler Chong <tyler.chong@consensys.net> Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net> Co-authored-by: Gaurav Goel <grvgoel19@gmail.com>




Description
Adds the mobile QR login flow for Agentic CLI. The flow receives a Mobile Wallet Protocol connection request, displays the OTP in MetaMask Mobile, exchanges the mobile bearer token for a dashboard auth token, opens the dashboard auth WebView, receives the CLI token through the WebView bridge, and sends it back through the SDK connection.
This PR is opened as a draft while final production hardening and cross-platform verification continue.
Changelog
CHANGELOG entry: null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Before
N/A
After
To be added before marking ready for review.
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Validation
Focused Jest suites printed PASS locally:
app/components/Views/AgenticCliDashboardWebview/AgenticCliDashboardWebviewService.test.tsapp/core/SDKConnectV2/types/connection-request.test.tsapp/core/SDKConnectV2/adapters/host-application-adapter.test.tsapp/core/SDKConnectV2/services/connection-registry.test.tsThe Jest parent process hung after success output and was stopped manually.
Note
High Risk
Touches authentication (bearer/Hydra exchange), WebView origin allowlists and postMessage parsing, and a new token path back to the CLI—security-sensitive with broad test coverage but still draft/hardening per PR notes.
Overview
Adds Agentic CLI QR login end-to-end in mobile: MWP deeplinks with
connectionType: agentic-clirun an untrusted handshake, show an OTP bottom sheet, then exchange the wallet bearer token for a dashboard token and open a hardened dashboard WebView to collect a CLI auth token and return it over the SDK connection.SDK Connect V2 gains
showOtpCode/hideOtpCodeon the host adapter,display_otp/connectedhandling onConnection,sendAuthToken, and registry branching viaAgenticCliQrLoginService(unlock wait, no persistent session save for this flow). Navigation registersSDKConnectV2OtpandAgenticCliDashboardConfirmationscreens plus new copy inen.json. Relay URL picks dev vs prod fromMETAMASK_ENVIRONMENT.Reviewed by Cursor Bugbot for commit f6c70a7. Bugbot is set up for automated code reviews on this repo. Configure here.