https://paystream-app-seven.vercel.app
Connect your Freighter wallet on Stellar testnet to try it.
The reference frontend for PayStream — showing developers how to build on the soroban-paystream contract
Create, manage, and monitor per-second payment streams directly from your browser. No CLI, no manual transaction crafting — just connect a wallet and stream. Built on the soroban-paystream smart contract.
Overview • Features • Architecture • Getting Started • Project Structure • Contributing
paystream-app is the React + TypeScript frontend for the PayStream protocol. It talks directly to the deployed Soroban smart contract on Stellar and lets anyone create and manage payment streams without touching the command line.
A stream is a time-locked token deposit that drips into a recipient's claimable balance every second over a fixed window:
- The recipient can withdraw their accrued balance at any time.
- The sender can pause, resume, or cancel at any time.
- Nothing is escrowed off-chain and no balances are moved on a timer — the contract computes the claimable amount on demand from elapsed time. Only create, withdraw, and cancel cost gas.
Everything happens on-chain. This app is purely the interface: reads are simulated against the RPC (no gas, no signing), and writes are signed in your wallet and submitted to the network.
Token: The app currently streams native XLM via its Stellar Asset Contract. The underlying
soroban-paystreamcontract is token-agnostic and accepts any Soroban token address, so multi-asset support is a natural future extension.
The app connects to the PayStream contract deployed on Stellar testnet:
CC2SUYO3WFVMER3SKBUWM3JVI7P4OL73YD6NHWWUAN5OPY4AV46POAWE
- Wallet connection via Freighter, with auto-reconnect on page refresh
- Wrong-network detection — warns you if Freighter is pointed at mainnet
- Create streams by entering a recipient address, amount, and duration in days
- Personal dashboard showing every stream where you are the sender or the recipient
- Live claimable balance that refreshes every 10 seconds on active streams
- Per-second rate displayed on each stream card
- Role-gated actions — withdraw for recipients; pause, resume, and cancel for senders
- Human-readable errors mapped from every contract error code
- At-a-glance details — duration and start/end date range on each card
paystream-app/
│
├── src/
│ ├── config.ts ← contract ID, RPC URL, network config
│ ├── lib/
│ │ ├── contract.ts ← all contract reads and writes
│ │ ├── format.ts ← address, amount, duration formatters
│ │ └── errors.ts ← contract error code → message map
│ ├── hooks/
│ │ ├── useWallet.ts ← Freighter wallet connection state
│ │ └── useClaimable.ts ← live claimable polling hook
│ └── components/
│ ├── ConnectWallet.tsx ← wallet button and state display
│ ├── Dashboard.tsx ← fetches and renders all user streams
│ ├── StreamCard.tsx ← single stream display
│ ├── StreamActions.tsx ← withdraw, pause, resume, cancel buttons
│ └── CreateStreamForm.tsx ← new stream form
The codebase follows a strict layering rule that keeps it approachable for new contributors:
lib/— pure, framework-free logic. Contract calls, formatting, error mapping. No React.hooks/— stateful React logic. Wallet state, polling. No markup.components/— presentational. They receive data and render it; data fetching lives in hooks orDashboard.tsx.
Soroban has no separate "query" endpoint — everything is a transaction. The difference is whether we submit it.
Read (get_stream, get_claimable, get_streams_by_user, ...)
→ build operation
→ simulate against the RPC
→ decode the result
⇒ no gas, no signing, no wallet required
Write (create_stream, withdraw, pause, resume, cancel)
→ build operation with the sender's real sequence number
→ prepare transaction (Soroban footprint + resource fees + auth)
→ sign with Freighter
→ submit to the network
→ poll until confirmed
- Node.js 20+
- The Freighter wallet browser extension
- A funded Stellar testnet account
git clone https://github.com/OpenStreamFi/paystream-app.git
cd paystream-app
pnpm install
pnpm devOpen http://localhost:5173 in the browser that has Freighter installed.
If your Freighter wallet has no testnet XLM, visit Friendbot with your public key:
https://friendbot.stellar.org/?addr=YOUR_G_ADDRESS
Friendbot sends 10,000 free testnet XLM instantly.
In Freighter, go to Settings → Network → Testnet. The app displays a warning banner if your wallet is on the wrong network.
| File | Purpose |
|---|---|
src/config.ts |
Single source for contract ID, RPC URL, and network passphrase |
src/lib/contract.ts |
All contract interactions — reads via simulate, writes via sign-and-submit |
src/lib/format.ts |
Pure formatting functions for addresses, amounts, and durations |
src/lib/errors.ts |
Maps contract error codes to human-readable messages |
src/hooks/useWallet.ts |
Freighter connection, auto-reconnect, and network check |
src/hooks/useClaimable.ts |
Polls get_claimable every 10s for active streams only |
src/components/Dashboard.tsx |
Fetches stream IDs, then loads all streams in parallel |
src/components/StreamCard.tsx |
Displays one stream with live claimable and action buttons |
src/components/StreamActions.tsx |
Role-gated buttons based on the connected wallet address |
src/components/CreateStreamForm.tsx |
Form to create a new stream, with input validation |
- React 19 + TypeScript
- Vite for dev server and builds
- Tailwind CSS v4 for styling
- @stellar/stellar-sdk for network calls and transaction building
- @stellar/freighter-api for wallet connection and signing
- Freighter wallet connect with auto-reconnect
- Create stream form with validation
- Live dashboard with per-second claimable polling
- Withdraw, pause, resume, and cancel actions
- Landing page with hero, how-it-works, and features
- Site footer with on-chain details
- Incoming / outgoing role badges and stream counts
- Friendly, human-readable contract error messages
- TypeScript SDK (@openstreamfi/sdk) — letting any developer add payment streaming to their Stellar app with a simple npm install
- Multi-token support (beyond XLM)
- Batch stream creation
- Mainnet deployment
Contributions are welcome across every area — React components, TypeScript, Tailwind styling, testing, documentation, and accessibility.
Issues are labeled by difficulty. Good first issues are scoped for contributors new to the project and require no knowledge of the Soroban contract.
See CONTRIBUTING.md for the full workflow.
| Prefix | Use for |
|---|---|
feat: |
New feature |
fix: |
Bug fix |
test: |
Adding or updating tests |
docs: |
Documentation changes |
chore: |
Tooling, CI, config |
refactor: |
Code restructuring |
- soroban-paystream — the Soroban smart contract this app connects to
- OpenStreamFi — the GitHub organization
Released under the MIT License.