Skip to content

Customizing session persistence

By default, the Privy Expo SDK makes use of expo-secure-store package to persist sessions after your app is closed.

Custom storage adapters

If you'd rather persist sessions in a different way, you can easily build an adapter and provide it as an optional prop to the PrivyProvider component:

tsx
import MyStorageProvider from 'my-storage-provider';

import {PrivyProvider} from '@privy-io/expo';
import type {Storage} from '@privy-io/js-sdk-core';

import AppContent from './AppContent';

const myStorage: Storage = {
  get: (key) => MyStorageProvider.getItem(key),
  put: (key, val) => MyStorageProvider.setItem(key, val),
  del: (key) => MyStorageProvider.deleteItem(key),
  getKeys: () => MyStorageProvider.allKeys(),
};

export function App() {
  return (
    <PrivyProvider appId={'my-app-id'} storage={myStorage}>
      <AppContent />
    </PrivyProvider>
  );
}

Customizing the access policy for expo-secure-store

The default expo-secure-store adapter uses requires the device to be unlocked before accessing storage. Your app may require a more permissive access policy, to perform background operations for example.

In this case, create a Custom Storage Adapter that specifies the desired value for keychainAccessible as a configuration option for each method.

tsx
import * as SecureStore from 'expo-secure-store';

import type {Storage} from '@privy-io/js-sdk-core';

// Instead of always requiring the device to ALWYAS be unlocked before accessing storage,
// this adapter allows access if the device has been unlocked ONCE by the user.
export const MyPermissiveSecureStorageAdapter: Storage = {
  get(key) {
    return SecureStore.getItemAsync(key, {
      keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
    });
  },
  put(key, val) {
    return SecureStore.setItemAsync(key, val as string, {
      keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
    });
  },
  del(key) {
    return SecureStore.deleteItemAsync(key, {
      keychainAccessible: SecureStore.AFTER_FIRST_UNLOCK,
    });
  },
  getKeys: async () => [],
};