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

# Escrow

> Holds depositors' USDC and their rail terms, and pays out only through the orchestrator.

The escrow holds every depositor's USDC in one contract, with a balance record per depositor. Unlocked USDC is the depositor's to withdraw at any time. Locked USDC belongs to one open order and moves only when the orchestrator says so.

## State

```rust theme={null}
pub struct RailTerms {
    pub currency: Symbol,          // ISO 4217, for example PHP
    pub min_rate_e6: i128,         // fiat minor units per 1 USDC, × 10^6
    pub payee_id_hash: BytesN<32>, // hash of the account that receives payments
}

pub struct ProviderBalance {
    pub token: Address,
    pub total_deposited: i128,     // 7-decimal Circle USDC
    pub locked: i128,
    pub rails: Map<Symbol, RailTerms>,
    pub allowed_takers: Vec<Address>, // empty = anyone
    pub trust_tier: u32,
}
```

## Functions

| Function | Caller | What it does |
| - | - | - |
| `deposit(provider, amount)` | Depositor | Transfers USDC in, then adds it to `total_deposited` |
| `set_rail_terms(provider, rail, terms)` | Depositor | Sets currency, minimum rate and payee hash for a rail. Fails while `locked > 0` |
| `set_allowed_takers(provider, takers)` | Depositor | Limits who can open orders. Applies to new orders only |
| `withdraw(provider, amount)` | Depositor | Withdraws up to `total_deposited − locked` |
| `lock_for_intent(...)` | Orchestrator | Locks an amount for an order and records the taker |
| `unlock_for_intent(intent_hash)` | Orchestrator | Returns a lock to the depositor's free balance |
| `release(intent_hash, fee, fee_recipient)` | Orchestrator | Pays `lock.amount − fee` to the taker and `fee` to the fee recipient, then removes the lock |
| `rail_terms(provider, rail)` | Anyone | Reads a depositor's terms for a rail |

## Guarantees

* **Solvency.** A lock succeeds only when `amount ≤ total_deposited − locked`. Across all depositors, `Σ locked ≤ Σ total_deposited ≤ USDC balance of the escrow`.
* **Full release only.** `release` always pays the whole lock, so no remainder can be stranded.
* **Stable terms.** Rail terms cannot change while the depositor has any open lock. A taker who paid the shown account can always settle.
* **Withdraw is unilateral.** `withdraw` needs only the depositor's signature. No Pesa key is involved.

## Sell orders

A sell is a deposit by the user. The user sets rail terms with their own payee hash and names the LP in `set_allowed_takers`. The LP then opens the order as the taker.


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