Particle Auth for Android

The Particle Auth Android SDK is the flagship mechanism for integrating Particle’s Wallet-as-a-Service within Android applications. This SDK is the sole facilitator of Android integration for most applications and is built for simplicity.

As with the other Particle Auth SDKs, it requires only a few lines of code.

Unlike the Unity SDK and Web SDK, the Android SDK differs in installation and configuration; these specific intricacies and setup processes are detailed below.


Getting Started

Using the Particle Auth Android SDK is straightforward but requires meeting a few minimum version prerequisites to ensure compatibility.

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.

Configuration

Before you begin using the Particle Auth Android SDK, you’ll need a few required universal values across all Particle Auth SDKs.

These values are projectId, clientKey, and appId. All three can be retrieved by heading to the Particle dashboard.

Follow the quickstart tutorial to set up a project and find the required keys: Create a new project.

Installation

Once you’ve created a project and application on the Particle Dashboard, you can install and initialize ParticleNetwork.

Start by declaring the Particle Auth SDK in your Gradle file.

Kotlin
repositories {
  google()
  mavenCentral()
  maven { setUrl("https://jitpack.io") }
  //...
}

dependencies {
   modules {
        module("org.bouncycastle:bcprov-jdk15to18") {
            replacedBy("org.bouncycastle:bcprov-jdk15on")
        }
        module("org.bouncycastle:bcprov-jdk18on") {
            replacedBy("org.bouncycastle:bcprov-jdk15on")
        }
    }
  implementation("network.particle:auth-core:${latest_version}")

  // Find the latest version of the SDK:
  // https://search.maven.org/search?q=g:network.particle
}

For release updates, subscribe to the GitHub repository.

Additionally, you’ll need to declare specific configurations, such as inserting values above projectId, clientKey, and appId within the relevant AndroidManifest.xml file.

An example of such a configuration is attached below. Placeholders such as pn_project_id will need to be filled in.

XML
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="network.particle.wallet_plugin.example">
    <!-- AuthCore need add android:fullBackupContent  -->
    <application
        tools:replace="android:fullBackupContent"
        android:fullBackupContent="@xml/pn_backup_rules"
        >

    <!-- Particle AuthCore Start -->
    <activity
        android:name="com.particle.auth.controller.AuthCoreWebActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:exported="true"
        android:launchMode="singleTask"
        android:theme="@style/ThemeAuthWeb">
        <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />

        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="ac${PN_APP_ID}" />
        </intent-filter>
    </activity>
    <!-- Particle AuthCore End -->

    <meta-data
        android:name="particle.network.project_id"
        android:value="${pn_project_id}" />

    <meta-data
        android:name="particle.network.project_client_key"
        android:value="${pn_project_client_key}" />

    <meta-data
        android:name="particle.network.app_id"
        android:value="${pn_app_id}" />

    </application>
</manifest>

Examples of utilization

Initialize the SDK

Upon application startup, ParticleNetwork must be initialized to function correctly.

This can be done by calling the init method on ParticleNetwork and passing in the primary chain you intend to use within your application.

Kotlin
class App : Application() {

  override fun onCreate() {
    super.onCreate()

    // Initialize Particle Auth SDK for Ethereum
    ParticleNetwork.init(this, Env.PRODUCTION, Ethereum)

    // If you're using Solana, initialization looks like this
    ParticleNetwork.init(this, Env.PRODUCTION, Solana)
  }
}

Switch Chain

To switch the chain after the initial configuration, use AuthCore.switchChain. This allows for asynchronous switching, just like the initial setup.

Kotlin
val chainInfo = ChainInfo.Polygon
AuthCore.switchChain(chainInfo, callback)

// For switching chains synchronously, without checking login status
ParticleNetwork.setChainInfo(chainInfo,callback)

Login

AuthCore.connect triggers the standard login popup, which changes based on configurations like loginType (similar to the Web SDK’s preferredAuthType) and supportAuthTypeValues.

This popup serves as the primary method for account creation and login for existing users.

The AuthCore.login function accepts the following parameters:

FieldTypeDescription
loginTypeLoginTypeSpecifies the preferred social login method. Options include EMAIL, PHONE, TWITTER, GOOGLE, FACEBOOK, APPLE, DISCORD, GITHUB, TWITCH, MICROSOFT, LINKEDIN, and JWT.
accountStringThe account parameter allows you to pass an expected email, phone number, or JWT. This field is optional for email and phone logins but required for JWT. The phone number must be in E.164 format.
supportLoginTypesList<SupportLoginType>Defines the supported social login methods. By default, all options are supported: EMAIL, PHONE, FACEBOOK, GOOGLE, APPLE, TWITTER, DISCORD, GITHUB, TWITCH, MICROSOFT, and LINKEDIN. You can also specify a subset of these types if needed.
promptLoginPrompt?Controls the prompt displayed after social login. Options are None, Consent, or SelectAccount. This is only supported by Google, Discord, and Microsoft.
loginPageConfigLoginPageConfig?Customizes the UI of the login page, including the project name, icon, and description.
loginCallbackAuthCoreServiceCallback<UserInfo>Callback triggered after the login attempt.

