> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Wallet Pregeneration

> Create and manage pregenerated wallets for users in Flutter applications

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

<Info>
  Creating wallets from a backend? Use the [REST API](/v3/rest/overview) instead — no user share to store, and wallets
  are still claimable when the user signs up. Use this guide when your flow needs direct user-share control on the
  client.
</Info>

Para's Wallet Pregeneration feature allows you to create wallets for users before they authenticate, giving you control over when and how users claim ownership of their wallets. In mobile applications you can use device-specific storage for the user share.

## Mobile-Specific Benefits

While pregeneration works the same across all Para SDKs, Flutter applications offer unique advantages:

<CardGroup cols={2}>
  <Card title="Seamless Web2 to Web3 Transition" description="Create wallets behind the scenes when users login to your existing mobile app" />

  <Card title="Local Secure Storage" description="Store user shares directly on the device using encrypted storage options" />

  <Card title="Device-Specific Wallets" description="Create wallets tied to specific devices for enhanced security" />

  <Card title="App Clips and Instant Experiences" description="Enable blockchain functionality in lightweight app experiences" />
</CardGroup>

<Note>
  Pregeneration is especially valuable for devices that may not have full WebAuthn support for passkeys. It allows you to create Para wallets for users on any device while managing the security of the wallet yourself.
</Note>

## Creating Pregenerated Wallets

In Flutter, you can create pregenerated wallets of multiple types with a single method call:

```dart theme={null}
import 'package:para/para.dart';

Future<List<Wallet>> createPregenWallets() async {
  final pregenWalletsFuture = para.createPregenWalletPerType(
    pregenId: {'EMAIL': 'user@example.com'}, // Map format for pregen ID
    types: [WalletType.evm], // Optionally specify wallet types
  );

  final pregenWallets = await pregenWalletsFuture.future;

  // Get the user share
  final userShareFuture = para.getUserShare();
  final userShare = await userShareFuture.future;

  // Store user share securely (see storage options below)

  return pregenWallets;
}
```

## Mobile Storage Options

In Flutter applications, you have several options for securely storing the user share:

<Tabs>
  <Tab title="Flutter Secure Storage">
    ```dart theme={null}
    import 'package:flutter_secure_storage/flutter_secure_storage.dart';

    final storage = FlutterSecureStorage();

    // Store the user share
    Future<void> storeUserShare(String userShare) async {
      try {
        await storage.write(
          key: 'para_user_share',
          value: userShare,
        );
      } catch (e) {
        // Handle error
      }
    }

    // Retrieve the user share
    Future<String?> retrieveUserShare() async {
      try {
        return await storage.read(key: 'para_user_share');
      } catch (e) {
        // Handle error
        return null;
      }
    }
    ```
  </Tab>

  <Tab title="Encrypted Shared Preferences">
    ```dart theme={null}
    import 'package:encrypted_shared_preferences/encrypted_shared_preferences.dart';

    final encryptedPrefs = EncryptedSharedPreferences();

    // Store the user share
    Future<void> storeUserShare(String userShare) async {
      try {
        await encryptedPrefs.setString('para_user_share', userShare);
      } catch (e) {
        // Handle error
      }
    }

    // Retrieve the user share
    Future<String?> retrieveUserShare() async {
      try {
        return await encryptedPrefs.getString('para_user_share');
      } catch (e) {
        // Handle error
        return null;
      }
    }
    ```
  </Tab>
</Tabs>

<Warning>
  Whichever storage method you choose, ensure you implement proper security measures. The user share is critical for wallet access, and if lost, the wallet becomes permanently inaccessible.
</Warning>

## Using Pregenerated Wallets in Flutter Apps

Once you have created a pregenerated wallet and stored the user share, you can use it for signing operations:

```dart theme={null}
import 'dart:convert';
import 'package:para/para.dart';

Future<String> usePregenWallet(String walletId) async {
  // Retrieve the user share from your secure storage
  final userShare = await retrieveUserShare();

  if (userShare == null) {
    throw Exception("User share not found");
  }

  // Load the user share into the Para client
  await para.setUserShare(userShare);

  // Now you can perform signing operations
  final messageBase64 = base64Encode(utf8.encode("Hello, World!"));
  final signatureFuture = para.signMessage(
    walletId: walletId,
    messageBase64: messageBase64,
  );

  final signatureResult = await signatureFuture.future;
  // The signature is in the signedTransaction property
  return (signatureResult as SuccessfulSignatureResult).signedTransaction;
}
```

