React Native (JavaScript) - Auth

Interacting with Particle Auth within applications made using React Native

Particle Auth for React Native

For mobile applications, both iOS and Android, leveraging React Native for end-to-end interaction with Particle's Wallet-as-a-Service is possible through the utilization of the Particle Auth React Native SDK. The Particle Auth React Native SDK is largely adjacent to the Flutter (Dart) SDK. It enables the integration of Particle's Wallet-as-a-Service within mobile applications using JavaScript, providing a potentially more accessible alternative to mobile interaction with Particle Network.

Initial configuration guides, along with various examples of utilization, are detailed below.

Getting Started

The setup process for the Particle Auth React Native SDK is relatively straightforward but deviates depending on the platform in question. However, if you've used the other Particle Auth SDKs for mobile, the general flow will feel familiar, specifically if you've used the Particle Auth Flutter SDK.

Before diving into platform-specific configuration, all Particle Auth SDKs require three standard values for initialization: projectId, clientKey, and appId, all of which can be retrieved from the Particle dashboard.

  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 (corresponding with your platform of choice; iOS or Android in this case).

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

‎‎

‎‎

‎‎

Adding the Particle Auth React Native SDK to your application

Another constant in the setup process is the installation of @particle-network/rn-auth, either through npm or Yarn, depending on your preference.

npm install @particle-network/rn-auth

// Or

yarn add @particle-network/rn-auth


// Alternatively, to use Auth Core
npm install @particle-network/rn-auth-core

// Or

yarn add @particle-network/rn-auth-core

Android configuration

If you're planning on using Android for your React Native application, ensure you meet the following prerequisites (otherwise, expect issues or non-functionality):

  • Targets API Level 23 (Marshmallow) or higher.
  • Uses Android 6.0 or higher.
  • Uses Jetpack (Android X).
  • Uses Java 11.

Once you've made sure your project meets these requirements, you'll need to move on and define the aforementioned configuration values (projectId, clientKey, and appId) within your build.grade file (generally found at ${project name}/android/app/build.gradle). These directly link your application's instance of Particle Auth with the dashboard.

Specifically, within build.gradle, you'll need to set four different values:

  1. dataBinding, this should be enabled with enabled = true.
  2. manifestPlaceholders["PN_PROJECT_ID"], the projectId previously retrieved from the Particle dashboard.
  3. manifestPlaceholders["PN_PROJECT_CLIENT_KEY"], the clientKey previously retrieved from the Particle dashboard.
  4. manifestPlaceholders["PN_APP_ID"], the appId previously retrieved from the Particle dashboard.
android {
  ...
  defaultConfig {
      ......
      manifestPlaceholders["PN_PROJECT_ID"] = "your project id"
      manifestPlaceholders["PN_PROJECT_CLIENT_KEY"] = "your project client key"
      manifestPlaceholders["PN_APP_ID"] = "your app id"
  }
  
  dataBinding {
      enabled = true
  }

}

iOS configuration

Alternatively, if you plan to use iOS for your React Native application, the underlying setup process differs slightly. Before diving in, you'll need to ensure that your project meets the following requirements:

  • Xcode 15.0 or later.

  • iOS 14 or later.

With these requirements set, you'll need to open an exported iOS project and find ios/{project name}.xcworkspace.

At the root of your Xcode project, create a new file, ParticleNetwork-Info.plist. Ensure this is marked under "Target Membership."

From here, with a fresh ParticleNetwork-Info.plist file, go ahead and fill it in with the following:

<?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>

Similar to the Android configuration, you'll need to fill in PROJECT_UUID (projectId), PROJECT_CLIENT_KEY (clientKey), and PROJECT_APP_UUID (appId) with the corresponding values retrieved from the Particle dashboard.

Next, you'll need to head over to your AppDelegate file to add an import of react_native_particle_auth.

#import <react_native_particle_auth/react_native_particle_auth-Swift.h>

Additionally, within your application's application method (as shown below), you'll need to include a handler condition derived from ParticleAuthSchemeManager handleUrl:url. This should be as simple as a YES (true) return upon a truthy value of ParticleAuthSchemeManager handleUrl:url.

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  if ([ParticleAuthSchemeManager handleUrl:url] == YES) {
    return YES;
  } else {
    // other methods
  }
  return YES;
}

Wrapping up, you'll need to configure your application's scheme URL. To configure this, select your application from "TARGETS" under the "Info" section, then click "+" to add a URL type.

This should be set to "pn" + your projectId (retrieved and configured prior to this), resulting in a scheme URL that looks something like the following:

pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f

Finally, you'll need to edit your Podfile to align with the snippet below; this is required for all iOS projects that leverage Particle Auth.

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

📘

Specific note for using Expo

If you're working with Expo, your Podfile needs additional editing to ensure compatibility with Particle Auth, as below:

post_install do |installer|
  installer.pods_project.targets.each do |target|
  # Example for react-native-particle-auth package
    if target.name == 'ParticleNetworkBase' or 
       target.name == 'ParticleAuthService' or 
       target.name == 'CryptoSwift' or  
       target.name == 'SwiftyUserDefaults'
       target.build_configurations.each do |config|
            config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
end

Examples of utilization

Initialization

Now that you've configured the Particle Auth React Native SDK according to the platform you're using, you're ready to go ahead and initialize the SDK itself, unlocking the full extent of the SDK's functionality within your application. Initialization, in this case, is a two-step process, the first of which involves importing @particle-network/rn-auth, in this case as particleAuth.

import * as particleAuth from "@particle-network/rn-auth";

With @particle-network/rn-auth imported, you'll need to call the init function on your representation of @particle-network/rn-auth, which in this case is particleAuth. init takes the following parameters:

  • chainInfo, this refers to an object containing relevant information about the primary chain to be used. ChainInfo objects can be imported from @particle-network/chains.
  • env, imported from @particle-network/rn-auth, and can be either:
    • Env.Production
    • Env.Staging
    • Env.Dev
const chainInfo = Ethereum;
const env = Env.Production;
particleAuth.init(chainInfo, env);

Login

Onboarding a user with Particle's Wallet-as-a-Service (Particle Auth) happens through social login. This mechanism is controlled by particleAuth.login. Upon calling this method, depending on specific parameters, a popup will be displayed, prompting a user to sign in with a social account, thus leading to the generation and assignment of a wallet. particleAuth.login takes the following parameters:

  • type, the specific social login to be used. This can be either .email, .phone, .google, .apple, .jwt, or .facebook.
  • account, when type is set to either .email, .phone, or .jwt, you can use the account parameter to pass in an expected email, phone number, or JWT. This is optional for the former two but required for .jwt.
  • supportAuthType, the methods of authentication visible on the authentication popup UI. By default, this will be exclusive to the chosen social login method, although by passing in additional types, you can expand the UI to include the ability to log in with those as an alternative to type.
  • socialLoginPrompt, either 'none', 'consent', or 'select_account'.
  • authorization, optionally, a hex string prompting an authentication signature upon sign-in.
import type { LoginType, SupportAuthType } from '@particle-network/rn-auth'

const type = LoginType.Phone;
const supportAuthType = [SupportAuthType.All];

const userInfo = await particleAuth.login(type, '', supportAuthType);

Logout

An active session (logged-in user) can be disconnected (logged out) by simply calling one of two methods: Either particleAuth.logout for traditional logout, or particleAuth.fastLogout, which optimizes the logout process (removing any loading animations to disconnect a user as fast as possible).

await particleAuth.logout();

// Alternatively
await particleAuth.fastLogout();

Is Login

Another important method is particleAuth.isLogin. This method returns a Boolean indicating whether a user is logged in. This can be used as a condition on which to base the execution of particleAuth.login or particleAuth.logout.

const result = await particleAuth.isLogin();

Get Address

To retrieve the address of a currently logged-in user (EVM address if connected to an EVM chain, otherwise their Solana address), particleAuth.getAddress can be called. This will simply return a string containing the address of the user active within the session in which this method is called.

const address = await particleAuth.getAddress();

Get User Info

If a user has logged in, their user info (email, name, wallet addresses, and other key pieces of information) can be retrieved through particleAuth.getUserInfo. This same response will be automatically saved to a successful call of particleAuth.login.

const userInfo = await particleAuth.getUserInfo();

Sign Message

For the simple signature of a standard message (a string), particleAuth.signMessage can be used, passing in a raw string representing the message you'd like to be prompted for signature. Upon calling particleAuth.signMessage, a UI element will pop up requesting signature confirmation from the user.

const message = "GM, Particle!"
const result = await particleAuth.signMessage(message);

// Alternatively
const result = await particleAuth.signMessageUnique(message);

Sign Transaction

particleAuth.signTransaction is a Solana-exclusive method for signing a transaction without pushing it to the network. particleAuth.signTransaction simply takes a transaction string (can be a stringified object) representing a Solana transaction to be prompted for signature. Similarly to particleAuth.signMessage, this will prompt a user with a popup outlining transaction details and requesting signature confirmation.

