-
Notifications
You must be signed in to change notification settings - Fork 0
Verify a Wallet Signed Transaction in Rails
pzupan edited this page Jul 5, 2026
·
1 revision
Server-side handling of the Wallet Standard signTransaction interface. A browser wallet (Phantom, Backpack, Solflare, …) signs a transaction and returns wire bytes; Rails decodes those bytes and verifies every Ed25519 signature without broadcasting — because Solana addresses are Ed25519 public keys, no additional key lookup is required.
# app/controllers/payments_controller.rb
require 'base64'
WS = Solana::Ruby::Kit::WalletStandard
TX = Solana::Ruby::Kit::Transactions
class PaymentsController < ApplicationController
# POST /payments/verify
# Body: { signed_transaction: "<base64 wire bytes from wallet>" }
def verify
wire_bytes = Base64.strict_decode64(params[:signed_transaction])
# 1. Decode the wallet output and verify every present signature.
# Raises WalletStandard::SIGNATURE_VERIFICATION_FAILED on any mismatch.
tx = WS.verify_signed_transaction!(wire_bytes)
# 2. Assert all required signers have signed (no nil slots remain).
TX.assert_fully_signed_transaction!(tx)
# 3. Confirm the expected wallet address actually signed.
wallet_address = Solana::Ruby::Kit::Addresses::Address.new(params[:wallet_address])
render json: { error: 'wrong signer' }, status: :unprocessable_entity and return \
unless WS.signed_by?(tx, wallet_address)
# 4. Optionally broadcast through your own RPC node instead of the browser.
rpc = Solana::Ruby::Kit.rpc_client
wire_b64 = Base64.strict_encode64(TX.wire_encode_transaction(tx))
sig = rpc.send_transaction(wire_b64, encoding: 'base64')
render json: { signature: sig.value }
rescue Solana::Ruby::Kit::SolanaError => e
render json: { error: e.message, code: e.code }, status: :unprocessable_entity
end
endUse these when building frontend metadata or documenting required wallet capabilities:
WS = Solana::Ruby::Kit::WalletStandard
WS::SIGN_TRANSACTION # => 'solana:signTransaction'
WS::SIGN_AND_SEND_TRANSACTION # => 'solana:signAndSendTransaction'
WS::SIGN_MESSAGE # => 'solana:signMessage'
WS::CONNECT # => 'standard:connect'See also: Build a Transaction for Browser Signing for the server-side counterpart that produces the unsigned transaction this controller verifies.