From e30ec490982393bce1d0967ae4b638fa33524085 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Thu, 27 Nov 2025 09:15:11 +0400 Subject: [PATCH] clean up docs --- .../version-0.11.0-sidebars.json | 9 - .../experimental/_category_.json | 4 - .../erc-7710-redeem-delegations.md | 233 ------------------ .../erc-7715-request-permissions.md | 182 -------------- .../store-retrieve-delegations.md | 170 ------------- 5 files changed, 598 deletions(-) delete mode 100644 gator_versioned_sidebars/version-0.11.0-sidebars.json delete mode 100644 smart-accounts-kit/experimental/_category_.json delete mode 100644 smart-accounts-kit/experimental/erc-7710-redeem-delegations.md delete mode 100644 smart-accounts-kit/experimental/erc-7715-request-permissions.md delete mode 100644 smart-accounts-kit/experimental/store-retrieve-delegations.md diff --git a/gator_versioned_sidebars/version-0.11.0-sidebars.json b/gator_versioned_sidebars/version-0.11.0-sidebars.json deleted file mode 100644 index e8bd6fa30ee..00000000000 --- a/gator_versioned_sidebars/version-0.11.0-sidebars.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "docSidebar": [ - { - "type": "autogenerated", - "dirName": "." - } - ] -} - \ No newline at end of file diff --git a/smart-accounts-kit/experimental/_category_.json b/smart-accounts-kit/experimental/_category_.json deleted file mode 100644 index 00c51c61b99..00000000000 --- a/smart-accounts-kit/experimental/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Experimental", - "position": 5 -} \ No newline at end of file diff --git a/smart-accounts-kit/experimental/erc-7710-redeem-delegations.md b/smart-accounts-kit/experimental/erc-7710-redeem-delegations.md deleted file mode 100644 index 81c1049e306..00000000000 --- a/smart-accounts-kit/experimental/erc-7710-redeem-delegations.md +++ /dev/null @@ -1,233 +0,0 @@ ---- -description: Learn how to redeem ERC-7710 delegations with a smart contract account or an externally owned account (EOA). ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# ERC-7710: Redeem delegations - -:::caution Experimental -This is an experimental feature and may change in future releases. -::: - -[ERC-7710](https://eip.tools/eip/7710) introduces a standard way for MetaMask Smart Accounts to delegate capabilities to other -smart accounts or externally owned accounts (EOAs). - -The MetaMask Smart Accounts Kit provides two experimental functions, `erc7710BundlerActions()` and `erc7710WalletActions()`, that let -a caller redeem delegations granted by MetaMask's permissions system. - -## Extract relevant data - -Refer to [ERC-7715: Request permissions](erc-7715-request-permissions.md) for information on how to request user permissions. -Once the permission has been granted, extract the relevant data from the response. -For example: - -```typescript -// Response received from the ERC-7715 wallet_grantPermissions request. -const permissionsResponse = [{ - chainId: "0xe715", - account: "0xD6f56C2B10b1e02D841E4a97c60Afe914E884DBd", - expiry: 1234567890, - permission: { - type: "native-token-stream", - data: { - amountPerSecond: "0x1", - maxAmount: "0x2", - initialAmount: undefined, - startTime: 2, - }, - }, - context: "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d" - signer: { - type: "account", - data: { - account: "0x07bfc7230D5BD2544059816D88A895BB000Abe00" - } - }, - signerMeta: { - delegationManager: "0xDC7e12b41E5e61BfCc7F56AAFB7B93288F61e841" - }, - accountMetadata: [{ - factory: "0x65E726b404149fE37F4b291c81Dc6eddd44763A7", - factoryData: "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b" - }] -}]; - -const permissionsContext = permissionsResponse[0].context; -const delegationManager = permissionsResponse[0].signerMeta.delegationManager; -// accountMeta is only present when the smart account is not deployed. -const accountMetadata = permissionsResponse[0].accountMeta; -``` - -This data encodes the authority that lets the delegate redeem the permission. - -### Security considerations for `accountMeta` - -When a user grants a permission, they can provide `accountMeta` which is an array of `factory` and `factoryData` values. -These calls must be executed before redeeming the permission (this is handled for you in [`sendUserOperationWithDelegation`](../reference/advanced-permissions/bundler-client.md#senduseroperationwithdelegation)). - -Because each `accountMeta` is an arbitrary call specified by the granter, it is important that these are executed carefully. -We recommend taking the following precautions: - -- **Only grant permissions to session accounts** - When requesting permissions, use an account that is only used for that single purpose, and does not contain tokens. -This way, any `accountMeta` executed can't perform any damaging actions. - -- **Only execute `accountMeta` against trusted factory addresses** - Ensure that only `accountMeta` targeting a known factory address is executed. -The bundler action `sendUserOperationWithDelegation` only executes `accountMeta` that targets the `SimpleFactory` address for the current Delegation Framework. -If you redeem delegations in any other way, it is your responsibility to validate trusted factory addresses. - -## Redeem the permission - -Redeem a delegation with a [MetaMask smart account](#redeem-with-a-metamask-smart-account) or an [externally owned account (EOA)](#redeem-with-an-eoa). - -### Redeem with a MetaMask smart account - -To redeem a delegation with a MetaMask smart account, [create a smart account](../guides/smart-accounts/create-smart-account.md) -and a [Viem Bundler Client](https://viem.sh/account-abstraction/clients/bundler). - -After setting up your Bundler Client, you can extend its functionality with `erc7710BundlerActions` actions to support ERC-7710. Once extended, use [`sendUserOperationWithDelegation`](../reference/advanced-permissions/bundler-client.md#senduseroperationwithdelegation) to redeem the permission. - - - - -```typescript -import { sessionAccount, bundlerClient, publicClient } from "./config.ts"; - -// These properties must be extracted from the permission response. -const permissionsContext = permissionsResponse[0].context; -const delegationManager = permissionsResponse[0].signerMeta.delegationManager; -const accountMetadata = permissionsResponse[0].accountMeta; - -// Calls without permissionsContext and delegationManager will be executed -// as a normal user operation. -const userOperationHash = await bundlerClient.sendUserOperationWithDelegation({ - publicClient, - account: sessionAccount, - calls: [ - { - to: sessionAccount.address, - data: "0x", - value: 1n, - permissionsContext, - delegationManager, - }, - ], - // Appropriate values must be used for fee-per-gas. - maxFeePerGas: 1n, - maxPriorityFeePerGas: 1n - accountMetadata, -}); -``` - - - - -```typescript -import { createPublicClient, http, createBundlerClient } from "viem"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; -import { sepolia as chain } from "viem/chains"; -import { createBundlerClient } from "viem/account-abstraction"; -import { erc7710BundlerActions } from "@metamask/smart-accounts-kit/actions"; -import { toMetaMaskSmartAccount, Implementation } from "@metamask/smart-accounts-kit"; - -export const publicClient = createPublicClient({ - chain: chain, - transport: http(), -}); - -// Your session account for requesting and redeeming should be same. -const privateKey = "0x..."; -const account = privateKeyToAccount(privateKey); - - -export const sessionAccount = await toMetaMaskSmartAccount({ - client: publicClient, - implementation: Implementation.Hybrid, - deployParams: [account.address, [], [], []], - deploySalt: "0x", - signer: { account }, -}); - -export const bundlerClient = createBundlerClient({ - transport: http( - `https://your-bundler-url` - ), - // Allows you to use the same Bundler Client as paymaster. - paymaster: true -}).extend(erc7710BundlerActions()); -``` - - - -:::note -`sendUserOperationWithDelegation` is similar to the `sendUserOperation` function, but does not accept `callData` directly. -::: - -### Redeem with an EOA - -To redeem a delegation with an EOA, create a [Viem Wallet Client](https://viem.sh/docs/clients/wallet). - -After creating your Wallet Client, you can extend its functionality with `erc7710WalletActions` actions to support ERC-7710. Once extended, use [`sendTransactionWithDelegation`](../reference/advanced-permissions/wallet-client.md#sendtransactionwithdelegation) to redeem the permission. - - - - -```typescript -import { walletClient, publicClient } from "./config.ts"; - -// These properties must be extracted from the permission response. -const permissionsContext = permissionsResponse[0].context; -const delegationManager = permissionsResponse[0].signerMeta.delegationManager; -const accountMetadata = permissionsResponse[0].accountMeta; - -if (accountMetadata?.length !== 0) { - // If the granted permission contains accountMetadata, this must be executed before attempting to - // redeem the delegation. - - // This transaction will deploy the delegator account. - const hash = walletClient.sendTransaction({ - to: accountMetadata[0].factory, - data: accountMetadata[0].factoryData, - }); - - // You should wait for transaction to be successfully executed. - // You can use the TransactionReceipt.status to verify the state. - await publicClient.waitForTransactionReceipt( { hash }); -} - -const hash = walletClient.sendTransactionWithDelegation({ - chain, - to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", - value: 1n, - permissionsContext, - delegationManager -}); -``` - - - - -```typescript -import { http, createPublicClient, createWalletClient } from "viem"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; -import { sepolia as chain } from "viem/chains"; -import { erc7710WalletActions } from "@metamask/smart-accounts-kit/actions"; - -export const publicClient = createPublicClient({ - chain, - transport: http() -}); - -// Your session account for requesting and redeeming should be same. -const privateKey = "0x..."; -const account = privateKeyToAccount(privateKey); - -const walletClient = createWalletClient({ - account, - transport: http(), - chain, -}).extend(erc7710WalletActions()); -``` - - diff --git a/smart-accounts-kit/experimental/erc-7715-request-permissions.md b/smart-accounts-kit/experimental/erc-7715-request-permissions.md deleted file mode 100644 index a3aef3bf0cf..00000000000 --- a/smart-accounts-kit/experimental/erc-7715-request-permissions.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -description: Learn how to request ERC-7715 permissions. ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# ERC-7715: Request permissions - -:::caution Experimental -This is an experimental feature. -It requires MetaMask Flask 13.5.0 or later, and may change in future releases. -::: - -[ERC-7715](https://eip.tools/eip/7715) introduces a standard way for dapps to request permissions from a wallet to execute -transactions on a user's behalf. - -The MetaMask Smart Accounts Kit provides the experimental actions for ERC-7715 that lets a caller request permissions from MetaMask's permissions system. - -## Request permissions - -To request permissions, extend your [Viem Wallet Client](https://viem.sh/docs/clients/wallet) with `erc7715ProviderActions` actions. -You'll need a session account to request the permission, which can be either a smart account or an externally owned account (EOA). -This example uses a MetaMask smart account: - - - - -```typescript -import { sepolia as chain } from "viem/chains"; -import { sessionAccount, walletClient } from "./config.ts"; - -const expiry = Math.floor(Date.now() / 1000 + 604_800); // 1 week from now. -const currentTime = Math.floor(Date.now() / 1000); // now - -const grantedPermissions = await walletClient.grantPermissions([{ - chainId: chain.id, - expiry, - signer: { - type: "account", - data: { - address: sessionAccount.address, - }, - }, - permission: { - type: "native-token-stream", - data: { - initialAmount: 1n, // 1 wei - amountPerSecond: 1n, // 1 wei per second - maxAmount: 10n, // 10 wei - startTime: currentTime, - justification: "Payment for a week long subscription", - }, - }, -}]); -``` - - - - - -```typescript -import { createWalletClient, custom, createPublicClient, http } from "viem"; -import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; -import { sepolia as chain } from "viem/chains"; -import { erc7715ProviderActions } from "@metamask/smart-accounts-kit/actions"; -import { toMetaMaskSmartAccount, Implementation } from "@metamask/smart-accounts-kit"; - -const publicClient = createPublicClient({ - chain: chain, - transport: http(), -}); - -// The private key of the session owner. -const privateKey = "0x..."; -const account = privateKeyToAccount(privateKey); - -export const sessionAccount = await toMetaMaskSmartAccount({ - client: publicClient, - implementation: Implementation.Hybrid, - deployParams: [account.address, [], [], []], - deploySalt: "0x", - signer: { account }, -}); - -export const walletClient = createWalletClient({ - transport: custom(window.ethereum), -}).extend(erc7715ProviderActions()); -``` - - - -
- ERC-7715 request permission sample -
- Here's what your ERC-7715 native token streaming allowance request looks like: - - ```ts - [{ - chainId: "0xaa36a7", - expiry: 1745041429, - permission: { - type: "native-token-stream", - data: { - amountPerSecond: "0x1", - maxAmount: "0x1", - initialAmount: "0xa", - startTime: 1744955029, - justification: "Payment for a week long subscription", - }, - }, - signer: { - type: "account", - data: { - address: "0x1234...", - }, - }, - }] - ``` - - Learn more about the [ERC-7715 permission schema](https://eip.tools/eip/7715). -
-
- - -Additionally, you can allow users to modify the requested permission by setting the `isAdjustmentAllowed` parameter to `true` in the request. - -```typescript -import { sepolia as chain } from "viem/chains"; -// The config.ts is the same as in the previous example. -import { sessionAccount, walletClient } from "./config.ts"; - -const expiry = Math.floor(Date.now() / 1000 + 604_800); // 1 week from now. -const currentTime = Math.floor(Date.now() / 1000); // now - -const grantedPermissions = await walletClient.grantPermissions([{ - chainId: chain.id, - expiry, - signer: { - type: "account", - data: { - address: sessionAccount.address, - }, - }, - permission: { - type: "native-token-stream", - // add-next-line -+ isAdjustmentAllowed: true, - data: { - initialAmount: 1n, // 1 wei - amountPerSecond: 1n, // 1 wei per second - maxAmount: 10n, // 10 wei - startTime: currentTime, - justification: "Payment for a week long subscription", - }, - }, -}]); -``` - -:::note -Users have full control over the permissions they grant—depending on the permission you request, they may choose to grant more limited permissions than requested. -You should always verify the granted permissions and adjust your dapp's behavior accordingly. -::: - -## Security considerations for `accountMeta` - -When a user grants a permission, they can provide [`accountMeta`](erc-7710-redeem-delegations.md#extract-relevant-data) which is an array of `factory` and `factoryData` values. -These calls must be executed before redeeming the permission (this is handled for you in [`sendUserOperationWithDelegation`](../reference/advanced-permissions/bundler-client.md#senduseroperationwithdelegation)). - -Because each `accountMeta` is an arbitrary call specified by the granter, it is important that these are executed carefully. -We recommend taking the following precautions: - -- **Only grant permissions to session accounts** - When requesting permissions, use an account that is only used for that single purpose, and does not contain tokens. - This way, any `accountMeta` executed can't perform any damaging actions. - -- **Only execute `accountMeta` against trusted factory addresses** - Ensure that only `accountMeta` targeting a known factory address is executed. - The bundler action `sendUserOperationWithDelegation` only executes `accountMeta` that targets the `SimpleFactory` address for the current Delegation Framework. - If you redeem delegations in any other way, it is your responsibility to validate trusted factory addresses. - -## Next steps - -You can redeem the granted permission using the experimental [ERC-7710 `erc7710WalletActions()`](erc-7710-redeem-delegations.md). diff --git a/smart-accounts-kit/experimental/store-retrieve-delegations.md b/smart-accounts-kit/experimental/store-retrieve-delegations.md deleted file mode 100644 index db0cbdfb1a0..00000000000 --- a/smart-accounts-kit/experimental/store-retrieve-delegations.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -description: Store and retrieve delegations using the `DelegationStorageClient`. -toc_max_heading_level: 2 ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -# Store and retrieve delegations - -:::caution Experimental -This is an experimental feature and may change in future releases. -::: - -You can use methods provided by the `DelegationStorageClient` of the MetaMask Delegation Toolkit to store and retrieve -[delegations](../concepts/delegation/index.md). - -## Prerequisites - -- [Install and set up the Delegation Toolkit.](../get-started/install.md) -- Ensure you have an API key and API key ID to interact with the `DelegationStorageClient`. - If you need to gain access, email hellogators@consensys.net. - -## Configure the storage client - -Create the `DelegationStorageClient` instance, and configure it using your API key and API key ID. - -```typescript -import { - DelegationStorageClient, - DelegationStorageEnvironment -} from "@metamask/smart-accounts-kit/experimental"; - -const delegationStorageClient = new DelegationStorageClient({ - apiKey: "", - apiKeyId: "", - environment: DelegationStorageEnvironment.prod -}); -``` - -## Store a delegation - -To store a delegation, use the `storeDelegation` method of the `DelegationStorageClient`. This method takes one parameter: - -1. `delegation` - A `Delegation` object representing the delegation to be stored. - -### Example - - - - -```typescript -import { delegationStorageClient } from "./config.ts"; - -const delegationHash = await delegationStorageClient.storeDelegation(delegation); -``` - - - - -```typescript -import { - DelegationStorageClient, - DelegationStorageEnvironment -} from "@metamask/smart-accounts-kit/experimental"; - -export const delegationStorageClient = new DelegationStorageClient({ - apiKey: "", - apiKeyId: "", - environment: DelegationStorageEnvironment.prod -}); -``` - - - -## Retrieve a delegation chain - -To retrieve a delegation chain, use the `getDelegationChain` method of the `DelegationStorageClient`. This method takes one parameter: - -1. `leafDelegationOrDelegationHash` - Either a `Delegation` object or the delegation hash as a hex string. - -:::note -A delegation can be a root delegation, where its `authority` is `0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`. It can also be a child of another delegation, where its `authority` is the hash of its parent delegation. This method returns the delegation referenced by `leafDelegationOrDelegationHash` and any ancestors. -::: - -### Example - - - - -```typescript -import { delegationStorageClient } from "./config.ts"; -import { getDelegationHashOffchain } from "@metamask/smart-accounts-kit"; - -// Assuming you have the leaf delegation -const delegationHash = getDelegationHashOffchain(leafDelegation); - -const delegationChain: Delegation[] = await delegationStorageClient.getDelegationChain( - delegationHash -); -``` - - - - -```typescript -import { - DelegationStorageClient, - DelegationStorageEnvironment -} from "@metamask/smart-accounts-kit/experimental"; - -export const delegationStorageClient = new DelegationStorageClient({ - apiKey: "", - apiKeyId: "", - environment: DelegationStorageEnvironment.prod -}); -``` - - - -## Retrieve delegations for a specific account - -To retrieve delegations stored for a specific account, use the `fetchDelegations` method of the `DelegationStorageClient`. This method allows you to fetch delegations where the specified account is either the delegator or the delegate. -It takes two parameters: - -1. `account` - The address of the account for which you want to retrieve delegations. -2. `filter` - The nature of the delegations. Possible values are: - - `DelegationStoreFilter.Given` - For delegations where the specified `account` is the `delegator`. - - `DelegationStoreFilter.Received` - For delegations where the specified `account` is the `delegate`. - -### Example - - - - -```typescript -import { delegationStorageClient } from "./config.ts"; - -const address = "0x027aeAFF3E5C33c4018FDD302c20a1B83aDCD96C" - -// Fetch the delegations given by address. -const grantedDelegations = await delegationStorageClient.fetchDelegations( - address, - DelegationStoreFilter.Given, -); - -// Fetch the delegations received by the address. -const receivedDelegations = await delegationStore.fetchDelegations( - address, - DelegationStoreFilter.Received, -); -``` - - - - -```typescript -import { - DelegationStorageClient, - DelegationStorageEnvironment -} from "@metamask/smart-accounts-kit/experimental"; - -export const delegationStorageClient = new DelegationStorageClient({ - apiKey: "", - apiKeyId: "", - environment: DelegationStorageEnvironment.prod -}); -``` - -