TryMellon
Navigation

SIWE Login (EIP-4361)

Sign-In with Ethereum — use wallet signatures as identity proof for passwordless auth.

SIWE Login (EIP-4361)

TryMellon accepts Ethereum wallet signatures as identity proof via the EIP-4361 standard. Users sign a structured message with their wallet, and TryMellon verifies the signature, creates or matches a user, and returns a session token. No password, no email required.

Flow overview

  1. Request nonce — your app calls client.siwe.getNonce() to get a one-time challenge nonce from TryMellon.
  2. Construct message — build an EIP-4361 compliant message including the nonce, domain, chain ID, and wallet address.
  3. Sign — the user signs the message with their Ethereum wallet (MetaMask, WalletConnect, etc.).
  4. Verify — send the message and signature to client.siwe.verify(). TryMellon validates the signature, checks the nonce, and returns a session token.
  5. Session established — the wallet address is linked as an identifier. The user is authenticated.

SDK + wagmi example

import { useSignMessage } from 'wagmi';

// 1. Get nonce
const { nonce } = await client.siwe.getNonce();

// 2. Construct EIP-4361 message
const message = `trymellonauth.com wants you to sign in with your Ethereum account:
${address}

Sign in to TryMellon

URI: https://trymellonauth.com
Version: 1
Chain ID: 1
Nonce: ${nonce}
Issued At: ${new Date().toISOString()}`;

// 3. Sign with wallet
const signature = await signMessageAsync({ message });

// 4. Verify and get session
const result = await client.siwe.verify({ message, signature });
// result.value.sessionToken, result.value.walletAddress

If the wallet address is not yet associated with a user, TryMellon creates an anonymous user and links the address automatically. If the address already exists, the existing user is authenticated.

Chain ID configuration

Each application has an allowed_chain_ids setting that controls which Ethereum networks are accepted. The default is mainnet (1). Configure additional chain IDs (e.g. 137 for Polygon, 42161 for Arbitrum) in your application settings. Messages signed with a chain ID not in the allowlist are rejected with SIWE_CHAIN_NOT_ALLOWED.

API reference

EndpointMethodDescription
/v1/siwe/noncePOSTGenerate a one-time nonce. TTL: 5 minutes.
/v1/siwe/verifyPOSTVerify EIP-4361 message + signature. Returns session token.

Error codes

CodeDescription
SIWE_NONCE_EXPIREDThe nonce TTL (5 minutes) has elapsed. Request a new one.
SIWE_SIGNATURE_INVALIDThe signature does not match the message or the recovered address.
SIWE_CHAIN_NOT_ALLOWEDThe chainId in the message is not in the application’s allowlist.
SIWE_DOMAIN_MISMATCHThe domain in the message does not match the application’s configured origin.