Skip to content

[bug]: Trust Wallet reports INVALID domain for verified React Native iOS dapp over relay #578

Description

@ue

Description

Trust Wallet reports Invalid domain when connecting from our React Native iOS dapp through AppKit, even though the same Reown project and metadata domain are reported as Verified domain when connecting from the web dapp.

We do not want to enable SIWX solely to add an extra signature/authentication step during wallet connection. We need domain verification to work for a normal native WalletConnect session.

Environment

  • Platform: iOS physical device
  • Dapp framework: Expo SDK 54 / React Native 0.81.5
  • @reown/appkit-react-native: 2.0.2
  • @reown/appkit-wagmi-react-native: 2.0.2
  • @walletconnect/universal-provider: 2.21.10
  • Wallet: Trust Wallet (current iOS release)
  • iOS bundle identifier: com.dexly.trade
  • Metadata URL: https://dexly.trade
  • Universal redirect: https://dexly.trade/walletconnect
  • Native redirect: dexly://

Reown Dashboard configuration

The same Reown project ID is used by web and mobile.

Mobile Application IDs already include:

  • iOS: com.dexly.trade
  • Android: com.dexly.app

The web connection from https://dexly.trade is shown by Trust Wallet as Verified domain. The native iOS connection is shown as Invalid domain.

iOS universal-link configuration verified

The App ID has the Associated Domains capability enabled and the production provisioning profile contains the entitlement.

The production app includes:

{
  "associatedDomains": ["applinks:dexly.trade"]
}

Both AASA endpoints return HTTP 200 with Content-Type: application/json:

  • https://dexly.trade/.well-known/apple-app-site-association
  • https://dexly.trade/apple-app-site-association

AASA contains:

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "Q6NUJ5P8X6.com.dexly.trade",
        "paths": ["/walletconnect", "/walletconnect/*"]
      }
    ]
  }
}

The issue was reproduced after deleting the old app and installing a newly signed production/TestFlight build containing the entitlement.

AppKit configuration

createAppKit({
  projectId,
  networks,
  adapters: [wagmiAdapter],
  metadata: {
    name: "Dexly",
    description: "Dexly is an on-chain decentralized crypto trading platform",
    url: "https://dexly.trade",
    icons: ["https://dexly.trade/icons/icon-192.png"],
    redirect: {
      native: "dexly://",
      universal: "https://dexly.trade/walletconnect",
    },
  },
});

Steps to reproduce

  1. Install the signed iOS app on a physical device.
  2. Open AppKit and choose Trust Wallet.
  3. Trust Wallet opens with the WalletConnect session proposal.
  4. Observe Invalid domain in Trust Wallet.
  5. For comparison, connect from https://dexly.trade using the same Reown project; Trust Wallet displays Verified domain.

Expected behavior

Trust Wallet should display Verified domain, or at minimum not return validation: "INVALID", because:

  • the proposal metadata URL is the verified production domain;
  • the iOS bundle ID is allowlisted in the Reown project;
  • the App ID and provisioning profile include Associated Domains;
  • the AASA file and universal redirect are valid.

Actual behavior

The native connection consistently displays Invalid domain. Wallet connection itself can still proceed.

Relevant SDK behavior

While investigating the installed SDK sources, we found two potentially relevant paths:

  1. In @walletconnect/core, Verify.register() returns immediately outside the browser:
public register = async (params) => {
  if (!isBrowser() || this.isDevEnv) return;
  // browser attestation registration...
};

Therefore the React Native proposer does not create the same browser-origin attestation used by the verified web flow.

  1. In WalletConnectConnector.connect(), universalLink is used by the SIWX/authenticate branch, but the regular non-SIWX branch calls UniversalProvider.connect() without it:
if (isEVMOnly && SIWXUtil.getSIWX()) {
  session = await SIWXUtil.universalProviderAuthenticate({
    universalProvider: this.provider,
    chains,
    methods,
    universalLink,
  });
} else {
  session = await this.provider.connect({
    optionalNamespaces: namespaces,
  });
}

This appears to leave ordinary React Native sessions on relay verification without a browser attestation or Link Mode origin match. On the wallet side, Verify compares the resolved origin with new URL(metadata.url).origin, which may explain the INVALID result.

We also checked 2.0.6; the non-SIWX branch still does not use universalLink.

Questions

  1. How should a normal React Native dapp session be verified against its allowlisted iOS Bundle ID?
  2. Is INVALID expected for relay-based React Native proposers without SIWX?
  3. Is Link Mode/domain verification intentionally limited to SIWX in AppKit React Native?
  4. Can AppKit support verified native sessions without forcing an additional SIWX signature step?

A fix or supported configuration that preserves the normal one-step wallet connection UX would be appreciated.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions