Particle Network
Particle Network is the L1 unifying all chains through Universal Accounts. They have deployed its complete Wallet Abstraction stack on peaq, krest, and agung, natively bringing social logins and account abstraction to the ecosystem. Using Particle Network's SDKs, applications built on peaq can onboard users into ERC-4337 smart contract wallets through Web2-adjacent mechanisms such as Google, Twitter, email, phone, and so on.
Overview
Developers can integrate and leverage Particle Network's Wallet Abstraction stack through a variety of SDKs spanning over nine different frameworks and platforms. This document will focus on the basic flow of building a React-based web application on peaq using Particle Network to onboard users into ERC-4337 smart accounts through social logins. To try Particle Network for yourself, head over to their web demo. Additionally, a complete demo repository containing the code covered throughout this document can be found here. By the end of this page, you'll understand the process of implementing an onboarding flow similar to the preview above.
Using Particle Network: Guide
Particle Network's Wallet Abstraction stack can be leveraged through a variety of mechanisms, each varying in complexity and integration flow. These options are:
- Particle Connect, a custom connection kit (similar to RainbowKit) that facilitates both social logins and Web3 wallet connections. Available for Web, Unity, Android, iOS, Flutter, and React Native.
- Particle Auth, the primary library facilitating social logins through either a standard modal provided by Particle or lower-level shortcuts within your own interface.
- External connection kits, such as Web3Modal, Web3-Onboard, and RainbowKit. Any of the above libraries are capable of introducing social logins to your application with Particle Network. Tying in account abstraction (ERC-4337) into these approaches requires the usage of Particle Network's standalone AA SDK. This SDK leverages Particle's native Bundler and Paymaster deployed on peaq krest and agung. For this guide, we'll be using Particle Auth alongside Particle's AA SDK to facilitate a standard implementation of social logins. Particle Auth can be integrated through a variety of platforms and frameworks. This guide will focus on Particle Auth Core, a React-based SDK for web applications. To explore the integration process for alternative platforms, head to Particle Network's documentation.
Part 1: Installation
Working with Particle Auth Core alongside Particle's AA SDK involves the installation of a few core libraries, including:
@particle-network/auth-core-modal
, the primary mechanism for facilitating social logins.@particle-network/aa
, for generating and assigning ERC-4337 smart accounts to traditional accounts (EOAs) created and linked to the user’s identity through social login.@particle-network/chains
, for using peaq.
To install these libraries, run one of the two following commands:
yarn add @particle-network/auth-core-modal @particle-network/aa @particle-network/chains
# OR
npm install @particle-network/auth-core-modal @particle-network/aa @particle-network/chains
Part 2: Configuration
Both @particle-network/auth-core-modal
and @particle-network/aa
need to be configured independently, although a common denominator between the two is the need for three key values from the Particle dashboard:
- projectId
- clientKey
- appId
Collectively, these values authenticate each SDK. The retrieval process is as follows:
Log in or sign up to the Particle dashboard.
Create a new project.
Within this project, create an application.
Copy the Project ID, Client Key, and App ID from the dashboard. If applicable, save these to environment variables within your application.
Configuring Particle Auth involves the initialization of its core React component, AuthCoreContextProvider. This component will wrap the application in which we intend to use Particle Auth and, beyond the aforementioned values, contain parameters for customizing the embedded wallet modal, specifying the smart account implementation you intend to use, and so on.
After importing AuthCoreContextProvider from @particle-network/auth-core-modal
, open it within your JSX. You'll need to use the options property for configuration. This takes the following values:
projectId
,clientKey
, andappId
. These are the values you found on the Particle dashboard.wallet
, a collection of properties for configuring the embedded wallet modal that optionally shows after a user logs in with their social account.wallet
contains:visible
, a Boolean dictating whether the embedded wallet interface is shown post-login. Iftrue
, this materializes by default through a button placed near the bottom right of the application.customStyle
, which, in this example, takessupportChains
, an array of chain objects that dictate the blockchains supported within the embedded wallet modal. To lock this to peaq, importPeaqKrest
orPeaqAgungTestnet
from@particle-network/chains
.
erc4337
, used for specifying a Smart Account implementation to be shown within the embedded wallet modal rather than the EOA. Ifvisible
isfalse
onwallet
, ignore this property.erc4337
contains:name
, the name of the Smart Account implementation used within your application. For both peaq krest and agung, this should be'SIMPLE'
.version
, the version of the Smart Account implementation referenced inname
. Currently, only'1.0.0'
is supported with'SIMPLE'
.
After defining these various parameters, AuthCoreContextProvider should look like the following example (which is the index.tsx file of the aforementioned create-react-app example):
// index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { PeaqKrest, PeaqAgungTestnet } from '@particle-network/chains';
import { AuthCoreContextProvider } from '@particle-network/auth-core-modal';
import App from './App'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<AuthCoreContextProvider
options={{
projectId: process.env.REACT_APP_PROJECT_ID, // --
clientKey: process.env.REACT_APP_CLIENT_KEY, // From https://dashboard.particle.network
appId: process.env.REACT_APP_APP_ID, // --
erc4337: {
name: 'SIMPLE',
version: '1.0.0',
},
wallet: {
visible: true,
customStyle: {
supportChains: [PeaqAgungTestnet],
}
}
}}
>
<App /> // Where Particle Auth will be used
</AuthCoreContextProvider>
</React.StrictMode>
)
Additionally, Particle Network's AA SDK needs to be configured in a very similar fashion. However, rather than being initialized through a React component, @particle-network/aa
will need to be configured within the same component where you intend to leverage Particle Auth.
Specifically, @particle-network/aa
has a key "master" object, SmartAccount, which, once initialized, enables end-to-end management of the user's smart account.
After configuring Particle Auth Core, you'll need to define provider from the useEthereum hook (imported through @particle-network/auth-core-modal
) within your application. provider represents the EIP-1193 provider object we'll need to configure an attached smart account. Below is an example of this.
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { provider } = useEthereum(); // EIP-1193 provider
...
}
Using provider, you'll need to define a new instance of SmartAccount. In addition to provider, SmartAccount takes an object which contains:
projectId
,clientKey
, andappId
, as was previously defined inAuthCoreContextProvider
.aaOptions
, containing:accountContracts
, a collection of the Smart Account implementations you intend to support. For peaq, this should just be:SIMPLE
, an array of objects which takes:chainIds
, an array of chain IDs (integers) for the blockchain(s) you'll be using the Smart Account on.version
, the version of the Smart Account you'll use; in the case ofSIMPLE
, this should be'1.0.0'
.
Therefore, defining an instance of SmartAccount should look similar to the snippet below:
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { provider } = useEthereum();
const smartAccount = new SmartAccount(provider, {
projectId: process.env.REACT_APP_PROJECT_ID,
clientKey: process.env.REACT_APP_CLIENT_KEY,
appId: process.env.REACT_APP_APP_ID,
aaOptions: {
accountContracts: {
SIMPLE: [{ chainIds: [PeaqAgungTestnet.id], version: '1.0.0' }]
}
}
});
}
In this example, smartAccount is the central source for controlling and reading data from the smart account attached to the user's social login.
Part 3: Social Login
Using Particle Auth, users are onboarded through traditional Web2 social accounts such as Google, Twitter, email, and so on.
To initiate social logins programmatically, you'll need to use the useConnect hook from @particle-network/auth-core-modal
. useConnect exposes the connect function, which directly handles social logins. This takes the following parameters:
socialType
, the specific social login mechanism to be opened. If this is left as a blank string (''
), a generalized interface will open, allowing a user to enter their email, choose an external social account, etc. Otherwise, if a string such as'google'
or'twitter'
is used, these will be opened directly.chain
, the blockchain to be connected to. This should be an object from@particle-network/chains
, eitherPeaqKrest
orPeaqAgungTestnet
in this case. Below is a snippet showcasing an example implementation ofconnect
:
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { connect, disconnect } = useConnect();
const handleLogin = async (authType) => {
if (!userInfo) {
await connect({
socialType: authType, // 'google', 'twitter', etc. - can also be ''
chain: PeaqAgungTestnet, // or PeaqKrest
});
}
};
...
disconnect(); // Often mapped to an element within your JSX
}
After logging in, provider will be populated and, by proxy, SmartAccount will be initialized. At this point, you'll be ready to execute transactions.
Part 4: Transaction Execution
Application interaction, or transaction execution, can be done through one of two ways with @particle-network/aa
, either:
Through the instance of
SmartAccount
directly.Using an external Web3 library such as Ethers or Web3.js.
Option 1: Using SmartAccount
Instances of SmartAccount have various methods capable of constructing and executing transactions, otherwise known as UserOperations (within the ERC-4337 standard). These methods are as follows:
sendTransaction
sendUserOperation
sendSignedUserOperation
buildUserOperation
getFeeQuotes
signUserOperation
Both vary in granularity and operational significance; although for this example we'll focus on the most straightforward method,sendTransaction
. For information about the others listed above, head over to Particle Network's documentation.sendTransaction
can be used to construct and execute any standard transaction; just as you would with Ethers, Web3.js, or any related library. Transactions should be constructed using typical parameters such asto
,value
, anddata
. Upon calling{your SmartAccount instance}.sendTransaction
, the user will be asked to confirm the transaction through an in-app popup. Upon doing so, it'll be executed on-chain. The snippet below is an example of this approach:
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { provider } = useEthereum();
// Smart Account configuration
const smartAccount = new SmartAccount(provider, {
projectId: process.env.REACT_APP_PROJECT_ID,
clientKey: process.env.REACT_APP_CLIENT_KEY,
appId: process.env.REACT_APP_APP_ID,
aaOptions: {
accountContracts: {
SIMPLE: [{ chainIds: [PeaqAgungTestnet.id], version: '1.0.0' }]
}
}
});
...
// Executing a burn of 0.001 AGUNG
const executeUserOp = async () => {
const tx = {
to: "0x000000000000000000000000000000000000dEaD",
value: ethers.utils.parseEther("0.001"),
};
const txResponse = smartAccount.sendTransaction(tx)
return txResponse;
};
}
Option 2: Using Ethers
More commonly, an instance of SmartAccount can be used in the construction of an instance of Ethers (or Web3.js, viem, and so on), allowing for a more standardized mechanism of programmatic interaction.
This is done by building an intermediary EIP-1193 provider object using AAWrapProvider from @particle-network/aa
within your instance of SmartAccount. After plugging this into an object such as new ethers.providers.Web3Provider, you’ll be able to interact with the smart account directly through Ethers.
Below is an example of this configuration process:
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { connect, disconnect } = useConnect();
const { provider } = useEthereum();
// Smart Account configuration
const smartAccount = new SmartAccount(provider, {
projectId: process.env.REACT_APP_PROJECT_ID,
clientKey: process.env.REACT_APP_CLIENT_KEY,
appId: process.env.REACT_APP_APP_ID,
aaOptions: {
accountContracts: {
SIMPLE: [{ chainIds: [PeaqAgungTestnet.id], version: '1.0.0' }]
}
}
});
// Ethers provider construction
const customProvider = new ethers.providers.Web3Provider(new AAWrapProvider(smartAccount, SendTransactionMode.Gasless), "any");
}
From this point, your Ethers instance can be used to construct and execute transactions as normal, automatically routing signatures to the embedded wallet generated through social login.
Conclusion
Below is an example of an application component implementing all of the previously covered code snippets:
// App.tsx
import { useEthereum, useConnect, useAuthCore } from '@particle-network/auth-core-modal';
import { PeaqAgungTestnet } from '@particle-network/chains';
import { AAWrapProvider, SmartAccount } from '@particle-network/aa';
import { ethers } from 'ethers';
const App = () => {
const { connect, disconnect } = useConnect();
const { provider } = useEthereum();
// Smart Account configuration
const smartAccount = new SmartAccount(provider, {
projectId: process.env.REACT_APP_PROJECT_ID,
clientKey: process.env.REACT_APP_CLIENT_KEY,
appId: process.env.REACT_APP_APP_ID,
aaOptions: {
accountContracts: {
SIMPLE: [{ chainIds: [PeaqAgungTestnet.id], version: '1.0.0' }]
}
}
});
// Ethers provider construction
const customProvider = new ethers.providers.Web3Provider(new AAWrapProvider(smartAccount, SendTransactionMode.Gasless), "any");
// Facilitating social login
const handleLogin = async (authType) => {
if (!userInfo) {
await connect({
socialType: authType,
chain: PeaqAgungTestnet,
});
}
};
// Executing a burn of 0.001 ETH
const executeUserOp = async () => {
const signer = customProvider.getSigner();
const tx = {
to: "0x000000000000000000000000000000000000dEaD",
value: ethers.utils.parseEther("0.001"),
};
const txResponse = await signer.sendTransaction(tx);
const txReceipt = await txResponse.wait();
return txReceipt;
};
}
Extending this tutorial, a demo application containing this same code can be found here. You can try it within your own browser here.
Using Particle Network's Wallet Abstraction stack, you can now implement Web2-like user onboarding flows and account abstraction capabilities on peaq with only a few lines of code, as demonstrated here. To learn more about Particle Network and its various SDKs, take a look at the following links:
Documentation provided by Particle, 2024.