Android (Kotlin/Java)

Working with Particle Wallet within Android applications

Particle Wallet for Android

Particle Wallet is the primary interface outside of integrated applications for utilizing the account generated by Particle Auth or linked using Particle Connect. In short, Particle Wallet, for Android, is a standard wallet UI for sending, swapping, and purchasing cryptocurrency natively with your account (derived from a social login or Web3 wallet linkage). This wallet is highly customizable, meaning you can onboard users and facilitate interaction within your application while providing a shortcut to a customized instance of Particle Wallet.

Details regarding the programmatic usage of Particle Wallet can be found below.


Getting Started

Particle Wallet, on mobile, is a complimentary SDK to Particle Connect, enabling the unified utilization of accounts within Particle Connect. To begin working with Particle Wallet on Android, you must go through a quick initial configuration process.

Prerequisites

Before jumping in, several requirements are needed to avoid compatibility issues. Ensure your project meets or exceeds these minimum prerequisites before continuing.

  • Targets API Level 23 (Marshmallow) or higher.
  • Uses Android 6.0 or higher.
  • Uses Jetpack (AndroidX).

Setting up the Particle dashboard

Once your project meets the aforementioned requirements, you'll need to move onto retrieving three key (and universally required across all SDKs) values from the Particle dashboard.

These are your projectId, clientKey, and appId. During configuration, you'll need these to connect your project with the Particle dashboard, unlocking customization, analytics, tracking, etc. To retrieve these values, follow the process detailed below:

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

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

  1. Create a new Android 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 the dashboard setup, you'll also need to set up your build.gradle file to use the necessary dependencies. As mentioned, Particle Wallet is complimentary to Particle Connect, and thus, there are several requirements needed to use the wallet SDK, network.particle:wallet-service:

  • Modules org.bouncycastle:bcprov-jdk15to18 and org.bouncycastle:bcprov-jdk15on.
  • Particle Connect dependencies:
    • network.particle:auth-service.
    • network.particle:connect.
    • network.particle:connect-auth-adapter (or, for Auth Core, network.particle:connect-auth-core-adapter).
    • Other wallet adapters that you plan on using.
  • Particle Wallet SDK, network.particle:wallet-service.

The latest versions for these SDKs can be found on Maven.

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

dependencies {
    modules {
        module("org.bouncycastle:bcprov-jdk15to18") {
            replacedBy("org.bouncycastle:bcprov-jdk15on") 
        }
    }
  
  	implementation 'network.particle:auth-service:{latest-version}'
    implementation 'network.particle:connect:{latest-version}'
    
    implementation 'network.particle:connect-auth-adapter:${latest_version}'
    // implementation 'network.particle:connect-auth-core-adapter:${latest_version}'
 		// Other adapters, such as network.particle:connect-phantom-adapter
    
    implementation 'network.particle:api-service:${latest_version}'
    implementation 'network.particle:wallet-service:${latest_version}'
    // ...
}

Examples of Utilization

Initialization ***

Before you can use the full extent of the Particle Wallet SDK, you'll need to initialize ParticleWallet (imported from com.particle.gui.ParticleWallet) with ParticleWallet.init. Additional methods won't function until this happens. This method, init, takes a number of optional parameters:

  • supportChains, an array of ChainInfo objects dictating the chains available within the Particle Wallet interface.
  • setShowTestNetworks, whether or not test networks (Testnets) should be shown within the chain selection menu on Particle Wallet. This takes one parameter, true or false (false by default).
  • setShowManageWalletSetting, whether or not the "Manage Wallet" button within the Particle Wallet interface is shown. This takes one parameter, true or false (true by default).
  • hideMainBackIcon, removes the "Back" icon on the main wallet page.
  • setShowAppearanceSetting, if the appearance (dark/light mode) setting is shown and available to the user. It takes one parameter, true or false (true by default).
  • setSupportDappBrowser, whether or not the dApp browser is available within the wallet interface (custom browser instance using the account as a connection mechanism with dApps). It takes one parameter, true or false (true by default).
  • setWalletIcon, the icon/logo shown within the wallet interface. It takes one parameter, a string representing an icon URL.

E.g.:

ParticleWallet.init(
    context,
    supportChains,
).apply {
  setShowTestNetworkSetting(true) //default is false
  setShowManageWalletSetting(true) // default is true
  hideMainBackIcon() // hide the back icon in the main page
  setShowAppearanceSetting(true) //default is true
  setShowLanguageSetting(true) //default is true
  setSupportDappBrowser(true) //default is true
  setWalletIcon("https://xxx.xxx/xxx.png") //set the wallet icon
}

