robinhood-chain-sdk 0.10.0 → 0.12.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/README.md +29 -3
- package/dist/index.d.ts +316 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/stream.d.ts +2 -2
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +4 -0
- package/dist/stream.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +74 -74
package/README.md
CHANGED
|
@@ -251,9 +251,11 @@ const { events, has_more, next_before, coverage } = await client.lpEvents({ toke
|
|
|
251
251
|
for (const ev of events) {
|
|
252
252
|
if (ev.provider_is_token_deployer) console.warn("deployer pulled liquidity:", ev.tx_hash, ev.dex, ev.token_amount_raw);
|
|
253
253
|
}
|
|
254
|
-
console.log(coverage.
|
|
254
|
+
console.log(coverage.events); // ["remove"] — the default request is removals only
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
+
Since 2026-09-23 `action: "add" | "pool_created" | "all"` opts into liquidity adds (kept 7 days) and pool creations, and every row carries the depth fields `tick_lower` / `tick_upper`, `liquidity_delta`, `in_range`, `active_liquidity_delta`, `active_share` (v3/v4), `share_of_reserves` (v2) and `material` — null where the pool state was unknown and on older rows.
|
|
258
|
+
|
|
257
259
|
> **Removals ONLY.** Liquidity adds are not persisted (v4 adds share the topic and are dropped at decode; v2/v3 `Mint` is not subscribed), so every row is `event: "remove"` and an empty page means "no removals seen", never "no liquidity activity" — the `coverage` block spells this out. Amounts are **raw uint256 decimal strings** (`liquidity`, `amount0` / `amount1`, plus pre-resolved `token_amount_raw` / `quote_token` / `quote_amount_raw`) — do not `Number()` them; v4 rows carry `liquidity` only because the pool manager emits no token amounts. Filters: `token`, `pool` (v2/v3 address or v4 bytes32 poolId), `provider`, `dex`. Data since 2026-08-05.
|
|
258
260
|
|
|
259
261
|
## Token intelligence — `client.tokens`
|
|
@@ -583,7 +585,7 @@ await client.kol.firstTouchSubscriptions.update(subscription.id, { filters: {} }
|
|
|
583
585
|
|
|
584
586
|
## Streaming — `client.stream` (PRO+)
|
|
585
587
|
|
|
586
|
-
Managed WebSocket with token fetch on every (re)connect, auto-reconnect with backoff, heartbeat liveness, and typed events. Stream tokens **never expire** (since 2026-08-27) — there is no refresh timer; `client.stream.getToken()` returns the same token every call (`expires_at` / `next_refresh_at` are always `null`), and `getToken({ rotate: true })` replaces it (the old one keeps working for 60 s).
|
|
588
|
+
Managed WebSocket with token fetch on every (re)connect, auto-reconnect with backoff, heartbeat liveness, and typed events. Stream tokens **never expire** (since 2026-08-27) — there is no refresh timer; `client.stream.getToken()` returns the same token every call (`expires_at` / `next_refresh_at` are always `null`), and `getToken({ rotate: true })` replaces it (the old one keeps working for 60 s). Fourteen RHC channels:
|
|
587
589
|
|
|
588
590
|
| Channel | Emits | Tier | Scope |
|
|
589
591
|
|---|---|---|---|
|
|
@@ -595,8 +597,32 @@ Managed WebSocket with token fetch on every (re)connect, auto-reconnect with bac
|
|
|
595
597
|
| `rhc:price_alert:events` | `rhc:price_alert:dip`, `rhc:price_alert:recovery` | PRO+ | user-scoped; event-driven off each trade (a few seconds), not sub-second |
|
|
596
598
|
| `rhc:kol:coordination` | `rhc:kol:coordination` | PRO+ | user-scoped — only **your** rules' fires |
|
|
597
599
|
| `rhc:kol:first_touches` | `rhc:kol:first_touch` | PRO+ | broadcast — ULTRA gates only the first-touch *subscription CRUD*, not this channel |
|
|
598
|
-
| `rhc:token_locks` | `rhc:token_lock` | PRO+ | broadcast — a token lock / vesting contract created on chain |
|
|
600
|
+
| `rhc:token_locks` | `rhc:token_lock` (+ `rhc:token_unlock_upcoming`, `rhc:token_unlock_available` with `filters.lifecycle: true`) | PRO+ | broadcast — a token lock / vesting contract created on chain; opt-in unlock-schedule events (claims / cancels are not observable on RHC) |
|
|
599
601
|
| `rhc:token_prices` | `rhc:token_price` | PRO+ | **address-scoped** — `filters.addresses` required (25 / 100 / 250 per connection); one `snapshot: true` frame per address, then ≤ 1 tick per address per 250 ms with `quality` fresh / stale / unreliable + reason (`RhcTokenPriceTick`); no `seq` / `id` |
|
|
602
|
+
| `rhc:lp_events` | `rhc:lp_event` | **ULTRA+** | broadcast — liquidity `add` / `remove` / `pool_created` on tracked Uniswap v2/v3/v4 pools with `in_range`, `active_share`, `share_of_reserves`, `material` (`RhcLpStreamEvent`); filters `RhcLpEventsFilters`; durable resume |
|
|
603
|
+
| `rhc:token_candles` | `rhc:candle_closed`, `rhc:candle_revised` (+ `rhc:candle_update` with `filters.updates: true`) | PRO+ | scoped — live 1-minute candles for `filters.addresses` (`RhcCandleClosedEvent` / `RhcCandleUpdateEvent`); durable resume |
|
|
604
|
+
| `rhc:token_risk` | `rhc:risk_verdict_changed` (+ `rhc:risk_verdict` snapshot) | PRO+ | scoped — risk-verdict changes for `filters.addresses` (`RhcRiskVerdictChangedEvent`); score HIGHER = SAFER |
|
|
605
|
+
| `rhc:wallet_scores` | `rhc:deployer_tier_changed` | PRO+ | scoped — deployer tier changes for `filters.wallets` (0x deployers, `RhcDeployerTierChangedEvent`) |
|
|
606
|
+
|
|
607
|
+
**Liquidity events and lock schedule (server 2026-09-23).** `rhc:lp_events` frames carry raw `amount0` / `amount1` strings (null on v4), the position range and, for v3/v4, `in_range` / `active_liquidity_delta` / `active_share` — a share of liquidity at the current price, not of TVL (an out-of-range removal is `active_share: 0`); v2 carries `share_of_reserves`; `material: true` = a removal of ≥ 25 %. When the pool's tick was not known the active fields are `null` with `active_share_reason: "pool_state_unknown"` — never guessed. `provider` is usually the router / position manager. No USD field. On `rhc:token_locks`, `filters.lifecycle: true` adds `rhc:token_unlock_upcoming` (within 24 h) and `rhc:token_unlock_available` (passed within 30 min — **claimable per the schedule, not claimed**; `withdrawals_tracked: false`).
|
|
608
|
+
|
|
609
|
+
```ts
|
|
610
|
+
const lp = client.stream.connect();
|
|
611
|
+
lp.subscribe({ subId: "rugs", channels: ["rhc:lp_events"], filters: { actions: ["remove"], material_only: true } });
|
|
612
|
+
lp.on("rhc:lp_event", (e: RhcLpStreamEvent) => console.log(e.dex, e.pool, e.action, e.active_share ?? e.share_of_reserves));
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
**Candles, risk verdicts and deployer tiers (server 2026-09-23).** All three are PRO+ and **scoped**: per-connection cap PRO 25 / ULTRA 100 / BUSINESS 250 across named subscriptions; over the cap or without a scope the channel is rejected, never truncated. `rhc:token_candles` (`filters.addresses`, a budget separate from `rhc:token_prices`): `rhc:candle_closed` is the stored 1-minute row (id `candle:robinhood:<address>:<bucket epoch s>`), `rhc:candle_revised` the same row rewritten (`revision` n > 0, id suffix `:r<n>`); `filters.updates: true` adds `rhc:candle_update`, the in-progress minute (≤ 1 per address per second, a state stream: no id, never replayed, no snapshot). `rhc:token_risk` (`filters.addresses`, optional `risk_events`, `risk_snapshot` default `true`): `rhc:risk_verdict_changed` when a sweep recheck stores a different verdict — the change happened somewhere in `(previous_checked_at, checked_at]` — plus one `rhc:risk_verdict` snapshot frame per address (`frame.snapshot === true`); `score` is **higher = safer**, the opposite of Solana's `risk_score`. `rhc:wallet_scores` (`filters.wallets`, 0x deployers, optional `score_events`): `rhc:deployer_tier_changed` after each 5-min refresh ("recomputed at T", not "changed at T").
|
|
616
|
+
|
|
617
|
+
```ts
|
|
618
|
+
const s = client.stream.connect();
|
|
619
|
+
s.subscribe({ subId: "candles", channels: ["rhc:token_candles"], filters: { addresses: [TOKEN], updates: true } });
|
|
620
|
+
s.subscribe({ subId: "risk", channels: ["rhc:token_risk"], filters: { addresses: [TOKEN] } });
|
|
621
|
+
s.subscribe({ subId: "tiers", channels: ["rhc:wallet_scores"], filters: { wallets: [DEPLOYER] } });
|
|
622
|
+
s.on("rhc:candle_closed", (c: RhcCandleClosedEvent) => console.log(c.bucket_start, c.open_price_usd, c.close_price_usd, c.volume_usd));
|
|
623
|
+
s.on("rhc:risk_verdict_changed", (e: RhcRiskVerdictChangedEvent) => console.log(e.token_address, e.changed, e.before.score, "→", e.after.score));
|
|
624
|
+
s.on("rhc:deployer_tier_changed", (e: RhcDeployerTierChangedEvent) => console.log(e.address, e.tier_before, "→", e.tier_after));
|
|
625
|
+
```
|
|
600
626
|
|
|
601
627
|
> **Deprecated:** `rhc:trades` was never a real channel — 0.4.0 subscribers got a `channels_rejected` warning and silence. The server now accepts it as an alias of `rhc:dex_trades` (and acks it under the canonical name), and the SDK keeps the literal marked `@deprecated` so 0.4.0 code compiles. Use `rhc:dex_trades`.
|
|
602
628
|
|
package/dist/index.d.ts
CHANGED
|
@@ -369,17 +369,26 @@ export interface RhcLpEventsParams {
|
|
|
369
369
|
provider?: string;
|
|
370
370
|
/** Filter by DEX version. */
|
|
371
371
|
dex?: UniswapVersion;
|
|
372
|
+
/**
|
|
373
|
+
* Which actions to return (2026-09-23). Default `"remove"` = the historical
|
|
374
|
+
* removals-only feed, unchanged. `"add"` (kept 7 days), `"pool_created"` or
|
|
375
|
+
* `"all"` opt into rows persisted since the WS Phase 3 producer.
|
|
376
|
+
*/
|
|
377
|
+
action?: RhcLpAction | "all";
|
|
372
378
|
/** Opaque cursor from `next_before` (same (block_time,id) keyset as /rhc/trades). */
|
|
373
379
|
before?: string;
|
|
374
380
|
}
|
|
381
|
+
/** A liquidity action on Robinhood Chain. */
|
|
382
|
+
export type RhcLpAction = "add" | "remove" | "pool_created";
|
|
375
383
|
/**
|
|
376
|
-
* One liquidity
|
|
377
|
-
*
|
|
378
|
-
* STRINGS; v4 rows carry `liquidity` only
|
|
379
|
-
* amounts), so `amount0` / `amount1` /
|
|
384
|
+
* One liquidity event from `/rhc/lp-events`. Without `action` every row is
|
|
385
|
+
* `event: "remove"` (the default feed is removals only). Amounts are raw
|
|
386
|
+
* on-chain uint256 integers as decimal STRINGS; v4 rows carry `liquidity` only
|
|
387
|
+
* (the pool manager emits no token amounts), so `amount0` / `amount1` /
|
|
388
|
+
* `token_amount_raw` are null there.
|
|
380
389
|
*/
|
|
381
390
|
export interface RhcLpEvent {
|
|
382
|
-
event:
|
|
391
|
+
event: RhcLpAction;
|
|
383
392
|
pool: string;
|
|
384
393
|
dex: UniswapVersion;
|
|
385
394
|
fee_tier: number | null;
|
|
@@ -411,6 +420,305 @@ export interface RhcLpEvent {
|
|
|
411
420
|
block_time: string;
|
|
412
421
|
tx_hash: string;
|
|
413
422
|
log_index: number;
|
|
423
|
+
tick_lower?: number | null;
|
|
424
|
+
tick_upper?: number | null;
|
|
425
|
+
/** Signed liquidity change (v3/v4), int256 as string. */
|
|
426
|
+
liquidity_delta?: string | null;
|
|
427
|
+
/** tick_lower <= current tick < tick_upper just before the event; null = tick unknown. */
|
|
428
|
+
in_range?: boolean | null;
|
|
429
|
+
/** liquidity_delta when in range, "0" out of range. */
|
|
430
|
+
active_liquidity_delta?: string | null;
|
|
431
|
+
/** |active delta| / active liquidity before (v3/v4); 0 out of range; adds can exceed 1. */
|
|
432
|
+
active_share?: number | null;
|
|
433
|
+
/** v2 only: amount / reserve before (from the pair's Sync). */
|
|
434
|
+
share_of_reserves?: number | null;
|
|
435
|
+
/** true = a removal of ≥ 25 % of reserves / active liquidity; null for adds, creations and unknown shares. */
|
|
436
|
+
material?: boolean | null;
|
|
437
|
+
}
|
|
438
|
+
/** Why `active_share` is null / not the relevant share. */
|
|
439
|
+
export type RhcLpActiveShareReason = "pool_created" | "not_concentrated" | "pool_state_unknown" | "no_active_liquidity";
|
|
440
|
+
/**
|
|
441
|
+
* `rhc:lp_event` frame `data` (WS channel `rhc:lp_events`, ULTRA / BUSINESS,
|
|
442
|
+
* 2026-09-23). Frame id = `rhc:lp_event:<tx_hash>:<log_index>`. Every key is
|
|
443
|
+
* always present (null when unknown). `in_range` / `active_*` are null with
|
|
444
|
+
* `active_share_reason: "pool_state_unknown"` when the pool's tick was not
|
|
445
|
+
* known — never guessed. `provider` is usually a router / position manager,
|
|
446
|
+
* not the beneficial owner. No USD field.
|
|
447
|
+
*/
|
|
448
|
+
export interface RhcLpStreamEvent {
|
|
449
|
+
chain: Chain;
|
|
450
|
+
action: RhcLpAction;
|
|
451
|
+
dex: UniswapVersion;
|
|
452
|
+
pool: string;
|
|
453
|
+
token_address: string | null;
|
|
454
|
+
token: {
|
|
455
|
+
address: string | null;
|
|
456
|
+
symbol: string | null;
|
|
457
|
+
decimals: number | null;
|
|
458
|
+
};
|
|
459
|
+
token0: string | null;
|
|
460
|
+
token1: string | null;
|
|
461
|
+
provider: string | null;
|
|
462
|
+
liquidity: string | null;
|
|
463
|
+
/** NULL on v4 — ModifyLiquidity reports no token amounts. */
|
|
464
|
+
amount0: string | null;
|
|
465
|
+
amount1: string | null;
|
|
466
|
+
tick_lower: number | null;
|
|
467
|
+
tick_upper: number | null;
|
|
468
|
+
liquidity_delta: string | null;
|
|
469
|
+
in_range: boolean | null;
|
|
470
|
+
active_liquidity_delta: string | null;
|
|
471
|
+
active_share: number | null;
|
|
472
|
+
active_share_reason: RhcLpActiveShareReason | null;
|
|
473
|
+
share_of_reserves: number | null;
|
|
474
|
+
material: boolean | null;
|
|
475
|
+
block_number: number | null;
|
|
476
|
+
block_time: string | null;
|
|
477
|
+
tx_hash: string;
|
|
478
|
+
log_index: number | null;
|
|
479
|
+
}
|
|
480
|
+
/** Per-subscription filters for `rhc:lp_events` (all optional, AND; invalid values reject the channel). */
|
|
481
|
+
export interface RhcLpEventsFilters {
|
|
482
|
+
addresses?: string[];
|
|
483
|
+
pools?: string[];
|
|
484
|
+
dexes?: UniswapVersion[];
|
|
485
|
+
actions?: RhcLpAction[];
|
|
486
|
+
material_only?: boolean;
|
|
487
|
+
/** 0..1000 — only events whose relevant share (reserves on v2, active on v3/v4) is known and ≥ this. */
|
|
488
|
+
min_share?: number;
|
|
489
|
+
}
|
|
490
|
+
/** Unlock-schedule event names on `rhc:token_locks` (only with `filters.lifecycle: true`). */
|
|
491
|
+
export type RhcTokenLockLifecycleEventName = "rhc:token_unlock_upcoming" | "rhc:token_unlock_available";
|
|
492
|
+
/**
|
|
493
|
+
* Filters that switch `rhc:token_locks` to lifecycle mode. Claims, extensions
|
|
494
|
+
* and cancels are NOT observable on Robinhood Chain — only the unlock schedule.
|
|
495
|
+
*/
|
|
496
|
+
export interface RhcTokenLockLifecycleFilters {
|
|
497
|
+
lifecycle: true;
|
|
498
|
+
events?: RhcTokenLockLifecycleEventName[];
|
|
499
|
+
unlock_kinds?: Array<"cliff" | "final" | "tranche">;
|
|
500
|
+
/** Token scope for creates AND lifecycle (≤ 500); applied only with `lifecycle: true`. */
|
|
501
|
+
addresses?: string[];
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* `rhc:token_unlock_upcoming` (the lock's NEXT unlock, when it is within 24 h) /
|
|
505
|
+
* `rhc:token_unlock_available` (passed within the last 30 min — claimable PER
|
|
506
|
+
* THE SCHEDULE, NOT claimed). Frame id = `<event>:<event_key>`.
|
|
507
|
+
*/
|
|
508
|
+
export interface RhcTokenUnlockScheduleEvent {
|
|
509
|
+
event_key: string;
|
|
510
|
+
lock_id: string;
|
|
511
|
+
token_address: string;
|
|
512
|
+
family: string;
|
|
513
|
+
observed_at: string | null;
|
|
514
|
+
unlock_at: string;
|
|
515
|
+
unlock_kind: "cliff" | "final" | "tranche";
|
|
516
|
+
amount_raw: string | null;
|
|
517
|
+
amount_reason: string | null;
|
|
518
|
+
unlocked_total_raw: string | null;
|
|
519
|
+
release_model: "at_end" | "linear" | "tranched";
|
|
520
|
+
claimable?: true;
|
|
521
|
+
chain: Chain;
|
|
522
|
+
locker: string | null;
|
|
523
|
+
kind: string | null;
|
|
524
|
+
subject: string | null;
|
|
525
|
+
lp_kind: string | null;
|
|
526
|
+
lp_pool: string | null;
|
|
527
|
+
sender: string | null;
|
|
528
|
+
recipient: string | null;
|
|
529
|
+
locked_amount_raw: string | null;
|
|
530
|
+
amount_unit: string | null;
|
|
531
|
+
decimals: number | null;
|
|
532
|
+
withdrawals_tracked: false;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* `rhc:token_candles` subscribe filters (PRO+). `addresses` is REQUIRED (0x,
|
|
536
|
+
* case-insensitive) and capped per CONNECTION across named subscriptions —
|
|
537
|
+
* PRO 25 / ULTRA 100 / BUSINESS 250, a budget separate from
|
|
538
|
+
* `rhc:token_prices`. Over the cap, a missing scope or a non-boolean
|
|
539
|
+
* `updates` rejects the channel, never truncates.
|
|
540
|
+
*/
|
|
541
|
+
export interface RhcTokenCandlesFilters {
|
|
542
|
+
addresses: string[];
|
|
543
|
+
/** Also receive the in-progress minute as `rhc:candle_update` (a state stream). Default false. */
|
|
544
|
+
updates?: boolean;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* `rhc:candle_closed` / `rhc:candle_revised` frame `data` — the STORED
|
|
548
|
+
* 1-minute row (`rhc_ohlc_1m`), identical live and on a durable resume.
|
|
549
|
+
* Every key is always present (null when unknown). Frame id =
|
|
550
|
+
* `candle:robinhood:<address>:<bucket_start epoch s>`, plus `:r<n>` for the
|
|
551
|
+
* n-th revision (not event-prefixed). `revision` 0 = the close as first
|
|
552
|
+
* written; a rewrite (restart merge, spoofed-pool purge) bumps it and is
|
|
553
|
+
* announced as `rhc:candle_revised` with the full rewritten row.
|
|
554
|
+
*/
|
|
555
|
+
export interface RhcCandleClosedEvent {
|
|
556
|
+
chain: Chain;
|
|
557
|
+
address: string;
|
|
558
|
+
bucket_start: string;
|
|
559
|
+
/** bucket_start + 60 s. */
|
|
560
|
+
bucket_end: string;
|
|
561
|
+
/** When the row was first written. */
|
|
562
|
+
closed_at: string | null;
|
|
563
|
+
revision: number;
|
|
564
|
+
/** Latest rewrite; null for revision 0. */
|
|
565
|
+
revised_at: string | null;
|
|
566
|
+
open_price_usd: number | null;
|
|
567
|
+
high_price_usd: number | null;
|
|
568
|
+
low_price_usd: number | null;
|
|
569
|
+
close_price_usd: number | null;
|
|
570
|
+
open_mc_usd: number | null;
|
|
571
|
+
high_mc_usd: number | null;
|
|
572
|
+
low_mc_usd: number | null;
|
|
573
|
+
close_mc_usd: number | null;
|
|
574
|
+
close_liquidity_usd: number | null;
|
|
575
|
+
close_supply: number | null;
|
|
576
|
+
volume_usd: number | null;
|
|
577
|
+
buy_volume_usd: number | null;
|
|
578
|
+
sell_volume_usd: number | null;
|
|
579
|
+
trades: number | null;
|
|
580
|
+
buy_count: number | null;
|
|
581
|
+
sell_count: number | null;
|
|
582
|
+
dex: string | null;
|
|
583
|
+
pool_address: string | null;
|
|
584
|
+
final: true;
|
|
585
|
+
source: "rhc_ohlc_1m";
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* `rhc:candle_update` frame `data` (only with `filters.updates: true`) — the
|
|
589
|
+
* producer's in-progress minute, ≤ 1 per address per second. A state stream:
|
|
590
|
+
* no id / seq, never replayed, no snapshot on subscribe.
|
|
591
|
+
*/
|
|
592
|
+
export interface RhcCandleUpdateEvent {
|
|
593
|
+
chain: Chain;
|
|
594
|
+
address: string;
|
|
595
|
+
bucket_start: string;
|
|
596
|
+
bucket_end: string;
|
|
597
|
+
open_price_usd: number | null;
|
|
598
|
+
high_price_usd: number | null;
|
|
599
|
+
low_price_usd: number | null;
|
|
600
|
+
close_price_usd: number | null;
|
|
601
|
+
close_mc_usd: number | null;
|
|
602
|
+
volume_usd: number | null;
|
|
603
|
+
trades: number | null;
|
|
604
|
+
final: false;
|
|
605
|
+
/** The producer's timestamp of this state (ISO). */
|
|
606
|
+
as_of: string | null;
|
|
607
|
+
source: "rhc-dex-stream:open_candle";
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* `rhc:token_risk` subscribe filters (PRO+). `addresses` is REQUIRED (0x,
|
|
611
|
+
* lowercased), capped per connection PRO 25 / ULTRA 100 / BUSINESS 250.
|
|
612
|
+
*/
|
|
613
|
+
export interface RhcTokenRiskFilters {
|
|
614
|
+
addresses: string[];
|
|
615
|
+
/** Non-empty subset of the channel's event types. */
|
|
616
|
+
risk_events?: Array<"rhc:risk_verdict_changed">;
|
|
617
|
+
/** Send one `rhc:risk_verdict` snapshot per address on subscribe / scope change / resume. Default true. */
|
|
618
|
+
risk_snapshot?: boolean;
|
|
619
|
+
}
|
|
620
|
+
/** A stored RHC risk verdict (event `before` / `after`, snapshot `verdict`). */
|
|
621
|
+
export interface RhcRiskVerdict {
|
|
622
|
+
/** 100 − penalties: HIGHER = SAFER — the opposite of Solana's `risk_score`; never compare the two. */
|
|
623
|
+
score: number | null;
|
|
624
|
+
sellable: boolean | null;
|
|
625
|
+
sellable_reason: string | null;
|
|
626
|
+
proxy_kind: string | null;
|
|
627
|
+
upgradeable: boolean | null;
|
|
628
|
+
owner_model: string | null;
|
|
629
|
+
can_mint: boolean | null;
|
|
630
|
+
can_pause: boolean | null;
|
|
631
|
+
lp_custody: string | null;
|
|
632
|
+
lp_burned_pct: number | null;
|
|
633
|
+
code_size: number | null;
|
|
634
|
+
flags: string[];
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* `rhc:risk_verdict_changed` — a sweep recheck stored a verdict that differs
|
|
638
|
+
* in a diffed field. The change happened somewhere in
|
|
639
|
+
* `(previous_checked_at, checked_at]` (days to weeks), never at `checked_at`.
|
|
640
|
+
* A first assessment is never an event. Frame id =
|
|
641
|
+
* `rhc:risk_verdict_changed:<event_key>`.
|
|
642
|
+
*/
|
|
643
|
+
export interface RhcRiskVerdictChangedEvent {
|
|
644
|
+
chain: Chain;
|
|
645
|
+
token_address: string;
|
|
646
|
+
/** `<token>:verdict:<checked_at epoch ms>`. */
|
|
647
|
+
event_key: string;
|
|
648
|
+
changed: Array<"score" | "sellable" | "proxy_kind" | "upgradeable" | "owner_model" | "can_mint" | "can_pause" | "lp_custody" | "flags">;
|
|
649
|
+
flags_added: string[];
|
|
650
|
+
flags_removed: string[];
|
|
651
|
+
before: RhcRiskVerdict;
|
|
652
|
+
after: RhcRiskVerdict;
|
|
653
|
+
checked_at: string;
|
|
654
|
+
previous_checked_at: string | null;
|
|
655
|
+
score_semantics: "higher_is_safer";
|
|
656
|
+
detection: {
|
|
657
|
+
method: "recheck_sweep";
|
|
658
|
+
recheck_target_hours: number;
|
|
659
|
+
sweep_interval_minutes: number;
|
|
660
|
+
min_liquidity_usd: number;
|
|
661
|
+
note: string;
|
|
662
|
+
};
|
|
663
|
+
written_at: string;
|
|
664
|
+
source: "rhc_token_risk";
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* `rhc:risk_verdict` snapshot frame `data` (frame `snapshot: true`, no id /
|
|
668
|
+
* seq): the CURRENT stored verdict of one scoped address.
|
|
669
|
+
*/
|
|
670
|
+
export interface RhcRiskVerdictSnapshot {
|
|
671
|
+
chain: Chain;
|
|
672
|
+
token_address: string;
|
|
673
|
+
/** false = never assessed (verdict and checked_at null). */
|
|
674
|
+
assessed: boolean;
|
|
675
|
+
verdict: RhcRiskVerdict | null;
|
|
676
|
+
checked_at: string | null;
|
|
677
|
+
score_semantics: "higher_is_safer";
|
|
678
|
+
source: "rhc_token_risk";
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* `rhc:wallet_scores` subscribe filters (PRO+). `wallets` is REQUIRED — 0x
|
|
682
|
+
* deployer addresses (lowercased) — capped per connection PRO 25 / ULTRA 100 /
|
|
683
|
+
* BUSINESS 250. A subscription that also holds the Solana `wallet:scores`
|
|
684
|
+
* channel may mix in base58 wallets; an entry of a chain the subscription does
|
|
685
|
+
* not hold is refused.
|
|
686
|
+
*/
|
|
687
|
+
export interface RhcWalletScoresFilters {
|
|
688
|
+
wallets: string[];
|
|
689
|
+
/** Optional subset of the held channels' event types. */
|
|
690
|
+
score_events?: Array<"rhc:deployer_tier_changed" | "deployer:tier_changed" | "kol:score_state_changed">;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* `rhc:deployer_tier_changed` — the 5-min `mv_rhc_deployers` refresh found a
|
|
694
|
+
* different tier ("recomputed at T", not "changed at T"). A deployer appearing
|
|
695
|
+
* `neutral` is not an event; entering a ranked tier is (`tier_before:
|
|
696
|
+
* "neutral"`), a first appearance already ranked has `tier_before: null` +
|
|
697
|
+
* `first_appearance: true`, vanishing from the matview has `tier_after: null`.
|
|
698
|
+
* Frame id = `rhc:deployer_tier_changed:<event_key>`.
|
|
699
|
+
*/
|
|
700
|
+
export interface RhcDeployerTierChangedEvent {
|
|
701
|
+
/** `<address>:<refresh epoch ms>`. */
|
|
702
|
+
event_key: string;
|
|
703
|
+
chain: Chain;
|
|
704
|
+
address: string;
|
|
705
|
+
tier_before: DeployerTier | null;
|
|
706
|
+
tier_after: DeployerTier | null;
|
|
707
|
+
first_appearance: boolean;
|
|
708
|
+
/** null when the deployer left the matview. */
|
|
709
|
+
stats: {
|
|
710
|
+
tokens_deployed: number | null;
|
|
711
|
+
graduated: number | null;
|
|
712
|
+
graduation_rate: number | null;
|
|
713
|
+
runners: number | null;
|
|
714
|
+
runner_rate: number | null;
|
|
715
|
+
best_peak_mc_usd: number | null;
|
|
716
|
+
first_deploy_at: string | null;
|
|
717
|
+
last_deploy_at: string | null;
|
|
718
|
+
} | null;
|
|
719
|
+
computed_at: string;
|
|
720
|
+
source: "matview_refresh";
|
|
721
|
+
matview: "mv_rhc_deployers";
|
|
414
722
|
}
|
|
415
723
|
export interface RhcLpEventsResponse {
|
|
416
724
|
chain: Chain;
|
|
@@ -419,10 +727,11 @@ export interface RhcLpEventsResponse {
|
|
|
419
727
|
has_more: boolean;
|
|
420
728
|
/** Opaque pagination cursor; pass back as `before`. */
|
|
421
729
|
next_before: string | null;
|
|
422
|
-
/** Honesty block:
|
|
730
|
+
/** Honesty block: the actions this response covers (["remove"] by default), adds_persisted, note, since. */
|
|
423
731
|
coverage: {
|
|
424
732
|
events: string[];
|
|
425
|
-
adds_persisted: boolean;
|
|
733
|
+
adds_persisted: boolean | null;
|
|
734
|
+
adds_retention_days?: number;
|
|
426
735
|
note: string;
|
|
427
736
|
since: string;
|
|
428
737
|
};
|