Part 1: Project Setup

This is Part 1 of our guide to building a Cardano transaction application with Next.js and Weld. In this section, you'll set up the project structure and dependencies.

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 TODO: Add public URL)

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

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.

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.

Last updated

Was this helpful?