This example shows how to integrate @walletconnect/pay with @turnkey/react-native-wallet-kit for gasless USDC payments in a React Native app. Turnkey handles embedded wallet creation and EIP-712 signing; WalletConnect Pay handles transaction construction, gas sponsorship via 7702 paymaster, and on-chain broadcast.
wcpay-turnkey-demo.mp4
Make sure you have Node.js installed locally; we recommend using Node v18+. To run on iOS you'll need Xcode 26.4+, since Expo SDK 57 requires Xcode 26.4 or newer.
This example uses @turnkey/react-native-wallet-kit from the workspace (workspace:*), so it runs against your local copy of the kit and its Turnkey dependencies instead of a published version. Install from the repo root and build the packages before running the app:
$ git clone https://github.com/tkhq/sdk
$ cd sdk
$ pnpm install
$ pnpm build-all
$ cd examples/defi/with-walletconnect-pay/The app loads the kit's built dist output, so rerun the build after changing the kit or @turnkey/core, then reload the app.
To configure the demo wallet you'll need the following:
| Variable | Description |
|---|---|
EXPO_PUBLIC_TURNKEY_ORGANIZATION_ID |
Your Turnkey organization ID from the Turnkey Dashboard |
EXPO_PUBLIC_TURNKEY_API_BASE_URL |
Turnkey API base URL (default: https://api.turnkey.com) |
EXPO_PUBLIC_TURNKEY_AUTH_PROXY_CONFIG_ID |
Auth Proxy configuration ID for email OTP. Find it in the Turnkey WalletKit Dashboard |
EXPO_PUBLIC_WC_API_KEY |
WalletConnect Pay API key from the WalletConnect Dashboard |
Once you've gathered these values, add them to a new .env.local file. Notice that your credentials should be securely managed and never be committed to git.
$ cp .env.local.example .env.local- Go to dashboard.walletconnect.com → create a new project → select "Wallet" as the project type (the WalletConnect Pay tab is not visible on App projects)
- WalletConnect Pay tab → API Keys → generate a key → set it as
EXPO_PUBLIC_WC_API_KEY - Under TEST → Receiving addresses, add your address in CAIP-10 format (e.g.
eip155:8453:0xYourAddress) - Click Go to POS App → New sale → set an amount → a payment QR is generated
On the iOS simulator (no camera): click the QR code image in the WalletConnect dashboard to get the payment link, then paste it into the manual entry field in the app.
Note: WalletConnect Pay is mainnet only. Testnets are not supported. The payer's wallet needs real USDC on Base (or another supported chain). Since you set your own address as the merchant recipient, payments go back to yourself. ~$1 USDC is enough to test.
Option 1: CLI
$ pnpm iosOption 2: Xcode
# Generate the native project first (Option 1 does this automatically)
$ npx expo prebuild --platform ios
# In one terminal: start the Metro bundler
$ npx expo start
# In another terminal (or double-click):
$ open ios/WCPayTurnkeyDemo.xcworkspaceThen in Xcode: select a simulator from the device picker (e.g., iPhone 17 Pro) and press ⌘R.
app/_layout.tsx:TurnkeyProviderwraps the app, providing auth state andsignMessageto all screensconstants/walletconnect.ts:WalletConnectPaysingleton client, initialized with your WC API keylib/turnkey-signer.ts: bridges WC Pay RPC actions (eth_signTypedData_v4,personal_sign) to Turnkey's EIP-712 signingapp/payment.tsx: orchestrates the full payment flow: fetch options → identity verification → sign → broadcast
User ──▶ Email OTP ──▶ Turnkey creates sub-org + ETH wallet
│
▼
Scan WC Pay QR ──▶ Fetch payment options from WC Pay
│
▼
Confirm payment ──▶ Identity verification (if required)
│
▼
Turnkey signs EIP-712 ──▶ WC Pay broadcasts via 7702 paymaster ──▶ ✅ On-chain
- Auth: Email OTP via Turnkey. Each user gets a dedicated sub-org with a 1-of-1 Ethereum wallet. Only the authenticated user can authorize signing.
- Identity verification: If required by the merchant (Travel Rule compliance), the user completes a WC Pay-hosted verification step before signing.
- Gas: Fully abstracted. Turnkey signs the EIP-712 payment authorization, WC Pay handles transaction construction and broadcast via its 7702 paymaster. No ETH required.
This demo is provided for testing and demonstration purposes only. It is not intended for production use. Use at your own risk.