shadcn.io is not affiliated with official shadcn/ui
Wallet Connect Web3 Block for Ark UI
A grant app's open rounds page with its Connect wallet dialog shown open: six wallets or a QR code, a box that makes the request fail, and a Continue that ends in a connected demo account or a declined request with Retry.
Installation
Overview
Let people link a wallet before they apply, with this connect dialog for React with Ark UI. It opens from the Open grant rounds page of Grantbloom, a community grants app: 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 Connect wallet Button. The dialog has two Tabs. Wallets is a Radio Group of six services named in text (MetaMask, WalletConnect, Coinbase Wallet, Phantom, Rabby and Trust Wallet), each with a two-letter tile in place of a logo and the last-used one marked with a Badge; QR code shows a QR Code of a typed pairing string with three steps beside it. A Checkbox makes the request fail so the whole failure path can be walked. Continue, the only Shine Button, waits a moment and then replaces the body with its result: connected as the typed demo account, with its short address, or Request declined with a way to retry. Once connected, the header button shows the short address and the drawn rounds fill in their Apply pills. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog with the same tabs and the same state. For grants, DAOs, marketplaces and any app that asks for a wallet.
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 Connect wallet 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 ConnectFields component and share the block's state, so a wallet picked in the copy is still picked in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
What stays local, and how do I wire a real wallet?
All of it. Nothing calls window.ethereum, a wallet SDK or a network: Continue waits 800 ms in a timer and then shows the typed demo account (DEMO_ADDRESS), invented and never a real address. In your app replace that timer in go with your wallet library's connect call for the chosen wallet, show the returned address in place of DEMO_ADDRESS, and keep the Continue button busy until the promise settles.
What does the declined path show, and how do I map a real refusal?
Ticking Simulate a declined request makes Continue end in Request declined: the wallet's name, a sentence saying nothing was connected, and a Retry button that returns to the choice. In a real app map the wallet's rejection (an EIP-1193 provider answers a refused request with error code 4001) to this pane, and keep other failures, such as a wallet that is locked or not installed, as their own messages with their own next step.
Are the wallets and their tiles real?
The six services are real and named in text only, as any connect dialog does. The two-letter tiles are placeholders: drop in each wallet's official mark, under its brand terms, in the tile's icon slot. Never redraw a logo. The list is data (WALLETS), and the one marked Last used is also the one chosen when the dialog opens; build both from your connector configuration and the browser's saved choice.
What does the QR code encode?
A typed string, wc:grantbloom-demo, which is not a real pairing URI and pairs with nothing. In your app encode the pairing URI your WalletConnect session gives you, show a new code when it expires, and keep the wallet row for WalletConnect so keyboard users have a path that needs no camera. Choosing the QR tab chooses WalletConnect for Continue.
Is it accessible, and how does it look on a phone?
Yes. The real dialog is named by its title and described by its sentence, the radios and tabs use arrow keys, the result takes focus when it appears and a polite status message reports each step. The trigger is the button wrapped in DialogTrigger with asChild. On a phone the copy shown on load docks to the foot of the frame as a bottom sheet with its actions pinned, and the list scrolls above them.