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

# EscrowPeriod

> Time-lock condition that records authorization time and enforces escrow windows

## Overview

EscrowPeriod is a dual-purpose contract, it functions as both a **hook** and a **condition**:

* **As a hook:** Records the `block.timestamp` at payment authorization
* **As a condition:** Returns `true` only after the escrow period has elapsed

Use the **same address** for both `AUTHORIZE_POST_ACTION_HOOK` and `CAPTURE_PRE_ACTION_CONDITION` slots on the operator.

**Type:** Per-deployment via [EscrowPeriodFactory](/contracts/factories)

## Architecture

```mermaid theme={null}
flowchart LR
    EP[EscrowPeriod] -->|extends| ATR[AuthorizationTimeRecorderHook]
    EP -->|implements| IC[ICondition]
    ATR -->|implements| IR[IHook]
```

EscrowPeriod extends [AuthorizationTimeRecorderHook](/contracts/hooks/authorization-time) and adds `ICondition` implementation. You don't need to deploy AuthorizationTimeRecorderHook on its own, use EscrowPeriod directly.

## Logic

```solidity theme={null}
// ICondition, returns true when escrow period has passed
function check(
    AuthCaptureEscrow.PaymentInfo calldata paymentInfo,
    uint256,
    address,
    bytes calldata
) external view returns (bool allowed) {
    return !isDuringEscrowPeriod(paymentInfo);
}

// View function to check if still in escrow period
function isDuringEscrowPeriod(
    AuthCaptureEscrow.PaymentInfo calldata paymentInfo
) public view returns (bool) {
    bytes32 hash = escrow.getHash(paymentInfo);
    uint256 authTime = authorizationTimes[hash];
    if (authTime == 0) return false;
    return block.timestamp < authTime + ESCROW_PERIOD;
}
```

**Checks:**

1. The payment has a recorded authorization timestamp
2. Current time >= authorization time + escrow period

## Deployment

Deploy via [EscrowPeriodFactory](/contracts/factories):

```typescript theme={null}
const escrowPeriodAddress = await escrowPeriodFactory.write.deploy([
  7 * 24 * 60 * 60,    // 7 days in seconds
  zeroHash             // bytes32(0) = operator-only
]);
```

Then configure the operator:

```typescript theme={null}
const config = {
  authorizePostActionHook: escrowPeriodAddress,   // Record auth time
  capturePreActionCondition: escrowPeriodAddress,    // Check escrow passed
  // ...
};
```

## Composition with Freeze

Compose this condition with a separate [Freeze](/contracts/conditions/freeze) condition via [AndCondition](/contracts/conditions/combinators) to gate capture on both escrow elapsed **and** not frozen. See [Composition Patterns](/contracts/conditions/freeze#composition-patterns) for the wiring.

## Use Cases

* **Time-lock releases**: 7-day escrow for e-commerce
* **Delayed fund access**: Grace period before receiver can access funds
* **Buyer protection**: Give payers time to freeze or request refunds

## Gas

**Cost:** \~20k gas per `run()` call (one `SSTORE` for the timestamp). The `check()` call is a `view` function with one `SLOAD`.

## Next Steps

<CardGroup cols={2}>
  <Card title="Freeze" icon="snowflake" href="/contracts/conditions/freeze">
    Add freeze protection to escrow periods.
  </Card>

  <Card title="Factories" icon="industry" href="/contracts/factories">
    Deploy EscrowPeriod via factory.
  </Card>
</CardGroup>
