跳转至

Particle Network的智能钱包即服务

概览

Particle Network是一个智能钱包即服务提供商,它允许开发者通过使用可定制的模块化外部拥有账户(Externally Owned Account,简称EOA)和账户抽象(Account Abstraction,简称AA)嵌入式钱包组件来提升用户体验。

Particle智能钱包即服务堆栈的其中一个重要组件是Particle Auth,该组件可通过用户熟悉的Web2账户(例如谷歌账户、邮箱地址和电话号码)简化用户入门流程。这是通过使用基于多方计算的阈值签名方案(MPC-TSS)技术进行密钥管理来实现的。

想要了解关于Particle堆栈的完整版介绍,请参考Particle的博客文章:介绍Particle智能钱包即服务模块化堆栈

Particle通过标准EOA交互和原生ERC-4337 SimpleAccount实现支持Moonbeam、Moonriver和Moonbase Alpha测试网,从而促进全堆栈账户抽象。

具体来说,Particle Network的Moonbeam集成由以下组件组成:

  • Particle Network Wallet-as-a-Service - 这是一个由Particle Network提供的钱包即服务旗舰产品,支持由MPC-TSS支持的应用程序嵌入式钱包,从而实现无缝且类似Web2入门和交互的体验。
  • Particle Network Modular AA Stack - 除了以EOA为中心的基本交互之外(此交互默认情况下通过Particle的钱包即服务实现),Particle还具有原生模块化账户抽象堆栈,用于Moonbeam上ERC-4337账户抽象的实现。这意味着在构建支持账户抽象的应用程序时,您可以将智能账户、bundler和paymaster与Particle的钱包即服务结合使用,从而获得固有的灵活性

Particle Network Smart WaaS map

本教程中,我们将展示使用Particle Network的智能钱包即服务的分步教程。

创建应用程序

要在Moonbeam上使用Particle Network的智能钱包即服务,首先您需要通过在Particle Network数据面板创建账户并启动应用程序。

  1. 前往Particle Network数据面板,然后注册或登录

    Dashboard login

  2. 登陆后,点击Add New Project创建新项目

    Project creation

  3. 输入项目名称并点击Save保存

    Application creation

  4. 在项目的数据面板处,往下滑动找到Your Apps部分,选择iOSAndroidWeb并提供要求的信息以创建新的App

    Application creation

  5. 最后,复制Project IDClient KeyApp ID

    Application dashboard

安装依赖项

要将Particle Network集成至Moonbeam,您需要安装一系列的依赖项,具体取决于您是否要完全使用Particle的钱包即服务生成的默认EOA,或使用附加的智能账户。

无论是使用EOA还是智能合约,都需要先安装@particle-network/auth

npm install @particle-network/auth
yarn add @particle-network/auth

如果您想要原生使用ERC-4337账户抽象,还需要安装@particle-network/aa

npm install @particle-network/aa
yarn add @particle-network/aa

创建抽象账户后,您需要将其传给提供商。您可以使用Particle或任何EVM钱包提供商。如果您使用的是Particle提供商,您需要安装@particle-network/provider

npm install @particle-network/provider
yarn add @particle-network/provider

配置Particle Network

创建好应用程序并安装完依赖项后,您可以开始配置项目了。

配置项目需要执行以下步骤:

  1. @particle-network/auth导入ParticleNetwork
  2. 您将在下一个步骤用到Moonbeam的链名称和ID,因此您需要先从@particle-network/chains导入Moonbeam
  3. 使用您的项目凭据以及Moonbeam的链名称和ID初始化ParticleNetwork,并且您可以在这里选择配置钱包显示和安全设置

    注意事项

    您可以使用dotenv安全存储您的项目凭证。

"use client";

import React from "react";
import { ConnectKitProvider, createConfig } from "@particle-network/connectkit";
import { authWalletConnectors } from "@particle-network/connectkit/auth";
import { moonbeam } from "@particle-network/connectkit/chains";
import { wallet, EntryPosition } from "@particle-network/connectkit/wallet";
import { aa } from "@particle-network/connectkit/aa";

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: [
    wallet({
      entryPosition: EntryPosition.BR, // Positions the modal button at the bottom right on login
      visible: true, // Determines if the wallet modal is displayed
    }),
    aa({
      name: "SIMPLE",
      version: "2.0.0",
    }),
  ],
  chains: [moonbeam],
});

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

创建ERC-4337账户抽象

如果您想要使用ERC-4337账户抽象,您需要执行一些额外的步骤:

  1. @particle-network/aa@particle-network/auth导入SmartAccount
  2. 使用您在上述步骤创建的particle实例,初始化ParticleProvider以处理钱包连接请求
  3. 使用提供商、项目凭证以及账户抽象实现和配置来初始化SmartAccount。对于Moonbeam来说,您需要使用simple实现并传入Moonbeam链ID
  4. 启用ERC-4337模式,指定SIMPLE实现

到现在为止,您已经注册并创建了一个应用程序,安装了所有所需依赖项,同时配置了ParticleNetworkSmartAccount(若适用)。

包装EIP-1193提供商

如果您要与Ethers.jsWeb3.js等以太坊库交互,您可以将账户抽象包装在自定义的提供商中。

为此,您需要执行以下步骤:

  1. '@particle-network/aa'导入AAWrapProvider
  2. 自行选择导入所需要的库
  3. 使用上述步骤中创建的账户抽象初始化AAWrapProvider
  4. 使用所选择的库和AAWrapProvider包装EIP-1193提供商


使用示例

