1.0.0 • Published 2 years ago

@sloikaxyz/remix-auth-siwe v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

MIT License

@sloikaxyz/remix-auth-siwe

A Remix Auth strategy to sign in with Ethereum

@sloikaxyz/remix-auth-siwe provides a remix-siwe authentication strategy for Sign in with Ethereum.

Strategy Name

siwe

Supported runtimes

RuntimeHas Support
Node.js
Cloudflare

How to use

Set up the authenticator:

// app/services/auth.server.ts
import { Authenticator } from "remix-auth";
import { SiweStrategy } from "remix-auth-siwe";

import { sessionStorage } from "~/services/session.server";
import type { User } from "~/services/session.server";

// Create an instance of the authenticator, pass a generic with what
// strategies will return and will store in the session
export let authenticator = new Authenticator<User>(sessionStorage, {
  sessionKey: "sessionKey", // keep in sync
  sessionErrorKey: "sessionErrorKey", // keep in sync
});

authenticator.use(
  new SiweStrategy({ domain: "localhost:3000" }, async ({ message }) => {
    return await Promise.resolve({ address: message.address });
  }),
  "siwe"
);

Create an action to authenticate user:

export const action: ActionFunction = async ({ request, context }) => {
  await authenticator.authenticate("siwe", request, {
    successRedirect: "/",
    failureRedirect: "/login",
    context, // optional
  });
};

From your login entry point send message and signature as formData:

   import { useSubmit } from '@remix-run/react';
   import { SiweMessage } from 'siwe';


   export default function Screen() {
      const submit = useSubmit();

      function authenticate = useCallback(() => {
         // create siwe message
         const message = await new SiweMessage({ siweMessageOptions });
         // sign siwe message
         const signature = await signer.signMessage(message);

         const formData = new FormData();
         formData.append('message', message);
         formData.append('signature', signature);
         submit(formData, {
            action: {YOUR_LOGIN_ACTION},
            method: 'post',
            replace: true,
         });
      }, [submit])

      return <button onClick={authenticate}>Sign In</button>;
   }

You can check if the user is authenticated with authenticator.isAuthenticated and redirect to the dashboard if it is, or to login if it's not

export let loader: LoaderFunction = async ({ request }) => {
  // If the user is already authenticated redirect to /dashboard
  // otherwise redirect to /login
  return await authenticator.isAuthenticated(request, {
    successRedirect: "/dashboard",
    failureRedirect: "/login",
  });
};

You can get user object from authenticator.isAuthenticated:

let user = await authenticator.isAuthenticated(request, {
  failureRedirect: "/login",
});

Installation

Install with npm or yarn:

  npm install @sloikaxyz/remix-auth-siwe siwe@^2.0.5 ethers@^5.6.8
  # or
  yarn add @sloikaxyz/remix-auth-siwe siwe@^2.0.5 ethers@^5.6.8