Skip to content

Travel-Kitty/travel-kitty-web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

78 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿพ Travel Kitty โ€” Web App (Next.js 15)

Travel Kitty is an alpha-stage group expense splitter for trips and friends. It records split bills on-chain (Base Sepolia), stores receipt data on IPFS (Helia), and supports optional mock on-chain settlement with mUSD.

โš ๏ธ Alpha notice โ€” This is a hackathon demo. Contracts & code are unaudited. Do not use on mainnet.


๐Ÿš€ What this app does

  • Wallet connect (RainbowKit + wagmi) on Base Sepolia

  • Join a trip (on-chain join())

  • Add expense with:

    • OCR JSON / receipt image uploaded to IPFS via Helia โ†’ CID
    • On-chain addExpense(amountUsd6, cid, splitWith[])
  • Mock settlement (approve mUSD โ†’ settleToken())

  • Off-chain history (Supabase + Prisma) for lists/filters

  • Clean, minimal Next.js 15 App Router UX with TailwindCSS


๐Ÿงฐ Tech Stack

  • Frontend: Next.js 15 (App Router), TypeScript, TailwindCSS
  • Web3: wagmi + viem, RainbowKit, Base Sepolia
  • IPFS: Helia (helia + @helia/unixfs) โ€” browser node
  • Data: Supabase Postgres + Prisma (server actions/route handlers)
  • Server-state: React Query
  • AI/OCR: optional via OpenRouter (vision model) โ€” stubbed in demo API

๐Ÿ—‚ Project structure

travel-kitty-web/
โ”œโ”€ app/
โ”‚  โ”œโ”€ api/ocr/route.ts        # (optional) OCR proxy (stub)
โ”‚  โ”œโ”€ globals.css
โ”‚  โ”œโ”€ layout.tsx              # App providers (wagmi, RainbowKit, React Query)
โ”‚  โ””โ”€ page.tsx                # Home (Join, Faucet, Add Expense, Settle)
โ”œโ”€ lib/
โ”‚  โ”œโ”€ wagmi.ts                # chain config
โ”‚  โ”œโ”€ contracts.ts            # addresses + ABIs
โ”‚  โ”œโ”€ helia.ts                # Helia + unixfs helpers
โ”‚  โ”œโ”€ react-query.tsx         # QueryClient provider
โ”‚  โ”œโ”€ prisma.ts               # Prisma client (server)
โ”‚  โ””โ”€ supabase.ts             # Supabase client (browser)
โ”œโ”€ prisma/
โ”‚  โ””โ”€ schema.prisma           # Trip, TripMember, Expense
โ”œโ”€ public/
โ”œโ”€ next.config.ts
โ”œโ”€ package.json
โ””โ”€ tsconfig.json

๐Ÿ”‘ Environment variables

Create .env.local in the repo root:

# Chain
NEXT_PUBLIC_CHAIN_ID=84532
NEXT_PUBLIC_RPC_URL=https://base-sepolia.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>

# Deployed contract addresses (from contracts repo or broadcast/_addresses_84532.json)
NEXT_PUBLIC_TRAVEL_KITTY=0x...
NEXT_PUBLIC_MOCK_USD=0x...
NEXT_PUBLIC_FAUCET=0x...

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://<project>.supabase.co
NEXT_PUBLIC_SUPABASE_ANON=<public-anon-key>
SUPABASE_SERVICE_ROLE=<service-role-key>   # only for server actions if needed

# Optional OCR via OpenRouter
OPENROUTER_API_KEY=sk-...
OPENROUTER_MODEL=openai/gpt-4o-mini

And set DATABASE_URL for Prisma (Supabase โ†’ Settings โ†’ Database):

DATABASE_URL="postgresql://postgres:<PASSWORD>@db.<host>.supabase.co:5432/postgres"

Keep SERVICE_ROLE & DATABASE_URL server-only (not exposed to client).


๐Ÿ› ๏ธ Install & run

# 1) Install deps
npm i

# 2) Init Prisma schema to your Supabase DB
npx prisma db push

# 3) Dev server
npm run dev

