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

# Account Abstraction

> Gasless and batched EVM transactions on Flutter using Alchemy smart accounts backed by Para

export const Card = ({imgUrl, title, description, href, horizontal = false, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  const handleClick = e => {
    e.preventDefault();
    if (newTab) {
      window.open(href, '_blank', 'noopener,noreferrer');
    } else {
      window.location.href = href;
    }
  };
  return <div className={`not-prose relative my-2 p-[1px] rounded-xl transition-all duration-300 ${isHovered ? 'bg-gradient-to-r from-[#FF4E00] to-[#874AE3]' : 'bg-gray-200'}`} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      <a href={href} onClick={handleClick} className={`not-prose flex ${horizontal ? 'flex-row' : 'flex-col'} font-normal h-full bg-white overflow-hidden w-full cursor-pointer rounded-[11px] no-underline`}>
        {imgUrl && <div className={`relative overflow-hidden flex-shrink-0 ${horizontal ? 'w-[30%] rounded-l-[11px]' : 'w-full'}`} onClick={e => e.stopPropagation()}>
            <img src={imgUrl} alt={title} className="w-full h-full object-cover pointer-events-none select-none" draggable="false" />
            <div className="absolute inset-0 pointer-events-none" />
          </div>}
        <div className={`flex-grow px-6 py-5 ${horizontal ? 'w-[70%]' : 'w-full'} flex flex-col ${horizontal && imgUrl ? 'justify-center' : 'justify-start'}`}>
          {title && <h2 className="font-semibold text-base text-gray-800 m-0">{title}</h2>}
          {description && <div className={`font-normal text-gray-500 re leading-6 ${horizontal || !imgUrl ? 'mt-0' : 'mt-1'}`}>
              <p className="m-0 text-xs">{description}</p>
            </div>}
        </div>
      </a>
    </div>;
};

The Flutter SDK can spin up an Alchemy smart account for any EVM wallet your user holds. The Para wallet signs; the smart account is what shows up on-chain. You get gas sponsorship through Alchemy's Gas Manager and atomic batched calls through the Account Kit.

<Note>
  Only Alchemy (EIP-4337) is wired through the native bridge today. ZeroDev, Pimlico, and the other providers already available on web and React Native are on the roadmap for Flutter.
</Note>

## Setup

1. Create an [Alchemy account](https://dashboard.alchemy.com/signup), grab your **API key**, and create a Gas Manager **policy** for the chain you're targeting. The policy ID is what tells the paymaster to sponsor gas.

2. Drop the values into your `.env` file. `flutter_dotenv` is already wired into the Flutter example:

```bash .env theme={null}
ALCHEMY_API_KEY=your_alchemy_api_key
ALCHEMY_GAS_POLICY_ID=your_gas_policy_id
```

You don't need to add a pub.dev dependency. The Flutter SDK reaches `@getpara/aa-alchemy` through the bridge on the web side.

## Usage

Create the smart account, then send a gasless transaction with it:

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

// `para` is your authenticated Para instance
final info = await para.createSmartAccount(
  apiKey: dotenv.env['ALCHEMY_API_KEY']!,
  chainId: 11155111, // Sepolia
  gasPolicyId: dotenv.env['ALCHEMY_GAS_POLICY_ID'],
);
print('Smart account: ${info.smartAccountAddress}');

// Zero-value tx to the burn address, paid for by the paymaster.
final receipt = await para.sendSmartAccountTransaction(
  smartAccountAddress: info.smartAccountAddress,
  chainId: 11155111,
  to: '0x000000000000000000000000000000000000dEaD',
);
print('tx: ${receipt.transactionHash}, status: ${receipt.status}');
```

Heads up on timing: UserOp inclusion on a public chain usually lands in 30 to 90 seconds, and the call blocks until it does. `ParaConfig.requestTimeout` defaults to 120s for this reason. Override it when you build your `ParaConfig` if you'd rather bail earlier.

### Batched transactions

One UserOp, multiple calls, one receipt. Use it for approve + swap, approve + transfer, or anything that should succeed or fail together:

```dart theme={null}
final batchReceipt = await para.sendSmartAccountBatchTransaction(
  smartAccountAddress: info.smartAccountAddress,
  chainId: 11155111,
  calls: [
    SmartAccountCall(to: '0xRecipientA', value: '10000000000000000'), // 0.01 ETH
    SmartAccountCall(to: '0xRecipientB', data: '0xEncodedCallData'),
  ],
);
```

### Error handling

Provider failures come back with a `SmartAccountErrorCode` from `@getpara/core-sdk`. The ones you're most likely to see:

* `PROVIDER_RATE_LIMITED`: back off and retry.
* `SPONSORSHIP_DENIED`: the gas policy rejected this UserOp. Check the Alchemy dashboard.
* `TRANSACTION_REVERTED`: the target contract reverted at execution time.
* `MISSING_ACCOUNT_ADDRESS`: you called `sendSmartAccountTransaction` before `createSmartAccount` for this chain + address.

Errors surface as `ParaBridgeException` and keep the provider's original message.

## What gets returned

`createSmartAccount` returns a `SmartAccountInfo`:

```dart theme={null}
class SmartAccountInfo {
  final String smartAccountAddress;
  final String mode;        // "4337"
  final String provider;    // "ALCHEMY"
  final int chainId;
}
```

`sendSmartAccountTransaction` and `sendSmartAccountBatchTransaction` return an `AATransactionReceipt`:

```dart theme={null}
class AATransactionReceipt {
  final String transactionHash;
  final String blockHash;
  final String blockNumber;       // uint256, decimal string
  final String from;
  final String? to;
  final String status;            // "success" or "reverted"
  final String gasUsed;
  final String effectiveGasPrice;
}
```

BigInt fields arrive as decimal strings so you don't lose `uint256` precision across the bridge.

## Reference

Full working implementation: [`examples-hub/mobile/with-flutter/lib/features/smart_account/smart_account_screen.dart`](https://github.com/getpara/examples-hub/tree/3.0.0/mobile/with-flutter/lib/features/smart_account).
