Skip to content

Commit aa0bd2a

Browse files
authored
feat(analytics): emit dapp_name + dapp_url on Remote Connection Request Received/Failed (#29746)
## **Description** Wires the self-reported dapp identity from the V2 MWP connection request metadata (\`connReq.metadata.dapp.{name,url}\`) into both Remote Connection Request analytics events emitted by \`ConnectionRegistry.handleConnectDeeplink\`: - **\`Remote Connection Request Received\`** (success path, \`connection-registry.ts\` ~L254-L263): adds \`dapp_name\` and \`dapp_url\`. - **\`Remote Connection Request Failed\`** (catch path, \`connection-registry.ts\` ~L302-L313): adds \`dapp_name\` and \`dapp_url\` via optional chaining, so both gracefully degrade to \`undefined\` when the failure occurred before \`parseConnectionRequest\` returned (e.g. invalid URL, malformed payload). **Why:** these two events are the earliest wallet-side signal in the dapp-connect funnel — they fire *before* the permission UI. Today they carry \`transport_type\` / \`sdk_version\` / \`sdk_platform\` / \`remote_session_id\` but not the dapp identity, so we can't measure per-dapp drop-off between connection-received and \`Connect Request Started\` without reconstructing it via \`remote_session_id\` joins. The downstream \`Connect Request Started/Completed/Cancelled\` events already carry \`dapp_name\` and \`dapp_url\` — this closes the parity gap. **Pairs with:** [Consensys/segment-schema#552](Consensys/segment-schema#552), which declares both fields as optional \`string\` properties on the two YAMLs (\`remote-connection-request-received.yaml\` and \`remote-connection-request-failed.yaml\`). Per the standard schema-first ordering, only merge this mobile PR **after** schema#552 has merged and the tracking-plan sync has picked it up — otherwise Protocols will strip the new fields. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** Feature: Remote Connection Request analytics carry dapp identity Scenario: user opens an MWP deeplink that successfully establishes a connection Given a dapp generates a valid V2 MWP connect deeplink with \`metadata.dapp = { name: 'My Test DApp', url: 'https://test.dapp' }\` When the user opens the deeplink in MetaMask Mobile Then a \`Remote Connection Request Received\` Segment event fires with \`dapp_name = 'My Test DApp'\` and \`dapp_url = 'https://test.dapp'\` (in addition to the existing \`transport_type\`, \`sdk_version\`, \`sdk_platform\`, \`remote_session_id\`) Scenario: user opens an MWP deeplink that fails during the relay handshake Given a dapp generates a valid V2 MWP connect deeplink with \`metadata.dapp = { name: 'My Test DApp', url: 'https://test.dapp' }\` And the relay handshake fails (e.g. relay unreachable, pairing timeout) When the user opens the deeplink in MetaMask Mobile Then a \`Remote Connection Request Failed\` Segment event fires with \`dapp_name = 'My Test DApp'\`, \`dapp_url = 'https://test.dapp'\`, and \`failure_reason\` populated Scenario: user opens a malformed MWP deeplink that fails before metadata can be parsed Given a deeplink whose payload is not valid JSON or fails URL validation When the user opens the deeplink Then a \`Remote Connection Request Failed\` event still fires, with \`dapp_name\` and \`dapp_url\` absent (\`undefined\`) — and \`failure_reason\` populated **Local Segment debugging:** see \`docs/readme/metametrics-debugging.md\` (set \`SEGMENT_FLUSH_INTERVAL=1\`, opt into MetaMetrics, watch the Metro console for \`TRACK event saved\` lines). ## **Screenshots/Recordings** N/A — analytics-only change, no UI surface. ### **Before** \`Remote Connection Request Received\` and \`Remote Connection Request Failed\` carry \`transport_type\`, \`sdk_version\`, \`sdk_platform\`, \`remote_session_id\` but not the dapp identity. \`Failed\` additionally carries \`failure_reason\`. ### **After** Both events also carry \`dapp_name\` and \`dapp_url\`. On Failed, both gracefully degrade to \`undefined\` when the failure occurred before metadata could be parsed. ## **Pre-merge author checklist** - [x] 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). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] 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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk analytics-only change that adds two optional properties to existing MetaMetrics events; main risk is schema/consumer mismatch if tracking plan isn’t updated. > > **Overview** > **Analytics parity improvement:** `ConnectionRegistry.handleConnectDeeplink` now includes the self-reported dapp identity (`dapp_name`, `dapp_url`) in both `REMOTE_CONNECTION_REQUEST_RECEIVED` and `REMOTE_CONNECTION_REQUEST_FAILED` events (using optional chaining on the failure path). > > **Tests updated:** `connection-registry.test.ts` assertions were extended to expect these new properties on the tracked “received” and “failed” events. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e4206b8. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent ee27c28 commit aa0bd2a

2 files changed

Lines changed: 10 additions & 0 deletions

File tree

app/core/SDKConnectV2/services/connection-registry.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ describe('ConnectionRegistry', () => {
442442
transport_type: TransportType.MWP,
443443
sdk_version: '2.0.0',
444444
sdk_platform: 'JavaScript',
445+
dapp_name: 'Test DApp',
446+
dapp_url: 'https://test.dapp',
445447
}),
446448
);
447449
});
@@ -583,6 +585,10 @@ describe('ConnectionRegistry', () => {
583585
expect.objectContaining({
584586
remote_session_id: mockConnectionRequest.sessionRequest.id,
585587
transport_type: TransportType.MWP,
588+
sdk_version: '2.0.0',
589+
sdk_platform: 'JavaScript',
590+
dapp_name: 'Test DApp',
591+
dapp_url: 'https://test.dapp',
586592
failure_reason: 'Connection failed',
587593
}),
588594
);

app/core/SDKConnectV2/services/connection-registry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ export class ConnectionRegistry {
258258
transport_type: TransportType.MWP,
259259
sdk_version: connReq.metadata.sdk.version,
260260
sdk_platform: connReq.metadata.sdk.platform,
261+
dapp_name: connReq.metadata.dapp.name,
262+
dapp_url: connReq.metadata.dapp.url,
261263
});
262264

263265
// Defense-in-depth: block connections whose self-reported dapp metadata
@@ -305,6 +307,8 @@ export class ConnectionRegistry {
305307
transport_type: TransportType.MWP,
306308
sdk_version: connReq?.metadata?.sdk?.version,
307309
sdk_platform: connReq?.metadata?.sdk?.platform,
310+
dapp_name: connReq?.metadata?.dapp?.name,
311+
dapp_url: connReq?.metadata?.dapp?.url,
308312
failure_reason: error instanceof Error ? error.message : String(error),
309313
});
310314

0 commit comments

Comments
 (0)