Skip to content

Commit

Permalink
feat: deploying safe accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmccomish committed Mar 16, 2024
1 parent 77546d5 commit f6bd8c7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 31 deletions.
2 changes: 1 addition & 1 deletion apps/dapp/src/components/deploy-account-button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button } from "@/components/ui/button";
import { createSafe4337Account } from "@/lib/permissionless";
import { createSafe4337Account } from "@/lib/safe-account";

export function DeployAccountButton() {
return (
Expand Down
33 changes: 27 additions & 6 deletions apps/dapp/src/lib/permissionless.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { createBundlerClient, createSmartAccountClient } from "permissionless"
import { baseSepolia } from "viem/chains"
import { createPublicClient, http } from "viem"
import { createPublicClient, createWalletClient, http } from "viem"
import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico";
import { privateKeyToSimpleSmartAccount } from "permissionless/accounts";
import { privateKeyToSimpleSmartAccount, signerToSafeSmartAccount } from "permissionless/accounts";
import { privateKeyToAccount } from "viem/accounts";

// ! Dont do this in prod
const pimlicoApiKey = import.meta.env.PUBLIC_PIMLICO_API_KEY
const privateKey = import.meta.env.PUBLIC_PRIVATE_KEY

const pimlicoTransport = (version: 'v1' | 'v2') => http(`https://api.pimlico.io/${version}/${baseSepolia.id}/rpc?apikey=${pimlicoApiKey}`)

const ENTRYPOINT_ADDRESS_V07 = '0x0000000071727De22E5E9d8BAf0edAc6f37da032';
const ENTRYPOINT_ADDRESS_V06 = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
export const ENTRYPOINT_ADDRESS_V07 = '0x0000000071727De22E5E9d8BAf0edAc6f37da032';
export const ENTRYPOINT_ADDRESS_V06 = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';

// create clients --------------------------------------------

export const publicClient = createPublicClient({
transport: http(baseSepolia.rpcUrls.default.http[0])
//entryPoint: ENTRYPOINT_ADDRESS
});

export const walletClient = createWalletClient({
chain: baseSepolia,
transport: http(baseSepolia.rpcUrls.default.http[0]),
account: privateKeyToAccount(privateKey)
});

export const bundlerClient = createBundlerClient({
Expand All @@ -28,7 +34,7 @@ export const bundlerClient = createBundlerClient({

export const paymasterClient = createPimlicoPaymasterClient({
transport: pimlicoTransport('v2'),
entryPoint: ENTRYPOINT_ADDRESS_V07
entryPoint: ENTRYPOINT_ADDRESS_V06
});

// create account & account client --------------------------------------------
Expand All @@ -39,11 +45,26 @@ export const simpleAccount = await privateKeyToSimpleSmartAccount(publicClient,
entryPoint: ENTRYPOINT_ADDRESS_V07
});

export const safeAccount = await signerToSafeSmartAccount(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V06,
signer: privateKeyToAccount(privateKey),
saltNonce: 0n, // optional
safeVersion: "1.4.1",
//address: "0x...", // optional, only if you are using an already created account
})

export const smartAccountClient = createSmartAccountClient({
account: simpleAccount,
entryPoint: ENTRYPOINT_ADDRESS_V07,
chain: baseSepolia,
bundlerTransport: pimlicoTransport('v2'),
});

export const safeAccountClient = createSmartAccountClient({
account: safeAccount,
entryPoint: ENTRYPOINT_ADDRESS_V06,
chain: baseSepolia,
bundlerTransport: pimlicoTransport('v2'),
});


37 changes: 13 additions & 24 deletions apps/dapp/src/lib/safe-account.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,30 @@
import { encodeFunctionData } from "viem"
import { bundlerClient, paymasterClient, smartAccountClient } from './permissionless'

import { walletClient, publicClient } from './permissionless'

// abis --------------------------------------------

const ONIT_FACTORY_ADDRESS = '0x42ab880ea77fc7a09eb6ba0fe82fbc9901c114b6'

const createSafe4337Abi = [
{ "type": "function", "name": "createSafe4337", "inputs": [{ "name": "passkeyPublicKey", "type": "uint256[2]", "internalType": "uint256[2]" }, { "name": "nonce", "type": "uint256", "internalType": "uint256" }], "outputs": [{ "name": "onitAccountAddress", "type": "address", "internalType": "address" }], "stateMutability": "nonpayable" }
]

// formatting calls --------------------------------------------

export const createSafe4337Account = async () => {
const userOperation = await smartAccountClient.prepareUserOperationRequest({
userOperation: {
callData: formatFactoryCreateSafe4337Calldata(1n, 2n, 3n),
callGasLimit: 10000000n,
verificationGasLimit: 10000000n,
preVerificationGas: 10000000n,

}
const { request } = await publicClient.simulateContract({
account: walletClient.account,
address: ONIT_FACTORY_ADDRESS,
abi: createSafe4337Abi,
functionName: 'createSafe4337',
args: [[1n, 2n], 3n],
})
console.log({ userOperation })

// const gas = await bundlerClient.estimateUserOperationGas({
// userOperation: userOperation
// })
console.log({ request })

// console.log({ gas })

const r = await paymasterClient.sponsorUserOperation({
userOperation: userOperation,
sponsorshipPolicyId: 'sp_volatile_quasimodo'
// entryPoint: ENTRYPOINT_ADDRESS_V07
})
console.log({ r })
const deployResponse = await walletClient.writeContract(request)
console.log({ deployResponse })

return r
return deployResponse
}

const formatFactoryCreateSafe4337Calldata = (x: bigint, y: bigint, nonce: bigint) => {
Expand Down

0 comments on commit f6bd8c7

Please sign in to comment.