sol-parser-sdk 0.5.19 → 0.5.20
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 +52 -25
- package/README_CN.md +45 -25
- package/dist/core/dex_event.d.ts +3 -0
- package/dist/grpc/types.d.ts +1 -1
- package/dist/grpc/types.js +5 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/instr/pump_routes.d.ts +27 -0
- package/dist/instr/pump_routes.js +71 -0
- package/dist/logs/pump_upgrade.js +4 -8
- package/dist/shredstream/index.d.ts +2 -2
- package/dist/shredstream/index.js +4 -2
- package/dist/shredstream/instruction_parse.d.ts +7 -5
- package/dist/shredstream/instruction_parse.js +54 -6
- package/dist/shredstream/wire_to_shred_tx.js +3 -7
- package/dist/wire_transaction.d.ts +17 -0
- package/dist/wire_transaction.js +22 -10
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -24,15 +24,21 @@ Parser SDK language versions and related Rust SDKs:
|
|
|
24
24
|
|
|
25
25
|
| Language | Repository | Description | Version |
|
|
26
26
|
|----------|------------|-------------|---------|
|
|
27
|
-
| Rust | [sol-parser-sdk](https://github.com/0xfnzero/sol-parser-sdk) | Solana DEX transaction and account event parsing | `v0.7.
|
|
28
|
-
| Node.js | [sol-parser-sdk-nodejs](https://github.com/0xfnzero/sol-parser-sdk-nodejs) | TypeScript/JavaScript for Node.js | `v0.5.
|
|
29
|
-
| Python | [sol-parser-sdk-python](https://github.com/0xfnzero/sol-parser-sdk-python) | Async/await native support | `v0.5.
|
|
30
|
-
| Go | [sol-parser-sdk-golang](https://github.com/0xfnzero/sol-parser-sdk-golang) | Go transaction and account event parsing | `v0.5.
|
|
31
|
-
| **Rust** | [sol-shred-sdk](https://github.com/0xfnzero/sol-shred-sdk) | Raw Solana shred decoding and ShredStream DEX event parsing | `v4.0.
|
|
32
|
-
| **Rust** | [sol-trade-sdk](https://github.com/0xfnzero/sol-trade-sdk) | Solana DEX trade construction and transaction execution | `v6.0.
|
|
27
|
+
| Rust | [sol-parser-sdk](https://github.com/0xfnzero/sol-parser-sdk) | Solana DEX transaction and account event parsing | `v0.7.14` |
|
|
28
|
+
| Node.js | [sol-parser-sdk-nodejs](https://github.com/0xfnzero/sol-parser-sdk-nodejs) | TypeScript/JavaScript for Node.js | `v0.5.20` |
|
|
29
|
+
| Python | [sol-parser-sdk-python](https://github.com/0xfnzero/sol-parser-sdk-python) | Async/await native support | `v0.5.13` |
|
|
30
|
+
| Go | [sol-parser-sdk-golang](https://github.com/0xfnzero/sol-parser-sdk-golang) | Go transaction and account event parsing | `v0.5.13` |
|
|
31
|
+
| **Rust** | [sol-shred-sdk](https://github.com/0xfnzero/sol-shred-sdk) | Raw Solana shred decoding and ShredStream DEX event parsing | `v4.0.5` |
|
|
32
|
+
| **Rust** | [sol-trade-sdk](https://github.com/0xfnzero/sol-trade-sdk) | Solana DEX trade construction and transaction execution | `v6.0.2` |
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
+
## v0.5.20 — Pump routes and offline replay
|
|
37
|
+
|
|
38
|
+
Adds native Pump route-intent parsing for official multi-hop instructions and the exact RapidBuy/BuyPumpDelta wrapper layouts captured in reported transactions. Adds locally cached ALT resolution and rejects unresolved account identities by default, with explicit best-effort compatibility APIs where supported. Route intents expose instruction constraints and hop identities; confirmed execution amounts require execution metadata.
|
|
39
|
+
|
|
40
|
+
Includes the latest complete implementation, signed transaction fixtures, native offline-bank regression examples and reproducible local hot-path benchmarks. Unknown wrapper layouts are not inferred from embedded bytes. Local tests do not measure production network latency.
|
|
41
|
+
|
|
36
42
|
## v0.5.19 — Pump depth-2 compatibility
|
|
37
43
|
|
|
38
44
|
Adds signed Pump depth-2 create-event replay coverage, including ALT-loaded accounts and executed logs. Existing event layouts and public parsing interfaces remain unchanged.
|
|
@@ -119,7 +125,7 @@ Validation includes local CPU benchmarks and offline signed-bank scenarios. Meas
|
|
|
119
125
|
**From npm**
|
|
120
126
|
|
|
121
127
|
```bash
|
|
122
|
-
npm install sol-parser-sdk@0.5.
|
|
128
|
+
npm install sol-parser-sdk@0.5.20
|
|
123
129
|
```
|
|
124
130
|
|
|
125
131
|
**From source** (folder may be named `sol-parser-sdk-ts` in a monorepo)
|
|
@@ -286,7 +292,7 @@ The client decodes gRPC `entries` bytes in **TypeScript** (same layout as the Go
|
|
|
286
292
|
npx tsx examples/shredstream_example.ts -- --url=http://127.0.0.1:10800
|
|
287
293
|
```
|
|
288
294
|
|
|
289
|
-
Without `connection` or prewarmed ALT snapshots,
|
|
295
|
+
Without `connection` or prewarmed ALT snapshots, instructions containing unresolved indexes are skipped. Legacy placeholder behavior is available only through the explicit `dexEventsFromShredWasmTxBestEffort` API. With `connection` or `address_lookup_tables`, parsing uses complete cached ALT snapshots only: a cache miss skips the entire transaction, increments `getReceiveStats().altCacheMissTransactions`, and is never replayed. `connection` performs RPC only during explicit `await client.preloadAddressLookupTables(altAddresses)` before subscribing and in the independent background refresher (default 1000 ms, at most one request in flight). Supply already loaded tables via `config.address_lookup_tables` to avoid cold misses. The cache and pending refresh queue each retain at most 2048 tables; refreshed snapshots apply only to later messages. `shredstream_pumpfun_json.ts` uses **`RPC_URL`** (or `--rpc`) for this background refresh; its entry parsing never waits for RPC.
|
|
290
296
|
|
|
291
297
|
---
|
|
292
298
|
|
|
@@ -297,29 +303,29 @@ From the **package root** after `npm install`. Examples use `npx tsx` and load `
|
|
|
297
303
|
| Description | Run command | Source |
|
|
298
304
|
|-------------|-------------|--------|
|
|
299
305
|
| **Scripts** | | |
|
|
300
|
-
| gRPC integration test (PumpFun + PumpSwap, account-filled `DexEvent`) | `npx tsx scripts/test-grpc-ts.ts` | [test-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/test-grpc-ts.ts) | `v0.5.
|
|
301
|
-
| Debug: print `metaRaw` / log structure | `npx tsx scripts/debug-grpc-ts.ts` | [debug-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/debug-grpc-ts.ts) | `v0.5.
|
|
306
|
+
| gRPC integration test (PumpFun + PumpSwap, account-filled `DexEvent`) | `npx tsx scripts/test-grpc-ts.ts` | [test-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/test-grpc-ts.ts) | `v0.5.20` |
|
|
307
|
+
| Debug: print `metaRaw` / log structure | `npx tsx scripts/debug-grpc-ts.ts` | [debug-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/debug-grpc-ts.ts) | `v0.5.20` |
|
|
302
308
|
| **PumpFun** | | |
|
|
303
|
-
| CREATE + dev BUY/SELL, long-running low latency | `npx tsx examples/devtrades_low_latency.ts` | [devtrades_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_low_latency.ts) | `v0.5.
|
|
304
|
-
| PumpFun + full-volume PumpSwap dev trades/liquidity | `npm run example:grpc:devtrades:pumpswap` | [devtrades_pumpfun_pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_pumpfun_pumpswap_low_latency.ts) | `v0.5.
|
|
305
|
-
| Pretty-print full JSON `DexEvent` over gRPC | `npx tsx examples/pumpfun_grpc_json.ts` | [pumpfun_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_grpc_json.ts) | `v0.5.
|
|
306
|
-
| PumpFun events + metrics | `npx tsx examples/pumpfun_with_metrics.ts` | [pumpfun_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_with_metrics.ts) | `v0.5.
|
|
307
|
-
| PumpFun trade filter | `npx tsx examples/pumpfun_trade_filter.ts` | [pumpfun_trade_filter.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_trade_filter.ts) | `v0.5.
|
|
308
|
-
| Quick PumpFun connection test | `npx tsx examples/pumpfun_quick_test.ts` | [pumpfun_quick_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_quick_test.ts) | `v0.5.
|
|
309
|
+
| CREATE + dev BUY/SELL, long-running low latency | `npx tsx examples/devtrades_low_latency.ts` | [devtrades_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_low_latency.ts) | `v0.5.20` |
|
|
310
|
+
| PumpFun + full-volume PumpSwap dev trades/liquidity | `npm run example:grpc:devtrades:pumpswap` | [devtrades_pumpfun_pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_pumpfun_pumpswap_low_latency.ts) | `v0.5.20` |
|
|
311
|
+
| Pretty-print full JSON `DexEvent` over gRPC | `npx tsx examples/pumpfun_grpc_json.ts` | [pumpfun_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_grpc_json.ts) | `v0.5.20` |
|
|
312
|
+
| PumpFun events + metrics | `npx tsx examples/pumpfun_with_metrics.ts` | [pumpfun_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_with_metrics.ts) | `v0.5.20` |
|
|
313
|
+
| PumpFun trade filter | `npx tsx examples/pumpfun_trade_filter.ts` | [pumpfun_trade_filter.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_trade_filter.ts) | `v0.5.20` |
|
|
314
|
+
| Quick PumpFun connection test | `npx tsx examples/pumpfun_quick_test.ts` | [pumpfun_quick_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_quick_test.ts) | `v0.5.20` |
|
|
309
315
|
| **PumpSwap** | | |
|
|
310
|
-
| Pretty-print full JSON `DexEvent` over gRPC | `npx tsx examples/pumpswap_grpc_json.ts` | [pumpswap_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_grpc_json.ts) | `v0.5.
|
|
311
|
-
| PumpSwap events + metrics | `npx tsx examples/pumpswap_with_metrics.ts` | [pumpswap_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_with_metrics.ts) | `v0.5.
|
|
312
|
-
| PumpSwap swaps, pool creation, and liquidity events (ultra-low latency) | `npm run example:grpc:pumpswap` | [pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_low_latency.ts) | `v0.5.
|
|
316
|
+
| Pretty-print full JSON `DexEvent` over gRPC | `npx tsx examples/pumpswap_grpc_json.ts` | [pumpswap_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_grpc_json.ts) | `v0.5.20` |
|
|
317
|
+
| PumpSwap events + metrics | `npx tsx examples/pumpswap_with_metrics.ts` | [pumpswap_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_with_metrics.ts) | `v0.5.20` |
|
|
318
|
+
| PumpSwap swaps, pool creation, and liquidity events (ultra-low latency) | `npm run example:grpc:pumpswap` | [pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_low_latency.ts) | `v0.5.20` |
|
|
313
319
|
| **Meteora DAMM** | | |
|
|
314
|
-
| Meteora DAMM V2 events | `npx tsx examples/meteora_damm_grpc.ts` | [meteora_damm_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/meteora_damm_grpc.ts) | `v0.5.
|
|
320
|
+
| Meteora DAMM V2 events | `npx tsx examples/meteora_damm_grpc.ts` | [meteora_damm_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/meteora_damm_grpc.ts) | `v0.5.20` |
|
|
315
321
|
| **ShredStream** (HTTP, not Yellowstone gRPC; see **step 5** above) | | |
|
|
316
|
-
| Ultra-low-latency subscribe + queue / latency stats. URL: `--url` / `SHREDSTREAM_URL` / `.env` (default `http://127.0.0.1:10800`). | `npx tsx examples/shredstream_example.ts` | [shredstream_example.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_example.ts) | `v0.5.
|
|
317
|
-
| PumpFun `DexEvent` JSON from ShredStream; RPC (`RPC_URL` or `--rpc`) refreshes ALT snapshots outside parsing. Cold cache misses are skipped, counted, and not replayed; prewarm required tables. | `npx tsx examples/shredstream_pumpfun_json.ts` | [shredstream_pumpfun_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_pumpfun_json.ts) | `v0.5.
|
|
322
|
+
| Ultra-low-latency subscribe + queue / latency stats. URL: `--url` / `SHREDSTREAM_URL` / `.env` (default `http://127.0.0.1:10800`). | `npx tsx examples/shredstream_example.ts` | [shredstream_example.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_example.ts) | `v0.5.20` |
|
|
323
|
+
| PumpFun `DexEvent` JSON from ShredStream; RPC (`RPC_URL` or `--rpc`) refreshes ALT snapshots outside parsing. Cold cache misses are skipped, counted, and not replayed; prewarm required tables. | `npx tsx examples/shredstream_pumpfun_json.ts` | [shredstream_pumpfun_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_pumpfun_json.ts) | `v0.5.20` |
|
|
318
324
|
| **Multi-protocol** | | |
|
|
319
|
-
| Subscribe to all DEX protocols | `npx tsx examples/multi_protocol_grpc.ts` | [multi_protocol_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/multi_protocol_grpc.ts) | `v0.5.
|
|
325
|
+
| Subscribe to all DEX protocols | `npx tsx examples/multi_protocol_grpc.ts` | [multi_protocol_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/multi_protocol_grpc.ts) | `v0.5.20` |
|
|
320
326
|
| **Utility** | | |
|
|
321
|
-
| Verify `onUpdate` sync errors do not kill the gRPC stream | `npx tsx examples/grpc_onupdate_error_test.ts` | [grpc_onupdate_error_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/grpc_onupdate_error_test.ts) | `v0.5.
|
|
322
|
-
| Parse tx by signature (`parseTransactionFromRpc`; not gRPC). Set `TX_SIGNATURE` in `.env` or env. | `npx tsx examples/parse_tx_by_signature.ts` | [parse_tx_by_signature.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/parse_tx_by_signature.ts) | `v0.5.
|
|
327
|
+
| Verify `onUpdate` sync errors do not kill the gRPC stream | `npx tsx examples/grpc_onupdate_error_test.ts` | [grpc_onupdate_error_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/grpc_onupdate_error_test.ts) | `v0.5.20` |
|
|
328
|
+
| Parse tx by signature (`parseTransactionFromRpc`; not gRPC). Set `TX_SIGNATURE` in `.env` or env. | `npx tsx examples/parse_tx_by_signature.ts` | [parse_tx_by_signature.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/parse_tx_by_signature.ts) | `v0.5.20` |
|
|
323
329
|
|
|
324
330
|
**`npm run` aliases** (same source files as the ShredStream rows above):
|
|
325
331
|
|
|
@@ -366,3 +372,24 @@ Full cross-language API parity is still in progress. See the [API migration guid
|
|
|
366
372
|
实时 parser → trade 接入使用 Yellowstone **gRPC**;见 [gRPC 缓存接入与三语言示例](docs/USAGE.md#grpc-cache)。此路径不使用 WebSocket,报价和构建热路径不调用 RPC。
|
|
367
373
|
|
|
368
374
|
Shared PumpFun create/create_v2 mainnet fixtures, replay instructions and verification limits are documented in the [validation guide](https://github.com/0xfnzero/sol-parser-sdk-golang/tree/main/validation/pumpfun_create_20261007).
|
|
375
|
+
|
|
376
|
+
### Offline Pump ShredStream regressions
|
|
377
|
+
|
|
378
|
+
Pump route intents, strict cached ALT resolution and native signed replay/SBF simulation examples are documented in [examples/offline_bank/README.md](examples/offline_bank/README.md). Run the language-native examples and tests from this repository; no other-language test driver or RPC endpoint is needed. Unresolved instructions now skip by default; use the explicit best-effort API only for legacy behavior. Route intents must not be treated as confirmed fills.
|
|
379
|
+
|
|
380
|
+
### Repeatable local hot-path benchmark
|
|
381
|
+
|
|
382
|
+
```sh
|
|
383
|
+
npx tsx examples/hotpath_benchmark.ts
|
|
384
|
+
# Optional: pass the path to your edited JSON configuration
|
|
385
|
+
npx tsx examples/hotpath_benchmark.ts examples/hotpath_benchmark.json
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
The checked-in JSON config controls warmup, sample count and batch size. Fixture
|
|
389
|
+
loading and setup occur before timing; timed loops perform no RPC or network I/O.
|
|
390
|
+
The fixed workloads use captured signed wrapped-program transactions, including
|
|
391
|
+
ALTs, and measure resolved parsing and wire decoding plus parsing separately.
|
|
392
|
+
Output reports p50/p95/p99 of batch-normalized microseconds per transaction, a
|
|
393
|
+
checksum and runtime metadata. These local CPU distributions include scheduling
|
|
394
|
+
and GC effects; they measure neither provider/network latency nor production
|
|
395
|
+
landing speed. Compare warmed runs with the same runtime, config and host load.
|
package/README_CN.md
CHANGED
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
|
|
25
25
|
| 语言 | 仓库 | 描述 | 版本 |
|
|
26
26
|
|------|------|------|
|
|
27
|
-
| Rust | [sol-parser-sdk](https://github.com/0xfnzero/sol-parser-sdk) | Solana DEX 交易与账户事件解析 | `v0.7.
|
|
28
|
-
| Node.js | [sol-parser-sdk-nodejs](https://github.com/0xfnzero/sol-parser-sdk-nodejs) | TypeScript/JavaScript,Node.js 支持 | `v0.5.
|
|
29
|
-
| Python | [sol-parser-sdk-python](https://github.com/0xfnzero/sol-parser-sdk-python) | 原生 async/await 支持 | `v0.5.
|
|
30
|
-
| Go | [sol-parser-sdk-golang](https://github.com/0xfnzero/sol-parser-sdk-golang) | Go 交易与账户事件解析 | `v0.5.
|
|
31
|
-
| **Rust** | [sol-shred-sdk](https://github.com/0xfnzero/sol-shred-sdk) | Solana 原始 shred 解码与 ShredStream DEX 事件解析 | `v4.0.
|
|
32
|
-
| **Rust** | [sol-trade-sdk](https://github.com/0xfnzero/sol-trade-sdk) | Solana DEX 交易构建与交易执行 | `v6.0.
|
|
27
|
+
| Rust | [sol-parser-sdk](https://github.com/0xfnzero/sol-parser-sdk) | Solana DEX 交易与账户事件解析 | `v0.7.14` |
|
|
28
|
+
| Node.js | [sol-parser-sdk-nodejs](https://github.com/0xfnzero/sol-parser-sdk-nodejs) | TypeScript/JavaScript,Node.js 支持 | `v0.5.20` |
|
|
29
|
+
| Python | [sol-parser-sdk-python](https://github.com/0xfnzero/sol-parser-sdk-python) | 原生 async/await 支持 | `v0.5.13` |
|
|
30
|
+
| Go | [sol-parser-sdk-golang](https://github.com/0xfnzero/sol-parser-sdk-golang) | Go 交易与账户事件解析 | `v0.5.13` |
|
|
31
|
+
| **Rust** | [sol-shred-sdk](https://github.com/0xfnzero/sol-shred-sdk) | Solana 原始 shred 解码与 ShredStream DEX 事件解析 | `v4.0.5` |
|
|
32
|
+
| **Rust** | [sol-trade-sdk](https://github.com/0xfnzero/sol-trade-sdk) | Solana DEX 交易构建与交易执行 | `v6.0.2` |
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
@@ -48,6 +48,12 @@
|
|
|
48
48
|
|
|
49
49
|
## 发布说明
|
|
50
50
|
|
|
51
|
+
## v0.5.20 — Pump routes and offline replay
|
|
52
|
+
|
|
53
|
+
Adds native Pump route-intent parsing for official multi-hop instructions and the exact RapidBuy/BuyPumpDelta wrapper layouts captured in reported transactions. Adds locally cached ALT resolution and rejects unresolved account identities by default, with explicit best-effort compatibility APIs where supported. Route intents expose instruction constraints and hop identities; confirmed execution amounts require execution metadata.
|
|
54
|
+
|
|
55
|
+
Includes the latest complete implementation, signed transaction fixtures, native offline-bank regression examples and reproducible local hot-path benchmarks. Unknown wrapper layouts are not inferred from embedded bytes. Local tests do not measure production network latency.
|
|
56
|
+
|
|
51
57
|
## v0.5.19 — Pump depth-2 compatibility
|
|
52
58
|
|
|
53
59
|
Adds signed Pump depth-2 create-event replay coverage, including ALT-loaded accounts and executed logs. Existing event layouts and public parsing interfaces remain unchanged.
|
|
@@ -119,7 +125,7 @@ Validation includes local CPU benchmarks and offline signed-bank scenarios. Meas
|
|
|
119
125
|
**npm**
|
|
120
126
|
|
|
121
127
|
```bash
|
|
122
|
-
npm install sol-parser-sdk@0.5.
|
|
128
|
+
npm install sol-parser-sdk@0.5.20
|
|
123
129
|
```
|
|
124
130
|
|
|
125
131
|
**源码**(monorepo 里目录可能是 `sol-parser-sdk-ts`)
|
|
@@ -279,7 +285,7 @@ mint 或 quote mint 映射到 pool,再将 `PumpSwapLiquidityAdded.user` 与该
|
|
|
279
285
|
npx tsx examples/shredstream_example.ts -- --url=http://127.0.0.1:10800
|
|
280
286
|
```
|
|
281
287
|
|
|
282
|
-
未配置 `connection` 或预热 ALT
|
|
288
|
+
未配置 `connection` 或预热 ALT 快照时,默认跳过含未解析索引的指令;旧占位行为仅通过显式 `dexEventsFromShredWasmTxBestEffort` API 提供。配置 `connection` 或 `address_lookup_tables` 后,解析只读取完整的 ALT 缓存快照:缓存 miss 跳过整笔交易,累计 `getReceiveStats().altCacheMissTransactions`,不会重放。`connection` 仅用于订阅前显式调用 `await client.preloadAddressLookupTables(altAddresses)` 预热,以及独立后台刷新任务(默认间隔 1000 毫秒,最多一个请求在途);也可通过 `config.address_lookup_tables` 注入已加载的快照。缓存和待刷新队列各最多保留 2048 张表,刷新结果只供后续消息使用。`shredstream_pumpfun_json.ts` 的 **`RPC_URL`**(或 `--rpc`)用于后台刷新,Entry 解析不等待 RPC。
|
|
283
289
|
|
|
284
290
|
---
|
|
285
291
|
|
|
@@ -290,29 +296,29 @@ npx tsx examples/shredstream_example.ts -- --url=http://127.0.0.1:10800
|
|
|
290
296
|
| 描述 | 运行命令 | 源码 |
|
|
291
297
|
|------|----------|------|
|
|
292
298
|
| **本包脚本** | | |
|
|
293
|
-
| gRPC 集成测试(PumpFun + PumpSwap,账户填充后的 `DexEvent`) | `npx tsx scripts/test-grpc-ts.ts` | [test-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/test-grpc-ts.ts) | `v0.5.
|
|
294
|
-
| 调试:打印 `metaRaw` / 日志结构 | `npx tsx scripts/debug-grpc-ts.ts` | [debug-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/debug-grpc-ts.ts) | `v0.5.
|
|
299
|
+
| gRPC 集成测试(PumpFun + PumpSwap,账户填充后的 `DexEvent`) | `npx tsx scripts/test-grpc-ts.ts` | [test-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/test-grpc-ts.ts) | `v0.5.20` |
|
|
300
|
+
| 调试:打印 `metaRaw` / 日志结构 | `npx tsx scripts/debug-grpc-ts.ts` | [debug-grpc-ts.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/scripts/debug-grpc-ts.ts) | `v0.5.20` |
|
|
295
301
|
| **PumpFun** | | |
|
|
296
|
-
| CREATE + dev BUY/SELL 长时间低延迟订阅 | `npx tsx examples/devtrades_low_latency.ts` | [devtrades_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_low_latency.ts) | `v0.5.
|
|
297
|
-
| PumpFun + 全量 PumpSwap 开发者交易/加池 | `npm run example:grpc:devtrades:pumpswap` | [devtrades_pumpfun_pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_pumpfun_pumpswap_low_latency.ts) | `v0.5.
|
|
298
|
-
| gRPC 输出完整 JSON `DexEvent` | `npx tsx examples/pumpfun_grpc_json.ts` | [pumpfun_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_grpc_json.ts) | `v0.5.
|
|
299
|
-
| PumpFun 事件 + 性能指标 | `npx tsx examples/pumpfun_with_metrics.ts` | [pumpfun_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_with_metrics.ts) | `v0.5.
|
|
300
|
-
| PumpFun 交易类型过滤 | `npx tsx examples/pumpfun_trade_filter.ts` | [pumpfun_trade_filter.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_trade_filter.ts) | `v0.5.
|
|
301
|
-
| PumpFun 快速连接测试 | `npx tsx examples/pumpfun_quick_test.ts` | [pumpfun_quick_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_quick_test.ts) | `v0.5.
|
|
302
|
+
| CREATE + dev BUY/SELL 长时间低延迟订阅 | `npx tsx examples/devtrades_low_latency.ts` | [devtrades_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_low_latency.ts) | `v0.5.20` |
|
|
303
|
+
| PumpFun + 全量 PumpSwap 开发者交易/加池 | `npm run example:grpc:devtrades:pumpswap` | [devtrades_pumpfun_pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/devtrades_pumpfun_pumpswap_low_latency.ts) | `v0.5.20` |
|
|
304
|
+
| gRPC 输出完整 JSON `DexEvent` | `npx tsx examples/pumpfun_grpc_json.ts` | [pumpfun_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_grpc_json.ts) | `v0.5.20` |
|
|
305
|
+
| PumpFun 事件 + 性能指标 | `npx tsx examples/pumpfun_with_metrics.ts` | [pumpfun_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_with_metrics.ts) | `v0.5.20` |
|
|
306
|
+
| PumpFun 交易类型过滤 | `npx tsx examples/pumpfun_trade_filter.ts` | [pumpfun_trade_filter.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_trade_filter.ts) | `v0.5.20` |
|
|
307
|
+
| PumpFun 快速连接测试 | `npx tsx examples/pumpfun_quick_test.ts` | [pumpfun_quick_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpfun_quick_test.ts) | `v0.5.20` |
|
|
302
308
|
| **PumpSwap** | | |
|
|
303
|
-
| gRPC 输出完整 JSON `DexEvent` | `npx tsx examples/pumpswap_grpc_json.ts` | [pumpswap_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_grpc_json.ts) | `v0.5.
|
|
304
|
-
| PumpSwap 事件 + 性能指标 | `npx tsx examples/pumpswap_with_metrics.ts` | [pumpswap_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_with_metrics.ts) | `v0.5.
|
|
305
|
-
| PumpSwap 交易、创建池及流动性事件(超低延迟) | `npm run example:grpc:pumpswap` | [pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_low_latency.ts) | `v0.5.
|
|
309
|
+
| gRPC 输出完整 JSON `DexEvent` | `npx tsx examples/pumpswap_grpc_json.ts` | [pumpswap_grpc_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_grpc_json.ts) | `v0.5.20` |
|
|
310
|
+
| PumpSwap 事件 + 性能指标 | `npx tsx examples/pumpswap_with_metrics.ts` | [pumpswap_with_metrics.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_with_metrics.ts) | `v0.5.20` |
|
|
311
|
+
| PumpSwap 交易、创建池及流动性事件(超低延迟) | `npm run example:grpc:pumpswap` | [pumpswap_low_latency.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/pumpswap_low_latency.ts) | `v0.5.20` |
|
|
306
312
|
| **Meteora DAMM** | | |
|
|
307
|
-
| Meteora DAMM V2 事件 | `npx tsx examples/meteora_damm_grpc.ts` | [meteora_damm_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/meteora_damm_grpc.ts) | `v0.5.
|
|
313
|
+
| Meteora DAMM V2 事件 | `npx tsx examples/meteora_damm_grpc.ts` | [meteora_damm_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/meteora_damm_grpc.ts) | `v0.5.20` |
|
|
308
314
|
| **ShredStream**(HTTP,**非** Yellowstone gRPC;端点见上文步骤 5) | | |
|
|
309
|
-
| 超低延迟订阅、队列与延迟统计。端点:`--url` / `SHREDSTREAM_URL` / `.env`(默认 `http://127.0.0.1:10800`)。 | `npx tsx examples/shredstream_example.ts` | [shredstream_example.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_example.ts) | `v0.5.
|
|
310
|
-
| ShredStream → PumpFun `DexEvent` JSON;RPC(`RPC_URL` 或 `--rpc`)只后台刷新 ALT,冷缓存 miss 跳过并计数、不重放;应预热所需表。 | `npx tsx examples/shredstream_pumpfun_json.ts` | [shredstream_pumpfun_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_pumpfun_json.ts) | `v0.5.
|
|
315
|
+
| 超低延迟订阅、队列与延迟统计。端点:`--url` / `SHREDSTREAM_URL` / `.env`(默认 `http://127.0.0.1:10800`)。 | `npx tsx examples/shredstream_example.ts` | [shredstream_example.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_example.ts) | `v0.5.20` |
|
|
316
|
+
| ShredStream → PumpFun `DexEvent` JSON;RPC(`RPC_URL` 或 `--rpc`)只后台刷新 ALT,冷缓存 miss 跳过并计数、不重放;应预热所需表。 | `npx tsx examples/shredstream_pumpfun_json.ts` | [shredstream_pumpfun_json.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/shredstream_pumpfun_json.ts) | `v0.5.20` |
|
|
311
317
|
| **多协议** | | |
|
|
312
|
-
| 同时订阅所有 DEX 协议 | `npx tsx examples/multi_protocol_grpc.ts` | [multi_protocol_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/multi_protocol_grpc.ts) | `v0.5.
|
|
318
|
+
| 同时订阅所有 DEX 协议 | `npx tsx examples/multi_protocol_grpc.ts` | [multi_protocol_grpc.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/multi_protocol_grpc.ts) | `v0.5.20` |
|
|
313
319
|
| **工具** | | |
|
|
314
|
-
| 验证 onUpdate 同步错误不会打断 gRPC 流 | `npx tsx examples/grpc_onupdate_error_test.ts` | [grpc_onupdate_error_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/grpc_onupdate_error_test.ts) | `v0.5.
|
|
315
|
-
| 按签名解析交易(`parseTransactionFromRpc`;非 gRPC)。在 `.env` 或环境中设置 `TX_SIGNATURE`。 | `npx tsx examples/parse_tx_by_signature.ts` | [parse_tx_by_signature.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/parse_tx_by_signature.ts) | `v0.5.
|
|
320
|
+
| 验证 onUpdate 同步错误不会打断 gRPC 流 | `npx tsx examples/grpc_onupdate_error_test.ts` | [grpc_onupdate_error_test.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/grpc_onupdate_error_test.ts) | `v0.5.20` |
|
|
321
|
+
| 按签名解析交易(`parseTransactionFromRpc`;非 gRPC)。在 `.env` 或环境中设置 `TX_SIGNATURE`。 | `npx tsx examples/parse_tx_by_signature.ts` | [parse_tx_by_signature.ts](https://github.com/0xfnzero/sol-parser-sdk-nodejs/blob/main/examples/parse_tx_by_signature.ts) | `v0.5.20` |
|
|
316
322
|
|
|
317
323
|
**`npm run` 别名**(与上表 ShredStream 行同一源码文件,每行一条):
|
|
318
324
|
|
|
@@ -356,3 +362,17 @@ MIT — https://github.com/0xfnzero/sol-parser-sdk-nodejs
|
|
|
356
362
|
完整跨语言 API 对齐仍在进行;公开行为和支持边界见 [API 迁移说明](docs/USAGE.md#api-compatibility),使用方法见 examples 目录。
|
|
357
363
|
|
|
358
364
|
PumpFun create/create_v2 的共享主网样本、重放方法和验证边界见 [验证说明](https://github.com/0xfnzero/sol-parser-sdk-golang/tree/main/validation/pumpfun_create_20261007)。
|
|
365
|
+
|
|
366
|
+
### Pump ShredStream 离线回归
|
|
367
|
+
|
|
368
|
+
已同步路由意图事件、严格 ALT 缓存解析和本语言原生签名回放/SBF 模拟示例。运行命令、缓存 API、冻结数据来源与测试范围见 [examples/offline_bank/README.md](examples/offline_bank/README.md)。默认跳过账户未解析完整的指令;旧行为需显式使用 best-effort 入口。路由意图不等于已成交事件,解析热路径不调用 RPC。
|
|
369
|
+
|
|
370
|
+
### 可重复的本地热路径基准
|
|
371
|
+
|
|
372
|
+
运行 `npx tsx examples/hotpath_benchmark.ts`;可选第二个参数为 JSON
|
|
373
|
+
配置路径。默认配置在 `examples/hotpath_benchmark.json`,可修改预热次数、
|
|
374
|
+
样本数与批大小。固定工作负载覆盖真实签名的包装程序和 ALT 交易,分别测量
|
|
375
|
+
完整账户解析与 wire 解码加解析。文件读取、配置及样例准备均在计时之外,
|
|
376
|
+
计时循环无 RPC/网络请求。输出 p50/p95/p99 为每批折算的单交易微秒分布,
|
|
377
|
+
包含调度和 GC 影响;这不是生产延迟或上链速度保证。比较时保持运行时、
|
|
378
|
+
配置和主机负载一致,双方均需先预热。
|
package/dist/core/dex_event.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { PumpRouteIntentEvent } from "../instr/pump_routes.js";
|
|
1
2
|
import type { PumpFunPostCompleteBuyEvent, PumpFunSweepBondingCurveFeeEvent, PumpFunCompleteEvent, PumpSwapSweepPoolFeeEvent } from "../logs/pump_upgrade.js";
|
|
2
3
|
import type { RawAccountSnapshotEvent, LiquidityAccountSnapshotEvent } from '../liquidity_snapshot.js';
|
|
3
4
|
import type { EventMetadata } from "./metadata.js";
|
|
4
5
|
/** 统一 DEX 事件:外部标签 JSON(单键对象);键名清单见 `scripts/dex-event-variant-names.json` */
|
|
5
6
|
export type DexEvent = {
|
|
7
|
+
PumpRouteIntent: PumpRouteIntentEvent;
|
|
8
|
+
} | {
|
|
6
9
|
PumpFunPostCompleteBuy: PumpFunPostCompleteBuyEvent;
|
|
7
10
|
} | {
|
|
8
11
|
PumpFunSweepBondingCurveFee: PumpFunSweepBondingCurveFeeEvent;
|
package/dist/grpc/types.d.ts
CHANGED
|
@@ -154,7 +154,7 @@ export declare function accountFilterFromProgramOwners(programIds: string[]): Ac
|
|
|
154
154
|
*/
|
|
155
155
|
export declare function accountFilterMemcmp(offset: number, bytes: Uint8Array): SubscribeRequestFilterAccountsFilter;
|
|
156
156
|
/** 事件类型过滤标签 */
|
|
157
|
-
export type EventType = "AccountRawSnapshot" | "AccountLiquiditySnapshot" | "BlockMeta" | "RaydiumLaunchlabTrade" | "RaydiumLaunchlabPoolCreate" | "RaydiumLaunchlabMigrateAmm" | "PumpFunTrade" | "PumpFunBuy" | "PumpFunSell" | "PumpFunBuyExactSolIn" | "PumpFunCreate" | "PumpFunCreateV2" | "PumpFunComplete" | "PumpFunMigrate" | "PumpFeesCreateFeeSharingConfig" | "PumpFeesInitializeFeeConfig" | "PumpFeesResetFeeSharingConfig" | "PumpFeesRevokeFeeSharingAuthority" | "PumpFeesTransferFeeSharingAuthority" | "PumpFeesUpdateAdmin" | "PumpFeesUpdateFeeConfig" | "PumpFeesUpdateFeeShares" | "PumpFeesUpsertFeeTiers" | "PumpFunPostCompleteBuy" | "PumpFunSweepBondingCurveFee" | "PumpSwapSweepPoolFee" | "PumpFunMigrateBondingCurveCreator" | "PumpSwapTrade" | "PumpSwapBuy" | "PumpSwapSell" | "PumpSwapCreatePool" | "PumpSwapLiquidityAdded" | "PumpSwapLiquidityRemoved" | "RaydiumCpmmSwap" | "RaydiumCpmmDeposit" | "RaydiumCpmmWithdraw" | "RaydiumCpmmInitialize" | "RaydiumClmmSwap" | "RaydiumClmmCreatePool" | "RaydiumClmmOpenPosition" | "RaydiumClmmClosePosition" | "RaydiumClmmIncreaseLiquidity" | "RaydiumClmmDecreaseLiquidity" | "RaydiumClmmLiquidityChange" | "RaydiumClmmConfigChange" | "RaydiumClmmCreatePersonalPosition" | "RaydiumClmmLiquidityCalculate" | "RaydiumClmmOpenLimitOrder" | "RaydiumClmmIncreaseLimitOrder" | "RaydiumClmmDecreaseLimitOrder" | "RaydiumClmmSettleLimitOrder" | "RaydiumClmmUpdateRewardInfos" | "RaydiumClmmOpenPositionWithTokenExtNft" | "RaydiumClmmCollectFee" | "RaydiumAmmV4Swap" | "RaydiumAmmV4Deposit" | "RaydiumAmmV4Withdraw" | "RaydiumAmmV4Initialize2" | "RaydiumAmmV4WithdrawPnl" | "OrcaWhirlpoolSwap" | "OrcaWhirlpoolLiquidityIncreased" | "OrcaWhirlpoolLiquidityDecreased" | "OrcaWhirlpoolPoolInitialized" | "MeteoraPoolsSwap" | "MeteoraPoolsAddLiquidity" | "MeteoraPoolsRemoveLiquidity" | "MeteoraPoolsBootstrapLiquidity" | "MeteoraPoolsPoolCreated" | "MeteoraPoolsSetPoolFees" | "MeteoraDammV2Swap" | "MeteoraDammV2AddLiquidity" | "MeteoraDammV2RemoveLiquidity" | "MeteoraDammV2InitializePool" | "MeteoraDammV2CreatePosition" | "MeteoraDammV2ClaimPositionFee" | "MeteoraDammV2ClaimReward" | "MeteoraDlmmClaimReward" | "MeteoraDammV2ClosePosition" | "MeteoraDammV2UpdateDelegatePermission" | "MeteoraDammV2WithdrawDeadLiquidityReward" | "MeteoraDammV2WithdrawIneligibleReward" | "MeteoraDammV2UpdateRewardFunder" | "MeteoraDammV2UpdateRewardDuration" | "MeteoraDammV2InitializeReward" | "MeteoraDammV2FundReward" | "MeteoraDammV2CreateConfig" | "MeteoraDammV2CreateDynamicConfig" | "MeteoraDbcSwap" | "MeteoraDbcInitializePool" | "MeteoraDbcCurveComplete" | "MeteoraDlmmSwap" | "MeteoraDlmmAddLiquidity" | "MeteoraDlmmRemoveLiquidity" | "MeteoraDlmmInitializePool" | "MeteoraDlmmInitializeBinArray" | "MeteoraDlmmCreatePosition" | "MeteoraDlmmClosePosition" | "MeteoraDlmmClaimFee" | "TokenAccount" | "TokenInfo" | "NonceAccount" | "AccountPumpFunGlobal" | "AccountPumpFunBondingCurve" | "AccountPumpFunFeeConfig" | "AccountPumpFunSharingConfig" | "AccountPumpFunGlobalVolumeAccumulator" | "AccountPumpFunUserVolumeAccumulator" | "AccountPumpSwapGlobalConfig" | "AccountPumpSwapPool" | "AccountRaydiumClmmAmmConfig" | "AccountRaydiumClmmPoolState" | "AccountRaydiumClmmTickArrayState" | "AccountRaydiumCpmmAmmConfig" | "AccountRaydiumCpmmPoolState" | "AccountOrcaWhirlpool" | "AccountOrcaPosition" | "AccountOrcaTickArray" | "AccountOrcaFeeTier" | "AccountOrcaWhirlpoolsConfig";
|
|
157
|
+
export type EventType = "PumpRouteIntent" | "AccountRawSnapshot" | "AccountLiquiditySnapshot" | "BlockMeta" | "RaydiumLaunchlabTrade" | "RaydiumLaunchlabPoolCreate" | "RaydiumLaunchlabMigrateAmm" | "PumpFunTrade" | "PumpFunBuy" | "PumpFunSell" | "PumpFunBuyExactSolIn" | "PumpFunCreate" | "PumpFunCreateV2" | "PumpFunComplete" | "PumpFunMigrate" | "PumpFeesCreateFeeSharingConfig" | "PumpFeesInitializeFeeConfig" | "PumpFeesResetFeeSharingConfig" | "PumpFeesRevokeFeeSharingAuthority" | "PumpFeesTransferFeeSharingAuthority" | "PumpFeesUpdateAdmin" | "PumpFeesUpdateFeeConfig" | "PumpFeesUpdateFeeShares" | "PumpFeesUpsertFeeTiers" | "PumpFunPostCompleteBuy" | "PumpFunSweepBondingCurveFee" | "PumpSwapSweepPoolFee" | "PumpFunMigrateBondingCurveCreator" | "PumpSwapTrade" | "PumpSwapBuy" | "PumpSwapSell" | "PumpSwapCreatePool" | "PumpSwapLiquidityAdded" | "PumpSwapLiquidityRemoved" | "RaydiumCpmmSwap" | "RaydiumCpmmDeposit" | "RaydiumCpmmWithdraw" | "RaydiumCpmmInitialize" | "RaydiumClmmSwap" | "RaydiumClmmCreatePool" | "RaydiumClmmOpenPosition" | "RaydiumClmmClosePosition" | "RaydiumClmmIncreaseLiquidity" | "RaydiumClmmDecreaseLiquidity" | "RaydiumClmmLiquidityChange" | "RaydiumClmmConfigChange" | "RaydiumClmmCreatePersonalPosition" | "RaydiumClmmLiquidityCalculate" | "RaydiumClmmOpenLimitOrder" | "RaydiumClmmIncreaseLimitOrder" | "RaydiumClmmDecreaseLimitOrder" | "RaydiumClmmSettleLimitOrder" | "RaydiumClmmUpdateRewardInfos" | "RaydiumClmmOpenPositionWithTokenExtNft" | "RaydiumClmmCollectFee" | "RaydiumAmmV4Swap" | "RaydiumAmmV4Deposit" | "RaydiumAmmV4Withdraw" | "RaydiumAmmV4Initialize2" | "RaydiumAmmV4WithdrawPnl" | "OrcaWhirlpoolSwap" | "OrcaWhirlpoolLiquidityIncreased" | "OrcaWhirlpoolLiquidityDecreased" | "OrcaWhirlpoolPoolInitialized" | "MeteoraPoolsSwap" | "MeteoraPoolsAddLiquidity" | "MeteoraPoolsRemoveLiquidity" | "MeteoraPoolsBootstrapLiquidity" | "MeteoraPoolsPoolCreated" | "MeteoraPoolsSetPoolFees" | "MeteoraDammV2Swap" | "MeteoraDammV2AddLiquidity" | "MeteoraDammV2RemoveLiquidity" | "MeteoraDammV2InitializePool" | "MeteoraDammV2CreatePosition" | "MeteoraDammV2ClaimPositionFee" | "MeteoraDammV2ClaimReward" | "MeteoraDlmmClaimReward" | "MeteoraDammV2ClosePosition" | "MeteoraDammV2UpdateDelegatePermission" | "MeteoraDammV2WithdrawDeadLiquidityReward" | "MeteoraDammV2WithdrawIneligibleReward" | "MeteoraDammV2UpdateRewardFunder" | "MeteoraDammV2UpdateRewardDuration" | "MeteoraDammV2InitializeReward" | "MeteoraDammV2FundReward" | "MeteoraDammV2CreateConfig" | "MeteoraDammV2CreateDynamicConfig" | "MeteoraDbcSwap" | "MeteoraDbcInitializePool" | "MeteoraDbcCurveComplete" | "MeteoraDlmmSwap" | "MeteoraDlmmAddLiquidity" | "MeteoraDlmmRemoveLiquidity" | "MeteoraDlmmInitializePool" | "MeteoraDlmmInitializeBinArray" | "MeteoraDlmmCreatePosition" | "MeteoraDlmmClosePosition" | "MeteoraDlmmClaimFee" | "TokenAccount" | "TokenInfo" | "NonceAccount" | "AccountPumpFunGlobal" | "AccountPumpFunBondingCurve" | "AccountPumpFunFeeConfig" | "AccountPumpFunSharingConfig" | "AccountPumpFunGlobalVolumeAccumulator" | "AccountPumpFunUserVolumeAccumulator" | "AccountPumpSwapGlobalConfig" | "AccountPumpSwapPool" | "AccountRaydiumClmmAmmConfig" | "AccountRaydiumClmmPoolState" | "AccountRaydiumClmmTickArrayState" | "AccountRaydiumCpmmAmmConfig" | "AccountRaydiumCpmmPoolState" | "AccountOrcaWhirlpool" | "AccountOrcaPosition" | "AccountOrcaTickArray" | "AccountOrcaFeeTier" | "AccountOrcaWhirlpoolsConfig";
|
|
158
158
|
/** 与 Rust `grpc::EventType`(由 `StreamingEventType` 导出)一致 */
|
|
159
159
|
export type StreamingEventType = EventType;
|
|
160
160
|
/** 所有事件类型列表 */
|
package/dist/grpc/types.js
CHANGED
|
@@ -30,6 +30,7 @@ exports.eventTypeFilterIncludesRaydiumAmmV4 = eventTypeFilterIncludesRaydiumAmmV
|
|
|
30
30
|
exports.eventTypeFilterIncludesOrcaWhirlpool = eventTypeFilterIncludesOrcaWhirlpool;
|
|
31
31
|
exports.eventTypeFilterIncludesRaydiumLaunchlab = eventTypeFilterIncludesRaydiumLaunchlab;
|
|
32
32
|
exports.eventTypeFilterAllowsInstructionParsing = eventTypeFilterAllowsInstructionParsing;
|
|
33
|
+
const pump_routes_js_1 = require("../instr/pump_routes.js");
|
|
33
34
|
const metadata_js_1 = require("../core/metadata.js");
|
|
34
35
|
function defaultClientConfig() {
|
|
35
36
|
return {
|
|
@@ -260,6 +261,7 @@ exports.ALL_EVENT_TYPES = [
|
|
|
260
261
|
"PumpFunPostCompleteBuy",
|
|
261
262
|
"PumpFunSweepBondingCurveFee",
|
|
262
263
|
"PumpSwapSweepPoolFee",
|
|
264
|
+
"PumpRouteIntent",
|
|
263
265
|
];
|
|
264
266
|
const ALL_EVENT_TYPE_SET = new Set(exports.ALL_EVENT_TYPES);
|
|
265
267
|
const PUMPFUN_BUY_FAMILY = ["PumpFunBuy", "PumpFunBuyExactSolIn"];
|
|
@@ -390,6 +392,7 @@ const RAYDIUM_LAUNCHLAB_FILTER_TYPES = [
|
|
|
390
392
|
"RaydiumLaunchlabMigrateAmm",
|
|
391
393
|
];
|
|
392
394
|
const INSTRUCTION_EVENT_TYPES = [
|
|
395
|
+
"PumpRouteIntent",
|
|
393
396
|
...PUMPFUN_FILTER_TYPES,
|
|
394
397
|
...PUMP_FEES_EVENT_TYPES,
|
|
395
398
|
...PUMPSWAP_FILTER_TYPES,
|
|
@@ -436,6 +439,8 @@ function eventTypeFromDexEvent(event) {
|
|
|
436
439
|
return ALL_EVENT_TYPE_SET.has(variant) ? variant : null;
|
|
437
440
|
}
|
|
438
441
|
function eventTypeFilterShouldIncludeDexEvent(filter, event) {
|
|
442
|
+
if ("PumpRouteIntent" in event)
|
|
443
|
+
return (0, pump_routes_js_1.allowsPumpRoute)(filter, event.PumpRouteIntent.program);
|
|
439
444
|
const eventType = eventTypeFromDexEvent(event);
|
|
440
445
|
return eventType === null || filter.shouldInclude(eventType);
|
|
441
446
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export { connectYellowstoneGeyser, defaultGeyserConnectConfig, geyserGrpcChannel
|
|
|
48
48
|
/** 与 Rust `sol_parser_sdk::grpc::event_parser` 模块对应 */
|
|
49
49
|
export * as event_parser from "./grpc/event_parser.js";
|
|
50
50
|
export { connectYellowstoneGeyser as connect_yellowstone_geyser, defaultGeyserConnectConfig as default_geyser_connect_config, geyserGrpcChannelOptions as geyser_grpc_channel_options, } from "./grpc/geyser_connect.js";
|
|
51
|
-
export { ShredStreamClient, ShredEventQueue, dexEventsFromShredWasmTx, dexEventsFromShredWasmTxWithFullKeys, fullAccountKeyStringsFromShredTx, loadAddressLookupTableAccounts, bincodeVecEntryCount, decodeEntriesBincodeFlat, decodeEntriesBincodeNested, decodeShredstreamEntriesBincode, wireBytesToShredWasmTx, type ShredStreamReceiveStats, type ShredWasmTx, type ShredWasmCompiledIx, type ShredStreamConfig, type DecodedWireTransaction, defaultShredStreamConfig, lowLatencyShredStreamConfig, highThroughputShredStreamConfig, type SubscribeEntriesRequest, type ShredstreamEntryMessage, } from "./shredstream/index.js";
|
|
51
|
+
export { ShredStreamClient, ShredEventQueue, dexEventsFromShredWasmTx, dexEventsFromShredWasmTxBestEffort, dexEventsFromShredWasmTxWithLoadedAddresses, dexEventsFromShredWasmTxWithFullKeys, fullAccountKeyStringsFromShredTx, loadAddressLookupTableAccounts, bincodeVecEntryCount, decodeEntriesBincodeFlat, decodeEntriesBincodeNested, decodeShredstreamEntriesBincode, wireBytesToShredWasmTx, type ShredStreamReceiveStats, type ShredWasmTx, type ShredWasmCompiledIx, type ShredStreamConfig, type DecodedWireTransaction, defaultShredStreamConfig, lowLatencyShredStreamConfig, highThroughputShredStreamConfig, type SubscribeEntriesRequest, type ShredstreamEntryMessage, } from "./shredstream/index.js";
|
|
52
52
|
export { defaultShredStreamConfig as default_shred_stream_config, lowLatencyShredStreamConfig as low_latency_shred_stream_config, highThroughputShredStreamConfig as high_throughput_shred_stream_config, } from "./shredstream/index.js";
|
|
53
53
|
export { decodeWireTransaction, type WireMessage, type WireInstruction, type DecodedWireTransaction as NativeWireTransaction } from './wire_transaction.js';
|
|
54
54
|
export * from './transaction_route.js';
|
|
@@ -59,3 +59,4 @@ export { parseBlockMetaUpdate } from "./grpc/block_meta.js";
|
|
|
59
59
|
export { buildSubscribeRequestWithEventFilter } from "./grpc/subscribe_builder.js";
|
|
60
60
|
export type { LaunchLabPoolCreateEvent, StonkFunPoolCreateEvent, LaunchLabTradeEvent, StonkFunTradeEvent, } from "./core/dex_event.js";
|
|
61
61
|
export * from "./logs/pump_upgrade.js";
|
|
62
|
+
export * from "./instr/pump_routes.js";
|
package/dist/index.js
CHANGED
|
@@ -40,7 +40,7 @@ exports.pubkeyBytesToBs58 = exports.grpcTxIndexFromInfo = exports.parseDexEvents
|
|
|
40
40
|
exports.RAYDIUM_CPMM_PROGRAM_ID = exports.RAYDIUM_LAUNCHLAB_PROGRAM_ID = exports.PUMP_FEES_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = exports.PROTOCOL_PROGRAM_IDS = exports.all_event_types = exports.ALL_EVENT_TYPES = exports.eventTypeFilterAllowsInstructionParsing = exports.eventTypeFilterIncludesPumpFees = exports.eventTypeFilterIncludesRaydiumLaunchlab = exports.eventTypeFilterIncludesOrcaWhirlpool = exports.eventTypeFilterIncludesRaydiumAmmV4 = exports.eventTypeFilterIncludesRaydiumCpmm = exports.eventTypeFilterIncludesRaydiumClmm = exports.eventTypeFilterIncludesMeteoraDlmm = exports.eventTypeFilterIncludesMeteoraPools = exports.eventTypeFilterIncludesMeteoraDbc = exports.eventTypeFilterIncludesMeteoraDammV2 = exports.eventTypeFilterIncludesPumpswap = exports.eventTypeFilterIncludesPumpfun = exports.eventTypeFilterExclude = exports.eventTypeFilterIncludeOnly = exports.accountFilterMemcmp = exports.accountFilterFromProgramOwners = exports.slotFilterMaxSlot = exports.slotFilterMinSlot = exports.newSlotFilter = exports.newAccountFilter = exports.transactionFilterFromProgramIds = exports.newTransactionFilter = exports.highThroughputClientConfig = exports.lowLatencyClientConfig = exports.defaultClientConfig = exports.try_yellowstone_signature = exports.collect_watch_transfer_counterparty_pairs = exports.spl_token_counterparty_by_owner = exports.token_balance_raw_amount = exports.heuristic_sol_counterparties_for_watched_keys = exports.lamport_balance_deltas = exports.collect_account_keys_bs58 = exports.pubkey_bytes_to_bs58 = exports.tryYellowstoneSignature = exports.collectWatchTransferCounterpartyPairs = exports.splTokenCounterpartyByOwner = exports.tokenBalanceRawAmount = exports.heuristicSolCounterpartiesForWatchedKeys = exports.lamportBalanceDeltas = exports.collectAccountKeysBs58 = void 0;
|
|
41
41
|
exports.discriminatorToProtocol = exports.discriminator_to_name = exports.discriminatorToName = exports.parse_log_unified = exports.parse_log_optimized = exports.parse_meteora_dlmm_log = exports.parse_meteora_damm_log = exports.parseProgramCompleteInfo = exports.parseLogUnified = exports.parseLogOptimizedWithProgramId = exports.parseLogOptimized = exports.parseInvokeInfo = exports.build_subscribe_transaction_filters_named = exports.build_subscribe_request_with_commitment = exports.build_subscribe_request = exports.CommitmentLevel = exports.buildSubscribeTransactionFiltersNamed = exports.buildSubscribeRequestWithCommitment = exports.buildSubscribeRequest = exports.exclude_types = exports.include_only = exports.event_type_filter_exclude = exports.event_type_filter_include_only = exports.account_filter_memcmp = exports.account_filter_from_program_owners = exports.slot_filter_max_slot = exports.slot_filter_min_slot = exports.new_slot_filter = exports.new_account_filter = exports.transaction_filter_from_program_ids = exports.new_transaction_filter = exports.high_throughput_client_config = exports.low_latency_client_config = exports.default_client_config = exports.account_filter_for_protocols = exports.transaction_filter_for_protocol_accounts = exports.transaction_filter_for_protocols = exports.get_program_ids_for_protocols = exports.protocol_program_ids = exports.accountFilterForProtocols = exports.transactionFilterForProtocolAccounts = exports.transactionFilterForProtocols = exports.getProgramIdsForProtocols = exports.METEORA_DBC_PROGRAM_ID = exports.METEORA_DLMM_PROGRAM_ID = exports.METEORA_DAMM_V2_PROGRAM_ID = exports.METEORA_POOLS_PROGRAM_ID = exports.ORCA_WHIRLPOOL_PROGRAM_ID = exports.RAYDIUM_AMM_V4_PROGRAM_ID = exports.RAYDIUM_CLMM_PROGRAM_ID = void 0;
|
|
42
42
|
exports.event_parser = exports.geyserGrpcChannelOptions = exports.defaultGeyserConnectConfig = exports.connectYellowstoneGeyser = exports.YellowstoneGrpc = exports.programIds = exports.parse_pump_fees_instruction = exports.parse_meteora_pools_instruction = exports.parse_meteora_dlmm_instruction = exports.parse_meteora_damm_instruction = exports.parse_pumpswap_instruction = exports.parse_pumpfun_instruction = exports.parse_instruction_unified = exports.parsePumpFeesInstruction = exports.parseMeteoraPoolsInstruction = exports.parseMeteoraDlmmInstruction = exports.parseMeteoraDammInstruction = exports.parsePumpswapInstruction = exports.parsePumpfunInstruction = exports.parseInstructionUnified = exports.user_wallet_pubkey_for_onchain_account = exports.rpc_resolve_user_wallet_pubkey = exports.parse_pumpswap_pool = exports.parse_pumpswap_global_config = exports.parse_pumpfun_global = exports.parse_token_account = exports.parse_nonce_account = exports.parse_account_unified = exports.rpcResolveUserWalletPubkey = exports.userWalletPubkeyForOnchainAccount = exports.hasDiscriminator = exports.isPoolAccount = exports.isGlobalConfigAccount = exports.parsePumpswapAccount = exports.parsePumpswapPool = exports.parsePumpswapGlobalConfig = exports.isPumpfunGlobalAccount = exports.parsePumpfunAccount = exports.parsePumpfunGlobal = exports.parseTokenAccount = exports.isNonceAccount = exports.parseNonceAccount = exports.parseAccountUnified = exports.u64leDiscriminator = exports.PUMPSWAP_DISC = exports.PROGRAM_LOG_DISC = exports.parseMeteoraDammLog = exports.lookup_discriminator = exports.lookupDiscriminator = exports.discriminator_to_protocol = void 0;
|
|
43
|
-
exports.buildSubscribeRequestWithEventFilter = exports.parseBlockMetaUpdate = exports.analyzeSimulationRoutes = exports.decodeWireTransaction = exports.high_throughput_shred_stream_config = exports.low_latency_shred_stream_config = exports.default_shred_stream_config = exports.highThroughputShredStreamConfig = exports.lowLatencyShredStreamConfig = exports.defaultShredStreamConfig = exports.wireBytesToShredWasmTx = exports.decodeShredstreamEntriesBincode = exports.decodeEntriesBincodeNested = exports.decodeEntriesBincodeFlat = exports.bincodeVecEntryCount = exports.loadAddressLookupTableAccounts = exports.fullAccountKeyStringsFromShredTx = exports.dexEventsFromShredWasmTxWithFullKeys = exports.dexEventsFromShredWasmTx = exports.ShredEventQueue = exports.ShredStreamClient = exports.geyser_grpc_channel_options = exports.default_geyser_connect_config = exports.connect_yellowstone_geyser = void 0;
|
|
43
|
+
exports.buildSubscribeRequestWithEventFilter = exports.parseBlockMetaUpdate = exports.analyzeSimulationRoutes = exports.decodeWireTransaction = exports.high_throughput_shred_stream_config = exports.low_latency_shred_stream_config = exports.default_shred_stream_config = exports.highThroughputShredStreamConfig = exports.lowLatencyShredStreamConfig = exports.defaultShredStreamConfig = exports.wireBytesToShredWasmTx = exports.decodeShredstreamEntriesBincode = exports.decodeEntriesBincodeNested = exports.decodeEntriesBincodeFlat = exports.bincodeVecEntryCount = exports.loadAddressLookupTableAccounts = exports.fullAccountKeyStringsFromShredTx = exports.dexEventsFromShredWasmTxWithFullKeys = exports.dexEventsFromShredWasmTxWithLoadedAddresses = exports.dexEventsFromShredWasmTxBestEffort = exports.dexEventsFromShredWasmTx = exports.ShredEventQueue = exports.ShredStreamClient = exports.geyser_grpc_channel_options = exports.default_geyser_connect_config = exports.connect_yellowstone_geyser = void 0;
|
|
44
44
|
var constants_js_1 = require("./common/constants.js");
|
|
45
45
|
Object.defineProperty(exports, "DEFAULT_CHANNEL_SIZE", { enumerable: true, get: function () { return constants_js_1.DEFAULT_CHANNEL_SIZE; } });
|
|
46
46
|
Object.defineProperty(exports, "DEFAULT_CONNECT_TIMEOUT", { enumerable: true, get: function () { return constants_js_1.DEFAULT_CONNECT_TIMEOUT; } });
|
|
@@ -290,6 +290,8 @@ var index_js_1 = require("./shredstream/index.js");
|
|
|
290
290
|
Object.defineProperty(exports, "ShredStreamClient", { enumerable: true, get: function () { return index_js_1.ShredStreamClient; } });
|
|
291
291
|
Object.defineProperty(exports, "ShredEventQueue", { enumerable: true, get: function () { return index_js_1.ShredEventQueue; } });
|
|
292
292
|
Object.defineProperty(exports, "dexEventsFromShredWasmTx", { enumerable: true, get: function () { return index_js_1.dexEventsFromShredWasmTx; } });
|
|
293
|
+
Object.defineProperty(exports, "dexEventsFromShredWasmTxBestEffort", { enumerable: true, get: function () { return index_js_1.dexEventsFromShredWasmTxBestEffort; } });
|
|
294
|
+
Object.defineProperty(exports, "dexEventsFromShredWasmTxWithLoadedAddresses", { enumerable: true, get: function () { return index_js_1.dexEventsFromShredWasmTxWithLoadedAddresses; } });
|
|
293
295
|
Object.defineProperty(exports, "dexEventsFromShredWasmTxWithFullKeys", { enumerable: true, get: function () { return index_js_1.dexEventsFromShredWasmTxWithFullKeys; } });
|
|
294
296
|
Object.defineProperty(exports, "fullAccountKeyStringsFromShredTx", { enumerable: true, get: function () { return index_js_1.fullAccountKeyStringsFromShredTx; } });
|
|
295
297
|
Object.defineProperty(exports, "loadAddressLookupTableAccounts", { enumerable: true, get: function () { return index_js_1.loadAddressLookupTableAccounts; } });
|
|
@@ -317,3 +319,4 @@ Object.defineProperty(exports, "parseBlockMetaUpdate", { enumerable: true, get:
|
|
|
317
319
|
var subscribe_builder_js_3 = require("./grpc/subscribe_builder.js");
|
|
318
320
|
Object.defineProperty(exports, "buildSubscribeRequestWithEventFilter", { enumerable: true, get: function () { return subscribe_builder_js_3.buildSubscribeRequestWithEventFilter; } });
|
|
319
321
|
__exportStar(require("./logs/pump_upgrade.js"), exports);
|
|
322
|
+
__exportStar(require("./instr/pump_routes.js"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Program-bound wire intents. No RPC, fills, balances or reserves are inferred. */
|
|
2
|
+
import type { EventMetadata } from '../core/metadata.js';
|
|
3
|
+
import type { EventTypeFilter } from '../grpc/types.js';
|
|
4
|
+
export interface PumpRouteHop {
|
|
5
|
+
base_mint: string;
|
|
6
|
+
quote_mint: string;
|
|
7
|
+
venue: string;
|
|
8
|
+
base_vault: string;
|
|
9
|
+
quote_vault: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PumpRouteIntentEvent {
|
|
12
|
+
metadata: EventMetadata;
|
|
13
|
+
kind: 'MultiHopSwap' | 'MultiHopCurveSwap' | 'RapidBuy' | 'BuyPumpDelta';
|
|
14
|
+
program: string;
|
|
15
|
+
instruction_index: number;
|
|
16
|
+
user: string;
|
|
17
|
+
input_account: string;
|
|
18
|
+
output_account: string;
|
|
19
|
+
amount_in: bigint | null;
|
|
20
|
+
min_amount_out: bigint | null;
|
|
21
|
+
hops: PumpRouteHop[];
|
|
22
|
+
instruction_data: number[];
|
|
23
|
+
}
|
|
24
|
+
export declare function mayParsePumpRoute(program: string, data: Uint8Array): boolean;
|
|
25
|
+
export declare function allowsPumpRoute(filter: EventTypeFilter | undefined, program: string): boolean;
|
|
26
|
+
export declare function pumpMultiHopArgs(program: string, data: Uint8Array, a: readonly string[]): [bigint, bigint] | null;
|
|
27
|
+
export declare function parsePumpRoute(program: string, data: Uint8Array, a: readonly string[], metadata: EventMetadata, index: number, filter?: EventTypeFilter): PumpRouteIntentEvent | null;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mayParsePumpRoute = mayParsePumpRoute;
|
|
4
|
+
exports.allowsPumpRoute = allowsPumpRoute;
|
|
5
|
+
exports.pumpMultiHopArgs = pumpMultiHopArgs;
|
|
6
|
+
exports.parsePumpRoute = parsePumpRoute;
|
|
7
|
+
const PUMP = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P', AMM = 'pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA', RAPID = 'rapidV5DAKtecYzetwCNoxXWHpezjeg4hGt9BGiVcGW', DELTA = 'J7pourVwqP1VtRNBiFNqbdGxwkx7ta2LHAURURRRJqmd', TOKEN = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', TOKEN22 = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb', SYSTEM = '11111111111111111111111111111111', ATA = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL', GLOBAL = '4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf', EVENT = 'Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1', FEES = 'pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ';
|
|
8
|
+
function matches(data, at, bytes) { return bytes.every((v, i) => data[at + i] === v); }
|
|
9
|
+
const MULTI = [43, 100, 73, 19, 233, 246, 111, 148], CURVE = [225, 154, 117, 22, 215, 86, 246, 103];
|
|
10
|
+
function mayParsePumpRoute(program, data) {
|
|
11
|
+
return (program === AMM && matches(data, 0, MULTI)) || (program === PUMP && matches(data, 0, CURVE))
|
|
12
|
+
|| (program === DELTA && data.length === 28 && matches(data, 0, [122, 28, 94, 147, 180, 45, 240, 97]))
|
|
13
|
+
|| (program === RAPID && data.length === 41 && data[0] === 0 && matches(data, 9, [1, 0, 0, 27, 15, 14, 8, 24]) && matches(data, 17, [194, 171, 28, 70, 104, 77, 91, 47]) && matches(data, 25, Array(8).fill(0)));
|
|
14
|
+
}
|
|
15
|
+
function allowsPumpRoute(filter, program) {
|
|
16
|
+
if (!filter)
|
|
17
|
+
return true;
|
|
18
|
+
const excluded = filter.exclude_types ?? [];
|
|
19
|
+
if (excluded.includes('PumpRouteIntent') || excluded.includes('PumpFunTrade') || (program === AMM && excluded.includes('PumpSwapTrade')))
|
|
20
|
+
return false;
|
|
21
|
+
const included = filter.include_only;
|
|
22
|
+
return included ? included.includes('PumpRouteIntent') || included.includes('PumpFunTrade') || (program === AMM && included.includes('PumpSwapTrade')) : filter.shouldInclude('PumpRouteIntent');
|
|
23
|
+
}
|
|
24
|
+
function context(a, pairs) { return Object.entries(pairs).every(([i, v]) => a[Number(i)] === v); }
|
|
25
|
+
function pumpMultiHopArgs(program, data, a) {
|
|
26
|
+
if (program !== AMM || data.length !== 24 || !matches(data, 0, MULTI) || a.length < 21 || (a.length - 16) % 5 || !context(a, { 7: TOKEN, 8: TOKEN22, 9: SYSTEM, 11: AMM, 12: PUMP }))
|
|
27
|
+
return null;
|
|
28
|
+
const d = new DataView(data.buffer, data.byteOffset, data.byteLength), amount = d.getBigUint64(8, true);
|
|
29
|
+
return amount ? [amount, d.getBigUint64(16, true)] : null;
|
|
30
|
+
}
|
|
31
|
+
function parsePumpRoute(program, data, a, metadata, index, filter) {
|
|
32
|
+
if (!mayParsePumpRoute(program, data) || !allowsPumpRoute(filter, program))
|
|
33
|
+
return null;
|
|
34
|
+
const d = new DataView(data.buffer, data.byteOffset, data.byteLength), u = (at) => d.getBigUint64(at, true);
|
|
35
|
+
let kind, fixed, user, input, output, amount, minimum;
|
|
36
|
+
if (program === AMM) {
|
|
37
|
+
const args = pumpMultiHopArgs(program, data, a);
|
|
38
|
+
if (!args)
|
|
39
|
+
return null;
|
|
40
|
+
[kind, fixed, user, input, output, amount, minimum] = ['MultiHopSwap', 16, 0, 1, 2, ...args];
|
|
41
|
+
}
|
|
42
|
+
else if (program === PUMP) {
|
|
43
|
+
if (data.length < 20)
|
|
44
|
+
return null;
|
|
45
|
+
const count = d.getUint32(16, true);
|
|
46
|
+
if (!count || data.length !== 20 + count || a.length !== 13 + count * 5 || !context(a, { 8: TOKEN, 9: TOKEN22, 10: SYSTEM, 11: EVENT, 12: PUMP }))
|
|
47
|
+
return null;
|
|
48
|
+
[kind, fixed, user, input, output, amount, minimum] = ['MultiHopCurveSwap', 13, 3, 5, 6, u(8), null];
|
|
49
|
+
}
|
|
50
|
+
else if (program === RAPID) {
|
|
51
|
+
if (a.length !== 33 || a[0] !== a[19] || a[2] !== a[8] || ![TOKEN, TOKEN22].includes(a[9]) || !context(a, { 3: TOKEN, 4: SYSTEM, 5: PUMP, 6: GLOBAL, 10: TOKEN, 11: ATA, 29: FEES, 30: SYSTEM, 31: EVENT, 32: PUMP }))
|
|
52
|
+
return null;
|
|
53
|
+
[kind, fixed, user, input, output, amount, minimum] = ['RapidBuy', 0, 0, 21, 20, u(1), u(33)];
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (a.length !== 30 || a[0] !== a[14] || ![TOKEN, TOKEN22].includes(a[4]) || ![TOKEN, TOKEN22].includes(a[5]) || !context(a, { 1: GLOBAL, 6: ATA, 24: FEES, 25: SYSTEM, 26: EVENT, 27: PUMP }))
|
|
57
|
+
return null;
|
|
58
|
+
[kind, fixed, user, input, output, amount, minimum] = ['BuyPumpDelta', 0, 0, 16, 15, null, null];
|
|
59
|
+
}
|
|
60
|
+
if (amount === 0n)
|
|
61
|
+
return null;
|
|
62
|
+
const hop = (h) => ({ base_mint: h[0], quote_mint: h[1], venue: h[2], base_vault: h[3], quote_vault: h[4] });
|
|
63
|
+
const hops = [];
|
|
64
|
+
if (fixed) {
|
|
65
|
+
for (let i = fixed; i < a.length; i += 5)
|
|
66
|
+
hops.push(hop(a.slice(i, i + 5)));
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
hops.push(hop((program === RAPID ? [7, 2, 16, 17, 18] : [2, 3, 11, 12, 13]).map(i => a[i])));
|
|
70
|
+
return { metadata, kind, program, instruction_index: index, user: a[user], input_account: a[input], output_account: a[output], amount_in: amount, min_amount_out: minimum, hops, instruction_data: Array.from(data) };
|
|
71
|
+
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.pumpUpgradeEventType = pumpUpgradeEventType;
|
|
4
4
|
exports.parsePumpUpgradeEvent = parsePumpUpgradeEvent;
|
|
5
5
|
exports.decodePumpMultiHopIntent = decodePumpMultiHopIntent;
|
|
6
|
+
const pump_routes_js_1 = require("../instr/pump_routes.js");
|
|
6
7
|
const binary_js_1 = require("../util/binary.js");
|
|
7
8
|
function pumpUpgradeEventType(disc, programId) {
|
|
8
9
|
if (disc === 18146529233607700591n &&
|
|
@@ -99,15 +100,10 @@ function parsePumpUpgradeEvent(disc, data, metadata, programId) {
|
|
|
99
100
|
}
|
|
100
101
|
/** Intent amounts are limits, not execution. Each hop emits its own actual trade. */
|
|
101
102
|
function decodePumpMultiHopIntent(program, data, accounts) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
(0, binary_js_1.readU64LE)(data, 0) !== 10696039120939607083n ||
|
|
105
|
-
accounts.length < 21 ||
|
|
106
|
-
(accounts.length - 16) % 5 !== 0)
|
|
107
|
-
return null;
|
|
108
|
-
const amountIn = (0, binary_js_1.readU64LE)(data, 8), minAmountOut = (0, binary_js_1.readU64LE)(data, 16);
|
|
109
|
-
if (!amountIn || !minAmountOut)
|
|
103
|
+
const args = (0, pump_routes_js_1.pumpMultiHopArgs)(program, data, accounts);
|
|
104
|
+
if (!args)
|
|
110
105
|
return null;
|
|
106
|
+
const [amountIn, minAmountOut] = args;
|
|
111
107
|
const hops = [];
|
|
112
108
|
for (let i = 16; i < accounts.length; i += 5)
|
|
113
109
|
hops.push({
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* - ALT 仅使用预热缓存;启用缓存后 miss 会跳过该交易并记录 altCacheMissTransactions,不回放
|
|
6
6
|
* - 无 inner instructions,无法 CPI 解析
|
|
7
7
|
* - 无 block_time
|
|
8
|
-
* - 无交易日志(program logs);客户端使用外层指令解析。未配置 ALT
|
|
8
|
+
* - 无交易日志(program logs);客户端使用外层指令解析。未配置 ALT 缓存时仅解析账户完整的静态指令。
|
|
9
9
|
* - `metadata.tx_index` 为**单条 gRPC `Entry` 消息内**跨所有 Solana `Entry` 分组的连续下标(与 golang `shredstream_entries` 扁平 `ti` 对齐),非 slot 级全局序号
|
|
10
10
|
*/
|
|
11
11
|
export { type ShredStreamConfig, defaultShredStreamConfig, lowLatencyShredStreamConfig, highThroughputShredStreamConfig, } from "./config.js";
|
|
12
12
|
export { ShredStreamClient, ShredEventQueue, type ShredStreamReceiveStats, } from "./client.js";
|
|
13
|
-
export { dexEventsFromShredWasmTx, dexEventsFromShredWasmTxWithFullKeys, type ShredWasmTx, type ShredWasmCompiledIx, } from "./instruction_parse.js";
|
|
13
|
+
export { dexEventsFromShredWasmTx, dexEventsFromShredWasmTxBestEffort, dexEventsFromShredWasmTxWithLoadedAddresses, dexEventsFromShredWasmTxWithFullKeys, type ShredWasmTx, type ShredWasmCompiledIx, } from "./instruction_parse.js";
|
|
14
14
|
export { fullAccountKeyStringsFromShredTx, loadAddressLookupTableAccounts } from "./alt_lookup.js";
|
|
15
15
|
export type { SubscribeEntriesRequest, ShredstreamEntryMessage } from "./proto_types.js";
|
|
16
16
|
export { bincodeVecEntryCount, decodeEntriesBincodeFlat, decodeEntriesBincodeNested, decodeShredstreamEntriesBincode, type DecodedWireTransaction, } from "./entries_decode.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AddressLookupTableCache = exports.wireBytesToShredWasmTx = exports.decodeShredstreamEntriesBincode = exports.decodeEntriesBincodeNested = exports.decodeEntriesBincodeFlat = exports.bincodeVecEntryCount = exports.loadAddressLookupTableAccounts = exports.fullAccountKeyStringsFromShredTx = exports.dexEventsFromShredWasmTxWithFullKeys = exports.dexEventsFromShredWasmTx = exports.ShredEventQueue = exports.ShredStreamClient = exports.highThroughputShredStreamConfig = exports.lowLatencyShredStreamConfig = exports.defaultShredStreamConfig = void 0;
|
|
3
|
+
exports.AddressLookupTableCache = exports.wireBytesToShredWasmTx = exports.decodeShredstreamEntriesBincode = exports.decodeEntriesBincodeNested = exports.decodeEntriesBincodeFlat = exports.bincodeVecEntryCount = exports.loadAddressLookupTableAccounts = exports.fullAccountKeyStringsFromShredTx = exports.dexEventsFromShredWasmTxWithFullKeys = exports.dexEventsFromShredWasmTxWithLoadedAddresses = exports.dexEventsFromShredWasmTxBestEffort = exports.dexEventsFromShredWasmTx = exports.ShredEventQueue = exports.ShredStreamClient = exports.highThroughputShredStreamConfig = exports.lowLatencyShredStreamConfig = exports.defaultShredStreamConfig = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Jito ShredStream 超低延迟订阅(与 Rust `sol-parser-sdk::shredstream` 对齐)。
|
|
6
6
|
*
|
|
@@ -8,7 +8,7 @@ exports.AddressLookupTableCache = exports.wireBytesToShredWasmTx = exports.decod
|
|
|
8
8
|
* - ALT 仅使用预热缓存;启用缓存后 miss 会跳过该交易并记录 altCacheMissTransactions,不回放
|
|
9
9
|
* - 无 inner instructions,无法 CPI 解析
|
|
10
10
|
* - 无 block_time
|
|
11
|
-
* - 无交易日志(program logs);客户端使用外层指令解析。未配置 ALT
|
|
11
|
+
* - 无交易日志(program logs);客户端使用外层指令解析。未配置 ALT 缓存时仅解析账户完整的静态指令。
|
|
12
12
|
* - `metadata.tx_index` 为**单条 gRPC `Entry` 消息内**跨所有 Solana `Entry` 分组的连续下标(与 golang `shredstream_entries` 扁平 `ti` 对齐),非 slot 级全局序号
|
|
13
13
|
*/
|
|
14
14
|
var config_js_1 = require("./config.js");
|
|
@@ -20,6 +20,8 @@ Object.defineProperty(exports, "ShredStreamClient", { enumerable: true, get: fun
|
|
|
20
20
|
Object.defineProperty(exports, "ShredEventQueue", { enumerable: true, get: function () { return client_js_1.ShredEventQueue; } });
|
|
21
21
|
var instruction_parse_js_1 = require("./instruction_parse.js");
|
|
22
22
|
Object.defineProperty(exports, "dexEventsFromShredWasmTx", { enumerable: true, get: function () { return instruction_parse_js_1.dexEventsFromShredWasmTx; } });
|
|
23
|
+
Object.defineProperty(exports, "dexEventsFromShredWasmTxBestEffort", { enumerable: true, get: function () { return instruction_parse_js_1.dexEventsFromShredWasmTxBestEffort; } });
|
|
24
|
+
Object.defineProperty(exports, "dexEventsFromShredWasmTxWithLoadedAddresses", { enumerable: true, get: function () { return instruction_parse_js_1.dexEventsFromShredWasmTxWithLoadedAddresses; } });
|
|
23
25
|
Object.defineProperty(exports, "dexEventsFromShredWasmTxWithFullKeys", { enumerable: true, get: function () { return instruction_parse_js_1.dexEventsFromShredWasmTxWithFullKeys; } });
|
|
24
26
|
var alt_lookup_js_1 = require("./alt_lookup.js");
|
|
25
27
|
Object.defineProperty(exports, "fullAccountKeyStringsFromShredTx", { enumerable: true, get: function () { return alt_lookup_js_1.fullAccountKeyStringsFromShredTx; } });
|
|
@@ -26,9 +26,11 @@ export type ShredWasmTx = {
|
|
|
26
26
|
recentBlockhash?: Uint8Array;
|
|
27
27
|
addressTableLookups?: ShredAddressTableLookup[];
|
|
28
28
|
};
|
|
29
|
-
/**
|
|
30
|
-
* 使用已解析的完整账户表(静态+ALT)解析外层指令。
|
|
31
|
-
*/
|
|
32
|
-
export declare function dexEventsFromShredWasmTxWithFullKeys(tx: ShredWasmTx, fullAccountKeys: string[], slot: number | bigint | string, txIndex: number | bigint | string, grpcRecvUs: number | bigint | string, eventTypeFilter?: EventTypeFilter): DexEvent[];
|
|
33
|
-
/** 仅静态账户表(无 RPC 时;V0+ALT 缺失账户以默认 pubkey 占位) */
|
|
29
|
+
/** 仅静态账户表(无 RPC;跳过未解析账户的指令) */
|
|
34
30
|
export declare function dexEventsFromShredWasmTx(tx: ShredWasmTx, slot: number | bigint | string, txIndex: number | bigint | string, grpcRecvUs: number | bigint | string, eventTypeFilter?: EventTypeFilter): DexEvent[];
|
|
31
|
+
/** Full-key entry point rejects inconsistent ALT counts and indices before emitting anything. */
|
|
32
|
+
export declare function dexEventsFromShredWasmTxWithFullKeys(tx: ShredWasmTx, keys: string[], slot: number | bigint | string, txIndex: number | bigint | string, recvUs: number | bigint | string, filter?: EventTypeFilter): DexEvent[];
|
|
33
|
+
/** Explicit legacy placeholder/discriminator fallback; route adapters always require resolved keys. */
|
|
34
|
+
export declare function dexEventsFromShredWasmTxBestEffort(tx: ShredWasmTx, slot: number | bigint | string, txIndex: number | bigint | string, recvUs: number | bigint | string, filter?: EventTypeFilter): DexEvent[];
|
|
35
|
+
/** Separate writable/readonly validation avoids ambiguous counts between the two classes. */
|
|
36
|
+
export declare function dexEventsFromShredWasmTxWithLoadedAddresses(tx: ShredWasmTx, writable: readonly string[], readonly: readonly string[], slot: number | bigint | string, txIndex: number | bigint | string, recvUs: number | bigint | string, filter?: EventTypeFilter): DexEvent[];
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dexEventsFromShredWasmTxWithFullKeys = dexEventsFromShredWasmTxWithFullKeys;
|
|
4
6
|
exports.dexEventsFromShredWasmTx = dexEventsFromShredWasmTx;
|
|
7
|
+
exports.dexEventsFromShredWasmTxWithFullKeys = dexEventsFromShredWasmTxWithFullKeys;
|
|
8
|
+
exports.dexEventsFromShredWasmTxBestEffort = dexEventsFromShredWasmTxBestEffort;
|
|
9
|
+
exports.dexEventsFromShredWasmTxWithLoadedAddresses = dexEventsFromShredWasmTxWithLoadedAddresses;
|
|
10
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
11
|
+
const metadata_js_1 = require("../core/metadata.js");
|
|
12
|
+
const pump_routes_js_1 = require("../instr/pump_routes.js");
|
|
5
13
|
const dex_event_js_1 = require("../core/dex_event.js");
|
|
6
14
|
const pumpfun_fee_enrich_js_1 = require("../core/pumpfun_fee_enrich.js");
|
|
7
15
|
const types_js_1 = require("../grpc/types.js");
|
|
@@ -42,19 +50,32 @@ function ixAccountStrings(fullAccountKeys, accBytes) {
|
|
|
42
50
|
/**
|
|
43
51
|
* 使用已解析的完整账户表(静态+ALT)解析外层指令。
|
|
44
52
|
*/
|
|
45
|
-
function
|
|
53
|
+
function parseShredKeys(tx, fullAccountKeys, slot, txIndex, grpcRecvUs, eventTypeFilter, bestEffort = false) {
|
|
46
54
|
const ixs = tx.instructions;
|
|
47
55
|
if (!ixs?.length || fullAccountKeys.length === 0)
|
|
48
56
|
return [];
|
|
49
57
|
if (!shouldParseShredInstructions(eventTypeFilter))
|
|
50
58
|
return [];
|
|
51
59
|
const out = [];
|
|
52
|
-
for (const rawIx of ixs) {
|
|
60
|
+
for (const [instructionIndex, rawIx] of ixs.entries()) {
|
|
53
61
|
const pidIdx = rawIx.programIdIndex;
|
|
54
|
-
if (!Number.
|
|
62
|
+
if (!Number.isInteger(pidIdx) || pidIdx < 0)
|
|
55
63
|
continue;
|
|
56
64
|
const accBytes = asU8(rawIx.accounts);
|
|
57
65
|
const data = asU8(rawIx.data);
|
|
66
|
+
const resolved = pidIdx < fullAccountKeys.length && accBytes.every(i => i < fullAccountKeys.length);
|
|
67
|
+
if (!resolved && !bestEffort)
|
|
68
|
+
continue;
|
|
69
|
+
const pid = fullAccountKeys[pidIdx];
|
|
70
|
+
if (pid && (0, pump_routes_js_1.mayParsePumpRoute)(pid, data)) {
|
|
71
|
+
if (resolved && (0, pump_routes_js_1.allowsPumpRoute)(eventTypeFilter, pid)) {
|
|
72
|
+
const metadata = (0, metadata_js_1.makeMetadata)(tx.signature, slot, txIndex, undefined, grpcRecvUs);
|
|
73
|
+
const intent = (0, pump_routes_js_1.parsePumpRoute)(pid, data, Array.from(accBytes, i => fullAccountKeys[i]), metadata, instructionIndex, eventTypeFilter);
|
|
74
|
+
if (intent)
|
|
75
|
+
out.push({ PumpRouteIntent: intent });
|
|
76
|
+
}
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
58
79
|
const accountStrs = ixAccountStrings(fullAccountKeys, accBytes);
|
|
59
80
|
if (pidIdx >= fullAccountKeys.length) {
|
|
60
81
|
for (const programId of UNKNOWN_PROGRAM_CANDIDATES) {
|
|
@@ -71,10 +92,37 @@ function dexEventsFromShredWasmTxWithFullKeys(tx, fullAccountKeys, slot, txIndex
|
|
|
71
92
|
if (ev)
|
|
72
93
|
out.push(ev);
|
|
73
94
|
}
|
|
95
|
+
if (tx.recentBlockhash && out.length) {
|
|
96
|
+
const recentBlockhash = bs58_1.default.encode(tx.recentBlockhash);
|
|
97
|
+
for (const event of out) {
|
|
98
|
+
const metadata = (0, dex_event_js_1.metadataForDexEvent)(event);
|
|
99
|
+
if (metadata)
|
|
100
|
+
metadata.recent_blockhash = recentBlockhash;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
74
103
|
(0, pumpfun_fee_enrich_js_1.enrichPumpfunSameTxPostMerge)(out);
|
|
75
104
|
return out;
|
|
76
105
|
}
|
|
77
|
-
/** 仅静态账户表(无 RPC
|
|
106
|
+
/** 仅静态账户表(无 RPC;跳过未解析账户的指令) */
|
|
78
107
|
function dexEventsFromShredWasmTx(tx, slot, txIndex, grpcRecvUs, eventTypeFilter) {
|
|
79
|
-
return
|
|
108
|
+
return parseShredKeys(tx, tx.accounts, slot, txIndex, grpcRecvUs, eventTypeFilter);
|
|
109
|
+
}
|
|
110
|
+
/** Full-key entry point rejects inconsistent ALT counts and indices before emitting anything. */
|
|
111
|
+
function dexEventsFromShredWasmTxWithFullKeys(tx, keys, slot, txIndex, recvUs, filter) {
|
|
112
|
+
const loaded = (tx.addressTableLookups ?? []).reduce((n, l) => n + l.writableIndexes.length + l.readonlyIndexes.length, 0);
|
|
113
|
+
if (keys.length !== tx.accounts.length + loaded || tx.accounts.some((k, i) => keys[i] !== k)
|
|
114
|
+
|| tx.instructions?.some(ix => !Number.isInteger(ix.programIdIndex) || ix.programIdIndex < 0 || ix.programIdIndex >= keys.length || ix.accounts.some(i => i >= keys.length)))
|
|
115
|
+
throw new RangeError('Inconsistent ALT keys or instruction index');
|
|
116
|
+
return parseShredKeys(tx, keys, slot, txIndex, recvUs, filter);
|
|
117
|
+
}
|
|
118
|
+
/** Explicit legacy placeholder/discriminator fallback; route adapters always require resolved keys. */
|
|
119
|
+
function dexEventsFromShredWasmTxBestEffort(tx, slot, txIndex, recvUs, filter) {
|
|
120
|
+
return parseShredKeys(tx, tx.accounts, slot, txIndex, recvUs, filter, true);
|
|
121
|
+
}
|
|
122
|
+
/** Separate writable/readonly validation avoids ambiguous counts between the two classes. */
|
|
123
|
+
function dexEventsFromShredWasmTxWithLoadedAddresses(tx, writable, readonly, slot, txIndex, recvUs, filter) {
|
|
124
|
+
const lookups = tx.addressTableLookups ?? [];
|
|
125
|
+
if (writable.length !== lookups.reduce((n, l) => n + l.writableIndexes.length, 0) || readonly.length !== lookups.reduce((n, l) => n + l.readonlyIndexes.length, 0))
|
|
126
|
+
throw new RangeError('ALT address counts do not match transaction');
|
|
127
|
+
return dexEventsFromShredWasmTxWithFullKeys(tx, [...tx.accounts, ...writable, ...readonly], slot, txIndex, recvUs, filter);
|
|
80
128
|
}
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.wireBytesToShredWasmTx = wireBytesToShredWasmTx;
|
|
7
4
|
/** Native wire decoding shared with RPC routes, including V1 without ALT. */
|
|
8
|
-
const bs58_1 = __importDefault(require("bs58"));
|
|
9
5
|
const wire_transaction_js_1 = require("../wire_transaction.js");
|
|
10
6
|
function wireBytesToShredWasmTx(raw) {
|
|
11
7
|
try {
|
|
12
|
-
const { transaction: tx } = (0, wire_transaction_js_1.
|
|
8
|
+
const { transaction: tx } = (0, wire_transaction_js_1.decodeWireTransactionBytes)(raw), msg = tx.message;
|
|
13
9
|
if (!tx.signatures[0])
|
|
14
10
|
return null;
|
|
15
11
|
return { signature: tx.signatures[0], accounts: msg.accountKeys,
|
|
16
|
-
instructions: msg.instructions.map(ix => ({ programIdIndex: ix.programIdIndex, accounts: Uint8Array.from(ix.accounts), data:
|
|
12
|
+
instructions: msg.instructions.map(ix => ({ programIdIndex: ix.programIdIndex, accounts: Uint8Array.from(ix.accounts), data: ix.data })),
|
|
17
13
|
messageVersion: tx.version === 'legacy' ? 'legacy' : tx.version === 0 ? 'v0' : 'v1', header: msg.header,
|
|
18
|
-
recentBlockhash:
|
|
14
|
+
recentBlockhash: msg.recentBlockhash,
|
|
19
15
|
addressTableLookups: msg.addressTableLookups.map(l => ({ ...l, writableIndexes: Uint8Array.from(l.writableIndexes), readonlyIndexes: Uint8Array.from(l.readonlyIndexes) })) };
|
|
20
16
|
}
|
|
21
17
|
catch {
|
|
@@ -29,7 +29,24 @@ export interface DecodedWireTransaction {
|
|
|
29
29
|
message: WireMessage;
|
|
30
30
|
version: "legacy" | 0 | 1;
|
|
31
31
|
}
|
|
32
|
+
type DecodedInstruction<T> = Omit<WireInstruction, "data"> & {
|
|
33
|
+
data: T;
|
|
34
|
+
};
|
|
35
|
+
type DecodedMessage<T> = Omit<WireMessage, "recentBlockhash" | "instructions"> & {
|
|
36
|
+
recentBlockhash: T;
|
|
37
|
+
instructions: DecodedInstruction<T>[];
|
|
38
|
+
};
|
|
39
|
+
type DecodedTransaction<T> = Omit<DecodedWireTransaction, "message"> & {
|
|
40
|
+
message: DecodedMessage<T>;
|
|
41
|
+
};
|
|
42
|
+
/** Public string representation retained for RPC/log consumers. */
|
|
32
43
|
export declare function decodeWireTransaction(data: Uint8Array, offset?: number, requireComplete?: boolean): {
|
|
33
44
|
transaction: DecodedWireTransaction;
|
|
34
45
|
length: number;
|
|
35
46
|
};
|
|
47
|
+
/** Internal Shred adapter path avoids Base58 round trips; returned payload bytes are owned copies. */
|
|
48
|
+
export declare function decodeWireTransactionBytes(data: Uint8Array, offset?: number, requireComplete?: boolean): {
|
|
49
|
+
transaction: DecodedTransaction<Uint8Array>;
|
|
50
|
+
length: number;
|
|
51
|
+
};
|
|
52
|
+
export {};
|
package/dist/wire_transaction.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.decodeWireTransaction = decodeWireTransaction;
|
|
7
|
+
exports.decodeWireTransactionBytes = decodeWireTransactionBytes;
|
|
7
8
|
/** Native canonical Solana Legacy, V0 and V1 decoder; no Rust runtime. */
|
|
8
9
|
const bs58_1 = __importDefault(require("bs58"));
|
|
9
10
|
class Reader {
|
|
@@ -16,7 +17,8 @@ class Reader {
|
|
|
16
17
|
take(n) {
|
|
17
18
|
if (!Number.isSafeInteger(n) || n < 0 || this.pos + n > this.data.length)
|
|
18
19
|
throw new Error("Truncated transaction");
|
|
19
|
-
|
|
20
|
+
// Views stay internal; public text output encodes synchronously and binary output copies.
|
|
21
|
+
const value = this.data.subarray(this.pos, this.pos + n);
|
|
20
22
|
this.pos += n;
|
|
21
23
|
return value;
|
|
22
24
|
}
|
|
@@ -50,7 +52,7 @@ class Reader {
|
|
|
50
52
|
throw new Error("Invalid short-u16");
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
|
-
function
|
|
55
|
+
function decodeWireTransactionInternal(encode, data, offset = 0, requireComplete = true) {
|
|
54
56
|
if (!Number.isInteger(offset) || offset < 0 || offset >= data.length)
|
|
55
57
|
throw new Error("Invalid wire offset");
|
|
56
58
|
const r = new Reader(data, offset);
|
|
@@ -92,7 +94,7 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
92
94
|
instructions = headers.map(([programIdIndex, n, length]) => ({
|
|
93
95
|
programIdIndex,
|
|
94
96
|
accounts: Array.from(r.take(n)),
|
|
95
|
-
data:
|
|
97
|
+
data: encode(r.take(length)),
|
|
96
98
|
}));
|
|
97
99
|
signatures = Array.from({ length: header[0] }, () => r.take(64));
|
|
98
100
|
if (r.pos - offset > 4096)
|
|
@@ -125,7 +127,7 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
125
127
|
instructions.push({
|
|
126
128
|
programIdIndex,
|
|
127
129
|
accounts,
|
|
128
|
-
data:
|
|
130
|
+
data: encode(payload),
|
|
129
131
|
});
|
|
130
132
|
}
|
|
131
133
|
if (version === 0) {
|
|
@@ -148,8 +150,9 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
148
150
|
header[1] >= header[0] ||
|
|
149
151
|
header[2] > keys.length - header[0])
|
|
150
152
|
throw new Error("Invalid message header");
|
|
153
|
+
const accountKeys = keys.map((k) => bs58_1.default.encode(k));
|
|
151
154
|
if (version === 1) {
|
|
152
|
-
if (new Set(
|
|
155
|
+
if (new Set(accountKeys).size !== keys.length)
|
|
153
156
|
throw new Error("Duplicate V1 accounts");
|
|
154
157
|
}
|
|
155
158
|
let accountCount = keys.length;
|
|
@@ -162,7 +165,9 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
162
165
|
if (accountCount > 256)
|
|
163
166
|
throw new Error("Too many resolved account keys");
|
|
164
167
|
for (const ix of instructions)
|
|
165
|
-
if (ix.programIdIndex === 0 ||
|
|
168
|
+
if (ix.programIdIndex === 0 ||
|
|
169
|
+
ix.programIdIndex >= keys.length ||
|
|
170
|
+
ix.accounts.some((i) => i >= accountCount))
|
|
166
171
|
throw new Error("Invalid instruction index");
|
|
167
172
|
if (requireComplete && r.pos !== data.length)
|
|
168
173
|
throw new Error("Trailing transaction bytes");
|
|
@@ -172,13 +177,12 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
172
177
|
numReadonlySignedAccounts: header[1],
|
|
173
178
|
numReadonlyUnsignedAccounts: header[2],
|
|
174
179
|
},
|
|
175
|
-
accountKeys
|
|
176
|
-
recentBlockhash:
|
|
180
|
+
accountKeys,
|
|
181
|
+
recentBlockhash: encode(hash),
|
|
177
182
|
instructions,
|
|
178
183
|
addressTableLookups: lookups,
|
|
184
|
+
...(config ? { config } : {}),
|
|
179
185
|
};
|
|
180
|
-
if (config)
|
|
181
|
-
message.config = config;
|
|
182
186
|
return {
|
|
183
187
|
transaction: {
|
|
184
188
|
signatures: signatures.map((s) => bs58_1.default.encode(s)),
|
|
@@ -188,3 +192,11 @@ function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
|
188
192
|
length: r.pos - offset,
|
|
189
193
|
};
|
|
190
194
|
}
|
|
195
|
+
/** Public string representation retained for RPC/log consumers. */
|
|
196
|
+
function decodeWireTransaction(data, offset = 0, requireComplete = true) {
|
|
197
|
+
return decodeWireTransactionInternal(bs58_1.default.encode, data, offset, requireComplete);
|
|
198
|
+
}
|
|
199
|
+
/** Internal Shred adapter path avoids Base58 round trips; returned payload bytes are owned copies. */
|
|
200
|
+
function decodeWireTransactionBytes(data, offset = 0, requireComplete = true) {
|
|
201
|
+
return decodeWireTransactionInternal((bytes) => Uint8Array.from(bytes), data, offset, requireComplete);
|
|
202
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sol-parser-sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.20",
|
|
4
4
|
"description": "High-performance Solana DEX event parser for Node.js/TypeScript (Yellowstone gRPC, log parsing)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
"example:shredstream:subscribe": "tsx examples/shredstream_example.ts",
|
|
39
39
|
"example:shredstream:pumpfun-json": "tsx examples/shredstream_pumpfun_json.ts",
|
|
40
40
|
"example:shredstream": "tsx examples/shredstream_example.ts",
|
|
41
|
-
"example:shredstream:pumpfun": "tsx examples/shredstream_pumpfun_json.ts"
|
|
41
|
+
"example:shredstream:pumpfun": "tsx examples/shredstream_pumpfun_json.ts",
|
|
42
|
+
"example:pump:replay": "tsx examples/pump_shred_routes.ts",
|
|
43
|
+
"example:pump:bank": "tsx examples/pump_offline_bank.ts",
|
|
44
|
+
"check:pump-examples": "tsc --noEmit --target ES2022 --module NodeNext --moduleResolution NodeNext --strict --esModuleInterop --skipLibCheck examples/pump_shred_routes.ts examples/pump_offline_bank.ts examples/hotpath_benchmark.ts"
|
|
42
45
|
},
|
|
43
46
|
"keywords": [
|
|
44
47
|
"solana",
|
|
@@ -49,8 +52,10 @@
|
|
|
49
52
|
],
|
|
50
53
|
"license": "MIT",
|
|
51
54
|
"devDependencies": {
|
|
55
|
+
"@solana/kit": "8.5.0",
|
|
52
56
|
"@types/node": "^22.19.17",
|
|
53
57
|
"dotenv": "^17.4.1",
|
|
58
|
+
"litesvm": "1.6.0",
|
|
54
59
|
"tsx": "^4.21.0",
|
|
55
60
|
"typescript": "^5.6.3",
|
|
56
61
|
"vitest": "^2.1.9"
|