# Part 1 - Connect Wallet using Metamask and mint an NFT

This 2-part tutorial will guide you through integrating with Bastion SDK in your Next.js app through Metamask and then using social login via Particle Auth.&#x20;

This is Part 1 of the tutorial.

{% hint style="info" %}
**Note:** You can find the complete code for this app in this [Github repo](https://github.com/bastion-wallet/nextjs-demo-app/blob/main/pages/index.tsx).
{% endhint %}

### Prerequisites

1. Node.js and npm installed
2. Basic understanding of Next.js and React
3. A Bastion account for API key
4. A Particle Network account

### Step 1: Set Up Your Next.js Project

If you haven't already set up a Next.js project, create one by running:

```bash
npx create-next-app nextjs-demo-app
```

*Make sure that you choose the following options for this demo to work. (It should still work with different options, but the project structure would be different).*

<figure><img src="/files/2RdGcPtczAyNUpRfrJle" alt=""><figcaption></figcaption></figure>

*Note:- If you're using App Router in NextJS 13, you should use /app/index.tsx instead of /pages/index.tsx*

Navigate into your project folder:

```bash
cd nextjs-demo-app
```

### Step 2: Install Required Packages

Install the required npm packages:

```bash
npm install bastion-wallet-sdk ethers@5 next @particle-network/auth @particle-network/provider
```

### Step 3: Get Bastion API Key

1. Log in to the [Bastion Dashboard](https://dashboard.bastionwallet.io/).
2. Generate a new API key.

### Step 4: Add Environment Variables

Create a `.env.local` file at the root of your Next.js project and add the following:

```env
NEXT_PUBLIC_BASTION_API_KEY=<your_bastion_api_key>
```

Replace the placeholder values with your Bastion API key.

### Step 5: Implement connect with Metamask and connect with Bastion

Add the following code to the file `pages/index.tsx`&#x20;

{% code lineNumbers="true" fullWidth="true" %}

```tsx
// /pages/index.tsx

import { useState, useEffect } from "react";
import { ethers, Contract } from "ethers";
import { Bastion } from "bastion-wallet-sdk";

export default function Home() {
	const [address, setAddress] = useState<string>("");
	const [bastionConnect, setBastionConnect] = useState<any>();
	const [isMinting, setIsMinting] = useState<boolean>(false);
	const [userOpHash, setUserOpHash] = useState<string>("");

	useEffect(() => {
		if (window.ethereum) {
			window.ethereum.on("accountsChanged", (accounts: string[]) => {
				setAddress(accounts[0]);
			});
		}
	}, []);

	const loginWithMetamask = async () => {
		try {
			// Check if Metamask is installed
			if (!window.ethereum || !window.ethereum.isMetaMask) {
				alert("Please install Metamask.");
				return;
			}

			// Request account access
			const accounts = await window.ethereum.request({
				method: "eth_requestAccounts",
			});

			setAddress(accounts[0]);

			const tempProvider = new ethers.providers.Web3Provider(window.ethereum, "any");

			const bastion = new Bastion();
			const bastionConnect = await bastion.bastionConnect;

			await bastionConnect.init(tempProvider, {
				apiKey: process.env.NEXT_PUBLIC_BASTION_API_KEY || "",
			});

			setBastionConnect(bastionConnect);
		} catch (e) {
			console.error(e);
		}
	};

	const mintNFT = async () => {
		try {
			setIsMinting(true);
			const contractAddress = "0xEAC57C1413A2308cd03eF3CEa5c9224487825341";
			const contractABI = ["function safeMint(address to) public"];

			const nftContract = new Contract(contractAddress, contractABI, bastionConnect);

			const res = await nftContract.safeMint(address);
			console.log(res);
			setIsMinting(false);
			setUserOpHash(res.hash);
		} catch (e) {
			console.error(e);
		}
	};

	return (
		<div>
			{address ? (
				<div>
					<h1>Welcome to Bastion!</h1>
					<h4>Logged in as {address}</h4>
					{isMinting && <h3>Minting...</h3>}
					{userOpHash && <h3>Minted NFT! User Operation Hash: {userOpHash}</h3>}
					<button onClick={mintNFT} className="rounded-2 bg-gradient-to-r from-[#6C1EB0] to-[#DE389F] mx-4 my-4 px-10 py-4 h-full rounded-xl">
						Mint NFT
					</button>
				</div>
			) : (
				<div>
					<h1>Welcome to Bastion!</h1>
					<button onClick={loginWithMetamask} className="rounded-2 bg-gradient-to-r from-[#6C1EB0] to-[#DE389F] mx-4 my-4 px-10 py-4 h-full rounded-xl">
						Login with Metamask
					</button>
				</div>
			)}
		</div>
	);
}
```

{% endcode %}

### Step 6: Add CSS

Go to your globals.css file, which is usually under /styles.

Add the following CSS at the bottom -&#x20;

{% code fullWidth="true" %}

```css
/* styles/globals.css */

html, body {
  max-width: 100vw;
  overflow-x: hidden;
  height: 100vh;  /* New: Set height to full viewport height */
}

/* Reset some default browser styles */
body, h1, button {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

/* Make a container for the whole page */
div {
  text-align: center;
  margin: 0 auto; /* Updated: Removed top and bottom margin */
  height: 100vh;  /* New: Set height to full viewport height */
  display: flex;
  flex-direction: column;
  justify-content: center;  /* Center content vertically */
  align-items: center;  /* Center content horizontally */
}

/* Add some padding and a background gradient to buttons */
button {
  padding: 15px 25px;
  font-size: 16px;
  cursor: pointer;
  border: none;
  border-radius: 4px;
  color: #fff;
  background: linear-gradient(to right, #6C1EB0, #DE389F);
  transition: 0.3s ease-out;
  margin-top: 15px;
}

h3{
  margin-top: 15px;
}

.main-container {
  text-align: center;
  height: 100vh;  /* Set height to full viewport height */
  display: flex;
  flex-direction: column;
  justify-content: center;  /* Center content vertically */
  align-items: center;  /* Center content horizontally */
}

/* Hover effect for buttons */
button:hover {
  background: linear-gradient(to right, #DE389F, #6C1EB0);
}

/* Add some spacing between items */
h1, h2, h3, button {
  margin-bottom: 20px;
}
```

{% endcode %}

### Step 7: Test your app

Now you can run your app using&#x20;

```bash
npm run dev
```

Navigate to `http://localhost:3000` and click on the "Login with Metamask" button. Follow the usual Metamask login procedure, and you should see your Ethereum address displayed on the screen, indicating a successful login.

<figure><img src="/files/fTpKmpGv8VHiTpzyh6RY" alt=""><figcaption></figcaption></figure>

You should also see a Mint NFT button on the page now. If you click on this button, the app will mint an NFT to your Smart Wallet by sending a User Operation on the Arbitrum Goerli testnet using the Pimlico bundler.

<figure><img src="/files/0meTyEYs9w9cpESOZc7Y" alt=""><figcaption></figcaption></figure>

That's it! You've successfully integrated Metamask with the Bastion SDK in a Next.js application. You can now proceed to build more complex functionalities into your decentralized application.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bastionwallet.io/bastion-sdk/nextjs-tutorial/part-1-connect-wallet-using-metamask-and-mint-an-nft.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
