sol-parser-sdk-python 0.4.4__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.
Files changed (54) hide show
  1. sol_parser/__init__.py +400 -0
  2. sol_parser/account_dispatcher.py +209 -0
  3. sol_parser/account_fillers/__init__.py +5 -0
  4. sol_parser/account_fillers/bonk.py +30 -0
  5. sol_parser/account_fillers/meteora.py +51 -0
  6. sol_parser/account_fillers/orca.py +40 -0
  7. sol_parser/account_fillers/pumpfun.py +97 -0
  8. sol_parser/account_fillers/pumpswap.py +93 -0
  9. sol_parser/account_fillers/raydium.py +119 -0
  10. sol_parser/accounts/__init__.py +461 -0
  11. sol_parser/accounts/rpc_wallet.py +64 -0
  12. sol_parser/accounts/utils.py +71 -0
  13. sol_parser/check_migration.py +18 -0
  14. sol_parser/clock.py +10 -0
  15. sol_parser/common/__init__.py +27 -0
  16. sol_parser/dex_parsers.py +2576 -0
  17. sol_parser/entries_decode.py +186 -0
  18. sol_parser/env_config.py +215 -0
  19. sol_parser/event_types.py +1750 -0
  20. sol_parser/geyser_pb2.py +148 -0
  21. sol_parser/geyser_pb2_grpc.py +398 -0
  22. sol_parser/grpc/__init__.py +61 -0
  23. sol_parser/grpc/geyser_connect.py +42 -0
  24. sol_parser/grpc/subscribe_builder.py +133 -0
  25. sol_parser/grpc/transaction_meta.py +183 -0
  26. sol_parser/grpc_client.py +870 -0
  27. sol_parser/grpc_instruction_parser.py +318 -0
  28. sol_parser/grpc_types.py +919 -0
  29. sol_parser/inner_instruction_parser.py +281 -0
  30. sol_parser/instr/__init__.py +15 -0
  31. sol_parser/instr_account_utils.py +58 -0
  32. sol_parser/instructions.py +1026 -0
  33. sol_parser/json_util.py +41 -0
  34. sol_parser/log_instr_dedup.py +284 -0
  35. sol_parser/logs/__init__.py +15 -0
  36. sol_parser/merger.py +233 -0
  37. sol_parser/order_buffer.py +171 -0
  38. sol_parser/parser.py +300 -0
  39. sol_parser/pumpfun_fee_enrich.py +75 -0
  40. sol_parser/rpc_parser.py +655 -0
  41. sol_parser/rust_api_inventory.py +42 -0
  42. sol_parser/rust_event_json.py +50 -0
  43. sol_parser/shredstream_client.py +191 -0
  44. sol_parser/shredstream_pb2.py +40 -0
  45. sol_parser/shredstream_pb2_grpc.py +81 -0
  46. sol_parser/shredstream_pumpfun.py +296 -0
  47. sol_parser/solana_storage_pb2.py +75 -0
  48. sol_parser/solana_storage_pb2_grpc.py +24 -0
  49. sol_parser/u128_parity.py +115 -0
  50. sol_parser/verify_discriminators.py +85 -0
  51. sol_parser_sdk_python-0.4.4.dist-info/METADATA +14 -0
  52. sol_parser_sdk_python-0.4.4.dist-info/RECORD +54 -0
  53. sol_parser_sdk_python-0.4.4.dist-info/WHEEL +4 -0
  54. sol_parser_sdk_python-0.4.4.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,41 @@
