🦊MetaMask Authentication

Sign in with MetaMask (SIWE) using OmniAuth OpenID Connect

This guide adds “Sign in with MetaMask” (Sign-In with Ethereum, SIWE) to your Lightning Rails app using Devise + OmniAuth OpenID Connect. It keeps your regular Devise auth and adds a wallet-based login. No private keys ever touch your server—users only sign a message.

You’ll:

  • Install and configure OmniAuth OIDC

  • Register an OIDC client for development and production

  • Add a Devise callback controller

  • Store the user’s wallet address and show it in the navbar

1) Add gems


2) Add User fields

Generate and run the migration to store the wallet address and a timestamp:

If you prefer the exact file from the PR:


3) Make your Devise model omniauthable

We use the provider name :openid_connect to match routes and callback.


4) OmniAuth configuration

Create the OmniAuth initializer and allow POST/GET (GET helps during local testing; you can lock to POST later).


5) Devise routes

This generates:

  • Authorize: /users/auth/openid_connect

  • Callback: /users/auth/openid_connect/callback


6) OmniAuth callbacks controller

Generate the controller:

Replace its content with:


7) Add the “Sign in with MetaMask” button

On your Devise sessions page (Lightning Rails’ sign-in):

OmniAuth 2 prefers POST for the authorize request; using button_to handles that.


8) Show the wallet in the navbar (optional)

Helper:

Navbar snippet:


9) Environment variables (.env)

Lightning Rails already loads .env. Add these:

Important: the redirect path must match your provider name :openid_connect. If you change the provider name to :siwe, use /users/auth/siwe/callback and update all references.


10) Register your OIDC client

You need a client per environment (dev and prod). Most SIWE OIDC issuers support dynamic registration.

Development registration (example)

You’ll receive JSON with client_id and client_secret. Put them in your dev .env.

Production registration

Use your production domain:

Add the prod values to your production environment (e.g., Render/Heroku/Fly secrets) as:

If you use another issuer (e.g., https://oidc.signinwithethereum.org/), the steps are identical—just change SIWE_ISSUER and the registration URL.


11) Sanity checks

After you’ve set everything:

You should see:

Common fixes:

  • Routing error for /auth/...Your Devise routes live under /users/auth/.... Make sure the registered redirect URI matches exactly.

  • “Mapping omniauth_callbacks on a resource that is not omniauthable”: ensure :omniauthable and omniauth_providers: [:openid_connect] are in User.

  • Path helper not found: ensure the provider name matches in the initializer, model, controller method, and the button helper.


12) What you have now

  • Users can sign in with MetaMask (SIWE) via a trusted OIDC provider.

  • You store their wallet address on the users table.

  • You can display it in the UI and later fetch balances/holdings.

From here, you can add:

  • A “Link/Unlink wallet” page

  • ETH balance fetch on the dashboard

  • Parallel Solana login (Phantom) if you want multi-chain auth

That’s it—SIWE is live in your Lightning Rails app.

Last updated

Was this helpful?