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

# How it works

> The v2 trade lifecycle: ad → order → lock → co-sign → aggregate → prove → unlock

A trade moves through six states:

```
Open → Locked → Signed (2/2) → Aggregated → Settling → Filled
```

```mermaid theme={null}
sequenceDiagram
    participant M as Maker
    participant AC as Ad chain<br/>(AdManager)
    participant R as Relayer<br/>(coordinator)
    participant OC as Order chain<br/>(OrderPortal)
    participant B as Bridger

    M->>AC: escrow liquidity (ad)
    B->>OC: create + fund order
    M->>AC: lock for order
    Note over AC,OC: both deposits appended to each chain's MMR — state: Locked
    M->>R: BLS co-signature σ₁
    B->>R: BLS co-signature σ₂
    Note over R: Signed (2/2) → aggregate σ₁+σ₂ → generate deposit proofs
    R->>AC: unlock (agg sig + proof of order-chain deposit)
    R->>OC: unlock (agg sig + proof of ad-chain deposit)
    Note over AC,OC: contracts verify registry keys, pairing, proof, nullifier
    AC-->>B: bridged funds to bridger's recipient
    OC-->>M: funds to maker's recipient
```

## 1. The maker posts an ad

A maker escrows liquidity in the **AdManager** on their chain and publishes
a route (say, USDC on Sepolia → USDC on Stellar) with limits and a price.

## 2. The bridger opens an order

The bridger picks an ad, creates an order, and funds it — their tokens go
into the **OrderPortal** escrow on the order chain. Creating an order
reserves the matching slice of the maker's ad; unfunded reservations expire
automatically, so abandoned checkouts never strand maker liquidity.

## 3. The maker locks

The maker (or their bot) locks the matching funds from the ad. Both escrows
are now committed to this specific trade: state **Locked**.

Each deposit is appended to that chain's **Merkle Mountain Range** — an
append-only tree the deposit proofs are built against.

## 4. Both parties co-sign

Once both deposits are confirmed, each party signs a fixed settlement
message — the **SettlementAuth** — with their registered BLS key. The
message binds the exact order and both chains' Merkle roots, so a signature
can't be replayed against different state.

Signing is silent (no wallet transaction — the settlement key signs
locally) and the two parties sign independently. Counter shows
**Signed (2/2)** when both are in.

## 5. Background workers finish the trade

From here everything is automatic:

1. **Aggregate** — the two BLS signatures combine into one.
2. **Prove** — a zero-knowledge proof is generated per side showing the
   counterparty's deposit is included in the other chain's Merkle root.
   Proof generation takes seconds.
3. **Submit** — the relayer submits the unlock on each chain, paying gas.

State advances **Aggregated → Settling → Filled**.

## 6. On-chain verification

Each chain's `unlock` verifies three things before releasing funds:

* the **aggregated BLS signature** against the keys registered for the two
  party wallets in the on-chain `BLSKeyRegistry`
* the **zero-knowledge deposit proof** against the counterparty chain's
  Merkle root
* the **nullifier** — each deposit can be unlocked exactly once

Unlocks are permissionless: the transaction data is public and funds always
reach the hash-bound recipient regardless of who submits.

<Note>
  There is no ProofBridge approval anywhere in this flow. The pre-auth
  authorization token and signature parameters from v1 no longer exist in
  the contracts.
</Note>