# Build & start
npm run build
npm start

๐Ÿ”— Contracts used (Base Sepolia)

Fill envs from your contracts repo (or manually):

  • TravelKitty โ€” NEXT_PUBLIC_TRAVEL_KITTY=0x...
  • MockUSD (mUSD) โ€” NEXT_PUBLIC_MOCK_USD=0x...
  • MockUSDFaucet โ€” NEXT_PUBLIC_FAUCET=0x...

If you used Foundry script that writes broadcast/_addresses_84532.json, you can copy those addresses here.


๐Ÿงญ User flow (demo)

  1. Connect wallet (RainbowKit) on Base Sepolia

  2. Join trip โ†’ calls TravelKitty.join()

  3. Claim mUSD (rate-limited faucet)

  4. Add expense

    • Uploads receipt JSON (or image) to IPFS (Helia) โ†’ CID
    • Calls TravelKitty.addExpense(amountUsd6, cid, splitWith[])
  5. Settle (optional)

    • approve(mUSD, kitty, amount) then settleToken(creditor, amount, mUSD)
  6. History stored in Supabase (off-chain list + filters)


๐Ÿงฉ Key Files

lib/contracts.ts (addresses + ABI)

export const ADDR = {
  TRAVEL_KITTY: process.env.NEXT_PUBLIC_TRAVEL_KITTY as `0x${string}`,
  MOCK_USD: process.env.NEXT_PUBLIC_MOCK_USD as `0x${string}`,
  FAUCET: process.env.NEXT_PUBLIC_FAUCET as `0x${string}`,
};

// travelKittyAbi, erc20Abi, faucetAbi โ€ฆ (see file)

lib/helia.ts (IPFS)

Creates a browser Helia node and exposes putToIpfs(data) that returns a CID string.

app/page.tsx

Landing with Join, Faucet, Add Expense (โ†’ IPFS + on-chain), Settle actions.


๐Ÿงฎ Data model (Prisma)

model User      { id String @id @default(cuid()); wallet String @unique; createdAt DateTime @default(now()); trips TripMember[] }
model Trip      { id String @id @default(cuid()); name String; owner String; createdAt DateTime @default(now()); members TripMember[]; expenses Expense[] }
model TripMember{ id String @id @default(cuid()); tripId String; wallet String; joinedAt DateTime @default(now()); trip Trip @relation(fields:[tripId], references:[id]) }
model Expense   { id String @id @default(cuid()); tripId String; payer String; amountUsd6 Int; cid String; txHash String?; createdAt DateTime @default(now()); trip Trip @relation(fields:[tripId], references:[id]) }

Populate via server actions after a successful on-chain call (see app/actions.ts).


๐Ÿงช How to demo (judge flow)

  1. Open app โ†’ Connect wallet (Base Sepolia)

  2. Click Join Trip โ†’ show tx in Basescan

  3. Click Claim mUSD โ†’ see balance in MetaMask

  4. Select a small receipt (or use demo JSON), click Add Expense

    • Show IPFS CID in tx input
    • Open Basescan link for the tx
  5. Paste creditor address, click Approve + Settle to send mUSD and reduce balances

  6. Show Supabase table updating (expenses list)


๐Ÿงท Security notes

  • Do not expose service keys to the client.
  • All contracts & app code is for demo. No guarantees.
  • Helia runs a browser IPFS node; for production youโ€™d pin through a gateway/pinning service.

๐Ÿž Troubleshooting

  • โ€œwrong networkโ€ โ†’ wallet must be Base Sepolia (84532)
  • โ€œexecution reverted NOT_MEMBERโ€ โ†’ call Join first
  • Faucet fails โ†’ faucet has cooldown; wait or use a 2nd account
  • IPFS errors โ†’ check browser permissions; retry (Helia boot takes a moment)

๐Ÿ“ฆ NPM Scripts

{
  "dev": "next dev -p 3000",
  "build": "next build",
  "start": "next start",
  "prisma:push": "prisma db push",
  "prisma:studio": "prisma studio"
}

โš–๏ธ License

License: MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors