Skip to main content

Introduction

Safe Smart Accounts is a product by Safe (formerly Gnosis Safe) that enables the creation of ERC-4337-compatible smart accounts for your users. This integration allows you to leverage the power of Account Abstraction and other Safe features within your Para-powered application.
Safe Smart Accounts use the user’s Externally Owned Account (EOA) as the smart account’s signer. This builds upon the robust smart contract infrastructure that powers the widely-used Safe wallet.

Understanding EOAs and Smart Accounts

An EOA (Externally Owned Account) is an Ethereum account controlled by a private key. Para’s embedded wallets and most external wallets (like MetaMask or Coinbase Wallet) are EOAs.EOAs differ from contract accounts, which are controlled by smart contract code and don’t have their own private key. Safe’s smart wallet is a contract account, offering enhanced capabilities such as gas sponsorship and batched transactions.
In this integration:
  • The user’s EOA (from Para) serves as the signer for their smart wallet (from Safe).
  • The smart wallet (Safe) holds all assets and submits transactions to the network.
  • The signer (Para) is responsible for producing signatures and initiating transaction flows.

Integration Steps

To create Safe smart accounts for your users with Para, follow these steps:
1

Install Dependencies

First, install the necessary dependencies:
npm install @getpara/viem-v2-integration viem @safe-global/protocol-kit @safe-global/api-kit @safe-global/safe-core-sdk-types
2

Import Required Modules

Import the necessary modules in your project:
import { createParaViemClient } from '@getpara/viem-v2-integration';
import { http, createPublicClient } from 'viem';
import { sepolia } from 'viem/chains';
import Safe, { EthersAdapter, SafeFactory } from '@safe-global/protocol-kit';
import { ethers } from 'ethers';
import { SafeAccountConfig } from '@safe-global/safe-core-sdk-types';
import { BrowserProvider, JsonRpcSigner } from 'ethers';
import type { Account, Chain, Client, Transport, WalletClient } from 'viem';

/**
* Converts a viem Wallet Client to an ethers.js Signer.
* @param client The viem WalletClient to convert.
* @returns An ethers.js JsonRpcSigner.
*/
function walletClientToSigner(client: Client<Transport, Chain, Account>): JsonRpcSigner {
const { account, chain, transport } = client;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
};
const provider = new BrowserProvider(transport, network);
const signer = new JsonRpcSigner(provider, account.address);
return signer;
}
3

Initialize Para VIEM Client

Set up the Para VIEM client:
const paraViemClient = createParaViemClient(para, {
  chain: sepolia, // Replace with your desired chain
  transport: http('https://rpc.sepolia.org'), // Replace with your RPC URL
});
4

Create Safe Account Configuration

Define the configuration for the Safe account:
const safeAccountConfig: SafeAccountConfig = {
  owners: [await paraViemClient.account.address],
  threshold: 1,
};
5

Initialize Safe SDK

Create an instance of the Safe SDK:
const ethAdapter = new EthersAdapter({
  ethers,
  signerOrProvider: walletClientToSigner(paraViemClient),
});

const safeFactory = await SafeFactory.create({ ethAdapter });
const safeSdk = await safeFactory.deploySafe({ safeAccountConfig });
6

Get Safe Address

After deploying, you can get the address of the Safe smart account:
const safeAddress = await safeSdk.getAddress();
console.log("Safe deployed at:", safeAddress);
7

Interact with the Safe Smart Account

Now you can interact with the Safe smart account using the Para VIEM client:
// Example: Send a transaction through the Safe smart account
const transaction = await paraViemClient.sendTransaction({
  account: safeAddress,
  to: '0x...',  // Recipient address
  value: 1000000000000000000n,  // 1 ETH in wei
});

console.log('Transaction hash:', transaction);
I