sol-parser-sdk 0.5.9 → 0.5.10
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 +31 -6
- package/README_CN.md +29 -6
- package/dist/accounts/pumpswap.js +15 -2
- package/dist/core/account_fill_raydium.d.ts +1 -1
- package/dist/core/account_fill_raydium.js +5 -1
- package/dist/core/dex_event.d.ts +11 -0
- package/dist/grpc/async_event_queue.d.ts +19 -0
- package/dist/grpc/async_event_queue.js +73 -0
- package/dist/grpc/client.d.ts +15 -4
- package/dist/grpc/client.js +102 -64
- package/dist/grpc/geyser_connect.d.ts +7 -1
- package/dist/grpc/geyser_connect.js +7 -1
- package/dist/grpc/log_instr_dedup.js +30 -12
- package/dist/grpc/types.d.ts +5 -3
- package/dist/grpc/types.js +5 -2
- package/dist/index.d.ts +1 -1
- package/dist/instr/inner.js +37 -15
- package/dist/instr/meteora_dlmm_ix.js +130 -38
- package/dist/instr/orca_whirlpool_ix.js +2 -1
- package/dist/instr/pumpswap_ix.js +10 -0
- package/dist/instr/raydium_amm_v4_ix.js +59 -36
- package/dist/instr/raydium_cpmm_ix.js +2 -2
- package/dist/logs/discriminator_lut.js +6 -2
- package/dist/logs/meteora_dlmm.d.ts +1 -0
- package/dist/logs/meteora_dlmm.js +135 -11
- package/dist/logs/optimized_matcher.js +25 -10
- package/dist/logs/program_log_discriminators.d.ts +1 -0
- package/dist/logs/program_log_discriminators.js +2 -0
- package/dist/logs/pump_amm.js +90 -22
- package/dist/logs/raydium_amm.d.ts +2 -0
- package/dist/logs/raydium_amm.js +36 -0
- package/dist/logs/raydium_cpmm.d.ts +2 -0
- package/dist/logs/raydium_cpmm.js +43 -0
- package/dist/rpc_transaction.js +118 -26
- package/package.json +1 -1
package/dist/logs/raydium_amm.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseRayLogSwap = parseRayLogSwap;
|
|
3
4
|
exports.parseSwapBaseInFromData = parseSwapBaseInFromData;
|
|
4
5
|
exports.parseSwapBaseOutFromData = parseSwapBaseOutFromData;
|
|
5
6
|
exports.parseDepositFromData = parseDepositFromData;
|
|
@@ -37,6 +38,41 @@ function emptySwap(metadata, amm, user) {
|
|
|
37
38
|
user_source_owner: user,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
41
|
+
const RAY_LOG_PREFIX = "Program log: ray_log: ";
|
|
42
|
+
/** Decode Raydium AMM V4's official bincode `SwapBaseInLog` / `SwapBaseOutLog`. */
|
|
43
|
+
function parseRayLogSwap(log, metadata) {
|
|
44
|
+
const prefix = log.indexOf(RAY_LOG_PREFIX);
|
|
45
|
+
if (prefix < 0)
|
|
46
|
+
return null;
|
|
47
|
+
const encoded = log.slice(prefix + RAY_LOG_PREFIX.length).trim();
|
|
48
|
+
let data;
|
|
49
|
+
try {
|
|
50
|
+
data = Buffer.from(encoded, "base64");
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// Both swap bincode structs are one u8 followed by seven u64 values.
|
|
56
|
+
if (data.length !== 57 || (data[0] !== 3 && data[0] !== 4))
|
|
57
|
+
return null;
|
|
58
|
+
const input = (0, binary_js_1.readU64LE)(data, 1);
|
|
59
|
+
const output = (0, binary_js_1.readU64LE)(data, 9);
|
|
60
|
+
const actual = (0, binary_js_1.readU64LE)(data, 49);
|
|
61
|
+
if (input == null || output == null || actual == null)
|
|
62
|
+
return null;
|
|
63
|
+
const ev = emptySwap(metadata, (0, dex_event_js_1.defaultPubkey)(), (0, dex_event_js_1.defaultPubkey)());
|
|
64
|
+
if (data[0] === 3) {
|
|
65
|
+
ev.amount_in = input;
|
|
66
|
+
ev.minimum_amount_out = output;
|
|
67
|
+
ev.amount_out = actual;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
ev.max_amount_in = input;
|
|
71
|
+
ev.amount_out = output;
|
|
72
|
+
ev.amount_in = actual;
|
|
73
|
+
}
|
|
74
|
+
return { RaydiumAmmV4Swap: ev };
|
|
75
|
+
}
|
|
40
76
|
function parseSwapBaseInFromData(data, metadata) {
|
|
41
77
|
let o = 0;
|
|
42
78
|
const amm = (0, binary_js_1.readPubkey)(data, o);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { EventMetadata } from "../core/metadata.js";
|
|
2
2
|
import type { DexEvent } from "../core/dex_event.js";
|
|
3
|
+
/** Current Anchor `SwapEvent` payload (the 8-byte event discriminator is removed by the caller). */
|
|
4
|
+
export declare function parseSwapEventFromData(data: Uint8Array, metadata: EventMetadata): DexEvent | null;
|
|
3
5
|
export declare function parseSwapBaseInFromData(data: Uint8Array, metadata: EventMetadata): DexEvent | null;
|
|
4
6
|
export declare function parseSwapBaseOutFromData(data: Uint8Array, metadata: EventMetadata): DexEvent | null;
|
|
5
7
|
export declare function parseCreatePoolFromData(data: Uint8Array, metadata: EventMetadata): DexEvent | null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSwapEventFromData = parseSwapEventFromData;
|
|
3
4
|
exports.parseSwapBaseInFromData = parseSwapBaseInFromData;
|
|
4
5
|
exports.parseSwapBaseOutFromData = parseSwapBaseOutFromData;
|
|
5
6
|
exports.parseCreatePoolFromData = parseCreatePoolFromData;
|
|
@@ -9,6 +10,48 @@ const binary_js_1 = require("../util/binary.js");
|
|
|
9
10
|
function bn64(v) {
|
|
10
11
|
return v ?? 0n;
|
|
11
12
|
}
|
|
13
|
+
/** Current Anchor `SwapEvent` payload (the 8-byte event discriminator is removed by the caller). */
|
|
14
|
+
function parseSwapEventFromData(data, metadata) {
|
|
15
|
+
// pool_id + six u64 fields + base_input. Newer IDLs append mint/fee fields,
|
|
16
|
+
// which remain wire-compatible with this stable prefix.
|
|
17
|
+
if (data.length < 32 + (6 * 8) + 1)
|
|
18
|
+
return null;
|
|
19
|
+
let o = 0;
|
|
20
|
+
const pool_id = (0, binary_js_1.readPubkey)(data, o);
|
|
21
|
+
if (!pool_id)
|
|
22
|
+
return null;
|
|
23
|
+
o += 32;
|
|
24
|
+
const input_vault_before = (0, binary_js_1.readU64LE)(data, o);
|
|
25
|
+
o += 8;
|
|
26
|
+
const output_vault_before = (0, binary_js_1.readU64LE)(data, o);
|
|
27
|
+
o += 8;
|
|
28
|
+
const input_amount = (0, binary_js_1.readU64LE)(data, o);
|
|
29
|
+
o += 8;
|
|
30
|
+
const output_amount = (0, binary_js_1.readU64LE)(data, o);
|
|
31
|
+
o += 8;
|
|
32
|
+
const input_transfer_fee = (0, binary_js_1.readU64LE)(data, o);
|
|
33
|
+
o += 8;
|
|
34
|
+
const output_transfer_fee = (0, binary_js_1.readU64LE)(data, o);
|
|
35
|
+
o += 8;
|
|
36
|
+
const base_input = (0, binary_js_1.readBool)(data, o);
|
|
37
|
+
if (input_vault_before == null || output_vault_before == null ||
|
|
38
|
+
input_amount == null || output_amount == null ||
|
|
39
|
+
input_transfer_fee == null || output_transfer_fee == null ||
|
|
40
|
+
base_input == null)
|
|
41
|
+
return null;
|
|
42
|
+
const ev = {
|
|
43
|
+
metadata,
|
|
44
|
+
pool_id,
|
|
45
|
+
input_vault_before,
|
|
46
|
+
output_vault_before,
|
|
47
|
+
input_amount,
|
|
48
|
+
output_amount,
|
|
49
|
+
input_transfer_fee,
|
|
50
|
+
output_transfer_fee,
|
|
51
|
+
base_input,
|
|
52
|
+
};
|
|
53
|
+
return { RaydiumCpmmSwap: ev };
|
|
54
|
+
}
|
|
12
55
|
function parseSwapBaseInFromData(data, metadata) {
|
|
13
56
|
let o = 0;
|
|
14
57
|
const pool_state = (0, binary_js_1.readPubkey)(data, o);
|
package/dist/rpc_transaction.js
CHANGED
|
@@ -19,8 +19,31 @@ const rpc_invoke_map_js_1 = require("./core/rpc_invoke_map.js");
|
|
|
19
19
|
const log_instr_dedup_js_1 = require("./grpc/log_instr_dedup.js");
|
|
20
20
|
const inner_js_1 = require("./instr/inner.js");
|
|
21
21
|
const mod_js_1 = require("./instr/mod.js");
|
|
22
|
+
const program_ids_js_1 = require("./instr/program_ids.js");
|
|
22
23
|
const optimized_matcher_js_1 = require("./logs/optimized_matcher.js");
|
|
23
24
|
const DEFAULT_PK = web3_js_1.PublicKey.default.toBase58();
|
|
25
|
+
const PUMPFUN_TRADE_EVENT_NAMES = new Set([
|
|
26
|
+
"PumpFunTrade",
|
|
27
|
+
"PumpFunBuy",
|
|
28
|
+
"PumpFunSell",
|
|
29
|
+
"PumpFunBuyExactSolIn",
|
|
30
|
+
]);
|
|
31
|
+
const EVENT_CPI_PREFIX = Uint8Array.from([228, 69, 165, 46, 81, 203, 154, 29]);
|
|
32
|
+
const LEGACY_EVENT_CPI_SUFFIX = Uint8Array.from([155, 167, 108, 32, 122, 76, 173, 64]);
|
|
33
|
+
function bytesEqualAt(data, expected, offset) {
|
|
34
|
+
for (let i = 0; i < expected.length; i++) {
|
|
35
|
+
if (data[offset + i] !== expected[i])
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
function isDlmmEventCpi(programId, data) {
|
|
41
|
+
return programId === program_ids_js_1.METEORA_DLMM_PROGRAM_ID && data.length >= 16 && (bytesEqualAt(data, EVENT_CPI_PREFIX, 0) ||
|
|
42
|
+
bytesEqualAt(data, LEGACY_EVENT_CPI_SUFFIX, 8));
|
|
43
|
+
}
|
|
44
|
+
function isDlmmEvent(event) {
|
|
45
|
+
return eventName(event).startsWith("MeteoraDlmm");
|
|
46
|
+
}
|
|
24
47
|
function eventName(ev) {
|
|
25
48
|
return Object.keys(ev)[0] ?? "";
|
|
26
49
|
}
|
|
@@ -224,35 +247,48 @@ function mergePumpSwapBuySellInstruction(base, inner) {
|
|
|
224
247
|
fillStringIfEmpty(base, key, ix);
|
|
225
248
|
}
|
|
226
249
|
}
|
|
250
|
+
function mergeDlmmInstruction(baseName, base, inner) {
|
|
251
|
+
const context = baseName === "MeteoraDlmmInitializePool"
|
|
252
|
+
? { creator: base.creator, active_bin_id: base.active_bin_id }
|
|
253
|
+
: baseName === "MeteoraDlmmCreatePosition"
|
|
254
|
+
? { lower_bin_id: base.lower_bin_id, width: base.width }
|
|
255
|
+
: baseName === "MeteoraDlmmClosePosition"
|
|
256
|
+
? { pool: base.pool }
|
|
257
|
+
: null;
|
|
258
|
+
Object.assign(base, inner);
|
|
259
|
+
if (context)
|
|
260
|
+
Object.assign(base, context);
|
|
261
|
+
}
|
|
227
262
|
function mergeInstructionEvent(base, inner) {
|
|
228
263
|
const baseName = eventName(base);
|
|
229
264
|
const innerName = eventName(inner);
|
|
230
265
|
const baseData = eventPayload(base);
|
|
231
266
|
const innerData = eventPayload(inner);
|
|
232
267
|
if (!baseData || !innerData)
|
|
233
|
-
return;
|
|
234
|
-
|
|
235
|
-
"PumpFunTrade",
|
|
236
|
-
"PumpFunBuy",
|
|
237
|
-
"PumpFunSell",
|
|
238
|
-
"PumpFunBuyExactSolIn",
|
|
239
|
-
]);
|
|
240
|
-
if (pumpfunTradeNames.has(baseName) && pumpfunTradeNames.has(innerName)) {
|
|
268
|
+
return false;
|
|
269
|
+
if (PUMPFUN_TRADE_EVENT_NAMES.has(baseName) && PUMPFUN_TRADE_EVENT_NAMES.has(innerName)) {
|
|
241
270
|
mergePumpfunTradeInstruction(baseData, innerData);
|
|
242
|
-
return;
|
|
271
|
+
return true;
|
|
243
272
|
}
|
|
244
273
|
if (baseName === "PumpFunCreateV2" && innerName === "PumpFunCreateV2") {
|
|
245
274
|
mergePumpfunCreateV2Instruction(baseData, innerData);
|
|
246
|
-
return;
|
|
275
|
+
return true;
|
|
247
276
|
}
|
|
248
277
|
if ((baseName === "PumpSwapBuy" && innerName === "PumpSwapBuy") ||
|
|
249
278
|
(baseName === "PumpSwapSell" && innerName === "PumpSwapSell")) {
|
|
250
279
|
mergePumpSwapBuySellInstruction(baseData, innerData);
|
|
251
|
-
return;
|
|
280
|
+
return true;
|
|
252
281
|
}
|
|
253
282
|
if (baseName === innerName) {
|
|
254
|
-
|
|
283
|
+
if (baseName.startsWith("MeteoraDlmm")) {
|
|
284
|
+
mergeDlmmInstruction(baseName, baseData, innerData);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
Object.assign(baseData, innerData);
|
|
288
|
+
}
|
|
289
|
+
return true;
|
|
255
290
|
}
|
|
291
|
+
return false;
|
|
256
292
|
}
|
|
257
293
|
function mergeInstructionEvents(events) {
|
|
258
294
|
if (events.length === 0)
|
|
@@ -265,27 +301,71 @@ function mergeInstructionEvents(events) {
|
|
|
265
301
|
return ak - bk;
|
|
266
302
|
});
|
|
267
303
|
const out = [];
|
|
268
|
-
let
|
|
304
|
+
let outerTarget = null;
|
|
305
|
+
const dlmmTargets = [];
|
|
269
306
|
for (const item of events) {
|
|
270
307
|
if (item.innerIdx === null) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
308
|
+
out.push(item.event);
|
|
309
|
+
const resultIdx = out.length - 1;
|
|
310
|
+
outerTarget = { outerIdx: item.outerIdx, resultIdx };
|
|
311
|
+
dlmmTargets.length = 0;
|
|
312
|
+
if (isDlmmEvent(item.event)) {
|
|
313
|
+
dlmmTargets.push({
|
|
314
|
+
outerIdx: item.outerIdx,
|
|
315
|
+
stackHeight: item.stackHeight,
|
|
316
|
+
resultIdx,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
274
319
|
continue;
|
|
275
320
|
}
|
|
276
|
-
if (
|
|
277
|
-
|
|
321
|
+
if (item.isDlmmEventCpi) {
|
|
322
|
+
let merged = false;
|
|
323
|
+
for (let i = dlmmTargets.length - 1; i >= 0; i--) {
|
|
324
|
+
const target = dlmmTargets[i];
|
|
325
|
+
const directChild = target.stackHeight === undefined || item.stackHeight === undefined ||
|
|
326
|
+
item.stackHeight === target.stackHeight + 1;
|
|
327
|
+
if (target.outerIdx === item.outerIdx && directChild) {
|
|
328
|
+
dlmmTargets.length = i + 1;
|
|
329
|
+
merged = mergeInstructionEvent(out[target.resultIdx], item.event);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (!merged)
|
|
334
|
+
out.push(item.event);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
let resultIdx = -1;
|
|
338
|
+
if (outerTarget && outerTarget.outerIdx === item.outerIdx &&
|
|
339
|
+
mergeInstructionEvent(out[outerTarget.resultIdx], item.event)) {
|
|
340
|
+
resultIdx = outerTarget.resultIdx;
|
|
278
341
|
}
|
|
279
342
|
else {
|
|
280
|
-
if (pending) {
|
|
281
|
-
out.push(pending.event);
|
|
282
|
-
pending = null;
|
|
283
|
-
}
|
|
284
343
|
out.push(item.event);
|
|
344
|
+
resultIdx = out.length - 1;
|
|
345
|
+
}
|
|
346
|
+
if (isDlmmEvent(item.event)) {
|
|
347
|
+
if (item.stackHeight === undefined) {
|
|
348
|
+
dlmmTargets.length = 0;
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
while (dlmmTargets.length > 0) {
|
|
352
|
+
const last = dlmmTargets[dlmmTargets.length - 1];
|
|
353
|
+
if (last.outerIdx !== item.outerIdx ||
|
|
354
|
+
(last.stackHeight !== undefined && last.stackHeight >= item.stackHeight)) {
|
|
355
|
+
dlmmTargets.pop();
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
dlmmTargets.push({
|
|
363
|
+
outerIdx: item.outerIdx,
|
|
364
|
+
stackHeight: item.stackHeight,
|
|
365
|
+
resultIdx,
|
|
366
|
+
});
|
|
285
367
|
}
|
|
286
368
|
}
|
|
287
|
-
if (pending)
|
|
288
|
-
out.push(pending.event);
|
|
289
369
|
return out;
|
|
290
370
|
}
|
|
291
371
|
function resolveAccounts(resolver, indices) {
|
|
@@ -303,7 +383,13 @@ function parseOuterAndInnerInstructions(message, meta, signature, slot, txIndex,
|
|
|
303
383
|
const accounts = resolveAccounts(resolver, ix.accountKeyIndexes);
|
|
304
384
|
const ev = (0, mod_js_1.parseInstructionUnified)(data, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs, filter, programId);
|
|
305
385
|
if (ev)
|
|
306
|
-
indexedEvents.push({
|
|
386
|
+
indexedEvents.push({
|
|
387
|
+
outerIdx,
|
|
388
|
+
innerIdx: null,
|
|
389
|
+
stackHeight: 1,
|
|
390
|
+
isDlmmEventCpi: false,
|
|
391
|
+
event: ev,
|
|
392
|
+
});
|
|
307
393
|
}
|
|
308
394
|
const innerGroups = meta?.innerInstructions;
|
|
309
395
|
if (!innerGroups)
|
|
@@ -318,7 +404,13 @@ function parseOuterAndInnerInstructions(message, meta, signature, slot, txIndex,
|
|
|
318
404
|
const ev = (0, inner_js_1.parseInnerCompiledInstructionIfSupported)(data, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs, filter, programId) ??
|
|
319
405
|
(0, inner_js_1.parseInnerInstructionUnified)(data, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs, filter, programId, isCreatedBuy);
|
|
320
406
|
if (ev)
|
|
321
|
-
indexedEvents.push({
|
|
407
|
+
indexedEvents.push({
|
|
408
|
+
outerIdx: group.index,
|
|
409
|
+
innerIdx,
|
|
410
|
+
stackHeight: ix.stackHeight,
|
|
411
|
+
isDlmmEventCpi: isDlmmEventCpi(programId, data),
|
|
412
|
+
event: ev,
|
|
413
|
+
});
|
|
322
414
|
}
|
|
323
415
|
}
|
|
324
416
|
return mergeInstructionEvents(indexedEvents);
|
package/package.json
CHANGED