Skip to content

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

SimpleAccount
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
		},
	},
})