From b586968f9e3503d01f75e91ac9d19e4c7b851ec5 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 10:53:17 +0530 Subject: [PATCH 01/10] add delegations buyer guide --- gator-sidebar.js | 13 + .../guides/x402/buyer/delegations.md | 251 ++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 smart-accounts-kit/guides/x402/buyer/delegations.md diff --git a/gator-sidebar.js b/gator-sidebar.js index 4805680dc5e..4f2ebbdaf81 100644 --- a/gator-sidebar.js +++ b/gator-sidebar.js @@ -113,6 +113,19 @@ const sidebar = { 'guides/advanced-permissions/create-redelegation', ], }, + { + type: 'category', + label: 'x402', + collapsed: true, + items: [ + { + type: 'category', + label: 'Buyer', + collapsed: true, + items: ['guides/x402/buyer/delegations'], + }, + ], + }, ], }, { diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md new file mode 100644 index 00000000000..5eb36fe6c03 --- /dev/null +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -0,0 +1,251 @@ +--- +description: Access x402-protected API data using delegation. +sidebar_label: Delegations +keywords: [x402, ERC-7710, delegation, smart account, facilitator, buyer, API] +--- + +import Tabs from '@theme/Tabs' +import TabItem from '@theme/TabItem' +import GlossaryTerm from '@theme/GlossaryTerm' + +# Pay for x402 API with delegations + +In this guide, you use a buyer smart account +to access API data from an x402 server. + +You create an open delegation, restrict redemption to the facilitator, encode the delegation chain, +and send it as the payment payload when calling a protected API route. + +## Prerequisites + +- [Install and set up the Smart Accounts Kit.](../../../get-started/install.md) +- Fund smart account with USDC for the requested payment. + +## Steps + +### 1. Create a buyer account + +Create an account to represent buyer, the delegator who will create a delegation. + +The delegator must be a ; use the toolkit's [`toMetaMaskSmartAccount`](../../../reference/smart-account.md#tometamasksmartaccount) method to create the buyer account. + + + + +```ts +import { Implementation, toMetaMaskSmartAccount } from '@metamask/smart-accounts-kit' +import { publicClient, buyerAccount } from './config' + +export const buyerSmartAccount = await toMetaMaskSmartAccount({ + client: publicClient, + implementation: Implementation.Hybrid, + deployParams: [buyerAccount.address, [], [], []], + deploySalt: '0x', + signer: { account: buyerAccount }, +}) +``` + + + + +```ts +import { createPublicClient, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { base as chain } from 'viem/chains' + +export const publicClient = createPublicClient({ + chain, + transport: http(), +}) + +export const buyerAccount = privateKeyToAccount('0x') +``` + + + + +### 2. Get payment requirements + +Call the protected API route once without a payment header. + +The server returns `402` and includes `PAYMENT-REQUIRED`, which gives you the payment terms needed +to create an appropriate payment payload. + + + + +```ts +import { PaymentRequirements } from './types' + +// Update the URL +const challengeResponse = await fetch('https://api.example.com/paid-endpoint') +if (challengeResponse.status !== 402) { + console.error('Expected 402 challenge from protected route') + // Handle error +} + +const paymentRequiredHeader = challengeResponse.headers.get('PAYMENT-REQUIRED') +if (!paymentRequiredHeader) { + console.error('PAYMENT-REQUIRED header is missing') + // Handle error +} + +const decodedPaymentRequired = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8') +const paymentRequired = JSON.parse(decodedPaymentRequired) as { + accepts: PaymentRequirements[] +} + +const accepted = paymentRequired.accepts[0] +if (!accepted) { + console.error('Server did not provide accepted payment requirements') + // Handle error +} + +if (accepted.extra.assetTransferMethod !== 'erc7710') { + console.error('Server does not support ERC-7710 delegation payments') + // Handle error +} +``` + + + + +```ts +export type PaymentRequirements = { + scheme: string + network: string + amount: string + asset: `0x${string}` + payTo: `0x${string}` + maxTimeoutSeconds: number + extra: { + assetTransferMethod: string + facilitators?: `0x${string}`[] + } +} +``` + + + + +### 3. Create a delegation + +Create an [open root delegation](../../../concepts/delegation/overview.md#open-root-delegation) +from the buyer's smart account. With an open root delegation, the buyer delegates authority without +setting a specific delegate. Use [`createOpenDelegation`](../../../reference/delegation/index.md#createopendelegation) to create the open root delegation. + +This example uses the [`erc20TransferAmount`](../../../guides/delegation/use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) +scope to allow USDC transfers up to the amount requested in `PAYMENT-REQUIRED`. +It also uses the [`redeemer`](../../../reference/delegation/caveats.md#redeemer) caveat enforcer to restrict +redemption to facilitator addresses provided by the server. + +Before creating the delegation, make sure your buyer smart account is deployed. If it is not +deployed, delegation redemption will fail. + +```ts +import { CaveatType, createOpenDelegation, ScopeType } from '@metamask/smart-accounts-kit' + +const facilitators = accepted.extra.facilitators +if (!facilitators || facilitators.length === 0) { + console.log('No facilitators found in PAYMENT-REQUIRED') + // Handle the error +} + +// Use the amount requested by the seller. +const maxAmount = BigInt(accepted.amount) + +const caveats = [ + { + type: CaveatType.Redeemer, + redeemers: facilitators, + }, +] + +const delegation = createOpenDelegation({ + from: buyerSmartAccount.address, + environment: buyerSmartAccount.environment, + scope: { + type: ScopeType.Erc20TransferAmount, + tokenAddress: accepted.asset, + maxAmount, + }, + caveats, +}) + +const signature = await buyerSmartAccount.signDelegation({ + delegation, +}) + +const signedDelegation = { + ...delegation, + signature, +} +``` + +### 4. Create the payment payload + +Create a payment payload using the signed delegation and accepted requirements. +For ERC-7710, x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. +The facilitator uses `permissionContext` to simulate during verification and then settle the payment. + +Use `encodeDelegations` to encode the delegation chain. Then base64 encode the full payment payload before sending it in the `payment-signature` header. + + + + +```ts +import { encodeDelegations } from '@metamask/smart-accounts-kit/utils' +import { PaymentPayload } from './types' + +const permissionContext = encodeDelegations([signedDelegation]) + +const paymentPayload: PaymentPayload = { + x402Version: 2, + accepted, + payload: { + delegationManager: buyerSmartAccount.environment.DelegationManager, + permissionContext, + delegator: buyerSmartAccount.address, + }, +} + +const encodedPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('base64') +``` + + + + +```ts +export type PaymentPayload = { + x402Version: 2 + accepted: PaymentRequirements + payload: { + delegationManager: `0x${string}` + permissionContext: `0x${string}` + delegator: `0x${string}` + } +} +``` + + + + +### 5. Call the API + +Send the encoded payment payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. + +```ts +const apiResponse = await fetch('https://api.example.com/paid-endpoint', { + headers: { + 'payment-signature': encodedPayment, + }, +}) + +if (!apiResponse.ok) { + const errorBody = await apiResponse.json() + throw new Error(errorBody.error ?? 'API request failed') +} + +const data = await apiResponse.json() +console.log('Protected API response:', data) +``` From e7ae56e747a871e7c961591d520b2b0e218143c1 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 11:00:54 +0530 Subject: [PATCH 02/10] update step title --- smart-accounts-kit/guides/x402/buyer/delegations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md index 5eb36fe6c03..700c03ba5e1 100644 --- a/smart-accounts-kit/guides/x402/buyer/delegations.md +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -230,7 +230,7 @@ export type PaymentPayload = { -### 5. Call the API +### 5. Make paid request Send the encoded payment payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. From ef8566c9cad40ab3271ae5ba1023ff2b67b0e018 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 13:32:19 +0530 Subject: [PATCH 03/10] add advanced permission buyer guide --- gator-sidebar.js | 2 +- .../guides/x402/buyer/advanced-permissions.md | 289 ++++++++++++++++++ .../guides/x402/buyer/delegations.md | 27 +- 3 files changed, 306 insertions(+), 12 deletions(-) create mode 100644 smart-accounts-kit/guides/x402/buyer/advanced-permissions.md diff --git a/gator-sidebar.js b/gator-sidebar.js index 4f2ebbdaf81..d5459e2d848 100644 --- a/gator-sidebar.js +++ b/gator-sidebar.js @@ -122,7 +122,7 @@ const sidebar = { type: 'category', label: 'Buyer', collapsed: true, - items: ['guides/x402/buyer/delegations'], + items: ['guides/x402/buyer/delegations', 'guides/x402/buyer/advanced-permissions'], }, ], }, diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md new file mode 100644 index 00000000000..add9936b3f1 --- /dev/null +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -0,0 +1,289 @@ +--- +description: Access an x402-protected API data using Advanced Permissions with a fixed allowance. +sidebar_label: Advanced Permissions +keywords: + [x402, ERC-7715, ERC-7710, advanced permissions, redeemers, allowance, session account, buyer] +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import GlossaryTerm from '@theme/GlossaryTerm'; + +# Pay for an x402 API with Advanced Permissions + +In this guide, you request with a fixed ERC-20 allowance +to pay for a specific x402-protected resource. + +## Prerequisites + +- [Install and set up the Smart Accounts Kit.](../../../get-started/install.md) + +## Steps + +### 1. Set up a Wallet Client + +Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. This client will +help you interact with MetaMask. + +Then, extend the Wallet Client functionality using `erc7715ProviderActions`. +These actions enable you to request from the user. + +```typescript +import { createWalletClient, custom } from 'viem' +import { erc7715ProviderActions } from '@metamask/smart-accounts-kit/actions' + +const walletClient = createWalletClient({ + transport: custom(window.ethereum), +}).extend(erc7715ProviderActions()) +``` + +### 2. Set up a session account + +Set up a session account. The requested permissions are granted to the session account, which is responsible for making x402 API calls. + +The session account can be either a smart account or an EOA. This examples uses EOA as a session account. + +```typescript +import { privateKeyToAccount } from 'viem/accounts' +import { sepolia as chain } from 'viem/chains' +import { createWalletClient, http } from 'viem' + +const sessionAccount = privateKeyToAccount('0x...') +``` + +### 3. Get payment requirements + +Call the protected API route once without a payment header. + +The server returns `402` with the payment terms (`PAYMENT-REQUIRED`) in the response, which you use +to build the payment payload. + + + + +```ts +import { PaymentRequirements } from './types' + +// Update the URL +const challengeResponse = await fetch('https://api.example.com/paid-endpoint') +if (challengeResponse.status !== 402) { + console.error('Expected 402 challenge from protected route') + // Handle error +} + +const paymentRequiredHeader = challengeResponse.headers.get('PAYMENT-REQUIRED') +if (!paymentRequiredHeader) { + console.error('PAYMENT-REQUIRED header is missing') + // Handle error +} + +const decodedPaymentRequired = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8') +const paymentRequired = JSON.parse(decodedPaymentRequired) as { + accepts: PaymentRequirements[] +} + +const accepted = paymentRequired.accepts[0] +if (!accepted) { + console.error('Server did not provide accepted payment requirements') + // Handle error +} + +if (accepted.extra.assetTransferMethod !== 'erc7710') { + console.error('Server does not support ERC-7710 delegation payments') + // Handle error +} +``` + + + + +```ts +import { Address } from 'viem' + +export type PaymentRequirements = { + scheme: string + network: string + amount: string + asset: Address + payTo: Address + maxTimeoutSeconds: number + extra: { + assetTransferMethod: string + facilitators?: Address[] + } +} +``` + + + + +### 4. Request Advanced Permissions + +Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. + +In this example, you request an ERC-20 allowance permission with a fixed allowance equal to the +resource cost. Use the `redeemers` rule to restrict redemption to facilitator addresses from +the payment requirements. + +See the [`requestExecutionPermissions`](../../../reference/advanced-permissions/wallet-client.md#requestexecutionpermissions) API reference for more information. + +```ts +import { base as chain } from 'viem/chains' + +const facilitators = accepted.extra.facilitators +if (!facilitators || facilitators.length === 0) { + console.error('No facilitators found in PAYMENT-REQUIRED') + // Handle error +} + +const supportedPermissions = await walletClient.getSupportedExecutionPermissions() +const currentTime = Math.floor(Date.now() / 1000) +const expiry = currentTime + 3600 + +const grantedPermissions = await walletClient.requestExecutionPermissions([ + { + chainId: chain.id, + expiry, + to: sessionAccount.address, + permission: { + type: 'erc20-token-allowance', + data: { + tokenAddress: accepted.asset, + // Fixed allowance for this resource. + allowanceAmount: BigInt(accepted.amount), + justification: 'Permission to pay for a specific x402-protected API resource', + }, + isAdjustmentAllowed: false, + }, + rules: [ + { + type: 'redeemers', + data: { + addresses: facilitators!, + }, + }, + ], + }, +]) +``` + +### 5. Create a redelegation + +The granted advanced permisison is delegated to the session account. To let facilitator addresses +redeem this permission context for x402 settlement, create an open redelegation from the session account. + +Use the Wallet Client's [`redelegatePermissionContextOpen`](../../../reference/erc7710/wallet-client.md#redelegatepermissioncontextopen) +action to create a redelegated permission context. The granted permission already includes +a [redeemer enforcer](../../../reference/delegation/caveats.md#redeemer), so you do not add extra caveats here. + + + + +```ts +import { environment, sessionAccountWalletClient } from './config.ts' + +const permission = grantedPermissions[0] +if (!permission) { + console.error('No permission response returned by requestExecutionPermissions') + // Handle error +} + +const { permissionContext: redelegatedPermissionContext } = + await sessionAccountWalletClient.redelegatePermissionContextOpen({ + environment, + permissionContext: permission!.context, + }) +``` + + + + +```ts +import { createWalletClient, http } from 'viem' +import { base as chain } from 'viem/chains' +import { getSmartAccountsEnvironment } from '@metamask/smart-accounts-kit' +import { erc7710WalletActions } from '@metamask/smart-accounts-kit/actions' +import { sessionAccount } from './session-account.ts' + +export const environment = getSmartAccountsEnvironment(chain.id) + +export const sessionAccountWalletClient = createWalletClient({ + account: sessionAccount, + chain, + transport: http(), +}).extend(erc7710WalletActions()) +``` + + + + +### 6. Create the payment payload + +Create a payment payload using the redelegated permission context and accepted requirements. +For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `delegationManager`, +`permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate +during verification and then settle the payment. + +Encode the full payment payload as base64, then send it in the `payment-signature` header. + + + + +```ts +import { PaymentPayload } from './types' + +const permission = grantedPermissions[0] + +const paymentPayload: PaymentPayload = { + x402Version: 2, + accepted, + payload: { + delegationManager: permission.delegationManager, + permissionContext: redelegatedPermissionContext, + delegator: permission.from, + }, +} + +const encodedPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('base64') +``` + + + + +```ts +import { Address, Hex } from 'viem' + +export type PaymentPayload = { + x402Version: 2 + accepted: PaymentRequirements + payload: { + delegationManager: Address + permissionContext: Hex + delegator: Address + } +} +``` + + + + +### 7. Make the paid request + +Send the base64 encoded payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. + +```ts +const apiResponse = await fetch('https://api.example.com/paid-endpoint', { + headers: { + 'payment-signature': encodedPayment, + }, +}) + +if (!apiResponse.ok) { + const errorBody = await apiResponse.json() + console.error(errorBody.error ?? 'API request failed') + // Handle error +} + +const data = await apiResponse.json() +console.log('Protected API response:', data) +``` diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md index 700c03ba5e1..8d9b6eeda7c 100644 --- a/smart-accounts-kit/guides/x402/buyer/delegations.md +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -4,11 +4,11 @@ sidebar_label: Delegations keywords: [x402, ERC-7710, delegation, smart account, facilitator, buyer, API] --- -import Tabs from '@theme/Tabs' -import TabItem from '@theme/TabItem' -import GlossaryTerm from '@theme/GlossaryTerm' +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import GlossaryTerm from '@theme/GlossaryTerm'; -# Pay for x402 API with delegations +# Pay for an x402 API with delegation In this guide, you use a buyer smart account to access API data from an x402 server. @@ -19,16 +19,19 @@ and send it as the payment payload when calling a protected API route. ## Prerequisites - [Install and set up the Smart Accounts Kit.](../../../get-started/install.md) -- Fund smart account with USDC for the requested payment. ## Steps ### 1. Create a buyer account -Create an account to represent buyer, the delegator who will create a delegation. +Create an account to represent the buyer, the delegator who will create a delegation. The delegator must be a ; use the toolkit's [`toMetaMaskSmartAccount`](../../../reference/smart-account.md#tometamasksmartaccount) method to create the buyer account. +:::note Important +Fund the smart account with USDC for the requested payment. +::: + @@ -68,8 +71,8 @@ export const buyerAccount = privateKeyToAccount('0x') Call the protected API route once without a payment header. -The server returns `402` and includes `PAYMENT-REQUIRED`, which gives you the payment terms needed -to create an appropriate payment payload. +The server returns `402` with the payment terms (`PAYMENT-REQUIRED`) in the response, which you use +to build the payment payload. @@ -131,7 +134,7 @@ export type PaymentRequirements = { ### 3. Create a delegation Create an [open root delegation](../../../concepts/delegation/overview.md#open-root-delegation) -from the buyer's smart account. With an open root delegation, the buyer delegates authority without +from the buyer smart account. With an open root delegation, the buyer delegates authority without setting a specific delegate. Use [`createOpenDelegation`](../../../reference/delegation/index.md#createopendelegation) to create the open root delegation. This example uses the [`erc20TransferAmount`](../../../guides/delegation/use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) @@ -139,8 +142,10 @@ scope to allow USDC transfers up to the amount requested in `PAYMENT-REQUIRED`. It also uses the [`redeemer`](../../../reference/delegation/caveats.md#redeemer) caveat enforcer to restrict redemption to facilitator addresses provided by the server. +:::warning Before creating the delegation, make sure your buyer smart account is deployed. If it is not deployed, delegation redemption will fail. +::: ```ts import { CaveatType, createOpenDelegation, ScopeType } from '@metamask/smart-accounts-kit' @@ -185,7 +190,7 @@ const signedDelegation = { ### 4. Create the payment payload Create a payment payload using the signed delegation and accepted requirements. -For ERC-7710, x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. +For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. Use `encodeDelegations` to encode the delegation chain. Then base64 encode the full payment payload before sending it in the `payment-signature` header. @@ -230,7 +235,7 @@ export type PaymentPayload = { -### 5. Make paid request +### 5. Make the paid request Send the encoded payment payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. From 5ad13abe829e07a26a93ac15549c13bf2edd37b4 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 18:31:00 +0530 Subject: [PATCH 04/10] add recurring payments guide --- gator-sidebar.js | 6 +- .../guides/x402/buyer/advanced-permissions.md | 4 +- .../guides/x402/buyer/delegations.md | 6 +- .../guides/x402/buyer/recurring-payments.md | 276 ++++++++++++++++++ 4 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 smart-accounts-kit/guides/x402/buyer/recurring-payments.md diff --git a/gator-sidebar.js b/gator-sidebar.js index d5459e2d848..3f1c659c5aa 100644 --- a/gator-sidebar.js +++ b/gator-sidebar.js @@ -122,7 +122,11 @@ const sidebar = { type: 'category', label: 'Buyer', collapsed: true, - items: ['guides/x402/buyer/delegations', 'guides/x402/buyer/advanced-permissions'], + items: [ + 'guides/x402/buyer/delegations', + 'guides/x402/buyer/advanced-permissions', + 'guides/x402/buyer/recurring-payments', + ], }, ], }, diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index add9936b3f1..e07fac30d5a 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -224,7 +224,7 @@ For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `dele `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. -Encode the full payment payload as base64, then send it in the `payment-signature` header. +Encode the full payment payload as base64, then send it in the payment signature header. @@ -269,7 +269,7 @@ export type PaymentPayload = { ### 7. Make the paid request -Send the base64 encoded payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. +Send the base64 encoded payload in the payment signature header. If verification succeeds, the server returns the protected data. ```ts const apiResponse = await fetch('https://api.example.com/paid-endpoint', { diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md index 8d9b6eeda7c..7e19a41090b 100644 --- a/smart-accounts-kit/guides/x402/buyer/delegations.md +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -138,7 +138,7 @@ from the buyer smart account. With an open root delegation, the buyer delegates setting a specific delegate. Use [`createOpenDelegation`](../../../reference/delegation/index.md#createopendelegation) to create the open root delegation. This example uses the [`erc20TransferAmount`](../../../guides/delegation/use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) -scope to allow USDC transfers up to the amount requested in `PAYMENT-REQUIRED`. +scope to allow USDC transfers up to the amount requested in payment terms. It also uses the [`redeemer`](../../../reference/delegation/caveats.md#redeemer) caveat enforcer to restrict redemption to facilitator addresses provided by the server. @@ -193,7 +193,7 @@ Create a payment payload using the signed delegation and accepted requirements. For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. -Use `encodeDelegations` to encode the delegation chain. Then base64 encode the full payment payload before sending it in the `payment-signature` header. +Use `encodeDelegations` to encode the delegation chain. Then base64 encode the full payment payload before sending it in the payment signature header. @@ -237,7 +237,7 @@ export type PaymentPayload = { ### 5. Make the paid request -Send the encoded payment payload in the `payment-signature` header. If verification succeeds, the server returns the protected data. +Send the encoded payment payload in the payment signature header. If verification succeeds, the server returns the protected data. ```ts const apiResponse = await fetch('https://api.example.com/paid-endpoint', { diff --git a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md new file mode 100644 index 00000000000..e1b50ddb0ca --- /dev/null +++ b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md @@ -0,0 +1,276 @@ +--- +description: Set up recurring x402 API payments using Advanced Permissions. +sidebar_label: Recurring payments +keywords: + [ + x402, + ERC-7715, + ERC-7710, + advanced permissions, + recurring payments, + periodic permission, + session account, + buyer, + ] +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import GlossaryTerm from '@theme/GlossaryTerm'; + +# Recurring x402 payments + +In this guide, you set up recurring x402 payments by requesting an ERC-20 periodic + permission from a user. + +For example, a user gives your agent permission to spend up to 10 USDC per week. +Later, when the agent needs access an x402 endpoint, it checks the price, uses the permission the user +already gave it, and pays. + +## Prerequisites + +- [Install and set up the Smart Accounts Kit.](../../../get-started/install.md) + +## Steps + +### 1. Set up a Wallet Client + +Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. +This client will help you interact with MetaMask. + +Then, extend the Wallet Client functionality using `erc7715ProviderActions`. +These actions enable you to request from the user. + +```typescript +import { createWalletClient, custom } from 'viem' +import { erc7715ProviderActions } from '@metamask/smart-accounts-kit/actions' + +const walletClient = createWalletClient({ + transport: custom(window.ethereum), +}).extend(erc7715ProviderActions()) +``` + +### 2. Set up an agent account + +Set up an agent account. The requested permissions are granted to this account, which allows the agent +to make x402 API calls on behalf of the user. + +The agent account can be either a smart account or an EOA. This example uses an EOA as an agent account. + +```typescript +import { privateKeyToAccount } from 'viem/accounts' + +const sessionAccount = privateKeyToAccount('0x...') +``` + +### 3. Request Advanced Permisisons + +Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. + +In this example, you request an [ERC-20 periodic permission](../../advanced-permissions/use-permissions/erc20-token.md#erc-20-periodic-permission) with a weekly allowance of 10 USDC. This creates +a recurring payment budget that your agent can store and reuse for making x402 API call. + +See the [`requestExecutionPermissions`](../../../reference/advanced-permissions/wallet-client.md#requestexecutionpermissions) API reference for more information. + +```ts +import { base as chain } from 'viem/chains' +import { parseUnits } from 'viem' + +// USDC address on Base. +const tokenAddress = '0x...' + +const currentTime = Math.floor(Date.now() / 1000) +const expiry = currentTime + 60 * 60 * 24 * 30 // Permission expires in 30 days. + +const grantedPermissions = await walletClient.requestExecutionPermissions([ + { + chainId: chain.id, + expiry, + to: sessionAccount.address, + permission: { + type: 'erc20-token-periodic', + data: { + tokenAddress: accepted.asset, + periodAmount: parseUnits('10', 6), + periodDuration: 604800, + startTime: currentTime, + justification: + 'Permission for agent to spend up to 10 USDC every week for making x402 API calls', + }, + isAdjustmentAllowed: false, + }, + }, +]) +``` + +### 4. Get payment requirements + +Once your agent has been granted permission, when it wants to access an x402-protected endpoint, it +calls the endpoint without a payment header to request payment terms. + +The server returns `402` with the payment terms (`PAYMENT-REQUIRED`) in the response, which agent can use to +build the payment payload. + +```ts +import { PaymentRequirements } from './types' + +// Update the URL +const challengeResponse = await fetch('https://api.example.com/paid-endpoint') +if (challengeResponse.status !== 402) { + console.error('Expected 402 challenge from protected route') + // Handle error +} + +const paymentRequiredHeader = challengeResponse.headers.get('PAYMENT-REQUIRED') +if (!paymentRequiredHeader) { + console.error('PAYMENT-REQUIRED header is missing') + // Handle error +} + +const decodedPaymentRequired = Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8') +const paymentRequired = JSON.parse(decodedPaymentRequired) as { + accepts: PaymentRequirements[] +} + +const accepted = paymentRequired.accepts[0] +if (!accepted) { + console.error('Server did not provide accepted payment requirements') + // Handle error +} + +if (accepted.extra.assetTransferMethod !== 'erc7710') { + console.error('Server does not support ERC-7710 delegation payments') + // Handle error +} + +if (accepted.asset.toLowerCase() !== tokenAddress.toLowerCase()) { + console.error('Requested payment asset does not match recurring payment token') + // Handle error +} +``` + +### 5. Create a redelegation + +The granted advanced permission is delegated to the agent account. +For each protected API call, create a redelegation from the agent account so facilitator addresses +can redeem the permission context for x402 settlement. + +This example uses the [`erc20TransferAmount`](../../../guides/delegation/use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) +scope while creating redelegation to allow USDC transfers up to the amount requested in payment terms. It also uses +the [`redeemer`](../../../reference/delegation/caveats.md#redeemer) enforcer to restrict +redemption to facilitator addresses provided by the server. + +Use the Wallet Client's [`redelegatePermissionContext`](../../../reference/erc7710/wallet-client.md#redelegatepermissioncontextopen) action to create a redelegated permission +context. + + + + +```ts +import { environment, sessionAccountWalletClient } from './config.ts' +import { ScopeType, CaveatType } from '@metamask/smart-accounts-kit' + +const permission = grantedPermissions[0] +if (!permission) { + console.error('No permission response returned by requestExecutionPermissions') + // Handle error +} + +const facilitators = accepted.extra.facilitators +if (!facilitators || facilitators.length === 0) { + console.error('No facilitators found in payment terms') + // Handle error +} + +const { permissionContext: redelegatedPermissionContext } = + await sessionAccountWalletClient.redelegatePermissionContext({ + environment, + permissionContext: permission.context, + scope: { + type: ScopeType.Erc20TransferAmount, + tokenAddress: accepted.asset, + maxAmount: BigInt(accepted.amount), + }, + caveats: [ + { + type: CaveatType.Redeemer, + redeemers: facilitators, + }, + ], + }) +``` + + + + +```ts +import { createWalletClient, http } from 'viem' +import { base as chain } from 'viem/chains' +import { getSmartAccountsEnvironment } from '@metamask/smart-accounts-kit' +import { erc7710WalletActions } from '@metamask/smart-accounts-kit/actions' + +export const environment = getSmartAccountsEnvironment(chain.id) + +// Use sessionAccount from previous step +export const sessionAccountWalletClient = createWalletClient({ + account: sessionAccount, + chain, + transport: http(), +}).extend(erc7710WalletActions()) +``` + + + + +### 6. Make the payment payload + +For each protected API call, create a payment payload with the redelegated permission context. + +For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `delegationManager`, +`permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate +during verification and then settle the payment. + +Encode the full payment payload as base64, then send it in the payment signature header. + +```ts +import { PaymentPayload } from './types' + +const permission = grantedPermissions[0] + +const paymentPayload: PaymentPayload = { + x402Version: 2, + accepted, + payload: { + delegationManager: permission.delegationManager, + permissionContext: redelegatedPermissionContext, + delegator: permission.from, + }, +} + +const encodedPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('base64') +``` + +### 7. Make the paid request + +Send the base64 encoded payload in the payment signature header. + +```ts +const apiResponse = await fetch('https://api.example.com/paid-endpoint', { + headers: { + 'payment-signature': encodedPayment, + }, +}) + +if (!apiResponse.ok) { + const errorBody = await apiResponse.json() + console.error(errorBody.error ?? 'API request failed') + // Handle error +} + +const data = await apiResponse.json() +console.log('Protected API response:', data) +``` + +Reuse the same weekly granted permission for additional protected routes and providers in your agent flow. +Your agent can continue paying until the weekly cap is reached, then continue after the next weekly +period starts. From 370a69c2d1ff9ae5443d149b020618b216663931 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 18:32:44 +0530 Subject: [PATCH 05/10] fix typo --- smart-accounts-kit/guides/x402/buyer/advanced-permissions.md | 2 +- smart-accounts-kit/guides/x402/buyer/recurring-payments.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index e07fac30d5a..0239bbac240 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -169,7 +169,7 @@ const grantedPermissions = await walletClient.requestExecutionPermissions([ ### 5. Create a redelegation -The granted advanced permisison is delegated to the session account. To let facilitator addresses +The granted advanced permission is delegated to the session account. To let facilitator addresses redeem this permission context for x402 settlement, create an open redelegation from the session account. Use the Wallet Client's [`redelegatePermissionContextOpen`](../../../reference/erc7710/wallet-client.md#redelegatepermissioncontextopen) diff --git a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md index e1b50ddb0ca..9e5a3893ac6 100644 --- a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md +++ b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md @@ -63,7 +63,7 @@ import { privateKeyToAccount } from 'viem/accounts' const sessionAccount = privateKeyToAccount('0x...') ``` -### 3. Request Advanced Permisisons +### 3. Request Advanced Permissions Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. From 50af603c2a61c7941c1de0b149b562acdbadb26c Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 18:44:18 +0530 Subject: [PATCH 06/10] clean up code snippets --- smart-accounts-kit/guides/x402/buyer/advanced-permissions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index 0239bbac240..40cf4028535 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -136,7 +136,6 @@ if (!facilitators || facilitators.length === 0) { // Handle error } -const supportedPermissions = await walletClient.getSupportedExecutionPermissions() const currentTime = Math.floor(Date.now() / 1000) const expiry = currentTime + 3600 From d981a1f95af6ccd9049b35ed6ffc377067ed93ba Mon Sep 17 00:00:00 2001 From: Ayush Bherwani Date: Wed, 13 May 2026 23:33:09 +0530 Subject: [PATCH 07/10] Apply suggestions from code review Co-authored-by: Alexandra Carrillo <12214231+alexandratran@users.noreply.github.com> --- smart-accounts-kit/guides/x402/buyer/advanced-permissions.md | 2 +- smart-accounts-kit/guides/x402/buyer/recurring-payments.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index 40cf4028535..f78df7590e3 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -169,7 +169,7 @@ const grantedPermissions = await walletClient.requestExecutionPermissions([ ### 5. Create a redelegation The granted advanced permission is delegated to the session account. To let facilitator addresses -redeem this permission context for x402 settlement, create an open redelegation from the session account. +redeem this permission context for x402 settlement, create an open redelegation from the session account. Use the Wallet Client's [`redelegatePermissionContextOpen`](../../../reference/erc7710/wallet-client.md#redelegatepermissioncontextopen) action to create a redelegated permission context. The granted permission already includes diff --git a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md index 9e5a3893ac6..082e19c2661 100644 --- a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md +++ b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md @@ -24,7 +24,7 @@ In this guide, you set up recurring x402 payments by requesting an ERC-20 period permission from a user. For example, a user gives your agent permission to spend up to 10 USDC per week. -Later, when the agent needs access an x402 endpoint, it checks the price, uses the permission the user +Later, when the agent needs access to an x402 endpoint, it checks the price, uses the permission the user already gave it, and pays. ## Prerequisites @@ -68,7 +68,7 @@ const sessionAccount = privateKeyToAccount('0x...') Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. In this example, you request an [ERC-20 periodic permission](../../advanced-permissions/use-permissions/erc20-token.md#erc-20-periodic-permission) with a weekly allowance of 10 USDC. This creates -a recurring payment budget that your agent can store and reuse for making x402 API call. +a recurring payment budget that your agent can store and reuse for making an x402 API call. See the [`requestExecutionPermissions`](../../../reference/advanced-permissions/wallet-client.md#requestexecutionpermissions) API reference for more information. From 9559bae0dae45088f5b5f3ee08da514e51544e73 Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 23:46:52 +0530 Subject: [PATCH 08/10] minor fixes --- .../execute-on-metamask-users-behalf.md | 4 ++-- .../guides/x402/buyer/advanced-permissions.md | 9 +++++---- smart-accounts-kit/guides/x402/buyer/delegations.md | 6 ++++-- .../guides/x402/buyer/recurring-payments.md | 6 +++--- smart-accounts-kit/reference/erc7710/bundler-client.md | 2 +- smart-accounts-kit/reference/erc7710/wallet-client.md | 2 +- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/smart-accounts-kit/guides/advanced-permissions/execute-on-metamask-users-behalf.md b/smart-accounts-kit/guides/advanced-permissions/execute-on-metamask-users-behalf.md index 25296849092..ded0307650c 100644 --- a/smart-accounts-kit/guides/advanced-permissions/execute-on-metamask-users-behalf.md +++ b/smart-accounts-kit/guides/advanced-permissions/execute-on-metamask-users-behalf.md @@ -258,7 +258,7 @@ import { calldata } from './config.ts' // These properties must be extracted from the permission response. const permissionContext = grantedPermissions[0].context -const delegationManager = grantedPermissions[0].signerMeta.delegationManager +const delegationManager = grantedPermissions[0].delegationManager // USDC address on Ethereum Sepolia. const tokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' @@ -290,7 +290,7 @@ import { calldata } from './config.ts' // These properties must be extracted from the permission response. const permissionContext = grantedPermissions[0].context -const delegationManager = grantedPermissions[0].signerMeta.delegationManager +const delegationManager = grantedPermissions[0].delegationManager // USDC address on Ethereum Sepolia. const tokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238' diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index f78df7590e3..d78c1541958 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -122,7 +122,7 @@ export type PaymentRequirements = { Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. In this example, you request an ERC-20 allowance permission with a fixed allowance equal to the -resource cost. Use the `redeemers` rule to restrict redemption to facilitator addresses from +resource cost. Use the `redeemer` rule to restrict redemption to facilitator addresses from the payment requirements. See the [`requestExecutionPermissions`](../../../reference/advanced-permissions/wallet-client.md#requestexecutionpermissions) API reference for more information. @@ -156,7 +156,7 @@ const grantedPermissions = await walletClient.requestExecutionPermissions([ }, rules: [ { - type: 'redeemers', + type: 'redeemer', data: { addresses: facilitators!, }, @@ -223,7 +223,7 @@ For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `dele `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. -Encode the full payment payload as base64, then send it in the payment signature header. +Encode the full x402 payment payload as base64, then send it in the `payment-signature` header. @@ -268,7 +268,8 @@ export type PaymentPayload = { ### 7. Make the paid request -Send the base64 encoded payload in the payment signature header. If verification succeeds, the server returns the protected data. +Send the base64-encoded x402 payment payload in the `payment-signature` header. +If verification succeeds, the server returns the protected data. ```ts const apiResponse = await fetch('https://api.example.com/paid-endpoint', { diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md index 7e19a41090b..9dc8ca843ee 100644 --- a/smart-accounts-kit/guides/x402/buyer/delegations.md +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -193,7 +193,8 @@ Create a payment payload using the signed delegation and accepted requirements. For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. -Use `encodeDelegations` to encode the delegation chain. Then base64 encode the full payment payload before sending it in the payment signature header. +Use `encodeDelegations` to encode the delegation chain. +Then base64 encode the full x402 payment payload before sending it in the `payment-signature` header. @@ -237,7 +238,8 @@ export type PaymentPayload = { ### 5. Make the paid request -Send the encoded payment payload in the payment signature header. If verification succeeds, the server returns the protected data. +Send the encoded x402 payment payload in the `payment-signature` header. +If verification succeeds, the server returns the protected data. ```ts const apiResponse = await fetch('https://api.example.com/paid-endpoint', { diff --git a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md index 082e19c2661..6c4c7398842 100644 --- a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md +++ b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md @@ -90,7 +90,7 @@ const grantedPermissions = await walletClient.requestExecutionPermissions([ permission: { type: 'erc20-token-periodic', data: { - tokenAddress: accepted.asset, + tokenAddress, periodAmount: parseUnits('10', 6), periodDuration: 604800, startTime: currentTime, @@ -230,7 +230,7 @@ For ERC-7710 (Smart Contract Delegation), x402 requires the payload fields `dele `permissionContext`, and `delegator`. The facilitator uses `permissionContext` to simulate during verification and then settle the payment. -Encode the full payment payload as base64, then send it in the payment signature header. +Encode the full x402 payment payload as base64, then send it in the `payment-signature` header. ```ts import { PaymentPayload } from './types' @@ -252,7 +252,7 @@ const encodedPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('bas ### 7. Make the paid request -Send the base64 encoded payload in the payment signature header. +Send the base64-encoded x402 payment payload in the `payment-signature` header. ```ts const apiResponse = await fetch('https://api.example.com/paid-endpoint', { diff --git a/smart-accounts-kit/reference/erc7710/bundler-client.md b/smart-accounts-kit/reference/erc7710/bundler-client.md index 7f4d71cf1bc..e8fd93aabfe 100644 --- a/smart-accounts-kit/reference/erc7710/bundler-client.md +++ b/smart-accounts-kit/reference/erc7710/bundler-client.md @@ -45,7 +45,7 @@ import { sessionAccount, bundlerClient, publicClient } from './client.ts' // These properties must be extracted from the permission response. const permissionContext = permissionsResponse[0].context -const delegationManager = permissionsResponse[0].signerMeta.delegationManager +const delegationManager = permissionsResponse[0].delegationManager // Calls without permissionContext and delegationManager will be executed // as a normal user operation. diff --git a/smart-accounts-kit/reference/erc7710/wallet-client.md b/smart-accounts-kit/reference/erc7710/wallet-client.md index 406897eeaa7..7786a90f6d0 100644 --- a/smart-accounts-kit/reference/erc7710/wallet-client.md +++ b/smart-accounts-kit/reference/erc7710/wallet-client.md @@ -53,7 +53,7 @@ import { walletClient, publicClient } from './client.ts' // These properties must be extracted from the permission response. See // `grantPermissions` action to learn how to request permissions. const permissionContext = permissionsResponse[0].context -const delegationManager = permissionsResponse[0].signerMeta.delegationManager +const delegationManager = permissionsResponse[0].delegationManager const hash = walletClient.sendTransactionWithDelegation({ chain, From fdbf318adef891933fa6c6c58d397355c8c7ad9b Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Wed, 13 May 2026 23:49:52 +0530 Subject: [PATCH 09/10] add link to rule reference --- smart-accounts-kit/guides/x402/buyer/advanced-permissions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index d78c1541958..f646b63a04b 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -122,8 +122,8 @@ export type PaymentRequirements = { Request Advanced Permissions from the user with the Wallet Client's `requestExecutionPermissions` action. In this example, you request an ERC-20 allowance permission with a fixed allowance equal to the -resource cost. Use the `redeemer` rule to restrict redemption to facilitator addresses from -the payment requirements. +resource cost. Use the [`redeemer`](../../../reference/advanced-permissions/rules.md#redeemer) rule +to restrict redemption to facilitator addresses from the payment requirements. See the [`requestExecutionPermissions`](../../../reference/advanced-permissions/wallet-client.md#requestexecutionpermissions) API reference for more information. From 9915b95ce12b38b5d9a907e69c6a80f466b764cb Mon Sep 17 00:00:00 2001 From: AyushBherwani1998 Date: Thu, 14 May 2026 10:12:42 +0530 Subject: [PATCH 10/10] resolve review comments --- .../guides/x402/buyer/advanced-permissions.md | 11 +++++----- .../guides/x402/buyer/delegations.md | 2 +- .../guides/x402/buyer/recurring-payments.md | 21 +++++++------------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md index f646b63a04b..06fff475688 100644 --- a/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md +++ b/smart-accounts-kit/guides/x402/buyer/advanced-permissions.md @@ -1,5 +1,5 @@ --- -description: Access an x402-protected API data using Advanced Permissions with a fixed allowance. +description: Pay for an x402-protected API data using Advanced Permissions with a fixed allowance. sidebar_label: Advanced Permissions keywords: [x402, ERC-7715, ERC-7710, advanced permissions, redeemers, allowance, session account, buyer] @@ -22,11 +22,9 @@ to pay for a specific x402-protected resource. ### 1. Set up a Wallet Client -Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. This client will -help you interact with MetaMask. +Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. Use this client to interact with MetaMask. -Then, extend the Wallet Client functionality using `erc7715ProviderActions`. -These actions enable you to request from the user. +Extend the Wallet Client with `erc7715ProviderActions` to enable requests. ```typescript import { createWalletClient, custom } from 'viem' @@ -41,7 +39,8 @@ const walletClient = createWalletClient({ Set up a session account. The requested permissions are granted to the session account, which is responsible for making x402 API calls. -The session account can be either a smart account or an EOA. This examples uses EOA as a session account. +The session account can be either a smart account or an EOA. +This example uses an EOA as the session account. ```typescript import { privateKeyToAccount } from 'viem/accounts' diff --git a/smart-accounts-kit/guides/x402/buyer/delegations.md b/smart-accounts-kit/guides/x402/buyer/delegations.md index 9dc8ca843ee..06453ca8f62 100644 --- a/smart-accounts-kit/guides/x402/buyer/delegations.md +++ b/smart-accounts-kit/guides/x402/buyer/delegations.md @@ -1,5 +1,5 @@ --- -description: Access x402-protected API data using delegation. +description: Pay for an x402-protected API data using delegation. sidebar_label: Delegations keywords: [x402, ERC-7710, delegation, smart account, facilitator, buyer, API] --- diff --git a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md index 6c4c7398842..fc0c03e68c7 100644 --- a/smart-accounts-kit/guides/x402/buyer/recurring-payments.md +++ b/smart-accounts-kit/guides/x402/buyer/recurring-payments.md @@ -24,8 +24,7 @@ In this guide, you set up recurring x402 payments by requesting an ERC-20 period permission from a user. For example, a user gives your agent permission to spend up to 10 USDC per week. -Later, when the agent needs access to an x402 endpoint, it checks the price, uses the permission the user -already gave it, and pays. +Later, when the agent calls an x402 endpoint, it checks the price, uses the granted permission, and pays. ## Prerequisites @@ -35,11 +34,9 @@ already gave it, and pays. ### 1. Set up a Wallet Client -Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. -This client will help you interact with MetaMask. +Set up a Wallet Client using Viem's [`createWalletClient`](https://viem.sh/docs/clients/wallet) function. Use this client to interact with MetaMask. -Then, extend the Wallet Client functionality using `erc7715ProviderActions`. -These actions enable you to request from the user. +Extend the Wallet Client with `erc7715ProviderActions` to enable requests. ```typescript import { createWalletClient, custom } from 'viem' @@ -52,10 +49,8 @@ const walletClient = createWalletClient({ ### 2. Set up an agent account -Set up an agent account. The requested permissions are granted to this account, which allows the agent -to make x402 API calls on behalf of the user. - -The agent account can be either a smart account or an EOA. This example uses an EOA as an agent account. +The session account can be either a smart account or an EOA. +This example uses an EOA as the session account. ```typescript import { privateKeyToAccount } from 'viem/accounts' @@ -105,8 +100,8 @@ const grantedPermissions = await walletClient.requestExecutionPermissions([ ### 4. Get payment requirements -Once your agent has been granted permission, when it wants to access an x402-protected endpoint, it -calls the endpoint without a payment header to request payment terms. +Call the x402-protected endpoint without a payment header to request payment terms +after your agent has been granted permission. The server returns `402` with the payment terms (`PAYMENT-REQUIRED`) in the response, which agent can use to build the payment payload. @@ -222,7 +217,7 @@ export const sessionAccountWalletClient = createWalletClient({ -### 6. Make the payment payload +### 6. Create the payment payload For each protected API call, create a payment payload with the redelegated permission context.