# Architecture Overview Source: https://docs.getpara.com/concepts/architecture An introduction to Para's architecture and core components Para provides a robust and secure architecture for creating and managing embedded wallets across various blockchain ecosystems. This overview introduces the key components and features of Para's design, setting the stage for a deeper dive into its technical aspects. ## Core Concepts Para's architecture leverages several key concepts: 1. **Multi-Party Computation (MPC) Key Management**: Para uses a 2-of-2 MPC system for secure key management, comprising a User Share and a Cloud Key. 2. **Passkey**: This separate key leverages hardware secure enclaves while maintaining blockchain compatibility. 3. **Distributed Key Generation (DKG)**: Ensures that the full private key is never assembled in a single location. 4. **Passkeys and WebAuthn**: Implements the WebAuthn standard for enhanced security. 5. **Permissions Framework**: Allows granular control over transaction signing across multiple applications. These components work together to provide a secure, flexible, and user-friendly wallet solution that can be embedded in various applications across different platforms and blockchain ecosystems. ## Explore Para's Architecture Dive deeper into specific aspects of Para's architecture and functionality: Learn about Para's innovative approach to key management using MPC and hardware secure enclaves. Explore the various security features that protect user assets and data in Para wallets. Understand how Para enables secure wallet recovery in case of device loss or other issues. Learn about Para's approach to wallet portability and cross-application usage. Find answers to common technical questions about Para's architecture and functionality. By leveraging these architectural components and features, Para provides a comprehensive solution for developers to implement secure, user-friendly embedded wallets in their applications across various platforms and blockchain ecosystems. # Key Management System Source: https://docs.getpara.com/concepts/key-management An in-depth look at Para's innovative approach to secure key management using MPC and hardware secure enclaves export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; Para's Key Management System forms the core of its security architecture, employing advanced cryptographic techniques to safeguard user assets while ensuring usability across various platforms and blockchain ecosystems. At its heart is a distributed (MPC) system that leverages (DKG) and distributed signing. This innovative approach ensures that user keys are never stored in a single vulnerable location, and neither applications nor Para itself can access users' private keys, providing a robust foundation for secure, non-custodial wallet management. ## Key Components Para's key management system relies on a 2-of-2 MPC system comprised of three main components: 1. MPC Key 1: User Share 2. MPC Key 2: Para Share 3. Passkey ### User Share The User Share is custodied by the user and acts like a hot wallet. It is accessible in the browser or on the user's device, providing immediate control over assets while interacting with crypto applications. ### Cloud Share The Cloud Share is managed by Para and stored securely in cloud hardware-security modules (HSMs). This setup provides a secure off-device backup of the user's key, safeguarding the assets even in the event of device loss or compromise. ### Passkey The Passkey is a unique feature of Para's system, designed to bridge the gap between device security capabilities and blockchain requirements. Most modern smartphones come with hardware secure enclaves, which are dedicated areas within the device's main processor used for storing and protecting sensitive data. However, these enclaves primarily support the secp256r1 elliptic curve, which differs from the secp256k1 curve used by most modern blockchains. To address this, Para generates a separate Passkey. This key is used to authorize access to the Cloud Share, enabling biometric authentication and signing on the secp256k1 curve. This process ensures users can leverage their device's hardware security features while interacting seamlessly with blockchain networks. ## Key Generation and Management Process 1. **Distributed Key Generation**: When a user creates a wallet, Para initiates a DKG process. This generates the User Share and Cloud Share without ever assembling the full private key in one place. 2. **Passkey Creation**: Simultaneously, an Passkey is generated and stored in the device's secure enclave. 3. **Cloud Share Storage**: The Cloud Share is securely stored in Para's HSMs. 4. **User Share Protection**: The User Share is protected by the user's authentication method (e.g., passkey, biometrics) and stored securely on the device. ## Security Benefits This key management system offers several security advantages: * **No Single Point of Failure**: Since the private key is never fully assembled, there's no single point of vulnerability. * **Phishing Resistance**: Even if a user's email or social login is compromised, an attacker would still need physical access to the user's device to initiate transactions. * **Device Loss Protection**: If a user loses their device, they can still recover their wallet using the Cloud Share and proper authentication. * **Censorship Resistance**: Users have the option to export their Cloud Share, ensuring they maintain control over their assets . ## Flexible Backup Mechanisms Para supports flexible backup mechanisms and a key-based permissions system, allowing for customized security setups based on specific application needs. These can be configured in the By leveraging this advanced key management system, Para provides a secure, flexible, and user-friendly solution for embedded wallets, balancing robust security with seamless user experience across various blockchain ecosystems. # Wallet Portability Source: https://docs.getpara.com/concepts/portability Exploring Para's approach to wallet portability and seamless cross-application usage Para allows users to seamlessly use their wallet across different applications and platforms, providing a more fluid and user-friendly experience in the crypto ecosystem. ## Overview In the crypto ecosystem, users often need to access the same wallet across various applications. However, this convenience can pose security risks if not managed properly. Para's multi-app architecture addresses these challenges by implementing a sophisticated permissions scheme that balances accessibility with security. Wallet portability is not about transferring assets between wallets, but rather accessing the same wallet from different applications and platforms. ## Key Components Para's approach to wallet portability leverages its unique architecture and security features: Para associates wallets with user identities (typically email addresses) rather than individual applications A granular permissions system ensures that applications only have the access they need, enhancing security in a multi-app context Users can log in to new applications using their Para credentials, automatically gaining access to their existing wallet Para's MPC-based key management allows for secure key sharing across applications without exposing the full private key. This implementation ensures that users can easily and securely use their Para wallet across multiple applications while maintaining strong security and privacy controls. ## Benefits 1. * Access the same wallet across multiple applications without complex key exports 2. * No need to manage multiple wallets or perform 3. * Consistent user experience across different platforms 4. * Permissions for transparent security and granular access confrol 1. * Easier onboarding of users who already have a Para wallet 2. * Access to richer transaction history from shared wallets 3. * Easily craft multi-app experiences and build an ecosystem 4. * request specific permissions based on the application's needs. ## Wallet Portability vs. Traditional Approaches To understand the advantages of Para's wallet portability, let's compare it with traditional approaches: | Feature | Third-Party Wallets | Traditional Embedded Wallets | Para Portable Wallets | | ---------------------------------- | :-----------------: | :--------------------------: | :-------------------: | | Portable across apps | ✔️ | | ✔️ | | Smooth in-app UX | | ✔️ | ✔️ | | Integrated with app functionality | | ✔️ | ✔️ | | No browser extensions required | | ✔️ | ✔️ | | Granular permissions per app | | | ✔️ | | No manual key management for users | | | ✔️ | This comparison highlights how Para Portable Wallets combine the best features of both third-party and traditional embedded wallets, while also offering unique advantages such as granular permissions and simplified key management. ## Security Features Each application can be granted specific permissions, limiting potential damage if one app is compromised. The User Share is encrypted specifically for each application, preventing unauthorized access. Each key sharing process includes a signature verification step to ensure authenticity. Thanks to MPC, the full private key is never exposed to any single application or stored in one place. ## How Wallet Portability Works When a user creates a Para wallet in one application, it's associated with their identity (e.g., email). When the user wants to use their wallet in a new application: - They log in with their Para credentials - The new application requests specific permissions - Upon approval, the application gains access to the user's wallet Para securely shares the necessary key information with the new application, without exposing the full private key. The user can now seamlessly use their wallet across all connected applications, with each app respecting its granted permissions. ## Example Use Cases 1. **DeFi Dashboard**: An app that aggregates data from multiple DeFi protocols could request read-only permissions across various chains. 2. **NFT Marketplace**: Could request permissions specifically for NFT-related transactions on relevant chains. 3. **Cross-Chain DEX**: Might request permissions for swap transactions across multiple chains. ## Preview: Upcoming Enhancements Para is continuously working on enhancing wallet portability. Future developments may include: * More granular permission controls * Enhanced analytics and insights for users across their entire wallet usage * More seamless cross-chain experiences By providing true wallet portability, Para aims to make the crypto experience more user-friendly and secure, paving the way for broader adoption and more innovative multi-app ecosystems. # Wallet Recovery Process Source: https://docs.getpara.com/concepts/recovery A guide to Para's secure wallet recovery mechanism Para employs a robust recovery mechanism to ensure that wallet access remains resilient to events such as device loss or phishing attempts. This document outlines the recovery process implemented in Para's infrastructure. ## How Para Enables Recovery Para's recovery mechanism is designed to maintain user access to funds even if they lose access to their primary device. This is achieved through a combination of recovery secrets, backup devices, and multi-factor authentication. The recovery flow is managed through Para's web application, the Para Portal, eliminating the need for individual app developers to implement their own recovery mechanisms. When setting up a Para wallet, two key elements are generated: 1. **A unique recovery secret**: This is shared with the user client-side. The application has the option to store this secret. It's important to note that this secret is not related to the 2-of-2 MPC scheme and is solely used for restoring wallet access in case of device loss or theft. Para does not have access to this secret. 2. **A copy of the Cloud Key**: This is shared with the user in the Para Backup Kit. The Cloud Key is part of Para's two-key scheme, providing strong censorship resistance and protection against downtime. In the event of a lost or stolen device, recovery is possible through two main methods: 1. **Keychain backup**: If enabled, the key (k1) from the old device can be recovered on a new device. Using this key and the recovery secret, the user can add a new Passkey (r1) to Para's allow list. 2. **Recovery secret**: If the user has their recovery secret, they can initiate a recovery attempt via the Para Portal. After successfully adding a new Passkey, Para prompts the user to perform a key rotation. This process generates an entirely new set of keys, enhancing the security of the user's account and protecting against potential unauthorized access to the old keys. Users have the option to add backup devices (such as a laptop or smartwatch) during the wallet setup process. If a primary device is lost, the user can log in from one of these backup devices. From there, they can add new devices and remove lost ones, ensuring uninterrupted access to their wallet. If the user cannot recover their User Share from their KeyChain backup or a secondary device, they can initiate a key rotation using the recovery key. This process includes: 1. Two-factor authentication (2FA) with their phone number or another multi-factor authentication (MFA) method. 2. This additional step ensures the integrity of the recovery process and protects against impersonation attempts. ## Security Measures The recovery process requires multiple forms of verification, including the recovery secret and optional 2FA, enhancing security against unauthorized access attempts. After recovery, a full key rotation ensures that potentially compromised keys are invalidated, providing an additional layer of security. The option to add multiple backup devices provides redundancy and increases the likelihood of successful recovery in various scenarios. ## Best Practices for Users Store the recovery secret in a secure, offline location. Never share this secret with anyone, including Para. Activate two-factor authentication for an additional layer of security during the recovery process. Add multiple backup devices when possible to increase recovery options. Periodically verify the ability to access the account from backup devices to ensure they remain functional. By implementing this comprehensive recovery process, Para ensures that users have a secure and reliable method to regain access to their wallets, balancing strong security measures with user-friendly processes. # Security Mechanisms Source: https://docs.getpara.com/concepts/security An in-depth exploration of Para's robust security features designed to protect user assets and data Para employs a multi-layered approach to security, incorporating various mechanisms to protect user assets and data. This document outlines the key security features implemented in Para's architecture. ## Multi-Party Computation (MPC) At the core of Para's security is its use of Multi-Party Computation (MPC) for key management. MPC enhances security by: * Preventing the entire private key from being in one location * Eliminating single points of failure * Enabling secure key generation and transaction signing without exposing the full private key ## Hardware Secure Enclaves Para leverages hardware secure enclaves available in modern devices for additional security. These enclaves offer: * A dedicated, isolated environment for sensitive operations * Hardware-level protection for cryptographic keys * Secure biometric authentication capabilities ## Passkeys and WebAuthn Instead of traditional password-based authentication, Para implements the WebAuthn standard to create passkeys. This approach: * Eliminates risks associated with password-based authentication * Leverages device-specific security features * Provides phishing-resistant authentication ## Distributed Key Generation (DKG) Para uses Distributed Key Generation to create key shares without ever assembling the full private key. DKG: * Ensures no single party has access to the complete private key * Provides protection against key theft during the generation process * Allows for secure key refresh and rotation ## Permissions Framework Para implements a sophisticated permissions system to control transaction signing across multiple applications. This framework: * Allows granular control over what actions applications can perform * Mitigates risks associated with compromised applications * Enables users to manage their wallet's exposure across different apps ## Two-Factor Authentication (2FA) Para supports 2FA for additional account security, particularly during the wallet recovery process. The 2FA implementation: * Is an optional feature that can be enabled by users * Utilizes time-based one-time passwords (TOTP) * Adds an extra layer of security for critical operations ## Secure Backup and Recovery Para provides robust mechanisms for wallet backup and recovery, including: * Recovery secrets generated during wallet setup * Support for multiple backup devices * 48-hour delay for recovery attempts to prevent unauthorized access * Para Backup Kit for censorship resistance ## Encryption and Secure Communication All communication between the user's device, Para's servers, and connected applications is encrypted. This includes: * Use of TLS for all network communications * End-to-end encryption for sensitive data * Secure storage of user data with encryption at rest ## Regular Security Audits Para is committed to maintaining the highest security standards through regular third-party audits. The audit process includes: * Periodic audits by reputable security firms * Comprehensive review of cryptographic implementations * Continuous monitoring and improvement of security measures ## Censorship Resistance Para's design ensures that users maintain control over their assets even in the event of service disruptions. Measures include: * Option for users to export their Cloud Key * Ability to sign transactions independently if Para services are unavailable * Decentralized nature of key management prevents single points of failure By implementing these comprehensive security mechanisms, Para provides a robust framework for protecting user assets and data. This multi-layered approach ensures that Para-powered wallets remain secure against a wide range of potential threats while maintaining a seamless user experience. # Technical FAQ Source: https://docs.getpara.com/concepts/technical-faq Frequently asked technical questions about implementing and using Para for developers export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; As you integrate Para into your applications, you may encounter various technical questions. This FAQ aims to address the most common inquiries from developers, covering aspects of implementation, security, architecture, and integration. If you don't find the answer you're looking for, our comprehensive documentation and support team are available to assist you further. Para uses the DKLS19 MPC algorithm and leverages an for core functions like distributed key generation and signing ceremonies. This ensures a robust and auditable foundation for Para's key management system. Para uses the EIP712-specified transaction signature interface. Additionally, Para publishes an EIP-1193 Provider, which is most commonly used via the Wagmi Connector. This ensures compatibility with a wide range of Ethereum-based applications and tools. Para uses sessions as a security measure when signing transactions. By default, session length is 90 minutes. Developers can implement session refresh logic in their applications to maintain longer sessions if required. While Para primarily uses MPC for key management, it is designed to work with ERC-4337 (Account Abstraction) out of the box. This allows developers to leverage Para's security features while also taking advantage of AA capabilities if desired. As long as the cloud key sent during onboarding is not deleted by the user, they can always refresh keys, export, or sign transactions independently. This design ensures that Para cannot censor transactions and provides a robust fallback mechanism. Para offers SDKs for: - TypeScript/React for web developers - React Native for mobile developers - Flutter for cross-platform mobile development These SDKs provide a consistent interface for wallet management and transaction signing across different platforms. The biometric key is stored on-device in a secure enclave. For Ethereum-based transactions, Para uses secp256k1 curve signatures. However, the secure enclave supports the secp256r1 curve. Para generates a secp256r1 key, which is used to authorize a secp256k1 curve signature for ECDSA signatures, bridging this compatibility gap securely. All UI elements and copy in the Para flow are fully configurable. Developers can whitelabel the product to match their application's look and feel. While Para aims for a somewhat consistent user experience, copy, colors, and sizes are fully customizable. Refer to the for detailed configuration options. Para supports sign-in via Google, Apple, Twitter/X, Discord, and Facebook. This allows developers to offer a range of authentication options to their users, potentially increasing adoption and ease of use. Para's multi-app architecture allows the same wallet to be used across different applications while maintaining security. It uses a permissions scheme that specifies what types of transactions an application can perform and which ones require user approval. This is implemented through encrypted User Shares specific to each application and an allow-list mechanism managed by Para. Para implements a robust recovery mechanism involving: 1. A recovery secret generated during wallet setup 2. Option to add backup devices 3. Two-factor authentication for additional security 4. A key rotation process after recovery to ensure security The recovery process is managed through the Para Portal, reducing the implementation burden on individual developers. Para's architecture is designed to be blockchain-agnostic. It offers native support for: - All EVM-compatible chains - Cosmos ecosystem - Solana Developers can integrate Para with popular libraries like ethers.js, viem, and CosmJS for interacting with these networks. Wallet portability in Para is achieved through: 1. Associating wallets with user identities (typically email addresses) rather than individual applications 2. Using MPC for secure key sharing across applications 3. Implementing a permissions framework for granular access control 4. Providing seamless authentication when users access new applications Developers can leverage these features through Para's SDKs and APIs to enable users to access their wallets across different applications seamlessly. For further technical details or questions not covered here, please refer to our documentation or reach out to our developer support team at . # Mobile Examples Source: https://docs.getpara.com/flutter/examples Explore Para's mobile integration examples for Flutter export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Para offers comprehensive Flutter examples to help you integrate our technology into your cross-platform mobile applications. Our example repository demonstrates minimal implementation requirements with clean, focused code that you can easily adapt to your specific application needs. ## Para Flutter Example Explore our Flutter example showcasing Para integration with various features: The Flutter example demonstrates: * Email and passkey authentication * Social login integration * Wallet creation and management * Transaction signing across multiple chains * Session management * Pregenerated wallets ## Need Something Specific? Don't see an example for your use case? Para's team is eager to create new examples to help you integrate with different libraries, third-party features, or providers. # Cosmos Integration Source: https://docs.getpara.com/flutter/guides/cosmos Integrate Para with Cosmos ecosystem in your Flutter applications (Coming Soon) export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; **Coming Soon**: Cosmos integration for Flutter applications is currently in development and will be available soon. Reach out to us at if you'd like to get early access. Para will soon provide support for Cosmos ecosystem integration in Flutter applications, allowing you to leverage Para's secure wallet infrastructure with Cosmos-based blockchains. # EVM Integration Source: https://docs.getpara.com/flutter/guides/evm Integrate Para with EVM-compatible chains in your Flutter applications export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; ## Introduction This guide demonstrates how to integrate Para with Ethereum Virtual Machine (EVM) compatible blockchains in your Flutter applications. Para acts as a secure signer for your transactions, while Web3Dart handles the blockchain interactions. Para's approach to EVM transaction signing is designed for flexibility and security: * Para signs the raw transaction bytes without modifying the transaction data * Your application maintains full control over transaction construction * Para never has access to your application's blockchain RPC endpoints ## Prerequisites Before you begin, ensure you have: 1. Para SDK set up in your Flutter project (see the [Setup Guide](/flutter/setup)) 2. A user authenticated with Para 3. Web3Dart package installed in your project ```bash flutter pub add web3dart:'^2.7.3' ``` Use version `^2.7.3` of Web3Dart to ensure compatibility with Para's EVM signer. ## Setting Up the Para EVM Signer The Para SDK provides an EVM signer that implements interfaces compatible with Web3Dart. First, let's create a signer and connect it to Web3Dart: ```dart import 'package:para/para.dart'; import 'package:web3dart/web3dart.dart'; import 'package:http/http.dart'; Future setupEvmSigner() async { // Initialize Para SDK (if not already done) final para = Para( environment: Environment.beta, apiKey: 'YOUR_API_KEY', ); // Get the user's EVM wallet final wallets = await para.getWallets(); final evmWallet = wallets.values .firstWhere((wallet) => wallet.type == WalletType.evm); // Create the Para EVM signer final signer = await para.getEvmSigner(evmWallet); // Initialize Web3Dart client with your RPC endpoint final client = Web3Client( 'https://rpc.ankr.com/eth_sepolia', // Example RPC URL (Sepolia testnet) Client(), ); // The signer and client are now ready for transaction creation and signing } ``` ## Signing Transactions Para acts as the underlying signer, taking the serialized version of the transaction data and signing the raw bytes. Para never modifies the transaction data, which means your application is responsible for properly constructing transactions. ### EIP-1559 Transaction EIP-1559 transactions are the recommended format for most modern EVM chains, offering more predictable gas fees: ```dart Future sendEip1559Transaction( Web3Client client, ParaEvmSigner signer, EthereumAddress recipientAddress, BigInt amount, ) async { // Prepare transaction parameters final credentials = signer.credentials; final fromAddress = await credentials.extractAddress(); // Get the latest gas parameters from the network final gasPrice = await client.getGasPrice(); final chainId = await client.getChainId(); final nonce = await client.getTransactionCount(fromAddress); // Create the transaction final transaction = Transaction( from: fromAddress, to: recipientAddress, value: EtherAmount.fromBigInt(EtherUnit.wei, amount), nonce: nonce, maxGas: 21000, // Standard gas limit for ETH transfers maxFeePerGas: gasPrice, maxPriorityFeePerGas: EtherAmount.fromBigInt(EtherUnit.gwei, BigInt.from(1)), ); // Sign and send the transaction final txHash = await client.sendTransaction( credentials, transaction, chainId: chainId.toInt(), ); return txHash; } ``` ## Interacting with Smart Contracts Para can also sign transactions that interact with smart contracts: ```dart Future callSmartContract( Web3Client client, ParaEvmSigner signer, String contractAddress, String contractAbi, String functionName, List parameters, ) async { // Prepare transaction parameters final credentials = signer.credentials; final fromAddress = await credentials.extractAddress(); // Parse the contract ABI and create a contract instance final contract = DeployedContract( ContractAbi.fromJson(contractAbi, 'Contract'), EthereumAddress.fromHex(contractAddress), ); // Get the function from the contract final function = contract.function(functionName); // Estimate gas needed for this transaction final gasEstimate = await client.estimateGas( sender: fromAddress, to: contract.address, data: function.encodeCall(parameters), ); // Get the latest gas parameters and nonce final gasPrice = await client.getGasPrice(); final chainId = await client.getChainId(); final nonce = await client.getTransactionCount(fromAddress); // Create and send the transaction final txHash = await client.sendTransaction( credentials, Transaction( from: fromAddress, to: contract.address, data: function.encodeCall(parameters), maxGas: (gasEstimate * BigInt.from(1.5)).toInt(), // Add buffer to gas estimate maxFeePerGas: gasPrice, maxPriorityFeePerGas: EtherAmount.fromBigInt(EtherUnit.gwei, BigInt.from(1)), nonce: nonce, ), chainId: chainId.toInt(), ); return txHash; } ``` ## Error Handling When working with Para and EVM transactions, you might encounter several types of errors: 1. **Para Signing Errors**: Occur when Para cannot sign the transaction (e.g., user cancels or verification fails) 2. **Transaction Formation Errors**: Occur when the transaction is improperly formed 3. **RPC Errors**: Occur when the blockchain node rejects the transaction ## Best Practices When using Para with EVM chains: 1. **Always verify transaction data before signing**: Para signs whatever you provide, so ensure transaction data is correct 2. **Keep RPC endpoints secure**: Never expose your RPC endpoints in client-side code 3. **Estimate gas properly**: Always estimate gas and add a buffer to avoid transaction failures 4. **Handle nonce management**: Track nonces carefully, especially for high-frequency transaction applications 5. **Test on testnets first**: Always test your integration on testnets before moving to mainnet ## Multi-Chain Support Para's EVM signer works with any EVM-compatible chain. To support multiple chains, simply change the RPC endpoint in your Web3Client: ```dart // Ethereum Mainnet final ethMainnetClient = Web3Client( 'https://rpc.ankr.com/eth', Client(), ); // Polygon Mainnet final polygonClient = Web3Client( 'https://rpc.ankr.com/polygon', Client(), ); // Arbitrum final arbitrumClient = Web3Client( 'https://rpc.ankr.com/arbitrum', Client(), ); ``` ## Example For an example on using Para with EVM in Flutter, check out this evm\_sign\_example.dart in our examples repository: ## Additional Resources For more information on Web3Dart usage, refer to the Web3Dart documentation: # Flutter Session Management Source: https://docs.getpara.com/flutter/guides/sessions Guide to managing authentication sessions in Para for Flutter applications export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; Para provides a comprehensive set of methods for managing authentication sessions in Flutter applications. These sessions are crucial for secure transaction signing and other authenticated operations. ## Session Duration The Para session length is `2 hours` by default, but can be configured to up to 30 days. To configure this parameter, please visit the Configuration section of the . A user signing a message or transaction extends the session by the duration of the session length. ## Managing Sessions ### Checking Session Status Use `isSessionActive()` to verify whether a user's session is currently valid before performing authenticated operations. ```dart Future isSessionActive() ``` In Flutter applications, it's especially important to check the session status before allowing users to access authenticated areas of your app due to the persistence of local storage between app launches. Example usage: ```dart import 'package:para_flutter/client/para.dart'; Future checkSession() async { try { final isActive = await para.isSessionActive(); if (!isActive) { // First clear any existing data await para.logout(); // Navigate to login screen // Handle navigation according to your app's navigation strategy } else { // Session is valid, proceed with app flow // Navigate to authenticated part of your app } } catch (e) { // Handle error } } ``` ### Refreshing Expired Sessions When a session has expired, Para recommends initiating a full authentication flow rather than trying to refresh the session. For Flutter applications, always call `logout()` before reinitiating authentication when a session has expired to ensure all stored data is properly cleared. ```dart import 'package:para_flutter/client/para.dart'; Future handleSessionExpiration() async { // When session expires, first clear storage await para.logout(); // Then redirect to authentication screen // Handle navigation according to your app's navigation strategy } ``` ## Exporting Sessions to Your Server Use `exportSession()` when you need to transfer session state to your server for performing operations on behalf of the user. ```dart String exportSession() ``` Example implementation: ```dart import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:para_flutter/client/para.dart'; Future> sendSessionToServer() async { // Export session without signing capabilities final sessionData = para.exportSession(); // Send to your server try { final response = await http.post( Uri.parse('https://your-api.com/sessions'), headers: { 'Content-Type': 'application/json', }, body: jsonEncode({'session': sessionData}), ); if (response.statusCode != 200) { throw Exception('Failed to send session to server'); } return jsonDecode(response.body); } catch (e) { // Handle error throw e; } } ``` ## Best Practices for Flutter 1. **Check Sessions on App Launch**: Verify session status when your app starts to determine if users need to reauthenticate. ```dart import 'package:flutter/material.dart'; import 'package:para_flutter/client/para.dart'; // In your app's entry point or state initialization @override void initState() { super.initState(); checkSessionOnLaunch(); } Future checkSessionOnLaunch() async { final isActive = await para.isSessionActive(); if (isActive) { // Navigate to authenticated part of your app } else { await para.logout(); // Clear any lingering data // Navigate to login screen } } ``` 2. **Handle App Lifecycle Changes**: Flutter apps can be backgrounded and foregrounded, which may affect session status. ```dart import 'package:flutter/material.dart'; import 'package:para_flutter/client/para.dart'; class YourWidget extends StatefulWidget { @override _YourWidgetState createState() => _YourWidgetState(); } class _YourWidgetState extends State with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { // App came to foreground, check session checkSession(); } } Future checkSession() async { final isActive = await para.isSessionActive(); if (!isActive) { await para.logout(); // Navigate to login screen } } @override Widget build(BuildContext context) { // Your widget implementation return Container(); } } ``` ## Next Steps Explore more advanced features and integrations with Para in Flutter: # Social Login Source: https://docs.getpara.com/flutter/guides/social-login Implementing social login with Para in Flutter applications export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Para supports social login authentication in Flutter applications, allowing users to sign in using popular providers like Google, Apple, Twitter, Discord, and Farcaster. This guide explains how to implement social login in your Flutter app using Para's Flutter SDK. The social login flow in mobile applications requires handling browser sessions and deeplinks to redirect users back to your app after successful authentication. Once the social login flow completes, Para uses the returned identifier to authenticate users through the standard email-based flow, creating or authenticating with a native passkey. ## Prerequisites Before implementing social login, ensure you have completed the basic Para setup for your Flutter application. ## Configuration Add URL schemes to your `Info.plist` file to handle callbacks from authentication: ```xml CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLSchemes YOUR_APP_SCHEME ``` In your `AndroidManifest.xml`, add the callback activity and URL scheme: ```xml ``` Replace `YOUR_APP_SCHEME` with your application's unique URL scheme (e.g., `paraflutter`). This scheme must be unique to your application and will be used for redirecting back to your app after authentication. ## Implementation ### OAuth Authentication ```dart OAuth Authentication import 'package:para/para.dart'; import 'package:para_flutter/client/para.dart'; // OAuth connection with Para final oAuthResponse = await para.oAuthConnect(provider, "YOUR_APP_SCHEME"); // For existing users if (oAuthResponse.userExists) { // Login with the email from OAuth response final wallet = await para.login(email: oAuthResponse.email); } // For new users else { // Verify OAuth completion final biometricsId = await para.verifyOAuth(); // Generate passkey await para.generatePasskey(oAuthResponse.email!, biometricsId); // Create wallet final result = await para.createWallet(skipDistribute: false); } ``` ```dart Farcaster Authentication import 'package:para/para.dart'; import 'package:para_flutter/client/para.dart'; // Connect with Farcaster final farcasterResponse = await para.farcasterConnect(); // For existing users if (farcasterResponse.userExists) { // Login with Farcaster username final wallet = await para.login(farcasterUsername: farcasterResponse.username); } // For new users else { // Verify OAuth completion final biometricsId = await para.verifyOAuth(); // Generate passkey await para.generatePasskey(farcasterResponse.username, biometricsId); // Create wallet final result = await para.createWallet(skipDistribute: false); } ``` Social login with Para still requires creating a native passkey to secure the user's wallets. After social authentication completes, Para associates a native passkey with the user's account. For returning users, the native passkey is used for authentication. The passkey is associated on a per-app basis, making authentication streamlined, and users will only see passkey options they created for your specific app. ## Available OAuth Providers Para supports various OAuth providers through the `OAuthMethod` enum: ```dart // Available OAuth methods OAuthMethod.google // Google authentication OAuthMethod.apple // Apple authentication OAuthMethod.twitter // Twitter (X.com) authentication OAuthMethod.discord // Discord authentication ``` ## Checking Login Status You may want to check if a user is already authenticated when your app starts: ```dart // Check if user is logged in final isLoggedIn = await para.isFullyLoggedIn(); // If logged in, get user wallets if (isLoggedIn) { final wallets = await para.getWallets(); // Process wallets as needed } ``` ## Examples Explore our complete example implementations for social login with Para: ## Next Steps After integrating Para, you can explore other features and integrations to enhance your Para experience. # Solana Integration Source: https://docs.getpara.com/flutter/guides/solana Integrate Para with Solana in your Flutter applications export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; ## Introduction This guide demonstrates how to integrate Para with Solana in your Flutter applications. Para acts as a secure signer for your Solana transactions, while the Solana Dart package handles the blockchain interactions. Para's approach to Solana transaction signing is designed for flexibility and security: * Para signs the raw transaction bytes without modifying the transaction data * Your application maintains full control over transaction construction * Your private keys remain secure in Para's wallet infrastructure ## Prerequisites Before you begin, ensure you have: 1. Para SDK set up in your Flutter project (see the [Setup Guide](/flutter/setup)) 2. A user authenticated with Para 3. Solana Dart package installed in your project ```bash flutter pub add solana ``` ## Setting Up the Para Solana Signer The Para SDK provides a Solana signer that works with the Solana Dart package. First, let's create the necessary components: ```dart import 'package:para/para.dart'; import 'package:solana/solana.dart' as web3; // Initialize Para and get wallet (assuming user is already authenticated) final para = Para( environment: Environment.beta, apiKey: 'YOUR_API_KEY', ); // Set up Solana client with the desired network final devnetRpcUrl = Uri.parse('https://api.devnet.solana.com'); final devnetWsUrl = Uri.parse('wss://api.devnet.solana.com'); final solanaClient = web3.SolanaClient( rpcUrl: devnetRpcUrl, websocketUrl: devnetWsUrl, ); // Initialize Para Solana signer final solanaSigner = ParaSolanaWeb3Signer( para: para, solanaClient: solanaClient, ); ``` ## Sending Transactions After signing a transaction, you can send it to the Solana network: ```dart Future sendSolanaTransaction( Wallet wallet, String recipientAddress, double amountInSol, ) async { // Convert wallet address to Solana public key final publicKey = web3.Ed25519HDPublicKey.fromBase58(wallet.address!); // Convert recipient address to Solana public key final recipient = web3.Ed25519HDPublicKey.fromBase58(recipientAddress); // Get the latest blockhash (required for Solana transactions) final blockhash = (await solanaClient.rpcClient.getLatestBlockhash()).value; // Convert SOL amount to lamports (Solana's smallest unit) final lamports = (web3.lamportsPerSol * amountInSol).toInt(); // Create a transfer instruction final instruction = web3.SystemInstruction.transfer( fundingAccount: publicKey, recipientAccount: recipient, lamports: lamports, ); // Create and compile the message final message = web3.Message(instructions: [instruction]); final compiledMessage = message.compile( recentBlockhash: blockhash.blockhash, feePayer: publicKey, ); // Sign the transaction using Para final signedTransaction = await solanaSigner.signTransaction(compiledMessage); // Send the signed transaction to the network final signature = await solanaSigner.sendTransaction(signedTransaction); return signature; } ``` ## Checking Transaction Status After sending a transaction, you may want to check its status: ```dart Future confirmTransaction(String signature) async { try { final confirmation = await solanaClient.rpcClient .confirmTransaction(signature, commitment: web3.Commitment.confirmed); return confirmation.value; } catch (e) { return false; } } ``` ## Working with SPL Tokens Para can also sign transactions involving SPL tokens (Solana's token standard). Here's an example of transferring an SPL token: ```dart import 'package:solana/solana.dart' as web3; import 'package:solana/token_program.dart' as token_program; Future transferSplToken( Wallet wallet, String recipientAddress, String tokenMintAddress, double amount, int decimals, ) async { // Convert wallet address to Solana public key final publicKey = web3.Ed25519HDPublicKey.fromBase58(wallet.address!); // Convert recipient address to Solana public key final recipient = web3.Ed25519HDPublicKey.fromBase58(recipientAddress); // Convert token mint address to Solana public key final tokenMint = web3.Ed25519HDPublicKey.fromBase58(tokenMintAddress); // Get the latest blockhash final blockhash = (await solanaClient.rpcClient.getLatestBlockhash()).value; // Find the token account addresses for sender and recipient final senderTokenAccount = await token_program.findAssociatedTokenAddress( owner: publicKey, mint: tokenMint, ); final recipientTokenAccount = await token_program.findAssociatedTokenAddress( owner: recipient, mint: tokenMint, ); // Check if recipient token account exists, if not create it final instructions = []; final accounts = await solanaClient.rpcClient .getTokenAccountsByOwner( recipient.toBase58(), const web3.TokenAccountsFilter.byMint(tokenMint), ); final recipientTokenAccountExists = accounts.value.any( (account) => account.pubkey == recipientTokenAccount, ); if (!recipientTokenAccountExists) { instructions.add( token_program.createAssociatedTokenAccountInstruction( associatedToken: recipientTokenAccount, payer: publicKey, owner: recipient, mint: tokenMint, ), ); } // Convert token amount accounting for decimals final tokenAmount = (amount * (10 * decimals)).toInt(); // Add token transfer instruction instructions.add( token_program.transferInstruction( source: senderTokenAccount, destination: recipientTokenAccount, owner: publicKey, amount: tokenAmount, ), ); // Create and compile the message final message = web3.Message(instructions: instructions); final compiledMessage = message.compile( recentBlockhash: blockhash.blockhash, feePayer: publicKey, ); // Sign the transaction using Para final signedTransaction = await solanaSigner.signTransaction(compiledMessage); // Send the signed transaction final signature = await solanaSigner.sendTransaction(signedTransaction); return signature; } ``` ## Best Practices When using Para with Solana: 1. **Always verify transaction data before signing**: Para signs whatever you provide, so ensure transaction data is correct 2. **Use appropriate commitment levels**: For important transactions, wait for "confirmed" or "finalized" commitment 3. **Handle network congestion**: Solana transactions can fail during network congestion, implement appropriate retry mechanisms 4. **Check token accounts**: Always verify token accounts exist before sending SPL tokens 5. **Test on devnet first**: Always test your integration on Solana devnet before moving to mainnet ## Example For an example of signing with Solana transactions using para and the Solana Dart package, check out the following code example: ## Resources For more information about using the Solana Dart package, refer to the official documentation: # Overview Source: https://docs.getpara.com/flutter/overview An introduction to Flutter integrations with Para export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Para provides comprehensive support for Flutter, allowing you to easily implement secure wallet and authentication functionality in your cross-platform mobile applications. This overview will guide you through the available integrations and features. ## Getting Started with Flutter ## Blockchain Ecosystem Integrations Para works seamlessly with major blockchain ecosystems in your Flutter apps, allowing you to leverage Para's authentication alongside chain-specific libraries and development tools. ## Advanced Features Customize Para's behavior and extend its functionality with these advanced configuration guides. ## Authentication Options Enhance your application's security and user experience with additional authentication methods. ## Implementation Examples Explore complete implementation examples to accelerate your Flutter development with Para. # Flutter (Mobile) Source: https://docs.getpara.com/flutter/setup Step-by-step instructions for integrating the Para Flutter SDK into your mobile app. export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; This guide walks you through the setup of Para in a Flutter application. You'll learn how to install the SDK, configure iOS/Android for passkey-based logins, implement user authentication flows, and generate wallets. If you haven't already created your Flutter app, follow to set up a new project. ## Prerequisites To use Para, you need an API key. This key authenticates your requests to Para services and is essential for integration. Don't have an API key yet? Request access to the to create API keys, manage billing, teams, and more. ## Installation Start by installing the Para SDK: ```bash flutter pub add para ``` ## Project Setup To set up associated domains for passkey functionality in your Flutter project, you need to configure both iOS and Android platforms: Associated Domains To enable passkeys on iOS, you need to set up associated domains in your Xcode project: 1. Open your Flutter project's iOS folder in Xcode 2. Select your target and go to "Signing & Capabilities" 3. Click "+ Capability" and add "Associated Domains" 4. Add the following domains: * `webcredentials:app.beta.usecapsule.com` * `webcredentials:app.usecapsule.com` For more details, see the . **Important**: You must register your TeamId and BundleId with Para via the to use associated domains. This is required by Apple for passkey security. Allow up to 24 hours for domain propagation. For Android setup, you need to provide your app's SHA-256 certificate fingerprint to Para. **Quick Testing Option**: You can use `com.getpara.example.flutter` as your package name for immediate testing. This package name is pre-registered and works with the SHA-256 certificate from the default debug.keystore, making it testable in debug mode for newly scaffolded Flutter apps. ### Fix Namespace Issue For newer versions of Flutter, you need to add the following configuration block to your `android/build.gradle` file to resolve a namespace issue with the passkey dependency: ```gradle subprojects { afterEvaluate { project -> if (project.hasProperty('android')) { project.android { if (namespace == null) { namespace project.group } } } } } ``` ### Get SHA-256 Fingerprint To get your SHA-256 fingerprint: * For debug builds: `keytool -list -v -keystore ~/.android/debug.keystore` * For release builds: `keytool -list -v -keystore ` For production apps, you'll need to: 1. Upgrade your plan in the Developer Portal 2. Register your actual package name 3. Provide your app's SHA-256 fingerprint 4. Wait up to 24 hours for the Digital Asset Links to propagate To ensure passkey functionality works correctly: * Enable biometric or device unlock settings (fingerprint, face unlock, or PIN) * Sign in to a Google account on the device (required for Google Play Services passkey management) ## Initializing Para To use Para's features, you'll need to initialize a Para client instance that can be accessed throughout your app. This client handles all interactions with Para's services, including authentication, wallet management, and transaction signing. Create a file (e.g., `lib/services/para_client.dart`) to initialize your Para client: ```dart import 'package:para/para.dart'; // Initialize a global Para client instance final para = Para( environment: Environment.beta, // Use Environment.prod for production apiKey: 'YOUR_PARA_API_KEY', ); ``` You can access `para` from anywhere in your app by importing the file where you initialized it. This singleton pattern ensures consistent state management across your application. Para 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. ## Using the Para SDK The Para SDK provides multiple authentication methods including email and phone. Here's how to implement these methods in your Flutter application. **Beta Testing Credentials** In the `BETA` Environment, you can use any email ending in `@test.getpara.com` (like [dev@test.getpara.com](mailto:dev@test.getpara.com)) or US phone numbers (+1) in the format `(area code)-555-xxxx` (like (425)-555-1234). Any OTP code will work for verification with these test credentials. These credentials are for beta testing only. You can delete test users anytime in the beta developer console to free up user slots. ### Create a User with Email Follow these steps to register a new user with email verification: ```dart Future registerUser(String email) async { // Check if user exists if (await para.checkIfUserExists(email)) { // User exists, handle login flow return; } // Create a new user account - this sends a verification code await para.createUser(email); // Next step: Verify the email with the code } Future verifyAndCreateWallet(String email, String verificationCode) async { // Verify the code to get biometricsId final biometricsId = await para.verifyEmail(verificationCode); // Generate a passkey for this device await para.generatePasskey(email, biometricsId); // Create a wallet for the user final result = await para.createWallet(skipDistribute: false); // Store the recovery share securely final recoveryShare = result.recoveryShare; } ``` ### Login with Email To authenticate an existing user with their email: ```dart Future loginUser() async { // This triggers the platform's native passkey selection UI final wallet = await para.login(); // User is now logged in // You can access their wallet address final address = wallet.address; } ``` You can also check if a user is already logged in: ```dart Future checkLoginStatus() async { final isLoggedIn = await para.isFullyLoggedIn(); if (isLoggedIn) { // User is logged in, get their wallets final wallets = await para.getWallets(); // Access the first wallet if (wallets.isNotEmpty) { final wallet = wallets.values.first; final address = wallet.address; } } } ``` ### Create a User with Phone Follow these steps to register a new user with phone verification: ```dart Future registerUserByPhone(String phone, String countryCode) async { // Check if user exists if (await para.checkIfUserExistsByPhone(phone, countryCode)) { // User exists, handle login flow return; } // Create a new user account - this sends an SMS verification code await para.createUserByPhone(phone, countryCode); // Next step: Verify the phone with the code } Future verifyPhoneAndCreateWallet(String phone, String countryCode, String verificationCode) async { // Verify the code to get biometricsId final biometricsId = await para.verifyPhone(verificationCode); // Generate a passkey for this device // The full phone number format should be: +{countryCode}{phone} final fullPhoneNumber = '+$countryCode$phone'; await para.generatePasskey(fullPhoneNumber, biometricsId); // Create a wallet for the user final result = await para.createWallet(skipDistribute: false); // Store the recovery share securely final recoveryShare = result.recoveryShare; } ``` Phone numbers need to be in the format `+1234567890` with the country code included. For country code ensure a + is included. ### Login with Phone To authenticate an existing user with their phone number: ```dart Future loginUserByPhone() async { // This triggers the platform's native passkey selection UI final wallet = await para.login(); // User is now logged in // You can access their wallet address final address = wallet.address; } ``` ### Resend Verification Code If the user doesn't receive the verification code: ```dart Future resendVerificationCode() async { await para.resendVerificationCodeByPhone(); } ``` When `createWallet` is called with `skipDistribute: false`, Para automatically handles the distribution of backup shares. Make sure to securely store and display the recovery secret to the user in your app as it's essential for account recovery. ## Working with Wallets Once a user is authenticated, you can access and manage their wallets: ```dart // Get all wallets for the current user Future getUserWallets() async { try { final wallets = await para.getWallets(); // Access wallet information for (final wallet in wallets) { print('Wallet type: ${wallet.type}'); print('Wallet address: ${wallet.address}'); } } catch (e) { // Handle errors } } ``` ## Examples For practical implementations of the Para SDK in Flutter environments, check out our GitHub repository: ## Troubleshooting If you encounter issues during the integration or usage of the Para SDK in your Flutter application, here are some common problems and their solutions: If you're having trouble initializing the Para SDK: * Ensure that you're using the correct API key and environment. * Check that all necessary dependencies are installed properly. * Look for any Dart errors in your Flutter debug console. * Verify that your Flutter version is compatible with the Para SDK. If passkey creation, retrieval, or usage isn't working: * Verify that you've set up associated domains correctly in your iOS project. * For Android, check that you've configured your `build.gradle` file with the namespace fix. * Make sure you've provided the correct SHA-256 fingerprint to the Para team for Android. * Ensure that biometric authentication is enabled on the test device. * For Android, confirm the test device has a Google account signed in. If you're experiencing authentication issues: * Double-check that your API key is correct and properly set in your Para client initialization. * Verify you're using the correct environment (`beta` or `prod`) that matches your API key. * Ensure your account has the necessary permissions for the operations you're attempting. * Check for any network-related issues that might be blocking API requests. If you're encountering platform-specific problems: * For iOS, ensure your team ID and bundle ID are correctly registered with Para. * For Android, confirm your package name and SHA-256 fingerprint are properly registered. * Check that you're running on a physical device or emulator that supports biometric authentication. * Verify that your Flutter plugins are compatible with your Flutter SDK version. ## Next Steps After integrating Para into your Flutter app, you can explore other features and integrations to enhance your Para experience. # Account Abstraction Source: https://docs.getpara.com/general/account-abstraction Explore account abstraction integration options with Para across different platforms export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Account Abstraction (AA) enables a more intuitive and flexible blockchain experience by allowing for programmable accounts with features like gasless transactions, batched operations, and custom authorization logic. Para serves as the Signer and EOA (Externally Owned Account) for smart wallets and is not a smart wallet itself. Para does not provide gas sponsorship, but you can use any of the supported providers to implement smart wallet functionality for your users. ## Choose Your Platform Note that client-side support for account abstraction is not currently available for Swift and Flutter platforms. If you need account abstraction functionality in Flutter or Swift applications, it's recommended to use server-side account abstraction integration. ## Supported Providers Para integrates with several leading Account Abstraction providers: * * * * * # Go Live Checklist Source: https://docs.getpara.com/general/checklist A checklist to help you go live with the Para SDK. export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; Before going live, ensure you've completed the following steps: * [x] 🔑 Request Access to the to manage your integration * [x] Create and configure a `BETA` API Key for testing the integration * [x] : Get the SDK or Modal Up and Running * [x] Check out the or sections for help! * [ ] ⛓ Get signing & on-chain connectivity set up and make sure you're able to sign transactions * [ ] **\[EVM]** * [ ] **\[Cosmos]** : Add on the `cosm.js` signer or plug in one of our wallet adapters for popular libraries * [ ] : Decide if you'll be using Account Abstraction with Para * [ ] : Connect Para users to your existing infrastructure * [ ] 🔒 Ensure Security and Session Management works for your app * [ ] : Decide what login methods you'd like to use * [ ] Implement Logic * [ ] Decide if you want to enable * [ ] 🎨 Make Para your own with by adding the visual finishing touches * [ ] : Configure Branding, UI and more * [ ] 🚀 Test and go live! * [ ] Make a `PRODUCTION` API Key (Note: you'll need to set up billing first) * [ ] Ping us if you'd like help testing anything ## Para Environments: `BETA` vs `PRODUCTION` Para has two different environments. **NOTE: Wallets are not shared across environments** `BETA` is intended for you to develop and test against, **not for production builds or real users and funds** * `BETA` can be used with any plan, including the free tier * This is the correct environment to use for local or staging builds * `BETA` users can be deleted for your convenience while testing, and is limited to *50 max users per project* `PRODUCTION` is intended for any real users/funds * `PRODUCTION` **requires a paid plan** * This is the correct environment to use for release or production builds * `PRODUCTION` users can NOT be deleted, and have no per-project limit # Migrating from Capsule to Para Source: https://docs.getpara.com/general/migration-from-capsule Guide for migrating from @usecapsule/* packages to @getpara/* packages export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; ## Overview This guide covers the migration process from Capsule to Para SDKs. The migration includes package namespace changes, method signature updates to use object parameters, and introduces new React hooks for state management. ## Package Changes All packages have been migrated from the `@usecapsule` namespace to `@getpara`. Update your dependencies by replacing `@usecapsule` with `@getpara` in your package.json: ```diff { "dependencies": { - "@usecapsule/react-sdk": "^3.0.0", - "@usecapsule/evm-wallet-connectors": "^3.0.0" + "@getpara/react-sdk": "^1.0.0", + "@getpara/evm-wallet-connectors": "^1.0.0" } } ``` All packages have been reset to version 1.0.0 under the new namespace. The functionality and package names remain the same - only the organization prefix has changed from `@usecapsule` to `@getpara`. ```bash npm npm install @getpara/[package-name] ``` ```bash yarn yarn add @getpara/[package-name] ``` ```bash pnpm pnpm add @getpara/[package-name] ``` ## Mobile SDK Updates ### Flutter The Flutter package has moved from `capsule` to `para` on pub.dev: ```diff dependencies: - capsule: 0.7.0 + para: ^1.0.0 ``` Create instances using `Para()` instead of `Capsule()`. All method signatures remain unchanged. ### Swift The Swift SDK package is now available at `github.com/getpara/swift-sdk`. The main class has been renamed from `CapsuleManager` to `ParaManager`, while maintaining the same method signatures: ```diff - let manager = CapsuleManager() + let manager = ParaManager() ``` Method signatures and functionality remain identical for both mobile SDKs - only the package names and main class names have changed. ## Breaking Changes ### Method Updates All methods have been updated to use object parameters instead of multiple arguments. This change improves extensibility, type safety, and reflects our commitment to consistent API design. ```typescript // Old createUser(email: string) // New createUser({ email: string }) ``` ```typescript // Old createUserByPhone(phone: string, countryCode: string) // New createUserByPhone({ phone: string, countryCode: string }) ``` ```typescript // Old externalWalletLogin(address: string, type: string, provider?: string, addressBech32?: string) // New externalWalletLogin({ address: string, type: string, provider?: string, addressBech32?: string }) ``` ```typescript // Old createWallet(type: WalletType, skipDistribute?: boolean) // New createWallet({ type: WalletType, skipDistribute?: boolean = false }) ``` ```typescript // Old createWalletPerType(skipDistribute?: boolean, types?: WalletType[]) // New. Note: Function name changed, default value added, and types is now required createWalletPerType({ skipDistribute?: boolean = false, types: WalletType[] }) ``` ```typescript // Old distributeNewWalletShare( walletId: string, userShare?: string, skipBiometricShareCreation?: boolean, forceRefreshRecovery?: boolean ) // New distributeNewWalletShare({ walletId: string, userShare?: string, skipBiometricShareCreation?: boolean = false, forceRefresh?: boolean = false }) ``` ```typescript // Old createWalletPreGen( type: WalletType, pregenIdentifier: string, pregenIdentifierType?: PregenIdentifierType ) // New createPregenWallet({ type: WalletType, pregenIdentifier: string, pregenIdentifierType?: PregenIdentifierType }) ``` ```typescript // Old - Note: Function name changed updateWalletIdentifierPreGen( newIdentifier: string, walletId: string, newType?: PregenIdentifierType ) // New updatePregenWalletIdentifier({ walletId: string, newPregenIdentifier: string, newPregenIdentifierType?: PregenIdentifierType }) ``` ```typescript // Old signMessage( walletId: string, messageBase64: string, timeoutMs?: number, cosmosSignDocBase64?: string ) // New signMessage({ walletId: string, messageBase64: string, timeoutMs?: number, cosmosSignDocBase64?: string }) ``` ```typescript // Old signTransaction( walletId: string, rlpEncodedTxBase64: string, timeoutMs?: number, chainId: string ) // New signTransaction({ walletId: string, rlpEncodedTxBase64: string, timeoutMs?: number, chainId: string }) ``` All methods now use object parameters with optional properties defaulting to reasonable values. This change makes the SDK more maintainable and easier to extend in the future. ## New Features: React Hooks Para now includes React hooks for easier state management and SDK interaction. Here's a basic setup: ```typescript import { ParaProvider, ParaModal } from "@getpara/react-sdk"; function App() { return ( ); } ``` ### Available Hooks Access current account state and connection status Get current wallet information and state Create a new Para user account Check if a user exists by email Start the login process Handle user logout Maintain active user session Create wallet after passkey verification Sign messages with connected wallet Sign transactions with connected wallet Handle login flow and initial setup Monitor account creation process Access Para client instance Control Para modal visibility Manage wallet state ## Next Steps 1. Update your package dependencies to use `@getpara/*` packages 2. Migrate method calls to use new object parameters 3. Consider implementing React hooks for simpler state management 4. Review framework-specific integration guides for detailed setup instructions # Wallet Pregeneration Source: https://docs.getpara.com/general/pregen Overview of generating pregenerated wallets for Para export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Wallet pregeneration allows you to create wallets in advance of user interactions, which can significantly improve user onboarding speeds and overall experience in your application. With pregeneration, you can create a wallet for any identifier (email, phone number, username, etc.), executing Para's 2-of-2 MPC protocol where your application initially maintains ownership over the user's share of the MPC. The pregenerated wallet can later be claimed by the user associated with that identifier, transferring ownership of their share to them – if your application permits this option. This flexibility opens up numerous possibilities for streamlining user experiences and creating innovative onboarding flows. ## Choose Your Platform Para supports wallet pregeneration across all supported platforms. Select your development platform to view platform-specific implementation details: ## Innovative Use Cases Pregeneration enables powerful new ways to incorporate blockchain into your application: * **Mass User Onboarding**: Create wallets for your existing user base or email lists instantly * **Social Integration**: Generate wallets based on social identifiers like Twitter followers * **Agent-Owned Wallets**: Allow AI agents or bots to create and manage wallets for specific functions * **Server-Side Operations**: Create app-managed wallets to perform operations on behalf of users * **Airdrops and Rewards**: Preload funds or NFTs into wallets that users can claim later * **Staged Onboarding**: Let users experience your application before formally creating their wallet These use cases represent just a few of the possibilities enabled by wallet pregeneration. The platform-specific guides provide detailed implementation instructions for your chosen environment. # Telegram Bots & Mini-Apps Source: https://docs.getpara.com/general/telegram A user-friendly guide to quickly integrate Telegram Apps export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; For signing in to Para with Telegram, refer to . Para supports both Telegram Bots and Mini-Apps. are a way to program logic natively into the Telegram App interface via text-based prompts and commands. Telegram Bots feel native to the UX of Telegram, but are limited to the UX and functionality of text-based options and menus. are an easy way to serve hosted web applications from within Telegram. Given Mini-Apps are added functionality to an existing web app, they are much more flexible but have a UX pattern that deviates from the native Telegram experience. ## Telegram Bot The most popular way to use Para in a Telegram Bot is to leverage with the . You have the option of allowing your users to their pregenerated wallets, which can happen directly within Telegram or in a standalone app. ## Mini-App You can build Mini-Apps two ways: 1. Use the with the password option. 2. Use with the web SDK in a web framework of your choice. Once you have a web example working, use Telegram to create an interface for getting and setting data, like in . 3. You'll need to decide where and how you want users to claim their pregenerated wallets. This can happen within Telegram Mini-Apps or in a standalone app. Telegram Storage APIs have some limitations on data size. You may need to implement chunking to work around this. See this for more info. # Troubleshooting Source: https://docs.getpara.com/general/troubleshooting Something not working quite right? This is the section for you! export const Link = ({href, label}) => { e.currentTarget.querySelector("#underline").style.height = "2px"; }} onMouseLeave={e => { e.currentTarget.querySelector("#underline").style.height = "1px"; }}> {label} ; export const Card = ({imgUrl, iconUrl, fontAwesomeIcon, title, description, href, horizontal = false}) => { return
{ e.currentTarget.style.background = "linear-gradient(45deg, #FF4E00, #874AE3)"; }} onMouseOut={e => { e.currentTarget.style.background = "#e5e7eb"; }}> {(imgUrl || iconUrl) &&
{imgUrl && {title}} {(iconUrl || fontAwesomeIcon) &&
{title}
}
}
{title &&

{title}

} {description &&

{description}

}
; }; Having trouble with your Para integration? You're in the right place. This section contains platform-specific troubleshooting guides to help you resolve common issues across different frameworks and environments. Using an LLM (ChatGPT, Claude) or Coding Assistant (Cursor, Github Copilot)? Here are a few tips: 1. Include the to ensure you're getting the most up-to-date help! 2. Check out the for an interactive LLM that leverages the Para Examples Hub! ## Choose Your Platform ### Web ### Mobile ## Popular Web Frameworks If we're missing a troubleshooting guide for a framework you're using, please get in touch! We're constantly expanding our documentation to cover more environments. ### Integration Support If you're experiencing issues that aren't resolved by our troubleshooting resources, please contact our team for assistance. To help us resolve your issue quickly, please include the following information in your request:
  1. 1

    A detailed description of the problem you're encountering.

  2. 2

    Any relevant error messages or logs.

  3. 3

    Steps to reproduce the issue.

  4. 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. # User Data Management Source: https://docs.getpara.com/general/user-data A comprehensive guide to managing user data when integrating Para into your application Effective user data management is crucial when integrating Para into your application. This guide covers best practices for handling user information, including storage, retrieval, and privacy considerations. ## User Data in Para Para's approach to user data is designed with privacy and security in mind. Here's what you need to know: Para only collects essential information required for account identification and recovery, typically just the user's email address. User data is securely stored and encrypted on Para's servers. However, the most sensitive information - the user's private keys - are never fully stored in one place due to Para's MPC technology. As a developer, you have limited direct access to user data stored by Para. This is by design to ensure user privacy and security. ## Managing User Data in Your Application While Para handles the core wallet functionality, you may need to manage additional user data in your application. Here are some best practices: ### Storing User Information When storing additional user information in your application: 1. Only store what's necessary for your application's functionality. 2. Use secure, encrypted storage methods. 3. Consider using Para's wallet ID as a unique identifier for your users. Example of storing user data: ```typescript type UserData = { paraWalletId: string; username: string; preferences: Record; }; // Assume you're using a secure database async function storeUserData(userData: UserData) { await database.users.insert(userData); } // Usage const wallets = await para.getWallets(); const walletId = Object.values(wallets)[0].id; await storeUserData({ paraWalletId: walletId, username: "user123", preferences: { theme: "dark" }, }); ``` ### Retrieving User Information To retrieve user information: 1. Use Para's methods to get wallet-related information. 2. Fetch additional data from your own storage using the Para wallet ID as a reference. Example: ```typescript async function getUserData(email: string) { const wallets = await para.getWallets(); const walletId = Object.values(wallets)[0].id; // Fetch additional data from your storage const userData = await database.users.findOne({ paraWalletId: walletId }); return { walletId, ...userData, }; } ``` ### Updating User Data When updating user data: 1. Use Para's methods for updating wallet-related information. 2. Update additional data in your own storage. ```typescript async function updateUserPreferences(walletId: string, newPreferences: Record) { // Update in your storage await database.users.update({ paraWalletId: walletId }, { $set: { preferences: newPreferences } }); } ``` ## Privacy and Security Considerations When managing user data, always prioritize privacy and security: Only collect and store data that is absolutely necessary for your application's functionality. Always encrypt sensitive data, both in transit and at rest. Implement strict access controls to ensure that only authorized personnel can access user data. Conduct regular audits of your data management practices to ensure compliance with privacy regulations. ## Compliance with Regulations Ensure your user data management practices comply with relevant regulations such as GDPR, CCPA, or other applicable laws. This may include: * Providing users with the ability to request their data * Allowing users to delete their data * Implementing data portability features Example of a data deletion function: ```typescript async function deleteUserData(walletId: string) { // Delete from your storage await database.users.delete({ paraWalletId: walletId }); // Note: Para wallet data cannot be deleted directly through the SDK // Advise the user to contact Para support for complete account deletion } ``` Remember that while you can delete user data from your own storage, Para wallet data is managed separately for security reasons. Users should be directed to Para's official channels for complete account deletion requests. ## Best Practices for User Data Management 1. **Separation of Concerns**: Keep Para-related data separate from your application-specific user data. 2. **Regular Backups**: Implement a robust backup strategy for user data stored in your application. 3. **Transparent Policies**: Clearly communicate your data handling practices to users through privacy policies and terms of service. 4. **Secure Transmission**: Always use secure, encrypted channels when transmitting user data. 5. **Data Validation**: Implement thorough input validation to prevent injection attacks and ensure data integrity. ## Troubleshooting If you encounter issues with user data management: 1. Ensure you're using the latest version of the Para SDK. 2. Verify that you're correctly handling asynchronous operations when interacting with Para and your own data storage. 3. Double-check that you're using the correct wallet IDs and other identifiers. 4. Review your error handling to ensure you're catching and addressing all potential exceptions. # Para Media Resources Source: https://docs.getpara.com/general/webinars Check out talks by the Para team about our roadmap, MPC, and in-depth looks at Para's architecture and use cases. Founder/CEO Nitya Subramanian covers how multi-party computation can enable flexible and programmable transactions at zkParis 2023