sol-parser-sdk 0.5.9 → 0.5.11

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.
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseDlmmFromDecoded = parseDlmmFromDecoded;
4
+ exports.parseDlmmEventFromData = parseDlmmEventFromData;
4
5
  exports.parseMeteoraDlmmLog = parseMeteoraDlmmLog;
5
6
  /** Meteora DLMM 结构化日志解析 */
6
7
  const metadata_js_1 = require("../core/metadata.js");
8
+ const dex_event_js_1 = require("../core/dex_event.js");
7
9
  const program_data_js_1 = require("./program_data.js");
8
10
  const binary_js_1 = require("../util/binary.js");
9
11
  function disc(bytes) {
@@ -13,14 +15,23 @@ function disc(bytes) {
13
15
  return new DataView(u8.buffer).getBigUint64(0, true);
14
16
  }
15
17
  const DLMM = {
16
- SWAP: disc([143, 190, 90, 218, 196, 30, 51, 222]),
17
- ADD_LIQ: disc([181, 157, 89, 67, 143, 182, 52, 72]),
18
- REMOVE_LIQ: disc([80, 85, 209, 72, 24, 206, 35, 178]),
18
+ SWAP: disc([81, 108, 227, 190, 205, 208, 10, 196]),
19
+ SWAP2: disc([46, 116, 82, 215, 148, 27, 84, 77]),
20
+ ADD_LIQ: disc([31, 94, 125, 90, 227, 52, 61, 186]),
21
+ REMOVE_LIQ: disc([116, 244, 97, 232, 103, 31, 152, 58]),
19
22
  INIT_BIN_ARRAY: disc([11, 18, 155, 194, 33, 115, 238, 119]),
20
- INIT_POOL: disc([95, 180, 10, 172, 84, 174, 232, 40]),
21
- CREATE_POS: disc([123, 233, 11, 43, 146, 180, 97, 119]),
22
- CLOSE_POS: disc([94, 168, 102, 45, 59, 122, 137, 54]),
23
- CLAIM_FEE: disc([152, 70, 208, 111, 104, 91, 44, 1]),
23
+ INIT_POOL: disc([185, 74, 252, 125, 27, 215, 188, 111]),
24
+ CREATE_POS: disc([144, 142, 252, 84, 157, 53, 37, 121]),
25
+ CLOSE_POS: disc([255, 196, 16, 107, 28, 202, 53, 128]),
26
+ CLAIM_FEE: disc([75, 122, 154, 48, 140, 74, 123, 163]),
27
+ CLAIM_FEE2: disc([232, 171, 242, 97, 58, 77, 35, 45]),
28
+ LEGACY_SWAP: disc([143, 190, 90, 218, 196, 30, 51, 222]),
29
+ LEGACY_ADD_LIQ: disc([181, 157, 89, 67, 143, 182, 52, 72]),
30
+ LEGACY_REMOVE_LIQ: disc([80, 85, 209, 72, 24, 206, 35, 178]),
31
+ LEGACY_INIT_POOL: disc([95, 180, 10, 172, 84, 174, 232, 40]),
32
+ LEGACY_CREATE_POS: disc([123, 233, 11, 43, 146, 180, 97, 119]),
33
+ LEGACY_CLOSE_POS: disc([94, 168, 102, 45, 59, 122, 137, 54]),
34
+ LEGACY_CLAIM_FEE: disc([152, 70, 208, 111, 104, 91, 44, 1]),
24
35
  };
25
36
  function bn64(v) {
26
37
  return v ?? 0n;
@@ -31,7 +42,12 @@ function parseDlmmFromDecoded(programData, metadata) {
31
42
  const dv = new DataView(programData.buffer, programData.byteOffset, 8);
32
43
  const discriminator = dv.getBigUint64(0, true);
33
44
  const data = programData.subarray(8);
34
- if (discriminator === DLMM.SWAP) {
45
+ return parseDlmmEventFromData(discriminator, data, metadata);
46
+ }
47
+ function parseDlmmEventFromData(discriminator, data, metadata) {
48
+ if (discriminator === DLMM.SWAP || discriminator === DLMM.LEGACY_SWAP) {
49
+ if (data.length < 129)
50
+ return null;
35
51
  let o = 0;
36
52
  const pool = (0, binary_js_1.readPubkey)(data, o);
37
53
  o += 32;
@@ -70,7 +86,52 @@ function parseDlmmFromDecoded(programData, metadata) {
70
86
  };
71
87
  return { MeteoraDlmmSwap: ev };
72
88
  }
73
- if (discriminator === DLMM.ADD_LIQ) {
89
+ if (discriminator === DLMM.SWAP2) {
90
+ if (data.length < 147)
91
+ return null;
92
+ let o = 0;
93
+ const pool = (0, binary_js_1.readPubkey)(data, o);
94
+ o += 32;
95
+ const from = (0, binary_js_1.readPubkey)(data, o);
96
+ o += 32;
97
+ const start_bin_id = (0, binary_js_1.readI32LE)(data, o);
98
+ o += 4;
99
+ const end_bin_id = (0, binary_js_1.readI32LE)(data, o);
100
+ o += 4;
101
+ const swap_for_y = (0, binary_js_1.readBool)(data, o);
102
+ o += 1;
103
+ const fee_bps = (0, binary_js_1.readU128LE)(data, o);
104
+ o += 16;
105
+ const amount_in = bn64((0, binary_js_1.readU64LE)(data, o));
106
+ o += 8;
107
+ o += 8; // amount_left
108
+ const amount_out = bn64((0, binary_js_1.readU64LE)(data, o));
109
+ o += 8;
110
+ const fee = bn64((0, binary_js_1.readU64LE)(data, o));
111
+ o += 8;
112
+ const protocol_fee = bn64((0, binary_js_1.readU64LE)(data, o));
113
+ o += 8;
114
+ o += 8; // limit_order_fee
115
+ const host_fee = bn64((0, binary_js_1.readU64LE)(data, o));
116
+ const ev = {
117
+ metadata,
118
+ pool,
119
+ from,
120
+ start_bin_id,
121
+ end_bin_id,
122
+ amount_in,
123
+ amount_out,
124
+ swap_for_y,
125
+ fee,
126
+ protocol_fee,
127
+ fee_bps,
128
+ host_fee,
129
+ };
130
+ return { MeteoraDlmmSwap: ev };
131
+ }
132
+ if (discriminator === DLMM.ADD_LIQ || discriminator === DLMM.LEGACY_ADD_LIQ) {
133
+ if (data.length < 116)
134
+ return null;
74
135
  let o = 0;
75
136
  const pool = (0, binary_js_1.readPubkey)(data, o);
76
137
  o += 32;
@@ -93,7 +154,9 @@ function parseDlmmFromDecoded(programData, metadata) {
93
154
  };
94
155
  return { MeteoraDlmmAddLiquidity: ev };
95
156
  }
96
- if (discriminator === DLMM.REMOVE_LIQ) {
157
+ if (discriminator === DLMM.REMOVE_LIQ || discriminator === DLMM.LEGACY_REMOVE_LIQ) {
158
+ if (data.length < 116)
159
+ return null;
97
160
  let o = 0;
98
161
  const pool = (0, binary_js_1.readPubkey)(data, o);
99
162
  o += 32;
@@ -117,6 +180,24 @@ function parseDlmmFromDecoded(programData, metadata) {
117
180
  return { MeteoraDlmmRemoveLiquidity: ev };
118
181
  }
119
182
  if (discriminator === DLMM.INIT_POOL) {
183
+ if (data.length < 98)
184
+ return null;
185
+ let o = 0;
186
+ const pool = (0, binary_js_1.readPubkey)(data, o);
187
+ o += 32;
188
+ const bin_step = (0, binary_js_1.readU16LE)(data, o);
189
+ const ev = {
190
+ metadata,
191
+ pool,
192
+ creator: (0, dex_event_js_1.defaultPubkey)(),
193
+ active_bin_id: 0,
194
+ bin_step,
195
+ };
196
+ return { MeteoraDlmmInitializePool: ev };
197
+ }
198
+ if (discriminator === DLMM.LEGACY_INIT_POOL) {
199
+ if (data.length < 70)
200
+ return null;
120
201
  let o = 0;
121
202
  const pool = (0, binary_js_1.readPubkey)(data, o);
122
203
  o += 32;
@@ -135,6 +216,8 @@ function parseDlmmFromDecoded(programData, metadata) {
135
216
  return { MeteoraDlmmInitializePool: ev };
136
217
  }
137
218
  if (discriminator === DLMM.INIT_BIN_ARRAY) {
219
+ if (data.length < 72)
220
+ return null;
138
221
  let o = 0;
139
222
  const pool = (0, binary_js_1.readPubkey)(data, o);
140
223
  o += 32;
@@ -145,6 +228,27 @@ function parseDlmmFromDecoded(programData, metadata) {
145
228
  return { MeteoraDlmmInitializeBinArray: ev };
146
229
  }
147
230
  if (discriminator === DLMM.CREATE_POS) {
231
+ if (data.length < 96)
232
+ return null;
233
+ let o = 0;
234
+ const pool = (0, binary_js_1.readPubkey)(data, o);
235
+ o += 32;
236
+ const position = (0, binary_js_1.readPubkey)(data, o);
237
+ o += 32;
238
+ const owner = (0, binary_js_1.readPubkey)(data, o);
239
+ const ev = {
240
+ metadata,
241
+ pool,
242
+ position,
243
+ owner,
244
+ lower_bin_id: 0,
245
+ width: 0,
246
+ };
247
+ return { MeteoraDlmmCreatePosition: ev };
248
+ }
249
+ if (discriminator === DLMM.LEGACY_CREATE_POS) {
250
+ if (data.length < 104)
251
+ return null;
148
252
  let o = 0;
149
253
  const pool = (0, binary_js_1.readPubkey)(data, o);
150
254
  o += 32;
@@ -166,6 +270,23 @@ function parseDlmmFromDecoded(programData, metadata) {
166
270
  return { MeteoraDlmmCreatePosition: ev };
167
271
  }
168
272
  if (discriminator === DLMM.CLOSE_POS) {
273
+ if (data.length < 64)
274
+ return null;
275
+ let o = 0;
276
+ const position = (0, binary_js_1.readPubkey)(data, o);
277
+ o += 32;
278
+ const owner = (0, binary_js_1.readPubkey)(data, o);
279
+ const ev = {
280
+ metadata,
281
+ pool: (0, dex_event_js_1.defaultPubkey)(),
282
+ position,
283
+ owner,
284
+ };
285
+ return { MeteoraDlmmClosePosition: ev };
286
+ }
287
+ if (discriminator === DLMM.LEGACY_CLOSE_POS) {
288
+ if (data.length < 96)
289
+ return null;
169
290
  let o = 0;
170
291
  const pool = (0, binary_js_1.readPubkey)(data, o);
171
292
  o += 32;
@@ -175,7 +296,10 @@ function parseDlmmFromDecoded(programData, metadata) {
175
296
  const ev = { metadata, pool, position, owner };
176
297
  return { MeteoraDlmmClosePosition: ev };
177
298
  }
178
- if (discriminator === DLMM.CLAIM_FEE) {
299
+ if (discriminator === DLMM.CLAIM_FEE || discriminator === DLMM.CLAIM_FEE2 || discriminator === DLMM.LEGACY_CLAIM_FEE) {
300
+ const requiredLength = discriminator === DLMM.CLAIM_FEE2 ? 116 : 112;
301
+ if (data.length < requiredLength)
302
+ return null;
179
303
  let o = 0;
180
304
  const pool = (0, binary_js_1.readPubkey)(data, o);
181
305
  o += 32;
@@ -28,14 +28,16 @@ const binary_js_1 = require("../util/binary.js");
28
28
  const program_log_discriminators_js_1 = require("./program_log_discriminators.js");
29
29
  const program_ids_js_1 = require("../grpc/program_ids.js");
30
30
  const DLMM_DISC = {
31
- SWAP: program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_IN,
32
- ADD_LIQUIDITY: (0, program_log_discriminators_js_1.u64leDiscriminator)([181, 157, 89, 67, 143, 182, 52, 72]),
33
- REMOVE_LIQUIDITY: (0, program_log_discriminators_js_1.u64leDiscriminator)([80, 85, 209, 72, 24, 206, 35, 178]),
34
- INITIALIZE_POOL: (0, program_log_discriminators_js_1.u64leDiscriminator)([95, 180, 10, 172, 84, 174, 232, 40]),
31
+ SWAP: (0, program_log_discriminators_js_1.u64leDiscriminator)([81, 108, 227, 190, 205, 208, 10, 196]),
32
+ SWAP2: (0, program_log_discriminators_js_1.u64leDiscriminator)([46, 116, 82, 215, 148, 27, 84, 77]),
33
+ ADD_LIQUIDITY: (0, program_log_discriminators_js_1.u64leDiscriminator)([31, 94, 125, 90, 227, 52, 61, 186]),
34
+ REMOVE_LIQUIDITY: (0, program_log_discriminators_js_1.u64leDiscriminator)([116, 244, 97, 232, 103, 31, 152, 58]),
35
+ INITIALIZE_POOL: (0, program_log_discriminators_js_1.u64leDiscriminator)([185, 74, 252, 125, 27, 215, 188, 111]),
35
36
  INITIALIZE_BIN_ARRAY: (0, program_log_discriminators_js_1.u64leDiscriminator)([11, 18, 155, 194, 33, 115, 238, 119]),
36
- CREATE_POSITION: (0, program_log_discriminators_js_1.u64leDiscriminator)([123, 233, 11, 43, 146, 180, 97, 119]),
37
- CLOSE_POSITION: (0, program_log_discriminators_js_1.u64leDiscriminator)([94, 168, 102, 45, 59, 122, 137, 54]),
38
- CLAIM_FEE: (0, program_log_discriminators_js_1.u64leDiscriminator)([152, 70, 208, 111, 104, 91, 44, 1]),
37
+ CREATE_POSITION: (0, program_log_discriminators_js_1.u64leDiscriminator)([144, 142, 252, 84, 157, 53, 37, 121]),
38
+ CLOSE_POSITION: (0, program_log_discriminators_js_1.u64leDiscriminator)([255, 196, 16, 107, 28, 202, 53, 128]),
39
+ CLAIM_FEE: (0, program_log_discriminators_js_1.u64leDiscriminator)([75, 122, 154, 48, 140, 74, 123, 163]),
40
+ CLAIM_FEE2: (0, program_log_discriminators_js_1.u64leDiscriminator)([232, 171, 242, 97, 58, 77, 35, 45]),
39
41
  };
40
42
  function discriminatorToEventType(disc) {
41
43
  if (disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.PUMPFUN_CREATE)
@@ -247,7 +249,9 @@ function programScopedDiscriminatorToEventType(programId, disc) {
247
249
  return null;
248
250
  }
249
251
  if (programId === program_ids_js_1.RAYDIUM_CPMM_PROGRAM_ID) {
250
- if (disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_IN || disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_OUT)
252
+ if (disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_EVENT ||
253
+ disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_IN ||
254
+ disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_OUT)
251
255
  return "RaydiumCpmmSwap";
252
256
  if (disc === program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_CREATE_POOL)
253
257
  return "RaydiumCpmmInitialize";
@@ -321,7 +325,7 @@ function programScopedDiscriminatorToEventType(programId, disc) {
321
325
  return null;
322
326
  }
323
327
  if (programId === program_ids_js_1.METEORA_DLMM_PROGRAM_ID) {
324
- if (disc === DLMM_DISC.SWAP)
328
+ if (disc === DLMM_DISC.SWAP || disc === DLMM_DISC.SWAP2)
325
329
  return "MeteoraDlmmSwap";
326
330
  if (disc === DLMM_DISC.ADD_LIQUIDITY)
327
331
  return "MeteoraDlmmAddLiquidity";
@@ -335,7 +339,7 @@ function programScopedDiscriminatorToEventType(programId, disc) {
335
339
  return "MeteoraDlmmCreatePosition";
336
340
  if (disc === DLMM_DISC.CLOSE_POSITION)
337
341
  return "MeteoraDlmmClosePosition";
338
- if (disc === DLMM_DISC.CLAIM_FEE)
342
+ if (disc === DLMM_DISC.CLAIM_FEE || disc === DLMM_DISC.CLAIM_FEE2)
339
343
  return "MeteoraDlmmClaimFee";
340
344
  return null;
341
345
  }
@@ -568,6 +572,15 @@ function parseUnscopedPumpfunLaunchlabTrade(data, metadata, filter, isCreatedBuy
568
572
  return null;
569
573
  }
570
574
  function parseLogOptimized(log, signature, slot, txIndex, blockTimeUs, grpcRecvUs, eventTypeFilter, isCreatedBuy, recentBlockhash, programId) {
575
+ if (programId === program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID && log.indexOf("ray_log: ") >= 0) {
576
+ if (eventTypeFilter && !eventTypeFilter.shouldInclude("RaydiumAmmV4Swap"))
577
+ return null;
578
+ const rb = recentBlockhash && recentBlockhash.length > 0
579
+ ? bs58_1.default.encode(recentBlockhash)
580
+ : undefined;
581
+ const metadata = (0, metadata_js_1.makeMetadata)(signature, slot, txIndex, blockTimeUs, grpcRecvUs, rb);
582
+ return (0, raydium_amm_js_1.parseRayLogSwap)(log, metadata);
583
+ }
571
584
  const buf = (0, program_data_js_1.decodeProgramDataLine)(log);
572
585
  if (!buf)
573
586
  return null;
@@ -642,6 +655,8 @@ function parseLogOptimized(log, signature, slot, txIndex, blockTimeUs, grpcRecvU
642
655
  }
643
656
  if (programId === program_ids_js_1.RAYDIUM_CPMM_PROGRAM_ID) {
644
657
  switch (disc) {
658
+ case program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_EVENT:
659
+ return applyActualEventTypeFilter((0, raydium_cpmm_js_1.parseSwapEventFromData)(data, metadata), eventTypeFilter);
645
660
  case program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_IN:
646
661
  return applyActualEventTypeFilter((0, raydium_cpmm_js_1.parseSwapBaseInFromData)(data, metadata), eventTypeFilter);
647
662
  case program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CPMM_SWAP_BASE_OUT:
@@ -48,6 +48,7 @@ export declare const PROGRAM_LOG_DISC: {
48
48
  readonly RAYDIUM_CLMM_CREATE_POOL: bigint;
49
49
  readonly RAYDIUM_CLMM_COLLECT_PERSONAL_FEE: bigint;
50
50
  readonly RAYDIUM_CLMM_COLLECT_PROTOCOL_FEE: bigint;
51
+ readonly RAYDIUM_CPMM_SWAP_EVENT: bigint;
51
52
  readonly RAYDIUM_CPMM_SWAP_BASE_IN: bigint;
52
53
  readonly RAYDIUM_CPMM_SWAP_BASE_OUT: bigint;
53
54
  readonly RAYDIUM_CPMM_CREATE_POOL: bigint;
@@ -57,6 +57,8 @@ exports.PROGRAM_LOG_DISC = {
57
57
  RAYDIUM_CLMM_CREATE_POOL: u64leDiscriminator([25, 94, 75, 47, 112, 99, 53, 63]),
58
58
  RAYDIUM_CLMM_COLLECT_PERSONAL_FEE: u64leDiscriminator([166, 174, 105, 192, 81, 161, 83, 105]),
59
59
  RAYDIUM_CLMM_COLLECT_PROTOCOL_FEE: u64leDiscriminator([206, 87, 17, 79, 45, 41, 213, 61]),
60
+ // Anchor event: `event:SwapEvent` (shared with CLMM; program context disambiguates it).
61
+ RAYDIUM_CPMM_SWAP_EVENT: u64leDiscriminator([64, 198, 205, 232, 38, 8, 113, 226]),
60
62
  RAYDIUM_CPMM_SWAP_BASE_IN: u64leDiscriminator([143, 190, 90, 218, 196, 30, 51, 222]),
61
63
  RAYDIUM_CPMM_SWAP_BASE_OUT: u64leDiscriminator([55, 217, 98, 86, 163, 74, 180, 173]),
62
64
  RAYDIUM_CPMM_CREATE_POOL: u64leDiscriminator([233, 146, 209, 142, 207, 104, 64, 188]),
@@ -17,9 +17,64 @@ function bnI64(v) {
17
17
  return v ?? 0n;
18
18
  }
19
19
  const ZP = (0, dex_event_js_1.defaultPubkey)();
20
+ function emptyTradeTail() {
21
+ return {
22
+ cashback_fee_basis_points: 0n,
23
+ cashback: 0n,
24
+ buyback_fee_basis_points: 0n,
25
+ buyback_fee: 0n,
26
+ virtual_quote_reserves: 0n,
27
+ can_boost: false,
28
+ base_supply: 0n,
29
+ };
30
+ }
31
+ function parseTradeTail(data) {
32
+ const tail = emptyTradeTail();
33
+ if (data.length === 0)
34
+ return tail;
35
+ if (data.length < 16)
36
+ return null;
37
+ tail.cashback_fee_basis_points = bn64((0, binary_js_1.readU64LE)(data, 0));
38
+ tail.cashback = bn64((0, binary_js_1.readU64LE)(data, 8));
39
+ if (data.length === 16)
40
+ return tail;
41
+ if (data.length < 32)
42
+ return null;
43
+ tail.buyback_fee_basis_points = bn64((0, binary_js_1.readU64LE)(data, 16));
44
+ tail.buyback_fee = bn64((0, binary_js_1.readU64LE)(data, 24));
45
+ if (data.length === 32)
46
+ return tail;
47
+ if (data.length < 57)
48
+ return null;
49
+ const virtual = (0, binary_js_1.readU128LE)(data, 32);
50
+ if (virtual === null)
51
+ return null;
52
+ tail.virtual_quote_reserves = BigInt.asIntN(128, virtual);
53
+ const canBoost = (0, binary_js_1.readU8)(data, 48);
54
+ if (canBoost !== 0 && canBoost !== 1)
55
+ return null;
56
+ tail.can_boost = canBoost === 1;
57
+ tail.base_supply = bn64((0, binary_js_1.readU64LE)(data, 49));
58
+ return tail;
59
+ }
60
+ function readStrictBorshString(data, offset) {
61
+ const len = (0, binary_js_1.readU32LE)(data, offset);
62
+ if (len === null || offset + 4 + len > data.length)
63
+ return null;
64
+ try {
65
+ const value = new TextDecoder("utf-8", { fatal: true }).decode(data.subarray(offset + 4, offset + 4 + len));
66
+ return { value, next: offset + 4 + len };
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
20
72
  function parseBuyFromData(data, metadata) {
21
- const MIN = 16 * 8 + 7 * 32 + 1 + 5 * 8 + 4;
22
- if (data.length < MIN)
73
+ const LEGACY_LEN = 16 * 8 + 7 * 32 + 1 + 4 * 8;
74
+ const MIN_REQUIRED_LEN = LEGACY_LEN + 8 + 4;
75
+ if (data.length !== LEGACY_LEN && data.length < MIN_REQUIRED_LEN)
76
+ return null;
77
+ if (data[352] !== 0 && data[352] !== 1)
23
78
  return null;
24
79
  let o = 0;
25
80
  const timestamp = bnI64((0, binary_js_1.readI64LE)(data, o));
@@ -68,7 +123,7 @@ function parseBuyFromData(data, metadata) {
68
123
  o += 8;
69
124
  const coin_creator_fee = bn64((0, binary_js_1.readU64LE)(data, o));
70
125
  o += 8;
71
- const track_volume = (0, binary_js_1.readBool)(data, o);
126
+ const track_volume = data[o] === 1;
72
127
  o += 1;
73
128
  const total_unclaimed_tokens = bn64((0, binary_js_1.readU64LE)(data, o));
74
129
  o += 8;
@@ -78,15 +133,21 @@ function parseBuyFromData(data, metadata) {
78
133
  o += 8;
79
134
  const last_update_timestamp = bnI64((0, binary_js_1.readI64LE)(data, o));
80
135
  o += 8;
81
- const min_base_amount_out = bn64((0, binary_js_1.readU64LE)(data, o));
82
- o += 8;
136
+ let min_base_amount_out = 0n;
83
137
  let ix_name = "";
84
- if (o + 4 <= data.length) {
85
- const len = (0, binary_js_1.readU32LE)(data, o);
86
- o += 4;
87
- if (o + len <= data.length) {
88
- ix_name = new TextDecoder().decode(data.subarray(o, o + len));
89
- }
138
+ let tail = emptyTradeTail();
139
+ if (data.length !== LEGACY_LEN) {
140
+ min_base_amount_out = bn64((0, binary_js_1.readU64LE)(data, o));
141
+ o += 8;
142
+ const name = readStrictBorshString(data, o);
143
+ if (name === null)
144
+ return null;
145
+ ix_name = name.value;
146
+ o = name.next;
147
+ const parsedTail = parseTradeTail(data.subarray(o));
148
+ if (parsedTail === null)
149
+ return null;
150
+ tail = parsedTail;
90
151
  }
91
152
  const ev = {
92
153
  metadata,
@@ -120,8 +181,13 @@ function parseBuyFromData(data, metadata) {
120
181
  last_update_timestamp,
121
182
  min_base_amount_out,
122
183
  ix_name,
123
- cashback_fee_basis_points: 0n,
124
- cashback: 0n,
184
+ cashback_fee_basis_points: tail.cashback_fee_basis_points,
185
+ cashback: tail.cashback,
186
+ buyback_fee_basis_points: tail.buyback_fee_basis_points,
187
+ buyback_fee: tail.buyback_fee,
188
+ virtual_quote_reserves: tail.virtual_quote_reserves,
189
+ can_boost: tail.can_boost,
190
+ base_supply: tail.base_supply,
125
191
  is_pump_pool: false,
126
192
  base_mint: ZP,
127
193
  quote_mint: ZP,
@@ -135,9 +201,12 @@ function parseBuyFromData(data, metadata) {
135
201
  return { PumpSwapBuy: ev };
136
202
  }
137
203
  function parseSellFromData(data, metadata) {
138
- const REQUIRED = 13 * 8 + 7 * 32;
204
+ const REQUIRED = 14 * 8 + 7 * 32 + 2 * 8;
139
205
  if (data.length < REQUIRED)
140
206
  return null;
207
+ const tail = parseTradeTail(data.subarray(REQUIRED));
208
+ if (tail === null)
209
+ return null;
141
210
  let o = 0;
142
211
  const timestamp = bnI64((0, binary_js_1.readI64LE)(data, o));
143
212
  o += 8;
@@ -185,12 +254,6 @@ function parseSellFromData(data, metadata) {
185
254
  o += 8;
186
255
  const coin_creator_fee = bn64((0, binary_js_1.readU64LE)(data, o));
187
256
  o += 8;
188
- let cashback_fee_basis_points = 0n;
189
- let cashback = 0n;
190
- if (data.length >= 368) {
191
- cashback_fee_basis_points = bn64((0, binary_js_1.readU64LE)(data, 352));
192
- cashback = bn64((0, binary_js_1.readU64LE)(data, 360));
193
- }
194
257
  const ev = {
195
258
  metadata,
196
259
  timestamp,
@@ -216,8 +279,13 @@ function parseSellFromData(data, metadata) {
216
279
  coin_creator,
217
280
  coin_creator_fee_basis_points,
218
281
  coin_creator_fee,
219
- cashback_fee_basis_points,
220
- cashback,
282
+ cashback_fee_basis_points: tail.cashback_fee_basis_points,
283
+ cashback: tail.cashback,
284
+ buyback_fee_basis_points: tail.buyback_fee_basis_points,
285
+ buyback_fee: tail.buyback_fee,
286
+ virtual_quote_reserves: tail.virtual_quote_reserves,
287
+ can_boost: tail.can_boost,
288
+ base_supply: tail.base_supply,
221
289
  is_pump_pool: false,
222
290
  base_mint: ZP,
223
291
  quote_mint: ZP,
@@ -1,5 +1,7 @@
1
1
  import type { EventMetadata } from "../core/metadata.js";
2
2
  import type { DexEvent } from "../core/dex_event.js";
3
+ /** Decode Raydium AMM V4's official bincode `SwapBaseInLog` / `SwapBaseOutLog`. */
4
+ export declare function parseRayLogSwap(log: string, 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 parseDepositFromData(data: Uint8Array, metadata: EventMetadata): DexEvent | null;
@@ -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);