Skip to content
FidmosDocumentation

Wallet login (SIWE)

The third sign-in method is a wallet signature following the SIWE (Sign-In with Ethereum) standard. This page describes what happens inside the Fidmos window when a person picks a wallet: which requests go out and what errors can occur.

  1. The window gets a one-time nonce — POST /api/v1/embed/siwe/nonce:

    POSThttps://id.fidmos.com/api/v1/embed/siwe/nonce
    Content-Type: application/json
    
    { "flow_id": "..." }
    { "nonce": "..." }
  2. The person signs a message. The window assembles a SIWE message with this nonce and asks the wallet to sign it — the confirmation happens in the wallet itself.

  3. The window verifies the signature — POST /api/v1/embed/siwe/verify:

    POSThttps://id.fidmos.com/api/v1/embed/siwe/verify
    Content-Type: application/json
    
    { "flow_id": "...", "message": "...", "signature": "0x..." }

    The server recovers the address from the signature, checks the message’s domain and timing and burns the nonce. If the nonce did not match — nonce_mismatch; if the message or signature check failed — a code from the “Signature verification” table below.

  4. The identity is linked to a user. If the wallet is already linked, the flow is ready for completion ({ "status": "authenticated", "completion_handle": "..." }); if not linked yet, the window gets identity_unlinked and creates a new user (POST /api/v1/embed/identity/create with the same flow_id).

  5. The window completes sign-in — it exchanges completion_handle for an authorization code (POST /api/v1/embed/complete) and hands it to your page via onSuccess. Next — the usual code-for-token exchange.

All error responses come in the envelope { "error": "<code>" }. The code meanings and the general breakdown are in the error reference.

Code When
nonce_mismatch the nonce in the message did not match the issued one
no_pending_identity there is no pending sign-in method to create a user from
identity_taken this address was linked to another user in the meantime
invalid_completion the flow completion failed (HTTP 409)
authorization_failed the window could not issue an authorization code
flow_expired the flow was not found or has expired
parent_origin_mismatch the request came from a foreign origin

If the SIWE message or signature check fails, verify returns one of these codes (the partner does not branch on them — for the window it is the common outcome “signature not accepted”):

Code When
malformed_message the message did not parse as the SIWE format
message_too_long the message is longer than allowed
bad_signature the signature is in the wrong format or cannot be recovered
signature_mismatch the signature does not match the address in the message
malleable_signature the signature is in a “malleable” form (low-S violated)
unsupported_version the SIWE version is not 1
unsupported_chain the network is not Ethereum mainnet
origin_mismatch the message’s uri is not among the allowed origins
domain_mismatch the message’s domain did not match its uri
stale_message the timestamp is outside the allowed window
expired_message the message’s Expiration Time has been reached
not_yet_valid the message’s Not Before has not been reached yet