Tempo Books is a full-stack accounting and invoicing platform I built for businesses that operate with stablecoins on the Tempo blockchain. The idea started from a real frustration — there's no QuickBooks or Xero for on-chain payments. If you're a freelancer getting paid in pathUSD or a company paying contractors in AlphaUSD, you're stuck with spreadsheets and manual reconciliation. I wanted to fix that.
At its core, Tempo Books handles the entire lifecycle of stablecoin payments — from creating an invoice to receiving payment to generating financial reports. But the interesting part is how deeply it leans into Tempo's unique blockchain primitives to do things that simply aren't possible on other chains.
Every invoice you create gets a unique 32-byte memo ID (inspired by ISO 20022 payment references). When you send an invoice to a client, they get a clean payment link. They connect their wallet, hit pay, and the transferWithMemo transaction carries that memo on-chain.
Here's the magic: a background watcher monitors incoming transactions. When it sees a payment with a matching memo, the invoice is automatically marked as paid — no human in the loop. On chains without native memo support, you'd need some fragile off-chain matching system. On Tempo, it's just how transfers work.
Groups of people can track shared expenses and settle debts on-chain. The app calculates who owes whom using a debt simplification algorithm (minimizing the total number of transfers needed), and each settlement is a real on-chain transaction with a traceable memo. Useful for teams, DAOs, or just splitting dinner.
Need to pay 50 contractors at once? Upload a CSV and Tempo Books dispatches all the payments in parallel using Tempo's 2D nonce architecture. On most blockchains, you'd need to send transactions one-by-one and pray none fail mid-sequence. On Tempo, they all go out simultaneously and settle in under a second.
The app integrates Tempo's enshrined DEX directly — no third-party router, no bridge. You can swap between any of the four TIP-20 stablecoins (pathUSD, AlphaUSD, BetaUSD, ThetaUSD) with real-time quotes and configurable slippage. This also powers the auto-convert feature: if you prefer to hold everything in pathUSD, incoming payments in other tokens can be swapped automatically.
Configure a tax percentage and a tax wallet in settings. When an invoice payment lands, the system automatically splits the funds — operating capital stays in your wallet, tax reserve goes to the designated address with a TAX:INV-... memo. No forgetting to set aside taxes at the end of the quarter.
Set up billing templates with weekly, biweekly, monthly, quarterly, or yearly schedules. The system generates real invoices with unique memos when each billing period arrives. Set it and forget it.
Period-based reporting with revenue by token, expenses by category, top clients by revenue, cash flow over time, and invoice performance metrics. Everything exportable to CSV so you can hand it to your accountant or import into whatever legacy system you need to.
Each invoice has a shareable payment link. The client doesn't need an account — they just open the link, connect a wallet (via Privy), and pay. The payment page shows the full invoice breakdown and handles the on-chain transfer.
A complete transaction history with income/expense categorization, token filtering, date ranges, and CSV export. Essentially the general ledger that ties everything together.
- Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS 4, shadcn/ui
- Auth: Privy (supports email, phone, Google, MetaMask — all map to wallets)
- Blockchain: Official Tempo SDK (
viem/tempo) for all on-chain interactions —Actions.token.transfer,Actions.dex.sell,Abis.tip20,Addressesfor system contracts - Database: PostgreSQL on Neon (serverless), Prisma ORM with
Decimalprecision for all monetary fields - State: TanStack React Query for data fetching and cache management
I'm using the official viem/tempo package throughout — not raw ABIs and manual contract calls. Here's how Tempo's primitives map to features:
| Tempo Primitive | What It Enables |
|---|---|
Actions.token.transfer with memo |
Invoice payments, tax splits, batch payouts, expense settlements |
| 32-byte structured memos | Auto-reconciliation (match payment → invoice by memo) |
| 2D nonce architecture | Parallel batch payout execution (all at once, not queued) |
Actions.dex.sell / Actions.dex.getSellQuote |
In-app token swaps via the enshrined DEX |
tempoModerato chain definition |
Proper Tempo transaction formatting (type 0x76) |
| Fee sponsorship | Zero gas for invoice payments — no friction for payers |
| Sub-second deterministic finality | Real-time reconciliation, not "wait for 12 confirmations" |
All four TIP-20 stablecoins on Tempo Moderato testnet:
- pathUSD —
0x20c0000000000000000000000000000000000000 - AlphaUSD —
0x20c0000000000000000000000000000000000001 - BetaUSD —
0x20c0000000000000000000000000000000000002 - ThetaUSD —
0x20c0000000000000000000000000000000000003
10 models handling the full financial lifecycle:
- Invoice — Line items, status tracking, memo-based reconciliation, FK to transactions
- RecurringInvoice — Templates for automated billing cycles
- Contact — Client/vendor directory with wallet addresses
- Transaction — On-chain transaction ledger (income/expense categorized)
- SwapTransaction — DEX swap history with rates
- PayoutBatch — Batch payment operations
- UserSettings — Tax split config, currency preferences, business info
- ExpenseGroup — Shared expense groups for splitting
- Expense — Individual expenses within a group
- Settlement — On-chain debt settlements with tx hashes
All monetary fields use Decimal @db.Decimal(18, 6) for financial precision — no floating point rounding errors.
- Node.js 18+
- PostgreSQL (or a free Neon database)
- A Privy app configured for Tempo Network
git clone https://github.com/Adwaitbytes/Tempo-Book.git
cd tempo-books
npm installCreate a .env file:
DATABASE_URL="postgresql://..."
NEXT_PUBLIC_PRIVY_APP_ID="your-privy-app-id"
PRIVY_APP_SECRET="your-privy-app-secret"
NEXT_PUBLIC_TEMPO_RPC_URL="https://rpc.moderato.tempo.xyz"
NEXT_PUBLIC_TEMPO_CHAIN_ID="42431"
NEXT_PUBLIC_TEMPO_EXPLORER="https://explore.tempo.xyz"
NEXT_PUBLIC_FEE_SPONSOR_URL="https://sponsor.testnet.tempo.xyz"
npx prisma db push
npx prisma generate
npm run devOpen http://localhost:3000 and connect your wallet.
src/
app/
page.tsx # Landing page (3D book animation)
pay/[id]/ # Public invoice payment page
dashboard/
page.tsx # Dashboard overview
invoices/ # Create, view, manage invoices
payments/ # Single payments & batch payouts
contacts/ # Contact directory
books/ # Transaction ledger
splits/ # Expense splitting & settlement
recurring/ # Recurring invoice templates
swap/ # DEX token swaps
reports/ # Financial reporting
links/ # Payment link management
settings/ # Tax split, preferences, business info
api/
invoices/ # Invoice CRUD, stats, reconciliation
splits/ # Expense groups, expenses, settlements
recurring/ # Recurring invoice management
contacts/ # Contact CRUD
transactions/ # Transaction ledger
settings/ # User preferences
reconcile/watch/ # On-chain payment detection
swaps/ # DEX swap history
reports/ # Financial report generation
hooks/
use-send-payment.ts # Single transfer with memo
use-batch-payout.ts # Parallel batch payouts (2D nonces)
use-swap.ts # DEX swap (approve + sell)
use-tax-split.ts # Auto tax withholding
use-settle-debt.ts # Expense split settlement
use-auto-reconcile.ts # Background payment watcher
lib/
tempo.ts # Tempo SDK setup, balance queries, explorer URLs
constants.ts # Token list, SDK addresses, system contracts
dex.ts # DEX quote fetching via SDK
memo.ts # Memo encoding/decoding
invoice-utils.ts # Invoice formatting helpers
prisma.ts # DB client with retry logic
| Method | Route | Description |
|---|---|---|
| GET/POST | /api/invoices |
List and create invoices |
| GET/PUT/DELETE | /api/invoices/[id] |
Single invoice operations |
| GET | /api/invoices/stats |
Aggregated invoice statistics |
| POST | /api/invoices/reconcile |
Match payment to invoice by memo |
| GET/POST | /api/splits |
List and create expense groups |
| GET/DELETE | /api/splits/[id] |
Single expense group operations |
| POST | /api/splits/[id]/expenses |
Add expense to group |
| POST | /api/splits/[id]/settle |
Record on-chain settlement |
| GET/POST | /api/recurring |
Recurring invoice templates |
| PUT/DELETE | /api/recurring/[id] |
Update/delete templates |
| POST | /api/recurring/generate |
Generate due invoices |
| GET/POST | /api/contacts |
Contact directory |
| PUT/DELETE | /api/contacts/[id] |
Update/delete contacts |
| GET/POST | /api/transactions |
Transaction ledger |
| GET/PUT | /api/settings |
User settings |
| POST | /api/reconcile/watch |
On-chain payment detection |
| GET/POST | /api/swaps |
DEX swap history |
| GET | /api/reports |
Financial reports |
I didn't just pick Tempo because it was the hackathon chain. These features genuinely require Tempo's primitives:
-
Structured memos are native. The 32-byte memo on
transferWithMemois what makes auto-reconciliation work. On chains without this, you'd need off-chain databases or oracle infrastructure to match payments to invoices — fragile and expensive. -
Parallel execution is built in. The 2D nonce system means I can fire off 50 batch payments simultaneously and they all land in the same block. On sequential-nonce chains (basically everything else), you queue transactions and cross your fingers.
-
Finality is deterministic and fast. When my watcher sees a payment, it's final. No waiting for 12 confirmations, no reorg risk. The invoice gets marked as paid in under a second.
-
The DEX is enshrined. Swaps are a protocol primitive, not a third-party AMM that could get exploited or lose liquidity. This makes auto-conversion and treasury management reliable enough for a real business to depend on.
-
Fees are sponsorable. My clients don't pay gas when they pay invoices. That's a huge UX win — the payment link works more like a Venmo request than a crypto transaction.
MIT