完成上述操作后,您可以根据上述类似步骤使用Particle Network,如下方示例应用程序所示:

具体来说,该应用程序通过社交登录在Moonbeam主网上创建一个智能账户,然后使用该应用程序发送一笔0.001 GLMR的测试交易。

"use client";
import React, { useEffect, useState } from "react";

// Particle imports
import {
  ConnectButton,
  useAccount,
  usePublicClient,
  useSmartAccount,
} from "@particle-network/connectkit";

// Eip1193 and AA Provider
import { AAWrapProvider, SendTransactionMode } from "@particle-network/aa"; // Only needed with Eip1193 provider
import { ethers, type Eip1193Provider } from "ethers";
import { formatEther, parseEther } from "viem";

export default function Home() {
  const { isConnected, chain } = useAccount();
  const publicClient = usePublicClient();
  const smartAccount = useSmartAccount();

  const [userAddress, setUserAddress] = useState<string>("");
  const [balance, setBalance] = useState<string | null>(null);
  const [recipientAddress, setRecipientAddress] = useState<string>("");
  const [transactionHash, setTransactionHash] = useState<string | null>(null);

  // Init custom provider with gasless transaction mode
  const customProvider = smartAccount
    ? new ethers.BrowserProvider(
        new AAWrapProvider(
          smartAccount,
          SendTransactionMode.Gasless
        ) as Eip1193Provider,
        "any"
      )
    : null;

  /**
   * Fetches the balance of a given address.
   * @param {string} address - The address to fetch the balance for.
   */
  const fetchBalance = async (address: string) => {
    try {
      const balanceResponse = await publicClient?.getBalance({
        address: address as `0x${string}`,
      });
      if (balanceResponse) {
        const balanceInEther = formatEther(balanceResponse).toString();
        setBalance(balanceInEther);
      } else {
        setBalance("0.0");
      }
    } catch (error) {
      console.error("Error fetching balance:", error);
      setBalance("0.0");
    }
  };

  /**
   * Loads the user's account data, including address and balance.
   */
  useEffect(() => {
    const loadAccountData = async () => {
      if (isConnected && smartAccount) {
        try {
          const address = await smartAccount.getAddress();
          setUserAddress(address);
          await fetchBalance(address);
        } catch (error) {
          console.error("Error loading account data:", error);
        }
      }
    };
    loadAccountData();
  }, [isConnected, smartAccount]);

  /**
   * Sends a transaction using the ethers.js library.
   * This transaction is gasless since the customProvider is initialized as gasless
   */
  const executeTxEthers = async () => {
    if (!customProvider) return;

    const signer = await customProvider.getSigner();
    try {
      const tx = {
        to: recipientAddress,
        value: parseEther("0.01").toString(),
      };

      const txResponse = await signer.sendTransaction(tx);
      const txReceipt = await txResponse.wait();

      setTransactionHash(txReceipt?.hash || null);
    } catch (error) {
      console.error("Failed to send transaction using ethers.js:", error);
    }
  };

  return (
    <div className="container min-h-screen flex flex-col justify-center items-center mx-auto gap-4 px-4 md:px-8">
      <div className="w-full flex justify-center mt-4">
        <ConnectButton label="Click to login" />
      </div>
      {isConnected && (
        <>
          <div className="border border-purple-500 p-6 rounded-lg w-full">
            <h2 className="text-lg font-semibold mb-2 text-white">
              Address: <code>{userAddress || "Loading..."}</code>
            </h2>
            <h2 className="text-lg font-semibold mb-2 text-white">
              Balance: {balance || "Loading..."} {chain?.nativeCurrency.symbol}
            </h2>
            <input
              type="text"
              placeholder="Recipient Address"
              value={recipientAddress}
              onChange={(e) => setRecipientAddress(e.target.value)}
              className="mt-4 p-3 w-full rounded border border-gray-700 bg-gray-900 text-white focus:outline-none"
            />
            <button
              className="bg-purple-600 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded mt-4"
              onClick={executeTxEthers}
              disabled={!recipientAddress}
            >
              Send 0.001 {chain?.nativeCurrency.name}
            </button>
            {transactionHash && (
              <p className="text-green-500 mt-4">
                Transaction Hash: {transactionHash}
              </p>
            )}
          </div>
        </>
      )}
    </div>
  );
}

要查看包含上述代码的完整演示代码库,请访问particle-moonbeam-demo GitHub repository

这就是关于Particle智能钱包即服务堆栈以及如何在Moonbeam上开始使用Particle的简要介绍。想要了解更多信息,请参考Particle Network文档网站

本网站的所有信息由第三方提供,仅供参考之用。Moonbeam文档网站(https://docs.moonbeam.network/)上列出和描述的任何项目与Moonbeam立场无关。Moonbeam Foundation不保证网站信息的准确性、完整性或真实性。如使用或依赖本网站信息,需自行承担相关风险,Moonbeam Foundation不承担任何责任和义务。这些材料的所有陈述和/或意见由提供方个人或实体负责,与Moonbeam Foundation立场无关,概不构成任何投资建议。对于任何特定事项或情况,应寻求专业权威人士的建议。此处的信息可能会包含或链接至第三方提供的信息与/或第三方服务(包括任何第三方网站等)。这类链接网站不受Moonbeam Foundation控制。Moonbeam Foundation对此类链接网站的内容(包括此类链接网站上包含的任何信息或资料)概不负责也不认可。这些链接内容仅为方便访客而提供,Moonbeam Foundation对因您使用此信息或任何第三方网站或服务提供的信息而产生的所有责任概不负责。
最后更新: May 22, 2024