From 7eb5251c9730dda8649ce75cd3657cf3dcf072de Mon Sep 17 00:00:00 2001 From: Funkatronics Date: Tue, 1 Aug 2023 11:14:23 -0600 Subject: [PATCH 01/15] init, with authorize refactor --- spec/_diagrams/authorize_and_sign.plantuml | 7 +- spec/_diagrams/reauthorize_and_sign.plantuml | 13 ++- spec/spec.md | 115 +++++-------------- 3 files changed, 41 insertions(+), 94 deletions(-) diff --git a/spec/_diagrams/authorize_and_sign.plantuml b/spec/_diagrams/authorize_and_sign.plantuml index 5edeb7d87..be38c0b26 100644 --- a/spec/_diagrams/authorize_and_sign.plantuml +++ b/spec/_diagrams/authorize_and_sign.plantuml @@ -16,7 +16,8 @@ activate Dapp == Authorize for transaction signing == Dapp -> Dapp : i = DappIdentity() -Dapp -> Wallet ++-- : authorize {i, ["sign_transactions"]} +Dapp -> Dapp : c = "{cluster}" +Dapp -> Wallet ++-- : authorize {i, c} Wallet -> Wallet : validate Dapp identity i Wallet -> Wallet : Generate new auth token\nat = GenerateAuthToken(i, ["sign_transactions"]) Wallet -> Wallet : pub = base58encode(GetPublicKey()) @@ -29,8 +30,8 @@ Dapp -> Dapp : Store(at, pub, uri) == Submit transaction for signing == Dapp -> Dapp : t = CreateTransaction(pub, ...) -Dapp -> Wallet ++-- : sign_transactions {at, t} -Wallet -> Wallet : validate auth token at +Dapp -> Wallet ++-- : sign_transactions {t} +Wallet -> Wallet : verify session is in authorized state Wallet -> Wallet : validate transaction t Wallet -> Wallet : sign transaction\nst = SignSolanaTransactions(t) Wallet --> Dapp ++-- : response {st} diff --git a/spec/_diagrams/reauthorize_and_sign.plantuml b/spec/_diagrams/reauthorize_and_sign.plantuml index 127be4f4b..fdd1b046d 100644 --- a/spec/_diagrams/reauthorize_and_sign.plantuml +++ b/spec/_diagrams/reauthorize_and_sign.plantuml @@ -18,14 +18,15 @@ Dapp -> Dapp : t = CreateTransaction(pub, ...) == Submit for signing with cached auth token == -Dapp -> Wallet ++-- : sign_transactions {at, t} -Wallet -X Wallet : validate auth token at -Wallet --> Dapp ++-- : error {ERROR_REAUTHORIZE} +Dapp -> Wallet ++-- : sign_transactions {t} +Wallet -X Wallet : verify session is in authorized state +Wallet --> Dapp ++-- : error {ERROR_AUTHORIZATION_FAILED} == Reauthorize == Dapp -> Dapp : i = DappIdentity() -Dapp -> Wallet ++-- : reauthorize {i, at} +Dapp -> Dapp : c = "{cluster}" +Dapp -> Wallet ++-- : authorize {i, c, at} Wallet -> Wallet : validate Dapp identity i matches at Wallet -> Wallet : Generate new auth token\nat2 = RegenerateAuthToken(i, at) Wallet -> Wallet : pub = base58encode(GetPublicKey()) @@ -37,8 +38,8 @@ Dapp -> Dapp : Store(at2, pub, uri) == Resubmit for signing with new auth token == -Dapp -> Wallet ++-- : sign_transactions(at2, t) -Wallet -> Wallet : validate auth token at2 +Dapp -> Wallet ++-- : sign_transactions(t) +Wallet -> Wallet : verify session is in authorized state Wallet -> Wallet : validate transaction t Wallet -> Wallet : sign transaction\nst = SignSolanaTransactions(t) Wallet --> Dapp ++-- : response(st) diff --git a/spec/spec.md b/spec/spec.md index c38c11664..b3aa7ed52 100644 --- a/spec/spec.md +++ b/spec/spec.md @@ -23,6 +23,7 @@ This specification uses [semantic versioning](https://en.wikipedia.org/wiki/Soft | Version | Description | | ------- | ----------------------------------------------------------------------------------------------------------------------------------- | | 1.0.0 | Initial release version of the Mobile Wallet Adapter specification (identical to pre-release version 0.9.1) | +| 2.0.0 | Initial draft of Mobile Wallet Adaper 2.0 | ### Pre-v1.0.0 changelog @@ -274,7 +275,7 @@ If either public keypoint `Qd` or `Qw` is not valid, if no `HELLO_RSP` message i ### Operation -After [session establishment](#session-establishment) completes, the wallet endpoint is ready to accept [JSON-RPC 2.0](https://www.jsonrpc.org/specification) non-privileged method calls from the dapp endpoint. To invoke privileged methods, a dapp endpoint must first put the session into an authorized state via either an [`authorize`](#authorize) or a [`reauthorize`](#reauthorize) method call. For details on how a session enters and exits an authorized state, see the [non-privileged methods](#non-privileged-methods). +After [session establishment](#session-establishment) completes, the wallet endpoint is ready to accept [JSON-RPC 2.0](https://www.jsonrpc.org/specification) non-privileged method calls from the dapp endpoint. To invoke privileged methods, a dapp endpoint must first put the session into an authorized state via an [`authorize`](#authorize) method call. For details on how a session enters and exits an authorized state, see the [non-privileged methods](#non-privileged-methods). ### Encrypted message wrapping @@ -322,6 +323,7 @@ authorize “name”: “”, }, "cluster": "", + “auth_token”: “”, } ``` @@ -332,6 +334,7 @@ where: - `icon`: (optional) a relative path (from `uri`) to an image asset file of an icon identifying the dapp endpoint making this authorization request - `name`: (optional) the display name for this dapp endpoint - `cluster`: (optional) if set, the Solana network cluster with which the dapp endpoint intends to interact; supported values include `mainnet-beta`, `testnet`, `devnet`. If not set, defaults to `mainnet-beta`. +- `auth_token`: (optional) an opaque string previously returned by a call to [`authorize`](#authorize), or [`clone_authorization`](#clone_authorization). When present, the wallet endpoint should attempt to reauthorize the dapp endpoint sliently without promting the user. ###### Result {: .no_toc } @@ -349,7 +352,7 @@ where: where: -- `auth_token`: an opaque string representing a unique identifying token issued by the wallet endpoint to the dapp endpoint. The format and contents are an implementation detail of the wallet endpoint. The dapp endpoint can use this on future connections to `reauthorize` access to [privileged methods](#privileged-methods). +- `auth_token`: an opaque string representing a unique identifying token issued by the wallet endpoint to the dapp endpoint. The format and contents are an implementation detail of the wallet endpoint. The dapp endpoint can use this on future connections to reauthorize access to [privileged methods](#privileged-methods). - `accounts`: one or more value objects that represent the accounts to which this auth token corresponds. These objects hold the following properties: - `address`: a base64-encoded address for this account - `label`: (optional) a human-readable string that describes the account. Wallet endpoints that allow their users to label their accounts may choose to return those labels here to enhance the user experience at the dapp endpoint. @@ -364,57 +367,27 @@ where: ##### Description -This method allows the dapp endpoint to request authorization from the wallet endpoint for access to [privileged methods](#privileged-methods). On success, it returns an `auth_token` providing access to privileged methods, along with addresses and optional labels for all authorized accounts. It may also return a URI suitable for future use as an [endpoint-specific URI](#endpoint-specific-uris). After a successful call to `authorize`, the current session will be placed into an authorized state, with privileges associated with the returned `auth_token`. On failure, the current session with be placed into the unauthorized state. - -The returned `auth_token` is an opaque string with meaning only to the wallet endpoint which created it. It is recommended that the wallet endpoint include a mechanism to authenticate the contents of auth tokens it issues (for e.g., with an HMAC, or by encryption with a secret symmetric key). This `auth_token` may be used to [`reauthorize`](#reauthorize) future sessions between these dapp and wallet endpoints. - -Dapp endpoints should make every effort possible to [verify the authenticity](#dapp-identity-verification) of the presented identity. While the `uri` parameter is optional, it is strongly recommended - without it, the wallet endpoint may not be able to verify the authenticity of the dapp. - -The `cluster` parameter allows the dapp endpoint to select a specific Solana cluster with which to interact. This is relevant for both [`sign_transactions`](#sign_transactions), where a wallet may refuse to sign transactions without a currently valid blockhash, and for [`sign_and_send_transactions`](#sign_and_send_transactions), where the wallet endpoint must know which cluster to submit the transactions to. This parameter would normally be used to select a cluster other than `mainnet-beta` for dapp development and testing purposes. Under normal circumstances, this field should be omitted, in which case the wallet endpoint will interact with the `mainnet-beta` cluster. - -#### deauthorize - -##### JSON-RPC method specification - -###### Method -{: .no_toc } - -``` -deauthorize -``` - -###### Params -{: .no_toc } - -``` -{ - “auth_token”: “”, -} -``` +This method allows the dapp endpoint to request authorization from the wallet endpoint for access to [privileged methods](#privileged-methods). On success, it returns an `auth_token` providing access to privileged methods, along with addresses and optional labels for all authorized accounts. It may also return a URI suitable for future use as an [endpoint-specific URI](#endpoint-specific-uris). After a successful call to [`authorize`](#authorize)`, the current session will be placed into an authorized state, with privileges associated with the returned `auth_token`. On failure, the current session with be placed into the unauthorized state. -where: +The returned `auth_token` is an opaque string with meaning only to the wallet endpoint which created it. It is recommended that the wallet endpoint include a mechanism to authenticate the contents of auth tokens it issues (for e.g., with an HMAC, or by encryption with a secret symmetric key). This `auth_token` may be used to reauthorize future sessions between these dapp and wallet endpoints by including it in future calls to [`authorize`](#authorize). -- `auth_token`: an opaque string previously returned by a call to [`authorize`](#authorize), [`reauthorize`](#reauthorize), or [`clone_authorization`](#clone_authorization) +If an `auth_token` is provided by the dapp endpoint, the wallet endpoint should put the current session in an authorized state, with privileges associated with the specified `auth_token`. Additionally, updated values for `auth_token`, `accounts`, and/or `wallet_uri_base` will be returned. These may differ from those originally provided in the authorize response for this auth token; if so, they override any previous values for these parameters. The prior values should be discarded and not reused. This allows a wallet endpoint to update the auth token used by the dapp endpoint, or to modify the set of authorized account addresses or their labels without requiring the dapp endpoint to restart the authorization process. -###### Result -{: .no_toc } +If an `auth_token` is provided by the dapp endpoint, and the result is `ERROR_AUTHORIZATION_FAILED`, this auth token cannot be reused, and should be discarded. The dapp endpoint should request a new token with the [`authorize`](#authorize) method. The session with be placed into the unauthorized state. -``` -{} -``` +Wallet endpoints should make every effort possible to [verify the authenticity](#dapp-identity-verification) of the presented identity. While the `uri` parameter is optional, it is strongly recommended - without it, the wallet endpoint may not be able to verify the authenticity of the dapp. -###### Errors -{: .no_toc } +The `cluster` parameter allows the dapp endpoint to select a specific Solana cluster with which to interact. This is relevant for both [`sign_transactions`](#sign_transactions), where a wallet may refuse to sign transactions without a currently valid blockhash, and for [`sign_and_send_transactions`](#sign_and_send_transactions), where the wallet endpoint must know which cluster to submit the transactions to. This parameter would normally be used to select a cluster other than `mainnet-beta` for dapp development and testing purposes. Under normal circumstances, this field should be omitted, in which case the wallet endpoint will interact with the `mainnet-beta` cluster. -- `-32602` (Invalid params) if the params object does not match the format defined above +##### Non-normative commentary -##### Description +Previous versions of this specification (pre 2.0) defiend a separate `reauthorize` method that required an `auth_token` parameter and attempted to put the current session in an authorized state, with privileges associated with the specified `auth_token`. The additon of the optional `auth-token` parameter on the [`authorize`](#authorize) method allows dapps to reauthorize a previously issued auth token. This change was made to simplify the interface and reduce confusion on when to use each method, and to align with the functionaly of the [wallet-standard `connect`](https://github.com/wallet-standard/wallet-standard/blob/master/packages/core/features/src/connect.ts) feature which takes an optional `silent` parameter to request accounts that have already been authorized without prompting the user. -This method will make the provided `auth_token` invalid for use (if it ever was valid). To avoid disclosure, this method will not indicate whether the `auth_token` was previously valid to the caller. +Authorization of a previously issued auth token is intended to be a lightweight operation, as compared to issuing a new auth token. It normally should not present any UI to the user, but instead perform only the subset of dapp endpoint identity checks that can be performed quickly and without user intervention. The intent is to quickly verify that an auth token remains valid for use by this dapp endpoint. If verification fails for any reason, the wallet endpoint should report `ERROR_AUTHORIZATION_FAILED` to the dapp endpoint, which would then discard the stored auth token and begin authorization from scratch with a new call to [`authorize`](#authorize). -If, during the current session, the specified auth token was returned by the most recent call to [`authorize`](#authorize) or [`reauthorize`](#reauthorize), the session with be placed into the unauthorized state. +Wallet endpoints should balance the responsibility for performing these identity checks against their latency impact. For example, a wallet endpoint may choose to accept an auth token issued in the last several minutes without performing any additional checks, but require dapp endpoint identity checks to be performed for an auth token that was issued before then. This facilitates multiple [sessions to be established](#session-establishment) in a short timespan, related to the same user interaction with a dapp endpoint. The auth token validity policy is a competency of the wallet endpoint, and dictating any specific auth token lifespan or timeout is outside the scope of this protocol specification. However, it is strongly recommended that wallet endpoints do not issue auth tokens with unlimited lifespans or for which dapp endpoint identity checks are never performed on `authorize`. -#### reauthorize +#### deauthorize ##### JSON-RPC method specification @@ -422,7 +395,7 @@ If, during the current session, the specified auth token was returned by the mos {: .no_toc } ``` -reauthorize +deauthorize ``` ###### Params @@ -430,59 +403,31 @@ reauthorize ``` { - “identity”: { - “uri”: “”, - “icon”: “”, - “name”: “”, - }, “auth_token”: “”, } ``` where: -- `identity`: as defined for [`authorize`](#authorize) -- `auth_token`: an opaque string previously returned by a call to [`authorize`](#authorize), [`reauthorize`](#reauthorize), or [`clone_authorization`](#clone_authorization) +- `auth_token`: an opaque string previously returned by a call to [`authorize`](#authorize), or [`clone_authorization`](#clone_authorization) ###### Result {: .no_toc } ``` -{ - “auth_token”: “”, - “accounts”: [ - {“address”: “
", “label”: “