From 0921bd68f5bd814b26fa7eea605792cdc93b9a42 Mon Sep 17 00:00:00 2001 From: Bumblefudge Date: Tue, 24 Jan 2023 18:23:59 +0100 Subject: [PATCH 01/13] Update caip-25.md --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 8b78501e..a031e947 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -3,7 +3,7 @@ caip: 25 title: JSON-RPC Provider Authorization author: Pedro Gomes (@pedrouid), Hassan Malik (@hmalik88) discussions-to: https://github.com/ChainAgnostic/CAIPs/pull/25 -status: Review +status: Last Call type: Standard created: 2020-10-14 updated: 2022-10-26 From 6632d055cbb3a443200d607e870a5de21c3db2c6 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Mon, 30 Jan 2023 11:40:06 +0100 Subject: [PATCH 02/13] Clarify privacy and progressive consent --- CAIPs/caip-25.md | 123 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 22 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index a031e947..2897b78a 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -32,25 +32,51 @@ application through a provider connecting to a wallet. ## Specification The session is defined by a wallet's response to a provider's request, and -updated, extended, closed, etc by successive calls and events. These are out of -scope of this CAIP interface and will be specified in a forthcoming one. - -Within that session model, this interface outlines the authorization of an -injected provider per namespace. These authorization call/responses should be -idempotent, assuming the provider is tracking a session property, referred to by -a `sessionIdentifier` as defined in [CAIP-171][]. If a wallet needs to initiate -a new session, whether due to user input, security policy, or session expiry -reasons, it can simply generate a new session identifier to signal this event to -the calling provider. - -The application interfaces with a provider to populate a session with a base -state describing authorized chains, methods, event, and accounts. This -negotation takes place by sending the application's REQUIRED and REQUESTED -properties of the session. If any requirements are not met, a failure response -expressive of one or more specific failure states will be sent (see below). +updated, extended, closed, etc by successive calls and events. The exact +parameters and assumptions of that session abstraction are defined in +[CAIP-171][], but note that a string identifier referring to it is absent from +the initial call (if authorization is granted) and present in both the initial +response and all future responses. + +Given the session model of [CAIP-171][], this interface outlines the +authorization of a provider to handle a set of interfaces grouped into +namespaces, as well as to interact with a session abstraction used by both +caller and respondent to manage the authorization over time. The +`sessionIdentifier` defined in [CAIP-171][] enables this mutual management and +alignment across calls that are idempotent if identical. If a respondent (e.g. a +wallet) needs to initiate a new session, whether due to user input, security +policy, or session expiry reasons, it can simply generate a new session +identifier to signal this event to the calling provider; if a caller needs to +initiate a new session, it can do so by sending a new request without +`sessionIdentifier`. In such cases, a respondent (e.g. wallet) may choose to +explicitly close all sessions upon generation of a new one from the same origin, +or leave it to time-out; maintaining concurrent sessions is discouraged (see +Security Considerations). + +In the initial call, the application interfaces with a provider to populate a +session with a base state describing authorized chains, methods, event, and +accounts. This negotation takes place by sending the application's REQUIRED and +REQUESTED properties of the session, organized into arrays of namespaces (named +`requiredNamespaces` and `optionalNamespaces` respectively). These two arrays +are not mutually exclusive (i.e., additional properties of a required namespace +may be requested under the same namespace key in the requested object). + +If any properties in the required namespace(s) are not authorized by the +respondent (e.g. wallet), a failure response expressive of one or more specific +failure states will be sent (see [#### failure states](#failure-states) below), +with the exception of user denying consent. For privacy reasons, an `undefined` +response (or no response, depending on implementation) should be sent to prevent +incentivizing unwanted requests and to minimize the surface for fingerprinting +of public web traffic (See Privacy Considerations below). + Conversely, a succesful response will contain all the required properties *and the provider's choice of the optional properties* expressed as a unified set of -parameters. +parameters. In the case of identically-keyed namespaces appearing in both arrays +in the request where properties from both are returned as authorized, the two +namespaces MUST be merged in the response (see examples below). However, +respondents MUST NOT restructure namespaces (e.g., by folding properties from a +[CAIP2][]-scoped namespace into a namespace-wide namespace) as this may +introduce ambiguities (See Security Considerations below). ### Request @@ -196,15 +222,15 @@ An example of an error response should match the following format: "jsonrpc": "2.0", "error": { "code": 5000, - "message": "User disapproved requested chains" + "message": "Unknown error" } } ``` The valid error messages codes are the following: -* When user disapproves exposing accounts to requested chains +* Unknown error OR no requested namespaces were authorized * code = 5000 - * message = "User disapproved requested chains" + * message = "Unknown error" * When user disapproves accepting calls with the request methods * code = 5001 * message = "User disapproved requested methods" @@ -229,9 +255,62 @@ The valid error messages codes are the following: * Invalid Session Properties Object * code = 5200 * message = "Invalid Session Properties requested" - * Required Session Properties +* Session Properties requested outside of Session Properties Object * code = 5201 - * message = "Session Properties can only be optional" + * message = "Session Properties can only be optional and global" + +## Security Considerations + +The crucial security function of a shared session negotiated and maintained by a +series of CAIP-25 calls is to reduce ambiguity in authorization. This requires +a somewhat counterintuitive structuring of the building-blocks of a +Chain-Agnostic session into namespaces that can be scoped to either one of the +CASA [namespaces][] as a whole or to a specific [CAIP-2][] chain within such a +namespace; for this reason, requests and responses are structures as arrays of +these namespaces keyed to their scope, formatted either as a bare entry in the +[namespaces][] registry OR as a full [CAIP-2][]. While internal systems are +free to translate this object into other structures, preserving it in the +CAIP-25 interface is crucial to the unambiguous communication between caller and +respondent about what exact authorization is granted. + +## Privacy Considerations + +One major risk in browser-based or HTTP-based communications is "fingerprinting +risk", i.e. the risk that public or intercepted traffic can be used to +deanonymize browsers and/or wallets deductively based on response times, error +codes, etc. To minimize this risk, and to minimize the data (including +behavioral data) leaked by responses to potentially malicious CAIP-25 calls, +respondents are recommended to ignore calls +1. which the respondent does not authorize, +2. which are rejected by policy, or +3. requests which are rejected for unknown reasons. + +"Ignoring" these calls means responding to all three in a way that is +*indistinguishable* to a malicious caller or observer which might deduce +information from differences in those responses (including the time taken to +provide them). Effectively, this means allowing requests in all three cases to +time out even if the end-user experience might be better served by +differentiating them, particularly in complex multi-party architectures where +parties on one side of this interface need to have a shared understanding of why +a request did not receive a response. At scale, however, better user experiences in a single architecture or context can contribute to a systemic erosion of anonymity. + +Given this "silent time out" behavior, the best strategy to ensure good user +experience is not to request too many properties in the initial establishment of +a session and to iteratively and incrementally expand session authorization over +time. This also contributes to a more consentful experience overall and +encourages progressive trust establishment across complex architectures with +many distinct actors and agents. + +Another design pattern that accomodates the "silent time out" behavior is minor +updates to the session. For example, a caller sending a request identical to a +previous request (or a previous response) except for a new session expiry +further in the future could expect one of exactly three responses: +1. An identical response to the previous request (meaning the session extension was denied); +2. A response identical expect that it includes the new, extended session expiry; or, +3. A silent time out (meaning the calling behavior was malformed in ways the +respondent cannot understand, or the respondent choses not to make explicit how +the request was malformed, or the end-user rejected them, or the request itself +was in violation of policy). ## Changelog From 524124cbaa046050d4a2d86d3a46cee362489806 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Mon, 30 Jan 2023 11:40:35 +0100 Subject: [PATCH 03/13] Add privacy & security sections to CAIP template --- caip-template.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/caip-template.md b/caip-template.md index 4f065910..130b8313 100644 --- a/caip-template.md +++ b/caip-template.md @@ -1,7 +1,7 @@ --- # Every document starts with a front matter in YAML enclosed by triple dashes. # See https://jekyllrb.com/docs/front-matter/ to learn more about this concept. -caip: +caip: CAIP-X title: author: , FirstName (@GitHubUsername) and GitHubUsername (@GitHubUsername)> discussions-to: @@ -40,14 +40,19 @@ The technical specification should describe the standard in detail. The specific The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.--> +## Test Cases + + +## Security Considerations + + +## Privacy Considerations + + ## Backwards Compatibility All CAIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The CAIP must explain how the author proposes to deal with these incompatibilities. CAIP submissions without a sufficient backwards compatibility treatise may be rejected outright. -## Test Cases - -Please add test cases here if applicable. - ## Links Links to external resources that help understanding the CAIP better. This can e.g. be links to existing implementations. From 7d5a86dd31f4eeb032cb7e60525c84acb53d5e46 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Feb 2023 06:44:00 +0100 Subject: [PATCH 04/13] rename namespaces to scopes --- CAIPs/caip-25.md | 97 +++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 2897b78a..6f91afb1 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -56,12 +56,16 @@ Security Considerations). In the initial call, the application interfaces with a provider to populate a session with a base state describing authorized chains, methods, event, and accounts. This negotation takes place by sending the application's REQUIRED and -REQUESTED properties of the session, organized into arrays of namespaces (named -`requiredNamespaces` and `optionalNamespaces` respectively). These two arrays -are not mutually exclusive (i.e., additional properties of a required namespace -may be requested under the same namespace key in the requested object). - -If any properties in the required namespace(s) are not authorized by the +REQUESTED authorizations of the session, grouped into objects scoping those +authorizations which in turn are grouped into two top-level arrays (named +`requiredScopes` and `optionalScopes` respectively). These two arrays are not +mutually exclusive (i.e., additional properties of a required scope may be +requested under the same keyed scope object key in the requested array). Note +that scopes can be keyed to an entire [CAIP-104][] "namespace", meaning +applicable to *any* current or future [CAIP-2][] chainID within that namespace, +or keyed to a specific [CAIP-2][] within that namespace. + +If any properties in the required scope(s) are not authorized by the respondent (e.g. wallet), a failure response expressive of one or more specific failure states will be sent (see [#### failure states](#failure-states) below), with the exception of user denying consent. For privacy reasons, an `undefined` @@ -71,12 +75,12 @@ of public web traffic (See Privacy Considerations below). Conversely, a succesful response will contain all the required properties *and the provider's choice of the optional properties* expressed as a unified set of -parameters. In the case of identically-keyed namespaces appearing in both arrays -in the request where properties from both are returned as authorized, the two -namespaces MUST be merged in the response (see examples below). However, -respondents MUST NOT restructure namespaces (e.g., by folding properties from a -[CAIP2][]-scoped namespace into a namespace-wide namespace) as this may -introduce ambiguities (See Security Considerations below). +parameters. In the case of identically-keyed scopes appearing in both arrays in +the request where properties from both are returned as authorized, the two +scopes MUST be merged in the response (see examples below). However, respondents +MUST NOT restructure scopes (e.g., by folding properties from a [CAIP2][]-keyed, +chain-specific scope object into a [CAIP-104][]-keyed, namespace-wide scope +object) as this may introduce ambiguities (See Security Considerations below). ### Request @@ -91,7 +95,7 @@ Example: "jsonrpc": "2.0", "method": "provider_authorization", "params": { - "requiredNamespaces": { + "requiredScopes": { "eip155": { "chains": ["eip155:1", "eip155:137"], "methods": ["eth_sendTransaction", "eth_signTransaction", "eth_sign", "get_balance", "personal_sign"], @@ -105,7 +109,7 @@ Example: ... } }, - "optionalNamespaces":{ + "optionalScopes":{ "eip155:42161": { "methods": ["eth_sendTransaction", "eth_signTransaction", "get_balance", "personal_sign"], "events": ["accountsChanged", "chainChanged"] @@ -119,20 +123,20 @@ Example: ``` The JSON-RPC method is labelled as `provider_authorization` and both the -"requiredNamespaces" and "optionalNamespaces" arrays are populated with -`namespace` objects each named after the scope of authorization: -1. EITHER an entire ChainAgnostic [namespace][] -2. OR a specific [CAIP-2][] in that namespace. +"requiredScopes" and "optionalScopes" arrays are populated with +"scope objects" each named after the scope of authorization requested: +1. EITHER an entire [CAIP-104][] [namespace][] +2. OR a specific [CAIP-2][]-identified chain in a specific namespace. -Each `namespace` object contains the following parameters: +Each scope object contains the following parameters: - chains - array of [CAIP-2][]-compliant `chainId`'s. This parameter MAY be omitted if a single-chain scope is already declared in the index of the object. - methods - array of JSON-RPC methods expected to be used during the session - events - array of JSON-RPC message/events expected to be emitted during the session -The `requiredNamespaces` array MUST contain 1 or more of these objects, if present; the `optionalNamespaces` array MUST contain 1 or more of them, if -present. +The `requiredScopes` array MUST contain 1 or more of these objects, if present; +the `optionalScopes` array MUST contain 1 or more of them, if present. A third object is the `sessionProperties` object, all of whose properties MUST be in the interpreted as optional, since requesting applications cannot mandate @@ -156,21 +160,22 @@ The wallet can respond to this method with either a success result or an error m The succesfull reslt contains one mandatory string (keyed as `sessionId` with a value conformant to [CAIP-171][]) and two session objects, both mandatory and non-empty. -The first is called `sessionNamespaces` and contains 1 or more namespace objects. -* All required namespaces and all, none, or some of the optional namespaces (at the -discretion of the provider) MUST be included if successful. -* As in the request, each namespace object MUST contain `methods` and `events` objects, -and a `chains` object if a specific chain is not specified in the object's index. -* Unlike the request, each namespace object MUST also contain an `accounts` array, -containing 0 or more [CAIP-10][] conformant accounts authorized for the session and valid -in the namespace and chain(s) authorized by the object they are in. Additional constraints -on the accounts authorized for a given session MAY be specified in the corresponding -[namespaces][] specification. - -A `sessionProperties` object MAY also be present, and its contents MAY correspond to the -properties requested in the response or not (at the discretion of the provider) but MUST -conform to the properties names and value constraints described in [CAIP-170][]; any other -MUST be dropped by the requester. +The first is called `sessionScopes` and contains 1 or more scope objects. +* All required scope objects and all, none, or some of the optional scope object +(at the discretion of the provider) MUST be included if successful. +* As in the request, each scope object object MUST contain `methods` and +`events` objects, and a `chains` object if a specific chain is not specified in +the object's index. +* Unlike the request, each scope object MUST also contain an `accounts` array, +containing 0 or more [CAIP-10][] conformant accounts authorized for the session +and valid in the namespace and chain(s) authorized by the scope object they are +in. Additional constraints on the accounts authorized for a given session MAY be +specified in the corresponding [CAIP-104][] namespaces specification. + +A `sessionProperties` object MAY also be present, and its contents MAY +correspond to the properties requested in the response or not (at the discretion +of the provider) but MUST conform to the property names and value constraints +described in [CAIP-170][]; any other MUST be dropped by the requester. An example of a successful response follows: @@ -180,7 +185,7 @@ An example of a successful response follows: "jsonrpc": "2.0", "result": { "sessionId": "0xdeadbeef", - "sessionNamespaces": { + "sessionScopes": { "eip155": { "chains": ["eip155:1", "eip155:137"], "methods": ["eth_sendTransaction", "eth_signTransaction", "get_balance", "eth_sign", "personal_sign"] @@ -228,7 +233,7 @@ An example of an error response should match the following format: ``` The valid error messages codes are the following: -* Unknown error OR no requested namespaces were authorized +* Unknown error OR no requested scopes were authorized * code = 5000 * message = "Unknown error" * When user disapproves accepting calls with the request methods @@ -263,14 +268,13 @@ The valid error messages codes are the following: The crucial security function of a shared session negotiated and maintained by a series of CAIP-25 calls is to reduce ambiguity in authorization. This requires -a somewhat counterintuitive structuring of the building-blocks of a -Chain-Agnostic session into namespaces that can be scoped to either one of the -CASA [namespaces][] as a whole or to a specific [CAIP-2][] chain within such a -namespace; for this reason, requests and responses are structures as arrays of -these namespaces keyed to their scope, formatted either as a bare entry in the -[namespaces][] registry OR as a full [CAIP-2][]. While internal systems are -free to translate this object into other structures, preserving it in the -CAIP-25 interface is crucial to the unambiguous communication between caller and +a potentially counterintuitive structuring of the building-blocks of a +Chain-Agnostic session into scopes at the "namespace-wide" ([CAIP-104][]) or at +the "chain-specific" ([CAIP-2][]) level; for this reason, requests and responses +are structures as arrays of objects keyed to these scopes, formatted either as a +[CAIP-104][] scheme OR as a full [CAIP-2][]. While internal systems are free to +translate this object into other structures, preserving it in the CAIP-25 +interface is crucial to the unambiguous communication between caller and respondent about what exact authorization is granted. ## Privacy Considerations @@ -330,6 +334,7 @@ was in violation of policy). [CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 [CAIP-25]: https://chainagnostic.org/CAIPs/caip-25 [CAIP-75]: https://chainagnostic.org/CAIPs/caip-75 +[CAIP-104]: https://chainagnostic.org/CAIPs/caip-104 [CAIP-171]: https://chainagnostic.org/CAIPs/caip-171 [namespaces]: https://namespaces.chainagnostic.org [RFC3339]: https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 From 32c4a67de8ffb46b09b5722b30412bac5b726b9d Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Feb 2023 08:45:31 +0100 Subject: [PATCH 05/13] rollback Last Call status --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 6f91afb1..84e5b092 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -3,7 +3,7 @@ caip: 25 title: JSON-RPC Provider Authorization author: Pedro Gomes (@pedrouid), Hassan Malik (@hmalik88) discussions-to: https://github.com/ChainAgnostic/CAIPs/pull/25 -status: Last Call +status: Review type: Standard created: 2020-10-14 updated: 2022-10-26 From 17169c2ac3cf883f28f3568cc6dcc479c9abaad9 Mon Sep 17 00:00:00 2001 From: Bumblefudge Date: Thu, 2 Mar 2023 16:26:16 +0100 Subject: [PATCH 06/13] Update CAIPs/caip-25.md Co-authored-by: Hassan Malik <41640681+hmalik88@users.noreply.github.com> --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 84e5b092..07b0f49e 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -122,7 +122,7 @@ Example: } ``` -The JSON-RPC method is labelled as `provider_authorization` and both the +The JSON-RPC method is labelled as `provider_authorize` and both the "requiredScopes" and "optionalScopes" arrays are populated with "scope objects" each named after the scope of authorization requested: 1. EITHER an entire [CAIP-104][] [namespace][] From cd43574061b56626862743840179923ffa8eeeab Mon Sep 17 00:00:00 2001 From: Bumblefudge Date: Thu, 2 Mar 2023 16:30:46 +0100 Subject: [PATCH 07/13] rename method to provider_authorize Co-authored-by: Hassan Malik <41640681+hmalik88@users.noreply.github.com> --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 07b0f49e..46e18b05 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -93,7 +93,7 @@ Example: { "id": 1, "jsonrpc": "2.0", - "method": "provider_authorization", + "method": "provider_authorize", "params": { "requiredScopes": { "eip155": { From 7f57a960ff3adbe1b7ccad4c494317a53fb13b8b Mon Sep 17 00:00:00 2001 From: Bumblefudge Date: Thu, 2 Mar 2023 16:32:03 +0100 Subject: [PATCH 08/13] typo Co-authored-by: Hassan Malik <41640681+hmalik88@users.noreply.github.com> --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 46e18b05..e3332bbe 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -157,7 +157,7 @@ The wallet can respond to this method with either a success result or an error m #### Success -The succesfull reslt contains one mandatory string (keyed as `sessionId` with a value +The succesfull result contains one mandatory string (keyed as `sessionId` with a value conformant to [CAIP-171][]) and two session objects, both mandatory and non-empty. The first is called `sessionScopes` and contains 1 or more scope objects. From c80ea5662cc290577615cf6bed36e4b7ecf63917 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Mar 2023 17:13:20 +0100 Subject: [PATCH 09/13] error messages overhaul --- CAIPs/caip-25.md | 66 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index e3332bbe..a48af1d5 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -157,7 +157,7 @@ The wallet can respond to this method with either a success result or an error m #### Success -The succesfull result contains one mandatory string (keyed as `sessionId` with a value +The successful result contains one mandatory string (keyed as `sessionId` with a value conformant to [CAIP-171][]) and two session objects, both mandatory and non-empty. The first is called `sessionScopes` and contains 1 or more scope objects. @@ -214,56 +214,90 @@ An example of a successful response follows: #### Failure States -The response MUST NOT be a success result when the user disapproves the accounts -matching the requested chains to be exposed or the requested methods are not -approved or the requested chains are not supported by the wallet or the -requested methods are not supported. +The response MUST NOT be a JSON-RPC success result in any of the following +failure states. -An example of an error response should match the following format: +##### Generic Failure Code + +Unless the dapp is known to the wallet and trusted, the generic/undefined error +response, ```jsonc { "id": 1, "jsonrpc": "2.0", "error": { - "code": 5000, + "code": 0, "message": "Unknown error" } } ``` +is RECOMMENDED for any of the following cases: +- the user denies consent for exposing accounts that match the requested and + approved chains, +- the user denies consent for requested methods, +- the user denies all requested or any required scope objects, +- the wallet cannot support all requested or any required scope objects, +- the requested chains are not supported by the wallet, or +- the requested methods are not supported by the wallet + +##### Trusted Failure Codes + +Send more informative error messages MAY be used in trusted-counterparty +circumstances, although extending this trust too widely may contribute to +widespread fingerprinting and analytics which corrode herd privacy (see +[Privacy Considerations](#privacy-considerations) below). The core error +messages over trusted connections are as follows: + The valid error messages codes are the following: -* Unknown error OR no requested scopes were authorized +* Unknown error OR no scopes were authorized * code = 5000 - * message = "Unknown error" + * message = "Unknown error with request" * When user disapproves accepting calls with the request methods * code = 5001 * message = "User disapproved requested methods" * When user disapproves accepting calls with the request events * code = 5002 * message = "User disapproved requested events" -* When wallet evaluates requested chains to not be supported +* When provider evaluates requested chains to not be supported * code = 5100 * message = "Requested chains are not supported" -* When wallet evaluates requested methods to not be supported +* When provider evaluates requested methods to not be supported * code = 5101 * message = "Requested methods are not supported" -* When wallet evaluates requested events to not be supported +* When provider evaluates requested events to not be supported * code = 5102 * message = "Requested events are not supported" + +##### Trust-Agnostic Malformed Request Failure Codes + +Regardless of caller trust level, the following error responses can reduce +friction and user experience problems in the case of malformed requests. + +* When provider does not recognize one or more requested method(s) + * code = 5201 + * message = "Unknown method(s) requested" +* When provider does not recognize one or more requested event(s) + * code = 5202 + * message = "Unknown event(s) requested" * When a badly-formed request includes a `chainId` mismatched to scope - * code = 5103 + * code = 5203 * message = "Scope/chain mismatch" * When a badly-formed request defines one `chainId` two ways - * code = 5104 + * code = 5204 * message = "ChainId defined in two different scopes" * Invalid Session Properties Object - * code = 5200 + * code = 5300 * message = "Invalid Session Properties requested" * Session Properties requested outside of Session Properties Object - * code = 5201 + * code = 5301 * message = "Session Properties can only be optional and global" +Note: respondents are RECOMMENDED to implement support for core RPC Documents +per each supported namespace to avoid sending error messages 5201 and 5202 in +cases where 0, 5101 or 5102 would be more appropriate. + ## Security Considerations The crucial security function of a shared session negotiated and maintained by a From 57cd5d54b5f9760fb269211544379d2e92c5f3dc Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Mar 2023 17:22:57 +0100 Subject: [PATCH 10/13] error messages typo --- CAIPs/caip-25.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index a48af1d5..33bb59ce 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -244,7 +244,7 @@ is RECOMMENDED for any of the following cases: ##### Trusted Failure Codes -Send more informative error messages MAY be used in trusted-counterparty +More informative error messages MAY be sent in trusted-counterparty circumstances, although extending this trust too widely may contribute to widespread fingerprinting and analytics which corrode herd privacy (see [Privacy Considerations](#privacy-considerations) below). The core error From 1ae513260f235cabf7b4298b734b67ab1ba79ff6 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Mar 2023 20:19:39 +0100 Subject: [PATCH 11/13] events-->notifs --- CAIPs/caip-25.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 33bb59ce..6b4f8eee 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -32,7 +32,7 @@ application through a provider connecting to a wallet. ## Specification The session is defined by a wallet's response to a provider's request, and -updated, extended, closed, etc by successive calls and events. The exact +updated, extended, closed, etc by successive calls and notifications. The exact parameters and assumptions of that session abstraction are defined in [CAIP-171][], but note that a string identifier referring to it is absent from the initial call (if authorization is granted) and present in both the initial @@ -46,17 +46,17 @@ caller and respondent to manage the authorization over time. The alignment across calls that are idempotent if identical. If a respondent (e.g. a wallet) needs to initiate a new session, whether due to user input, security policy, or session expiry reasons, it can simply generate a new session -identifier to signal this event to the calling provider; if a caller needs to -initiate a new session, it can do so by sending a new request without +identifier to signal this notification to the calling provider; if a caller +needs to initiate a new session, it can do so by sending a new request without `sessionIdentifier`. In such cases, a respondent (e.g. wallet) may choose to explicitly close all sessions upon generation of a new one from the same origin, or leave it to time-out; maintaining concurrent sessions is discouraged (see Security Considerations). In the initial call, the application interfaces with a provider to populate a -session with a base state describing authorized chains, methods, event, and -accounts. This negotation takes place by sending the application's REQUIRED and -REQUESTED authorizations of the session, grouped into objects scoping those +session with a base state describing authorized chains, methods, notification, +and accounts. This negotation takes place by sending the application's REQUIRED +and REQUESTED authorizations of the session, grouped into objects scoping those authorizations which in turn are grouped into two top-level arrays (named `requiredScopes` and `optionalScopes` respectively). These two arrays are not mutually exclusive (i.e., additional properties of a required scope may be @@ -99,11 +99,11 @@ Example: "eip155": { "chains": ["eip155:1", "eip155:137"], "methods": ["eth_sendTransaction", "eth_signTransaction", "eth_sign", "get_balance", "personal_sign"], - "events": ["accountsChanged", "chainChanged"] + "notifications": ["accountsChanged", "chainChanged"] }, "eip155:10": { "methods": ["get_balance"], - "events": ["accountsChanged", "chainChanged"] + "notifications": ["accountsChanged", "chainChanged"] }, "cosmos": { ... @@ -112,7 +112,7 @@ Example: "optionalScopes":{ "eip155:42161": { "methods": ["eth_sendTransaction", "eth_signTransaction", "get_balance", "personal_sign"], - "events": ["accountsChanged", "chainChanged"] + "notifications": ["accountsChanged", "chainChanged"] }, "sessionProperties": { "expiry": "2022-12-24T17:07:31+00:00", @@ -132,8 +132,8 @@ Each scope object contains the following parameters: - chains - array of [CAIP-2][]-compliant `chainId`'s. This parameter MAY be omitted if a single-chain scope is already declared in the index of the object. - methods - array of JSON-RPC methods expected to be used during the session -- events - array of JSON-RPC message/events expected to be emitted during the - session +- notifications - array of JSON-RPC message/notifications expected to be emitted + during the session The `requiredScopes` array MUST contain 1 or more of these objects, if present; the `optionalScopes` array MUST contain 1 or more of them, if present. @@ -164,8 +164,8 @@ The first is called `sessionScopes` and contains 1 or more scope objects. * All required scope objects and all, none, or some of the optional scope object (at the discretion of the provider) MUST be included if successful. * As in the request, each scope object object MUST contain `methods` and -`events` objects, and a `chains` object if a specific chain is not specified in -the object's index. +`notifications` objects, and a `chains` object if a specific chain is not +specified in the object's index. * Unlike the request, each scope object MUST also contain an `accounts` array, containing 0 or more [CAIP-10][] conformant accounts authorized for the session and valid in the namespace and chain(s) authorized by the scope object they are @@ -189,17 +189,17 @@ An example of a successful response follows: "eip155": { "chains": ["eip155:1", "eip155:137"], "methods": ["eth_sendTransaction", "eth_signTransaction", "get_balance", "eth_sign", "personal_sign"] - "events": ["accountsChanged", "chainChanged"], + "notifications": ["accountsChanged", "chainChanged"], "accounts": ["eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", "eip155:137:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb"] }, "eip155:10": { "methods": ["get_balance"], - "events": ["accountsChanged", "chainChanged"], + "notifications": ["accountsChanged", "chainChanged"], "accounts:" [] }, "eip155:42161": { "methods": ["personal_sign"], - "events": ["accountsChanged", "chainChanged"], + "notifications": ["accountsChanged", "chainChanged"], "accounts":["eip155:42161:0x0910e12C68d02B561a34569E1367c9AAb42bd810"] "cosmos": { ... @@ -257,18 +257,18 @@ The valid error messages codes are the following: * When user disapproves accepting calls with the request methods * code = 5001 * message = "User disapproved requested methods" -* When user disapproves accepting calls with the request events +* When user disapproves accepting calls with the request notifications * code = 5002 - * message = "User disapproved requested events" + * message = "User disapproved requested notifications" * When provider evaluates requested chains to not be supported * code = 5100 * message = "Requested chains are not supported" * When provider evaluates requested methods to not be supported * code = 5101 * message = "Requested methods are not supported" -* When provider evaluates requested events to not be supported +* When provider evaluates requested notifications to not be supported * code = 5102 - * message = "Requested events are not supported" + * message = "Requested notifications are not supported" ##### Trust-Agnostic Malformed Request Failure Codes @@ -278,9 +278,9 @@ friction and user experience problems in the case of malformed requests. * When provider does not recognize one or more requested method(s) * code = 5201 * message = "Unknown method(s) requested" -* When provider does not recognize one or more requested event(s) +* When provider does not recognize one or more requested notification(s) * code = 5202 - * message = "Unknown event(s) requested" + * message = "Unknown notification(s) requested" * When a badly-formed request includes a `chainId` mismatched to scope * code = 5203 * message = "Scope/chain mismatch" From 4adb5bea3b6d501b2b41330c19d9b6742c215368 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Mar 2023 20:28:20 +0100 Subject: [PATCH 12/13] object/array typos --- CAIPs/caip-25.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 6b4f8eee..40441c90 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -122,9 +122,9 @@ Example: } ``` -The JSON-RPC method is labelled as `provider_authorize` and both the -"requiredScopes" and "optionalScopes" arrays are populated with -"scope objects" each named after the scope of authorization requested: +The JSON-RPC method is labelled as `provider_authorize` and its `params` object +contains "requiredScopes" and/or "optionalScopes" objects populated with "scope +objects" each named after the scope of authorization requested: 1. EITHER an entire [CAIP-104][] [namespace][] 2. OR a specific [CAIP-2][]-identified chain in a specific namespace. From 00fe3a9664c939e5ff7e6592a2046745de9c7175 Mon Sep 17 00:00:00 2001 From: bumblefudge Date: Thu, 2 Mar 2023 20:31:07 +0100 Subject: [PATCH 13/13] object/array typos part 2 --- CAIPs/caip-25.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CAIPs/caip-25.md b/CAIPs/caip-25.md index 40441c90..45b5ba38 100644 --- a/CAIPs/caip-25.md +++ b/CAIPs/caip-25.md @@ -57,10 +57,10 @@ In the initial call, the application interfaces with a provider to populate a session with a base state describing authorized chains, methods, notification, and accounts. This negotation takes place by sending the application's REQUIRED and REQUESTED authorizations of the session, grouped into objects scoping those -authorizations which in turn are grouped into two top-level arrays (named -`requiredScopes` and `optionalScopes` respectively). These two arrays are not +authorizations which in turn are grouped into two top-level objects (named +`requiredScopes` and `optionalScopes` respectively). These two objects are not mutually exclusive (i.e., additional properties of a required scope may be -requested under the same keyed scope object key in the requested array). Note +requested under the same keyed scope object key in the requested object). Note that scopes can be keyed to an entire [CAIP-104][] "namespace", meaning applicable to *any* current or future [CAIP-2][] chainID within that namespace, or keyed to a specific [CAIP-2][] within that namespace. @@ -330,7 +330,9 @@ provide them). Effectively, this means allowing requests in all three cases to time out even if the end-user experience might be better served by differentiating them, particularly in complex multi-party architectures where parties on one side of this interface need to have a shared understanding of why -a request did not receive a response. At scale, however, better user experiences in a single architecture or context can contribute to a systemic erosion of anonymity. +a request did not receive a response. At scale, however, better user experiences +in a single architecture or context can contribute to a systemic erosion of +anonymity. Given this "silent time out" behavior, the best strategy to ensure good user experience is not to request too many properties in the initial establishment of