Warning
Alpha Software
This starter template is currently in alpha stage and under active development. It may contain bugs, incomplete features, and breaking changes. Do not use in production environments or with real funds.
For production use, please wait for the stable release or use at your own risk in development/testing environments only.
An Expo + React Native starter demonstrating how to build a secure, multi-chain, non-custodial wallet using the WDK (Wallet Development Kit). Features BareKit worklets for cryptographic operations, secure secret management, and a complete wallet implementation with onboarding, transactions, and asset management.
Click below to see the wallet in action:
This repository is part of the WDK (Wallet Development Kit) project, which empowers developers to build secure, non-custodial wallets with unified blockchain access, stateless architecture, and complete user control.
For detailed documentation about the complete WDK ecosystem, visit docs.wallet.tether.io.
- Bitcoin (SegWit): Native bitcoin transfers with SegWit addresses
- Ethereum: EVM transactions with gas sponsorship support
- Polygon: Low-cost EVM transactions with gas sponsorship
- Arbitrum: Layer 2 scaling with gas sponsorship support
- TON: Native TON blockchain transfers
- Tron: TRC-20 token support with low fees
- Solana: High-performance blockchain support
- BTC: Native Bitcoin on SegWit and Lightning networks
- USDโฎ (Tether USD): Multi-chain USDโฎ support (Ethereum, Polygon, Arbitrum, TON, Tron, Solana)
- XAUโฎ (Tether Gold): Gold-backed stablecoin on Ethereum
- Secure Seed Generation: Cryptographically secure 12-word mnemonic generation
- Seed Import: Import existing BIP39-compatible mnemonic phrases
- Encrypted Storage: Secure key storage via native secure storage (iOS Keychain, Android KeyStore)
- Biometric Authentication: Face ID/Touch ID for wallet unlock
- Wallet Naming: Custom wallet names for better organization
- Real-Time Balances: Live balance updates via WDK Indexer
- Transaction History: Complete transaction tracking and history
- Price Conversion: Real-time fiat pricing via Bitfinex integration
- Multi-Asset View: Aggregate portfolio view across all tokens and chains
- Asset Details: Detailed views for individual tokens with transaction history
- QR Code Scanner: Scan wallet addresses and payment requests via camera
- Send Flows: Complete send flow with network and token selection
- Receive Flows: Generate QR codes for receiving payments
- Activity Feed: Real-time transaction monitoring with status updates
- Settings: Wallet management, security, and app preferences
- Dark Mode: Modern dark theme optimized for readability
- Node.js 22+
- iOS: Xcode toolchain
- Android: SDK (see
app.jsonbuild properties for version requirements)
Clone this repository and install dependencies:
npm installOptional but Recommended: Configure API keys for balance, transaction data, and Tron network support:
# Copy the example environment file
cp .env.example .env
# Edit .env and configure the following:
# EXPO_PUBLIC_WDK_INDEXER_BASE_URL=https://wdk-api.tether.io
# EXPO_PUBLIC_WDK_INDEXER_API_KEY=your_wdk_api_key_here
# EXPO_PUBLIC_TRON_API_KEY=your_tron_api_key_here (optional, for Tron network)
# EXPO_PUBLIC_TRON_API_SECRET=your_tron_api_secret_here (optional, for Tron network)Note: The WDK Indexer API key is used for balance and transaction API requests. While not mandatory for development, it enables full functionality. Tron API keys are optional and only needed if you want to use the Tron network. Get your free WDK Indexer API key in the WDK docs.
For Better Performance: The app uses public RPC endpoints by default, which may have rate limits and variable performance. For a better experience, customize provider URLs in src/config/get-chains-config.ts:
Edit src/config/get-chains-config.ts to update these provider URLs:
Ethereum
ethereum: {
provider: 'https://eth.merkle.io', // Replace with your Ethereum RPC URL
bundlerUrl: 'https://api.candide.dev/public/v3/ethereum',
paymasterUrl: 'https://api.candide.dev/public/v3/ethereum',
}Arbitrum
arbitrum: {
provider: 'https://arb1.arbitrum.io/rpc', // Replace with your Arbitrum RPC URL
bundlerUrl: 'https://api.candide.dev/public/v3/arbitrum',
paymasterUrl: 'https://api.candide.dev/public/v3/arbitrum',
}Do the same for other chains.
Then start the app:
# iOS simulator
npm run ios
# Android emulator/device
npm run androidsrc/
โโโ app/ # App screens (Expo Router file-based routing)
โ โโโ _layout.tsx # Root layout with providers
โ โโโ index.tsx # Entry point & routing logic
โ โโโ onboarding/ # Onboarding flow screens
โ โโโ wallet-setup/ # Wallet creation/import flows
โ โโโ wallet.tsx # Main wallet dashboard
โ โโโ assets.tsx # Asset list screen
โ โโโ activity.tsx # Transaction history
โ โโโ send/ # Send flow screens
โ โโโ receive/ # Receive flow screens
โ โโโ authorize.tsx # Biometric authentication
โ โโโ settings.tsx # App settings
โ โโโ scan-qr.tsx # QR code scanner
โ โโโ token-details.tsx # Individual token details
โโโ components/ # Reusable UI components
โ โโโ onboarding/ # Onboarding components
โ โโโ ui/ # Base UI components
โ โโโ *.tsx # Shared components
โโโ config/ # Configuration files
โ โโโ assets.ts # Token/asset configurations
โ โโโ avatar-options.ts # Wallet avatar configurations
โ โโโ networks.ts # Network configurations
โ โโโ get-chains-config.ts # Chain-specific settings & provider URLs
โโโ services/ # Business logic & external services
โ โโโ pricing-service.ts # Fiat pricing via Bitfinex
โโโ hooks/ # Custom React hooks
โ โโโ use-debounced-navigation.ts # Debounced navigation to prevent rapid taps
โ โโโ use-keyboard.ts # Keyboard visibility detection
โ โโโ use-wallet-avatar.ts # Wallet avatar management
โโโ utils/ # Utility functions
โโโ gas-fee-calculator.ts # Gas fee estimation & network utilities
โโโ format-amount.ts # Amount formatting helpers
โโโ format-token-amount.ts # Token-specific amount formatting
โโโ format-usd-value.ts # USD value formatting
โโโ get-display-symbol.ts # Token symbol display utilities
โโโ get-denomination-value.ts # Token denomination utilities
โโโ parse-worklet-error.ts # Worklet error parsing for better UX
โโโ recent-tokens.ts # Recent token tracking
The app follows a clean architecture pattern with clear separation of concerns:
-
Providers Layer (
_layout.tsx)WalletProvider: Manages wallet state, blockchain interactions, and WDK serviceThemeProvider: Handles dark mode and custom themingNavigationThemeProvider: React Navigation theme configuration
-
Screen Layer (
app/directory)- File-based routing via Expo Router
- Each screen is a self-contained React component
- Navigation handled automatically based on file structure
-
Business Logic (
services/directory)- Pricing service for real-time fiat conversion
-
Configuration (
config/directory)- Centralized network and asset configurations
- Chain-specific RPC endpoints and settings
- Onboarding โ View welcome screen with app features
- Wallet Setup โ Choose "Create New Wallet"
- Name Wallet โ Set a custom wallet name
- Secure Wallet โ View and backup 12-word seed phrase
- Confirm Phrase โ Verify seed phrase knowledge
- Complete โ Wallet created and unlocked
- Wallet Dashboard โ Access main wallet interface
- Onboarding โ View welcome screen
- Wallet Setup โ Choose "Import Existing Wallet"
- Import Wallet โ Enter 12-word seed phrase
- Name Wallet โ Set a custom wallet name
- Complete โ Wallet imported and unlocked
- Wallet Dashboard โ Access main wallet interface
- Entry Point (
index.tsx) โ Check wallet status - Authorization โ Biometric authentication (Face ID/Touch ID)
- Wallet Dashboard โ Access wallet after unlock
- Wallet Dashboard โ Tap "Send" button
- Select Token โ Choose token to send (BTC, USDโฎ, XAUโฎ)
- Select Network โ Choose blockchain network
- Send Details โ Enter recipient address, amount, and review fees
- Confirm โ Approve transaction
- Transaction Submitted โ View transaction status
- Wallet Dashboard โ Tap "Receive" button
- Select Token โ Choose token to receive
- Select Network โ Choose blockchain network
- Receive Details โ View QR code and address, copy or share
This starter supports the following blockchain networks and operations:
| Network | Balance | History | Send | Receive | Gas Sponsorship |
|---|---|---|---|---|---|
| Bitcoin (SegWit) | โ | โ | โ | โ | N/A |
| Lightning | โ | โ | โ | โ | N/A |
| Ethereum | โ | โ | โ | โ | โ |
| Polygon | โ | โ | โ | โ | โ |
| Arbitrum | โ | โ | โ | โ | โ |
| TON | โ | โ | โ | โ | โ |
| Tron | โ | โ | โ | โ | โ |
| Solana | โ | โ | โ | โ | โ |
| Token | Symbol | Networks |
|---|---|---|
| Bitcoin | BTC | Bitcoin (SegWit), Lightning |
| Tether USD | USDโฎ | Ethereum, Polygon, Arbitrum, TON, Tron, Solana |
| Tether Gold | XAUโฎ | Ethereum |
- Gas Sponsorship: EVM networks (Ethereum, Polygon, Arbitrum) and other supported chains offer gasless transactions via paymasters
- Multi-Network: Send the same token across different networks based on preference and fees
- Real-Time Data: Live balance and transaction updates via WDK Indexer
- QR Code Support: Generate and scan QR codes for easy address sharing
This starter implements multiple layers of security for protecting user assets:
- BareKit Worklets: Cryptographic operations run in isolated worklet context
- Secret Manager: Keys stored encrypted using native secure storage (iOS Keychain, Android KeyStore)
- No Key Exposure: Private keys never leave the secure context or device
- BIP39 Compliant: Standard 12-word mnemonic seed phrase generation
- Biometric Lock: Face ID/Touch ID for wallet unlock
- App Lock: Wallet locked on app background/close
- Session Management: Secure session handling with automatic timeout
- User Confirmation: All transactions require explicit user approval
- Amount Verification: Clear display of amounts and fees before signing
- Address Validation: Input validation for recipient addresses
- Network Selection: User must explicitly choose network to prevent errors
- No Analytics: No user data or transaction info sent to third parties
- Local Storage: All wallet data stored locally on device
- Open Source: Fully auditable codebase
- Non-Custodial: Users have complete control of their private keys
The app includes comprehensive Node.js polyfills for React Native compatibility via @tetherto/wdk-react-native-provider/metro-polyfills
- Sodium:
sodium-javascript(WebAssembly-based cryptography) - Random:
react-native-get-random-values(secure randomness) - PBKDF2:
react-native-fast-pbkdf2(key derivation) - TCP:
react-native-tcp-socket(for Bitcoin Electrum)
| Script | Description |
|---|---|
npm start |
Start Expo development server with dev client |
npm run ios |
Run on iOS simulator |
npm run android |
Run on Android emulator/device |
npm run web |
Run in web browser |
npm run prebuild |
Generate native project files |
npm run prebuild:clean |
Clean and regenerate native project files |
npm run lint |
Run ESLint to check code quality |
npm run lint:fix |
Run ESLint and auto-fix issues |
npm run format |
Format code with Prettier |
npm run format:check |
Check code formatting without making changes |
npm run typecheck |
Run TypeScript type checking |
- Expo: ~54.0.8
- React: 19.1.0
- React Native: 0.81.4
- TypeScript: ~5.9.2
- New Architecture: Enabled in
app.jsonfor improved performance - React Native Reanimated: ~4.1.0 for smooth animations
- React Compiler: Enabled for automatic memoization
- Android: minSdkVersion 29, compileSdkVersion 36
- iOS: Latest Xcode toolchain recommended
- Node.js: 22+ required
@tetherto/wdk-react-native-provider: Main wallet provider@tetherto/wdk-uikit-react-native: UI components library@tetherto/wdk-pricing-provider: Fiat pricing integration@tetherto/wdk-pricing-bitfinex-http: Bitfinex price data provider@tetherto/pear-wrk-wdk: BareKit worklets runtime
- Add token configuration in
src/config/assets.ts:
export const assetConfig: Record<string, AssetConfig> = {
newtoken: {
name: 'New Token',
icon: require('../../assets/images/tokens/newtoken-logo.png'),
color: '#YOUR_COLOR',
supportedNetworks: [NetworkType.ETHEREUM],
},
};- Add token icon to
assets/images/tokens/
- Add network configuration in
src/config/networks.ts:
[NetworkType.NEW_NETWORK]: {
id: 'new-network',
name: 'New Network',
gasLevel: 'Low',
gasColor: '#34C759',
icon: require('../../assets/images/chains/new-network-logo.png'),
color: '#YOUR_COLOR',
}- Add chain configuration in
src/config/get-chains-config.ts:
newnetwork: {
chainId: YOUR_CHAIN_ID,
blockchain: 'newnetwork',
provider: 'https://your-rpc-url.com',
// Add other chain-specific configuration
}- Add chain logo to
assets/images/chains/
Update the brand configuration in src/app/_layout.tsx:
<ThemeProvider
defaultMode="dark"
brandConfig={{
primaryColor: '#YOUR_BRAND_COLOR',
}}
>Metro bundler cache issues
npx expo start -cNative build issues
npm run prebuild:clean
cd ios && pod install
cd android && ./gradlew cleanType errors after updates
npm run typecheck- Use Expo Dev Client for faster development cycles
- Enable Fast Refresh for instant UI updates
- Check Metro bundler logs for build issues
- Use React DevTools for component debugging
- Monitor network requests in browser DevTools (web) or Reactotron (native)
This project is licensed under the Apache-2.0 - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Read the code of conduct
- See contributing guide
For support, please:
- Check the WDK documentation
- Open an issue on the GitHub repository
- Join the WDK developer community