You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 30, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: apps/nextra/pages/en/build/sdks/ts-sdk/account/account-abstraction.mdx
+361-3Lines changed: 361 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,6 +65,14 @@ enum AbstractionAuthData has copy, drop {
65
65
}
66
66
```
67
67
68
+
**Why is the `digest` important?**
69
+
70
+
The `digest` is checked by the MoveVM to ensure that the signing message of the transaction being submitted is the same as the one presented in the `AbstractionAuthData`. This
71
+
is important because it allows the authentication function to verify signatures with respect to the correct transaction.
72
+
73
+
For example, if you want to permit a public key to sign transactions on behalf of the user, you can permit the public key to sign a transaction with a specific payload.
74
+
However, if a malicious user sends a signature for the correct public key but a different payload from the `digest`, the signature will not be valid.
75
+
68
76
**Example (Move)**
69
77
70
78
This example demonstrates a simple authentication logic that checks if the authenticator is equal to `"hello world"`.
@@ -99,7 +107,7 @@ const abstractedAccount = new AbstractedAccount({
To deploy the module, you can use the following commands from the [Aptos CLI](/en/build/cli). We assume that you already have set up a workspace with `aptos init` and
135
+
To deploy the module, you can use the following commands from the [Aptos CLI](../../../../build/cli). We assume that you already have set up a workspace with `aptos init` and
128
136
declared the named addresses in your `Move.toml` file.
129
137
130
138
```bash
@@ -260,12 +268,362 @@ console.log("Coin transfer transaction submitted! ", pendingCoinTransferTransact
260
268
### 7. Conclusion
261
269
262
270
To verify that you have successfully sign and submitted the transaction using the abstracted account, you can use the explorer to check the transaction. If the
263
-
transaction signature contains a `function_info` and `auth_data` field, it means you succesfully used account abstraction!
271
+
transaction signature contains a `function_info` and `auth_data` field, it means you succesfully used account abstraction! The full E2E demo can be found [here](https://github.com/aptos-labs/aptos-ts-sdk/blob/main/examples/typescript/public_key_authenticator_account_abstraction.ts).
Now that you have a basic understanding of how account abstraction works, let's dive into a more complex example.
280
+
281
+
In this example, we will create an authenticator that allows users to permit certain public keys to sign transactions on behalf of the abstracted account.
282
+
283
+
<Steps>
284
+
285
+
### 1. Create an Authenticator module
286
+
287
+
We will deploy the `public_key_authenticator` module that does two things:
288
+
- Allow users to permit and/or revoke public keys from signing on behalf of the user.
289
+
- Allow users to authenticate on behalf of somebody else using account abstraction.
290
+
291
+
```move
292
+
module deployer::public_key_authenticator {
293
+
use std::signer;
294
+
use aptos_std::smart_table::{Self, SmartTable};
295
+
use aptos_std::ed25519::{
296
+
Self,
297
+
new_signature_from_bytes,
298
+
new_unvalidated_public_key_from_bytes,
299
+
unvalidated_public_key_to_bytes
300
+
};
301
+
use aptos_framework::bcs_stream::{Self, deserialize_u8};
302
+
use aptos_framework::auth_data::{Self, AbstractionAuthData};
The `PublicKeyPermissions` struct is a key that contains a `SmartTable` of public keys that determines
393
+
whether a public key is permitted to sign transactions on behalf of the user.
394
+
395
+
```move
396
+
module deployer::public_key_authenticator {
397
+
// ...
398
+
399
+
struct PublicKeyPermissions has key {
400
+
public_key_table: SmartTable<vector<u8>, bool>,
401
+
}
402
+
403
+
}
404
+
```
405
+
406
+
**Permitting and Revoking Public Keys**
407
+
408
+
We define two entry functions to permit and revoke public keys. These functions are used to add and remove public keys from the `PublicKeyPermissions` struct.
The `authenticate` function is the main function that allows users to authenticate on behalf of somebody else using account abstraction. The `authenticator`
454
+
will contain the **public key** and a **signature** of the user. We will verify that the public key is permitted and that the signature is valid.
455
+
456
+
The signature is the result of signing the `digest`. The `digest` is the sha256 hash of the **signing message** which contains information about the transaction.
457
+
By signing the `digest`, we confirm that the user has approved the specific transaction that was submitted.
To deploy the module, you can use the following commands from the [Aptos CLI](../../../../build/cli). We assume that you already have set up a workspace with `aptos init` and
494
+
declared the named addresses in your `Move.toml` file.
Once deployed, you can setup your environment. In this example, we will use Devnet and create an account named `alice` as the user that will be authenticated on behalf of
503
+
and `bob` as the user that will be permitted to sign transactions on behalf of `alice`.
### 3. (Optional) Check if Account Abstraction is Enabled
516
+
517
+
Before we enable the authentication function, we can check if the account has account abstraction enabled by calling the `isAccountAbstractionEnabled` function.
518
+
This will return a boolean value indicating if the account has account abstraction enabled.
Assuming that the account does not have account abstraction enabled, we need to enable the authentication function for the account. This can be done by calling
532
+
the `enableAccountAbstractionTransaction` function. This creates a raw transaction that needs to be signed and submitted to the network. In this example, `alice`
console.log(`Enable Bob's public key transaction hash: ${pendingEnableBobPublicKeyTransaction.hash}`);
573
+
```
574
+
575
+
### 6. Create an Abstracted Account
576
+
577
+
Now that we have permitted `bob`'s public key, we can create an abstracted account that will be used to sign transactions on behalf of `alice`.
578
+
**Notice that the `signer` function uses `bob`'s signer.**
579
+
580
+
```ts
581
+
const abstractedAccount =newAbstractedAccount({
582
+
accountAddress: alice.accountAddress,
583
+
signer: (digest) => {
584
+
const serializer =newSerializer();
585
+
bob.publicKey.serialize(serializer);
586
+
bob.sign(digest).serialize(serializer);
587
+
returnserializer.toUint8Array();
588
+
},
589
+
authenticationFunction,
590
+
});
591
+
```
592
+
593
+
### 7. Sign and Submit a Transaction using the Abstracted Account
594
+
595
+
Now that we have created the abstracted account, we can use it to sign transactions normally. It is important that the `sender` field in the transaction
console.log("Coin transfer transaction submitted! ", pendingCoinTransferTransaction.hash);
616
+
```
617
+
618
+
### 8. Conclusion
619
+
620
+
To verify that you have successfully sign and submitted the transaction using the abstracted account, you can use the explorer to check the transaction. If the
621
+
transaction signature contains a `function_info` and `auth_data` field, it means you succesfully used account abstraction! The full E2E demo can be found [here](https://github.com/aptos-labs/aptos-ts-sdk/blob/main/examples/typescript/public_key_authenticator_account_abstraction.ts)
If you want to disable account abstraction for an account, you can use the `disableAccountAbstractionTransaction`. If you do not specify an authentication function,
0 commit comments