Demo - Magic Auth + Biconomy

Deployed app

  • Email OTP and SMS logins available
  • SMS login requires +1 to be prepended to phone number (e.g. +18008675309)
  • Login Credential and Wallet Address provided by Magic SDK
  • Current Caller and Current Number read from deployed Goerli Smart Contract
  • Submit a "lucky number" to update number and caller in SC, Biconomy SDK used to subsidize gas fees

Magic Auth Client SDK

Intro

Magic Auth Applications in the Wild

Instantiating Magic

Authentication

User Module

Whitelabel Features

Session Management & Security Features

Frequently Asked Questions


Prerequisites

  1. Create a Magic developer account at https://magic.link/
  2. Create a Magic Auth application
  3. Retain the application's publishable API key

Constructing Magic Instance

Configure and construct your Magic SDK instance

  • Confirm API key is retrieved from Magic Auth application created in Magic dashboard.
  • 'mainnet' or 'goerli' can be passed into the network key to utilize Magic's node infrastructure. These map to 2 unique set of addresses.
  • If only API key is passed, Ethereum mainnet will be set by default.
  • A custom node configuration can also be passed into the network key. Example here
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY', {
    network: 'mainnet' // Ethereum Mainnet
})

Initializing Provider

Ethers.js

import { Magic } from 'magic-sdk';
import { ethers } from 'ethers';

const magicClient = new Magic('API_KEY');
const provider = new ethers.providers.Web3Provider(magicClient.rpcProvider);

Web3.js

import { Magic } from 'magic-sdk';
import Web3 from 'web3';

const magicClient = new Magic('API_KEY');
const web3 = new Web3(magicClient.rpcProvider);

Configuring other Blockchains

Magic supports the following blockchains outright and can support all EVM chains. Note some chains require use of a Magic extension NPM package.

Authentication - Email OTP

loginWithEmailOTP method is accessible on the magic instance via the Auth Module.

  • This promise resolves upon authentication request success to a Decentralized ID token with a default 15-minute lifespan.
  • UI customization is possible by passing in showUI: false, more information on how to implement this to come.
  • You can test this login on the deployed app
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  const didToken = await magicClient.auth.loginWithEmailOTP({ 
    email: 'hello@example.com',
    showUI: false, // optional, defaults to true
  });
} catch {
  // Handle errors
}

Authentication - Phone SMS OTP

loginWithSMS method is accessible on the magic instance via the Auth Module.

  • This promise resolves upon authentication request success to a Decentralized ID token with a default 15-minute lifespan.
  • UI customization is not possible yet but could be setup to accept showUI: false to make this happen.
  • The phone number must be formatted to E.164 standard.
  • Magic currently blocks SMS to certain country codes on the OFAC list or deemed high security risk. List of blocked country codes
  • You can test this login on the deployed app
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  await magicClient.auth.loginWithSMS({ 
    phoneNumber: '+1-800-867-5309',
  });
} catch {
  // Handle errors
}

Authentication - Social Logins

Social Logins work as an extension to Magic SDK. Steps to install and use the OAuthExtension can be found in our docs and detailed below.

import { Magic } from 'magic-sdk';
import { OAuthExtension } from '@magic-ext/oauth';

const magicClient = new Magic('YOUR_API_KEY', {
  network: 'mainnet',
  extensions: [new OAuthExtension()],
});
  • Start the OAuth 2.0 login flow.
await magicClient.oauth.loginWithRedirect({
  provider: 'google' // or 'facebook', 'apple', 'github', etc
  redirectURI: 'https://your-app.com/your/oauth/callback',
  scope: ['user:email'], // optional
});
  • Upon the redirect back to your application, get the final OAuth 2.0 result.
const result = await magicClient.oauth.getRedirectResult();

// Result has the following interface
interface OAuthRedirectResult {
  oauth: {
    provider: string;
    scope: string[];
    accessToken: string;
    userHandle: string;

    // `userInfo` contains the OpenID Connect profile information
    // about the user. The schema of this object should match the
    // OpenID spec, except that fields are `camelCased` instead
    // of `snake_cased`.
    // The presence of some fields may differ depending on the
    // specific OAuth provider and the user's own privacy settings.
    // See: https://openid.net/specs/openid-connect-basic-1_0.html#StandardClaims

    userInfo: ...;
  };

  magic: {
    idToken: string;
    userMetadata: MagicUserMetadata;
  };
}

Update Email

updateEmail method is available to call on an email authenticated user via the User Module.

  • This promise resolves upon successful completion of update email flow to a true boolean.
  • UI customization is possible by passing in showUI: false and events handling.
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  await magicClient.user.updateEmail({ 
    email: 'new_user_email@example.com',
    showUI: false, // optional, defaults to true 
  });
} catch {
  // Handle errors
}

Update Phone Number

updatePhoneNumber method is available to call on a phone authenticated user via the User Module.

  • This promise resolves upon successful completion of update phone number flow to a true boolean.
  • UI customization is not possible yet but could be setup to accept showUI: false along with events to make this happen.
  • However, it is unlikely a user will have access to both phone numbers simultaneously to complete this flow.
  • Test behavior in codesandbox demo
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  await magicClient.user.updatePhoneNumber();
} catch {
  // Handle errors
}

Get ID Token

getIdToken method is available to call on an authenticated user via the User Module.

  • This promise resolves to a Decentralized ID token.
  • The default lifespan of this token is 900 seconds (15 minutes).
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
    const didToken = await magicClient.user.getIdToken({
        lifespan: 3600, // lifespan of token set to 1 hour
    })
} catch {
    // Handle errors
}

Get Metadata

getMetadata method is available to call on an authenticated user via the User Module.

  • This promise resolves to an object containing the issuer (unique user ID), email address, phone number, and cryptographic public address of the authenticated user.
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  const metadata = await magicClient.user.getMetadata();
} catch {
  // Handle errors
}

Check if user is currently logged in

isLoggedIn method is available to call on an authenticated user via the User Module.

  • This promise resolves to a true or false boolean after checking if the user is currently logged in to the Magic SDK.
import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  const isUserLoggedIn = await magicClient.user.isLoggedIn();
  console.log(isUserLoggedIn);  // true or false
} catch {
  // Handle errors
}

Logout

logout method is available to call on an authenticated user via the User Module.

import { Magic } from 'magic-sdk';

const magicClient = new Magic('API_KEY');

try {
  await magicClient.user.logout();
  console.log(await magicClient.user.isLoggedIn());  // false
} catch {
  // Handle errors
}

Magic Admin SDK

NodeJS API Reference

  • DID tokens resolved from authentication methods or getIdToken can be used to protect your server.
  • Users can be logged out server-side and information you may not want to pass from client to server may be extracted from the DID token in your backend.

FAQs