Skip to content

vaariance/para-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Para + Variance: ERC-4337 Account Abstraction Integration

A complete demonstration of bridging Para's embedded wallet with Variance SDK to enable ERC-4337 Account Abstraction (smart accounts).

🎯 Overview

This integration demonstrates how to use Para's embedded wallet as a signer for ERC-4337 smart accounts using the Variance SDK. It bridges Para's authentication and key management with Ethereum's Account Abstraction standard, enabling gasless transactions, batch operations, and enhanced security for your users.

What This Enables

  • βœ… Smart Account Creation: Deploy ERC-4337 Safe smart accounts for users
  • βœ… Gasless Transactions: Sponsor gas fees for your users
  • βœ… Batch Operations: Execute multiple transactions atomically
  • βœ… Social Recovery: Add guardians and recovery mechanisms
  • βœ… Session Keys: Delegate limited permissions without exposing main keys
  • βœ… Para Authentication: OAuth (Google, Apple) + Passkey security

πŸ“š Table of Contents

Required Packages

dependencies:
  flutter: sdk: flutter
  para: ^latest_version
  variance_dart: ^0.2.0
  web3_signers: ^latest_version
  web3dart: ^2.7.0
  crypto: ^3.0.3
  eth_sig_util: ^latest_version

API Keys & Configuration

  1. Para Account: Sign up at Para Dashboard
  2. RPC Provider: Your target RPC
  3. Bundler: ERC-4337 bundler endpoint (Pimlico, Stackup, Gelato or run your own)

πŸ“¦ Installation

1. Add Dependencies

flutter pub add para variance_dart web3_signers web3dart crypto eth_sig_util

2. Clone This Repository

git clone https://github.com/vaariance/para-demo.git
cd para-demo

3. Configure Environment

Create a .env file:

PARA_API_KEY=your_para_api_key
PARA_ENVIRONMENT=beta  # or production
VARIANCE_API_KEY=your_variance_api_key
RPC_URL=your_ethereum_rpc_url
BUNDLER_URL=your_bundler_url
ENTRYPOINT_ADDRESS= There are existing entrypoints address in the variance_dart package to utilize

4. Para Configuration

final para = Parra.fromConfig(
      config: ParaConfig(
        apiKey: dotenv.env['PARA_API_KEY'] ?? '',
        environment: Environment.beta,
        requestTimeout: const Duration(seconds: 60),
      ),
      appScheme: 'parademo',
      sessionPersistence: sessionPersistence,
    );

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Your Flutter App                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
                         ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    ParaSigner (MSI)                          β”‚
β”‚  β€’ Implements MultiSignerInterface                           β”‚
β”‚  β€’ Bridges Para ↔ Variance                                   β”‚
β”‚  β€’ Handles EIP-191 signing                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                            β”‚
             ↓                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Parra (Custom)      β”‚   β”‚    Variance SDK              β”‚
β”‚  β€’ signMessageRaw()    β”‚   β”‚  β€’ Smart Account Factory     β”‚
β”‚  β€’ Base64 encoding     β”‚   β”‚  β€’ UserOp creation           β”‚
β”‚  β€’ JS Bridge access    β”‚   β”‚  β€’ Bundler communication     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                                   β”‚
         ↓                                   ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Para SDK            β”‚   β”‚    ERC-4337 Network          β”‚
β”‚  β€’ Capsule MPC         β”‚   β”‚  β€’ EntryPoint Contract       β”‚
β”‚  β€’ OAuth               β”‚   β”‚  β€’ Bundler                   β”‚
β”‚  β€’ Passkey Auth        β”‚   β”‚  β€’ Paymaster (optional)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Components

1. Parra Class (Extended Para SDK)

The Parra class extends Para's SDK to add raw byte signing capability, which is required for ERC-4337 but not supported out-of-the-box.

class Parra extends Para {
  /// Signs raw bytes by directly accessing the Capsule JS bridge
  /// This bypasses Para's string-only signMessage API
  ParaFuture<SignatureResult> signMessageRaw({
    required String walletId,
    required String messageBase64,  // Base64-encoded bytes
  }) {
    // Direct JS bridge call with proper keyshare loading
  }
}

Key Features:

  • Direct access to Capsule's signing infrastructure
  • Base64 encoding for byte transport
  • Automatic transmission keyshare loading
  • Proper error handling

2. ParaSigner Class (MSI Implementation)

Implements the MultiSignerInterface (MSI) from web3_signers, making Para compatible with Variance and other Ethereum libraries.

class ParaSigner extends MSI {
  final Parra client;
  final para.Wallet _wallet;

