Human approval for AI agent actions
This page describes a setup, where an autonomous agent proposes transactions, and one or more human signers approve and execute the transaction.
This setup benefits from increased security, as the Smart Account can not be compromised by convincing the agent to execute a malicious transaction.
On the other hand, it can take minutes or hours to collect the necessary approvals, which reduces the agility of this setup.
Setup the Smart Account
For this setup, we recommend a 2-out-of-3, 3-out-of-5, or 5-out-of-7 threshold. The important considerations are:
- The AI agent should be one signer
- The threshold should be two more, so at least one human approval is required
- The amount of signers should be higher than the threshold to make sure the Safe Smart Account is functional when one key is lost
Here is an example setup:
Deploy Safe
You can add the AI agent as a signer in the Safe Wallet (opens in a new tab).
You can also setup the Safe Smart Account programmatically like this using the Safe Protocol Kit:
_16import Safe from '@safe-global/protocol-kit'_16_16const AGENT_ADDRESS = // ..._16const AGENT_PRIVATE_KEY = // ..._16const HUMAN_SIGNER_1_ADDRESS = // ..._16const HUMAN_SIGNER_2_ADDRESS = // ..._16const RPC_URL = 'https://rpc.ankr.com/eth_sepolia'_16_16const newSafe = await Safe.init({_16 provider: RPC_URL,_16 signer: AGENT_PRIVATE_KEY,_16 safeOptions: {_16 owners: [AGENT_ADDRESS, HUMAN_SIGNER_1_ADDRESS, HUMAN_SIGNER_2_ADDRESS],_16 threshold: 2_16 }_16})
Here, the AI agent creates the Safe Smart Account and adds two human signers for a 2-out-of-3 setup. The Smart Account will be deployed when the first transaction is executed.
Assemble and propose a transaction
The AI agent can now propose transactions. We recommend sending the transactions to the Safe Transaction Service. By this, you make sure that the transactions show up in the Safe Wallet interface and can easily be checked, approved and executed by the human signers.
You can use the API Kit to propose transactions to the Safe Transaction Service.
A simple example transaction to the zero address can be proposed like this:
_29import SafeApiKit from '@safe-global/api-kit'_29_29const apiKit = new SafeApiKit({_29 chainId: 11155111n_29})_29_29const tx = await newSafe.createTransaction({_29 transactions: [_29 {_29 to: '0x0000000000000000000000000000000000000000',_29 data: '0x',_29 value: '0'_29 }_29 ]_29})_29_29// Every transaction has a Safe (Smart Account) Transaction Hash different than the final transaction hash_29const safeTxHash = await newSafe.getTransactionHash(tx)_29// The AI agent signs this Safe (Smart Account) Transaction Hash_29const signature = await newSafe.signHash(safeTxHash)_29_29// Now the transaction with the signature is sent to the Transaction Service with the Api Kit:_29await apiKit.proposeTransaction({_29 safeAddress: safeAddress,_29 safeTransactionData: tx.data,_29 safeTxHash,_29 senderSignature: signature.data,_29 senderAddress: AGENT_ADDRESS_29})
Approve and execute the transactions
The transactions will now show up in the transaction interface of the Safe Wallet (opens in a new tab). The human signers now have to connect their Metamask, and approve and/or execute the transactions with a click. They can also use the Mobile App (opens in a new tab) to sign the transactions.
In the Safe Wallet, the human signers will see the transaction in the queued transaction view:
And can either add a signature or execute the transaction when enough signatures were collected:
Next steps
Now your AI agent is equipped with a Safe Smart Account and you are in full control of the transactions. We are exited to see what you will build.
If you have a technical question, feel free to reach out on Stack Exchange (opens in a new tab) with the safe-core tag.