class ape_safe.multisend.MultiSend(safe: SafeAccount | None = None, version: Version | str | None = None)

Create a sequence of calls to execute at once using eth_sendTransaction via the MultiSend contract.

Usage example:

from ape_safe import multisend
from ape import accounts

# load the safe
me = account.load("my-alias")
safe = accounts.load("my-safe")

txn = multisend.MultiSend()
txn.add(contract.myMethod, *call_args)
txn.add(contract.myMethod, *call_args)
...  # Add as many calls as desired to execute
txn.add(contract.myMethod, *call_args)
# or, using a builder pattern:
txn = multisend.MultiSend()
    .add(contract.myMethod, *call_args)
    .add(contract.myMethod, *call_args)
    ...  # Add as many calls as desired to execute
    .add(contract.myMethod, *call_args)

# Stage the transaction to publish on-chain
# NOTE: if not enough signers are available, publish to Safe API instead
receipt = txn(submitter=me)
add(call, *args, value: int = 0) MultiSend

Append a call to the MultiSend session object.

Raises:

InvalidOption – If one of the kwarg modifiers is not able to be used.

Parameters:
  • callContractMethodHandler The method to call.

  • *args – The arguments to invoke the method with.

  • value – int The amount of ether to forward with the call. Defaults to 0.

add_from_calldata(calldata: bytes) MultiSend

Decode all calls from a multisend calldata and add them to this MultiSend.

Parameters:

calldata – Calldata encoding the MultiSend.multiSend call.

add_from_receipt(receipt: ReceiptAPI) MultiSend

Append a call to the MultiSend session object from a receipt. Especially useful for more complex simulations.

Usage:

with networks.fork():
    receipt = contract.method(*args, sender=safe.address)
    assert contract.viewMethod() == ...
    batch.add_from_receipt(receipt)

batch(...)
Parameters:

receiptReceiptAPI The receipt object to pull information from for the call to add.

as_transaction(safe: SafeAccount | None = None, impersonate: bool = False, **txn_kwargs) TransactionAPI

Encode the MultiSend transaction as a TransactionAPI object, but do not execute it.

Parameters:
  • safe (Optional[SafeAccount]) – The Safe account to use for executing this batch. If not provided, then it uses value provided to __init__().

  • impersonate (bool) – Whether to mock approvals for executing this transaction.

  • **txn_kwargs – the kwargs to pass through to the transaction handler.

Returns:

TransactionAPI

classmethod inject(version: Version | str | None = None)

Create the multisend module contract on-chain, so we can use it. Must use a provider that supports debug_setCode.

Parameters:

version (Union[Version, str, None]) – The version of MultiSend/MultiSendCallOnly contract to use from SDK. Defaults to max available from SDK.

Usage example:

from ape_safe.multisend import MultiSend


@pytest.fixture(scope="session")
def multisend():
    MultiSend.inject()
    return MultiSend()