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

# Stream Contract: Payment Escrow and Verification

> The Aven stream contract locks client funds, manages the full payment lifecycle, and orchestrates atomic worker payouts paired with on-chain attestations.

The stream contract is Aven's payment escrow engine. It holds client funds, controls the payment lifecycle, and orchestrates the atomic verification-and-payout process. When a client creates a stream, tokens are immediately transferred into the contract and held until a verified work session is confirmed — at which point the worker is paid and an attestation is minted in the same indivisible Stellar transaction.

## Contract Address

**Testnet:** `CAZSE5UHSWNF62K26OZKOL7BSFB2647CXRPOICHUDCUJ5EKS4NCOA6ZA`

## Key Functions

### For Clients

<ResponseField name="create_stream" type="function → u64">
  Creates a new payment stream and immediately locks the client's funds in the contract. Returns the new `stream_id`.

  **Parameters:**

  * `sender` — The client's Stellar address (must authorize)
  * `recipient` — The worker's Stellar address
  * `rate_per_second` — Payment rate in stroops per second
  * `asset` — Token contract address (USDC or XLM)
  * `total_deposited` — Total amount to lock in escrow (stroops)
  * `duration_ledgers` — Stream duration in Stellar ledgers
  * `checkpoint_count` — Number of payment checkpoints (1–30)
  * `withdrawable_cap_percent` — Percentage of earned funds releasable before checkpoint approval
  * `approval_timeout_ledgers` — Ledgers before a pending request auto-releases
  * `category` — Work category (`Freelance`, `Salary`, `Bounty`, `Grant`, `AgentTask`, `Subscription`)
  * `title` — Human-readable stream name (max 80 bytes)
</ResponseField>

<ResponseField name="pause_stream" type="function → ()">
  Pauses an active stream, freezing the payment clock. Only the sender (client) may call this. The stream accumulates `paused_duration_ledgers` so that elapsed time is tracked accurately on resume.

  **Parameters:**

  * `stream_id` — ID of the stream to pause
  * `caller` — Must match the stream sender
</ResponseField>

<ResponseField name="resume_stream" type="function → ()">
  Resumes a paused stream and restarts the payment clock from where it stopped. Only the sender may call this.

  **Parameters:**

  * `stream_id` — ID of the stream to resume
  * `caller` — Must match the stream sender
</ResponseField>

<ResponseField name="cancel_stream" type="function → ()">
  Cancels an active or paused stream. Earned-but-unpaid funds are transferred to the worker immediately; remaining unearned funds are refunded to the client.

  **Parameters:**

  * `stream_id` — ID of the stream to cancel
  * `caller` — Must match the stream sender
</ResponseField>

<ResponseField name="approve_withdrawal" type="function → ()">
  Explicitly approves a pending withdrawal request, allowing the worker to claim funds without waiting for the auto-release timeout.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `sender` — Must match the stream sender
  * `request_id` — The withdrawal request identifier
</ResponseField>

<ResponseField name="dispute_withdrawal" type="function → ()">
  Marks a pending withdrawal request as disputed, preventing auto-release and freeing the reserved funds back into the withdrawable pool.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `sender` — Must match the stream sender
  * `request_id` — The withdrawal request identifier
</ResponseField>

<ResponseField name="approve_checkpoint" type="function → u64">
  Explicitly approves a submitted checkpoint, triggering immediate finalization and attestation minting. Returns the new `attestation_id`.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `sender` — Must match the stream sender
  * `index` — Zero-based checkpoint index
</ResponseField>

### For Workers

<ResponseField name="request_withdrawal" type="function → ()">
  Submits a withdrawal request for a completed work period. Only available when no verifier is configured on the contract. When a verifier is set, use the dashboard flow instead — the verifier calls `verify_work` on your behalf.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `recipient` — Must match the stream recipient (must authorize)
  * `request_id` — Unique string identifier for this request (max 64 bytes)
  * `amount` — Amount to request in stroops
</ResponseField>

<ResponseField name="withdraw_approved" type="function → i128">
  Executes an approved (or auto-released) withdrawal, transferring tokens to the worker and minting an attestation atomically. Returns the amount transferred.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `recipient` — Must match the stream recipient (must authorize)
  * `request_id` — The approved withdrawal request identifier
</ResponseField>

