WDK logoWDK documentation

React Native Quickstart

Get started with WDK in React Native in under 3 minutes

What You'll Build

In this quickstart, you'll integrate WDK into a React Native app to create a multi-chain wallet that:

  • Supports multiple blockchains (Bitcoin, Ethereum, Polygon, Arbitrum, TON, Tron)
  • Manages multiple tokens (BTC, USD₮, XAU₮, and more)
  • Provides secure seed generation and encrypted storage
  • Shows real-time balances and transaction history
  • Includes wallet creation, import, and unlock flows

You can try all features without real funds required. You can use the Pimlico or Candide faucets to get some Sepolia USD₮.

See the ERC-4337 configuration for quick setup and Sepolia testnet configuration.

Prerequisites

Before we start, make sure you have:

ToolVersionWhy You Need It
Node.js22+To run JavaScript code
npmLatestTo install packages
React Native0.81.0+Framework version
Android SDKAPI 29+Android minimum SDK version
iOS15.1+iOS deployment target

Quickstart Paths

You have 2 options for using WDK in a React Native. Choose your preferred starting point:

Get up and running in 3 minutes with our pre-configured starter template.

→ Jump to Starter Template Setup


Option 1: Starter Template

The fastest way to get started is with our starter template. Note: this is still in alpha, and may be subject to breaking changes.

Step 1: Clone the Starter

git clone https://github.com/tetherto/wdk-starter-react-native.git
cd wdk-starter-react-native

Step 2: Install Dependencies

npm install

Step 3: Configure Environment

Create an environment file for the WDK Indexer API:

cp .env.example .env

Edit .env and add your WDK Indexer API key:

EXPO_PUBLIC_WDK_INDEXER_BASE_URL=https://wdk-api.tether.io
EXPO_PUBLIC_WDK_INDEXER_API_KEY=your_actual_api_key_here
# Optional: For Tron network support
EXPO_PUBLIC_TRON_API_KEY=your_tron_api_key
EXPO_PUBLIC_TRON_API_SECRET=your_tron_api_secret

Where do I get an Indexer API key? The WDK Indexer is required for transaction history and balance indexing. Get your free API key from the Indexer API setup guide.

Step 4: Run Your App

npm run ios

Congratulations! You now have a multi-chain wallet running.

→ Skip to What's Next


Option 2: Add to Existing App

Integrate WDK into your existing React Native or Expo project using @tetherto/wdk-react-native-core.

Step 1: Install

npm install @tetherto/wdk-react-native-core@1.0.0-beta.18 react-native-bare-kit
npx expo install expo-crypto

The v1.0.0-beta.18 npm artifact includes the React Native source entry at src/index.ts, but it does not include the declared default JavaScript or type declaration files under dist/. TypeScript must use moduleResolution: "bundler" with customConditions: ["react-native"], and Metro must retain the react-native export condition. Resolvers that select default or types target files that are not present in this artifact.

Beta.18 requires expo-crypto >=55.0.0 <57.0.0 and react-native-bare-kit >=0.14.5 as peer dependencies. Confirm that the version selected by npx expo install is both inside the package range and compatible with the app's Expo SDK. If the SDK requires a version outside that range, do not force the peer installation; use compatible releases instead. Bare React Native apps must install and configure Expo modules before installing expo-crypto.

Step 2: Configure Android minSdkVersion

The library requires Android API 29 or higher to support react-native-bare-kit.

Add to your app.json or app.config.js:

{
  "expo": {
    "plugins": [
      [
        "expo-build-properties",
        {
          "android": {
            "minSdkVersion": 29
          }
        }
      ]
    ]
  }
}

If you haven't installed expo-build-properties:

npx expo install expo-build-properties

Step 3: Configure the Bundle

The WDK engine runs inside a Bare worklet. Use the @tetherto/wdk-worklet-bundler CLI to generate an HRPC bundle with only the modules you need:

# 1. Install the bundler CLI
npm install -g @tetherto/wdk-worklet-bundler

# 2. Initialize configuration in your React Native project
wdk-worklet-bundler init

# 3. Edit wdk.config.js to configure your networks (see example below)

# 4. Install required WDK modules (pick the ones you need)
npm install @tetherto/wdk @tetherto/wdk-wallet-evm-erc-4337

# 5. Generate the bundle
wdk-worklet-bundler generate

