Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Message Sign Web3 Block for React

A notes app's wallet sign-in request shown open: the site, account, statement, nonce and times as a list over the exact text, a sample signature with nothing signed, and a Verify tab that says how many characters changed.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Make a signing request readable, and show why a signature belongs to its text, with this sign-in dialog for React with Base UI. It opens from the Sign in to Inksig Notes page, a notes app with wallet sign-in: the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, and its header holds an outline Sign in with wallet Button. The dialog has two Tabs. Sign lays the request out as a list (site, account, statement, nonce, issued at, expires at) over the exact text that would be signed, in mono type; Sign message, the only Shine Button, waits a moment and shows a typed sample signature labelled Nothing was signed by a key. Verify holds the same text in a Textarea with the signature: Verify compares the text with the original and says Matches or Does not match with the number of characters changed. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog with the same state. For wallet sign-in, session proofs and any app that asks for a signature.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused. The header button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same SignFields component and share the block's state. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element.

What is the text, and why show it?

It follows the shape of a sign-in message (EIP-4361): the site wants you to sign in with your account, a statement, the URI, version, chain, a nonce and two times. Showing the exact text, not only a summary, is the point: a wallet signs those characters, and the list above them is the same facts in a form people can read.

What does Verify really do?

It compares the text in the box with the original, character by character, and counts the positions that differ plus any characters added or removed. Change one letter and it says 1 character changed. It does not check the signature with a key, because the signature is a typed sample: in your app recover the signer from the signature and the text on your server and compare it with the claimed account.

What stays local, and how do I wire a wallet?

All of it. No wallet is asked and no key is used: Sign message waits 800 ms in a timer and shows SAMPLE_SIGNATURE, a typed string. In your app build the message on the server with a fresh nonce, send it to the wallet's personal-sign method in go, and verify the result on the server before you start a session.

Is it accessible from the keyboard?

Yes. The real dialog traps focus and returns it to the header button; Escape closes either copy. The tabs are a real tab list, the textarea has a label, and one polite status reports the signature and each verdict. The sample signature takes focus when it appears.

How does it look on a phone?

The in-place dialog docks to the foot of its frame and scrolls its body while Cancel and the Shine Button stay pinned; the real dialog uses the catalog's phone layout.