Web3 applications (decentralized apps, wallets, DeFi protocols, NFT marketplaces) have unique deep linking challenges. Users navigate between wallet apps, dApps, and web interfaces constantly. A swap on a DeFi protocol requires opening a wallet app to sign a transaction, then returning to the dApp. An NFT purchase links from a marketplace to a wallet for payment, then back to the marketplace for confirmation.
This guide covers how deep linking works in the Web3 ecosystem. For deep linking in super apps, see deep linking for super apps. For crypto-specific deep linking patterns, see deep links for cryptocurrency apps.
The Web3 Deep Linking Landscape
Key Interactions That Need Deep Links
| Flow | From | To | Context Needed |
|---|---|---|---|
| Wallet connect | dApp (web/app) | Wallet app | Session, chain, dApp metadata |
| Transaction signing | dApp | Wallet | Transaction data, callback URL |
| Token viewing | Marketplace | Wallet | Token ID, contract address |
| dApp browsing | Wallet browser | dApp | Wallet address, chain |
| Payment request | Merchant app | Wallet | Amount, recipient, memo |
WalletConnect Protocol
WalletConnect is the most widely used standard for connecting dApps to wallet apps. It uses deep links as the transport:
wc:abc123@2?relay-protocol=irn&symKey=xyz
This URI launches the wallet app, which establishes an encrypted session with the dApp. The deep link carries the session parameters.
// dApp: initiate WalletConnect session
import { Core } from '@walletconnect/core';
import { Web3Wallet } from '@walletconnect/web3wallet';
const core = new Core({ projectId: 'YOUR_PROJECT_ID' });
// Generate connection URI (this is the deep link)
const { uri, approval } = await signClient.connect({
requiredNamespaces: {
eip155: {
methods: ['eth_sendTransaction', 'personal_sign'],
chains: ['eip155:1'],
events: ['accountsChanged']
}
}
});
// Open wallet app with the URI
const walletDeepLink = `https://metamask.app.link/wc?uri=${encodeURIComponent(uri)}`;
window.location.href = walletDeepLink;
Wallet App Deep Links
MetaMask
MetaMask supports deep links for common actions:
// Open MetaMask and connect
metamask://wc?uri=wc:abc123@2...
// Open a specific dApp in MetaMask's browser
https://metamask.app.link/dapp/uniswap.org
// Send transaction
metamask://send/0xRecipientAddress?value=1e18
Universal Link Pattern for Wallets
Most wallets use Universal Links for cross-platform compatibility:
https://metamask.app.link/... (MetaMask)
https://link.trustwallet.com/... (Trust Wallet)
https://phantom.app/ul/... (Phantom, Solana)
https://rainbow.me/... (Rainbow)
dApp Deep Link Patterns
NFT Marketplace Links
Link directly to specific tokens, collections, or profiles:
/assets/{chain}/{contract}/{tokenId} → specific NFT
/collection/{slug} → collection page
/profile/{address} → user profile
/activity/{address} → transaction history
DeFi Protocol Links
Link to specific pools, swaps, or positions:
/swap?inputCurrency=ETH&outputCurrency=0xUSDC&chain=1
/pool/{poolAddress}
/positions/{positionId}
/farm/{farmId}
Web Fallback for Web3 Deep Links
Web3 deep link pages should work without a wallet connected:
<!-- NFT detail page - works for everyone -->
<div class="nft-detail">
<img src="/images/nft-preview.jpg" alt="NFT #1234">
<h1>CryptoArt #1234</h1>
<p>Current price: 0.5 ETH</p>
<!-- For users with wallet -->
<button id="buyBtn" onclick="connectAndBuy()">Buy Now</button>
<!-- For users without wallet -->
<div id="noWallet" style="display:none;">
<p>You need a wallet to purchase this NFT.</p>
<a href="https://metamask.io/download/">Get MetaMask</a>
</div>
</div>
<script>
if (typeof window.ethereum === 'undefined') {
document.getElementById('buyBtn').style.display = 'none';
document.getElementById('noWallet').style.display = 'block';
}
</script>
Transaction Deep Links
EIP-681: Payment Request URLs
EIP-681 defines a standard URL format for Ethereum payment requests:
ethereum:0xRecipientAddress@1/transfer?
address=0xTokenContract&
uint256=1000000&
value=0
Components:
ethereum:scheme0xRecipientAddresstarget address@1chain ID (Ethereum mainnet)/transferfunction name- Query parameters for function arguments
Cross-Chain Deep Links
Different blockchains use different URL schemes:
| Chain | Deep Link Format |
|---|---|
| Ethereum | ethereum:0xAddress?value=1e18 |
| Bitcoin | bitcoin:address?amount=0.001 |
| Solana | solana:address?amount=1&spl-token=USDC |
| Polygon | ethereum:0xAddress@137?value=1e18 |
Handling Transaction Deep Links in Your App
// iOS wallet app: handle EIP-681 payment request
func handlePaymentURL(_ url: URL) {
guard url.scheme == "ethereum" else { return }
let components = url.pathComponents
let address = url.host // recipient address
let chainId = url.port // chain ID (e.g., 1 for mainnet)
let params = url.queryParameters
let value = params["value"] // ETH amount in wei
let gasLimit = params["gasLimit"]
// Show transaction confirmation screen
showTransactionConfirmation(
to: address,
value: value,
chain: chainId ?? 1,
gasLimit: gasLimit
)
}
Token-Gated Content via Deep Links
The Flow
Deep links can gate content based on token ownership:
User taps deep link → https://yourapp.com/exclusive/holders-only
→ Web page checks wallet connection
→ Wallet connected and owns required token → show content
→ Wallet not connected → prompt to connect
→ Connected but does not own token → show "token required" message
Implementation
async function checkTokenGate(url) {
const path = new URL(url).pathname;
const gateConfig = await getGateConfig(path); // which token is required
if (!gateConfig) {
// No gate on this content
showContent(path);
return;
}
const wallet = await connectWallet();
if (!wallet) {
showConnectPrompt(url);
return;
}
const ownsToken = await checkTokenOwnership(
wallet.address,
gateConfig.contractAddress,
gateConfig.chainId,
gateConfig.minBalance
);
if (ownsToken) {
showContent(path);
} else {
showTokenRequired(gateConfig);
}
}
Tolinku for Web3 Deep Links
Tolinku handles URL routing for Web3 applications. Configure routes for your dApp pages in the Tolinku dashboard, and Tolinku routes users to your mobile app (for native dApp experiences) or web fallback. The web fallback can include wallet connection prompts and transaction initiation.
For more on industry trends, see the future of mobile deep linking.
Get deep linking tips in your inbox
One email per week. No spam.