Skip to content

Instantly share code, notes, and snippets.

@samkingco
Created November 21, 2022 23:00
Show Gist options
  • Select an option

  • Save samkingco/db0be41f80b974baea66c4713142b1cc to your computer and use it in GitHub Desktop.

Select an option

Save samkingco/db0be41f80b974baea66c4713142b1cc to your computer and use it in GitHub Desktop.
connectkit-next-auth
import { IncomingMessage } from "http";
import { NextApiRequest, NextApiResponse } from "next";
import NextAuth, { type NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { getCsrfToken } from "next-auth/react";
import { SiweMessage } from "siwe";
export function getAuthOptions(req: IncomingMessage): NextAuthOptions {
const providers = [
CredentialsProvider({
async authorize(credentials) {
console.log(credentials);
try {
const siwe = new SiweMessage(
JSON.parse(credentials?.message || "{}")
);
const nextAuthUrl =
process.env.NEXTAUTH_URL ||
(process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: null);
if (!nextAuthUrl) {
return null;
}
const nextAuthHost = new URL(nextAuthUrl).host;
if (siwe.domain !== nextAuthHost) {
return null;
}
if (siwe.nonce !== (await getCsrfToken({ req }))) {
return null;
}
await siwe.validate(credentials?.signature || "");
return {
id: siwe.address,
};
} catch (e) {
return null;
}
},
credentials: {
message: {
label: "Message",
placeholder: "0x0",
type: "text",
},
signature: {
label: "Signature",
placeholder: "0x0",
type: "text",
},
},
name: "Ethereum",
}),
];
return {
callbacks: {
async session({ session, token }) {
console.log(session, token);
const address = token.sub || "";
session.address = address;
session.chainId = 1;
session.wallets = {
...session.wallets,
eth: address,
};
return session;
},
},
providers,
secret: process.env.NEXTAUTH_SECRET,
session: {
strategy: "jwt",
},
};
}
export default async function auth(req: NextApiRequest, res: NextApiResponse) {
const authOptions = getAuthOptions(req);
if (!Array.isArray(req.query.nextauth)) {
res.status(400).send("Bad request");
return;
}
const isDefaultSigninPage =
req.method === "GET" &&
req.query.nextauth.find((value) => value === "signin");
// Hide Sign-In with Ethereum from default sign page
if (isDefaultSigninPage) {
authOptions.providers.pop();
}
return await NextAuth(req, res, authOptions);
}
import { SIWEConfig } from "connectkit/build/components/Standard/SIWE/SIWEContext";
export const siweConfig: SIWEConfig = {
createMessage: ({ address, chainId, nonce }) => {
return new SiweMessage({
version: "1",
domain: window.location.host,
uri: window.location.origin,
address,
chainId,
nonce,
statement: "Sign in with Ethereum.",
}).prepareMessage();
},
getSession: async () => {
const session = await getSession();
if (!session) return null;
return session;
},
getNonce: async () => {
const nonce = await getCsrfToken();
if (!nonce) throw new Error();
return nonce;
},
signOut: async () => {
try {
await signOut({ redirect: false });
return true;
} catch (error) {
console.error(error);
return false;
}
},
verifyMessage: async ({ message, signature }) => {
const response = await signIn("credentials", {
message: JSON.stringify(message),
redirect: false,
signature,
});
return response?.ok ?? false;
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment