FuturePass is a comprehensive solution that offers experiences a drop-in authentication solution for onboarding both Web2 and Web3 users into their experience.
By leveraging the Futureverse UI component library, FuturePass can handle user flows and make it simple for users to sign in with email addresses, Google, Metamask, WalletConnect, or Coinbase.
FuturePass implements best practices for authentication on mobile devices and websites, which can maximise sign-in and sign-up conversion for your experience. It also handles tricky edge cases such as account recovery, linking, and switching that can be security sensitive and error-prone to handle correctly.
FuturePass integrates tightly with the Futureverse custodial wallet and uses industry standards like OpenID Connect and OAuth 2.0 a secure and uncomplicated onboarding experience.
Checkout the FuturePass Dashboard to see FuturePass in action.
Due to the nuances and complexity of FuturePass it is recommended that developers integrate the FuturePass profile component which is designed to cohesively solve common usability problems and provide an easy and familiar UX across multiple experience's, such as;
- Viewing and copy wallet addresses
- Logout
- Login
- Link to block explorers
- Switch networks (To come)
- Switch address (To come)
yarn add @futureverse/react@0.0.1-pre.2
Before being able to use
<FutureverseProvider />
container you will need to register an OAuth2 client with the Futureverse Idp.
Production client applications may be registered at https://login.futureverse.app/manageclients (production.)
During development, we offer a staging environment at https://login.futureverse.cloud/manageclients.
To get started with the Futureverse SDK for react, simply wrap your react application with <FutureverseProvider />
, filling in the necessary configuration as per below example:
import { FutureverseProvider, FutureverseAuthClient } from '@futureverse/react'
import * as sdk from '@futureverse/experience-sdk'
function MyAppShell() {
const authClient = useMemo(() => {
const environment = {
stage: '<development | production>',
idpURL: 'YOUR IDENTITY PROVIDER URL',
signerURL: 'YOUR SIGNER URL',
chain: 'YOUR TRN CHAIN (mainnet | porcini)',
}
const client = new FutureverseAuthClient({
clientId: 'YOUR CLIENT ID',
environment,
redirectUri: 'YOUR REDIRECT URI',
})
// add any user state listeners here
return client
}, [])
return (
<FutureverseProvider stage={'<development | production>'} authClient={authClient} Web3Provider={'wagmi | web3React'} walletConnectProjectId={'<YOUR PROJECT ID>'} requiredChains={['ETHEREUM', 'TRN']}>
<MyApp />
</FutureverseProvider>
)
}
config.clientId
- The Client ID of your registered OAuth client. See
Registering OAuth2 client for information on how to register your app with
the Futureverse Identity Provider.
config.redirectUri
- The OAuth2 callback url where the Idp should redirect to
after successfully logging the user in. This route is NOT handled by the
library, and MUST be implemented. See section on Authentication flow for
more details on how to get this set up.
Web3Provider
- The web3 provider to use. May be "wagmi"
(default),
"web3react"
, or a component function for a custom integration.
walletConnectProjectId
- This is required to use WalletConnect since the V2 upgrade. You will need to visit the WalletConnect dashboard and create a project Id for your app.
requiredChains
- This takes an array of networks that your experience needs to function when using WalletConnect. We currently support Ethereum (ETHEREUM
) and The Root Network (TRN
) with Ethereum as the default. if your app
requires more than the default please define the full list.
The default authentication flow employs a client-side PKCE grant. All the details of handling that flow are abstracted as part of the library except mounting a callback handler.
-
Add a route for handling the OAuth2 redirect (your
redirectUri
.) -
In the client side handler for that route, complete the OAuth2 callback flow, by calling
handleCallback
as per example below:function MyLoginRedirectHandler() { const { handleCallback, login } = useFutureverse() useEffect(() => { handleCallback().then((result) => { // some kind of error happened that prevented login from succeeding. // perhaps show your users some kind of message here. if (result == null) { return } // this happens if a silent login was attempted. In this example we'll // simply retry logging in, but this time invoking a prompt. if (result === 'login_required') { login() return } // finally, redirect the user somewhere... router.replace('/somewhere') }) }, [handleCallback, login, router]) }
With the callback handler mounted, we can now start authenticating our users.
Invoking login
will display the standard Futureverse login prompt, offering a
range of different login methods to the user. Here the user can choose to login
/ signup using an existing wallet or by letting us create and manage a wallet on
their behalf.
function MyApp() {
const { login } = useFutureverse()
return (
<button
onClick={() => {
login()
}}
>
Login!
</button>
)
}
To access the user session query the user
property on useFutureverse
which
will be available as long as the user is logged in.
function MyApp() {
const { user } = useFutureverse()
if (user) return <>You are logged in!</>
return <>Not logged in</>
}
The <FutureverseProvider/>
container wraps the app in a given web3 react
provider library (wagmi by default.) Interacting with web3 apis is thus
simply a matter of using the web3 react provider library’s API as per usual.
This is true both for custodial and non-custodial logons.
🚧 If you need a finer gained control or want to wrap your application in a different web3 react provider, you can use the
web3provider
option<FutureverseProvider ... web3provider={...} />
. This enables you to wrap your application in any web3 react library, however, in order to get login working you’ll have to provide a customLoginAdapter
. This login adapter enables the Futureverse sign in code to sign the challenges it needs to in order to prove ownership over an account.
The @futureverse/react
library is designed to be used in a dedicated
environment and defaults to a production environment. Available environments are:
-
production
(default) - The live environment targeting the root network, available undersdk.ENVIRONMENTS.production
-
staging
- A staging environment targeting the Porcini test network, available undersdk.ENVIRONMENTS.staging