DSL Reference
The Conditions DSL (Domain-Specific Language) is how you express what tokens to find and what conditions they must match. It's a JSON format that gets validated and compiled to safe, parameterized SQL.
Overview
A DSL condition is a JSON object with these properties:
{
"target": "tokens", // Required: what to query (only "tokens" for now)
"select": [...], // Optional: which fields to return
"joins": [...], // Optional: additional data to join
"derived_joins": [...], // Optional: computed metrics from trades
"where": {...}, // Optional: filter conditions
"order_by": [...], // Optional: sort order
"limit": 100 // Optional: max results (capped at 500)
}Queryable Data
Available Fields
Token Fields (tokens.*)
| Field | Type | Description |
|---|---|---|
tokens.mint_address | string | Unique token identifier |
tokens.symbol | string | Token symbol (e.g., PEPE) |
tokens.meta_url | string | Metadata URL |
tokens.created_timestamp | number | Unix timestamp of creation |
tokens.created_block | number | Block number of creation |
tokens.creator_address | string | Creator's wallet address |
tokens.bonding_curve_address | string | Bonding curve address |
tokens.platform_type | string | Platform type |
Token Metrics Fields (token_metrics.*)
Requires joins: ["token_metrics"].
| Field | Type | Description |
|---|---|---|
token_metrics.price_lamports | number | Current price in lamports |
token_metrics.mc_lamports | number | Market cap in lamports |
token_metrics.holder_count | number | Number of holders |
token_metrics.ath_price_lamports | number | All-time high price |
token_metrics.ath_mc_lamports | number | All-time high market cap |
token_metrics.ath_timestamp | number | When ATH was reached |
token_metrics.graduate_timestamp | number | When token graduated (null if not) |
token_metrics.updated_timestamp | number | Last metrics update |
Derived Fields (derived.*)
Requires a derived_joins entry.
| Field | Description |
|---|---|
derived.pct_range | Price range % (from trade_price_range_1h) |
derived.min_price_sol | Minimum price in SOL (from trade_price_window) |
derived.max_price_sol | Maximum price in SOL (from trade_price_window) |
derived.volume_sol | Trading volume in SOL (from trade_price_window) |
derived.trade_count | Number of trades (from trade_price_window) |
Trade Fields (trades.*)
Only available inside exists conditions.
| Field | Type | Description |
|---|---|---|
trades.side | string | "buy" or "sell" |
trades.sol_amount_lamports | number | Trade amount in lamports |
trades.token_amount | number | Token amount traded |
trades.price_lamports | number | Price at time of trade |
trades.block_timestamp | number | When trade occurred |
trades.wallet_address | string | Trader's wallet |
Joins
Regular Joins
{
"target": "tokens",
"joins": ["token_metrics"]
}Currently only token_metrics is supported.
Derived Joins
Derived joins compute aggregated values from trade data. The on clause is required and must be exactly as shown:
{
"target": "tokens",
"derived_joins": [
{
"derived": "trade_price_range_1h",
"on": {
"left": "tokens.mint_address",
"right": "derived.mint_address"
}
}
]
}{
"target": "tokens",
"derived_joins": [
{
"derived": "trade_price_window",
"window": "1h",
"on": {
"left": "tokens.mint_address",
"right": "derived.mint_address"
}
}
]
}Available windows: 5m, 15m, 1h (default), 4h, 24h
Where Operators
Comparison: cmp
Compare a field to a literal value.
{
"op": "cmp",
"cmp": ">=",
"left": {
"type": "field",
"field": "token_metrics.holder_count"
},
"right": 100
}Comparison operators: <, <=, >, >=, =, !=
Comparison: cmp_field
Compare two fields directly.
{
"op": "cmp_field",
"cmp": "<",
"left": {
"type": "field",
"field": "token_metrics.price_lamports"
},
"right": {
"type": "field",
"field": "token_metrics.ath_price_lamports"
}
}Comparison: cmp_scaled_field
Compare a field to another field multiplied by a scale factor.
{
"op": "cmp_scaled_field",
"cmp": "<=",
"left": {
"type": "field",
"field": "token_metrics.mc_lamports"
},
"right": {
"type": "field",
"field": "token_metrics.ath_mc_lamports"
},
"scale": 0.3
}Range Sugar: min and max
Shorthand for common >= and <= comparisons.
{
"op": "min",
"ref": {
"type": "field",
"field": "token_metrics.mc_lamports"
},
"value": 1000
}{
"op": "max",
"ref": {
"type": "field",
"field": "token_metrics.holder_count"
},
"value": 500
}String Matching: ilike and like
Case-insensitive pattern matching.
{
"op": "ilike",
"ref": {
"type": "field",
"field": "tokens.symbol"
},
"pattern": "%wif%"
}Pattern syntax:
%matches any sequence of characters_matches any single character
NULL Checks: is_null and is_not_null
{
"op": "is_null",
"ref": {
"type": "field",
"field": "token_metrics.graduate_timestamp"
}
}{
"op": "is_not_null",
"ref": {
"type": "field",
"field": "token_metrics.graduate_timestamp"
}
}Time Comparison: now_minus_seconds_cmp
Compare a timestamp field to "now minus X seconds".
{
"op": "now_minus_seconds_cmp",
"ref": {
"type": "field",
"field": "tokens.created_timestamp"
},
"cmp": ">=",
"seconds": 7200
}Existence Check: exists
Check if related records exist in trades.
{
"op": "exists",
"source": "trades",
"join_on": {
"left": "tokens.mint_address",
"right": "trades.mint_address"
},
"where": {
"op": "and",
"args": [
{
"op": "cmp",
"cmp": "=",
"left": {
"type": "field",
"field": "trades.side"
},
"right": "buy"
},
{
"op": "cmp",
"cmp": ">=",
"left": {
"type": "field",
"field": "trades.sol_amount_lamports"
},
"right": 10000000000
},
{
"op": "now_minus_seconds_cmp",
"ref": {
"type": "field",
"field": "trades.block_timestamp"
},
"cmp": ">=",
"seconds": 1800
}
]
}
}Logical Operators: and, or, not
Combine multiple conditions.
{
"op": "and",
"args": [
{
"op": "now_minus_seconds_cmp",
"ref": {
"type": "field",
"field": "tokens.created_timestamp"
},
"cmp": ">=",
"seconds": 3600
},
{
"op": "cmp",
"cmp": ">=",
"left": {
"type": "field",
"field": "token_metrics.holder_count"
},
"right": 50
}
]
}Complete Examples
New Token Discovery
Find tokens created in the last hour with at least 50 holders:
{
"target": "tokens",
"joins": [
"token_metrics"
],
"where": {
"op": "and",
"args": [
{
"op": "now_minus_seconds_cmp",
"ref": {
"type": "field",
"field": "tokens.created_timestamp"
},
"cmp": ">=",
"seconds": 3600
},
{
"op": "cmp",
"cmp": ">=",
"left": {
"type": "field",
"field": "token_metrics.holder_count"
},
"right": 50
}
]
},
"order_by": [
{
"field": "token_metrics.holder_count",
"dir": "desc"
}
],
"limit": 20
}Sideways Detection
Find tokens trading in a tight range (max price within 1.2x of min):
{
"target": "tokens",
"derived_joins": [
{
"derived": "trade_price_window",
"window": "1h",
"on": {
"left": "tokens.mint_address",
"right": "derived.mint_address"
}
}
],
"where": {
"op": "cmp_scaled_field",
"cmp": "<=",
"left": {
"type": "field",
"field": "derived.max_price_sol"
},
"right": {
"type": "field",
"field": "derived.min_price_sol"
},
"scale": 1.2
},
"limit": 50
}Dip from ATH
Find graduated tokens that dropped to 30% of their ATH:
{
"target": "tokens",
"joins": [
"token_metrics"
],
"where": {
"op": "and",
"args": [
{
"op": "is_not_null",
"ref": {
"type": "field",
"field": "token_metrics.graduate_timestamp"
}
},
{
"op": "cmp_scaled_field",
"cmp": "<=",
"left": {
"type": "field",
"field": "token_metrics.mc_lamports"
},
"right": {
"type": "field",
"field": "token_metrics.ath_mc_lamports"
},
"scale": 0.3
}
]
},
"limit": 100
}Limitations
| Aspect | Limitation |
|---|---|
| Target | Only "tokens" is supported |
| Joins | Only ["token_metrics"] |
| Derived joins | Maximum 1 per condition |
| Results | Capped at 500 per evaluation |
| Tables | Cannot query arbitrary tables |
Security
Your conditions are safe because:
- Validated: Every field and operator is checked against a whitelist
- Parameterized: All values become SQL parameters, not string concatenation
- No raw SQL: You write JSON, the system compiles it safely
For details on evaluation behavior, see How It Works.
