From be7a72e5335c8191ba355db0889a24702a7b30d8 Mon Sep 17 00:00:00 2001
From: Soos3D <99700157+soos3d@users.noreply.github.com>
Date: Mon, 9 Sep 2024 14:51:27 -0300
Subject: [PATCH 1/2] App Particle Network tutorial
---
docs/fuse-box/tutorials/partner/README.mdx | 1 +
.../tutorials/partner/particle-connect.mdx | 591 ++++++++++++++++++
2 files changed, 592 insertions(+)
create mode 100644 docs/fuse-box/tutorials/partner/particle-connect.mdx
diff --git a/docs/fuse-box/tutorials/partner/README.mdx b/docs/fuse-box/tutorials/partner/README.mdx
index 39e3960a..9ccc1969 100644
--- a/docs/fuse-box/tutorials/partner/README.mdx
+++ b/docs/fuse-box/tutorials/partner/README.mdx
@@ -7,3 +7,4 @@ sidebar_position: 3
| :------------------------------------------------------------ | :---- |
| [FuseBox Login using MetaMask](metamask-login) | Web |
| [FuseBox Social Login using Web3Auth](web3auth-login) | Web |
+| [Social Logins and Account Abstraction with Particle Connect](particle-connect) | Web |
diff --git a/docs/fuse-box/tutorials/partner/particle-connect.mdx b/docs/fuse-box/tutorials/partner/particle-connect.mdx
new file mode 100644
index 00000000..87be51fa
--- /dev/null
+++ b/docs/fuse-box/tutorials/partner/particle-connect.mdx
@@ -0,0 +1,591 @@
+---
+title: Social Logins and Account Abstraction with Particle Connect
+sidebar_position: 8
+---
+
+Particle Connect combines Social and Web3 logins with built-in Account Abstraction support, all within a single SDK. This approach allows you to simplify user onboarding while directly incorporating AA features into your **Fuse dApp**.
+
+Integrating **Particle Connect** into your **Fuse** web application can be done in **under five minutes**.
+
+This guide provides a concise overview of how to install, configure, and enable social logins in a Next.js application using `create @particle-network/connectkit` as your starting point.
+
+:::note
+For a detailed explanation of each feature and more advanced configurations, refer to the [Particle Connect SDK reference](/api-reference/connect/desktop/web).
+:::
+
+---
+
+### Boilerplate: Initializing Particle Connect
+
+The easiest way to get started with **Particle Connect** is through its built-in starter/boilerplate; this includes the core file setup and code structure needed to configure Particle Connect.
+
+To initialize this boilerplate, copy and execute one of the following commands.
+
+```sh Terminal
+npm init @particle-network/connectkit@latest
+# or
+pnpm create @particle-network/connectkit@latest
+# or
+yarn create @particle-network/connectkit
+```
+
+After running one of the aforementioned commands, the CLI will guide you through a setup process; it will prompt you to enter a project name, choose your preferred framework (Next.js or React), and select additional options.
+
+```shell Terminal
+🤩 Welcome to Particle Network!
+
+✔ What is the name of your project? … connectkit-aa-usage
+
+✔ What is the template of your project? › create-next-app
+✔ Which chains does your app support?​ › EVM
+✔ Which ERC-4337 Contract does your app support?​ › SIMPLE-2.0.0
+✔ Does it support an embedded wallet?​ … yes
+```
+
+:::note
+This guide will proceed with a **Next.js** project setup, although **React (create-react-app)** is also supported.
+
+Additionally, the **Fuse** Network for Account Abstraction is only supported by the `SIMPLE` instance of Smart Account.
+:::
+
+### Configuring Particle Connect
+
+With a starter project initialized, you're ready to configure Particle Connect through its core component, `ConnectKitProvider`.
+
+Before diving deeper, you'll need some keys from the [Particle dashboard](https://dashboard.particle.network).
+
+**Particle Connect** requires three key values from the dashboard to be initiated: `projectId`, `clientKey`, and `appId`.
+
+### Access the Particle Dashboard
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+:::note
+To get started, sign up or log in to the [Particle dashboard](https://dashboard.particle.network).
+:::
+
+### Create a New Project or Use an Existing One
+
+
+
+
+You can create a new project by clicking the **Add New Project** button on the dashboard.
+
+
+
+
+Already have a project? Simply choose your existing project from the list on the dashboard.
+
+
+
+
+### Create a New Web Application
+
+Create a new **Web** application from the **Your Apps** section in the Particle dashboard.
+
+### Retrieve the Project ID, Client Key, and Application ID
+
+Follow these steps to retrieve your credentials:
+
+1. Navigate to the **Project Information** section in your dashboard.
+ - Here, you'll find both your `projectId` and `clientKey`.
+2. Go to the **Your Apps** section.
+ - Locate the web application you just created (or an existing one), and find the `appId` listed under the app's details.
+
+:::note
+For a quick overview of the Particle dashboard, watch [this video](https://www.youtube.com/watch?v=d7DYCMNDmjo&ab_channel=ParticleNetwork) or check out the [Dashboard Quickstart Guide](/guides/dashboard).
+:::
+
+After obtaining your `projectId`, `clientKey`, and `appId`, you'll need to use these to configure the `ConnectKitProvider` component from `@particle-network/connectkit`.
+
+The boilerplate already includes the basic variable setup—just add your API keys to the `.env.sample` file and rename it to `.env`.
+
+:::tip
+At this point, you're ready to either run and test the application or begin development through `app/page.tsx`.
+
+We’ll also go over some of the granular controls available through `ConnectKitProvider`.
+:::
+
+### Configuring ConnectKitProvider
+
+When working with `ConnectKitProvider`, it's recommended to use a dedicated `Connectkit.tsx` file in the `src` directory where you can configure and export the component. Then, you'll use this export to wrap your main App component (the location of your Particle Connect implementation through `ConnectButton`).
+
+Here’s how you can configure `ConnectKitProvider`:
+
+**Required Configurations:**
+- `projectId`, `clientKey`, and `appId` — Get these from the [Particle dashboard](https://dashboard.particle.network).
+- `chains` — Specify the supported chains for your dApp (this is an array of Viem-originating chain objects imported from `@particle-network/connectkit/chains`).
+- `walletConnectors` — Define the wallets you want to support.
+
+**Optional Configurations:**
+- `theme` and `language` for basic customization of the connection modal UI.
+- Additional appearance customizations.
+
+:::note
+In the boilerplate application, you'll find a pre-configured `Connectkit.tsx` file located in the `src` directory.
+:::
+
+Below is an example of a **configured** instance of `ConnectKitProvider`. For more details around each available property, head over to the [Particle Connect Web SDK reference](/api-reference/connect/desktop/web).
+
+In this example, we import the `fuse` and `fuseSparknet` networks from `"@particle-network/connectkit/chains"`, and then add them to the `chains` array inside the `plugins` object.
+
+```tsx
+
+"use client";
+
+// Particle imports
+import { ConnectKitProvider, createConfig } from '@particle-network/connectkit';
+import { authWalletConnectors } from '@particle-network/connectkit/auth';
+import { evmWalletConnectors } from '@particle-network/connectkit/evm';
+import { solanaWalletConnectors } from '@particle-network/connectkit/solana';
+import { EntryPosition, wallet } from '@particle-network/connectkit/wallet';
+
+import { fuse, fuseSparknet } from "@particle-network/connectkit/chains"; // Chains are imported here
+import { aa } from "@particle-network/connectkit/aa"; // Account Abstraction packages
+import React from 'react';
+
+const config = createConfig({
+ projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
+ clientKey: process.env.NEXT_PUBLIC_CLIENT_KEY!,
+ appId: process.env.NEXT_PUBLIC_APP_ID!,
+
+ appearance: {
+ recommendedWallets: [
+ { walletId: 'metaMask', label: 'Recommended' },
+ { walletId: 'coinbaseWallet', label: 'popular' },
+ ],
+ language: 'en-US',
+ mode: "auto", // dark or auto.
+ },
+
+ walletConnectors: [
+ evmWalletConnectors({
+ // Replace this with your app metadata.
+ metadata: {
+ name: 'Connectkit Demo',
+ icon: typeof window !== 'undefined' ? `${window.location.origin}/favicon.ico` : '',
+ description: 'Particle Connectkit Next.js Scaffold.',
+ url: typeof window !== 'undefined' ? window.location.origin : '',
+ },
+ walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID as string,
+ }),
+
+ authWalletConnectors({
+ authTypes: ['email', 'google', 'twitter', 'github'], // Optional, restricts the types of social logins supported
+ }),
+ ],
+
+ plugins: [
+ wallet({
+ visible: true,
+ entryPosition: EntryPosition.BR, // Use BR (bottom right), BL (bottom left), TR (top right), TL (top left) to move the wallet entry position
+ }),
+
+ // aa config start
+ aa({
+ name: "SIMPLE",
+ version: "2.0.0",
+ }),
+ // aa config end
+ ],
+
+ // List the chains you want to include
+ chains: [fuse, fuseSparknet],
+});
+
+// Wrap your application with this exported component, or ConnectKitProvider directly.
+export const ParticleConnectkit = ({ children }: React.PropsWithChildren) => {
+ return {children} ;
+};
+```
+
+:::tip
+For more detailed information, visit the full [**Particle Connect** SDK documentation](/api-reference/connect/desktop/web).
+:::
+
+### Wrapping Your Application with ConnectKitProvider
+
+Wrap your primary application component (wherever you place and use `ConnectButton` alongside the various hooks from Particle Connect) with the `ParticleConnectKit` component (exported from `ConnectKitProvider`).
+
+:::note
+In the boilerplate application, you'll find a pre-configured `layout.tsx` file located in the `app` directory.
+:::
+
+Here’s an example of what this looks like for a `layout.tsx` file:
+
+```tsx layout.tsx
+import { ParticleConnectkit } from '@/connectkit'; // Export of a configured ConnectKitProvider instance
+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 (
+
+
+ {children}
+
+
+ );
+}
+```
+
+### Facilitating Logins and Chain Interactions
+
+With **Particle Connect** now configured, you can proceed to enable social logins within your application through the aforementioned `ConnectButton` component.
+
+Additionally, for driving application-level interaction (after initial onboarding), `@particle-network/connectkit` provides a variety of hooks. You can explore all available hooks in the [Particle Connect SDK documentation](/api-reference/connect/desktop/web#key-react-hooks-for-particle-connect).
+
+:::note
+The boilerplate application includes a basic example featuring only a **Connect** button (`ConnectButton`).
+:::
+
+After logging in (connecting), users can access the embedded wallet modal provided by **Particle Connect** via the button in the bottom right corner, unless customized through the `wallet` configuration within `ConnectKitProvider`.
+
+To explore additional features like fetching and displaying user information, balances, on-ramp services, and sending transactions using either the native Particle Provider (Viem-based WalletClient) or ethers.js through an EIP-1193 provider, paste the following code into `app/page.tsx`.
+
+```tsx page.tsx
+"use client";
+
+import React, { useEffect, useState } from "react";
+
+// Particle imports
+import {
+ ConnectButton,
+ useAccount,
+ useDisconnect,
+ usePublicClient,
+ useParticleAuth,
+ useWallets,
+} from "@particle-network/connectkit";
+
+// Connectkit uses Viem, so Viem's features can be utilized
+import { formatEther, parseEther } from "viem";
+
+// Optional: Import ethers provider for EIP-1193 compatibility
+import { ethers, type Eip1193Provider } from "ethers";
+
+export default function Home() {
+ // Initialize account-related states from Particle's useAccount hook
+ const { address, isConnected, isConnecting, isDisconnected, chainId } =
+ useAccount();
+ const { disconnect, disconnectAsync } = useDisconnect();
+ const { getUserInfo } = useParticleAuth();
+
+ // Optional: Initialize public client for RPC calls using Viem
+ const publicClient = usePublicClient();
+
+ // Retrieve the primary wallet from the Particle Wallets
+ const [primaryWallet] = useWallets();
+
+ // Define state variables
+ const [account, setAccount] = useState(null); // Store account information
+ const [balance, setBalance] = useState(""); // Store user's balance
+ const [userAddress, setUserAddress] = useState(""); // Store user's address
+ const [userInfo, setUserInfo] = useState(null); // Store user's information
+ const [isLoadingUserInfo, setIsLoadingUserInfo] = useState(false); // Loading state for fetching user info
+ const [userInfoError, setUserInfoError] = useState(null); // Error state for fetching user info
+ const [recipientAddress, setRecipientAddress] = useState(""); // Store recipient's address for transactions
+ const [transactionHash, setTransactionHash] = useState(null); // Store transaction hash after sending
+ const [isSending, setIsSending] = useState(false); // State for showing sending status
+
+ // Connection status message
+
+ based on the account's connection state
+ const connectionStatus = isConnecting
+ ? "Connecting..."
+ : isConnected
+ ? "Connected"
+ : isDisconnected
+ ? "Disconnected"
+ : "Unknown";
+
+ // Load account details and fetch balance when address or chainId changes
+ useEffect(() => {
+ async function loadAccount() {
+ if (address) {
+ setAccount(account);
+ setUserAddress(address);
+ await fetchBalance();
+ }
+ }
+ loadAccount();
+ }, [chainId, address]);
+
+ // Fetch and set user information when connected
+ useEffect(() => {
+ const fetchUserInfo = async () => {
+ setIsLoadingUserInfo(true);
+ setUserInfoError(null);
+
+ try {
+ const userInfo = await getUserInfo();
+ console.log(userInfo);
+ setUserInfo(userInfo);
+ } catch (error) {
+ setUserInfoError(
+ "Error fetching user info: The current wallet is not a particle wallet."
+ );
+ console.error("Error fetching user info:", error);
+ } finally {
+ setIsLoadingUserInfo(false);
+ }
+ };
+
+ if (isConnected) {
+ fetchUserInfo();
+ }
+ }, [isConnected, getUserInfo]);
+
+ // Fetch user's balance and format it for display
+ const fetchBalance = async () => {
+ try {
+ if (!address) return;
+ const balanceResponse = await publicClient?.getBalance({ address });
+ const balanceInEther = formatEther(balanceResponse!);
+ console.log(balanceResponse);
+ setBalance(parseFloat(balanceInEther).toFixed(4)); // Display balance with 4 decimal places
+ } catch (error) {
+ console.error("Error fetching balance:", error);
+ }
+ };
+
+ // Handle user disconnect action
+ const handleDisconnect = async () => {
+ try {
+ await disconnectAsync();
+ } catch (error) {
+ console.error("Error disconnecting:", error);
+ }
+ };
+
+ // Option 1: Send transaction using ethers.js with a custom EIP-1193 provider
+ const executeTxEthers = async () => {
+ const tx = {
+ to: recipientAddress,
+ value: parseEther("0.01"), // Set value to 0.01 Ether
+ data: "0x", // No data, as there is no contract interaction
+ };
+
+ setIsSending(true);
+
+ try {
+ const EOAprovider = await primaryWallet.connector.getProvider();
+ const customProvider = new ethers.BrowserProvider(
+ EOAprovider as Eip1193Provider,
+ "any"
+ );
+
+ const signer = await customProvider.getSigner();
+ const txResponse = await signer.sendTransaction(tx);
+ const txReceipt = await txResponse.wait();
+
+ if (txReceipt) {
+ setTransactionHash(txReceipt.hash);
+ } else {
+ console.error("Transaction receipt is null");
+ }
+ } catch (error) {
+ console.error("Error executing EVM transaction:", error);
+ } finally {
+ setIsSending(false);
+ }
+ };
+
+ // Option 2: Send transaction using the native Particle provider
+ const executeTxNative = async () => {
+ try {
+ const tx = {
+ to: recipientAddress,
+ value: parseEther("0.01"), // Set value to 0.01 Ether
+ data: "0x", // No data, as there is no contract interaction
+ chainId: primaryWallet.chainId, // Current chainId
+ account: primaryWallet.accounts[0], // Primary account
+ };
+
+ setIsSending(true);
+
+ const walletClient = primaryWallet.getWalletClient();
+ const transactionResponse = await walletClient.sendTransaction(tx);
+
+ setTransactionHash(transactionResponse);
+ console.log("Transaction sent:", transactionResponse);
+ } catch (error) {
+ console.error("Failed to send transaction:", error);
+ } finally {
+ setIsSending(false);
+ }
+ };
+
+ // Parameters for the on-ramp URL
+ const fiatCoin = "USD";
+ const cryptoCoin = "ETH";
+ const network = "Ethereum";
+ const theme = "dark";
+ const language = "en";
+
+ // Function to handle the on-ramp button click
+ const handleOnRamp = () => {
+ const onRampUrl = `https://ramp.particle.network/?fiatCoin=${fiatCoin}&cryptoCoin=${cryptoCoin}&network=${network}&theme=${theme}&language=${language}`;
+ window.open(onRampUrl, "_blank");
+ };
+
+ // Function to copy text to clipboard
+ const copyToClipboard = (text: string) => {
+ navigator.clipboard.writeText(text).then(() => {
+ alert("Copied to clipboard!");
+ });
+ };
+
+ // Function to truncate Ethereum address
+ const truncateAddress = (address: string) => {
+ return address.slice(0, 6) + "..." + address.slice(-4);
+ };
+
+ return (
+
+ {/* Header */}
+
+
+ Particle Connect 2.0
+
+ Particle Connect Quickstart— Fetch user data and send trasnactions
+
+
+
+
+ {/* Display connection status */}
+
+
+ Status: {connectionStatus}
+
+
+
+ {isConnected ? (
+ <>
+
+
+
+ {isLoadingUserInfo ? (
+
Loading user info...
+ ) : userInfoError ? (
+
{userInfoError}
+ ) : (
+ userInfo && ( // Conditionally render user info
+
+
+ Name: {userInfo.name || "N/A"}
+
+ {userInfo.avatar && (
+
+ )}
+
+ )
+ )}
+
+ Address: {truncateAddress(userAddress)}
+ copyToClipboard(userAddress)}
+ >
+ 📋
+
+
+
+ Chain ID: {chainId}
+
+
+ Balance: {balance !== "" ? balance : "Loading..."}
+
+ 🔄
+
+
+
+ Buy Crypto with Fiat
+
+
+
+ Disconnect
+
+
+
+
+
+
+ Send a transaction
+
+
Send 0.01
+
setRecipientAddress(e.target.value)}
+ className="mt-4 p-2
+
+ w-full rounded border border-gray-700 bg-gray-900 text-white focus:outline-none focus:ring-2 focus:ring-purple-400"
+ />
+
+ {isSending ? "Sending..." : `Send 0.01 Particle provider`}
+
+
+ {isSending ? "Sending..." : `Send 0.01 with ethers`}
+
+ {/* Display transaction notification with the hash */}
+ {transactionHash && (
+
+ Transaction Hash: {transactionHash}
+
+ )}
+
+
+
+ >
+ ) : (
+
+ )}
+
+
+ );
+}
+```
+
+:::tip
+ A Next.js demo repository containing the above code can be found on [GitHub](https://github.com/Particle-Network/particle-connectkit2.0-quickstart).
+:::
From 46bda83489fcfbec519c98e65fd0fc12f90cf370 Mon Sep 17 00:00:00 2001
From: Soos3D <99700157+soos3d@users.noreply.github.com>
Date: Mon, 9 Sep 2024 15:15:21 -0300
Subject: [PATCH 2/2] Update particle-connect.mdx
---
.../tutorials/partner/particle-connect.mdx | 336 +-----------------
1 file changed, 3 insertions(+), 333 deletions(-)
diff --git a/docs/fuse-box/tutorials/partner/particle-connect.mdx b/docs/fuse-box/tutorials/partner/particle-connect.mdx
index 87be51fa..61b4f290 100644
--- a/docs/fuse-box/tutorials/partner/particle-connect.mdx
+++ b/docs/fuse-box/tutorials/partner/particle-connect.mdx
@@ -45,7 +45,7 @@ After running one of the aforementioned commands, the CLI will guide you through
:::note
This guide will proceed with a **Next.js** project setup, although **React (create-react-app)** is also supported.
-Additionally, the **Fuse** Network for Account Abstraction is only supported by the `SIMPLE` instance of Smart Account.
+Additionally, Account Abstraction on Fuse is only supported through the `SIMPLE` instance of Smart Account.
:::
### Configuring Particle Connect
@@ -254,338 +254,8 @@ The boilerplate application includes a basic example featuring only a **Connect*
After logging in (connecting), users can access the embedded wallet modal provided by **Particle Connect** via the button in the bottom right corner, unless customized through the `wallet` configuration within `ConnectKitProvider`.
-To explore additional features like fetching and displaying user information, balances, on-ramp services, and sending transactions using either the native Particle Provider (Viem-based WalletClient) or ethers.js through an EIP-1193 provider, paste the following code into `app/page.tsx`.
-
-```tsx page.tsx
-"use client";
-
-import React, { useEffect, useState } from "react";
-
-// Particle imports
-import {
- ConnectButton,
- useAccount,
- useDisconnect,
- usePublicClient,
- useParticleAuth,
- useWallets,
-} from "@particle-network/connectkit";
-
-// Connectkit uses Viem, so Viem's features can be utilized
-import { formatEther, parseEther } from "viem";
-
-// Optional: Import ethers provider for EIP-1193 compatibility
-import { ethers, type Eip1193Provider } from "ethers";
-
-export default function Home() {
- // Initialize account-related states from Particle's useAccount hook
- const { address, isConnected, isConnecting, isDisconnected, chainId } =
- useAccount();
- const { disconnect, disconnectAsync } = useDisconnect();
- const { getUserInfo } = useParticleAuth();
-
- // Optional: Initialize public client for RPC calls using Viem
- const publicClient = usePublicClient();
-
- // Retrieve the primary wallet from the Particle Wallets
- const [primaryWallet] = useWallets();
-
- // Define state variables
- const [account, setAccount] = useState(null); // Store account information
- const [balance, setBalance] = useState(""); // Store user's balance
- const [userAddress, setUserAddress] = useState(""); // Store user's address
- const [userInfo, setUserInfo] = useState(null); // Store user's information
- const [isLoadingUserInfo, setIsLoadingUserInfo] = useState(false); // Loading state for fetching user info
- const [userInfoError, setUserInfoError] = useState(null); // Error state for fetching user info
- const [recipientAddress, setRecipientAddress] = useState(""); // Store recipient's address for transactions
- const [transactionHash, setTransactionHash] = useState(null); // Store transaction hash after sending
- const [isSending, setIsSending] = useState(false); // State for showing sending status
-
- // Connection status message
-
- based on the account's connection state
- const connectionStatus = isConnecting
- ? "Connecting..."
- : isConnected
- ? "Connected"
- : isDisconnected
- ? "Disconnected"
- : "Unknown";
-
- // Load account details and fetch balance when address or chainId changes
- useEffect(() => {
- async function loadAccount() {
- if (address) {
- setAccount(account);
- setUserAddress(address);
- await fetchBalance();
- }
- }
- loadAccount();
- }, [chainId, address]);
-
- // Fetch and set user information when connected
- useEffect(() => {
- const fetchUserInfo = async () => {
- setIsLoadingUserInfo(true);
- setUserInfoError(null);
-
- try {
- const userInfo = await getUserInfo();
- console.log(userInfo);
- setUserInfo(userInfo);
- } catch (error) {
- setUserInfoError(
- "Error fetching user info: The current wallet is not a particle wallet."
- );
- console.error("Error fetching user info:", error);
- } finally {
- setIsLoadingUserInfo(false);
- }
- };
-
- if (isConnected) {
- fetchUserInfo();
- }
- }, [isConnected, getUserInfo]);
-
- // Fetch user's balance and format it for display
- const fetchBalance = async () => {
- try {
- if (!address) return;
- const balanceResponse = await publicClient?.getBalance({ address });
- const balanceInEther = formatEther(balanceResponse!);
- console.log(balanceResponse);
- setBalance(parseFloat(balanceInEther).toFixed(4)); // Display balance with 4 decimal places
- } catch (error) {
- console.error("Error fetching balance:", error);
- }
- };
-
- // Handle user disconnect action
- const handleDisconnect = async () => {
- try {
- await disconnectAsync();
- } catch (error) {
- console.error("Error disconnecting:", error);
- }
- };
-
- // Option 1: Send transaction using ethers.js with a custom EIP-1193 provider
- const executeTxEthers = async () => {
- const tx = {
- to: recipientAddress,
- value: parseEther("0.01"), // Set value to 0.01 Ether
- data: "0x", // No data, as there is no contract interaction
- };
-
- setIsSending(true);
-
- try {
- const EOAprovider = await primaryWallet.connector.getProvider();
- const customProvider = new ethers.BrowserProvider(
- EOAprovider as Eip1193Provider,
- "any"
- );
-
- const signer = await customProvider.getSigner();
- const txResponse = await signer.sendTransaction(tx);
- const txReceipt = await txResponse.wait();
-
- if (txReceipt) {
- setTransactionHash(txReceipt.hash);
- } else {
- console.error("Transaction receipt is null");
- }
- } catch (error) {
- console.error("Error executing EVM transaction:", error);
- } finally {
- setIsSending(false);
- }
- };
-
- // Option 2: Send transaction using the native Particle provider
- const executeTxNative = async () => {
- try {
- const tx = {
- to: recipientAddress,
- value: parseEther("0.01"), // Set value to 0.01 Ether
- data: "0x", // No data, as there is no contract interaction
- chainId: primaryWallet.chainId, // Current chainId
- account: primaryWallet.accounts[0], // Primary account
- };
-
- setIsSending(true);
-
- const walletClient = primaryWallet.getWalletClient();
- const transactionResponse = await walletClient.sendTransaction(tx);
-
- setTransactionHash(transactionResponse);
- console.log("Transaction sent:", transactionResponse);
- } catch (error) {
- console.error("Failed to send transaction:", error);
- } finally {
- setIsSending(false);
- }
- };
-
- // Parameters for the on-ramp URL
- const fiatCoin = "USD";
- const cryptoCoin = "ETH";
- const network = "Ethereum";
- const theme = "dark";
- const language = "en";
-
- // Function to handle the on-ramp button click
- const handleOnRamp = () => {
- const onRampUrl = `https://ramp.particle.network/?fiatCoin=${fiatCoin}&cryptoCoin=${cryptoCoin}&network=${network}&theme=${theme}&language=${language}`;
- window.open(onRampUrl, "_blank");
- };
-
- // Function to copy text to clipboard
- const copyToClipboard = (text: string) => {
- navigator.clipboard.writeText(text).then(() => {
- alert("Copied to clipboard!");
- });
- };
-
- // Function to truncate Ethereum address
- const truncateAddress = (address: string) => {
- return address.slice(0, 6) + "..." + address.slice(-4);
- };
-
- return (
-
- {/* Header */}
-
-
- Particle Connect 2.0
-
- Particle Connect Quickstart— Fetch user data and send trasnactions
-
-
-
-
- {/* Display connection status */}
-
-
- Status: {connectionStatus}
-
-
-
- {isConnected ? (
- <>
-
-
-
- {isLoadingUserInfo ? (
-
Loading user info...
- ) : userInfoError ? (
-
{userInfoError}
- ) : (
- userInfo && ( // Conditionally render user info
-
-
- Name: {userInfo.name || "N/A"}
-
- {userInfo.avatar && (
-
- )}
-
- )
- )}
-
- Address: {truncateAddress(userAddress)}
- copyToClipboard(userAddress)}
- >
- 📋
-
-
-
- Chain ID: {chainId}
-
-
- Balance: {balance !== "" ? balance : "Loading..."}
-
- 🔄
-
-
-
- Buy Crypto with Fiat
-
-
-
- Disconnect
-
-
-
-
-
-
- Send a transaction
-
-
Send 0.01
-
setRecipientAddress(e.target.value)}
- className="mt-4 p-2
-
- w-full rounded border border-gray-700 bg-gray-900 text-white focus:outline-none focus:ring-2 focus:ring-purple-400"
- />
-
- {isSending ? "Sending..." : `Send 0.01 Particle provider`}
-
-
- {isSending ? "Sending..." : `Send 0.01 with ethers`}
-
- {/* Display transaction notification with the hash */}
- {transactionHash && (
-
- Transaction Hash: {transactionHash}
-
- )}
-
-
-
- >
- ) : (
-
- )}
-
-
- );
-}
-```
+Find an example of additional features like fetching and displaying user information, balances, on-ramp services, and sending transactions using either the native Particle Provider (Viem-based WalletClient) or ethers.js through an EIP-1193 provider from the [page.tsx](https://github.com/Particle-Network/particle-connectkit2.0-quickstart/blob/main/particle-connect/src/app/page.tsx) file in the demo repository.
:::tip
- A Next.js demo repository containing the above code can be found on [GitHub](https://github.com/Particle-Network/particle-connectkit2.0-quickstart).
+ A Next.js demo repository can be found on [GitHub](https://github.com/Particle-Network/particle-connectkit2.0-quickstart).
:::