> ## Documentation Index
> Fetch the complete documentation index at: https://aven-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Streams: Escrow-Backed Work Agreements on Stellar

> A stream locks a project budget into Stellar smart contract escrow and releases exact payments only once verified work is reviewed and approved.

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.

```mermaid theme={null}
stateDiagram-v2
  [*] --> Active: create_stream
  Active --> Paused: pause_stream
  Paused --> Active: resume_stream
  Active --> Cancelled: cancel_stream
  Paused --> Cancelled: cancel_stream
  Active --> Completed: all funds released
  Paused --> Completed: all funds released
```

***

## Stream Fields

Every stream stored on-chain includes the following fields:

| Field | Type | Description |
| - | - | - |
| `stream_id` | `u64` | Sequential integer identifier assigned at creation |
| `sender` | `Address` | Stellar public key of the employer who funded the stream |
| `recipient` | `Address` | Stellar public key of the worker receiving payments |
| `asset` | `Address` | Token contract address — XLM (native SAC) or USDC |
| `rate_per_second` | `i128` | Payment rate in stroops per active second of verified work (stored on-chain as `rate_per_ledger` after multiplying by the ledger-per-second constant) |
| `total_deposited` | `i128` | Full budget locked in escrow at stream creation, in stroops |
| `duration_ledgers` | `u32` | Agreement duration expressed as a Stellar ledger count |
| `status` | `StreamStatus` | Current stream state: `Active`, `Paused`, `Cancelled`, or `Completed` |
| `category` | `Category` | Work type: `Freelance`, `Salary`, `Bounty`, `Grant`, `AgentTask`, or `Subscription` |
| `title` | `String` | Human-readable project title (maximum 80 bytes) |
| `approval_timeout_ledgers` | `u32` | Ledgers the employer has to review a session before it can be finalized |
| `withdrawable_cap_percent` | `u32` | Legacy field retained for contract decoding compatibility |

> [!NOTE]
>
> Stream IDs are sequential integers. The sender and recipient addresses are Stellar public keys beginning with `G`.

***

## Stream Statuses

> **Active**
>
> 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.

> **Paused**
>
> 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.

> **Cancelled**
>
> 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.

> **Completed**
>
> 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.

> [!NOTE]
>
> 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](https://aven-chi.vercel.app/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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.