Skip to main content
A stream is the foundational agreement in Aven. When an employer creates a stream, the full project budget is transferred directly into a Soroban smart contract on Stellar and held in escrow until verified work is approved. No funds move until a session has been verified, reviewed, and released — and the contract enforces every payment calculation independently. The sender is the employer who funds the stream. The recipient is the freelancer or worker who delivers the work and receives payments.

Stream Lifecycle

A stream moves through well-defined states from creation to completion. The sender controls pausing and cancellation; completion happens automatically when the full budget has been released.

Stream Fields

Every stream stored on-chain includes the following fields:
Stream IDs are sequential integers. The sender and recipient addresses are Stellar public keys beginning with G.

Stream Statuses

The stream is open and accepting new work sessions. The recipient can submit sessions, request review, and withdraw approved payments. The sender can approve, dispute, pause, or cancel.
The sender has paused the stream. Existing pending or approved withdrawal records can still be resolved, but no new work sessions can be verified while the stream is paused. The sender can resume at any time.
The sender has cancelled the stream. All remaining unreserved escrow is refunded to the sender. Cancellation is only permitted when there are no outstanding reserved (pending) withdrawals — all open sessions must be resolved first.
The stream transitions to Completed automatically when the final withdrawal brings total_withdrawn equal to total_deposited. No further sessions can be submitted. A StreamCompletion attestation is minted at this point for reputation scoring.

Escrow Mechanics

All deposited funds are held by the stream contract itself — not by Aven, and not in any off-chain account. The contract exposes two read functions that reflect the current state of escrow at any moment:
  • compute_available — returns the unreserved escrow balance: total_deposited − total_withdrawn − currently_reserved. This is the amount still available for future sessions.
  • compute_earned — returns the total value already measured by submitted sessions: total_withdrawn + currently_reserved.
When a session is verified, the calculated amount is added to the reserved total. When a session is withdrawn, it moves from reserved to withdrawn and the tokens leave the contract to the recipient’s wallet.

Withdrawal Cap

The withdrawable_cap_percent field is a legacy field that was used in earlier contract versions to limit how much of the escrow could be released per session as a percentage of the total. In the current work-session flow, this field is retained in the StreamRecord struct for backwards-compatible client decoding but is not enforced — the payment cap is instead determined by the unreserved escrow balance at the time of verification.

Approval Timeout

Every stream is created with an approval_timeout_ledgers value. When a verified session is submitted, the contract records a deadline_ledger equal to the current ledger plus this timeout. If the employer has not approved or disputed the session by the time deadline_ledger is reached, the session enters a state where it can be finalized by the recipient without employer action. This protects workers from funds being withheld indefinitely through inaction.
Stellar produces approximately one ledger every 5 seconds. An approval_timeout_ledgers value of 17,280 corresponds to roughly 24 hours.

Creating a Stream

Streams are created from the /stream/create page in the Aven dashboard using a guided four-step form. The sender must have a Freighter wallet connected to Stellar testnet with sufficient XLM or USDC balance. The full budget (total_deposited) must be at least rate_per_second × duration_in_seconds to satisfy the contract’s deposit requirement. The entire amount is transferred to the contract at the moment the transaction is signed.