Expo
Learn how to integrate the Capsule SDK with Expo projects.
The Capsule SDK for Expo allows you to easily integrate secure and scalable wallet functionalities into your mobile applications. This guide covers the installation, setup, and usage of the Capsule SDK in Expo projects.
Prerequisites
To use Capsule, you need an API key. This key authenticates your requests to Capsule services and is essential for integration.
Don’t have an API key yet? You can request access to the Capsule SDK by completing the Developer Access Form.
Dependency Installation
To get started with the Capsule SDK in your Expo project, install the required packages:
Project Setup
Follow these steps to set up the Capsule SDK in your Expo environment:
Set Up Associated Domains
Configure your app.json
file to enable passkey functionality and secure communication:
{
"expo": {
"ios": {
"bundleIdentifier": "your.app.bundleIdentifier",
"associatedDomains": [
"webcredentials:app.beta.usecapsule.com",
"webcredentials:app.usecapsule.com"
]
}
}
}
Important: Your teamId + bundleIdentifier
must be registered with the Capsule team to set up associated domains. For example, if your Team ID is A1B2C3D4E5
and Bundle Identifier is com.yourdomain.yourapp
, provide A1B2C3D4E5.com.yourdomain.yourapp
to Capsule. This is required by Apple for passkey security. Allow up to 24 hours for domain propagation.
Prebuild and Run
To integrate native modules and generate the necessary native code for both iOS and Android:
npx expo prebuild
npx expo run:ios
npx expo run:android
Run these commands after adding or updating packages with native code. This step is crucial for setting up the native environment for both iOS and Android platforms.
Configure Polyfills and Shims
- Configure Metro bundler by creating or updating
metro.config.js
in your project root:
const { getDefaultConfig } = require('expo/metro-config');
const nodeLibs = require('node-libs-react-native');
const config = getDefaultConfig(__dirname);
config.resolver.extraNodeModules = {
...nodeLibs,
crypto: require.resolve('react-native-quick-crypto'),
buffer: require.resolve('@craftzdog/react-native-buffer'),
};
module.exports = config;
- Create
shim.js
in your project root:
import * as Random from 'expo-crypto';
import { decode, encode } from 'base-64';
window.addEventListener = (x) => x;
window.removeEventListener = (x) => x;
if (!global.navigator.userAgent) {
global.navigator.userAgent = 'React Native';
}
if (!global.btoa) {
global.btoa = encode;
}
if (!global.atob) {
global.atob = decode;
}
if (typeof process === 'undefined') {
global.process = require('process');
} else {
const bProcess = require('process');
for (var p in bProcess) {
if (!(p in process)) {
process[p] = bProcess[p];
}
}
}
if (typeof Buffer === 'undefined') {
global.Buffer = require('buffer').Buffer;
}
if (typeof window === 'object') {
if (!window.crypto) window.crypto = {};
if (!window.crypto.getRandomValues) {
window.crypto.getRandomValues = async function getRandomValues(arr) {
let orig = arr;
if (arr.byteLength != arr.length) {
arr = new Uint8Array(arr.buffer);
}
const bytes = await Random.getRandomBytesAsync(arr.length);
for (var i = 0; i < bytes.length; i++) {
arr[i] = bytes[i];
}
return orig;
};
}
}
require('@usecapsule/react-native-wallet').shim();
- Import shim in
index.js
:
import './shim';
// Other imports...
Add WebView Crypto Polyfill
Add the PolyfillCrypto
component to your root App
component:
import PolyfillCrypto from 'react-native-webview-crypto';
export default function App() {
return (
<>
<PolyfillCrypto />
{/* Your app components */}
</>
);
}
Using the Capsule SDK
The Capsule SDK provides two main authentication flows: creating a new user and logging in an existing user. Both flows utilize Native Passkeys for secure and seamless authentication. Follow the steps below to implement these flows in your Expo application.
Create New User
This flow guides you through the process of registering a new user, verifying their email, and setting up their wallet.
Initialize Capsule Client
First, set up the Capsule client to enable SDK interactions:
import { CapsuleMobile, Environment } from '@usecapsule/react-native-wallet';
const capsule = new CapsuleMobile(Environment.BETA, YOUR_API_KEY);
Capsule offers two hosted environments: Environment.BETA
(alias Environment.DEVELOPMENT
) for
testing, and Environment.PROD
(alias Environment.PRODUCTION
) for live use. Select the
environment that matches your current development phase.
Register New User
Create a new user account by calling the createUser
method. This will automatically send a verification email to the user:
const handleCreateUser = async (email: string): Promise<void> => {
try {
await capsule.createUser(email);
console.log("User created. Verification email sent.");
} catch (error) {
console.error("Error creating user:", error);
}
};
Verify Email
Once the user receives the verification code, call the verifyEmailBiometricsId
method to confirm their email:
const handleVerifyEmail = async (code: string): Promise<string | undefined> => {
try {
const biometricsId = await capsule.verifyEmailBiometricsId(code);
console.log("Email verified successfully");
return biometricsId;
} catch (error) {
console.error("Error verifying email:", error);
}
};
Register Passkey and Create Wallet
Use the returned biometricsId to register the user’s passkey and create their wallet:
import { webcrypto } from 'crypto';
const handleRegisterPasskeyAndCreateWallet = async (email: string, biometricsId: string): Promise<{ wallets: any, recoverySecret: string } | undefined> => {
try {
await capsule.registerPasskey(email, biometricsId, webcrypto);
console.log("Passkey registered successfully");
const { wallets, recoverySecret } = await capsule.createWalletPerMissingType(false);
console.log("User wallet created");
return { wallets, recoverySecret };
} catch (error) {
console.error("Error registering passkey or creating wallet:", error);
}
};
Complete New User Flow
Implement the full flow by combining all the previous steps:
const handleNewUserFlow = async (email: string, verificationCode: string): Promise<void> => {
await handleCreateUser(email);
const biometricsId = await handleVerifyEmail(verificationCode);
if (biometricsId) {
const result = await handleRegisterPasskeyAndCreateWallet(email, biometricsId);
if (result) {
console.log("Wallet created:", result.wallets);
console.log("Recovery Secret:", result.recoverySecret);
// Securely display or store the recovery secret for the user
}
}
};
It’s crucial to securely share the recoverySecret
with the user. This secret is necessary for account recovery in case the user loses access to their device. Ensure you have a secure method to display or store this secret for the user.
Login Existing User
This flow demonstrates how to authenticate an existing user using their email and passkey.
Initialize Capsule Client
Ensure the Capsule client is set up (if not already done):
import { CapsuleMobile, Environment } from '@usecapsule/react-native-wallet';
const capsule = new CapsuleMobile(Environment.BETA, YOUR_API_KEY);
Check User Existence and Login
Verify if the user exists and log them in using their passkey:
const handleLogin = async (email: string): Promise<void> => {
try {
const userExists = await capsule.checkIfUserExists(email);
if (userExists) {
await capsule.login();
console.log("User logged in successfully");
} else {
console.log("User does not exist. Please create a new account.");
}
} catch (error) {
console.error("Login error:", error);
}
};
By following these steps, you can implement a secure and user-friendly authentication system in your Expo application using the Capsule SDK.
Examples
For practical implementations of the Capsule SDK in Expo environments, check out our GitHub repository:
Capsule Expo Integration Examples
Explore our repository containing Expo implementations, along with shared UI components demonstrating Capsule integration.
Next Steps
After integrating Capsule, you can explore other features and integrations to enhance your Capsule experience. Here are some resources to help you get started:
Ecosystems
Learn how to use Capsule with popular Web3 clients and wallet connectors. We’ll cover integration with key libraries for EVM, Solana, and Cosmos ecosystems.
EVM Integration
Learn how to use Capsule with EVM-compatible libraries like ethers.js, viem, and wagmi.
Solana Integration
Discover how to integrate Capsule with solana-web3.js.
Cosmos Integration
Explore Capsule integration with Cosmos ecosystem using CosmJS, Cosmos Kit, and Leap Social Login.
If you’re ready to go live with your Capsule integration, make sure to review our go-live checklist:
Go-Live Checklist
Review our go-live checklist to ensure you've configured all necessary settings before launching your Capsule integration.
Troubleshooting
If you encounter issues during the integration or usage of the Capsule SDK in your Expo application, here are some common problems and their solutions:
For a more comprehensive list of solutions, including Expo-specific issues, visit our troubleshooting guide:
Troubleshooting
Our troubleshooting guide provides solutions to common integration and usage problems for Expo and React Native.
Support
If you’re experiencing issues that aren’t resolved by our troubleshooting resources, please contact our support team for assistance. To help us serve you better, include the following information in your support request:
1
A detailed description of the problem you’re encountering.
2
Any relevant error messages or logs.
3
Steps to reproduce the issue.
4
Details about your system or environment (e.g., device, operating system, software version).
Providing this information will enable our team to address your concerns more efficiently.
Was this page helpful?