With native Account Abstraction, Starknet has a lot of flexibility in the management of accounts rather than having their behavior determined at the protocol level. The potential for innovation is virtually limitless leveraging the scalability and capabilities of the STARK proofs, so different use cases are, and will continue to bring different implementations of accounts to the ecosystem.
With this said different dapps, protocols, and standard contracts (like tokens) often require interaction with accounts in a predictable way, either by recognizing them or by expecting certain features.
Currently, Starknet at the protocol level requires account contracts to implement at least two entry points for being able to send transactions: __execute__
and __validate__
, but there is no mechanism (at a protocol level) for recognizing if a given contract is an account or not. Also, account implementors (like OZ, Argent, and Braavos) are adding an is_valid_signature
method to the public interface for making ecosystem interoperability easier, by allowing off-chain and on-chain signature validation from other modules.
The intention of this post is to propose defining a SNIP (SRC) for the Starknet Standard Account, addressing two issues:
- The first one: Define a minimal interface for Standard Accounts, supporting ecosystem interoperability, by making different implementations compatible at the core.
- The second one: Define a standardized application-level mechanism for recognizing Standard Accounts, supporting discoverability and interoperability.
While the Starknet protocol allows deploying accounts that will be non-standard accounts, we expect this standard to be widely adopted by account implementors, again, with the goal of supporting interoperability in the ecosystem.
After some discussion among OZ, Argent, and Braavos, the proposal for the interface is the following:
trait IStandardAccount {
fn __execute__(calls: Array<Call>) -> Array<Span<felt252>>;
fn __validate__(calls: Array<Call>) -> felt252;
// The return value is still in discussion at the moment of writing
fn is_valid_signature(message: felt252, signature: Array<felt252>) -> [bool or felt252];
}
__execute__
and __validate__
entry points are required for sending transactions at the protocol level, while is_valid_signature
is added for supporting interoperability with ecosystem dapps.
Notice that __validate_declare__
is not included, because allowing the account to declare is an extra feature we don’t consider need to be in the standard interface, and can be added separately.
The SRC will state that the Standard Account MUST also implement the ISRC5 interface:
trait ISRC5 {
fn supports_interface(interface_id: felt252) -> bool;
}
And MUST expose the IStandardAccount interface id through this. Then StandardAccounts will be discoverable by introspection.
NOTE: If bool is selected as the return value for is_valid_signature
, Accounts MUST NEVER return true from a fallback mechanism, when (if) such a mechanism is implemented for Starknet.