1
+ """与 TS `dexEventToJsonString` 对应:将解析结果安全序列化为 JSON(`default=str` 覆盖非原生类型)。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from dataclasses import asdict, is_dataclass
7
+ from typing import Any
8
+
9
+ from .event_types import DexEvent
10
+ from .grpc_types import EventType
11
+
12
+
13
+ def dex_event_json_dumps(obj: Any, **kwargs: Any) -> str:
14
+ return json.dumps(obj, default=str, **kwargs)
15
+
16
+
17
+ def dex_event_to_jsonable(ev: Any) -> Any:
18
+ """将 :class:`~sol_parser.event_types.DexEvent` 转为可 JSON 化的 ``{"type","data"}`` 结构。
19
+
20
+ ``data`` 内嵌 dataclass(含 ``metadata``)用 :func:`dataclasses.asdict` 递归展开,
21
+ 便于 ``indent`` 后一行一个字段阅读。
22
+ """
23
+ if isinstance(ev, DexEvent):
24
+ t = ev.type.value if isinstance(ev.type, EventType) else str(ev.type)
25
+ if ev.data is None:
26
+ return {"type": t, "data": None}
27
+ if is_dataclass(ev.data):
28
+ return {"type": t, "data": asdict(ev.data)}
29
+ return {"type": t, "data": ev.data}
30
+ if is_dataclass(ev):
31
+ return asdict(ev)
32
+ return ev
33
+
34
+
35
+ def format_dex_event_json(ev: Any, *, indent: int = 2, ensure_ascii: bool = False) -> str:
36
+ """将事件格式化为缩进 JSON 字符串(默认每字段一行,对齐常见日志阅读习惯)。"""
37
+ return dex_event_json_dumps(
38
+ dex_event_to_jsonable(ev),
39
+ indent=indent,
40
+ ensure_ascii=ensure_ascii,
41
+ )
@@ -0,0 +1,284 @@
1
+ """Rust-style log/instruction dedupe for Yellowstone transaction parsing."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Dict, List, Optional, Tuple
6
+
7
+ from .event_types import DexEvent
8
+ from .grpc_types import EventType
9
+
10
+ ZERO = "11111111111111111111111111111111"
11
+
12
+ PUMPFUN_TRADE_TYPES = {
13
+ EventType.PUMP_FUN_TRADE,
14
+ EventType.PUMP_FUN_BUY,
15
+ EventType.PUMP_FUN_SELL,
16
+ EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
17
+ }
18
+
19
+
20
+ def _empty(value: Any) -> bool:
21
+ return value is None or value == "" or value == ZERO
22
+
23
+
24
+ def _fill_attr(log: Any, attr: str, ix: Any, ix_attr: Optional[str] = None) -> None:
25
+ src_attr = ix_attr or attr
26
+ value = getattr(ix, src_attr, None)
27
+ if _empty(getattr(log, attr, None)) and not _empty(value):
28
+ setattr(log, attr, value)
29
+
30
+
31
+ def _fill_bonk_mint_param(log: Any, ix: Any, key: str) -> None:
32
+ src = getattr(ix, "base_mint_param", None)
33
+ if not isinstance(src, dict):
34
+ return
35
+ dst = getattr(log, "base_mint_param", None)
36
+ if not isinstance(dst, dict):
37
+ dst = {}
38
+ setattr(log, "base_mint_param", dst)
39
+ value = src.get(key)
40
+ if _empty(dst.get(key)) and not _empty(value):
41
+ dst[key] = value
42
+
43
+
44
+ def _ix_lane(ix_name: Any) -> int:
45
+ if ix_name == "sell":
46
+ return 1
47
+ if ix_name == "buy_exact_sol_in":
48
+ return 2
49
+ return 0
50
+
51
+
52
+ PumpfunLaneBase = Tuple[str, str, bool, int]
53
+
54
+
55
+ def _next_occurrence(base: PumpfunLaneBase, counts: Dict[PumpfunLaneBase, int]) -> int:
56
+ current = counts.get(base, 0)
57
+ counts[base] = current + 1
58
+ return current
59
+
60
+
61
+ def _dedupe_key(ev: DexEvent, pumpfun_lane_counts: Dict[PumpfunLaneBase, int]) -> Optional[str]:
62
+ data = ev.data
63
+ if data is None:
64
+ return None
65
+
66
+ if ev.type in PUMPFUN_TRADE_TYPES:
67
+ lane = _ix_lane(getattr(data, "ix_name", ""))
68
+ base = (
69
+ getattr(data, "mint", ""),
70
+ getattr(data, "user", ""),
71
+ bool(getattr(data, "is_buy", False)),
72
+ lane,
73
+ )
74
+ occ = _next_occurrence(base, pumpfun_lane_counts)
75
+ return f"PumpFunTrade|{base[0]}|{base[1]}|{base[2]}|{base[3]}|{occ}"
76
+
77
+ t = ev.type
78
+ if t == EventType.PUMP_FUN_CREATE:
79
+ return f"PumpFunCreate|{getattr(data, 'mint', '')}"
80
+ if t == EventType.PUMP_FUN_CREATE_V2:
81
+ return f"PumpFunCreateV2|{getattr(data, 'mint', '')}"
82
+ if t == EventType.PUMP_FUN_MIGRATE:
83
+ return (
84
+ f"PumpFunMigrate|{getattr(data, 'mint', '')}|"
85
+ f"{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
86
+ )
87
+ if t == EventType.BONK_TRADE:
88
+ return (
89
+ f"BonkTrade|{getattr(data, 'pool_state', '')}|"
90
+ f"{getattr(data, 'user', '')}|{bool(getattr(data, 'is_buy', False))}"
91
+ )
92
+ if t == EventType.BONK_POOL_CREATE:
93
+ return f"BonkPoolCreate|{getattr(data, 'pool_state', '')}"
94
+ if t == EventType.BONK_MIGRATE_AMM:
95
+ return (
96
+ f"BonkMigrateAmm|{getattr(data, 'old_pool', '')}|"
97
+ f"{getattr(data, 'new_pool', '')}|{getattr(data, 'user', '')}"
98
+ )
99
+ if t == EventType.PUMP_SWAP_BUY:
100
+ return f"PumpSwapBuy|{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
101
+ if t == EventType.PUMP_SWAP_SELL:
102
+ return f"PumpSwapSell|{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
103
+ if t == EventType.PUMP_SWAP_CREATE_POOL:
104
+ return (
105
+ f"PumpSwapCreatePool|{getattr(data, 'pool', '')}|"
106
+ f"{getattr(data, 'base_mint', '')}|{getattr(data, 'quote_mint', '')}"
107
+ )
108
+ if t == EventType.PUMP_SWAP_LIQUIDITY_ADDED:
109
+ return f"PumpSwapLiquidityAdded|{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
110
+ if t == EventType.PUMP_SWAP_LIQUIDITY_REMOVED:
111
+ return f"PumpSwapLiquidityRemoved|{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
112
+ if t == EventType.RAYDIUM_CLMM_SWAP:
113
+ return f"RaydiumClmmSwap|{getattr(data, 'pool_state', '')}|{bool(getattr(data, 'zero_for_one', False))}"
114
+ if t == EventType.RAYDIUM_AMM_V4_SWAP:
115
+ return f"RaydiumAmmV4Swap|{getattr(data, 'amm', '')}"
116
+ if t == EventType.METEORA_DLMM_SWAP:
117
+ return (
118
+ f"MeteoraDlmmSwap|{getattr(data, 'pool', '')}|"
119
+ f"{getattr(data, 'from_addr', '')}|{bool(getattr(data, 'swap_for_y', False))}"
120
+ )
121
+ return None
122
+
123
+
124
+ def _merge_pumpfun_trade(log: Any, ix: Any) -> None:
125
+ for attr in (
126
+ "bonding_curve",
127
+ "associated_bonding_curve",
128
+ "token_program",
129
+ "creator_vault",
130
+ "fee_recipient",
131
+ "creator",
132
+ "extra_instruction_account",
133
+ ):
134
+ _fill_attr(log, attr, ix)
135
+ if getattr(log, "ix_name", "") == "" and getattr(ix, "ix_name", "") != "":
136
+ log.ix_name = ix.ix_name
137
+ log.is_created_buy = bool(getattr(log, "is_created_buy", False)) or bool(
138
+ getattr(ix, "is_created_buy", False)
139
+ )
140
+
141
+
142
+ def _merge_pumpfun_create(log: Any, ix: Any) -> None:
143
+ for attr in ("name", "symbol", "uri", "bonding_curve", "user", "creator", "token_program"):
144
+ _fill_attr(log, attr, ix)
145
+
146
+
147
+ def _merge_pumpfun_create_v2(log: Any, ix: Any) -> None:
148
+ _merge_pumpfun_create(log, ix)
149
+ for attr in (
150
+ "mint_authority",
151
+ "associated_bonding_curve",
152
+ "global_account",
153
+ "system_program",
154
+ "associated_token_program",
155
+ "mayhem_program_id",
156
+ "global_params",
157
+ "sol_vault",
158
+ "mayhem_state",
159
+ "mayhem_token_vault",
160
+ "event_authority",
161
+ "program",
162
+ "observed_fee_recipient",
163
+ ):
164
+ _fill_attr(log, attr, ix)
165
+
166
+
167
+ def _merge_pumpswap_buy_sell(log: Any, ix: Any, include_ix_name: bool) -> None:
168
+ for attr in (
169
+ "user_base_token_account",
170
+ "user_quote_token_account",
171
+ "protocol_fee_recipient",
172
+ "protocol_fee_recipient_token_account",
173
+ "coin_creator",
174
+ "base_mint",
175
+ "quote_mint",
176
+ "pool_base_token_account",
177
+ "pool_quote_token_account",
178
+ "coin_creator_vault_ata",
179
+ "coin_creator_vault_authority",
180
+ "base_token_program",
181
+ "quote_token_program",
182
+ ):
183
+ _fill_attr(log, attr, ix)
184
+ if include_ix_name and getattr(log, "ix_name", "") == "" and getattr(ix, "ix_name", "") != "":
185
+ log.ix_name = ix.ix_name
186
+
187
+
188
+ def _merge_grpc_instruction_into_log(log_ev: DexEvent, ix_ev: DexEvent) -> None:
189
+ log = log_ev.data
190
+ ix = ix_ev.data
191
+ if log is None or ix is None:
192
+ return
193
+
194
+ if log_ev.type in PUMPFUN_TRADE_TYPES and ix_ev.type in PUMPFUN_TRADE_TYPES:
195
+ _merge_pumpfun_trade(log, ix)
196
+ elif log_ev.type == EventType.PUMP_FUN_CREATE and ix_ev.type == EventType.PUMP_FUN_CREATE:
197
+ _merge_pumpfun_create(log, ix)
198
+ elif log_ev.type == EventType.PUMP_FUN_CREATE_V2 and ix_ev.type == EventType.PUMP_FUN_CREATE_V2:
199
+ _merge_pumpfun_create_v2(log, ix)
200
+ elif log_ev.type == EventType.PUMP_FUN_MIGRATE and ix_ev.type == EventType.PUMP_FUN_MIGRATE:
201
+ for attr in ("bonding_curve", "pool", "user"):
202
+ _fill_attr(log, attr, ix)
203
+ elif log_ev.type == EventType.PUMP_SWAP_BUY and ix_ev.type == EventType.PUMP_SWAP_BUY:
204
+ _merge_pumpswap_buy_sell(log, ix, True)
205
+ elif log_ev.type == EventType.PUMP_SWAP_SELL and ix_ev.type == EventType.PUMP_SWAP_SELL:
206
+ _merge_pumpswap_buy_sell(log, ix, False)
207
+ elif log_ev.type == EventType.PUMP_SWAP_CREATE_POOL and ix_ev.type == EventType.PUMP_SWAP_CREATE_POOL:
208
+ for attr in (
209
+ "creator",
210
+ "pool",
211
+ "lp_mint",
212
+ "user_base_token_account",
213
+ "user_quote_token_account",
214
+ "coin_creator",
215
+ ):
216
+ _fill_attr(log, attr, ix)
217
+ elif (
218
+ log_ev.type == EventType.PUMP_SWAP_LIQUIDITY_ADDED
219
+ and ix_ev.type == EventType.PUMP_SWAP_LIQUIDITY_ADDED
220
+ ) or (
221
+ log_ev.type == EventType.PUMP_SWAP_LIQUIDITY_REMOVED
222
+ and ix_ev.type == EventType.PUMP_SWAP_LIQUIDITY_REMOVED
223
+ ):
224
+ for attr in ("user_base_token_account", "user_quote_token_account", "user_pool_token_account"):
225
+ _fill_attr(log, attr, ix)
226
+ elif log_ev.type == EventType.RAYDIUM_CLMM_SWAP and ix_ev.type == EventType.RAYDIUM_CLMM_SWAP:
227
+ for attr in ("token_account_0", "token_account_1", "sender"):
228
+ _fill_attr(log, attr, ix)
229
+ elif log_ev.type == EventType.RAYDIUM_AMM_V4_SWAP and ix_ev.type == EventType.RAYDIUM_AMM_V4_SWAP:
230
+ for attr in (
231
+ "token_program",
232
+ "amm_authority",
233
+ "amm_open_orders",
234
+ "pool_coin_token_account",
235
+ "pool_pc_token_account",
236
+ "serum_program",
237
+ "serum_market",
238
+ "serum_bids",
239
+ "serum_asks",
240
+ "serum_event_queue",
241
+ "serum_coin_vault_account",
242
+ "serum_pc_vault_account",
243
+ "serum_vault_signer",
244
+ "user_source_token_account",
245
+ "user_destination_token_account",
246
+ ):
247
+ _fill_attr(log, attr, ix)
248
+ elif log_ev.type == EventType.BONK_POOL_CREATE and ix_ev.type == EventType.BONK_POOL_CREATE:
249
+ _fill_attr(log, "creator", ix)
250
+ for key in ("name", "symbol", "uri"):
251
+ _fill_bonk_mint_param(log, ix, key)
252
+ elif log_ev.type == EventType.BONK_MIGRATE_AMM and ix_ev.type == EventType.BONK_MIGRATE_AMM:
253
+ for attr in ("old_pool", "new_pool", "user"):
254
+ _fill_attr(log, attr, ix)
255
+
256
+
257
+ def dedupe_log_instruction_events(
258
+ log_events: List[DexEvent],
259
+ instruction_events: List[DexEvent],
260
+ ) -> List[DexEvent]:
261
+ out: List[DexEvent] = []
262
+ index_by_key: Dict[str, int] = {}
263
+ log_pumpfun_counts: Dict[PumpfunLaneBase, int] = {}
264
+ ix_pumpfun_counts: Dict[PumpfunLaneBase, int] = {}
265
+
266
+ for ev in log_events:
267
+ key = _dedupe_key(ev, log_pumpfun_counts)
268
+ if key is not None:
269
+ index_by_key[key] = len(out)
270
+ out.append(ev)
271
+
272
+ for ev in instruction_events:
273
+ key = _dedupe_key(ev, ix_pumpfun_counts)
274
+ if key is None:
275
+ out.append(ev)
276
+ continue
277
+ idx = index_by_key.get(key)
278
+ if idx is None:
279
+ index_by_key[key] = len(out)
280
+ out.append(ev)
281
+ continue
282
+ _merge_grpc_instruction_into_log(out[idx], ev)
283
+
284
+ return out
@@ -0,0 +1,15 @@
1
+ """对齐 Rust ``logs`` 模块:日志解析入口与工具(实现位于 ``parser`` / ``dex_parsers``)。"""
2
+
3
+ from ..parser import (
4
+ decode_program_data_line,
5
+ parse_log,
6
+ parse_log_optimized,
7
+ parse_log_unified,
8
+ )
9
+
10
+ __all__ = [
11
+ "decode_program_data_line",
12
+ "parse_log",
13
+ "parse_log_optimized",
14
+ "parse_log_unified",
15
+ ]
sol_parser/merger.py ADDED
@@ -0,0 +1,233 @@
1
+ """Instruction + inner instruction 事件合并(对齐 Rust ``core/merger``)。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import dataclasses
6
+ from typing import Any
7
+
8
+ from .event_types import (
9
+ DexEvent,
10
+ PumpFunCreateEvent,
11
+ PumpFunCreateV2TokenEvent,
12
+ PumpFunMigrateEvent,
13
+ PumpFunTradeEvent,
14
+ PumpSwapBuyEvent,
15
+ PumpSwapCreatePoolEvent,
16
+ PumpSwapLiquidityAddedEvent,
17
+ PumpSwapLiquidityRemovedEvent,
18
+ PumpSwapSellEvent,
19
+ RaydiumAmmV4DepositEvent,
20
+ RaydiumAmmV4SwapEvent,
21
+ RaydiumAmmV4WithdrawEvent,
22
+ RaydiumClmmCollectFeeEvent,
23
+ RaydiumClmmCreatePoolEvent,
24
+ RaydiumClmmDecreaseLiquidityEvent,
25
+ RaydiumClmmIncreaseLiquidityEvent,
26
+ RaydiumClmmSwapEvent,
27
+ RaydiumCpmmDepositEvent,
28
+ RaydiumCpmmSwapEvent,
29
+ RaydiumCpmmWithdrawEvent,
30
+ MeteoraDammV2AddLiquidityEvent,
31
+ MeteoraDammV2ClosePositionEvent,
32
+ MeteoraDammV2CreatePositionEvent,
33
+ MeteoraDammV2RemoveLiquidityEvent,
34
+ MeteoraDammV2SwapEvent,
35
+ MeteoraPoolsAddLiquidityEvent,
36
+ MeteoraPoolsRemoveLiquidityEvent,
37
+ MeteoraPoolsSwapEvent,
38
+ OrcaWhirlpoolLiquidityDecreasedEvent,
39
+ OrcaWhirlpoolLiquidityIncreasedEvent,
40
+ OrcaWhirlpoolSwapEvent,
41
+ BonkTradeEvent,
42
+ )
43
+ from .grpc_types import EventType
44
+
45
+
46
+ def _merge_generic(base: Any, inner: Any) -> None:
47
+ for f in dataclasses.fields(type(base)):
48
+ setattr(base, f.name, getattr(inner, f.name))
49
+
50
+
51
+ def merge_pumpfun_trade(base: PumpFunTradeEvent, inner: PumpFunTradeEvent) -> None:
52
+ base.mint = inner.mint
53
+ base.sol_amount = inner.sol_amount
54
+ base.token_amount = inner.token_amount
55
+ base.is_buy = inner.is_buy
56
+ base.user = inner.user
57
+ base.timestamp = inner.timestamp
58
+ base.virtual_sol_reserves = inner.virtual_sol_reserves
59
+ base.virtual_token_reserves = inner.virtual_token_reserves
60
+ base.real_sol_reserves = inner.real_sol_reserves
61
+ base.real_token_reserves = inner.real_token_reserves
62
+ base.fee_recipient = inner.fee_recipient
63
+ base.fee_basis_points = inner.fee_basis_points
64
+ base.fee = inner.fee
65
+ base.creator = inner.creator
66
+ base.creator_fee_basis_points = inner.creator_fee_basis_points
67
+ base.creator_fee = inner.creator_fee
68
+ base.track_volume = inner.track_volume
69
+ base.total_unclaimed_tokens = inner.total_unclaimed_tokens
70
+ base.total_claimed_tokens = inner.total_claimed_tokens
71
+ base.current_sol_volume = inner.current_sol_volume
72
+ base.last_update_timestamp = inner.last_update_timestamp
73
+ base.ix_name = inner.ix_name
74
+ base.is_created_buy = inner.is_created_buy
75
+ base.mayhem_mode = inner.mayhem_mode
76
+ base.cashback_fee_basis_points = inner.cashback_fee_basis_points
77
+ base.cashback = inner.cashback
78
+ base.is_cashback_coin = inner.is_cashback_coin
79
+
80
+
81
+ def merge_pumpfun_create(base: PumpFunCreateEvent, inner: PumpFunCreateEvent) -> None:
82
+ base.name = inner.name
83
+ base.symbol = inner.symbol
84
+ base.uri = inner.uri
85
+ base.mint = inner.mint
86
+ base.bonding_curve = inner.bonding_curve
87
+ base.user = inner.user
88
+ base.creator = inner.creator
89
+ base.timestamp = inner.timestamp
90
+ base.virtual_token_reserves = inner.virtual_token_reserves
91
+ base.virtual_sol_reserves = inner.virtual_sol_reserves
92
+ base.real_token_reserves = inner.real_token_reserves
93
+ base.token_total_supply = inner.token_total_supply
94
+ base.token_program = inner.token_program
95
+ base.is_mayhem_mode = inner.is_mayhem_mode
96
+ base.is_cashback_enabled = inner.is_cashback_enabled
97
+
98
+
99
+ def merge_pumpfun_migrate(base: PumpFunMigrateEvent, inner: PumpFunMigrateEvent) -> None:
100
+ base.user = inner.user
101
+ base.mint = inner.mint
102
+ base.mint_amount = inner.mint_amount
103
+ base.sol_amount = inner.sol_amount
104
+ base.pool_migration_fee = inner.pool_migration_fee
105
+ base.bonding_curve = inner.bonding_curve
106
+ base.timestamp = inner.timestamp
107
+ base.pool = inner.pool
108
+
109
+
110
+ def merge_dex_events(base: DexEvent, inner: DexEvent) -> None:
111
+ """将 ``inner`` 合并进 ``base``(就地修改 ``base.data``)。"""
112
+ bd = base.data
113
+ ind = inner.data
114
+
115
+ if isinstance(bd, PumpFunTradeEvent) and isinstance(ind, PumpFunTradeEvent):
116
+ if base.type in (
117
+ EventType.PUMP_FUN_TRADE,
118
+ EventType.PUMP_FUN_BUY,
119
+ EventType.PUMP_FUN_SELL,
120
+ EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
121
+ ) and inner.type in (
122
+ EventType.PUMP_FUN_TRADE,
123
+ EventType.PUMP_FUN_BUY,
124
+ EventType.PUMP_FUN_SELL,
125
+ EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
126
+ ):
127
+ merge_pumpfun_trade(bd, ind)
128
+ base.type = inner.type
129
+ return
130
+
131
+ if isinstance(bd, PumpFunCreateEvent) and isinstance(ind, PumpFunCreateEvent):
132
+ merge_pumpfun_create(bd, ind)
133
+ return
134
+
135
+ if isinstance(bd, PumpFunCreateV2TokenEvent) and isinstance(ind, PumpFunCreateV2TokenEvent):
136
+ _merge_generic(bd, ind)
137
+ return
138
+
139
+ if isinstance(bd, PumpFunMigrateEvent) and isinstance(ind, PumpFunMigrateEvent):
140
+ merge_pumpfun_migrate(bd, ind)
141
+ return
142
+
143
+ if isinstance(bd, PumpSwapBuyEvent) and isinstance(ind, PumpSwapBuyEvent):
144
+ _merge_generic(bd, ind)
145
+ return
146
+ if isinstance(bd, PumpSwapSellEvent) and isinstance(ind, PumpSwapSellEvent):
147
+ _merge_generic(bd, ind)
148
+ return
149
+ if isinstance(bd, PumpSwapCreatePoolEvent) and isinstance(ind, PumpSwapCreatePoolEvent):
150
+ _merge_generic(bd, ind)
151
+ return
152
+ if isinstance(bd, PumpSwapLiquidityAddedEvent) and isinstance(ind, PumpSwapLiquidityAddedEvent):
153
+ _merge_generic(bd, ind)
154
+ return
155
+ if isinstance(bd, PumpSwapLiquidityRemovedEvent) and isinstance(ind, PumpSwapLiquidityRemovedEvent):
156
+ _merge_generic(bd, ind)
157
+ return
158
+
159
+ if isinstance(bd, RaydiumClmmSwapEvent) and isinstance(ind, RaydiumClmmSwapEvent):
160
+ _merge_generic(bd, ind)
161
+ return
162
+ if isinstance(bd, RaydiumClmmIncreaseLiquidityEvent) and isinstance(ind, RaydiumClmmIncreaseLiquidityEvent):
163
+ _merge_generic(bd, ind)
164
+ return
165
+ if isinstance(bd, RaydiumClmmDecreaseLiquidityEvent) and isinstance(ind, RaydiumClmmDecreaseLiquidityEvent):
166
+ _merge_generic(bd, ind)
167
+ return
168
+ if isinstance(bd, RaydiumClmmCreatePoolEvent) and isinstance(ind, RaydiumClmmCreatePoolEvent):
169
+ _merge_generic(bd, ind)
170
+ return
171
+ if isinstance(bd, RaydiumClmmCollectFeeEvent) and isinstance(ind, RaydiumClmmCollectFeeEvent):
172
+ _merge_generic(bd, ind)
173
+ return
174
+
175
+ if isinstance(bd, RaydiumCpmmSwapEvent) and isinstance(ind, RaydiumCpmmSwapEvent):
176
+ _merge_generic(bd, ind)
177
+ return
178
+ if isinstance(bd, RaydiumCpmmDepositEvent) and isinstance(ind, RaydiumCpmmDepositEvent):
179
+ _merge_generic(bd, ind)
180
+ return
181
+ if isinstance(bd, RaydiumCpmmWithdrawEvent) and isinstance(ind, RaydiumCpmmWithdrawEvent):
182
+ _merge_generic(bd, ind)
183
+ return
184
+
185
+ if isinstance(bd, RaydiumAmmV4SwapEvent) and isinstance(ind, RaydiumAmmV4SwapEvent):
186
+ _merge_generic(bd, ind)
187
+ return
188
+ if isinstance(bd, RaydiumAmmV4DepositEvent) and isinstance(ind, RaydiumAmmV4DepositEvent):
189
+ _merge_generic(bd, ind)
190
+ return
191
+ if isinstance(bd, RaydiumAmmV4WithdrawEvent) and isinstance(ind, RaydiumAmmV4WithdrawEvent):
192
+ _merge_generic(bd, ind)
193
+ return
194
+
195
+ if isinstance(bd, OrcaWhirlpoolSwapEvent) and isinstance(ind, OrcaWhirlpoolSwapEvent):
196
+ _merge_generic(bd, ind)
197
+ return
198
+ if isinstance(bd, OrcaWhirlpoolLiquidityIncreasedEvent) and isinstance(ind, OrcaWhirlpoolLiquidityIncreasedEvent):
199
+ _merge_generic(bd, ind)
200
+ return
201
+ if isinstance(bd, OrcaWhirlpoolLiquidityDecreasedEvent) and isinstance(ind, OrcaWhirlpoolLiquidityDecreasedEvent):
202
+ _merge_generic(bd, ind)
203
+ return
204
+
205
+ if isinstance(bd, MeteoraPoolsSwapEvent) and isinstance(ind, MeteoraPoolsSwapEvent):
206
+ _merge_generic(bd, ind)
207
+ return
208
+ if isinstance(bd, MeteoraPoolsAddLiquidityEvent) and isinstance(ind, MeteoraPoolsAddLiquidityEvent):
209
+ _merge_generic(bd, ind)
210
+ return
211
+ if isinstance(bd, MeteoraPoolsRemoveLiquidityEvent) and isinstance(ind, MeteoraPoolsRemoveLiquidityEvent):
212
+ _merge_generic(bd, ind)
213
+ return
214
+
215
+ if isinstance(bd, MeteoraDammV2SwapEvent) and isinstance(ind, MeteoraDammV2SwapEvent):
216
+ _merge_generic(bd, ind)
217
+ return
218
+ if isinstance(bd, MeteoraDammV2AddLiquidityEvent) and isinstance(ind, MeteoraDammV2AddLiquidityEvent):
219
+ _merge_generic(bd, ind)
220
+ return
221
+ if isinstance(bd, MeteoraDammV2RemoveLiquidityEvent) and isinstance(ind, MeteoraDammV2RemoveLiquidityEvent):
222
+ _merge_generic(bd, ind)
223
+ return
224
+ if isinstance(bd, MeteoraDammV2CreatePositionEvent) and isinstance(ind, MeteoraDammV2CreatePositionEvent):
225
+ _merge_generic(bd, ind)
226
+ return
227
+ if isinstance(bd, MeteoraDammV2ClosePositionEvent) and isinstance(ind, MeteoraDammV2ClosePositionEvent):
228
+ _merge_generic(bd, ind)
229
+ return
230
+
231
+ if isinstance(bd, BonkTradeEvent) and isinstance(ind, BonkTradeEvent):
232
+ _merge_generic(bd, ind)
233
+ return