Let users bring the wallet they already have. No SDK required.
A hosted page you point users at: 600+ EVM and Solana wallets, on web, iOS, Android and Flutter. Redirect back with the address, or go headless to sign messages and transactions. You never hold keys.
Connect a wallet
Pick a wallet to continue
Hosted connect page
Web guide ↗What this page returns
The hosted flow reads the user's public wallet address and hands it back to you - it requests no signature. That proves the user can present an address, not that they control it. To prove control, or to sign a transaction, use the headless engine on iOS, Android or Flutter.
Link to the connect page
Open this page in the user's browser (or a webview) with the following query parameters:
redirect_uriURLrequiredWhere we send the user back after they connect. Must be an http(s) URL you control. Alias: redirect_url.
noncestringoptionalAn opaque value we echo back unchanged so you can correlate the response to the request. If you don't send one, we don't return one.
1https://connect.dynamicauth.com/2 ?redirect_uri=https://your-app.com/wallet/callback3 &nonce=a1b2c3d4e5
Receive the result
After a successful connection we redirect the browser to your redirect_uri with these query parameters appended:
addressstringoptionalThe connected wallet's public address.
chain"evm" | "solana"optionalWhich chain family the address belongs to.
walletNamestringoptionalDisplay name of the wallet (e.g. MetaMask).
walletImageURLoptionalIcon URL for the wallet (empty for a manually-entered address).
noncestringoptionalThe exact nonce you passed in, present only if you sent one.
1https://your-app.com/wallet/callback2 ?address=0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b3 &chain=evm4 &walletName=MetaMask5 &walletImage=https://.../metamask.svg6 &nonce=a1b2c3d4e5
Read it on your callback
On your redirect_uri, read the params off the URL:
1const params = new URLSearchParams(location.search);23const address = params.get("address"); // "0x1a2b…9a0b"4const chain = params.get("chain"); // "evm" | "solana"5const nonce = params.get("nonce"); // echoed back, or null67// Verify `nonce` matches the one you issued, then continue.
An address alone proves the user can present it, not that they control it. For proof of ownership, add a sign-in step - or use the headless engine, where the wallet signs. In production, set NEXT_PUBLIC_CONNECT_ALLOWED_REDIRECT_HOSTS to the hosts you accept: an unrestricted redirect_uri is an open redirect.