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
The Para SDK provides an EVM signer that implements interfaces compatible with Web3Dart. First, let’s create a signer and connect it to Web3Dart:
Copy
Ask AI
import 'package:para/para.dart';import 'package:web3dart/web3dart.dart';import 'package:http/http.dart';Future<void> 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}
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 transactions are the recommended format for most modern EVM chains, offering more predictable gas fees:
Copy
Ask AI
Future<String> 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;}
Para can also sign transactions that interact with smart contracts:
Copy
Ask AI
Future<String> callSmartContract( Web3Client client, ParaEvmSigner signer, String contractAddress, String contractAbi, String functionName, List<dynamic> 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;}