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:
- Sign up/log in to the Particle dashboard.
- Create a new project or enter an existing project.
- Create a new Android application, or skip this step if you already have one.
- 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
andorg.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 ofChainInfo
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
orfalse
(false
by default).setShowManageWalletSetting
, whether or not the "Manage Wallet" button within the Particle Wallet interface is shown. This takes one parameter,true
orfalse
(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
orfalse
(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
orfalse
(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 asMobileWCWalletName.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:
Name | Description | Type | Required |
---|---|---|---|
network | [Solana, Ethereum, Binance Smart Chain, Polygon, Tron, Optimism, etc.]. | string | False (True if Particle not connected) |
fiatCoin | Fiat currency denomination. | string | False |
cryptoCoin | Cryptocurrency denomination. | string | False |
fiatAmt | The amount of fiat to be automatically filled in as the purchase volume. | number | False |
bool | Lock fiat currency in the buy menu. | bool | False |
fixCryptoCoin | Lock cryptocurrency in the buy menu. | bool | False |
fixFiatAmt | Lock fiat amount in the buy menu. | bool | False |
walletAddress | The wallet address to receive the cryptocurrency. | string | False (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 offromTokenAddress
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)