madeonsol-x402 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -24,12 +24,27 @@ export interface KolTrade {
24
24
  export interface KolFeedResponse {
25
25
  trades: KolTrade[];
26
26
  count: number;
27
+ /** LEGACY strict timestamp cursor (skips same-timestamp siblings) — prefer next_cursor. */
28
+ next_before?: string | null;
29
+ /** Pass as `cursor` for the next (older) page; null at the end. */
30
+ next_cursor?: string | null;
31
+ /** false only when the feed is exhausted. */
32
+ has_more?: boolean;
33
+ /** Present when a filter was applied after the candidate fetch; scan_truncated=true means more matches MAY exist past next_cursor. */
34
+ scan?: {
35
+ post_filtered: boolean;
36
+ scanned: number;
37
+ scan_truncated: boolean;
38
+ scan_budget: number;
39
+ };
27
40
  }
28
41
  export type KolStrategy = "scalper" | "day_trader" | "swing_trader" | "hodler" | "mixed";
29
42
  export interface KolFeedParams {
30
43
  limit?: number;
31
- /** Cursor — ISO 8601 timestamp; returns trades strictly older than this. Pass `next_before` from the previous response for polling. */
44
+ /** LEGACY cursor — ISO 8601 timestamp; returns trades strictly older than this (skips same-timestamp rows). Prefer `cursor`. */
32
45
  before?: string;
46
+ /** PREFERRED pagination: `next_cursor` from the previous page — opaque strict keyset (no skipped/repeated rows at shared timestamps). Cannot be combined with `before`. */
47
+ cursor?: string;
33
48
  action?: "buy" | "sell";
34
49
  kol?: string;
35
50
  /** PRO+: minimum SOL size per trade */
@@ -89,6 +104,14 @@ export interface KolCoordinationResponse {
89
104
  min_kols: number;
90
105
  /** v1.1 — score formula version. */
91
106
  score_version?: string;
107
+ /** 2026-09-21 — the clusters the ranking covered: top `max_size` by (kol_count DESC, net_sol_flow DESC); filters + score sort run inside it. */
108
+ universe?: {
109
+ kind: "top_by_kol_count";
110
+ order: string;
111
+ max_size: number;
112
+ size: number;
113
+ truncated_at_max: boolean;
114
+ };
92
115
  /** v1.1 — peak-density window used. */
93
116
  window_minutes?: number;
94
117
  }
@@ -171,8 +194,10 @@ export type ScoutTier = "S" | "A" | "B" | "C";
171
194
  export interface FirstTouchesParams {
172
195
  /** ISO datetime — return events strictly newer than this. Use as a polling cursor. */
173
196
  since?: string;
174
- /** ISO datetime — return events strictly older than this. Use for pagination. */
197
+ /** ISO datetime — return events strictly older than this. LEGACY pagination; prefer `cursor`. */
175
198
  before?: string;
199
+ /** PREFERRED pagination: `next_cursor` from the previous page — opaque strict keyset (no skipped/repeated rows at shared timestamps). Cannot be combined with `before`. */
200
+ cursor?: string;
176
201
  limit?: number;
177
202
  /** Filter to one KOL wallet address (32–44 base58 chars). */
178
203
  kol?: string;
@@ -231,6 +256,17 @@ export interface FirstTouchesResponse {
231
256
  events: FirstTouchEvent[];
232
257
  count: number;
233
258
  next_before: string | null;
259
+ /** Pass as `cursor` for the next (older) page; null at the end. */
260
+ next_cursor?: string | null;
261
+ /** false only when the feed is exhausted. */
262
+ has_more?: boolean;
263
+ /** Present when a filter was applied after the candidate fetch; scan_truncated=true means more matches MAY exist past next_cursor. */
264
+ scan?: {
265
+ post_filtered: boolean;
266
+ scanned: number;
267
+ scan_truncated: boolean;
268
+ scan_budget: number;
269
+ };
234
270
  data_age_seconds: number | null;
235
271
  }
236
272
  export interface FirstTouchSubscriptionFilters {
@@ -293,10 +329,24 @@ export interface KolLeaderboardEntry {
293
329
  median_hold_minutes_30d?: number | null;
294
330
  /** v1.12 — percentile rank (0-100) of early entry quality over the last 30 days. */
295
331
  percentile_early_entry_30d?: number | null;
332
+ /** v1.24 — complete SQL aggregate over the period; null when that read failed (entry_mc_complete=false). */
333
+ entry_mc_samples?: number | null;
334
+ avg_entry_mc_usd?: number | null;
335
+ }
336
+ /** v1.24 — pagination walks a FIXED ranked universe, not every KOL. */
337
+ export interface LeaderboardUniverse {
338
+ kind: string;
339
+ period?: string;
340
+ max_size: number;
341
+ size: number;
342
+ note?: string;
296
343
  }
297
344
  export interface KolLeaderboardResponse {
298
345
  leaderboard: KolLeaderboardEntry[];
299
346
  period: string;
347
+ universe?: LeaderboardUniverse;
348
+ entry_mc_window_start?: string | null;
349
+ entry_mc_complete?: boolean;
300
350
  }
301
351
  export type KolLeaderboardSort = "pnl" | "winrate" | "profit_factor" | "roi" | "early_entry";
302
352
  export interface KolLeaderboardParams {
@@ -348,12 +398,27 @@ export interface DeployerAlertsResponse {
348
398
  alerts: DeployerAlert[];
349
399
  limit: number;
350
400
  offset: number;
351
- /** Cursor for the next page — pass as `before` to fetch older alerts. */
401
+ /** LEGACY strict timestamp cursor (skips alerts sharing the boundary created_at) — prefer next_cursor. */
352
402
  next_before?: string | null;
403
+ /** Pass as `cursor` for the next (older) page; null at the end. */
404
+ next_cursor?: string | null;
405
+ /** false only when the feed is exhausted. */
406
+ has_more?: boolean;
407
+ /** false only if kol_buys could not be aggregated exactly (counts are then lower bounds). */
408
+ kol_buys_complete?: boolean;
409
+ /** Present with min_kol_buys; scan_truncated=true means more matches MAY exist past next_cursor. */
410
+ scan?: {
411
+ post_filtered: boolean;
412
+ scanned: number;
413
+ scan_truncated: boolean;
414
+ scan_budget: number;
415
+ };
353
416
  }
354
417
  export interface DeployerAlertsParams {
355
418
  since?: string;
356
- /** Cursor — ISO 8601 timestamp; returns alerts strictly older than this. Preferred over `offset` at scale. */
419
+ /** Opaque strict (created_at, id) cursor — `next_cursor` from the previous page. Preferred. Not combinable with before/offset. */
420
+ cursor?: string;
421
+ /** LEGACY cursor — ISO 8601 timestamp; returns alerts strictly older than this (skips same-timestamp siblings). */
357
422
  before?: string;
358
423
  limit?: number;
359
424
  offset?: number;
@@ -606,7 +671,19 @@ export interface KolEntryOrderEntry {
606
671
  export interface KolEntryOrderResponse {
607
672
  token_mint: string;
608
673
  entries: KolEntryOrderEntry[];
609
- count: number;
674
+ /** @deprecated the route never returned `count` — use `returned` (entries.length) / `total_kol_buyers`. */
675
+ count?: number;
676
+ /** v1.24 — total_kol_buyers counts ALL first buyers (was capped by a 2,000-row read). */
677
+ total_kol_buyers?: number;
678
+ returned?: number;
679
+ has_more?: boolean;
680
+ complete?: boolean;
681
+ }
682
+ /** v1.24 — HTTP 503 when the entry-order aggregate is unavailable (e.g. during a schema rollout). Retry. */
683
+ export interface KolEntryOrderUnavailableResponse {
684
+ error: string;
685
+ retryable: true;
686
+ retry_after_seconds: number;
610
687
  }
611
688
  export interface KolEntryOrderParams {
612
689
  /** Cap number of ranked entries (default 50) */
@@ -641,6 +718,15 @@ export interface KolCompareOverlapToken {
641
718
  export interface KolCompareResponse {
642
719
  profiles: KolCompareProfile[];
643
720
  overlap?: KolCompareOverlapToken[];
721
+ /** v1.24 — overlap is the top 25 of `total` qualifying tokens over the full 30 d window; null total = the aggregate failed. */
722
+ overlap_meta?: {
723
+ window_start: string;
724
+ min_wallets: number;
725
+ total: number | null;
726
+ returned: number;
727
+ has_more: boolean | null;
728
+ complete: boolean;
729
+ };
644
730
  count: number;
645
731
  }
646
732
  export interface KolCompareParams {
@@ -705,10 +791,15 @@ export interface AlphaLeaderboardEntry {
705
791
  buy_size_stddev?: number;
706
792
  active_hours?: number;
707
793
  bot_confidence?: "low" | "medium" | "high" | "none";
794
+ /** v1.24 — null (not 0) when the entry-MC aggregate failed. */
795
+ entry_mc_samples?: number | null;
796
+ avg_entry_mc_usd?: number | null;
708
797
  }
709
798
  export interface AlphaLeaderboardResponse {
710
799
  leaderboard: AlphaLeaderboardEntry[];
711
800
  total: number;
801
+ entry_mc_window_start?: string | null;
802
+ entry_mc_complete?: boolean;
712
803
  period: AlphaPeriod;
713
804
  sort: AlphaSort;
714
805
  min_tokens: number;
@@ -761,7 +852,10 @@ export interface AlphaLinkedResponse {
761
852
  wallet: string;
762
853
  linked: AlphaLinkedWallet[];
763
854
  }
764
- export type BuyerQualityConfidence = "low" | "medium" | "high";
855
+ /** v1.24 (audit 2026-09-21) — "insufficient_data" when no buyer's win rate fed the
856
+ * score (the neutral-50 placeholder or an all-excluded cohort). Treat unknown
857
+ * future values as low confidence. */
858
+ export type BuyerQualityConfidence = "insufficient_data" | "low" | "medium" | "high";
765
859
  export type BuyerQualitySignal = "positive" | "neutral" | "negative";
766
860
  export interface CapTableBuyer {
767
861
  rank: number;
@@ -797,7 +891,16 @@ export interface TradeCoverage {
797
891
  scope: string;
798
892
  in_scope?: boolean | null;
799
893
  note?: string;
800
- }
894
+ /** v1.24 — same value as in_scope: persisted rows exist (presence, not completeness). */
895
+ data_observed?: boolean | null;
896
+ /** v1.24 — does the CURRENT capture gate admit this mint? */
897
+ eligibility?: TradeEligibility | null;
898
+ eligibility_basis?: string | null;
899
+ /** v1.24 — always "not_verified": rows existing never proves a complete interval. */
900
+ completeness?: "not_verified";
901
+ }
902
+ /** v1.24 — treat unknown future values as "unknown". */
903
+ export type TradeEligibility = "eligible" | "lapsed" | "excluded" | "unknown" | "admitted_previously" | "not_applicable";
801
904
  export interface TokenCapTableResponse {
802
905
  mint: string;
803
906
  buyers: CapTableBuyer[];
@@ -832,13 +935,20 @@ export interface TokenBuyerQualityResponse {
832
935
  * dump_cluster_count 0 historically leans runner.
833
936
  */
834
937
  recycled_early_buyer_count: number;
938
+ /** v1.24 — buyers with ≥3 tokens of history (cohort identification, not predictive). */
939
+ wallets_with_history?: number;
940
+ /** v1.24 — buyers whose win rate fed the score; the basis of `confidence`. */
941
+ qualified_win_rate_wallets?: number;
835
942
  };
836
943
  note?: string;
837
944
  /** v1.23.4 — trade-coverage disclosure (absent on older cached responses). */
838
945
  coverage?: TradeCoverage;
839
946
  }
840
947
  export type TokenRiskBand = "safe" | "caution" | "danger";
841
- export type TokenRiskStatus = "ok" | "warn" | "danger";
948
+ /** v1.24 (score v2) — unknown = the input should exist but could not be read / is insufficient;
949
+ * not_assessed = no evidence source applies to this token. Both carry 0 points and are never
950
+ * positive evidence. Treat any future value as not-ok. */
951
+ export type TokenRiskStatus = "ok" | "warn" | "danger" | "unknown" | "not_assessed";
842
952
  export interface TokenRiskFactor {
843
953
  key: string;
844
954
  label: string;
@@ -869,7 +979,18 @@ export interface TokenRiskInputs {
869
979
  liquidity_to_mc_ratio: number | null;
870
980
  transfer_fee_bps: number | null;
871
981
  is_token_2022: boolean | null;
982
+ /** DEPRECATED alias of token_supply_burn_detected — a token-SUPPLY burn, never an LP burn (score v2). */
872
983
  burn_detected: boolean | null;
984
+ /** v1.24 — the mint's on-chain supply decreased. Not LP evidence. */
985
+ token_supply_burn_detected?: boolean | null;
986
+ /** v1.24 — verified LP custody; "unknown" for every Solana pool today. */
987
+ lp_burn_status?: LpBurnStatus;
988
+ /** v1.24 — creator history label; only "established" moves the score. */
989
+ deployer_history_status?: DeployerHistoryStatus | null;
990
+ deployer_reputation_scored?: boolean;
991
+ supply_inflation_pct?: number | null;
992
+ /** v1.24 — when the liquidity figure was last observed; a not-assessed creator needs it < 6 h for "safe" (a policy threshold, not proof of safety). */
993
+ liquidity_observed_at?: string | null;
873
994
  launch_cohort_sol: number | null;
874
995
  launch_cohort_size: number | null;
875
996
  deployer_bonding_rate: number | null;
@@ -907,8 +1028,30 @@ export interface TokenRiskDev {
907
1028
  holdings_supply_pct: number | null;
908
1029
  /** Is the dev wallet empty NOW (holdings < 1 token)? null when holdings unknown. */
909
1030
  wallet_empty: boolean | null;
910
- /** True when on-chain holdings sit well below the trade-derived expectation (tokens moved WITHOUT a sell). null = unknown (trade coverage or rollup freshness gate failed) — never a guess. */
1031
+ /** DEPRECATED boolean view of transfer_status: true = "suspected" (never a verified transfer), false = "none_detected", null = "unknown". */
911
1032
  transferred_out: boolean | null;
1033
+ /** v1.24 — suspected | none_detected | unknown (batch: always unknown). */
1034
+ transfer_status?: "suspected" | "none_detected" | "unknown";
1035
+ transfer_reason?: string;
1036
+ expected_tokens_from_trades?: number | null;
1037
+ /** v1.24 — observation times: holdings (RPC) vs the dev-activity rollup. */
1038
+ holdings_observed_at?: string | null;
1039
+ activity_rollup_through?: string | null;
1040
+ activity_rollup_ran_at?: string | null;
1041
+ }
1042
+ /** v1.24 — LP custody evidence. */
1043
+ export type LpBurnStatus = "verified" | "not_verified" | "unknown";
1044
+ /** v1.24 — creator history label (audit F08). "unranked" tier is NOT "new". */
1045
+ export type DeployerHistoryStatus = "new_in_our_index" | "limited_history" | "reputation_pending" | "established";
1046
+ /** v1.24 — what the score could not observe. status "incomplete" ⇒ the score is a lower bound and band is never "safe". */
1047
+ export interface TokenRiskAssessment {
1048
+ status: "complete" | "incomplete";
1049
+ unknown_inputs: string[];
1050
+ not_assessed: string[];
1051
+ /** Reason per listed input, keyed by input name, plus `band_cap` when the band was capped at caution. */
1052
+ explanations?: Record<string, string> & {
1053
+ band_cap?: string;
1054
+ };
912
1055
  }
913
1056
  /** Transparent 0–100 token rug-risk/safety score (higher = riskier). PRO/ULTRA only. */
914
1057
  export interface TokenRiskResponse {
@@ -922,14 +1065,31 @@ export interface TokenRiskResponse {
922
1065
  dev?: TokenRiskDev | null;
923
1066
  /** v1.23.4 — trade-coverage disclosure (keyed single-mint route only). Its `note` names the split: trade-derived sub-fields are launchpad-pipeline scoped, on-chain sub-fields are unaffected. */
924
1067
  coverage?: TradeCoverage;
1068
+ /** v1.24 (score_version "v2") — unknown vs not-assessed inputs. */
1069
+ assessment?: TokenRiskAssessment;
1070
+ /** v1.24 — ok | not_found (no pending_deploys row) | unavailable (lookup failed). */
1071
+ dev_status?: "ok" | "not_found" | "unavailable";
925
1072
  as_of: string;
926
1073
  }
1074
+ /** v1.24 — HTTP 503 body when a score-critical input could not be read (retry; never a partial score).
1075
+ * A 503 can also carry the generic statement-timeout body { error, error_kind: "statement_timeout", retry_after_seconds }. */
1076
+ export interface TokenRiskUnavailableResponse {
1077
+ error: string;
1078
+ code: "risk_inputs_unavailable";
1079
+ unavailable_inputs: string[];
1080
+ retryable: true;
1081
+ retry_after_seconds: number;
1082
+ }
927
1083
  /** Per-mint error object for untracked / failed mints in a batch risk response.
928
1084
  * Untracked mints come back as `not_tracked` and do NOT fail the batch; a
929
1085
  * per-mint compute failure comes back as `error`. */
930
1086
  export interface TokenBatchRiskError {
931
1087
  mint: string;
932
- error: "not_tracked" | "error";
1088
+ /** v1.24 — "unavailable" = a score-critical input could not be read (retryable). */
1089
+ error: "not_tracked" | "error" | "unavailable";
1090
+ code?: "risk_inputs_unavailable";
1091
+ unavailable_inputs?: string[];
1092
+ retryable?: boolean;
933
1093
  }
934
1094
  /** One entry in the `tokens` array of POST /tokens/batch/risk — either a full
935
1095
  * risk result (same shape as GET /tokens/{mint}/risk) or a per-mint error. */
@@ -1335,7 +1495,14 @@ export interface ScoutLeaderboardParams {
1335
1495
  export interface KolConsensusResponse {
1336
1496
  total_kol_buyers: number;
1337
1497
  total_kol_sellers: number;
1498
+ /** Share of KOL buyers with ≥1 recorded sell (any size) — NOT a full position exit. */
1338
1499
  kol_exit_rate: number | null;
1500
+ /** v1.24 — accurately named copy of kol_exit_rate. */
1501
+ kol_any_sell_rate?: number | null;
1502
+ /** v1.24 — false when the trade read hit its row ceiling (numbers cover the oldest rows_scanned trades). */
1503
+ complete?: boolean;
1504
+ truncated?: boolean;
1505
+ rows_scanned?: number;
1339
1506
  net_flow_sol: number;
1340
1507
  total_buy_sol: number;
1341
1508
  total_sell_sol: number;
@@ -1389,11 +1556,85 @@ export interface TokenSnapshot {
1389
1556
  primary_pool_address: string | null;
1390
1557
  is_token_2022: boolean | null;
1391
1558
  transfer_fee_bps: number | null;
1392
- top_buyers: TokenSnapshotTopBuyer[];
1559
+ /** @deprecated never returned at this level — the route nests it as kol_activity.top_buyers. Kept optional for source compatibility. */
1560
+ top_buyers?: TokenSnapshotTopBuyer[];
1561
+ /** v1.24 — DEPRECATED meaning: a token-SUPPLY burn (mint supply decreased), never LP evidence. null = unknown (no mc-tracker observation). */
1562
+ burn_detected?: boolean | null;
1563
+ /** v1.24 — creator + reputation; resolved for unbonded launches too. null ⇒ read deployer_identity. */
1564
+ deployer?: TokenSnapshotDeployer | null;
1565
+ /** v1.24 — complete 7-day aggregate; status "unavailable" ⇒ every figure is null (never 0 / "neutral"). */
1566
+ kol_activity?: TokenSnapshotKolActivity;
1567
+ /** null = the cohort read failed; 0 = no cohort rows. */
1568
+ launch_cohort_size?: number | null;
1569
+ /** Last trade seen by ANY source — not a price-age anchor (use price_observed_at). */
1570
+ last_trade_at?: string | null;
1571
+ /** v1.24 — mc_tracker | dex_stream; null when there is no price. */
1572
+ price_source?: "mc_tracker" | "dex_stream" | null;
1573
+ /** v1.24 — observation time of the SELECTED price source (price age anchor). */
1574
+ price_observed_at?: string | null;
1575
+ /** null = a price exists but its age is unknown (never a false "fresh"). */
1576
+ price_is_stale?: boolean | null;
1577
+ price_age_seconds?: number | null;
1578
+ /** v1.24 — why `deployer` is null: unknown creator vs failed lookup. */
1579
+ deployer_identity?: {
1580
+ identity_status: "resolved" | "unknown" | "lookup_failed";
1581
+ history_status: DeployerHistoryStatus | null;
1582
+ address: string | null;
1583
+ source: "deployer_tokens" | "pending_deploys" | null;
1584
+ };
1585
+ /** v1.24 — per-block read status; "unavailable" blocks are null, never defaults. */
1586
+ data_status?: Record<string, "ok" | "unavailable">;
1587
+ token_supply_burn_detected?: boolean | null;
1588
+ lp_burn_status?: LpBurnStatus;
1589
+ /** null = the blacklist lookup failed (unknown). */
1590
+ is_blacklisted?: boolean | null;
1591
+ }
1592
+ /** v1.24 — GET /token/{mint} creator block (audit F08). */
1593
+ export interface TokenSnapshotDeployer {
1594
+ wallet: string;
1595
+ address: string;
1596
+ tier: string;
1597
+ bonding_rate: number;
1598
+ total_deployed: number;
1599
+ total_bonded: number;
1600
+ recent_bond_rate: number;
1601
+ identity_status: "resolved";
1602
+ identity_source: "deployer_tokens" | "pending_deploys";
1603
+ /** Only "established" means bonding_rate is a real track record. */
1604
+ history_status: DeployerHistoryStatus;
1605
+ first_seen_at: string | null;
1606
+ observed_launch_count: number;
1607
+ resolved_outcome_count: number;
1608
+ stats_computed_at: string | null;
1609
+ }
1610
+ /** v1.24 — GET /token/{mint} KOL activity (audit F05): a complete window aggregate, never a newest-N sample. */
1611
+ export interface TokenSnapshotKolActivity {
1612
+ status: "ok" | "unavailable";
1613
+ buying_kols: number | null;
1614
+ selling_kols: number | null;
1615
+ net_flow_sol: number | null;
1616
+ signal: "accumulating" | "distributing" | "neutral" | null;
1617
+ /** Wallet addresses are ULTRA-only. */
1618
+ top_buyers: Array<TokenSnapshotTopBuyer & {
1619
+ wallet?: string;
1620
+ }>;
1621
+ window_hours: number;
1622
+ window_start: string | null;
1623
+ computed_at: string | null;
1624
+ last_trade_at: string | null;
1625
+ unique_kols: number | null;
1626
+ unique_wallets: number | null;
1627
+ buys: number | null;
1628
+ sells: number | null;
1629
+ buy_sol: number | null;
1630
+ sell_sol: number | null;
1631
+ counts_basis: "complete_window" | null;
1393
1632
  }
1394
1633
  /** Response of GET /token/{mint} — live token snapshot. */
1395
1634
  export interface TokenSnapshotResponse {
1396
1635
  token: TokenSnapshot;
1636
+ /** v1.24 — response assembly time; NOT the observation time of any field. */
1637
+ as_of?: string;
1397
1638
  }
1398
1639
  /** Valid signal names accepted by GET /signals/{name}/performance. */
1399
1640
  export type SignalName = "dump_cluster_count" | "runner_rate" | "recycled_early_buyer_count" | "coordination_count";
@@ -1446,8 +1687,8 @@ export interface TokenResponseBody {
1446
1687
  liquidity_to_mc_ratio?: number | null;
1447
1688
  /** v1.12 — SOL raised in the token's launch cohort (first-N buyers). */
1448
1689
  launch_cohort_sol?: number | null;
1449
- /** v1.12 — number of wallets in the launch cohort (0–20). */
1450
- launch_cohort_size?: number;
1690
+ /** v1.12 — number of wallets in the launch cohort (0–20); v1.24: null when the cohort read failed. */
1691
+ launch_cohort_size?: number | null;
1451
1692
  [key: string]: unknown;
1452
1693
  }
1453
1694
  export type ApiTier = "BASIC" | "PRO" | "ULTRA";
@@ -1532,6 +1773,16 @@ export interface TokensListParams {
1532
1773
  max_liq_mc_ratio?: number;
1533
1774
  /** v1.12 — filter by deployer tier. */
1534
1775
  deployer_tier?: "elite" | "good" | "moderate" | "rising" | "cold" | "unranked";
1776
+ /**
1777
+ * @deprecated use `lp_burn_status` per token, or `supply_burn` for the token-supply burn flag.
1778
+ * v1.24 — VERIFIED LP evidence only: true = lp_burnt_pct ≥ 99, false = measured AND below 99.
1779
+ * Unknown LP custody (every token today) matches NEITHER value, so both match nothing until an
1780
+ * LP-evidence writer exists. Sending it adds a `deprecations` entry to the response.
1781
+ */
1782
+ lp_burned?: boolean;
1783
+ /** v1.24 — the token-SUPPLY burn flag (what lp_burned used to filter on). */
1784
+ supply_burn?: boolean;
1785
+ launchpad?: "pumpfun" | "launchlab" | "bags";
1535
1786
  sort?: TokenListSort;
1536
1787
  limit?: number;
1537
1788
  offset?: number;
@@ -1557,6 +1808,11 @@ export interface TokenSummary {
1557
1808
  liquidity_to_mc_ratio?: number | null;
1558
1809
  /** v1.12 — deployer tier for this token's deployer; null when deployer is untracked. */
1559
1810
  deployer_tier?: string | null;
1811
+ launchpad?: string | null;
1812
+ /** v1.24 — VERIFIED LP evidence only; null = unknown (every token today). Was a supply-burn proxy before. */
1813
+ lp_burned?: boolean | null;
1814
+ lp_burn_status?: LpBurnStatus;
1815
+ token_supply_burn_detected?: boolean | null;
1560
1816
  }
1561
1817
  export interface TokensListResponse {
1562
1818
  tokens: TokenSummary[];
@@ -1566,8 +1822,27 @@ export interface TokensListResponse {
1566
1822
  returned: number;
1567
1823
  has_more: boolean;
1568
1824
  post_filtered: boolean;
1825
+ /** v1.24 — resume offset (a RAW candidate offset on post-filtered scans); null = end. */
1826
+ next_offset?: number | null;
1827
+ /** v1.24 — offsets walk a live ranking, not a snapshot: dedupe on mint. */
1828
+ order_is_live?: boolean;
1829
+ scanned?: number;
1830
+ scanned_until_offset?: number;
1831
+ /** v1.24 — the scan budget ran out: more matches MAY exist past next_offset. */
1832
+ scan_truncated?: boolean;
1833
+ scan_budget?: number;
1569
1834
  };
1570
1835
  filters: Record<string, unknown>;
1836
+ /** v1.24 — present only when a deprecated parameter (today: lp_burned) was sent. */
1837
+ deprecations?: TokensDeprecation[];
1838
+ }
1839
+ /** v1.24 — disclosure for a deprecated /tokens parameter. */
1840
+ export interface TokensDeprecation {
1841
+ param: string;
1842
+ status: "deprecated";
1843
+ /** Exactly what the parameter matches today. */
1844
+ matches: string;
1845
+ replacement: string;
1571
1846
  }
1572
1847
  export type AlmostBondedSort = "velocity_desc" | "progress_desc" | "eta_asc";
1573
1848
  export interface AlmostBondedParams {
@@ -1581,6 +1856,8 @@ export interface AlmostBondedParams {
1581
1856
  max_age_minutes?: number;
1582
1857
  /** Filter by deployer reputation tier. */
1583
1858
  deployer_tier?: "elite" | "good" | "moderate" | "rising" | "cold" | "unranked";
1859
+ /** Restrict to one launchpad venue (default: both). */
1860
+ launchpad?: "pumpfun" | "launchlab";
1584
1861
  /** Only tokens whose mint+freeze authorities are revoked. */
1585
1862
  authority_revoked?: boolean;
1586
1863
  /** Minimum liquidity_usd. */
@@ -1613,6 +1890,14 @@ export interface AlmostBondedResponse {
1613
1890
  tokens: AlmostBondedToken[];
1614
1891
  filters: Record<string, unknown>;
1615
1892
  returned: number;
1893
+ /** v1.24 — what the ranking covered; scan_truncated ⇒ velocity/eta ranks cover only `scanned` candidates. */
1894
+ scan?: {
1895
+ scanned: number;
1896
+ matched: number | null;
1897
+ complete: boolean;
1898
+ scan_truncated: boolean;
1899
+ scan_budget: number;
1900
+ };
1616
1901
  note: string;
1617
1902
  }
1618
1903
  export interface WalletStats {
@@ -1795,10 +2080,19 @@ export interface WalletPnlResponse {
1795
2080
  notes: {
1796
2081
  cost_basis_observable_from: string;
1797
2082
  truncated_trades?: number;
2083
+ trades_through?: string;
2084
+ trades_through_block_time?: number;
2085
+ trades_through_same_second?: number;
1798
2086
  };
1799
2087
  cache_hit?: boolean;
1800
2088
  computed_at?: string;
1801
2089
  ttl_seconds?: number;
2090
+ /** v1.24 — seconds since computed_at (source age survives a cache hit). */
2091
+ cache_age_seconds?: number;
2092
+ /** v1.24 — hits: head_checked (no newer trade) | unverified (check failed). */
2093
+ cache_validation?: "head_checked" | "unverified";
2094
+ /** v1.24 — a cache row existed but the wallet traded since; this response was recomputed. */
2095
+ cache_invalidated?: "new_activity";
1802
2096
  }
1803
2097
  export interface WalletPositionsResponse {
1804
2098
  address: string;
@@ -1806,6 +2100,9 @@ export interface WalletPositionsResponse {
1806
2100
  cache_hit?: boolean;
1807
2101
  computed_at?: string | null;
1808
2102
  ttl_seconds?: number | null;
2103
+ cache_age_seconds?: number;
2104
+ cache_validation?: "head_checked" | "unverified";
2105
+ cache_invalidated?: "new_activity";
1809
2106
  }
1810
2107
  export interface WalletHoldingsParams {
1811
2108
  /** 1–500, default 200. */
@@ -2407,8 +2704,10 @@ export interface TokenLocksResponse {
2407
2704
  export interface TokenLocksFeedParams {
2408
2705
  /** ISO date-time — only contracts created after this instant (use `pagination.next_since`). */
2409
2706
  since?: string;
2410
- /** ISO date-time — page back: only contracts created before this instant (`pagination.next_before`). */
2707
+ /** ISO date-time — page back: only contracts created before this instant (`pagination.next_before`). Legacy + strict: skips same-timestamp siblings — prefer `cursor`. */
2411
2708
  before?: string;
2709
+ /** v1.24 — opaque `pagination.next_cursor` from the previous page: strict (created_at, id) keyset, no repeats, no skips. Not combinable with `before`. */
2710
+ cursor?: string;
2412
2711
  mint?: string;
2413
2712
  sender?: string;
2414
2713
  recipient?: string;
@@ -2433,6 +2732,13 @@ export interface TokenFeedPagination {
2433
2732
  next_since: string | null;
2434
2733
  /** Pass as `before` to page back. */
2435
2734
  next_before: string | null;
2735
+ /** v1.24 (locks feed) — pass as `cursor` to page back without skipping same-timestamp rows; null = end. */
2736
+ next_cursor?: string | null;
2737
+ /** v1.24 — present when a post-filter (min_usd / min_pct_of_supply / status) was scanned. */
2738
+ post_filtered?: boolean;
2739
+ scanned?: number;
2740
+ scan_truncated?: boolean;
2741
+ scan_budget?: number;
2436
2742
  }
2437
2743
  /** WebSocket pointer returned by the feed endpoints — the same rows are pushed live on `channel`. */
2438
2744
  export interface TokenFeedStreamPointer {
@@ -2449,6 +2755,8 @@ export interface TokenFeedStreamPointer {
2449
2755
  export interface TokenLocksFeedResponse {
2450
2756
  locks: TokenLockFeedEntry[];
2451
2757
  pagination: TokenFeedPagination;
2758
+ /** v1.24 — "mint_facts:<table>" when a per-mint enrichment read failed; those rows' usd/ui/pct are null (unknown) and min_usd / min_pct_of_supply could not be applied to them. */
2759
+ degraded_fields?: string[];
2452
2760
  /** Pointer to the `token:locks` WS channel (event `token:lock`). */
2453
2761
  stream: TokenFeedStreamPointer;
2454
2762
  meta?: Record<string, unknown>;
@@ -3110,6 +3418,12 @@ export interface DeployerStatsResponse {
3110
3418
  bonds_detected: number;
3111
3419
  bond_rate: number;
3112
3420
  tiers: DeployerTierCounts;
3421
+ /** Per-tier average MC at alert over 30 d. v1.24: complete SQL aggregate; all null when mc_at_alert_complete=false. */
3422
+ avg_mc_at_alert_usd_30d?: Record<string, number | null>;
3423
+ /** v1.24: values are null (not 0) when the aggregate read failed. */
3424
+ mc_at_alert_samples_30d?: Record<string, number | null>;
3425
+ mc_at_alert_window_start?: string;
3426
+ mc_at_alert_complete?: boolean;
3113
3427
  }
3114
3428
  export interface DeployerLeaderboardParams {
3115
3429
  /** Restrict to one grade. */