Primero creamos un projecto en Nextjs you utilizo yarn pero puedes elegir el que mas te guste
yarn create next-app
en mi caso me gusta usar typescript pero puedes utilizar javascript si te es más cómodo
✔ Would you like to use TypeScript with this project? … No / Yes
Puedes crear tu project o con tus preferencias en este caso usaremos la carpeta experimental app, luego de que se instalen todas las dependencias corra el projecto
ahora vamos a agregar next auth
yarn add next-auth
otras dependencias
yarn add siwe@beta ethers wagmi
aqui vamos a usar algo feo debido a que aun no he visto otra manera de integrar nextAuth crearemos la carpeta al mismo nivel que la carpeta app pages/api/auth/[...nextauth].ts
ahora nuestro archivo debe verse así
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { getCsrfToken } from "next-auth/react";
import { SiweMessage } from "siwe";
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options
export default async function auth(req: any, res: any) {
const providers = [
CredentialsProvider({
name: "Ethereum",
credentials: {
message: {
label: "Message",
type: "text",
placeholder: "0x0",
},
signature: {
label: "Signature",
type: "text",
placeholder: "0x0",
},
},
async authorize(credentials) {
try {
const siwe = new SiweMessage(
JSON.parse(credentials?.message || "{}")
);
const nextAuthUrl = new URL(process.env.NEXTAUTH_URL || "");
const result = await siwe.verify({
signature: credentials?.signature || "",
domain: nextAuthUrl.host,
nonce: await getCsrfToken({ req }),
});
if (result.success) {
return {
id: siwe.address,
};
}
return null;
} catch (e) {
return null;
}
},
}),
];
const isDefaultSigninPage =
req.method === "GET" && req.query.nextauth.includes("signin");
// Hide Sign-In with Ethereum from default sign page
if (isDefaultSigninPage) {
providers.pop();
}
// eslint-disable-next-line no-return-await
return await NextAuth(req, res, {
// https://next-auth.js.org/configuration/providers/oauth
providers,
session: {
strategy: "jwt",
},
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
async session({ session, token }: { session: any; token: any }) {
// eslint-disable-next-line no-param-reassign
session.address = token.sub;
// eslint-disable-next-line no-param-reassign
session.user.name = token.sub;
// eslint-disable-next-line no-param-reassign
session.user.image = "https://www.fillmurray.com/128/128";
return session;
},
},
});
}
creemos nuestras variables de entorno, ahora para la Create a NEXTAUTH_SECRET puedes usar el siguiente comando openssl rand -base64 32
pero yo te recomiendo usar el que te genera GENERATE-SECRET
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=clave generada
ahora creamos nuestra carpeta app y creamos una folder llamada container donde crearemos las siguientes files
wagmi.container.ts
import React from "react";
import { configureChains, createClient, WagmiConfig } from "wagmi";
import { mainnet, bsc, polygon, bscTestnet, goerli } from "wagmi/chains";
import { publicProvider } from "wagmi/providers/public";
import { InjectedConnector } from "wagmi/connectors/injected";
// Config
const { chains, provider } = configureChains(
[mainnet, bsc, polygon, bscTestnet, goerli],
[publicProvider()]
);
const client = createClient({
autoConnect: true,
connectors: [new InjectedConnector({ chains })],
provider,
});
// Provider
const WagmiProvider: React.FC<{
children: React.ReactNode;
}> = ({ children }) => {
return <WagmiConfig client={client}>{children}</WagmiConfig>;
};
export default WagmiProvider;
and
root.provider.ts
"use client";
import React from "react";
import { Session } from "next-auth";
import { SessionProvider } from "next-auth/react";
import WagmiProvider from "./wagmi.container";
// Root Provider
function RootProvider({
children,
session,
}: {
children: React.ReactNode;
// eslint-disable-next-line react/require-default-props
session?: Session;
}) {
return (
<WagmiProvider>
<SessionProvider session={session} refetchInterval={0}>
{children}
</SessionProvider>
</WagmiProvider>
);
}
export default RootProvider;
creamos el middleware este archivo va al mismo nivel de la carpeta app
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { getToken } from "next-auth/jwt";
export async function middleware(req: NextRequest) {
const session = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
if (!session) {
const requestedPage = req.nextUrl.pathname;
const url = req.nextUrl.clone();
url.pathname = `/`;
url.search = `p=${requestedPage}`;
return NextResponse.redirect(url);
}
return NextResponse.next();
}
// See "Matching Paths" below to learn more
export const config = {
matcher: ["/home", ""], // array con todas las routas que quieres proteger
};
en este projecto uso tailwind pero puedes usar la liberia que te guste
este es el componente para realizar el login
<button
// lassName="h-10 bg-blue-600 text-white px-6 rounded-full hover:bg-blue-800 transition-colors ease-in-out duration-200"
type="button"
onClick={(e) => {
e.preventDefault();
if (!isConnected) {
connect();
} else {
handleLogin();
}
}}
>
Connect Wallet
</button>
en la app creamos un page app/home/page.tsx
import React from "react";
import { useSession } from "next-auth/react";
import { useDisconnect } from "wagmi";
import { signOut } from "next-auth/react";
function Home() {
const { data: session } = useSession();
const address = session?.user?.email ?? session?.user?.name;
const { disconnect } = useDisconnect();
const callbackUrl = "/";
return (
<div>
<p>{address}</p>
<button
type="button"
onClick={(e) => {
e.preventDefault();
disconnect();
signOut({
redirect: true,
callbackUrl,
});
}}
>
Disconnect Wallet
</button>
</div>
);
}
hasta aqui tienes las bases para crear tu primera Dapp seguire subiendo tutoriales de como intreracturar con contratos y como crear tu propios smart contracts
Top comments (0)