Custom Wallet UI ***

Once initialization is complete, you can apply additional customizations and configurations to Particle Wallet.

The first of these is the ability to apply initialization configurations (such as setShowTestNetworkSetting) after initial configuration through methods such as ParticleWallet.showTestNetworks(), ParticleWallet.hideManageWallet(), and so on.

Additionally, if you'd like to use a custom wallet within the Particle Wallet interface (for example, a wallet name, network, etc., specific to your project), then you'll need to use WalletInfo.createWallet to create a custom wallet object. This takes the following parameters:

  • address, the user's public address belonging to the current active session (connected via Particle Connect).
  • chainName, the name of the chain to be used within Particle Wallet.
  • chainId, the ID of the chain to be used within Particle Wallet.
  • ?
  • walletName, the name of your wallet/project to be shown in UI.
  • adapterName, the name of the adapter you're using for this wallet (such as MobileWCWalletName.Particle.name).

Saving this as an object, you can pass it into ParticleWallet.setWallet, changing the active interface/wallet according to the parameters outlined within WalletInfo.createWallet. E.g.:

// Post-initialization configuration
ParticleWallet.showTestNetworks()
ParticleWallet.hideManageWallet()

// Custom wallet configuration
val yourWalletName = "Your Wallet"
val wallet = WalletInfo.createWallet(
  ParticleNetwork.getAddress(),
  ParticleNetwork.chainInfo.name,
  ParticleNetwork.chainInfo.id,
  1,
  yourWalletName,
  MobileWCWalletName.Particle.name
)

ParticleWallet.setWallet(wallet)


// If you'd like, you can set your custom localizable string
// Overlay strings.xml  
YourProject/app/src/main/res/
  values/strings.xml
  values-ja-rJP/strings.xml
  values-ko-rKR/strings.xml
  values-zh-rCN/strings.xml
  values-zh-rHK/strings.xml
  values-zh-rTW/strings.xml
  
// Reassign a value
<string name="pn_network_fee">new NetworkFee</string>
<string name="pn_particle_auth_wallet">New Wallet</string>

Open Wallet

PNRouter, imported from com.particle.gui.router.PNRouter, can be used to programmatically open different components of Particle Wallet. To open the main wallet interface (the page displaying address, balance, tokens, and buttons leading to other pages), you'll need to call PNRouter.build, passing in RouterPath.Wallet (in which RouterPath is imported from com.particle.gui.router.RouterPath and dictates the page, or path, to be opened), then calling navigation. E.g.:

PNRouter.build(RouterPath.Wallet).navigation()

Open Send Token

To open the page coordinating sending a token (token referring to either native tokens or ERC20/SPL tokens), you can call PNRouter.build, passing in RouterPath.TokenSend. If you're sending an ERC20/SPL token, you'll need to fill in params- a WalletSendParams object (imported from com.particle.gui.ui.send.WalletSendParams) containing the following:

  • tokenAddress, the address of the token to be sent (required).
  • toAddress, the recipient address (optional).
  • toAmount, the amount to be sent (optional).

Otherwise, passing RouterPath.TokenSend alone without params will open the same page with the native token of the network selected.

val params = WalletSendParams(tokenAddress, toAddress?, toAmount?)
PNRouter.build(RouterPath.TokenSend, params).navigation()

PNRouter.build(RouterPath.TokenSend).navigation()

Open Receive Token

A page displaying both the user's address and an associated QR code can be opened through PNRouter.build, using RouterPath.TokenReceive. E.g.:

PNRouter.build(RouterPath.TokenReceive).navigation() 

Open Transaction Records

Transaction records (history) for ERC20/721 tokens, along with native tokens, can be programmatically opened through PNRouter.build, using RouterPath.TokenTransactionRecords. If you're specifically looking for a given token, you'll also need to use params, a TokenTransactionRecordsParams object (imported from com.particle.gui.ui.token_detail.TokenTransactionRecordsParams) containing a given tokenAddress. Otherwise, RouterPath.TokenTransactionRecords can be used on its own. E.g.:

val params = TokenTransactionRecordsParams(tokenAddress)
PNRouter.build(RouterPath.TokenTransactionRecords, params).navigation()

PNRouter.build(RouterPath.TokenTransactionRecords).navigation()

Open NFT Details

Particle Wallet also natively supports viewing specific NFTs (traits, description, image, etc.). Forcing this menu programmatically can happen through PNRouter.build, passing both RouterPath.NftDetails and params, a NftDetailsParams object (imported from com.particle.gui.ui.nft_detail.NftDetailParams) containing a tokenAddress (address of the ERC721 token), and the recipientAddress (owner of the NFT). E.g.:

