Migrate to v5
This guide references the major changes between v4 and v5 to help those migrating an existing app.
Removing SafeFactory
class
The SafeFactory
class, previously used for deploying Safes, has been removed. The functionality to deploy Safes is now directly available in the Safe
class through the new createSafeDeploymentTransaction
method.
Old Method Using SafeFactory
_24// old v4 code_24import { SafeFactory, SafeAccountConfig } from '@safe-global/protocol-kit'_24_24const safeFactory = await SafeFactory.init({_24 provider,_24 signer,_24 safeVersion // Optional_24})_24_24const safeAccountConfig: SafeAccountConfig = {_24 owners: ['0x...', '0x...', '0x...'],_24 threshold: 2_24}_24_24const protocolKit = await safeFactory.deploySafe({_24 safeAccountConfig,_24 saltNonce // Optional_24})_24_24// Confirm the Safe is deployed and fetch properties_24console.log('Is Safe deployed:', await protocolKit.isSafeDeployed())_24console.log('Safe Address:', await protocolKit.getAddress())_24console.log('Safe Owners:', await protocolKit.getOwners())_24console.log('Safe Threshold:', await protocolKit.getThreshold())
New Method Using Safe
class
_45// new v5 code_45import Safe, { PredictedSafeProps } from '@safe-global/protocol-kit'_45_45const predictedSafe: PredictedSafeProps = {_45 safeAccountConfig: {_45 owners: ['0x...', '0x...', '0x...'],_45 threshold: 2_45 },_45 safeDeploymentConfig: {_45 saltNonce, // Optional_45 safeVersion // Optional_45 }_45}_45_45let protocolKit = await Safe.init({_45 provider,_45 signer,_45 predictedSafe_45})_45_45// you can predict the address of your Safe if the Safe version is `v1.3.0` or above_45const safeAddress = await protocolKit.getAddress()_45_45const deploymentTransaction = await protocolKit.createSafeDeploymentTransaction()_45_45// Execute this transaction using the integrated signer or your preferred external Ethereum client_45const client = await protocolKit.getSafeProvider().getExternalSigner()_45_45const txHash = await client.sendTransaction({_45 to: deploymentTransaction.to,_45 value: BigInt(deploymentTransaction.value),_45 data: deploymentTransaction.data as `0x${string}`,_45 chain: sepolia_45})_45_45const txReceipt = await client.waitForTransactionReceipt({ hash: txHash })_45_45// Reconnect to the newly deployed Safe using the protocol-kit_45protocolKit = await protocolKit.connect({ safeAddress })_45_45// Confirm the Safe is deployed and fetch properties_45console.log('Is Safe deployed:', await protocolKit.isSafeDeployed())_45console.log('Safe Address:', await protocolKit.getAddress())_45console.log('Safe Owners:', await protocolKit.getOwners())_45console.log('Safe Threshold:', await protocolKit.getThreshold())
Predict the Safe Address
You can predict the address of a Safe account before its deployment, as long as you are using Safe v1.3.0
or greater, by replacing the SafeFactory.predictSafeAddress
method with the Safe.getAddress
method:
_10// old v4 code_10const predictedSafeAddress = await safeFactory.predictSafeAddress(_10 safeAccountConfig,_10 saltNonce // optional_10)_10_10// new v5 code_10const predictedSafeAddress = await protocolKit.getAddress()
Migration Steps
- Remove any import or reference of the
SafeFactory
class from your code. - Replace the
SafeFactory.deploySafe
method with theSafe.createSafeDeploymentTransaction
method where necessary. You can use your Ethereum client to execute this deployment transaction. - To predict the Address of your Safe Account, replace the
SafeFactory.predictSafeAddress
method with theSafe.getAddress
method. - After the deployment transaction has been executed, it is necessary to reconnect the Protocol Kit instance to the newly created Safe address by using the
connect
method.
The removal of SafeFactory
means there’s one less class to initialize and manage within your project. You can now directly use the Safe
class to handle all operations related to Safes, including their deployment.