### Mobile-Specific Use Cases

<AccordionGroup>
  <Accordion title="Device-Specific Wallets">
    Create wallets that are bound to a specific device by using device-specific identifiers combined with secure local storage. This approach is ideal for multi-device users who need different wallets for different devices.

    ```dart theme={null}
    import 'package:device_info_plus/device_info_plus.dart';
    import 'package:para/para.dart';

    Future<List<Wallet>> createDeviceWallet() async {
      final deviceInfo = DeviceInfoPlugin();
      String deviceId;

      if (Platform.isAndroid) {
        final androidInfo = await deviceInfo.androidInfo;
        deviceId = androidInfo.id;
      } else if (Platform.isIOS) {
        final iosInfo = await deviceInfo.iosInfo;
        deviceId = iosInfo.identifierForVendor ?? 'unknown';
      } else {
        deviceId = 'unknown';
      }

      final pregenWalletsFuture = para.createPregenWalletPerType(
        pregenId: {'CUSTOM_ID': 'device-$deviceId'},
      );

      final pregenWallets = await pregenWalletsFuture.future;

      // Store the user share in device-specific secure storage
      final userShare = await para.getUserShare().future;
      await storeUserShare(userShare);

      return pregenWallets;
    }
    ```
  </Accordion>

  <Accordion title="Transparent Web3 Integration">
    Seamlessly introduce blockchain functionality to your existing app users without requiring them to understand wallets or crypto.

    ```dart theme={null}
    import 'package:para/para.dart';

    Future<List<Wallet>> createWalletForExistingUser(String userId) async {
      final pregenIdentifier = "user-$userId";

      try {
        final pregenWalletsFuture = para.createPregenWalletPerType(
          pregenId: {'CUSTOM_ID': pregenIdentifier},
        );

        final pregenWallets = await pregenWalletsFuture.future;

        final userShare = await para.getUserShare().future;
        await storeUserShare(userShare);

        return pregenWallets;
      } catch (e) {
        // Handle errors
        throw e;
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Claiming Pregenerated Wallets

When a user is ready to take ownership of their pregenerated wallet, they can claim it once they've authenticated with Para:

```dart theme={null}
import 'package:para/para.dart';

Future<String> claimWallet(Map<String, String> pregenId) async {
  // Ensure user is authenticated
  if (!(await para.isSessionActive().future)) {
    throw Exception("User must be authenticated to claim wallets");
  }

  // Retrieve and load the user share
  final userShare = await retrieveUserShare();
  if (userShare != null) {
    await para.setUserShare(userShare);
  }

  // Claim the wallet with the pregen ID
  final claimFuture = para.claimPregenWallets(
    pregenId: pregenId, // e.g., {'EMAIL': 'user@example.com'}
  );
  final recoverySecret = await claimFuture.future;

  // Optionally, clear the locally stored user share after claiming
  // since Para now manages it through the user's authentication
  await clearUserShare();

  return recoverySecret;
}
```

<Note>
  After claiming, Para will manage the user share through the user's authentication methods. You can safely remove the user share from your local storage if you no longer need to access the wallet directly.
</Note>

## Best Practices for Mobile

1. **Utilize Device Security**: Leverage biometric authentication (TouchID/FaceID) to protect access to locally stored user shares.

2. **Implement Device Sync**: For users with multiple devices, consider implementing your own synchronization mechanism for user shares across devices.

3. **Handle Offline States**: Mobile applications often work offline. Design your pregenerated wallet system to function properly even when connectivity is limited.

4. **Backup Strategies**: Provide users with options to back up their wallet data, especially for device-specific wallets that might not be associated with their Para account.

5. **Clear Security Boundaries**: Clearly communicate to users when they're using an app-managed wallet versus a personally-owned wallet.

## Related Resources

<CardGroup cols={2}>
  <Card horizontal title="Social Login" imgUrl="/images/v3/custom-ui-social.png" href="/v3/flutter/guides/social-login" description="Learn how to implement social login in Flutter applications" />

  <Card horizontal title="Session Management" imgUrl="/images/v3/general-storage.png" href="/v3/flutter/guides/sessions" description="Managing authentication sessions in Flutter applications" />
</CardGroup>
