WalletConnect Pay Integration via WalletKit (Swift)
Integration guide for iOS/Swift wallets that already have WalletKit integrated.Agent Guidance (For AI Assistants)
Adaptation Principles
-
WalletKit Required - This guide assumes WalletKit is already configured. Pay is accessed via
WalletKit.instance.Pay.*. -
Configuration Order Matters:
-
CAIP-10 Format Required - All accounts must be in
eip155:{chainId}:{address}format. - Signature Order Critical - Signatures array must match actions array order exactly.
-
Travel Rule Conditional - Only collect user data when
selectedOption.collectDatais non-nil. IC is per-option, not global.
Code Adaptation Guidelines
When adapting for a specific wallet:- Replace Signing Logic - Use the wallet’s native EIP-712 signing implementation.
- Adapt UI Flow - Match the wallet’s existing design patterns and navigation.
- Account Discovery - Use the wallet’s account management to build CAIP-10 accounts.
- Error Handling - Add wallet-specific error handling and user feedback.
Common Patterns
Prerequisites
- iOS 13.0+
- Swift 5.7+
- WalletKit already integrated
- WalletConnect Cloud
PROJECT_ID(Get one)
Architecture Overview
State Machine
Step 1: Configure WalletKit
IMPORTANT: Pay is auto-configured when you configure WalletKit. No separate Pay configuration needed.Step 2: Handle Deep Links
Info.plist Configuration
SceneDelegate Implementation
Step 3: Detect Payment Links
UseWalletKit.isPaymentLink() to detect payment links from QR codes or deep links.
pay.hosts (e.g.,pay.walletconnect.com)pay=parameter in WalletConnect URIspay_prefix in bare payment IDs
Step 4: Get Payment Options
eip155:{chainId}:{address}
Step 5: Complete Payment Flow
WebView Data Collection
WhencollectData.url is present, display the URL in a WKWebView. The hosted form handles rendering, validation, and T&C acceptance.
Important: When using the WebView approach, do not passcollectedDatatoconfirmPayment(). The WebView submits data directly to the backend.
Core API Reference
Methods
Types
Troubleshooting
Configuration Issues
| Symptom | Cause | Solution |
|---|---|---|
| ”You must call configure() before accessing instance” | WalletKit not configured | Call Networking.configure() then WalletKit.configure() at app launch |
| Pay methods not available | Wrong import | Use import ReownWalletKit |
Deep Link Issues
| Symptom | Cause | Solution |
|---|---|---|
| App not opening from links | URL scheme missing | Add CFBundleURLSchemes to Info.plist |
| Payment link not detected | Format not recognized | Use WalletKit.isPaymentLink() |
| Cold start link ignored | UI not ready | Add delay before handling |
Payment Failures
| Error | Meaning | Solution |
|---|---|---|
paymentExpired | Link expired | Merchant generates new link |
routeExpired | Route expired | Retry getPaymentOptions |
invalidSignature | Signature mismatch | Check signature order matches actions |
optionNotFound | Stale option | Refresh options and reselect |
Signing Issues
| Symptom | Cause | Solution |
|---|---|---|
| Invalid signature error | Wrong method | Use eth_signTypedData_v4 (EIP-712) |
| Params parsing fails | Unexpected format | Parse as ["address", "typedDataJson"] |
File Checklist
| File | Purpose |
|---|---|
Info.plist | URL scheme configuration |
SceneDelegate.swift | Deep link handling |
PaymentPresenter.swift | Payment flow logic |
PaymentView.swift | Payment UI |
Common Pitfalls
-
Forgetting CAIP-10 format - Accounts must be
eip155:{chainId}:{address}, not just addresses. - Wrong signature order - Signatures array must match actions array order exactly.
-
Skipping WebView data collection - Always check
selectedOption.collectData?.urlafter the user selects an option and show the WebView before confirmation. - Not handling cold start - Deep links on app launch need delayed handling.
-
Using wrong signing method - Must use
eth_signTypedData_v4for EIP-712 typed data. - Missing chains - Provide accounts for all chains you support to maximize payment options.
Testing
-
Enable Logging:
-
Test Both Deep Link Formats:
- WC URI:
yourwallet://?uri=wc:abc...&pay=pay_xyz - POS:
yourwallet://walletconnectpay?paymentId=pay_xyz
- WC URI:
-
Test Cold vs Warm Start:
- Cold: Kill app, open deep link
- Warm: App in background, open deep link