Success: Returns UserInfo.
Failure: Returns ErrorInfo.
You can use your existing user base or authentication method with Particle Auth through JWT. This way, your users can still log in with their current accounts. Check Custom Authentication (JWT) to learn how to configure it.
Kotlin
// Connect with Email or Phone
AuthCore.connect(LoginType.EMAIL, loginCallback = connectCallback)
AuthCore.connect(LoginType.PHONE, loginCallback = connectCallback)
// Connect with Google
AuthCore.connect(SocialLoginType.GOOGLE, prompt = LoginPrompt.SelectAccount,connectCallback)
// Connect with JWT
AuthCore.connect("JWT",connectCallback =connectCallback)

// Send verification code to email or phone number, the phone number must be in E.164 format.
AuthCore.sendCode(CodeReq(email = "xxx@xx.com"), callback)
AuthCore.sendCode(CodeReq(phone = "+11234567890"), callback)
// After sending the verification code, you can use the user-entered code to log in. With this approach, you can customize the UI and simply call our API for the login process.
AuthCore.connect(LoginReq(email = "xxx@xx.com", code = "Verification code received by the user"),connectCallback)
AuthCore.connect(LoginReq(phone = "+11234567890", code = "Verification code received by the user"),connectCallback)

val connectCallback = object :AuthCoreServiceCallback<UserInfo>{
    override fun success(output: UserInfo) {}
    override fun failure(errMsg: ErrorInfo) {}
}

UserInfo and Address Retrieval (post-login)

After a successful login, you can retrieve detailed user information by calling the following methods.

Kotlin
AuthCore.getUserInfo()
AuthCore.evm.getAddress()
AuthCore.solana.getAddress()

Logout

AuthCore.disconnect logs the user out of their current session and returns them to their pre-login state.

Kotlin
AuthCore.disconnect(object : ResultCallback {
  override fun success() {
    // Handle success
  }

  override fun failure() {
    // Handle error
  }
})

Is User Logged In

AuthCore.isLogin returns a Boolean indicating whether the user is currently logged in with Particle.

Kotlin
AuthCore.isConnected()

If the user logs in on another device, causing their token to become invalid, you can use syncUserInfo to synchronize the information.

try{
	val syncUserInfoStatus = AuthCore.syncUserInfo()
}catch(e:ServerException){
	//token is invalid
}

Signatures

Once ParticleNetwork has been initialized and a user has successfully logged in, signatures can be proposed for confirmation through a pop-up.

EVM

Signing Messages (EIP191)

To request an EIP191 signature from a user’s embedded wallet, you can use either the AuthCore.evm.personalSign or AuthCore.evm.personalSignUnique method.

If you need the same message to return a unique signature each time, use the AuthCore.evm.personalSignUnique method. Otherwise, the AuthCore.evm.personalSignmethod is generally recommended.

FieldTypeDescription
hexUnSignedMessagePrefixedHexStringA required field that accepts either a hexadecimal string starting with ‘0x’ or a human-readable string.
callbackAuthCoreSignCallback<SignOutput>Handles the response of the signing operation.
Success: Returns the signature.
Failure: Returns ErrorInfo.
signAndSendTransaction (Kotlin)
AuthCore.evm.personalSign(hexUnSignedMessage: PrefixedHexString, callback)
AuthCore.evm.personalSignUnique(hexUnSignedMessage: PrefixedHexString, callback)

Signing Typed Data V4 (EIP712)

To request an EIP712 signature from a user’s embedded wallet, you can use either the AuthCore.evm.signTypedData or AuthCore.evm.signTypedDataUnique method.

If you need the same message to return a unique signature each time, use the AuthCore.evm.signTypedDataUnique method. Otherwise, the AuthCore.evm.signTypedData method is generally recommended.

FieldTypeDescription
data PrefixedHexStringA hexadecimal string that must start with “0x”.
callbackAuthCoreSignCallback<SignOutput>Handles the response of the signing operation.
Success: Returns the signature.
Failure: Returns ErrorInfo.
signAndSendTransaction (Kotlin)
AuthCore.evm.signTypedData(data: PrefixedHexString, callback)
AuthCore.evm.signTypedDataUnique(data: PrefixedHexString, callback)

Transaction

To send a transaction from a user’s embedded wallet, you can use AuthCore.evm.sendTransaction.

