Particle Wallet for React Native

Particle Wallet is a central wallet interface facilitating interaction with both social logins (via Particle Auth) and external Web3 wallets. Particle Wallet works closely with Particle Connect to provide a standard UI for the utilization of associated/connected accounts. Particle Wallet is built to be relatively application-specific through significant customization potential and built-in modularization.

Configuration and utilization processes are detailed below.

Repository

Before jumping in, it may be worth looking at the Particle Wallet React Native GitHub repository to contextualize the SDK with a preliminary understanding of the underlying architecture and implementation flow by viewing the source code alongside included demos.


Getting Started

The setup process for the Particle Wallet React Native SDK is quite similar to the Particle Auth and Particle Connect setup process, although it deviates slightly.

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

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

Adding the Particle Wallet React Native SDK to your application

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

Terminal
npm install @particle-network/rn-wallet

// Or

yarn add @particle-network/rn-wallet

Android configuration

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

  • 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. (before react-native:0.75.2, use 8.8)

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 Connect 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.
build.gradle
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

To use iOS for your React Native application, 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:

ParticleNetwork-Info.plist
<?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.swift file to add an import of react_native_particle_connect, which Particle Wallet depends on in a large capacity.

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

AppDelegate.swift
#import <react_native_particle_connect/react_native_particle_connect-Swift.h>

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  if ([ParticleConnectSchemeManager 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 simply be set to “pn” + your projectId (retrieved and configured prior), resulting in a scheme URL that looks something like the following:

pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f

Additionally, head over to your Info.plist file and include the following snippet.

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>oneinch</string>
<string>awallet</string>
<string>okex</string>
<string>bnc</string>
</array>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access in order to open photos of barcodes</string>
<key>NSCameraUsageDescription</key>
<string>We use the camera to scan barcodes</string>
<key>NSFaceIDUsageDescription</key>
<string>We use Face ID for secure access to the app.</string>

Finally, you’ll need to edit your Podfile to ensure particle_connect (which, as mentioned, Particle Wallet depends on) is properly imported. Head over to the linked guide to complete this if you have not already.


Examples of Utilization

Initialization

The Particle Wallet SDK won’t function until initialization occurs. This will set several key parameters used and required by the wallet interface. Specifically, this is done through particleWallet.initWallet, which takes one parameter, walletMetaData. This should a DappMetaData object containing:

  • walletConnectProjectId, your WalletConnect project ID retrieved from the WalletConnect dashboard.
  • name, the name of your project.
  • icon, your project’s logo - ideally 512x512.
  • url, the URL of your project’s website.
  • description, a brief description of your project.
  • Optionally, redirect and verifyUrl.

If you’re also using Particle Connect within the same file, you can call init, passing in chainInfo and env. For more information on Particle Connect, see the Particle Connect React Native SDK.

import * as particleWallet from '@particle-network/rn-wallet';
import * as particleConnect from '@particle-network/rn-connect';
import * as particleAuthCore from '@particle-network/rn-auth-core';

const chainInfo = Ethereum;
const env = Env.Dev;
const metaData = {
  walletConnectProjectId: 'Your WalletConnect Project ID, retrieved from https://cloud.walletconnect.com',
  name: 'Particle Connect',
  icon: 'https://connect.particle.network/icons/512.png',
  url: 'https://connect.particle.network',
  description: 'Particle Wallet',
};
particleConnect.init(chainInfo, env, metaData);
particleAuthCore.init();
particleWallet.initWallet(metaData);

Open Wallet

To programmatically force the main wallet page open, you can call particleWallet.navigatorWallet. navigatorWallet takes one parameter, a binary selection indicating whether tokens or NFTs are displayed within the main wallet page. WalletDisplay.token sets this to tokens, and WalletDisplay.nft to NFTs. E.g.:

const display = WalletDisplay.Token;
particleWallet.navigatorWallet(display);

Open Token Receive

particleWallet.navigatorTokenReceive opens a page dedicated to receiving tokens, through both a general address and a QR code. This takes one optional parameter, tokenAddress, that can change the associated QR code to be specific to a given token, including its icon at the center of the QR code image. E.g.

particleWallet.navigatorTokenReceive(tokenAddress);

Open Token Send

You can also open a page for sending tokens (ERC20/SPL/native) directly to other addresses. This can be done through particleWallet.navigatorTokenSend, optionally passing in the following parameters to predefine (fill in) specific values within the page:

  • tokenAddress, the contract address of the token to be sent, can be set to native for the default/native network token.
  • toAddress, the recipient’s address.
  • amount, the volume of tokenAddress that’ll be sent to toAddress.

E.g.

particleWallet.navigatorTokenSend(tokenAddress, toAddress, amount);

Open Transaction Records

It’s also quite simple to open a page containing transaction records (history) for a connected wallet: particleWallet.navigatorTokenTransactionRecords. If you’d like to filter these records only to show entries that include a specific token, then you can pass in a tokenAddress representing the token to be filtered. E.g.

particleWallet.navigatorTokenTransactionRecords(tokenAddress);

Open NFT Send

Alike navigatorTokenSend, you can use particleWallet.navigatorNFTSend to prompt a page for sending a specific NFT (defined by a mint/contractAddress and tokenId) to another address. navigatorNFTSend takes three parameters:

  • receiverAddress, the recipient’s address.
  • mint (also known as contractAddress), the address of the NFT contract to be sent.
  • tokenId, the token ID for the specific NFT associated with mint. This can be set as null for Solana.

E.g.

particleWallet.navigatorNFTSend(receiverAddress, mint, tokenId);

Open NFT Details

To open the details of a specific NFT (image, attributes, description, etc.) on-screen, you’ll need to call particleWallet.navigatorNFTDetails by passing in mint (contractAddress) and the associated tokenId that you’d like to view. E.g.

particleWallet.navigatorNFTDetails(mint, tokenId);

Open Buy Crypto

Open Buy Crypto

Particle Wallet also has a native onramp aggregator, allowing users to bring fiat on-chain through various onramp providers. Opening this programmatically can happen through ParticleWallet.navigatorBuyCrypto, passing in several optional parameters to customize the values used within the onramp. Upon calling, this will return a popup or total redirect over to a configuration of https://ramp.particle.network.

The specific parameters that can be used within ParticleWallet.navigatorBuyCrypto are listed below:

FieldTypeDescription
walletAddressstring?(Optional) The wallet address to receive the cryptocurrency, default is current user address.
cryptoCoinstring?(Optional) Cryptocurrency denomination. Default is current chain native token symbol.
fiatCoinstring?(Optional) Fiat currency denomination. Default is current fiat coin.
fiatAmtint?(Optional) The amount of fiat to be automatically filled in as the purchase volume.
chainInfoChainInfo?(Optional) The chainInfo, default is current chainInfo.
fixFiatCoinboolean(Optional) Lock selection of fiat coin in the buy menu, default is false.
fixFiatAmtboolean(Optional) Lock selection of fiat amount in the buy menu, default is false.
fixCryptoCoinboolean(Optional) Lock selection of crypto coin in the buy menu, default is false.
themestring?(Optional) The buy page theme, dark or light, default is curreny appearance.
languageLanguage?(Optional) The buy page lanuage, default is current language.
const config = {
  walletAddres: '0xa0869E99886e1b6737A4364F2cf9Bb454FD637E4',
  cryptoCoin: 'BNB',
  fiatCoin: 'USD',
  fiatAmt: 1000,
  chainInfo: Polygon,
  fixFiatCoin: true,
  fixCryptoCoin: true,
  fixFiatAmt: true,
  theme: 'dark',
  language: Language.JA
};

particleWallet.navigatorBuyCrypto(config);

Open Swap

Particle Wallet features a built-in swap widget, aggregating multiple providers such as 1inch to initiate and execute swaps. This widget/interface can be thrown by using particleWallet.navigatorSwap, and optionally passing in the following parameters (can work without them):

FieldTypeDescription
fromTokenAddressstring?(Optional) The swap pair from token address
toTokenAddressstring?(Optional) The swap pair to token address
amountstring?(Optional) The swap from token amount, should pass the minimal unit string, for example 0.01 ETH, it’s decimals is 18, should pass “10000000000000000”

E.g.:

particleWallet.navigatorSwap(fromTokenAddress, toTokenAddress, amount);

Open DApp Browser

Particle Wallet also includes a dApp Browser, enabling users to open different dApps (web apps) and automatically connect with the account loaded into the instance of Particle Wallet. This enables account usage across any web-based dApp. This can be programmatically opened through particleWallet.navigatorDappBrowser, taking one parameter, url, which will dictate the specific site opened. E.g.:

particleWallet.navigatorDappBrowser("https://opensea.io");

Set Supported Chains

To set the specific supported chain(s) available within the chain selection menu on Particle Wallet, you can use ParticleWallet.setSupportChain, which takes an array of ChainInfo objects. Each object (representing different chains) will directly enable an additional chain within the wallet interface.

If you add a Testnet to this list and pass it to setSupportChain, you’ll also need to ensure that ParticleWallet.setShowTestNetwork is set to true (by passing in true). E.g.:

const chainInfos = [Ethereum, EthereumSepolia, PolygonAmoy];
    particleWallet.setSupportChain(chainInfos);

Switch Wallet

You can also switch the walletType being used within Particle Wallet. For example, if you’re using Metamask as a wallet type within Particle Wallet and would like to switch to Particle (social logins), this would be the method you’d use. You can initiate this switch through particleWallet.createSelectedWallet, passing in the new walletType object (of type WalletType), and the targeted user address of the current active session. E.g.

WalletType contains the following:

  • AuthCore, Particle Auth Core, an alternative to Particle Auth (Particle).
  • EvmPrivateKey, custom EVM wallet imports/exports.
  • SolanaPrivateKey, custom Solana wallet imports/exports.
  • MetaMask.
  • Rainbow.
  • Trust.
  • ImToken.
  • Bitget.
  • WalletConnect.
  • Phantom, intended for Solana.
  • Zerion.
  • Math.
  • Inch1, 1inch.
  • Zengo.
  • Alpha.
  • Bitpie.
  • OKX.
  • TokenPocket, not supported by iOS.
particleWallet.createSelectedWallet(account.publicAddress, WalletType.AuthCore, "Custom Wallet Name");

Set Wallet Name

You can customize the wallet name and icon by particleWallet.setCustomWalletName,

FieldTypeDescription
namestringWallet name, for Android, you need call createSelectedWallet to customize the wallet name after particle wallet connected
iconstringWallet icon, a uri such as https://example.com/icon.png
particleWallet.setCustomWalletName('My Wallet', "https://example.com/icon.png")

Set Custom Localizable

You can use custom localization strings. For example, when customizing a wallet name, you need to update the localization strings with method particleWallet.setCustomLocalizable. This method only support iOS,

if (Platform.OS === 'ios') {
      // use language code in type Language
      const localizables: any = {
        'en': {
          "network fee": "Service Fee",
          "particle auth wallet": "Playbux Wallet"
        },
      };

      console.log()

      particleWallet.setCustomLocalizable(localizables);
    }

Custom UI

Particle Wallet can also undergo additional customization, specifically regarding which UI elements are shown and how. Each of these configurations are accessed through a unique method on particleWallet (@particle-network/rn-wallet). These methods include (but are not limited to):

  • setSwapDisabled, whether or not the “Swap” functionality is displayed within the interface. This takes one parameter, either true or false, with the default being false.

  • setPayDisabled, whether or not the “Buy” functionality is displayed within the interface. This takes one parameter, either true or false, with the default being false.

  • setBridgeDisabled, whether or not the “Bridge” functionality is displayed within the interface. This takes one parameter, either true or false, with the default being false.

  • setDisplayTokenAddresses, an synchronous function to set specific token addresses to be displayed in the Particle Wallet. It takes an array of token addresses as a parameter, tokenAddresses.

  • setDisplayNFTContractAddresses, an synchronous function for setting specific NFT contract addresses to be displayed in the Particle Wallet. This function accepts an array of NFT contract addresses, nftContractAddresses.

  • setPriorityTokenAddresses, an synchronous function that prioritizes certain token addresses to appear at the top of lists within the Particle Wallet. It requires an array of token addresses, tokenAddresses.

  • setPriorityNFTContractAddresses, an synchronous function to prioritize specific NFT contract addresses in the Particle Wallet, making them appear at the top of lists. It takes an array of NFT contract addresses, nftContractAddresses.

  • setShowLanguageSetting, an synchronous function to toggle the visibility of the language setting option in the Particle Wallet. It takes a Boolean value, true or false.

  • setShowAppearanceSetting, an synchronous function that controls the display of the appearance setting in the Particle Wallet. It accepts a Boolean parameter, either true or false.

  • setSupportAddToken, an synchronous function to toggle the option to add tokens in the Particle Wallet. It takes a Boolean value of true or false.

  • setSupportWalletConnect, an synchronous function set whether WalletConnect is supported on the wallet page. It takes a boolean value, true or false.

  • setSupportDappBrowser, configures the availability of the dApp browser feature. It accepts a boolean parameter, true or false.

E.g.

particleWallet.setDisplayTokenAddresses(tokenAddresses);

particleWallet.setDisplayNFTContractAddresses(nftContractAddresses);

particleWallet.setPriorityTokenAddresses(tokenAddresses);

particleWallet.setPriorityNFTContractAddresses(nftContractAddresses);

particleWallet.setShowLanguageSetting(false);

particleWallet.setShowAppearanceSetting(false);

particleWallet.setSupportAddToken(false);