---
updatedAt: 2026-07-21T08:25:53.000Z
agentTools:
  projectIndex: https://docs.liquid.net/llms.txt
---

# Waterfalls

Waterfalls is a server that provides fast wallet scanning for Liquid (and Bitcoin). Instead of querying each address individually like traditional Esplora or Electrum scanning, you send your descriptor and get back the complete wallet history in a single request.

## The problem Waterfalls solves

Traditional wallet sync works like this:

```mermaid
sequenceDiagram
  participant W as Your Wallet
  participant E as Esplora

  W->>W: Derive address 1
  W->>E: Get history for address 1
  E-->>W: History
  W->>W: Derive address 2
  W->>E: Get history for address 2
  E-->>W: History
  W->>W: Derive address N
  W->>E: Get history for address N
  E-->>W: History
  Note over W,E: N roundtrips for N addresses
```

For a wallet with hundreds of addresses, this means hundreds of sequential HTTP requests. Slow, and likely to hit rate limits.

Waterfalls replaces this with:

```mermaid
sequenceDiagram
  participant W as Your Wallet
  participant WF as Waterfalls

  W->>WF: Send descriptor
  WF->>WF: Derive all addresses, fetch all history
  WF-->>W: Complete wallet history
  Note over W,WF: 1 roundtrip
```

## Performance

Real world benchmarks comparing traditional Esplora scanning vs. Waterfalls:

| Wallet txs | Method     | First scan | Second scan | HTTP requests (1st) | HTTP requests (2nd) |
| ---------- | ---------- | ---------- | ----------- | ------------------- | ------------------- |
| 2          | Esplora    | 3.2s       | 2.1s        | 68                  | 62                  |
| 2          | Waterfalls | 0.4s       | 0.2s        | 7                   | 2                   |
| 65         | Esplora    | 13.1s      | 7.1s        | 294                 | 164                 |
| 65         | Waterfalls | 1.8s       | 0.1s        | 70                  | 2                   |
| 6,442      | Esplora    | 529s       | 261s        | 18,894              | 6,504               |
| 6,442      | Waterfalls | 198s       | 1.2s        | 6,454               | 10                  |

The difference is dramatic. For the 6,442 transaction wallet, the second sync (incremental) goes from 261 seconds to 1.2 seconds.

## Public instance

Blockstream operates a public Waterfalls instance:

| Network            | URL                                                    |
| ------------------ | ------------------------------------------------------ |
| **Liquid mainnet** | `https://waterfalls.liquidwebwallet.org/liquid`        |
| **Liquid testnet** | `https://waterfalls.liquidwebwallet.org/liquidtestnet` |

## Using Waterfalls with LWK

LWK has built in Waterfalls support. The language bindings differ slightly:

#### Rust

```rust
use lwk_wollet::WaterfallsClient;

let client = WaterfallsClient::new(
    "https://waterfalls.liquidwebwallet.org/liquid"
).unwrap();

wollet.full_scan(&client).unwrap();

let balance = wollet.balance().unwrap();
println!("Balances: {:?}", balance);
```

#### Python

```python
client = lwk.WaterfallsClient("https://waterfalls.liquidwebwallet.org/liquid")
wollet.full_scan(client)

balance = wollet.balance()
```

#### JavaScript

In `lwk_wasm` there is **no separate `WaterfallsClient` class**. Waterfalls mode is enabled by passing `waterfalls = true` (3rd argument) to `EsploraClient`, pointing at a Waterfalls server:

```javascript

const client = new EsploraClient(
  network,
  "https://waterfalls.liquidwebwallet.org/liquidtestnet/api", // testnet
  true, // waterfalls mode on
  4,    // concurrency
  false // utxo-only mode
);

const update = await client.fullScan(wollet);
if (update) {
  wollet.applyUpdate(update);
}

const balance = wollet.balance();
```

For mainnet use `https://waterfalls.liquidwebwallet.org/liquid/api`.

Drop in replacement for the Esplora/Electrum client. Same `full_scan` call, faster results.

## API reference

### Wallet scan (v2, recommended)

```
GET /v2/waterfalls?descriptor=<descriptor>&page=<page>&to_index=<max_index>&utxo_only=<bool>
```