This generates a .wdk/ directory in your project. Import it:

import { bundle } from './.wdk'

Which WDK modules do I need? Each blockchain requires its own wallet module (e.g., wdk-wallet-evm-erc-4337 for Ethereum/Polygon, wdk-wallet-btc for Bitcoin). See the full list of available modules in the wdk-worklet-bundler documentation.

@tetherto/pear-wrk-wdk provides worklet transport and runtime handlers; it does not export a pre-built WDK bundle.

Step 4: Configure WDK Settings

Create a configuration file for your WDK setup (e.g., src/config/wdk.ts):

// src/config/wdk.ts
import type { WdkConfigs } from '@tetherto/wdk-react-native-core'

export const wdkConfigs: WdkConfigs = {
  networks: {
    ethereum: {
      blockchain: 'ethereum',
      config: {
        chainId: 11155111, // Sepolia testnet
        provider: 'https://rpc.sepolia.org',
        bundlerUrl: 'https://api.candide.dev/public/v3/11155111',
        paymasterUrl: 'https://api.candide.dev/public/v3/11155111',
        paymasterAddress: '0x8b1f6cb5d062aa2ce8d581942bbb960420d875ba',
        transferMaxFee: 5000000,
        paymasterToken: {
          address: '0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0', // USDT on Sepolia
        },
      },
    },
    // Add more networks as needed
  },
}

This example uses Sepolia testnet with a free public RPC so you can start immediately without API keys. For production or mainnet configuration, see the Chain Configuration Guide.

Step 5: Add WdkAppProvider

Wrap your app with WdkAppProvider to enable wallet functionality throughout your app.

Add to your app/_layout.tsx:

// app/_layout.tsx
import { WdkAppProvider } from '@tetherto/wdk-react-native-core'
import { bundle } from '../.wdk'
import { Stack } from 'expo-router'
import { wdkConfigs } from '../src/config/wdk'

export default function RootLayout() {
  return (
    <WdkAppProvider bundle={{ bundle }} wdkConfigs={wdkConfigs}>
      <Stack />
    </WdkAppProvider>
  )
}

Step 6: Use Hooks

Now you can use the WDK hooks in any component inside WdkAppProvider:

React Native Core beta.17 and later never guesses which wallet to unlock. Keep the selected wallet ID in your authenticated application state and pass it explicitly. LOCKED.walletId is only an optional hint while a specific wallet is already being targeted.

import { useWdkApp, useWalletManager, useAccount } from '@tetherto/wdk-react-native-core'

function WalletScreen({
  walletId,
  authenticate,
}: {
  walletId: string
  authenticate: () => Promise<boolean>
}) {
  const { state } = useWdkApp()
  const { createWallet, unlock } = useWalletManager()
  const { address } = useAccount({ network: 'ethereum', accountIndex: 0 })

  const create = async () => {
    if (await authenticate()) await createWallet(walletId)
  }

  const open = async () => {
    if (await authenticate()) await unlock(state.walletId ?? walletId)
  }

  switch (state.status) {
    case 'INITIALIZING':
    case 'REINITIALIZING':
      return <Text>Loading...</Text>
    case 'NO_WALLET':
      return <Button title="Create Wallet" onPress={create} />
    case 'LOCKED':
      return <Button title="Unlock" onPress={open} />
    case 'READY':
      return <Text>Address: {address}</Text>
    case 'ERROR':
      return <Text>Error: {state.error.message}</Text>
  }
}

For the full list of available hooks and their parameters, see the React Native Core API Reference.

Step 7: Rebuild and Run

For Expo projects, run prebuild to apply native changes:

npx expo prebuild --clean
npx expo run:ios
# or
npx expo run:android

Congratulations! You've successfully integrated WDK into your React Native app!


What's Next?

Now that you have WDK integrated, here's what you can explore:

Send Transactions

Use the useAccount() hook to send transactions:

import { useAccount, BaseAsset } from '@tetherto/wdk-react-native-core'

const usdt = new BaseAsset({
  id: 'usdt-ethereum',
  network: 'ethereum',
  symbol: 'USDT',
  name: 'Tether USD',
  decimals: 6,
  isNative: false,
  address: '0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0', // USDT on Sepolia
})