  @override
  Future<Uint8List> personalSign(Uint8List hash, {int? index}) async {
    // EIP-191 implementation with Para signing
  }

  @override
  Future<MsgSignature> signToEc(Uint8List hash, {int? index}) async {
    // ECDSA signature for transaction signing
  }
}

Key Features:

  • EIP-191 compliant personal message signing
  • EIP-712 typed data signing support
  • Signature verification
  • V value normalization (0/1 β†’ 27/28)

3. Smart Account Factory

Creates and manages ERC-4337 Safe smart accounts.

static Future<SmartWallet> createSafeAccount(
  Parra client,
  para.Wallet wallet,
  Chain chain,
  Uint256 salt,
) async {
  final signer = ParaSigner.fromWallet(client, wallet);
  final factory = SmartWalletFactory(chain, signer);
  return await factory.createSafeAccount(salt);
}

πŸš€ Quick Start

Step 1: Initialize Para

import 'package:para/para.dart';
import 'parra.dart';  // Your custom extension

Future<Parra> initializePara() async {
  final para = Parra(
    environment: Environment.beta,
    apiKey: 'your_api_key',
    appScheme: 'myapp',
  );

  return para;
}

Step 2: Authenticate User

Future<para.Wallet> authenticateUser(Parra client) async {
  // OAuth authentication
  final authResult = await client.verifyOAuth(
    provider: OAuthProvider.google,
  );

  if (authResult.stage == AuthStage.login) {
    // User authenticated, get wallet
    final wallets = await client.getWallets();
    return wallets.first;
  }

  throw Exception('Authentication failed');
}

Step 3: Create Smart Account

import 'package:variance_dart/variance_dart.dart';
import 'para_signer.dart';

Future<SmartWallet> createSmartAccount(
  Parra paraClient,
  para.Wallet paraWallet,
) async {
  // Configure chain
  final chain = Chain(
    chainId: 84532,  // Base Sepolia
    rpcUrl: 'your_rpc_url',
    bundlerUrl: 'your_bundler_url',
    entrypoint: EthereumAddress.fromHex(
      '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
    ),
  );

  // Create smart account
  final smartWallet = await ParaSigner.createSafeAccount(
    paraClient,
    paraWallet,
    chain,
    Uint256.zero,  // Salt for deterministic address
  );

  print('Smart Account Address: ${smartWallet.address}');
  return smartWallet;
}

Step 4: Send Transaction

Future<String> sendTransaction(SmartWallet wallet) async {
  // Create transaction
  final tx = Contract.function(
    'transfer',
    EthereumAddress.fromHex('0xRecipient...'),
    amount: BigInt.from(1000000),  // 0.001 ETH
  );

  // Send via smart account
  final userOpHash = await wallet.sendUserOperation(tx);
  print('UserOp Hash: $userOpHash');

  // Wait for confirmation
  final receipt = await wallet.waitForUserOperationReceipt(userOpHash);
  print('Transaction Hash: ${receipt.transactionHash}');

  return receipt.transactionHash;
}

Our Solution

// 1. Encode bytes as base64 (string representation of bytes)
String messageBase64 = base64Encode(hash);  // "Op9f2b..."

// 2. Call Capsule JS bridge directly
final sig = await client.signMessageRaw(
  walletId: wallet.id!,
  messageBase64: messageBase64,  // Para decodes back to bytes internally
);

// 3. Capsule signs the actual bytes (not string)
// Result: Valid Ethereum signature βœ…

EIP-191 Personal Sign Implementation

Future<Uint8List> personalSign(Uint8List message) async {
  // 1. Add Ethereum message prefix
  final prefix = '\u0019Ethereum Signed Message:\n${message.length}';
  final prefixBytes = ascii.encode(prefix);

  // 2. Concatenate prefix + message
  final payload = prefixBytes.concat(message);

  // 3. Hash the complete payload
  final digest = keccak256(payload);

  // 4. Sign via Para (as base64)
  final sig = await client.signMessageRaw(
    walletId: _wallet.id!,
    messageBase64: base64Encode(digest),
  );

  // 5. Parse and normalize signature
  final sigBytes = hexToBytes(sig.signedTransaction);
  final r = sigBytes.sublist(0, 32);
  final s = sigBytes.sublist(32, 64);
  final v = 27 + sigBytes[64];  // Convert parity (0/1) to Ethereum v (27/28)

  return Uint8List.fromList([...r, ...s, v]);
}

Demo vido

https://github.com/user-attachments/assets/9fce562d-b8de-40eb-aec0-8d598ba81fc2

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors