SolRengine

Add Solana Wallet Login to Rails in 5 Minutes

One gem, one generator, one Stimulus controller. Add Sign In With Solana to any Rails 8 app with solrengine-auth.

· moviendo.me

No passwords. No OAuth. No email verification. Just a wallet signature.

This tutorial adds Sign In With Solana (SIWS) to a Rails 8 app using the solrengine-auth gem. Users connect Phantom, Solflare, or Backpack, sign a message, and they’re in.

Setup

Add the gem and install:

bundle add solrengine-auth
rails generate solrengine:auth:install
rails db:prepare

The generator creates: - A User model with wallet_address as the identity field - A SessionsController with nonce, verify, and destroy actions - Auth routes mounted at /auth - An initializer with sensible defaults

JavaScript

Install the wallet utilities:

yarn add @solrengine/wallet-utils @solana/kit @wallet-standard/app @solana/wallet-standard-features

Register the shared wallet controller:

// app/javascript/controllers/index.js
import { application } from "./application"
import { WalletController } from "@solrengine/wallet-utils/controllers"
application.register("wallet", WalletController)

That’s it for JavaScript. The WalletController handles wallet discovery, legacy provider compatibility (Chrome popup workaround), SIWS message signing, and server verification.

The Login Page

<div data-controller="wallet"
     data-wallet-nonce-url-value="<%= auth_nonce_path %>"
     data-wallet-verify-url-value="<%= auth_verify_path %>"
     data-wallet-dashboard-url-value="<%= dashboard_path %>">

  <div data-wallet-target="walletList" class="hidden"></div>
  <div data-wallet-target="status" class="hidden"></div>

  <button data-wallet-target="connectBtn"
          data-action="click->wallet#authenticate">
    Connect Wallet
  </button>

  <div data-wallet-target="signing" class="hidden">
    Approve the sign-in request in your wallet...
  </div>
</div>

When the user clicks “Connect Wallet”:

  1. The controller discovers installed wallets via Wallet Standard
  2. Connects to the wallet (legacy provider first for Chrome compatibility)
  3. Requests a nonce from your Rails server
  4. The wallet signs the SIWS challenge message
  5. Sends the signature to Rails for Ed25519 verification
  6. On success, redirects to the dashboard

Protect Your Pages

The generator adds helpers to ApplicationController:

class DashboardController < ApplicationController
  before_action :authenticate!

  def show
    @wallet = current_user.wallet_address
  end
end

current_user returns the authenticated user. logged_in? checks if a session exists. authenticate! redirects unauthenticated visitors to login.

How It Works

The gem uses Ed25519 signature verification — the same cryptography Solana uses for transactions.

Browser                     Rails                      Wallet
  │                           │                           │
  ├── GET /auth/nonce ──────► │                           │
  │   ?wallet_address=7xK... │── generate nonce          │
  │ ◄── { message: "..." } ──┤                           │
  │                           │                           │
  ├── signMessage ────────────────────────────────────────►│
  │ ◄── signature ────────────────────────────────────────┤
  │                           │                           │
  ├── POST /auth/verify ────► │                           │
  │   { wallet, message, sig }│── Ed25519.verify          │
  │                           │── create session          │
  │ ◄── 200 OK ──────────────┤                           │
  │                           │                           │
  ├── redirect /dashboard     │                           │

The nonce rotates after every verification — replay attacks are impossible.

Configuration

# config/initializers/solrengine_auth.rb
Solrengine::Auth.configure do |config|
  config.domain = ENV.fetch("APP_DOMAIN", "localhost")
  config.nonce_ttl = 5.minutes
  config.after_sign_in_path = "/dashboard"
  config.after_sign_out_path = "/"
end

Compare This to Next.js

In a Next.js Solana app, wallet authentication requires @solana/wallet-adapter-base, @solana/wallet-adapter-react, @solana/wallet-adapter-react-ui, @solana/wallet-adapter-wallets, a React context provider wrapping your app, state management for connection status, and a separate API route for nonce/verify.

With SolRengine: one gem, one generator, one Stimulus controller.

What’s Next

Once users are authenticated, you can:

  • Show their token portfolio with solrengine-tokens (Jupiter metadata + USD prices)
  • Let them send SOL with solrengine-transactions (confirmation tracking via Solid Queue)
  • Push real-time updates with solrengine-realtime (Solana WebSocket + Turbo Streams)
  • Interact with Anchor programs with solrengine-programs (IDL parsing + Borsh encoding)

Or install everything at once:

bundle add solrengine
rails generate solrengine:install

See it live at wallet.solrengine.org or browse the source at github.com/solrengine/wallet-train.

← All posts