Autonomous Safe Multisig Operations: How to Build Scheduled Batches and 24/7 Watchers Without Private Keys
Architectural blueprint for scheduled MultiSendCallOnly payroll, invariant guards, and non-custodial treasury surveillance.
- Automating Safe multisig operations requires zero private key custody. Event indexing and calldata generation run entirely through read-only RPCs and the Safe Transaction Service API.
- MultiSendCallOnly must always be chosen over MultiSend for automated batches. Standard MultiSend executes via DELEGATECALL, exposing the Safe internal storage to overwrite attacks if an untrusted sub-transaction is introduced.
- Because Safe batches enforce strict all-or-nothing atomicity, a single reverted sub-transaction causes error GS013 and drops the entire payout run. Pre-execution simulation on a local fork is mandatory.
- Automated batch engines must generate deterministic manifest hashes to prevent double-proposing payments when network retries occur.
Safe multisig contracts secure over one hundred billion dollars in on-chain assets. Yet when you talk to the core contributors of growing DAOs and protocols, the weekly treasury routine looks surprisingly fragile. A treasury manager copies twenty recipient addresses from a spreadsheet, pastes them into a web interface, and pings three co-signers across four time zones to approve the batch before gas prices spike.
When teams try to automate this, they often jump to the extreme opposite: they give a server-side bot a private key or install an unvetted Safe module. Both choices introduce severe security hazards. You do not need to give a server private keys to automate treasury operations. You only need to separate the preparation of data from the authority to sign it.
The Multisig Automation Dilemma
Every treasury lead wants recurring payroll and routine operational transfers to happen reliably. But the trade-off is often framed as convenience versus security. If you leave everything manual, signers get tired. They stop inspecting calldata and begin blind signing on their hardware wallets. If you automate naively by putting an externally owned account private key in an environment variable, an API leak empties the treasury.
The correct middle ground uses Safe smart accounts as they were intended: as programmable state machines. An off-chain worker can do 95 percent of the heavy lifting. It can pull approved grant milestones, calculate token balances, package calldata into an atomic batch, and submit the payload to the Safe Transaction Service. The human signers only need to verify the pre-simulated proposal and provide their cryptographic signatures.
MultiSend vs. MultiSendCallOnly: The Delegatecall Trap
When batching multiple transfers into a single transaction, developers use the Safe Protocol Kit. Behind the scenes, the Safe interacts with a helper contract. Many developers do not realize there are two distinct versions: MultiSend.sol and MultiSendCallOnly.sol. The difference between them is critical.
| Feature | MultiSend (MultiSend.sol) | MultiSendCallOnly (MultiSendCallOnly.sol) |
|---|---|---|
| Allowed Operations | Supports CALL (0) and DELEGATECALL (1) | Strictly enforces CALL (0) only |
| Execution Context | Can execute code inside Safe storage context | Restricted to target contract storage |
| Security Risk Profile | High: malicious sub-call can rewrite Safe owners | Low: eliminates storage manipulation vectors |
| Recommended Use | Complex contract deployments only | Standard automated batches, payroll, token transfers |
When a Safe executes a MultiSend batch, the Safe invokes the MultiSend contract via DELEGATECALL. This means MultiSend executes within the Safe storage. If you use standard MultiSend and one of the sub-transactions specifies OperationType.DelegateCall, that sub-transaction runs in the context of the Safe itself. A malicious or compromised target contract could overwrite the owner array, change the signature threshold, or self-destruct.
Atomic Batch Mechanics & Error GS013
Both MultiSend and MultiSendCallOnly enforce strict all-or-nothing atomicity. They loop through each packed transaction in bytes memory. If even one sub-transaction fails, the entire batch reverts. On Etherscan or block explorers, this surfaces as Safe error GS013: Safe transaction reverted.
This atomicity has major consequences for scheduled automation. Consider a monthly payroll batch with thirty contributors. If contributor number twenty-four has their address blacklisted by a stablecoin contract, or if the treasury USDC balance is ten cents short of the total sum, the entire batch of thirty transfers reverts. None of the contributors get paid, and the gas spent evaluating the preceding twenty-three transfers is lost.
import Safe from "@safe-global/protocol-kit";
import { MetaTransactionData, OperationType } from "@safe-global/types-kit";
import { encodeFunctionData, parseUnits } from "viem";
const ERC20_ABI = [
{
type: "function",
name: "transfer",
inputs: [
{ name: "recipient", type: "address" },
{ name: "amount", type: "uint256" },
],
outputs: [{ name: "", type: "bool" }],
stateMutability: "nonpayable",
},
] as const;
export async function buildPayrollBatch(
safeSdk: Safe,
tokenAddress: `0x${string}`,
payouts: Array<{ recipient: `0x${string}`; amountUsdc: string }>
) {
// Convert each transfer into an atomic CALL sub-transaction
const transactions: MetaTransactionData[] = payouts.map((p) => ({
to: tokenAddress,
value: "0",
data: encodeFunctionData({
abi: ERC20_ABI,
functionName: "transfer",
args: [p.recipient, parseUnits(p.amountUsdc, 6)],
}),
operation: OperationType.Call, // Strictly disallow DELEGATECALL
}));
// Create transaction bundle via Safe Protocol Kit
const safeTransaction = await safeSdk.createTransaction({
transactions,
onlyCalls: true, // Forces MultiSendCallOnly usage
});
return safeTransaction;
}Building an Idempotent Payroll Worker
A production automation worker must be resilient to network failures. If an automated script submits a batch proposal to the Safe Transaction Service and the HTTP request times out, did the proposal succeed or fail? If the script blindly retries, it might create a duplicate proposal with a different nonce, confusing signers and cluttering the queue.
To solve this, calculate a deterministic manifest hash before calling the API. The manifest hash is a keccak256 hash of the target Safe address, the pay period identifier, the sorted recipient addresses, and the exact token amounts. The worker records this hash in a database with a unique index. If a retry fires, the database prevents duplicate proposal jobs from spawning.
- Step 1: Ingest approved payroll records from internal database or grant registry.
- Step 2: Check treasury balances against the sum of all payouts plus a safety margin.
- Step 3: Generate the deterministic manifest hash and assert idempotency in local storage.
- Step 4: Simulate the exact batch payload on a local fork or via Tenderly simulation API.
- Step 5: Submit the staged transaction to the Safe Transaction Service API.
- Step 6: Dispatch notification to signer channels with the simulation link and manifest breakdown.
Zero-Key Monitoring and Nonce Sync
Once a batch transaction is staged in the Safe queue, it cannot execute until signers meet the required signature threshold. This creates a coordination problem. Often signers do not know an urgent transaction is waiting, or worse, they do not realize that a lower-nonce transaction has stalled the entire queue.
Safe enforces sequential nonce execution. If transaction nonce 42 is stalled because it lacks signatures, transaction nonce 43 cannot execute even if it collects all required approvals. A dedicated monitoring sentinel solves this without holding any keys.
interface SafeTransactionRecord {
safeTxHash: string;
nonce: number;
confirmationsRequired: number;
confirmations: Array<{ owner: string; submissionDate: string }>;
isExecuted: boolean;
}
export function evaluateThresholdUrgency(tx: SafeTransactionRecord): {
isUrgent: boolean;
signaturesRemaining: number;
} {
const currentSignatures = tx.confirmations ? tx.confirmations.length : 0;
const remaining = tx.confirmationsRequired - currentSignatures;
// Alert when exactly 1 signature is needed to broadcast
return {
isUrgent: remaining === 1 && !tx.isExecuted,
signaturesRemaining: remaining,
};
}The monitoring daemon polls the Safe Transaction Service endpoints or listens to WebSocket event streams. It parses the current pending queue, calculates the signatures remaining, checks whether the current nonce matches the on-chain Safe nonce, and alerts signers only when action is required.
The Production Architecture
When you step back and look at the whole system, the pattern becomes clear. You do not need to give up security to remove manual toil. By decoupling transaction construction from signing authority, your team gets the best of both worlds: automated data preparation, fork simulation, and proactive alert delivery, while the private keys remain safely locked inside your signers' hardware wallets.
If your protocol or DAO spends hours every week manually preparing MultiSend batches, or if your signers suffer from alert fatigue because they never know which pending transaction actually needs their signature, this is the exact operational architecture we deploy through our Safe Multi-Sig Payroll Batcher and Treasury Watch Sentinel.
Deploy Production Web3 AI Agents in 48 Hours
Need an autonomous multisig sentinel, anti-phishing moderation bot, or custom on-chain telemetry agent for your protocol? We build, test, and hand over production agents with zero private keys.
Related Engineering Blueprints
View AllWhy Crypto Teams Need a Dedicated AI Agent Security Budget
Web3 protocols spend millions on smart contract audits but assign zero budget to autonomous AI agents. Learn why DIY bots lead to prompt injection drainers and why an AI security budget is mandatory.
Non-Custodial Architecture: How Spellbook Deploys AI Agents Without Key Risk
A deep dive into Spellbook zero-private-key custody architecture for Web3 AI agents. Learn how we decouple LLM reasoning loops from transaction signing, enforce bounded permissions with Safe multisig and session keys, simulate execution via RPC forks, and guarantee client sovereignty.