From a11d2af3c6e77398ffcc8a4eaaeacfb2e52c1fc4 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:17:25 +0200 Subject: [PATCH 01/19] ERC-4361 editorial: remove invalid space after :// in informal template (#18) --- ERCS/erc-4361.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index a2bd2284f7f..c22b753cab5 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -127,7 +127,7 @@ This specification defines the following SIWE Message fields that can be parsed A Bash-like informal template of the full SIWE Message is presented below for readability and ease of understanding, and it does not reflect the allowed optionality of the fields. Field descriptions are provided in the following section. A full ABNF description is provided in [ABNF Message Format](#abnf-message-format). ``` -${scheme}:// ${domain} wants you to sign in with your Ethereum account: +${scheme}://${domain} wants you to sign in with your Ethereum account: ${address} ${statement} From e7a56390f04f46dd65b8f834b6bce62339175e2d Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:17:39 +0200 Subject: [PATCH 02/19] ERC-4361 editorial: fix stale request-uri reference (#19) --- ERCS/erc-4361.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index c22b753cab5..1d3ddae7a4c 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -228,7 +228,7 @@ Resources: #### Verifying a signed Message -- The SIWE Message MUST be checked for conformance to the ABNF Message Format in the previous sections, checked against expected values after parsing (e.g., `expiration-time`, `nonce`, `request-uri` etc.), and its signature MUST be checked as defined in [Signing and Verifying Messages with Ethereum Accounts](#signing-and-verifying-messages-with-ethereum-accounts). +- The SIWE Message MUST be checked for conformance to the ABNF Message Format in the previous sections, checked against expected values after parsing (e.g., `expiration-time`, `nonce`, `uri` etc.), and its signature MUST be checked as defined in [Signing and Verifying Messages with Ethereum Accounts](#signing-and-verifying-messages-with-ethereum-accounts). #### Creating Sessions From ceac03e55899056dd8f095d9ffd607ec66030c76 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:17:52 +0200 Subject: [PATCH 03/19] ERC-4361 editorial: clarify RFC 3339 is a profile of ISO 8601, not equivalent (#20) --- ERCS/erc-4361.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 1d3ddae7a4c..497c3b503fa 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -93,8 +93,9 @@ nonce = 8*( ALPHA / DIGIT ) issued-at = date-time expiration-time = date-time not-before = date-time - ; See RFC 3339 (ISO 8601) for the - ; definition of "date-time". + ; See RFC 3339 for date-time. RFC 3339 is + ; a profile of ISO 8601; only RFC 3339 + ; forms are permitted here. request-id = *pchar ; See RFC 3986 for the definition of "pchar". From 1794b8e407910f61e1706718ee542a6b0e83e88f Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:18:03 +0200 Subject: [PATCH 04/19] ERC-4361 editorial: normalize EIP-55 to ERC-55 in ABNF comment (#21) --- ERCS/erc-4361.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 497c3b503fa..9f4a4d477f5 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -70,7 +70,7 @@ domain = authority address = "0x" 40*40HEXDIG ; Must also conform to capitalization - ; checksum encoding specified in EIP-55 + ; checksum encoding specified in ERC-55 ; where applicable (EOAs). statement = *( reserved / unreserved / " " ) From 7aeadf144ceec64ede2f6520f2693484438f24e0 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:18:18 +0200 Subject: [PATCH 05/19] ERC-4361 clarification: assign ERC-191 prefixing to wallet/signing primitive only (#2) --- ERCS/erc-4361.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 9f4a4d477f5..ff00c0d44b1 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -29,8 +29,8 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S Sign-In with Ethereum (SIWE) works as follows: -1. The relying party generates a SIWE Message and prefixes the SIWE Message with `\x19Ethereum Signed Message:\n` as defined in [ERC-191](./eip-191.md). -2. The wallet presents the user with a structured plaintext message or equivalent interface for signing the SIWE Message with the [ERC-191](./eip-191.md) signed data format. +1. The relying party generates a SIWE Message (the plaintext payload, without any prefix) and transmits it to the wallet. +2. The wallet presents the user with a structured plaintext message or equivalent interface, and, upon user consent, signs the SIWE Message using the [ERC-191](./eip-191.md) signed data format. The ERC-191 prefix (`\x19Ethereum Signed Message:\n`) is applied by the signing primitive exactly once; the relying party MUST NOT pre-prefix the message. 3. The signature is then presented to the relying party, which checks the signature's validity and SIWE Message content. 4. The relying party might further fetch data associated with the Ethereum address, such as from the Ethereum blockchain (e.g., ENS, account balances, [ERC-20](./eip-20.md)/[ERC-721](./eip-721.md)/[ERC-1155](./eip-1155.md) asset ownership), or other data sources that might or might not be permissioned. From 8ff673681ebfb66408844b6535354c932ea61f00 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:18:42 +0200 Subject: [PATCH 06/19] ERC-4361 clarification: harmonize omitted-scheme default via wallet defaultScheme (#7) --- ERCS/erc-4361.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index ff00c0d44b1..e8c3097107a 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -110,7 +110,7 @@ resource = "- " URI This specification defines the following SIWE Message fields that can be parsed from a SIWE Message by following the rules in [ABNF Message Format](#abnf-message-format): - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. -- `domain` REQUIRED. The domain that is requesting the signing. Its value MUST be an RFC 3986 authority. The authority includes an OPTIONAL port. If the port is not specified, the default port for the provided `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified, HTTPS is assumed by default. +- `domain` REQUIRED. The domain that is requesting the signing. Its value MUST be an RFC 3986 authority. The authority includes an OPTIONAL port. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. - `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./eip-55.md) where applicable. - `statement` OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include `'\n'` (the byte `0x0a`). - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). @@ -262,7 +262,7 @@ The algorithm takes the following input variables: - fields from the SIWE message. - `origin` of the signing request - in the case of a browser wallet implementation - the origin of the page which requested the signin via the provider. - `allowedSchemes` - a list of schemes allowed by the Wallet. -- `defaultScheme` - a scheme to assume when none was provided. Wallet implementers in the browser SHOULD use `https`. +- `defaultScheme` - the scheme to assume when none was provided in the message. Wallet implementers in the browser MUST use `https`; non-browser wallet implementers MAY choose a different value appropriate to their transport. - developer mode indication - a setting deciding if certain risks should be a warning instead of rejection. Can be manually configured or derived from `origin` being localhost. The algorithm is described as follows: From 88f0fd19f5f140d06d4a59970b1e3425c5ef6760 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:19:02 +0200 Subject: [PATCH 07/19] ERC-4361 clarification: drop redundant subdomain-mismatch rule, host already covers it (#8) --- ERCS/erc-4361.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index e8c3097107a..ece12b1557b 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -270,8 +270,7 @@ The algorithm is described as follows: - If `scheme` was not provided, then assign `defaultScheme` as `scheme`. - If `scheme` is not contained in `allowedSchemes`, then the `scheme` is not expected and the Wallet MUST reject the request. Wallet implementers in the browser SHOULD limit the list of `allowedSchemes` to just `'https'` unless a developer mode is activated. - If `scheme` does not match the scheme of `origin`, the Wallet SHOULD reject the request. Wallet implementers MAY show a warning instead of rejecting the request if a developer mode is activated. In that case the Wallet continues processing the request. -- If the `host` part of the `domain` and `origin` do not match, the Wallet MUST reject the request unless the Wallet is in developer mode. In developer mode the Wallet MAY show a warning instead and continues processing the request. -- If `domain` and `origin` have mismatching subdomains, the Wallet SHOULD reject the request unless the Wallet is in developer mode. In developer mode the Wallet MAY show a warning instead and continues processing the request. +- If the `host` subcomponent of `domain` and the host of `origin` do not match exactly, the Wallet MUST reject the request unless the Wallet is in developer mode. In developer mode the Wallet MAY show a warning instead and continue processing the request. Because `host` per RFC 3986 already includes the full hostname (all labels, including subdomains), a mismatched subdomain is a mismatched host and is covered by this rule. - Let `port` be the port component of `domain`, and if no port is contained in `domain`, assign `port` the default port specified for the `scheme`. - If `port` is not empty, then the Wallet SHOULD show a warning if the `port` does not match the port of `origin`. - If `port` is empty, then the Wallet MAY show a warning if `origin` contains a specific port. (Note 'https' has a default port of 443 so this only applies if `allowedSchemes` contain unusual schemes) From f62bb494eaaab709db052e41877e8fc679b05091 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:19:24 +0200 Subject: [PATCH 08/19] ERC-4361 clarification: formalize RFC 3986/5234/7405 grammar imports (#5) --- ERCS/erc-4361.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index ece12b1557b..e58d7e65478 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -38,7 +38,7 @@ Sign-In with Ethereum (SIWE) works as follows: #### ABNF Message Format -A SIWE Message MUST conform with the following Augmented Backus–Naur Form (ABNF, [RFC 5234](https://www.rfc-editor.org/rfc/rfc5234)) expression (note that `%s` denotes case sensitivity for a string term, as per [RFC 7405](https://www.rfc-editor.org/rfc/rfc7405)). +A SIWE Message MUST conform with the following Augmented Backus–Naur Form (ABNF, [RFC 5234](https://www.rfc-editor.org/rfc/rfc5234)) expression. `%s` denotes case sensitivity for a string term, as per [RFC 7405](https://www.rfc-editor.org/rfc/rfc7405). The grammar also normatively imports the following productions from [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986): `URI`, `authority`, `host`, `port`, `pchar`, `reserved`, and `unreserved`. ```abnf sign-in-with-ethereum = @@ -58,6 +58,13 @@ sign-in-with-ethereum = [ LF %s"Resources:" resources ] +; Imported from RFC 3986 Section 3: +; URI, authority, host, port, pchar, reserved, unreserved. +; Imported from RFC 5234 Appendix B.1: +; ALPHA, DIGIT, HEXDIG, LF. +; Imported from RFC 7405: +; %s (case-sensitive string literal prefix). + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) ; See RFC 3986 for the fully contextualized ; definition of "scheme". From ae9bcbb5efd7aa179f3637b373f0c9354b20ece0 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:19:44 +0200 Subject: [PATCH 09/19] ERC-4361 clarification: declare UTF-8 as the wire encoding (#1) --- ERCS/erc-4361.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index e58d7e65478..029ea360bb3 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -40,6 +40,8 @@ Sign-In with Ethereum (SIWE) works as follows: A SIWE Message MUST conform with the following Augmented Backus–Naur Form (ABNF, [RFC 5234](https://www.rfc-editor.org/rfc/rfc5234)) expression. `%s` denotes case sensitivity for a string term, as per [RFC 7405](https://www.rfc-editor.org/rfc/rfc7405). The grammar also normatively imports the following productions from [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986): `URI`, `authority`, `host`, `port`, `pchar`, `reserved`, and `unreserved`. +A SIWE Message is a sequence of Unicode code points encoded as UTF-8. All ABNF productions below describe the UTF-8 byte stream of the message. The `` component of the ERC-191 prefix (`\x19Ethereum Signed Message:\n`) MUST be computed as the UTF-8 byte length of the SIWE Message. + ```abnf sign-in-with-ethereum = [ scheme "://" ] domain %s" wants you to sign in with your Ethereum account:" LF From cfef9ef5be9c9454299bee040792a940cd0c37cf Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:20:41 +0200 Subject: [PATCH 10/19] ERC-4361 judgment: harmonize ERC-55 to SHOULD and pin "0x" to case-sensitive (#3) --- ERCS/erc-4361.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 029ea360bb3..0b54d7e7a38 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -77,9 +77,9 @@ domain = authority ; See RFC 3986 for the fully contextualized ; definition of "authority". -address = "0x" 40*40HEXDIG - ; Must also conform to capitalization - ; checksum encoding specified in ERC-55 +address = %s"0x" 40*40HEXDIG + ; SHOULD also conform to the mixed-case + ; capitalization checksum specified in ERC-55 ; where applicable (EOAs). statement = *( reserved / unreserved / " " ) From d7f3ee3a7796b6857d005e43b16de302c0b86a76 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:22:00 +0200 Subject: [PATCH 11/19] ERC-4361 narrow: require non-empty domain host and exclude userinfo subcomponent (#16) --- ERCS/erc-4361.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 0b54d7e7a38..4e9ab0a648c 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -71,11 +71,11 @@ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) ; See RFC 3986 for the fully contextualized ; definition of "scheme". -domain = authority - ; From RFC 3986: - ; authority = [ userinfo "@" ] host [ ":" port ] - ; See RFC 3986 for the fully contextualized - ; definition of "authority". +domain = host [ ":" port ] + ; host and port are imported from RFC 3986. + ; The userinfo component of RFC 3986 + ; authority is intentionally excluded + ; from SIWE domain values. address = %s"0x" 40*40HEXDIG ; SHOULD also conform to the mixed-case @@ -119,7 +119,7 @@ resource = "- " URI This specification defines the following SIWE Message fields that can be parsed from a SIWE Message by following the rules in [ABNF Message Format](#abnf-message-format): - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. -- `domain` REQUIRED. The domain that is requesting the signing. Its value MUST be an RFC 3986 authority. The authority includes an OPTIONAL port. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. +- `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. - `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./eip-55.md) where applicable. - `statement` OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include `'\n'` (the byte `0x0a`). - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). From 4b2cecffe1befec1b931729d80d39c02be13108c Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 30 Apr 2026 16:26:44 +0200 Subject: [PATCH 12/19] ERC-4361 clarification: empty optional field forms equate to omission (#12, #13, #14) --- ERCS/erc-4361.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 4e9ab0a648c..175e3be970a 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -121,7 +121,7 @@ This specification defines the following SIWE Message fields that can be parsed - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. - `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. - `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./eip-55.md) where applicable. -- `statement` OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include `'\n'` (the byte `0x0a`). +- `statement` OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include `'\n'` (the byte `0x0a`). Producers SHOULD omit the `[ statement LF ]` production entirely when no statement is present (producing a single blank-line-only sequence between the address and the URI line) rather than emitting an empty statement. Parsers MUST accept both forms. When emitted, an empty `statement` carries the same meaning as an omitted one. - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). - `version` REQUIRED. The current version of the SIWE Message, which MUST be `1` for this specification. - `chain-id` REQUIRED. The [EIP-155](./eip-155.md) Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved. @@ -129,8 +129,8 @@ This specification defines the following SIWE Message fields that can be parsed - `issued-at` REQUIRED. The time when the message was generated, typically the current time. Its value MUST be an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime string. - `expiration-time` OPTIONAL. The time when the signed authentication message is no longer valid. Its value MUST be an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime string. - `not-before` OPTIONAL. The time when the signed authentication message will become valid. Its value MUST be an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime string. -- `request-id` OPTIONAL. A system-specific identifier that MAY be used to uniquely refer to the sign-in request. -- `resources` OPTIONAL. A list of information or references to information the user wishes to have resolved as part of authentication by the relying party. Every resource MUST be an RFC 3986 URI separated by `"\n- "` where `\n` is the byte `0x0a`. +- `request-id` OPTIONAL. A system-specific identifier that MAY be used to uniquely refer to the sign-in request. Producers SHOULD NOT emit an empty `request-id`; when no identifier is available, the `Request ID:` header is to be omitted entirely. Parsers MUST continue to accept messages that contain an empty `request-id` value, for backwards compatibility with existing message streams. +- `resources` OPTIONAL. A list of information or references to information the user wishes to have resolved as part of authentication by the relying party. Every resource MUST be an RFC 3986 URI separated by `"\n- "` where `\n` is the byte `0x0a`. Producers SHOULD NOT emit a bare `Resources:` header with no following resources; when no resources are present, the entire `[ LF %s"Resources:" resources ]` production is to be omitted. Parsers MUST accept a bare `Resources:` header as semantically equivalent to an omitted one, for backwards compatibility. #### Informal Message Template From 2e54091a0b3edb0695157b3a770ed99bbea9305e Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:24:13 +0200 Subject: [PATCH 13/19] ERC-4361 widen: statement charset to printable ASCII excluding LF (#11) --- ERCS/erc-4361.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 175e3be970a..20aa3e892ed 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -82,10 +82,9 @@ address = %s"0x" 40*40HEXDIG ; capitalization checksum specified in ERC-55 ; where applicable (EOAs). -statement = *( reserved / unreserved / " " ) - ; See RFC 3986 for the definition - ; of "reserved" and "unreserved". - ; The purpose is to exclude LF (line break). +statement = *( %x20-7E ) + ; Printable ASCII excluding LF (0x0A) + ; and other control characters. uri = URI ; See RFC 3986 for the definition of "URI". @@ -121,7 +120,7 @@ This specification defines the following SIWE Message fields that can be parsed - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. - `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. - `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./eip-55.md) where applicable. -- `statement` OPTIONAL. A human-readable ASCII assertion that the user will sign which MUST NOT include `'\n'` (the byte `0x0a`). Producers SHOULD omit the `[ statement LF ]` production entirely when no statement is present (producing a single blank-line-only sequence between the address and the URI line) rather than emitting an empty statement. Parsers MUST accept both forms. When emitted, an empty `statement` carries the same meaning as an omitted one. +- `statement` OPTIONAL. A human-readable assertion that the user will sign. If emitted, the statement is a sequence of zero or more printable ASCII characters (bytes `0x20` through `0x7E`) and MUST NOT include `'\n'` (the byte `0x0a`) or any other control character. Producers SHOULD omit the `[ statement LF ]` production entirely when no statement is present rather than emitting an empty statement. Parsers MUST accept both empty and omitted statements. For authentication semantics, an empty statement is equivalent to an omitted statement. - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). - `version` REQUIRED. The current version of the SIWE Message, which MUST be `1` for this specification. - `chain-id` REQUIRED. The [EIP-155](./eip-155.md) Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved. From ab3818b83fe6e92d1918d705eeec69ad7522cb17 Mon Sep 17 00:00:00 2001 From: jalil Date: Thu, 23 Apr 2026 14:25:35 +0200 Subject: [PATCH 14/19] ERC-4361 clarification: align reference implementation with cumulative grammar (#4) --- assets/erc-4361/example.js | 123 +++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 39 deletions(-) diff --git a/assets/erc-4361/example.js b/assets/erc-4361/example.js index 12ec7ee74a5..59070a65141 100644 --- a/assets/erc-4361/example.js +++ b/assets/erc-4361/example.js @@ -1,15 +1,42 @@ // To run this example, navigate to this directory and run `npm i && node example.js` +// +// ---------------------------------------------------------------------------- +// Regression tests - the following messages from the ERC-4361 specification +// body (Examples section) MUST parse successfully against the grammar below. +// If you edit the grammar, verify these still parse before committing. +// ---------------------------------------------------------------------------- +// +// Example 1 - implicit scheme: +// +// example.com wants you to sign in with your Ethereum account: +// 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 +// +// I accept the ExampleOrg Terms of Service: https://example.com/tos +// +// URI: https://example.com/login +// Version: 1 +// Chain ID: 1 +// Nonce: 32891756 +// Issued At: 2021-09-30T16:25:24Z +// Resources: +// - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ +// - https://example.com/my-web2-claim.json +// +// Example 2 - implicit scheme, explicit port (example.com:3388 in place of +// example.com on the first line; otherwise identical to Example 1). +// +// Example 3 - explicit scheme (https://example.com in place of example.com +// on the first line; otherwise identical to Example 1). const apgApi = require('apg-js/src/apg-api/api'); const apgLib = require('apg-js/src/apg-lib/node-exports'); const GRAMMAR = ` sign-in-with-ethereum = - domain %s" wants you to sign in with your Ethereum account:" LF + [ scheme "://" ] domain %s" wants you to sign in with your Ethereum account:" LF address LF LF - [ statement LF ] - LF + statement-section %s"URI: " URI LF %s"Version: " version LF %s"Chain ID: " chain-id LF @@ -21,15 +48,20 @@ sign-in-with-ethereum = [ LF %s"Resources:" resources ] -domain = authority +domain = host [ ":" port ] + ; userinfo subcomponent of RFC 3986 authority + ; is excluded; host MUST NOT be empty. -address = "0x" 40*40HEXDIG - ; Must also conform to captilization - ; checksum encoding specified in EIP-55 +address = %s"0x" 40*40HEXDIG + ; SHOULD also conform to the mixed-case + ; capitalization checksum specified in ERC-55 ; where applicable (EOAs). -statement = 1*( reserved / unreserved / " " ) - ; The purpose is to exclude LF (line breaks). +statement = *( %x20-7E ) + ; Printable ASCII excluding LF (0x0A) + ; and other control characters. + +statement-section = statement LF LF / LF version = "1" @@ -164,28 +196,18 @@ const parseMessage = (message) => { return ret; }; - const domain = getField("domain"); - parser.ast.callbacks.domain = domain; - const address = getField("address"); - parser.ast.callbacks.address = address; - const statement = getField("statement"); - parser.ast.callbacks.statement = statement; - const uri = getField("uri"); - parser.ast.callbacks.uri = uri; - const version = getField("version"); - parser.ast.callbacks.version = version; - const chainId = getField("chainId"); - parser.ast.callbacks['chain-id'] = chainId; - const nonce = getField("nonce"); - parser.ast.callbacks.nonce = nonce; - const issuedAt = getField("issuedAt"); - parser.ast.callbacks['issued-at'] = issuedAt; - const expirationTime = getField("expirationTime"); - parser.ast.callbacks['expiration-time'] = expirationTime; - const notBefore = getField("notBefore"); - parser.ast.callbacks['not-before'] = notBefore; - const requestId = getField("requestId"); - parser.ast.callbacks['request-id'] = requestId; + parser.ast.callbacks.scheme = getField("scheme"); + parser.ast.callbacks.domain = getField("domain"); + parser.ast.callbacks.address = getField("address"); + parser.ast.callbacks.statement = getField("statement"); + parser.ast.callbacks.uri = getField("uri"); + parser.ast.callbacks.version = getField("version"); + parser.ast.callbacks['chain-id'] = getField("chainId"); + parser.ast.callbacks.nonce = getField("nonce"); + parser.ast.callbacks['issued-at'] = getField("issuedAt"); + parser.ast.callbacks['expiration-time'] = getField("expirationTime"); + parser.ast.callbacks['not-before'] = getField("notBefore"); + parser.ast.callbacks['request-id'] = getField("requestId"); const resources = function (state, chars, phraseIndex, phraseLength, data) { const ret = id.SEM_OK; @@ -212,14 +234,37 @@ const parseMessage = (message) => { return obj; } -const createMessage = ({ domain, address, uri, version, chainId, nonce, issuedAt }) => { - const header = `${domain} wants you to sign in with your Ethereum account:\n${address}\n\n\n`; - const uriField = `URI: ${uri}\n`; - const versionField = `Version: ${version}\n`; - const chainField = `Chain ID: ${chainId}\n`; - const nonceField = `Nonce: ${nonce}\n`; - const issuedAtField = `Issued At: ${issuedAt}`; - return [header, uriField, versionField, chainField, nonceField, issuedAtField].join(''); +const createMessage = ({ + scheme, + domain, + address, + uri, + version, + chainId, + nonce, + issuedAt, + expirationTime, + notBefore, + requestId, + resources, +}) => { + const prefix = scheme ? `${scheme}://${domain}` : domain; + const header = `${prefix} wants you to sign in with your Ethereum account:\n${address}\n\n\n`; + const requiredFields = [ + `URI: ${uri}\n`, + `Version: ${version}\n`, + `Chain ID: ${chainId}\n`, + `Nonce: ${nonce}\n`, + `Issued At: ${issuedAt}`, + ]; + const optionalFields = []; + if (expirationTime) optionalFields.push(`\nExpiration Time: ${expirationTime}`); + if (notBefore) optionalFields.push(`\nNot Before: ${notBefore}`); + if (requestId) optionalFields.push(`\nRequest ID: ${requestId}`); + if (Array.isArray(resources) && resources.length >= 1) { + optionalFields.push(`\nResources:\n- ${resources.join('\n- ')}`); + } + return [header, ...requiredFields, ...optionalFields].join(''); } const message = createMessage({ From 3a7bc36f763118eae39e98177c40766934abed5d Mon Sep 17 00:00:00 2001 From: 0xthrpw <0xthrpw@gmail.com> Date: Tue, 19 May 2026 11:04:51 -0400 Subject: [PATCH 15/19] ERC-4361 clarification: amended commit ab3818: optional LF and example statement implementation --- assets/erc-4361/example.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/assets/erc-4361/example.js b/assets/erc-4361/example.js index 59070a65141..016ebf3c2d1 100644 --- a/assets/erc-4361/example.js +++ b/assets/erc-4361/example.js @@ -61,7 +61,7 @@ statement = *( %x20-7E ) ; Printable ASCII excluding LF (0x0A) ; and other control characters. -statement-section = statement LF LF / LF +statement-section = statement LF LF / [ LF ] version = "1" @@ -238,6 +238,7 @@ const createMessage = ({ scheme, domain, address, + statement, uri, version, chainId, @@ -249,7 +250,8 @@ const createMessage = ({ resources, }) => { const prefix = scheme ? `${scheme}://${domain}` : domain; - const header = `${prefix} wants you to sign in with your Ethereum account:\n${address}\n\n\n`; + const header = `${prefix} wants you to sign in with your Ethereum account:\n${address}\n\n`; + const statementSection = statement ? `${statement}\n\n` : `` const requiredFields = [ `URI: ${uri}\n`, `Version: ${version}\n`, @@ -264,7 +266,7 @@ const createMessage = ({ if (Array.isArray(resources) && resources.length >= 1) { optionalFields.push(`\nResources:\n- ${resources.join('\n- ')}`); } - return [header, ...requiredFields, ...optionalFields].join(''); + return [header, statementSection, ...requiredFields, ...optionalFields].join(''); } const message = createMessage({ From a1ec1a496e7766089c8681e3c09e3ce56e78cf06 Mon Sep 17 00:00:00 2001 From: 0xthrpw <0xthrpw@gmail.com> Date: Tue, 19 May 2026 11:58:28 -0400 Subject: [PATCH 16/19] ERC-4361 update: fix outgoing links to EIPs and ERCs --- ERCS/erc-4361.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 20aa3e892ed..8423c425af6 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -30,9 +30,9 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S Sign-In with Ethereum (SIWE) works as follows: 1. The relying party generates a SIWE Message (the plaintext payload, without any prefix) and transmits it to the wallet. -2. The wallet presents the user with a structured plaintext message or equivalent interface, and, upon user consent, signs the SIWE Message using the [ERC-191](./eip-191.md) signed data format. The ERC-191 prefix (`\x19Ethereum Signed Message:\n`) is applied by the signing primitive exactly once; the relying party MUST NOT pre-prefix the message. +2. The wallet presents the user with a structured plaintext message or equivalent interface, and, upon user consent, signs the SIWE Message using the [ERC-191](./erc-191.md) signed data format. The ERC-191 prefix (`\x19Ethereum Signed Message:\n`) is applied by the signing primitive exactly once; the relying party MUST NOT pre-prefix the message. 3. The signature is then presented to the relying party, which checks the signature's validity and SIWE Message content. -4. The relying party might further fetch data associated with the Ethereum address, such as from the Ethereum blockchain (e.g., ENS, account balances, [ERC-20](./eip-20.md)/[ERC-721](./eip-721.md)/[ERC-1155](./eip-1155.md) asset ownership), or other data sources that might or might not be permissioned. +4. The relying party might further fetch data associated with the Ethereum address, such as from the Ethereum blockchain (e.g., ENS, account balances, [ERC-20](./erc-20.md)/[ERC-721](./erc-721.md)/[ERC-1155](./erc-1155.md) asset ownership), or other data sources that might or might not be permissioned. ### Message Format @@ -119,11 +119,11 @@ This specification defines the following SIWE Message fields that can be parsed - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. - `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. -- `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./eip-55.md) where applicable. +- `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./erc-55.md) where applicable. - `statement` OPTIONAL. A human-readable assertion that the user will sign. If emitted, the statement is a sequence of zero or more printable ASCII characters (bytes `0x20` through `0x7E`) and MUST NOT include `'\n'` (the byte `0x0a`) or any other control character. Producers SHOULD omit the `[ statement LF ]` production entirely when no statement is present rather than emitting an empty statement. Parsers MUST accept both empty and omitted statements. For authentication semantics, an empty statement is equivalent to an omitted statement. - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). - `version` REQUIRED. The current version of the SIWE Message, which MUST be `1` for this specification. -- `chain-id` REQUIRED. The [EIP-155](./eip-155.md) Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved. +- `chain-id` REQUIRED. The [ERC-155](./erc-155.md) Chain ID to which the session is bound, and the network where Contract Accounts MUST be resolved. - `nonce` REQUIRED. A random string typically chosen by the relying party and used to prevent replay attacks, at least 8 alphanumeric characters. - `issued-at` REQUIRED. The time when the message was generated, typically the current time. Its value MUST be an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime string. - `expiration-time` OPTIONAL. The time when the signed authentication message is no longer valid. Its value MUST be an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) datetime string. @@ -214,17 +214,17 @@ Resources: ### Signing and Verifying Messages with Ethereum Accounts -- For Externally Owned Accounts (EOAs), the verification method specified in [ERC-191](./eip-191.md) MUST be used. +- For Externally Owned Accounts (EOAs), the verification method specified in [ERC-191](./erc-191.md) MUST be used. - For Contract Accounts, - - The verification method specified in [ERC-1271](./eip-1271.md) SHOULD be used, and if it is not, the implementer MUST clearly define the verification method to attain security and interoperability for both wallets and relying parties. - - When performing [ERC-1271](./eip-1271.md) signature verification, the contract performing the verification MUST be resolved from the specified `chain-id`. - - Implementers SHOULD take into consideration that [ERC-1271](./eip-1271.md) implementations are not required to be pure functions, and can return different results for the same inputs depending on blockchain state. This can affect the security model and session validation rules. For example, a service with [ERC-1271](./eip-1271.md) signing enabled could rely on webhooks to receive notifications when state affecting the results is changed. When it receives a notification, it invalidates any matching sessions. + - The verification method specified in [ERC-1271](./erc-1271.md) SHOULD be used, and if it is not, the implementer MUST clearly define the verification method to attain security and interoperability for both wallets and relying parties. + - When performing [ERC-1271](./erc-1271.md) signature verification, the contract performing the verification MUST be resolved from the specified `chain-id`. + - Implementers SHOULD take into consideration that [ERC-1271](./erc-1271.md) implementations are not required to be pure functions, and can return different results for the same inputs depending on blockchain state. This can affect the security model and session validation rules. For example, a service with [ERC-1271](./erc-1271.md) signing enabled could rely on webhooks to receive notifications when state affecting the results is changed. When it receives a notification, it invalidates any matching sessions. ### Resolving Ethereum Name Service (ENS) Data - The relying party or wallet MAY additionally perform resolution of ENS data, as this can improve the user experience by displaying human-friendly information that is related to the `address`. Resolvable ENS data include: - - The [primary ENS name](./eip-181.md). + - The [primary ENS name](./erc-181.md). - The ENS avatar. - Any other resolvable resources specified in the ENS documentation. - If resolution of ENS data is performed, implementers SHOULD take precautions to preserve user privacy and consent, as their `address` could be forwarded to third party services as part of the resolution process. @@ -254,13 +254,13 @@ Resources: - The full SIWE message MUST be checked for conformance to the ABNF defined in [ABNF Message Format](#abnf-message-format). - Wallet implementers SHOULD warn users if the substring `"wants you to sign in - with your Ethereum account"` appears anywhere in an [ERC-191](./eip-191.md) message signing + with your Ethereum account"` appears anywhere in an [ERC-191](./erc-191.md) message signing request unless the message fully conforms to the format defined [ABNF Message Format](#abnf-message-format). #### Verifying the Request Origin - Wallet implementers MUST prevent phishing attacks by verifying the origin of the request against the `scheme` and `domain` fields in the SIWE Message. For example, when processing the SIWE message beginning with `"example.com wants you to sign in..."`, the wallet checks that the request actually originated from `https://example.com`. -- The origin SHOULD be read from a trusted data source such as the browser window or over WalletConnect ([ERC-1328](./eip-1328.md)) sessions for comparison against the signing message contents. +- The origin SHOULD be read from a trusted data source such as the browser window or over WalletConnect ([ERC-1328](./erc-1328.md)) sessions for comparison against the signing message contents. - Wallet implementers MAY warn instead of rejecting the verification if the origin is pointing to localhost. The following is a RECOMMENDED algorithm for Wallets to conform with the requirements on request origin verification defined by this specification. @@ -317,12 +317,12 @@ Additional functional requirements: ### Technical Decisions -- Why [ERC-191](./eip-191.md) (Signed Data Standard) over [EIP-712](./eip-712.md) (Ethereum typed structured data hashing and signing) - - [ERC-191](./eip-191.md) is already broadly supported across wallets UX, while [EIP-712](./eip-712.md) support for friendly user display is pending. **(1, 2, 3, 4)** - - [ERC-191](./eip-191.md) is simple to implement using a pre-set prefix prior to signing, while [EIP-712](./eip-712.md) is more complex to implement requiring the further implementations of a bespoke Solidity-inspired type system, RLP-based encoding format, and custom keccak-based hashing scheme. **(2)** - - [ERC-191](./eip-191.md) produces more human-readable messages, while [EIP-712](./eip-712.md) creates signing outputs for machine consumption, with most wallets not displaying the payload to be signed in a manner friendly to humans. **(1)**![](../assets/eip-4361/signing.png) +- Why [ERC-191](./erc-191.md) (Signed Data Standard) over [EIP-712](https://eips.ethereum.org/EIPS/eip-712) (Ethereum typed structured data hashing and signing) + - [ERC-191](./erc-191.md) is already broadly supported across wallets UX, while [EIP-712](https://eips.ethereum.org/EIPS/eip-712) support for friendly user display is pending. **(1, 2, 3, 4)** + - [ERC-191](./erc-191.md) is simple to implement using a pre-set prefix prior to signing, while [EIP-712](https://eips.ethereum.org/EIPS/eip-712) is more complex to implement requiring the further implementations of a bespoke Solidity-inspired type system, RLP-based encoding format, and custom keccak-based hashing scheme. **(2)** + - [ERC-191](./erc-191.md) produces more human-readable messages, while [EIP-712](https://eips.ethereum.org/EIPS/eip-712) creates signing outputs for machine consumption, with most wallets not displaying the payload to be signed in a manner friendly to humans. **(1)**![](../assets/eip-4361/signing.png) - - [EIP-712](./eip-712.md) has the advantage of on-chain representation and on-chain verifiability, such as for their use in metatransactions, but this feature is not relevant for the specification's scope. **(2)** + - [EIP-712](https://eips.ethereum.org/EIPS/eip-712) has the advantage of on-chain representation and on-chain verifiability, such as for their use in metatransactions, but this feature is not relevant for the specification's scope. **(2)** - Why not use JWTs? Wallets don't support JWTs. The keccak hash function is not assigned by IANA for use as a JOSE algorithm. **(2, 3)** - Why not use YAML or YAML with exceptions? YAML is loose compared to ABNF, which can readily express character set limiting, required ordering, and strict whitespacing. **(2, 3)** @@ -344,12 +344,12 @@ The following items are considered for future support either through an iteratio - Possible support for Decentralized Identifiers and Verifiable Credentials. - Possible cross-chain support. - Possible SIOPv2 support. -- Possible future support for [EIP-712](./eip-712.md). +- Possible future support for [EIP-712](https://eips.ethereum.org/EIPS/eip-712). - Version interpretation rules, e.g., sign with minor revision greater than understood, but not greater major version. ## Backwards Compatibility -- Most wallet implementations already support [ERC-191](./eip-191.md), so this is used as a base pattern with additional features. +- Most wallet implementations already support [ERC-191](./erc-191.md), so this is used as a base pattern with additional features. - Requirements were gathered from existing implementations of similar sign-in workflows, including statements to allow the user to accept a Terms of Service, nonces for replay protection, and inclusion of the Ethereum address itself in the message. ## Reference Implementation @@ -368,7 +368,7 @@ A reference implementation is available [here](../assets/eip-4361/example.js). - Sign-In with Ethereum gives users control through their keys. This is additional responsibility that mainstream users may not be accustomed to accepting, and key management is a hard problem especially for individuals. For example, there is no "forgot password" button as centralized identity providers commonly implement. - Early adopters of this specification are likely to be already adept at key management, so this consideration becomes more relevant with mainstream adoption. -- Certain wallets can use smart contracts and multisigs to provide an enhanced user experience with respect to key usage and key recovery, and these can be supported via [ERC-1271](./eip-1271.md) signing. +- Certain wallets can use smart contracts and multisigs to provide an enhanced user experience with respect to key usage and key recovery, and these can be supported via [ERC-1271](./erc-1271.md) signing. ### Wallet and Relying Party combined Security @@ -398,7 +398,7 @@ A reference implementation is available [here](../assets/eip-4361/example.js). There are several cases where an implementer SHOULD check for state changes as they relate to sessions. -- If an [ERC-1271](./eip-1271.md) implementation or dependent data changes the signature computation, the server SHOULD invalidate sessions appropriately. +- If an [ERC-1271](./erc-1271.md) implementation or dependent data changes the signature computation, the server SHOULD invalidate sessions appropriately. - If any resources specified in `resources` change, the server SHOULD invalidate sessions appropriately. However, the interpretation of `resources` is out of scope of this specification. ### Maximum Lengths for ABNF Terms From 7578829d30d2963d2343797607c89cf431d7ed2e Mon Sep 17 00:00:00 2001 From: 0xthrpw <0xthrpw@gmail.com> Date: Tue, 19 May 2026 12:24:30 -0400 Subject: [PATCH 17/19] ERC-4361 clarification: https enforcement in default scheme --- ERCS/erc-4361.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index 8423c425af6..b9d7882bbe7 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -118,7 +118,7 @@ resource = "- " URI This specification defines the following SIWE Message fields that can be parsed from a SIWE Message by following the rules in [ABNF Message Format](#abnf-message-format): - `scheme` OPTIONAL. The URI scheme of the origin of the request. Its value MUST be an RFC 3986 URI scheme. -- `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes; browser wallets' `defaultScheme` MUST be `https`. +- `domain` REQUIRED. The domain that is requesting the signing. Its value is an RFC 3986 `host` optionally followed by a `":"` and a port (the `userinfo` subcomponent of RFC 3986 `authority` is excluded). The `host` subcomponent MUST be non-empty. If the port is not specified, the default port for the effective `scheme` is assumed (e.g., 443 for HTTPS). If `scheme` is not specified in the message, the wallet's `defaultScheme` (see the Wallet Implementer Steps) is used as the effective scheme for origin-comparison purposes. - `address` REQUIRED. The Ethereum address performing the signing. Its value SHOULD be conformant to mixed-case checksum address encoding specified in [ERC-55](./erc-55.md) where applicable. - `statement` OPTIONAL. A human-readable assertion that the user will sign. If emitted, the statement is a sequence of zero or more printable ASCII characters (bytes `0x20` through `0x7E`) and MUST NOT include `'\n'` (the byte `0x0a`) or any other control character. Producers SHOULD omit the `[ statement LF ]` production entirely when no statement is present rather than emitting an empty statement. Parsers MUST accept both empty and omitted statements. For authentication semantics, an empty statement is equivalent to an omitted statement. - `uri` REQUIRED. An RFC 3986 URI referring to the resource that is the subject of the signing (as in the _subject of a claim_). @@ -270,7 +270,7 @@ The algorithm takes the following input variables: - fields from the SIWE message. - `origin` of the signing request - in the case of a browser wallet implementation - the origin of the page which requested the signin via the provider. - `allowedSchemes` - a list of schemes allowed by the Wallet. -- `defaultScheme` - the scheme to assume when none was provided in the message. Wallet implementers in the browser MUST use `https`; non-browser wallet implementers MAY choose a different value appropriate to their transport. +- `defaultScheme` - the scheme to assume when none was provided in the message. Wallet implementers in the browser SHOULD use `https`. - developer mode indication - a setting deciding if certain risks should be a warning instead of rejection. Can be manually configured or derived from `origin` being localhost. The algorithm is described as follows: From 70447030d93ef6ab6cb019a221ac84262d12c95b Mon Sep 17 00:00:00 2001 From: 0xthrpw <0xthrpw@gmail.com> Date: Wed, 20 May 2026 10:49:50 -0400 Subject: [PATCH 18/19] ERC-4361 update: specific rules for ERC-55 support --- ERCS/erc-4361.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-4361.md b/ERCS/erc-4361.md index b9d7882bbe7..720f7832cb8 100644 --- a/ERCS/erc-4361.md +++ b/ERCS/erc-4361.md @@ -78,9 +78,8 @@ domain = host [ ":" port ] ; from SIWE domain values. address = %s"0x" 40*40HEXDIG - ; SHOULD also conform to the mixed-case - ; capitalization checksum specified in ERC-55 - ; where applicable (EOAs). + ; If the address format is mixed-case, it + ; MUST conform to its ERC-55 checksum. statement = *( %x20-7E ) ; Printable ASCII excluding LF (0x0A) From 2663fff71a1d2956925ff203f30815bd1d8d26a1 Mon Sep 17 00:00:00 2001 From: jalil Date: Wed, 20 May 2026 18:25:01 +0200 Subject: [PATCH 19/19] ERC-4361 update: Fix stale grammar comment --- assets/erc-4361/example.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assets/erc-4361/example.js b/assets/erc-4361/example.js index 016ebf3c2d1..bdfbf44cada 100644 --- a/assets/erc-4361/example.js +++ b/assets/erc-4361/example.js @@ -53,9 +53,8 @@ domain = host [ ":" port ] ; is excluded; host MUST NOT be empty. address = %s"0x" 40*40HEXDIG - ; SHOULD also conform to the mixed-case - ; capitalization checksum specified in ERC-55 - ; where applicable (EOAs). + ; If the address format is mixed-case, it + ; MUST conform to its ERC-55 checksum. statement = *( %x20-7E ) ; Printable ASCII excluding LF (0x0A)