sol-parser-sdk-python 0.5.7__py3-none-any.whl → 0.5.8__py3-none-any.whl
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.
- sol_parser/__init__.py +10 -0
- sol_parser/account_dispatcher.py +79 -0
- sol_parser/account_fillers/meteora.py +10 -2
- sol_parser/account_fillers/raydium.py +3 -2
- sol_parser/account_fillers/raydium_launchlab.py +50 -0
- sol_parser/accounts/__init__.py +47 -2
- sol_parser/dex_parsers.py +648 -68
- sol_parser/event_type_parity.py +4 -0
- sol_parser/event_types.py +221 -3
- sol_parser/grpc_instruction_parser.py +85 -26
- sol_parser/grpc_types.py +12 -0
- sol_parser/inner_instruction_parser.py +5 -7
- sol_parser/instructions.py +213 -49
- sol_parser/log_instr_dedup.py +56 -12
- sol_parser/merger.py +73 -85
- sol_parser/parser.py +11 -0
- sol_parser/pumpfun_fee_enrich.py +2 -0
- sol_parser/rpc_parser.py +30 -4
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/METADATA +26 -9
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/RECORD +22 -22
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/WHEEL +1 -1
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/entry_points.txt +0 -0
sol_parser/merger.py
CHANGED
|
@@ -32,6 +32,14 @@ from .event_types import (
|
|
|
32
32
|
MeteoraDammV2CreatePositionEvent,
|
|
33
33
|
MeteoraDammV2RemoveLiquidityEvent,
|
|
34
34
|
MeteoraDammV2SwapEvent,
|
|
35
|
+
MeteoraDlmmAddLiquidityEvent,
|
|
36
|
+
MeteoraDlmmClaimFeeEvent,
|
|
37
|
+
MeteoraDlmmClosePositionEvent,
|
|
38
|
+
MeteoraDlmmCreatePositionEvent,
|
|
39
|
+
MeteoraDlmmInitializeBinArrayEvent,
|
|
40
|
+
MeteoraDlmmInitializePoolEvent,
|
|
41
|
+
MeteoraDlmmRemoveLiquidityEvent,
|
|
42
|
+
MeteoraDlmmSwapEvent,
|
|
35
43
|
MeteoraPoolsAddLiquidityEvent,
|
|
36
44
|
MeteoraPoolsRemoveLiquidityEvent,
|
|
37
45
|
MeteoraPoolsSwapEvent,
|
|
@@ -44,6 +52,40 @@ from .grpc_types import EventType
|
|
|
44
52
|
|
|
45
53
|
ZERO = "11111111111111111111111111111111"
|
|
46
54
|
|
|
55
|
+
GENERIC_MERGE_TYPES = (
|
|
56
|
+
PumpSwapCreatePoolEvent,
|
|
57
|
+
PumpSwapLiquidityAddedEvent,
|
|
58
|
+
PumpSwapLiquidityRemovedEvent,
|
|
59
|
+
RaydiumClmmSwapEvent,
|
|
60
|
+
RaydiumClmmIncreaseLiquidityEvent,
|
|
61
|
+
RaydiumClmmDecreaseLiquidityEvent,
|
|
62
|
+
RaydiumClmmCreatePoolEvent,
|
|
63
|
+
RaydiumClmmCollectFeeEvent,
|
|
64
|
+
RaydiumCpmmSwapEvent,
|
|
65
|
+
RaydiumCpmmDepositEvent,
|
|
66
|
+
RaydiumCpmmWithdrawEvent,
|
|
67
|
+
RaydiumAmmV4SwapEvent,
|
|
68
|
+
RaydiumAmmV4DepositEvent,
|
|
69
|
+
RaydiumAmmV4WithdrawEvent,
|
|
70
|
+
OrcaWhirlpoolSwapEvent,
|
|
71
|
+
OrcaWhirlpoolLiquidityIncreasedEvent,
|
|
72
|
+
OrcaWhirlpoolLiquidityDecreasedEvent,
|
|
73
|
+
MeteoraPoolsSwapEvent,
|
|
74
|
+
MeteoraPoolsAddLiquidityEvent,
|
|
75
|
+
MeteoraPoolsRemoveLiquidityEvent,
|
|
76
|
+
MeteoraDammV2SwapEvent,
|
|
77
|
+
MeteoraDammV2AddLiquidityEvent,
|
|
78
|
+
MeteoraDammV2RemoveLiquidityEvent,
|
|
79
|
+
MeteoraDammV2CreatePositionEvent,
|
|
80
|
+
MeteoraDammV2ClosePositionEvent,
|
|
81
|
+
MeteoraDlmmSwapEvent,
|
|
82
|
+
MeteoraDlmmAddLiquidityEvent,
|
|
83
|
+
MeteoraDlmmRemoveLiquidityEvent,
|
|
84
|
+
MeteoraDlmmInitializeBinArrayEvent,
|
|
85
|
+
MeteoraDlmmClaimFeeEvent,
|
|
86
|
+
RaydiumLaunchlabTradeEvent,
|
|
87
|
+
)
|
|
88
|
+
|
|
47
89
|
|
|
48
90
|
def _merge_generic(base: Any, inner: Any) -> None:
|
|
49
91
|
for f in dataclasses.fields(type(base)):
|
|
@@ -134,6 +176,8 @@ def merge_pumpfun_trade(base: PumpFunTradeEvent, inner: PumpFunTradeEvent) -> No
|
|
|
134
176
|
"quote_amount",
|
|
135
177
|
"virtual_quote_reserves",
|
|
136
178
|
"real_quote_reserves",
|
|
179
|
+
"holder_rewards_bps",
|
|
180
|
+
"holder_rewards",
|
|
137
181
|
"amount",
|
|
138
182
|
"max_sol_cost",
|
|
139
183
|
"min_sol_output",
|
|
@@ -243,6 +287,8 @@ def merge_pumpfun_create(base: PumpFunCreateEvent, inner: PumpFunCreateEvent) ->
|
|
|
243
287
|
base.is_cashback_enabled = inner.is_cashback_enabled
|
|
244
288
|
base.quote_mint = inner.quote_mint
|
|
245
289
|
base.virtual_quote_reserves = inner.virtual_quote_reserves
|
|
290
|
+
base.creator_fee_bps = inner.creator_fee_bps
|
|
291
|
+
base.is_holder_reward = bool(base.is_holder_reward) or bool(inner.is_holder_reward)
|
|
246
292
|
|
|
247
293
|
|
|
248
294
|
def merge_pumpfun_migrate(base: PumpFunMigrateEvent, inner: PumpFunMigrateEvent) -> None:
|
|
@@ -258,6 +304,11 @@ def merge_pumpfun_migrate(base: PumpFunMigrateEvent, inner: PumpFunMigrateEvent)
|
|
|
258
304
|
|
|
259
305
|
def merge_dex_events(base: DexEvent, inner: DexEvent) -> None:
|
|
260
306
|
"""将 ``inner`` 合并进 ``base``(就地修改 ``base.data``)。"""
|
|
307
|
+
try_merge_dex_events(base, inner)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def try_merge_dex_events(base: DexEvent, inner: DexEvent) -> bool:
|
|
311
|
+
"""Merge compatible events and report success so unmatched events are retained."""
|
|
261
312
|
bd = base.data
|
|
262
313
|
ind = inner.data
|
|
263
314
|
|
|
@@ -274,108 +325,45 @@ def merge_dex_events(base: DexEvent, inner: DexEvent) -> None:
|
|
|
274
325
|
EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
|
|
275
326
|
):
|
|
276
327
|
merge_pumpfun_trade(bd, ind)
|
|
277
|
-
|
|
328
|
+
return True
|
|
329
|
+
return False
|
|
278
330
|
|
|
279
331
|
if isinstance(bd, PumpFunCreateEvent) and isinstance(ind, PumpFunCreateEvent):
|
|
280
332
|
merge_pumpfun_create(bd, ind)
|
|
281
|
-
return
|
|
333
|
+
return True
|
|
282
334
|
|
|
283
335
|
if isinstance(bd, PumpFunCreateV2TokenEvent) and isinstance(ind, PumpFunCreateV2TokenEvent):
|
|
284
336
|
_merge_generic(bd, ind)
|
|
285
|
-
return
|
|
337
|
+
return True
|
|
286
338
|
|
|
287
339
|
if isinstance(bd, PumpFunMigrateEvent) and isinstance(ind, PumpFunMigrateEvent):
|
|
288
340
|
merge_pumpfun_migrate(bd, ind)
|
|
289
|
-
return
|
|
341
|
+
return True
|
|
290
342
|
|
|
291
343
|
if isinstance(bd, PumpSwapBuyEvent) and isinstance(ind, PumpSwapBuyEvent):
|
|
292
344
|
merge_pumpswap_buy(bd, ind)
|
|
293
|
-
return
|
|
345
|
+
return True
|
|
294
346
|
if isinstance(bd, PumpSwapSellEvent) and isinstance(ind, PumpSwapSellEvent):
|
|
295
347
|
merge_pumpswap_sell(bd, ind)
|
|
296
|
-
return
|
|
297
|
-
if isinstance(bd,
|
|
298
|
-
|
|
299
|
-
return
|
|
300
|
-
if isinstance(bd, PumpSwapLiquidityAddedEvent) and isinstance(ind, PumpSwapLiquidityAddedEvent):
|
|
301
|
-
_merge_generic(bd, ind)
|
|
302
|
-
return
|
|
303
|
-
if isinstance(bd, PumpSwapLiquidityRemovedEvent) and isinstance(ind, PumpSwapLiquidityRemovedEvent):
|
|
304
|
-
_merge_generic(bd, ind)
|
|
305
|
-
return
|
|
306
|
-
|
|
307
|
-
if isinstance(bd, RaydiumClmmSwapEvent) and isinstance(ind, RaydiumClmmSwapEvent):
|
|
308
|
-
_merge_generic(bd, ind)
|
|
309
|
-
return
|
|
310
|
-
if isinstance(bd, RaydiumClmmIncreaseLiquidityEvent) and isinstance(ind, RaydiumClmmIncreaseLiquidityEvent):
|
|
311
|
-
_merge_generic(bd, ind)
|
|
312
|
-
return
|
|
313
|
-
if isinstance(bd, RaydiumClmmDecreaseLiquidityEvent) and isinstance(ind, RaydiumClmmDecreaseLiquidityEvent):
|
|
314
|
-
_merge_generic(bd, ind)
|
|
315
|
-
return
|
|
316
|
-
if isinstance(bd, RaydiumClmmCreatePoolEvent) and isinstance(ind, RaydiumClmmCreatePoolEvent):
|
|
317
|
-
_merge_generic(bd, ind)
|
|
318
|
-
return
|
|
319
|
-
if isinstance(bd, RaydiumClmmCollectFeeEvent) and isinstance(ind, RaydiumClmmCollectFeeEvent):
|
|
320
|
-
_merge_generic(bd, ind)
|
|
321
|
-
return
|
|
322
|
-
|
|
323
|
-
if isinstance(bd, RaydiumCpmmSwapEvent) and isinstance(ind, RaydiumCpmmSwapEvent):
|
|
324
|
-
_merge_generic(bd, ind)
|
|
325
|
-
return
|
|
326
|
-
if isinstance(bd, RaydiumCpmmDepositEvent) and isinstance(ind, RaydiumCpmmDepositEvent):
|
|
327
|
-
_merge_generic(bd, ind)
|
|
328
|
-
return
|
|
329
|
-
if isinstance(bd, RaydiumCpmmWithdrawEvent) and isinstance(ind, RaydiumCpmmWithdrawEvent):
|
|
330
|
-
_merge_generic(bd, ind)
|
|
331
|
-
return
|
|
332
|
-
|
|
333
|
-
if isinstance(bd, RaydiumAmmV4SwapEvent) and isinstance(ind, RaydiumAmmV4SwapEvent):
|
|
334
|
-
_merge_generic(bd, ind)
|
|
335
|
-
return
|
|
336
|
-
if isinstance(bd, RaydiumAmmV4DepositEvent) and isinstance(ind, RaydiumAmmV4DepositEvent):
|
|
337
|
-
_merge_generic(bd, ind)
|
|
338
|
-
return
|
|
339
|
-
if isinstance(bd, RaydiumAmmV4WithdrawEvent) and isinstance(ind, RaydiumAmmV4WithdrawEvent):
|
|
340
|
-
_merge_generic(bd, ind)
|
|
341
|
-
return
|
|
342
|
-
|
|
343
|
-
if isinstance(bd, OrcaWhirlpoolSwapEvent) and isinstance(ind, OrcaWhirlpoolSwapEvent):
|
|
344
|
-
_merge_generic(bd, ind)
|
|
345
|
-
return
|
|
346
|
-
if isinstance(bd, OrcaWhirlpoolLiquidityIncreasedEvent) and isinstance(ind, OrcaWhirlpoolLiquidityIncreasedEvent):
|
|
347
|
-
_merge_generic(bd, ind)
|
|
348
|
-
return
|
|
349
|
-
if isinstance(bd, OrcaWhirlpoolLiquidityDecreasedEvent) and isinstance(ind, OrcaWhirlpoolLiquidityDecreasedEvent):
|
|
348
|
+
return True
|
|
349
|
+
if isinstance(bd, MeteoraDlmmInitializePoolEvent) and isinstance(ind, MeteoraDlmmInitializePoolEvent):
|
|
350
|
+
creator, active_bin_id = bd.creator, bd.active_bin_id
|
|
350
351
|
_merge_generic(bd, ind)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if isinstance(bd,
|
|
354
|
-
|
|
355
|
-
return
|
|
356
|
-
if isinstance(bd, MeteoraPoolsAddLiquidityEvent) and isinstance(ind, MeteoraPoolsAddLiquidityEvent):
|
|
352
|
+
bd.creator, bd.active_bin_id = creator, active_bin_id
|
|
353
|
+
return True
|
|
354
|
+
if isinstance(bd, MeteoraDlmmCreatePositionEvent) and isinstance(ind, MeteoraDlmmCreatePositionEvent):
|
|
355
|
+
lower_bin_id, width = bd.lower_bin_id, bd.width
|
|
357
356
|
_merge_generic(bd, ind)
|
|
358
|
-
|
|
359
|
-
|
|
357
|
+
bd.lower_bin_id, bd.width = lower_bin_id, width
|
|
358
|
+
return True
|
|
359
|
+
if isinstance(bd, MeteoraDlmmClosePositionEvent) and isinstance(ind, MeteoraDlmmClosePositionEvent):
|
|
360
|
+
pool = bd.pool
|
|
360
361
|
_merge_generic(bd, ind)
|
|
361
|
-
|
|
362
|
+
bd.pool = pool
|
|
363
|
+
return True
|
|
362
364
|
|
|
363
|
-
if
|
|
364
|
-
_merge_generic(bd, ind)
|
|
365
|
-
return
|
|
366
|
-
if isinstance(bd, MeteoraDammV2AddLiquidityEvent) and isinstance(ind, MeteoraDammV2AddLiquidityEvent):
|
|
367
|
-
_merge_generic(bd, ind)
|
|
368
|
-
return
|
|
369
|
-
if isinstance(bd, MeteoraDammV2RemoveLiquidityEvent) and isinstance(ind, MeteoraDammV2RemoveLiquidityEvent):
|
|
365
|
+
if base.type == inner.type and type(bd) is type(ind) and isinstance(bd, GENERIC_MERGE_TYPES):
|
|
370
366
|
_merge_generic(bd, ind)
|
|
371
|
-
return
|
|
372
|
-
if isinstance(bd, MeteoraDammV2CreatePositionEvent) and isinstance(ind, MeteoraDammV2CreatePositionEvent):
|
|
373
|
-
_merge_generic(bd, ind)
|
|
374
|
-
return
|
|
375
|
-
if isinstance(bd, MeteoraDammV2ClosePositionEvent) and isinstance(ind, MeteoraDammV2ClosePositionEvent):
|
|
376
|
-
_merge_generic(bd, ind)
|
|
377
|
-
return
|
|
367
|
+
return True
|
|
378
368
|
|
|
379
|
-
|
|
380
|
-
_merge_generic(bd, ind)
|
|
381
|
-
return
|
|
369
|
+
return False
|
sol_parser/parser.py
CHANGED
|
@@ -79,6 +79,17 @@ def parse_log_optimized(
|
|
|
79
79
|
) -> Optional[DexEvent]:
|
|
80
80
|
"""单次 base64 decode 后按 discriminator 做 early filter,再按实际事件类型二次过滤。"""
|
|
81
81
|
grpc = int(time.time() * 1_000_000) if grpc_recv_us is None else grpc_recv_us
|
|
82
|
+
if program_id == "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8" and "ray_log: " in log:
|
|
83
|
+
from .dex_parsers import parse_amm_ray_log_swap
|
|
84
|
+
from .grpc_types import EventType
|
|
85
|
+
|
|
86
|
+
if event_type_filter is not None and not event_type_filter.should_include(
|
|
87
|
+
EventType.RAYDIUM_AMM_V4_SWAP
|
|
88
|
+
):
|
|
89
|
+
return None
|
|
90
|
+
return parse_amm_ray_log_swap(
|
|
91
|
+
log, _meta(signature, slot, tx_index, block_time_us, grpc, recent_blockhash)
|
|
92
|
+
)
|
|
82
93
|
buf = decode_program_data_line(log)
|
|
83
94
|
if not buf:
|
|
84
95
|
return None
|
sol_parser/pumpfun_fee_enrich.py
CHANGED
|
@@ -102,10 +102,12 @@ def enrich_create_v2_from_create_events(events: List[DexEvent]) -> None:
|
|
|
102
102
|
"real_token_reserves",
|
|
103
103
|
"token_total_supply",
|
|
104
104
|
"virtual_quote_reserves",
|
|
105
|
+
"creator_fee_bps",
|
|
105
106
|
):
|
|
106
107
|
_fill_int_if_zero(c2, attr, getattr(c, attr))
|
|
107
108
|
c2.is_cashback_enabled = c2.is_cashback_enabled or c.is_cashback_enabled
|
|
108
109
|
c2.is_mayhem_mode = c2.is_mayhem_mode or c.is_mayhem_mode
|
|
110
|
+
c2.is_holder_reward = c2.is_holder_reward or c.is_holder_reward
|
|
109
111
|
|
|
110
112
|
|
|
111
113
|
def enrich_pumpfun_trades_from_create_instructions(events: List[DexEvent]) -> None:
|
sol_parser/rpc_parser.py
CHANGED
|
@@ -11,7 +11,11 @@ import base58
|
|
|
11
11
|
from .dex_parsers import DexEvent
|
|
12
12
|
from .grpc_types import EventTypeFilter, EventType, event_type_filter_allows_instruction_parsing
|
|
13
13
|
from .inner_instruction_parser import parse_inner_instruction
|
|
14
|
-
from .instructions import
|
|
14
|
+
from .instructions import (
|
|
15
|
+
METEORA_DLMM_PROGRAM_ID,
|
|
16
|
+
parse_inner_compiled_instruction_if_supported,
|
|
17
|
+
parse_instruction_unified,
|
|
18
|
+
)
|
|
15
19
|
from .log_instr_dedup import dedupe_log_instruction_events
|
|
16
20
|
from .pumpfun_fee_enrich import enrich_pumpfun_same_tx_post_merge
|
|
17
21
|
|
|
@@ -30,6 +34,7 @@ class RpcCompiledInstruction:
|
|
|
30
34
|
program_id_index: int
|
|
31
35
|
accounts: Union[List[int], bytes]
|
|
32
36
|
data: bytes
|
|
37
|
+
stack_height: Optional[int] = None
|
|
33
38
|
|
|
34
39
|
|
|
35
40
|
@dataclass
|
|
@@ -215,8 +220,9 @@ def parse_rpc_transaction(
|
|
|
215
220
|
block_tx_index = int(getattr(tx, "transaction_index", 0) or 0)
|
|
216
221
|
full_account_keys = _merge_rpc_full_account_keys(msg.account_keys, meta)
|
|
217
222
|
|
|
218
|
-
indexed_instruction_events: List[Tuple[
|
|
223
|
+
indexed_instruction_events: List[Tuple[Any, ...]] = []
|
|
219
224
|
from .grpc_instruction_parser import (
|
|
225
|
+
_is_dlmm_event_cpi,
|
|
220
226
|
detect_pumpfun_create_from_logs,
|
|
221
227
|
merge_instruction_events,
|
|
222
228
|
)
|
|
@@ -238,7 +244,7 @@ def parse_rpc_transaction(
|
|
|
238
244
|
is_created_buy=has_pumpfun_create_log,
|
|
239
245
|
)
|
|
240
246
|
if ev:
|
|
241
|
-
indexed_instruction_events.append((outer_idx, None, ev))
|
|
247
|
+
indexed_instruction_events.append((outer_idx, None, 1, False, ev))
|
|
242
248
|
|
|
243
249
|
# 解析内层指令
|
|
244
250
|
for group in meta.inner_instructions:
|
|
@@ -256,7 +262,18 @@ def parse_rpc_transaction(
|
|
|
256
262
|
is_created_buy=has_pumpfun_create_log,
|
|
257
263
|
)
|
|
258
264
|
if ev:
|
|
259
|
-
|
|
265
|
+
pid = (
|
|
266
|
+
full_account_keys[ix.program_id_index]
|
|
267
|
+
if ix.program_id_index < len(full_account_keys)
|
|
268
|
+
else ""
|
|
269
|
+
)
|
|
270
|
+
indexed_instruction_events.append((
|
|
271
|
+
int(group.index),
|
|
272
|
+
inner_idx,
|
|
273
|
+
ix.stack_height,
|
|
274
|
+
pid == METEORA_DLMM_PROGRAM_ID and _is_dlmm_event_cpi(ix.data),
|
|
275
|
+
ev,
|
|
276
|
+
))
|
|
260
277
|
|
|
261
278
|
instruction_events = merge_instruction_events(indexed_instruction_events)
|
|
262
279
|
enrich_pumpfun_same_tx_post_merge(instruction_events)
|
|
@@ -525,6 +542,13 @@ def _parse_rpc_compiled_ix(ix: dict, account_keys: List[str]) -> RpcCompiledInst
|
|
|
525
542
|
program_id_index=pidx,
|
|
526
543
|
accounts=acc_list,
|
|
527
544
|
data=_ix_data_from_rpc(ix),
|
|
545
|
+
stack_height=(
|
|
546
|
+
int(ix["stackHeight"])
|
|
547
|
+
if ix.get("stackHeight") is not None
|
|
548
|
+
else int(ix["stack_height"])
|
|
549
|
+
if ix.get("stack_height") is not None
|
|
550
|
+
else None
|
|
551
|
+
),
|
|
528
552
|
)
|
|
529
553
|
|
|
530
554
|
|
|
@@ -717,6 +741,8 @@ def rpc_response_to_solana_storage(
|
|
|
717
741
|
acc = ix.accounts
|
|
718
742
|
ii.accounts = bytes(acc) if not isinstance(acc, bytes) else acc
|
|
719
743
|
ii.data = ix.data
|
|
744
|
+
if ix.stack_height is not None:
|
|
745
|
+
ii.stack_height = ix.stack_height
|
|
720
746
|
if m.loaded_addresses:
|
|
721
747
|
for w in m.loaded_addresses.writable:
|
|
722
748
|
meta.loaded_writable_addresses.append(base58.b58decode(w))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: sol-parser-sdk-python
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.8
|
|
4
4
|
Summary: Solana DEX program log parsing (pure Python, API aligned with sol-parser-sdk)
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Requires-Dist: base58>=2.0
|
|
@@ -46,12 +46,6 @@ Description-Content-Type: text/markdown
|
|
|
46
46
|
<a href="https://discord.gg/vuazbGkqQE">Discord</a>
|
|
47
47
|
</p>
|
|
48
48
|
|
|
49
|
-
> ☕ **Support This Project**
|
|
50
|
-
>
|
|
51
|
-
> This SDK is completely free and open source. However, maintaining and continuously updating it requires significant AI computing resources and token consumption. If this SDK helps with your development, consider making a monthly SOL donation — any amount is appreciated and helps keep this project alive!
|
|
52
|
-
>
|
|
53
|
-
> **Donation Wallet:** `6oW7AXz1yRb57pYSxysuXnMs2aR1ha5rzGzReZ1MjPV8`
|
|
54
|
-
|
|
55
49
|
---
|
|
56
50
|
|
|
57
51
|
## Other language SDKs
|
|
@@ -65,8 +59,31 @@ Description-Content-Type: text/markdown
|
|
|
65
59
|
|
|
66
60
|
---
|
|
67
61
|
|
|
62
|
+
## What This SDK Is For
|
|
63
|
+
|
|
64
|
+
This is the Python implementation of the FnZero Solana DEX parser SDK for asyncio services, research scripts, indexers, copy-trading systems, sniper pipelines, and backend jobs that need normalized real-time DEX events.
|
|
65
|
+
|
|
66
|
+
| Area | Coverage |
|
|
67
|
+
|------|----------|
|
|
68
|
+
| Parser inputs | Yellowstone gRPC, ShredStream, RPC transactions, encoded transactions, protocol account data |
|
|
69
|
+
| DEX protocols | PumpFun, PumpSwap, Pump Fees, Raydium LaunchLab, Raydium CPMM, Raydium CLMM, Raydium AMM V4, Meteora DAMM v2, Meteora DLMM, Meteora DBC, Orca Whirlpool |
|
|
70
|
+
| Use cases | Real-time DEX event parsing, token launch monitoring, copy trading, sniper bots, analytics notebooks, JSON event pipelines |
|
|
71
|
+
| Runtime | Python 3.10+, asyncio workers, backend services, data pipelines, low-latency bot infrastructure |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
68
75
|
## Release notes
|
|
69
76
|
|
|
77
|
+
### v0.5.8
|
|
78
|
+
|
|
79
|
+
- Syncs with Rust **sol-parser-sdk 0.7.3**, including the current PumpFun, PumpSwap, and Pump Fees protocol definitions.
|
|
80
|
+
- Adds Meteora DAMM v2 events: `UpdateDelegatePermission`, `WithdrawDeadLiquidityReward`, `CreateConfig`, `CreateDynamicConfig`.
|
|
81
|
+
- Fixes DAMM v2 `EvtSwap2` full 180-byte layout, three swap modes, transfer fees, reserves, and compounding-fee layout activation slot `406048752`.
|
|
82
|
+
- Routes unified `EvtLiquidityChange` by `change_type` to AddLiquidity / RemoveLiquidity.
|
|
83
|
+
- Adds DLMM mint/user-token/`min_amount_out` context, PumpFun pre/post token & SOL balances, and LaunchLab quote/global/platform account fields.
|
|
84
|
+
- Adds current PumpFun/PumpSwap creator-fee and holder-reward fields across instruction, log, account, gRPC, and JSON event paths.
|
|
85
|
+
- Rejects truncated known PumpSwap trade and CreatePool tails while retaining complete historical layouts.
|
|
86
|
+
|
|
70
87
|
### v0.5.6
|
|
71
88
|
|
|
72
89
|
- Adds Meteora DBC log parsing with program-context routing and filter parity.
|
|
@@ -92,7 +109,7 @@ Description-Content-Type: text/markdown
|
|
|
92
109
|
**From PyPI**
|
|
93
110
|
|
|
94
111
|
```bash
|
|
95
|
-
pip install sol-parser-sdk-python==0.5.
|
|
112
|
+
pip install sol-parser-sdk-python==0.5.8
|
|
96
113
|
```
|
|
97
114
|
|
|
98
115
|
**From source**
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
sol_parser/__init__.py,sha256=
|
|
2
|
-
sol_parser/account_dispatcher.py,sha256=
|
|
1
|
+
sol_parser/__init__.py,sha256=2b7VW5C0aEbBsfkUPEUzuDXZIxLSm5Jwg2xkFvjHrR8,15031
|
|
2
|
+
sol_parser/account_dispatcher.py,sha256=Zy--fqFypjDk_kU-6Z6Z3T5xqG1IvMHROYBd_n3VsKk,13028
|
|
3
3
|
sol_parser/check_migration.py,sha256=PsRE_Zhnw2g_iaP_iYtlGsQutE2w_FsaZIP4GPeN8-o,537
|
|
4
4
|
sol_parser/clock.py,sha256=RHF99qMerKvEsT55krkftIh-uqy_uTzpgdKCqKBMDmA,278
|
|
5
|
-
sol_parser/dex_parsers.py,sha256=
|
|
5
|
+
sol_parser/dex_parsers.py,sha256=ogyuqBQro2MisryGrGfyGiZwxZc3ImiSNB8GAROaTLU,134727
|
|
6
6
|
sol_parser/entries_decode.py,sha256=-eooIYrXOcpNtrSgSEVehY8NkBhwUMnziAR5Wx8S0Nk,5620
|
|
7
7
|
sol_parser/env_config.py,sha256=Lw0SdZuy_MvUaVkyFxS0qPBgMzR9UBbxbN0CVz8nxg4,7296
|
|
8
|
-
sol_parser/event_type_parity.py,sha256=
|
|
9
|
-
sol_parser/event_types.py,sha256=
|
|
8
|
+
sol_parser/event_type_parity.py,sha256=L_oxbUtCTQ9JLGyRiLXNhDTp0UUOcEbe_IPrisgdMBY,4206
|
|
9
|
+
sol_parser/event_types.py,sha256=BtNNPUTniBh0sMJrEYDg3YhmRtQdtnc09LTThlszXw0,86841
|
|
10
10
|
sol_parser/geyser_pb2.py,sha256=Hq66wmWxXD2jSbSVQW7vmBRB7nWmR1DuYDMQ6nKgl3o,20123
|
|
11
11
|
sol_parser/geyser_pb2_grpc.py,sha256=ASPmZsCNvyCzt_j4IrhKjSacWUNLVuAiLfpjmyd-2Qc,15322
|
|
12
12
|
sol_parser/grpc_client.py,sha256=LvYM7FOO-IOEB0GXf8wtGyJNtuiJHvDVRiOwT0kJoI8,32278
|
|
13
|
-
sol_parser/grpc_instruction_parser.py,sha256=
|
|
14
|
-
sol_parser/grpc_types.py,sha256=
|
|
15
|
-
sol_parser/inner_instruction_parser.py,sha256=
|
|
13
|
+
sol_parser/grpc_instruction_parser.py,sha256=p_9BnhC5FHHIXLKPKEM2_infbMC7apr4CQEhMxfkKz4,13450
|
|
14
|
+
sol_parser/grpc_types.py,sha256=750OCMauel0nVQWg2kAk5yFd0Tiwl5S7z-NCbHFFKjw,38327
|
|
15
|
+
sol_parser/inner_instruction_parser.py,sha256=Mynr-pzSFG3AuRUl9wu2_G-wzDJZp_GcorGslP88f0s,20831
|
|
16
16
|
sol_parser/instr_account_utils.py,sha256=MY8bgoIDiv2yJKeWxqhpfKc3pV4xUFTcYKnSXtnQMWc,1990
|
|
17
|
-
sol_parser/instructions.py,sha256=
|
|
17
|
+
sol_parser/instructions.py,sha256=3B3mrL0OJhzNs_K_8-0bLPkh2kF1jh-G3ofTK9tx-a8,78917
|
|
18
18
|
sol_parser/json_util.py,sha256=qq0A5bs-HxxQH6vgg1Kja4tQ8cPaop9uItBcW7Ajox4,1458
|
|
19
|
-
sol_parser/log_instr_dedup.py,sha256=
|
|
19
|
+
sol_parser/log_instr_dedup.py,sha256=AWF3EMaEXI5V_bwjyF24uH_ozWTijRvd0zf7lGBXTMk,14559
|
|
20
20
|
sol_parser/market.py,sha256=p_N6n3b4hEtUjHAQQyGSnrKdHYmkHdY1hXXObHRKc0Y,1858
|
|
21
|
-
sol_parser/merger.py,sha256=
|
|
21
|
+
sol_parser/merger.py,sha256=NGjqSzTNDvDDlIH-8DV2Mk_Z5xJ3ItlnUiAGOAK6kPU,12362
|
|
22
22
|
sol_parser/order_buffer.py,sha256=xW-Okii8a9t9tCqbBKtxFh1moTEi7RqycMFO2kwp-d4,6447
|
|
23
|
-
sol_parser/parser.py,sha256=
|
|
24
|
-
sol_parser/pumpfun_fee_enrich.py,sha256=
|
|
25
|
-
sol_parser/rpc_parser.py,sha256=
|
|
23
|
+
sol_parser/parser.py,sha256=jd-NkWXso7Rcp8TJiBFvjTmNO468tb7rsEElQkU-EV0,11286
|
|
24
|
+
sol_parser/pumpfun_fee_enrich.py,sha256=NHC_chCv2wuaOW5taYG8R6M1bu8cmdxcLf8cjSfo7Kc,4688
|
|
25
|
+
sol_parser/rpc_parser.py,sha256=iWTl_OtNOEpoOmvVEPVmum5QDdGyjSiX6r_3Hx4LOTg,25361
|
|
26
26
|
sol_parser/rust_api_inventory.py,sha256=V5Bx1M3GT-ku_vj_kD6lnbqWExv1K_A00PrmhCFfRec,2257
|
|
27
27
|
sol_parser/rust_event_json.py,sha256=7hho9TGfSOQjHev_8uRa4YHU1hrEsW1RfwcU9qHYz1o,1649
|
|
28
28
|
sol_parser/shredstream_client.py,sha256=xBE6KE9kyTXkXO82iEi99dQCSHq-dIIkFF7u8NHBWHE,9967
|
|
@@ -34,13 +34,13 @@ sol_parser/solana_storage_pb2_grpc.py,sha256=-Gys-K2Kw5Uy3JjtgIXmaYE6YKnXd5ZfBaM
|
|
|
34
34
|
sol_parser/u128_parity.py,sha256=D8PYuy1l-1QwkIEeGCLvrGfzAfTzpBDcGINxRIJAEPs,3487
|
|
35
35
|
sol_parser/verify_discriminators.py,sha256=oqCBWL065ixBIjhHW255nk4S-F1F0x4zfTzs68nXMqA,3011
|
|
36
36
|
sol_parser/account_fillers/__init__.py,sha256=q4q7HZF0Z4-rxhKoRMzV52HSkJ_n_POm4vimYUQlCOA,235
|
|
37
|
-
sol_parser/account_fillers/meteora.py,sha256=
|
|
37
|
+
sol_parser/account_fillers/meteora.py,sha256=ecY3F4KkjnVxBc-Zsnzru52DggkYOdbeauaYrznDxFY,2111
|
|
38
38
|
sol_parser/account_fillers/orca.py,sha256=2s-hfi20fa5sy6p1rGc7_7NxzkpaleJdqn3YD41aBAw,895
|
|
39
39
|
sol_parser/account_fillers/pumpfun.py,sha256=hZgvqquXRDAR1Vny7y69YX7BZyo0tWiqZlnJLu1Zlxs,5969
|
|
40
40
|
sol_parser/account_fillers/pumpswap.py,sha256=1_JBmwFGMr_tAMZpYQsPnUJDoQlGvCpwB90iZzWHLzM,4042
|
|
41
|
-
sol_parser/account_fillers/raydium.py,sha256=
|
|
42
|
-
sol_parser/account_fillers/raydium_launchlab.py,sha256=
|
|
43
|
-
sol_parser/accounts/__init__.py,sha256=
|
|
41
|
+
sol_parser/account_fillers/raydium.py,sha256=av6SUeWVnvm6cxC_A3RIxPhQR1rONgqIzXTDVR-6q_g,3392
|
|
42
|
+
sol_parser/account_fillers/raydium_launchlab.py,sha256=gED19-pyUySD6qe7ecBxMDnfzreCQRY3QlC0NZSb2To,2479
|
|
43
|
+
sol_parser/accounts/__init__.py,sha256=YPhWgp5EBZO1Rc3Gbf_iWQlpnZvRpS7eFoDNLn0tznc,33924
|
|
44
44
|
sol_parser/accounts/raydium_orca.py,sha256=Q3eYe5kBO18LnGOe-xRAGQu8RJv878CEnmPIyVFbZyo,17158
|
|
45
45
|
sol_parser/accounts/rpc_wallet.py,sha256=IT0WEzna9phG7AzhJR8o4GA_BlB4ZvhuDWfCHQcMXwg,1944
|
|
46
46
|
sol_parser/accounts/utils.py,sha256=BAACAIvA2Uz0U26BpYPTalTqiuarXYhkbS-i2o1uJUY,2140
|
|
@@ -51,7 +51,7 @@ sol_parser/grpc/subscribe_builder.py,sha256=fv6_jQAR6Q0seUhXjgcDPnPsG03Bxs59lHGe
|
|
|
51
51
|
sol_parser/grpc/transaction_meta.py,sha256=NmIffIQ1_OIfWGjy6JY-f8pIK5ucjDZXXJryjnlgoQs,5894
|
|
52
52
|
sol_parser/instr/__init__.py,sha256=0_Ky8KpVEoXzxszHcHLTuY2SDsJwu0uAF2Q0wMY1e-c,503
|
|
53
53
|
sol_parser/logs/__init__.py,sha256=e1cbhbCNeXy-NZvVsYCpGksBpZf4NJBLmdlky06og-U,349
|
|
54
|
-
sol_parser_sdk_python-0.5.
|
|
55
|
-
sol_parser_sdk_python-0.5.
|
|
56
|
-
sol_parser_sdk_python-0.5.
|
|
57
|
-
sol_parser_sdk_python-0.5.
|
|
54
|
+
sol_parser_sdk_python-0.5.8.dist-info/METADATA,sha256=hfEZwNMDJ3A-5OrDUyVoQg6kFf1GEMBuWb7UkCXDEOU,14402
|
|
55
|
+
sol_parser_sdk_python-0.5.8.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
56
|
+
sol_parser_sdk_python-0.5.8.dist-info/entry_points.txt,sha256=ZGXRb-2jBdc56d8PCAZFiJBLTAzUKFeHPohysJnKVbA,206
|
|
57
|
+
sol_parser_sdk_python-0.5.8.dist-info/RECORD,,
|
{sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/entry_points.txt
RENAMED
|
File without changes
|