Skip to content

Recovering the wallet on a new device

When a user uses their embedded wallet on a new device for the first time, the wallet must first be recovered on that device

Checking if the wallet needs to be recovered

The wallet must be recovered before you can request signatures or transact with the embedded wallet. You can check if the wallets needs to be recovered using the needsRecovery utility from the Expo SDK.

tsx
import {needsRecovery, useEmbeddedWallet, usePrivy, getUserEmbeddedWallet} from '@privy-io/expo';

// ...

const wallet = useEmbeddedWallet();
const {user} = usePrivy();
const account = getUserEmbeddedWallet(user);

if (needsRecovery(wallet) && account.recovery_method !== 'privy') {
  // Recover the wallet per the instructions below
}

// ...

INFO

For wallets where the recovery_method is 'privy' the wallet will be automatically recovered and should never need recovery. For these wallets, you can skip these steps and directly request a signature or transaction.

Recovering the wallet

To recover an embedded wallet for your user, use the recover function of the Privy Expo SDK's useEmbeddedWallet hook.

You can determine the proper arguments for recover via the account.recovery_method property on the embedded wallet account:

  • user-passcode, call recover with recoveryMethod: 'user-passcode' and the user input password
  • google-drive, call recover with recoveryMethod: 'google-drive'

TIP

When the wallet needs to be recovered, you might consider popping up a modal with a button where the user can recover their wallet from their cloud account.

tsx
import {useEmbeddedWallet, needsRecovery, getUserEmbeddedWallet, usePrivy} from '@privy-io/expo';

const CreateWalletButton = () => {
  const [password, setPassword] = useState('');
  const wallet = useEmbeddedWallet();
  const {user} = usePrivy();
  const account = getUserEmbeddedWallet(user);

  if (needsRecovery(wallet) && account.recovery_method === 'user-passcode') {
    return (
      <View>
        {/* Make sure to handle sensitive information appropriately */}
        <TextInput value={password} onChangeText={setPassword} />
        <Button
          onPress={() =>
            wallet.recover({
              recoveryMethod: 'user-passcode',
              password,
            })
          }
        >
          Recover Wallet
        </Button>
      </View>
    );
  }

  return null;
};