function SendScreen({ recipient }: { recipient: string }) {
  const { address, send } = useAccount({ network: 'ethereum', accountIndex: 0 })

  const handleSend = async () => {
    if (!address) return

    const result = await send({
      to: recipient,
      asset: usdt,
      amount: '1000000', // 1 USDT (6 decimals)
    })

    if (result.success) {
      console.log('TX hash:', result.hash, 'Fee:', result.fee)
    } else {
      console.error('TX failed:', result.error)
    }
  }

  return <Button title="Send 1 USDT" onPress={handleSend} />
}

This token configuration is for Sepolia. Validate the recipient for the configured chain and require the user to review the recipient, asset, amount, and fee before calling send().

Lock the Wallet

Use lock() to clear the active wallet identity and local address state:

function LockButton() {
  const { lock } = useWalletManager()

  const handleLock = async () => {
    // This does not stop or prove zeroization of the running worklet.
    await lock()
  }

  return <Button title="Lock" onPress={handleLock} />
}

lock() resets local lifecycle flags but leaves the Bare worklet and IPC connection running. Treat it as an application access boundary, not evidence that seeds or keys were erased from worklet memory.

Refresh Balances

import { useRefreshBalance } from '@tetherto/wdk-react-native-core'

const { mutate: refreshBalance } = useRefreshBalance()

// Refresh all balances for account 0
refreshBalance({ accountIndex: 0, type: 'wallet' })

Troubleshooting

Android build fails with "Execution failed for task ':app:checkDebugAarMetadata'"

This means your minSdkVersion is too low. Make sure you've set it to 29:

{
  "expo": {
    "plugins": [
      ["expo-build-properties", { "android": { "minSdkVersion": 29 } }]
    ]
  }
}

Then rebuild:

npx expo prebuild --clean
npx expo run:android

"useWdkApp must be used within WdkAppProvider"

Ensure your component is rendered inside WdkAppProvider. The provider must be at the root of your component tree:

// Correct
<WdkAppProvider bundle={{ bundle }} wdkConfigs={configs}>
  <MyComponent />  {/* Can use useWdkApp() here */}
</WdkAppProvider>

// Wrong - hook used outside provider
<MyComponent />  {/* Cannot use useWdkApp() here */}
<WdkAppProvider bundle={{ bundle }} wdkConfigs={configs}>
  ...
</WdkAppProvider>

No biometric prompt appears before a wallet operation

React Native Core beta.18 does not enforce biometrics and does not accept a requireBiometrics provider prop. Run your app's biometric, passcode, or other authentication flow before calling createWallet(), restoreWallet(), unlock(), switchWallet(), or key-access methods.

For background locking, revoke the app's authenticated UI state synchronously, then call and catch lock(). The lifecycle mutex rejects instead of queuing when another guarded operation is running, so track a pending lock and retry it after the in-flight guarded operation settles. Require authentication again on foreground and do not treat the SDK session as locked until a retry succeeds.

Metro cache issues

If you see stale module errors after upgrading, clear the Metro cache:

npx expo start --clear
# or
npx react-native start --reset-cache

TypeScript cannot resolve React Native Core

Beta.18's published default and types export targets are absent. Configure TypeScript to select the included React Native source export:

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "customConditions": ["react-native"]
  }
}

Use a current React Native or Expo Metro configuration that honors package exports and retains the react-native condition. skipLibCheck can suppress checks inside declarations after resolution; it cannot repair the missing beta.18 export targets.

Complete Setup Checklist

For Expo projects:

  • Install @tetherto/wdk-react-native-core plus its expo-crypto and react-native-bare-kit peer dependencies
  • Configure Android minSdkVersion to 29 in app.json
  • Set up bundle (custom or pre-built)
  • Create WdkConfigs configuration
  • Add WdkAppProvider to app/_layout.tsx
  • Use hooks (useWdkApp, useWalletManager, useAccount, useBalance)
  • Run npx expo prebuild --clean before building

For bare React Native:

  • Install @tetherto/wdk-react-native-core plus its expo-crypto and react-native-bare-kit peer dependencies
  • Install and configure Expo modules before adding expo-crypto
  • Set minSdkVersion to 29 in android/build.gradle
  • Set up bundle (custom or pre-built)
  • Create WdkConfigs configuration
  • Wrap root component with WdkAppProvider
  • Rebuild native code

Learn More

Ready to dive deeper? Check out these resources:

Core Concepts

Examples & Starters

Need Help?

On this page