const result = await particleAuth.signTransaction(transaction);

Sign All Transactions

Another Solana-exclusive method, particleAuth.signAllTransactions is the former but plural in that it takes an array of transactions (string representations) to be prompted for collective signature, without pushing them to the network.

const result = await particleAuth.signAllTransactions(transactions);

Sign And Send Transaction

particleAuth.signAndSendTransaction is the standard method available on EVM and Solana for sending a transaction. Alike particleAuth.signTransaction, this will take a transaction string (serialized) to be prompted for signature. Upon receiving a signature (the user pressing "Confirm" on the resulting popup), the transaction will be sent to the network.

// A transaction can either be manually constructed and serialized, 
// or you can use EvmService.createTransaction(from, data, amount, to)

const result = await particleAuth.signAndSendTransaction(transaction);

Sign Typed Data

particleAuth.signTypedData is an EVM-exclusive method for signing structured (typed) data, as opposed to a raw string with particleAuth.signMessage. This is a parallel method to eth_signTypedData, specifically supporting v1, v3, and v4.

particleAuth.signTypedData takes a string representing typed data to be prompted for signature (can be a stringified object) alongside the version of eth_signTypedData to be used.

const typedData = "[    {    \"type\":\"string\",    \"name\":\"Message\",    \"value\":\"Hi, Alice!\"    },    {    \"type\":\"uint32\",    \"name\":\"A nunmber\",    \"value\":\"1337\"    }]";

const version = "v1";

const result = await particleAuth.signTypedData(typedData, version);

Set Chain Info

If you'd like to switch chains post-login/initialization, you'll need to call either particleAuth.setChainInfo for synchronous (local) chain switching, or particleAuth.setChainInfoAsync for asynchronous (server-side) chain switching. These will override the original primary chain selected within theparticleAuth.init.

const chainInfo = SolanaDevnet;
const result = await particleAuth.setChainInfoAsync(chainInfo);

const result = await particleAuth.setChainInfo(chainInfo);

Get Chain Info

To retrieve an object containing the information for the currently connected chain, particleAuth.getChainInfo can be used.

const result = await particleAuth.getChainInfo();

Open Web Wallet

If you'd like to open the wallet modal within the browser (redirect if you're calling from an Android/iOS application), you can do so through particleAuth.openWebWallet. Particle Network has both an iOS and Android app, although the wallet web application contains most of the functionality present within those apps, but without requiring a specific downloads. If you'd like your users to have an interface to interact with the wallet outside of directly within your application, particleAuth.openWebWallet is an option.

See Particle Wallet for Web for a rundown of specific configuration options.

let webConfig = {
  supportAddToken: false,
  supportChains: [
      {
          id: 1,
          name: 'Ethereum',
      },
      {
          id: 5,
          name: 'Ethereum',
      },
  ],
};

const webConfigJSON = JSON.stringify(webConfig);
particleAuth.openWebWallet(webConfigJSON);

Open Account and Security Page

Wallets generated with Particle Auth can be subject to a plethora of security settings, including the linkage of additional social accounts, setting a master password, payment password, and so on. To provide a user with a general, all-encompassing interface in which all security and account settings can be accessed, you'll need to use particleAuth.openAccountAndSecurity.

particleAuth.openAccountAndSecurity();

Set Language

The language used within the modal (popups, wallet UI, security config, etc.) can also be changed; this is done with particleAuth.setLanguage and will take either "en", "zh_hans", "zh_hant", "ja", or "ko".

particleAuth.setLanguage(language);

Has Master Password, Payment Password, Security Account

Additionally, a Boolean representing whether or not a user has set a master password (password upon login), payment password (password upon state-changing signature), or security account (additional phone number or email set and verified for added authentication upon security changes) can be retrieved through two ways:

  • Local retrieval with particleAuth.hasMasterPassword, particleAuth.hasPaymentPassword, and particleAuth.hasSecurityAccount.
  • Through server-side retrieval with the parsing of particleAuth.getSecurityAccount.
// Local retrieval
const hasMasterPassword = await particleAuth.hasMasterPassword();
const hasPaymentPassword = await particleAuth.hasPaymentPassword();
const hasSecurityAccount = await particleAuth.hasSecurityAccount();

