Rainbow logo
RainbowKit
2.1.6

Custom Authentication

Custom Authentication

Connect to your own authentication back-end

While RainbowKit provides first-class support for Sign-In with Ethereum and NextAuth.js, you can also integrate with custom back-ends and message formats.

First create an authentication adapter. This allows RainbowKit to create/prepare messages and communicate with your back-end.

As an example, we could make an authentication adapter that lets us use Sign-In with Ethereum against some custom API endpoints.

import { createAuthenticationAdapter } from '@rainbow-me/rainbowkit';
import { SiweMessage } from 'siwe';
const authenticationAdapter = createAuthenticationAdapter({
getNonce: async () => {
const response = await fetch('/api/nonce');
return await response.text();
},
createMessage: ({ nonce, address, chainId }) => {
return new SiweMessage({
domain: window.location.host,
address,
statement: 'Sign in with Ethereum to the app.',
uri: window.location.origin,
version: '1',
chainId,
nonce,
});
},
getMessageBody: ({ message }) => {
return message.prepareMessage();
},
verify: async ({ message, signature }) => {
const verifyRes = await fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message, signature }),
});
return Boolean(verifyRes.ok);
},
signOut: async () => {
await fetch('/api/logout');
},
});

Assuming your application is already managing the authentication lifecycle in some way, you can pass the current authentication status along with your custom adapter to RainbowKitAuthenticationProvider, wrapping your existing RainbowKitProvider.

import { createAuthenticationAdapter, RainbowKitAuthenticationProvider, RainbowKitProvider, } from '@rainbow-me/rainbowkit';
import { AppProps } from 'next/app';
import { WagmiProvider } from 'wagmi';
import { QueryClientProvider, QueryClient, } from "@tanstack/react-query";
const authenticationAdapter = createAuthenticationAdapter({
/* See above... */
});
const queryClient = new QueryClient();
export default function App({ Component, pageProps }: AppProps) {
// You'll need to resolve AUTHENTICATION_STATUS here
// using your application's authentication system.
// It needs to be either 'loading' (during initial load),
// 'unauthenticated' or 'authenticated'.
return (
<WagmiProvider {...etc}>
<QueryClientProvider client={queryClient}>
<RainbowKitAuthenticationProvider adapter={authenticationAdapter} status={AUTHENTICATION_STATUS} >
<RainbowKitProvider {...etc}>
<Component {...pageProps} />
</RainbowKitProvider>
</RainbowKitAuthenticationProvider>
</QueryClientProvider>
</WagmiProvider>
);
}

If you've got this far and created an adapter for an existing open source authentication library, please consider creating a package for others to use!