Guides

Part 1: Setting Up a Next.js Project with Anvil API#

Introduction#

In this first part, we'll create a Next.js application and configure it to work with Anvil API. By the end of this section, you'll have a working development environment ready for wallet integration.

Prerequisites#

Before you begin, ensure you have:

  • Node.js 18+ installed
  • Basic familiarity with React and Next.js
  • An Anvil API key: (sign up at Anvil)

Project Creation#

1. Create a new Next.js project#

Start by creating a new Next.js application using the create-next-app tool:

npx create-next-app@latest my-basic-transaction-app
cd my-basic-transaction-app

When prompted for options, select the following:

  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: Yes
  • src/ directory: Yes
  • App Router: Yes
  • Use TurboPack: (Optional)
  • Custom Import Alias (@/*): No

2. Install Required Dependencies#

Next, install Weld and other required dependencies:

npm install @ada-anvil/weld

This single package includes everything needed for the client-side wallet integration. Other dependencies (e.g., Next.js, Tailwind CSS) should already be installed as part of the project creation. See the Weld Documentation for more information.

The @ada-anvil/weld package includes all the necessary functionality for wallet integration. The React-specific hooks are exported from the package via the /react subpath: @ada-anvil/weld/react.

3. Environment Configuration#

Create a .env.example file to document the required environment variables for other developers:

NEXT_PUBLIC_ANVIL_API_URL=https://preprod.api.ada-anvil.app/v2/services
ANVIL_API_KEY=testnet_EyrkvCWDZqjkfLSe1pxaF0hXxUcByHEhHuXIBjt9
NEXT_PUBLIC_NETWORK=preprod

This file can be safely committed to your repository.

Next, create a .env.local file at the root of your project with your actual values

Never commit your .env.local file to version control. Add it to your .gitignore file to keep your API key secure.

4. Project Structure#

The project will be built incrementally across all three parts of this guide. Here's a preview of the complete project structure you'll create:

my-basic-transaction-app/
├── src/
│   ├── app/
│   │   ├── api/                     # API routes
│   │   │   └── transaction/
│   │   │       ├── build/
│   │   │       │   └── route.ts     # Transaction Build
│   │   │       └── submit/
│   │   │           └── route.ts     # Transaction Submit
│   │   ├── globals.css              # Global styles
│   │   ├── layout.tsx               # Main Layout
│   │   └── page.tsx                 # Main Page
│   ├── components/                  # Component files
│   │   ├── WalletConnector.tsx      # Wallet Connector
│   │   ├── TransactionForm.tsx      # Transaction Form
│   │   └── WeldProvider.tsx         # Weld Provider
│   ├── hooks/                       # Custom React hooks
│   │   └── useTransactionSubmission.ts  # Transaction Submission Hook
│   └── utils/                       # Utility functions
│       └── anvil-api.ts             # Anvil API
├── public/                          # Static assets
├── .env.local                       # Environment variables
├── .env.example                     # Environment variables
├── package.json                     # Package configuration
└── other project config files       # Project configuration

In Part 1 (this guide), we'll focus on setting up the basic Next.js application structure, configuring environment variables, and adding styles. The implementation of specific components and API routes will come in Parts 2 and 3.

5. Basic Styling#

Create a consistent look and feel by adding basic styles to your src/app/globals.css file: We are using custom styles for the paper, button, and custom-rounded classes. You can modify these styles to match your desired design. Or you can use Tailwind's built-in utilities to create your own styles. For now, copy the following code into your src/app/globals.css file:

/* src/app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --bg-primary: #333;
  --bg-secondary: #ebebeb;
  --bg-accent: #212121;
  --fg-primary: #fff;
  --fg-secondary: #000;
  --fg-variant: #333;
  --white: #fff;
  --black: #000;
  --font:
    system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.paper {
  --bg-primary: #000;
  --bg-secondary: #dfd0b9;
  --bg-accent: #000;
  --fg-primary: #fff;
  --fg-secondary: #000;
  --fg-variant: #edede7;
  --white: #edede7;
  --black: #000;
}

@layer base {
  body {
    font-family: var(--font);
    background-color: var(--white);
    color: var(--black);
  }

  p,
  span {
    color: var(--fg-secondary);
  }
}

@layer components {
  .w-300 {
    max-width: 18.75rem;
    min-width: 18.75rem;
    width: 18.75rem;
  }

  .break {
    word-break: break-word;
  }

  .custom-border {
    border: 0.125rem solid var(--fg-secondary);
  }

  .custom-rounded {
    border-radius: 1rem;
  }

  section,
  article {
    box-shadow: 0.25rem 0.25rem var(--black);
    padding: 1rem;
    border: 0.125rem solid var(--fg-secondary);
    border-radius: 1rem;
    margin-bottom: 1rem;
  }

  .btn {
    border: 0.125rem solid var(--fg-secondary);
    border-radius: 1rem;
    box-shadow: 0.25rem 0.25rem;
    background-color: var(--white);
    color: var(--fg-secondary);
    padding: 1rem;
    font-family: var(--font);
    font-weight: bold;
    font-size: medium;
    transition: 0.1s;
    cursor: pointer;
  }

  .btn:hover {
    translate: 0.25rem 0.25rem;
    box-shadow: none;
    background-color: var(--bg-secondary);
  }

  .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  input[type="text"],
  input[type="number"],
  select {
    width: 100%;
    padding: 10px;
    margin: 8px 0;
    display: block;
    border: 2px solid var(--black);
    background-color: var(--white);
    color: var(--black);
    font-size: 16px;
    box-sizing: border-box;
    border-radius: 1rem;
  }

  input[type="text"]:focus,
  input[type="number"]:focus,
  select:focus {
    outline: none;
    border-color: var(--black);
  }

  .container-spacing {
    padding: 1rem;
  }

  .container-spacing > * {
    margin-bottom: 1rem;
  }

  .container-spacing > *:last-child {
    margin-bottom: 0;
  }
}

Verify Your Setup#

Let's make sure your setup is working correctly:

  1. Modify the existing home page at src/app/page.tsx. Next.js has already created this file during setup. Replace its contents with:
export default function Home() {
  return (
    <main className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-6">Cardano Transaction App</h1>
      <p>Welcome to the Cardano Transaction App!</p>
    </main>
  );
}
  1. Start your development server:
npm run dev
  1. Navigate to http://localhost:3000 in your browser. You should see the welcome message.

Congratulations! You've completed Part 1 of the guide. You now have a Next.js project ready for Cardano wallet integration.

What's Next?#

Now that you have a basic Next.js application set up, you're ready to integrate the Weld wallet connector. In Part 2: Wallet Integration, we'll implement the wallet connection functionality.