Unity (C#) - Auth

Interacting with Particle Auth on Unity (Mobile) Using C#

Particle Auth for Unity (Mobile)

In addition to the Windows/macOS Unity SDK, Particle Auth also extends to standard Unity for Mobile platforms (through C#). This SDK includes all the standard functions required for initializing and interacting with Particle Auth to craft a Web2-adjacent onboarding flow within your Unity games.

Instructions setting up, and a rundown of some common functions and examples are covered below.


Getting Started

Prerequisites

Your Unity project needs to meet several requirements to avoid any compatibility issues. These requirements will be, in some capacity, dependent on the platform that you've decided to use. They are:

  • Unity 2020.3.26f1 or higher.
  • If you're using iOS:
    • Xcode 14.1 or higher.
    • CocoaPods 1.12.1 or higher.
    • iOS 14 or higher.
  • If you're using Android:
    • Minimum API level 23 or higher.
    • Targets API level 33 or higher.
    • Java SDK version 11.

Setting up the Particle dashboard

Once you've ensured that your project meets the above prerequisites, you'll also need three key values from the Particle dashboard: your projectId, clientKey, and appId. These connect your Unity project with the Particle dashboard, enabling customization, analytics, tracking, etc. To retrieve these, you'll need to head into the dashboard and create a new project, then a new application, as shown below:

  1. Sign up/log in to the Particle dashboard.

  1. Create a new project or enter an existing project.

  1. Create a new application, or skip this step if you already have one.

  1. Retrieve the project ID (projectId), the client key (clientKey), and the application ID (appId).

‎‎

‎‎

‎‎

‎‎

Configuration

With these values retrieved, you can move on to initial configuration and dependency management. This will vary in complexity depending on the platform in question. To begin, you'll need to download and install the Particle Unity package, which includes the necessary files for both Particle Connect and Particle Auth.

Head over to the particle-unity GitHub repository, and download the latest release (.unitypackage), then import it into your project.

iOS configuration

If you're building a Unity game on iOS, you must follow a specific configuration process to ensure that Particle Connect functions. The first step within this process is to set up a scheme URL within the Unity editor.

  1. Head into the iOS Player Settings menu (Edit -> Project Settings -> Player Settings -> iOS).
  2. From here, select Other, then scroll down to Configuration.
  3. Open the Supported URL schemes section, and within the Element 0 field, paste in your projectId with a prefix of pn.
    1. For example, if your projectId (from the Particle dashboard) is something like 63bfa427-cf5f-4742-9ff1-e8f5a1b9828f, then the scheme URL would be pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f.

📘

Remove other services, if needed

Within ParticleNetworkIOSBridge.cs, you'll have a number of services included in the SDK:

  • ParticleNetworkBase - required universally.
  • ParticleAuthService - required for Particle Auth.
  • ParticleWalletGUI - usage of the Particle Wallet UI, contains all services.
  • ParticleAuthCore - only if you're using Particle Auth Core.

You'll also need to configure your Podfile if you haven't already. If you don't have a Podfile, go to the root of your project directory and run pod init, which will generate a Podfile.

Open this Podfile, and insert the specific pods (services) you'd like to use within your project. In this case, ParticleConnect and CommonConnect will generally suffice, but additional services can be added if needed.

Additionally, you'll need to paste the code snippet below for installation handling:

pod 'ParticleWalletGUI'
// If you're using this, also include:
// pod 'SkeletonView', :git => 'https://github.com/SunZhiC/SkeletonView.git', :branch => 'main'

pod 'ParticleAuthService'

// Paste this
post_install do |installer|
installer.pods_project.targets.each do |target|
  target.build_configurations.each do |config|
  config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
 end

With your Podfile set, you'll need to run pod install and open your .xcworkspace file, such as is shown below:

pod install --repo-update

open {your project}.xcworkspace

Finally, for iOS, you'll need to formally use the projectId, clientKey, and appId previously retrieved. To do this, head into the root of your Xcode project and create a file, ParticleNetwork-Info.plist. Within this file, paste the following text (then replace the placeholders):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>PROJECT_UUID</key>
	<string>YOUR_PROJECT_UUID</string>
	<key>PROJECT_CLIENT_KEY</key>
	<string>YOUR_PROJECT_CLIENT_KEY</string>
	<key>PROJECT_APP_UUID</key>
	<string>YOUR_PROJECT_APP_UUID</string>
</dict>
</plist>

‎‎‎‎Follow the steps to configure your Xcode workspace.

  1. Download UnityManger.swift, Unity-iPhone-Bridging-Header.h and AppDelegate.swift from under github /Assets/Plugins/iOS/.Swift , Copy files into the root of your Xcode project. Xcode will ask you if auto create Bridging file, click yes.

  2. Make sure Build Settings, Swift Compiler - General, has Objective-C Bridging Header, its connect is Unity-iPhone-Bridging-Header.h 's local path.

  3. Remove main.mm under MainApp folder.

  4. Under /Assets/Plugins/iOS is NativeCallProxy files, they are requested by Unity to interact with iOS code. Remove code under Particle Wallet GUI if you don't need wallet service.

  5. In UnityManger.swift, it has implemented methods defined in NativeCallProxy.h.

  6. Select NativeCallProxy.h, in the file inspector, check public in Target Membership.

  7. If you want to use ParticleConnect, you should add LSApplicationQueriesSchemes to info.plist.

<key>LSApplicationQueriesSchemes</key>  
<array>  
    <string>metamask</string>  
    <string>phantom</string>  
    <string>bitkeep</string>  
    <string>imtokenv2</string>  
    <string>rainbow</string>  
    <string>trust</string>  
    <string>zerion</string>  
    <string>mathwallet</string>  
    <string>1inch</string>  
    <string>awallet</string>  
    <string>okex</string>  
</array>

Android configuration

Alternatively, if you're building your Unity game for Android, you'll just need to configure two files before you're ready to go. The first of these two files can be found at Assets/Plugins/Android/launcherTemplate.gradle within your project. Here, you'll need to ensure that you have the necessary dependencies.

Specifically, you'll need the following dependencies at a minimum:

  • network.particle:auth-serviceif you're planning on using Particle Auth Directly
  • network.particle:unity-bridge, required universally
  • The full list of network.particle packages can be found here.
dependencies {
    implementation project(':unityLibrary') 
    implementation "network.particle:auth-service:${sdkVersion}"
    implementation "network.particle:unity-bridge:${sdkVersion}"
  	implementation "network.particle:connect:${sdkVersion}"
  	// Other dependencies
}

‎‎

Finally, for Android, you'll need to place your projectId, clientKey, and appId within gradleTemplate.properties, found at Assets/Plugins/Android/gradleTemplate.properties.

particle.network.project_client_key=Your Client Key
particle.network.project_id=Your Project ID
particle.network.app_id=Your App ID

Initialization

Before you can call core functions within the SDK, you'll need to initialize ParticleNetwork. For the Unity SDK, this is handled by calling init on ParticleNetwork, which is derived from Network.Particle.Scripts.Core) and passing in information about the primary chain being used. This is generally pulled from a child of ChainInfo.

📘

The Particle Auth Unity SDK does not require authentication from the Particle dashboard.

ParticleNetwork.Init(ChainInfo.Ethereum); 

Add the prefab to your scene

Additionally, you'll need to ensure ParticleAuthService.prefab is added to your main scene. This is required as Particle Auth will not function otherwise. Below is a GIF showcasing an example of including ParticleAuthService.prefab.

-- placeholder for gif


Examples of Utilization

Login

With Particle Auth configured and included within your first scene, you can leverage Particle Auth to initiate the social login onboarding process and thus unlock the remaining functions within the SDK (post-login).

This is achieved and configured via ParticleAuthService.Instance.Login. Once this method is called, a corresponding login popup will be displayed requesting user authentication before returning to the application in a signed-in state.

ParticleAuthService.Instance.Login takes the following parameters:

  • loginType, the mechanism of social login to be thrown; such as email, Google, Twitter, etc.
    • LoginType.EMAIL
    • LoginType.PHONE
    • LoginType.GOOGLE
    • LoginType.FACEBOOK
    • LoginType.APPLE
    • LoginType.TWITTER
    • LoginType.DISCORD
    • LoginType.GITHUB
    • LoginType.TWITCH
    • LoginType.MICROSOFT
    • LoginType.LINKEDIN
    • LoginType.JWT
  • account, for predetermined/expected phone numbers or emails (optional). If you're using custom authentication with JWTs, this field is required with the expected JWT.
  • supportAuthTypes, the authentication types to be supported in the authentication popup, only applicable for LoginType.EMAIL and LoginType.PHONE. The types listed here will be available as additional buttons in the generalized popup within email and phone-based login.
    • SupportAuthType.NONE
    • SupportAuthType.APPLE
    • SupportAuthType.GOOGLE
    • SupportAuthType.FACEBOOK
    • SupportAuthType.DISCORD
    • SupportAuthType.GITHUB
    • SupportAuthType.TWITCH
    • SupportAuthType.MICROSOFT
    • SupportAuthType.LINKEDIN
    • SupportAuthType.PHONE
    • SupportAuthType.EMAIL
    • SupportAuthType.TWITTER
    • SupportAuthType.ALL
  • authorization, an optional field in which a message can be passed for signature upon login for added authorization.
// Authorization is an optional configuration that if filled out, will request an authentication signature upon login
var authorization = new LoginAuthorization("your message", false); // Hex string for EVM, base58 for Solana

await ParticleAuthService.Instance.Login(LoginType.EMAIL, null, SupportAuthType.ALL, SocialLoginPrompt.SelectAccount, authorization);

Logout

Once a user has been logged in, you can programmatically initiate logout through ParticleAuthService.Instance.Logout.

await ParticleAuthService.Instance.Logout();

FastLogout

Alternatively, to log out while hiding specific UI elements that may marginally slow the logout process (such as a loading animation), you can use ParticleAuthService.Instance.FastLogout().

await ParticleAuthService.Instance.FastLogout();

IsLogin

Whether or not a user is logged in may need to be retrieved, specifically in cases where a user stays logged in after refreshing an application due to the continuation of a given session. To check the currently active login status, you can call ParticleAuthServiceInteraction.IsLogin().

ParticleAuthServiceInteraction.IsLogin(); 

// Async/server-side
await ParticleAuthService.Instance.IsLoginAsync();

GetAddress

To retrieve the address of the currently active account (either EVM or Solana, depending on the previously selected chain), ParticleAuthServiceInteraction.GetAddress can be called.

ParticleAuthServiceInteraction.GetAddress();

SignMessage

Simple message signing can be achieved by calling ParticleAuthService.Instance.SignMessage and passing in a standard string (no need for encoding on this method) with the message you'd like to be prompted for signature.

var message = "Hello world";
await ParticleAuthService.Instance.SignMessage(message);

SignTransaction

Similarly, for signing a transaction, you'll need to call ParticleAuthService.Instance.SignTransaction and pass in a serialized (string) standard transaction object to be prompted for signature. This is a Solana-specific method.

var transaction = "your transaction";
await ParticleAuthService.Instance.SignTransaction(transaction);

SignAllTransactions

ParticleAuthService.Instance.SignAllTransactions is another Solana-specific method that functions adjacent to the former but instead signs multiple (a list of) transactions represented as strings.

var transaction1 = "transaction1";
var transaction2 = "transaction2";

string[] transactions = new[] { transaction1, transaction2 };
  
await ParticleAuthService.Instance.SignAllTransactions(transactions);

SignAndSendTransaction

ParticleAuthService.Instance.SignAndSendTransaction is the primary method within the SDK for sending transactions as it immediately sends a given transaction after requesting signature (confirmation). This will also take a serialized (string) representation of a transaction,

var transaction = "transaction";
  
var nativeResultData = await ParticleAuthService.Instance.SignAndSendTransaction(transaction);

SignTypedData

ParticleAuthService.Instance.SignTypedData is an EVM-specific method for signing structured (typed) data. ParticleAuthService.Instance.SignTypedData supports all versions of eth_signTypedData represented through SignTypedDataVersion.V{X}. For more information on signTypedData, see the Web (JavaScript/TypeScript) page.

string typedData = "your typedata";
  
await ParticleAuthService.Instance.SignTypedData(typedData, SignTypedDataVersion.V1);

SetChainInfo

If you'd like to set the primary chain after initial configuration, you'll need to use ParticleNetwork.SetChainInfo, which simply takes a chainInfo object parallel to the type of object passed into the original ParticleNetwork.Init call.

ParticleNetwork.SetChainInfo(_chainInfo);

// Asynchronous
await ParticleAuthService.Instance.SetChainInfoAsync(_chainInfo);

HasMasterPassword, HasPaymentPassword, HasSecurityAccount

Now that we've explored some general interaction examples, security options are also an important component of utilization, given you'd like either knowledge or control over the level of security a given user has opted in for on their account.

ParticleAuthServiceInteraction.HasMasterPassword will return a Boolean based on whether or not a user has set a master password (a non-recoverable password required upon every fresh login).

ParticleAuthServiceInteraction.HasPaymentPassword will return a Boolean based on whether or not a user has set a payment password (a pin required upon every transaction).

ParticleAuthServiceInteraction.HasSecurityAccount will return a Boolean based on whether or not the user has initialized a security account.

ParticleAuthServiceInteraction.HasMasterPassword();

ParticleAuthServiceInteraction.HasPaymentPassword();

ParticleAuthServiceInteraction.HasSecurityAccount();

GetSecurityAccount

ParticleAuthService.Instance.GetSecurityAccount retrieves the higher-level security account object corresponding with their underlying account; this contains information such as the presence of a master password (securityAccount.HasMasterPassword), a payment password (securityAccount.HasPaymentPassword), alongside the specific details of the account itself, such as the connected email (securityAccount.Email), phone (securityAccount.Phone), etc.

var nativeResultData = await ParticleAuthService.Instance.GetSecurityAccount();

if (nativeResultData.isSuccess) {
  var securityAccount = JsonConvert.DeserializeObject<SecurityAccount>(nativeResultData.data);
  var hasSecurityAccount = !string.IsNullOrEmpty(securityAccount.Email) || !string.IsNullOrEmpty(securityAccount.Phone);
  Debug.Log(securityAccount);
  Debug.Log($"HasMasterPassword {securityAccount.HasMasterPassword}, HasPaymentPassword {securityAccount.HasPaymentPassword}, HasSecurityAccount {hasSecurityAccount}");
}

Master reference

For a direct, raw view into every method provided through ParticleNetwork, ParticleAuthService, and ParticleAuthServiceInteraction, below is a table containing every relevant method, alongside specific parameters and a short description. For methods listed that weren't covered in the above examples, live implementation often mimics the common structure covered throughout this document.

ClassMethodsParameters (* indicates optional)
ParticleAuthServiceLoginloginType, account*, supportAuthTypes, socialLoginPrompt, authorization*
ParticleAuthServiceLoginCallBackjson
ParticleAuthServiceIsLoginAsync
ParticleAuthServiceIsLoginAsyncCallBackjson
ParticleAuthServiceLogout
ParticleAuthServiceLogoutCallBackjson
ParticleAuthServiceFastLogout
ParticleAuthServiceFastLogoutCallBackjson
ParticleAuthServiceSignMessagemessage
ParticleAuthServiceSignMessageCallBackjson
ParticleAuthServiceSignMessageUniquemessage
ParticleAuthServiceSignMessageUniqueCallBackjson
ParticleAuthServiceSetChainInfoAsyncchainInfo
ParticleAuthServiceSetChainInfoAsyncCallBackjson
ParticleAuthServiceSignTransactiontransaction
ParticleAuthServiceSignTransactionCallBackjson
ParticleAuthServiceSignAllTransactionstransactions
ParticleAuthServiceSignAllTransactionsCallBackjson
ParticleAuthServiceSignAndSendTransactiontransaction, feeMode*
ParticleAuthServiceSignAndSendTransactionCallBackjson
ParticleAuthServiceBatchSendTransactionstransactions, feeMode*
ParticleAuthServiceBatchSendTransactionsCallBackjson
ParticleAuthServiceSignTypedDatatypedData, signTypedDataVersion
ParticleAuthServiceSignTypedDataCallBackjson
ParticleAuthServiceOpenAccountAndSecurity
ParticleAuthServiceOpenAccountAndSecurityCallBackjson
ParticleAuthServiceInteractionLoginloginType, account*, supportAuthTypes, socialLoginPrompt, authorization*
ParticleAuthServiceInteractionIsLoginAsync
ParticleAuthServiceInteractionLogout
ParticleAuthServiceInteractionFastLogout
ParticleAuthServiceInteractionSignMessagemessage
ParticleAuthServiceInteractionSignMessageUniquemessage
ParticleAuthServiceInteractionSignTransactiontransaction
ParticleAuthServiceInteractionSignAllTransactionstransactions
ParticleAuthServiceInteractionSignAndSendTransactiontransaction, feeMode*
ParticleAuthServiceInteractionBatchSendTransactionstransactions, feeMode*
ParticleAuthServiceInteractionSignTypedDatamessage, signTypedDataVersion
ParticleAuthServiceInteractionSetChainInfoAsyncchainInfo
ParticleAuthServiceInteractionOpenAccountAndSecurity
ParticleNetworkInitchainInfo, env
ParticleNetworkSetChainInfochainInfo
ParticleNetworkGetChainInfo
ParticleNetworkSetAppearancestyle
ParticleNetworkSetLanguagelanguage
ParticleNetworkSetFiatCoinfiatCoin
ParticleNetworkSetSecurityAccountConfigconfig
ParticleNetworkSetWebAuthConfigdisplayWallet, appearance
ParticleNetworkCallNativemethodName, args
ParticleNetworkCallConnectNativemethodName, args
ParticleNetworkCallAuthCoreNativemethodName, args
ParticleNetworkGetUnityBridgeClass
ParticleNetworkGetUnityConnectBridgeClass
ParticleNetworkGetAuthCoreBridgeClass