Skip to main content
BETA
HomeIntegration BuilderAPI ReferenceGuides
View Mirror World on Github
Join the Discord server

How to Authenticate With The Mirror World Smart SDK

By Jonathan Bakebwa

In this tutorial, we shall be covering how to authenticate your users with the Mirror World SDK. This specific tutorial will be focusing on JavaScript for the front end.

We shall be creating more tutorials for back end authentication soon! If you are looking for other frameworks, please see the integration guides for Android, Unity, iOS and Rust.

Getting Started

Create a Mirror World Project

The first step to building with the Mirror World SDK is to create a project and get it's API Key. Please follow the guide on creating your first Mirror World Project.

If you have an API Key, you can skip the step.

Install dependencies


# with pnpm
pnpm add @usemirrorworld/web3.js
# or with NPM
npm install @usemirrorworld/web3.js
# or with Yarn
yarn add @usemirrorworld/web3.js

See Android Installation Guide and Unity Installation Guide for Android and Unity respectively

Project Setup

Create a Next JS app by running this command in your terminal


yarn create next-app mirrorworld-js
# or
npx create-next-app@latest mirrorworld-js

Install the Mirror World Smart SDK

Next, let's make sure we have the Mirror World Smart SDK installed in our project. This will enable us to run the following command in your project's root directory, in the terminal:


yarn add @usemirrorworld/web3.js

Implementing Login

Let's implement login functionality into our app using the Mirror World Smart SDK. To use the SDK, we'll need to create a new instance of the SDK.

Edit your index.tsx file to look like this

📁 pages/index.tsx


import { MirrorWorld, Solana } from "@usemirrorworld/web3.js"
import styles from "../styles/Home.module.css"
export default function Home() {
const mirrorworld = new MirrorWorld({
apiKey: "YOUR_SECRET_API_KEY", // Replace this with the API Key for your project
chainConfig: Solana("mainnet-beta"),
})
return <div className={styles.container}></div>
}

Next, we're going to create a function that logs the user in, and a button to trigger that function.

Update your index.tsx file to look like this


import { useState } from "react"
import { MirrorWorld, Solana } from "@usemirrorworld/web3.js"
import styles from "../styles/Home.module.css"
export default function Home() {
const [user, setUser] = useState()
const mirrorworld = new MirrorWorld({
apiKey: "YOUR_SECRET_API_KEY", // Replace this with the API Key for your project
chainConfig: Solana("mainnet-beta"),
})
async function login() {
const { user } = await mirrorworld.login()
setUser(user)
}
return (
<div className={styles.container}>
<main className={styles.main}>
<button onClick={login}>Login to Mirror World</button>
</main>
</div>
)
}

As you can see, we've bound the login method to the button. When you click on the button a popup appears giving you multiple options to login to mirror world.

User wallet login

We also include a user state using the useState hook from React so that we can set the user object and use it in our app as we'll see shortly.

Let's go ahead and display the user information in our app with this piece of code:


return (
<div className={styles.container}>
<main className={styles.main}>
<button onClick={login}>Login to Mirror World</button>
{user ? (
<div className="user-info">
<ul>
<li>Username: {user.username} </li>
<li>Email: {user.email}</li>
<li>ETH Address: {user.wallet.eth_address}</li>
<li>SOL Address: {user.wallet.sol_address}</li>
</ul>
</div>
) : (
<p>No User available</p>
)}
</main>
</div>
);
}

Try to log in again and you should see your user details displayed like this:

Displaying user info

Extract Login Logic to a React Hook for

Great! With the current setup, the user can now login at the click of a button, however, we would like to refresh the user's login state everytime the visit the app so that they don't have to keep logging in every time they come to your app.

Create useMirrorWorld hook

Let's create a new hook called useMirrorWorld that will provide our SDK instance and automatically fetch user's state each time the app loads.

Create a new file called useMirrorWorld.tsx with the following code.


