Account Abstraction on Android

Particle Network’s AA SDK facilitates the comprehensive use of ERC-4337 account abstraction. Particle’s AA SDK handles every step in leveraging account abstraction: smart account deployment, user operation construction and sending, fee quote generation, etc., and is fully compatible with Android applications.


Getting Started

Installing, initializing, and ultimately using the Particle Network AA SDK for Android only takes a few steps.

Prerequisites

  • minSdkVersion 23 or higher.
  • compileSdkVersion, targetSdkVersion 34 or higher.
  • JavaVersion 17.
  • Jetpack (AndroidX).
  • Android Gradle Plugin Version: 8.5.1 or higher.
  • Gradle Version: 8.9 or higher.

The first is including the network.particle:aa-service dependency within your build.gradle file, filling in latest_version with the most recent release on Maven.

This should be defined in a way similar to the example below:

build.gradle
dependencies {
    implementation("network.particle:aa-service:${latest_version}")

    // https://search.maven.org/search?q=g:network.particle
    // ...
}

📘 Important details before initialization

Before initializing the SDK, there are a few key points to keep in mind, specifically regarding the utilization of Paymasters (to sponsor gas fees, pay for gas in ERC-20 tokens, etc.)

  • All Testnets automatically have the Verifying Particle Network Omnichain Verifying Paymaster enabled. Transactions that request it will automatically be sponsored and thus gasless.

  • On the occasion that you’d like to use the Particle Network Omnichain Verifying Paymaster for Mainnets, you’ll need to deposit USDT on either Ethereum or BNB Chain within the Particle dashboard. This USDT will then automatically be converted as needed into the native token of the network on which you’re requesting (and qualifying for) sponsorship.

  • The Particle Network AA SDK automatically uses Biconomy’s Token Paymaster; transactions that request it will be able to leverage it without additional configuration.


Initialization

With your project configured, you can move onto initializing the AA SDK. This is required before other SDK functions will work and allow you to select which smart account implementation you use. You can kickstart initialization through ParticleNetwork.initAAMode, which takes the following parameters:

E.g.:

Kotlin
ParticleNetwork.initAAMode(aaService = BiconomyV2AAService)

Enable AA Mode

Additionally, after initializing the SDK with initAAMode, you’ll need to intentionally enable it (signaling an updated address on the wallet interface, among other things) by using ParticleNetwork.getAAService().enableAAMode(). Alternatively, if it’s already enabled and you’d like to disable it, you can do so with disableAAMode.

If you’re unsure whether or not AA mode is enabled or not, you can retrieve a Boolean representing this status with isAAModeEnable.

E.g.:

Kotlin
ParticleNetwork.getAAService().enableAAMode()

ParticleNetwork.getAAService().disableAAMode()

val isEnable = ParticleNetwork.getAAService().isAAModeEnable()

Send Transaction

Sending a standard transaction (UserOperation after enabling AA mode), requesting a signature, and then automatically pushing it to the network with ParticleNetwork can be done through ParticleNetwork.signAndSendTransaction, which takes the following parameters:

  • transaction, a stringified standard transaction object.
  • callback, return handling.
  • feeMode, the mechanism to be used for paying gas fees, can be:
    • FeeModeGasless, for sponsored transactions. This will happen automatically for Testnets, pulling from your previously defined (or configured) Paymaster for Mainnets.
    • FeeModeNative, native payments.
    • FeeModeToken, enables the selection of a specific mechanism, takes one parameter:
      • feeQuote, to be used when leveraging a Token Paymaster, can be retrieved through ParticleNetwork.getAAService().rpcGetFeeQuotes().

Additionally, if you’re using Particle Connect, you can send the same type of transaction by calling the signAndSendTransaction method on a relevant adapter. This takes the same parameters, although it requires passing the publicAddress of the targeted user for the transaction.

Kotlin
val feeModeGasLess: FeeMode = FeeModeGasless()
val transaction = "your transaction"
val feeQuote = ParticleNetwork.getAAService().rpcGetFeeQuotes("eoa address", listOf(transaction)).result
val feeModeNative: FeeMode = FeeModeNative(verifyingPaymasterNative =feeQuote.verifyingPaymasterNative )
val feeModeToken: FeeMode = FeeModeToken(feeQuote.tokenPaymaster.feeQuotes[0], feeQuote.tokenPaymaster.tokenPaymasterAddress)
AuthCore.evm.sendTransaction(transaction, object : AuthCoreSignCallback<SignOutput> {
    override fun success(output: SignOutput) {
        // success output.signature
    }

    override fun failure(errMsg: ErrorInfo) {
        // Handle error
    }
}, feeModeGasLess) //feeModeNative or feeModeToken

// Alternatively, if using Particle Connect
connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeGasLess, callback)

connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeToken, callback)

connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeToken, callback)

Send Batch Transactions

As an alternative to signAndSendTransaction, you can use quickSendTransaction to batch multiple transactions together within a single UserOperation. quickSendTransaction requires the following parameters:

  • transactions, an array of stringified transaction objects.
  • feeMode, the mechanism for paying gas fees.
  • messageSigner, the owner/Signer address that’ll be signing the UserOperation.
  • callback, return handling.

E.g.:

Kotlin
ParticleNetwork.getAAService().quickSendTransaction(transactions, feeMode, messageSigner, callback)

Master reference

For a direct, raw view into every method provided, below is a table containing every relevant one, alongside specific parameters and a short description. For methods listed that weren’t covered in the above examples, live implementation often mimics the previously covered common structure throughout the SDK.

MethodsParameters
rpcGetSmartAccountaddresses: List<String>
rpcGetFeeQuoteseoaAddress: String, transactions: List<PrefixedHexString>
rpcCreateUserPaidTransactioneoaAddress: String, transactions: List<PrefixedHexString>, erc4337FeeQuote: Erc4337FeeQuote
rpcSendUserPaidTransactioneoaAddress: String, walletTransaction: WalletTransaction, signature: String
rpcSendGaslessTransactioneoaAddress: String, userOp: WalletUserOp, signature: String
rpcCreateGaslessTransactioneoaAddress: String, transactions: List<PrefixedHexString>
isDeployeoaAddress: String
deployWalletContractmessageSigner: MessageSigner, feeMode: FeeMode*
isAAModeEnable
enableAAMode
disableAAMode
getSmartAccounteosAddress: String
getSmartAccountSynceosAddress: String
getSmartAddresseosAddress: String
getSmartAccountseosAddresses: List<String>
isSupportChainInfochainInfo: ChainInfo
getSupportChainInfos
quickSendTransactiontransactions: String, feeMode: FeeMode\*, messageSigner: MessageSigner, sendCallback: WebServiceCallback<SignOutput>*
quickSendTransactiontransactions: List<String>, feeMode: FeeMode*, messageSigner: MessageSigner, sendCallback: WebServiceCallback<SignOutput>*