FieldTypeDescription
transactionPrefixedHexStringA hexadecimal string that must start with “0x”.
callbackAuthCoreSignCallback<SignOutput>Handles the response of the signing operation.
Success: Returns the signature.
Failure: Returns ErrorInfo.
feeModeFeeModeThe mode for handling transaction fees. The default is FeeModeNative(). Use this field only when AA mode is enabled.
AuthCore.evm.sendTransaction(transaction: PrefixedHexString, callback: AuthCoreSignCallback<SignOutput>, feeMode: FeeMode = FeeModeNative())

You can create an EVM transaction using the ParticleNetwork.evm.createTransaction() method.

val tx = ParticleNetwork.evm.createTransaction()
val hexTx = tx.serialize()

Solana

Signing Messages

To request a signature from a user’s embedded wallet, use AuthCore.solana.signMessage.

FieldTypeDescription
messageStringA base58-formatted string that is required for the signature request.
callbackAuthCoreSignCallback<SignOutput>Handles the response of the signing operation.
Success: Returns the signature.
Failure: Returns ErrorInfo.
val message = Base58Utils.encodeFromString("This is the message that is being signed")
AuthCore.solana.signMessage(message, chainInfo: nil)

Transaction

To send a transaction from a user’s embedded wallet, use AuthCore.solana.signAndSendTransaction.

FieldTypeDescription
transactionStringA base58-formatted string that is required for the transaction.
callbackAuthCoreSignCallback<SignOutput>Handles the response of the transaction.
Success: Returns the signature.
Failure: Returns ErrorInfo.
AuthCore.solana..signAndSendTransaction(transaction: Base58String, callback: AuthCoreSignCallback<SignOutput>)

To sign a transaction from a user’s embedded wallet, use “AuthCore.solana.signTransaction`.

FieldTypeDescription
transactionStringA base58-formatted string is required.
callbackAuthCoreSignCallback<SignOutput>Success: Returns the signature.
Failure: Returns ErrorInfo.
AuthCore.solana..signTransaction(transaction: Base58String, callback: AuthCoreSignCallback<SignOutput>)

To sign multiple transactions from a user’s embedded wallet, use AuthCore. Solana.signAllTransactions.

FieldTypeDescription
serializedTransactionsList<Base58String>A list of base58-formatted strings is required.
callbackAuthCoreSignCallback<SignAllOutput>Success: Returns the signatures.
Failure: Returns ErrorInfo.
AuthCore.solana.signAllTransactions(transaction: Base58String, callback: AuthCoreSignCallback<SignAllOutput>)

Open Account and Security

If you want to force the “Account and Security” options to open on-screen—where you can manage master passwords, payment passwords, additional accounts, and more—call AuthCore.openAccountAndSecurity.

Kotlin
AuthCore.openAccountAndSecurity()

Set Security Account Config

Within the security settings, specific popups can be configured to display during confirmation or when entering the wallet UI.

These include promptSettingWhenSign for payment (signature) passwords and promptMasterPasswordSettingWhenLogin for a login-based master password.

By default, promptSettingWhenSign is set to 1, prompting the user on the first signature for a given account. If set to 0, the prompt is never shown; if set to 2, it is shown for every signature confirmation.

The same logic applies to promptMasterPasswordSettingWhenLogin, though it defaults to 0.

Kotlin
ParticleNetwork.setSecurityAccountConfig(
  SecurityAccountConfig(
      promptSettingWhenSign = 1,
      promptMasterPasswordSettingWhenLogin = 2
  )
)

Master Password and Payment Password

Users can set a master password and payment password to protect their assets. To set or change the master password, call auth.changeMasterPassword.

To set or change the payment password, call AuthCore.openAccountAndSecurity().

// Check if user has a master password set
val result = AuthCore.hasMasterPassword()
// Set or change master password
AuthCore.changeMasterPassword()

// Check if user has payment password set
val result = AuthCore.hasPaymentPassword()

Language Setting

You can force a specific language within the UI using ParticleNetwork.setLanguage and retrieve the currently active language with ParticleNetwork.getAppliedLanguage. The default language is English.

FieldTypeDescription
languageEnumLanguageEnumThe specific language to be used. Options include ZH_CN, ZH_TW, EN, JA, KO.
isRelaunchBooleanIf true, the app will relaunch upon a language switch; if false, the activity will be recreated.
isInitBooleanIf isRelaunch is set to true, isInit defaults to true. The activity will not be recreated and should be called before methods like signMessage or sendTransaction.
ParticleNetwork.setLanguage(LanguageEnum.EN)
ParticleNetwork.getLanguage()

Enable Blind Signing

Silently sign messages/transactions if the following conditions are met:

  1. Your account is connected via JWT.
  2. Your account does not have a payment password set.
  3. SecurityAccountConfig.promptSettingWhenSign is set to 0. You can update this value by calling ParticleNetwork.setSecurityAccountConfig.
AuthCore.setBlindEnable(true)
val result = AuthCore.getBlindEnable()