I Built a Fully On-Chain Notes App on Solana Using Anchor + Next.js
Hey devs! π
I recently built a full-stack Solana dApp where users can create, update, and delete notes that live entirely on-chain. It was a great experience to combine Anchor (Rust) for the smart contract with Next.js 14 + TailwindCSS for the frontend β so I thought I'd share what I learned and how I approached it.
π§ What I Built
It's a classic CRUD app β but on Solana!
Users can:
- π Create a note (title + content)
- βοΈ Update it
- ποΈ Delete it
All stored on-chain in Solana accounts using Program Derived Addresses (PDAs).
Live demo coming soon... π
π§± Stack
- π¨ Anchor (Rust framework for Solana smart contracts)
- βοΈ Next.js 14 (with App Router)
- π¨ TailwindCSS (for styling)
- π @solana/wallet-adapter (wallet connection)
- π£ SweetAlert2 (beautiful loading/toast popups)
π§ What I Learned
- How to structure accounts in Solana using Anchorβs
#[account]
macro - Writing validators and error handling with
require!
and custom#[error_code]
- Creating PDAs using seeds:
seeds = [b"note", author.key().as_ref(), title.as_bytes()]
`
- Hooking up the frontend using
@project-serum/anchor
and React hooks - Handling wallet connection state, transaction sending, and UI feedback
π§Ύ The Smart Contract (Rust + Anchor)
Here is a simplified view of the program logic:
`
pub fn create_note(ctx: Context<CreateNote>, title: String, content: String) -> Result<()> {
let note = &mut ctx.accounts.note;
let clock = Clock::get()?;
require!(title.len() <= 100, NotesError::TitleTooLong);
require!(!content.trim().is_empty(), NotesError::ContentIsEmpty);
note.author = ctx.accounts.author.key();
note.title = title;
note.content = content;
note.created_at = clock.unix_timestamp;
note.last_updated = clock.unix_timestamp;
Ok(())
}
The Note
account looks like this:
#[account]
#[derive(InitSpace)]
pub struct Note {
pub author: Pubkey,
#[max_len(100)]
pub title: String,
#[max_len(1000)]
pub content: String,
pub created_at: i64,
pub last_updated: i64,
}
π₯οΈ Frontend Highlights
- Connect to wallet via
@solana/wallet-adapter-react
- Interact with the program using
@project-serum/anchor
- SweetAlert2 loading indicators
- Tailwind UI for responsive layout
const provider = new AnchorProvider(connection, wallet, {});
const program = new Program(idl, programId, provider);
await program.methods
.createNote(title, content)
.accounts({ author, note, systemProgram })
.rpc();
π Built with β€οΈ for the Solana ecosystem
Thanks for reading!
Top comments (0)