Particle Connect on Lumia

Particle Network provides Wallet Abstraction services with an Account Abstraction stack, simplifying user onboarding with options like social logins and Web3 wallets.

Particle-Lumia demo

The Particle Connect SDK supports multiple EVM-compatible chains, including Lumia, enabling easy 2-click integration into EOAs (Externally Owned Accounts) and smart contract-based accounts.

Objectives

By the end of this tutorial, you’ll be able to set up a Particle Connect project to create an Externally-Owned Account (EOA) using social login, link a SIMPLE instance of a smart account to the generated EOA, enable streamlined 2-click login processes, and build and perform a gasless transaction.

Prerequisites

Wallet Funds

To follow along with this guide, you’ll need Lumia testent tokens to demonstrate the gasless transaction process. You can fund your wallet using the faucet on the Lumia Docs page.

Understanding Particle Network

Wallet Abstraction

Particle Network offers SDKs designed to reduce account-based friction for Web3 users as they onboard and manage wallets within applications. In this guide, friction mainly refers to login complexity: consumer-facing dApps often need login flows that avoid requiring users to download or manage traditional wallets, which can be a barrier.

Particle Connect is one of Particle's flagship onboarding SDKs, offering a unified modal for both social logins and Web3 wallet connections.

Account Abstraction

Particle Network also addresses account flexibility through Account Abstraction, moving from standard EOAs to smart accounts. Smart accounts, as programmable smart contracts, offer the flexibility of EOAs while allowing customized functionality.

Particle Network provides a SimpleAccount implementation on Lumia, allowing users easy access to smart accounts.

Integrating Particle Connect

The Particle Connect SDK streamlines wallet creation, user login, and blockchain interactions. It offers a unified interface for social logins and traditional Web3 wallets, providing an accessible experience for all users, regardless of their familiarity with Web3.

Set Up a New Next.js Project

To start, create a new Next.js project using the Next.js CLI. Follow the prompts to set up the project with TypeScript and Tailwind CSS enabled.

Copy

$ npx create-next-app@latest

# Select the following options:
What is your project named? particle-connect-app
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like your code inside a `src/` directory? Yes
Would you like to use App Router? (recommended) Yes
Would you like to customize the import alias (`@/*` by default)? No

Install Required Dependencies

Next, install the necessary dependencies:

Copy

# Using Yarn
yarn add @particle-network/connectkit viem@^2

# OR with npm
npm install @particle-network/connectkit viem@^2

This command installs the latest version of the Particle Connect SDK along with Viem v2, the default library Particle Connect uses for blockchain interactions and transactions. :::info The Particle Connect SDK includes built-in Account Abstraction, so it’s the only Particle package you need. If you prefer to use other EIP-1193 providers (like ethers), you’ll need the Particle AA SDK. For more information, see the Particle Documentation. :::

Configure Particle Connect

After installing dependencies, set up a project and application in the Particle Dashboard to obtain the projectId, clientKey, and appId needed for Particle Connect.

Here’s how:

  1. Log in to the Particle Dashboard using your email.

  2. Select Add New Project and enter a project name.

  3. Copy the Project ID and Client Key provided.

  4. Add a new application by selecting Web as the platform.

  5. Name the application and specify its domain. Any placeholder (e.g., 'test.com') will work if you don't have a domain yet.

  6. Copy the App ID once the application is created.

Store these API keys in a .env file in the root of your project, following this structure:

Copy

NEXT_PUBLIC_PROJECT_ID='PROJECT_ID'
NEXT_PUBLIC_CLIENT_KEY='CLIENT_KEY'
NEXT_PUBLIC_APP_ID='APP_ID'

Now, you’re ready to configure Particle Connect. Start by creating a Connectkit.tsx file in the src directory with the following code:

Copy

'use client';

import React from 'react';
import { ConnectKitProvider, createConfig } from '@particle-network/connectkit';
import { authWalletConnectors } from '@particle-network/connectkit/auth';
import { defineChain } from '@particle-network/connectkit/chains';

// Define the Lumia testnet
const lumiaTestnet = defineChain({
  id: 1952959480,
  name: "Lumia Testnet",
  nativeCurrency: {
    decimals: 18,
    name: "LUMIA",
    symbol: "LUMIA",
  },
  rpcUrls: {
    default: {
      http: ["https://testnet-rpc.lumia.org"],
    },
  },
  blockExplorers: {
    default: { name: "Explorer", url: "https://testnet-explorer.lumia.org/" },
  },
  testnet: true,
});

const config = createConfig({
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
  clientKey: process.env.NEXT_PUBLIC_CLIENT_KEY!,
  appId: process.env.NEXT_PUBLIC_APP_ID!,
  walletConnectors: [authWalletConnectors({})],

  plugins: [
    aa({
      name: 'SIMPLE',
      version: '2.0.0',
    }),
  ],

  chains: [lumiaTestnet],
});

export const ParticleConnectkit = ({ children }: React.PropsWithChildren) => {
  return <ConnectKitProvider config={config}>{children}</ConnectKitProvider>;
};

This file exports the ParticleConnectKit component, where you input project keys and configure SDK settings.

In this example, API keys are loaded from .env, social logins are enabled via authWalletConnectors, a SIMPLE smart account is set up, and supported chains are limited to the Lumia Testnet.

Note: This example provides a basic ConnectKit.tsx setup. For detailed configurations, see the Particle Connect documentation.

Integrate the ParticleConnectKit Component in Your App

With the configuration ready, wrap your application with the ParticleConnectKit component to enable global access to the Particle Connect SDK. Here’s an example setup in your layout.tsx file within src:

Copy

