Magic's authentication can enable passwordless Web3 onboarding (no seed phrases) using multiple configurable methods. Each method either creates an account address for the user (non-custodial) or utilizes an existing account address. This is handled completely by Magic with out-of-the-box UI, with no lift from the integrating dApp. Currently the supported authentication methods are:

  • Google One Tap
  • Email one-time passcode
  • Third-party wallets

#Use Cases

  • Allow your users to log in and/or sign up to your dapp using their preferred authentication method and gain access to their public wallet address on the network you are connected to.
  • Optionally, you can also collect a signed token for wallet address verification and skip the need to explictly request a personal signature which would prompt an additional screen.

#Authentication Methods

#Email One-Time Passcode

If a user chooses to authenticate through their email, they will recieve a unique code to their email that's generated per attempt and be required to enter it to authenticate. OTPs for email provides a simple and effective way to increase security and ensure the safety of user assets.

#Google One-Tap

One-tap login with Google provides effortless authentication for your users that have Google Accounts. Utilizing the 'One Tap' sign-up API, users can easily create a secure, passwordless account with just one tap, all within the context of your app. Magic handles all of the authentication flow with Google with no setup for you dapp required.


User's that sign using the email OTP method and/or Google One-Tap will resolve to the same address as long as their gmail address is a personal account with the ending and is automatically linked. Auto-linking is not supported for custom G Suite/Google Workspace domains (such as [email protected]).

#Third-Party Wallets

Universal Wallet allows users to connect with existing third-party wallets (e.g. MetaMask). When a user is asked for a public address, they can select a supported third-party wallet to use from the Universal Wallet login view.

The SDK will remember this choice on the client and all further RPC calls will be forwarded to the selected wallet. This selection can be reset by calling the disconnect() SDK method.

Currently, MetaMask and Coinbase Wallet are disabled by default for all Universal Wallet apps. Visibility of third-party wallets can be toggled on or off via the Wallet Providers page in the Magic developer dashboard.

If you are looking to bring your own authentication provider, see our enterprise solutions for Magic Wallet Services.

#Device Registration

Device Registration is a security feature that helps protect end-users from sophisticated phishing techniques. When a returning user initiates an email login from an unrecognized device or browser, they’ll receive an email to review and confirm the login request.

Device Registration does not apply to new user signups, Google One Tap logins, or third-party wallet users. For an optimal user experience, please be sure to use the latest version of Magic's web SDK (v19.3.1 or higher).

You can learn more about Magic’s commitment to security in this blog post.

#UX Overview

If a returning user attempts to log in via email from an unrecognized device or browser, they will be shown a prompt to register their device. The user will receive a themed email containing information about the login request, with a button to approve the login.

Clicking the “Approve this login” button navigates users to a secure domain owned by Magic, which compares the user’s current device profile to the device profile used to initiate the login request.

If the profiles match, the user’s new device will be registered automatically. They can then return to your app and continue with their standard login process.

However, if the confirming device profile does not match the device profile used to initiate a login request, Magic will display a secondary confirmation with information about login request. Users can then choose to approve or reject the login. This will most commonly occur for end-users that initiate a login on one device (laptop) and check their email on a different device (phone).


Magic offers a utility method connectWithUI which will ask permission from your user's selected authentication method to connect to your dapp.


01import { Magic } from "magic-sdk"
02import Web3 from 'web3';
04const magic = new Magic('YOUR_API_KEY', { 
05  network: "goerli",
08const provider = await magic.wallet.getProvider();
10const web3 = new Web3(provider);
12const accounts = await magic.wallet.connectWithUI();

Login with wallet verification

⁠👉 Play with a demo

If you require a signature from the wallet’s private keys on authentication (same as a personal sign) in order to validate the ownership of the wallet address, you can do this by catching the following event after a login occurs as shown below. This requires the domain you are on is whitelisted on the domain allowlist and verify the token using our Magic Admin SDK's token module.

If you would like to verify the ownership of your user's wallet address in a single login step, you can optionally listen for the id-token-created event that's fired after connectWithUI is called. The token will only be emitted for email or Google logins, and not for any 3rd party wallet connections.

01/* On the front end, collect the token as the user signs in */
02await ⁠magic.wallet.connectWithUI().on('id-token-created', (params) => {
03 const { idToken } = params;
04 console.log(idToken);
05 // send to your resource server for validation with the Magic Admin SDK
06 // ...
09/* Alternative to the above, if you are using a third party wallet provider or tool and wish to recieve the event, you can do the following. */
10await magic.rpcProvider.enable().on('id-token-created', (params) => {
11 const { idToken } = params;
12 console.log(idToken);
13 // send to your resource server for validation with the Magic Admin SDK
14 // ...
17/* On your own resource server */
18const { MagicAdmin } = require('@magic-sdk/admin');
19const magicAdmin = await MagicAdmin.init('YOUR_SECRET_API_KEY');
22/* In some context where the ID token from the FE is passed in */
23app.get('/login', async (req: any, res: any) => {
24  /*
25    Assumes DIDToken was passed in the Authorization header
26    in the standard `Bearer {token}` format.
27   */
28  const DIDToken = req.headers.authorization.substring(7);
29  magicAdmin.token.validate(DIDToken); // returns void, throws error if invalid
30  /* User is logged in. Set cookies! */

Security Notes:

  • The token provided is only valid for 90 seconds after the user has logged in.
  • In the Admin SDK, the user’s token is validated against your client’s unique identifier to ensure the signature occurred on your app’s site.

⁠ ⁠Alternatively, you can also explictly request a personal signature from the user with an additional confirmation screen.


  • You can configure which authentication methods and/or third party wallets are supported by your dapp in your Dashboard settings.
  • See how to brand this experience with your own logo and colors in the customization section.