English · Español
StelFlow is a payment-streaming protocol for Stellar/Soroban: a sender locks a SEP-41 asset once, and the recipient's balance accrues continuously against Stellar ledger time instead of arriving as discrete transfers. Unlike a pure time-based stream, StelFlow can gate portions of a stream behind milestones, so funds keep accruing but stay unwithdrawable until a named approver verifies the condition.
Status: working MVP on Stellar testnet. Unaudited.
The contract is written, tested, and live on testnet. 75 tests pass. A dashboard drives every entry point, and CI gates both.
No audit, and nothing on mainnet. Do not put real value in this. The contract is non-upgradeable by design, so a bug found later cannot be patched — which raises the stakes on the audit that has not happened, rather than lowering them. See SECURITY.md.
Active development is paused here on purpose — see where this stops, and why.
Stellar has fast, cheap settlement and a native stablecoin story, but recurring value transfer on it is still a scheduling problem. Today you either send periodic payments from a bot or a treasury multisig, or you hold funds in an escrow that releases in a lump on approval. The first requires a live signer and trust that someone keeps paying; the second gives the recipient nothing until the whole tranche clears.
EVM has had continuous streaming for years — Sablier is the reference implementation, and vesting, payroll, and grant tooling grew on top of it. Soroban has escrow primitives (notably Trustless Work) but no general streaming primitive underneath them. StelFlow is meant to be that primitive, with one addition that pure streaming lacks: most real disbursements are not purely time-based. A grant is time-based and conditional. A vesting schedule has a cliff. A DAO contributor gets paid over the quarter but the last tranche depends on shipping.
So StelFlow combines three things that usually live in separate contracts:
- Continuous accrual — the recipient's claimable balance is a function of ledger time, computed on read, not pushed on a schedule.
- Milestone gates — a stream segment can be held until an approver marks its milestone met. Accrual continues; withdrawal does not.
- Cancel and clawback — the sender can stop a stream and recover the unstreamed remainder. Already-accrued funds stay with the recipient.
Target uses: grant disbursement, DAO payroll, and vesting with cliffs — the cases where a lump-sum escrow is too coarse and a cron job is too fragile.
This section used to say that Soroban's streaming projects were "hackathon-scale MVPs". That was wrong, and the survey that checked it is docs/comparison.md.
Two Soroban-native streaming projects — StellarStream and stellar-stream — are actively developed, both pushed within a week of the survey date and both carrying substantial contributor programmes. Neither is abandoned and neither deserved the description.
What did hold up is narrower: neither implements approver-gated milestones. Both are time-based linear streaming with cancellation. Nor does Sablier, the EVM reference — its "tranched" streams unlock on a clock, not on a signature, which is a different mechanism wearing a similar word.
So the honest claim is one feature, not a category: StelFlow gates tranches behind a named approver, and nothing surveyed does. Everything else it does is well-trodden. The full table, including where StelFlow must not claim a win, is in the survey.
flowchart TB
Sender(["Sender"])
Recipient(["Recipient"])
Approver(["Approver"])
subgraph OffChain["Off-chain"]
UI["React dashboard<br/>create, monitor, withdraw"]
SDK["TypeScript SDK<br/>typed client, accrual preview,<br/>tx assembly"]
IDX["Indexer<br/>ingests contract events,<br/>serves stream history"]
UI --> SDK
IDX -->|"history, aggregates"| SDK
end
RPC["Stellar RPC"]
subgraph OnChain["On-chain (Soroban)"]
SC["StelFlow Core<br/>stream state, accrual math,<br/>milestone gates"]
TOK["SEP-41 asset<br/>(SAC or custom token)"]
TW["Trustless Work escrow<br/>(optional integration)"]
SC -->|"transfer / transfer_from"| TOK
SC <-.->|"milestone approval"| TW
end
Sender --> UI
Recipient --> UI
Approver --> UI
SDK -->|"simulate + submit"| RPC
RPC --> SC
SC -.->|"events"| RPC
RPC -.->|"event stream"| IDX
classDef planned stroke-dasharray: 5 5
class IDX,TW planned
Solid components are built and running on testnet. Dashed ones are not: there is no indexer (the dashboard reads Stellar RPC's event log directly, which retains a rolling window rather than full history), and the Trustless Work integration is a design intention with no code and no conversation behind it. docs/architecture.md explains each component and why Soroban's constraints shape it the way they do.
| Layer | Choice | Notes |
|---|---|---|
| Contracts | Rust + soroban-sdk |
Built to the wasm32v1-none target; needs Rust 1.84+ |
| Assets | SEP-41 token interface | Works with the Stellar Asset Contract (SAC) and any SEP-41 token |
| Tooling | Stellar CLI (stellar) |
Formerly soroban-cli; stellar contract build, stellar contract deploy |
| SDK | TypeScript + @stellar/stellar-sdk |
Typed bindings generated from the contract spec |
| Dashboard | Next.js 16 + Tailwind 4 | App Router, Stellar Wallets Kit for Freighter and friends |
| Indexer | not built | The dashboard folds RPC's getEvents directly. the indexer spec specifies the service for when that stops being enough |
Everything lives in docs/, and every file there has a job.
| concepts.md | What money streaming and milestone gates mean, from zero — plus the glossary and the questions people actually ask |
| architecture.md | Components, data flow, and the Soroban constraints behind each choice |
| use-cases.md | Paying a team, funding work in stages, vesting over years |
| design-decisions.md | Upgradeability and pause, milestone revocation, milestone deadlines — each settled by removing a capability rather than guarding it |
| threat-model.md | Twelve threats ranked, with the risks we accept stated plainly |
| research.md | Measured findings on state archival, the indexer spec for work not yet built, and an honest survey of what else exists |
| the test suite | The behaviour spec, executable — written before the code, so the tests could not be shaped to fit it |
| testing.md | End-to-end walkthrough with a real wallet |
| deploy.md | Putting the app on Vercel |
| ROADMAP.md | What is built, what is next, and where development deliberately stops |
# 1. Toolchain
rustup target add wasm32v1-none # Rust 1.84+
brew install stellar-cli # or: cargo install --locked stellar-cli
pnpm install
# 2. Contract: 75 tests, then a Wasm build
pnpm contract:test
pnpm contract:build
# 3. Dashboard against the deployed testnet contract
pnpm dev # http://localhost:3000To use the dashboard you need Freighter (or any wallet the kit supports) set to testnet, with a funded account:
stellar keys generate --global alice --network testnet --fundDeploying your own instance instead of using the shared one:
stellar contract build
stellar contract deploy \
--wasm target/wasm32v1-none/release/stelflow.wasm \
--source alice --network testnet \
-- --pauser "\"$(stellar keys address alice)\""The pauser argument is a constructor parameter, so setup happens atomically with deployment — there
is no initialize for someone else to call first. Pass null to deploy with no pauser at all.
Then point deployments.json at the new contract id and run pnpm bindings.
Read CONTRIBUTING.md. Short version: issues labeled good first issue are scoped to be finishable without reading the whole design; comment on one before you start so two people don't write it twice. Design feedback on docs/ is welcome as an issue — at this stage a good argument against the storage layout is worth more than a PR.
Contributors are credited in CONTRIBUTORS.md.
Maintained by @jayteemoney, who previously built StackStream, a payment-streaming protocol on Stacks — around 1,100 lines of Clarity across two contracts, with a test suite and a documented security review.
Two things from that project carry directly into this one.
The first is design experience: the accrual math, the cancellation semantics, and a withdrawal API that had to be redesigned once are lessons applied here rather than learned again.
The second matters more if you're deciding whether to contribute. StackStream's security review was run as an open multi-auditor process — 11 independent contributors across four PRs and an issue thread, which found and fixed four real bugs including a missing recovery path and two griefing vectors. That review is published in full, false positives and deferred findings included. StelFlow intends to work the same way, which is why the issues here are scoped with acceptance criteria and why SECURITY.md already describes a disclosure process for a project with nothing to disclose yet.
StackStream is a separate codebase, not a preview of this one. Clarity and Rust/Soroban differ enough in storage model, fee model, and asset interface that porting was never on the table. Most of what makes StelFlow's design specific — the persistent-storage choice, TTL archival handling, the milestone cap forced by the per-transaction read budget — answers Soroban constraints that have no Stacks equivalent.
Apache-2.0. See LICENSE.