Skip to main content

Mobile Linking

Note

This feature is only relevant to native platforms.

Usage

Mobile Linking allows your wallet to automatically redirect back to the Dapp allowing for less user interactions and hence a better UX for your users.

Establishing Communication Between Mobile Wallets and Apps

When integrating a wallet with a mobile application, it's essential to understand how they communicate. The process involves two main steps:

  1. QR Code Handshake: The mobile app (Dapp) generates a unique URI (Uniform Resource Identifier) and displays it as a QR code. This URI acts like a secret handshake. When the user scans the QR code using their wallet app, they establish a connection. It's like saying, "Hey, let's chat!"
  2. Deep Links and Universal Links: The URI from the QR code allows the wallet app to create a deep link or universal link. These links work on both Android and iOS. They enable seamless communication between the wallet and the app.
tip

Developers should prefer Deep Linking over Universal Linking.

Universal Linking may redirect the user to a browser, which might not provide the intended user experience. Deep Linking ensures the user is taken directly to the app.

Key Behavior to Address

In some scenarios, wallets use redirect metadata provided in session proposals to open applications. This can cause unintended behavior, such as:

Redirecting to the wrong app when multiple apps share the same redirect metadata (e.g., a desktop and mobile version of the same Dapp). Opening an unrelated application if a QR code is scanned on a different device than where the wallet is installed.

To avoid this behavior, wallets should:

  • Restrict Redirect Metadata to Deep Link Use Cases: Redirect metadata should only be used when the session proposal is initiated through a deep link. QR code scans should not trigger app redirects using session proposal metadata.

The connection and sign request flows are similar across platforms.

Connection Flow

  • Dapp Prompts User: The Dapp asks the user to connect.
  • User Chooses Wallet: The user selects a wallet from a list of compatible wallets.
  • Redirect to Wallet: The user is redirected to their chosen wallet.
  • Wallet Approval: The wallet prompts the user to approve or reject the session (similar to granting permission).
  • Return to Dapp:
    • Manual Return: The wallet asks the user to manually return to the Dapp.
    • Automatic Return: Alternatively, the wallet automatically takes the user back to the Dapp.
  • User Reunites with Dapp: After all the interactions, the user ends up back in the Dapp.
Mobile Linking Connect FlowMobile Linking Connect Flow

Sign Request Flow

When the Dapp needs the user to sign something (like a transaction), a similar pattern occurs:

  • Automatic Redirect: The Dapp automatically sends the user to their previously chosen wallet.
  • Approval Prompt: The wallet asks the user to approve or reject the request.
  • Return to Dapp:
    • Manual Return: The wallet asks the user to manually return to the Dapp.
    • Automatic Return: Alternatively, the wallet automatically takes the user back to the Dapp.
  • User Reconnects: Eventually, the user returns to the Dapp.
Mobile Linking Sign FlowMobile Linking Sign Flow

Platform preparations

In order for Dapps to be able to trigger your wallet for a connection or sign request using deep links you first need to add your own wallet to the Explorer by login to your Reown Cloud account, declare a deep link and define an <intent-filter> in your wallet's Manifest.xml with the same deep link added in Explorer:

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplewallet" /> <!-- your own custom scheme -->
</intent-filter>
tip

Dapps developers must do the same for their own custom schemes if they want the wallet to be able to navigate back after a session approval or a sign request response

How to test

Before submitting your project to the Cloud Explorer you can test mobile linking in our sample Dapp:

  1. On your mobile device, visit the appropriate link:
  1. Click the "Custom Wallet" button and fill in the form with your wallet information. The website will reload and your wallet will be stored locally.
  2. Click the "Connect Wallet" button and choose your mobile wallet. It should automatically open and redirect to your wallet.

Learn more about mobile linking in the Best Practices section.

Integration

Wallet Support

Disclaimer: The below solution is designed for the communication between native Android Dapps and native Android wallets. In the case of mobile browser Dapps and native Android wallets communication, we recommend moving wallets into the background after both approving and rejecting sessions or approving and rejecting requests to persist smooth deep-link UX.

In order to add support for mobile linking within your wallet and receive session proposals, register following deep link in your mobile wallet using intent filters in your Activity/Fragment or deepLink tag in your navigation graph.

To support universal native modal and WalletConnectModal register: wc://

Deep link example: examplewallet://wc?uri={pairingUri}

To receive signing request in your Wallet, you'll need to initialize Kotlin SDK with the Redirect object where you pass a deep link that redirects to your wallet when it comes to receiving signing request from Dapp.

val redirect = "examplewallet://request" //should be unique for your wallet

val appMetaData = Core.Model.AppMetaData(
name = "Wallet Name",
description = "Wallet Description",
url = "Wallet Url",
icons = listOfIconUrlStrings,
redirect = redirect
)

CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = application, metaData = appMetaData)

val init = Wallet.Params.Init(coreClient = CoreClient)
WalletKit.initialize(init)

Redirect when responding to a session proposal:

 WalletKit.approveSession(approveProposal,
onSuccess = {
// trigger deeplink: proposal.redirect
}
)

Redirect when responding to a request:

val redirect = WalletKit.getActiveSessionByTopic(sessionRequest.topic)?.redirect?.toUri()
WalletKit.respondSessionRequest(response,
onSuccess = {
// trigger deeplink: redirect
}
)

Heads-up: To make this flow working well, Wallet must register one of its Android components with the same deep link that it initialized with.

To check the flow implementation described above have a look on our sample wallet: https://github.com/WalletConnect/WalletConnectKotlinV2/tree/master/sample/wallet

Dapp Support

To send session proposals to mobile wallet user the pairing URI as deep link that triggers a wallet to open and consume pairing URI

requireActivity().startActivity(Intent(Intent.ACTION_VIEW, deeplinkPairingUri.toUri()))

In order to add support for mobile linking within your Dapp and receive signing request responses from wallet, you'll need to initialize Kotlin SDK with the Redirect object where you pass a deep link that redirects to your Dapp when it comes to receiving signing request responses from wallet.

val redirect = "kotlin-dapp-wc://request" //should be unique for your Dapp

val appMetaData = Core.Model.AppMetaData(
name = "Dapp Name",
description = "Dapp Description",
url = "Dapp URL",
icons = listOfIconUrlStrings,
redirect = redirect
)

CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = application, metaData = appMetaData)

val init = Sign.Params.Init(core = CoreClient)
SignClient.initialize(init)

Heads-up: To make this flow working well, Dapp must register one of its Android components with the same deep link that it initialized with.

To check the flow implementation described above have a look on our Sample Dapp: https://github.com/WalletConnect/WalletConnectKotlinV2/tree/master/sample/dapp

References