How to use a Capsule signer with permissionless.js
Capsule offers a signing solution enabling the creation of secure, embedded MPC wallets accessible via email or social login. These wallets, compatible across different applications, offer portability, recoverability, and programmability, eliminating the need for users to establish separate signers or contract accounts for each application.
Setup
To use Capsule with permissionless.js, first create an application that integrates with Capsule.
- Refer to the Capsule documentation site for instructions on setting up an application with the Capsule.
- For a quick start, Capsule provides an example hub, available here.
Integration
Integrating permissionless.js with Capsule is straightforward after setting up the project. Capsule provides an Externally Owned Account (EOA) wallet to use as a signer with permissionless.js accounts.
Create the Capsule signer
After following the Capsule documentation, you will have access to a CapsuleWeb3Provider
object that you can pass as an owner to createeSmartAccountClient
:
import Capsule from "@usecapsule/web-sdk"
import { createCapsuleViemClient } from "@usecapsule/viem-v2-integration"
import { http } from "viem"
import { sepolia } from "viem/chains"
// Param options here will be specific to your project. See the Capsule docs for more info.
const capsule = new Capsule(env, apiKey)
// Follow the Capsule docs for more instructions on creating the Viem client https://docs.usecapsule.com/integration-guide/signing-transactions
const smartAccountOwner = createCapsuleViemClient(capsule, {
chain: sepolia,
transport: http("https://rpc.ankr.com/eth_sepolia"),
})
Use with permissionless.js
import { createSmartAccountClient } from "permissionless"
import { toSimpleSmartAccount } from "permissionless/accounts"
import { createPublicClient, http } from "viem"
import { sepolia } from "viem/chains"
import { createPimlicoClient } from "permissionless/clients/pimlico"
import { entryPoint07Address } from "viem/account-abstraction"
const publicClient = createPublicClient({
chain: sepolia, // or whatever chain you are using
transport: http(),
})
const pimlicoUrl = `https://api.pimlico.io/v2/sepolia/rpc?apikey=<PIMLICO_API_KEY>`
const pimlicoClient = createPimlicoClient({
transport: http(pimlicoUrl),
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
})
const simpleSmartAccount = await toSimpleSmartAccount({
owner: smartAccountOwner,
client: publicClient,
entryPoint: {
address: entryPoint07Address,
version: "0.7",
},
})
const smartAccountClient = createSmartAccountClient({
account: simpleSmartAccount,
chain: sepolia,
bundlerTransport: http(pimlicoUrl),
paymaster: pimlicoClient,
userOperation: {
estimateFeesPerGas: async () => {
return (await pimlicoClient.getUserOperationGasPrice()).fast
},
},
})