<ResponseField name="submit_checkpoint" type="function → ()">
  Submits evidence for a checkpoint period, signalling to the client that work is ready for review.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `worker` — Must match the stream recipient (must authorize)
  * `index` — Zero-based checkpoint index
  * `evidence_hash` — 32-byte SHA-256 hash of the work evidence
</ResponseField>

### Verifier-Only (Dashboard)

<ResponseField name="verify_work" type="function → ()">
  Called by the Aven dashboard's verifier key after validating a work session report. Creates a `WithdrawalRecord` with the verified evidence hash and reserves the funds for payout. The worker then calls `withdraw_approved` to complete the transfer and mint the attestation.

  **Parameters:**

  * `stream_id` — ID of the stream
  * `request_id` — Unique session identifier (max 64 bytes)
  * `amount` — Verified payment amount in stroops
  * `evidence_hash` — 32-byte hash of the verified session report
  * `active_duration_seconds` — Active working seconds in the session
  * `work_start_ledger` — Ledger sequence when the session started
</ResponseField>

### Read Functions

<ResponseField name="get_stream" type="function → StreamRecord">
  Returns the full `StreamRecord` for the given stream ID.
</ResponseField>

<ResponseField name="get_sender_streams" type="function → Vec<u64>">
  Returns all stream IDs where the given address is the sender.
</ResponseField>

<ResponseField name="get_recipient_streams" type="function → Vec<u64>">
  Returns all stream IDs where the given address is the recipient.
</ResponseField>

<ResponseField name="compute_available" type="function → i128">
  Returns the amount currently available for withdrawal — earned funds minus already-reserved pending requests.
</ResponseField>

<ResponseField name="compute_earned" type="function → i128">
  Returns the total earned (withdrawable) amount for the stream based on elapsed active ledgers and checkpoint unlock status.
</ResponseField>

<ResponseField name="get_withdrawal" type="function → WithdrawalRecord">
  Returns the `WithdrawalRecord` for a specific `(stream_id, request_id)` pair.
</ResponseField>

<ResponseField name="get_checkpoint" type="function → CheckpointRecord">
  Returns the `CheckpointRecord` for a specific `(stream_id, index)` pair.
</ResponseField>

<ResponseField name="settle_checkpoints" type="function → u32">
  Scans all elapsed checkpoint periods for the given stream and finalizes any that are unlocked (either explicitly approved or past the auto-approval timeout). Returns the number of checkpoints settled. Can be called by anyone.

  **Parameters:**

  * `stream_id` — ID of the stream to settle
</ResponseField>

## StreamRecord Fields

The `StreamRecord` struct is returned by `get_stream`. Its fields describe the full state of a payment stream.

<ResponseField name="id" type="u64">
  Unique auto-incrementing stream identifier assigned at creation.
</ResponseField>

<ResponseField name="sender" type="Address">
  The client's Stellar address — the account that funded the stream.
</ResponseField>

<ResponseField name="recipient" type="Address">
  The worker's Stellar address — the account that receives payments.
</ResponseField>

<ResponseField name="rate_per_ledger" type="i128">
  Payment rate in stroops per Stellar ledger, derived from the per-second rate at creation (`rate_per_second × 5`).
</ResponseField>

<ResponseField name="asset" type="Address">
  Token contract address for the streaming asset (USDC or native XLM).
</ResponseField>

<ResponseField name="total_deposited" type="i128">
  Total amount locked in escrow at stream creation, in stroops.
</ResponseField>

<ResponseField name="total_withdrawn" type="i128">
  Cumulative amount already paid out to the worker, in stroops.
</ResponseField>

<ResponseField name="start_ledger" type="u32">
  Stellar ledger sequence number at which the stream was created.
</ResponseField>

<ResponseField name="duration_ledgers" type="u32">
  Total stream duration in Stellar ledgers (approximately 5 seconds each).
</ResponseField>

<ResponseField name="status" type="StreamStatus">
  Current lifecycle state: `Active`, `Paused`, `Completed`, or `Cancelled`.
</ResponseField>

<ResponseField name="category" type="Category">
  Work category used to classify the attestations minted from this stream: `Freelance`, `Salary`, `Bounty`, `Grant`, `AgentTask`, or `Subscription`.
</ResponseField>

<ResponseField name="title" type="String">
  Human-readable stream name (max 80 UTF-8 bytes), stored on-chain and copied to every attestation.
</ResponseField>

<ResponseField name="checkpoint_count" type="u32">
  Number of payment checkpoints dividing the stream duration (1–30).
