> For the complete documentation index, see [llms.txt](https://help.tokenpocket.pro/developer-en/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.tokenpocket.pro/developer-en/agentic-wallet/eip-7715-account-with-permissions/request-execution-permissions.md).

# Request Execution Permissions

`wallet_requestExecutionPermissions` is the core EIP-7715 method. A DApp/Agent uses it to request authorization from a TokenPocket user. After the user confirms in the wallet UI, it returns a permission response that can be used for subsequent redeem operations.

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

1. Wallet connected (`eth_requestAccounts`).
2. It is recommended to call `wallet_getSupportedExecutionPermissions` first to confirm capabilities.
3. A **Session Account** address prepared and set in the `to` field of the request.

### RPC Method <a href="#rpc-method" id="rpc-method"></a>

```
wallet_requestExecutionPermissions
```

#### Request Parameters <a href="#request-parameters" id="request-parameters"></a>

```typescript
type PermissionRequest = {
  chainId: `0x${string}` // hex chainId
  from?: `0x${string}` // user's account
  to: `0x${string}` // DApp/Agent Session Account / Delegate address
  permission: {
    type: string
    isAdjustmentAllowed: boolean
    data: Record<string, unknown>
  }
  rules?: {
    type: string
    data: Record<string, unknown>
  }[]
}

// params is PermissionRequest array
params: PermissionRequest[]
```

### Complete Example: Request a Single Authorization <a href="#complete-example-request-a-single-authorization" id="complete-example-request-a-single-authorization"></a>

```typescript
import { parseUnits, toHex } from "viem";

const provider = window.ethereum;

// 1. connect wallet
const [userAddress] = await provider.request({ method: "eth_requestAccounts" });

// 2. Session Account which receive permissions
const sessionAddress = "0xYourSessionAccount...";

// 3. Build the request
const chainId = "0x38"; // BNB Chain = 56
const expiry = Math.floor(Date.now() / 1000) + 7 * 86400;

const grantedPermissions = await provider.request({
  method: "wallet_requestExecutionPermissions",
  params: [
    {
      chainId,
      from: userAddress,
      to: sessionAddress,
      permission: {
        type: "erc20-token-periodic",
        isAdjustmentAllowed: true,
        data: {
          tokenAddress: "0x55d398326f99059fF775485246999027B3197955",
          periodAmount: toHex(parseUnits("10", 18)),
          periodDuration: 86400,
          justification: "Allow DApp/Agent to transfer up to 10 USDT per day",
        },
      },
      rules: [
        {
          type: "expiry",
          data: { timestamp: expiry },
        },
      ],
    },
  ],
});

console.log(grantedPermissions[0].context);
console.log(grantedPermissions[0].delegationManager);
```

### Response Structure <a href="#response-structure" id="response-structure"></a>

```typescript
type PermissionResponse = PermissionRequest & {
  context: `0x${string}`;
  delegationManager: `0x${string}`;
  dependencies: {
    factory: `0x${string}`;
    factoryData: `0x${string}`;
  }[];
};
```

| Field               | Description                                                                                                                       |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `context`           | Passed to `_permissionContexts` when redeeming                                                                                    |
| `delegationManager` | Target contract for calling `redeemDelegations`                                                                                   |
| `dependencies`      | Account deployment dependencies that may need to be handled before redeem; empty means no extra pre-deployment steps are required |

> The response may contain permission parameters adjusted by the user (when `isAdjustmentAllowed: true` is set). Do not assume they match the request exactly.

### Batch Requests <a href="#batch-requests" id="batch-requests"></a>

`params` supports an array, allowing multiple permissions to be requested at once, **but they must share the same `chainId`**:

```typescript
const granted = await provider.request({
  method: "wallet_requestExecutionPermissions",
  params: [
    {
      chainId: "0x38",
      to: sessionAddress,
      permission: {
        /* erc20-token-periodic */
      },
      rules: [{ type: "expiry", data: { timestamp: expiry } }],
    },
    {
      chainId: "0x38",
      to: sessionAddress,
      permission: {
        /* native-token-stream */
      },
      rules: [{ type: "expiry", data: { timestamp: expiry } }],
    },
  ],
});
```

Cross-chain batch requests will fail.

### Field Descriptions <a href="#field-descriptions" id="field-descriptions"></a>

#### `from` <a href="#from" id="from"></a>

* Source account for authorization (user EOA / smart account).
* Can be omitted when a single account is connected; the wallet uses the currently active account.

#### `to` <a href="#to" id="to"></a>

* **DApp/Agent Session Account / Delegate address**, i.e., the permission recipient.
* When redeeming with this permission later, this address should be the execution/signing entity.

#### `isAdjustmentAllowed` <a href="#isadjustmentallowed" id="isadjustmentallowed"></a>

* `true`: Allows the wallet to adjust the authorization scope before the user confirms, such as amount, period, flow rate, expiry, and other fields the wallet supports editing. The DApp/Agent must treat the permission returned by the wallet as authoritative.
* `false`: The user cannot adjust permission parameters; suitable when the DApp/Agent requires fixed authorization conditions.

#### `justification` <a href="#justification" id="justification"></a>

* Authorization description shown to the user; should clearly describe the purpose.

#### Amount Fields <a href="#amount-fields" id="amount-fields"></a>

Amount fields such as `periodAmount`, `initialAmount`, `maxAmount`, and `amountPerSecond` use **hex-encoded smallest units** (RPC quantity):

```typescript
import { parseUnits, toHex } from "viem";

toHex(parseUnits("10", 18)); // ERC-20, 18 decimals
toHex(parseUnits("10", 6)); // USDC, 6 decimals
```

`periodDuration`, `startTime`, and `rules[].data.timestamp` use plain **number** values.

### Permission Type Quick Reference <a href="#permission-type-quick-reference" id="permission-type-quick-reference"></a>

| Type                    | Documentation          |
| ----------------------- | ---------------------- |
| `erc20-token-periodic`  | ERC-20 periodic        |
| `erc20-token-stream`    | ERC-20 streaming       |
| `native-token-periodic` | Native token periodic  |
| `native-token-stream`   | Native token streaming |

### Error Handling <a href="#error-handling" id="error-handling"></a>

Common failure reasons:

* Permission type or chain not supported
* Invalid parameter format (e.g., `amountPerSecond` is 0)
* User rejected authorization
* For `stream` types, `maxAmount < initialAmount`
* Batch request contains multiple `chainId` values

```typescript
try {
  const granted = await provider.request({
    method: "wallet_requestExecutionPermissions",
    params: [request],
  });
} catch (error) {
  // EIP-1193 error
}
```

### Steps After Authorization <a href="#steps-after-authorization" id="steps-after-authorization"></a>

1. Save `context`, `delegationManager`, and the complete `permission` data.
2. Have the Session Account call `redeemDelegations`
