You are a Safe Wallet user.
You created your transaction via Safe{Wallet}.
You are about to hit “sign” and confirm on your hardware wallet.
This is a guide on how to perform a check of the transaction on your hardware wallet with a 3rd party command line tool.
For a basic guide on how to verify transaction data on e.g. Metamask or Rabby, refer to this guide.
If you can’t verify it, don’t sign it.
Security Best Practices
Multi-Device Verification
🔒 Use separate devices for enhanced security:
Sign transactions using software accounts (MetaMask, Rainbow, Rabby) on a different device than where you're using Safe Wallet
Create multi-factor authentication by combining software accounts with dedicated device accounts (Ethereum Phone, GridPlus, Hito)
A dedicated verification device provides the strongest security
Tool Selection
🛠️ Use multiple verification tools:
Transaction decoders:
@rimeissner's decoder provides readable and detailed information
Etherscan decoder, Dethcrypto tools
Simulators:
Tenderly: Use "Contracts" and "Events" tabs for detailed transaction analysis
Can run on a separate device from Safe for additional security
Hash verification:
OpenZeppelin's Safe Utils: User-friendly UI using original code
@pcaversaccio's safe-tx-hashes-util for command line verification
Contract Verification
📋 Maintain a list of trusted contracts:
Bookmark contracts you regularly interact with for quick verification
Find official contracts on Etherscan directly from project teams
Verify using multiple sources (team websites, CoinGecko, social channels)
Check for social verification signals (mutual followers on X/Warpcast)
Some apps (like CoWSwap) include contract information directly in their interface
⚠️ Key principle: Always verify transaction data across multiple tools and devices before signing. If anything seems suspicious or cannot be verified, do not sign the transaction.
Verifying data on a Hardware Wallet
Step 1: Verify transaction data in Safe{Wallet}
Before you hit sign, from the Safe{Wallet} interface, get the following and verify that this is what you expect:
to
- set to the recipient for Ether transfers, the ERC20 token contract for token transfers, or the smart contract to interact with for contract interactions.value
- usually 0 for contract interactions and > 0 for Ether transfers.data
(“Raw data”) - Use a call data decoder such as this one from Etherscan, this one from @rimeissner, or this one from @dethtools to actually check the entire call data.call_type
- Usually you should see a simple “call”. You should only see something else such as “create”, or “delegate_call” if you actually know what you are doing.nonce
- index of the next transaction you want to execute
Now you hit “sign” which sends the transaction data to your hardware wallet. (Depending on how you are connected, you first confirm via Rabby, Metamask, or the wallet you connected via WalletConnect.)
Step 2a: Verify hashed transaction data on hardware wallet
If your hardware wallet supports signing typed data via EIP712, skip to step 2b below.
Get the safe-tx-hashes-util command line tool made by @pcaversaccio.
Note that it requires a few prerequisites to be installed on your computer.
Also please familiarize yourself with the trust assumptions of the script.
Use the tool to fetch the transaction data from the Safe API and calculate
Safe transaction hash
Domain hash
Message hash
Double check the fetched transaction data
Multisig address
- your Safe addressEnsure that
to
,value
,data
,call_type
match the respective parameters of step 1 above.
Double check the calculated hashes
Ensure that the Safe transaction hash is exactly the same like
safeTxHash
from step 1 above.Verify Domain and Message hash on your hardware wallet.
ONLY when ALL of the above checks out, confirm on your hardware wallet.
In case the Safe API is currently unavailable, consider using one of the the following options to pass all transaction data manually instead of fetching them from the API:
Interactive mode of the safe-tx-hash-util tool above.
Offline mode of the safe-tx-hashes fork by Patrick Collins.
Step 2b: Verify typed data on hardware wallet
Some of the newer hardware wallets from Trezor, Ledger, GridPlus, and others display typed structured data via EIP712, or support some form of clear signing. In that case you can directly verify the transaction data on your hardware wallet:
to
Does this match
to
from step 1?Is it set to an address you recognize?
value
Does this match
value
from step 1?Is it
0
for contract interactions and the correct amount for Ether transfers?
data
(“Raw data”)Does this match
data
from step 1?
operation
Is this set to
0
? This means a simplecall
1
would mean delegatecall which is dangerous and you should check with a technical person.
nonce
Does this match
nonce
from step 1?Is this the index of the next transaction you want to execute?
safeTxGas
,baseGas
Are both
0
for your Safe with version 1.3.0 or higher? Otherwise this can be higher.
baseGas
,gasPrice
Are both
0
?
gasToken
,refundReceiver
Are both
0x0000000000000000000000000000000000000000
?
ONLY when ALL of the above checks out, confirm on your wallet.