WalletConnect Integration in Mobile Crypto Applications
WalletConnect is an open protocol for connecting mobile wallets with DApps. Users scan a QR code or follow a deep link to establish a secure, encrypted connection between their wallet and a web application without storing private keys on the DApp server.
WalletConnect v2: What Changed
WalletConnect v1 was deprecated in 2023. v2 (now called Web3Modal SDK / AppKit) uses a centralized relay server but maintains end-to-end cryptography. Key differences from v1:
- Multi-chain support in a single session
- Project ID required from
cloud.walletconnect.com - Sign API v2 protocol instead of Legacy API
- Namespace-based requests:
eip155:1for Ethereum mainnet,solana:mainnetfor Solana
iOS Implementation (Swift)
The official SDK is WalletConnectSwiftV2. Install via SPM:
// Package.swift or Xcode Package Manager
.package(url: "https://github.com/WalletConnect/WalletConnectSwift-v2", from: "1.9.0")
Initialization:
Networking.configure(
groupIdentifier: "group.com.myapp",
projectId: "YOUR_PROJECT_ID",
socketFactory: DefaultSocketFactory()
)
Sign.configure(crypto: DefaultCryptoProvider())
Handle incoming session proposals:
Sign.instance.sessionProposalPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] proposal in
// Show user the requested methods and networks
self?.showApprovalAlert(proposal: proposal)
}
.store(in: &cancellables)
On approval, create a namespace object with supported methods (eth_sendTransaction, personal_sign, eth_signTypedData) and call Sign.instance.approve(proposalId:namespaces:).
Handling Signature Requests
After session establishment, the DApp sends requests. The most common is personal_sign:
Sign.instance.sessionRequestPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] request in
switch request.method {
case "personal_sign":
let params = try? request.params.get([String].self)
let message = params?[0] ?? ""
// Show user what is being signed
self?.showSignRequest(message: message, request: request)
case "eth_sendTransaction":
// Display transaction details
break
default:
// Reject unknown methods
Task { try await Sign.instance.respond(
topic: request.topic,
requestId: request.id,
response: .error(.methodNotFound)
)}
}
}
.store(in: &cancellables)
Important: never sign automatically—every signature request requires explicit user confirmation.
Deep Links for Mobile Use
WalletConnect supports two modes: QR codes (for desktop DApps) and Universal Links / Custom URL Schemes (for mobile DApps). For wallet-to-wallet connections, users tap a button in the mobile browser DApp, which redirects them through a deep link with wc:// URI.
Handle URIs in SceneDelegate / @main App:
.onOpenURL { url in
if url.scheme == "wc" {
Task { try await Sign.instance.pair(uri: WalletConnectURI(string: url.absoluteString)!) }
}
}
Android
For Android, use WalletConnect Android Core (com.walletconnect:android-core) plus the sign library. The API is similar but event-driven through CoreClient.Wallet.setWalletDelegate(delegate).
Testing
WalletConnect provides a test DApp at lab.web3modal.com—a useful tool for testing all signature methods without a real blockchain. For transactions, use test networks (Sepolia, Mumbai).
Timeline: basic WalletConnect v2 integration with personal_sign and eth_sendTransaction—1–2 weeks. Full multi-chain support, eth_signTypedData v4, session revocation, and connection state UI—3–4 weeks.







