Closed11

AlchemyのAccount Abstraction Kitを導入する

naoto.a.kimuranaoto.a.kimura

ライブラリを追加

pnpm install @alchemy/aa-alchemy @alchemy/aa-accounts @alchemy/aa-core viem

package.json

  "dependencies": {
    "@alchemy/aa-accounts": "^0.2.0",
    "@alchemy/aa-alchemy": "^0.2.0",
    "@alchemy/aa-core": "^0.2.0",
    "next": "12.1.2",
    "openai": "^4.0.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "viem": "^1.18.6"
  },
naoto.a.kimuranaoto.a.kimura

Providerを取得する:

import {
  LightSmartContractAccount,
  getDefaultLightAccountFactoryAddress,
} from "@alchemy/aa-accounts"
import { AlchemyProvider } from "@alchemy/aa-alchemy"
import { LocalAccountSigner, type SmartAccountSigner } from "@alchemy/aa-core"
import { sepolia } from "viem/chains"

export const getProvider = async () => {
  const chain = sepolia
  const PRIVATE_KEY = process.env.NEXT_PUBLIC_LIGHT_ACCOUNT_OWNER_PRIVATE_KEY as `0x${string}`
  const ALCHEMY_API_KEY = process.env.NEXT_PUBLIC_ALCHEMY_API_KEY_SEPOLIA
  // https://docs.alchemy.com/reference/eth-supportedentrypoints
  const ENTRYPOINT_ADDRESS = "5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" as `0x${string}`

  const eoaSigner: SmartAccountSigner = LocalAccountSigner.privateKeyToAccountSigner(PRIVATE_KEY)

  // Create a provider with your EOA as the smart account owner, this provider is used to send user operations from your smart account and interact with the blockchain
  const provider = new AlchemyProvider({
    rpcUrl: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, // or replace with your Alchemy API key, you can get one at https://dashboard.alchemy.com/
    chain,
    // Entrypoint address, you can use a different entrypoint if needed, check out https://docs.alchemy.com/reference/eth-supportedentrypoints for all the supported entrypoints
    entryPointAddress: ENTRYPOINT_ADDRESS,
  }).connect(
    (rpcClient) =>
      new LightSmartContractAccount({
        entryPointAddress: ENTRYPOINT_ADDRESS,
        chain: rpcClient.chain,
        owner: eoaSigner,
        factoryAddress: getDefaultLightAccountFactoryAddress(rpcClient.chain), // Default address for Light Account on Sepolia, you can replace it with your own.
        rpcClient,
      })
  )

  return provider
}
naoto.a.kimuranaoto.a.kimura

Providerを利用して、UserOperationを送る:

import { SendUserOperationResult } from "@alchemy/aa-core"
import { parseEther } from "viem"
import { getProvider } from "./getProvider"

export const sendUserOperation = async () => {
  const provider = await getProvider()
  provider.getAddress().then((address: string) => console.log(address))

  const targetAddress = "56a4975de8F187667AfDd1DBde72cf6CF88BfBb4" as `0x${string}`
  const amountToSend: bigint = parseEther("0.0001")

  const result: SendUserOperationResult = await provider.sendUserOperation({
    target: targetAddress,
    data: "0x",
    value: amountToSend,
  })

  console.log("User operation result: ", result)
  console.log("\nWaiting for the user operation to be included in a mined transaction...")

  const txHash = await provider.waitForUserOperationTransaction(result.hash as `0x${string}`)
  console.log("\nTransaction hash: ", txHash)

  const userOpReceipt = await provider.getUserOperationReceipt(result.hash as `0x${string}`)
  console.log("\nUser operation receipt: ", userOpReceipt)

  const txReceipt = await provider.rpcClient.waitForTransactionReceipt({
    hash: txHash,
  })
  console.log("\nTransaction receipt: ", txReceipt)
}
naoto.a.kimuranaoto.a.kimura

sendUserOperationの使い方(公式マニュアル

provider.sendUserOperation({
  data: "0xCalldata",
  target: "0xTarget",
  value: 0n,
});
  • target: Address - the target of the call (equivalent to to in a transaction)
    • 実行したいコントラクトのアドレス
    • 例)0x54571Bee711bf03269f65D379fDE3ff078d6F786
      • 注)先頭に0xが必要
  • data: Hex - can be either 0x or a call data string
    • 実行したいコントラクトおよび関数の情報。例えば viem を利用する場合は下記のように記載する
data: encodeFunctionData({
  abi: AlchemyTokenAbi,
  functionName: "mint",
  args: [await provider.getAddress()],
})
  • value?: bigint - optionally, set the value in wei you want to send to the target
naoto.a.kimuranaoto.a.kimura

ここでWeb3AuthのSDKがRact17に対応していないことがわかったので、泣く泣くReact18にUpdate

error - ./node_modules/.pnpm/@web3auth+ui@7.1.0_@babel+runtime@7.23.2_react-dom@17.0.2_react@17.0.2/node_modules/@web3auth/ui/dist/index.js:5:0
Module not found: Can't resolve 'react-dom/client'

Import trace for requested module:
./node_modules/.pnpm/@web3auth+modal@7.1.1_@babel+runtime@7.23.2_@solana+web3.js@1.87.5_@walletconnect+sign-client_4wsnbkubynkkjxhvwtcle7i5g4/node_modules/@web3auth/modal/dist/modal.esm.js
./src/core/Web3Auth.ts
./src/core/Provider.ts
./src/core/sendUserOperation.ts
./src/components/Header.tsx
./src/pages/index.tsx

https://nextjs.org/docs/messages/module-not-found
naoto.a.kimuranaoto.a.kimura

Web3AuthでSepoliaに対応したインスタンスを作成

const getWeb3Auth = () => {
  const web3auth = new Web3Auth({
    clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
    web3AuthNetwork: "sapphire_mainnet", // Web3Auth Network
    chainConfig: {
      chainNamespace: "eip155",
      chainId: "0x11155111",
      rpcTarget: "https://sepolia.infura.io/v3/",
      displayName: "Sepolia test network",
      blockExplorer: "https://sepolia.etherscan.io",
      ticker: "SepoliaETH",
      tickerName: "Sepolia",
    },
  })
  return web3auth
}

コンストラクタに設定する内容:https://web3auth.io/docs/sdk/pnp/web/modal/initialize#adding-a-custom-chain-configuration

naoto.a.kimuranaoto.a.kimura

メモ:Providerコントラクトウォレットからの送金を、EOAまたはweb3authの署名によってキックしている

このスクラップは2023/11/26にクローズされました