Skip to main content

Portal-Managed Backups

Portal lets you securely back up your users’ MPC wallets so they can recover their wallets even if their device is lost or damaged. By default, Portal encrypts and stores both backup shares (“Portal-Managed Backups”):
  1. The client backup share is encrypted on the user’s device, with the encryption key stored using their chosen backup method (Google Drive, iCloud, Password, or Passkey). The encrypted share is then stored by Portal.
  2. The custodian backup share is encrypted and stored by Portal, with the encryption key stored in our KMS infrastructure.
By default, Portal manages storing both the encrypted client backup share and the custodian backup share for you. If you prefer to store and manage the backup shares in your own infrastructure instead of using Portal-Managed Backups, see our Self-Managed Backups guide.
Both the client backup share and the custodian backup share are necessary to recover a Portal wallet.

Backup Methods

You can choose one or more backup methods for storing the encryption key for the client backup share.

Password/PIN

Allow customers to create a password/pin. Customers can either remember the password or store it in a password storage manager.

Implementation Requirements

  1. Create a UI for password input.
  2. Enforce password requirements. Customer can choose between password, PIN code, passcode, or any other text-based input.
  3. If user forgets password there are no additional recovery options.
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

// Run backup with password
final response = await portal.backupWallet(
  method: PortalBackupMethod.password,
  password: 'THE-USER-PASSWORD',
);

print('Backup complete!');
print('Cipher text: ${response.cipherText}');

Passkey + Enclave

Allow customers to create a native passkey on their device that is used to authenticate into a secure enclave that holds the encryption key for the user. Customer’s passkeys are backed up to the native cloud storage for their device.

Implementation Requirements

  1. Configure passkey storage with a relying party.
  2. Set up your associated domain correctly in your app.

Use Portal as your relying party

  1. Add portalhq.io as a web credential domain in your app.
  2. Share your app bundle id with the Portal Team.

Use your own domain as the relying party

Ensure you have set up your associate domain correctly in your app and that you are serving an aasa file from whatever your relying party domain is set to.
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

// Configure passkey storage
await portal.configurePasskeyStorage(
  relyingPartyId: 'portalhq.io',
  relyingPartyOrigins: ['https://portalhq.io'],
);

// Run backup with passkey
final response = await portal.backupWallet(
  method: PortalBackupMethod.passkey,
);

print('Backup complete!');

Google Drive

Google Drive backup stores the encryption key in the user’s Google Drive account. This method is available on both Android and iOS.

Implementation Requirements

  1. Configure your Google OAuth client ID.
  2. Set up Google Sign-In in your app.
See the docs on how to configure Google Drive.
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

// Configure Google Drive storage
await portal.configureGoogleStorage(
  clientId: 'your-google-client-id',
  applicationName: 'Your App Name', // Optional
);

// Run backup with Google Drive
final response = await portal.backupWallet(
  method: PortalBackupMethod.googleDrive,
);

print('Backup complete!');

iCloud

iCloud backup stores the encryption key in the user’s iCloud Keychain. This method is only available on iOS. See the docs on how to configure iCloud.
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

// Configure iCloud storage (iOS only)
await portal.configureICloudStorage();

// Run backup with iCloud
final response = await portal.backupWallet(
  method: PortalBackupMethod.iCloud,
);

print('Backup complete!');
iCloud backup is only available on iOS devices. On Android, use Google Drive or Passkey backup instead.

Checking Backup Status

You can check if a wallet has been backed up:
final isBackedUp = await portal.isWalletBackedUp();

if (isBackedUp) {
  print('Wallet is backed up');
} else {
  print('Wallet needs to be backed up');
}

Platform Support Matrix

Backup MethodAndroidiOS
Password
Passkey
Google Drive
iCloud-
Related Documentation