Outside Execution

Enabling meta-transactions on Starknet

Outside Execution will work for everyone on Sepolia testnet but if you need to provide support for it in your dApp on mainnet, please reach out to us at ecosystem@argent.xyz.

Outside execution allows external contracts the ability to execute transactions from outside an account contract, thereby creating opportunities for meta-transactions, transaction scheduling (limit orders) etc.

While we wait for native paymasters on Starknet, there are certain use cases that requires giving external contracts access to execute transactions through an account contract. This is currently not possible due to the structure of the execute entrypoint in existing account contracts.

In a bid to prevent re-entrancy attacks, the execute entrypoint prevents calls from external contracts, which means in order to enable meta-transactions we need to introduce a new entrypoint that allows calls from external contracts, execute_from_outside.

fn execute_from_outside(
    ref self: ContractState, outside_execution: OutsideExecution, signature: Array<felt252>
) -> Array<Span<felt252>>

Studying the interface above, we notice the execute_from_outside entrypoint requires two

paramenters:

  • The OutsideExecution struct

  • A valid signature

In the next section, let's take a look at how you can execute "outside transactions" as an application builder.

Executing from Outside as a dApp developer

To get started executing outside transactions:

  1. Build your OutsideExecution Struct

An OutsideExecution struct contains the details of the transaction to be executed from outside.

struct OutsideExecution {
    caller: ContractAddress,
    nonce: felt252,
    execute_after: u64,
    execute_before: u64,  
    calls: Span<Call>
}

For an outside execution transaction to be valid, it needs to contain a caller (the address allowed to call the execute_from_outside), a nonce (a unique value to prevent signature reuse), an execute_after value (specifying the time after which the transaction can succeed), an execute_before value (specifying the time before which the transaction should succeed), and finally an array of calls to be executed.

2. Sign it using EIP-712 typed data hashing

The signature signs over the EIP712 message encoding of outside_execution. Dapps are encouraged to request signatures following the EIP712 standard for a clearer UX.

Refer to the standard here.

  1. Call the execute_from_outside method on the account contract

To do this we advise that you first verify that the account contract being interacted with has support for outside execution. To do this, simply call the supports_interface method on the account contract:

let acccount = IErc165Dispatcher { contract_address: acount_address };
let is_supported = account.supports_interface(ERC165_OUTSIDE_EXECUTION_INTERFACE_ID);

The interface ID to be queried for is: 0x68cfd18b92d1907b8ba3cc324900277f5a3622099431ea85dd8089255e4181.

If it returns true, then you can go ahead to call the execute_from_outside method:

let acccount = IOutsideExecutionDispatcher { contract_address: acount_address };

Last updated