npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tetherto/wdk-react-native-core

v1.0.0-beta.19

Published

Core functionality for React Native wallets - wallet management, balance fetching, and worklet operations

Readme

@tetherto/wdk-react-native-core

Core functionality for React Native wallets, providing wallet management, balance fetching, and more.

This library uses a unique worklet bundle to run intensive cryptographic operations on a separate thread, ensuring your app's UI remains fast and responsive.

Features

  • ⛓️ Multi-Chain Support: Manage wallets across different EVM-based networks.
  • 🧩 Extensible Architecture: Add support for new blockchains and account types via worklets.
  • 🔐 Secure Storage: Automatic encryption and secure keychain storage for sensitive data.
  • ⚛️ Modern React Hooks: A simple, powerful API for integrating wallet features into your React Native app.
  • 📦 Lightweight & Modular: Generate optimized bundles with only the chains you need.

Table of Contents

Installation

1. Install the Core Library

Install the expo-crypto version compatible with your app's Expo SDK, then install the core library:

npx expo install expo-crypto
npm install @tetherto/wdk-react-native-core

2. Install the Worklet Bundler

You need the bundler to generate the bundle file. You can install it globally or as a dev dependency in your project.

Global Install (Recommended for easy access):

npm install -g @tetherto/wdk-worklet-bundler

Or, as a Dev Dependency:

npm install --save-dev @tetherto/wdk-worklet-bundler

Bundle Configuration

A key part of this library's architecture is the Worklet Bundle.

What is the Worklet Bundle? The bundle is a separate JavaScript file (bundle.js) that contains all the core cryptographic and blockchain logic. This code runs on a dedicated, high-performance thread, completely separate from the React Native UI thread.

Why is it necessary? Running wallet operations in a separate thread is crucial for performance. It ensures that intensive tasks like signing transactions or deriving keys do not slow down or freeze your app's user interface, resulting in a smooth and responsive experience. The bundling step also allows you to create a small, optimized bundle with only the blockchain modules you actually need.

To get the bundle, use the @tetherto/wdk-worklet-bundler CLI to generate one with only the blockchain modules you need:

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

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

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

Example wdk.config.js:

// wdk.config.js
module.exports = {
  // Define the networks you want to support and their corresponding packages.
  networks: {
    ethereum: {
      package: '@tetherto/wdk-wallet-evm-erc-4337'
    },
    bitcoin: {
      package: '@tetherto/wdk-wallet-btc'
    }
  }
};

After running wdk-worklet-bundler generate, you will see the bundle in the directory .wdk.

For the full bundler documentation, see wdk-worklet-bundler.

Quick Start

Getting started involves three main steps:

  1. Configuration: Define your networks and generate the worklet bundle.
  2. Provider Setup: Wrap your application in WdkAppProvider and pass it your configuration.
  3. Use the Hooks: Use hooks like useWalletManager and useAddresses to manage the wallet and access its data.

➡️ For a complete example, see the Full Quick Start Guide.

Guide to Hooks

The library's functionality is exposed through a set of React hooks. They are designed to separate concerns, giving you specific tools for managing the app state, wallet lifecycle, and account interactions.

useWdkApp

  • Design Rationale: Provides a global, top-level view of the library's state via a single state.status value. It's the source of truth for which screen your app should render - loading, onboarding, unlock, or the main app.
  • Standard Use Case: Routing your app's top-level UI off one status value instead of juggling several booleans.
  • Snippet:
    import { useWdkApp } from '@tetherto/wdk-react-native-core';
    
    const { state } = useWdkApp();
    
    switch (state.status) {
      case 'INITIALIZING':
        return <LoadingScreen />;
      case 'NO_WALLET':
        return <CreateOrRestoreWalletScreen />;
      case 'LOCKED':
        // state.walletId is a hint, present when a specific wallet is
        // targeted; it's undefined when a wallet exists but none is
        // active yet. Either way, show your own unlock flow.
        return <UnlockScreen walletId={state.walletId} />;
      case 'READY':
        return <AppContent walletId={state.walletId} />;
      case 'ERROR':
        return <ErrorScreen error={state.error} />;
    }
    See Wallet Lifecycle for exactly what each status means and when it's reported.

