How to use the Safe7579 with Permissionless.js
Permissionless.js (opens in a new tab) is one of the most widely used account SDKs. It is a typescript library that makes it easy to build with smart accounts. This guide will show you how to use the Safe7579 with permissionless.js.
Install the packages
npm i viem permissionless
Import the required packages
import { sepolia } from 'viem/chains'
import { erc7579Actions } from 'permissionless/actions/erc7579'
import { signerToSafeSmartAccount } from 'permissionless/accounts'
import { createPublicClient, getContract, http, parseEther } from 'viem'
import {
ENTRYPOINT_ADDRESS_V07,
createSmartAccountClient,
} from 'permissionless'
import {
createPimlicoBundlerClient,
createPimlicoPaymasterClient,
} from 'permissionless/clients/pimlico'
Create the clients
Create the smart account client and the bundler client.
export const publicClient = createPublicClient({
transport: http('https://rpc.ankr.com/eth_sepolia'),
})
export const pimlicoBundlerClient = createPimlicoBundlerClient({
transport: http('https://api.pimlico.io/v2/sepolia/rpc?apikey=API_KEY'),
entryPoint: ENTRYPOINT_ADDRESS_V07,
})
Create the signer
The Safe account will need to have a signer to sign user operations. In permissionless.js, the default Safe account validates ECDSA signatures.
For example, to create a signer based on a private key:
import { privateKeyToAccount } from 'viem/accounts'
const signer = privateKeyToAccount('0xPRIVATE_KEY')
Create the Safe account
Create the Safe account object using the signer.
const safeAccount = await signerToSafeSmartAccount(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V07,
signer: signer,
saltNonce: 0n, // optional
safeVersion: '1.4.1',
address: '0x...', // optional, only if you are using an already created account
})
Create the smart account client
The smart account client is used to interact with the smart account.
const smartAccountClient = createSmartAccountClient({
account: safeAccount,
entryPoint: ENTRYPOINT_ADDRESS_V07,
chain: sepolia,
bundlerTransport: http(
'https://api.pimlico.io/v2/sepolia/rpc?apikey=API_KEY',
),
middleware: {
gasPrice: async () => {
return (await pimlicoBundlerClient.getUserOperationGasPrice()).fast
},
},
}).extend(erc7579Actions({ entryPoint: ENTRYPOINT_ADDRESS_V07 }))
Use the account
Now that you have created the smart account client, you can use it to interact with the Safe account. For example, you can install an executor as shown below.
const ownableExecutorModule = '0xc98B026383885F41d9a995f85FC480E9bb8bB891'
const moduleData = encodePacked(
['address'],
['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'],
)
const userOpHash = await smartAccountClient.installModule({
type: 'executor',
address: ownableExecutorModule,
context: moduleData,
})
const receipt = await pimlicoBundlerClient.waitForUserOperationReceipt({
hash: userOpHash,
})