Skip to content

How to use a Web3Auth signer with permissionless.js

Web3Auth is a popular embedded wallet provider that supports social logins. While social logins are great, your users still need to onramp in order to pay for gas, which introduces significant friction.

By combining permissionless.js with Web3Auth, you can use Web3Auth to enable a smooth social login experience, while using permissionless.js accounts as the smart wallets to sponsor gas for users, batch transactions, and more.

Setup

To use Web3Auth with permissionless.js, first create an application that integrates with Web3Auth.

  • Refer to the Web3Auth documentation site for instructions on setting up an application with the Web3Auth.
  • For a quick start, Web3Auth provides example starter projects, available here.

Integration

Integrating permissionless.js with Web3Auth is straightforward after setting up the project. Web3Auth provides an Externally Owned Account (EOA) wallet to use as a signer with permissionless.js accounts.

Create the Web3Auth object

After following the Web3Auth documentation, you will have access to a web3auth object as shown below that you can pass as an owner to createeSmartAccountClient:

import { CHAIN_NAMESPACES, WEB3AUTH_NETWORK } from "@web3auth/base"
import { Web3Auth } from "@web3auth/modal"
import { EIP1193Provider } from "viem"
 
// Config options here will be specific to your project.  See the Web3Auth docs for more info.
const web3auth = new Web3Auth({
	clientId,
	chainConfig: {
		chainNamespace: CHAIN_NAMESPACES.EIP155,
		chainId: "0xaa36a7",
		rpcTarget: "https://rpc.ankr.com/eth_sepolia",
		displayName: "Sepolia Testnet",
		blockExplorer: "https://sepolia.etherscan.io",
		ticker: "ETH",
		tickerName: "Ethereum",
	},
	uiConfig: {},
	web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
})
 
// Get the Provider and EOA address (this will be the address of the signer) from Web3Auth
const smartAccountOwner = web3auth.provider as EIP1193Provider
 
if (!smartAccountOwner) {
	throw new Error("No provider found")
}

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

For a full example, see the example permissionless + Web3Auth app.