useWalletManager

  • Design Rationale: Exclusively handles the wallet's identity lifecycle - create, restore, unlock, lock, and switch. Identity is always caller-owned: the library never guesses which wallet to load or auto-unlocks on your behalf, so these actions are explicit and deliberate, typically triggered from app startup, a settings screen, or your own auth flow.
  • Standard Use Case: Onboarding a new user, unlocking an existing wallet after your own auth check, or switching between accounts.
  • Snippet:
    import { useWalletManager } from '@tetherto/wdk-react-native-core';
    
    const { createWallet, unlock, lock, switchWallet } = useWalletManager();
    
    // First-time user: create a wallet for a specific id (e.g. your app's user id)
    await createWallet(userId);
    
    // Returning user: unlock after your own auth check (biometrics, passcode, etc.)
    await unlock(userId);
    
    // Signing out
    await lock();
    
    // Switching accounts - atomically locks the previous wallet, then unlocks the next
    await switchWallet(otherUserId);
    See Wallet Lifecycle for the full set of rules around switching identities.

useAddresses

  • Design Rationale: Decouples the loading and management of addresses from other account operations. This provides a focused way to get a list of addresses for the active wallet.
  • Standard Use Case: Loading the addresses for the active wallet to display them.
  • Snippet:
    import { useAddresses } from '@tetherto/wdk-react-native-core';
    
    const { addresses, loadAddresses } = useAddresses();
    
    // After a wallet is loaded (e.g. in another useEffect), load addresses.
    useEffect(() => {
      if (walletIsActive) { // Replace with your app's state logic
        loadAddresses([0, 1]); // Load addresses for account 0 and 1
      }
    }, [walletIsActive, loadAddresses]);

useAccount

  • Design Rationale: Provides the actual "actor" for a specific account (e.g., account #0 on Ethereum). This is where you find methods for doing things like signing transactions or messages.
  • Standard Use Case: Getting the account object to call signMessage when a user clicks a button.
  • Snippet:
    import { useAccount } from '@tetherto/wdk-react-native-core';
    
    const { account } = useAccount({ network: 'ethereum', accountIndex: 0 });
    
    const handleSignPress = async () => {
      const signature = await account?.signMessage('Hello WDK');
      console.log(signature);
    };

useBalance

  • Design Rationale: Isolates the logic for fetching balances. It uses TanStack Query internally to automatically handle caching, refetching, and loading states, saving you from writing boilerplate.
  • Standard Use Case: Getting the balance for a native asset (like ETH). You must define your assets first.
  • Snippet:
    import { useBalance } from '@tetherto/wdk-react-native-core';
        
    // Assume 'ethAsset' is an asset object you've defined elsewhere
    const { data } = useBalance({ 
      accountIndex: 0, 
      asset: ethAsset 
    });
    
    const balanceString = data?.balance; // e.g., '1000000000000000000'

Wallet Lifecycle

Identity is always caller-owned - the library never persists, guesses, or auto-unlocks a wallet for you. Only one wallet can be active at a time: unlock, createWallet, and restoreWallet all reject if a wallet is already active, so call await lock() first before switching to a different one (or use switchWallet(walletId), which does both atomically).

Status meanings (useWdkApp().state.status):

  • INITIALIZING - not enough information yet to say anything more specific.
  • NO_WALLET - confirmed: no wallet exists. Safe to show onboarding.
  • LOCKED - no wallet unlocked. walletId is a hint (present when a specific wallet is targeted, absent when one just isn't active yet) - show your own unlock flow either way.
  • READY - a wallet is unlocked and ready.
  • ERROR - something failed; inspect state.error.
  • REINITIALIZING - the worklet is being manually reinitialized.

Best Practices

See Best Practices for important patterns and recommendations for building robust apps.

Architecture

See Architecture for details on the internal design.

Security

See Security for details on security features and best practices.

Troubleshooting

See Troubleshooting for common issues and solutions.

Development

See the Contributing Guide for details on how to build, test, and contribute to this project.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.