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
|
@@ -7,7 +7,7 @@ exports.defaultGeyserConnectConfig = defaultGeyserConnectConfig;
|
|
|
7
7
|
exports.geyserGrpcChannelOptions = geyserGrpcChannelOptions;
|
|
8
8
|
exports.connectYellowstoneGeyser = connectYellowstoneGeyser;
|
|
9
9
|
const yellowstone_grpc_1 = __importDefault(require("@triton-one/yellowstone-grpc"));
|
|
10
|
-
/**
|
|
10
|
+
/** 公共字段与 Rust `GeyserConnectConfig::default` 一致,并包含 Node gRPC 通道默认值。 */
|
|
11
11
|
function defaultGeyserConnectConfig() {
|
|
12
12
|
return {
|
|
13
13
|
connectTimeoutMs: 8000,
|
|
@@ -15,6 +15,9 @@ function defaultGeyserConnectConfig() {
|
|
|
15
15
|
xToken: undefined,
|
|
16
16
|
keepAliveIntervalMs: 30_000,
|
|
17
17
|
keepAliveTimeoutMs: 5000,
|
|
18
|
+
initialReconnectBackoffMs: 1000,
|
|
19
|
+
maxReconnectBackoffMs: 60_000,
|
|
20
|
+
flowControlWindowBytes: 1024 * 1024,
|
|
18
21
|
};
|
|
19
22
|
}
|
|
20
23
|
/** 与 `ClientConfig` / `grpc.keepalive_*` 对齐,用于长连接抗 NAT/负载均衡 idle 断开 */
|
|
@@ -29,6 +32,9 @@ function geyserGrpcChannelOptions(config = defaultGeyserConnectConfig()) {
|
|
|
29
32
|
"grpc.keepalive_timeout_ms": timeout,
|
|
30
33
|
/** 无活跃 RPC 时仍发 keepalive,避免长时间仅订阅时被中间设备掐断 */
|
|
31
34
|
"grpc.keepalive_permit_without_calls": 1,
|
|
35
|
+
"grpc.initial_reconnect_backoff_ms": config.initialReconnectBackoffMs,
|
|
36
|
+
"grpc.max_reconnect_backoff_ms": config.maxReconnectBackoffMs,
|
|
37
|
+
"grpc-node.flow_control_window": config.flowControlWindowBytes,
|
|
32
38
|
};
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
@@ -62,7 +62,7 @@ function nextOccurrence(base, counts) {
|
|
|
62
62
|
counts.set(base, current + 1);
|
|
63
63
|
return current;
|
|
64
64
|
}
|
|
65
|
-
function dedupeKey(ev,
|
|
65
|
+
function dedupeKey(ev, occurrenceCounts) {
|
|
66
66
|
const name = eventName(ev);
|
|
67
67
|
const data = payload(ev);
|
|
68
68
|
if (!data)
|
|
@@ -70,7 +70,7 @@ function dedupeKey(ev, pumpfunLaneCounts) {
|
|
|
70
70
|
if (PUMPFUN_TRADE_NAMES.has(name)) {
|
|
71
71
|
const lane = ixLane(data.ix_name);
|
|
72
72
|
const base = `${data.mint}|${data.user}|${Boolean(data.is_buy)}|${lane}`;
|
|
73
|
-
const occurrence = nextOccurrence(base
|
|
73
|
+
const occurrence = nextOccurrence(`PumpFun|${base}`, occurrenceCounts);
|
|
74
74
|
return `PumpFunTrade|${base}|${occurrence}`;
|
|
75
75
|
}
|
|
76
76
|
switch (name) {
|
|
@@ -98,12 +98,28 @@ function dedupeKey(ev, pumpfunLaneCounts) {
|
|
|
98
98
|
return `PumpSwapLiquidityAdded|${data.pool}|${data.user}`;
|
|
99
99
|
case "PumpSwapLiquidityRemoved":
|
|
100
100
|
return `PumpSwapLiquidityRemoved|${data.pool}|${data.user}`;
|
|
101
|
-
case "RaydiumClmmSwap":
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
case "
|
|
106
|
-
|
|
101
|
+
case "RaydiumClmmSwap": {
|
|
102
|
+
const base = String(data.pool_state);
|
|
103
|
+
return `RaydiumClmmSwap|${base}|${nextOccurrence(`RaydiumClmm|${base}`, occurrenceCounts)}`;
|
|
104
|
+
}
|
|
105
|
+
case "RaydiumCpmmSwap": {
|
|
106
|
+
const base = String(data.pool_id);
|
|
107
|
+
return `RaydiumCpmmSwap|${base}|${nextOccurrence(`RaydiumCpmm|${base}`, occurrenceCounts)}`;
|
|
108
|
+
}
|
|
109
|
+
case "RaydiumAmmV4Swap": {
|
|
110
|
+
const base = data.max_amount_in !== 0n && data.max_amount_in !== 0
|
|
111
|
+
? `out|${data.amount_out}`
|
|
112
|
+
: `in|${data.amount_in}`;
|
|
113
|
+
return `RaydiumAmmV4Swap|${base}|${nextOccurrence(`RaydiumAmmV4|${base}`, occurrenceCounts)}`;
|
|
114
|
+
}
|
|
115
|
+
case "OrcaWhirlpoolSwap": {
|
|
116
|
+
const base = String(data.whirlpool);
|
|
117
|
+
return `OrcaWhirlpoolSwap|${base}|${nextOccurrence(`OrcaWhirlpool|${base}`, occurrenceCounts)}`;
|
|
118
|
+
}
|
|
119
|
+
case "MeteoraDlmmSwap": {
|
|
120
|
+
const base = `${data.pool}|${data.from}|${Boolean(data.swap_for_y)}`;
|
|
121
|
+
return `MeteoraDlmmSwap|${base}|${nextOccurrence(`MeteoraDlmm|${base}`, occurrenceCounts)}`;
|
|
122
|
+
}
|
|
107
123
|
default:
|
|
108
124
|
return null;
|
|
109
125
|
}
|
|
@@ -282,6 +298,8 @@ function mergeRaydiumAmmV4Swap(log, ix) {
|
|
|
282
298
|
"serum_vault_signer",
|
|
283
299
|
"user_source_token_account",
|
|
284
300
|
"user_destination_token_account",
|
|
301
|
+
"user_source_owner",
|
|
302
|
+
"amm",
|
|
285
303
|
]) {
|
|
286
304
|
fillString(log, key, ix);
|
|
287
305
|
}
|
|
@@ -376,16 +394,16 @@ function mergeGrpcInstructionIntoLog(logEvent, ixEvent) {
|
|
|
376
394
|
function dedupeLogInstructionEvents(logEvents, instructionEvents) {
|
|
377
395
|
const out = [];
|
|
378
396
|
const indexByKey = new Map();
|
|
379
|
-
const
|
|
380
|
-
const
|
|
397
|
+
const logOccurrenceCounts = new Map();
|
|
398
|
+
const ixOccurrenceCounts = new Map();
|
|
381
399
|
for (const ev of logEvents) {
|
|
382
|
-
const key = dedupeKey(ev,
|
|
400
|
+
const key = dedupeKey(ev, logOccurrenceCounts);
|
|
383
401
|
if (key)
|
|
384
402
|
indexByKey.set(key, out.length);
|
|
385
403
|
out.push(ev);
|
|
386
404
|
}
|
|
387
405
|
for (const ev of instructionEvents) {
|
|
388
|
-
const key = dedupeKey(ev,
|
|
406
|
+
const key = dedupeKey(ev, ixOccurrenceCounts);
|
|
389
407
|
if (!key) {
|
|
390
408
|
out.push(ev);
|
|
391
409
|
continue;
|
package/dist/grpc/types.d.ts
CHANGED
|
@@ -98,16 +98,18 @@ export interface ClientConfig {
|
|
|
98
98
|
keep_alive_interval_ms: number;
|
|
99
99
|
keep_alive_timeout_ms: number;
|
|
100
100
|
buffer_size: number;
|
|
101
|
+
/** Node gRPC HTTP/2 receive window. Larger values reduce stalls on bursty streams. */
|
|
102
|
+
flow_control_window_bytes?: number;
|
|
101
103
|
order_mode: OrderMode;
|
|
102
104
|
order_timeout_ms: number;
|
|
103
105
|
micro_batch_us: number;
|
|
104
106
|
}
|
|
105
|
-
/** 与 Rust `grpc::config` 中 `StreamingConfig`
|
|
107
|
+
/** 与 Rust `grpc::config` 中 `StreamingConfig` 别名一致,并包含可选 Node gRPC 参数。 */
|
|
106
108
|
export type StreamingConfig = ClientConfig;
|
|
107
109
|
export declare function defaultClientConfig(): ClientConfig;
|
|
108
|
-
/**
|
|
110
|
+
/** Rust `ClientConfig::low_latency` 的 Node 调优版本,使用更小的 JS 对象队列。 */
|
|
109
111
|
export declare function lowLatencyClientConfig(): ClientConfig;
|
|
110
|
-
/**
|
|
112
|
+
/** Rust `ClientConfig::high_throughput` 的 Node 调优版本,使用更小的 JS 对象队列。 */
|
|
111
113
|
export declare function highThroughputClientConfig(): ClientConfig;
|
|
112
114
|
export interface TransactionFilter {
|
|
113
115
|
account_include: string[];
|
package/dist/grpc/types.js
CHANGED
|
@@ -42,12 +42,13 @@ function defaultClientConfig() {
|
|
|
42
42
|
keep_alive_interval_ms: 30000,
|
|
43
43
|
keep_alive_timeout_ms: 5000,
|
|
44
44
|
buffer_size: 8192,
|
|
45
|
+
flow_control_window_bytes: 1024 * 1024,
|
|
45
46
|
order_mode: "Unordered",
|
|
46
47
|
order_timeout_ms: 100,
|
|
47
48
|
micro_batch_us: 100,
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
|
-
/**
|
|
51
|
+
/** Rust `ClientConfig::low_latency` 的 Node 调优版本,使用更小的 JS 对象队列。 */
|
|
51
52
|
function lowLatencyClientConfig() {
|
|
52
53
|
return {
|
|
53
54
|
enable_metrics: false,
|
|
@@ -60,12 +61,13 @@ function lowLatencyClientConfig() {
|
|
|
60
61
|
keep_alive_interval_ms: 10_000,
|
|
61
62
|
keep_alive_timeout_ms: 2000,
|
|
62
63
|
buffer_size: 16384,
|
|
64
|
+
flow_control_window_bytes: 16 * 1024 * 1024,
|
|
63
65
|
order_mode: "Unordered",
|
|
64
66
|
order_timeout_ms: 50,
|
|
65
67
|
micro_batch_us: 50,
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
|
-
/**
|
|
70
|
+
/** Rust `ClientConfig::high_throughput` 的 Node 调优版本,使用更小的 JS 对象队列。 */
|
|
69
71
|
function highThroughputClientConfig() {
|
|
70
72
|
return {
|
|
71
73
|
enable_metrics: true,
|
|
@@ -78,6 +80,7 @@ function highThroughputClientConfig() {
|
|
|
78
80
|
keep_alive_interval_ms: 60_000,
|
|
79
81
|
keep_alive_timeout_ms: 10_000,
|
|
80
82
|
buffer_size: 32768,
|
|
83
|
+
flow_control_window_bytes: 16 * 1024 * 1024,
|
|
81
84
|
order_mode: "Unordered",
|
|
82
85
|
order_timeout_ms: 200,
|
|
83
86
|
micro_batch_us: 200,
|
package/dist/index.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export { parseInstructionUnified, parsePumpfunInstruction, parsePumpswapInstruct
|
|
|
41
41
|
/** Rust `instr` 根模块蛇形命名别名 */
|
|
42
42
|
export { parse_instruction_unified, parse_pumpfun_instruction, parse_pumpswap_instruction, parse_meteora_damm_instruction, parse_meteora_dlmm_instruction, parse_meteora_pools_instruction, parse_pump_fees_instruction, } from "./instr/rust_aliases.js";
|
|
43
43
|
export * as programIds from "./instr/program_ids.js";
|
|
44
|
-
export { YellowstoneGrpc, type SubscribeCallbacks, type DexEventSubscription } from "./grpc/client.js";
|
|
44
|
+
export { YellowstoneGrpc, type SubscribeCallbacks, type DexEventSubscription, type SubscribeDexEventsOptions, type EventQueueOverflowStrategy, } from "./grpc/client.js";
|
|
45
45
|
export { connectYellowstoneGeyser, defaultGeyserConnectConfig, geyserGrpcChannelOptions, type GeyserConnectConfig, } from "./grpc/geyser_connect.js";
|
|
46
46
|
/** 与 Rust `sol_parser_sdk::grpc::event_parser` 模块对应 */
|
|
47
47
|
export * as event_parser from "./grpc/event_parser.js";
|
package/dist/instr/inner.js
CHANGED
|
@@ -48,7 +48,7 @@ function filterDexEvent(ev, filter) {
|
|
|
48
48
|
? (0, types_js_1.eventTypeFilterNormalizeDexEvent)(filter, ev)
|
|
49
49
|
: null;
|
|
50
50
|
}
|
|
51
|
-
function
|
|
51
|
+
function eventCpiDiscriminator(disc) {
|
|
52
52
|
if (bytesEq(disc, 0, EVENT_CPI_PREFIX))
|
|
53
53
|
return (0, binary_js_1.readU64LE)(disc, 8);
|
|
54
54
|
if (bytesEq(disc, 8, EVENT_CPI_SUFFIX))
|
|
@@ -116,14 +116,16 @@ const LOG = {
|
|
|
116
116
|
METEORA_DAMM_INITIALIZE_POOL: [228, 50, 246, 85, 203, 66, 134, 37],
|
|
117
117
|
METEORA_DAMM_CREATE_POSITION: [156, 15, 119, 198, 29, 181, 221, 55],
|
|
118
118
|
METEORA_DAMM_CLOSE_POSITION: [20, 145, 144, 68, 143, 142, 214, 178],
|
|
119
|
-
METEORA_DLMM_SWAP: [
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
METEORA_DLMM_SWAP: [81, 108, 227, 190, 205, 208, 10, 196],
|
|
120
|
+
METEORA_DLMM_SWAP2: [46, 116, 82, 215, 148, 27, 84, 77],
|
|
121
|
+
METEORA_DLMM_ADD_LIQUIDITY: [31, 94, 125, 90, 227, 52, 61, 186],
|
|
122
|
+
METEORA_DLMM_REMOVE_LIQUIDITY: [116, 244, 97, 232, 103, 31, 152, 58],
|
|
123
|
+
METEORA_DLMM_INITIALIZE_POOL: [185, 74, 252, 125, 27, 215, 188, 111],
|
|
123
124
|
METEORA_DLMM_INITIALIZE_BIN_ARRAY: [11, 18, 155, 194, 33, 115, 238, 119],
|
|
124
|
-
METEORA_DLMM_CREATE_POSITION: [
|
|
125
|
-
METEORA_DLMM_CLOSE_POSITION: [
|
|
126
|
-
METEORA_DLMM_CLAIM_FEE: [
|
|
125
|
+
METEORA_DLMM_CREATE_POSITION: [144, 142, 252, 84, 157, 53, 37, 121],
|
|
126
|
+
METEORA_DLMM_CLOSE_POSITION: [255, 196, 16, 107, 28, 202, 53, 128],
|
|
127
|
+
METEORA_DLMM_CLAIM_FEE: [75, 122, 154, 48, 140, 74, 123, 163],
|
|
128
|
+
METEORA_DLMM_CLAIM_FEE2: [232, 171, 242, 97, 58, 77, 35, 45],
|
|
127
129
|
RAYDIUM_LAUNCHLAB_POOL_CREATE: [151, 215, 226, 9, 118, 161, 115, 174],
|
|
128
130
|
RAYDIUM_LAUNCHLAB_TRADE: [189, 219, 127, 211, 78, 230, 97, 238],
|
|
129
131
|
};
|
|
@@ -200,6 +202,28 @@ const IX = {
|
|
|
200
202
|
[80, 85, 209, 72, 24, 206, 177, 108],
|
|
201
203
|
[95, 180, 10, 172, 84, 174, 232, 40],
|
|
202
204
|
],
|
|
205
|
+
METEORA_DLMM: [
|
|
206
|
+
[181, 157, 89, 67, 143, 182, 52, 72],
|
|
207
|
+
[228, 162, 78, 28, 70, 219, 116, 115],
|
|
208
|
+
[169, 32, 79, 137, 136, 232, 70, 137],
|
|
209
|
+
[112, 191, 101, 171, 28, 144, 127, 187],
|
|
210
|
+
[123, 134, 81, 0, 49, 68, 98, 98],
|
|
211
|
+
[174, 90, 35, 115, 186, 40, 147, 226],
|
|
212
|
+
[35, 86, 19, 185, 78, 212, 75, 211],
|
|
213
|
+
[45, 154, 237, 210, 221, 15, 166, 92],
|
|
214
|
+
[73, 59, 36, 120, 237, 83, 108, 198],
|
|
215
|
+
[219, 192, 234, 71, 190, 191, 102, 80],
|
|
216
|
+
[143, 19, 242, 145, 213, 15, 104, 115],
|
|
217
|
+
[46, 82, 125, 146, 85, 141, 228, 153],
|
|
218
|
+
[80, 85, 209, 72, 24, 206, 177, 108],
|
|
219
|
+
[230, 215, 82, 127, 241, 101, 227, 146],
|
|
220
|
+
[248, 198, 158, 145, 225, 117, 135, 200],
|
|
221
|
+
[65, 75, 63, 76, 235, 91, 91, 136],
|
|
222
|
+
[250, 73, 101, 33, 38, 207, 75, 184],
|
|
223
|
+
[43, 215, 247, 132, 137, 60, 243, 81],
|
|
224
|
+
[56, 173, 230, 208, 173, 228, 156, 205],
|
|
225
|
+
[74, 98, 192, 214, 177, 51, 75, 51],
|
|
226
|
+
],
|
|
203
227
|
};
|
|
204
228
|
function firstByteIn(data, allowed) {
|
|
205
229
|
return data.length > 0 && allowed.includes(data[0]);
|
|
@@ -213,7 +237,7 @@ function normalInstructionDataMayParse(programId, data) {
|
|
|
213
237
|
if (programId === program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID)
|
|
214
238
|
return firstByteIn(data, [1, 3, 4, 7, 9, 11]);
|
|
215
239
|
if (programId === program_ids_js_1.METEORA_DLMM_PROGRAM_ID)
|
|
216
|
-
return
|
|
240
|
+
return headIn(data, IX.METEORA_DLMM);
|
|
217
241
|
if (programId === program_ids_js_1.METEORA_DAMM_V2_PROGRAM_ID) {
|
|
218
242
|
return discEq(data, LOG.METEORA_DAMM_INITIALIZE_POOL);
|
|
219
243
|
}
|
|
@@ -243,7 +267,7 @@ function parseInnerCompiledInstructionIfSupported(data, accounts, signature, slo
|
|
|
243
267
|
return (0, mod_js_1.parseInstructionUnified)(data, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs, filter, programId);
|
|
244
268
|
}
|
|
245
269
|
function parsePumpFeesInner(disc, data, metadata) {
|
|
246
|
-
const eventDisc =
|
|
270
|
+
const eventDisc = eventCpiDiscriminator(disc);
|
|
247
271
|
if (eventDisc === null)
|
|
248
272
|
return null;
|
|
249
273
|
if (eventDisc === disc8(LOG.PUMP_FEES_CREATE_FEE_SHARING_CONFIG)) {
|
|
@@ -431,12 +455,10 @@ function parseInnerInstructionUnified(instructionData, accounts, signature, slot
|
|
|
431
455
|
else if (programId === program_ids_js_1.METEORA_DLMM_PROGRAM_ID) {
|
|
432
456
|
if (filter && !(0, types_js_1.eventTypeFilterIncludesMeteoraDlmm)(filter))
|
|
433
457
|
return null;
|
|
434
|
-
|
|
458
|
+
const eventDisc = eventCpiDiscriminator(disc);
|
|
459
|
+
if (eventDisc === null)
|
|
435
460
|
return null;
|
|
436
|
-
|
|
437
|
-
decoded.set(disc.subarray(0, 8), 0);
|
|
438
|
-
decoded.set(data, 8);
|
|
439
|
-
ev = (0, meteora_dlmm_js_1.parseDlmmFromDecoded)(decoded, metadata);
|
|
461
|
+
ev = (0, meteora_dlmm_js_1.parseDlmmEventFromData)(eventDisc, data, metadata);
|
|
440
462
|
}
|
|
441
463
|
else if (programId === program_ids_js_1.RAYDIUM_LAUNCHLAB_PROGRAM_ID) {
|
|
442
464
|
if (filter && !(0, types_js_1.eventTypeFilterIncludesRaydiumLaunchlab)(filter))
|
|
@@ -5,100 +5,157 @@ const dex_event_js_1 = require("../core/dex_event.js");
|
|
|
5
5
|
const binary_js_1 = require("../util/binary.js");
|
|
6
6
|
const utils_js_1 = require("./utils.js");
|
|
7
7
|
const Z = (0, dex_event_js_1.defaultPubkey)();
|
|
8
|
+
function discEq(data, bytes) {
|
|
9
|
+
return data.length >= 8 && bytes.every((b, i) => data[i] === b);
|
|
10
|
+
}
|
|
11
|
+
const IX = {
|
|
12
|
+
ADD_LIQUIDITY: [181, 157, 89, 67, 143, 182, 52, 72],
|
|
13
|
+
ADD_LIQUIDITY2: [228, 162, 78, 28, 70, 219, 116, 115],
|
|
14
|
+
CLAIM_FEE: [169, 32, 79, 137, 136, 232, 70, 137],
|
|
15
|
+
CLAIM_FEE2: [112, 191, 101, 171, 28, 144, 127, 187],
|
|
16
|
+
CLOSE_POSITION: [123, 134, 81, 0, 49, 68, 98, 98],
|
|
17
|
+
CLOSE_POSITION2: [174, 90, 35, 115, 186, 40, 147, 226],
|
|
18
|
+
INITIALIZE_BIN_ARRAY: [35, 86, 19, 185, 78, 212, 75, 211],
|
|
19
|
+
INITIALIZE_LB_PAIR: [45, 154, 237, 210, 221, 15, 166, 92],
|
|
20
|
+
INITIALIZE_LB_PAIR2: [73, 59, 36, 120, 237, 83, 108, 198],
|
|
21
|
+
INITIALIZE_POSITION: [219, 192, 234, 71, 190, 191, 102, 80],
|
|
22
|
+
INITIALIZE_POSITION2: [143, 19, 242, 145, 213, 15, 104, 115],
|
|
23
|
+
INITIALIZE_POSITION_PDA: [46, 82, 125, 146, 85, 141, 228, 153],
|
|
24
|
+
REMOVE_LIQUIDITY: [80, 85, 209, 72, 24, 206, 177, 108],
|
|
25
|
+
REMOVE_LIQUIDITY2: [230, 215, 82, 127, 241, 101, 227, 146],
|
|
26
|
+
SWAP: [248, 198, 158, 145, 225, 117, 135, 200],
|
|
27
|
+
SWAP2: [65, 75, 63, 76, 235, 91, 91, 136],
|
|
28
|
+
SWAP_EXACT_OUT: [250, 73, 101, 33, 38, 207, 75, 184],
|
|
29
|
+
SWAP_EXACT_OUT2: [43, 215, 247, 132, 137, 60, 243, 81],
|
|
30
|
+
SWAP_WITH_PRICE_IMPACT: [56, 173, 230, 208, 173, 228, 156, 205],
|
|
31
|
+
SWAP_WITH_PRICE_IMPACT2: [74, 98, 192, 214, 177, 51, 75, 51],
|
|
32
|
+
};
|
|
8
33
|
function parseMeteoraDlmmInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
|
|
9
|
-
if (instructionData.length
|
|
10
|
-
return null;
|
|
11
|
-
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
12
|
-
if (!pool)
|
|
34
|
+
if (instructionData.length < 8)
|
|
13
35
|
return null;
|
|
14
36
|
const metadata = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
17
|
-
|
|
37
|
+
const data = instructionData.subarray(8);
|
|
38
|
+
if (discEq(instructionData, IX.INITIALIZE_LB_PAIR)) {
|
|
39
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
40
|
+
if (!pool || data.length < 6)
|
|
18
41
|
return null;
|
|
19
|
-
const active_bin_id = (0, binary_js_1.readI32LE)(
|
|
20
|
-
const bin_step = (0, binary_js_1.readU16LE)(
|
|
42
|
+
const active_bin_id = (0, binary_js_1.readI32LE)(data, 0);
|
|
43
|
+
const bin_step = (0, binary_js_1.readU16LE)(data, 4);
|
|
21
44
|
if (active_bin_id === null || bin_step === null)
|
|
22
45
|
return null;
|
|
23
46
|
return {
|
|
24
47
|
MeteoraDlmmInitializePool: {
|
|
25
48
|
metadata,
|
|
26
49
|
pool,
|
|
27
|
-
creator: (0, utils_js_1.getAccount)(accounts,
|
|
50
|
+
creator: (0, utils_js_1.getAccount)(accounts, 8) ?? Z,
|
|
28
51
|
active_bin_id,
|
|
29
52
|
bin_step,
|
|
30
53
|
},
|
|
31
54
|
};
|
|
32
55
|
}
|
|
33
|
-
if (
|
|
34
|
-
|
|
56
|
+
if (discEq(instructionData, IX.INITIALIZE_LB_PAIR2)) {
|
|
57
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
58
|
+
if (!pool || data.length < 4)
|
|
59
|
+
return null;
|
|
60
|
+
return {
|
|
61
|
+
MeteoraDlmmInitializePool: {
|
|
62
|
+
metadata,
|
|
63
|
+
pool,
|
|
64
|
+
creator: (0, utils_js_1.getAccount)(accounts, 8) ?? Z,
|
|
65
|
+
active_bin_id: (0, binary_js_1.readI32LE)(data, 0) ?? 0,
|
|
66
|
+
bin_step: 0,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (discEq(instructionData, IX.INITIALIZE_BIN_ARRAY)) {
|
|
71
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
72
|
+
if (!pool || data.length < 8)
|
|
35
73
|
return null;
|
|
36
74
|
return {
|
|
37
75
|
MeteoraDlmmInitializeBinArray: {
|
|
38
76
|
metadata,
|
|
39
77
|
pool,
|
|
40
78
|
bin_array: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
|
|
41
|
-
index: (0, binary_js_1.
|
|
79
|
+
index: (0, binary_js_1.readI64LE)(data, 0) ?? 0n,
|
|
42
80
|
},
|
|
43
81
|
};
|
|
44
82
|
}
|
|
45
|
-
if (
|
|
46
|
-
|
|
83
|
+
if (discEq(instructionData, IX.ADD_LIQUIDITY) || discEq(instructionData, IX.ADD_LIQUIDITY2)) {
|
|
84
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 1);
|
|
85
|
+
if (!pool)
|
|
86
|
+
return null;
|
|
87
|
+
const senderIndex = discEq(instructionData, IX.ADD_LIQUIDITY2) ? 9 : 11;
|
|
88
|
+
const from = (0, utils_js_1.getAccount)(accounts, senderIndex);
|
|
89
|
+
if (!from)
|
|
47
90
|
return null;
|
|
48
91
|
return {
|
|
49
92
|
MeteoraDlmmAddLiquidity: {
|
|
50
93
|
metadata,
|
|
51
94
|
pool,
|
|
52
|
-
from
|
|
53
|
-
position: (0, utils_js_1.getAccount)(accounts,
|
|
95
|
+
from,
|
|
96
|
+
position: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
|
|
54
97
|
amounts: [0n, 0n],
|
|
55
98
|
active_bin_id: 0,
|
|
56
99
|
},
|
|
57
100
|
};
|
|
58
101
|
}
|
|
59
|
-
if (
|
|
60
|
-
|
|
102
|
+
if (discEq(instructionData, IX.REMOVE_LIQUIDITY) || discEq(instructionData, IX.REMOVE_LIQUIDITY2)) {
|
|
103
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 1);
|
|
104
|
+
if (!pool)
|
|
105
|
+
return null;
|
|
106
|
+
const senderIndex = discEq(instructionData, IX.REMOVE_LIQUIDITY2) ? 9 : 11;
|
|
107
|
+
const from = (0, utils_js_1.getAccount)(accounts, senderIndex);
|
|
108
|
+
if (!from)
|
|
61
109
|
return null;
|
|
62
110
|
return {
|
|
63
111
|
MeteoraDlmmRemoveLiquidity: {
|
|
64
112
|
metadata,
|
|
65
113
|
pool,
|
|
66
|
-
from
|
|
67
|
-
position: (0, utils_js_1.getAccount)(accounts,
|
|
114
|
+
from,
|
|
115
|
+
position: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
|
|
68
116
|
amounts: [0n, 0n],
|
|
69
117
|
active_bin_id: 0,
|
|
70
118
|
},
|
|
71
119
|
};
|
|
72
120
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
121
|
+
if (discEq(instructionData, IX.INITIALIZE_POSITION) ||
|
|
122
|
+
discEq(instructionData, IX.INITIALIZE_POSITION2) ||
|
|
123
|
+
discEq(instructionData, IX.INITIALIZE_POSITION_PDA)) {
|
|
124
|
+
if (data.length < 8)
|
|
125
|
+
return null;
|
|
126
|
+
const lower_bin_id = (0, binary_js_1.readI32LE)(data, 0);
|
|
127
|
+
const width = (0, binary_js_1.readI32LE)(data, 4);
|
|
128
|
+
if (lower_bin_id === null || width === null || width < 0)
|
|
75
129
|
return null;
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
|
|
130
|
+
const pda = discEq(instructionData, IX.INITIALIZE_POSITION_PDA);
|
|
131
|
+
const position = (0, utils_js_1.getAccount)(accounts, pda ? 2 : 1);
|
|
132
|
+
const pool = (0, utils_js_1.getAccount)(accounts, pda ? 3 : 2);
|
|
133
|
+
const owner = (0, utils_js_1.getAccount)(accounts, pda ? 4 : 3);
|
|
134
|
+
if (!position || !pool || !owner)
|
|
79
135
|
return null;
|
|
80
136
|
return {
|
|
81
137
|
MeteoraDlmmCreatePosition: {
|
|
82
138
|
metadata,
|
|
83
139
|
pool,
|
|
84
|
-
position
|
|
85
|
-
owner
|
|
140
|
+
position,
|
|
141
|
+
owner,
|
|
86
142
|
lower_bin_id,
|
|
87
143
|
width,
|
|
88
144
|
},
|
|
89
145
|
};
|
|
90
146
|
}
|
|
91
|
-
if (
|
|
92
|
-
|
|
147
|
+
if (discEq(instructionData, IX.SWAP) || discEq(instructionData, IX.SWAP2)) {
|
|
148
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
149
|
+
if (!pool || data.length < 16)
|
|
93
150
|
return null;
|
|
94
151
|
return {
|
|
95
152
|
MeteoraDlmmSwap: {
|
|
96
153
|
metadata,
|
|
97
154
|
pool,
|
|
98
|
-
from: (0, utils_js_1.getAccount)(accounts,
|
|
155
|
+
from: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
|
|
99
156
|
start_bin_id: 0,
|
|
100
157
|
end_bin_id: 0,
|
|
101
|
-
amount_in: (0, binary_js_1.readU64LE)(
|
|
158
|
+
amount_in: (0, binary_js_1.readU64LE)(data, 0) ?? 0n,
|
|
102
159
|
amount_out: 0n,
|
|
103
160
|
swap_for_y: false,
|
|
104
161
|
fee: 0n,
|
|
@@ -108,25 +165,60 @@ function parseMeteoraDlmmInstruction(instructionData, accounts, signature, slot,
|
|
|
108
165
|
},
|
|
109
166
|
};
|
|
110
167
|
}
|
|
111
|
-
if (
|
|
168
|
+
if (discEq(instructionData, IX.SWAP_EXACT_OUT) ||
|
|
169
|
+
discEq(instructionData, IX.SWAP_EXACT_OUT2) ||
|
|
170
|
+
discEq(instructionData, IX.SWAP_WITH_PRICE_IMPACT) ||
|
|
171
|
+
discEq(instructionData, IX.SWAP_WITH_PRICE_IMPACT2)) {
|
|
172
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
173
|
+
if (!pool || data.length < 8)
|
|
174
|
+
return null;
|
|
175
|
+
return {
|
|
176
|
+
MeteoraDlmmSwap: {
|
|
177
|
+
metadata,
|
|
178
|
+
pool,
|
|
179
|
+
from: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
|
|
180
|
+
start_bin_id: 0,
|
|
181
|
+
end_bin_id: 0,
|
|
182
|
+
amount_in: (0, binary_js_1.readU64LE)(data, 0) ?? 0n,
|
|
183
|
+
amount_out: discEq(instructionData, IX.SWAP_EXACT_OUT) || discEq(instructionData, IX.SWAP_EXACT_OUT2)
|
|
184
|
+
? (0, binary_js_1.readU64LE)(data, 8) ?? 0n
|
|
185
|
+
: 0n,
|
|
186
|
+
swap_for_y: false,
|
|
187
|
+
fee: 0n,
|
|
188
|
+
protocol_fee: 0n,
|
|
189
|
+
fee_bps: 0n,
|
|
190
|
+
host_fee: 0n,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (discEq(instructionData, IX.CLAIM_FEE) || discEq(instructionData, IX.CLAIM_FEE2)) {
|
|
195
|
+
const pool = (0, utils_js_1.getAccount)(accounts, 0);
|
|
196
|
+
const owner = (0, utils_js_1.getAccount)(accounts, discEq(instructionData, IX.CLAIM_FEE2) ? 2 : 4);
|
|
197
|
+
if (!pool || !owner)
|
|
198
|
+
return null;
|
|
112
199
|
return {
|
|
113
200
|
MeteoraDlmmClaimFee: {
|
|
114
201
|
metadata,
|
|
115
202
|
pool,
|
|
116
203
|
position: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
|
|
117
|
-
owner
|
|
204
|
+
owner,
|
|
118
205
|
fee_x: 0n,
|
|
119
206
|
fee_y: 0n,
|
|
120
207
|
},
|
|
121
208
|
};
|
|
122
209
|
}
|
|
123
|
-
if (
|
|
210
|
+
if (discEq(instructionData, IX.CLOSE_POSITION) || discEq(instructionData, IX.CLOSE_POSITION2)) {
|
|
211
|
+
const position = (0, utils_js_1.getAccount)(accounts, 0);
|
|
212
|
+
const v2 = discEq(instructionData, IX.CLOSE_POSITION2);
|
|
213
|
+
const owner = (0, utils_js_1.getAccount)(accounts, v2 ? 1 : 4);
|
|
214
|
+
if (!position || !owner)
|
|
215
|
+
return null;
|
|
124
216
|
return {
|
|
125
217
|
MeteoraDlmmClosePosition: {
|
|
126
218
|
metadata,
|
|
127
|
-
pool,
|
|
128
|
-
position
|
|
129
|
-
owner
|
|
219
|
+
pool: v2 ? Z : (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
|
|
220
|
+
position,
|
|
221
|
+
owner,
|
|
130
222
|
},
|
|
131
223
|
};
|
|
132
224
|
}
|
|
@@ -34,10 +34,11 @@ function parseOrcaWhirlpoolInstruction(instructionData, accounts, signature, slo
|
|
|
34
34
|
return null;
|
|
35
35
|
const input_amount = amount_specified_is_input ? amount : 0n;
|
|
36
36
|
const output_amount = amount_specified_is_input ? other_threshold : amount;
|
|
37
|
+
const whirlpoolIndex = discEq(instructionData, DISC.SWAP_V2) ? 4 : 2;
|
|
37
38
|
return {
|
|
38
39
|
OrcaWhirlpoolSwap: {
|
|
39
40
|
metadata: meta,
|
|
40
|
-
whirlpool: (0, utils_js_1.getAccount)(accounts,
|
|
41
|
+
whirlpool: (0, utils_js_1.getAccount)(accounts, whirlpoolIndex) ?? Z,
|
|
41
42
|
a_to_b,
|
|
42
43
|
pre_sqrt_price: sqrt_price_limit,
|
|
43
44
|
post_sqrt_price: 0n,
|
|
@@ -94,6 +94,11 @@ function buyLike(data, accounts, meta, swapOrder) {
|
|
|
94
94
|
ix_name: "",
|
|
95
95
|
cashback_fee_basis_points: 0n,
|
|
96
96
|
cashback: 0n,
|
|
97
|
+
buyback_fee_basis_points: 0n,
|
|
98
|
+
buyback_fee: 0n,
|
|
99
|
+
virtual_quote_reserves: 0n,
|
|
100
|
+
can_boost: false,
|
|
101
|
+
base_supply: 0n,
|
|
97
102
|
is_pump_pool: false,
|
|
98
103
|
base_mint: g(3),
|
|
99
104
|
quote_mint: g(4),
|
|
@@ -157,6 +162,11 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
|
|
|
157
162
|
coin_creator_fee: 0n,
|
|
158
163
|
cashback_fee_basis_points: 0n,
|
|
159
164
|
cashback: 0n,
|
|
165
|
+
buyback_fee_basis_points: 0n,
|
|
166
|
+
buyback_fee: 0n,
|
|
167
|
+
virtual_quote_reserves: 0n,
|
|
168
|
+
can_boost: false,
|
|
169
|
+
base_supply: 0n,
|
|
160
170
|
is_pump_pool: false,
|
|
161
171
|
base_mint: g(3),
|
|
162
172
|
quote_mint: g(4),
|