Integrating Universal Accounts with Browser Wallets
Learn how to integrate Universal Accounts alongside standard EVM wallets (e.g. MetaMask).
Within this guide, you’ll learn how to use Universal Accounts alongside browser-injected EVM wallets —such as MetaMask or other providers.You’ll learn how to:
Initialize a Universal Account from a connected EOA.
Create and sign a transaction with MetaMask.
Send the transaction through the Universal Accounts SDK.
This guide uses window.ethereum as the provider used via ethers.js.
To interact with Universal Accounts using window.ethereum, you first need to connect to an EVM-compatible browser wallet like MetaMask.Here’s a simple example using ethers.js:
Copy
Ask AI
import { ethers } from "ethers";// Ensure MetaMask (or another injected provider) is availableif (!window.ethereum) { throw new Error("MetaMask is not installed");}const provider = new ethers.BrowserProvider(window.ethereum);// Prompt user to connect their walletawait provider.send("eth_requestAccounts", []);// Retrieve the connected accountconst accounts = await provider.listAccounts();const walletAddress = accounts[0].address;setWalletAddress(walletAddress);
This example uses ethers.BrowserProvider, available in ethers v6.
This wallet address can now be passed into the Universal Account SDK as the ownerAddress.
Once the user connects their wallet and you obtain their EOA address, create a new Universal Account instance:
Copy
Ask AI
import { UniversalAccount } from "@particle-network/universal-account-sdk";const universalAccount = new UniversalAccount({ projectId: process.env.NEXT_PUBLIC_PROJECT_ID!, projectClientKey: process.env.NEXT_PUBLIC_CLIENT_KEY!, projectAppUuid: process.env.NEXT_PUBLIC_APP_ID!, ownerAddress: address, // If not set it will use auto-slippage tradeConfig: { slippageBps: 100, // 1% slippage tolerance //usePrimaryTokens: [SUPPORTED_TOKEN_TYPE.SOL], // Specify token to use as source (only for swaps) },});
You only need the EOA wallet address to initialize a Universal Account.
Once you have a Universal Account instance, you can use it to send transactions.The code below shows how to set up a custom transaction using the user’s browser-injected EVM wallet as a signer.In this case, the funds will be automatically sourced from the user’s Primary Assets and converted into 1 USDT on Avalanche.
Copy
Ask AI
import { ethers } from "ethers";import { CHAIN_ID, SUPPORTED_TOKEN_TYPE } from "@particle-network/universal-account-sdk";const transaction = await universalAccount.createUniversalTransaction({ chainId: CHAIN_ID.AVALANCHE_MAINNET, expectTokens: [ { type: SUPPORTED_TOKEN_TYPE.USDT, amount: "1", }, ], transactions: [],});if (!window.ethereum) { throw new Error("Wallet not found");}const provider = new ethers.BrowserProvider(window.ethereum);const signer = await provider.getSigner();const signature = await signer.signMessage(transaction.rootHash);const result = await universalAccount.sendTransaction(transaction, signature);console.log(`View on Explorer: https://universalx.app/activity/details?id=${result.transactionId}`);
This pattern works for all transaction types supported by the SDK.