Prerequisites
Before you begin, make sure you have the following installed:
An Algorand wallet (e.g., Pera, Defly, etc)
Getting Started
Clone the NextAuth.js example repository:
git clone https://github.com/nextauthjs/next-auth-example
cd next-auth-example
Integrating SIWA with NextAuth.js
This guide will walk you through the process of integrating Sign-In with Algorand (SIWA) into a Next.js application using NextAuth.js.
Prerequisites
Before you begin, make sure you have the following installed:
An Algorand wallet (e.g., Pera, Defly)
Getting Started
Clone the NextAuth.js example repository:
git clone https://github.com/nextauthjs/next-auth-example
cd next-auth-example
Create a .env.local
file with the following content:
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=yoursecretkey
Install the required dependencies:
yarn add @avmkit/siwa algosdk
Configuring NextAuth.js
Modify the pages/api/auth/[...nextauth].ts
file to include the SIWA provider:
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { getCsrfToken } from "next-auth/react"
import { SiwaMessage } from "@avmkit/siwa"
export default async function auth(req: any, res: any) {
const providers = [
CredentialsProvider({
name: "Algorand",
credentials: {
message: {
label: "Message",
type: "text",
placeholder: "0x0",
},
signature: {
label: "Signature",
type: "text",
placeholder: "0x0",
},
},
async authorize(credentials) {
try {
const siwa = new SiwaMessage(JSON.parse(credentials?.message || "{}"))
const nextAuthUrl = new URL(process.env.NEXTAUTH_URL)
const result = await siwa.verify({
signature: credentials?.signature || "",
domain: nextAuthUrl.host,
nonce: await getCsrfToken({ req }),
})
if (result.success) {
return {
id: siwa.address,
}
}
return null
} catch (e) {
return null
}
},
}),
]
// ... rest of the NextAuth configuration
}
Creating a SIWA Sign-In Page
Create a new file pages/siwa.tsx
for the SIWA sign-in page:
import { getCsrfToken, signIn, useSession } from "next-auth/react"
import { SiwaMessage } from "@avmkit/siwa"
import { useEffect, useState } from "react"
import Layout from "../components/layout"
function Siwa() {
const [address, setAddress] = useState("")
const { data: session, status } = useSession()
const handleLogin = async () => {
try {
const callbackUrl = "/protected"
const message = new SiwaMessage({
domain: window.location.host,
address: address,
statement: "Sign in with Algorand to the app.",
uri: window.location.origin,
version: "1",
chainId: "416001", // Algorand TestNet
nonce: await getCsrfToken(),
})
// Here, you would use your Algorand wallet library to sign the message
// For example, with Pera:
// const signMessageWithPera = async (message, address) => {
// const encodedMessage = prepareMessage(message);
// const signatureArray = await peraWallet.signData(
// [{ data: encodedMessage, message: "" }],
// address );
// return signatureArray[0]; // Returns the signature
// };
// For this example, we'll use a placeholder signature
const signature = "placeholder_signature"
signIn("credentials", {
message: JSON.stringify(message),
redirect: false,
signature,
callbackUrl,
})
} catch (error) {
console.error(error)
alert("An error occurred during sign-in")
}
}
return (
<Layout>
<h1>Sign-In with Algorand</h1>
<input
type="text"
placeholder="Enter Algorand address"
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
<button onClick={handleLogin}>Sign-in with Algorand</button>
</Layout>
)
}
export default Siwa
Modify the components/header.tsx
file to include a link to the SIWA page:
import Link from "next/link"
import styles from "./header.module.css"
export default function Header() {
// ... existing header code
return (
<header>
{/* ... existing header content */}
<nav>
<ul className={styles.navItems}>
<li className={styles.navItem}>
<Link href="/">
Home
</Link>
</li>
<li className={styles.navItem}>
<Link href="/siwa">
SIWA
</Link>
</li>
</ul>
</nav>
</header>
)
}
Running the Application
Start the development server:
Navigate to http://localhost:3000
and click on the "SIWA" link in the header to test the Sign-In with Algorand functionality.
Next Steps
This guide provides a basic integration of SIWA with NextAuth.js. For a production-ready implementation, you should:
Implement proper Algorand wallet integration for message signing.
Add error handling and user feedback.
Customize the UI to match your application's design.
Implement proper session management and protected routes.
Remember to always follow best practices for security when dealing with authentication in your application.