madeonsol-x402 3.2.1 → 4.1.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/LICENSE +21 -21
- package/README.md +169 -3
- package/dist/early-codec.d.ts +4 -0
- package/dist/early-codec.d.ts.map +1 -0
- package/dist/early-codec.js +43 -0
- package/dist/early-codec.js.map +1 -0
- package/dist/early-stream.d.ts +85 -0
- package/dist/early-stream.d.ts.map +1 -0
- package/dist/early-stream.js +399 -0
- package/dist/early-stream.js.map +1 -0
- package/dist/early-subscriptions.d.ts +9 -0
- package/dist/early-subscriptions.d.ts.map +1 -0
- package/dist/early-subscriptions.js +25 -0
- package/dist/early-subscriptions.js.map +1 -0
- package/dist/index.d.ts +19 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -16
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +142 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 MadeOnSol
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MadeOnSol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# madeonsol-x402
|
|
2
2
|
|
|
3
|
+
> **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: `EarlyChannel`, `EarlyStreamFilters`, `EarlyAmountFilter`, `EarlySubscribeControl`, `EarlyUpdateControl`, `EarlyWalletList*`; `StreamToken.early_stream` gains the six channel names and `coverage`. Observations are provisional instruction intent, not executed fills; coverage is partial and replay is never durable history. Existing methods are unchanged.
|
|
4
|
+
|
|
5
|
+
|
|
3
6
|
[](https://www.npmjs.com/package/madeonsol-x402)
|
|
4
7
|
[](https://www.npmjs.com/package/madeonsol-x402)
|
|
5
8
|
[](https://www.typescriptlang.org/)
|
|
@@ -17,6 +20,8 @@ TypeScript SDK for the [MadeOnSol](https://madeonsol.com) Solana KOL intelligenc
|
|
|
17
20
|
|
|
18
21
|
> **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.
|
|
19
22
|
|
|
23
|
+
> **New in 4.0.0: sniper is ULTRA+ only and no longer keyless (breaking).** `sniperRecent()` in keyless (x402) mode now throws `KeylessNotAvailableError` before any request or payment: the server retired `/api/x402/sniper/recent` on 2026-10-06 (HTTP 410 `x402_endpoint_retired`, nothing charged). With an ULTRA, BUSINESS or ENTERPRISE API key `sniperRecent()` / `sniperByDeployer()` work as before (PRO keys now get 403 `tier_required`). Types: `SniperDeploy` gains the early-observation fields (`event_id`, `source` shredprism | deshred, `outer_instruction_index`, `observation_stage`, `execution_status`, `transaction_version`, `transaction_config`, `fee_payer`), `sniperByDeployer()` returns the typed `SniperByDeployerResponse`, `attribution_status` is the closed set unverified | confirmed | corrected, and `StreamToken` gains `early_ws_url` / `early_stream` (ULTRA+ only, present while the early stream is active). Observations are intent, not execution proof.
|
|
24
|
+
|
|
20
25
|
> **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.
|
|
21
26
|
|
|
22
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.
|
|
@@ -199,9 +204,9 @@ A new client or process starts a new allowance. These limits are not a durable,
|
|
|
199
204
|
| `almostBonded(params?)` | **New 1.21** · Launchpad tokens approaching graduation (pump.fun + LetsBonk LaunchLab) — bonding progress, velocity (Δprogress/min), ETA, deployer tier. **$0.01** |
|
|
200
205
|
| `tokenTopTraders(mint, params?)` | **New 1.21** · Wallets ranked by realized PnL (or ROI) on a token, enriched with KOL identity + alpha reputation. **$0.02** |
|
|
201
206
|
| `tokenCapTable(mint)` | **New 1.21** · Early-buyer cap table — first 10 non-deployer buyers with PnL, exit status, bundle/KOL/alpha flags + buyer-quality score. **$0.02** |
|
|
202
|
-
| `sniperRecent(params?)` |
|
|
207
|
+
| `sniperRecent(params?)` | Retired in keyless mode; raises `KeylessNotAvailableError` before the request. Use an ULTRA/BUSINESS/ENTERPRISE API key. |
|
|
203
208
|
| `deployerTrajectory(wallet, params?)` | **New 1.21** · Deployer bond-rate trajectory — streaks, rolling bond rates, trend, cadence. `include: "daily_snapshots"` adds 90 days. **$0.01** |
|
|
204
|
-
| `discovery()` | Lists
|
|
209
|
+
| `discovery()` | Lists the current keyless endpoints, prices, and parameter docs (free) |
|
|
205
210
|
|
|
206
211
|
**API key only (not on the x402 rail):** `scoutLeaderboard()`, `coordinationHistory()`, `kolConsensus()`, `peakHistory()` and `tokenBundle()` have no keyless x402 route (the server answers 404). With an API key they call `/api/v1/` as before; in private-key (x402) mode they throw `KeylessNotAvailableError` before any request or payment. The list is exported as `X402_UNAVAILABLE_PATHS`. `discovery()` returns the live x402 catalog.
|
|
207
212
|
|
|
@@ -253,7 +258,7 @@ Scored from 1.5M+ early-buyer records (wallets seen in the first 20 buyers of Pu
|
|
|
253
258
|
| `rest.tokenCandles(mint, params?)` | PRO+ | OHLC candles. PRO = OHLCV, last 30 days; ULTRA = + net flow (buy/sell volume, `net_volume_usd`, counts, MEV vol), liquidity delta, full history |
|
|
254
259
|
| `rest.tokenTrades(mint, params?)` | PRO+ | **New 1.21** · Mint-scoped trade tape — cursor-paginated raw trades (`price_sol`/`price_usd`, `early_buyer_rank`, `slot`), filter by `action`/`wallet`/`since`/`until`. Default window = **full history**; `coverage` block carries `history_start` (2026-04-12) + `scope` (pump.fun pipeline) |
|
|
255
260
|
| `rest.tokenTopTraders(mint, params?)` | PRO+ | **New 1.21** · Wallets ranked by realized PnL (or ROI) on a token — `sort` ("pnl" \| "roi"), `window_days` (1–180), `min_bought_sol`; enriched with KOL identity + alpha reputation (`bot_confidence`, historical win rate/PnL) |
|
|
256
|
-
| `rest.sniperRecent(params?)` |
|
|
261
|
+
| `rest.sniperRecent(params?)` | ULTRA/BUSINESS/ENTERPRISE | Early deploy observations with action identity and separate execution status; unknown enrichment stays null. |
|
|
257
262
|
|
|
258
263
|
**tokenCandles params** — `tf` ("1m" \| "5m" \| "15m" \| "1h" \| "4h" \| "1d", default "1h"), `limit` (1–1000, default 200), `from` (ISO 8601), `to` (ISO 8601)
|
|
259
264
|
|
|
@@ -637,3 +642,164 @@ Docs: [madeonsol.com/solana-api](https://madeonsol.com/solana-api)
|
|
|
637
642
|
| MCP Server (Claude, Cursor) | [`mcp-server-madeonsol`](https://www.npmjs.com/package/mcp-server-madeonsol) · [Smithery](https://smithery.ai/servers/madeonsol/solana-kol-intelligence) · [Glama](https://glama.ai/mcp/servers/madeonsol/mcp-server-madeonsol) |
|
|
638
643
|
| ElizaOS | [`@madeonsol/plugin-madeonsol`](https://www.npmjs.com/package/@madeonsol/plugin-madeonsol) |
|
|
639
644
|
| Solana Agent Kit | [`solana-agent-kit-plugin-madeonsol`](https://www.npmjs.com/package/solana-agent-kit-plugin-madeonsol) |
|
|
645
|
+
|
|
646
|
+
## Managed ShredPrism early-stream client (4.1.0+)
|
|
647
|
+
|
|
648
|
+
`MadeOnSolREST.earlyStream()` extends this SDK with the separate early protocol.
|
|
649
|
+
It requires ULTRA, BUSINESS or ENTERPRISE and an `early_ws_url` in `getStreamToken()`
|
|
650
|
+
discovery; subscribe only to channels listed in `early_stream.channels`.
|
|
651
|
+
The existing confirmed-stream `stream()` contract is unchanged.
|
|
652
|
+
|
|
653
|
+
```js
|
|
654
|
+
import { MadeOnSolREST, walletTrades, followTokens } from 'madeonsol-x402';
|
|
655
|
+
const api = new MadeOnSolREST({ apiKey: process.env.MADEONSOL_API_KEY });
|
|
656
|
+
const stream = api.earlyStream({
|
|
657
|
+
subscriptions: [
|
|
658
|
+
walletTrades(['YOUR_WALLET'], { sub_id: 'wallets', directions: ['buy'] }),
|
|
659
|
+
followTokens(['YOUR_MINT'], { sub_id: 'token' }),
|
|
660
|
+
],
|
|
661
|
+
onFrame(frame) {
|
|
662
|
+
// early:observed is provisional instruction intent; early:outcome reports status.
|
|
663
|
+
// Correlate outcomes through frame.data.observed_event_id.
|
|
664
|
+
console.log(frame);
|
|
665
|
+
},
|
|
666
|
+
onStatus(status) {
|
|
667
|
+
if (['gap', 'fatal', 'reconnect'].includes(status.type)) console.error(status);
|
|
668
|
+
},
|
|
669
|
+
});
|
|
670
|
+
stream.connect();
|
|
671
|
+
// Once subscriptions are ready (and any replay has completed), await each control:
|
|
672
|
+
// await stream.updateSubscription('wallets', { filters: { wallets: ['NEW_WALLET'] } });
|
|
673
|
+
// await stream.updateSubscription('wallets', { format: 'compact-v1' });
|
|
674
|
+
// await stream.unsubscribe('token');
|
|
675
|
+
// stream.close();
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
Replace placeholder addresses before running. The repository example is
|
|
679
|
+
`packages/madeonsol-x402/examples/early-stream.mjs`: build the SDK, set
|
|
680
|
+
`MADEONSOL_API_KEY` plus exactly one of `EARLY_WALLETS` or `EARLY_MINTS`, and run
|
|
681
|
+
that file with Node 22+. It uses the platform WebSocket; `WebSocketImpl` can inject
|
|
682
|
+
`ws`.
|
|
683
|
+
|
|
684
|
+
- Token acquisition uses the existing REST client on every connection. Tokens
|
|
685
|
+
do not expire automatically; the SDK never schedules rotation. Browser-compatible
|
|
686
|
+
handshake authentication uses `?token=`, which must remain redacted in proxy logs.
|
|
687
|
+
Credentials and raw REST/transport errors are excluded from SDK diagnostics.
|
|
688
|
+
- Transient disconnects retry with jittered exponential backoff (500 ms to 30 s;
|
|
689
|
+
10 consecutive reconnect attempts by default). Authorization closes have a
|
|
690
|
+
three-rejection budget. A connection-limit close waits at least 60 s. Policy
|
|
691
|
+
rejection stops. Token acquisition, handshake, controls and replay have 15 s
|
|
692
|
+
deadlines. There is no additional application heartbeat; the gateway's WS
|
|
693
|
+
ping/pong remains responsible for detecting an idle broken connection.
|
|
694
|
+
- Up to 10 configured subscriptions share one connection; server tier/connection
|
|
695
|
+
caps still apply. Updates and unsubscribe require a connected client and one
|
|
696
|
+
control at a time. Await each call. The SDK replaces local settings only after
|
|
697
|
+
server acknowledgement. Omitted filters remain; `{}` clears them. Use `subscribe(control)` to add a new subscription after connecting. An empty
|
|
698
|
+
initial array is supported for list-management-only sessions.
|
|
699
|
+
- Frames are handled in arrival order. Async `onFrame` handlers are awaited, and
|
|
700
|
+
an exception/rejection stops the client without advancing past that event.
|
|
701
|
+
The pending queue is bounded to 2,048 frames / 8 MiB, measured in UTF-8, by default.
|
|
702
|
+
Overflow stops with `client_queue_limit`; expensive work should leave the handler.
|
|
703
|
+
Closing invalidates pending work and cancels retry/replay/control timers.
|
|
704
|
+
- `getCursors()` returns separate safe checkpoints per subscription. During replay,
|
|
705
|
+
new live traffic is delivered but cannot advance the checkpoint until a complete
|
|
706
|
+
replay finishes. A disconnect mid-replay resumes from the prior safe point.
|
|
707
|
+
Incomplete replay or a reported gap freezes the checkpoint. A later complete
|
|
708
|
+
recovery can resolve it; `acceptGap(subId)` explicitly skips to received progress
|
|
709
|
+
once replay ends if the caller accepts the missing range. No gap is silently
|
|
710
|
+
accepted. Process-local replay is bounded and is never durable history.
|
|
711
|
+
- Persist cursors with their matching subscription settings outside the handler,
|
|
712
|
+
after processing has completed. To restart, put each saved cursor in that
|
|
713
|
+
subscription's `resume`. Recent IDs are deduplicated per subscription and event
|
|
714
|
+
type (10,000 IDs per subscription). Deduplication is bounded and in-memory:
|
|
715
|
+
downstream processing must tolerate duplicates after eviction/restart.
|
|
716
|
+
- `full` remains the default. `compact-v1` is expanded before the application
|
|
717
|
+
callback. The local managed client costs more CPU than a minimal reader; no
|
|
718
|
+
zero-overhead or customer lead-time claim is made. Keep handlers short. Current
|
|
719
|
+
protocol coverage is partial and all observations remain provisional.
|
|
720
|
+
|
|
721
|
+
Full wire contract: https://madeonsol.com/docs/shredprism-stream.md.
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
## Private saved wallet lists
|
|
725
|
+
|
|
726
|
+
The early gateway stores named lists separately from the confirmed wallet-tracker
|
|
727
|
+
watchlist. Its authenticated stream-token owner is authoritative; a request cannot
|
|
728
|
+
supply another user ID. These lists are never added to public KOL/alpha rosters and
|
|
729
|
+
do not change upstream wallet-tracker subscriptions.
|
|
730
|
+
|
|
731
|
+
On a connected SDK client (it may start with `subscriptions: []`):
|
|
732
|
+
|
|
733
|
+
```js
|
|
734
|
+
const created = await stream.manageWalletList({
|
|
735
|
+
op: 'create', name: 'My wallets', wallets: ['YOUR_WALLET'],
|
|
736
|
+
});
|
|
737
|
+
await stream.subscribe({
|
|
738
|
+
type: 'subscribe', sub_id: 'private-trades', channels: ['early:trades'],
|
|
739
|
+
wallet_list: created.list.id,
|
|
740
|
+
});
|
|
741
|
+
const changed = await stream.manageWalletList({
|
|
742
|
+
op: 'replace', id: created.list.id, revision: created.list.revision,
|
|
743
|
+
name: 'My wallets', wallets: ['ANOTHER_WALLET'],
|
|
744
|
+
});
|
|
745
|
+
// list returns metadata + wallet_count; get returns the actual wallet array.
|
|
746
|
+
await stream.manageWalletList({ op: 'list' });
|
|
747
|
+
await stream.manageWalletList({ op: 'get', id: created.list.id });
|
|
748
|
+
// Explicitly delete with the current revision when no longer needed:
|
|
749
|
+
// await stream.manageWalletList({ op: 'delete', id: created.list.id, revision: changed.list.revision });
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
Replace the placeholder addresses, wait for the SDK `ready` status, and await each
|
|
753
|
+
control. Raw WS uses `{type:"wallet_list", ...control}` and receives
|
|
754
|
+
`{type:"wallet_list_result", op, list?, lists?, limits}`. Revisions are decimal
|
|
755
|
+
strings. `replace` supplies the whole name/address snapshot; `replace` and `delete`
|
|
756
|
+
require the current revision. A conflict leaves the existing stored row intact.
|
|
757
|
+
`list` is summary-only so a full BUSINESS account cannot exceed the control-frame
|
|
758
|
+
byte budget; use `get` for one list's addresses. There is no new REST endpoint.
|
|
759
|
+
|
|
760
|
+
Limits reuse existing tier budgets: ULTRA 10 lists / 100 wallets per list;
|
|
761
|
+
BUSINESS and ENTERPRISE 20 / 500. Lists contain 1..limit unique Solana addresses,
|
|
762
|
+
with a unique owner-scoped name of 1..64 characters. Delete an empty group instead
|
|
763
|
+
of subscribing with an empty wallet filter. The SDK supports 10 simultaneous
|
|
764
|
+
subscriptions; server subscription and connection caps remain authoritative.
|
|
765
|
+
|
|
766
|
+
A subscription's top-level `wallet_list` is an ID, valid only for `early:trades`.
|
|
767
|
+
Do not combine it with `filters.wallets` or `filters.actors`; direction, amount,
|
|
768
|
+
protocol and other compatible filters still intersect. Omitting it on update
|
|
769
|
+
keeps the reference; explicit `wallet_list: null` detaches it, so supply replacement
|
|
770
|
+
filters if the subscription should remain wallet-scoped.
|
|
771
|
+
|
|
772
|
+
Subscribe/update acknowledgements and `list` controls report
|
|
773
|
+
`wallet_list: {id, revision}`. A successful edit atomically replaces each active
|
|
774
|
+
subscription's in-memory index, then emits `wallet_list_updated` with the active
|
|
775
|
+
revision. An update arriving during replay ends the old replay as incomplete;
|
|
776
|
+
clients retain the prior safe cursor. Reconnect reloads the current saved revision,
|
|
777
|
+
and replay uses that current list, not historical list membership.
|
|
778
|
+
|
|
779
|
+
Local successful writes are applied to current owner subscriptions immediately.
|
|
780
|
+
Edits from another process are discovered by a 5-second refresh. Unchanged rows
|
|
781
|
+
return their revision without resending wallet arrays. A previous snapshot is valid
|
|
782
|
+
for at most 15 seconds after a successful read. On deletion, missing access, failed
|
|
783
|
+
application, excess wallets after tier downgrade, or expiry, the affected binding
|
|
784
|
+
is removed and `wallet_list_unavailable` is sent. The SDK surfaces it as a `gap`;
|
|
785
|
+
resubscribe after correcting the cause. A transient failed read does not extend TTL.
|
|
786
|
+
Normal auth expiry/downgrade enforcement still applies.
|
|
787
|
+
|
|
788
|
+
A dedicated one-connection database pool handles controls/refresh, with 2-second
|
|
789
|
+
query deadlines and at most 8 admitted list queries. At most 256 distinct active
|
|
790
|
+
owner/list references are materialized per gateway, within the existing 100,000
|
|
791
|
+
binding budget. Overload fails explicitly. Decode, matching, live publication and
|
|
792
|
+
replay never query the database; delivery checks the local snapshot expiry and tier
|
|
793
|
+
limit. Do not describe this bounded local implementation as zero-overhead or as
|
|
794
|
+
complete wallet transaction coverage.
|
|
795
|
+
|
|
796
|
+
## Client scope
|
|
797
|
+
|
|
798
|
+
The managed early client ships in this TypeScript package only. The Python package,
|
|
799
|
+
MCP server, ElizaOS plugin and Solana Agent Kit plugin do not include it; use the raw
|
|
800
|
+
WebSocket contract there. The existing `sniperRecent()` / `sniperByDeployer()` helpers
|
|
801
|
+
are separate from direct six-family subscriptions and private-list WS controls.
|
|
802
|
+
|
|
803
|
+
Coverage and dated local benchmarks (with raw downloads and methodology):
|
|
804
|
+
https://madeonsol.com/solutions/shredprism-stream. Those development measurements do
|
|
805
|
+
not establish a fixed customer head start.
|
|
@@ -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,CAc3D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
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 data = {};
|
|
30
|
+
for (const k of Object.keys(frame.data)) {
|
|
31
|
+
const key = k.startsWith('~') ? k.slice(1) : names.get(k);
|
|
32
|
+
if (key === undefined || Object.hasOwn(data, key))
|
|
33
|
+
throw new Error('invalid_compact_frame');
|
|
34
|
+
if (key === '__proto__')
|
|
35
|
+
Object.defineProperty(data, key, { value: frame.data[k], enumerable: true, writable: true, configurable: true });
|
|
36
|
+
else
|
|
37
|
+
data[key] = frame.data[k];
|
|
38
|
+
}
|
|
39
|
+
const result = { ...frame, data };
|
|
40
|
+
delete result.format;
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
//# 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, StreamToken } from './types.js';
|
|
2
|
+
export { expandEarlyFrame } from './early-codec.js';
|
|
3
|
+
export type { EarlyChannel, EarlyAmountField, EarlyAmountFilter, EarlyStreamFilters, EarlyEventFormat, EarlySubscribeControl, EarlyUpdateControl } 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?: 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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"}
|