# Particle Bundler
Source: https://developers.particle.network/aa/architecture/bundler
Particle Network's Bundler is now fully open-source!
***
An ERC-4337 Bundler acts as a transaction aggregator that collects individual `UserOperations` from a specialized mempool, bundles them, and submits them as a single transaction to the network. This enables enhanced account abstraction on Ethereum and other EVM networks. It is a core infrastructure component for account abstraction on Ethereum Virtual Machine (EVM) networks.
The Particle Bundler is a specialized tool designed to make smart contracts and transactions work smoothly using the ERC-4337 standard. It is a fully compliant, feature-rich, high-performance, infinitely scalable 4337 Bundler implementation.
## Advantages of the Particle Bundler
Particle's Bundler offers several compelling advantages:
* **Seamless `UserOperations`:** We have implemented the persistence of `UserOperations`, Smart Account Nonce management, and automatic batch sending of `UserOperations`, among other features. The Particle Bundler simplifies the transaction process for users, streamlining the submission of `UserOperations`. This enhances the accessibility of ERC-4337, making it more user-friendly and approachable for a broader audience.
* **Smart Ops:** We know the importance of stable and reliable operational features for developers, so we have implemented functionalities like Bundler Signer configuration, automatic recharging, automatic blocking and recovery, and automatic monitoring alerts, enabling easy management and automatic expansion. The era of multi-chain Web3 is still unfolding, so we have simplified the deployment process to new chains down to executing a single command with minimum additional configurations. Thanks to this, support for a new chain can be completed within 5 minutes.
* **High Performance:** Particle's Bundler is engineered for optimal performance and can efficiently handle demanding workloads. Leveraging proprietary technology and optimization techniques, the Bundler ensures transactions are processed swiftly and effectively.
* **High Stability:** Stability is a hallmark feature of Particle's Bundler. Built with reliability in mind, it operates seamlessly, even under challenging conditions. Its robust architecture and adherence to best practices in infrastructure management contribute to its exceptional stability, providing users and developers with a dependable platform to solve their needs.
As a high-performance, highly stable Bundler implementation, the Bundler also features:
## Features
* All standard RPCs supported.
* Configurable RPCs, Signers, etc.
* Support for any chain.
* `UserOp` Persistence.
* `UserOp` Concurrent Handling.
* Built-in Gas Price Oracle.
* Multi-Bundler Signers Manager.
* Auto-fulfill bundler Signers’ balance.
* Auto-retry for failed transactions from a Bundler Signer account.
* Returns the correct transaction even when affected by MEV.
* Deploy new chains with one command.
Learn more through the [open-source repository](https://github.com/Particle-Network/particle-bundler-server).
# Omnichain Paymaster
Source: https://developers.particle.network/aa/architecture/omni-paymaster
Our proprietary Paymaster allows developers to recharge and spend across different chains.
***
Particle Network’s Paymaster is a specialized tool designed to make gas payments easier and friendlier for end users across chains, leveraging Particle Network's Omnichain Account Abstraction design. This service, which has helped us sponsor over 500k `UserOperations` across different networks in the previous month, is already fully integrated with Particle’s Wallet as a Service (WaaS).
## Advantages of the Particle Paymaster
Particle's Paymaster offers several compelling advantages, making it a powerful component of the Omnichain AA ecosystem:
* **Multi-chain usage:** Once developers deposit USDT, they can sponsor UserOps on every EVM-compatible chain.
* **Adaptable sponsorship logic using Webhooks:** Configuring webhooks allows developers to accurately control which UserOP can be accepted by the cross-chain Paymaster
* **Monitoring:** Developers are able to monitor every UserOp they sponsored.
* **Expiration times:** Developers can define an expiration time for the Paymaster signature. Once the UserOperation reaches its expiration, the Paymaster signature will automatically lapse.
## How to use
1. Use [Particle Network's AA SDKs](/aa/sdks/desktop/web.mdx), Particle's Paymaster will be automatically included, and no extra configuration is needed;
2. Use [Particle Paymaster's RPC](/aa/paymaster) directly to plug the multi-chain paymaster in your AA project.
## Webhooks
Configuring webhooks allows developers to accurately control which UserOP can be accepted by the Paymaster. We use two types of webhooks:
1. Before the Paymaster signs— `before_paymaster_sign`.
2. After the Paymaster signs— `after_paymaster_sign`.
Every time a Webhook request is made, a signature for the body is generated, which developers can verify to determine whether the request was sent by Particle Network. A unique public and private key (RSA-2048) is generated for each project. This key can be downloaded from the users’ [Particle dashboard page](https://dashboard.particle.network/#/login) for verification.
### Webhook: `before_paymaster_sign`
This hook will be triggered before the Paymaster signs. The Paymaster will determine whether to sign the UserOP based on the status code returned by the Hook. It includes:
* Body
* `chainId`
* `UserOp` - UserOperation struct.
* `entryPoint` - The entryPoint address.
* `parsed` - Transaction struct. The Paymaster will attempt to parse the calldata of the UserOP. If it cannot be parsed, this field may not exist.
* Response\
If the status code of the response returned is 200, then the Paymaster will accept the UserOP and sign it.
### Webhook: `after_paymaster_sign`
This hook will trigger after the Paymaster signs. It includes:
* Body
* `chainId`
* `UserOp` - UserOperation struct.
* `entryPoint` - The entryPoint address.
* `parsed` - Transaction struct. The Paymaster will attempt to parse the calldata of the `UserOP`. If it cannot be parsed, this field may not exist.
Find a guide on how to implement webhooks in [Paymaster guidance](/aa/guides/paymaster#conditional-sponsorship-webhooks).
### Whitelist Smart Contract
Developers can configure a whitelist of contract methods they want to sponsor in the backend. This means that after configuration, our server will only provide the Paymaster’s signature for the specified contract methods.
## Sponsorship Policy
The simplest way is to configure a whitelist of contract methods to sponsor. However, using Webhooks provides more flexibility, allowing for unlimited sponsorship strategies through any programmatic logic.
Developers can use Webhooks to implement any sponsorship logic they wish in conjunction with the Paymaster.
For the `before_paymaster_sign` webhook, we return all the data necessary:
* projectUuid
* chainId
* `UserOp`
* and parsed data:
* accountType: BICONOMY, CYBERCONNECT, SIMPLE
* txs
* Any policy
* You can use chainId to decide which chains you want to sponsor.
* You can use `UserOp` to decide which user address(sender) you want to sponsor.
* You can use `UserOp` to calculate the gas fee and decide whether to sponsor or not.
* You can use the accountType and txs to use them as a smart contract whitelist or blacklist.
This allows, for example, for the following business scenarios:
* A GameFi project to allow every new user to mint a game NFT gaslessly.
* A financial platform can sponsor gas for every deposit, so their users don't need to learn the concept of gas.
* An NFT platform can enable users to trade NFTs without gas, using their own fees to cover gas.
In many cases, programmatic sponsorship policies can be used and adapted to create a friendly experience and simplify experiences where it matters most.
To learn more about Particle's Account Abstraction Stack, head over to the relevant [AA SDK reference pages](/aa/introduction).
# estimateUserOperationGas
Source: https://developers.particle.network/aa/bundler/estimateuseroperationgas
openapi-bundler POST /#eth_estimateUserOperationGas
Learn how to use the estimateUserOperationGas JSON-RPC method.
## Understanding `estimateUserOperationGas`
* `estimateUserOperationGas` takes a partial UserOperation object and returns detailed gas estimates to be used in continued UserOperation construction. It takes:
* Partial user operation object:
* `sender` - string.
* `nonce` - string.
* `initCode` - string.
* `callData` - string.
* `signature` - string.`signature` can be a dummy string, such as `0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c`.
* `entrypointAddress` - string.
***
## Query example
```json JSON theme={null}
{
"method": "eth_estimateUserOperationGas",
"params": [
// partial user operation
{
"sender": "0x8fb859e944561678be40cdd2db16551396c0b074",
"nonce": "0x0152",
"initCode": "0x",
"callData": "0x9e5d4c49000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"signature": "0x73c3ac716c487ca34bb858247b5ccf1dc354fbaabdd089af3b2ac8e78ba85a4959a2d76250325bd67c11771c31fccda87c33ceec17cc0de912690521bb95ffcb1b"
},
"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"
],
"id": 1695717515,
"jsonrpc": "2.0",
"chainId": 80001
}
```
# getUserOperationByHash
Source: https://developers.particle.network/aa/bundler/getuseroperationbyhash
openapi-bundler POST /#eth_getUserOperationByHash
Learn how to use the getUserOperationByHash JSON-RPC method.
## Understanding `getUserOperationByHash`
* `getUserOperationByHash` returns a UserOperation object corresponding with a specific hash. It takes:
* `hash` - string.
***
## Query example
```json JSON theme={null}
{
"method": "eth_getUserOperationByHash",
"params": [
// user operation hash
"0x1ee478a6e967c407e8dfb5e3f2eb1131a7418c36396147fce1f7e81a871102a3"
],
"id": 1695717473,
"jsonrpc": "2.0",
"chainId": 80001
}
```
# getUserOperationReceipt
Source: https://developers.particle.network/aa/bundler/getuseroperationreceipt
openapi-bundler POST /#eth_getUserOperationReceipt
Learn how to use the getUserOperationReceipt JSON-RPC method.
## Understanding `getUserOperationReceipt`
* `getUserOperationReceipt` returns a detailed object containing specific transaction details for a given user operation hash. It takes:
* `hash` - string.
***
## Query example
```json JSON theme={null}
{
"method": "eth_getUserOperationReceipt",
"params": [
// user operation hash
"0x1ee478a6e967c407e8dfb5e3f2eb1131a7418c36396147fce1f7e81a871102a3"
],
"id": 1695717473,
"jsonrpc": "2.0",
"chainId": 80001
}
```
# sendUserOperation
Source: https://developers.particle.network/aa/bundler/senduseroperation
openapi-bundler POST /#eth_sendUserOperation
Learn how to use the sendUserOperation JSON-RPC method.
## Contextualizing `sendUserOperation`
* `sendUserOperation` pushes a signed UserOperation to the network, in this case through the Particle Bundler. It takes:
* UserOperation object.
* `entrypointAddress` - string.
***
## Query example
```json JSON theme={null}
{
"method": "eth_sendUserOperation",
"params": [
// user operation
{
"sender": "0x8Fb859E944561678be40Cdd2dB16551396c0b074",
"nonce": "0x0150",
"initCode": "0x",
"callData": "0x9e5d4c49000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"callGasLimit": "0xa13c",
"verificationGasLimit": "0xe2d8",
"maxFeePerGas": "0x7ca702cd",
"maxPriorityFeePerGas": "0x7ca702b0",
"paymasterAndData": "0x000031dd6d9d3a133e663660b959162870d755d4000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000416665636080709b968ebec098bf71fb0e79b3b480cc9ff809f192afb478c84ec50ad2de74b93a67860542099b11a1b5dbfa9bc21a2790c58e10015ce992a02f411b00000000000000000000000000000000000000000000000000000000000000",
"preVerificationGas": "0x011120",
"signature": "0x7cc0a2ae350b79c5b189bd36d55ab6a2756097d6d37537e3ec2c26daaa82c6d909fed87ff9d79a6fa127bd798126259ee72fa9395ecbeb1f70ed22ca35983aea1c"
},
// entrypoint contract address
"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"
],
"id": 1695717470,
"jsonrpc": "2.0",
"chainId": 80001
}
```
# supportedEntryPoints
Source: https://developers.particle.network/aa/bundler/supportedentrypoints
openapi-bundler POST /#eth_supportedEntryPoints
Learn how to use the supportedEntryPoints JSON-RPC method.
## Contextualizing `supportEntryPoints`
* `supportEntryPoints` returns a list of EntryPoint addresses supported by the Particle Bundler. It takes no parameters.
At the moment, only `0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789` is supported due to it being the flagship EntryPoint contract for ERC-4337.
***
## Query example
```json JSON theme={null}
{
"chainId": 80001,
"jsonrpc": "2.0",
"id": 1,
"method": "eth_supportedEntryPoints",
"params": []
}
```
# Particle Account Abstraction FAQ
Source: https://developers.particle.network/aa/faq
Find Frequently Asked Questions about Particle Account Abstraction.
**Answer:** Particle Network uses the Biconomy Paymaster to sponsor transactions using ERC-20 tokens for gas fees. To support new ERC-20 tokens, it is dependent on Biconomy's integration. The availability of a token for gas payments is determined by Biconomy's supported token list.
For a complete list of supported ERC-20 tokens, please refer to the [Biconomy documentation](https://docs.biconomy.io/supportedNetworks#supported-tokens).
**Answer:** You can fund the Paymaster by depositing **USDT** on either **Ethereum** or **BNB Chain** through the **Paymaster** menu on the **Particle Network Dashboard**.
The choice of chain only affects the deposit origin, not the Paymaster’s functionality. Once deposited, USDT is converted to the native token of the target chain, enabling you to sponsor transactions on any supported EVM chain.
To view the full list of supported EVM chains, head over to the [Network Coverage](/social-logins/network-coverage) page.
No USDT deposit is needed for testnet sponsorship.
**Answer:** The AA SDK currently doesn't offer native support for custom smart accounts. We support a select range of smart accounts:
* **SimpleAccount**: `SIMPLE`
* **Biconomy**: `BICONOMY`
* **CyberConnect**: `CYBERCONNECT`
* **Light**: `LIGHT`
* **Coinbase**: `COINBASE`
For more information on supported smart accounts and how to initialize them, visit the [AA SDK documentation](/aa/sdks/desktop/web#initialization).
**Answer:** Yes, with Biconomy V2, you can use **session keys** to grant users the ability to conditionally delegate signing authority. This allows for the automation of transactions and the elimination of confirmation pop-ups, providing a smoother user experience.
Learn more about implementing [Session Keys](/aa/guides/keys) in your application.
**Answer:** Although our SDK doesn't natively support custom Bundlers, you can still create a `UserOperation` object using the SDK. Once constructed, this object can be executed via a standard API call to your own Bundler endpoint.
For detailed guidance on creating and using `UserOperation` objects, check out our [API reference](/aa/rpc/createuserop).
**Answer:** The AA SDK currently only supports Particle's native Paymaster, accessible via the [Particle Network Dashboard](https://dashboard.particle.network), and Biconomy's Paymaster. If you wish to use a custom Paymaster, you'll need to integrate it through a custom API in your application, sponsoring a `UserOperation` constructed by the AA SDK/API.
After that, using our SDK, you can execute the resulting `UserOperation` (including `paymasterAndData` from your Paymaster).
For more details on the available endpoints, visit the [AA APIs documentation](/aa/rpc/getsmartaccount).
**Answer:** Each natively-supported smart account differs in feature-set (such as session keys, multi-chain signatures, and so on).
Below is a table detailing the core differences between account types as it relates to the features they support.
| Account Type | Session Keys | Transferable Signer | Multichain Signatures | Gasless Transactions |
| ----------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------- | --------------------- | -------------------- |
| [Biconomy (V2)](https://github.com/bcnmy/scw-contracts/blob/main/contracts/smart-account/SmartAccount.sol) | ✓ | ✓ | ✓ | ✓ |
| Biconomy (V1) | ✗ | ✗ | ✗ | ✓ |
| [Light](https://github.com/alchemyplatform/light-account) | ✗ | ✓ | ✗ | ✓ |
| [Coinbase](https://github.com/coinbase/coinbase-wallet-sdk) | ✗ | ✗ | ✗ | ✓ |
| CyberConnect | ✗ | ✗ | ✗ | ✓ |
| [SimpleAccount](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol) | ✗ | ✗ | ✗ | ✓ |
For more information on the chains supported by each account type, head over to the [Network Coverage page](/social-logins/network-coverage).
**Still need help?**
[Open a ticket](https://t.me/particle_developer_bot) with Particle's Developer Relations team through the dedicated Telegram support bot.
# Bundler
Source: https://developers.particle.network/aa/guides/bundler
# Particle Bundler
The **Particle Bundler** is our open-source, production-ready ERC-4337 bundler.\
It has already processed **nearly 1M+ UserOperations** across the EVM ecosystem and powers some of the largest AA campaigns in Web3.
* Free to use via a public RPC: `https://bundler.particle.network`
* Automatically included in all Particle AA SDKs
* Proven to scale and battle-tested in live campaigns
Explore the [Particle Bundler repository](https://github.com/Particle-Network/particle-bundler-server).
***
## Why use the Particle Bundler?
* **Open-source & free** — no lock-in, use it standalone or with our SDKs
* **Production-grade** — tested at scale with millions of UserOps
* **Full RPC support** — standard bundler methods available out of the box
* **Multi-chain ready** — live on every chain supported by Particle’s Smart Wallet-as-a-Service
***
## Available RPC Methods
The Bundler RPC endpoint:
[https://bundler.particle.network/\{chainId?}](https://bundler.particle.network/\{chainId?})
Supported methods (no auth required):
* `eth_supportedEntryPoints`
* `eth_estimateUserOperationGas`
* `eth_sendUserOperation`
* `eth_getUserOperationByHash`
* `eth_getUserOperationReceipt`
Example request:
```json JSON [expandable] theme={null}
{
"method": "eth_sendUserOperation",
"params": [
{
"sender": "0x8Fb859E944561678be40Cdd2dB16551396c0b074",
"nonce": "0x0150",
"initCode": "0x",
"callData": "0x9e5d4c49000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"callGasLimit": "0xa13c",
"verificationGasLimit": "0xe2d8",
"maxFeePerGas": "0x7ca702cd",
"maxPriorityFeePerGas": "0x7ca702b0",
"paymasterAndData": "0x000031dd6d9d3a133e663660b959162870d755d4000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce8000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000416665636080709b968ebec098bf71fb0e79b3b480cc9ff809f192afb478c84ec50ad2de74b93a67860542099b11a1b5dbfa9bc21a2790c58e10015ce992a02f411b00000000000000000000000000000000000000000000000000000000000000",
"preVerificationGas": "0x011120",
"signature": "0x7cc0a2ae350b79c5b189bd36d55ab6a2756097d6d37537e3ec2c26daaa82c6d909fed87ff9d79a6fa127bd798126259ee72fa9395ecbeb1f70ed22ca35983aea1c"
},
"0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"
],
"id": 1695717470,
"jsonrpc": "2.0",
"chainId": 80001
}
```
### Supported Chains
The Particle Bundler supports all chains available in Smart Wallet-as-a-Service.
👉 For the full list, see [Network Coverage](/social-logins/network-coverage).
### Interactive Examples
You can try Bundler methods directly in our docs:
```
```
# Session Keys
Source: https://developers.particle.network/aa/guides/keys
How to use session keys with Particle’s Account Abstraction SDKs and RPC.
# Session Keys
**Session keys** let you delegate signing permissions under specific conditions to a temporary keypair.
With session keys, your app can:
* Allow users to interact without constant signature popups
* Enable short-term delegated permissions
* Automate transactions safely under defined rules
Particle Network supports session keys through both the [AA SDKs](/aa/introduction) and the [Account Abstraction RPC](/aa/rpc/getsmartaccount).
Currently supported only on the **Biconomy v2.0.0 smart account implementation**. Other smart account types will throw errors.
***
## How It Works
The session key flow has two main parts:
1. **Create & register the session**
* Generate a temporary keypair (session key).
* Define metadata (`sessionKeyData`) including:
* Session key address (temporary public key)
* Linked user address
* Permission parameters (limits, scope, etc.)
* Deploy or configure a **`sessionValidationModule`** contract to validate `UserOps`.
* Register the session on-chain.
2. **Use the session key**
* `UserOps` can now be signed by the session key instead of the primary wallet.
* The validation module ensures only authorized operations go through.
👉 Check out this [demo repo](https://github.com/TABASCOatw/particle-session-key-demo/blob/main/src/App.tsx) for a practical example.
***
## API & SDK Methods
To work with session keys, use:
* `createSessions` — create and register a new session
* `validateSession` — validate that a `UserOperation` is authorized under the session
Both are available in:
* **AA SDKs**
* **AA RPC** ([createSessions](/aa/rpc/createsessions), [validateSession](/aa/rpc/validatesession))
***
## Example Validation Contract
Here’s an example `sessionValidationModule` contract that implements `validateSessionUserOp`:
```solidity Solidity [expandable] theme={null}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol";
abstract contract ISessionValidationModule {
// execute(address,uint256,bytes)
bytes4 public constant EXECUTE_SELECTOR = 0xb61d27f6;
// execute_ncC(address,uint256,bytes)
bytes4 public constant EXECUTE_OPTIMIZED_SELECTOR = 0x0000189a;
/**
* @dev validates if the _op (UserOperation) matches the SessionKey permissions
* and that _op has been signed by this SessionKey
* @param _op User Operation to be validated.
* @param _userOpHash Hash of the User Operation to be validated.
* @param _sessionKeyData SessionKey data, that describes sessionKey permissions
* @param _sessionKeySignature Signature over the the _userOpHash.
* @return true if the _op is valid, false otherwise.
*/
function validateSessionUserOp(
UserOperation calldata _op,
bytes32 _userOpHash,
bytes calldata _sessionKeyData,
bytes calldata _sessionKeySignature
) external virtual returns (bool);
}
```
## Tutorial Video
# Paymaster
Source: https://developers.particle.network/aa/guides/paymaster
How to use Particle Network’s Omnichain Paymaster for cross-chain gas sponsorship.
# Particle Omnichain Paymaster
The **Omnichain Paymaster** lets you sponsor gas fees across multiple chains with a **single USDT deposit**.
* Deposit USDT once (Ethereum or BNB Chain)
* Funds are automatically converted into the native gas token of the target chain
* Works out of the box with Particle’s Smart Wallet-as-a-Service
* Free to use on testnets (no deposit required)
* Fully customizable sponsorship logic via webhooks
This removes the need to manage separate balances for each chain.
***
## How to Use the Paymaster
There are two ways to use the Paymaster:
### 1. Through Particle’s AA SDKs
* Enabled automatically, no setup required.
* On testnets, transactions are sponsored for free.
* On mainnets, sponsorship is funded from your project’s Paymaster balance.
👉 Quickstarts: [Web](/aa/quickstart/web-aa) • [Mobile](/aa/quickstart/mobile-aa)
### 2. Through the Paymaster RPC
If you want direct control:
[https://paymaster.particle.network](https://paymaster.particle.network)
Supported RPC methods:
* `pm_sponsorUserOperation` — request gas sponsorship
* `pm_paymasterBalance` — check your deposit balance
👉 See [Paymaster RPC](/aa/paymaster/paymasterbalance) for examples and parameters.
***
## Funding the Paymaster
To sponsor transactions on mainnets:
1. Go to the [Particle Dashboard](https://dashboard.particle.network).
2. Create a project (if you don’t have one yet).
3. Open the **Paymaster** menu.
4. Deposit USDT on **Ethereum** or **BNB Chain**.
* Deposits are tied to your project (`projectId`, `clientKey`, `appId`).
* Deposits automatically cover sponsorships across all supported EVM chains.
USDT is not required for testnet sponsorship.
***
## Conditional Sponsorship (Webhooks)
You can define rules for when sponsorship applies using **webhooks**.
Available hooks:
* `before_paymaster_sign` — runs before sponsorship; determines if the `UserOp` should be signed.
* `after_paymaster_sign` — runs after sponsorship; useful for logging or post-processing.
Both hooks receive:
* `projectUuid` — your project ID
* `chainId` — chain where sponsorship is requested
* `userOp` — the full `UserOperation` object
* `entryPoint` — standard EntryPoint address (`0x5FF137...`)
* `parsed` — simplified transaction array
Return `200` to confirm sponsorship, or `400` to reject.
### Example: `before_paymaster_sign`
```json json [expandable] theme={null}
POST https://your-domain/hook-before-paymaster-sign
{
"type": "before_paymaster_sign",
"chainId": 80001,
"projectUuid": "ef6c29f5-ad2b-545c-ad0c-54441068b71d",
"userOp": {
"sender": "0x2e9661BDA6201F97430dcc1541A1579b83980DD1",
"nonce": "0x05",
"initCode": "0x",
"callData": "0xb61d27f6000000000000000000000000ac6a87c681a5ed4cb58bc4fa7bf81a83b928c83c00000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
"callGasLimit": "0x9acc",
"verificationGasLimit": "0x0186a0",
"preVerificationGas": "0xc5dc",
"maxFeePerGas": "0xa79dd02a",
"maxPriorityFeePerGas": "0xa79dd015",
"paymasterAndData": "0x",
"signature": "0x"
},
"parsed": {
"accountType": "SIMPLE",
"txs": [
{ "to": "0xaC6A...", "value": "0x5af3107a4000", "data": "0x" }
]
}
}
```
### Example: `after_paymaster_sign`
```json json [expandable] theme={null}
POST https://your-domain/hook-after-paymaster-sign
{
"type": "after_paymaster_sign",
"chainId": 80001,
"projectUuid": "ef6c29f5-ad2b-545c-ad0c-54441068b71d",
"userOpHash": "0x45d4f...",
"userOp": { "sender": "0x...", "nonce": "0x05", ... }
}
```
### Request Verification
All webhook requests from Particle are signed.
* A unique RSA-2048 keypair is generated for each project.
* Download your project’s public key from the Particle Dashboard.
* Use it to verify the `x-particle-signature` header on incoming requests.
### Additional Resources
# Introduction to Account Abstraction
Source: https://developers.particle.network/aa/introduction
Overview of Particle Network’s Account Abstraction SDKs.
## Account Abstraction with Particle
Particle Network makes it easy to use **ERC-4337 account abstraction** across your apps.\
With our Account Abstraction (AA) SDKs you can:
* Deploy and manage Smart Accounts
* Build and send UserOperations
* Sponsor gas fees
* Connect with Particle Auth or your own login system
***
### Why use the AA SDK?
* End-to-end account abstraction without running your own infra
* Works out of the box with Particle Auth
* Flexible enough to integrate into custom flows
* Access to Particle’s Bundler and enhanced RPC endpoints
***
### Available SDKs
Add account abstraction to web apps.
Use AA inside Unity games.
Add AA to Android apps.
Add AA to iOS apps.
Add AA to Flutter apps.
### Avilable APIs
Enhanced API for Smart Accounts.
API for Particle’s in-house Bundler.
API for Particle’s in-house Paymaster.
***
### Additional Resources
# Network Coverage
Source: https://developers.particle.network/aa/network-coverage
A complete list of all networks covered by Particle's Account Abstraction stack.
Particle Network's Account Abstraction (AA) stack provides comprehensive support across a wide range of EVM-compatible networks, enabling developers to build seamless, wallet-less experiences for users across multiple blockchains.
Our AA implementation supports various account types including Biconomy, SimpleAccount, CyberConnect, Light, and Coinbase, allowing you to choose the solution that best fits your application's needs.
## Smart Account Support
### Account Types
* **BV1**: Biconomy V1
* **BV2**: Biconomy V2
* **SA**: SimpleAccount
* **CC**: CyberConnect
* **LT**: Light
* **CB**: Coinbase
## Full Support Networks
| Network | BV1 | BV2 | SA | CC | LT | CB |
| -------- | --- | --- | -- | -- | -- | -- |
| Ethereum | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Polygon | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Optimism | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Base | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
## High Support Networks
| Network | BV1 | BV2 | SA | CC | LT | CB |
| --------- | --- | --- | -- | -- | -- | -- |
| BNB Chain | ✓ | ✓ | ✓ | ✓ | | |
| Arbitrum | ✓ | ✓ | ✓ | ✓ | | |
| Linea | | ✓ | ✓ | ✓ | | ✓ |
| opBNB | | ✓ | ✓ | ✓ | | ✓ |
| Avalanche | ✓ | ✓ | ✓ | | | ✓ |
## Medium Support Networks
| Network | BV1 | BV2 | SA | CC | LT | CB |
| ------------- | --- | --- | -- | -- | -- | -- |
| Mantle | | ✓ | ✓ | ✓ | | |
| Scroll | | ✓ | ✓ | ✓ | | |
| Cyber | | | ✓ | ✓ | | |
| Polygon zkEVM | ✓ | ✓ | ✓ | | | |
## Basic Support Networks (SimpleAccount & Biconomy V2)
| Network | BV1 | BV2 | SA | CC | LT | CB |
| --------- | --- | --- | -- | -- | -- | -- |
| Manta | | ✓ | ✓ | | | |
| Moonbeam | | ✓ | ✓ | | | |
| Combo | | ✓ | ✓ | | | |
| Gnosis | | ✓ | ✓ | | | |
| ZetaChain | | ✓ | ✓ | | | |
| Blast | | ✓ | ✓ | | | |
| Sei | | ✓ | ✓ | | | |
## SimpleAccount-Only Networks
| Network | SimpleAccount |
| ------------- | ------------- |
| Fantom | ✓ |
| GM Network | ✓ |
| Fuse | ✓ |
| IoTeX | ✓ |
| Taiko | ✓ |
| Bitlayer | ✓ |
| Xterio | ✓ |
| Astar zkEVM | ✓ |
| Viction | ✓ |
| Moonriver | ✓ |
| Core | ✓ |
| Mode | ✓ |
| Ancient8 | ✓ |
| ZKFair | ✓ |
| 5ire | ✓ |
| Kakarot | ✓ |
| Zircuit | ✓ |
| Aura | ✓ |
| Gravity | ✓ |
| DODOChain | ✓ |
| Duckchain | ✓ |
| Story Network | ✓ |
| Plume | ✓ |
| Soneium | ✓ |
| Lumia | ✓ |
| Movement | ✓ |
| HashKey | ✓ |
# paymasterBalance
Source: https://developers.particle.network/aa/paymaster/paymasterbalance
openapi-paymaster POST /#pm_paymasterBalance
Learn how to use the paymasterBalance JSON-RPC method.
## Understanding `paymasterBalance`
* `paymasterBalance` returns the USD balance (6 decimals) of the Paymaster associated with your `projectId` (`projectUuid`) and `serverKey` (`projectKey`). It takes no parameters other than the `projectUuid` and `projectKey` for authentication.
***
## Query example
```javascript JavaScript theme={null}
import Axios from "axios";
const projectUuid = "Your project uuid";
const projectKey = "Your project client key or server key";
const paymasterUrl = "https://paymaster.particle.network";
(async () => {
const response = await Axios.post(
paymasterUrl,
{
method: "pm_paymasterBalance",
params: [],
},
{
params: {
projectUuid,
projectKey,
},
}
);
console.log(response.data);
})();
```
# sponsorUserOperation
Source: https://developers.particle.network/aa/paymaster/sponsoruseroperation
openapi-paymaster POST /#pm_sponsorUserOperation
Learn how to use the sponsorUserOperation JSON-RPC method.
## Contextualizing `sponsorUserOperation`
* `sponsorUserOperation` returns a Paymaster signature to sponsor a given UserOperation, pulling from the USDT balance of the Paymaster. It takes:
* UserOperation object.
* `entrypointAddress` - string.
***
## Query example
```javascript JavaScript theme={null}
import Axios from "axios";
const chainId = 11155111;
const projectUuid = "Your project uuid";
const projectKey = "Your project client key or server key";
const entryPoint = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";
const userOp = {
sender: "0xfE71795B01d2c36FD5a001fe9D47EAec0da77e59",
nonce: "0x00",
initCode:
"0x9406cc6185a346906296840746125a0e449764545fbfb9cf0000000000000000000000009a8c05c7ac9acecc1185d5a624eb185e63dde9c20000000000000000000000000000000000000000000000000000000000000000",
callData:
"0xb61d27f6000000000000000000000000aae0de40f94469761b797920a46f223d0fffd013000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
maxFeePerGas: "0x5e18a0d2",
maxPriorityFeePerGas: "0x5de29812",
paymasterAndData: "0x",
signature: "0x",
preVerificationGas: "0xc954",
verificationGasLimit: "0x066c12",
callGasLimit: "0xf2a0",
};
const paymasterUrl = "https://paymaster.particle.network";
(async () => {
const response = await Axios.post(
paymasterUrl,
{
method: "pm_sponsorUserOperation",
params: [userOp, entryPoint],
},
{
params: {
chainId,
projectUuid,
projectKey,
},
}
);
console.log(response.data);
})();
```
# Mobile (Android/iOS) Quickstart - AA
Source: https://developers.particle.network/aa/quickstart/mobile-aa
# Using Particle's Mobile AA SDKs
The Particle Mobile AA SDKs bring account abstraction to native mobile apps. They handle:
* Smart account deployment and assignment
* `UserOperation` construction and sending
* Session keys
* Integration with paymasters and bundlers
These SDKs are modular and compatible with different smart account implementations (`BICONOMY`, `CYBERCONNECT`, `SIMPLE`, `LIGHT`, etc.).
***
## Supported Platforms
| Platform | Package |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Android** | `network.particle:aa-service` (Kotlin) |
| **iOS** | `ParticleAA` (via CocoaPods) |
| **Flutter** | `particle_aa` (Dart) |
| **React Native** | `@particle-network/rn-aa` (JavaScript) |
| **Unity** | [Unity AA Module](https://github.com/Particle-Network/particle-unity/tree/main/Assets/ParticleNetwork/Mobile/Modules/AA) |
***
## Setup Flow
1. Integrate either **Particle Connect** or **Particle Auth** (required as the authentication layer).
2. Install the AA SDK for your platform.
3. Initialize the AA service with your chosen smart account type.
* Options:
* `BICONOMY_V2`
* `CYBERCONNECT`
* `SIMPLE`
* `LIGHT`
* `COINBASE`
***
## Initialization Examples
```kotlin Android (Kotlin) theme={null}
// Optional: only if using Biconomy’s paymaster
val apiKey = mapOf(Ethereum.id to "API_KEY", Polygon.id to "API_KEY")
// Init with chosen service: BiconomyAAService, CyberConnectAAService, SimpleAAService
ParticleNetwork.initAAMode(apiKey, aaService = BiconomyAAService)
ParticleNetwork.getAAService().enableAAMode()
// Options: .biconomyV1, .biconomyV2, .cyberConnect, .simple, .light
AAService.initialize(name: .biconomyV1)
let aaService = AAService()
aaService.enableAAMode()
ParticleNetwork.setAAService(aaService)
// Options: BICONOMY_V1, BICONOMY_V2, CYBERCONNECT, SIMPLE, LIGHT
ParticleAA.init(AccountName.BICONOMY_V1())
ParticleAA.enableAAMode()
// Options: BICONOMY_V1, BICONOMY_V2, SIMPLE, CYBERCONNECT, LIGHT
ParticleAAInteraction.Init(AAAccountName.BICONOMY_V1())
// Options: BICONOMY_V1, BICONOMY_V2, CYBERCONNECT, SIMPLE, LIGHT
particleAA.init(AccountName.BICONOMY_V1())
```
***
Learn More
Select your platform for the full SDK reference:
# Web (Desktop) Quickstart - AA
Source: https://developers.particle.network/aa/quickstart/web-aa
Quickstart guide for leveraging Particle’s AA stack in web applications.
# Using Particle's Web AA SDK
The Particle Web **AA SDK** makes it simple to integrate account abstraction into your web apps. It streamlines smart account management, bundling transactions, and sponsoring gas fees—enhancing user experience and flexibility.
This guide shows how to initialize and configure the AA SDK in a web app using **Particle Authkit** as the authentication layer.
***
## Getting Started
1. Clone the [Particle Authkit starter](https://github.com/Particle-Network/particle-authkit-starter).
2. Follow the `README` instructions to set it up.
This guide uses the **Next.js** version of the starter repo.
Once your Authkit project is running, install the **AA SDK**:
```shell yarn theme={null}
yarn add @particle-network/aa
```
```shell npm theme={null}
npm install @particle-network/aa
```
### Configuring the Smart Account
If you’re using Authkit, you can enable smart accounts in the `authkit.tsx` file:
```typescript authkit.tsx theme={null}
erc4337: {
name: "SIMPLE",
version: "2.0.0",
},
```
* Contract options: `BICONOMY`, `CYBERCONNECT`, `SIMPLE`, `LIGHT`, `COINBASE`
* Versions: `1.0.0` or `2.0.0` (recommended for better gas efficiency)
Here is an example of the full configuration file:
```tsx authkit.tsx [expandable] theme={null}
"use client";
// Particle imports
import {
AuthCoreContextProvider,
PromptSettingType,
} from "@particle-network/authkit";
import { AuthType } from "@particle-network/auth-core";
import { baseSepolia, sepolia } from "@particle-network/authkit/chains";
export const ParticleAuthkit = ({ children }: React.PropsWithChildren) => {
return (
{children}
);
};
```
This is only a UI configuration for Authkit’s embedded wallet modal.
Next, configure the smart account itself in your app, in this case in `page.tsx`:
```typescript page.tsx theme={null}
import { SmartAccount } from '@particle-network/aa';
import { baseSepolia, sepolia } from "@particle-network/authkit/chains";
const smartAccount = new SmartAccount(provider, {
projectId: 'PROJECT_ID',
clientKey: 'CLIENT_KEY',
appId: 'APP_ID',
aaOptions: {
accountContracts: {
SIMPLE: [
{
version: '2.0.0',
chainIds: [baseSepolia.id, sepolia.id],
}
],
}
},
});
```
Now the smart account is initialized and ready to be used.
### Using with ethers.js
To use the smart account in ethers, wrap it with `AAWrapProvider` and select the transaction mode:
In this example we use `ethers.js` as the provider, but you can also use the AA SDK directly like shown in the [AA SDK reference](/aa/sdks/desktop/web#examples-of-utilization).
```typescript page.tsx theme={null}
import { AAWrapProvider, SendTransactionMode } from '@particle-network/aa';
import { ethers, type Eip1193Provider } from "ethers";
const createEthersProvider = () => {
return new ethers.BrowserProvider(
new AAWrapProvider(smartAccount, SendTransactionMode.Gasless) as Eip1193Provider, // options: .gasless, .userPaidNative
"any"
);
};
```
Here we use `Gasless` mode to sponsor the transaction.
### Sending a Transaction
Every transaction sent through the this ethers provider will automatically be gasless, and you can use the ethers.js API as usual.
```typescript page.tsx theme={null}
const executeTxEthers = async () => {
const ethersProvider = createEthersProvider();
const signer = await ethersProvider.getSigner();
const tx = {
to: recipientAddress,
value: ethers.parseEther("0.1"), // 0.1 ETH
};
const txResponse = await signer.sendTransaction(tx);
const txReceipt = await txResponse.wait();
console.log("Transaction receipt:", txReceipt);
};
```
Now you only need to wire this function to a button or UI element, and the transaction will be sent through the smart account.
The original EOA remains the onwer of the smart account and will be used to sign the `UserOperation`.
See a complete demo in this [repository](https://github.com/Particle-Network/kakarot-auth-aa-demo/blob/main/kakarot-particle-aa-nextjs/src/app/page.tsx).
# createSessions
Source: https://developers.particle.network/aa/rpc/createsessions
openapi-aa POST /#particle_aa_createSessions
Learn how to use the createSessions JSON-RPC method.
## Contextualizing `createSessions`
* `createSessions` will generate transactions (or UserOperation objects and hashes, according to the fee payment mechanism) for initializing a session key within predefined parameters. It takes:
* Account config object:
* `name` - string.
* `version` - string.
* `ownerAddress` - string.
* `biconomyApiKey` - (optional), string. It should only be used if you'd like to use a Biconomy Paymaster.
* Array of sessions:
* Session object:
* `validUntil` - integer.
* `validAfter` - integer.
* `sessionValidationModule` - string.
* `sessionKeyDataInAbi` (alternative: `sessionKeyData`) - array.
***
## Query example
```json JSON theme={null}
{
"chainId": 80001,
"jsonrpc": "2.0",
"id": "f7423e6b-0f69-4b96-8d1e-dcd485f8c2eb",
"method": "particle_aa_createSessions",
"params": [
{ "name": "BICONOMY", "version": "2.0.0", "ownerAddress": "0xc19dd1f3e212b39a30036EF3DE3F83dEf5a66E41" },
[
{
"validUntil": 0,
"validAfter": 0,
"sessionValidationModule": "0x4b7f018Fa27a97b6a17b6d4d8Cb3c0e2D9340133",
"sessionKeyDataInAbi": [ // or use sessionKeyData to replace
["address", "address", "address", "uint256"],
[
"0x1dacDa1087C4048774bEce7784EB8EC4CfBeDB2c",
"0x909E30bdBCb728131E3F8d17150eaE740C904649",
"0x11D266772b85C2C5D4f84A41ca3E08e9f04Fb5D3",
1
]
]
}
]
]
}
```
# createUserOp
Source: https://developers.particle.network/aa/rpc/createuserop
openapi-aa POST /#particle_aa_createUserOp
Learn how to use the createUserOp JSON-RPC method.
## Understanding `createUserOp`
* `createUserOp` will construct and return a UserOperation object and hash using a transaction or collection of transactions, alongside smart account and fee payment information. It takes:
* Account config object:
* `name` - string, either `BICONOMY`, `CYBERCONNECT`, or `SIMPLE`.
* `version` - string, either `1.0.0` or `2.0.0`.
* `ownerAddress` - string.
* `biconomyApiKey` - (optional, for using Biconomy's Paymaster), string.
* Array of transactions:
* Standard transaction object.
* Optionally, a token `feeQuote` object, retrieved from `getFeeQuotes`, only used if you're paying the gas fee in an ERC-20 token.
* Token paymaster address - (optional), string.
***
## Query example
```json JSON theme={null}
{
"jsonrpc": "2.0",
"id": "4259f7fe-87aa-44fd-89c8-fc1e41f6d3d8",
"chainId": 80001,
"method": "particle_aa_createUserOp",
"params": [
// account config
{
"name": "BICONOMY",
"version": "1.0.0",
"ownerAddress": "0xA60123a1056e9D38B64c4993615F27cCe9A9E8D5",
"biconomyApiKey": "LdF-gC43H.6f0ec763-fde5-4d5e-89f6-1b9ef12ba4a4" // optional
},
// txs
[
{
"to": "0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8",
"value": "0x1",
"data": "0x"
}
],
// optional: If you don't pass the following params, it'll create a gasless/user paid user op
// token feeQuote
{
"tokenInfo": {
"chainId": 80001,
"name": "WMATIC",
"symbol": "WMATIC",
"decimals": 18,
"address": "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889",
"logoURI": "https://polygonscan.com/token/images/wMatic_32.png"
},
"fee": "374428266633331",
"balance": "1019119852023946296",
"premiumPercentage": "10"
},
// token paymaster address
"0x00000f7365cA6C59A2C93719ad53d567ed49c14C"
]
}
```
# getFeeQuotes
Source: https://developers.particle.network/aa/rpc/getfeequotes
openapi-aa POST /#particle_aa_getFeeQuotes
Learn how to use the getFeeQuotes JSON-RPC method.
## Understanding `getFeeQuotes`
* `getFeeQuotes` returns an array of UserOperation objects and hashes derived from a standard transaction object. Each returned object corresponds to a specific gas Payment method. It takes:
* Account config object:
* `name` - string.
* `version` - string.
* `ownerAddress` - string.
* `biconomyApiKey` - (optional), string. It should only be used if you'd like to use a Biconomy Paymaster.
* An array of standard transaction objects.
***
## Query example
```json JSON theme={null}
{
"jsonrpc": "2.0",
"id": "f216c7ea-3986-4784-954f-e54320c75b40",
"chainId": 80001,
"method": "particle_aa_getFeeQuotes",
"params": [
// account config
{
"name": "BICONOMY",
"version": "1.0.0",
"ownerAddress": "0xA60123a1056e9D38B64c4993615F27cCe9A9E8D5",
"biconomyApiKey": "LdF-gC43H.6f0ec763-fde5-4d5e-89f6-1b9ef12ba4a4" // optional
},
// txs
[
{
"to": "0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8",
"value": "0x1",
"data": "0x"
}
]
]
}
```
# getSmartAccount
Source: https://developers.particle.network/aa/rpc/getsmartaccount
openapi-aa POST /#particle_aa_getSmartAccount
Learn how to use the getSmartAccount JSON-RPC method.
## Understanding `getSmartAccount`
* `getSmartAccount` returns information regarding a specific smart account (such as a `BICONOMY`, `CYBERCONNECT`, `SIMPLE`, `LIGHT`, `XTERIO` account) tied to an account address. It takes:
* Account config object:
* `name` - string. Either `BICONOMY`, `CYBERCONNECT` or `SIMPLE`.
* `version` - string. Either `1.0.0`, '1.0.2' or `2.0.0` (see the [Web SDK](/aa/sdks/desktop/web) reference for supported configurations).
* `ownerAddress` - string.
***
## Query example
```json JSON theme={null}
{
"jsonrpc": "2.0",
"id": "ee9cce2a-2f34-4c66-879e-c84c6f0e7f2d",
"chainId": 80001,
"method": "particle_aa_getSmartAccount",
"params": [
// account config array
{
"name": "BICONOMY",
"version": "1.0.0",
"ownerAddress": "0xA60123a1056e9D38B64c4993615F27cCe9A9E8D5"
},
{
"name": "BICONOMY",
"version": "1.0.0",
"ownerAddress": "0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8"
}
]
}
```
# sendUserOp
Source: https://developers.particle.network/aa/rpc/senduserop
openapi-aa POST /#particle_aa_sendUserOp
Learn how to use the sendUserOp JSON-RPC method.
## Understanding `sendUserOp`
* `sendUserOp` pushes a structured and signed UserOperation to the network, also handling session keys, sender management, etc. It takes:
* Account config object:
* `name` - string.
* `version` - string.
* `ownerAddress` - string.
* `biconomyApiKey` - (optional), string. Should only be used if you'd like to use a Biconomy Paymaster.
* UserOp object. This should be signed by the user and if applicable, the Paymaster as well.
* Optionally, `sessions` array - Session key object(s).
***
## Query example
```json JSON theme={null}
{
"jsonrpc": "2.0",
"id": "89916c65-2a47-4933-aa4c-55f7e29edbf0",
"chainId": 80001,
"method": "particle_aa_sendUserOp",
"params": [
// account config
{
"name": "BICONOMY",
"version": "1.0.0",
"ownerAddress": "0xA60123a1056e9D38B64c4993615F27cCe9A9E8D5",
"biconomyApiKey": "LdF-gC43H.6f0ec763-fde5-4d5e-89f6-1b9ef12ba4a4" // optional
},
// user op
{
"sender": "0x8fb859e944561678be40cdd2db16551396c0b074",
"nonce": "0x64",
"initCode": "0x",
"callData": "0x912ccaa3000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000020000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb032889000000000000000000000000329a7f8b91ce7479035cb1b5d62ab41845830ce80000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b300000000000000000000000000000f7365ca6c59a2c93719ad53d567ed49c14c0000000000000000000000000000000000000000000000000001548a5fd39873000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"signature": "0xf173083acfa6ddfdbbb84023ebdeb07ff2a38aa1a2e7f7b1b2eb27e180ff13987c14d72273b82f448b8e89066045aebb9e5423eea3c2314136cc9c75d7bb716f1b",
"verificationGasLimit": "0x163b8",
"callGasLimit": "0xd1e7",
"preVerificationGas": "50736",
"paymasterAndData": "0x00000f7365ca6c59a2c93719ad53d567ed49c14c000000000000000000000000000000000000000000000000000000000064d2762e0000000000000000000000000000000000000000000000000000000064d26f260000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb03288900000000000000000000000000000f7748595e46527413574a9327942e744e910000000000000000000000000000000000000000000000000de567836c0e69c0000000000000000000000000000000000000000000000000000000000010c8e09292fc583c0427b08765e4eccc030122182d141b6dbc5bb539fc4de726935042106faec9ee5b7537cf15c5f7d317fc355a0ff41877815fcbf9c906e0b584c4b61b",
"maxFeePerGas": "1500000034",
"maxPriorityFeePerGas": "1500000000"
},
// Optional
{
"sessions": [
{
"validUntil": 0,
"validAfter": 0,
"sessionValidationModule": "0x4b7f018Fa27a97b6a17b6d4d8Cb3c0e2D9340133",
"sessionKeyDataInAbi": [ // or use sessionKeyData to replace
["address", "address", "address", "uint256"],
[
"0x1dacDa1087C4048774bEce7784EB8EC4CfBeDB2c",
"0x909E30bdBCb728131E3F8d17150eaE740C904649",
"0x11D266772b85C2C5D4f84A41ca3E08e9f04Fb5D3",
1
]
]
}
],
"targetSession": {
"validUntil": 0,
"validAfter": 0,
"sessionValidationModule": "0x4b7f018Fa27a97b6a17b6d4d8Cb3c0e2D9340133",
"sessionKeyDataInAbi": [ // or use sessionKeyData to replace
["address", "address", "address", "uint256"],
[
"0x1dacDa1087C4048774bEce7784EB8EC4CfBeDB2c",
"0x909E30bdBCb728131E3F8d17150eaE740C904649",
"0x11D266772b85C2C5D4f84A41ca3E08e9f04Fb5D3",
1
]
]
}
}
]
}
```
# validateSession
Source: https://developers.particle.network/aa/rpc/validatesession
openapi-aa POST /#particle_aa_validateSession
Learn how to use the validateSession JSON-RPC method.
## Contextualizing `validateSession`
* `validateSession` returns a Boolean, `result`, indicating the validity of a given session key instance. It takes:
* Account config object:
* `name` - string.
* `version` - string.
* `ownerAddress` - string.
* `biconomyApiKey` - (optional), string. It should only be used if you'd like to use a Biconomy Paymaster.
* Array of sessions:
* Session object:
* `validUntil` - integer.
* `validAfter` - integer.
* `sessionValidationModule` - string.
* `sessionKeyDataInAbi` (alternative: `sessionKeyData`) - array.
***
## Query example
```json JSON theme={null}
{
"chainId": 80001,
"jsonrpc": "2.0",
"id": "0a7a18a1-53af-45b1-8a7f-4ece06c09e04",
"method": "particle_aa_validateSession",
"params": [
{ "name": "BICONOMY", "version": "2.0.0", "ownerAddress": "0xc19dd1f3e212b39a30036EF3DE3F83dEf5a66E41" },
{
"sessions": [
{
"validUntil": 0,
"validAfter": 0,
"sessionValidationModule": "0x4b7f018Fa27a97b6a17b6d4d8Cb3c0e2D9340133",
"sessionKeyDataInAbi": [ // or use sessionKeyData to replace
["address", "address", "address", "uint256"],
[
"0x1dacDa1087C4048774bEce7784EB8EC4CfBeDB2c",
"0x909E30bdBCb728131E3F8d17150eaE740C904649",
"0x11D266772b85C2C5D4f84A41ca3E08e9f04Fb5D3",
1
]
]
}
],
"targetSession": {
"validUntil": 0,
"validAfter": 0,
"sessionValidationModule": "0x4b7f018Fa27a97b6a17b6d4d8Cb3c0e2D9340133",
"sessionKeyDataInAbi": [ // or use sessionKeyData to replace
["address", "address", "address", "uint256"],
[
"0x1dacDa1087C4048774bEce7784EB8EC4CfBeDB2c",
"0x909E30bdBCb728131E3F8d17150eaE740C904649",
"0x11D266772b85C2C5D4f84A41ca3E08e9f04Fb5D3",
1
]
]
}
}
]
}
```
# Web (JavaScript/TypeScript) - AA
Source: https://developers.particle.network/aa/sdks/desktop/web
Leveraging Particle's AA SDK within web applications.
Particle’s **AA SDK** brings ERC-4337 to web apps: construct and send **UserOperations**, sponsor gas (gasless), pay in ERC-20 via token paymasters.
This guide assumes you already have an EIP-1193 provider (e.g., window\.ethereum from a wallet extension, WalletConnect, or a custom provider).
Check the [Quickstart](/aa/quickstart/web-aa) page for a step-by-step guide to integrate the AA SDK with [Particle Authkit](/social-logins/auth/introduction).
***
## General integration steps
The following steps outline the general process for integrating the **AA SDK** into your web application:
Connect to a user's existing wallet through `window.ethereum`, **WalletConnect**, or another compatible provider.
Initialize a Smart Account and configure your desired contract options.
Wrap your Smart Account with a provider adapter and choose how transaction gas will be paid - gasless (sponsored), user-paid with native tokens.
The wrapper automatically converts regular transactions into `UserOperations`, allowing you to use familiar libraries like **ethers.js** or **viem** with Account Abstraction.
The Particle AA SDK is open source, available at [Particle-Network/aa-sdk](https://github.com/Particle-Network/aa-sdk).
## Prerequisites
To integrate the Particle AA SDK into your web application, you'll need to:
1. **Install the SDK packages** in your project
2. **Configure your project credentials** from the Particle Dashboard
### Installation
Install the SDK in your project:
```shell yarn theme={null}
yarn add @particle-network/aa
```
```shell npm theme={null}
npm install @particle-network/aa
```
### Project setup
The AA SDK requires Particle project credentials from the [Particle Dashboard](https://dashboard.particle.network/).
To retrieve those values for configuration within your application, follow these steps:
Sign up or Log in into the [Particle dashboard](https://dashboard.particle.network/)
## Particle Paymaster
Particle Network includes a **Verifying Omnichain Paymaster** to sponsor gas fees:
* **Testnet use**: gasless transactions are automatically sponsored (no setup, no deposits).
* **Mainnet use**: deposit **USDT** on Ethereum or BNB in the [dashboard](/social-logins/dashboard#paymaster). The deposit is auto-converted into the native token of whichever chain your users transact on.
If you prefer to use **Biconomy’s Verifying Paymaster** instead, create one on the [Biconomy dashboard](https://dashboard.biconomy.io) and set its `paymasterApiKeys` in your `aaOptions`.
* For **ERC-20 gas payments** (Token Paymaster), you can rely on Biconomy’s Token Paymaster. Simply pass the `feeQuote` you receive from `getFeeQuotes`, and the SDK will handle the ERC-20 settlement.
***
## Initialization
The first step is to initialize the Smart Account instance.
You can do this by creating a new instance of the `SmartAccount` class and passing in the provider and configuration options.
```ts theme={null}
import { SmartAccount } from "@particle-network/aa";
// Any EIP-1193 provider: injected wallet, WalletConnect, etc.
const provider = window.ethereum;
const smartAccount = new SmartAccount(provider, {
projectId: "YOUR_PROJECT_ID",
clientKey: "YOUR_CLIENT_KEY",
appId: "YOUR_APP_ID",
aaOptions: {
accountContracts: {
// Choose one or more implementations and list all chains you'll transact on
SIMPLE: [{ version: "2.0.0", chainIds: [1, 8453, 11155111] }], // example: Ethereum, Base, Sepolia
// Other options if needed: BICONOMY, CYBERCONNECT, LIGHT, COINBASE
},
// Optional: Biconomy Verifying Paymaster keys per chain
// paymasterApiKeys: [{ chainId: 1, apiKey: "..." }]
},
});
// Switch implementation at runtime if needed
// smartAccount.setSmartAccountContract({ name: "BICONOMY", version: "2.0.0" });
```
Find an updated list of smart account available and their chain compatibility in [Network Coverage](/social-logins/network-coverage#smart-accounts).
***
## Using an EIP-1193 provider
You can easily use any EIP-1193 provider with the smart account by wrapping it with `AAWrapProvider` and choosing how gas is paid.
Gas modes
* `SendTransactionMode.Gasless`: sponsored when eligible
* `SendTransactionMode.UserPaidNative`: user pays native gas
### ethers.js example
The following example shows how to use the smart account with `ethers.js`.
```ts ethers.js theme={null}
import { AAWrapProvider, SendTransactionMode } from "@particle-network/aa";
import { ethers, type Eip1193Provider } from "ethers";
const ethersProvider = new ethers.BrowserProvider(
new AAWrapProvider(smartAccount, SendTransactionMode.Gasless) as Eip1193Provider,
"any"
);
// Send transactions using the normal ethers API.
// Any transaction will be automatically wrapped into a UserOperation and sent using the gasless provider.
const signer = await ethersProvider.getSigner();
const txResp = await signer.sendTransaction({ to: "0x...", value: ethers.parseEther("0.01") });
const txReceipt = await txResp.wait();
```
You can find a more complete example in this [demo repository](https://github.com/Particle-Network/connectkit-aa-usage/blob/da9dc9eb0401560c697778eb4ae8ae14a6bf2fbf/app/page.tsx#L169).
***
## Direct AA usage (no wrapper)
If you want to manage `UserOps` yourself, you have various options using the smart account instance directly.
### Smart account info
Fetch the smart account address, owner, and account info.
```ts theme={null}
const address = await smartAccount.getAddress();
const owner = await smartAccount.getOwner();
const info = await smartAccount.getAccount();
```
### Quote fees (single tx or batch)
Fetch the fee quotes for a single transaction or batch of transactions.
```ts ts theme={null}
const tx = { to: "0x...", value: "0x..." };
const feeQuotes = await smartAccount.getFeeQuotes(tx);
// Use one of the fee quotes to build a UserOperation depending on your use case
const gaslessUserOp = feeQuotes.verifyingPaymasterGasless?.userOp;
const nativeUserOp = feeQuotes.verifyingPaymasterNative?.userOp;
const tokenPaymasterAddress = feeQuotes.tokenPaymaster.tokenPaymasterAddress;
const tokenFeeQuotes = feeQuotes.tokenPaymaster.feeQuotes;
```
### Build & send UserOperation
Build and send a `UserOperation` for a single transaction or batch of transactions.
Here's a complete example of sending a gasless transfer transaction using the SDK to build a `userOp`:
```ts SDK example [expandable] theme={null}
async function sendGaslessTransaction(recipientAddress) {
// Prepare transaction parameters
const tx = {
to: recipientAddress,
value: ethers.parseEther("0.01").toString(),
data: "0x",
};
// Get fee quotes for gasless transaction
const feeQuotesResult = await smartAccount.getFeeQuotes(tx);
const gaslessQuote = feeQuotesResult?.verifyingPaymasterGasless;
if (!gaslessQuote) {
throw new Error("Failed to get gasless fee quote");
}
// Send the user operation
const hash = await smartAccount.sendUserOperation({
userOp: gaslessQuote.userOp,
userOpHash: gaslessQuote.userOpHash,
});
}
```
You can find a more complete example in this [demo repository](https://github.com/Particle-Network/connectkit-aa-usage/blob/da9dc9eb0401560c697778eb4ae8ae14a6bf2fbf/app/page.tsx#L132).
### Deployment control
Check if the smart account is deployed and deploy it if not.
```ts theme={null}
if (!(await smartAccount.isDeployed())) {
const txHash = await smartAccount.deployWalletContract();
}
```
***
## Use the AA SDK in a backend environment (server-owned EOA)
You can use the SDK in a backend environment to send transactions on behalf of the smart account.
The following example shows how to use the SDK with **viem** to create a wallet client from a private key, expose it as an EIP-1193 provider to the AA SDK, then route writes through the AA wrapper.
When using the SDK in a node environment, you need to import the package as follows:
```ts Node Imports theme={null}
import { SmartAccount, AAWrapProvider, SendTransactionMode } from '@particle-network/aa/dist/esm/index.mjs';
```
```ts Node Example [expandable] theme={null}
import { SmartAccount, AAWrapProvider, SendTransactionMode } from '@particle-network/aa/dist/esm/index.mjs';
import { createPublicClient, createWalletClient, custom, http, type Address } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { baseSepolia } from "viem/chains";
// 0) Load secrets safely (env, KMS/HSM). Never hard-code.
const RPC_URL = process.env.RPC_URL!;
const PROJECT_ID = process.env.PARTICLE_PROJECT_ID!;
const CLIENT_KEY = process.env.PARTICLE_CLIENT_KEY!;
const APP_ID = process.env.PARTICLE_APP_ID!;
const OWNER_PK = process.env.EOA_PRIVATE_KEY!; // hex string, "0x..."
const chain = baseSepolia;
// 1) Public client for reads
const publicClient = createPublicClient({ chain, transport: http(RPC_URL) });
// 2) Wallet client from private key (this is the Smart Account owner)
const ownerAccount = privateKeyToAccount(OWNER_PK);
const ownerWalletClient = createWalletClient({
account: ownerAccount,
chain,
transport: http(RPC_URL),
});
// 3) Expose the owner wallet as a minimal EIP-1193 provider for the AA SDK
const ownerEip1193 = {
request: (args: any) => ownerWalletClient.request(args),
} as any;
// 4) Create the Smart Account (list all chains you’ll use)
const smartAccount = new SmartAccount(ownerEip1193, {
projectId: PROJECT_ID,
clientKey: CLIENT_KEY,
appId: APP_ID,
aaOptions: {
accountContracts: {
SIMPLE: [{ version: "2.0.0", chainIds: [chain.id] }],
// You can add BICONOMY / CYBERCONNECT / LIGHT / COINBASE here if needed
},
// Optional: Verifying/Token Paymaster keys per chain
// paymasterApiKeys: [{ chainId: chain.id, apiKey: "..." }],
},
});
// 5) Wrap writes through AA; choose gas mode
const aaProvider = new AAWrapProvider(smartAccount, SendTransactionMode.Gasless); // or UserPaidNative
// 6) A wallet client for writes that routes requests to the AA provider
const aaWalletClient = createWalletClient({
chain,
account: (await smartAccount.getAddress()) as Address, // the smart account address
transport: custom({
request: (args) => aaProvider.request(args as any),
}),
});
// Reads use the public client
const saAddress = (await smartAccount.getAddress()) as Address;
const balance = await publicClient.getBalance({ address: saAddress });
// Writes are turned into UserOperations under the hood
const txHash = await aaWalletClient.sendTransaction({
to: "0xRecipient...",
value: 0n, // viem uses bigint
});
console.log("sent via AA:", txHash);
```
You can find a complete implementation in this [demo repository using the AA SDK to interacti with Circle Gateway](https://github.com/Particle-Network/circle-gateway-particle-aa-demo).
## Master reference
The following table is a **method-level reference** for the `SmartAccount` class. Use it when you need exact signatures or want to explore functionality beyond the common flows shown earlier (initialization, fee quotes, sending transactions).
Most methods follow the same input/output patterns as the examples above, so you can usually adapt them directly into your own code.
| Class | Methods | Parameters (\* indicates optional) |
| ------------ | ----------------------- | ----------------------------------- |
| SmartAccount | constructor | provider, config |
| SmartAccount | setSmartAccountContract | contract |
| SmartAccount | getChainId | |
| SmartAccount | getAccountConfig | |
| SmartAccount | getPaymasterApiKey | |
| SmartAccount | getFeeQuotes | tx |
| SmartAccount | buildUserOperation | tx, feeQuote, tokenPaymasterAddress |
| SmartAccount | signUserOperation | userOpHash, userOp |
| SmartAccount | sendUserOperation | userOpHash, userOp |
| SmartAccount | sendSignedUserOperation | userOp, sessionDataParams\* |
| SmartAccount | sendTransaction | tx, feeQuote, tokenPaymasterAddress |
| SmartAccount | getAccount | |
| SmartAccount | getAddress | |
| SmartAccount | getOwner | |
| SmartAccount | isDeployed | |
| SmartAccount | deployWalletContract | |
| SmartAccount | sendRpc | arg |
| SmartAccount | createSessions | options |
| SmartAccount | validateSession | targetSession, sessions |
# Android (Kotlin) - AA
Source: https://developers.particle.network/aa/sdks/mobile/android
Leveraging Particle's AA SDK within Android applications.
## Account Abstraction on Android
Particle Network's AA SDK facilitates the comprehensive use of ERC-4337 account abstraction. Particle's AA SDK handles every step in leveraging account abstraction: smart account deployment, user operation construction and sending, fee quote generation, etc., and is fully compatible with Android applications.
***
## Getting Started
Installing, initializing, and ultimately using the Particle Network AA SDK for Android only takes a few steps.
### Prerequisites
* minSdkVersion **23** or higher.
* compileSdkVersion, targetSdkVersion **34** or higher.
* JavaVersion **17**.
* [Jetpack (AndroidX)](https://developer.android.com/jetpack/androidx/migrate?authuser=0).
* Android Gradle Plugin Version: **8.5.1** or higher.
* Gradle Version: **8.9** or higher.
The first is including the `network.particle:aa-service` dependency within your `build.gradle` file, filling in `latest_version` with the most recent release on [Maven](https://central.sonatype.com/artifact/network.particle/aa-service/overview).
This should be defined in a way similar to the example below:
```groovy build.gradle theme={null}
dependencies {
implementation("network.particle:aa-service:${latest_version}")
// https://search.maven.org/search?q=g:network.particle
// ...
}
```
📘 Important details before initialization
Before initializing the SDK, there are a few key points to keep in mind,
specifically regarding the utilization of Paymasters (to sponsor gas fees,
pay for gas in ERC-20 tokens, etc.)
* All Testnets automatically have the Verifying Particle Network Omnichain
Verifying Paymaster enabled. Transactions that request it will automatically
be sponsored and thus gasless.
* On the occasion that you'd like to use the Particle Network Omnichain
Verifying Paymaster for Mainnets, you'll need to deposit USDT on either
Ethereum or BNB Chain within the
Particle dashboard. This
USDT will then automatically be converted as needed into the native token of
the network on which you're requesting (and qualifying for) sponsorship.
* The Particle Network AA SDK automatically uses Biconomy's Token Paymaster;
transactions that request it will be able to leverage it without additional
configuration.
***
## Initialization
With your project configured, you can move onto initializing the AA SDK. This is required before other SDK functions will work and allow you to select which smart account implementation you use. You can kickstart initialization through `ParticleNetwork.initAAMode`, which takes the following parameters:
* Optionally, `apiKey`, a singular or array of specific chains mapped to a given Biconomy API key, allowing for the usage of Biconomy's Paymaster (if applicable).
* `aaService`, dictating the smart account implementation to be used, this can be:
* `BiconomyV1AAService`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts)
* `BiconomyV2AAService`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts)
* `CyberConnectAAService`, a [CyberConnect smart account](https://wallet.cyber.co/).
* `SimpleV1AAService`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `SimpleV2AAService`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `LightAAService`, a [Light Account implementation](https://accountkit.alchemy.com/smart-contracts/light-account).
E.g.:
```kotlin Kotlin theme={null}
ParticleNetwork.initAAMode(aaService = BiconomyV2AAService)
```
## Enable AA Mode
Additionally, after initializing the SDK with `initAAMode`, you'll need to intentionally enable it (signaling an updated address on the wallet interface, among other things) by using `ParticleNetwork.getAAService().enableAAMode()`. Alternatively, if it's already enabled and you'd like to disable it, you can do so with `disableAAMode`.
If you're unsure whether or not AA mode is enabled or not, you can retrieve a Boolean representing this status with `isAAModeEnable`.
E.g.:
```kotlin Kotlin theme={null}
ParticleNetwork.getAAService().enableAAMode()
ParticleNetwork.getAAService().disableAAMode()
val isEnable = ParticleNetwork.getAAService().isAAModeEnable()
```
## Send Transaction
Sending a standard transaction (UserOperation after enabling AA mode), requesting a signature, and then automatically pushing it to the network with `ParticleNetwork` can be done through `ParticleNetwork.signAndSendTransaction`, which takes the following parameters:
* `transaction`, a stringified standard transaction object.
* `callback`, return handling.
* `feeMode`, the mechanism to be used for paying gas fees, can be:
* `FeeModeGasless`, for sponsored transactions. This will happen automatically for Testnets, pulling from your previously defined (or configured) Paymaster for Mainnets.
* `FeeModeNative`, native payments.
* `FeeModeToken`, enables the selection of a specific mechanism, takes one parameter:
* `feeQuote`, to be used when leveraging a Token Paymaster, can be retrieved through `ParticleNetwork.getAAService().rpcGetFeeQuotes()`.
Additionally, if you're using Particle Connect, you can send the same type of transaction by calling the `signAndSendTransaction` method on a relevant adapter. This takes the same parameters, although it requires passing the `publicAddress` of the targeted user for the transaction.
```kotlin Kotlin theme={null}
val feeModeGasLess: FeeMode = FeeModeGasless()
val transaction = "your transaction"
val feeQuote = ParticleNetwork.getAAService().rpcGetFeeQuotes("eoa address", listOf(transaction)).result
val feeModeNative: FeeMode = FeeModeNative(verifyingPaymasterNative =feeQuote.verifyingPaymasterNative )
val feeModeToken: FeeMode = FeeModeToken(feeQuote.tokenPaymaster.feeQuotes[0], feeQuote.tokenPaymaster.tokenPaymasterAddress)
AuthCore.evm.sendTransaction(transaction, object : AuthCoreSignCallback {
override fun success(output: SignOutput) {
// success output.signature
}
override fun failure(errMsg: ErrorInfo) {
// Handle error
}
}, feeModeGasLess) //feeModeNative or feeModeToken
// Alternatively, if using Particle Connect
connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeGasLess, callback)
connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeToken, callback)
connectAdapter.signAndSendTransaction(publicAddress, transaction, feeModeToken, callback)
```
## Send Batch Transactions
As an alternative to `signAndSendTransaction`, you can use `quickSendTransaction` to batch multiple transactions together within a single UserOperation. `quickSendTransaction` requires the following parameters:
* `transactions`, an array of stringified transaction objects.
* `feeMode`, the mechanism for paying gas fees.
* `messageSigner`, the owner/Signer address that'll be signing the UserOperation.
* `callback`, return handling.
E.g.:
```kotlin Kotlin theme={null}
ParticleNetwork.getAAService().quickSendTransaction(transactions, feeMode, messageSigner, callback)
```
***
## Master reference
For a direct, raw view into every method provided, below is a table containing every relevant one, alongside specific parameters and a short description. For methods listed that weren't covered in the above examples, live implementation often mimics the previously covered common structure throughout the SDK.
| Methods | Parameters |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| rpcGetSmartAccount | addresses: List`` |
| rpcGetFeeQuotes | eoaAddress: String, transactions: List`` |
| rpcCreateUserPaidTransaction | eoaAddress: String, transactions: List``, erc4337FeeQuote: Erc4337FeeQuote |
| rpcSendUserPaidTransaction | eoaAddress: String, walletTransaction: WalletTransaction, signature: String |
| rpcSendGaslessTransaction | eoaAddress: String, userOp: WalletUserOp, signature: String |
| rpcCreateGaslessTransaction | eoaAddress: String, transactions: List`` |
| isDeploy | eoaAddress: String |
| deployWalletContract | messageSigner: MessageSigner, feeMode: FeeMode\* |
| isAAModeEnable | |
| enableAAMode | |
| disableAAMode | |
| getSmartAccount | eosAddress: String |
| getSmartAccountSync | eosAddress: String |
| getSmartAddress | eosAddress: String |
| getSmartAccounts | eosAddresses: List` ` |
| isSupportChainInfo | chainInfo: ChainInfo |
| getSupportChainInfos | |
| quickSendTransaction | transactions: `String, feeMode: FeeMode\*, messageSigner: MessageSigner, sendCallback: WebServiceCallback`\* |
| quickSendTransaction | transactions: List``, feeMode: FeeMode\*, messageSigner: MessageSigner, sendCallback: WebServiceCallback``\* |
# Flutter (Dart) - AA
Source: https://developers.particle.network/aa/sdks/mobile/flutter
Leveraging Particle's AA SDK within applications built using Flutter.
## Account Abstraction for Flutter
Particle Network's AA SDK offers a mechanism for facilitating full-stack ERC-4337 account abstraction, leveraging built-in infrastructure modularity without compromising simplicity. Paired with Particle Auth or Particle Connect for seamless onboarding, the Particle Network AA SDK presents itself as a key method for building high-quality UX within applications built using Flutter.
## Repository
All Particle Network Flutter SDKs, including the AA SDK for Flutter, are open-source in the [`particle-flutter` repository on GitHub](https://github.com/Particle-Network/particle-flutter), with each including demos/examples. It may be worthwhile taking a look at the [AA Flutter SDK](https://github.com/Particle-Network/particle-flutter/tree/master/particle-aa)'s architecture and implementation flow before continuing to build some context.
***
## Getting Started
Before jumping in, you'll need to already have setup either [Particle Auth](/social-logins/auth/mobile-sdks/flutter) or [Particle Connect](/social-logins/connect/mobile/flutter) within your Flutter project (the AA SDK doesn't work on its own, requiring one of the two to function). If you don't have either of these already implemented, read through those pages and follow the outlined steps, then return to continue.
With either of these SDKs set up, you can move on to adding `particle_aa` to your Flutter project through the following command:
```
flutter pub add particle_aa
```
Important details before initialization
Before initializing the SDK, there are a few points to keep in mind, specifically regarding the utilization of Paymasters (to sponsor gas fees, pay for gas in ERC-20 tokens, etc.)
- All Testnets automatically have the Verifying Particle Network Omnichain Verifying Paymaster enabled. Transactions requesting it will automatically be sponsored and thus gasless.
- On the occasion that you'd like to use the Particle Network Omnichain Verifying Paymaster for Mainnets, you'll need to deposit USDT on either Ethereum or BNB Chain within the Particle dashboard. This USDT will then automatically be converted as needed into the native token of the network you're requesting (and qualifying for) sponsorship on.
- The Particle Network AA SDK automatically uses Biconomy's Token Paymaster; transactions that request it will be able to leverage it without additional configuration.
## Initialization
The Particle Network AA SDK will fail to function correctly until it has been initialized. Initialization allows you to specify a smart account implementation and version, alongside the Paymaster you'd like to use. This can be initiated through `ParticleAA.init`, which takes the following parameters:
* `name`, the smart account implementation to be used (any of these choices):
* `AccountName.BICONOMY_V1`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `AccountName.BICONOMY_V2`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `AccountName.CYBERCONNECT`, a [CyberConnect smart account](https://wallet.cyber.co/).
* `AccountName.SIMPLE_V1`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `AccountName.SIMPLE_V2`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `AccountName.LIGHT`, a [Light Account implementation](https://accountkit.alchemy.com/smart-contracts/light-account).
Once `init` has been called, you can close off initialization by enabling AA mode with `ParticleAA.enableAAMode`.
```dart theme={null}
// Support BICONOMY_V1 | BICONOMY_V2 | CYBERCONNECT | SIMPLE_V1 | SIMPLE_V2 | LIGHT
ParticleAA.init(AccountName.BICONOMY_V2());
ParticleAA.enableAAMode();
```
***
## Examples of Utilization
### Is Deployed
Now that you've initialized the AA SDK, you can move onto several methods to utilize it. First, it's important to note that the smart account implementation you chose will be automatically deployed with the first transaction it initiates. The deployment transaction will be bundled (batched) in with the first transaction.
However, if you'd like to check the deployment status of a given smart account manually, you can first retrieve the host address with `Evm.getAddress`, then pass that into `ParticleAA.isDeploy`, which returns a Boolean indicating deployment status.
E.g.:
```dart theme={null}
final eoaAddress = await Evm.getAddress();
var isDeploy = await ParticleAA.isDeploy(eoaAddress);
```
***
### Disable AA Mode
If you'd like to exit AA mode and thus disable account abstraction functionality within your application, you'll need to call `ParticleAA.disableAAMode`. This will immediately render the usage of AA incompatible. Additionally, if you're unsure whether or not AA mode is enabled, you can call `ParticleAA.isAAModeEnable`, which will return a Boolean representing this status. E.g.:
```dart theme={null}
ParticleAA.disableAAMode();
var result = await ParticleAA.isAAModeEnable();
```
***
### Send Transaction
Sending a transaction (UserOperation) is as simple as calling pre-existing methods within `ParticleConnect` or `Evm` in `particle_auth_core` and just passing in an additional parameter, `feeMode`. There are two ways to send transactions with the AA SDK: The first is with `signAndSendTransaction` of `sendTransaction` , which will send a singular transaction to the network. Alternatively, you can use `batchSendTransactions` to send batched transactions within a single UserOperation.
`ParticleConnect.signAndSendTransaction` or `Evm.sendTransaction` in `particle_auth_core` takes the following parameters:
* For Particle Connect, `walletType`, dictates the specific adapter being used/targeted.
* `account`, the public address of the smart account sending the transaction, which can be retrieved through `EvmService.getSmartAccount`.
* `transaction`, a stringified standard transaction object.
* `feeMode`, the mechanism to be used for paying gas fees, can be:
* `AAFeeMode.gasless`, for sponsored transactions. This will happen automatically for Testnets and will pull from your previously defined (or configured) Paymaster for Mainnets. Takes one parameter:
* `wholeFeeQuote`, which can be retrieved through `ParticleAA.rpcGetFeeQuotes`.
* `AAFeeMode.native`, paying for gas fees in a native token (such as ETH). Takes one parameter:
* `wholeFeeQuote`, which can be retrieved through `ParticleAA.rpcGetFeeQuotes`.
* `AAFeeMode.token`, paying for gas fees in an ERC-20 token (such as USDC). Takes one parameter:
* `feeQuote`, to be used when leveraging a Token Paymaster. It can be retrieved through `ParticleAA.rpcGetFeeQuotes`.
* `tokenPaymasterAddress`, which can be retrieved through `ParticleAA.rpcGetFeeQuotes`.
Alternatively, for `ParticleConnect.batchSendTransactions` or ParticleAuthCore `Evm.batchSendTransactions`, the parameters will be the same, with the exception of `transaction` being an array of transactions.
```dart theme={null}
// with particle_auth_core
await Evm.sendTransaction(transaction,
feeMode: AAFeeMode.gasless(result));
await Evm.sendTransaction(transaction,
feeMode: AAFeeMode.native(result));
await Evm.sendTransaction(transaction,
feeMode: AAFeeMode.token(feeQuote, tokenPaymasterAddress));
await Evm.batchSendTransactions(transactions,
feeMode: AAFeeMode.native(result));
// with particle_connect
await ParticleConnect.signAndSendTransaction(
WalletType.authCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.gasless(result));
await ParticleConnect.signAndSendTransaction(
WalletType.authCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.native(result));
await ParticleConnect.signAndSendTransaction(
WalletType.authCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.token(feeQuote, tokenPaymasterAddress));
await ParticleConnect.batchSendTransactions(
WalletType.authCore, eoaPublicAddress, transactions,
feeMode: AAFeeMode.native(result));
```
Check if you can send with AAFeeMode.gasless/native/token.
```dart theme={null}
var result = await ParticleAA.rpcGetFeeQuotes(EoaPublicAddress, [transaction]);
var verifyingPaymasterNative = result["verifyingPaymasterNative"];
var feeQuote = verifyingPaymasterNative["feeQuote"];
var fee = BigInt.parse(feeQuote["fee"], radix: 10);
var balance = BigInt.parse(feeQuote["balance"], radix: 10);
// Check if the account can afford gas
if (balance < fee) {
print("Native balance is not enough for gas fee");
return;
}
// Check if a gasless (sponsored) transaction is available
var verifyingPaymasterGasless = result["verifyingPaymasterGasless"];
if (verifyingPaymasterGasless == null) {
print("Gasless is not available");
return;
}
// Check if gas payment via ERC20 is available
List feeQuotes = result["tokenPaymaster"]["feeQuotes"];
var overFeeQuotes = feeQuotes.where((element) {
var fee = BigInt.parse(element["fee"], radix: 10);
var balance = BigInt.parse(element["balance"], radix: 10);
return balance >= fee;
}).toList();
if (overFeeQuotes.isEmpty) {
print("Can't pay in tokens, no valid token for gas fee");
return;
}
// Select a fee quote (native, gasless, token), for example the first.
var feeQuote = overFeeQuotes[0];
String tokenPaymasterAddress = result["tokenPaymaster"]["tokenPaymasterAddress"];
```
***
See the [Particle Auth](/social-logins/auth/mobile-sdks/flutter) and [Particle Connect](/social-logins/connect/mobile/flutter) pages for insights into additional compatible methods (such as `signAndSendTransaction`), as shown here.
# iOS (Swift) - AA
Source: https://developers.particle.network/aa/sdks/mobile/ios
Leveraging Particle's AA SDK within iOS applications.
## Account Abstraction for iOS
Particle Network's AA SDK, existing at the center of its Smart Wallet-as-a-Service, facilitates flexible end-to-end utilization of ERC-4337 account abstraction, natively supporting modular smart account implementations, Paymasters, and natural Bundler usage. Within iOS applications, the Particle Network AA SDK can be used (in tandem with Particle Auth or Particle Connect) to refine user experience through account abstraction.
Details on configuration, initialization, and utilization **are listed below**.
***
## Getting Started
To get started, you'll need to have already integrated either [Particle Connect](/social-logins/auth/mobile-sdks/ios) or [Particle Auth](/social-logins/connect/mobile/ios) within your iOS application. If you haven't, head over to those pages, follow the configuration process, and return here. Otherwise, you can begin by including `ParticleAA` within your Podfile, as shown below:
```ruby Podfile theme={null}
pod 'ParticleAA'
```
This new addition to your Podfile can then be settled and installed by running the command below:
```shell Terminal theme={null}
pod install --repo-update
```
Important details before initialization
Before initializing the SDK, there are a few points to keep in mind, specifically regarding the utilization of Paymasters (to sponsor gas fees, pay for gas in ERC-20 tokens, etc.)
- All Testnets automatically have the Verifying Particle Network Omnichain Verifying Paymaster enabled. Transactions requesting it will automatically be sponsored and thus gasless.
- On the occasion that you'd like to use the Particle Network Omnichain Verifying Paymaster for Mainnets, you'll need to deposit USDT on either Ethereum or BNB Chain within the Particle dashboard. This USDT will then automatically be converted as needed into the native token of the network you're requesting (and qualifying for) sponsorship on.
- The Particle Network AA SDK automatically uses Biconomy's Token Paymaster; transactions that request it will be able to leverage it without additional configuration.
***
## Initialization
To begin, before using the SDK, you'll need to initialize it; without this, the `setAAService` within `ParticleNetwork` will fail or raise issues down the line.
You can initialize the SDK through `AAService.initialize`, which requires the following parameters:
* `name`, the name of the smart account implementation to be used, the choices here are:
* `.biconomyV1`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `.biconomyV2`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `.cyberConnect`, a [CyberConnect smart account](https://wallet.cyber.co/).
* `.simpleV1`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `.simpleV2`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `.light`, a [Light Account](https://accountkit.alchemy.com/smart-contracts/light-account).
Once `AAService.initialize` has been called, you'll need to use `ParticleNetwork.setAAService`, passing in an instance of `AAService`. This will tell Particle Auth to use your smart account rather than your EOA. Either before or after doing this, you'll also need to call `aaService.enableAAMode`.
```swift theme={null}
AAService.initialize(name: .biconomyV1)
let aaService = AAService()
aaService.enableAAMode()
ParticleNetwork.setAAService(aaService)
```
## Examples of Utilization
### Disable AA Mode
If you'd like to disable AA mode (stop using account abstraction) after enabling it during the initialization process (through `enableAAMode`), then you'll need to call `aaService.disableAAMode`, with `aaService` being an instance of `AAService`.
However, if you aren't sure whether AA mode is enabled or not, you can call `aaService.isAAModeEnable`, which returns a Boolean representing this status.
E.g.:
```swift theme={null}
aaService.disableAAMode()
let isEnable = aayService.isAAModeEnable()
```
### Get Smart Account
You can also retrieve the address of the smart account, among other details, by calling the `getSmartAccount` method on `aaService` (which can be defined by `ParticleNetwork.getAAService` if needed), in which you can pass `by` (your Signer/owner address, which should be an EOA), and `chainInfo`, which should be a `ChainInfo` object representing the chain on which you're querying account information. E.g.:
| Field | Type | Description |
| --------------- | ------------ | ---------------------------------------- |
| `publicAddress` | `String` | EOA address. |
| `chainInfo` | `ChainInfo?` | (Optional) default is current chainInfo. |
```swift theme={null}
let smartAccount = try await aaService.getSmartAccount(by: eoaAddress, chainInfo: chainInfo).value
```
### Send Transaction
Sending a transaction (UserOperation) is also quite simple, primarily just deviating in the fee mechanism being used for it. There are three ways to send transactions with the AA SDK:
The `auth.evm.sendTransaction` method, defined in `ParticleAuthCore`, is used to send a single transaction to the network.
The `adapter.signAndSendTransaction` method, defined in `ConnectAdapter`, is used to send a single transaction to the network.
The `aaService.quickSendTransactions` method, defined in `ParticleAA`, is used to send batched transactions within a single UserOperation.
`auth.evm.sendTransaction` takes the following parameters:
* `transaction`, a stringified standard transaction object.
* `feeMode`, the mechanism to be used for paying gas fees, can be:
* `.gasless`, for sponsored transactions; this will happen automatically for Testnets, and will pull from your previously defined (or configured) Paymaster for Mainnets.
* `.native`, paying for gas fees in a native token (such as ETH).
* `.token`, paying for gas fees in an ERC-20 token (such as USDC), and thus takes one parameter:
* `feeQuote`, to be used when leveraging a Token Paymaster.
* Optionally, `chainInfo`: a `ChainInfo` object representing the chain on which this transaction will be executed.
`adapter.signAndSendTransaction` takes the following parameters:
* `publicAddress`, the connected public address, if `adapter.WalletType` is `.authCore`, you can pass an empty string, for other walletTypes, you need pass a connected public address.
* `transaction`, a stringified standard transaction object.
* `feeMode`, the mechanism to be used for paying gas fees, can be:
* `.gasless`, for sponsored transactions; this will happen automatically for Testnets, and will pull from your previously defined (or configured) Paymaster for Mainnets.
* `.native`, paying for gas fees in a native token (such as ETH).
* `.token`, paying for gas fees in an ERC-20 token (such as USDC), and thus takes one parameter:
* `feeQuote`, to be used when leveraging a Token Paymaster.
* Optionally, `chainInfo`: a `ChainInfo` object representing the chain on which this transaction will be executed.
Alternatively, for `aaService.quickSendTransactions`, the parameters will be the same with the following exceptions:
* `transactions` being an array of transactions.
* `feeMode` is same with upon.
* `messageSigner`, which is the Signer/owner authenticating the transaction.
* `wholeFeeQuote`, which for each `feeMode` should be passed with a complete fee quote object.
* Optionally, `chainInfo` is same with upon.
E.g.:
```swift theme={null}
// Gasless
let txHash = try await auth.evm.sendTransaction(transaction, feeMode: .gasless, chainInfo: chainInfo)
let txHash = try await aaService.quickSendTransactions([transaction], feeMode: .gasless, messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
// Native
let txHash = try await auth.evm.sendTransaction(transaction, feeMode: .native, chainInfo: chainInfo)
let txHash = try await aaService.quickSendTransactions([transaction], feeMode: .native, messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
// ERC-20 Token
let txHash = try await auth.evm.sendTransaction(transaction, feeMode: .token(feeQuote), chainInfo: chainInfo)
let txHash = try await aaService.quickSendTransactions([transaction], feeMode: .token(feeQuote), messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
```
Implement MessageSigner protocol
```swift theme={null}
class YourViewController {
var publicAddress: String = ""
}
extension YourViewController: MessageSigner {
func signMessage(_ message: String, chainInfo: ParticleNetworkBase.ParticleNetwork.ChainInfo?) -> RxSwift.Single {
// If you are using ParticleAuthService
return Single.fromAsync { [weak self] in
guard let self = self else { throw ParticleNetwork.ResponseError(code: nil, message: "self is nil") }
return try await self.evm.personalSign(message, chainInfo: chainInfo)
}
// If you are using ParticleConnectService
// Get current adapter by walletType and publicAddress
// Here we assume currentWalletType is Metamask
let currentWalletType = WalletType.metaMask
let adapters = ParticleConnect.getAllAdapters().filter {
$0.walletType == currentWalletType
}
if let adapter = adapters.first {
return adapter.signMessage(publicAddress: self.publicAddress, message: message)
} else {
return .error(NSError(domain: "", code: 0))
}
}
func getEoaAddress() -> String {
// If you are using ParticleAuthCore
return auth.evm.getAddress() ?? ""
// If you are using ParticleConnectService
return self.publicAddress
}
}
// Add this single extension to support converting rxswift function to combine function
extension Single {
static func fromAsync(_ fn: @escaping () async throws -> T) -> Single {
.create { observer in
let task = Task {
do { try await observer(.success(fn())) }
catch { observer(.failure(error)) }
}
return Disposables.create { task.cancel() }
}.observe(on: MainScheduler.instance)
}
}
```
Check if you can send gasless/native/token.
```swift theme={null}
extension YourViewController {
func sendTransactionInAA() async throws {
let aa = ParticleNetwork.getAAService()!
let chainInfo = ParticleNetwork.getChainInfo()
let eoaAddress = ""
let transaction = ""
let wholeFeeQuote = try await aa.rpcGetFeeQuotes(eoaAddress: eoaAddress, transactions: [transaction], chainInfo: chainInfo).value
if wholeFeeQuote.gasless != nil {
// There are two ways to sponsor transactions
// 1, call adapter or ParticleAuthService, requires one transaction
let txHash1 = try await auth.evm.sendTransaction(transaction, feeMode: .gasless, chainInfo: chainInfo)
// 2, call AA, supports batched transactions, requires implementation of MessageSigner delegate.
let txHash2 = try await aa.quickSendTransactions([transaction], feeMode: .gasless, messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
} else {
// Gasless wouldn't be possible in this condition.
}
let nativeFeeQuote = AA.FeeQuote(json: wholeFeeQuote.native.feeQuote, tokenPaymasterAddress: nil)
if nativeFeeQuote.isEnoughForPay {
// There are two ways to send, pay token
// 1, call adapter or ParticleAuthService, requires one transaction
let txHash1 = try await auth.evm.signAndSendTransaction(transaction, feeMode: .native, chainInfo: chainInfo)
// 2, call AA, supports batched transactions, requires implementation of MessageSigner delegate.
let txHash2 = try await aa.quickSendTransactions([transaction], feeMode: .native, messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
} else {
// User can't afford transaction
}
if let token = wholeFeeQuote.token {
let tokenPaymasterAddress = token.tokenPaymasterAddress
let tokenFeeQuotes = token.feeQuotes.map {
AA.FeeQuote(json: $0, tokenPaymasterAddress: tokenPaymasterAddress)
}.filter {
// Filter out balance >= fee
$0.isEnoughForPay
}
if tokenFeeQuotes.count > 0 {
// Select a feeQuote, here we select the first one.
let feeQuote = tokenFeeQuotes[0]
// There are two ways to send, pay token
// 1, call adapter or ParticleAuthService, requires one transaction
let txHash1 = try await auth.evm.signAndSendTransaction(transaction, feeMode: .token(feeQuote), chainInfo: chainInfo)
// 2, call AA, supports batched transactions, requires implementation of MessageSigner delegate.
let txHash2 = try await aa.quickSendTransactions([transaction], feeMode: .token(feeQuote), messageSigner: self, wholeFeeQuote: wholeFeeQuote, chainInfo: chainInfo).value
} else {
// You can't select a token to pay
}
}
}
}
```
### Manually Deploy Smart Account
An undeployed smart account will automatically be deployed upon the ***first transaction*** (UserOperation) it sends through the SDK (the deployment transaction is bundled/batched with the other). If you'd like to initiate deployment manually, bypassing automatic deployment, then you can use `aaService.deployWalletContract`, which will create, request signature for, and send a deployment transaction. This method requires `messageSigner` (the Signer of the transaction), and the `feeMode` of the deployment transaction.
The status of deployment can be retrieved with `smartAccount.isDeploy`, which takes an owner/Signer `eoaAddress`.
E.g.:
```swift theme={null}
let isDeploy = try await aaService.isDeploy(eoaAddress: eoaAddress).value
aaService.deployWalletContract(messageSigner: signer, feeMode: .gasless)
```
# React Native (JavaScript) - AA
Source: https://developers.particle.network/aa/sdks/mobile/react
Leveraging Particle's AA SDK within React Native applications.
## React Native
### 1. Add the Account Abstraction Service SDK to Your React Native App
Run this command:
```shell Terminal theme={null}
npm install @particle-network/rn-aa
// Or
yarn add @particle-network/rn-aa
```
Click [here](https://github.com/Particle-Network/particle-react-native/tree/master/particle-aa) to get the demo source code
### 2. Add Particle Auth or Particle Connect to your project
Account Abstraction service can't be used individually.
Important details before initialization.
Before initializing the SDK, there are a few key points to keep in mind, specifically regarding the utilization of Paymasters (to sponsor gas fees, pay for gas in ERC-20 tokens, etc.)
- All Testnets automatically have the Verifying Particle Network Omnichain Paymaster enabled. Transactions that request it will automatically be sponsored and thus gasless.
- On the occasion that you'd like to use the Particle Network Omnichain Paymaster for Mainnets, you'll need to deposit USDT on either Ethereum or BNB Chain within the Particle dashboard. This USDT will then automatically be converted as needed into the native token of the network you're requesting (and qualifying for) sponsorship on.
## Initialize the SDK
The Particle Network AA SDK will fail to function correctly until it has been initialized. Initialization allows you to specify a smart account implementation and version, alongside the Paymaster you'd like to use. This can be initiated through `particleAA.init`, which takes the following parameters:
* `accountName`, the smart account implementation to be used (any of these choices):
* `AccountName.BICONOMY_V1`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `AccountName.BICONOMY_V2`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `AccountName.CYBERCONNECT`, a [CyberConnect smart account](https://wallet.cyber.co/).
* `AccountName.SIMPLE_V1`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `AccountName.SIMPLE_V2`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `AccountName.LIGHT`, a [Light Account](https://accountkit.alchemy.com/smart-contracts/light-account).
Once `init` has been called, you can close off initialization by enabling AA mode with `ParticleAA.enableAAMode`.
```typeScript theme={null}
import * as particleAA from '@particle-network/rn-aa';
import { AAVersion } from '@particle-network/rn-base';
// Support BICONOMY_V1 | BICONOMY_V2 | CYBERCONNECT | SIMPLE_V1 | SIMPLE_V2 | LIGHT
particleAA.init(AccountName.BICONOMY_V2());
particleAA.enableAAMode();
```
***
### Is Deployed
Now that you've initialized the AA SDK, you can move onto several methods to utilize it. First, it's important to note that the smart account implementation you chose will be automatically deployed with the first transaction it initiates. The deployment transaction will be bundled (batched) in with the first transaction.
However, if you'd like to check the deployment status of a given smart account manually, you can first retrieve the host address with `evm.getAddress`, then pass that into `particleAA.isDeploy`, which returns a Boolean indicating deployment status.
E.g.:
```typeScript theme={null}
const eoaAddress = await evm.getAddress();
const isDeploy = await particleAA.isDeploy(eoaAddress);
```
***
### Disable AA Mode
If you'd like to exit AA mode and thus disable account abstraction functionality within your application, you'll need to call `ParticleAA.disableAAMode`. This will immediately render the usage of AA incompatible. Additionally, if you're unsure whether or not AA mode is enabled, you can call `ParticleAA.isAAModeEnable`, which will return a Boolean representing this status. E.g.:
```typeScript theme={null}
particleAA.disableAAMode();
const result = await particleAA.isAAModeEnable();
```
***
## RPC get fee quotes
This is always used with `sendTransaction`. Select a `feeQuote`, and then send the transaction using the chosen custom fee mode.
```typeScript theme={null}
const wholeFeeQuote = (await particleAA.rpcGetFeeQuotes(eoaAddress, [transaction])) as WholeFeeQuote;
```
### Send Transaction
Sending a transaction (UserOperation) is as simple as calling pre-existing methods within `ParticleConnect` or `Evm` in `@particle-network/rn-auth-core` and just passing in an additional parameter, `feeMode`.
There are two ways to send transactions with the AA SDK:
The first is with `signAndSendTransaction` of `sendTransaction` , which will send a singular transaction to the network. Alternatively, you can use `batchSendTransactions` to send batched transactions within a single UserOperation.
`particleConnect.signAndSendTransaction` or `Evm.sendTransaction` in `@particle-network/rn-auth-core` takes the following parameters:
* For Particle Connect, `walletType`, dictates the specific adapter being used/targeted.
* `account`, the public address of the smart account sending the transaction, which can be retrieved through `EvmService.getSmartAccount`.
* `transaction`, a stringified standard transaction object.
* `feeMode`, the mechanism to be used for paying gas fees, can be:
* `AAFeeMode.gasless`, for sponsored transactions. This will happen automatically for Testnets and will pull from your previously defined (or configured) Paymaster for Mainnets. Takes one parameter:
* `wholeFeeQuote`, which can be retrieved through `particleAA.rpcGetFeeQuotes`.
* `AAFeeMode.native`, paying for gas fees in a native token (such as ETH). Takes one parameter:
* `wholeFeeQuote`, which can be retrieved through `particleAA.rpcGetFeeQuotes`.
* `AAFeeMode.token`, paying for gas fees in an ERC-20 token (such as USDC). Takes one parameter:
* `feeQuote`, to be used when leveraging a Token Paymaster. It can be retrieved through `particleAA.rpcGetFeeQuotes`.
* `tokenPaymasterAddress`, can be retrieved through `particleAA.rpcGetFeeQuotes`.
Alternatively, for `particleConnect.batchSendTransactions` or ParticleAuthCore `Evm.batchSendTransactions`, the parameters will be the same, with the exception of `transaction` being an array of transactions.
```typeScript theme={null}
// with @particle-network/rn-auth-core
await evm.sendTransaction(transaction,
feeMode: AAFeeMode.gasless(result));
await evm.sendTransaction(transactions,
feeMode: AAFeeMode.native(result));
await evm.signAndSendTransaction(transaction,
feeMode: AAFeeMode.token(feeQuote, tokenPaymasterAddress));
await evm.batchSendTransactions(transactions,
feeMode: AAFeeMode.native(result));
// with @particle-network/rn-connect
await ParticleConnect.signAndSendTransaction(
WalletType.AuthCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.gasless(result));
await ParticleConnect.signAndSendTransaction(
WalletType.AuthCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.native(result));
await ParticleConnect.signAndSendTransaction(
WalletType.AuthCore, eoaPublicAddress, transaction,
feeMode: AAFeeMode.token(feeQuote, tokenPaymasterAddress));
await ParticleConnect.batchSendTransactions(
WalletType.AuthCore, eoaPublicAddress, transactions,
feeMode: AAFeeMode.native(result));
```
Check if you can send a transaction with AAFeeMode.gasless/native/token.
```typeScript theme={null}
const wholeFeeQuote = await particleAA.rpcGetFeeQuotes(eoaAddress, [
transaction,
]) as WholeFeeQuote;
const feeQuote = wholeFeeQuote.verifyingPaymasterNative['feeQuote'];
const fee = BigNumber(feeQuote['fee']);
const balance = BigNumber(feeQuote['balance']);
// Check if user can afford te transaction
if (balance.isLessThan(fee)) {
console.log("Native balance too low to pay for gas fees");
return;
}
// Check if the transaction can be sponsored
const verifyingPaymasterGasless = wholeFeeQuote.verifyingPaymasterGasless;
if (verifyingPaymasterGasless == undefined) {
console.log("Gasless mode is not available");
return;
}
// Check if the transaction can be paid for using ERC20 tokens
const feeQuotes = wholeFeeQuote.tokenPaymaster['feeQuotes'] as any[];
const validFeeQuotes = feeQuotes.filter(item => {
const fee = BigNumber(item['fee']);
const balance = BigNumber(item['balance']);
if (balance.isLessThan(fee)) {
return false;
} else {
return true;
}
});
if (validFeeQuotes.length == 0) {
console.log("Token not valid to pay gas fees");
return;
}
// Select a fee quote.
const feeQuote = validFeeQuotes[0];
const tokenPaymasterAddress =
wholeFeeQuote.tokenPaymaster["tokenPaymasterAddress"] as string;
```
***
## Dive Deeper
See the [Particle Auth](/social-logins/auth/mobile-sdks/react) and [Particle Connect](/social-logins/connect/mobile/react) pages for insights into additional compatible methods (such as `signAndSendTransaction`), as shown here.
# Unity (C#) - AA
Source: https://developers.particle.network/aa/sdks/mobile/unity
Leveraging Particle's AA SDK within on Unity applications with C#.
## Account Abstraction on Unity
Applications built using Unity can also directly leverage Particle Network's AA SDK to facilitate end-to-end utilization of ERC-4337 account abstraction. Particle Network's AA SDK handles smart account deployment (modularized to multiple built-in implementations), UserOperation construction and sponsoring, fee quote generation, etc. Particle's AA SDK is the core infrastructure component, working hand-in-hand with Particle's Bundler and Paymaster, which power Particle Network's Modular Smart Wallet-as-a-Service.
This document will cover the installation, configuration, and utilization flow of Particle's AA SDK for Unity.
## Repository
Before diving in, you'll need to open the official [`particle-unity` GitHub repository](https://github.com/Particle-Network/particle-unity). This is where all of Particle Network's Unity SDKs are open-sourced and available for download. Before beginning, feel free to take a look at the underlying architecture and demos within `particle-unity` to contextualize the processes covered within this page.
***
## Getting Started
### Prerequisites
To start using the Particle AA SDK for Unity, you'll need to ensure that your project meets the minimum requirements for your platform (iOS or Android). Otherwise, you may run into compatibility issues, resulting in the SDK being non-functional. These prerequisites are as follows:
* **Unity 2021.3.35f1** or higher.
* For iOS:
* **Xcode 15.0** or higher.
* **CocoaPods 1.14.3** or higher.
* **iOS 14** or higher.
* For Android:
* **Minimum API level 23** or higher.
* **Targets API level 33** or higher.
* **Java SDK version 11**.
### Setting up Particle Auth or Particle Connect
With your prerequisites set, you'll need to set up either Particle Auth or Particle Connect for Unity. Particle Auth will offer a direct social login mechanism resulting in a Particle wallet. Otherwise, Particle Connect will allow for a more generalized connection modal aggregating both social logins and external Web3 wallets.
* Particle Auth: [Unity (C#)](/social-logins/auth/mobile-sdks/unity).
* Particle Connect: [Unity (C#)](/social-logins/connect/mobile/unity).
Important details before initialization.
Before initializing the SDK, there are a few key points to keep in mind, specifically regarding the utilization of Paymasters (to sponsor gas fees, pay for gas in ERC-20 tokens, etc.)
- All Testnets automatically have the Verifying Particle Network Omnichain Verifying Paymaster enabled, transactions (that request it) will automatically be sponsored and thus gasless.
- On the occasion that you'd like to use the Particle Network Omnichain Verifying Paymaster for Mainnets, you'll need to deposit USDT on either Ethereum or BNB Chain within the Particle dashboard. This USDT will then automatically be converted as needed into the native token of the network you're requesting (and qualifying for) sponsorship on.
- The Particle Network AA SDK automatically uses Biconomy's Token Paymaster. Transactions that request it will be able to leverage it without additional configuration.
***
## Initialization
Now that you have a project set up with either Particle Auth or Particle Connect, you can initialize the Particle AA SDK. But first, make sure you have the `ParticleAA` prefab within your first scene. This can be retrieved through the AA package within the forenamed [GitHub repository](https://github.com/Particle-Network/particle-unity/tree/main/Assets/ParticleNetwork/Mobile/Modules/AA).
Before you can use the full extent of the SDK, you'll need to initialize it through `ParticleAAInteraction.Init`. This process will allow you to choose between a Biconomy or Particle Paymaster, alongside the specific smart account implementation you'd like your users to rely on. `ParticleAAInteraction.Init` takes the following parameters:
* `accountName`, the name of the smart account implementation you'd like to use. Either:
* `BICONOMY_V1`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `BICONOMY_V2`, a [Biconomy smart account](https://www.biconomy.io/smart-accounts).
* `CYBERCONNECT`, a [CyberConnect smart account](https://wallet.cyber.co).
* `SIMPLE_V1`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `SIMPLE_V2`, a [SimpleAccount implementation](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol).
* `LIGHT`, a [Light Account implementation](https://accountkit.alchemy.com/smart-contracts/light-account).
Once the Particle AA SDK has been initialized through `ParticleAAInteraction`, you'll need to go ahead and enable AA mode through `ParticleAAInteraction.EnableAAMode`. From there, you can directly interact with the SDK (sending UserOperations, retrieving fee quotes, etc.)
E.g.:
```csharp theme={null}
// BICONOMY_V1 || BICONOMY_V2 | SIMPLE_V1 | SIMPLE_V2 | CYBERCONNECT | LIGHT
ParticleAAInteraction.Init(AAAccountName.BICONOMY_V1);
ParticleAAInteraction.EnableAAMode();
// Inversely, ParticleAAInteraction.DisableAAMode();
```
## Examples of Utilization
### Is Deployed
Upon initiating social login, a smart account will be assigned to your user's EOA (either a SimpleAccount, Biconomy account, or CyberConnect account), although even upon assignment, that smart account still needs to be deployed. This deployment will happen automatically upon the first UserOperation execution, as the deployment operation will be batched in with the first transaction request. Although, if you'd like to see whether an EOA's assigned smart account has been deployed or not, you can call `ParticleAA.Instance.IsDeploy`, as shown below.
```csharp theme={null}
var evmAddress = ParticleAuthCoreInteraction.EvmGetAddress()
var result = await ParticleAA.Instance.IsDeploy(eoaAddress);
```
### Is AA Mode Enabled
As mentioned prior, upon initialization, you'll need to enable the AA mode. If you're unsure whether this is currently enabled for a specific instance, then you can use `ParticleAAInteraction.IsAAModeEnable`, which will return a Boolean indicating either`true` or `false` otherwise. E.g.:
```csharp theme={null}
var result = ParticleAAInteraction.IsAAModeEnable();
```
### Get Fee Quotes
As you'll see in a moment, sending a UserOperation requires the retrieval of a `feeQuote` object, containing constructed UserOperations for three different fee payment mechanisms, either gasless, native paid (native token), or token paid (ERC-20 token Paymaster). Thus, upon sending a transaction, you'll need to pass in a complete response from the `ParticleAA.Instance.RpcGetFeeQuotes` method. Specifically, `ParticleAA.Instance.RpcGetFeeQuotes` takes the following parameters:
* `eoaAddress`, the address of the Signer/owner of the smart account in question (can be retrieved through `ParticleAuthCoreInteraction.GetEvmAddress` for Particle Auth).
* `transaction`, an array of multiple or a singular standard transactions to be sent from the smart account. The fee quote response will be based on the parameters defined within the transaction object.
E.g.:
```csharp theme={null}
var nativeResultData = await ParticleAA.Instance.RpcGetFeeQuotes(eoaAddress, new List { transaction });
```
### Send Transaction
Sending a transaction or UserOperation within the AA SDK is also quite simple. There are four mechanisms that can achieve this: either through a singular transaction with Particle Auth, multiple (batched) transactions with Particle Auth, or the same two options for Particle Connect. Each option functions slightly differently; although, in general, these methods will take the following parameters:
* For Particle Connect, `walletType`. This is the specific adapter or wallet being used through Particle Connect.
* For Particle Connect, `eoaAddress`, the owner (or Signer) address of the smart account.
* `transaction` (or for batched transaction, `transactions`, an array), a standard transaction object (or objects) containing the parameters of the transaction in question (`to`, `value`, `data`, etc.)
* `AAFeeMode`, the mechanism used to pay gas fees. Either:
* `AAFeeMode.Native`, natively paid by the smart account (native referring to the network's base token).
* `AAFeeMode.Gasless`, sponsored by either the Particle Paymaster or a Biconomy Paymaster, depending on initialization settings.
* `AAFeeMode.Token`, leverages a token Paymaster to pay the gas fee in an ERC-20 token.
* For each of the above methods, you'll need to pass in a JSON representation of a `feeQuote` object. The SDK will automatically choose the fee quote corresponding to the previous choice. If you've chosen `AAFeeMode.Token`, you'll need to pass in the address of the token Paymaster alongside the `feeQuote` object.
E.g.:
```csharp theme={null}
// Particle Auth, singular transaction
var nativeResultData = await ParticleAuthCore.Instance.SendTransaction(transaction, AAFeeMode.Native(JObject.Parse(feeQuotesResult.data)));
// Particle Auth, batched transactions
var nativeResultData = await ParticleAuthCore.Instance.BatchSendTransactions(transactions, AAFeeMode.Gasless(JObject.Parse(feeQuotesResult.data)));
// Particle Connect, singular transaction
var nativeResultData = await ParticleConnect.Instance.SignAndSendTransaction(WalletType.MetaMask, eoaAddress, transaction, AAFeeMode.Token(feeQuote, tokenPaymasterAddress));
// Particle Connect, batched transactions
var nativeResultData = await ParticleConnect.Instance.BatchSendTransactions(WalletType.MetaMask, eoaAddress, transactions, AAFeeMode.Native(JObject.Parse(feeQuotesResult.data)));
```
Check if you can send gasless/native/token.
```csharp theme={null}
// Check if user can afford the transaction
var feeQuotesResult =
await ParticleAA.Instance.RpcGetFeeQuotes(eoaAddress, new List { transaction });
var verifyingPaymasterNative = JObject.Parse(feeQuotesResult.data)["verifyingPaymasterNative"];
var feeQuote = verifyingPaymasterNative["feeQuote"];
var fee = BigInteger.Parse((string)feeQuote["fee"]);
var balance = BigInteger.Parse((string)feeQuote["balance"]);
if (balance < fee)
{
Debug.Log("Native balance is not enough for gas fee");
return;
}
// Check if the transaction can be sponsored
var verifyingPaymasterGasless = JObject.Parse(feeQuotesResult.data)["verifyingPaymasterGasless"];
if (verifyingPaymasterGasless == null)
{
Debug.Log("Gasless is not available");
return;
}
// Check if the transaction can be paid for using an ERC20 token
JArray feeQuotes = (JArray)(JObject.Parse(feeQuotesResult.data)["tokenPaymaster"]["feeQuotes"]);
var overFeeQuotes = feeQuotes
.Where(jt => {
var fee = BigInteger.Parse(jt["fee"].Value());
var balance = BigInteger.Parse((string)jt["balance"].Value());
return balance >= fee;
})
.ToList();
if (overFeeQuotes.Count == 0)
{
Debug.Log("No valid token for gas fee");
return;
}
// Select a feeQuote, for example the first.
var feeQuote = overFeeQuotes[0];
var tokenPaymasterAddress =
JObject.Parse(feeQuotesResult.data)["tokenPaymaster"]["tokenPaymasterAddress"].Value();
```
***
# Introduction to Account Abstraction
Source: https://developers.particle.network/intro/account-abstraction
ERC-4337 smart accounts, powered by Particle Network’s SDK.
**Account Abstraction (AA)** brings smart account capabilities to users, enabling features like gasless transactions, batched operations, and programmable account logic.
Particle Network provides a full-stack **Account Abstraction SDK**, designed for developers who want to implement **ERC-4337 Smart Wallet-as-a-Service** with minimal effort. Whether paired with **Particle Auth** (MPC-secured EOAs) or integrated externally, the SDK handles the heavy lifting of smart account deployment and UserOperation management.
***
# Understanding Account Abstraction
From a technical standpoint, Account Abstraction (ERC-4337) separates account logic from EOAs, replacing them with **Smart Accounts**. These programmable accounts allow for improved UX while staying fully decentralized.
The **Particle AA SDK** enables developers to:
* Deploy smart accounts bound to EOAs (MPC-secured via Particle Auth or external).
* Construct, sponsor, and send **UserOperations**.
* Retrieve fee quotes and handle gas sponsorship.
* Support recovery flows and custom logic.
***
## Key Features
### User Experience
* **Gasless transactions** through paymaster sponsorship.
* **Batched operations** (e.g., approve + swap in one click).
* **Programmable logic** for recovery, spending limits, or custom policies.
### Developer Benefits
* **Full ERC-4337 support** out of the box.
* Works natively with Particle Auth (MPC EOAs) or external wallets.
* Simple SDK integration for constructing, simulating, and sending UserOperations.
***
Start building with ERC-4337 smart accounts.
**Smart Wallet-as-a-Service**
Particle’s AA SDK provides the infrastructure to launch fully programmable smart wallets, with sponsorship, batching, and recovery built-in. Ideal for consumer-ready dApps.
# Custom Page with Toggles
Source: https://developers.particle.network/intro/interactive
# Introduction
Source: https://developers.particle.network/intro/introduction
Particle Network's developer docs.

# Particle Network Documentation
Particle Network provides the infrastructure for building **chain-agnostic, next-generation Web3 applications**.
Our stack consists of three core products:
1. **Universal Accounts**
Universal Accounts enable any app to become chain-agnostic. They do so by providing users with a single account and unified balance across multiple chains.
Thanks to this, users can spend their assets from multiple chains in a combined manner, use integrated dApps regardless of where their assets are or the chain the dApp is deployed on, and never manually bridge again.
This user experience is known as [chain abstraction](https://developers.particle.network/intro/what-is-cha).
2. **Social Logins**
Wallet creation and access with familiar Web2 credentials (Google, Twitter, Discord, etc.). This lowers onboarding friction and lets users start using dApps instantly.
3. **Account Abstraction (ERC-4337 AA)**
Smart account infrastructure following the ERC-4337 standard.
Features include gas sponsorship, batched transactions, and programmable account logic.
***
## New to Particle Network?
Learn how Universal Accounts unify balances across chains to enable Chain Abstraction.
Onboard users instantly with familiar Web2 logins and auto-generated wallets.
Explore how ERC-4337 smart accounts enable gasless txs, batching, and programmability.
Understand our mission to make Web3 retail-ready through Chain Abstraction and beyond.
***
## Want to Build?
Integrate Universal Accounts into an existing dApp in minutes.
Add social logins to your dApp with just a few lines of code.
Start building with ERC-4337 Smart Accounts using the Particle AA SDK.
***
## Resources
Particle Network's open-source SDKs and core packages.
Watch walkthroughs and deep dives on integration.
Join our Slack community for support and collaboration.
# Brand Assets
Source: https://developers.particle.network/intro/more/assets
Aggregation of Particle Network brand assets for external usage.
## Particle Network Brand Assets
Particle Network has numerous brand assets that you can use for comarketing or to display the fact that your application is powered by Particle. To download these assets, click the following links. If none of these assets meet your needs, please contact us rather than modifying the logo yourself.
General icons: [https://particle.network/icons.zip](https://particle.network/icons.zip)
Powered by Particle Network banners: [https://particle.network/poweredby.zip](https://particle.network/poweredby.zip)
***
## Brand Colors
Additionally, see the following images for the specific colors used within Particle Network marketing material. It's recommended to use these when working with the above brand assets or associated Particle-related imagery.
### Light (Purple)
### Dark
### Banners
# Security Audits
Source: https://developers.particle.network/intro/more/audits
> 🏅 Particle Network has private audits with [Salus Sec](https://salusec.io/), as well as public ones with [CertiK](https://skynet.certik.com/projects/particle-network) and [OpenZeppelin](https://blog.openzeppelin.com/particle-network-btc-smart-account-audit).
>
> Particle Network regularly has it's codebase audited to ensure a constant baseline of security. Thus, Particle Network is currently ranked in [second place](https://skynet.certik.com/leaderboards/non-token), globally, among non-token audits by CertiK.
>
> Additionally, Particle Network runs an active bug bounty program with CertiK, viewable [here](https://skynet.certik.com/projects/particle-network).
# Model Context Protocol (MCP) Server
Source: https://developers.particle.network/intro/more/mcp
Access Particle's documentation programmatically via an MCP server
The Particle docs host a **Model Context Protocol (MCP) server** that lets AI applications query our documentation directly. This enables developers to build AI tools and assistants with first-class access to guides, API references, and implementation details.
***
## What is MCP?
The **Model Context Protocol (MCP)** is a standard for connecting AI systems to external tools and data sources.\
With MCP, AI models can extend their capabilities beyond static training data by retrieving real-time, contextual information.
Particle Network’s MCP server bridges AI applications and our documentation, allowing AI systems to:
* Search across the full documentation knowledge base
* Retrieve relevant guides, API references, and code snippets
* Provide contextual answers with direct links back to docs
***
## Connecting to Particle Network’s MCP Server
To use the Particle MCP server, your AI application must support the Model Context Protocol (MCP). Many modern AI tools and IDEs already provide native support.
Some examples include:
* **Windsurf IDE**: an AI-powered IDE with built-in MCP integration.
* **Claude Code**: Anthropic’s coding assistant with MCP support.
* **Any other MCP-compatible client**: custom tools or assistants that can connect to a streamable HTTP MCP endpoint.
You’ll connect these clients to the following server URL:
```sh URL theme={null}
https://developers.particle.network/mcp
```
## Available Tools
Currently, the Particle MCP server exposes one tool:
`SearchParticleNetworkDocs`
A search endpoint for querying the entire Particle Network documentation knowledge base. It returns contextual content along with titles and direct links to the docs.
Use this tool when you need to:
* Answer technical questions about Particle Network features
* Locate integration guides and API references
* Retrieve implementation details and code samples
* Provide contextual answers with links back to official docs
## Integration Instructions
### Using Windsurf IDE
Windsurf is an AI-powered IDE with built-in MCP support. You can connect it to the Particle Network docs in a few steps:
1. Navigate to `Advanced Settings → Cascade → Manage MCPs`.
2. Click `View Raw Config` and paste the following snippet:
```json mcp_config.json theme={null}
{
"mcpServers": {
"particle-docs": {
"serverUrl": "https://developers.particle.network/mcp"
}
}
}
```
Once added, Windsurf will automatically use the MCP server to query Particle’s documentation inside Cascade — giving your IDE real context about Particle SDKs, APIs, and integration details.
### Manual Configuration
For other AI tools that support streamable HTTP MCP (the current MCP standard, replacing older SSE connections), you can connect directly using the following URL:
```sh URL theme={null}
https://developers.particle.network/mcp
```
This provides full access to Particle Network’s documentation and developer resources via MCP.
# Introduction to Social Logins
Source: https://developers.particle.network/intro/social-logins
Onboard users with familiar credentials and automatic wallet creation.
**Social Logins** let users sign in to dApps using credentials they already know — Google, Twitter, Discord, Apple, and more — while automatically generating a secure, non-custodial wallet in the background.
This eliminates the friction of seed phrases and manual wallet setup, allowing developers to offer a **Web2-like onboarding experience** without sacrificing decentralization. Particle Network ensures keys are safely managed using [MPC (Multi-Party Computation)](/social-logins/mpc-tss), keeping control in the user’s hands.
***
# Understanding Social Logins
From a technical standpoint, Social Logins work by binding a user’s Web2 identity (e.g., Google OAuth) to a non-custodial wallet. Particle’s infrastructure abstracts away key management, ensuring wallets can be recovered while staying decentralized.
## Key Features
### User Experience
* One-click onboarding with familiar Web2 credentials.
* No need for seed phrases, extensions, or manual wallet creation.
* Fast, familiar login flow users already trust.
### Developer Benefits
* Easy SDK integration with minimal code changes.
* Works across web, mobile, and desktop environments.
* Fully compatible with other Particle products (Universal Accounts, Account Abstraction).
***
Add Social Logins to your dApp.
**Best for onboarding retail users**
Social Logins reduce drop-off by removing seed phrases and wallet setup barriers, making them ideal for consumer-ready dApps and mainstream audiences.
# API & SDK License Agreement
Source: https://developers.particle.network/intro/tos/license-agreement
Effective Date: May 1, 2022
## Developer API and SDK License Agreement | Particle Network
BY ACCESSING OR USING THE PARTICLE NETWORK LABS, INC. (“**WE**”, “**US**”, “**OUR**”, “**Particle Network**”) API OR SDK (EACH AS DEFINED BELOW), YOU OR THE ENTITY OR COMPANY THAT YOU REPRESENT (“**YOU,**” “**YOUR,**” “**YOURS**” OR “**LICENSEE**”) ARE AGREEING TO BE BOUND BY THIS PARTICLE NETWORK API/SDK LICENSE AGREEMENT, EACH OF OUR USER AND DEVELOPER TERMS OF SERVICE, ANY ADDITIONAL TERMS INCORPORATED BY REFERENCE HEREIN, TERMS WITHIN THE ACCOMPANYING API DOCUMENTATION, AND ANY RELATED APPLICABLE POLICIES AND GUIDELINES WE MAY MAKE AVAILABLE FROM TIME TO TIME (COLLECTIVELY, THE “**AGREEMENT**”), AND HEREBY REPRESENT THAT YOU ARE AUTHORIZED TO BIND LICENSEE.YOUR DOWNLOAD OR CONTINUED USE OF THE SDK OR API WILL CONSTITUTE ASSENT TO THE TERMS OF THIS AGREEMENT. IF YOU DO NOT UNCONDITIONALLY AGREE TO ALL OF THE TERMS OF THIS AGREEMENT, IMMEDIATELY CEASE THE DOWNLOAD OR USE, AND YOU WILL HAVE NO RIGHT TO USE, THE SDK OR API. IF THESE TERMS ARE CONSIDERED AN OFFER, ACCEPTANCE IS EXPRESSLY LIMITED TO THIS AGREEMENT TO THE EXCLUSION OF ALL OTHER TERMS.THIS AGREEMENT CONTAINS AN ARBITRATION PROVISION. YOU AGREE AND UNDERSTAND THAT DISPUTES ARISING UNDER THIS AGREEMENT WILL BE SETTLED IN BINDING ARBITRATION. YOU ALSO AGREE AND UNDERSTAND THAT ENTERING INTO THIS AGREEMENT CONSTITUTES A WAIVER OF YOUR RIGHT TO A TRIAL BY JURY OR PARTICIPATION IN A CLASS ACTION LAWSUIT.
* Subject to full compliance with the terms of this Agreement, Particle Network hereby grants you a limited, personal, non-sublicensable, non-transferable, royalty-free, nonexclusive license to access and use our application programming interface located at api.particle.network and related information and documentation (collectively, the “**API**”) and our API Software Development Kit (“**SDK**”), but only to build software applications (each an “**App**”) that communicate with our proprietary authentication platform service or other services that we may provide through the API (the “**Services**”). Some of the software required by or included in our APIs may be offered under an open source license. Open source software licenses constitute separate written agreements. For certain APIs, open source software is listed in the documentation. To the limited extent the open source software license expressly supersedes the Agreement, the open source license instead sets forth your agreement with Particle Network for the applicable open source software.
* Subject to full compliance with the terms of this Agreement, we hereby grant you a limited, personal, non-sublicensable, non-transferable, royalty-free, nonexclusive license to distribute those components of the SDK we identify as “**distributable**” but only in object code form, as part of an App.
* Except as expressly authorized herein, you will not disclose (or allow access to) the API or SDK (or any information derived from them) or any other confidential information provided to you to any third party and will limit access to the API and SDK (and any derived information) to your employees who are developing the App. In support of this obligation, you will apply at least the same security that you use to protect your own most confidential information. You will not reverse engineer any aspect of the API or SDK or permit anyone else to do so (except to the limited extent this restriction is expressly prohibited by applicable law).
* You will use your App and the Services in compliance with all applicable laws and regulations (“**Laws**”) and will obtain all necessary permits or licenses (“**Permits**”), which includes without limitation, all approvals, authorizations, consents, qualifications to do business and certificates issued by any governmental authority, quasi-governmental authority, or legal body of the United States or any foreign body of any foreign jurisdiction related to the transmission of fiat currency, digital or cryptocurrency or other blockchain tokens necessary for your end users use of your App or the Services.
* You will require your end users to comply with (and not knowingly enable them to violate) applicable Laws, regulations, and the Agreement, including separately agreeing to our User Terms of Service. You will provide and adhere to a privacy policy for your App that clearly and accurately describes to users of your App what user information you collect and how you use and share such information (including for advertising) with Particle Network and third parties. If your or your end users’ use of the Services is prohibited by Laws or you do not have the required Permits, then you and your end users are not authorized to use the Services. We cannot and will not be responsible for your or your end users using the Services in a way that breaks any Laws.
* You agree not to block, disable, hide or limit in any way the ability of any device (whether or not it includes the App) to access the Services or any portion or functionality of or enabled by the Services. In addition, you agree that, when using the APIs, you shall not (or allow those acting on your behalf to):
* Sublicense an API for use by a third party or create an App that functions substantially the same as the APIs and offer it for use by third parties;
* Perform an action with the intent of introducing to Particle Network products and services any viruses, worms, defects, Trojan horses, malware, or any items of a destructive nature;
* Seek to gain access to a user’s private key or other login information related to a digital asset wallet without their explicit consent subject to a previously disclosed privacy policy;
* Defame, abuse, harass, stalk, or threaten others;
* Interfere with or disrupt the APIs or the servers or networks providing the APIs;
* Promote or facilitate unlawful online gambling;
* Reverse engineer or attempt to extract the source code from any API or any related software, except to the extent that this restriction is expressly prohibited by applicable law; or
* Violate or infringe upon the privacy, publicity, intellectual property, or other proprietary rights of third parties.
* Each App must maintain 100% compatibility with the API, the SDK and the Services (including changes provided to you by Particle Network, which will be implemented in the App promptly thereafter). If any App uses or implements an outdated version of the API, SDK or the Services, you acknowledge and agree that such App may not be able to communicate with the Services. You agree not to modify, extend, subset or superset the API or SDK to any extent. You also acknowledge and agree that Particle Network may set and enforce limits on your use of the APIs (e.g. limiting the number of API requests that you may make or the number of users you may serve), in our sole discretion. You agree to, and will not attempt to circumvent, such limitations documented with each API without our express consent (and we may decline that request or condition acceptance on your agreement to additional terms and/or charges for that use). You understand that we may cease support of old versions or releases of the API or SDK.
* You will use commercially reasonable efforts to protect user information collected by your App, including personally identifiable information ("PII"), from unauthorized access or use and will promptly report to your users any unauthorized access or use of such information to the extent required by applicable law. Particle Network will use commercially reasonable efforts to (i) provide basic support to you and (ii) maintain the security and integrity of the Services.
* By using Particle Network Services, we do not acquire ownership in your App, and by using our APIs, you do not acquire ownership of any rights in our APIs, the SDK, or the content that is accessed through our APIs. However, you hereby grant Particle Network a nonexclusive, sublicensable, fully-paid, worldwide license to fully exercise and exploit all intellectual property rights with respect to improvements or extensions that you create or are created for you that are relevant to the API or SDK or otherwise result from or are enabled by access to the API or SDK. If you provide feedback or suggestions about our APIs, then we (and those we allow) may use such information without obligation to you. For clarity, you are not required to disclose any such patent or patent rights to Particle Network. Particle Network shall have the right to collect and analyze data and other information relating to the provision, use and performance of various aspects of the API, SDK and/or the Services and related systems and technologies, and Particle Network will be free (during and after the term hereof) to (i) use such information and data to improve and enhance the API, SDK and the Services and for other development, diagnostic and corrective purposes in connection with the API, SDK and the Services and other Particle Network offerings, and (ii) disclose such data solely in aggregate or other de-identified form in connection with its business.
* PARTICLE NETWORK PROVIDES THE API, SDK AND THE SERVICES “**AS IS**” AND WITHOUT WARRANTY OF ANY KIND, AND HEREBY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, PERFORMANCE, ACCURACY, RELIABILITY, AND NON-INFRINGEMENT. PARTICLE NETWORK DOES NOT MAKE ANY REPRESENTATIONS OR WARRANTIES THAT THE USE OF ITS API, SDK OR SERVICES WILL BE UNINTERRUPTED, TIMELY, OR ERROR-FREE.
* LIMITATION OF LIABILITY: NOTWITHSTANDING ANYTHING TO THE CONTRARY, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NONE OF PARTICLE NETWORK OR ITS SUPPLIERS OR RESELLERS WILL BE LIABLE UNDER ANY LEGAL OR EQUITABLE THEORY, INCLUDING, BUT NOT LIMITED TO, TORT, CONTRACT, NEGLIGENCE, STRICT LIABILITY, OR OTHERWISE, FOR (A) ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, , OR DAMAGES RESULTING FROM LICENSEE’S USE OF THE API OR SDK, OR (B) ANY DIRECT DAMAGES OF ANY KIND ARISING OUT OF THIS AGREEMENT IN EXCESS OF \\\$100. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATION AND EXCLUSION MAY NOT APPLY TO YOU.
* You agree to indemnify and hold harmless Particle Network, its affiliates, subsidiaries, directors, managers, members, officers, and employees from any and all claims, liabilities, demands, actions, damages, losses, costs or expenses, including without limitation, reasonable legal fees, arising out of or relating to (i) your or your end users’ use or misuse of, or access to, your App and the Services (ii) your violation of this Agreement or any Laws or Permits, (iii) your infringement, or the infringement by any third party using your account, of any intellectual property or other right of any person or entity, (iv) a claim alleging that any of your or your end users’ data infringes the rights of, or has caused harm to, a third party or (v) any violation of any rights of any other person or entity; provided however, that you will not indemnify Particle Network for claims or losses arising out of Particle Network’s gross negligence or willful misconduct.
* You may stop using our APIs at any time with or without notice. Further, if you want to terminate the Terms, you must provide us with prior written notice and upon termination and cease your use of the applicable APIs. We reserve the right to terminate the Agreement with you or discontinue the APIs or any portion or feature or your access thereto for any reason and at any time without liability or other obligation to you. Provisions that, by their nature, should survive termination of these Terms shall survive termination. By way of example, all of the following will survive termination: any obligation you have to pay us (if applicable) or indemnify us, any limitations on our liability, any terms regarding ownership or intellectual property rights, and terms regarding disputes between us.
* Except as described in this Agreement, all notices to be provided under this Agreement shall be given in writing (a) as to the Licensee, at the email address provided by Licensee upon registration of Licensee’s account or user ID in Particle Network’s systems, or at such other account Licensee maintains with Particle Network, and (b) as to Particle Network, at [contact@particle.network](mailto:contact@particle.network). This Agreement is the complete agreement concerning the subject matter hereof between the parties and supersedes all prior agreements and representations between them. Particle Network reserves the right to modify this Agreement from time to time upon notice to Licensee (via email or by posting a notice to the page where Licensee accesses its SDK or API account); if Licensee does not agree with this Agreement as so modified, its only remedy shall be to terminate this Agreement by providing notice to Particle Network. Any use of or access to the SDK or API and/or Services in any manner whatsoever following a notice of modification of this Agreement shall constitute acceptance of the Agreement as so modified. If any part of this Agreement is held to be unenforceable for any reason, that part will be reformed only to the extent necessary to make it enforceable. No failure by Particle Network in exercising any right under this Agreement will constitute a waiver of that right. You may not assign or transfer any of your rights or obligations without Particle Network’s consent and any action or conduct in violation of the foregoing will be void and without effect. Particle Network may assign or transfer this Agreement.
* If you would like to report a vulnerability or have a security concern regarding our user-facing and developer-related services, SDK, API, infrastructure, and architecture etc., please e-mail [help@particle.network](mailto:help@particle.network).
* The API and SDK were developed solely at private expense and are commercial computer software and related documentation within the meaning of the applicable U.S. Federal Acquisition Regulation and agency supplements thereto.
# Privacy Policy
Source: https://developers.particle.network/intro/tos/privacy-policy
Effective Date: May 1st, 2022
## Privacy Policy | Particle Network
At Particle Network, we take your privacy seriously. Please read this Privacy Policy to learn how we treat your personal data. By using or accessing our Services in any manner, you acknowledge that you accept the practices and policies outlined below, and you hereby consent that we will collect, use and share your information as described in this Privacy Policy. Any terms we use in this Policy without defining them have the definitions given to them in the Terms of Service.
## What this Privacy Policy Covers
This Privacy Policy covers how we treat Personal Data that we gather when you access or use our Services. “Personal Data” means any information that identifies or relates to a particular individual and also includes information referred to as “personally identifiable information” or “personal information” under applicable data privacy laws, rules, or regulations. This Privacy Policy does not cover the practices of companies we don’t own or control or people we don’t manage.
## Personal Data
### Categories of Personal Data We Collect
This chart details the categories of Personal Data that we collect and have collected over the past 12 months.
| Category of Personal Data | Examples of Personal Data We Collect | Categories of Third Parties With Whom We Share this Personal Data: |
| ------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
| Profile or Contact Data | Email address, Cell-phone number, Social login Provider ID or login information, Phone number | Service Providers, Analytics Partners |
| Device/IP Data | IP address, Device identifiers, Type of device, operating system, or web browser used to access the Services | Service Providers, Analytics Partners |
| Social Network Data | Email, IP address, Device ID, Phone number | Service Providers, Analytics Partners |
| Geolocation Data | IP-address-based location information | Service Providers, Analytics Partners |
#### Is collected Personal Information secure and confidential?
We endeavor to protect the privacy of your Personal Information we hold in our records, however, we cannot guarantee complete security. Unauthorized entry or use, hardware or software failure, and other factors may compromise the security of user information. If at any time, there is an identified concern for the security of the site or confidentiality of personal information, please contact [help@particle.network](mailto:help@particle.network) for a prompt investigation.
### Categories of Sources of Personal Data
We collect Personal Data about you from the following categories of sources:
* **You**
* When you provide such information directly to us.
* When you create an account or use our interactive tools and Services.
* When you voluntarily provide information in free-form text boxes through the Services or through responses to surveys or questionnaires.
* When you send us an email or otherwise contact us.
* **When you use the Services and such information is collected automatically.**
* Through Cookies (defined in the “Tracking Tools and Opt-Out” section below).
* If you use the software we make available, we may receive and collect information transmitted from your computing device for the purpose of providing you the relevant Services, such as information regarding when you are logged on, information about the device from which you are logged in, and the network used to connect to the Services (such as IP address).
### Our Commercial or Business Purposes for Collecting Personal Data
#### Providing, Customizing, and Improving the Services
* Creating and managing your account or other user profiles.
* Providing you with the products, services, or information you request.
* Meeting or fulfilling the reason you provided the information to us.
* Providing support and assistance for the Services.
* Improving the Services, including testing, research, internal analytics, and product development.
* Personalizing the Services, website content, and communications based on your preferences.
* Evaluating and providing fraud and automated bot protection.
* Improving site security and facilitating debugging.
* Carrying out other business purposes stated when collecting your Personal Data or as otherwise set forth in applicable data privacy laws, such as the California Consumer Privacy Act (the “CCPA”) or the European Union’s General Data Protection Regulation (“GDPR”).
#### Corresponding with You
* Responding to correspondence that we receive from you, contacting you when necessary or requested, and sending you information about Particle Network, or the Services.
* Sending emails and other communications according to your preferences or that display content that we think will interest you.
#### Meeting Legal Requirements and Enforcing Legal Terms
* Fulfilling our legal obligations under applicable law, regulation, court order, or other legal processes, such as preventing, detecting, and investigating security incidents and potentially illegal or prohibited activities.
* Protecting the rights, property, or safety of you, Particle Network, or another party.
* Enforcing any agreements with you.
* Responding to claims that any posting or other content violates third-party rights.
* Resolving disputes.
We will not collect additional categories of Personal Data or use the Personal Data we collected for materially different, unrelated, or incompatible purposes without providing you notice.
## How We Share Your Personal Data
We disclose your Personal Data to the categories of service providers and other parties listed in this section. Depending on state laws that may be applicable to you, some of these disclosures may constitute a “sale” of your Personal Data. For more information, please refer to the state-specific sections below.
#### Service Providers
These parties help us provide the Services or perform business functions on our behalf. They include:
* Hosting, technology, and communication providers.
* Security and fraud prevention consultants and vendors.
* Support and customer service vendors.
* Payment processors.
* Our payment processing partner Stripe, Inc. (“Stripe”) collects your voluntarily-provided payment card information necessary to process your payment. Please see Stripe’s terms of service and privacy policy for information on its use and storage of your Personal Data.
* Analytics Partners. These parties provide analytics on web traffic or usage of the Services. They include:
* Companies that track how users found or were referred to the Services.
* Companies that track how users interact with the Services.
* Companies that help identify user experience issues or service impacts.
#### Legal Obligations
We may share any Personal Data that we collect with third parties in conjunction with any of the activities set forth under “Meeting Legal Requirements and Enforcing Legal Terms” in the “Our Commercial or Business Purposes for Collecting Personal Data” section above.
#### Business Transfers
All of your Personal Data that we collect may be transferred to a third party if we undergo a merger, acquisition, bankruptcy, or other transaction in which that third party assumes control of our business (in whole or in part). Should one of these events occur, we will make reasonable efforts to notify you before your information becomes subject to different privacy and security policies and practices.
#### Data that is not Personal Data
We may create aggregated, de-identified, or anonymized data from the Personal Data we collect, including by removing information that makes the data personally identifiable to a particular user. We may use such aggregated, de-identified, or anonymized data and share it with third parties for our lawful business purposes, including to analyze, build and improve the Services and promote our business, provided that we will not share such data in a manner that could identify you.
## Tracking Tools and Opt-Out
The Services use cookies and similar technologies such as image loading, browser local storage, cookies, and JavaScript (collectively, “Cookies”) to enable our servers to recognize your web browser, tell us how and when you visit and use our Services, analyze trends, learn about our user base and operate and improve our Services. Cookies are small pieces of data – usually text files – placed on your computer, tablet, phone, or similar device when you use that device to access our Services. We may also supplement the information we collect from you with information received from third parties, including third parties that have placed their own Cookies on your device(s).
#### We use the following types of Cookies:
* **Essential Cookies**. Essential Cookies are required for providing you with features or services that you have requested. For example, certain Cookies enable you to log into secure areas of our Services. Disabling these Cookies may make certain features and services unavailable.
* **Functional Cookies**. Functional Cookies are used to record your choices and settings regarding our Services, maintain your preferences over time and recognize you when you return to our Services. These Cookies help us to personalize our content for you, greet you by name and remember your preferences (for example, your choice of language or region).
* **Performance/Analytical Cookies**. Performance/Analytical Cookies allow us to understand how visitors use our Services. They do this by collecting information about the number of visitors to the Services, what pages visitors view on our Services and how long visitors are viewing pages on the Services. Performance/Analytical Cookies also help us measure the performance of our advertising campaigns in order to help us improve our campaigns and the Services’ content for those who engage with our advertising.
You can decide whether or not to accept Cookies through your internet browser’s settings. Most browsers have an option for turning off the Cookie feature, which will prevent your browser from accepting new Cookies, as well as (depending on the sophistication of your browser software) allow you to decide on acceptance of each new Cookie in a variety of ways. You can also delete all Cookies that are already on your device. If you do this, however, you may have to manually adjust some preferences every time you visit our website and some of the Services and functionalities may not work.
## Data Security and Retention
We seek to protect your Personal Data from unauthorized access, use and disclosure using appropriate physical, technical, organizational and administrative security measures based on the type of Personal Data and how we are processing that data. You should also help protect your data by appropriately selecting and protecting your password and/or other sign-on mechanisms; limiting access to your computer or device and browser; and signing off after you have finished accessing your account. Although we work to protect the security of your account and other data that we hold in our records, please be aware that no method of transmitting data over the internet or storing data is completely secure. We retain Personal Data about you for as long as you have an open account with us or as otherwise necessary to provide you with our Services. In some cases, we retain Personal Data for longer, if doing so is necessary to comply with our legal obligations, resolve disputes, or collect fees owed, or is otherwise permitted or required by applicable law, rule, or regulation. We may further retain information in an anonymous or aggregated form where that information would not identify you personally. Information about data retention and our data retention policy is available.
## Personal Data of Children
As noted in the Terms of Use, we do not knowingly collect or solicit Personal Data about children under 18 years of age; if you are a child under the age of 18, please do not attempt to register for or otherwise use the Services or send us any Personal Data. If we learn we have collected Personal Data from a child under 18 years of age, we will delete that information as quickly as possible. If you believe that a child under 18 years of age may have provided Personal Data to us, please contact us at [help@particle.network](mailto:help@particle.network).
## Data Deletion Requests
### Requesting Data Deletion
If you would like to request the deletion of your personal data from our records, please follow the steps outlined below:
1. Email us at: [help@particle.network](mailto:help@particle.network) with subject starting with: "Data Deletion Requests";
2. Provide your Third-Party account and your Particle Account.
### Verification of Identity
To ensure the security and accuracy of the data deletion process, we may require additional information or verification of your identity before proceeding with your request. This is to protect your data from unauthorized access or deletion.
* We will verify the email address and Third-Party account and your Particle Account;
### Data Deletion Timeframe
We will make reasonable efforts to process and fulfill your data deletion request within 30 days from the date of receipt. However, please note that certain legal obligations or technical constraints may prevent immediate or complete deletion of your data.
### Communication of Data Deletion
Once your data has been successfully deleted from our systems, we will notify you through [help@particle.network](mailto:help@particle.network). Please note that residual copies of your data may remain in our backup systems for a limited period, as permitted by law or necessary for legitimate business purposes.
## California Resident Rights
If you are a California resident, you have the rights set forth in this section. Please see the “Exercising Your Rights” section below for instructions regarding how to exercise these rights. Please note that we may process the Personal Data of our customers’ end users or employees in connection with our provision of certain services to our customers. If we are processing your Personal Data as a service provider, you should contact the entity that collected your Personal Data in the first instance to address your rights with respect to such data. If there are any conflicts between this section and any other provision of this Privacy Policy and you are a California resident, the portion that is more protective of Personal Data shall control to the extent of such conflict. If you have any questions about this section or whether any of the following rights apply to you, please contact us at [help@particle.network](mailto:help@particle.network).
#### Access
You have the right to request certain information about our collection and use of your Personal Data over the past 12 months. In response, we will provide you with the following information:
* The categories of Personal Data that we have collected about you.
* The categories of sources from which that Personal Data was collected.
* The business or commercial purpose for collecting or selling your Personal Data.
* The categories of third parties with whom we have shared your Personal Data.
* The specific pieces of Personal Data that we have collected about you.
If we have disclosed your Personal Data to any third parties for a business purpose over the past 12 months, we will identify the categories of Personal Data shared with each category of the third-party recipient. If we have sold your Personal Data over the past 12 months, we will identify the categories of Personal Data sold to each category of the third-party recipient.
#### Deletion
You have the right to request that we delete the Personal Data that we have collected about you. Under the CCPA, this right is subject to certain exceptions: for example, we may need to retain your Personal Data to provide you with the Services or complete a transaction or other action you have requested. If your deletion request is subject to one of these exceptions, we may deny your deletion request.
#### Exercising Your Rights
To exercise the rights described above, you or your Authorized Agent (defined below) must send us a request that (1) provides sufficient information to allow us to verify that you are the person about whom we have collected Personal Data, and (2) describes your request in sufficient detail to allow us to understand, evaluate and respond to it. Each request that meets both of these criteria will be considered a “Valid Request.” We may not respond to requests that do not meet these criteria. We will only use Personal Data provided in a Valid Request to verify your identity and complete your request. You do not need an account to submit a Valid Request. Typically, accounts associated with an email address will require verification of the email address, as well as a description of the requested user rights or regulations invoked. Particle Network also values those who are not covered by specific regulations and offers to extend a goodwill effort towards requests originating from other jurisdictions. We will work to respond to your Valid Request within 30 days of receipt. We will not charge you a fee for making a Valid Request unless your Valid Request(s) is excessive, repetitive, or manifestly unfounded. If we determine that your Valid Request warrants a fee, we will notify you of the fee and explain that decision before completing your request. You may submit a Valid Request using the following methods:
* Email us at: [help@particle.network](mailto:help@particle.network)
You may also authorize an agent (an “Authorized Agent”) to exercise your rights on your behalf. To do this, you must provide your Authorized Agent with written permission to exercise your rights on your behalf, and we may request a copy of this written permission from your Authorized Agent when they make a request on your behalf.
#### Personal Data Sales Opt-Out and Opt-In
We will not sell your Personal Data and have not done so over the last 12 months. To our knowledge, we do not sell the Personal Data of minors under 18 years of age.
We will not discriminate against you for exercising your rights under the CCPA. We will not deny you our goods or services, charge you different prices or rates, or provide you a lower quality of goods and services if you exercise your rights under the CCPA. However, we may offer different tiers of our Services as allowed by applicable data privacy laws (including the CCPA) with varying prices, rates, or levels of quality of the goods or services you receive related to the value of Personal Data that we receive from you.
## Other State Law Privacy Rights
#### California Resident Rights
Under California Civil Code Sections 1798.83-1798.84, California residents are entitled to contact us to prevent disclosure of Personal Data to third parties for such third parties’ direct marketing purposes. In order to submit such a request, please contact us at [help@particle.network](mailto:help@particle.network). Please note, however, that we do not disclose Personal Data to third parties for such third parties’ direct marketing purposes.
#### Nevada Resident Rights
If you are a resident of Nevada, you have the right to opt-out of the sale of certain Personal Data to third parties who intend to license or sell that Personal Data. You can exercise this right by contacting us at [help@particle.network](mailto:help@particle.network) with the subject line “Nevada Do Not Sell Request” and providing us with your name and the email address associated with your account. Please note, however, that we do not sell Personal Data.
## European Union Data Subject Rights
#### EU Residents
If you are a resident of the European Union (“EU”), United Kingdom, Lichtenstein, Norway, or Iceland, you may have additional rights under the EU General Data Protection Regulation (the “GDPR”) with respect to your Personal Data, as outlined below. For this section, we use the terms “Personal Data” and “processing” as they are defined in the GDPR, but “Personal Data” generally means information that can be used to individually identify a person, and “processing” generally covers actions that can be performed in connection with data such as collection, use, storage, and disclosure. Particle Network will be the controller of your Personal Data processed in connection with the Services. If there are any conflicts between this section and any other provision of this Privacy Policy, the policy or portion that is more protective of Personal Data shall control to the extent of such conflict. If you have any questions about this section or whether any of the following applies to you, please contact us at [help@particle.network](mailto:help@particle.network). Note that we may also process the Personal Data of our customers’ end users or employees in connection with our provision of certain services to customers, in which case we are the processor of Personal Data. If we are the processor of your Personal Data (i.e., not the controller), please contact the controller party in the first instance to address your rights with respect to such data.
#### Personal Data We Collect
The “Categories of Personal Data We Collect” section above details the Personal Data that we collect from you.
### Personal Data Use and Processing Grounds
The “Our Commercial or Business Purposes for Collecting Personal Data” section above explains how we use your Personal Data. We will only process your Personal Data if we have a lawful basis for doing so. Lawful bases for processing include consent, contractual necessity, and our “legitimate interests” or the legitimate interest of others, as further described below.
**Contractual Necessity**: We process the following categories of Personal Data as a matter of “contractual necessity”, meaning that we need to process the data to perform under our Terms of Use with you, which enables us to provide you with the Services. When we process data due to contractual necessity, failure to provide such Personal Data will result in your inability to use some or all portions of the Services that require such data.
* Profile or Contact Data
* Device/IP Data
* Social Network Data
* Geolocation Data
**Legitimate Interest**: We process the following categories of Personal Data when we believe it furthers the legitimate interest of us or third parties:
* Profile or Contact Data
* Device/IP Data
* Geolocation Data
* We may also de-identify or anonymize Personal Data to further our legitimate interests.
Examples of these legitimate interests include (as described in more detail above):
* Providing, customizing, and improving the Services.
* Marketing the Services.
* Corresponding with you.
* Meeting legal requirements and enforcing legal terms.
* Completing corporate transactions.
**Consent**: In some cases, we process Personal Data based on the consent you expressly grant to us at the time we collect such data. When we process Personal Data based on your consent, it will be expressly indicated to you at the point and time of collection.
**Other Processing Grounds**: From time to time, we may also need to process Personal Data to comply with a legal obligation if it is necessary to protect the vital interests of you or other data subjects, or if it is necessary for a task carried out in the public interest.
#### Sharing Personal Data
The “How We Share Your Personal Data” section above details how we share your Personal Data with third parties.
### EU Data Subject Rights
You have certain rights with respect to your Personal Data, including those set forth below. For more information about these rights, or to submit a request, please email us at [help@particle.network](mailto:help@particle.network). Please note that in some circumstances, we may not be able to fully comply with your request, such as if it is frivolous or extremely impractical, if it jeopardizes the rights of others, or if it is not required by law, but in those circumstances, we will still respond to notify you of such a decision. In some cases, we may also need you to provide us with additional information, which may include Personal Data, if necessary to verify your identity and the nature of your request.
* **Access**: You can request more information about the Personal Data we hold about you and request a copy of such Personal Data. Users of Particle Network’s dashboard can also access certain of your Personal Data by logging on to your account.
* **Rectification**: If you believe that any Personal Data we are holding about you is incorrect or incomplete, you can request that we correct or supplement such data. Users of Particle Network’s dashboard can also correct some of this information (for example, email address) directly by logging on to your account.
* **Erasure**: You can request that we erase some or all of your Personal Data from our systems.
* **Withdrawal of Consent**: If we are processing your Personal Data based on your consent (as indicated at the time of collection of such data), you have the right to withdraw your consent at any time. Please note, however, that if you exercise this right, you may have to then provide express consent on a case-by-case basis for the use or disclosure of certain of your Personal Data, if such use or disclosure is necessary to enable you to utilize some or all of our Services.
* **Portability**: You can ask for a copy of your Personal Data in a machine-readable format. You can also request that we transmit the data to another controller where technically feasible.
* **Objection**: You can contact us to let us know that you object to the further use or disclosure of your Personal Data for certain purposes, such as for direct marketing purposes.
* **Restriction of Processing**: You can ask us to restrict further processing of your Personal Data.
* **Right to File Complaint**: You have the right to lodge a complaint about Particle Network's practices with respect to your Personal Data with the supervisory authority of your country or EU Member State.
## Changes to this Privacy Policy
We’re constantly trying to improve our Services, so we may need to change this Privacy Policy from time to time, but we will alert you to any such changes by placing a notice on the Particle Network website, by sending you an email, and/or by some other means. Please note that if you’ve opted not to receive legal notice emails from us (or you haven’t provided us with your email address), those legal notices will still govern your use of the Services, and you are still responsible for reading and understanding them. If you use the Services after any changes to the Privacy Policy have been posted, that means you agree to all of the changes. Use of information we collect is subject to the Privacy Policy in effect at the time such information is collected.
## Company Information
Name: **MINI JOY GLOBAL PTE. LTD.**
Reg Number: **202014032M**
Address: **1 RAFFLES PLACE #50 ONE RAFFLES PLACE SINGAPORE (048616)**
# Terms of Use
Source: https://developers.particle.network/intro/tos/terms-of-use
Effective Date: May 1, 2022.
### Terms of Service | Particle Network
Welcome to Particle Network and/or Dashboard. Particle Network (the “**Site**”), owned and operated by Particle Network Labs, Inc. (“Particle Network,” “Particle,” “**we**,” or “**us**”). By using this Site, you agree to these terms and conditions of use (the “**Terms**”), as well as our standard User Terms of Service (the “**User Terms**”) and any other terms or policies referenced in these Terms. If you do not agree, you may not use the Site. Particle Network may modify the Site and/or these Terms from time to time without notice to you, except that if Particle Network makes material changes to these Terms, we will post the revised Terms and the revised effective date on this Site and/or provide notice by some other means. You understand and agree that by using the Site following any modifications to the Terms, you agree to be bound by the modified Terms. **Important**: These Terms apply to the Site and your use of our developer tools and do not govern your use of Particle Network’s services as a direct end user of Particle Network’s services and products, which are subject to the User Terms.
### 1. Use of the Site
You must be of legal age to enter into contracts where you reside to use our Site. We do not knowingly collect or solicit personally identifiable information from individuals under 18. If you are under 18, please do not attempt to use the Services or send any personal information about yourself to us. If we learn we have collected personal information from an individual under 18, we will delete that information as quickly as possible. You will comply with all applicable laws, rules, and regulations in connection with your use of the Site. You will not violate or attempt to violate the security of the Site or Particle Network's systems or network security, including, without limitation by (i) accessing data not intended for users of the Site or gaining unauthorized access to an account, server or any other computer system; (ii) attempting to probe, scan or test the vulnerability of a system or network or to breach security or authentication measures; (iii) attempting to interfere with the function of the Site, host or network. You may not "**crawl**," "**scrape**," or "**spider**" any portion of the Site (through the use of manual or automated means); (iv) attempt to access another user's private key or other login information to a digital asset wallet without such user's explicit consent subject to a previously disclosed privacy policy; (v) framing or mirroring any part of the Site without our express prior written consent; or (vi) impersonating or pretending to be anyone else but you, falsely stating, or otherwise misrepresenting your affiliation with any person or entity in connection with the Site, or expressly or implicitly suggesting that we endorse any statement you make.
### 2. Information Not Confidential
If you choose to contact any Particle Network personnel using the contact information you find on the Site, you understand any information and/or materials you provide to such personnel will not be treated as confidential or proprietary. Particle Network undertakes no obligation to review information submitted by you or to return such information to you.
### 3. Particle Network Proprietary Rights
The Site, including all of its contents (including, text, images, audio, and the HTML used to generate the pages) (“**Content**”), are the property of Particle Network or that of our suppliers or licensors and are protected trademark, copyright, and/or other intellectual property laws. You may not download, copy, print, display, perform, reproduce, publish, modify, prepare derivative works from, license, transmit, or distribute any Content from this Site in whole or in part, for any public or commercial purpose without prior written consent from Particle Network. Particle Network grants you a limited, personal, non-exclusive, non-transferable license to access the Site and to use the Content, solely for personal, internal, and non-commercial purposes. Particle Network (on behalf of itself and its suppliers and licensors) reserves all rights not expressly granted herein. Without limiting the foregoing, as between you and Particle Network, Particle Network is the owner and/or authorized user of any trademark, registered trademark, logo, and/or service mark appearing on the Site (the “**Marks**”). Nothing on the Site should be construed to grant any license or right to use any Particle Network Mark. You may not use or exploit any Marks without prior written consent from Particle Network.
### 4. Links from and to the Site
The Site may contain links to third-party websites (“**Third Party Sites**”). Third-Party Sites are not reviewed, controlled, or examined by Particle Network in any way and Particle Network is not responsible for any content contained therein. These links do not imply Particle Network’s endorsement of, or association with, any Third Party Site. Particle Network is not liable, directly or indirectly, to anyone for any loss or damage arising from or in connection with the use of the Third Party Sites.
### 5. Reporting Suspected Vulnerabilities
If you would like to report a vulnerability or have a security concern regarding our user-facing and developer-related services, SDK, API, infrastructure, architecture etc., please e-mail [help@particle.network](mailto:help@particle.network).
### 6. Disclaimer of Warranties
THE SITE, INCLUDING, WITHOUT LIMITATION, THE SITE AND ALL CONTENT AND FUNCTIONALITY THEREOF, IS PROVIDED "**AS IS**," WITHOUT WARRANTY OF ANY KIND, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF AVAILABILITY, ACCURACY, COMPLETENESS, USEFULNESS, TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, AND PARTICLE NETWORK (ON BEHALF OF ITSELF AND ITS SUPPLIERS AND LICENSORS) HEREBY DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED. NO ADVICE, RESULTS, INFORMATION OR MATERIALS, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU THROUGH THE SITE WILL CREATE ANY WARRANTY NOT EXPRESSLY MADE HEREIN. NO CONTENT CAN OR SHOULD BE CONSTRUED AS PROFESSIONAL ADVICE OF ANY KIND (INCLUDING BUSINESS, INVESTMENT, ACCOUNTING, TAX, AND/OR LEGAL ADVICE).
### 7. Limitation of Liability
TO THE GREATEST EXTENT PERMITTED UNDER APPLICABLE LAW, IN NO EVENT WILL PARTICLE NETWORK, ITS AFFILIATES (INCLUDING AFFILIATED FUNDS) OR ANY OF ITS OR THEIR RESPECTIVE DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, SUPPLIERS OR LICENSORS (THE "**PARTICLE NETWORK PARTIES**"), BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY OR PUNITIVE DAMAGES ARISING FROM OR IN CONNECTION WITH THE USE OF, OR THE INABILITY TO USE, THE SITE OR THE CONTENT, EVEN IF ANY PARTICLE NETWORK PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OR EXCLUSION OF LIABILITY SO SOME OF THE ABOVE LIMITATIONS MAY NOT APPLY TO YOU. IN NO EVENT WILL THE TOTAL LIABILITY OF ANY PARTICLE NETWORK PARTY TO YOU FOR ALL DAMAGES, LOSSES, AND CAUSES OF ACTION (WHETHER IN CONTRACT OR TORT, INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE OR OTHERWISE) ARISING FROM OR RELATED TO THE TERMS, THE CONTENT, AND/OR YOUR USE OF THE SITE, EXCEED, IN THE AGGREGATE, \$100.00.
### 8. General Information
These Terms are governed by the laws of the State of California, without regard to the conflicts of laws provisions thereof. In the event of any dispute arising in connection with these Terms, you hereby consent to exclusive jurisdiction and venue in the state and federal courts of San Francisco County, California. The failure of Particle Network to exercise or enforce any right or provision of these Terms does not constitute a waiver of such right or provision. If any provision of these Terms is found by a court of competent jurisdiction to be invalid, that provision will be limited or eliminated, to the minimum extent necessary, so that these Terms shall otherwise remain in full force and effect and enforceable. You may not assign these Terms or transfer any of your rights or obligations hereunder without Particle Network’s express written consent. These Terms inure to the benefit of Particle Network’s successors, assigns, and licensees. These Terms are the entire agreement between you and Particle Network with respect to the subject matter herein.
### 9. Further Information You Give Us In Relation to the Particle Network Site and Particle Network Services.
Further information we collect from you in relation to [https://particle.network/](https://particle.network/) (the “Particle Network Site”) and Particle Network Services may include:
1. Further identity information, such as your country of birth, nationality, social security number, place of birth, employer, and occupation;
2. Passport and/or photo ID for identity verification purposes;
3. Information required to comply with anti-money laundering (AML) laws and know-your-customer (KYC) requirements (such as nationality and place of birth);
4. Source of funds for participating in token launches;
5. and Information that you give us in relation to your purchased token holdings, such as earnings received from staking, and the number of tokens in your wallet.
### 10. Company Information
Name: **MINI JOY GLOBAL PTE. LTD.**
Reg Number: **202014032M**
Address: **1 RAFFLES PLACE #50 ONE RAFFLES PLACE SINGAPORE (048616)**
# External Tutorials
Source: https://developers.particle.network/intro/tutorials-and-demos/list
Third-party tutorials on using Particle Network's SDKs.
Tutorial on integrating Moralis Auth API with Particle Connect.
Guide to using ZeroDev with Particle Auth.
Steps to integrate Stackup with Particle Auth.
Introduction to using Account Kit with Particle Auth.
How to use Pimlico with Particle Auth.
Guide to integrating Particle on Astar zkEVM.
Tutorial on using Particle with Polygon.
Steps to integrate Particle on Gnosis.
Guide to using Particle on Moonbeam.
Tutorial on integrating Particle on Mantle.
Steps to use Particle on Klaytn.
Guide to integrating Particle on COMBO.
Tutorial on using Particle on SKALE.
Steps to integrate Particle on PlatON.
Guide to using Particle on ZetaChain.
Tutorial on integrating Particle on Celo.
Steps to use Particle on Arbitrum.
Guide to integrating Particle on Merlin Chain.
Tutorial on using Particle on SatoshiVM.
Steps to integrate Particle on B².
Guide to using Particle on Base.
Tutorial on integrating Particle on Botanix.
Steps to use Particle on Bitlayer.
# Example Repositories
Source: https://developers.particle.network/intro/tutorials-and-demos/repositories
Collection of demos and examples application using Particle Network's products.
## Particle Auth
Example application for leveraging the Particle aa-signers package within Alchemy's Account Kit.
Demo application for leveraging Taiko within Particle's Smart Wallet-as-a-Service.
Demo application for using PGN within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Particle Auth Core on zkSync.
Demo application for leveraging Particle Auth Core (Smart WaaS) on COMBO.
Demo application for leveraging Scroll within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Particle Auth Core (Smart WaaS) on X1.
Demo application for leveraging Particle Auth Core (Smart WaaS) on Base.
Demo application for leveraging ZetaChain within Particle's Smart Wallet-as-a-Service.
Demo application for implementing the Particle Auth Core SDK within React applications.
Demo application for leveraging Fantom Mainnet within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Polygon zkEVM within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging ReadON within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Moonriver within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Viction within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Gnosis within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Astar zkEVM within Particle's Smart Wallet-as-a-Service.
Example for implementing Particle Auth within Avalanche applications to enable social login.
Example application for Solana "Sign in with Google" integration via. Particle Auth.
Example application for native Particle Auth integration within Solana's wallet-adapter.
Example application using Particle Connect and Vue3.
Example application for leveraging Particle Auth Core for social logins within applications built on Avalanche.
Demo application for using Particle Auth Core on Mantle.
Demo application for using Particle Auth Core on Linea.
Demo application for using Particle Auth Core on Kava.
Example application for leveraging Particle Auth Core for social logins within applications built on Berachain.
Example application for leveraging Particle Auth Core for social logins within applications built on Arbitrum.
Example application for leveraging Particle Auth Core for social logins within applications built on Blast.
Example application for leveraging Particle Auth Core for social logins within applications built on Celo.
Example repository showcasing the implementation of Particle Auth with Web3Modal V3.
***
## Account Abstraction
Demo application for leveraging session keys natively within Particle's Smart Wallet-as-a-Service.
Demo application for leveraging ZeroDev with Particle's Wallet-as-a-Service.
Demo application for leveraging Stackup with Particle's Smart Wallet-as-a-Service.
Demo application for leveraging Pimlico with Particle's Smart Wallet-as-a-Service.
Example application for using Particle as a signer in Alchemy's Account Kit.
Demo application for leveraging Particle Network along with Openfort for the utilization of session keys.
Demo application for using Biconomy's Particle Auth SDK to send gasless transactions.
***
## Particle Connect
Boilerplate demo application for facilitating wallet connection with Particle Connect.
Demo application using Particle Connect with `create-react-app`,
Demo application using Particle Connect with Next.js,
Demo application using Particle Connect with `create-react-app`,
Example application using Particle Connect with Vue3.
Demo application for implementing Particle Connect within applications built on Avalanche.
***
## BTC Connect
Demo application for leveraging BTC Connect from Particle Network on B².
Demo application for leveraging BTC Connect from Particle Network on BEVM.
Generalized demo application for leveraging BTC Connect.
Demo application for leveraging BTC Connect from Particle Network on Merlin.
Demo application for leveraging BTC Connect from Particle Network on SatoshiVM.
***
## Other
Boilerplate application for Particle Auth integration within RainbowKit.
Next.js started using Particle Auth with RainbowKit.
Example application for minting inscriptions with smart accounts through Particle Auth Core.
# Video Walkthroughs
Source: https://developers.particle.network/intro/tutorials-and-demos/videos
Video walkthroughs on integrating Particle's SDKs and APIs.
# Introduction to Universal Accounts
Source: https://developers.particle.network/intro/universal-accounts
One account, one balance, any chain.
**Universal Accounts** give users one account, balance, and interaction point to use across any chain—EVM or not.
Instead of managing different wallets and bridging tokens to interact with dApps on different chains, users interact through a Universal Account as if the entire Web3 ecosystem were one network. This is possible because Particle Network's underlying infrastructure automatically routes liquidity, bridges assets, and manages cross-chain logic using **Universal Liquidity**.
Developers can integrate Universal Accounts easily into their dApps using the [Universal SDK](/universal-accounts/cha/overview). UAs are compatible with both social logins and wallet connections and support gasless, cross-chain operations out of the box.
***
# Understanding Universal Accounts
From a technical standpoint, Universal Accounts are smart contract account deployments unified and coordinated by Particle Network's **Universal Liquidity** technology across chains. This enables seamless cross-chain transactions and interactions.
## Key Features
### Chain abstraction
* One account, one balance, any chain.
* Automatic bridging and cross-chain interactions on a per-transaction basis.
* Ability to use multiple gas tokens for different operations.
* Seamless asset transfers across chains.
### Smart Account implementation
* Built on the ERC-4337 standard.
* Leverages EIP-7702 to use existing EOA's assets without requiring users to migrate.
* Compatible with existing EOA wallets.
* Support social login integration.
## How It Works
1. **Integration**
* Simple SDK implementation, using any EOA as signer.
* Compatible with existing dApp infrastructure.
2. **Account Creation**
* Created via social logins, wallet connection, or private key.
* Automatic upgrade from EOA to Universal Account (assets instantly available without migrating in 7702 default mode).
3. **Cross-Chain Operations**
* Transactions submitted are funded using a user's collective onchain balance, automatically bridging as needed to fulfill their intent.
* Gas can be paid using different available tokens.
Start building with Universal Accounts.
**Try out Universal Accounts**
Particle Network has built the first chain-agnostic trading app based on Universal Accounts: [UniversalX](https://universalx.app/). Try it out to experience the power of chain abstraction!
# What is Chain Abstraction?
Source: https://developers.particle.network/intro/what-is-cha
The practical benefits of chain abstraction for dApps and users.
# Chain Abstraction
**Chain abstraction** removes the friction of dealing with multiple blockchains.\
With **Universal Accounts**, users and developers interact with Web3 as if it were one unified environment.
***
## What This Means for Users
* **One account and balance** across all chains.
* **Use any token as gas** on any transaction.
* **No bridges or chain switching** required.
***
## What This Means for Developers
* Build your dApp on one chain, serve users from all of them.
* No need to manage cross-chain deployments.
* Unified liquidity, handled automatically in the background.
## Next Steps
Start building with Universal Accounts.
Try UniversalX, a chain-agnostic trading app powered by Universal Accounts.
# What is Particle Network?
Source: https://developers.particle.network/intro/what-is-particle-network
Overview of Particle Network's products and mission.
# What is Particle Network?
Web3 today is fragmented across hundreds of chains, wallets, and bridges.
Particle Network’s mission is to make **Web3 retail-ready** by solving multi-chain fragmentation and building a user experience that feels as natural as Web2's.
We do this through a stack of products designed to remove friction for both users and developers, unifying Web3 into the way it should be:
* One account.
* One balance.
* Any chain.
***
## Chain Abstraction
Chain Abstraction is the foundation of Particle Network.
It allows users to interact with any dApp, on any supported chain, using a **single account and unified balance**—without worrying about bridges or network switching.
At the core of this are **Universal Accounts**, which enable:
* **One account, one balance, any chain**: Assets across all chains are automatically combined into one balance.
* **Chain-agnostic UX**: Users can spend tokens from anywhere, on any chain.
* **Universal Gas**: Users can pay fees in any supported token, regardless of the network.
Build your first chain-agnostic dApp with Universal Accounts.
***
## Social Logins
Onboarding is still one of the biggest blockers in Web3. Particle’s **Social Logins** let users access dApps with credentials they already know — Google, Twitter, Discord, and more — while automatically creating a wallet behind the scenes.
* **One-click onboarding** for mainstream users.
* **Non-custodial** by design, with keys split and secured.
* **Developer-ready SDKs** to add login flows in minutes.
Add fast, familiar onboarding to your dApp.
***
## Account Abstraction (ERC-4337)
Particle also provides infrastructure for **ERC-4337 Account Abstraction**, enabling programmable smart accounts with powerful UX improvements:
* **Gas sponsorship**: Users can transact without holding native gas tokens.
* **Batched transactions**: Bundle multiple actions into a single click.
* **Custom logic**: Recovery flows, spending limits, and more.
Implement ERC-4337 smart accounts in your dApp.
# What is Universal Liquidity?
Source: https://developers.particle.network/intro/what-is-ul
Overview of Particle Network’s liquidity mechanism powering Universal Accounts.
**Universal Liquidity** allows **Universal Accounts** to fulfill user actions without requiring them to **bridge** or manually move assets across chains. It routes funds across **solvers** with liquidity on supported networks based on the user’s **intent**, allowing them to interact with all chains as if they were **one**.
***
## How It Works
When a user performs an action on a chain where they don’t hold funds, Universal Liquidity handles the **cross-chain** complexity behind the scenes. **Liquidity sources** and **solvers** operate across networks to execute the transaction.
**Flow:**
1. The user initiates the action (**swap**, **mint**, **deposit**, etc.) and signs once to **authorize** it. No preparation of assets or **gas** on the target chain is required.
2. The **signature** conveys what the user wants to do and confirms they can cover the **cost**.
3. **Solvers** detect the request and temporarily provide the required **liquidity** on the destination chain. They:
* Execute the transaction on the user’s behalf
* Cover the required **costs upfront**
* Recoup the value afterward from the user’s **balances** on any chain
4. The transaction finalizes on the **destination network**.
The user’s funds **never move beforehand**. The solver only fronts the required liquidity, then withdraws **repayment** from the user’s existing balances according to the signed authorization.
A **solver** is simply an **on-chain entity** with liquidity (e.g., an **LP** holding **USDT** or another [**Primary Token**](/universal-accounts/cha/chains)). Particle currently operates the liquidity pools, with the goal of enabling **permissionless** participation in the future.
***
## Example
A user holds:
* **100 USDC** on Base
* **0.1 BNB** (\~\$90) on BNB Chain
* **0.3 SOL** (\~\$40) on Solana
They want to execute a transaction that requires **200 USDC on Ethereum**. A solver provides **200 USDC** on Ethereum and then receives **repayment** across the user’s existing balances, plus a small **fee**.
***
## Gas Abstraction
Universal Liquidity also removes the requirement to hold **native gas tokens** on every chain. **Paymasters** cover **gas fees** on the user’s behalf, then settle repayment afterward using **any supported asset** — even if that asset is on another chain.
**Flow:**
1. User signs to authorize the operation and **repayment**.
2. **Paymaster** fronts the gas immediately.
3. Transaction executes on the **target chain**.
4. Repayment is deducted afterward using available **balances**.
A **single signature** is enough to complete **cross-chain** operations while advancing both **liquidity** and **gas**.
***
## TL;DR
Universal Liquidity enables:
* Assets across chains to function as **one unified liquidity source**
* Execution of transactions using **any combination** of a user’s balances
* Removal of **bridging**, **gas concerns**, and **balance fragmentation**
***
## Get Started with Universal Accounts
Learn how to integrate **Universal Accounts** into your application.
Start building with Universal Accounts.
# Common API Errors
Source: https://developers.particle.network/social-logins/api/debug/api
Learn about a number of common errors you may run into while building your application.
## Understanding Common API Errors
When using both our SDKs and APIs/RPCs, there are a number of common errors you may run into while building your application. This page is intended to list as many of these errors as possible and highlight what may cause them, thus adding clarity to the standard return messages attached to the errors. For SDK-specific errors, look at [Common SDK Errors](/social-logins/api/debug/sdk).
***
## Error codes
| Code | Possible Return Message | Cause |
| :----------------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **System Errors** | | |
| 10001 | System error | System error, or 10001, gets thrown when an internal JSON-RPC error occurs, referring to an error beneath the layer you're directly interacting with. |
| 10002 | Invalid parameters | When the parameters of a given RPC/API request are incorrect or missing, 10002 is thrown. Refer to the [Introduction to API & SDK overview](/social-logins/api/introduction) section for more details. |
| **Common Errors: 401xx** | | |
| 40101 | User not exists | Accessing an invalid user (a Particle Auth wallet instance that's connected to your application and thus exposed a UUID and Token) will throw 40101, or "User not exists." |
| 40102 | Authentication failed | Initializing Particle Auth (or associated SDKs) requires a `projectId`, `clientKey`, and `appId`, if these are invalid, the error "Authentication failed" is returned. |
| 40103 | Address not exists | If you attempt to execute a method that takes a public address as a parameter, and this address is invalid, 40103 is thrown. |
| 40104 | Insufficient funds | 40104, or "Insufficient funds," is a common error given when a transaction (state-changing action requiring funds) is attempted while the sender has a balance lower than the minimum required to execute the transaction. |
| 40105 | EIP-1559: Invalid fee setting | 40105 occurs when attempting to execute a transaction with an invalid EIP-1159 fee setting (priority fee). Retrieve gas fees with [suggestedGasFees](/social-logins/api/evm/suggestedgasfees). |
| 40106 | Nonce error | Backed up RPC endpoints or attempting to send transactions in quick succession may throw 40106, which results from an invalid nonce order (value `nonce` on your attempted transaction). |
| 40107 | Cancel the biggest nonce first | When attempting to cancel a transaction, 40107 will be returned if this cancellation targets a nonce lower than the largest known. |
| 40108 | Transaction confirmed | Confirmed transactions can no longer be canceled or sped up, thus if you attempt to do this, error 40108 will occur. |
| 40109 | gasLimit too low | Attempting to send a transaction with a low `gasLimit` (sometimes expressed as `gas`). Increase your units of gas represented within this variable or estimate the gas with `estimateGas`. |
| 40110 | JSON-RPC request body error | Parameters or values passed into the request body that may be invalid will result in error 40110 ("JSON-RPC request body error") being returned. |
| 40113 | EIP-1559 transaction is not supported | When sending or constructing a transaction using EIP-1559 (often determined by `type` being `2`) that is invalid or not supported in that specific context, you'll encounter error 40113. |
| **Solana Errors: 402xx** | | |
| 40201 | Transaction Error | Attempting to send an invalid or failing transaction on Solana via. JSON-RPC will return 40201, indicating that the transaction itself likely has an underlying issue. |
| 40202 | You can not settle the auction because you have not participated in the auction | *Returned apart of the old Metaplex/Action House API endpoints, not listed on developers.particle.network* |
| 40203 | You are not the creator of this metadata | *Returned apart of the old Metaplex/Action House API endpoints, not listed on developers.particle.network* |
| 40204 | Auction is not in Started state | *Returned apart of the old Metaplex/Action House API endpoints, not listed on developers.particle.network* |
| 40205 | Metadata already exists | *Returned apart of the old Metaplex/Action House API endpoints, not listed on developers.particle.network* |
| 40206 | No need to unwrap | *Returned apart of the old Metaplex/Action House API endpoints, not listed on developers.particle.network* |
| **EVM-Specific Errors: 403xx** | | |
| 40301 | Swap Error | When using endpoints like [getSwap](/social-logins/api/swap/getswap) and [getQuote](/social-logins/api/swap/getquote), if the parameters provided to the endpoint are invalid or will result in a failed swap, 40301 may be returned. |
| **JSON RPC Errors: -32xxx** | | |
| -32700 | Parse error | If the server (the node or database) receives an invalid JSON request body, -32700 will be returned, indicating either an underlying issue or a problem with the values, parameters, or structure used within the request. |
| -32600 | Invalid request | Similar to the above, -32600 will be thrown if the request object is an invalid structure or includes invalid parameters. This is a targeted error, while -32700 is generic. |
| -32601 / -32006 | Method not found | Methods are dictated through the `method` parameter within the JSON-RPC request; if this is invalid (doesn't exist), error -32601 will be returned. |
| -32602 | Invalid parameters | More narrowly scoped than -32600, this error (-32602) will be thrown if the parameters themselves were determined as invalid, thus not meeting the server's expectations. |
| -32603 & -3200 | Internal error / System error / Server error | Like 10001, these errors may be thrown if an internal error occurs behind the scenes. This may or may not result from an invalid request. Contact us within the [Particle Network Discord](https://discord.com/invite/2y44qr6CR2) to help troubleshoot. |
| -32001 | Unsupported chainId | When passing a `chainId` within the standard JSON-RPC request parameters, -32001 may be returned if this value does not correspond with a currently supported blockchain. |
| -32002 | Arrays are not currently supported | If you're attempting to pass an array as a parameter value through either the [Paymaster RPC](/aa/paymaster/paymasterbalance) or [Bundler RPC](/aa/bundler/getuseroperationreceipt), -32002 will be thrown due to their lack of compatibility as a type within these requests. |
| -32003 / -32603 | Not supported entry point | When attempting to send UserOperations to or interact with an entrypoint that isn't `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789`, -32003 will be thrown due to the current exclusive compatibility with said entrypoint. |
| -32004 | The UserOP is already processed | Once a UserOperation has been sent, processed, and thus settled on-chain, it can no longer be re-sent or modified, thus when attempting to do this, -32004 is returned. |
| -32005 | Estimate gas failed | Gas estimations occur either automatically through something like [createUserOp](/aa/rpc/createuserop), or manually through [getFeeQuotes](/aa/rpc/getfeequotes). If the parameters passed into these requests are invalid or if the transaction may fail, -32005 will possibly be returned. |
| -32600 | Invalid Request | Sending an invalid request (meaning incorrect parameters, value, or structure) to the [Bundler RPC](/aa/bundler/getuseroperationreceipt) or [Paymaster RPC](/aa/paymaster/paymasterbalance) will result in error -32600, although this is a generalized error with the scope of the entire request. |
| -32602 | Invalid params | Alternatively, for requests to the [Bundler RPC](/aa/bundler/getuseroperationreceipt) or [Paymaster RPC](/aa/paymaster/paymasterbalance) in which the parameters themselves are deemed to be invalid (rather than the entire request), -32602 will be thrown. |
| -32604 | Send user operation failed | When sending a UserOperation to the [Bundler RPC](/aa/bundler/getuseroperationreceipt) and it fails due to a variety of potential reasons (balance errors, paymaster issues, account deployment issues, etc.), -32604 is returned. |
| -32605 | Validate user operation failed | Similar to the above, UserOperations undergoing validation through the [Bundler RPC](/aa/bundler/getuseroperationreceipt) that fail will result in -32605 being returned. |
| -32606 | Simulate user operation failed | If calling [estimateUserOperationGas](/aa/bundler/estimateuseroperationgas) on a UserOperation that may fail or contains invalid parameters, you may encounter -32606 (or, depending on the nature of the failure, -32600/-32602). |
| -32003 | The sign request is rejected | Requesting aymaster signature under invalid conditions may result in error -32003, which refers to the rejection of the sponsorship. Ensure you've set your conditions properly and funded the Paymaster. |
| -32004 | Can not fetch the usd price | When calling [paymasterBalance](/aa/paymaster/paymasterbalance), the USD price calculation may fail, resulting in error -32004. |
| -32005 | Insufficient deposit for the project | Before leveraging the Particle Network [Omnichain Paymaster](/aa/architecture/omni-paymaster) within your application, you'll need to deposit enough USDT for sponsorship. Failing to do so may result in error -32005 being thrown. |
# Common SDK Errors
Source: https://developers.particle.network/social-logins/api/debug/sdk
Learn about a number of common errors you may face while using our SDK.
## Understanding SDK Errors
Within Particle Network's SDKs, errors are almost always caught for SDK-related issues, meaning problems related to configuration, compatibility, initialization, etc.
For non-SDK related issues that may stem from external factors within your application (such as webpack/vite/etc. configurations, npm or yarn problems, etc.), you'll need to troubleshoot these manually or reach out to us through the [Particle Network Discord](https://discord.com/invite/2y44qr6CR2).
Additionally, the error you're looking for may be present within [Common API Errors](/social-logins/api/debug/api).
***
## Particle Auth/Connect
| Error message | Description | Component |
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------- |
| "You need to set project info" OR "Init AuthCore failed" OR "Param error, see doc for more info" | This error occurs when attempting to initialize Particle Auth without including your `projectId`, `clientKey`, and `appId`. Head over to the [Particle dashboard](https://dashboard.particle.network) to retrieve and set these. | \* |
| "chain is required when authorization is provided" | If initiating social login with `authorization` on Particle Auth Core, `chain` is required and should be a `ChainInfo` object imported from `@particle-network/chains`. Otherwise this error will be thrown. | useConnect |
| "Please init first!" (or some derivative of this) | A request for initialization (or init) will be thrown when attempting to access methods that require an underlying account. Ensure you've initialized Particle Auth before calling other methods within the SDK. | \* |
| "The chainId: is not supported." (or some derivative of this) | This will be thrown when attempting to pass a chain ID into a specific function (commonly `sendTransaction`) that isn't supported by Particle Auth. For the full list of supported chains, head to [Network Coverage](/social-logins/network-coverage). | \* |
| "WebSocket connection closed abnormally with code: 3000 (Authorization error: Unauthorized: invalid key)" OR "WebSocket connection closed abnormally with code: 3000 (Authorization error: Project ID is missing)" | This occurs when using Particle Connect and failing to include a valid WalletConnect project ID within `evmWallets`, or specific wallet adapters. To retrieve this value, head to the [WalletConnect dashboard](https://cloud.walletconnect.com). | \* |
***
## Particle AA SDK
| Error message | Description | Component |
| :--------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------- |
| "Please configure the smart account contract first" | When calling specific functions that require the context of an initialized smart account, you may encounter this error. To alleviate it, you'll need to ensure you've already constructed a valid instance of `SmartAccount` with a specific smart account chosen. | setSmartAccountContract, getAccountConfig |
| "Current chain is not supported, chainId: , please configure it first" | Upon assigning a smart account within `SmartAccount` and choosing a specific `chainId` (through `chainIds`), you may encounter this issue if the chain you're attempting to use to initialize the smart account is not supported by that implementation. Remember that different account implementations (SimpleAccount, Biconomy, CyberConnect) are each compatible with different chains. | getAccountConfig |
| "Only BICONOMY 2.0.0 is supported" | Session keys are currently supported on instances of `BICONOMY 2.0.0`. When attempting to call `createSessions` or `validateSession` on different account implementations, this error will be thrown. Ensure `SmartAccount` is configured to use `biconomy` version `2.0.0`. | createSessions, validateSession |
| "sendTxMode value error, must be in " | When setting `SendTransactionMode` on `AAWrapProvider`, you'll need to use either `SendTransactionMode.Gasless`, `SendTransactionMode.UserPaidNative`, or `SendTransactionMode.UserSelect`, otherwise this error will be thrown. | AAWrapProvider |
| "AA21 didn't pay prefund" | This is a generic error a Bundler issues when a given smart account does not have the funds for a user operation. In this case, it will most likely occur upon account initialization (the first UserOperation sent by the wallet). Ensure you're either sponsoring the gas fees or have funded the account. | *Generic* |
| "AA31 paymaster deposit too low" | AA31 stems from insufficient funds within the Paymaster to sponsor a given transaction. Ensure you've funded the Particle Paymaster (or Biconomy Paymaster) with USDT on either Ethereum or BNB Chain. Your USDT will be automatically converted for multi-chain sponsorships. | *Generic* |
| "AA25 Invalid Account Nonce" | While unlikely to occur within Particle's AA SDK, there may be scenarios in which nonce management is disrupted, resulting in this error. This may happen if you're sending large volumes of UserOperations from a single account in a short time or if network issues are present and thus an invalid nonce is being returned to the backend of the SDK. | *Generic* |
| "AA" | Other issues of this nature (AA), stem directly from the invalid construction or execution of a UserOperation. Feel free to reach out within the [Particle Network Discord](https://discord.com/invite/2y44qr6CR2) for more assistance. | *Generic* |
| "Account Abstraction Error" | This often acts as the prefix for a generic AA error, such as `AA21 didn't pay prefund`, or other related issues. | *Generic* |
***
More targeted error codes may present themselves while using the SDK
These aren't covered within this document (example: `personalSign error: {specific error description}`) and often stem from parameter issues or underlying RPC errors (see [Common API Errors](/social-logins/api/debug/sdk)).
# abi_encodeFunctionCall
Source: https://developers.particle.network/social-logins/api/evm/abi_encodefunctioncall
openapi-evm POST /#particle_abi_encodeFunctionCall
Learn how to use the abi_encodeFunctionCall JSON-RPC method.
## Contextualizing `abi_encodeFunctionCall`
* `abi_encodeFunctionCall` takes a contract address, a function name, and an array of function parameters to return an ABI-encoded string that represents the specific function call you intend to make on the smart contract.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: "particle_abi_encodeFunctionCall",
params: [
"0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
"erc20_transfer",
[
"0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8",
"1000000000000000000"
]
]
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# crosschain_getNFTs
Source: https://developers.particle.network/social-logins/api/evm/crosschain_getnfts
openapi-evm POST /#particle_crosschain_getNFTs
Learn how to use the crosschain_getNFTs JSON-RPC method.
# Understanding `crosschain_getNFTs`
* `crosschain_getNFTs` is an alternative to `getNFTs` in which NFTs (ERC-721 tokens) can be retrieved for a given address across multiple different EVM chains in the same query. It takes:
* `Addresses` - an array of strings (either one or more account addresses.)
* `Chain IDs` - an array of integers.
* `Contracts` - (optional) an array of strings. It filters based upon specific collection contracts.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: 'particle_crosschain_getNFTs',
params: [
['0x6a2C3C4C7169d69A67ae2251c7D765Ac79A4967e', '0xf584F8728B874a6a5c7A8d4d387C9aae9172D621'],
[1, 4, 137, 80001]
],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# deserializeTransaction
Source: https://developers.particle.network/social-logins/api/evm/deserializetransaction
openapi-evm POST /#particle_deserializeTransaction
Learn how to use the deserializeTransaction JSON-RPC method.
## Contextualizing deserializeTransaction
`deserializeTransaction` takes a serialized transaction hash (example below) and returns a human-readable deserialized transaction object, including additional details such as balance changes, method calls, token attributes, etc.
***
**Serialized transaction string example**
```
0x02f8d30182030a843b9aca00850608379d4b8301122e9499ecdf17ded4fcb6c5f0fe280d21f832af464f6780b86442842e0e00000000000000000000000003afc65278e6d37f23bc0b8bf4c9d61bd35edfc8000000000000000000000000a058fb195d274afbae4dc317be362d4e96ffa1b400000000000000000000000000000000000000000000000000000000000006c1c001a0f7e0c908e4b549d24dad47f28205d3437e00b123e9b57bec95dcd61e1fd8065ca053495aaeec3740c0520e7717060a208aac0970dbc30ef3380e3ae9f81f4f6f66
```
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: 'particle_deserializeTransaction',
params: [
'0x03afc65278e6d37f23bc0b8bf4c9d61bd35edfc8',
'0x02f8d30182030a843b9aca00850608379d4b8301122e9499ecdf17ded4fcb6c5f0fe280d21f832af464f6780b86442842e0e00000000000000000000000003afc65278e6d37f23bc0b8bf4c9d61bd35edfc8000000000000000000000000a058fb195d274afbae4dc317be362d4e96ffa1b400000000000000000000000000000000000000000000000000000000000006c1c001a0f7e0c908e4b549d24dad47f28205d3437e00b123e9b57bec95dcd61e1fd8065ca053495aaeec3740c0520e7717060a208aac0970dbc30ef3380e3ae9f81f4f6f66',
]
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getContractAbi
Source: https://developers.particle.network/social-logins/api/evm/getcontractabi
openapi-evm POST /#particle_abi_getContractAbi
Learn how to use the getContractAbi JSON-RPC method.
## Contextualizing `getContractAbi`
* `getContractAbi` takes the address of a **verified** contract and returns the complete ABI. It **will return null** if the contract is not verified.
If you're unsure whether a given contract is verified, Etherscan displays verification status on the **Contract** tab of smart contracts
Check it at: [https://etherscan.io/address/YOUR\_CONTRACT\_ADDRESS#code](https://etherscan.io/address/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#code)
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 56,
jsonrpc: '2.0',
id: 1,
method: "particle_abi_getContractAbi",
params: [
"0x2170Ed0880ac9A755fd29B2688956BD959F933F8",
true,
]
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getLatestBlock
Source: https://developers.particle.network/social-logins/api/evm/getlatestblock
openapi-evm POST /#particle_getLatestBlock
Learn how to use the getLatestBlock JSON-RPC method.
## Contextualizing `getLatestBlock`
* `getlatestBlock` returns a highly detailed response containing both standard and extraneous information about the latest block on the chain associated with `chainId`.
This response includes full receipts of transactions contained within the latest block. This is non-toggleable.
***
**Returned receipts contain the following attributes**
```json JSON theme={null}
// Example receipt
"blockHash":"0x9468f7e44e89921b38eb4812ec5dc7900ceffc454aecb0a452d9477952062efc",
"blockNumber":"0x11868d0",
"contractAddress":null,
"cumulativeGasUsed":"0x9e0096",
"effectiveGasPrice":"0x3094e55d9",
"from":"0x3527439923a63f8c13cf72b8fe80a77f6e572092",
"gasUsed":"0xbbad2",
"logs":[
{
"address":"0x32400084c286cf3e17e7b677ea9583e60a000324",
"blockHash":"0x9468f7e44e89921b38eb4812ec5dc7900ceffc454aecb0a452d9477952062efc",
"blockNumber":"0x11868d0",
"data":"0x",
"logIndex":"0x1b",
"removed":false,
"topics":[
"0x22c9005dd88c18b552a1cd7e8b3b937fcde9ca69213c1f658f54d572e4877a81",
"0x0000000000000000000000000000000000000000000000000000000000042fc4",
"0x0000000000000000000000000000000000000000000000000000000000042fc5"
],
"transactionHash":"0x373c6917650568746f2cb9a99c9250ef5c5fdda380ac0e322779e9532c0d5153",
"transactionIndex":"0x10"
}
],
"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000010020000000000000000000002020000000000000000000000000000000000000000100000400000000000000000000000000000000000000000000000000000000000000000000000010000000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status":"0x1",
"to":"0x3db52ce065f728011ac6732222270b3f2360d919",
"transactionHash":"0x373c6917650568746f2cb9a99c9250ef5c5fdda380ac0e322779e9532c0d5153",
"transactionIndex":"0x10",
"type":"0x2"
```
# getNFTs
Source: https://developers.particle.network/social-logins/api/evm/getnfts
openapi-evm POST /#particle_getNFTs
Learn how to use the getNFTs JSON-RPC method.
# Understanding `getNFTs`
* `getNFTs`, alike `getTokens`, retrieves a detailed list of NFTs (ERC721 tokens) belonging to a given public address. It takes:
* `Address` - string.
* `Token addresses` - (optional), an array of strings.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: 'particle_getNFTs',
params: ['0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getPendingTransactionsByAddress
Source: https://developers.particle.network/social-logins/api/evm/getpendingtransactionsbyaddress
openapi-evm POST /#particle_getPendingTransactionsByAddress
Learn how to use the getPendingTransactionsByAddress JSON-RPC method.
## Contextualizing `getPendingTransactionsByAddress`
* `getPendingTransactionsByAddress` fetches pending transactions for a specified address on a chain derived from `chainId`, offering detailed metrics like gas limits, transaction types, and statuses.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 5,
jsonrpc: '2.0',
id: 1,
method: 'particle_getPendingTransactionsByAddress',
params: ['0x425249Cf0F2f91f488E24cF7B1AA3186748f7516'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getPrice
Source: https://developers.particle.network/social-logins/api/evm/getprice
openapi-evm POST /#particle_getPrice
Learn how to use the getPrice JSON-RPC method.
## Contextualizing `getPrice`
* `getPrice` returns an array of JSON objects containing real-time exchange rates, market cap, 24-hour changes, and volume for each specified token address in selected currencies (either `usd`, `cny`, or both at the moment).
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 42,
jsonrpc: '2.0',
id: 1,
method: 'particle_getPrice',
params: [
[
'native',
'0x7968bc6a03017eA2de509AAA816F163Db0f35148',
],
[
'usd',
'cny',
],
],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
},
});
console.log(response.data);
})();
```
# getTokens
Source: https://developers.particle.network/social-logins/api/evm/gettokens
openapi-evm POST /#particle_getTokens
Learn how to use the getTokens JSON-RPC method.
# Contextualizing `getTokens`
* `getTokens`, as an alternative to `getTokensAndNFTs`, returns an object with detailed information regarding the various ERC-20 tokens owned by a given address. It takes:
* `Address` - string.
* `Token addresses` - (optional), an array of strings.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: 'particle_getTokens',
params: ['0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getTokensAndNFTs
Source: https://developers.particle.network/social-logins/api/evm/gettokensandnfts
openapi-evm POST /#particle_getTokensAndNFTs
Learn how to use the getTokensAndNFTs JSON-RPC method.
# Understanding `getTokensAndNFTs`
* `getTokensAndNFTs` retrieves the ERC-20 and ERC-721 (NFTs) owned by a given account address. It takes:
* `Address` - string.
* `Token addresses` - (optional), an array of strings.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 1,
jsonrpc: '2.0',
id: 1,
method: 'particle_getTokensAndNFTs',
params: ['0x329a7f8b91Ce7479035cb1B5D62AB41845830Ce8'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# getTransactionsByAddress
Source: https://developers.particle.network/social-logins/api/evm/gettransactionsbyaddress
openapi-evm POST /#particle_getTransactionsByAddress
Learn how to use the getTransactionsByAddress JSON-RPC method.
## Contextualizing `getTransactionsByAddress`
* `getTransactionsByAddress` provides a detailed transaction history for a given address, including status and gas metrics. It returns all associated transactions, regardless of whether they're pending, successful, or failed, along with the relevant transaction details like gas spent and fees for confirmed transactions.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 42,
jsonrpc: '2.0',
id: 1,
method: 'particle_getTransactionsByAddress',
params: ['0x425249Cf0F2f91f488E24cF7B1AA3186748f7516'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# SDK Reference (EvmService)
Source: https://developers.particle.network/social-logins/api/evm/sdk-ref
Reference for the common EvmService SDK extension.
Throughout many of Particle Network's SDKs, a common **`EvmService`** module is included. It enables direct programmatic utilization of Particle's suite of **enhanced RPC endpoints**, and more (such as transaction construction, contract interaction, etc.). These methods provide simple ways of retrieving **rich on-chain data** with minimal added complexity.
A full reference of common methods alongside their parameters **can be found below**.
| Class | Methods | Parameters (\* indicates optional) |
| ---------- | ------------------------ | ----------------------------------------------------------------------- |
| EvmService | rpc | method, params |
| EvmService | getPrice | addresses, currencies |
| EvmService | getTokensAndNFTs | address |
| EvmService | getTokens | address |
| EvmService | getNFTs | address |
| EvmService | getTransactionsByAddress | address |
| EvmService | suggestGasFee | |
| EvmService | estimateGas | from, to, value, data |
| EvmService | erc20Transfer | contractAddress, to, amount |
| EvmService | erc20Approve | contractAddress, spender, amount |
| EvmService | erc20TransferFrom | contractAddress, from, to, amount |
| EvmService | erc721SafeTransferFrom | contractAddress, from, to, tokenId |
| EvmService | erc1155SafeTransferFrom | contractAddress, from, to, id, amount, data\* |
| EvmService | abiEncodeFunctionCall | contractAddress, methodName, params, abiJsonString |
| EvmService | getTokenByTokenAddress | address, tokenAddresses |
| EvmService | readContract | contractAddress, methodName, params, abiJsonString |
| EvmService | writeContract | from, contractAddress, methodName, params, abiJsonString, gasFeeLevel\* |
| EvmService | createTransaction | from, data, value, to, gasFeeLevel\* |
| EvmService | getSmartAccount | eoaAddresses, version |
# suggestedGasFees
Source: https://developers.particle.network/social-logins/api/evm/suggestedgasfees
openapi-evm POST /#particle_suggestedGasFees
Learn how to use the suggestedGasFees JSON-RPC method.
## Contextualizing `suggestedGasFees`
* `suggestedGasFees` returns an object containing tiered gas fee suggestions under EIP-1559 regulations for a chain derived from a given `chainId`.
It provides gas fee options for low, medium, and fast transaction speeds, complete with estimated wait times and the current base fee. It takes no parameters, although, as usual with Particle's enhanced RPC, it still requires basic authentication.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/evm-chain', {
chainId: 42,
jsonrpc: '2.0',
id: 1,
method: 'particle_suggestedGasFees',
params: [],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# Introduction to Server APIs
Source: https://developers.particle.network/social-logins/api/introduction
Particle Network's server APIs let you look up and verify Particle Auth users from your backend.
Particle Network also provides a small set of **server APIs** for backend integrations.\
These endpoints are useful when you need to **look up user details** or **verify whether a wallet belongs to a user in your project**.
* Retrieve user information by UUID and token
* Retrieve user information by identity
* Check whether an address belongs to a user in your project
These endpoints are intended for server-side usage and require your project server key.
This section gives you a quick overview of the currently available server endpoints, along with examples and an interactive playground for testing.
***
Retrieve a registered user's information using their UUID and token.
Retrieve a registered user's information using a supported identity value.
Check whether a wallet address belongs to a user associated with your project.
# getUserInfo
Source: https://developers.particle.network/social-logins/api/server/getuserinfo
openapi-auth POST /#getUserInfo
Learn how to use the getUserInfo JSON-RPC method.
## Understanding `getUserInfo`
* `getUserInfo` retrieves a JSON object containing various data points relating to a registered user (a user that has already undergone social login), such as their name, UUID, token, email, and so on. The population of specific data points (such as `facebookId`, `googleId`, etc.) will be dependent upon their primary associated social account.\` It takes:
* `UUID` - string.
* `Token` - string.
***
## Query example
```javascript JavaScript theme={null}
const axios = require("axios");
(async () => {
const response = await axios.post(
"https://api.particle.network/server/rpc",
{
jsonrpc: "2.0",
id: 0,
method: "getUserInfo",
params: ["Particle Auth User Uuid", "Particle Auth User Token"],
},
{
auth: {
username: "Your Project Id",
password: "Your Project Server Key",
},
}
);
console.log(response.data);
})();
```
# getUserInfoByIdentity
Source: https://developers.particle.network/social-logins/api/server/getuserinfobyidentity
openapi-auth POST /#getUserInfoByIdentity
Learn how to use the getUserInfoByIdentity JSON-RPC method.
## Understanding `getUserInfoByIdentity`
* `getUserInfoByIdentity` retrieves a JSON object containing various data points relating to a registered user (a user that has already undergone social login), such as their name, UUID, token, email, and so on. The population of specific data points (such as `facebookId`, `googleId`, etc.) will be dependent upon their primary associated social account.\` It takes:
* `provider` - string, identity provider, now only support `jwt`.
* `UID` - string, user identifier.
Authorization use project server key
***
## Query example
```javascript JavaScript theme={null}
const axios = require("axios");
(async () => {
const response = await axios.post(
"https://api.particle.network/server/rpc",
{
jsonrpc: "2.0",
id: 0,
method: "getUserInfoByIdentity",
params: ["jwt", "User Identity ID"],
},
{
auth: {
username: "Your Project Id",
password: "Your Project Server Key",
},
}
);
console.log(response.data);
})();
```
# isProjectUser
Source: https://developers.particle.network/social-logins/api/server/isprojectuser
openapi-auth POST /#isProjectUser
Learn how to use the isProjectUser JSON-RPC method.
# Understanding `isProjectUser`
* `isProjectUser` returns a Boolean representing whether or not a specified user (their public address assumedly derived from social login) has interacted with or belongs to your project. It takes:
* `Chain` - either `solana` or `evm_chain`.
* `Address` - string.
***
## Query example
```javascript JavaScript theme={null}
const axios = require("axios");
(async () => {
const response = await axios.post(
"https://api.particle.network/server/rpc",
{
jsonrpc: "2.0",
id: 0,
method: "isProjectUser",
params: ["evm_chain", "0x6D5fCEd0C74F22a1B145ef48B25527Ce9BF829bF"],
},
{
auth: {
username: "Your Project Id",
password: "Your Project Server Key",
},
}
);
console.log(response.data);
})();
```
# enhancedGetPrice
Source: https://developers.particle.network/social-logins/api/solana/enhancedgetprice
openapi-solana POST /#enhancedGetPrice
Learn how to use the enhancedGetPrice JSON-RPC method.
## Understanding `enhancedGetPrice`
* `enhancedGetPrice` retrieves the real-time price (fiat exchange rate) of a Solana token (SPL token). It takes:
* `address` - array of strings. This represents the SPL token address; for \$SOL, you can use the string `native`.
* `currencies` - array of strings. It can contain `usd` and `cny`.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/solana', {
chainId: 103,
jsonrpc: '2.0',
id: 0,
method: 'enhancedGetPrice',
params: [
[
'native',
'2Dzzc14S1D7cEFGJyMZMACuoQRHVUYFhVE74C5o8Fwau',
],
[
'usd',
'cny',
],
],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
},
});
console.log(response.data);
})();
```
# enhancedGetTokensAndNFTs
Source: https://developers.particle.network/social-logins/api/solana/enhancedgettokensandnfts
openapi-solana POST /#enhancedGetTokensAndNFTs
Learn how to use the enhancedGetTokensAndNFTs JSON-RPC method.
## Contextualizing `enhancedGetTokensAndNFTs`
* `enhancedGetTokensAndNFTs`, like its EVM counterpart, `getTokensAndNFTs`, retrieves a detailed list of tokens and NFTs that belong to a specific address. It takes:
* `address` - a base58-encoded string.
* Object, optional:
* `parseMetadataUri` - Boolean (`false` by default).
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/solana', {
chainId: 103,
jsonrpc: '2.0',
id: 0,
method: 'enhancedGetTokensAndNFTs',
params: ['6XU36wCxWobLx5Rtsb58kmgAJKVYmMVqy4SHXxENAyAe', {
parseMetadataUri: true,
}],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# enhancedGetTransactionsByAddress
Source: https://developers.particle.network/social-logins/api/solana/enhancedgettransactionsbyaddress
openapi-solana POST /#enhancedGetTransactionsByAddress
Learn how to use the enhancedGetTransactionsByAddress JSON-RPC method.
## Understanding `enhancedGetTransactionsByAddress`
* `enhancedGetTransactionsByAddress` retrieves detailed parsed transaction history relating to a specific public address on Solana. It takes:
* `address` - a base58-encoded string.
* Object, optional:
* `limit` - integer (between `1` and `1000`, default `1000`).
* `before` - string, transaction hash.
* `after` - string, transaction hash.
* `until` - string, transaction hash.
***
## Query example
```javascript JavaScript theme={null}
const axios = require('axios');
(async () => {
const response = await axios.post('https://rpc.particle.network/solana', {
chainId: 103,
jsonrpc: '2.0',
id: 0,
method: 'enhancedGetTransactionsByAddress',
params: ['6XU36wCxWobLx5Rtsb58kmgAJKVYmMVqy4SHXxENAyAe'],
}, {
auth: {
username: 'Your Project Id',
password: 'Your Project Server Key',
}
});
console.log(response.data);
})();
```
# SDK Reference (SolanaService)
Source: https://developers.particle.network/social-logins/api/solana/solanaservice
Reference for the common SolanaService SDK extension.
Alongside the common `EvmService` SDK module, `SolanaService` enables programmatic data retrieval through Particle Network's suite of enhanced RPC endpoints. Specifically, `SolanaService` provides direct access to the endpoints listed on this document and additional SDK-exclusive methods, making it simple to work with rich data on Solana.
A full reference of each common method alongside their parameters can be found **below**.
| Class | Methods | Parameters (\* indicates optional) |
| ------------- | ----------------------------- | ---------------------------------- |
| SolanaService | rpc | method, params |
| SolanaService | getPrice | addresses, currencies |
| SolanaService | getTokensAndNFTs | address |
| SolanaService | getTransactionsByAddress | address |
| SolanaService | getTokenTransactionsByAddress | address, mintAddress |
| SolanaService | serializeSolTransaction | from, to, amount |
| SolanaService | serializeSplTokenTransaction | from, to, mint, amount |
# checkApprove
Source: https://developers.particle.network/social-logins/api/swap/checkapprove
openapi-swap POST /#particle_swap_checkApprove
Learn how to use the checkApprove JSON-RPC method.
# Contextualizing `checkApprove`
* `checkApprove` returns a Boolean based upon whether a given address has approved spending of a specified amount for a particular ERC-20 token. It takes:
* `address` - string.
* Token object, containing:
* `tokenAddress` - string.
* `amount` - string.
***
## Query example
```json JSON theme={null}
{
"id": 1,
"jsonrpc": "2.0",
"method": "particle_swap_checkApprove",
"params": [
"0x369aa8a7a7BE683E1a46d9A056806B2B3FD778C8", // wallet address
{
"tokenAddress": "0x111111111117dc0aa78b770fa6a738034120c302", // from token address
"amount": "1000000000"
}
]
}
```
# getQuote
Source: https://developers.particle.network/social-logins/api/swap/getquote
openapi-swap POST /#particle_swap_getQuote
Learn how to use the getQuote JSON-RPC method.
# Understanding `getQuote`
* `getQuote` calculates and returns the quote price for the swap (the amount of `toTokenAddress` tokens you'll receive) alongside details about the swap. It takes:
* `address` - string.
* Swap information object:
* `fromTokenAddress` - string.
* `toTokenAddress` - string.
* `amount` - string.
***
## Query example
```json JSON theme={null}
{
"id": 1,
"jsonrpc": "2.0",
"method": "particle_swap_getQuote",
"params": [
"0x369aa8a7a7BE683E1a46d9A056806B2B3FD778C8", // wallet address
{
"fromTokenAddress": "0x111111111117dc0aa78b770fa6a738034120c302",
"toTokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"amount": "1000000000"
}
]
}
```
# getSwap
Source: https://developers.particle.network/social-logins/api/swap/getswap
openapi-swap POST /#particle_swap_getSwap
Learn how to use the getSwap JSON-RPC method.
## Understanding `getSwap`
* `getSwap` returns a detailed object containing swap information, a price quote, and a complete transaction object to have the user sign for swap execution. It takes:
* `address` - string.
* Swap information object:
* `fromTokenAddress` - string.
* `toTokenAddress` - string.
* `amount` - string.
* `slippage` - integer.
***
## Query example
```json JSON theme={null}
{
"id": 1,
"jsonrpc": "2.0",
"method": "particle_swap_getSwap",
"params": [
"0x369aa8a7a7BE683E1a46d9A056806B2B3FD778C8",
{
"fromTokenAddress": "0x111111111117dc0aa78b770fa6a738034120c302",
"toTokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"amount": "1000000000",
"slippage": 1
}
]
}
```
# Introduction to Swap API
Source: https://developers.particle.network/social-logins/api/swap/introduction
Explore how you can execute swap transactions with the Swap API.
1. If you're swapping `from` an ERC-20 token, you'll need to check token approval with `checkApprove`. If approval doesn't meet your requirements for the swap, you'll need to request approval.
2. Get a quote for the swap with `getQuote`.
3. Retrieve the swap transaction object with `getSwap`.
4. Execute the swap transaction.
Native tokens, such as ETH, are represented as `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`
# Unity (C#) Desktop - Auth
Source: https://developers.particle.network/social-logins/auth/desktop-sdks/unity
Interacting with Particle Auth within games built on Unity using C#.
## Particle Auth for Unity on Windows/macOS
The **Particle Auth** [Unity SDK](https://github.com/Particle-Network/particle-unity) is the key tool for integrating Particle's **Wallet-as-a-Service** into Unity-based games.
This SDK streamlines **configuration**, **integration**, and **interaction**, making it the only library needed for most applications.
It supports end-to-end usage of Particle Network with **email**, **phone**, or **custom JWT authentication**.
While its structure is similar to the [Web (JavaScript/TypeScript)](/social-logins/auth/desktop-sdks/web) SDK, there are several key differences, **detailed below**.
Due to limitations with Webview, Particle Auth for Unity on Windows & macOS does not include most built-in social logins
Options include email, phone, and custom JWT authentication (indicated by 'email', 'phone', or 'jwt').
***
## Getting Started
To start with the **Particle Auth** **Unity** SDK on **Windows** and **macOS**, ensure you meet the prerequisites: a minimum **Unity** version and a **Unity** package for handling authentication popups.
## Prerequisites
* Unity **2021.3.35f1** or later.
* Requires one of the following packages:
* **Recommended**: 3D WebView for Windows and macOS (Web Browser) from Vuplex, version **4.3.3** or higher.
* Other web browser packages will also work here if necessary.
## Quickstart
Before diving into the specifics of SDK initialization and use, the best way to get started and explore a live implementation of the Unity SDK is through the **Windows/macOS** demo included within the [GitHub repository](https://github.com/Particle-Network/particle-unity).
This demo will consist of initializing the SDK and, as previously detailed, a Webview-based authentication menu for [MPC-TSS](/social-logins/mpc-tss) login, enabling interaction with the resulting wallet.
#### Quickstart demo installation
To start testing the included demo, download the **Windows/macOS** demo from [GitHub](https://github.com/Particle-Network/particle-unity/tree/2e08f144327a25a1f28098defa182155d120f177/Assets/ParticleNetwork/Windows).
If you've already imported the **SDK** from the [linked repository](https://github.com/Particle-Network/particle-unity), follow these steps to initialize the demo:
1. Open the Windows/macOS **Auth** demo scene in the Unity editor.
2. Click the **Particle Init** button to initialize the SDK.
3. Click **Login** to create an account instance and enable the sample functions.
## Initialization
After exploring the SDK's implementation through the **demo**, let's understand and dive into the **configuration**, which includes some structural deviations from the Web SDK.
***
### Initializing the Particle Auth SDK
1. **Create a GameObject:**
* Add a new `GameObject` to your scene.
* Attach the `ParticleSystem` script to this GameObject.
2. **Attach Canvas WebView:**
* Attach the `CanvasWebViewPrefab` to the `ParticleSystem` script.
3. **Add Particle Unity RPC:**
* Put a `ParticleUnityRpc` prefab into your scene.
* Update the prefab with your `project id`, `app id`, and `client key`.
4. **Configure the ParticleSystem:**
* Before using the SDK, you must configure the `ParticleSystem` (similar to the `ParticleNetwork` in the Web SDK).
* Execute this configuration by calling the `Init` method on `ParticleSystem.Instance` with the following parameters:
* **`config`**: Includes `ParticleConfigSecurityAccount` and `ParticleConfigWallet`.
* **`theme`**: Controls the theme settings such as dark or light mode, whether to display the wallet or show the close button.
* **`language`**: A string indicating the UI language, options include 'en-US', 'zh-CN', 'zh-TW', 'ja-JP', or 'ko-KR'.
* **`chainInfo`**: An object that specifies the primary blockchain to be used.
```csharp C# theme={null}
var supportChains = new List
{ new SupportChain(ChainInfo.EthereumSepolia.Name, ChainInfo.EthereumSepolia.Id) };
var config = new ParticleConfig(new ParticleConfigSecurityAccount(1, 1),
new ParticleConfigWallet(true, supportChains, null));
var theme = new ParticleTheme
{
UiMode = "dark",
DisplayWallet = true,
DisplayCloseButton = true
};
var language = "en-US";
var chainInfo = ChainInfo.EthereumSepolia;
ParticleSystem.Instance.Init(config.ToString(), theme.ToString(), language, chainInfo);
```
Among these parameters, the `ParticleUnityRpc` prefab containing `project id`, `app id` and `client key` are the most important. It directly connects your instance of Particle's Wallet-as-a-Service with your configurations in the [Particle dashboard](https://dashboard.particle.network/).
Find a full rundown on how to set up a project and find the required keys in the [Dashboard Guide ](/social-logins/dashboard).
### Examples of utilization
#### Login
`ParticleSystem.Instance.Login` displays the login popup, set to 'email', 'phone', or custom JWT authentication with 'jwt'.
This popup acts as the **primary mechanism** for facilitating account creation.
```csharp C# theme={null}
// PreferredAuthType: email, phone, or jwt
// Account: Required when using jwt
var loginResult = await ParticleSystem.Instance.Login(PreferredAuthType.email, "");
Debug.Log($"Login result {loginResult}"); // Contains user information
```
#### SignMessage
`ParticleSystem.Instance.SignMessage` enables the signing of a basic string.
This can be passed directly within `SignMessage` for **EVM** chains, as shown below.
For **Solana**, you'll need to convert this string to base58 before `SignMessage` will function properly. The confirmation popup will display this string, base58 or otherwise, in UTF-8.
```csharp C# theme={null}
var signature = await ParticleSystem.Instance.SignMessage("GM, Particle!");
Debug.Log($"SignMessage signature: {signature}");
```
#### SignAndSendTransaction
The `ParticleSystem.Instance.SignAndSendTransaction` method takes a transaction object constructed by `ParticleSystem.Instance.MakeEvmTransaction` (for EVM chains). It then prompts the user for confirmation (signature).
Once the user confirms, the transaction will be sent.
```csharp C# theme={null}
var transaction = ParticleSystem.Instance.MakeEvmTransaction("0x16380a03f21e5a5e339c15ba8ebe581d194e0db3", "0xA719d8C4C94C1a877289083150f8AB96AD0C6aa1", "0x", "0x123123");
var signMessageResult = await ParticleSystem.Instance.SignAndSendTransaction(transaction);
Debug.Log($"SignAndSendTransaction signature: {signature}");
```
#### SignTypedData
`ParticleSystem.Instance.SignTypedData` facilitates the signature of structured data; by default, this uses `eth_signTypedData_v4`.
For more information on `signTypedData`, see the [Web (JavaScript/TypeScript)](/social-logins/auth/desktop-sdks/web) page.
```csharp C# theme={null}
string typedDataV4 = "";
var signMessageResult = await ParticleSystem.Instance.SignTypedData(typedDataV4, SignTypedDataVersion.Default);
Debug.Log($"SignTypedData signature: {signature}");
```
#### SignTransaction
`ParticleSystem.Instance.SignTransaction` is a **Solana-specific** method for requesting a signature for a given transaction.
This will sign (but not send) a transaction.
```csharp C# theme={null}
string transaction = "";
var signMessageResult = await ParticleSystem.Instance.SignTransaction(transaction);
Debug.Log($"SignTransaction signature: {signature}");
```
#### SignAllTransactions
`ParticleSystem.Instance.SignAllTransactions` is the plural of those mentioned above; this is also \**Solana-specific*
```csharp C# theme={null}
List transactions = new List { "" }; // base58 strings
var signMessageResult = await ParticleSystem.Instance.SignAllTransactions(transactions);
Debug.Log($"SignAllTransactions signature: {string.Join(", ", signatureList)}");
```
#### OpenWebWallet
`ParticleSystem.Instance.OpenWebWallet` can open the web wallet.
```csharp C# theme={null}
ParticleSystem.Instance.OpenWebWallet();
// If you prefer to open wallet with a smart account selected, you can pass the account name, such as
ParticleSystem.Instance.OpenWebWallet(AAAccountName.BICONOMY_V2());
```
## Master reference
Below is a table containing every relevant method provided through `ParticleSystem` alongside specific parameters and a short description for a direct, raw view.
For methods listed that needed to be covered in the above examples, live implementation often mimics the standard structure covered throughout this document.
| Class | Methods | Parameters |
| -------------- | ---------------------- | ------------------------------------------- |
| ParticleSystem | Init | config, theme, language, chainName, chainId |
| ParticleSystem | Login | preferredAuthType, account |
| ParticleSystem | SignMessage | message |
| ParticleSystem | SignAndSendTransaction | transaction |
| ParticleSystem | SignTypedData | message, version |
| ParticleSystem | SignTransaction | transaction |
| ParticleSystem | SignAllTransactions | transactions |
| ParticleSystem | MakeEvmTransaction | from, to, data, value |
| ParticleSystem | UpdateChainId | chainId |
| ParticleSystem | UpdateChainName | chainName |
# Web (JavaScript/TypeScript) - Auth
Source: https://developers.particle.network/social-logins/auth/desktop-sdks/web
Interacting with Particle Auth within web applications using either JavaScript or TypeScript.
# Particle Auth for Web Applications
Among all the SDKs for **Particle Auth**, the Web SDK (`@particle-network/authkit`) is the most widely used. Thus, it offers extensive **support** and **flexibility** in driving onboarding through social logins, facilitating interaction with Particle's Wallet-as-a-Service.
The Particle Auth SDK is the primary mechanism for **configuring** and **using** social logins. **Whether you're starting from scratch** or **already have an onboarding or authentication flow** set up within your application, the Particle Auth Core Web SDK is a simple yet powerful integration.
***
## Getting Started
Check out the [Web Quickstart guide](/social-logins/auth/quickstart/web-quickstart) and get a new project up
and running in just 5 minutes.
To get started with the Particle Auth Web SDK, you can add `@particle-network/authkit` to your project using either of the two following mechanisms:
```shell Install theme={null}
npm install @particle-network/authkit viem@2
yarn add @particle-network/authkit viem@2
```
***
## Configuration
Configuration is primarily handled by wrapping an application with **Particle Auth**'s master configuration component, essential for authenticating your project and [customizing the optional embedded wallet modal](/social-logins/configuration/appearance/wallet).
No matter which **Particle Auth** SDK you're using, you must define your `projectId`, `clientKey`, and `appId` within this configuration object to authenticate your Particle Auth instance properly. Additionally, [you can apply customizations to the wallet modal](/social-logins/configuration/appearance/wallet) for a tailored user experience.
Follow the quickstart tutorial to set up a project and find the required keys: [Create a new
project](/social-logins/auth/quickstart/web-quickstart#configuring-particle-auth).
Below is an example of an `index.tsx` file from a `create-react-app` project. In this example, the `AuthCoreContextProvider` component acts as the configuration wrapper for the entire application.
```typescript @particle-network/authkit theme={null}
import React from 'react'
import ReactDOM from 'react-dom/client'
import { AuthType } from '@particle-network/auth-core';
import { AuthCoreContextProvider, PromptSettingType } from '@particle-network/authkit';
import { mainnet } from '@particle-network/authkit/chains';
import App from './App'
import('buffer').then(({ Buffer }) => {
window.Buffer = Buffer;
});
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
)
```
Learn how to customize the aesthetics of the login and embedded wallet interface in the [Customizing Login
Modal](/social-logins/configuration/appearance/auth) and [Customizing Wallet
Modal](/social-logins/configuration/appearance/wallet) pages.
When using a framework that supports React Server Components, you must include the `"use client"` directive
at the beginning of the file.
***
# Interaction with Web3
Now that you've configured an instance of **Particle Auth**, it's time to leverage Particle to facilitate **social logins** and interactions with **Web3**.
To begin, you'll need to choose between the following interaction mechanisms:
1. **Ethers.js**.
2. **viem**.
3. **Particle native**.
They all achieve the same end goal of facilitating interaction with Web3, although they will result in a slightly different initialization process.
If you've chosen **Particle native**, no initialization of this nature is needed past configuring `AuthCoreContextProvider` or `ParticleNetwork`.
```typescript Ethers.js V5 theme={null}
import { ethers } from "ethers";
import { useEthereum } from '@particle-network/authkit';
const { provider } = useEthereum();
const ethersProvider = new ethers.providers.Web3Provider(provider, "any");
```
```typescript Ethers.js V6 theme={null}
import { ethers, Eip1193Provider } from "ethers";
import { useEthereum } from '@particle-network/authkit';
const { provider } = useEthereum();
const ethersProvider = new ethers.BrowserProvider(
provider as Eip1193Provider,
"any"
);
```
```typescript viem theme={null}
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains
import { useEthereum } from '@particle-network/authkit';
const { provider } = useEthereum();
const viemProvider = createWalletClient({
chain: mainnet,
transport: custom(provider)
})
```
You can now use the **provider** object to interact with **Web3**, enabling actions like fetching account balances or sending transactions.
***
## Initiating Social Login
To interact with a user's account (wallet), they must first log in using **Particle Auth** or [Particle Connect](/social-logins/connect/desktop/web), similar to how one would enter a password and unlock MetaMask.
Before interactions can occur, the application must either recognize that the user is already logged in or prompt them to complete the login process.
You can use the `connect` and `connected` functions from the `useConnect()` hook to handle the connection logic:
```typescript theme={null}
import { useConnect } from '@particle-network/authkit';
const { connect, disconnect, connected } = useConnect();
// Handle user login
const handleLogin = async () => {
if (!connected) {
await connect({});
}
};
// Logout user
const handleLogout = async () => {
await disconnect();
};
```
In this example, the `handleLogin` function initiates the login process by displaying the login modal if the `connected` status is `false`, indicating that the user is not currently logged in.
### Customize the Login Experience
You can set specific configurations within the `connect()` function to further tailor the **login** experience beyond [frontend customizations](/social-logins/configuration/appearance/auth).
The following example showcases all available configuration options:
```typescript TypeScript theme={null}
'use client';
import { useConnect } from '@particle-network/authkit';
const { connect, disconnect, connected } = useConnect();
const useInfo = await connect({
// socialType, if set, will skip the auth modal shown above and will instead automatically redirect to a chosen social login
// 'email' | 'phone' | 'google' | 'apple' | 'twitter' | 'facebook' | 'microsoft' | 'linkedin' | 'github' | 'twitch' | 'discord'
socialType: 'google',
phone: '+1xxxxxxxx', // Optional, E.164 format
code: 'xxxxxx', // Optional
authorization: {
uniq: true, // Optional: Defaults to false
message: 'base58 string', // Signature message in hex or base58 for Solana
},
});
```
`web3.eth.getAccounts` will also initiate login automatically if a user isn't already logged in.
***
#### Log in with a Specific Social Platform
You can streamline the login process by bypassing the standard login modal and directing users to log in with a specific social platform.
The following example shows how to automatically prompt users to log in with their Google account, skipping the login modal entirely:
```tsx App.tsx theme={null}
'use client';
import { useConnect } from '@particle-network/authkit';
const { connect, disconnect, connected } = useConnect();
// Handle user login
const handleLogin = async () => {
if (!connected) {
await connect({
socialType: 'google',
});
}
};
```
#### Customizing the Email Login Flow
By default, **Particle Auth** supports email login with an **OTP** (One Time Password) flow through the login modal. However, you can build a custom UI to request and validate OTPs directly, allowing for greater flexibility and control over the authentication experience.
`@particle-network/auth-core` is already included as a dependency in `@particle-network/authkit`, so you don’t need to install it separately.
**Step 1: Request an OTP**
Use the `getConnectCaptcha()` function from `@particle-network/auth-core` to send an **OTP** to the user’s email.
```tsx page.tsx theme={null}
import { getConnectCaptcha } from "@particle-network/auth-core";
// Send an OTP to the email
const sendOtpRequest = async (email) => {
const success = await getConnectCaptcha({ email });
console.log(success ? "OTP sent successfully!" : "Failed to request OTP. Try again.");
};
```
**Step 2: Verify OTP & Log In**
Once the user receives the OTP, use the `connect()` function, including OTP and email within `loginParams`, to verify it and complete the login.
```tsx page.tsx theme={null}
import { ConnectWithEmailParam } from "@particle-network/auth-core";
// Verify the OTP and log in
const verifyOtp = async (email, otp) => {
const loginParams: ConnectWithEmailParam = { email, code: otp };
await connect(loginParams);
console.log("Login successful!");
};
```
Find a complete implementation in the [Particle Auth Custom Email Login repository](https://github.com/Particle-Network/particle-auth-custom-email-otp-demo).
#### Login with JWT
You can use your existing user base or authentication method with Particle Auth through JWT. This way, your users can still log in with their current accounts.
We only support RS256 now, [Example](https://dev-qr6-59ee.us.auth0.com/.well-known/jwks.json).
Before connecting, you must set your custom JWT configuration on the [Dashboard](https://dashboard.particle.network).
Then, you can refer to the code below to log in using JWT.
```typescript TypeScript theme={null}
'use client';
import { useConnect } from '@particle-network/authkit';
const { connect, disconnect, connected } = useConnect();
// connect with JWT
const userInfo = await connect({
provider: 'jwt',
thirdpartyCode: 'xxxxxxxxxx', // If applicable, JWT value
});
```
Learn more about [Custom Authentication](/social-logins/configuration/auth/jwt).
### Verify User Login Status
The `useConnect()` hook provides several functions to check the user's connection status:
* `connected` — Returns a boolean value indicating whether the user is logged in (`true`) or not (`false`). This is useful for managing login logic.
* `connectionStatus` — Returns a string representing the current stage of the user's flow:
* `loading`
* `connecting`
* `connected`
* `disconnected`
You can use `connectionStatus` to manage login logic or to display relevant status information in the UI.
```tsx page.tsx theme={null}
import { useConnect } from '@particle-network/authkit';
const { connectionStatus } = useConnect();
{/* Status changes are automatically handled*/}
Status: {connectionStatus}
;
```
### Handling User Information
Once the user is logged in, the `userInfo` object from the `useAuthCore()` hook becomes available.
The result of `connect()` will return the same object.
For example, you can use it to display the user's `name` and `avatar`, or access security details such as `has_set_master_password`.
This allows you to implement logic that prompts the user to set a master password if they haven’t already done so, thereby improving security.
* **uuid**: Unique identifier for the user.
* **created\_at**: Timestamp of when the user account was created.
* **updated\_at**: Timestamp of the last update to the user account.
* **phone**: User's phone number (if available).
* **email**: User's email address (if available).
* **apple\_email**: Email associated with Apple ID (if available).
* **apple\_id**: Apple ID (if available).
* **avatar**: URL to the user’s avatar image.
* **discord\_email**: Email associated with Discord (if available).
* **discord\_id**: Discord ID (if available).
* **facebook\_email**: Email associated with Facebook (if available).
* **facebook\_id**: Facebook ID (if available).
* **github\_email**: Email associated with GitHub (if available).
* **github\_id**: GitHub ID (if available).
* **google\_email**: Email associated with Google.
* **google\_id**: Google ID.
* **jwt\_id**: JSON Web Token ID (if available).
* **linkedin\_email**: Email associated with LinkedIn (if available).
* **linkedin\_id**: LinkedIn ID (if available).
* **microsoft\_email**: Email associated with Microsoft (if available).
* **microsoft\_id**: Microsoft ID (if available).
* **name**: Full name of the user.
* **passkeys\_id**: Passkeys ID (if available).
* **security\_account**: Object containing security-related fields:
* **has\_set\_master\_password**: Boolean indicating if a master password is set.
* **has\_set\_payment\_password**: Boolean indicating if a payment password is set.
* **payment\_password\_updated\_at**: Timestamp of the last update to the payment password.
* **telegram\_id**: Telegram ID (if available).
* **telegram\_phone**: Phone number associated with Telegram (if available).
* **thirdparty\_user\_info**: Object containing third-party authentication info:
* **provider**: Name of the third-party provider (e.g., "Google").
* **user\_info**: Object with detailed user information:
* **email**: Email used with the third-party provider.
* **id**: User ID associated with the third-party provider.
* **name**: Name associated with the third-party provider.
* **picture**: URL to the user’s profile picture from the third-party provider.
* **token**: Token used for authentication.
* **twitch\_email**: Email associated with Twitch (if available).
* **twitch\_id**: Twitch ID (if available).
* **twitter\_email**: Email associated with Twitter (if available).
* **twitter\_id**: Twitter ID (if available).
* **wallets**: Array of wallet objects:
* **uuid**: Unique identifier for the wallet.
* **chain\_name**: Name of the blockchain associated with the wallet (e.g., "evm\_chain", "solana").
The following is an example of how you can render user information taken from `userInfo`:
```tsx App.tsx theme={null}
const { userInfo } = useAuthCore();
// Or
// const userInfo = await connect();
{
userInfo && (
{/*
In this card, we display info from Particle Auth
*/}
Accounts info
Name: {userInfo.name}
);
}
```
***
## Retrieving the Public Address
To retrieve the public address linked to a user's account, when it's not already obtained through the login via `userInfo`, you can use the following method:
```typescript Ethers.js V6 theme={null}
import { ethers } from "ethers";
import { useEthereum } from '@particle-network/authkit';
const { provider } = useEthereum();
// Assuming Ethers is not already initialized
const ethersProvider = new ethers.BrowserProvider(
provider as Eip1193Provider,
"any"
);
const accounts = await ethersProvider.listAccounts();
const address = accounts[0].address;
// Or
const signer = await ethersProvider.getSigner();
const address = await signer.getAddress();
```
```typescript Ethers.js V5 theme={null}
import { ethers } from "ethers";
import { useEthereum } from '@particle-network/authkit';
const { provider } = useEthereum();
const ethersProvider = new ethers.providers.Web3Provider(provider, "any");
// Assuming Ethers is not already initialized
const accounts = await ethersProvider.listAccounts();
const address = accounts[0].address;
```
```typescript Particle (EVM) theme={null}
import { useEthereum } from '@particle-network/authkit';
// After configuring AuthCoreContextProvider and logging in
const { address, provider } = useEthereum();
// Or, alternatively, send a JSON-RPC request to the provider
const accounts = await provider.request({ method: 'eth_accounts' });
```
```typescript Particle (Solana) theme={null}
import { useSolana } from '@particle-network/authkit';
// After configuring AuthCoreContextProvider and logging in
const { address } = useSolana();
```
***
## Sending Transactions
Sending transactions using **Particle** as the Signer/underlying wallet is also quite simple.
If you're using **Ethers.js**, you're already set —as long as a user has logged in with Particle, transactions can be sent as you would with any other wallet.
When a given transaction is sent, and a signature is needed for authentication, a standard confirmation popup (also customizable through the Particle dashboard) will appear directly within the application. Transactions can be sent through the following:
```typescript Ethers.js theme={null}
const signer = ethersProvider.getSigner();
const executeTx = async () => {
const signer = await ethersProvider.getSigner();
const tx = {
to: recipientAddress,
value: ethers.parseEther("0.01"),
data: "0x",
};
const txResponse = await signer.sendTransaction(tx);
const txReceipt = await txResponse.wait();
// You can log or handle the receipt here
console.log(txReceipt);
};
```
```typescript Particle (EVM) theme={null}
// After configuring AuthCoreContextProvider and logging in
import { useEthereum } from '@particle-network/authkit';
const { sendTransaction } = useEthereum();
const txnHash = await sendTransaction(txnParams);
```
```typescript Particle (Solana) theme={null}
import { useSolana } from '@particle-network/authkit';
// After configuring AuthCoreContextProvider and logging in
const { signAndSendTransaction } = useSolana();
const result = await signAndSendTransaction(transaction);
```
To the end-user, sending transactions, regardless of the chosen method, looks like this (depending on
customization outlined in the [Particle dashboard](https://dashboard.particle.network/)).
***
## Data Signing
In cases where you'd like to sign either a raw string (personal) or typed data (`eth_signTypedData`), the process is quite straightforward.
You can accomplish this using standard libraries like **Ethers** or leveraging **Particle’s** native functionality. The examples below illustrate both approaches.
For instance, when sending transactions, the signatures are automatically formatted and presented to the user in a popup request. This ensures a user-friendly experience by displaying the relevant data in UTF-8 format.
### Personal Signatures
```typescript Particle (EVM) theme={null}
const msg = 'GM, Particle!';
// After configuring AuthCoreContextProvider and logging in
const { signMessage } = useEthereum();
const result = await signMessage(msg);
```
```typescript Particle (Solana) theme={null}
import { useSolana } from '@particle-network/authkit';
// After configuring AuthCoreContextProvider and logging in
const { signMessage } = useSolana();
const result = await signMessage('base58 string');
```
```typescript Ethers.js theme={null}
const msg = 'GM, Particle!';
const signer = ethersProvider.getSigner();
const accounts = await signer.getAddress();
signer
.signMessage(msg)
.then((result) => {
console.log('personal_sign', result);
})
.catch((error) => {
console.error('personal_sign', error);
});
```
### Sign Typed Data
```typescript Particle (EVM) theme={null}
// Placeholder data
const msg = { ... };
// After configuring AuthCoreContextProvider and logging in
const { signTypedData } = useEthereum();
const result = await signTypedData({ data: msg, version: 'V4' });
```
***
## Enabling Blind Signatures
To enable blind signatures (signing without a confirmation popup) in Particle Auth, certain conditions must be met when configuring the `AuthCoreContextProvider` component and setting up the authentication flow.
1. **Master Password Requirement**
* Users must either:
* Have entered the master password, or
* Not have set a master password in the first place.
2. **No Payment Password**
* Users should not have set a payment password (as this interrupts the signing process).
3. **Disable Payment Password Prompt Setting**
* Set the `promptPaymentPasswordSettingWhenSign` parameter to `false` within [`AuthCoreContextProvider`](/social-logins/auth/desktop-sdks/web#configuration).
```typescript theme={null}
// Configuration for disabling payment password prompt
promptSettingConfig = {
promptPaymentPasswordSettingWhenSign: false,
};
```
When these conditions are satisfied, blind signing is enabled.
***
## Particle Native Hooks
Below is a collection of examples describing the different hooks available with **Particle Auth**.
These hooks facilitate social login and native application-level interaction (such as message signing, sending transactions, etc.) directly through **Particle Auth**.
### useConnect
`useConnect` acts as the primary hook for facilitating login (connection) with **Particle Auth**.
```typescript TypeScript theme={null}
import { useConnect } from '@particle-network/authkit';
const { connect, disconnect, connected, connectionStatus, requestConnectCaptcha, setSocialConnectCallback } =
useConnect();
const userInfo = await connect();
const isLoggedIn = connected;
await disconnect();
```
### useEthereum
`useEthereum` provides direct interaction with a given **EVM** chain as an alternative to a traditional library such as **ethers**.
```typescript TypeScript theme={null}
const {
provider, // EIP1193 provider
address, // EVM public address
chainId, // Current chain
chainInfo,
switchChain,
signMessage,
signTypedData,
sendTransaction,
enable,
} = useEthereum();
const txHash = await sendTransaction({
to: '0xe8fc0baE43aA264064199dd494d0f6630E692e73',
value: '1000000',
});
const signature = await signMessage(message);
const signature = await signTypedData(typedData);
await switchChain('0x1'); // Also takes a standard number
```
### useSolana
`useSolana` is one of the primary ways to use **Solana** with **Particle Auth** if you aren't using an external connection modal such as `wallet-adapter`.
```typescript TypeScript theme={null}
import { useSolana } from '@particle-network/authkit';
const {
address, // Solana public address
chainId, // Current chain (Mainnet, Testnet, Devnet)
chainInfo,
switchChain,
signMessage,
signTransaction,
signAllTransactions,
signAndSendTransaction,
enable,
} = useSolana();
const txHash = await signAndSendTransaction(txData);
const signature = await signMessage(message);
```
### useAuthCore
`useAuthCore` provides additional functionality, such as retrieving `userInfo` after login, forcing different account menus to open, accessing the on-ramp page, and more.
```typescript TypeScript theme={null}
import { useAuthCore } from '@particle-network/authkit';
const {
userInfo, // Standard user info, null is returned if not connected
needRestoreWallet, // Whether or not a master password is needed from the current user
openAccountAndSecurity, // Opens account and security modal
openSetMasterPassword, // Opens set master password modal
openChangeMasterPassword, // Opens change master password modal
openRestoreByMasterPassword, // Opens input master password modal
openSetPaymentPassword, // Opens set payment password modal
openChangePaymentPassword, // Opens change payment password modal
openSetSecurityAccount, // Opens set security account modal
openLinkLoginAccount, // Opens link login account modal
openWallet, // Opens wallet in iframe
getWalletIFrame, // Manages the embedded wallet modal, used for opening the wallet modal in a custom iframe
openBuy, // Opens the onramp aggregation page
} = useAuthCore();
```
### useCustomize
`useCustomize` provides several methods for customizing the wallet modal, such as changing the theme type (light or dark), creating a custom style, changing the language, and more.
```typescript TypeScript theme={null}
import { useCustomize } from '@particle-network/authkit';
const {
setThemeType, // Sets theme type, 'light' or 'dark'
setCustomStyle, // Sets custom modal styles
setWalletOptions, // Sets wallet modal options
setLanguage, // Sets language being used
setFiatCoin, // Sets fiat coin being used
setERC4337, // Sets whether the modal has ERC-4337 enabled
} = useCustomize();
```
# Particle Auth FAQ
Source: https://developers.particle.network/social-logins/auth/faq
Find Frequently Asked Questions about Particle Auth.
**Answer:** Due to the unique characteristics of Multi-Party Computation (MPC), the signature result for the same message can vary each time, unlike traditional private key wallets such as MetaMask.
To address scenarios requiring a consistent signature result, we provide the `uniq` parameter. This parameter ensures that the signature remains consistent every time you sign the same message.
```tsx App.tsx theme={null}
// Sign a message with the uniq flag
const result = await signMessage(message, true);
```
**Answer:** Currently, silent login and signing are not directly supported. However, this functionality can be achieved using the following approaches:
1. **[Session Keys](https://your-link-to-guides/integrations/aa/keys#implementing-session-keys)** with Biconomy V2:
Session keys enable silent signing by creating temporary keys with limited permissions and expiration, allowing you to bypass frequent authentication popups.
2. **Enabling Blind Signatures with Particle Auth:**
Blind signing (signing without a confirmation popup) is possible in Particle Auth if specific conditions are met:
* **Authentication Method:** The user must be authenticated via JWT or Telegram.
* **Master Password Requirement:**
* The user has entered their master password, or
* The user has not set a master password.
* **No Payment Password:** The user has not set a payment password.
* **Disable Payment Password Prompt:** Configure `AuthCoreContextProvider` with the parameter `promptPaymentPasswordSettingWhenSign` set to `false`.
```javascript theme={null}
// Configuration for disabling payment password prompt
const promptSettingConfig = {
promptPaymentPasswordSettingWhenSign: false,
};
```
When these conditions are satisfied, blind signing is enabled.
**Answer:** When you retrieve `UserInfo`, either through the `connect` method or via the `userInfo` object from `useAuthCore`, a field provide the relevant information:
* **Account Creation:** The `created_at` field indicates the timestamp when the account was created.
Find more about Handling User Information in the [Particle Auth SDK](/social-logins/auth/desktop-sdks/web#handling-user-information) page.
**Answer:** The `userInfo` object contains a `security_account` property, which includes two fields:
* `has_set_master_password`: Indicates if the master password is set.
* `has_set_payment_password`: Indicates if the payment password is set.
Find more about Handling User Information in the [Particle Auth SDK](/social-logins/auth/desktop-sdks/web#handling-user-information) page.
**Answer:** This issue typically occurs when using Google login within a WebView environment.
* [Google Support](https://support.google.com/accounts/answer/12917337?hl=en#zippy=%2Cdisallowed-useragent).
**Answer:** Our team needs to implement support for integrating a new EVM chain on our platform. Once we have added support for the chain, developers can use it within their applications.
Please [contact us](https://t.me/particle_developer_bot) to discuss potential integration.
**Answer:** The `chain_name` values returned by the backend API include `evm_chain` and `solana`. Additionally, for Tron, the `chain_name` is also represented as `evm_chain`.
These values indicate the blockchain network associated with the account.
**Answer:** When using `create-react-app` version 5 or above, you might encounter issues due to the lack of NodeJS polyfills, which are no longer included by default. To fix this, you can use `react-app-rewired` and install the necessary polyfill modules.
* **Step 1:** After creating a new application with `CRA`, install `react-app-rewired` and the required polyfill packages.
If you're using Yarn:
```sh theme={null}
yarn add --dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process vm-browserify browserify-zlib
```
If you're using NPM:
```sh theme={null}
npm install --save-dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process vm-browserify browserify-zlib
```
* **Step 2:** Create a `config-overrides.js` file in the root of your project and add the necessary configuration to include the missing polyfills. This file will override the default Webpack configuration provided by `create-react-app`.
```js config-overrides.js theme={null}
const webpack = require('webpack');
module.exports = function override(config) {
const fallback = config.resolve.fallback || {};
Object.assign(fallback, {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
assert: require.resolve('assert'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
os: require.resolve('os-browserify'),
url: require.resolve('url'),
zlib: require.resolve('browserify-zlib'),
process: require.resolve('process/browser'),
});
config.resolve.fallback = fallback;
config.plugins = (config.plugins || []).concat([
new webpack.ProvidePlugin({
process: 'process/browser.js',
Buffer: ['buffer', 'Buffer'],
}),
]);
config.module.rules = config.module.rules.map((rule) => {
if (rule.oneOf instanceof Array) {
rule.oneOf[rule.oneOf.length - 1].exclude = [
/\.(js|mjs|jsx|cjs|ts|tsx)$/,
/\.html$/,
/\.json$/,
];
}
return rule;
});
return config;
};
```
* **Step 3:** Modify the `scripts` section in your `package.json` to use `react-app-rewired` instead of the default `react-scripts`:
```json theme={null}
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
```
After making these changes, your React application should build successfully without encountering NodeJS polyfill errors.
**Answer:** If you're encountering the error `"Cannot read properties of undefined (reading '__wbindgen_add_to_stack_pointer')"` in your React app using Vite, it likely relates to issues with loading a WebAssembly (Wasm) module.
To resolve this, you can use the Particle Network WASM plugin with a customized Vite configuration. Here's how to set it up:
1. **Install the Vite Plugin:** Ensure you have the necessary WASM files and the plugin configured.
```sh Terminal theme={null}
npm i @vitejs/plugin-react
```
2. **Update your `vite.config.ts`:** Add the following configuration to correctly handle the WebAssembly module in development mode:
```ts vite.config.ts theme={null}
import { defineConfig, Plugin, ConfigEnv } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'fs';
import path from 'path';
const particleWasmPlugin: Plugin | undefined = {
name: 'particle-wasm',
apply: (_, env: ConfigEnv) => {
return env.mode === 'development';
},
buildStart: () => {
const copiedPath = path.join(
__dirname,
'node_modules/@particle-network/thresh-sig/wasm/thresh_sig_wasm_bg.wasm'
);
const dir = path.join(__dirname, 'node_modules/.vite/wasm');
const resultPath = path.join(dir, 'thresh_sig_wasm_bg.wasm');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.copyFileSync(copiedPath, resultPath);
},
};
export default defineConfig({
plugins: [react(), particleWasmPlugin],
server: {
host: '0.0.0.0',
},
define: {
'process.env': process.env
},
build: {
target: 'esnext', // you can also use 'es2020' here
},
optimizeDeps: {
esbuildOptions: {
target: 'esnext', // you can also use 'es2020' here
},
},
});
```
This configuration helps ensure that the WebAssembly module is correctly copied and accessible during development, preventing the `__wbindgen_add_to_stack_pointer` error from occurring.
**Still need help?**
[Open a ticket](https://t.me/particle_developer_bot) with Particle's Developer Relations team through the dedicated Telegram support bot.
# Introduction to Particle Auth
Source: https://developers.particle.network/social-logins/auth/introduction
Particle Auth acts as the core authentication and interaction component within Particle WaaS, powering wallet creation and management via social logins.
***
## Particle Auth the core component of Particle WaaS
**Particle Auth** is the core SDK for **wallet creation** and **account interaction**, powered by Particle’s Wallet-as-a-Service.
It supports **social logins** out of the box and gives you **full control over the UI and user flow** for a branded onboarding experience.
Do you want to include Account Abstraction features? Check out the Account Abstraction section.
### Get Started
The SDK is available on **web, desktop, and mobile**, with support across major platforms.
***
Interacting with Particle Auth within web applications using either JavaScript or TypeScript.
Interacting with Particle Auth within Desktop games made on Unity using C#.
Interacting with Particle Auth within Mobile games made on Unity using C#.
Interacting with Particle Auth on Android using Kotlin.
Interacting with Particle Auth on iOS using Swift or Objective-C.
Interacting with Particle Auth within applications made using Flutter.
Interacting with Particle Auth within applications made using React Native.
Interacting with Particle Auth within applications made using Unreal Engine.
Interacting with Particle Auth within applications made using Cocos.
# Android (Kotlin) SDK - Auth
Source: https://developers.particle.network/social-logins/auth/mobile-sdks/android
Interacting with Particle Auth on Android using Kotlin.
# Particle Auth for Android
The **Particle Auth Android SDK** is the flagship mechanism for integrating Particle's Wallet-as-a-Service within Android applications. This SDK is the sole facilitator of Android integration for most applications and is built for simplicity.
As with the other **Particle Auth** SDKs, it requires only a few lines of code.
Unlike the Unity SDK and Web SDK, the Android SDK differs in installation and configuration; these specific intricacies and setup processes are detailed below.
***
## Getting Started
Using the **Particle Auth Android SDK** is straightforward but requires meeting a few minimum version prerequisites to ensure compatibility.
### Prerequisites
* minSdkVersion **23** or higher.
* compileSdkVersion, targetSdkVersion **34** or higher.
* JavaVersion **17**.
* [Jetpack (AndroidX)](https://developer.android.com/jetpack/androidx/migrate?authuser=0).
* Android Gradle Plugin Version: **8.5.1** or higher.
* Gradle Version: **8.9** or higher.
### Configuration
Before you begin using the **Particle Auth Android SDK**, you'll need a few required universal values across all **Particle Auth** SDKs.
These values are `projectId`, `clientKey`, and `appId`. All three can be retrieved by heading to the [Particle dashboard](https://dashboard.particle.network).
Find a full rundown in the [Dashboard Guide](/social-logins/dashboard).
### Installation
Once you've created a project and application on the **Particle Dashboard**, you can install and initialize `ParticleNetwork`.
Start by declaring the Particle Auth SDK in your Gradle file.
```kotlin Kotlin theme={null}
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") }
//...
}
dependencies {
modules {
module("org.bouncycastle:bcprov-jdk15to18") {
replacedBy("org.bouncycastle:bcprov-jdk15on")
}
module("org.bouncycastle:bcprov-jdk18on") {
replacedBy("org.bouncycastle:bcprov-jdk15on")
}
}
implementation("network.particle:auth-core:${latest_version}")
// Find the latest version of the SDK:
// https://search.maven.org/search?q=g:network.particle
}
```
For release updates, subscribe to the [GitHub
repository](https://github.com/Particle-Network/particle-android).
Additionally, you'll need to declare specific configurations, such as inserting values above `projectId`, `clientKey`, and `appId` within the relevant `AndroidManifest.xml` file.
An example of such a configuration is attached below. Placeholders such as `pn_project_id` will need to be filled in.
```xml XML theme={null}
```
***
## Examples of utilization
### Initialize the SDK
Upon application startup, `ParticleNetwork` must be initialized to function correctly.
This can be done by calling the `init` method on `ParticleNetwork` and passing in the primary chain you intend to use within your application.
```kotlin Kotlin theme={null}
class App : Application() {
override fun onCreate() {
super.onCreate()
// Initialize Particle Auth SDK for Ethereum
ParticleNetwork.init(this, Env.PRODUCTION, Ethereum)
// If you're using Solana, initialization looks like this
ParticleNetwork.init(this, Env.PRODUCTION, Solana)
}
}
```
### Switch Chain
To switch the chain after the initial configuration, use `AuthCore.switchChain`. This allows for asynchronous switching, just like the initial setup.
```kotlin Kotlin theme={null}
val chainInfo = ChainInfo.Polygon
AuthCore.switchChain(chainInfo, callback)
// For switching chains synchronously, without checking login status
ParticleNetwork.setChainInfo(chainInfo,callback)
```
### Login
`AuthCore.connect` triggers the standard login popup, which changes based on configurations like `loginType` (similar to the Web SDK's `preferredAuthType`) and `supportAuthTypeValues`.
This popup serves as the primary method for account creation and login for existing users.
The `AuthCore.login` function accepts the following parameters:
| **Field** | **Type** | **Description** |
| ----------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| loginType | LoginType | Specifies the preferred social login method. Options include `EMAIL`, `PHONE`, `TWITTER`, `GOOGLE`, `FACEBOOK`, `APPLE`, `DISCORD`, `GITHUB`, `TWITCH`, `MICROSOFT`, `LINKEDIN`, and `JWT`. |
| account | String | The account parameter allows you to pass an expected email, phone number, or JWT. This field is optional for email and phone logins but required for `JWT`. The phone number must be in E.164 format. |
| supportLoginTypes | List`` | Defines the supported social login methods. By default, all options are supported: `EMAIL`, `PHONE`, `FACEBOOK`, `GOOGLE`, `APPLE`, `TWITTER`, `DISCORD`, `GITHUB`, `TWITCH`, `MICROSOFT`, and `LINKEDIN`. You can also specify a subset of these types if needed. |
| prompt | LoginPrompt? | Controls the prompt displayed after social login. Options are `None`, `Consent`, or `SelectAccount`. This is only supported by Google, Discord, and Microsoft. |
| loginPageConfig | LoginPageConfig? | Customizes the UI of the login page, including the project name, icon, and description. |
| loginCallback | AuthCoreServiceCallback`` | Callback triggered after the login attempt.
**Success**: Returns `UserInfo`. **Failure**: Returns `ErrorInfo`. |
| | | |
You can use your existing user base or authentication method with Particle Auth through JWT. This way, your users can still log in with their current accounts. Check [Custom Authentication (JWT)](/social-logins/configuration/auth/jwt) to learn how to configure it.
```kotlin Kotlin theme={null}
// Connect with Email or Phone
AuthCore.connect(LoginType.EMAIL, loginCallback = connectCallback)
AuthCore.connect(LoginType.PHONE, loginCallback = connectCallback)
// Connect with Google
AuthCore.connect(SocialLoginType.GOOGLE, prompt = LoginPrompt.SelectAccount,connectCallback)
// Connect with JWT
AuthCore.connect("JWT",connectCallback =connectCallback)
// Send verification code to email or phone number, the phone number must be in E.164 format.
AuthCore.sendCode(CodeReq(email = "xxx@xx.com"), callback)
AuthCore.sendCode(CodeReq(phone = "+11234567890"), callback)
// After sending the verification code, you can use the user-entered code to log in. With this approach, you can customize the UI and simply call our API for the login process.
AuthCore.connect(LoginReq(email = "xxx@xx.com", code = "Verification code received by the user"),connectCallback)
AuthCore.connect(LoginReq(phone = "+11234567890", code = "Verification code received by the user"),connectCallback)
val connectCallback = object :AuthCoreServiceCallback{
override fun success(output: UserInfo) {}
override fun failure(errMsg: ErrorInfo) {}
}
```
### UserInfo and Address Retrieval (post-login)
After a successful login, you can retrieve detailed user information by calling the following methods.
```kotlin Kotlin theme={null}
AuthCore.getUserInfo()
AuthCore.evm.getAddress()
AuthCore.solana.getAddress()
```
### Logout
`AuthCore.disconnect` logs the user out of their current session and returns them to their pre-login state.
```kotlin Kotlin theme={null}
AuthCore.disconnect(object : ResultCallback {
override fun success() {
// Handle success
}
override fun failure() {
// Handle error
}
})
```
### Is User Logged In
`AuthCore.isLogin` returns a Boolean indicating whether the user is currently logged in with Particle.
```kotlin Kotlin theme={null}
AuthCore.isConnected()
```
If the user logs in on another device, causing their token to become invalid, you can use `syncUserInfo` to synchronize the information.
```
try{
val syncUserInfoStatus = AuthCore.syncUserInfo()
}catch(e:ServerException){
//token is invalid
}
```
### Signatures
Once `ParticleNetwork` has been initialized and a user has successfully logged in, signatures can be proposed for confirmation through a pop-up.
### EVM
### Signing Messages (EIP191)
To request an **EIP191** signature from a user's embedded wallet, you can use either the `AuthCore.evm.personalSign` or `AuthCore.evm.personalSignUnique` method.
If you need the same message to return a unique signature each time, use the `AuthCore.evm.personalSignUnique` method. Otherwise, the `AuthCore.evm.personalSign`method is generally recommended.
| Field | Type | Description |
| :------------------- | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `hexUnSignedMessage` | `PrefixedHexString` | A required field that accepts either a hexadecimal string starting with '0x' or a human-readable string. |
| `callback` | `AuthCoreSignCallback` | Handles the response of the signing operation. **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
```kotlin signAndSendTransaction (Kotlin) theme={null}
AuthCore.evm.personalSign(hexUnSignedMessage: PrefixedHexString, callback)
AuthCore.evm.personalSignUnique(hexUnSignedMessage: PrefixedHexString, callback)
```
### Signing Typed Data V4 (EIP712)
To request an EIP712 signature from a user's embedded wallet, you can use either the `AuthCore.evm.signTypedData` or `AuthCore.evm.signTypedDataUnique` method.
If you need the same message to return a unique signature each time, use the `AuthCore.evm.signTypedDataUnique` method. Otherwise, the `AuthCore.evm.signTypedData` method is generally recommended.
| Field | Type | Description |
| :--------- | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `data ` | `PrefixedHexString` | A hexadecimal string that must start with "0x". |
| `callback` | AuthCoreSignCallback`` | Handles the response of the signing operation. **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
```kotlin signAndSendTransaction (Kotlin) theme={null}
AuthCore.evm.signTypedData(data: PrefixedHexString, callback)
AuthCore.evm.signTypedDataUnique(data: PrefixedHexString, callback)
```
### Transaction
To send a transaction from a user's embedded wallet, you can use `AuthCore.evm.sendTransaction`.
| Field | Type | Description |
| :------------ | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `transaction` | `PrefixedHexString` | A hexadecimal string that must start with "0x". |
| `callback` | `AuthCoreSignCallback` | Handles the response of the signing operation. **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
| `feeMode` | `FeeMode` | The mode for handling transaction fees. The default is `FeeModeNative()`. Use this field only when AA mode is enabled. |
```
AuthCore.evm.sendTransaction(transaction: PrefixedHexString, callback: AuthCoreSignCallback, feeMode: FeeMode = FeeModeNative())
```
You can create an **EVM** transaction using the `ParticleNetwork.evm.createTransaction()` method.
```
val tx = ParticleNetwork.evm.createTransaction()
val hexTx = tx.serialize()
```
### Solana
### Signing Messages
To request a signature from a user's embedded wallet, use `AuthCore.solana.signMessage`.
| Field | Type | Description |
| :--------- | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `message` | `String` | A base58-formatted string that is required for the signature request. |
| `callback` | `AuthCoreSignCallback` | Handles the response of the signing operation. **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
```swift theme={null}
val message = Base58Utils.encodeFromString("This is the message that is being signed")
AuthCore.solana.signMessage(message, chainInfo: nil)
```
***
### Transaction
To send a transaction from a user's embedded wallet, use `AuthCore.solana.signAndSendTransaction`.
| Field | Type | Description |
| :------------ | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------- |
| `transaction` | `String` | A base58-formatted string that is required for the transaction. |
| `callback` | `AuthCoreSignCallback` | Handles the response of the transaction. **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
```kotlin theme={null}
AuthCore.solana..signAndSendTransaction(transaction: Base58String, callback: AuthCoreSignCallback)
```
To sign a transaction from a user's embedded wallet, use \`\`AuthCore.solana.signTransaction\`.
| Field | Type | Description |
| :------------ | :--------------------------------- | :------------------------------------------------------------------------- |
| `transaction` | `String` | A base58-formatted string is required. |
| `callback` | `AuthCoreSignCallback` | **Success**: Returns the signature. **Failure**: Returns `ErrorInfo`. |
```kotlin theme={null}
AuthCore.solana..signTransaction(transaction: Base58String, callback: AuthCoreSignCallback)
```
To sign multiple transactions from a user's embedded wallet, use `AuthCore. Solana.signAllTransactions`.
| Field | Type | Description |
| :----------------------- | :------------------------------------ | :-------------------------------------------------------------------------- |
| `serializedTransactions` | `List` | A list of base58-formatted strings is required. |
| `callback` | `AuthCoreSignCallback` | **Success**: Returns the signatures. **Failure**: Returns `ErrorInfo`. |
```swift theme={null}
AuthCore.solana.signAllTransactions(transaction: Base58String, callback: AuthCoreSignCallback)
```
### Open Account and Security
If you want to force the "Account and Security" options to open on-screen—where you can manage master passwords, payment passwords, additional accounts, and more—call `AuthCore.openAccountAndSecurity`.
```kotlin Kotlin theme={null}
AuthCore.openAccountAndSecurity()
```
### Set Security Account Config
Within the security settings, specific popups can be configured to display during confirmation or when entering the wallet UI.
These include `promptSettingWhenSign` for payment (signature) passwords and `promptMasterPasswordSettingWhenLogin` for a login-based master password.
By default, `promptSettingWhenSign` is set to 1, prompting the user on the first signature for a given account. If set to 0, the prompt is never shown; if set to 2, it is shown for every signature confirmation.
The same logic applies to `promptMasterPasswordSettingWhenLogin`, though it defaults to 0.
```kotlin Kotlin theme={null}
ParticleNetwork.setSecurityAccountConfig(
SecurityAccountConfig(
promptSettingWhenSign = 1,
promptMasterPasswordSettingWhenLogin = 2
)
)
```
### Master Password and Payment Password
Users can set a master password and payment password to protect their assets. To set or change the master password, call `auth.changeMasterPassword`.
To set or change the payment password, call `AuthCore.openAccountAndSecurity()`.
```kotlin theme={null}
// Check if user has a master password set
val result = AuthCore.hasMasterPassword()
// Set or change master password
AuthCore.changeMasterPassword()
// Check if user has payment password set
val result = AuthCore.hasPaymentPassword()
```
### Language Setting
You can force a specific language within the UI using `ParticleNetwork.setLanguage` and retrieve the currently active language with `ParticleNetwork.getAppliedLanguage`. The default language is English.
| Field | Type | Description |
| -------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `languageEnum` | `LanguageEnum` | The specific language to be used. Options include `ZH_CN`, `ZH_TW`, `EN`, `JA`, `KO`. |
| `isRelaunch` | `Boolean` | If true, the app will relaunch upon a language switch; if false, the activity will be recreated. |
| `isInit` | `Boolean` | If `isRelaunch` is set to true, `isInit` defaults to true. The activity will not be recreated and should be called before methods like `signMessage` or `sendTransaction`. |
```kotlin theme={null}
ParticleNetwork.setLanguage(LanguageEnum.EN)
ParticleNetwork.getLanguage()
```
***
### Enable Blind Signing
Silently sign messages/transactions if the following conditions are met:
1. Your account is connected via **JWT**.
2. Your account does not have a payment password set.
3. `SecurityAccountConfig.promptSettingWhenSign` is set to 0. You can update this value by calling `ParticleNetwork.setSecurityAccountConfig`.
```kotlin theme={null}
AuthCore.setBlindEnable(true)
val result = AuthCore.getBlindEnable()
```
# Cocos (JavaScript) - Auth
Source: https://developers.particle.network/social-logins/auth/mobile-sdks/cocos
Interacting with Particle Auth within applications made using Cocos.
## Particle Auth for Cocos
**Particle Auth** supports Cocos through the Particle Auth Cocos SDK, enabling full integration of Particle's Wallet-as-a-Service within Cocos-based game applications.
The usage of Particle Auth with Cocos is nearly identical to [React Native (JavaScript)](/social-logins/auth/mobile-sdks/react), with the main differences being in prerequisites and initial setup.
This document will guide you through the setup process. For usage examples, refer to the [React Native (JavaScript)](/social-logins/auth/mobile-sdks/react) documentation.
## Getting Started
To start the setup process for the Particle Auth Cocos SDK, make sure your project meets the following prerequisites to ensure compatibility:
* **Cocos 3.7.2** or higher.
* For iOS:
* **Xcode 15.0** or higher.
* **CocoaPods 1.14.3** or higher.
* **iOS 14** or higher.
* For Android:
* Minimum **API Level 23** or higher.
* Targets **API Level 31** or higher.
* Java SDK **version 11**.
Next, you’ll need to retrieve three essential values from the [Particle dashboard](https://dashboard.particle.network), which are required across all of Particle’s SDKs: `projectId`, `clientKey`, and `appId`.
Find a full rundown in the [Dashboard Guide](/social-logins/dashboard)
### Installation and configuration
To install and start using the Particle Auth Cocos SDK in your project, follow these steps:
#### Step 1: Copy the Core Assets
1. **Locate the Core Assets directory**:
* Navigate to the [assets/Mobile/Core directory in the `particle-cocos` repository](https://github.com/Particle-Network/particle-cocos/tree/mobile/assets/Mobile/Core).
2. **Copy the Core Assets directory**:
* Copy the entire `Core` folder to your project’s `assets` directory.
#### Step 2: Copy the Native Engine Files
1. **Locate the Native Engine directory**:
* Navigate to the [native/engine directory in the `particle-cocos` repository](https://github.com/Particle-Network/particle-cocos/tree/mobile/native/engine).
2. **Copy the Native Engine directory**:
* Copy the entire `engine` directory to your project’s `native` directory.
#### Android
If you're using Cocos on Android, the configuration is quite simple and purely requires the placement of the previously retrieved values (`projectId`, `clientKey`, and `appId`) within `$exportDir/proj/gradle.properties,` such as within the example below.
```kotlin gradle.properties theme={null}
android.enableJetifier=true
PN_PROJECT_ID = YOUR_PROJECT_ID
PN_PROJECT_CLIENT_KEY = YOUR_CLIENT_KEY
PN_APP_ID = YOUR_APP_ID
```
#### iOS
If you use iOS, the initial configuration will be more complicated. To begin, ensure you have a Podfile.
If you don't have one already, head over to the root of your Xcode project directory and run:
```shell Terminal theme={null}
pod init
```
Head into this newly generated (or existing) **Podfile** and remove all existing contents, then paste the configuration included below.
Alternatively, if you're already using other SDKs through **CocoaPods**, you can include the Particle Auth SDK declaration:
```ruby Ruby theme={null}
ENV['SWIFT_VERSION'] = '5'
platform :ios, '14.0'
source 'https://github.com/CocoaPods/Specs.git'
target 'boost_container' do
use_frameworks!
end
target 'cocos_engine' do
use_frameworks!
end
target 'ParticleCocosDemo-mobile' do
use_frameworks!
pod 'ParticleAuthService'
pod 'ParticleNetworkBase'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
```
Additionally, you can run `pod install --repo-update`, then `open {your project}.xcworkspace` to update and see your project within Xcode.
Now that you've configured your [Particle dashboard](https://dashboard.particle.network), installed the SDK, and configured a Podfile, it's time to initialize the SDK with the aforementioned `projectId`, `clientKey`, and `appId` retrieved from the [Particle dashboard](https://dashboard.particle.network).
1. Create a `ParticleNetwork-Info.plist` file from the root of your corresponding Xcode project.
2. Paste the following text into this file:
```xml ParticleNetwork-Info.plist theme={null}
PROJECT_UUIDYOUR_PROJECT_UUIDPROJECT_CLIENT_KEYYOUR_PROJECT_CLIENT_KEYPROJECT_APP_UUIDYOUR_PROJECT_APP_UUID
```
3. Replace the placeholders with the values retrieved from your project and application within the [Particle dashboard](https://dashboard.particle.network).
4. Drop the following files into your project and set the target at the main app. Make sure `Base58.swift`, `Model.swift`, and `ParticleAuthPlugin.swift` are marked within `TargetMembership`.
If Xcode asks to make a Swift bridging file, select **Yes**.
5. Open your `AppDelegate` file and include a custom return within the `(BOOL)application:openURL:options:` method, as shown in the example below:
```Text AppDelegate theme={null}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options {
return [ParticleAuthSchemeManager handleUrl:url];
}
```
6. Within `AppDelegate`, ensure a project-specific import is included at the top of the file. This should be `#import "{project name}-Swift.h"`.
`JsbBridgeTest.m` and `JsbBridgeTest.h` are crucial components, serving as the core bridge between JS and native code.
To prevent any issues arising from improper setup, ensure that the code within these files matches the code from the demo or includes the exact code from it.
7. Finally, to configure your app scheme URL, select your app from "TARGETS" within the "Info" section, click the plus icon to add the URL types, and paste your scheme in "URL Schemes."
Defining a scheme URL
Your scheme URL should be "pn" concatenated with your `projectId`.
For example, if your project app id is
`63bfa427-cf5f-4742-9ff1-e8f5a1b9828f`, your scheme URL is
`pn63bfa427-cf5f-4742-9ff1-e8f5a1b9828f`.
***
## Usage
Using the Particle Auth Cocos SDK is identical to the examples provided in the [React Native (JavaScript)](/social-logins/auth/mobile-sdks/react) documentation.
The only difference is the import statement, which should include the internal path `../../Core/particleAuth`, as shown below:
```js JavaScript theme={null}
import * as particleAuth from "../../Core/particleAuth";
```
# Flutter (Dart) - Auth
Source: https://developers.particle.network/social-logins/auth/mobile-sdks/flutter
Interacting with Particle Auth within applications made using Flutter.
## Particle Auth for Flutter
The **Particle Auth Flutter SDK** enables full-stack integration of Particle Auth into applications built on Flutter. This includes everything from the initial configuration of Particle's Wallet-as-a-Service to specific interactions.
In this case, Flutter can be leveraged in either Android or iOS environments, both to the same degree. This is done primarily through Dart.
Platform-specific configuration instructions, alongside examples of utilization, can be found below.
## Getting Started
Interaction with the Particle Auth Flutter SDK follows a standard approach consistent with other Particle Auth SDKs, though notable differences exist within the configuration process.
The configuration process for this SDK varies significantly depending on whether you're using Flutter for Android or iOS.
To begin, you'll need to head over to the [Particle dashboard](https://dashboard.particle.network) and retrieve your `projectId`, `clientKey`, and `appId`.
Find a full rundown in the [Dashboard Guide](/social-logins/dashboard)
### Adding the Particle Auth Flutter SDK to your application
Additionally, regardless of platform, you'll need to begin by adding `particle_auth_core` to your **Flutter** application; this is a requirement before moving onto platform-specific configuration.
```shell Terminal theme={null}
flutter pub add particle_auth_core
```
### Android configuration
#### Prerequisites
* minSdkVersion **23** or higher.
* compileSdkVersion, targetSdkVersion **34** or higher.
* JavaVersion **17**.
* [Jetpack (AndroidX)](https://developer.android.com/jetpack/androidx/migrate?authuser=0).
* Android Gradle Plugin Version : 8.5.1 or higher.
* Gradle Version : 8.9 or higher.
If you're building an Android application with Flutter, follow the steps below to configure Particle Auth. To begin, you'll need to go ahead and open your `build.gradle` file, often found at the following file path: `${project name}/android/app/build.gradle`
Within your `build.gradle` file, you'll need to add four new lines to ensure Particle Auth runs appropriately:
1. `minSdkVersion`, which in most cases will be set to `23`.
2. `manifestPlaceholders["PN_PROJECT_ID"]`, the `projectId` previously retrieved from the Particle dashboard.
3. `manifestPlaceholders["PN_PROJECT_CLIENT_KEY"]`, the `clientKey` previously retrieved from the Particle dashboard.
4. `manifestPlaceholders["PN_APP_ID"]`, the `appId` previously retrieved from the Particle dashboard.
```groovy build.gradle theme={null}
// Example
defaultConfig {
applicationId "com.example.particle_auth_test"
minSdkVersion 23 // Required by Particle Auth
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
manifestPlaceholders["PN_PROJECT_ID"] = "EXAMPLE"
manifestPlaceholders["PN_PROJECT_CLIENT_KEY"] = "EXAMPLE"
manifestPlaceholders["PN_APP_ID"] = "EXAMPLE"
}
```
Staying within your `build.gradle` file, you'll need to ensure that you're using version 17 of Java in both `compileOptions` and `kotlinOptions`, alongside enabling `dataBinding`.
```groovy build.gradle theme={null}
// Example
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
dataBinding {
enabled = true
}
```
Finally, for dependency management, within `build.gradle` you'll need to ensure that the `repositories` object in both `buildscript` and `allprojects` has `maven { setUrl("https://jitpack.io") }` present, such as is shown below.
```groovy build.gradle theme={null}
// Example
buildscript {
...
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") } // Add this
}
dependencies {
...
}
}
allprojects {
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") } // Add this
}
}
...
```
***
### iOS configuration
If you're building an iOS application with Flutter, this also entails a unique and iOS-specific configuration process. Before beginning, ensure your project meets the following prerequisites:
* Xcode 15.0 or later.
* iOS 14 or later.
With these requirements set, you'll need to open an exported iOS project and find `apps/{project name}.xcworkspace`.
At the root of your Xcode project, create a new file, `ParticleNetwork-Info.plist`. Ensure this is marked under `Target Membership`.
Now, with a fresh `ParticleNetwork-Info.plist` file, go ahead and fill it in with the following:
```xml ParticleNetwork-Info.plist theme={null}
PROJECT_UUIDYOUR_PROJECT_UUIDPROJECT_CLIENT_KEYYOUR_PROJECT_CLIENT_KEYPROJECT_APP_UUIDYOUR_PROJECT_APP_UUID
```
Similar to the Android configuration, you'll need to fill in `PROJECT_UUID` (`projectId`), `PROJECT_CLIENT_KEY`, and `PROJECT_APP_UUID` (`appId`) with the corresponding values retrieved from the [Particle dashboard](https://dashboard.particle.network).
To enable Face ID for your app, add a usage description to your `Info.plist` file by including the following code:
```xml Info.plist theme={null}
NSFaceIDUsageDescriptionWe use Face ID for secure access to the app.
```
Finally, you'll need to edit your Podfile to ensure `particle_auth_core` is properly imported. Head over to the [linked guide](https://github.com/Particle-Network/particle-flutter/blob/master/particle-auth-core/example/ios/Podfile) to complete this, if you haven't already.
Another important note before continuing.
Our SDK is a static library (XCFramework). When using the Particle Auth Flutter SDK, you'll need to specify that you're using a static framework through the following:
```ruby theme={null}
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
```
***
## Examples of utilization
### Initialization
Before using the full extent of the SDK, you'll need to initialize it with `init`, passing in the specific chain to which you intend to primarily onboard within Particle's Wallet-as-a-Service. This is represented as an object containing chain info (often derived from `ChainInfo.{Chain}`).
```dart theme={null}
// Set relevant project info, retrieved from https://dashboard.particle.network
ParticleInfo.set(projectId, clientKey);
// Initialize ParticleAuth and ParticleAuthCore.
ParticleBase.init(ChainInfo.Ethereum, env);
ParticleAuthCore.init()
```
### Connect
After installing, configuring, and initializing Particle Auth, initiate the login process by using `ParticleAuthCore.connect`. This triggers a social login prompt, and upon successful authentication, a user account is created, unlocking the full SDK functionality.
`ParticleAuthCore.connect` takes the following parameters:
| Field | Type | Description |
| ------------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loginType` | `LoginType` | The specific social login to be used. This can be either `.email`, `.phone`, `.google`, `.apple`, `.jwt`, `.facebook`, `.twitter`, `.discord`, `.github`, `.twitch`, `.microsoft` or `linkedin`. |
| `account` | `String?` | (Optional) When `type` is set to either `.email`, `.phone`, or `.jwt`, you can use the `account` parameter to pass in an expected email, phone number, or JWT. This is optional for the former two, but required for `.jwt`. If passing a phone number, it must be in E.164 format. |
| `prompt` | `SocialLoginPrompt?` | (Optional) Changes what the OAuth provider prompts a user to do; either `.none`, `.consent`, or `.select_account`. Only Google, Discord and Microsoft support it. |
| `loginPageConfig` | `LoginPageConfig?` | (Optional) Controls login UI customization: contains project name, icon and description. |
| `supportAuthTypes` | `List?` | The methods of authentication visible on the authentication popup UI. By default, this will be exclusive to the chosen social login method, although by passing in additional types, you can expand the UI to include the ability to login with those as an alternative to type. |
You can use your existing user base (account system) or a custom authentication method with Particle Connect through JWT. Click [here](/social-logins/configuration/auth/jwt) to learn how to configure JWT.
```dart theme={null}
// Google or other social login
final userInfo = await ParticleAuthCore.connect(LoginType.google, prompt: SocialLoginPrompt.select_account);
// Email or phone login, facilitated through Particle's UI
final userInfo = await ParticleAuthCore.connect(LoginType.email, supportAuthTypes: SupportAuthType.values, prompt: SocialLoginPrompt.select_account);
// Custom authentication via JWT
final userInfo = await ParticleAuthCore.connect(LoginType.jwt, account: jwt);
// Configuration of a custom email or phone login page, programmatically driving verification codes
final result = await ParticleAuthCore.sendEmailCode("user@example.com");
final result = await ParticleAuthCore.sendPhoneCode("+11234567890"); // Must be in E.164 format
// After a code is sent, the user should enter it within your UI, upon which you can use it for connection
final userInfo = await ParticleAuthCore.connectWithCode(email: "user@example.com", code: code);
final userInfo = await ParticleAuthCore.connectWithCode(phone: "+11234567890", code: code);
```
### Is Connected
There may be scenarios where it is important to know whether a current session (a user) is logged in with Particle Auth. This is achieved through `ParticleAuthCore.isConnected` (server-side check).
```dart theme={null}
final isConnected = await ParticleAuthCore.isConnected();
```
### Disconnect
To exit an existing session (logging a user out), call `ParticleAuthCore.disconnect`.
```dart theme={null}
final result = await ParticleAuthCore.disconnect();
```
### Get User Info
To retrieve an object containing detailed user information, call `ParticleAuthCore.getUserInfo`.
```dart theme={null}
final userInfo = await ParticleAuthCore.getUserInfo();
```
### Get Address
To retrieve the address, call `Evm.getAddress` or `Solana.getAddress`.
```dart theme={null}
final address = await Evm.getAddress();
final address = await Solana.getAddress();
```
### Sign Message (EIP191)
To request an EIP191 signature from a user's embedded wallet, you can use either the `Evm.personalSign` or `Evm.personalSignUnique` method.
If you need the same message to return a unique signature each time, use the `Evm.personalSignUnique` method. Otherwise, the `Evm.personalSign` method is generally recommended. On Solana, you can call `Solana.signMessage`, you can pass in a UTF-8/readable string.
| Field | Type | Description |
| --------- | -------- | --------------------------------------------------------------------------------- |
| `message` | `String` | On Evm requires a hexadecimal string, on Solana, requires a UTF-8/readable string |
```dart theme={null}
final messageHex = "0x${StringUtils.toHexString("Hello Particle")}";
String signature = await Evm.personalSign(messageHex);
String signature = await Evm.personalSignUnique(messageHex);
const message = "Hello Particle";
final signature = await Solana.signMessage(message);
```
### Sign Transaction
This is a **Solana-specific** method for signing a transaction without sending it. Similar to message signing, this will prompt a signature in-UI with details about the transaction.
Programmatically, the proposed transaction should be formatted as a (converted to a) base58 string. Passing in an object directly will not work in this case.
| Field | Type | Description |
| ------------- | -------- | ------------------------ |
| `transaction` | `String` | Requires a base58 string |
```dart theme={null}
final signature = await Solana.signTransaction(transaction);
```
### Sign All Transactions
Following the method above, you can use `Solana.signAllTransactions` to propose a collection of **Solana** transactions for signature, rather than just a single transaction.
| Field | Type | Description |
| -------------- | -------------- | ------------------------------------- |
| `transactions` | `List` | Each element requires a base58 string |
```dart theme={null}
List signatures = await Solana.signAllTransactions(transactions);
```
### Sign and Send Transaction
For more generalized transaction execution, `Evm.sendTransaction` and sendTransaction`and`Solana.signAndSendTransaction\` will be the primary methods used in virtually every scenario.
This will propose a signature (on both EVM and Solana) and then immediately push it to the network once confirmed.
| Field | Type | Description |
| ------------- | -------- | ------------------------------------------------------------------------- |
| `transaction` | `String` | On Evm requires a hexadecimal string, on Solana, requires a base58 string |
```dart theme={null}
final signature = await Evm.sendTransaction(transaction);
final signature = await Solana.signAndSendTransaction(transaction);
```
### Sign Typed Data V4 (EIP712)
To request an EIP712 signature from a user's embedded wallet, you can use the `Evm.signTypedData` or `Evm.signTypedDataUnique` method.
If you need the same message to return a unique signature each time, use the `Evm.signTypedDataUnique` method. Otherwise, the `Evm.signTypedData` method is generally recommended.
| Field | Type | Description |
| --------- | -------- | ----------------------------- |
| `message` | `String` | Requires a hexadecimal string |
```dart theme={null}
// your typed data is a json string
String typedDataHex = "0x${StringUtils.toHexString(typedData)}";
String signature = await Evm.signTypedData(typedDataHex);
String signature = await Evm.signTypedDataUnique(typedDataHex);
```
### Set Chain Info
To change the chain after it’s initially defined in `init`, you can use `ParticleBase.setChainInfo` for a synchronous update or `ParticleAuthCore.switchChain` for an asynchronous update, both typically using `ChainInfo.{Chain}`.
```dart theme={null}
await ParticleBase.setChainInfo(ChainInfo.Ethereum);
await ParticleAuthCore.switchChain(ChainInfo.Ethereum);
```
### Get Chain Info
To retrieve the currently selected (primary) chain in an active session, use `ParticleBase.getChainInfo`. This returns a `ChainInfo` object containing:
* `name`: The chain's name (e.g., Ethereum).
* `id`: The ID of the chain (e.g., 11155111).
* `network`: The specific network associated with the chain ID (e.g., Sepolia).
```dart theme={null}
final chainInfo = await ParticleBase.getChainInfo();
int id = chainInfo.id;
String name = chainInfo.name;
String network = chainInfo.network;
```
### Set Security Account Config
Another important component of integrating the Particle Auth SDK (Wallet-as-a-Service) is the (optional) security account requirements enforced upon application users.
For all Particle accounts, various security options are available, including:
* **Master Password**: A non-recoverable password required upon login.
* **Payment Password**: A PIN required for transaction signatures.
With the SDK, you can determine how often a user is prompted to configure their security settings. This control is facilitated by `ParticleBase.setSecurityAccountConfig`, where you pass in a `SecurityAccountConfig` object with two parameters:
| Field | Type | Description |
| -------------------------------------- | ----- | --------------------------------------------------- |
| `promptSettingWhenSign` | `int` | The security account config prompts (default is 1). |
| `promptMasterPasswordSettingWhenLogin` | `int` | The master password prompts (default is 0). |
* `0` means a prompt is never shown requesting this setting.
* `1` means a prompt is shown only upon the first startup.
* `2` means a prompt is shown every time.
* `3` means force set payment password before sign.
```dart theme={null}
final config = SecurityAccountConfig(1, 2);
ParticleBase.setSecurityAccountConfig(config);
```
### Open Account and Security Page
Following the above, if you'd like to force the opening of account/security settings (in-UI), you can do so with `ParticleAuthCore.openAccountAndSecurity`.
```dart theme={null}
await ParticleAuthCore.openAccountAndSecurity();
```
### Has Master Password, Payment Password, Security Account
Similarly to the `isConnected` function covered prior, there are various scenarios in which knowing whether or not a user has specific security settings enabled may be useful.
In the case of the Particle Auth Flutter SDK, this can happen in one of two ways:
With the built-in `ParticleAuthCore.hasMasterPassword`, `ParticleAuthCore.hasPaymentPassword`, and `ParticleAuthCore.changeMasterPassword` methods.
```dart theme={null}
await ParticleAuthCore.hasMasterPassword();
await ParticleAuthCore.hasPaymentPassword();
await ParticleAuthCore.changeMasterPassword();
```
### Set Appearance
You can forcibly set a specific appearance within the UI using `ParticleBase.setAppearance`. By default, it will follow the current system setting.
| Field | Type | Description |
| ------------ | ------------ | ------------------------------------------------------------------------------------ |
| `appearance` | `Appearance` | The specific appearance to be used. This can be either `.system`, `.dark`, `.light`. |
```dart theme={null}
// This is the default setting
ParticleBase.setAppearance(Appearance.system);
// Dark mode
ParticleBase.setAppearance(Appearance.dark);
// Light mode
ParticleBase.setAppearance(Appearance.light);
```
### Set and Get Language
You can forcibly set a specific language to be used within the UI using `ParticleBase.setLanguage`, with the retrieval of the currently active language facilitated by `ParticleBase.getLanguage`. By default, this is set to English.
| Field | Type | Description |
| ---------- | ---------- | ------------------------------------------------------------------------------------------------- |
| `language` | `Language` | The specific language to be used. This can be either `.en`, `.ja`, `.zh_hans`, `.zh_hant`, `.ko`. |
```dart theme={null}
ParticleBase.setLanguage(Language.en)
ParticleBase.getLanguage()
```
***
### Blind Sign Enable
Silently sign messages/transactions, this switch will work if the following conditions are met:
1. your account is connected with JWT
2. your account does not set payment password
3. SecurityAccountConfig.promptSettingWhenSign is 0, you can call `ParticleBase.setSecurityAccountConfig` to update its value.
```dart theme={null}
// Enable blind signing
ParticleAuthCore.setBlindEnable(enable);
// Retrieve a Boolean representing whether or not blind signing is enabled
final result = ParticleAuthCore.getBlindEnable();
```
***
### Filter Unsupported Countries (Phone Authentication)
If necessary, you can restrict specific countries from authenticating via phone number; upon entering a phone number originating from a country specified here, the login modal will block the user.
| Field | Type | Description |
| ------------- | -------------- | -------------------------------------------------------------------------------------------------------------- |
| `isoCodeList` | `List` | [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code list, such as the US, the UK, etc. |
```dart theme={null}
List isoCodeList = ['US', 'CA', 'GB'];
ParticleBase.setUnsupportCountries(isoCodeList);
```
***
## `EvmService` utilization examples
In addition to `ParticleAuthCore` for authentication and interaction with Particle's Wallet-as-a-Service, the Flutter SDK also includes a class, `EvmService`, for general interaction with EVM chains.
### Write Contract
`EvmService.writeContract` allows you to execute a write contract call defined by a specific method and set of parameters. This requires a corresponding ABI, contract address, and requester public address.
| Field | Type | Description |
| ----------------- | -------------- | --------------------------------------------------------------------------- |
| `address` | `String` | The user's public address. |
| `contractAddress` | `String` | The contract address. |
| `methodName` | `String` | The method name that defined in the contract, such as `mint`, `balanceOf`. |
| `parameters` | `List