feat(trenches): add server-side filter support to API client and update docs

- OpenApiClient: extend getTrenches/buildTrenchesBody to accept and spread
  server-side filter fields into each category section of the request body
- SKILL.md: clarify entrapment_ratio description as Entrapment/Phishing
- workflow-early-project-screening: add filter-preset examples to Step 1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gumponchain
2026-03-31 15:57:33 +08:00
committed by GMGN.AI
parent 3951d9963e
commit 40f75e0b64
3 changed files with 30 additions and 5 deletions
+24
View File
@@ -31,10 +31,34 @@ gmgn-cli market trenches --chain <chain> --type completed
From the results, note each token's `address`, `symbol`, `smart_degen_count`, `renowned_count`, `volume`, `swaps`, and `rug_ratio`.
**Tip — use filter flags to pre-screen at fetch time:**
```bash
# Fetch with safe baseline filter (server-side)
gmgn-cli market trenches --chain <chain> \
--type new_creation --type near_completion \
--filter-preset safe --sort-by smart_degen_count
# Strict: safe + require smart money + min 24h volume $1k
gmgn-cli market trenches --chain <chain> \
--type new_creation --type near_completion \
--filter-preset strict --sort-by smart_degen_count
# Custom: manual range filters (all sent server-side)
gmgn-cli market trenches --chain <chain> \
--type new_creation \
--max-rug-ratio 0.3 --max-bundler-rate 0.3 --max-insider-ratio 0.3 \
--min-smart-degen-count 1 --min-volume-24h 1000
```
Using `--filter-preset safe` (or `strict`) tells the server to pre-filter results before returning — equivalent to Steps 2's "Discard immediately" criteria, applied before the response is sent.
---
## Step 2 — First-Pass Filter (In-Response Scan)
> **If you used `--filter-preset safe` or `--filter-preset strict` in Step 1, the rug_ratio, bundler_rate, and insider_ratio checks below are already applied server-side.** Verify the remaining signals manually.
Before running any CLI commands per token, apply a quick in-response filter on the trenches results:
**Discard immediately if:**
+1 -1
View File
@@ -479,7 +479,7 @@ All filter flags are sent as part of the API request body — the server filters
| `--min-rug-ratio` / `--max-rug-ratio` | float | Rug pull risk score (01) |
| `--min-bundler-rate` / `--max-bundler-rate` | float | Bundle-bot trading ratio (01) |
| `--min-insider-ratio` / `--max-insider-ratio` | float | Insider trading ratio (01) |
| `--min-entrapment-ratio` / `--max-entrapment-ratio` | float | Entrapment trading ratio (01) |
| `--min-entrapment-ratio` / `--max-entrapment-ratio` | float | Entrapment/Phishing trading ratio (01) |
| `--min-private-vault-hold-rate` / `--max-private-vault-hold-rate` | float | Private vault holding ratio (01) |
| `--min-top70-sniper-hold-rate` / `--max-top70-sniper-hold-rate` | float | Top-70 sniper holding ratio (01) |
| `--min-bot-count` / `--max-bot-count` | int | Bot wallet count |
+5 -4
View File
@@ -126,8 +126,8 @@ export class OpenApiClient {
return this.normalRequest("GET", "/v1/user/wallet_token_balance", { chain, wallet_address: walletAddress, token_address: tokenAddress });
}
async getTrenches(chain: string, types?: string[], platforms?: string[], limit?: number): Promise<unknown> {
const body = buildTrenchesBody(chain, types, platforms, limit);
async getTrenches(chain: string, types?: string[], platforms?: string[], limit?: number, filters?: Record<string, number | string>): Promise<unknown> {
const body = buildTrenchesBody(chain, types, platforms, limit, filters);
return this.normalRequest("POST", "/v1/trenches", { chain }, body);
}
@@ -342,17 +342,18 @@ const TRENCHES_QUOTE_ADDRESS_TYPES: Record<string, number[]> = {
base: [11, 3, 12, 13, 0],
};
function buildTrenchesBody(chain: string, types?: string[], platforms?: string[], limit?: number): Record<string, unknown> {
function buildTrenchesBody(chain: string, types?: string[], platforms?: string[], limit?: number, filters?: Record<string, number | string>): Record<string, unknown> {
const selectedTypes = types?.length ? types : ["new_creation", "near_completion", "completed"];
const launchpad_platform = platforms?.length ? platforms : (TRENCHES_PLATFORMS[chain] ?? []);
const quote_address_type = TRENCHES_QUOTE_ADDRESS_TYPES[chain] ?? [];
const actualLimit = limit ?? 80;
const section = {
const section: Record<string, unknown> = {
filters: ["offchain", "onchain"],
launchpad_platform,
quote_address_type,
launchpad_platform_v2: true,
limit: actualLimit,
...filters,
};
const body: Record<string, unknown> = { version: "v2" };
for (const type of selectedTypes) {