Skip to main content

System overview

Sendall is a Next.js app (App Router, React 19) backed by PostgreSQL through Prisma, talking to Stellar through its RPC service rather than Horizon. There's no separate backend service: API routes under src/app/api are the entire server side.

Stack

LayerChoice
FrameworkNext.js 16 (App Router), TypeScript
DatabasePostgreSQL, accessed through Prisma 7
Blockchain@stellar/stellar-sdk, talking to Stellar RPC (not Horizon)
Wallets@creit.tech/stellar-wallets-kit, supporting Freighter, xBull, Albedo, Lobstr, Rabet, and Stellar Hot Wallet
AuthCustom SEP-53 sign-in, JWT sessions, rotating refresh tokens (see Authentication)
StylingTailwind CSS 4, no component library
TestingVitest for unit and integration tests, Playwright for end-to-end tests against a real Freighter build

Why RPC instead of Horizon

Two operations Sendall depends on heavily are cheaper and simpler through RPC than through Horizon: getLedgerEntries, used to bulk-check up to 200 accounts or trustlines in a single call (see Check balance and checkRecipients in src/lib/stellar/balanceCheck.ts), and sendTransaction / getTransaction, used to submit and poll a transaction without needing to reconstruct its result format from a REST response. Horizon isn't used anywhere in the codebase.

Directory layout

src/
app/
(app)/ route group for every authenticated-shell page
home/
batches/
new/
[batchId]/
address-lists/
check-balance/
demo/
api/ every server route, grouped by resource
page.tsx marketing landing page (no shell)
components/
shell/ AppShell: sidebar, top bar, layout
wallet/ WalletProvider, ConnectButton
batches/ BatchStageNav, RecipientsEditor
lib/
auth/ session, refresh tokens, anon sessions, batch access
stellar/ SIWS, RPC client, tx building, balance checks, submission
csv/ CSV parsing for batches and address lists
db/ Prisma client singleton
wallet/ wallet-kit initialization
prisma/
schema.prisma

Where to go next

  • Data model for the full Prisma schema and what each field means.
  • Authentication for how a wallet signs in without a transaction, and how sessions stay alive.
  • Transaction building for the chunking mechanism that keeps a large batch to one signature.
  • API reference for every route, grouped the same way the codebase is.