var params = NftDetailParams(tokenAddress, recipientAddress)
PNRouter.build(RouterPath.NftDetails, params).navigation()

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 ParticleNetwork.openBuy, passing in several optional parameters to customize the values used within the onramp. Upon calling, this will throw a popup or total redirect over to a configuration of https://ramp.particle.network.

The specific parameters that can be used within ParticleNetwork.openBuy are listed below:

NameDescriptionTypeRequired
network[Solana, Ethereum, Binance Smart Chain, Polygon, Tron, Optimism, etc.].stringFalse (True if Particle not connected)
fiatCoinFiat currency denomination.stringFalse
cryptoCoinCryptocurrency denomination.stringFalse
fiatAmtThe amount of fiat to be automatically filled in as the purchase volume.numberFalse
boolLock fiat currency in the buy menu.boolFalse
fixCryptoCoinLock cryptocurrency in the buy menu.boolFalse
fixFiatAmtLock fiat amount in the buy menu.boolFalse
walletAddressThe wallet address to receive the cryptocurrency.stringFalse (True if Particle not connected)
ParticleNetwork.openBuy(
  walletAddress: String? = null,
  amount: Int? = null,
  fiatCoin: String = "usd",
  cryptoCoin: String = "eth",
  fixFiatCoin: Boolean = false,
  fixFiatAmt: Boolean = false,
  fixCryptoCoin: Boolean = false,
  theme: String = "light",
  language: String = "en-us",
  chainName: String? = null  
)

Open Swap

Particle Wallet has built-in swap functionality (retrieves multiple quotes from different providers such as 1inch, iZUMi, etc., routing the swap through the best one depending on swap rate) for Mainnets (both Solana and EVM). Opening this menu can be done through PNRouter.navigatorSwap, which alone will open the default swap menu without values filled in. However, you can pass in a SwapConfig object (swapConfig in this example), imported from com.particle.gui.ui.swap.SwapConfig, containing:

  • fromTokenAddress, the token to swap from.
  • toTokenAddress, the token to swap to.
  • fromTokenUIAmount, the amount of fromTokenAddress to be automatically reflected within the UI.

E.g.:

PNRouter.navigatorSwap()

val swapConfig = SwapConfig(
  fromTokenAddress="",
  toTokenAddress="",
  fromTokenUIAmount="0.1"
)
PNRouter.navigatorSwap(swapConfig)

Open DApp Browser Page

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

PNRouter.navigatorDappBrowser(url:String)

// Alternatively
ParticleNetwork.navigatorDAppBrowser(url:String)

Relevant API Methods, Examples

In addition to methods through ParticleWallet and PNRouter that control Particle Wallet, it's also worth mentioning a few APIs that can be accessed through ParticleNetwork , which may be relevant to Particle Wallet.

Get Price

To retrieve the price of one or multiple tokens, you can call the getPrice method on either ParticleNetwork.evm or ParticleNetwork.solana, both taking addresses (either a singular or list of token addresses --for the native token, use 'native'), and currencies (either a singular or list of fiat currencies in which the prices are denominated (such as ['usd', 'cny']). E.g.:

ParticleNetwork.solana.getPrice(addresses, currencies)

ParticleNetwork.evm.getPrice(addresses, currencies)

Tokens by Address

You can also retrieve the tokens belonging to a specified address by calling either getTokensAndNFTs or getTokensAndNFTsFromDB (retrieves exclusively from DB) on ParticleNetwork.solana or ParticleNetwork.evm, taking one parameter, the address of the account being queried. E.g.:

ParticleNetwork.solana.getTokensAndNFTs(address)

ParticleNetwork.solana.getTokensAndNFTsFromDB(address)

ParticleNetwork.evm.getTokensAndNFTs(address)

ParticleNetwork.evm.getTokensAndNFTsFromDB(address)

Transaction History by Address

The full transaction history of a given address can be retrieved through either getTransactionsByAddress or getTransactionsByAddressFromDB (pulls data exclusively from DB) on ParticleNetwork.solana or ParticleNetwork.evm. Both of these take address (the user address to be queried), although ParticleNetwork.solana also takes an additional optional object, which in this example is optBody. This can contain additional parameters, such as the boolean, parseMetadataUri. E.g.:

ParticleNetwork.solana.getTransactionsByAddress(address, optBody)

ParticleNetwork.solana.getTransactionsByAddressFromDB(address, optBody)

ParticleNetwork.evm.getTransactionsByAddress(address)

ParticleNetwork.evm.getTransactionsByAddressFromDB(address)