# Daiko Terminal
> Daiko Terminal - Automated token monitoring with intelligent alerts
## 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.
import { DslSnippet, GlossaryCard } from "../../components";
:::tip
You don't need to write DSL manually—the web app provides a visual builder for conditions. This reference is for understanding what's possible.
:::
### Overview
A DSL condition is a JSON object with these properties:
```json
{
"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
```json
{
"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:
**Available windows**: `5m`, `15m`, `1h` (default), `4h`, `24h`
:::warning
Only **one** derived join is allowed per condition.
:::
### Where Operators
#### Comparison: `cmp`
Compare a field to a literal value.
=",
left: { type: "field", field: "token_metrics.holder_count" },
right: 100,
}}
/>
**Comparison operators**: `<`, `<=`, `>`, `>=`, `=`, `!=`
#### Comparison: `cmp_field`
Compare two fields directly.
#### Comparison: `cmp_scaled_field`
Compare a field to another field multiplied by a scale factor.
#### Range Sugar: `min` and `max`
Shorthand for common `>=` and `<=` comparisons.
:::note
`min` compiles to `field >= value`, `max` compiles to `field <= value`.
:::
#### String Matching: `ilike` and `like`
Case-insensitive pattern matching.
**Pattern syntax**:
* `%` matches any sequence of characters
* `_` matches any single character
:::tip
Both `like` and `ilike` are case-insensitive in this system.
:::
#### NULL Checks: `is_null` and `is_not_null`
#### Time Comparison: `now_minus_seconds_cmp`
Compare a timestamp field to "now minus X seconds".
=",
seconds: 7200,
}}
/>
#### Existence Check: `exists`
Check if related records exist in trades.
=", 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.
=",
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:
=",
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):
#### Dip from ATH
Find graduated tokens that dropped to 30% of their ATH:
### 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](/how-it-works).
## How It Works
This page explains how Daiko Terminal evaluates your conditions and delivers notifications. Understanding these concepts helps you create better conditions and set realistic expectations.
import { EvaluationFlowDiagram, GlossaryCard } from "../../components";
### The Evaluation Loop
When you save a condition, here's what happens behind the scenes:
1. **Your DSL is validated** - The system checks that your condition uses valid fields and operators
2. **It's compiled to SQL** - Your condition becomes a parameterized database query (no raw SQL injection possible)
3. **The query runs** - Matching tokens are fetched from the live database
4. **Results are filtered** - Cooldown and limits are applied
5. **Notifications are sent** - You receive alerts via Telegram (if connected)
This loop runs **periodically** (typically every few seconds), so your conditions are always being evaluated against fresh data.
### Key Concepts
100",
},
{
term: "Evaluation",
definition: "The periodic process of checking your conditions against the database and finding matches.",
},
{
term: "Cooldown",
definition:
"A period after notifying you about a token during which you won't be notified about it again for the same condition.",
example: "If cooldown is 1 hour, you'll only get one notification per token per hour",
},
{
term: "Limit",
definition: "The maximum number of tokens returned per evaluation cycle.",
},
]}
/>
### Limits and Constraints
:::warning
Understanding these limits helps you write effective conditions.
:::
#### Result Limit: 500 Tokens
Each evaluation returns **at most 500 tokens**. If your condition matches more than 500 tokens:
* Only the first 500 (based on your `order_by` or default ordering) are returned
* You won't see the rest until they rise to the top or your condition changes
**Best Practice**: Use more specific conditions or add an `order_by` clause to prioritize what matters most.
#### Cooldown Period
After you receive a notification about a specific token for a specific condition, that token enters a **cooldown period** for that condition. During cooldown:
* The token may still match your condition
* But you won't receive duplicate notifications
* Cooldown is tracked per (condition, token) pair
:::note
Cooldown is stored in-memory, so it may reset if the service restarts. This is rare but can happen during deployments.
:::
#### Active Conditions Only
Only **active conditions** for **active agents** are evaluated. If you:
* Deactivate a condition: It stops being evaluated
* Delete an agent: All its conditions are removed
### Notifications
#### Telegram (Primary Channel)
When tokens match your condition:
1. The system checks if you have Telegram connected
2. If yes, it sends a message with:
* Agent name
* Matching token details (symbol, address, metrics)
* A link to view more
:::tip
Make sure to connect Telegram in the web app to receive notifications. Without it, matches are computed but not delivered.
:::
#### What Gets Sent
Each notification includes:
| Field | Description |
| ---------------- | --------------------------------- |
| Symbol | Token symbol (e.g., PEPE, WIF) |
| Mint Address | Unique token identifier on Solana |
| Price (SOL) | Current price in SOL |
| Market Cap (USD) | Market capitalization in USD |
### Data Freshness
Your conditions run against **near-real-time data**:
* Token metadata (symbol, creation time): Updated as new tokens are created
* Metrics (price, market cap, holder count): Updated continuously from on-chain data
* Trade data: Streamed from the blockchain with minimal delay
:::info
Data freshness depends on blockchain indexing speed. In most cases, data is only seconds behind the chain.
:::
### Security Model
Your conditions are safe because:
1. **No raw SQL**: You write DSL (JSON), not SQL. The system validates and compiles it.
2. **Field whitelist**: Only specific, allowed fields can be queried
3. **Parameterized queries**: All values are passed as parameters, not string-concatenated
4. **Validation at parse time**: Invalid conditions are rejected before execution
This design prevents SQL injection and ensures you can only query intended data.
### Summary
| Aspect | Behavior |
| -------------------- | -------------------------------------- |
| Evaluation frequency | Periodic (every few seconds) |
| Max results per run | 500 tokens |
| Cooldown | Per (condition, token) pair, in-memory |
| Notifications | Telegram (requires connection) |
| Data freshness | Near real-time (seconds behind chain) |
| Security | Validated DSL → Parameterized SQL |
For details on what you can query, see the [DSL Reference](/dsl).
## Blog
This page is a placeholder for future expansion.
For now, please refer to the public documentation in the sidebar.
import { HomePage } from "vocs/components";
import { FeatureCard, FeatureGrid } from "../../components";
Click Sign in → the same screen opens inside your selected wallet app.
Click Sign in again.
When the signature modal appears, tap Confirm to complete sign-in.
Open **Settings**.
Switch the display language to English (optional; skip if you prefer).
Go to the rightmost **Settings** page and tap **Connect Telegram**.
The **Start** command runs automatically. When a one-time password appears, tap to copy it.
Return to the wallet app and paste the one-time password → linking complete.
:::warning
If Telegram is not connected, Daiko can still evaluate agents, but you will not receive alerts.
:::
Pick a **condition idea** shown below, or enter your own conditions to create an agent.
Give the agent a name and save it.
On the leftmost **Agent** page, you can always check notifications from agents you created or purchased.
You can share notifications and check PnL from Telegram as well.
### What Works Best
* Start broad enough that preview shows a few results.
* Keep one agent focused on one idea instead of mixing everything together.
* Use preview before every save. After saving, watch how notifications behave and adjust.
* Tighten thresholds only after you see too many matches.
### If Alerts Do Not Arrive
1. Make sure Telegram linking is complete (including pasting the one-time password in the wallet app).
2. Open the agent and check that **Preview** still returns matches.
3. Confirm the agent is enabled.
4. Wait out the cooldown if the same token already notified recently.
### If You Get Too Many Alerts
* Raise thresholds.
* Add one more filter.
* Lower the result limit and sort for the highest-signal matches first.
### Go Deeper
* Learn the [DSL Reference](/dsl) when you want more precise filters.
* Read [How It Works](/how-it-works) for the evaluation model behind alerts.
## Privacy Policy
This Privacy Policy describes how Daiko Terminal (the "Service") handles user information.
> This is a template. Undetermined items such as operator information and retention periods are indicated with `{{...}}` placeholders.
### 1. Information We Collect
The Service may handle the following information to the extent necessary for its provision.
* **Account Information**: Identifiers required for login (e.g., external authentication user ID, etc.)
* **Integration Information**: Information related to Telegram integration (e.g., notification destination chat ID, etc.)
* **Usage Information**: Service usage status (e.g., configured conditions, evaluation results, error logs, etc.)
* **Technical Information**: Browser/device information, IP address, cookies, etc. (for usage analysis and fraud prevention)
### 2. Purpose of Use
Collected information is primarily used for the following purposes.
* Providing and operating the Service (saving conditions, periodic evaluation, delivering notifications, etc.)
* Identity verification, authentication, and security assurance
* Responding to inquiries
* Troubleshooting, quality improvement, and feature enhancement
* Prevention of unauthorized use
### 3. Third-Party Disclosure
We do not provide user information to third parties except as required by law.
### 4. Outsourcing
In providing the Service, we may outsource tasks such as hosting, log management, and notification delivery to external service providers. In such cases, we exercise necessary and appropriate supervision over the contractors.
### 5. Retention Period / Deletion
User information is retained for the period necessary for the purpose of use, and is deleted within a reasonable scope when no longer needed or upon user request for deletion.
* Data retention period: `{{data-retention-period}}`
### 6. Security Measures
We implement reasonable security measures to prevent leakage, loss, and damage of user information (access control, encryption, log monitoring, etc.).
### 7. User Rights
Users may request disclosure, correction, deletion, etc. of their information through our prescribed procedures.
### 8. Contact Information
For privacy-related inquiries, please contact us at:
* Operator: `{{operator-name}}`
* Contact: `{{contact}}` (e.g., `{{contact-email}}`)
### 9. Change Notification
If we change this Policy, we will notify users through reasonable means.
### 10. Effective Date
* Effective Date: `{{effective-date}}`
## Chrome Extension
:::warning
The Chrome extension is currently **paused**. Please use the **web app** as the primary interface for creating and managing conditions.
:::
This page is kept for reference and future re-enablement.
### Installation
#### From Chrome Web Store
1. Visit the Chrome Web Store (link coming soon)
2. Click "Add to Chrome"
3. Confirm the installation
4. Pin the extension to your toolbar for easy access
#### Manual Installation (Development)
If you have a development build:
1. Go to `chrome://extensions`
2. Enable "Developer mode"
3. Click "Load unpacked"
4. Select the extension folder
### Opening the Extension
The extension uses Chrome's **Side Panel** feature:
1. Click the Daiko Terminal icon in your toolbar
2. The side panel opens on the right side of your browser
3. You can resize it by dragging the edge
### Main Features
#### Dashboard
The dashboard shows:
* Your active conditions
* Recent notifications
* Quick actions
#### Condition Builder
:::steps
#### Select Target
Choose 'tokens'
#### Add Filters
Set conditions
#### Preview
Test results
#### Save
Activate
:::
The condition builder helps you create DSL conditions without writing JSON:
1. **Target Selection**: Currently supports `tokens`
2. **Join Selection**: Add `token_metrics` if needed
3. **Condition Builder**: Visual interface for operators
4. **Preview**: See matching tokens before saving
#### Condition Management
For each condition, you can:
* **Edit**: Modify the condition parameters
* **Toggle**: Enable or disable evaluation
* **Delete**: Remove the condition entirely
* **Preview**: See current matches
#### Settings
Configure your experience:
* **Telegram Connection**: Link your Telegram account
* **Notification Preferences**: Customize alert settings
* **Account Settings**: Manage your profile
### Using the Condition Builder
#### Adding a Simple Filter
1. Click "Add Filter"
2. Select a field (e.g., `token_metrics.holder_count`)
3. Choose an operator (e.g., `>=`)
4. Enter a value (e.g., `100`)
#### Combining Multiple Filters
Multiple filters are combined with AND logic:
1. Add your first filter
2. Click "Add Filter" again
3. Add additional conditions
4. All must be true for a token to match
#### Using Advanced Features
For complex conditions:
* **Derived Joins**: Add trade-based metrics
* **Exists Checks**: Filter by trade patterns
* **Time Windows**: Focus on recent activity
:::tip
Preview after each change to see how it affects results!
:::
### Keyboard Shortcuts
| Shortcut | Action |
| -------------- | --------------- |
| `Ctrl/Cmd + N` | New condition |
| `Ctrl/Cmd + S` | Save condition |
| `Ctrl/Cmd + P` | Preview results |
| `Esc` | Close dialogs |
### Troubleshooting
#### Extension Not Opening
1. Make sure it's installed and enabled
2. Try clicking the icon in the toolbar
3. Check if Side Panel is supported in your Chrome version
#### Side Panel Too Small
* Drag the left edge to resize
* Minimum width ensures usability
* Chrome remembers your preferred size
#### Changes Not Saving
1. Check your internet connection
2. Make sure you're logged in
3. Look for error messages in the UI
#### Preview Shows No Results
* Your condition might be too strict
* Try relaxing some thresholds
* Check that you've added necessary joins
### Tips for Power Users
#### Duplicate and Modify
* Duplicate an existing condition
* Modify for a different use case
* Saves time vs. building from scratch
#### Use Naming Conventions
* Name conditions descriptively
* Example: "New tokens >100 holders"
* Makes management easier
#### Regular Review
* Check which conditions are useful
* Disable or delete unused ones
* Keep your list manageable
### Next Steps
* Read the [User Guide](/guide) for the full workflow
* Learn the [DSL Reference](/dsl) for advanced conditions
* Understand [How It Works](/how-it-works) technically
## Terms of Service
These Terms of Service (the "Terms") set forth the conditions for using Daiko Terminal (the "Service"). By using the Service, users agree to these Terms.
> This is a template. Undetermined items such as governing law and jurisdiction are indicated with `{{...}}` placeholders.
### 1. Scope
* These Terms apply to all relationships between us and users regarding the use of the Service.
### 2. Changes to Terms
We may change these Terms as necessary. Changed Terms shall take effect from the time they are communicated through reasonable means.
### 3. Accounts / Usage Conditions
* Users shall manage their account information at their own responsibility.
* We may restrict or suspend usage when there is reasonable cause.
### 4. Prohibited Activities
Users shall not engage in the following activities.
* Activities that violate laws or public order and morals
* Unauthorized access or placing excessive load
* Activities that interfere with the operation of the Service
* Activities that infringe on the rights of others (intellectual property rights, privacy, etc.)
* Providing benefits to antisocial forces or similar activities
### 5. Intellectual Property Rights
Intellectual property rights related to the Service belong to us or legitimate rights holders.
### 6. Disclaimer / Warranty Denial
We make no express or implied warranties regarding the suitability of the Service for a particular purpose, accuracy, continuity, etc.
### 7. Limitation of Liability
Even if we cause damage to users, we shall only be liable to a reasonable extent when there is cause attributable to us (specific limits may be set separately if necessary).
### 8. Service Changes/Suspension
We may change the content of the Service or suspend its provision without prior notice.
### 9. Governing Law and Jurisdiction
* Governing Law: `{{governing-law}}`
* Jurisdiction: `{{jurisdiction}}`
### 10. Contact Information
* Operator: `{{operator-name}}`
* Contact: `{{contact}}` (e.g., `{{contact-email}}`)