Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Coinbase Smart Wallet #224

Open
jacobgoren-sb opened this issue Jun 12, 2024 · 2 comments
Open

Support Coinbase Smart Wallet #224

jacobgoren-sb opened this issue Jun 12, 2024 · 2 comments

Comments

@jacobgoren-sb
Copy link

jacobgoren-sb commented Jun 12, 2024

Hi,

I want to deploy a Safe from a Smart Wallet using keys.coinbase.com

Copy link
Contributor

Hey can you share the full error and code on how you are trying to deploy from safe?

@jacobgoren-sb
Copy link
Author

I apologize I want to do it the other way:

From Coinbase Smart Wallet deploy a safe:

Here is the component:

//SmartWalletToSafe.tsx

import React, { useState } from "react";
import { useAccount } from "wagmi";
import { usePublicClient } from "wagmi";
import { useWalletClient } from "wagmi";
import { useEthersSigner } from "~~/hooks/useEthersSigner";
import { createSafe } from "~~/utils/createSafe";

export const SmartWalletToSafe: React.FC = () => {
  const { address } = useAccount();
  const [saltNonce] = useState<string>("ghvhgvh");
  const [smartAccountAddress, setSmartAccountAddress] = useState<`0x${string}`>();
  const { isConnected } = useAccount();
  const publicClient = usePublicClient();
  const ethersSigner = useEthersSigner();
  const { data: walletClient } = useWalletClient();

  async function createSafeAction() {
    if (isConnected && walletClient && publicClient && ethersSigner && address) {
      createSafe(isConnected, walletClient, publicClient, ethersSigner, saltNonce, setSmartAccountAddress);
    }
  }

  return (
    <div className="p-4 bg-base-200 rounded-lg shadow-md">
      <h2 className="text-2xl font-bold mb-4">Create Safe Account From a Smart Wallet</h2>
      <button type="button" className="btn btn-primary" onClick={createSafeAction}>
        Create Safe
      </button>
      {smartAccountAddress}
    </div>
  );
};




// Filename: createSafe.ts
import { bundlerUrl, paymasterClient, safeVersionString } from "./pimlicoClients";
import { ethers } from "ethers";
import { walletClientToSmartAccountSigner } from "permissionless";
import { ENTRYPOINT_ADDRESS_V06, createSmartAccountClient } from "permissionless";
import { signerToSafeSmartAccount } from "permissionless/accounts";
import { http, keccak256, toBytes } from "viem";
import { Account, Chain, Client, Transport, WalletClient } from "viem";
import { base } from "wagmi/chains";

export async function getSmartAccountClients(
  walletClient: WalletClient<Transport, Chain, Account>,
  publicClient: Client<Transport, Chain>,
  saltNonce: string,
): Promise<{ safeSmartAccountClient: any; smartAccountClient: any }> {
  const customSigner = walletClientToSmartAccountSigner(walletClient);
  const safeSmartAccountClient = await signerToSafeSmartAccount(publicClient, {
    entryPoint: ENTRYPOINT_ADDRESS_V06,
    signer: customSigner,
    safeVersion: safeVersionString,
    saltNonce: BigInt(keccak256(toBytes(saltNonce))),
  });

  const smartAccountClient = createSmartAccountClient({
    account: safeSmartAccountClient,
    chain: base,
    bundlerTransport: http(bundlerUrl),
    middleware: {
      sponsorUserOperation: paymasterClient.sponsorUserOperation,
    },
  });

  return { safeSmartAccountClient, smartAccountClient };
}

export async function createSafe(
  isConnected: boolean,
  walletClient: WalletClient<Transport, Chain, Account>,
  publicClient: Client<Transport, Chain>,
  ethersSigner: ethers.Signer,
  saltNonce: string,
  setSmartAccountAddress?: (address: `0x${string}`) => void,
): Promise<void> {
  if (isConnected && walletClient && publicClient && ethersSigner) {
    const { safeSmartAccountClient, smartAccountClient } = await getSmartAccountClients(
      walletClient,
      publicClient,
      saltNonce,
    );

    const txHash = await smartAccountClient.sendTransaction({
      to: safeSmartAccountClient.address,
      value: 0n,
      data: "0x",
    });
    if (setSmartAccountAddress) {
      setSmartAccountAddress(safeSmartAccountClient.address as `0x${string}`);
    }
    console.log("Transaction Hash: ", txHash);
  }
}
Screenshot 2024-06-14 at 10 57 12 AM Screenshot 2024-06-14 at 10 56 19 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants