I was trying to use @safe-global modules but found that in the protocol kit, only Ethers.js (<v6) and Web3.js are supported. I tend to use Viem and Wagmi because of their advantages in development. Is there any ViemAdapter for @safe-global in development or released by someone else?

Ideal scenario would be to be able to use Viem with its advantages with @safe-global SDK and the Web3AuthModalPack. Open to contribute to the safe if needed.

  • In theory there is no issue with having a ViemAdapter included in the Safe{Core} SDK, but there is currently no short-term plan to implement it as the team has other priorities at this moment. Of course, feel free to contribut to the repo if you like, we would appreciate that a lot :)
    – Germán
    Nov 8, 2023 at 13:13

1 Answer 1


I've started an unofficial Safe library for Viem, maybe it helps in your case:


Here's an example:

import { http, createPublicClient, parseEther, createWalletClient, Hex } from 'viem'
import { goerli } from 'viem/chains'
import { publicSafeActions, walletSafeActions } from '@stauro/piggybank/actions'
import { EIP3770Address, OperationType } from '@stauro/piggybank/types'
import { ApiClient } from '@stauro/piggybank/api'
import { privateKeyToAccount } from 'viem/accounts'

const safeAddress = process.env.SAFE_ADDRESS as EIP3770Address

const publicClient = createPublicClient({
  transport: http(),
  chain: goerli,

const walletClient = createWalletClient({
  transport: http(),
  chain: goerli,
  account: privateKeyToAccount(process.env.PK as Hex),

const txData = {
  to: process.env.SAFE_TO as EIP3770Address,
  value: parseEther('0.001'),
  operation: OperationType.Call,
  gasPrice: await publicClient.getGasPrice(),

const safeTxGas = await publicClient.estimateSafeTransactionGas(txData)

const baseGas = await publicClient.estimateSafeTransactionBaseGas({ ...txData, safeTxGas })

const nonce = await publicClient.getSafeNonce()

const safeTxHash = await publicClient.getSafeTransactionHash({ ...txData, safeTxGas, baseGas, nonce })

const senderSignature = await walletClient.generateSafeTransactionSignature({ ...txData, nonce, safeTxGas, baseGas })

const apiClient = new ApiClient({ url: 'https://safe-transaction-goerli.safe.global', safeAddress })

await apiClient.proposeTransaction({
  safeTransactionData: { ...txData, safeTxGas, baseGas, nonce },
  senderAddress: walletClient.account.address,
  chainId: goerli.id,
  origin: 'Piggybank',

for now only transaction proposal works but I'm glad to add any other APIs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.