From 02290f120001cee3b8670b3a82b517adfa3299e4 Mon Sep 17 00:00:00 2001 From: martbost Date: Wed, 19 Aug 2026 15:44:07 -0500 Subject: [PATCH] SIWE-format (EIP-4361) sign-in challenge with EIP-55 checksummed address so wallets show their friendly Sign-in UI instead of a raw-signature warning Co-Authored-By: Claude Fable 5 --- messages.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/messages.js b/messages.js index 8fc236c..9ab37d1 100644 --- a/messages.js +++ b/messages.js @@ -57,10 +57,20 @@ function recoverAddress(msg, signature) { // ---- auth ---- const ADDR_RE = /^0x[0-9a-fA-F]{40}$/; +// EIP-55 checksum (needed for the SIWE message format; wallets render +// EIP-4361-formatted requests with their friendly "Sign-in" UI instead of a +// raw-signature warning — matters for member trust in MetaMask) +function checksumAddress(address) { + const a = address.toLowerCase().replace(/^0x/, ''); + const h = keccak256(a); + let out = '0x'; + for (let i = 0; i < a.length; i++) out += parseInt(h[i], 16) >= 8 ? a[i].toUpperCase() : a[i]; + return out; +} function makeChallenge(address) { const a = address.toLowerCase(); const nonce = crypto.randomBytes(16).toString('hex'); - const message = `RM Circle member sign-in\n\nWallet: ${a}\nNonce: ${nonce}\n\nSigning is free, proves you own this wallet to rmcircle.team, and cannot move funds or approve anything.`; + const message = `rmcircle.team wants you to sign in with your Ethereum account:\n${checksumAddress(a)}\n\nRM Circle member sign-in for on-site messaging. This signature is free and cannot move funds or approve anything.\n\nURI: https://rmcircle.team\nVersion: 1\nChain ID: 137\nNonce: ${nonce}\nIssued At: ${new Date().toISOString()}`; challenges.set(a, { message, exp: Date.now() + CHALLENGE_TTL }); return message; }