diff --git a/docs/pages/guides/how-to/accounts/use-metamask-account.mdx b/docs/pages/guides/how-to/accounts/use-metamask-account.mdx index 71c0790c..8d9ceb59 100644 --- a/docs/pages/guides/how-to/accounts/use-metamask-account.mdx +++ b/docs/pages/guides/how-to/accounts/use-metamask-account.mdx @@ -1,49 +1,49 @@ # How to use MetaMask Smart Accounts with permissionless.js :::info -MetaMask maintains their own in-house SDK built closely on top of viem that you can use for the account system while still plugging in all the other components from permissionless.js. Take a look at [their documentation](https://docs.metamask.io/delegation-toolkit/how-to/send-user-operation) for more information. +MetaMask maintains their own in-house SDK built on top of Viem that you can use for the account system while still plugging in all the other components from permissionless.js. See [their documentation](https://docs.metamask.io/smart-accounts-kit) for more information. ::: -The [MetaMask Delegation Toolkit](https://docs.metamask.io/delegation-toolkit/get-started/quickstart) is a collection of tools for creating MetaMask Smart Accounts. A smart account can delegate to another signer with granular permission sharing. It is built over [ERC-7710](https://eip.tools/eip/7710) and [ERC-7715](https://eip.tools/eip/7715) to support a standardized minimal interface. Requesting ERC-7715 permissions and redeeming ERC-7710 delegations are experimental features. +The [MetaMask Smart Accounts Kit](https://docs.metamask.io/smart-accounts-kit) enables embedding MetaMask Smart Accounts into dapps. Smart accounts support programmable account behavior and advanced features like delegated permissions, multi-signature approvals, and gas abstraction. [Delegation](https://docs.metamask.io/smart-accounts-kit/guides/delegation/execute-on-smart-accounts-behalf) is a core feature of smart accounts, enabling secure, rule-based permission sharing. There are two types of accounts involved in delegation: -1. **Delegator account**: A smart account that supports programmable account behavior and advanced features such as multi-signature approvals, automated transaction batching, and custom security policies. -2. **Delegate account**: An account (smart account or EOA) that receives the delegation from the delegator account to perform actions on behalf of the delegator account. +1. **Delegator account**: An account that allows users to grant permissions to other accounts to perform executions on their behalf, under defined rules and restrictions. Delegator accounts must be MetaMask Smart Accounts. +2. **Delegate account**: An account that receives permissions to perform executions on behalf of the delegator account. Delegate accounts can be smart accounts or externally owned accounts (EOAs). You can use both accounts with permissionless.js. ## Installation -We will be using MetaMask's official SDK to create a smart account. +Use MetaMask's official SDK to create a smart account. :::code-group ```bash [npm] -npm install permissionless viem @metamask/delegation-toolkit +npm install permissionless viem @metamask/smart-accounts-kit ``` ```bash [yarn] -yarn add permissionless viem @metamask/delegation-toolkit +yarn add permissionless viem @metamask/smart-accounts-kit ``` ```bash [pnpm] -pnpm install permissionless viem @metamask/delegation-toolkit +pnpm install permissionless viem @metamask/smart-accounts-kit ``` ```bash [bun] -bun install permissionless viem @metamask/delegation-toolkit +bun install permissionless viem @metamask/smart-accounts-kit ``` ::: -## Delegator Account +## Delegator account ::::steps ### Create the clients -First we must create the public, (optionally) pimlico paymaster clients that will be used to interact with the MetaMask smart account. +First, create the public client and (optional) pimlico paymaster client that will be used to interact with the MetaMask smart account. ```ts // [!include ~/snippets/accounts/metamask.ts:clients] @@ -51,7 +51,7 @@ First we must create the public, (optionally) pimlico paymaster clients that wil ### Create the signer -MetaMask Smart Accounts can work with a variety of signing algorithms such as ECDSA, passkeys, and multisig. +MetaMask Smart Accounts can work with a variety of signing algorithms, such as ECDSA, passkeys, and multisig. For example, to create a signer based on a private key: @@ -62,7 +62,7 @@ For example, to create a signer based on a private key: ### Create the delegator smart account :::info -For a full list of options for creating a MetaMask smart account, take a look at the MetaMask's documentation page for [`toMetaMaskSmartAccount`](https://docs.metamask.io/delegation-toolkit/how-to/create-smart-account). +For a full list of options for creating a MetaMask smart account, see [the MetaMask documentation](https://docs.metamask.io/smart-accounts-kit/guides/smart-accounts/create-smart-account). ::: With a signer, you can create a MetaMask smart account as such: @@ -79,13 +79,13 @@ With a signer, you can create a MetaMask smart account as such: ### Send a transaction -Transactions using permissionless.js simply wrap around user operations. This means you can switch to permissionless.js from your existing viem EOA codebase with minimal-to-no changes. +Transactions using permissionless.js wrap around user operations. This means you can switch to permissionless.js from your existing Viem EOA codebase with minimal-to-no changes. ```ts // [!include ~/snippets/accounts/metamask.ts:submit] ``` -This also means you can also use viem Contract instances to transact without any modifications. +This also means you can also use Viem Contract instances to transact without any modifications. ```ts // [!include ~/snippets/accounts/metamask.ts:submitNft] @@ -99,22 +99,17 @@ You can also send an array of transactions in a single batch. :::: -## Delegate Account +## Delegate account A delegate account is an account that receives the delegation from the delegator account to perform actions on behalf of the delegator account. -To create a delegate account, we will follow the following steps: - -1. Create a delegate signer -2. Create the delegate smart account -3. Create a delegation using delegator smart account -4. Sign the delegation -5. Send transactions using delegate smart account with signed delegation +The delegate account can be a MetaMask smart account or an EOA. +The following example uses a smart account. ::::steps ### Create the clients -First we must create the public, (optionally) pimlico paymaster clients that will be used to interact with the MetaMask smart account. +First, create the public client and (optional) pimlico paymaster client that will be used to interact with the MetaMask smart account. ```ts // [!include ~/snippets/accounts/metamask.ts:clients] @@ -122,7 +117,7 @@ First we must create the public, (optionally) pimlico paymaster clients that wil ### Create the signer -MetaMask Smart Accounts can work with a variety of signing algorithms such as ECDSA, passkeys, and multisig. +MetaMask Smart Accounts can work with a variety of signing algorithms, such as ECDSA, passkeys, and multisig. For example, to create a signer based on a private key: @@ -133,7 +128,7 @@ For example, to create a signer based on a private key: ### Create the delegate smart account :::info -For a full list of options for creating a MetaMask smart account, take a look at the MetaMask's documentation page for [`toMetaMaskSmartAccount`](https://docs.metamask.io/delegation-toolkit/how-to/create-smart-account). +For a full list of options for creating a MetaMask smart account, see [the MetaMask documentation](https://docs.metamask.io/smart-accounts-kit/guides/smart-accounts/create-smart-account). ::: With a delegate signer, you can create a MetaMask delegate account as such: @@ -144,7 +139,8 @@ With a delegate signer, you can create a MetaMask delegate account as such: ### Create a delegation -This example passes an empty caveats array, which means the delegate can perform any action on the delegator's behalf. We recommend restricting the delegation by adding caveat enforcers. +This example uses the ERC-20 transfer scope, which ensures that ERC-20 token transfers made by the delegate account are limited to a specified amount. +You can read more about the Smart Accounts Kit's [delegation scopes](https://docs.metamask.io/smart-accounts-kit/guides/delegation/use-delegation-scopes). ```ts // [!include ~/snippets/accounts/metamask.ts:createDelegation] diff --git a/docs/snippets/accounts/metamask.ts b/docs/snippets/accounts/metamask.ts index bd178824..726c3a86 100644 --- a/docs/snippets/accounts/metamask.ts +++ b/docs/snippets/accounts/metamask.ts @@ -1,17 +1,11 @@ -// [!region imports] -import { createSmartAccountClient } from "permissionless"; -import { - createPublicClient, - encodeFunctionData, - getContract, - http, - parseEther, -} from "viem"; +// [!region clients] +import { createPublicClient, http } from "viem"; import { sepolia } from "viem/chains"; -// [!endregion imports] +import { createPimlicoClient } from "permissionless/clients/pimlico"; +import { entryPoint07Address } from "viem/account-abstraction"; -// [!region clients] export const publicClient = createPublicClient({ + chain: sepolia, transport: http("https://sepolia.rpc.thirdweb.com"), }); @@ -26,13 +20,13 @@ export const paymasterClient = createPimlicoClient({ // [!region signer] import { privateKeyToAccount } from "viem/accounts"; -import { createPimlicoClient } from "permissionless/clients/pimlico"; -import { entryPoint07Address } from "viem/account-abstraction"; const owner = privateKeyToAccount("0xPRIVATE_KEY"); // [!endregion signer] // [!region delegateSigner] +import { privateKeyToAccount } from "viem/accounts"; + const delegateSigner = privateKeyToAccount("0xPRIVATE_KEY"); // [!endregion delegateSigner] @@ -40,35 +34,45 @@ const delegateSigner = privateKeyToAccount("0xPRIVATE_KEY"); import { Implementation, toMetaMaskSmartAccount, -} from "@metamask/delegation-toolkit"; +} from "@metamask/smart-accounts-kit"; const delegatorSmartAccount = await toMetaMaskSmartAccount({ client: publicClient, implementation: Implementation.Hybrid, deployParams: [owner.address, [], [], []], deploySalt: "0x", - signatory: { account: owner }, + signer: { account: owner }, }); - // [!endregion smartAccount] // [!region delegateSmartAccount] +import { + Implementation, + toMetaMaskSmartAccount, +} from "@metamask/smart-accounts-kit"; + const delegateSmartAccount = await toMetaMaskSmartAccount({ client: publicClient, implementation: Implementation.Hybrid, deployParams: [delegateSigner.address, [], [], []], deploySalt: "0x", - signatory: { account: delegateSigner }, + signer: { account: delegateSigner }, }); // [!endregion delegateSmartAccount] // [!region createDelegation] -import { createDelegation } from "@metamask/delegation-toolkit"; +import { createDelegation } from "@metamask/smart-accounts-kit"; +import { parseUnits } from "viem"; const delegation = createDelegation({ to: delegateSmartAccount.address, from: delegatorSmartAccount.address, - caveats: [], + environment: delegatorSmartAccount.environment, + scope: { + type: "erc20TransferAmount", + tokenAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", + maxAmount: parseUnits("10", 6), + }, }); // [!endregion createDelegation] @@ -84,6 +88,8 @@ const signedDelegation = { // [!endregion signDelegation] // [!region smartAccountClient] +import { createSmartAccountClient } from "permissionless"; + const smartAccountClient = createSmartAccountClient({ account: delegatorSmartAccount, chain: sepolia, @@ -99,6 +105,8 @@ const smartAccountClient = createSmartAccountClient({ // [!endregion smartAccountClient] // [!region delegateSmartAccountClient] +import { createSmartAccountClient } from "permissionless"; + const delegateSmartAccountClient = createSmartAccountClient({ account: delegateSmartAccount, chain: sepolia, @@ -114,6 +122,8 @@ const delegateSmartAccountClient = createSmartAccountClient({ // [!endregion delegateSmartAccountClient] // [!region submit] +import { parseEther } from "viem"; + const txHash_$1 = await smartAccountClient.sendTransaction({ to: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", value: parseEther("0.1"), @@ -134,6 +144,8 @@ const tokenAbi = [ ] as const; // [!region submitNft] +import { getContract } from "viem"; + const nftContract = getContract({ address: "0xFC3e86566895Fb007c6A0d3809eb2827DF94F751", abi: tokenAbi, @@ -167,27 +179,27 @@ const userOpHash_$3 = await smartAccountClient.sendUserOperation({ // [!endregion submitBatch] // [!region sendTransactionWithDelegation] -import { DelegationManager } from "@metamask/delegation-toolkit/contracts"; -import { SINGLE_DEFAULT_MODE } from "@metamask/delegation-toolkit/utils"; -import { createExecution } from "@metamask/delegation-toolkit"; +import { DelegationManager } from "@metamask/smart-accounts-kit/contracts"; +import { createExecution, ExecutionMode } from "@metamask/smart-accounts-kit"; +import { encodeFunctionData, erc20Abi } from "viem"; const delegations = [signedDelegation]; // Actual execution to be performed by the delegate account const executions = [ createExecution({ - target: "0xFC3e86566895Fb007c6A0d3809eb2827DF94F751", + target: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", callData: encodeFunctionData({ - abi: tokenAbi, - functionName: "mint", - args: ["0x_MY_ADDRESS_TO_MINT_TOKENS", parseEther("1")], + abi: erc20Abi, + functionName: "transfer", + args: [delegateSmartAccount.address, parseUnits("1", 6)], }), }), ]; const redeemDelegationCalldata = DelegationManager.encode.redeemDelegations({ delegations: [delegations], - modes: [SINGLE_DEFAULT_MODE], + modes: [ExecutionMode.SingleDefault], executions: [executions], }); diff --git a/package.json b/package.json index 29eecf21..5c5b705d 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@lit-protocol/pkp-ethers": "^3.0.0", "@lit-protocol/types": "^3.0.0", "@magic-ext/oauth": "^16.1.1", - "@metamask/delegation-toolkit": "^0.12.0", + "@metamask/smart-accounts-kit": "^0.13.0", "@particle-network/auth": "^1.3.1", "@particle-network/provider": "^1.3.2", "@permissionless/wagmi": "^0.1.0",