</ResponseField>

<ResponseField name="checkpoint_span_ledgers" type="u32">
  Ledgers per checkpoint period (`duration_ledgers / checkpoint_count`).
</ResponseField>

<ResponseField name="withdrawable_cap_percent" type="u32">
  Percentage of earned funds available before a checkpoint is approved (0–100). Acts as a client protection mechanism.
</ResponseField>

<ResponseField name="approval_timeout_ledgers" type="u32">
  Number of ledgers a withdrawal request remains pending before it auto-releases without explicit client approval.
</ResponseField>

<ResponseField name="paused_at_ledger" type="u32">
  Ledger sequence when the stream was last paused. `0` when the stream is active.
</ResponseField>

<ResponseField name="paused_duration_ledgers" type="u32">
  Cumulative ledgers the stream has spent in the `Paused` state. Subtracted from elapsed time during payout calculations.
</ResponseField>

## Error Codes

| Code | Name                         | Meaning                                                                    |
| ---- | ---------------------------- | -------------------------------------------------------------------------- |
| 1    | `AlreadyInitialized`         | Contract `init` has already been called                                    |
| 2    | `NotInitialized`             | Contract has not been initialized yet                                      |
| 3    | `InvalidRate`                | `rate_per_second` is zero or negative                                      |
| 4    | `InvalidDeposit`             | `total_deposited` is zero or negative                                      |
| 5    | `InvalidDuration`            | `duration_ledgers` is zero                                                 |
| 6    | `TitleTooLong`               | Title exceeds 80 UTF-8 bytes                                               |
| 7    | `InsufficientDeposit`        | Deposit does not cover the full stream at the given rate                   |
| 8    | `StreamNotFound`             | No stream exists for the given stream ID                                   |
| 9    | `NotSender`                  | Caller is not the stream sender                                            |
| 10   | `NotRecipient`               | Caller is not the stream recipient                                         |
| 11   | `WrongStatus`                | Stream is not in the required status for this operation                    |
| 12   | `NothingToWithdraw`          | No earned funds are available                                              |
| 13   | `Overflow`                   | Arithmetic overflow during calculation                                     |
| 14   | `HistoryFull`                | The stream index for this address has reached the maximum of 1,000 entries |
| 15   | `InvalidCheckpointCount`     | Checkpoint count is zero or exceeds 30                                     |
| 16   | `DurationNotDivisible`       | Duration is not evenly divisible by checkpoint count                       |
| 17   | `InvalidCapPercent`          | `withdrawable_cap_percent` exceeds 100                                     |
| 18   | `InvalidTimeout`             | `approval_timeout_ledgers` is zero                                         |
| 19   | `IndexOutOfRange`            | Checkpoint index is greater than or equal to `checkpoint_count`            |
| 20   | `CheckpointNotSubmitted`     | Checkpoint has not been submitted by the worker yet                        |
| 21   | `CheckpointAlreadyFinalized` | Checkpoint has already been finalized and paid                             |
| 22   | `InvalidRequestId`           | Request ID is empty or exceeds 64 bytes                                    |
| 23   | `InvalidAmount`              | Requested amount is zero or negative                                       |
| 24   | `AmountExceedsWithdrawable`  | Request exceeds currently available earned funds                           |
| 25   | `WithdrawalNotFound`         | No withdrawal record for the given `(stream_id, request_id)`               |
| 26   | `WithdrawalAlreadyExists`    | A withdrawal request with this ID already exists                           |
| 27   | `WithdrawalNotApproved`      | Withdrawal is still pending and the timeout has not elapsed                |
| 28   | `WithdrawalDisputed`         | Withdrawal has been disputed by the client                                 |
| 29   | `WithdrawalApprovalRequired` | Direct withdrawal is disabled; use the approval flow                       |
| 30   | `NotAdmin`                   | Caller is not the contract admin                                           |
| 31   | `VerifierNotConfigured`      | `verify_work` called but no verifier is set                                |
| 32   | `VerificationRequired`       | Verifier is set; `request_withdrawal` is disabled                          |

<Note>
  Clients interact with the stream contract through the Aven dashboard, which handles wallet authorization and verifier coordination automatically. Direct contract invocation is possible via [Stellar Lab](https://lab.stellar.org) or the Stellar CLI for advanced users who want to inspect or interact with streams programmatically.
</Note>
