We've updated our Terms of Service. By continuing to use our services, you agree to the updated Terms.

Magic Links

Magic Links

#Overview

Authenticate a user passwordlessly using a "magic link" sent to the specified user's email address.

#Compatibility

note

Only available with Dedicated Wallet.

Magic link SDK methods are available via the Web client-side SDK. These methods are deprecated on all mobile SDKs.

#Usage

The loginWithMagicLink function sends an authentication request to the user. The resolved value is a Decentralized ID token with a default 15-minute lifespan. Refer to the API documentation for information on how to install and initialize Magic.

Javascript
01import { Magic } from 'magic-sdk';
02
03// must use a Dedicated Wallet API Key
04const magic = new Magic('API_KEY');
05
06// log in a user by their email
07try {
08  await magic.auth.loginWithMagicLink({ email: 'hello@example.com' });
09} catch {
10  // Handle errors if required!
11}
12
13// log in a user by their email, without showing an out-of-the box UI.
14try {
15  await magic.auth.loginWithMagicLink({ email: 'hello@example.com', showUI: false });
16} catch {
17  // Handle errors if required!
18}

#Error Handling

To achieve a fully white-labeled experience, you will need to implement some custom error handling according to your UI needs. Here's a short example to illustrate how errors can be caught and identified by their code:

Javascript
01import { Magic, RPCError, RPCErrorCode } from 'magic-sdk';
02
03const magic = new Magic('API_KEY');
04
05try {
06  await magic.auth.loginWithMagicLink({ email: 'hello@example.com', showUI: false });
07} catch (err) {
08  if (err instanceof RPCError) {
09    switch (err.code) {
10      case RPCErrorCode.MagicLinkFailedVerification:
11      case RPCErrorCode.MagicLinkExpired:
12      case RPCErrorCode.MagicLinkRateLimited:
13      case RPCErrorCode.UserAlreadyLoggedIn:
14        // Handle errors accordingly :)
15        break;
16    }
17  }
18}

#Test Mode

Magic's client-side Web SDK provides Test Mode as a quick way to test your integration locally by asserting specific error codes or bypassing the magic link flow completely. Test Mode only works when logging in with Magic links. As the name suggests, this is for testing. Users and wallets created in test mode should not be treated as secure or production-ready. Data surfaced while in Test Mode should not be considered secure, accurate, or production-ready.

To enable Test Mode, provide testMode: true to the SDK constructor.

Javascript
01import { Magic } from 'magic-sdk';
02
03const magic = new Magic('YOUR_API_KEY', {  
04  testMode: true,
05});

With Test Mode enabled, you can assert the desired behavior through the email address you provide to loginWithMagicLink:

  • To assert a success state, use test+success@magic.link
  • To assert a failed state, use test+fail@magic.link
  • To assert a case-specific failed state, provide an RPC error code with test+fail_with_{RPC_ERROR_CODE}@magic.link
Succeed
Fail
Fail With Error
01magic.auth.loginWithMagicLink({ email: 'test+success@magic.link' });

Web3 and blockchain use-cases sometimes require access to deterministic key-pairs so that testnet funds are available at runtime. To enable this, users can explicitly specify the key-pair associated to a test user with the following email: test+success_with_{PUBLIC_KEY:PRIVATE_KEY}@magic.link.

warning

The key-pair provided in the email address during test mode is not protected by Magic's delegated key management system. These keys should not be considered secure or private. Never store mainnet funds with these keys!

In practice, you can assert a successful login with:

Javascript
01magic.auth.loginWithMagicLink({  
02  email:
03    'test+success_with_{0x89A3983da27fF0eFCF901F74C4df84e0450A17B7:0x19de850af732e9e5745915162d707d6d8cf013ce7b2862e93081b0c8883bdfae}@magic.link',
04});

In the example above, we encode an Ethereum-compatible key-pair in the test user's email address. The login method will immediately resolve with a success state, bypassing the passwordless flow and enabling Ethereum or EVM-compatible signing methods to work seamlessly with your existing Web3 code.

#Security Notes

#IP Address Verification

Magic’s top priority is ensuring secure authentication for your end users in your app. Magic recently implemented and added a layer of security for all login flows with email magic link. Specifically, the change ensures that the IP address associated with the device that a user enters their email address on matches the IP address associated with the device that clicks the magic link. If the IP address does not match, the following error is shown to the user when they click on the magic link.

In addition, for desktop web users, magic links will now authenticate the session clicked from a user’s email. This means that the session or browser tab where the user first enters their email address will no longer sign the user in. This will help ensure that users remain secure in an evolving threat environment, while still delivering a smooth sign-in experience. For customers using the web SDK, there are no code changes required.

#Mobile Support

Magic Links are no longer supported on mobile as of June 20th, 2023. We advise customers to switch over to Email OTP instead. Please refer to the documentation below on how to implement OTP on mobile.

How to add OTP email login on iOS

How to add OTP email login on Android

How to add OTP email login on Flutter

How to add OTP email login on Unity

How to add OTP email login in React Native

#Resources