// Server-side retrival
getSecurityAccount = async () => {
  const result = await particleAuth.getSecurityAccount();
  if (result.status) {
      const securityAccount = result.data;
      const hasMasterPassword = securityAccount.has_set_master_password;
      const hasPaymentPassword = securityAccount.has_set_payment_password;
      const email = securityAccount.email;
      const phone = securityAccount.phone;
      const hasSecurityAccount = !email || !phone;
      console.log('hasMasterPassword', hasMasterPassword, 'hasPaymentPassword', hasPaymentPassword, 'hasSecurityAccount', hasSecurityAccount);
  } else {
      const error = result.data;
      console.log(error);
  }
}

In some cases, you may want a user to set a master password or payment password (perhaps both), and thus need to either suggest or force this upon them. To do this, you'll need to use particleAuth.setSecurityAccountConfig, passing in two integers:

  • promptSettingWhenSign, an integer in the range of 0 to 3 (inclusive).
  • promptMasterPasswordSettingWhenSign, an integer in the range of 0 to 3 (inclusive).

For both of these parameters, the specific integer chosen dictates the degree to which the user is suggested to set these passwords. With 0, these will never be suggested, 1 will suggest setting the corresponding password upon initial registration/login, 2 will show it upon every login (or for a payment password, for every signature), and 3 will force the user to go through the process of setting the password.

EvmService utilization examples

Also present within @particle-network/rn-auth is EvmService, an object for facilitating additional on-chain interaction, leveraging standard and enhanced RPC endpoints. EvmService can either be accessed through a complete (*) import (such as is shown above) by using particleAuth.EvmService.{method} or individually importing it from @particle-network/rn-auth.

📘

For a full list of methods available through EvmService, take a look at the EvmService SDK Reference.

Estimate Gas

Given a standard transaction structure (detached set of values, as shown below), gas estimation can be run to simulate and retrieve the volume of gas to be consumed by a specified transaction (wrapper for eth_estimateGas). This is done viaEvmService.estimateGas.

const result = await EvmService.estimateGas(from, to, value, data);

Get Suggested Gas Fees

To retrieve categorized gas price suggestions (3 categories scaling from low to high) based upon current network conditions, you can call EvmService.suggestedGasFees. This will return a JSON object containing the above data (useful for transaction construction).

const result = await EvmService.suggestedGasFee();

Get Tokens and NFTs

EvmService also extends to Data API methods such as getTokensAndNFTs, which returns a highly detailed JSON list of ERC20 tokens and ERC721 NFTs belonging to a specified address. This is accessible through calling EvmService.getTokensAndNFTs and passing in a given public address from which to retrieve the tokens and NFTs of.

const result = await EvmService.getTokensAndNFTs(publicAddress);

Get Transactions by Address

Similar to the former method, EvmService.getTransactionsByAddress enables the retrieval of a detailed JSON response containing the full list of transactions involving a specified address.

const result = await EvmService.getTransactionsByAddress(publicAddress);

Master reference

For a direct, raw view into every method provided through particleAuth, 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.

📘

ParticleAuth refers to the importation and complete assignment of @particle-network/rn-auth

In this above examples, this has been referred to by particleAuth.

ClassMethodsParameters (* indicates optional)
ParticleAuthinitchainInfo, env
ParticleAuthsetChainInfochainInfo
ParticleAuthgetChainInfo
ParticleAuthgetChainId
ParticleAuthsetChainInfoAsyncchainInfo
ParticleAuthlogintype, account, supportAuthType, socialLoginPrompt, authorization
ParticleAuthlogout
ParticleAuthfastLogout
ParticleAuthisLogin
ParticleAuthisLoginAsync
ParticleAuthsignMessagemessage
ParticleAuthsignMessageUniquemessage
ParticleAuthsignTransactiontransaction
ParticleAuthsignAllTransactionstransactions
ParticleAuthsignAndSendTransactiontransaction, feeMode
ParticleAuthbatchSendTransactionstransactions, feeMode
ParticleAuthsignTypedDatatypedData, version
ParticleAuthopenAccountAndSecurity
ParticleAuthgetAddress
ParticleAuthgetUserInfo
ParticleAuthsetModalPresentStylestyle
ParticleAuthsetMediumScreenisMediumScreen
ParticleAuthsetLanguagelanguage
ParticleAuthsetAppearanceappearance
ParticleAuthsetFiatCoinfiatCoin
ParticleAuthsetWebAuthConfigdisplayWallet, appearance
ParticleAuthopenWebWalletwebStyle
ParticleAuthsetSecurityAccountConfigpromptSettingWhenSign (int, 0-3), promptMasterPasswordSettingWhenSign (int, 0-3)
ParticleAuthhasMasterPassword
ParticleAuthhasPaymentPassword
ParticleAuthhasSecurityAccount
ParticleAuthgetSecurityAccount