// In your useMirrorWorld.tsx file
import {
ReactNode,
createContext,
useContext,
useState,
useEffect,
useRef,
} from "react"
import { Solana, IUser, MirrorWorld } from "@usemirrorworld/web3.js"
export interface IMirrorWorldContext {
user?: IUser
mirrorworld: MirrorWorld
login(): Promise<void>
}
/**
* Create a MirrorWorld context object
*/
const MirrorWorldContext = createContext<IMirrorWorldContext>(
{} as IMirrorWorldContext,
)
/**
* Export the `useMirrorWorld` hook to consume the state from our provider
*/
export function useMirrorWorld() {
return useContext(MirrorWorldContext)
}
// Create a storage key that the provider component will use
// to store the user's refresh_token in the client-side.
const storageKey = `authentication_demo_refresh_token`
/**
* Create a `MirrorWorldProvider` component to provide the user's
* authentication logic and our SDK instance to the client
*/
export const MirrorWorldProvider = ({ children }: { children: ReactNode }) => {
const [mirrorworld, setMirrorworld] = useState<MirrorWorld>()
const [user, setUser] = useState<IUser>()
const isInitialized = useRef(false)
/**
* Logs in the user and updates the provider state
* when the user successfullly logs in
*/
async function login() {
if (!mirrorworld) throw new Error("Mirror World SDK is not initialized")
const result = await mirrorworld.login()
if (result.user) {
setUser(result.user)
localStorage.setItem(storageKey, result.refreshToken)
}
}
/**
* Helper function to initialize the SDK
* PS: Remember to replace the `apiKey` with your
* project's API key from the first step.
*/
function initialize() {
const refreshToken = localStorage.getItem(storageKey)
const instance = new MirrorWorld({
apiKey: "mw_YOUR_SUPER_SECRET_API_KEY",
chainConfig: Solana("mainnet-beta"),
...(refreshToken && { autoLoginCredentials: refreshToken }),
})
/**
* This event is fired every time the user logs
* in with the SDK in the browser. You can also listen
* to this event somewhere else on the app.
*
* A full list of events can be found in the API reference:
* https://docs.mirrorworld.fun/api-reference/js#events--js
*/
instance.on("auth:refreshToken", async (refreshToken) => {
if (refreshToken) {
localStorage.setItem(storageKey, refreshToken)
const user = await instance.fetchUser()
setUser(user)
}
})
// Set the Mirror World SDK instance
setMirrorworld(instance)
}
useEffect(() => {
if (!isInitialized.current) {
initialize()
}
return () => {
isInitialized.current = true
}
}, [])
// Finally return the provider with the authentication
// logic!
return (
<MirrorWorldContext.Provider
value={{
mirrorworld: mirrorworld as MirrorWorld,
user,
login,
}}
>
{children}
</MirrorWorldContext.Provider>
)
}

Great! now you have a created a helper hook to clean up your index.tsx page.

Wrap app.tsx with the MirrorWorldProvider component

Wrap your _app.tsx with the MirrorWorldProvider component we just created in our useMirrorWorld.tsx file 👇🏽


// In your pages/_app.tsx file
import type { AppProps } from "next/app"
import { MirrorWorldProvider } from "../path/to/useMirrorWorld.tsx"
export default function App({ Component, pageProps }: AppProps) {
return (
<MirrorWorldProvider>
<Component {...pageProps} />
</MirrorWorldProvider>
)
}

Refactor pages/index.tsx to use the useMirrorWorld hook.

Phew! We can now clean up our pages/index.tsx page as shown below.


// Your new `pages/index.tsx` file
import { useState } from "react"
import styles from "../styles/Home.module.css"
import { useMirrorWorld } from "../path/to/useMirrorWorld.tsx" // [tl! ++]
export default function Home() {
// Simplified home page code!
const { user, login } = useMirrorWorld()
return (
<div className={styles.container}>
<main className={styles.main}>
<button onClick={login}>Login to Mirror World</button>
{user ? (
<div className="user-info">
<ul>
<li>Username: {user.username} </li>
<li>Email: {user.email}</li>
<li>ETH Address: {user.wallet.eth_address}</li>
<li>SOL Address: {user.wallet.sol_address}</li>
</ul>
</div>
) : (
<p>No User available</p>
)}
</main>
</div>
)
}

Congrats! Now your user's will automatically be logged in whenever they visit your app!

Going Further

Great! At this point you're pretty much ready to start doing building with the JavaScript SDK for Mirror World. There are a few things you can do to proceed from here:

Getting Support

If you're stuck or just looking for support, you may also schedule a support call with our team.

Happy Hacking!

Edit this page on GitHub

Copyright © Mirror World, Inc. 2023
On this page

Home

Integration

Guides

API Reference