import { ParticleConnectkit } from '@/connectkit';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Particle Connectkit App',
  description: 'Generated by create next app',
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ParticleConnectkit>{children}</ParticleConnectkit>
      </body>
    </html>
  );
}

Enabling Login and Wallet Connection

With Particle Connect set up, you can enable your app's social logins and wallet connections using the ConnectButton component from the Particle ConnectKit library. Here’s a basic implementation that you can add to the page.tsx file in the src directory:

Copy

import { ConnectButton, useAccount } from '@particle-network/connectkit';

export const App = () => {
  const { address, isConnected, chainId } = useAccount();

  return (
    <div>
      <ConnectButton />
      {isConnected && (
        <>
          <h2>Address: {address}</h2>
          <h2>Chain ID: {chainId}</h2>
        </>
      )}
    </div>
  );
};

This code snippet provides a straightforward interface for logging in and connecting users to your app, displaying their wallet address and the connected blockchain’s chain ID upon authentication.

For more application-level hooks, see the Particle Connect SDK documentation.

Sending a Gasless Transaction

Particle Connect provides all the infrastructure needed to send gasless transactions easily. A gasless transaction allows users to interact with the blockchain without needing to cover gas fees. Instead, fees can be sponsored, improving user experience.

Unlike standard transactions, gasless transactions sent through ERC-4337 account abstraction use a structure called UserOperations (or UserOps).

This section will guide you through building a UserOp.

Step 1: Create a Smart Account Instance

Start by creating an instance of smartAccount, which enables you to sign transactions and use Particle Connect’s infrastructure for gasless operations.

Copy

import { useSmartAccount } from '@particle-network/connectkit';
import { parseEther } from 'viem'; // To be used in the transaction function

// Inside your component or app
const smartAccount = useSmartAccount();

This code initializes smartAccount as the primary signer, allowing transaction execution through Particle Connect.

Step 2: Execute a Gasless Transaction

With the smartAccount instance ready, you can perform a gasless transaction by creating a UserOperation (userOp). Here’s an example that transfers 0.01 LUMIA without requiring the user to pay gas fees.

Copy

const executeTxNative = async () => {
  const tx = {
    to: recipientAddress, // Recipient's address
    value: parseEther('0.01').toString(), // Amount to send (in ETH)
  };

  // Fetch fee quotes and set up the transaction for gasless execution
  const feeQuotesResult = await smartAccount?.getFeeQuotes(tx);
  const { userOp, userOpHash } = feeQuotesResult?.verifyingPaymasterGasless || {};

  if (userOp && userOpHash) {
    const txHash = await smartAccount?.sendUserOperation({ userOp, userOpHash });
    console.log('Transaction sent:', txHash);
  }
};

This code shows how to build a UserOp and execute a gasless transaction with smartAccount as the signer.

Complete page.tsx File

Now that you have an understanding of each step, let’s bring everything together in the page.tsx file:

Copy

import React, { useState } from 'react';
import { ConnectButton, useAccount, useSmartAccount } from '@particle-network/connectkit';
import { parseEther } from 'viem'; // Used to handle ETH value parsing

export const App = () => {
  const { address, isConnected, chainId } = useAccount(); // Fetch user account information
  const smartAccount = useSmartAccount(); // Initialize smart account
  const [recipientAddress, setRecipientAddress] = useState(''); // State to store recipient address
  const [transactionHash, setTransactionHash] = useState(''); // State to store transaction hash

  // Function to execute gasless transaction
  const executeTxNative = async () => {
    if (!recipientAddress) {
      alert('Please enter a recipient address');
      return;
    }

    const tx = {
      to: recipientAddress, // Recipient's address
      value: parseEther('0.01').toString(), // Amount to send (in ETH)
      data: '0x', // No additional data for a basic transfer
    };

    // Fetch fee quotes and execute the gasless transaction
    const feeQuotesResult = await smartAccount?.getFeeQuotes(tx);
    const { userOp, userOpHash } = feeQuotesResult?.verifyingPaymasterGasless || {};

    if (userOp && userOpHash) {
      const txHash = await smartAccount?.sendUserOperation({ userOp, userOpHash });
      setTransactionHash(txHash); // Set the transaction hash state
      console.log('Transaction sent:', txHash);
    } else {
      console.error('Error fetching gasless transaction details');
    }
  };

  return (
    <div>
      <ConnectButton /> {/* Button to connect wallet */}
      {isConnected && (
        <>
          <h2>Address: {address}</h2>
          <h2>Chain ID: {chainId}</h2>

          <div>
            <label>Recipient Address: </label>
            <input
              type="text"
              value={recipientAddress}
              onChange={(e) => setRecipientAddress(e.target.value)}
              placeholder="Enter recipient address"
            />
          </div>

          <button onClick={executeTxNative}>Send 0.01 LUMIA Gasless</button>

          {transactionHash && (
            <div>
              <h3>Transaction Hash: {transactionHash}</h3>
            </div>
          )}
        </>
      )}
    </div>
  );
};

This code creates a simple interface for sending gasless transactions, with an input for the recipient’s address and a display for the transaction hash upon success.

Running the Application:

  1. Navigate to your project’s root directory.

  2. Start the server with npm run dev or yarn dev.

  3. Log in with a social account.

  4. Fund the displayed wallet address.

  5. Enter the recipient’s address.

  6. Click Send 0.01 LUMIA Gasless to complete the transaction.

Quickstart Guide

For a detailed, step-by-step setup of a new project with Particle Connect, refer to the Particle Connect Quickstart in the Particle Network documentation.

Conclusion

You’ve successfully built an application from scratch, enabling user onboarding into smart accounts via social logins with Particle Connect.

Last updated