From 247ee1691e2daa4b33671e5de141732b25769b78 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 29 May 2026 10:32:56 -0500 Subject: [PATCH 1/4] Add ERC-7715 execution permission methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add OpenRPC definitions for the ERC-7715 execution permission methods and their supporting schemas: - wallet_requestExecutionPermissions - wallet_getGrantedExecutionPermissions - wallet_getSupportedExecutionPermissions - wallet_revokeExecutionPermission These methods are already implemented in the wallet (via the permissions kernel Snap) and reachable over the EIP-1193 provider, but they are absent from the OpenRPC document. As a result they are not included in `KnownRpcMethods.eip155` (which `@metamask/chain-agnostic-permission` derives from this document), so they cannot be authorized in a CAIP-25 session and fail with an "unauthorized" error when invoked via the Multichain API (`wallet_invokeMethod`) — e.g. when used through MetaMask Connect. Adding them here makes them authorizable over the Multichain API, matching the existing EIP-1193 behaviour. --- CHANGELOG.md | 2 + openrpc.yaml | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8df988..6f102ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Add ERC-7715 execution permission methods: `wallet_requestExecutionPermissions`, `wallet_getGrantedExecutionPermissions`, `wallet_getSupportedExecutionPermissions`, `wallet_revokeExecutionPermission`, along with the `ExecutionPermission`, `ExecutionPermissionRule`, `ExecutionPermissionRequest`, and `ExecutionPermissionResponse` schemas ([#311](https://github.com/MetaMask/api-specs/pull/311)) ## [0.14.0] ### Added diff --git a/openrpc.yaml b/openrpc.yaml index 20ce8e4..1a6bd62 100644 --- a/openrpc.yaml +++ b/openrpc.yaml @@ -781,6 +781,180 @@ methods: '0xaa36a7': atomic: status: ready + - name: wallet_requestExecutionPermissions + tags: + - $ref: '#/components/tags/MetaMask' + - $ref: '#/components/tags/Experimental' + - $ref: '#/components/tags/Multichain' + summary: Requests ERC-7715 execution permissions. + description: >- + Requests that the user grant one or more ERC-7715 execution permissions, + allowing a delegate account to perform a constrained set of actions on + behalf of the user's account. Specified by + [ERC-7715](https://eips.ethereum.org/EIPS/eip-7715). + params: + - name: Permission requests + required: true + description: An array of execution permission requests. + schema: + type: array + items: + $ref: '#/components/schemas/ExecutionPermissionRequest' + result: + name: Granted permissions + description: An array of the granted execution permissions. + schema: + type: array + items: + $ref: '#/components/schemas/ExecutionPermissionResponse' + errors: + - $ref: '#/components/errors/InvalidParams' + - $ref: '#/components/errors/UserRejected' + - $ref: '#/components/errors/Unauthorized' + examples: + - name: wallet_requestExecutionPermissions example + params: + - name: Permission requests + value: + - chainId: '0xaa36a7' + to: '0x4B0897b0513FdBeEc7C469D9aF4fA6C0752aBea7' + permission: + type: native-token-periodic + isAdjustmentAllowed: true + data: + periodAmount: '0x38d7ea4c68000' + periodDuration: 86400 + justification: Permission to transfer 0.001 ETH every day + rules: [] + result: + name: Granted permissions + value: + - chainId: '0xaa36a7' + to: '0x4B0897b0513FdBeEc7C469D9aF4fA6C0752aBea7' + permission: + type: native-token-periodic + isAdjustmentAllowed: true + data: + periodAmount: '0x38d7ea4c68000' + periodDuration: 86400 + justification: Permission to transfer 0.001 ETH every day + rules: [] + context: '0x00000000000000000000000000000000000000000000000000000000000000' + delegationManager: '0x2D48e6f5Ae053e4E918d2be53570961D880905F2' + dependencies: [] + - name: wallet_getGrantedExecutionPermissions + tags: + - $ref: '#/components/tags/MetaMask' + - $ref: '#/components/tags/Experimental' + - $ref: '#/components/tags/Multichain' + summary: Gets granted ERC-7715 execution permissions. + description: >- + Returns the ERC-7715 execution permissions that the user has previously + granted to the requesting dapp. Specified by + [ERC-7715](https://eips.ethereum.org/EIPS/eip-7715). + params: [] + result: + name: Granted permissions + description: An array of the granted execution permissions. + schema: + type: array + items: + $ref: '#/components/schemas/ExecutionPermissionResponse' + errors: + - $ref: '#/components/errors/Unauthorized' + examples: + - name: wallet_getGrantedExecutionPermissions example + params: [] + result: + name: Granted permissions + value: [] + - name: wallet_getSupportedExecutionPermissions + tags: + - $ref: '#/components/tags/MetaMask' + - $ref: '#/components/tags/Experimental' + - $ref: '#/components/tags/Multichain' + summary: Gets supported ERC-7715 execution permissions. + description: >- + Returns the ERC-7715 execution permission types supported by the wallet, + keyed by permission type, including the chain IDs and rule types each + permission supports. Specified by + [ERC-7715](https://eips.ethereum.org/EIPS/eip-7715). + params: [] + result: + name: Supported permissions + description: >- + An object keyed by permission type. Each entry describes the chain IDs + and rule types supported for that permission type. + schema: + type: object + additionalProperties: + type: object + properties: + chainIds: + description: The chain IDs that support the permission type. + type: array + items: + $ref: '#/components/schemas/uint' + ruleTypes: + description: The rule types supported for the permission type. + type: array + items: + type: string + errors: + - $ref: '#/components/errors/Unauthorized' + examples: + - name: wallet_getSupportedExecutionPermissions example + params: [] + result: + name: Supported permissions + value: + native-token-periodic: + chainIds: + - '0xaa36a7' + ruleTypes: + - expiry + - name: wallet_revokeExecutionPermission + tags: + - $ref: '#/components/tags/MetaMask' + - $ref: '#/components/tags/Experimental' + - $ref: '#/components/tags/Multichain' + summary: Revokes an ERC-7715 execution permission. + description: >- + Revokes a previously granted ERC-7715 execution permission, identified by + its permission context. Specified by + [ERC-7715](https://eips.ethereum.org/EIPS/eip-7715). + params: + - name: Revoke request + required: true + description: An object identifying the permission to revoke. + schema: + type: object + required: + - permissionContext + properties: + permissionContext: + description: >- + The `0x`-prefixed context of the permission to revoke, as + returned by `wallet_requestExecutionPermissions`. + $ref: '#/components/schemas/bytes' + result: + name: Null response + description: This method returns an empty object if the permission is revoked. + schema: + type: object + additionalProperties: false + errors: + - $ref: '#/components/errors/InvalidParams' + - $ref: '#/components/errors/Unauthorized' + examples: + - name: wallet_revokeExecutionPermission example + params: + - name: Revoke request + value: + permissionContext: '0x00000000000000000000000000000000000000000000000000000000000000' + result: + name: Null response + value: {} - name: eth_requestAccounts tags: - $ref: '#/components/tags/MetaMask' @@ -1262,6 +1436,126 @@ components: Dapps can use this object to communicate with the wallet about supported capabilities. type: object + ExecutionPermission: + title: ExecutionPermission + description: >- + An ERC-7715 execution permission. The `type` determines the shape of the + `data` object (for example `native-token-periodic`, `native-token-stream`, + `erc20-token-periodic`, `erc20-token-allowance`). + type: object + required: + - type + - data + properties: + type: + description: The permission type. + type: string + isAdjustmentAllowed: + description: >- + Whether the wallet is allowed to adjust the requested permission + (for example to a lower allowance) before granting it. + type: boolean + data: + description: >- + Permission-type-specific data. All amounts are `0x`-prefixed + hexadecimal strings. + type: object + additionalProperties: true + properties: + justification: + description: A human-readable explanation of why the permission is requested. + type: string + ExecutionPermissionRule: + title: ExecutionPermissionRule + description: >- + A rule that constrains an ERC-7715 execution permission, such as an + `expiry`, `redeemer`, or `payee` rule. + type: object + required: + - type + - data + properties: + type: + description: The rule type. + type: string + data: + description: Rule-type-specific data. + type: object + additionalProperties: true + ExecutionPermissionRequest: + title: ExecutionPermissionRequest + description: An object describing a single ERC-7715 execution permission request. + type: object + required: + - chainId + - permission + properties: + chainId: + description: >- + The [EIP-155](https://eips.ethereum.org/EIPS/eip-155) chain ID the + permission applies to, as a `0x`-prefixed hexadecimal string. + $ref: '#/components/schemas/uint' + address: + description: >- + (Optional) The account address the permission should be granted from. + $ref: '#/components/schemas/address' + from: + description: >- + (Optional) The account address the permission should be granted from. + $ref: '#/components/schemas/address' + to: + description: The address the permission is granted to (the redeemer/delegate). + $ref: '#/components/schemas/address' + signer: + description: >- + (Optional) The signer that will redeem the permission. Used by the + ERC-7715 `account`/`wallet`/`key` signer types. + type: object + additionalProperties: true + expiry: + description: >- + (Optional) The UNIX timestamp (in seconds) after which the + permission is no longer valid. + type: number + permission: + $ref: '#/components/schemas/ExecutionPermission' + rules: + description: An array of rules constraining the permission. + type: array + items: + $ref: '#/components/schemas/ExecutionPermissionRule' + ExecutionPermissionResponse: + title: ExecutionPermissionResponse + description: >- + A granted ERC-7715 execution permission. Contains the original request + fields plus the data needed to redeem the permission. + allOf: + - $ref: '#/components/schemas/ExecutionPermissionRequest' + - type: object + properties: + context: + description: >- + An opaque `0x`-prefixed context used to identify and redeem the + granted permission. + $ref: '#/components/schemas/bytes' + delegationManager: + description: The address of the delegation manager contract. + $ref: '#/components/schemas/address' + dependencies: + description: >- + Account deployment dependencies required to redeem the + permission (for example a smart account factory and its data). + type: array + items: + title: ExecutionPermissionDependency + type: object + properties: + factory: + description: The address of the account factory contract. + $ref: '#/components/schemas/address' + factoryData: + description: The calldata to pass to the account factory. + $ref: '#/components/schemas/bytes' AddEthereumChainParameter: title: Chain description: Object containing information about the chain to add. From 132f415177574c6a388638f276420dabd2b32992 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 29 May 2026 12:09:10 -0500 Subject: [PATCH 2/4] Remove duplicate `address` field from ExecutionPermissionRequest The schema defined both `address` and `from` with identical descriptions. ERC-7715 only specifies `from`, so drop `address` and clarify the `from` description to match the spec. --- openrpc.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openrpc.yaml b/openrpc.yaml index 1a6bd62..b4fc7d2 100644 --- a/openrpc.yaml +++ b/openrpc.yaml @@ -1495,13 +1495,12 @@ components: The [EIP-155](https://eips.ethereum.org/EIPS/eip-155) chain ID the permission applies to, as a `0x`-prefixed hexadecimal string. $ref: '#/components/schemas/uint' - address: - description: >- - (Optional) The account address the permission should be granted from. - $ref: '#/components/schemas/address' from: description: >- - (Optional) The account address the permission should be granted from. + (Optional) The account the permission should be granted from. Useful + when a connection has been established and multiple accounts have + been exposed; lets the user choose which account to grant the + permission for. $ref: '#/components/schemas/address' to: description: The address the permission is granted to (the redeemer/delegate). From 1e8b9423fc5a6977417d3ac2803e716360a76eed Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 29 May 2026 12:18:18 -0500 Subject: [PATCH 3/4] Address review: align ERC-7715 spec with wallet implementation - Remove wallet_revokeExecutionPermission (not wired in extension/mobile; handler throws methodNotSupported with no processRevokeExecutionPermission hook) - Drop unsupported top-level request fields (signer, expiry); expiry is an expiry rule on the wire, not a top-level field - Require isAdjustmentAllowed on ExecutionPermission and to on ExecutionPermissionRequest (both required by 7715-permission-types) - Require context/dependencies/delegationManager on the response and factory/factoryData on dependency entries (needed to redeem permissions) - Demonstrate the expiry rule in the request/response examples --- CHANGELOG.md | 2 +- openrpc.yaml | 77 ++++++++++++++-------------------------------------- 2 files changed, 22 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f102ea..0376ac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- Add ERC-7715 execution permission methods: `wallet_requestExecutionPermissions`, `wallet_getGrantedExecutionPermissions`, `wallet_getSupportedExecutionPermissions`, `wallet_revokeExecutionPermission`, along with the `ExecutionPermission`, `ExecutionPermissionRule`, `ExecutionPermissionRequest`, and `ExecutionPermissionResponse` schemas ([#311](https://github.com/MetaMask/api-specs/pull/311)) +- Add ERC-7715 execution permission methods: `wallet_requestExecutionPermissions`, `wallet_getGrantedExecutionPermissions`, and `wallet_getSupportedExecutionPermissions`, along with the `ExecutionPermission`, `ExecutionPermissionRule`, `ExecutionPermissionRequest`, and `ExecutionPermissionResponse` schemas ([#311](https://github.com/MetaMask/api-specs/pull/311)) ## [0.14.0] ### Added diff --git a/openrpc.yaml b/openrpc.yaml index b4fc7d2..e7893f3 100644 --- a/openrpc.yaml +++ b/openrpc.yaml @@ -825,7 +825,10 @@ methods: periodAmount: '0x38d7ea4c68000' periodDuration: 86400 justification: Permission to transfer 0.001 ETH every day - rules: [] + rules: + - type: expiry + data: + timestamp: 1739577600 result: name: Granted permissions value: @@ -838,7 +841,10 @@ methods: periodAmount: '0x38d7ea4c68000' periodDuration: 86400 justification: Permission to transfer 0.001 ETH every day - rules: [] + rules: + - type: expiry + data: + timestamp: 1739577600 context: '0x00000000000000000000000000000000000000000000000000000000000000' delegationManager: '0x2D48e6f5Ae053e4E918d2be53570961D880905F2' dependencies: [] @@ -913,48 +919,6 @@ methods: - '0xaa36a7' ruleTypes: - expiry - - name: wallet_revokeExecutionPermission - tags: - - $ref: '#/components/tags/MetaMask' - - $ref: '#/components/tags/Experimental' - - $ref: '#/components/tags/Multichain' - summary: Revokes an ERC-7715 execution permission. - description: >- - Revokes a previously granted ERC-7715 execution permission, identified by - its permission context. Specified by - [ERC-7715](https://eips.ethereum.org/EIPS/eip-7715). - params: - - name: Revoke request - required: true - description: An object identifying the permission to revoke. - schema: - type: object - required: - - permissionContext - properties: - permissionContext: - description: >- - The `0x`-prefixed context of the permission to revoke, as - returned by `wallet_requestExecutionPermissions`. - $ref: '#/components/schemas/bytes' - result: - name: Null response - description: This method returns an empty object if the permission is revoked. - schema: - type: object - additionalProperties: false - errors: - - $ref: '#/components/errors/InvalidParams' - - $ref: '#/components/errors/Unauthorized' - examples: - - name: wallet_revokeExecutionPermission example - params: - - name: Revoke request - value: - permissionContext: '0x00000000000000000000000000000000000000000000000000000000000000' - result: - name: Null response - value: {} - name: eth_requestAccounts tags: - $ref: '#/components/tags/MetaMask' @@ -1445,6 +1409,7 @@ components: type: object required: - type + - isAdjustmentAllowed - data properties: type: @@ -1488,6 +1453,7 @@ components: type: object required: - chainId + - to - permission properties: chainId: @@ -1505,21 +1471,13 @@ components: to: description: The address the permission is granted to (the redeemer/delegate). $ref: '#/components/schemas/address' - signer: - description: >- - (Optional) The signer that will redeem the permission. Used by the - ERC-7715 `account`/`wallet`/`key` signer types. - type: object - additionalProperties: true - expiry: - description: >- - (Optional) The UNIX timestamp (in seconds) after which the - permission is no longer valid. - type: number permission: $ref: '#/components/schemas/ExecutionPermission' rules: - description: An array of rules constraining the permission. + description: >- + An array of rules constraining the permission. Time-bounded + permissions are expressed as an `expiry` rule (with a UNIX + `timestamp` in its `data`) rather than a top-level field. type: array items: $ref: '#/components/schemas/ExecutionPermissionRule' @@ -1531,6 +1489,10 @@ components: allOf: - $ref: '#/components/schemas/ExecutionPermissionRequest' - type: object + required: + - context + - dependencies + - delegationManager properties: context: description: >- @@ -1548,6 +1510,9 @@ components: items: title: ExecutionPermissionDependency type: object + required: + - factory + - factoryData properties: factory: description: The address of the account factory contract. From 72cca9fe654e16eab719e14f16b0b272caa95aea Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 29 May 2026 12:35:33 -0500 Subject: [PATCH 4/4] Require rules and use future expiry in ERC-7715 examples Add `rules` to ExecutionPermissionRequest.required (the permissions-kernel Snap requires it; pass `[]` for no constraints) and bump the example expiry timestamps to a future date so copied examples don't request an already-expired permission. --- openrpc.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openrpc.yaml b/openrpc.yaml index e7893f3..25dcc4e 100644 --- a/openrpc.yaml +++ b/openrpc.yaml @@ -828,7 +828,7 @@ methods: rules: - type: expiry data: - timestamp: 1739577600 + timestamp: 1893456000 result: name: Granted permissions value: @@ -844,7 +844,7 @@ methods: rules: - type: expiry data: - timestamp: 1739577600 + timestamp: 1893456000 context: '0x00000000000000000000000000000000000000000000000000000000000000' delegationManager: '0x2D48e6f5Ae053e4E918d2be53570961D880905F2' dependencies: [] @@ -1455,6 +1455,7 @@ components: - chainId - to - permission + - rules properties: chainId: description: >- @@ -1477,7 +1478,8 @@ components: description: >- An array of rules constraining the permission. Time-bounded permissions are expressed as an `expiry` rule (with a UNIX - `timestamp` in its `data`) rather than a top-level field. + `timestamp` in its `data`) rather than a top-level field. Pass an + empty array to apply no constraints. type: array items: $ref: '#/components/schemas/ExecutionPermissionRule'