Skip to content

feat: qr login flow#30442

Open
tylerc-consensys wants to merge 22 commits into
mainfrom
tylerc/agentic-qr-login-flow
Open

feat: qr login flow#30442
tylerc-consensys wants to merge 22 commits into
mainfrom
tylerc/agentic-qr-login-flow

Conversation

@tylerc-consensys

@tylerc-consensys tylerc-consensys commented May 20, 2026

Copy link
Copy Markdown
Contributor

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

Feature: Agentic CLI QR login

  Scenario: user completes QR login from MetaMask Mobile
    Given the Agentic CLI displays a QR login request
    And MetaMask Mobile is installed and unlocked

    When the user opens the QR login deeplink in MetaMask Mobile
    And the user enters the displayed OTP in the CLI
    And the dashboard auth WebView returns a CLI token to mobile
    Then mobile sends the CLI token back over the SDK connection
    And the CLI login completes successfully

Screenshots/Recordings

Before

N/A

After

To be added before marking ready for review.

Pre-merge author checklist

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 to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

Validation

Focused Jest suites printed PASS locally:

  • app/components/Views/AgenticCliDashboardWebview/AgenticCliDashboardWebviewService.test.ts
  • app/core/SDKConnectV2/types/connection-request.test.ts
  • app/core/SDKConnectV2/adapters/host-application-adapter.test.ts
  • app/core/SDKConnectV2/services/connection-registry.test.ts

The 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-cli run 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 / hideOtpCode on the host adapter, display_otp / connected handling on Connection, sendAuthToken, and registry branching via AgenticCliQrLoginService (unlock wait, no persistent session save for this flow). Navigation registers SDKConnectV2Otp and AgenticCliDashboardConfirmation screens plus new copy in en.json. Relay URL picks dev vs prod from METAMASK_ENVIRONMENT.

Reviewed by Cursor Bugbot for commit f6c70a7. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

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.

@metamaskbotv2 metamaskbotv2 Bot added the team-onboarding Onboarding team label May 20, 2026
@github-actions github-actions Bot added pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. size-XL labels May 20, 2026
@tylerc-consensys tylerc-consensys marked this pull request as ready for review May 21, 2026 09:47
@tylerc-consensys tylerc-consensys requested review from a team as code owners May 21, 2026 09:47
Comment thread app/core/SDKConnectV2/adapters/host-application-adapter.ts Outdated
Comment thread app/core/SDKConnectV2/services/connection-registry.ts
Comment thread app/core/SDKConnectV2/services/connection-registry.ts Outdated
Comment thread app/core/SDKConnectV2/services/connection-registry.ts Outdated
@ieow

ieow commented May 25, 2026

Copy link
Copy Markdown
Contributor

Not sure if we allowed to modify SDKConnectV2
if possible do outside of SDKConnectV2

Comment thread app/components/Views/AgenticCliDashboardWebview/index.tsx
@tylerc-consensys tylerc-consensys force-pushed the tylerc/agentic-qr-login-flow branch from 433728b to 9d3db7f Compare May 25, 2026 09:39
@tylerc-consensys tylerc-consensys force-pushed the tylerc/agentic-qr-login-flow branch from 9d3db7f to 4e4964a Compare May 25, 2026 09:43
@tylerc-consensys tylerc-consensys force-pushed the tylerc/agentic-qr-login-flow branch 2 times, most recently from 14f25ce to 2297a60 Compare May 25, 2026 10:52

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ 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.

