Skip to content

How to use a Fireblocks signer with permissionless.js

Fireblocks is a user-friendly platform designed for building blockchain-based products and managing digital asset operations. It uses a direct custody approach, combining high performance with zero counterparty risk and multi-layered security. The platform includes secure MPC-based digital asset wallets, a policy engine for governance and transaction rules, and comprehensive treasury management. Fireblocks' security framework features multiple layers, including MPC-CMP technology, secure enclaves, and a robust policy engine, ensuring protection against cyberattacks, internal threats, and human errors. It's widely used for various operations like treasury, trading, and managing NFTs, smart contracts, and user wallets.

Setup

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

  • Refer to the Fireblocks documentation site for instructions on setting up an application with the Fireblocks.
  • For a quick start, Fireblocks provides a guide, available here.

Integration

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

Create the Fireblocks object

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

import {
	ChainId,
	FireblocksWeb3Provider,
	type FireblocksProviderConfig,
} from "@fireblocks/fireblocks-web3-provider"
 
// Config options here will be specific to your project.  See the Fireblocks docs for more info.
const fireblocksProviderConfig: FireblocksProviderConfig = {
	apiKey: process.env.FIREBLOCKS_API_KEY,
	privateKey: process.env.FIREBLOCKS_API_PRIVATE_KEY_PATH,
	chainId: ChainId.SEPOLIA,
}
const smartAccountOwner = new FireblocksWeb3Provider(fireblocksProviderConfig)

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