In this guide, you will learn how to create and deploy both the Anchor program and UI for a basic on-chain Favorites dApp. This dApp will allow users to store their favorite number, color, and hobbies through on-chain transactions.

What you will learn

  • Setting up your development environment

  • Using npx create-soon-app

  • Understanding Anchor program structure

  • Creating and using Program Derived Addresses (PDAs)

  • Connecting an Anchor program to a Next.js UI

Prerequisites

For this guide, you will need:

  • Node.js and pnpm installed

  • Rust and Cargo

  • Anchor CLI

  • A SOON compatible wallet

Setting up the project

Create a new project using:

npx create-soon-app my-favorites-app

This will set up a complete project with:

  • Next.js frontend

  • Anchor program

  • Tailwind CSS

  • Jupiter wallet adapter integration

  • SOON testnet configuration

Understanding the Anchor Program

The Anchor program is located in anchor-program/programs/favorites/src/lib.rs. Let’s break down its key components:

Program State

#[account]
#[derive(InitSpace)]
pub struct Favorites {
    pub number: u64,
    #[max_len(50)]
    pub color: String,
    #[max_len(5, 50)]
    pub hobbies: Vec<String>
}

This structure defines what we’ll store on-chain:

  • A favorite number (u64)

  • A favorite color (string up to 50 chars)

  • A list of hobbies (up to 5 hobbies, each up to 50 chars)

Instruction Handler

pub fn set_favorites(
    ctx: Context<SetFavorites>,
    number: u64,
    color: String,
    hobbies: Vec<String>
) -> Result<()> {
    // Store user's favorites
    context.accounts.favorites.set_inner(Favorites {
        number,
        color,
        hobbies
    });
    Ok(())
}

Frontend Integration

The frontend is a Next.js application that uses:

  • Jupiter wallet adapter for SOON testnet

  • Anchor for program interaction

  • Tailwind CSS for styling

Key Components

  1. Wallet Connection:
const wallet = useWallet();
const { publicKey, sendTransaction } = useWallet();
  1. State Management:
const [number, setNumber] = useState("");
const [color, setColor] = useState("");
const [hobbies, setHobbies] = useState<string[]>([]);
  1. Transaction Handling:
const setFavorites = async () => {
  const [favoritesPda] = PublicKey.findProgramAddressSync(
    [Buffer.from("favorites"), publicKey.toBuffer()],
    programId
  );

  const transaction = await program.methods
    .setFavorites(new BN(number), color, hobbies)
    .accounts({
      user: wallet.publicKey,
      favorites: favoritesPda,
      systemProgram: SystemProgram.programId,
    })
    .transaction();
    
  const hash = await sendTransaction(transaction, connection);
};

Testing the dApp

  1. Connect your SOON wallet

  2. Input your favorites:

    • Enter a favorite number

    • Choose a favorite color

    • Add up to 5 hobbies

  3. Click “Save Favorites” to store on-chain

  4. View the transaction on SOON Explorer

Resources