Comment thread app/core/SDKConnectV2/index.ts Outdated
@tylerc-consensys tylerc-consensys force-pushed the tylerc/agentic-qr-login-flow branch from 2297a60 to f6c70a7 Compare May 26, 2026 02:54
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.54711% with 64 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.27%. Comparing base (65cbeec) to head (f6c70a7).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
...ponents/Views/AgenticCliDashboardWebview/index.tsx 69.51% 16 Missing and 9 partials ⚠️
app/core/AgenticCli/AgenticCliQrLoginService.ts 82.08% 8 Missing and 4 partials ⚠️
...hboardWebview/AgenticCliDashboardWebviewService.ts 89.33% 0 Missing and 8 partials ⚠️
.../core/SDKConnectV2/services/connection-registry.ts 82.35% 5 Missing and 1 partial ⚠️
app/core/SDKConnectV2/services/connection.ts 50.00% 6 Missing ⚠️
.../SDK/SDKConnectV2OtpModal/SDKConnectV2OtpModal.tsx 89.18% 1 Missing and 3 partials ⚠️
app/core/SDKConnectV2/types/connection-request.ts 81.81% 1 Missing and 1 partial ⚠️
app/core/SDKConnectV2/index.ts 50.00% 0 Missing and 1 partial ⚠️
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.
📢 Have feedback on the report? Share it here.

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

@grvgoel81 grvgoel81 removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeWalletPlatform, SmokeNetworkExpansion, SmokeMultiChainAPI, SmokeNetworkAbstractions, SmokeBrowser, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: high
  • AI Confidence: 78%
click to see 🤖 AI reasoning details

E2E Test Selection:
This PR introduces a new Agentic CLI QR Login feature with significant changes to core infrastructure:

  1. Navigation infrastructure changes (App.tsx, Routes.ts, NavigationService/types.ts): New routes added to the root navigation stack (SDK_CONNECT_V2_OTP, AGENTIC_CLI_DASHBOARD_WEBVIEW). These changes affect the global navigation stack used by all tests. Any test that navigates through the app could be impacted if the navigation stack is broken.

  2. SDKConnectV2 core changes (connection-registry.ts, connection.ts, host-application-adapter.ts): The connection registry now handles agentic CLI connections with new stages, cleanup logic, and session request modifications. The autodismiss time for connection loading notifications changed from 10000ms to 15000ms. These changes affect the core dApp connection flow used by SmokeWalletPlatform (EVM provider events), SmokeNetworkExpansion (multi-chain connections), and SmokeMultiChainAPI (CAIP-25 sessions).

  3. New WebView component (AgenticCliDashboardWebview): A new WebView-based screen that uses similar patterns to the existing browser. SmokeBrowser tests validate WebView behavior and navigation.

  4. New OTP Modal (SDKConnectV2OtpModal): A new BottomSheet modal registered in the navigation stack. BottomSheet modals are shared infrastructure used across many test flows.

  5. SDKConnectV2 relay URL change: The relay URL now switches between dev/prod based on devApiEnv(), which could affect connection behavior in test environments.

Tag selection rationale:

  • SmokeWalletPlatform: EVM provider events test uses dApp connections via SDKConnectV2 infrastructure; navigation changes affect wallet platform tests
  • SmokeNetworkExpansion: Multiple provider connections test uses SDKConnectV2 connection registry; Solana connection flows go through the same connection infrastructure
  • SmokeMultiChainAPI: CAIP-25 session management uses the connection registry that was modified
  • SmokeNetworkAbstractions: Chain permissions and dApp connection flows use the modified connection infrastructure
  • SmokeBrowser: New WebView component uses similar patterns; browser navigation tests validate WebView behavior
  • SmokeConfirmations: dApp transaction flows depend on the connection infrastructure that was modified

Performance Test Selection:
The changes are primarily additive (new Agentic CLI feature) and don't affect core performance-sensitive paths like account list rendering, onboarding flows, login, swaps, app launch, or asset loading. The SDKConnectV2 changes are in connection handling logic (not UI rendering), and the new WebView/OTP modal components are only shown during the new CLI connection flow. No performance-sensitive components or data loading paths were modified.

View GitHub Actions results

@sonarqubecloud

Copy link
Copy Markdown

@ieow ieow mentioned this pull request Jun 2, 2026
10 tasks
pull Bot pushed a commit to Reality2byte/metamask-mobile that referenced this pull request Jun 4, 2026
<!--
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants