Posting transactions through the API is very much worth the effort, especially if you need to generate transactions programmatically, and/or use complex operations like you imply.
First, you should know how to build a transaction on EVM networks using any web3 library of choice. You can find many examples for your chosen language and library online, so I will consider that out of scope for this question.
Once you can generate a transaction locally, you can post the details directly to the TXS
(Note: Ignore the Gas estimation section and the "Lazy way" of signing the txn. Sign the message with a valid key (signer or delegate) and leave gas at 0, which will be calculated at execute time. The core concepts in the doc are still valid.)
Posting this calldata directly to
execTransaction() would require that everyone sign the transaction offline, and provide those signatures along with the transaction data. It's an option available to you, but I personally find it more convenient to use the Safe API to submit and the UI for other owners to sign.
The Transaction Builder is a slightly different beast. While typical Multicall contracts simply accept an array of calldata, the deployed MultiSend contract requires more transaction metadata and has its own rules on how transaction data should be formatted.
It's not openly and definitively documented very well as far as I can tell, but the gist is that you generate one or more "Meta Transactions" (a keccak packed object comprising of a uint8
operation (just an Enum of
delegatecall, but since the current contract doesn't accept
delegatecalls, this should always be 0), address
calldata length, and bytes
calldata), then concatenate them together to serve as the argument for the contract's
There are several implementations that may help you get started:
For instance, if you're using Ethers.js, Safe has an entire MultiSend library.
The Safe Contracts repo has some generic TypeScript code
I was able to find a Python implementation, also in Safe's repo.
With some work, you could extract the logic to any backing library or language.