> ## 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.

# Combinators

> Compose conditions with And, Or, and Not logical operators

## Overview

Combinator conditions compose two or more conditions with logical operators. Deploy each via its respective factory.

## AndCondition

All conditions must pass (`A && B && C`).

```typescript theme={null}
// Deploy via factory
const comboAddress = await andConditionFactory.write.deploy([
  [RECEIVER_CONDITION, ESCROW_PERIOD_ADDRESS]  // Must be receiver AND after escrow
]);

// Use in operator config
config.capturePreActionCondition = comboAddress;
```

**Example:** Capture requires receiver AND escrow period passed.

## OrCondition

At least one condition must pass (`A || B`).

```typescript theme={null}
// Receiver OR Arbiter can capture
const comboAddress = await orConditionFactory.write.deploy([
  [RECEIVER_CONDITION, ARBITER_CONDITION]
]);

config.capturePreActionCondition = comboAddress;
```

**Example:** Either receiver or arbiter can capture.

## NotCondition

Inverts a condition (`!A`).

```typescript theme={null}
// Anyone EXCEPT payer can call
const comboAddress = await notConditionFactory.write.deploy([PAYER_CONDITION]);

config.capturePreActionCondition = comboAddress;
```

**Example:** Prevent payer from releasing their own payment.

## Nested Combinators

Combine combinators for complex logic:

```typescript theme={null}
// (Receiver OR Arbiter) AND EscrowPassed
const receiverOrArbiter = await orConditionFactory.write.deploy([
  [RECEIVER_CONDITION, ARBITER_CONDITION]
]);

const capturePreActionCondition = await andConditionFactory.write.deploy([
  [receiverOrArbiter, ESCROW_PERIOD_ADDRESS]
]);

config.capturePreActionCondition = capturePreActionConditionAddress;
```

**Logic Tree:**

```mermaid theme={null}
flowchart TD
    AND[AndCondition] --> OR[OrCondition]
    AND --> ESC[EscrowPeriod ✓]
    OR --> REC[ReceiverCondition ✓]
    OR --> ARB[ArbiterCondition ✗]
    AND --> RES[Result: PASS]
```

(One branch of OR passed, AND both passed)

## Limits

<Warning>
  **Max 10 conditions per combinator.** Keep combinators simple. Nested trees increase gas costs and make debugging harder.
</Warning>

## Gas

Simpler combinators = less gas:

```typescript theme={null}
// Better: 2 conditions
OrCondition([A, B])  // ~25K gas per check

// Worse: 4 conditions
OrCondition([A, B, C, D])  // ~45K gas per check
```

Each extra condition adds one external call. Prefer fewer conditions where possible.

## Next Steps

<CardGroup cols={2}>
  <Card title="EscrowPeriod" icon="clock" href="/contracts/conditions/escrow-period">
    Time-based condition for escrow windows.
  </Card>

  <Card title="Freeze" icon="snowflake" href="/contracts/conditions/freeze">
    Block releases on frozen payments.
  </Card>

  <Card title="Examples" icon="code" href="/contracts/examples">
    See combinators in real configurations.
  </Card>

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