**Parameters:**

| Parameter    | Type    | Required             | Default | Description                                           |
| ------------ | ------- | -------------------- | ------- | ----------------------------------------------------- |
| `descriptor` | string  | Yes (or `addresses`) |         | CT descriptor (URL encoded)                           |
| `addresses`  | string  | No                   |         | Comma separated addresses (alternative to descriptor) |
| `page`       | integer | No                   | 0       | Pagination                                            |
| `to_index`   | integer | No                   | 0       | Max derivation index                                  |
| `utxo_only`  | boolean | No                   | false   | Only return unspent outputs                           |

**Example:**

```bash
curl -s "https://waterfalls.liquidwebwallet.org/liquid/v2/waterfalls?descriptor=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("elwpkh(xpub6Bem.../*)"))' )"
```

**Response:**

```json
{
  "txs_seen": {
    "descriptor_or_addresses": [
      {
        "txid": "abc123...",
        "height": 12345,
        "block_hash": "def456...",
        "block_timestamp": 1700000000,
        "v": 1
      }
    ]
  },
  "page": 0,
  "tip": "current_tip_hash"
}
```

### UTXO only mode

If you only need current balances (not full transaction history), use `utxo_only=true`. This is faster and returns less data:

```bash
curl "https://waterfalls.liquidwebwallet.org/liquid/v2/waterfalls?descriptor=...&utxo_only=true"
```

### Last used index

```
GET /v1/last_used_index?descriptor=<descriptor>
```

Returns the highest derivation index that has been used. Useful for quickly determining the next unused address without downloading full history:

```json
{
  "external": 42,
  "internal": 15,
  "tip": "current_tip_hash"
}
```

### Other endpoints

Waterfalls also mirrors some Esplora endpoints:

| Endpoint                     | Description                 |
| ---------------------------- | --------------------------- |
| `GET /blocks/tip/hash`       | Current chain tip hash      |
| `GET /block-height/<height>` | Block hash at height        |
| `GET /block/<hash>/header`   | Block header                |
| `GET /tx/<txid>/raw`         | Raw transaction             |
| `GET /address/<address>/txs` | Address transaction history |
| `GET /fee-estimates`         | Fee rate estimates          |
| `POST /tx`                   | Broadcast transaction       |

## Privacy considerations

When you send a descriptor to Waterfalls, the server can derive all your addresses. This is the same information it would get if you queried each address individually, but now it also knows those addresses are related (from the same descriptor).

For Liquid specifically, this is less of a concern because **Confidential Transactions** mean the server can see which addresses have transactions, but it cannot see the amounts or asset types (the blinding keys are not sent).

For maximum privacy, **self host Waterfalls**.

## Self hosting

Waterfalls is open source and can be run with Docker:

```bash
# Pull and run for Liquid mainnet
docker run -p 3100:3100 -e NETWORK=liquid waterfalls:latest

# Or use Esplora as the data source instead of a local node
docker run -p 3100:3100 -e NETWORK=liquid -e USE_ESPLORA=true waterfalls:latest
```

Disk requirements for the Waterfalls database:

| Network        | Blocks dir | Waterfalls DB |
| -------------- | ---------- | ------------- |
| Liquid mainnet | \~38 GB    | \~876 MB      |
| Liquid testnet | \~4.1 GB   | \~258 MB      |

Much smaller than running a full Esplora indexer.

* [Waterfalls on GitHub](https://github.com/RCasatta/waterfalls)

## When to use Waterfalls vs. Esplora

| Scenario                              | Recommendation           |
| ------------------------------------- | ------------------------ |
| Wallet with few transactions          | Either works fine        |
| Wallet with hundreds/thousands of txs | Waterfalls (much faster) |
| You need address level queries        | Esplora                  |
| You need asset metadata               | Esplora                  |
| You want fastest possible sync        | Waterfalls               |
| You want to minimize server trust     | Self host either         |

For most exchanges, the best setup is: **Waterfalls for wallet sync + Esplora for everything else** (tx lookups, broadcasts, asset info).

## Next steps

* [0-Conf](/docs/zeroconf): mempool visibility signal for zero-confirmation acceptance