> For the complete documentation index, see [llms.txt](https://heimdahl.gitbook.io/heimdahl.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://heimdahl.gitbook.io/heimdahl.xyz/getting-started/resource-filtering-pattern.md).

# Resource filtering pattern

Heimdahl uses a consistent pattern-based filtering approach across all data types, with specific actions for accessing historical data and subscribing to real-time updates. This document explains our filtering pattern syntax, how to use it effectively, and why we chose this approach over alternative filtering methods.

### Pattern Structure

Heimdahl provides a consistent pattern structure across interfaces, with slight naming differences between command line and REST API and SDKs.

#### Command Line Interface

```
{resource} {action} {pattern}
```

Where:

* `{resource}` is the primary data category (event, transfer, swap) - singular form
* `{action}` is either `list` (for historical data) or `subscribe` (for real-time updates)
* `{pattern}` is a structured filtering expression using dot notation

#### REST API Interface

```
/{resources_plural}/{action}/{pattern}
```

Where:

* `{resources_plural}` is the primary data category in plural form (events, transfers, swaps) to follow RESTful conventions
* `{action}` is either `list` (for historical data) or `subscribe` (for real-time updates)
* `{pattern}` is the same structured filtering expression as used in the command line

### Actions

Heimdahl provides two primary actions for each resource type:

* **list**: Retrieves historical data matching the specified pattern
* **subscribe**: Creates a real-time subscription for new data matching the pattern

### Pattern Syntax By Resource Type

Each resource type has a specific pattern format that reflects its unique properties:

#### Event Pattern

```
event list {chain}.{network}.{token_address}.{event_name}
event subscribe {chain}.{network}.{token_address}.{event_name}
```

Examples:

```
event list base.mainnet.0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.Transfer
event subscribe base.mainnet.0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.Transfer
```

The first query returns historical Transfer events, while the second creates a real-time subscription.

#### Transfer Pattern

```
transfer list {chain}.{network}.{symbol}.{sender_addr}.{receiver_addr}.{size}
transfer subscribe {chain}.{network}.{symbol}.{sender_addr}.{receiver_addr}.{size}
```

Examples:

```
transfer list base.mainnet.usdc.all.all.all
transfer subscribe base.mainnet.usdc.all.all.all
```

The first query returns historical USDC transfers, while the second subscribes to new transfers as they occur.

#### Swap Pattern

```
swap list {chain}.{network}.{symbol1}.{symbol2}.{size}
swap subscribe {chain}.{network}.{symbol1}.{symbol2}.{size}
```

Examples:

```
swap list ethereum.mainnet.usdc.weth.all
swap subscribe ethereum.mainnet.usdc.weth.all
```

The first query returns historical USDC-WETH swaps, while the second creates a real-time subscription.

### Using the `all` Placeholder

The keyword `all` serves as a wildcard for any field you don't want to filter on. This allows for flexible queries that can be refined as needed:

**CLI examples:**

```
transfer list base.mainnet.usdc.all.all.all   # All historical USDC transfers on Base mainnet
transfer subscribe base.mainnet.usdc.0x123...abc.all.all   # Subscribe to new USDC transfers from a specific address
swap list ethereum.mainnet.all.weth.all   # All historical swaps involving WETH on Ethereum mainnet
```

**REST API examples:**

```
/transfers/list/base.mainnet.usdc.all.all.all   # All historical USDC transfers on Base mainnet
/transfers/subscribe/base.mainnet.usdc.0x123...abc.all.all   # Subscribe to new USDC transfers from a specific address
/swaps/list/ethereum.mainnet.all.weth.all   # All historical swaps involving WETH on Ethereum mainnet
```

### Examples

Below are examples showing both CLI and REST API usage for the same queries:

#### Events for a Specific Contract

**CLI:**

```
event list ethereum.mainnet.0x6B175474E89094C44Da98b954EedeAC495271d0F.Transfer
```

**REST API:**

```
/events/list/ethereum.mainnet.0x6B175474E89094C44Da98b954EedeAC495271d0F.Transfer
```

#### Real-time Transfer Monitoring by Token

**CLI:**

```
transfer subscribe ethereum.mainnet.dai.all.all.all
```

**REST API:**

```
/transfers/subscribe/ethereum.mainnet.dai.all.all.all
```

#### Historical Transfers from a Specific Sender

**CLI:**

```
transfer list ethereum.mainnet.usdc.0x123...abc.all.all
```

**REST API:**

```
/transfers/list/ethereum.mainnet.usdc.0x123...abc.all.all
```

#### Real-time Swap Monitoring Between Specific Token Pairs

**CLI:**

```
swap subscribe ethereum.mainnet.usdc.weth.all
```

**REST API:**

```
/swaps/subscribe/ethereum.mainnet.usdc.weth.all
```

### Why Pattern-based Filtering?

#### Consistency Across Methods

The same pattern structure works for both historical data retrieval and real-time subscriptions, creating a unified query language for all interactions with Heimdahl.

#### Cross-Chain Scalability

Our pattern approach provides a unified syntax that works across all supported blockchains while respecting their unique characteristics. Adding support for new chains doesn't change the fundamental query structure.

#### Parameter Extensibility

As we add support for new filtering parameters, the pattern syntax naturally accommodates them in a consistent way. This future-proofs your integration with Heimdahl.

#### Readability and Brevity

Patterns using dot notation are more concise and readable than traditional query parameters:

**CLI:**

```
# Pattern approach
transfer list ethereum.mainnet.usdc.0x123...abc.all.all

# Traditional query parameters approach would be more verbose
transfer --chain=ethereum --network=mainnet --token=usdc --sender=0x123...abc
```

**REST API:**

```
# Pattern approach
/transfers/list/ethereum.mainnet.usdc.0x123...abc.all.all

# Traditional query parameters
/transfers/list?chain=ethereum&network=mainnet&token=usdc&sender=0x123...abc
```

### Dotted Pattern vs. Flag-based Filtering

Many blockchain APIs use traditional flag or parameter-based filtering. While familiar, this approach has several disadvantages that our dotted pattern syntax addresses:

1. **Simplicity**: Dotted patterns create a natural hierarchy that's easy to understand and remember
2. **Consistency**: The same pattern structure works across all data types and interfaces
3. **Brevity**: Patterns require significantly fewer characters than equivalent flag-based queries
4. **Extensibility**: New filtering parameters can be added without changing the API structure
5. **Readability**: Patterns visually represent the relationship between filter parameters

For example, a typical flag-based query might look like:

```
?chain=ethereum&network=mainnet&token=usdc&sender=0x123...abc
```

While our dotted pattern approach simplifies this to:

```
ethereum.mainnet.usdc.0x123...abc.all.all
```

This approach scales much better as your queries become more complex.

### Advanced Usage

#### Pattern Refinement

Start with broader patterns and refine as needed:

**CLI:**

```
# Start with all historical USDC transfers
transfer list ethereum.mainnet.usdc.all.all.all

# Refine to specific senders
transfer list ethereum.mainnet.usdc.0x123...abc.all.all

# Subscribe to specific transfers between two addresses
transfer subscribe ethereum.mainnet.usdc.0x123...abc.0x456...def.all
```

**REST API:**

```
# Start with all historical USDC transfers
/transfers/list/ethereum.mainnet.usdc.all.all.all

# Refine to specific senders
/transfers/list/ethereum.mainnet.usdc.0x123...abc.all.all

# Subscribe to specific transfers between two addresses
/transfers/subscribe/ethereum.mainnet.usdc.0x123...abc.0x456...def.all
```

### Implementation Notes

When implementing clients to work with our API, we recommend:

1. Building pattern-construction utilities to help users create valid patterns
2. Creating template functions for common queries (list vs. subscribe)
3. Implementing proper subscription management for real-time data

### Conclusion

Our pattern-based filtering approach provides a powerful, consistent, and future-proof way to query blockchain data across different chains and data types. By using the same pattern syntax for both historical (`list`) and real-time (`subscribe`) data access, Heimdahl creates a unified experience that simplifies blockchain data integration.
