Skip to content

Build a Transaction for Browser Signing

pzupan edited this page Jul 5, 2026 · 1 revision

Build a Transaction Server-Side, Send to the Browser for Signing, Then Verify

Build an unsigned transaction on your Rails server, hand its wire bytes to the browser for the user's wallet to sign, then verify the signed result when it comes back.

Kit = Solana::Ruby::Kit
WS  = Kit::WalletStandard

# ── Server: build and serialise the unsigned transaction ─────────────────────
fee_payer   = Kit::Addresses::Address.new(params[:wallet_address])
rpc         = Kit.rpc_client
latest      = rpc.get_latest_blockhash
constraint  = Kit::TransactionMessages::BlockhashLifetimeConstraint.new(
  blockhash:               latest['blockhash'],
  last_valid_block_height: latest['lastValidBlockHeight']
)

message = Kit::Functional.pipe(
  Kit::TransactionMessages.create_transaction_message(version: :legacy),
  ->(m) { Kit::TransactionMessages.set_fee_payer(fee_payer, m) },
  ->(m) { Kit::TransactionMessages.set_blockhash_lifetime(constraint, m) }
)

compiled        = Kit::Transactions.compile_transaction_message(message)
unsigned_wire   = Kit::Transactions.wire_encode_transaction(compiled)
unsigned_base64 = Base64.strict_encode64(unsigned_wire)

# → send unsigned_base64 to the browser
# → browser calls: wallet.features['solana:signTransaction'].signTransaction(tx)
# → browser POSTs { signed_transaction: "<base64>" } back to /payments/verify

# ── Server: receive and verify the signed transaction ────────────────────────
tx = WS.verify_signed_transaction!(Base64.strict_decode64(params[:signed_transaction]))
Kit::Transactions.assert_fully_signed_transaction!(tx)

See also: Verify a Wallet-Signed Transaction in Rails for a fuller version of the verification endpoint, including error handling and confirming the expected signer.


← Back to guides

Clone this wiki locally