madeonsol-x402 4.0.0 → 4.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/README.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # madeonsol-x402
2
2
 
3
- > **Unreleased ShredPrism migration (PR #420):** sniper becomes ULTRA/BUSINESS/ENTERPRISE API-key only. The keyless sniper route returns HTTP 410 without a new payment. Early observations are not proof of execution. The changes below describe the release candidate; package publication and source activation are still pending. Historical release notes describe earlier behavior.
3
+
4
+ > **Agent Gateway and x402:** Current versions of this SDK support the existing
5
+ > documented keyed and keyless data routes. The new six-tool Agent Intelligence
6
+ > Gateway is a separate coordinated release, **not an automatically priced
7
+ > client method**. A paid composite requires a real route in the source-of-truth
8
+ > price catalog, exact Solana-USDC payment terms and same-proof paid-result
9
+ > recovery. For sustained agent activity, use the appropriate API subscription
10
+ > and preserve each underlying source's tier. See
11
+ > [Gateway contract](../../docs/agent-gateway.md) and
12
+ > [content/package release checklist](../../docs/runbooks/agent-gateway-content-release.md).
13
+
14
+
15
+ > **New in 4.1.0: managed ShredPrism early-stream client (additive).** `MadeOnSolREST.earlyStream()` plus the `walletTrades()` / `followTokens()` subscription helpers connect to the separate ULTRA/BUSINESS/ENTERPRISE early gateway with the same stream token: reconnect with backoff, separate safe checkpoints per subscription, bounded process-local replay with deduplication, explicit gaps, optional `compact-v1` frames (expanded before your callback) and private saved wallet list controls (`manageWalletList()`). It only connects when `getStreamToken()` advertises `early_ws_url`, and only the channels listed in `early_stream.channels` are served; otherwise it stops with `early_stream_unavailable` or a server rejection. New types cover the complete six-family wire contract: `EarlyObservationBase`, per-family deploy/trade/liquidity/migration/lock/token-change observation data, `EarlyOutcomeData`, plus `EarlyChannel`, filters, controls and private-list types; `StreamToken.early_stream` gains the six channel names and `coverage`. Released channels are `early:deploys`, `early:locks`, `early:trades`, `early:liquidity`, `early:migrations`, and `early:token_changes`. Observations are provisional instruction intent, not executed fills; coverage is partial and replay is never durable history. Existing methods are unchanged.
4
16
 
5
17
 
6
18
  [![npm version](https://img.shields.io/npm/v/madeonsol-x402?style=flat-square)](https://www.npmjs.com/package/madeonsol-x402)
@@ -16,7 +28,7 @@ TypeScript SDK for the [MadeOnSol](https://madeonsol.com) Solana KOL intelligenc
16
28
 
17
29
  > Real-time Solana trading intelligence: track 2,000+ KOL wallets with <3s latency on paid keys and x402 pay-per-call (free-tier live feeds are 5-min delayed), score 85K+ Pump.fun deployers, surface deshred deploy signals ~500ms before on-chain confirmation, score 1.5M+ early-buyer wallets (incl. dump-cluster detection), read bundle-cohort holdings (`held_pct_of_supply` — are the bundlers still holding?), verify any wallet's current on-chain holdings (with airdrop/insider `transfer_delta` detection), push every pump.fun graduation, and stream every DEX trade. Free tier: 200 requests/day across 40+ endpoints (live feeds 5-min delayed) — no signup payment. Get a key at [madeonsol.com/pricing](https://madeonsol.com/pricing).
18
30
 
19
- > **Server update 2026-10-05 (no package change needed): realtime developer activity and USDC/USDT trade sizing.** The webhook event `dev:activity` (PRO+) and, on the Ultra DEX firehose socket, `dev_subscribe` → `dev:activity` + `dev:activity_enrichment` (same `id`) now deliver a token developer's `dev_sell`, `dev_buy`, `dev_token_transfer_out` and `dev_token_transfer_in` as they happen (a transfer is never a sell; PRO gets the developer's own events without identity fields; transfer coverage is partial, see `transfer_watch_coverage`). On `dex:trades`, a swap paid in USDC or USDT now carries `sol_amount` = the SOL equivalent of its stable leg (used by `dust`, `min_sol`, `max_sol`) plus the additive fields `sol_amount_basis` (`native_sol` | `stable_quote_equivalent` | `stable_quote_unconverted`) and `stable_quote`; `stable_quote_unconverted` means `sol_amount` 0 (size unknown). Details: [changelog](https://madeonsol.com/changelog).
31
+ > **Server update 2026-10-05/08: realtime developer activity and USDC/USDT trade sizing.** The webhook event `dev:activity` (PRO+) and ULTRA+ DEX-socket `dev_subscribe` deliver `dev_sell`, `dev_buy`, `dev_token_transfer_out` and `dev_token_transfer_in` (a transfer is never a sell; PRO gets direct-developer events without identity stitching). Transfers now combine the legacy bounded wallet watch with the broad SPL Token/Token-2022 candidate source for attributed creators; `transfer_watch_coverage` describes the legacy watch only, while `transfer_sources.broad` reports the broad source's state/gaps. Recovered broad-source rows are REST history only, not retroactive realtime alerts. On `dex:trades`, a swap paid in USDC or USDT now carries `sol_amount` = the SOL equivalent of its stable leg (used by `dust`, `min_sol`, `max_sol`) plus the additive fields `sol_amount_basis` (`native_sol` | `stable_quote_equivalent` | `stable_quote_unconverted`) and `stable_quote`; `stable_quote_unconverted` means `sol_amount` 0 (size unknown). Details: [changelog](https://madeonsol.com/changelog).
20
32
 
21
33
  > **Server update 2026-10-04 (no package change needed): copy-trade rules follow any valid source wallet.** `source_wallets` no longer have to be tracked KOL wallets: any valid Solana wallet fires, KOL membership is optional enrichment, and copy-trade sources do not use Wallet Tracker quota. Each rule reports `source_admission` (`any_wallet`) and `operational_state` (`eligible`, or an infrastructure state `monitoring_pending` / `monitoring_unavailable` / `source_capacity_unavailable`). `source_wallets_tracked` / `source_wallets_untracked` and the `untracked_source_wallets` warning are legacy fields, still filled. This supersedes the "signals fire only for tracked KOL wallets" wording in older notes below. Limits are unchanged: PRO 3 rules × 5 wallets, ULTRA 20 × 50, BUSINESS 100 × 250.
22
34
 
@@ -24,7 +36,7 @@ TypeScript SDK for the [MadeOnSol](https://madeonsol.com) Solana KOL intelligenc
24
36
 
25
37
  > **New in 2.9.0: token lock provenance.** Typed: Token lock rows carry `provider` (`identity` verified | compatible | unverified; `lock_url` always null on Solana, never constructed), `explorer` (Solana Explorer links), `price_usd`, `seconds_until_end`, `seconds_until_next_unlock` and, for Bonfida, the tranche `schedule` (server 2026-10-02). Additive only.
26
38
 
27
- > **New in 3.2.0: deployer activity timeline.** `client.deployerActivity(wallet, { limit?, cursor?, since?, types? })` (typed `DeployerActivityResponse`) binds `GET /deployer-hunter/{wallet}/activity`: one newest-first timeline of launches, the deployer's own dev buys/sells, creator transfers, fee claims, funding in and capital out, windowed on each event's own time (PRO 30 d, ULTRA 365 d, BUSINESS unbounded; page clamped to 100 / 100 / 500). History is online-only for now: read `coverage.families.<family>.complete`, `archive_required_before` and `plan.history.archive_only` before treating an empty range as "nothing happened"; `skipped_reason: "no_attributed_launch"` marks a wallet with no attributed launch. PRO+, keyed (v1) only.
39
+ > **Deployer activity timeline (server-expanded 2026-10-08).** `client.deployerActivity(wallet, { limit?, cursor?, since?, types? })` binds `GET /deployer-hunter/{wallet}/activity`: launches, `dev_buy`, `dev_sell`, `dev_token_transfer_out`, `dev_token_transfer_in`, creator transfers, fee claims, funding in and capital out, newest first. Realtime dev rows come from persisted `dev_exit_events`; recovered transfer rows can carry `recovered`, `recovered_at`, `time_basis: "chain"`, `late_classified` and `counterparty_count`. Read `coverage.families.*`, retention boundaries and the history plan before interpreting an empty range; transfer history has a shorter online retention than trade history. PRO+, keyed (v1) only.
28
40
 
29
41
  > **New in 3.1.0 (types and docs only, no runtime change):** `DeployerProfile.first_deploy_at` (earliest deploy observed by MadeOnSol) and `DeployerProfileResponse.capital_intelligence` (PRO+) are typed; REST-only parameters are documented as rejected on the x402 route with `400 param_not_supported_on_x402` before any payment (they were documented as ignored); `DeployerTokensParams.only_bonded` is documented as applied.
30
42
 
@@ -643,3 +655,164 @@ Docs: [madeonsol.com/solana-api](https://madeonsol.com/solana-api)
643
655
  | ElizaOS | [`@madeonsol/plugin-madeonsol`](https://www.npmjs.com/package/@madeonsol/plugin-madeonsol) |
644
656
  | Solana Agent Kit | [`solana-agent-kit-plugin-madeonsol`](https://www.npmjs.com/package/solana-agent-kit-plugin-madeonsol) |
645
657
 
658
+ ## Managed ShredPrism early-stream client (4.1.0+)
659
+
660
+ `MadeOnSolREST.earlyStream()` extends this SDK with the separate early protocol.
661
+ It requires ULTRA, BUSINESS or ENTERPRISE and an `early_ws_url` in `getStreamToken()`
662
+ discovery; subscribe only to channels listed in `early_stream.channels`.
663
+ The existing confirmed-stream `stream()` contract is unchanged.
664
+
665
+ ```js
666
+ import { MadeOnSolREST, walletTrades, followTokens } from 'madeonsol-x402';
667
+ const api = new MadeOnSolREST({ apiKey: process.env.MADEONSOL_API_KEY });
668
+ const stream = api.earlyStream({
669
+ subscriptions: [
670
+ walletTrades(['YOUR_WALLET'], { sub_id: 'wallets', directions: ['buy'] }),
671
+ followTokens(['YOUR_MINT'], { sub_id: 'token' }),
672
+ ],
673
+ onFrame(frame) {
674
+ // early:observed is provisional instruction intent; early:outcome reports status.
675
+ // Correlate outcomes through frame.data.observed_event_id.
676
+ console.log(frame);
677
+ },
678
+ onStatus(status) {
679
+ if (['gap', 'fatal', 'reconnect'].includes(status.type)) console.error(status);
680
+ },
681
+ });
682
+ stream.connect();
683
+ // Once subscriptions are ready (and any replay has completed), await each control:
684
+ // await stream.updateSubscription('wallets', { filters: { wallets: ['NEW_WALLET'] } });
685
+ // await stream.updateSubscription('wallets', { format: 'compact-v1' });
686
+ // await stream.unsubscribe('token');
687
+ // stream.close();
688
+ ```
689
+
690
+ Replace placeholder addresses before running. The repository example is
691
+ `packages/madeonsol-x402/examples/early-stream.mjs`: build the SDK, set
692
+ `MADEONSOL_API_KEY` plus exactly one of `EARLY_WALLETS` or `EARLY_MINTS`, and run
693
+ that file with Node 22+. It uses the platform WebSocket; `WebSocketImpl` can inject
694
+ `ws`.
695
+
696
+ - Token acquisition uses the existing REST client on every connection. Tokens
697
+ do not expire automatically; the SDK never schedules rotation. Browser-compatible
698
+ handshake authentication uses `?token=`, which must remain redacted in proxy logs.
699
+ Credentials and raw REST/transport errors are excluded from SDK diagnostics.
700
+ - Transient disconnects retry with jittered exponential backoff (500 ms to 30 s;
701
+ 10 consecutive reconnect attempts by default). Authorization closes have a
702
+ three-rejection budget. A connection-limit close waits at least 60 s. Policy
703
+ rejection stops. Token acquisition, handshake, controls and replay have 15 s
704
+ deadlines. There is no additional application heartbeat; the gateway's WS
705
+ ping/pong remains responsible for detecting an idle broken connection.
706
+ - Up to 10 configured subscriptions share one connection; server tier/connection
707
+ caps still apply. Updates and unsubscribe require a connected client and one
708
+ control at a time. Await each call. The SDK replaces local settings only after
709
+ server acknowledgement. Omitted filters remain; `{}` clears them. Use `subscribe(control)` to add a new subscription after connecting. An empty
710
+ initial array is supported for list-management-only sessions.
711
+ - Frames are handled in arrival order. Async `onFrame` handlers are awaited, and
712
+ an exception/rejection stops the client without advancing past that event.
713
+ The pending queue is bounded to 2,048 frames / 8 MiB, measured in UTF-8, by default.
714
+ Overflow stops with `client_queue_limit`; expensive work should leave the handler.
715
+ Closing invalidates pending work and cancels retry/replay/control timers.
716
+ - `getCursors()` returns separate safe checkpoints per subscription. During replay,
717
+ new live traffic is delivered but cannot advance the checkpoint until a complete
718
+ replay finishes. A disconnect mid-replay resumes from the prior safe point.
719
+ Incomplete replay or a reported gap freezes the checkpoint. A later complete
720
+ recovery can resolve it; `acceptGap(subId)` explicitly skips to received progress
721
+ once replay ends if the caller accepts the missing range. No gap is silently
722
+ accepted. Process-local replay is bounded and is never durable history.
723
+ - Persist cursors with their matching subscription settings outside the handler,
724
+ after processing has completed. To restart, put each saved cursor in that
725
+ subscription's `resume`. Recent IDs are deduplicated per subscription and event
726
+ type (10,000 IDs per subscription). Deduplication is bounded and in-memory:
727
+ downstream processing must tolerate duplicates after eviction/restart.
728
+ - `full` remains the default. `compact-v1` is expanded before the application
729
+ callback. The local managed client costs more CPU than a minimal reader; no
730
+ zero-overhead or customer lead-time claim is made. Keep handlers short. Current
731
+ protocol coverage is partial and all observations remain provisional.
732
+
733
+ Full wire contract: https://madeonsol.com/docs/shredprism-stream.md.
734
+
735
+
736
+ ## Private saved wallet lists
737
+
738
+ The early gateway stores named lists separately from the confirmed wallet-tracker
739
+ watchlist. Its authenticated stream-token owner is authoritative; a request cannot
740
+ supply another user ID. These lists are never added to public KOL/alpha rosters and
741
+ do not change upstream wallet-tracker subscriptions.
742
+
743
+ On a connected SDK client (it may start with `subscriptions: []`):
744
+
745
+ ```js
746
+ const created = await stream.manageWalletList({
747
+ op: 'create', name: 'My wallets', wallets: ['YOUR_WALLET'],
748
+ });
749
+ await stream.subscribe({
750
+ type: 'subscribe', sub_id: 'private-trades', channels: ['early:trades'],
751
+ wallet_list: created.list.id,
752
+ });
753
+ const changed = await stream.manageWalletList({
754
+ op: 'replace', id: created.list.id, revision: created.list.revision,
755
+ name: 'My wallets', wallets: ['ANOTHER_WALLET'],
756
+ });
757
+ // list returns metadata + wallet_count; get returns the actual wallet array.
758
+ await stream.manageWalletList({ op: 'list' });
759
+ await stream.manageWalletList({ op: 'get', id: created.list.id });
760
+ // Explicitly delete with the current revision when no longer needed:
761
+ // await stream.manageWalletList({ op: 'delete', id: created.list.id, revision: changed.list.revision });
762
+ ```
763
+
764
+ Replace the placeholder addresses, wait for the SDK `ready` status, and await each
765
+ control. Raw WS uses `{type:"wallet_list", ...control}` and receives
766
+ `{type:"wallet_list_result", op, list?, lists?, limits}`. Revisions are decimal
767
+ strings. `replace` supplies the whole name/address snapshot; `replace` and `delete`
768
+ require the current revision. A conflict leaves the existing stored row intact.
769
+ `list` is summary-only so a full BUSINESS account cannot exceed the control-frame
770
+ byte budget; use `get` for one list's addresses. There is no new REST endpoint.
771
+
772
+ Limits reuse existing tier budgets: ULTRA 10 lists / 100 wallets per list;
773
+ BUSINESS and ENTERPRISE 20 / 500. Lists contain 1..limit unique Solana addresses,
774
+ with a unique owner-scoped name of 1..64 characters. Delete an empty group instead
775
+ of subscribing with an empty wallet filter. The SDK supports 10 simultaneous
776
+ subscriptions; server subscription and connection caps remain authoritative.
777
+
778
+ A subscription's top-level `wallet_list` is an ID, valid only for `early:trades`.
779
+ Do not combine it with `filters.wallets` or `filters.actors`; direction, amount,
780
+ protocol and other compatible filters still intersect. Omitting it on update
781
+ keeps the reference; explicit `wallet_list: null` detaches it, so supply replacement
782
+ filters if the subscription should remain wallet-scoped.
783
+
784
+ Subscribe/update acknowledgements and `list` controls report
785
+ `wallet_list: {id, revision}`. A successful edit atomically replaces each active
786
+ subscription's in-memory index, then emits `wallet_list_updated` with the active
787
+ revision. An update arriving during replay ends the old replay as incomplete;
788
+ clients retain the prior safe cursor. Reconnect reloads the current saved revision,
789
+ and replay uses that current list, not historical list membership.
790
+
791
+ Local successful writes are applied to current owner subscriptions immediately.
792
+ Edits from another process are discovered by a 5-second refresh. Unchanged rows
793
+ return their revision without resending wallet arrays. A previous snapshot is valid
794
+ for at most 15 seconds after a successful read. On deletion, missing access, failed
795
+ application, excess wallets after tier downgrade, or expiry, the affected binding
796
+ is removed and `wallet_list_unavailable` is sent. The SDK surfaces it as a `gap`;
797
+ resubscribe after correcting the cause. A transient failed read does not extend TTL.
798
+ Normal auth expiry/downgrade enforcement still applies.
799
+
800
+ A dedicated one-connection database pool handles controls/refresh, with 2-second
801
+ query deadlines and at most 8 admitted list queries. At most 256 distinct active
802
+ owner/list references are materialized per gateway, within the existing 100,000
803
+ binding budget. Overload fails explicitly. Decode, matching, live publication and
804
+ replay never query the database; delivery checks the local snapshot expiry and tier
805
+ limit. Do not describe this bounded local implementation as zero-overhead or as
806
+ complete wallet transaction coverage.
807
+
808
+ ## Client scope
809
+
810
+ The managed early client ships in this TypeScript package only. The Python package,
811
+ MCP server, ElizaOS plugin and Solana Agent Kit plugin do not include it; use the raw
812
+ WebSocket contract there. The existing `sniperRecent()` / `sniperByDeployer()` helpers
813
+ are separate from direct six-family subscriptions and private-list WS controls.
814
+
815
+ Coverage, the dated customer benchmark by channel (processed and confirmed references) and local
816
+ development benchmarks, with raw downloads and methodology:
817
+ https://madeonsol.com/solutions/shredprism-stream#benchmark-by-channel. Dated measurements from one
818
+ client, not a fixed customer head start.
@@ -0,0 +1,4 @@
1
+ import type { EarlyFrame } from './early-stream.js';
2
+ export declare const COMPACT_FIELDS: readonly string[];
3
+ export declare function expandEarlyFrame(value: unknown): EarlyFrame;
4
+ //# sourceMappingURL=early-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"early-codec.d.ts","sourceRoot":"","sources":["../src/early-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,eAAO,MAAM,cAAc,mBAgBzB,CAAC;AAEH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAe3D"}
@@ -0,0 +1,44 @@
1
+ export const COMPACT_FIELDS = Object.freeze([
2
+ 'schema_version', 'chain', 'channel', 'event_id', 'signature', 'observed_slot',
3
+ 'first_observed_at', 'source', 'source_region', 'observation_stage', 'execution_status',
4
+ 'decoding_basis', 'decoder_version', 'transaction_version', 'transaction_config',
5
+ 'lifetime_token', 'protocol', 'instruction', 'outer_instruction_index', 'program_id',
6
+ 'fee_payer', 'action', 'actor', 'attribution_basis', 'mint', 'quote_mint', 'pool',
7
+ 'direction', 'swap_mode', 'input_mint', 'output_mint', 'requested_input_raw',
8
+ 'max_input_raw', 'min_output_raw', 'target_output_raw', 'wallet_label',
9
+ 'observed_event_id', 'outcome_source', 'commitment', 'landed_slot',
10
+ 'execution_error', 'outcome_at', 'missing_fields', 'launchpad',
11
+ 'requested_amount_raw', 'lp_mint', 'target_lp_output_raw', 'requested_lp_input_raw',
12
+ 'max_base_input_raw', 'max_quote_input_raw', 'min_base_output_raw', 'min_quote_output_raw',
13
+ 'requested_base_input_raw', 'requested_quote_input_raw', 'authority', 'authority_type',
14
+ 'new_authority', 'authority_revocation_requested', 'target_scope', 'target_account',
15
+ 'token_account', 'decimals', 'authority_is_signer', 'lock_account', 'lock_kind',
16
+ 'sender', 'recipient', 'sender_token_account', 'destination_token_account', 'schedule',
17
+ ]);
18
+ const names = new Map(COMPACT_FIELDS.map((name, i) => [i.toString(36), name]));
19
+ export function expandEarlyFrame(value) {
20
+ if (!value || typeof value !== 'object' || Array.isArray(value))
21
+ throw new Error('invalid_frame');
22
+ const frame = value;
23
+ if (!['early:observed', 'early:outcome'].includes(frame.event ?? ''))
24
+ return frame;
25
+ if (frame.format === undefined || frame.format === 'full')
26
+ return frame;
27
+ if (frame.format !== 'compact-v1' || !frame.data || typeof frame.data !== 'object' || Array.isArray(frame.data))
28
+ throw new Error('invalid_compact_frame');
29
+ const input = frame.data;
30
+ const data = {};
31
+ for (const k of Object.keys(input)) {
32
+ const key = k.startsWith('~') ? k.slice(1) : names.get(k);
33
+ if (key === undefined || Object.hasOwn(data, key))
34
+ throw new Error('invalid_compact_frame');
35
+ if (key === '__proto__')
36
+ Object.defineProperty(data, key, { value: input[k], enumerable: true, writable: true, configurable: true });
37
+ else
38
+ data[key] = input[k];
39
+ }
40
+ const result = { ...frame, data };
41
+ delete result.format;
42
+ return result;
43
+ }
44
+ //# sourceMappingURL=early-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"early-codec.js","sourceRoot":"","sources":["../src/early-codec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import type { EarlySubscribeControl, EarlyStreamFilters, EarlyEventFormat, EarlyWalletListControl, EarlyWalletListResult, EarlyObservationData, EarlyOutcomeData, StreamToken } from './types.js';
2
+ export { expandEarlyFrame } from './early-codec.js';
3
+ export type { EarlyChannel, EarlyAmountField, EarlyAmountFilter, EarlyStreamFilters, EarlyEventFormat, EarlySubscribeControl, EarlyUpdateControl, EarlyObservationBase, EarlyWalletLabel, EarlyDeployObservationData, EarlyTradeObservationData, EarlyLiquidityObservationData, EarlyMigrationObservationData, EarlyLockSchedule, EarlyLockObservationData, EarlyTokenChangeObservationData, EarlyObservationData, EarlyOutcomeData } from './types.js';
4
+ export interface EarlyCursor {
5
+ instance: string;
6
+ seq: number;
7
+ }
8
+ export interface EarlyFrame {
9
+ event?: string;
10
+ type?: string;
11
+ sub_id?: string;
12
+ id?: string;
13
+ cursor?: EarlyCursor;
14
+ data?: EarlyObservationData | EarlyOutcomeData | Record<string, unknown>;
15
+ [key: string]: unknown;
16
+ }
17
+ export interface EarlyStreamOptions {
18
+ /** Existing non-expiring token, fetched on every connect; never rotate here. */
19
+ getToken: () => Promise<Pick<StreamToken, 'token' | 'early_ws_url'>>;
20
+ subscriptions: EarlySubscribeControl[];
21
+ /** Awaited in arrival order. A rejection stops delivery without committing. */
22
+ onFrame: (frame: EarlyFrame) => void | Promise<void>;
23
+ /** Diagnostic callback. Never receives credentials or raw transport errors. */
24
+ onStatus?: (status: Record<string, unknown>) => void;
25
+ /** Native browser/Node WebSocket by default; pass ws explicitly if desired. */
26
+ WebSocketImpl?: unknown;
27
+ autoReconnect?: boolean;
28
+ maxReconnectAttempts?: number;
29
+ maxAuthRetries?: number;
30
+ backoffMs?: number;
31
+ maxBackoffMs?: number;
32
+ controlTimeoutMs?: number;
33
+ maxPendingFrames?: number;
34
+ maxPendingBytes?: number;
35
+ dedupeSize?: number;
36
+ }
37
+ /** Managed ShredPrism early-stream client (4.1.0+). Bounded process-local
38
+ * recovery, per-subscription checkpoints, explicit gaps; never durable history. */
39
+ export declare class MadeOnSolEarlyStream {
40
+ private readonly options;
41
+ private readonly states;
42
+ private readonly limits;
43
+ private socket;
44
+ private pending;
45
+ private readonly replayTimers;
46
+ private timer;
47
+ private watchdog;
48
+ private generation;
49
+ private stopped;
50
+ private ready;
51
+ private attempts;
52
+ private authFailures;
53
+ private queue;
54
+ private queuedFrames;
55
+ private queuedBytes;
56
+ constructor(options: EarlyStreamOptions);
57
+ private status;
58
+ getSubscriptions(): EarlySubscribeControl[];
59
+ getCursors(): Record<string, EarlyCursor | null>;
60
+ /** Explicitly skip the reported missing range; never called automatically. */
61
+ acceptGap(id?: string): void;
62
+ connect(): void;
63
+ close(): void;
64
+ private fatal;
65
+ private rejectPending;
66
+ private retry;
67
+ private open;
68
+ private disconnect;
69
+ private enqueue;
70
+ private receive;
71
+ private command;
72
+ private restore;
73
+ /** Await the previous control before issuing another. A rejected update keeps
74
+ * the accepted configuration, including across reconnect. */
75
+ updateSubscription(id: string, change: {
76
+ filters?: EarlyStreamFilters;
77
+ format?: EarlyEventFormat;
78
+ wallet_list?: string | null;
79
+ }): Promise<void>;
80
+ /** Configure with subscriptions: [] to manage lists before adding a stream. */
81
+ manageWalletList(control: EarlyWalletListControl): Promise<EarlyWalletListResult>;
82
+ subscribe(raw: EarlySubscribeControl): Promise<void>;
83
+ unsubscribe(id?: string): Promise<void>;
84
+ }
85
+ //# sourceMappingURL=early-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"early-stream.d.ts","sourceRoot":"","sources":["../src/early-stream.ts"],"names":[],"mappings":"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"}