Implementing Universal Accounts in your application.
Connect a user's account
Initialize Universal Accounts
Use the UA instance
rootHash
. This hash must be signed by the connected EOA, then passed back into sendTransaction()
to broadcast.ethers.js
internally, but you’re not required to use it in your application.You can use any provider or signer logic that fits your setup.UniversalAccount
class in your app from @particle-network/universal-account-sdk
:
ua
instance to fetch data (a Universal Account’s balance or addresses) and send transactions.
$PARTI
via a swap on BNB Chain, the SDK will:
getPrimaryAssets()
method will then return a list of Primary Assets held by the Universal Account across all supported chains.
getPrimaryAssets()
has the following structure:
SUPPORTED_PRIMARY_TOKENS
constant from the SDK:
AssetInfo
assets
array represents a single token type aggregated across chains.
Expand to see the full structure
Field | Description |
---|---|
tokenType | Token identifier (e.g., “eth”, “usdt”) |
price | Current USD price |
amount | Total amount across chains (human-readable) |
amountInUSD | Total USD value |
chainAggregation | Per-chain balance breakdowns |
chainAggregation
formatchainAggregation
entry details the balance and metadata of the token on a specific chain:
Expand to see the full structure
Field | Description |
---|---|
token.chainId | Chain ID |
token.address | Token contract address |
amount | Token amount (human-readable float) |
amountInUSD | USD value |
rawAmount | Token amount in raw units (integer, stringified) |
token.decimals | ERC-20 decimals |
token.realDecimals | Adjusted decimals for display |
token.isMultiChain | Part of multi-chain registry |
token.isMultiChainDefault | Default canonical version across chains |
ETH
, the token.address
field will be 0x0000000000000000000000000000000000000000
.getPrimaryAssets()
in a real Next.js app using Particle Auth and Universal Accounts.Universal Accounts SDK
lets you send tokens to any address across supported chains using the createTransferTransaction()
method. Like other transactions, transfers don’t require the user to hold assets or gas tokens on the destination chain—liquidity and gas are abstracted behind the scenes.
Once you construct the transfer, the SDK returns a rootHash
to sign. You sign it with the connected EOA (e.g., from Particle Auth), then call sendTransaction()
to broadcast:
ETH
, the token address will be 0x0000000000000000000000000000000000000000
.TransactionResult
will include the transaction ID, as well as metadata like token movements and fee breakdowns. You can find more details about this in the TransactionResult section below.
createUniversalTransaction()
method. In this example, we interact with a smart contract on the Base Mainnet that requires exactly 0.0000001 ETH to execute a checkIn()
function.
By specifying an expectTokens
array, the SDK ensures the account has the necessary ETH on Base—even if the user’s assets are on other chains or in different tokens (e.g., USDC, USDT). The SDK will handle all additional required cross-chain routing and token conversion under the hood.
Once the transaction is created, it will return a rootHash
value representing the payload to be signed. You can then use a signer (e.g., Particle Auth) to sign this hash and broadcast it using sendTransaction()
.
The following code snippet shows how to use the Universal Accounts SDK to send a payable transaction:
TransactionResult
will include the transaction’s ID and metadata like token movements and fee breakdowns.
createBuyTransaction()
method. This allows you to programmatically route an amount in USD into a target token (e.g., USDT on Arbitrum), without requiring the user to hold funds on the destination chain.
Once the transaction is created, it returns a rootHash
value representing the payload to be signed. You then use your signer (in this case, Particle Auth) to sign the message, and pass the result into sendTransaction() to broadcast it:
sendTransaction
method will then return a TransactionResult
object, which includes the transaction ID and other metadata.
createConvertTransaction
method.
The example below demonstrates how to convert any primary asset into another—USDC on Arbitrum, in this case:
createTransferTransaction()
method, even if you hold no assets on Solana.
Here is an example:
rootHash
.
You can combine this swap transaction with a SOL transfer to automatically convert EVM-based assets to SOL and send them to another account in a single flow.
createTransferTransaction()
provides a full preview of the transaction before it’s executed. This includes key details such as estimated fees, token transfers, and other relevant metadata—allowing you to display clear, actionable information to users before confirmation.
For example:
sendTransaction()
Response StructuresendTransaction()
, the SDK will return a detailed object containing its execution status, fee breakdowns, token flows, and analytics.
Below is a breakdown of the key fields within this object:
Top-Level Fields
Field | Description |
---|---|
transactionId | Unique ID of the transaction (used to query status or activity details) |
mode | Network mode, typically "mainnet" or "testnet" |
sender / receiver | Address that initiated and received the transaction (usually same) |
type | Transaction type (e.g. "universal" ) |
status | Execution status code (internal enum) |
tag | Transaction tag (e.g., "buy" or "swap" ) |
created_at / updated_at | ISO timestamps for lifecycle tracking |
`fees` (Cost Breakdown)
Field | Description |
---|---|
totals.feeTokenAmountInUSD | Total fee in USD |
feeTokens[] | List of tokens used to pay fees, with symbols and USD values |
freeGasFee / freeServiceFee | Whether any component was waived |
`depositTokens` / `lendingTokens`
token.symbol
token.chainId
amount
and amountInUSD
tokenChanges (Before/After Effects)
Field | Description |
---|---|
decr[] | Tokens deducted from the user (chain, token, amount) |
incr[] | Tokens received by the user |
swaps[] | Swap routes (e.g. from USDC to USDT via 1inch) |
tokenBalances[] | Final post-transaction token balances |
Analytics & Valuation
Field | Description |
---|---|
slippage | Slippage used for the route (in basis points) |
totalFeeInUSD | Final USD fee value |
totalDecrAmountInUSD | Total USD value deducted |
totalIncrAmountInUSD | Total USD value received |
priceImpact | Estimated price impact (0 if none) |
minReceiveAmountInUSD | Minimum expected amount (to be received, post-slippage) in USD |
minReceiveToken | Token targeted by the buy/swap action |
`Explorer / Activity Link`
useWallets()
hook. The primaryWallet
object exposes a walletClient
, which acts as the signer.
This lets you sign the Universal Account transaction payload (rootHash) using any wallet connected via Particle Connect.
The following code snippet shows how to use the Universal Accounts SDK to sign a transaction with Particle Connect:
"000000"
by default) if you have one.