-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(accounts): add interfaces and mock impls for account abstraction #18404
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
syntax = "proto3"; | ||
|
||
package cosmos.accounts.interfaces.account_abstraction.v1; | ||
|
||
import "google/protobuf/any.proto"; | ||
import "cosmos/accounts/v1/account_abstraction.proto"; | ||
|
||
// MsgAuthenticate is a message that an x/account account abstraction implementer | ||
// must handle to authenticate a state transition. | ||
message MsgAuthenticate { | ||
// user_operation is the operation that the user is trying to perform. | ||
// it also contains authentication information. | ||
cosmos.accounts.v1.UserOperation user_operation = 1; | ||
// chain_id defines the network identifier. | ||
string chain_id = 2; | ||
// account_number is the account number of the user_operation. | ||
uint64 account_number = 3; | ||
} | ||
|
||
// MsgAuthenticateResponse is the response to MsgAuthenticate. | ||
// The authentication either fails or succeeds, this is why | ||
// there are no auxiliary fields to the response. | ||
message MsgAuthenticateResponse {} | ||
|
||
// MsgPayBundler is a message that an x/account account abstraction implementer | ||
// can optionally implement in case it wants to further refine control over | ||
// the bundler payment messages. | ||
// The account must ensure the caller of this message is the x/accounts module itself. | ||
message MsgPayBundler { | ||
// bundler_payment_messages are the messages that the operation sender will execute. | ||
// The account can modify the messages as it sees fit. | ||
repeated google.protobuf.Any bundler_payment_messages = 1; | ||
} | ||
|
||
// MsgPayBundlerResponse is the response to MsgPayBundler. | ||
message MsgPayBundlerResponse { | ||
// bundler_payment_messages_response are the messages that the bundler will pay for. | ||
repeated google.protobuf.Any bundler_payment_messages_response = 1; | ||
} | ||
|
||
// MsgExecute is a message that an x/account account abstraction implementer | ||
// can optionally implement in case it wants to further refine control over | ||
// the execution messages. It can be used to extend the execution flow, possibly | ||
// block certain messages, or modify them. | ||
// The account must ensure the caller of this message is the x/accounts module itself. | ||
message MsgExecute { | ||
// execution_messages are the messages that the operation sender will execute. | ||
// The account can modify the messages as it sees fit. | ||
repeated google.protobuf.Any execution_messages = 1; | ||
} | ||
|
||
// MsgExecuteResponse is the response to MsgExecute. | ||
message MsgExecuteResponse { | ||
// execution_messages_response are the messages that the operation sender will execute. | ||
repeated google.protobuf.Any execution_messages_response = 1; | ||
} | ||
|
||
// QueryAuthenticationMethods is a query that an x/account account abstraction implementer | ||
// must handle to return the authentication methods that the account supports. | ||
message QueryAuthenticationMethods {} | ||
|
||
// QueryAuthenticationMethodsResponse is the response to QueryAuthenticationMethods. | ||
message QueryAuthenticationMethodsResponse { | ||
// authentication_methods are the authentication methods that the account supports. | ||
repeated string authentication_methods = 1; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
syntax = "proto3"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the proto file for a testing x/account meant to test account abstraction. added pub key rotation to make things more spicy |
||
|
||
package cosmos.accounts.testing.rotation.v1; | ||
|
||
// MsgInit is the init message used to create a new account | ||
// abstraction implementation that we use for testing, this account | ||
// also allows for rotating the public key. | ||
message MsgInit { | ||
bytes pub_key_bytes = 1; | ||
} | ||
|
||
// MsgInitResponse is the init message response. | ||
message MsgInitResponse {} | ||
|
||
// MsgRotatePubKey is the message used to swap the public key | ||
// of the account. | ||
message MsgRotatePubKey { | ||
bytes new_pub_key_bytes = 1; | ||
} | ||
|
||
// MsgRotatePubKeyResponse is the MsgRotatePubKey response. | ||
message MsgRotatePubKeyResponse {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
syntax = "proto3"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. defines account abstraction core types used by the x/accounts module |
||
|
||
package cosmos.accounts.v1; | ||
|
||
option go_package = "cosmossdk.io/x/accounts/v1"; | ||
|
||
import "google/protobuf/any.proto"; | ||
|
||
// UserOperation defines the type used to define a state transition that | ||
// an account wants to make. | ||
message UserOperation { | ||
// sender defines the account that is sending the UserOperation. | ||
string sender = 1; | ||
// authentication_method defines the authentication strategy the account wants to use. | ||
// since accounts can have multiple authentication methods, this field is used to | ||
// instruct the account on what auth method to use. | ||
string authentication_method = 2; | ||
// authentication_data defines the authentication data associated with the authentication method. | ||
// It is the account implementer duty to assess that the UserOperation is properly signed. | ||
bytes authentication_data = 3; | ||
// sequence defines the sequence number of the account, the authentication method might require this | ||
// to ensure non-replayability. | ||
uint64 sequence = 4; | ||
// authentication_gas_limit expresses the gas limit to be used for the authentication part of the | ||
// UserOperation. | ||
uint64 authentication_gas_limit = 5; | ||
// bundler_payment_messages expresses a list of messages that the account | ||
// executes to pay the bundler for submitting the UserOperation. | ||
// It can be empty if the bundler does not need any form of payment, | ||
// the handshake for submitting the UserOperation might have happened off-chain. | ||
// Bundlers and accounts are free to use any form of payment, in fact the payment can | ||
// either be empty or be expressed as: | ||
// - NFT payment | ||
// - IBC Token payment. | ||
// - Payment through delegations. | ||
repeated google.protobuf.Any bundler_payment_messages = 6; | ||
// bundler_payment_gas_limit defines the gas limit to be used for the bundler payment. | ||
// This ensures that, since the bundler executes a list of UserOperations and there needs to | ||
// be minimal trust between bundler and UserOperation sender, the sender cannot consume | ||
// the whole bundle gas. | ||
uint64 bundler_payment_gas_limit = 7; | ||
// execution_messages expresses a list of messages that the account wants to execute. | ||
// This concretely is the intent of the transaction expressed as a UserOperation. | ||
repeated google.protobuf.Any execution_messages = 8; | ||
// execution_gas_limit defines the gas limit to be used for the execution of the UserOperation's | ||
// execution messages. | ||
uint64 execution_gas_limit = 9; | ||
} | ||
|
||
// UserOperationResponse defines the response of a UserOperation. | ||
message UserOperationResponse { | ||
// authentication_gas_used defines the gas used for the authentication part of the UserOperation. | ||
uint64 authentication_gas_used = 1; | ||
// bundler_payment_gas_used defines the gas used for the bundler payment part of the UserOperation. | ||
uint64 bundler_payment_gas_used = 2; | ||
// bundler_payment_responses defines the responses of the bundler payment messages. | ||
// It can be empty if the bundler does not need any form of payment. | ||
repeated google.protobuf.Any bundler_payment_responses = 3; | ||
// execution_gas_used defines the gas used for the execution part of the UserOperation. | ||
uint64 execution_gas_used = 4; | ||
// execution_responses defines the responses of the execution messages. | ||
repeated google.protobuf.Any execution_responses = 5; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package account_abstraction | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. implements the dummy account meant to test account abstraction + pub key rotation (pub key rotation is for spiciness) |
||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
account_abstractionv1 "cosmossdk.io/api/cosmos/accounts/interfaces/account_abstraction/v1" | ||
rotationv1 "cosmossdk.io/api/cosmos/accounts/testing/rotation/v1" | ||
"cosmossdk.io/api/cosmos/crypto/secp256k1" | ||
"cosmossdk.io/collections" | ||
"cosmossdk.io/x/accounts/accountstd" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
) | ||
|
||
var ( | ||
PubKeyPrefix = collections.NewPrefix(0) | ||
SequencePrefix = collections.NewPrefix(1) | ||
) | ||
|
||
var _ accountstd.Interface = (*PartialAccount)(nil) | ||
|
||
func NewPartialAccount(d accountstd.Dependencies) (PartialAccount, error) { | ||
return PartialAccount{ | ||
PubKey: collections.NewItem(d.SchemaBuilder, PubKeyPrefix, "pubkey", codec.CollValueV2[secp256k1.PubKey]()), | ||
Sequence: collections.NewItem(d.SchemaBuilder, SequencePrefix, "sequence", collections.Uint64Value), | ||
}, nil | ||
} | ||
|
||
// PartialAccount implements the Account interface. It also | ||
// implements the account_abstraction interface, it only implements | ||
// the minimum methods required to be a valid account_abstraction | ||
// implementer. | ||
type PartialAccount struct { | ||
PubKey collections.Item[*secp256k1.PubKey] | ||
Sequence collections.Item[uint64] | ||
} | ||
|
||
func (a PartialAccount) Init(ctx context.Context, msg *rotationv1.MsgInit) (*rotationv1.MsgInitResponse, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
func (a PartialAccount) RotatePubKey(ctx context.Context, msg *rotationv1.MsgRotatePubKey) (*rotationv1.MsgRotatePubKeyResponse, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
// Authenticate authenticates the account. | ||
func (a PartialAccount) Authenticate(ctx context.Context, msg *account_abstractionv1.MsgAuthenticate) (*account_abstractionv1.MsgAuthenticateResponse, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
// QueryAuthenticateMethods queries the authentication methods of the account. | ||
func (a PartialAccount) QueryAuthenticateMethods(ctx context.Context, req *account_abstractionv1.QueryAuthenticationMethods) (*account_abstractionv1.QueryAuthenticationMethodsResponse, error) { | ||
return nil, fmt.Errorf("not implemented") | ||
} | ||
|
||
func (a PartialAccount) RegisterInitHandler(builder *accountstd.InitBuilder) { | ||
accountstd.RegisterInitHandler(builder, a.Init) | ||
} | ||
|
||
func (a PartialAccount) RegisterExecuteHandlers(builder *accountstd.ExecuteBuilder) { | ||
accountstd.RegisterExecuteHandler(builder, a.RotatePubKey) | ||
accountstd.RegisterExecuteHandler(builder, a.Authenticate) // implements account_abstraction | ||
} | ||
|
||
func (a PartialAccount) RegisterQueryHandlers(builder *accountstd.QueryBuilder) { | ||
accountstd.RegisterQueryHandler(builder, a.QueryAuthenticateMethods) // implements account_abstraction | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the account abstraction interface messages and query messages.