sol-parser-sdk 0.5.15 → 0.5.16
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/NATIVE_ALIGNMENT.md +312 -0
- package/NATIVE_DAMM_FACTORY_ALIGNMENT_20261004.md +16 -0
- package/NATIVE_DAMM_FACTORY_EVIDENCE_20261004.json +55 -0
- package/NATIVE_MIGRATION.md +38 -0
- package/NATIVE_PUMPFUN_NATIVE_DEBIT_ALIGNMENT_20261004.md +18 -0
- package/NATIVE_PUMPFUN_NATIVE_DEBIT_EVIDENCE_20261004.json +57 -0
- package/NATIVE_PUMPFUN_SETTLEMENT_ALIGNMENT_20261004.md +11 -0
- package/NATIVE_PUMPFUN_SETTLEMENT_EVIDENCE_20261004.json +70 -0
- package/README.md +17 -1
- package/README_CN.md +14 -1
- package/dist/accounts/mod.js +7 -0
- package/dist/core/account_dispatcher_rpc.js +24 -4
- package/dist/core/account_fill_raydium.js +12 -2
- package/dist/core/account_fill_raydium_launchlab.js +6 -0
- package/dist/core/clock.js +1 -1
- package/dist/core/dex_event.d.ts +30 -0
- package/dist/core/metadata.d.ts +9 -5
- package/dist/core/metadata.js +28 -4
- package/dist/core/unified_parser.d.ts +7 -7
- package/dist/grpc/block_meta.d.ts +9 -0
- package/dist/grpc/block_meta.js +26 -0
- package/dist/grpc/client.d.ts +24 -9
- package/dist/grpc/client.js +129 -67
- package/dist/grpc/geyser_connect.d.ts +3 -3
- package/dist/grpc/geyser_connect.js +13 -15
- package/dist/grpc/native_client.d.ts +26 -0
- package/dist/grpc/native_client.js +101 -0
- package/dist/grpc/order_buffer.d.ts +1 -1
- package/dist/grpc/order_buffer.js +10 -9
- package/dist/grpc/program_ids.js +2 -0
- package/dist/grpc/protocol/LICENSE +202 -0
- package/dist/grpc/protocol/NOTICE +4 -0
- package/dist/grpc/protocol/geyser.d.ts +342 -0
- package/dist/grpc/protocol/geyser.js +37 -0
- package/dist/grpc/protocol/geyser.proto +326 -0
- package/dist/grpc/protocol/solana-storage.d.ts +139 -0
- package/dist/grpc/protocol/solana-storage.js +14 -0
- package/dist/grpc/protocol/solana-storage.proto +151 -0
- package/dist/grpc/rpc_to_grpc.d.ts +1 -1
- package/dist/grpc/subscribe_builder.d.ts +5 -3
- package/dist/grpc/subscribe_builder.js +11 -3
- package/dist/grpc/transaction_meta.d.ts +1 -1
- package/dist/grpc/types.d.ts +8 -8
- package/dist/grpc/types.js +7 -2
- package/dist/grpc/yellowstone_parse.d.ts +3 -3
- package/dist/grpc/yellowstone_parse.js +6 -8
- package/dist/grpc/yellowstone_transaction_adapter.d.ts +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +23 -5
- package/dist/instr/inner.d.ts +2 -2
- package/dist/instr/inner.js +1 -1
- package/dist/instr/meteora_damm_ix.d.ts +1 -1
- package/dist/instr/meteora_dlmm_ix.d.ts +1 -1
- package/dist/instr/meteora_pools_ix.d.ts +1 -1
- package/dist/instr/mod.d.ts +1 -1
- package/dist/instr/orca_whirlpool_ix.d.ts +1 -1
- package/dist/instr/pump_fees_ix.d.ts +1 -1
- package/dist/instr/pumpfun_ix.d.ts +1 -1
- package/dist/instr/pumpswap_ix.d.ts +1 -1
- package/dist/instr/raydium_amm_v4_ix.d.ts +1 -1
- package/dist/instr/raydium_amm_v4_ix.js +9 -5
- package/dist/instr/raydium_clmm_ix.d.ts +1 -1
- package/dist/instr/raydium_cpmm_ix.d.ts +1 -1
- package/dist/instr/raydium_launchlab_ix.d.ts +1 -1
- package/dist/instr/raydium_launchlab_ix.js +62 -2
- package/dist/instr/utils.d.ts +2 -2
- package/dist/instr/utils.js +2 -7
- package/dist/liquidity_snapshot.d.ts +54 -0
- package/dist/liquidity_snapshot.js +85 -0
- package/dist/logs/meteora_damm.d.ts +1 -1
- package/dist/logs/meteora_damm.js +4 -2
- package/dist/logs/meteora_dlmm.d.ts +1 -1
- package/dist/logs/optimized_matcher.d.ts +3 -3
- package/dist/logs/raydium_launchlab.js +19 -1
- package/dist/rpc_transaction.d.ts +4 -3
- package/dist/rpc_transaction.js +3 -2
- package/dist/shredstream/client.js +3 -7
- package/dist/shredstream/entries_decode.js +9 -85
- package/dist/shredstream/instruction_parse.d.ts +3 -3
- package/dist/shredstream/proto_types.d.ts +1 -1
- package/dist/shredstream/wire_to_shred_tx.d.ts +1 -1
- package/dist/shredstream/wire_to_shred_tx.js +9 -44
- package/dist/simulation_route.d.ts +6 -0
- package/dist/simulation_route.js +242 -0
- package/dist/stonkfun_registry.d.ts +30 -0
- package/dist/stonkfun_registry.js +137 -0
- package/dist/transaction_route.d.ts +84 -0
- package/dist/transaction_route.js +477 -0
- package/dist/wire_transaction.d.ts +35 -0
- package/dist/wire_transaction.js +191 -0
- package/package.json +7 -4
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"date": "2026-10-04",
|
|
3
|
+
"overall_alignment_complete": false,
|
|
4
|
+
"broadcasts": 0,
|
|
5
|
+
"hot_path_rpc_calls": 0,
|
|
6
|
+
"rust_baseline": {
|
|
7
|
+
"trade": "5.0.6",
|
|
8
|
+
"parser": "0.7.7"
|
|
9
|
+
},
|
|
10
|
+
"current_pumpfun_fee_oracle": {
|
|
11
|
+
"package": "@pump-fun/pump-sdk",
|
|
12
|
+
"version": "2.0.0",
|
|
13
|
+
"vectors_per_language": 240,
|
|
14
|
+
"runtime_dependency": false
|
|
15
|
+
},
|
|
16
|
+
"simulations": {
|
|
17
|
+
"direct_sol": {
|
|
18
|
+
"wire_bytes": 1044,
|
|
19
|
+
"err": null,
|
|
20
|
+
"evidence": "examples/fixtures/pumpfun_direct_sol_simulations_20261004.json"
|
|
21
|
+
},
|
|
22
|
+
"funded_wsol": {
|
|
23
|
+
"wire_bytes": 1238,
|
|
24
|
+
"wire_sha256": "76b18c71a930080a4c937483ed1ab670e7ade2188cfef6cf1d00ec8a1538adfd",
|
|
25
|
+
"err": null,
|
|
26
|
+
"actual_wsol_debit": "10000",
|
|
27
|
+
"verified_asset_payment": true,
|
|
28
|
+
"evidence": "examples/fixtures/pumpfun_settled_funded_wsol_evidence_20261004.json",
|
|
29
|
+
"cross_language_wire_match": [
|
|
30
|
+
"go",
|
|
31
|
+
"nodejs",
|
|
32
|
+
"python"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"verification": {
|
|
37
|
+
"full_suites_before_final_added_regressions": {
|
|
38
|
+
"trade_nodejs": 3326,
|
|
39
|
+
"parser_nodejs": 213,
|
|
40
|
+
"parser_nodejs_skipped": 8,
|
|
41
|
+
"trade_python": 3406,
|
|
42
|
+
"parser_python": 199,
|
|
43
|
+
"go_trade": "go test ./... passed",
|
|
44
|
+
"go_parser": "go test ./... passed"
|
|
45
|
+
},
|
|
46
|
+
"final_targeted": {
|
|
47
|
+
"trade_nodejs": 8,
|
|
48
|
+
"trade_python": 12,
|
|
49
|
+
"parser_nodejs_simulation": 47,
|
|
50
|
+
"parser_python_simulation": 49,
|
|
51
|
+
"go_parser_failed_intent_and_mainnet_corpus": "passed"
|
|
52
|
+
},
|
|
53
|
+
"go_vet": "both passed",
|
|
54
|
+
"go_race": "both full suites passed",
|
|
55
|
+
"node_trade_types_and_build": "passed",
|
|
56
|
+
"node_trade_example_types": "passed",
|
|
57
|
+
"node_parser_types": "passed",
|
|
58
|
+
"installed_wheel_verified_wire": "passed",
|
|
59
|
+
"installed_npm_public_api_verified_wire": "passed",
|
|
60
|
+
"six_repo_diff_check": "passed"
|
|
61
|
+
},
|
|
62
|
+
"not_verified": [
|
|
63
|
+
"current PumpFun funded sell simulation",
|
|
64
|
+
"native-quote PumpFun multi-hop settlement (explicitly rejected)",
|
|
65
|
+
"non-native USDC/stock PumpFun mainnet simulations",
|
|
66
|
+
"legacy low-level builder current-chain compatibility",
|
|
67
|
+
"SWQOS online V1 broadcast compatibility",
|
|
68
|
+
"full Rust public API/field alignment matrix and remaining lifecycle acceptance"
|
|
69
|
+
]
|
|
70
|
+
}
|
package/README.md
CHANGED
|
@@ -44,6 +44,12 @@
|
|
|
44
44
|
|
|
45
45
|
## Release notes
|
|
46
46
|
|
|
47
|
+
### v0.5.16
|
|
48
|
+
|
|
49
|
+
- Adds native gRPC lifecycle and block metadata support, instruction-level route analysis and StonkFun registry/snapshot examples.
|
|
50
|
+
- Improves exact metadata serialization, account matching and wire transaction bounds validation.
|
|
51
|
+
- Includes native alignment evidence and simulation route fixtures. These language releases do not yet implement the new CPMM creator-fee collection event API.
|
|
52
|
+
|
|
47
53
|
### v0.5.15
|
|
48
54
|
|
|
49
55
|
- Syncs with Rust `sol-parser-sdk` **0.7.3**, including the current PumpFun, PumpSwap, Pump Fees, and Meteora DAMM v2 protocol surfaces.
|
|
@@ -90,7 +96,7 @@
|
|
|
90
96
|
**From npm**
|
|
91
97
|
|
|
92
98
|
```bash
|
|
93
|
-
npm install sol-parser-sdk@0.5.
|
|
99
|
+
npm install sol-parser-sdk@0.5.16
|
|
94
100
|
```
|
|
95
101
|
|
|
96
102
|
**From source** (folder may be named `sol-parser-sdk-ts` in a monorepo)
|
|
@@ -328,3 +334,13 @@ npm run check:migration # parity checks; needs build
|
|
|
328
334
|
## License
|
|
329
335
|
|
|
330
336
|
MIT — https://github.com/0xfnzero/sol-parser-sdk-nodejs
|
|
337
|
+
|
|
338
|
+
## Native alignment status
|
|
339
|
+
|
|
340
|
+
See [NATIVE_ALIGNMENT.md](NATIVE_ALIGNMENT.md) for implemented native APIs, Rust golden tests, mainnet simulation evidence, examples, and remaining parity gaps. Full cross-language parity is still in progress.
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
实时 parser → trade 接入使用 Yellowstone **gRPC**;见 [gRPC 缓存接入与三语言示例](examples/GRPC_CACHE.md)。此路径不使用 WebSocket,报价和构建热路径不调用 RPC。
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
[本轮原生对齐 API 迁移](NATIVE_MIGRATION.md)(实施中,尚未发布)。
|
package/README_CN.md
CHANGED
|
@@ -44,6 +44,12 @@
|
|
|
44
44
|
|
|
45
45
|
## 发布说明
|
|
46
46
|
|
|
47
|
+
### v0.5.16
|
|
48
|
+
|
|
49
|
+
- Adds native gRPC lifecycle and block metadata support, instruction-level route analysis and StonkFun registry/snapshot examples.
|
|
50
|
+
- Improves exact metadata serialization, account matching and wire transaction bounds validation.
|
|
51
|
+
- Includes native alignment evidence and simulation route fixtures. These language releases do not yet implement the new CPMM creator-fee collection event API.
|
|
52
|
+
|
|
47
53
|
### v0.5.15
|
|
48
54
|
|
|
49
55
|
- 对齐 Rust sol-parser-sdk **0.7.3**,覆盖当前 PumpFun、PumpSwap、Pump Fees 与 Meteora DAMM v2 协议字段。
|
|
@@ -90,7 +96,7 @@
|
|
|
90
96
|
**npm**
|
|
91
97
|
|
|
92
98
|
```bash
|
|
93
|
-
npm install sol-parser-sdk@0.5.
|
|
99
|
+
npm install sol-parser-sdk@0.5.16
|
|
94
100
|
```
|
|
95
101
|
|
|
96
102
|
**源码**(monorepo 里目录可能是 `sol-parser-sdk-ts`)
|
|
@@ -321,3 +327,10 @@ npm run check:migration # 对齐与校验,需先 build
|
|
|
321
327
|
## 许可证
|
|
322
328
|
|
|
323
329
|
MIT — https://github.com/0xfnzero/sol-parser-sdk-nodejs
|
|
330
|
+
|
|
331
|
+
## Native alignment status
|
|
332
|
+
|
|
333
|
+
See [NATIVE_ALIGNMENT.md](NATIVE_ALIGNMENT.md) for implemented native APIs, Rust golden tests, mainnet simulation evidence, examples, and remaining parity gaps. Full cross-language parity is still in progress.
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
[本轮原生对齐 API 迁移](NATIVE_MIGRATION.md)(实施中,尚未发布)。
|
package/dist/accounts/mod.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.rpcResolveUserWalletPubkey = exports.userWalletPubkeyForOnchainAccount = exports.hasDiscriminator = exports.isOrcaWhirlpoolsConfigAccount = exports.isOrcaFeeTierAccount = exports.isOrcaTickArrayAccount = exports.isOrcaPositionAccount = exports.isOrcaWhirlpoolAccount = exports.isRaydiumCpmmPoolStateAccount = exports.isRaydiumCpmmAmmConfigAccount = exports.isRaydiumClmmTickArrayStateAccount = exports.isRaydiumClmmPoolStateAccount = exports.isRaydiumClmmAmmConfigAccount = exports.parseOrcaWhirlpoolsConfig = exports.parseOrcaFeeTier = exports.parseOrcaTickArray = exports.parseOrcaPosition = exports.parseOrcaWhirlpool = exports.parseOrcaWhirlpoolAccount = exports.parseRaydiumCpmmPoolState = exports.parseRaydiumCpmmAmmConfig = exports.parseRaydiumCpmmAccount = exports.parseRaydiumClmmTickArrayState = exports.parseRaydiumClmmPoolState = exports.parseRaydiumClmmAmmConfig = exports.parseRaydiumClmmAccount = exports.isPoolAccount = exports.isGlobalConfigAccount = exports.parsePumpswapAccount = exports.parsePumpswapPool = exports.parsePumpswapGlobalConfig = exports.isPumpfunUserVolumeAccumulatorAccount = exports.isPumpfunGlobalVolumeAccumulatorAccount = exports.isPumpfunSharingConfigAccount = exports.isPumpfunFeeConfigAccount = exports.isPumpfunBondingCurveAccount = exports.isPumpfunGlobalAccount = exports.parsePumpfunAccount = exports.parsePumpfunUserVolumeAccumulator = exports.parsePumpfunGlobalVolumeAccumulator = exports.parsePumpfunSharingConfig = exports.parsePumpfunFeeConfig = exports.parsePumpfunBondingCurve = exports.parsePumpfunGlobal = exports.parseTokenAccount = exports.isNonceAccount = exports.parseNonceAccount = void 0;
|
|
4
4
|
exports.parseAccountUnified = parseAccountUnified;
|
|
5
|
+
const liquidity_snapshot_js_1 = require("../liquidity_snapshot.js");
|
|
5
6
|
const types_js_1 = require("../grpc/types.js");
|
|
6
7
|
const program_ids_js_1 = require("../instr/program_ids.js");
|
|
7
8
|
const nonce_js_1 = require("./nonce.js");
|
|
@@ -86,6 +87,7 @@ const ACCOUNT_EVENT_TYPES = [
|
|
|
86
87
|
"AccountOrcaTickArray",
|
|
87
88
|
"AccountOrcaFeeTier",
|
|
88
89
|
"AccountOrcaWhirlpoolsConfig",
|
|
90
|
+
"AccountLiquiditySnapshot",
|
|
89
91
|
];
|
|
90
92
|
function filterParsedEvent(ev, eventTypeFilter) {
|
|
91
93
|
if (!ev || !eventTypeFilter)
|
|
@@ -101,6 +103,11 @@ function parseAccountUnified(account, metadata, eventTypeFilter) {
|
|
|
101
103
|
if (!shouldParse)
|
|
102
104
|
return null;
|
|
103
105
|
}
|
|
106
|
+
if (!eventTypeFilter || eventTypeFilter.shouldInclude('AccountLiquiditySnapshot')) {
|
|
107
|
+
const snapshot = (0, liquidity_snapshot_js_1.parseLiquidityAccount)(account, metadata);
|
|
108
|
+
if (snapshot)
|
|
109
|
+
return { LiquidityAccountSnapshot: snapshot };
|
|
110
|
+
}
|
|
104
111
|
if (account.owner === program_ids_js_1.PUMPSWAP_PROGRAM_ID) {
|
|
105
112
|
if (!eventTypeFilter ||
|
|
106
113
|
eventTypeFilter.shouldInclude("AccountPumpSwapGlobalConfig") ||
|
|
@@ -9,7 +9,27 @@ const account_fill_raydium_js_1 = require("./account_fill_raydium.js");
|
|
|
9
9
|
const account_fill_orca_js_1 = require("./account_fill_orca.js");
|
|
10
10
|
const account_fill_raydium_launchlab_js_1 = require("./account_fill_raydium_launchlab.js");
|
|
11
11
|
const account_fill_meteora_js_1 = require("./account_fill_meteora.js");
|
|
12
|
-
function tryFill(programId, programInvokes, message, meta, resolver, fn) {
|
|
12
|
+
function tryFill(programId, programInvokes, message, meta, resolver, fn, anchor, unambiguous = false) {
|
|
13
|
+
if (anchor || unambiguous) {
|
|
14
|
+
const hasAnchor = anchor && anchor.pool && anchor.pool !== "11111111111111111111111111111111";
|
|
15
|
+
if (!hasAnchor && !unambiguous)
|
|
16
|
+
return;
|
|
17
|
+
let selected = null;
|
|
18
|
+
for (const invocation of programInvokes.get(programId) ?? []) {
|
|
19
|
+
const candidate = (0, rpc_invoke_map_js_1.makeInvokeAccountGetter)(resolver, invocation, message, meta);
|
|
20
|
+
if (!candidate || (hasAnchor && candidate(anchor.index) !== anchor.pool))
|
|
21
|
+
continue;
|
|
22
|
+
// One pool can be traded by multiple users within the same transaction.
|
|
23
|
+
// Without an invocation position, keep missing context instead of guessing.
|
|
24
|
+
if (selected &&
|
|
25
|
+
Array.from({ length: 18 }, (_, i) => i).some((i) => selected(i) !== candidate(i)))
|
|
26
|
+
return;
|
|
27
|
+
selected = candidate;
|
|
28
|
+
}
|
|
29
|
+
if (selected)
|
|
30
|
+
fn(selected);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
13
33
|
const invoke = (0, rpc_invoke_map_js_1.findMaxAccountsInvoke)(programId, programInvokes, message, meta);
|
|
14
34
|
if (!invoke)
|
|
15
35
|
return;
|
|
@@ -93,7 +113,7 @@ function fillAccountsFromTransactionDataRpc(ev, message, meta, programInvokes, r
|
|
|
93
113
|
tryFill(program_ids_js_1.RAYDIUM_CPMM_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_js_1.fillRaydiumCpmmInitializeAccounts)(ev.RaydiumCpmmInitialize, g));
|
|
94
114
|
}
|
|
95
115
|
else if ("RaydiumAmmV4Swap" in ev) {
|
|
96
|
-
tryFill(program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_js_1.fillRaydiumAmmV4SwapAccounts)(ev.RaydiumAmmV4Swap, g));
|
|
116
|
+
tryFill(program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_js_1.fillRaydiumAmmV4SwapAccounts)(ev.RaydiumAmmV4Swap, g), { pool: ev.RaydiumAmmV4Swap.amm, index: 1 }, true);
|
|
97
117
|
}
|
|
98
118
|
else if ("RaydiumAmmV4Deposit" in ev) {
|
|
99
119
|
tryFill(program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_js_1.fillRaydiumAmmV4DepositAccounts)(ev.RaydiumAmmV4Deposit, g));
|
|
@@ -147,9 +167,9 @@ function fillAccountsFromTransactionDataRpc(ev, message, meta, programInvokes, r
|
|
|
147
167
|
tryFill(program_ids_js_1.METEORA_DLMM_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_meteora_js_1.fillMeteoraDlmmRemoveLiquidityAccounts)(ev.MeteoraDlmmRemoveLiquidity, g));
|
|
148
168
|
}
|
|
149
169
|
else if ("RaydiumLaunchlabTrade" in ev) {
|
|
150
|
-
tryFill(program_ids_js_1.RAYDIUM_LAUNCHLAB_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_launchlab_js_1.fillRaydiumLaunchlabTradeAccounts)(ev.RaydiumLaunchlabTrade, g));
|
|
170
|
+
tryFill(program_ids_js_1.RAYDIUM_LAUNCHLAB_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_launchlab_js_1.fillRaydiumLaunchlabTradeAccounts)(ev.RaydiumLaunchlabTrade, g), { pool: ev.RaydiumLaunchlabTrade.pool_state, index: 4 });
|
|
151
171
|
}
|
|
152
172
|
else if ("RaydiumLaunchlabPoolCreate" in ev) {
|
|
153
|
-
tryFill(program_ids_js_1.RAYDIUM_LAUNCHLAB_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_launchlab_js_1.fillRaydiumLaunchlabPoolCreateAccounts)(ev.RaydiumLaunchlabPoolCreate, g));
|
|
173
|
+
tryFill(program_ids_js_1.RAYDIUM_LAUNCHLAB_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_raydium_launchlab_js_1.fillRaydiumLaunchlabPoolCreateAccounts)(ev.RaydiumLaunchlabPoolCreate, g), { pool: ev.RaydiumLaunchlabPoolCreate.pool_state, index: 5 });
|
|
154
174
|
}
|
|
155
175
|
}
|
|
@@ -86,9 +86,19 @@ function fillRaydiumCpmmInitializeAccounts(e, get) {
|
|
|
86
86
|
e.pool = get(3);
|
|
87
87
|
}
|
|
88
88
|
function fillRaydiumAmmV4SwapAccounts(e, get) {
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
89
|
+
const empty = (v) => !v || v === Z();
|
|
90
|
+
if (empty(e.amm))
|
|
91
91
|
e.amm = get(1);
|
|
92
|
+
const modern = empty(get(8)) && !empty(get(7));
|
|
93
|
+
if (modern) {
|
|
94
|
+
for (const [field, index] of [['token_program', 0], ['amm_authority', 2], ['pool_coin_token_account', 3], ['pool_pc_token_account', 4], ['user_source_token_account', 5], ['user_destination_token_account', 6], ['user_source_owner', 7]]) {
|
|
95
|
+
if (empty(e[field]))
|
|
96
|
+
e[field] = get(index);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (empty(e.user_source_owner)) {
|
|
100
|
+
e.user_source_owner = empty(get(17)) ? get(16) : get(17);
|
|
101
|
+
}
|
|
92
102
|
}
|
|
93
103
|
function fillRaydiumAmmV4DepositAccounts(e, get) {
|
|
94
104
|
const zero = Z();
|
|
@@ -31,6 +31,12 @@ function fillRaydiumLaunchlabTradeAccounts(e, get) {
|
|
|
31
31
|
e.base_token_program = get(11);
|
|
32
32
|
if (!e.quote_token_program || e.quote_token_program === zero)
|
|
33
33
|
e.quote_token_program = get(12);
|
|
34
|
+
if (!e.system_program || e.system_program === zero)
|
|
35
|
+
e.system_program = get(15);
|
|
36
|
+
if (!e.platform_associated_account || e.platform_associated_account === zero)
|
|
37
|
+
e.platform_associated_account = get(16);
|
|
38
|
+
if (!e.creator_associated_account || e.creator_associated_account === zero)
|
|
39
|
+
e.creator_associated_account = get(17);
|
|
34
40
|
}
|
|
35
41
|
function fillRaydiumLaunchlabPoolCreateAccounts(e, get) {
|
|
36
42
|
const zero = Z();
|
package/dist/core/clock.js
CHANGED
|
@@ -12,7 +12,7 @@ function nowUs() {
|
|
|
12
12
|
exports.nowMicros = nowUs;
|
|
13
13
|
/** 与 Rust `now_nanos` 同语义:墙钟纳秒(`Date` 精度为毫秒,纳秒位为推算值) */
|
|
14
14
|
function nowNanos() {
|
|
15
|
-
return BigInt(
|
|
15
|
+
return BigInt(Date.now()) * 1000000n;
|
|
16
16
|
}
|
|
17
17
|
/** 与 Rust `elapsed_micros_since` 一致 */
|
|
18
18
|
function elapsedMicrosSince(startUs) {
|
package/dist/core/dex_event.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import type { RawAccountSnapshotEvent, LiquidityAccountSnapshotEvent } from '../liquidity_snapshot.js';
|
|
1
2
|
import type { EventMetadata } from "./metadata.js";
|
|
2
3
|
/** 统一 DEX 事件:外部标签 JSON(单键对象);键名清单见 `scripts/dex-event-variant-names.json` */
|
|
3
4
|
export type DexEvent = {
|
|
5
|
+
RawAccountSnapshot: RawAccountSnapshotEvent;
|
|
6
|
+
} | {
|
|
7
|
+
LiquidityAccountSnapshot: LiquidityAccountSnapshotEvent;
|
|
8
|
+
} | {
|
|
4
9
|
PumpFunCreate: PumpFunCreateTokenEvent;
|
|
5
10
|
} | {
|
|
6
11
|
PumpFunCreateV2: PumpFunCreateV2TokenEvent;
|
|
@@ -1353,6 +1358,21 @@ export interface RaydiumLaunchlabTradeEvent {
|
|
|
1353
1358
|
is_buy: boolean;
|
|
1354
1359
|
trade_direction: TradeDirection;
|
|
1355
1360
|
exact_in: boolean;
|
|
1361
|
+
total_base_sell?: bigint;
|
|
1362
|
+
virtual_base?: bigint;
|
|
1363
|
+
virtual_quote?: bigint;
|
|
1364
|
+
real_base_before?: bigint;
|
|
1365
|
+
real_quote_before?: bigint;
|
|
1366
|
+
real_base_after?: bigint;
|
|
1367
|
+
real_quote_after?: bigint;
|
|
1368
|
+
protocol_fee?: bigint;
|
|
1369
|
+
platform_fee?: bigint;
|
|
1370
|
+
creator_fee?: bigint;
|
|
1371
|
+
share_fee?: bigint;
|
|
1372
|
+
pool_status?: "Fund" | "Migrate" | "Trade";
|
|
1373
|
+
system_program?: string;
|
|
1374
|
+
platform_associated_account?: string;
|
|
1375
|
+
creator_associated_account?: string;
|
|
1356
1376
|
global_config?: string;
|
|
1357
1377
|
platform_config?: string;
|
|
1358
1378
|
user_base_token?: string;
|
|
@@ -1391,6 +1411,11 @@ export interface RaydiumLaunchlabMigrateAmmEvent {
|
|
|
1391
1411
|
new_pool: string;
|
|
1392
1412
|
user: string;
|
|
1393
1413
|
liquidity_amount: bigint;
|
|
1414
|
+
liquidity_amount_known?: boolean;
|
|
1415
|
+
base_mint?: string;
|
|
1416
|
+
quote_mint?: string;
|
|
1417
|
+
platform_config?: string;
|
|
1418
|
+
destination_program?: string;
|
|
1394
1419
|
}
|
|
1395
1420
|
export interface TokenInfoEvent {
|
|
1396
1421
|
metadata: EventMetadata;
|
|
@@ -1840,3 +1865,8 @@ export interface BlockMetaEvent {
|
|
|
1840
1865
|
}
|
|
1841
1866
|
export declare function metadataForDexEvent(ev: DexEvent): EventMetadata | null;
|
|
1842
1867
|
export declare function defaultPubkey(): string;
|
|
1868
|
+
/** Rust platform aliases share the existing LaunchLab event shape. */
|
|
1869
|
+
export type LaunchLabPoolCreateEvent = RaydiumLaunchlabPoolCreateEvent;
|
|
1870
|
+
export type StonkFunPoolCreateEvent = RaydiumLaunchlabPoolCreateEvent;
|
|
1871
|
+
export type LaunchLabTradeEvent = RaydiumLaunchlabTradeEvent;
|
|
1872
|
+
export type StonkFunTradeEvent = RaydiumLaunchlabTradeEvent;
|
package/dist/core/metadata.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/** 事件元数据(signature 为 Base58 字符串) */
|
|
2
2
|
export interface EventMetadata {
|
|
3
3
|
signature: string;
|
|
4
|
-
slot:
|
|
4
|
+
slot: bigint;
|
|
5
5
|
/** gRPC:与 Yellowstone `SubscribeUpdateTransactionInfo.index` 一致(Rust `info.index`)。Shred 等其它路径含义见各实现说明。 */
|
|
6
|
-
tx_index:
|
|
7
|
-
block_time_us:
|
|
8
|
-
grpc_recv_us:
|
|
6
|
+
tx_index: bigint;
|
|
7
|
+
block_time_us: bigint;
|
|
8
|
+
grpc_recv_us: bigint;
|
|
9
9
|
/** Time waiting in the local pre-parser queue, measured with a monotonic clock. */
|
|
10
10
|
local_queue_latency_us?: number;
|
|
11
11
|
/** Pure local adapter + parser duration. No network or RPC calls are included. */
|
|
@@ -16,4 +16,8 @@ export interface EventMetadata {
|
|
|
16
16
|
source_to_grpc_latency_us?: number;
|
|
17
17
|
recent_blockhash?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function makeMetadata(signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs: number, recentBlockhash?: string): EventMetadata;
|
|
19
|
+
export declare function makeMetadata(signature: string, slot: number | bigint | string, txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, grpcRecvUs: number | bigint | string, recentBlockhash?: string): EventMetadata;
|
|
20
|
+
export type ExactIntegerInput = bigint | string | number;
|
|
21
|
+
export declare function exactInteger(value: ExactIntegerInput, label?: string): bigint;
|
|
22
|
+
export declare function exactU64(value: ExactIntegerInput, label?: string): bigint;
|
|
23
|
+
export declare function exactI64(value: ExactIntegerInput, label?: string): bigint;
|
package/dist/core/metadata.js
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.makeMetadata = makeMetadata;
|
|
4
|
+
exports.exactInteger = exactInteger;
|
|
5
|
+
exports.exactU64 = exactU64;
|
|
6
|
+
exports.exactI64 = exactI64;
|
|
4
7
|
function makeMetadata(signature, slot, txIndex, blockTimeUs, grpcRecvUs, recentBlockhash) {
|
|
5
8
|
return {
|
|
6
9
|
signature,
|
|
7
|
-
slot,
|
|
8
|
-
tx_index: txIndex,
|
|
9
|
-
block_time_us: blockTimeUs ?? 0,
|
|
10
|
-
grpc_recv_us: grpcRecvUs,
|
|
10
|
+
slot: exactU64(slot, "slot"),
|
|
11
|
+
tx_index: exactU64(txIndex, "tx_index"),
|
|
12
|
+
block_time_us: exactI64(blockTimeUs ?? 0, "block_time_us"),
|
|
13
|
+
grpc_recv_us: exactI64(grpcRecvUs, "grpc_recv_us"),
|
|
11
14
|
recent_blockhash: recentBlockhash,
|
|
12
15
|
};
|
|
13
16
|
}
|
|
17
|
+
function exactInteger(value, label = "integer") {
|
|
18
|
+
if (typeof value === "number" && !Number.isSafeInteger(value))
|
|
19
|
+
throw new RangeError(`Unsafe ${label} integer`);
|
|
20
|
+
if (typeof value === "string" && !/^-?\d+$/.test(value))
|
|
21
|
+
throw new TypeError(`Invalid ${label} integer`);
|
|
22
|
+
if (!["bigint", "number", "string"].includes(typeof value))
|
|
23
|
+
throw new TypeError(`Invalid ${label} type`);
|
|
24
|
+
return BigInt(value);
|
|
25
|
+
}
|
|
26
|
+
function exactU64(value, label = "u64") {
|
|
27
|
+
const n = exactInteger(value, label);
|
|
28
|
+
if (n < 0n || n > (1n << 64n) - 1n)
|
|
29
|
+
throw new RangeError(`${label} outside u64`);
|
|
30
|
+
return n;
|
|
31
|
+
}
|
|
32
|
+
function exactI64(value, label = "i64") {
|
|
33
|
+
const n = exactInteger(value, label);
|
|
34
|
+
if (n < -(1n << 63n) || n > (1n << 63n) - 1n)
|
|
35
|
+
throw new RangeError(`${label} outside i64`);
|
|
36
|
+
return n;
|
|
37
|
+
}
|
|
@@ -8,12 +8,12 @@ export type StreamingEventListener = {
|
|
|
8
8
|
onDexEventStreaming: (event: DexEvent) => void;
|
|
9
9
|
};
|
|
10
10
|
/** 从交易解析事件;当前主路径为日志解析 */
|
|
11
|
-
export declare function parseTransactionEvents(_instructionData: Uint8Array, _accounts: string[], logs: string[], signature: string, slot: number, _txIndex: number, blockTimeUs: number | undefined, _programId: string): DexEvent[];
|
|
12
|
-
export declare function parseLogsOnly(logs: string[], signature: string, slot: number, blockTimeUs: number | undefined, txIndex?: number): DexEvent[];
|
|
13
|
-
export declare function parseTransactionWithListener(instructionData: Uint8Array, accounts: string[], logs: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, programId: string, listener: EventListener): void;
|
|
14
|
-
export declare function parseTransactionEventsStreaming(_instructionData: Uint8Array, _accounts: string[], logs: string[], signature: string, slot: number, _txIndex: number, blockTimeUs: number | undefined, _programId: string, callback: (event: DexEvent) => void): void;
|
|
15
|
-
export declare function parseLogsStreaming(logs: string[], signature: string, slot: number, blockTimeUs: number | undefined, callback: (event: DexEvent) => void, txIndex?: number): void;
|
|
16
|
-
export declare function parseTransactionWithStreamingListener(instructionData: Uint8Array, accounts: string[], logs: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, programId: string, listener: StreamingEventListener): void;
|
|
11
|
+
export declare function parseTransactionEvents(_instructionData: Uint8Array, _accounts: string[], logs: string[], signature: string, slot: number | bigint | string, _txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, _programId: string): DexEvent[];
|
|
12
|
+
export declare function parseLogsOnly(logs: string[], signature: string, slot: number | bigint | string, blockTimeUs: number | bigint | string | undefined, txIndex?: number | bigint | string): DexEvent[];
|
|
13
|
+
export declare function parseTransactionWithListener(instructionData: Uint8Array, accounts: string[], logs: string[], signature: string, slot: number | bigint | string, txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, programId: string, listener: EventListener): void;
|
|
14
|
+
export declare function parseTransactionEventsStreaming(_instructionData: Uint8Array, _accounts: string[], logs: string[], signature: string, slot: number | bigint | string, _txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, _programId: string, callback: (event: DexEvent) => void): void;
|
|
15
|
+
export declare function parseLogsStreaming(logs: string[], signature: string, slot: number | bigint | string, blockTimeUs: number | bigint | string | undefined, callback: (event: DexEvent) => void, txIndex?: number | bigint | string): void;
|
|
16
|
+
export declare function parseTransactionWithStreamingListener(instructionData: Uint8Array, accounts: string[], logs: string[], signature: string, slot: number | bigint | string, txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, programId: string, listener: StreamingEventListener): void;
|
|
17
17
|
/** 带完整 gRPC 元数据字段的日志解析 */
|
|
18
|
-
export declare function parseLog(log: string, signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs: number, eventTypeFilter: EventTypeFilter | undefined, isCreatedBuy: boolean, recentBlockhash?: Uint8Array): DexEvent | null;
|
|
18
|
+
export declare function parseLog(log: string, signature: string, slot: number | bigint | string, txIndex: number | bigint | string, blockTimeUs: number | bigint | string | undefined, grpcRecvUs: number | bigint | string, eventTypeFilter: EventTypeFilter | undefined, isCreatedBuy: boolean, recentBlockhash?: Uint8Array): DexEvent | null;
|
|
19
19
|
export { nowUs };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Local BlockMeta adapter; never fetches a block or blockhash. */
|
|
2
|
+
import type { DexEvent } from "../core/dex_event.js";
|
|
3
|
+
export declare function parseBlockMetaUpdate(meta: {
|
|
4
|
+
slot: string | number | bigint;
|
|
5
|
+
blockhash: string;
|
|
6
|
+
blockTime?: {
|
|
7
|
+
timestamp: string | number | bigint;
|
|
8
|
+
};
|
|
9
|
+
}, grpcRecvUs: number | bigint | string, fallbackBlockUs?: number | bigint | string): DexEvent;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseBlockMetaUpdate = parseBlockMetaUpdate;
|
|
4
|
+
const metadata_js_1 = require("../core/metadata.js");
|
|
5
|
+
function parseBlockMetaUpdate(meta, grpcRecvUs, fallbackBlockUs) {
|
|
6
|
+
const slot = (0, metadata_js_1.exactInteger)(meta.slot, "slot");
|
|
7
|
+
(0, metadata_js_1.exactU64)(slot, "slot");
|
|
8
|
+
const seconds = meta.blockTime?.timestamp;
|
|
9
|
+
let blockUs = (0, metadata_js_1.exactI64)(fallbackBlockUs ?? 0);
|
|
10
|
+
if (seconds !== undefined) {
|
|
11
|
+
const v = (0, metadata_js_1.exactInteger)(seconds, "timestamp") * 1000000n, lo = -(1n << 63n), hi = (1n << 63n) - 1n;
|
|
12
|
+
blockUs = v < lo ? lo : v > hi ? hi : v;
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
BlockMeta: {
|
|
16
|
+
metadata: {
|
|
17
|
+
signature: "1".repeat(64),
|
|
18
|
+
slot,
|
|
19
|
+
tx_index: 0n,
|
|
20
|
+
block_time_us: blockUs,
|
|
21
|
+
grpc_recv_us: (0, metadata_js_1.exactI64)(grpcRecvUs),
|
|
22
|
+
recent_blockhash: meta.blockhash || undefined,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
package/dist/grpc/client.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
* Yellowstone gRPC 客户端实现 - 基于 @triton-one/yellowstone-grpc
|
|
3
|
-
*/
|
|
4
|
-
import { CommitmentLevel } from "@triton-one/yellowstone-grpc";
|
|
1
|
+
import { CommitmentLevel } from "./protocol/geyser.js";
|
|
5
2
|
import { type DexEvent } from "../core/dex_event.js";
|
|
6
3
|
import { type EventQueueOverflowStrategy } from "./async_event_queue.js";
|
|
7
4
|
import { type AccountFilter, type ClientConfig, type EventTypeFilter, type TransactionFilter, type SubscribeCallbacks } from "./types.js";
|
|
8
5
|
export { SubscribeCallbacks };
|
|
9
6
|
export type { EventQueueOverflowStrategy } from "./async_event_queue.js";
|
|
7
|
+
export interface GrpcStreamStatus {
|
|
8
|
+
readonly state: "connecting" | "connected" | "reconnecting" | "stopped";
|
|
9
|
+
readonly continuityBroken: boolean;
|
|
10
|
+
readonly reconnects: number;
|
|
11
|
+
readonly dropped: number;
|
|
12
|
+
}
|
|
10
13
|
export interface DexEventSubscription extends AsyncIterable<DexEvent> {
|
|
11
14
|
id: string;
|
|
12
15
|
errors: AsyncIterable<Error>;
|
|
16
|
+
/** Bounded transition stream; inspect status() even if notifications were dropped. */
|
|
17
|
+
states: AsyncIterable<GrpcStreamStatus>;
|
|
18
|
+
status(): GrpcStreamStatus;
|
|
13
19
|
cancel(): void;
|
|
20
|
+
/** Wait until the stream and associated workers exit. */
|
|
21
|
+
join(): Promise<void>;
|
|
14
22
|
next(): Promise<IteratorResult<DexEvent>>;
|
|
15
23
|
len(): number;
|
|
16
24
|
/** Total drops across ingress and the public event queue. */
|
|
@@ -49,6 +57,11 @@ export declare class YellowstoneGrpc {
|
|
|
49
57
|
private connectPromise?;
|
|
50
58
|
private subscribers;
|
|
51
59
|
private dexSubscribers;
|
|
60
|
+
private dexLifecycle;
|
|
61
|
+
private activeDex?;
|
|
62
|
+
private withDexLifecycle;
|
|
63
|
+
private stopDexUnlocked;
|
|
64
|
+
stop(): Promise<void>;
|
|
52
65
|
constructor(endpoint: string, xToken: string, config?: ClientConfig);
|
|
53
66
|
/** 连接到 gRPC 服务器 */
|
|
54
67
|
connect(): Promise<void>;
|
|
@@ -86,26 +99,28 @@ export declare class YellowstoneGrpc {
|
|
|
86
99
|
* 事件队列满时按配置丢弃事件,避免回调阻塞 gRPC 读循环并让丢弃可观测。
|
|
87
100
|
*/
|
|
88
101
|
subscribeDexEvents(transactionFilters?: TransactionFilter[], accountFilters?: AccountFilter[], eventTypeFilter?: EventTypeFilter, options?: SubscribeDexEventsOptions): Promise<DexEventSubscription>;
|
|
102
|
+
private startDexEvents;
|
|
89
103
|
/** 取消订阅 */
|
|
90
104
|
unsubscribe(subId: string): void;
|
|
91
105
|
/** 动态更新当前 DEX 订阅过滤器(与 Rust update_subscription 语义对齐)。 */
|
|
92
106
|
updateSubscription(transactionFilters: TransactionFilter[], accountFilters: AccountFilter[]): Promise<void>;
|
|
107
|
+
private updateDexUnlocked;
|
|
93
108
|
update_subscription(transactionFilters: TransactionFilter[], accountFilters: AccountFilter[]): Promise<void>;
|
|
94
109
|
/** 获取最新区块哈希 */
|
|
95
110
|
getLatestBlockhash(commitment?: CommitmentLevel): Promise<{
|
|
96
|
-
slot:
|
|
111
|
+
slot: bigint;
|
|
97
112
|
blockhash: string;
|
|
98
|
-
lastValidBlockHeight:
|
|
113
|
+
lastValidBlockHeight: bigint;
|
|
99
114
|
}>;
|
|
100
115
|
/** 获取区块高度 */
|
|
101
|
-
getBlockHeight(commitment?: CommitmentLevel): Promise<
|
|
116
|
+
getBlockHeight(commitment?: CommitmentLevel): Promise<bigint>;
|
|
102
117
|
/** 获取当前 Slot */
|
|
103
|
-
getSlot(commitment?: CommitmentLevel): Promise<
|
|
118
|
+
getSlot(commitment?: CommitmentLevel): Promise<bigint>;
|
|
104
119
|
/** 获取服务器版本 */
|
|
105
120
|
getVersion(): Promise<string>;
|
|
106
121
|
/** 验证区块哈希是否有效 */
|
|
107
122
|
isBlockhashValid(blockhash: string, commitment?: CommitmentLevel): Promise<{
|
|
108
|
-
slot:
|
|
123
|
+
slot: bigint;
|
|
109
124
|
valid: boolean;
|
|
110
125
|
}>;
|
|
111
126
|
/** 发送 Ping 请求 */
|