Skip to content

Commit

Permalink
[AIP-113] AccountAbstraction that works per domain (#15899)
Browse files Browse the repository at this point in the history
Current AA requires registration for each account, and user has to have private key for an address to be able to do so.

This change allows for AA to be per domain - for example for Solana we need "ed25519_hex", and domain-separated addresses to automatically accept it.
  • Loading branch information
igor-aptos authored Feb 25, 2025
1 parent bc2244b commit 8787bb0
Show file tree
Hide file tree
Showing 25 changed files with 1,248 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ pub enum FeatureFlag {
AccountAbstraction,
VMBinaryFormatV8,
BulletproofsBatchNatives,
DomainAccountAbstraction,
}

fn generate_features_blob(writer: &CodeWriter, data: &[u64]) {
Expand Down Expand Up @@ -369,6 +370,7 @@ impl From<FeatureFlag> for AptosFeatureFlag {
FeatureFlag::PermissionedSigner => AptosFeatureFlag::PERMISSIONED_SIGNER,
FeatureFlag::AccountAbstraction => AptosFeatureFlag::ACCOUNT_ABSTRACTION,
FeatureFlag::BulletproofsBatchNatives => AptosFeatureFlag::BULLETPROOFS_BATCH_NATIVES,
FeatureFlag::DomainAccountAbstraction => AptosFeatureFlag::DOMAIN_ACCOUNT_ABSTRACTION,
}
}
}
Expand Down Expand Up @@ -526,6 +528,7 @@ impl From<AptosFeatureFlag> for FeatureFlag {
AptosFeatureFlag::PERMISSIONED_SIGNER => FeatureFlag::PermissionedSigner,
AptosFeatureFlag::ACCOUNT_ABSTRACTION => FeatureFlag::AccountAbstraction,
AptosFeatureFlag::BULLETPROOFS_BATCH_NATIVES => FeatureFlag::BulletproofsBatchNatives,
AptosFeatureFlag::DOMAIN_ACCOUNT_ABSTRACTION => FeatureFlag::DomainAccountAbstraction,
}
}
}
Expand Down
20 changes: 18 additions & 2 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,15 @@ impl AptosVM {
function_info,
auth_data,
}) => {
if self.features().is_account_abstraction_enabled() {
let enabled = match auth_data {
AbstractionAuthData::V1 { .. } => {
self.features().is_account_abstraction_enabled()
},
AbstractionAuthData::DomainV1 { .. } => {
self.features().is_domain_account_abstraction_enabled()
},
};
if enabled {
dispatchable_authenticate(
session,
gas_meter,
Expand Down Expand Up @@ -1962,7 +1970,15 @@ impl AptosVM {
function_info,
auth_data,
} => {
if self.features().is_account_abstraction_enabled() {
let enabled = match auth_data {
AbstractionAuthData::V1 { .. } => {
self.features().is_account_abstraction_enabled()
},
AbstractionAuthData::DomainV1 { .. } => {
self.features().is_domain_account_abstraction_enabled()
},
};
if enabled {
dispatchable_authenticate(
session,
gas_meter,
Expand Down
379 changes: 330 additions & 49 deletions aptos-move/framework/aptos-framework/doc/account_abstraction.md

Large diffs are not rendered by default.

191 changes: 184 additions & 7 deletions aptos-move/framework/aptos-framework/doc/auth_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,59 @@



- [Enum `DomainAccount`](#0x1_auth_data_DomainAccount)
- [Enum `AbstractionAuthData`](#0x1_auth_data_AbstractionAuthData)
- [Constants](#@Constants_0)
- [Function `digest`](#0x1_auth_data_digest)
- [Function `authenticator`](#0x1_auth_data_authenticator)
- [Function `is_domain`](#0x1_auth_data_is_domain)
- [Function `domain_authenticator`](#0x1_auth_data_domain_authenticator)
- [Function `domain_account_identity`](#0x1_auth_data_domain_account_identity)


<pre><code></code></pre>
<pre><code><b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
</code></pre>



<a id="0x1_auth_data_DomainAccount"></a>

## Enum `DomainAccount`



<pre><code>enum <a href="auth_data.md#0x1_auth_data_DomainAccount">DomainAccount</a> <b>has</b> <b>copy</b>, drop
</code></pre>



<details>
<summary>Variants</summary>


<details>
<summary>V1</summary>


<details>
<summary>Fields</summary>


<dl>
<dt>
<code>account_identity: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;</code>
</dt>
<dd>

</dd>
</dl>


</details>

</details>

</details>

<a id="0x1_auth_data_AbstractionAuthData"></a>

Expand Down Expand Up @@ -53,19 +98,76 @@
</dl>


</details>

</details>

<details>
<summary>DomainV1</summary>


<details>
<summary>Fields</summary>


<dl>
<dt>
<code>digest: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;</code>
</dt>
<dd>

</dd>
<dt>
<code>authenticator: <a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;</code>
</dt>
<dd>

</dd>
<dt>
<code><a href="account.md#0x1_account">account</a>: <a href="auth_data.md#0x1_auth_data_DomainAccount">auth_data::DomainAccount</a></code>
</dt>
<dd>

</dd>
</dl>


</details>

</details>

</details>

<a id="@Constants_0"></a>

## Constants


<a id="0x1_auth_data_ENOT_DOMAIN_AUTH_DATA"></a>



<pre><code><b>const</b> <a href="auth_data.md#0x1_auth_data_ENOT_DOMAIN_AUTH_DATA">ENOT_DOMAIN_AUTH_DATA</a>: u64 = 2;
</code></pre>



<a id="0x1_auth_data_ENOT_REGULAR_AUTH_DATA"></a>



<pre><code><b>const</b> <a href="auth_data.md#0x1_auth_data_ENOT_REGULAR_AUTH_DATA">ENOT_REGULAR_AUTH_DATA</a>: u64 = 1;
</code></pre>



<a id="0x1_auth_data_digest"></a>

## Function `digest`



<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_digest">digest</a>(signing_data: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_digest">digest</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>


Expand All @@ -74,8 +176,8 @@
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_digest">digest</a>(signing_data: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
&signing_data.digest
<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_digest">digest</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
&self.digest
}
</code></pre>

Expand All @@ -89,7 +191,81 @@



<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_authenticator">authenticator</a>(signing_data: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_authenticator">authenticator</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_authenticator">authenticator</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
<b>assert</b>!(self is V1, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="auth_data.md#0x1_auth_data_ENOT_REGULAR_AUTH_DATA">ENOT_REGULAR_AUTH_DATA</a>));
&self.authenticator
}
</code></pre>



</details>

<a id="0x1_auth_data_is_domain"></a>

## Function `is_domain`



<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_is_domain">is_domain</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_is_domain">is_domain</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): bool {
self is DomainV1
}
</code></pre>



</details>

<a id="0x1_auth_data_domain_authenticator"></a>

## Function `domain_authenticator`



<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_domain_authenticator">domain_authenticator</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_domain_authenticator">domain_authenticator</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
<b>assert</b>!(self is DomainV1, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="auth_data.md#0x1_auth_data_ENOT_REGULAR_AUTH_DATA">ENOT_REGULAR_AUTH_DATA</a>));
&self.authenticator
}
</code></pre>



</details>

<a id="0x1_auth_data_domain_account_identity"></a>

## Function `domain_account_identity`



<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_domain_account_identity">domain_account_identity</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt;
</code></pre>


Expand All @@ -98,8 +274,9 @@
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_authenticator">authenticator</a>(signing_data: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
&signing_data.authenticator
<pre><code><b>public</b> <b>fun</b> <a href="auth_data.md#0x1_auth_data_domain_account_identity">domain_account_identity</a>(self: &<a href="auth_data.md#0x1_auth_data_AbstractionAuthData">AbstractionAuthData</a>): &<a href="../../aptos-stdlib/../move-stdlib/doc/vector.md#0x1_vector">vector</a>&lt;u8&gt; {
<b>assert</b>!(self is DomainV1, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="auth_data.md#0x1_auth_data_ENOT_DOMAIN_AUTH_DATA">ENOT_DOMAIN_AUTH_DATA</a>));
&self.<a href="account.md#0x1_account">account</a>.account_identity
}
</code></pre>

Expand Down
73 changes: 73 additions & 0 deletions aptos-move/framework/aptos-framework/doc/common_domain_aa_auths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

<a id="0x1_common_domain_aa_auths"></a>

# Module `0x1::common_domain_aa_auths`



- [Constants](#@Constants_0)
- [Function `authenticate_ed25519_hex`](#0x1_common_domain_aa_auths_authenticate_ed25519_hex)


<pre><code><b>use</b> <a href="auth_data.md#0x1_auth_data">0x1::auth_data</a>;
<b>use</b> <a href="../../aptos-stdlib/doc/ed25519.md#0x1_ed25519">0x1::ed25519</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error">0x1::error</a>;
<b>use</b> <a href="../../aptos-stdlib/../move-stdlib/doc/string.md#0x1_string">0x1::string</a>;
<b>use</b> <a href="../../aptos-stdlib/doc/string_utils.md#0x1_string_utils">0x1::string_utils</a>;
</code></pre>



<a id="@Constants_0"></a>

## Constants


<a id="0x1_common_domain_aa_auths_EINVALID_SIGNATURE"></a>



<pre><code><b>const</b> <a href="common_domain_aa_auths.md#0x1_common_domain_aa_auths_EINVALID_SIGNATURE">EINVALID_SIGNATURE</a>: u64 = 1;
</code></pre>



<a id="0x1_common_domain_aa_auths_authenticate_ed25519_hex"></a>

## Function `authenticate_ed25519_hex`



<pre><code><b>public</b> <b>fun</b> <a href="common_domain_aa_auths.md#0x1_common_domain_aa_auths_authenticate_ed25519_hex">authenticate_ed25519_hex</a>(<a href="account.md#0x1_account">account</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, aa_auth_data: <a href="auth_data.md#0x1_auth_data_AbstractionAuthData">auth_data::AbstractionAuthData</a>): <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="common_domain_aa_auths.md#0x1_common_domain_aa_auths_authenticate_ed25519_hex">authenticate_ed25519_hex</a>(<a href="account.md#0x1_account">account</a>: <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, aa_auth_data: AbstractionAuthData): <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a> {
<b>let</b> hex_digest = <a href="../../aptos-stdlib/doc/string_utils.md#0x1_string_utils_to_string">string_utils::to_string</a>(aa_auth_data.digest());

<b>let</b> public_key = new_unvalidated_public_key_from_bytes(*aa_auth_data.domain_account_identity());
<b>let</b> signature = new_signature_from_bytes(*aa_auth_data.domain_authenticator());
<b>assert</b>!(
<a href="../../aptos-stdlib/doc/ed25519.md#0x1_ed25519_signature_verify_strict">ed25519::signature_verify_strict</a>(
&signature,
&public_key,
*hex_digest.bytes(),
),
<a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="common_domain_aa_auths.md#0x1_common_domain_aa_auths_EINVALID_SIGNATURE">EINVALID_SIGNATURE</a>)
);

<a href="account.md#0x1_account">account</a>
}
</code></pre>



</details>


[move-book]: https://aptos.dev/move/book/SUMMARY
Loading

0 comments on commit 8787bb0

Please sign in to comment.