sol-parser-sdk-python 0.5.6__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/dex_parsers.py CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import base64
10
11
  import struct
11
12
  from typing import Any, Dict, List, Optional
12
13
 
@@ -27,8 +28,14 @@ from .event_types import (
27
28
  RaydiumAmmV4WithdrawPnlEvent, RaydiumAmmV4Initialize2Event,
28
29
  RaydiumClmmSwapEvent, RaydiumClmmIncreaseLiquidityEvent,
29
30
  RaydiumClmmDecreaseLiquidityEvent, RaydiumClmmCreatePoolEvent,
30
- RaydiumClmmCollectFeeEvent, RaydiumCpmmSwapEvent, RaydiumCpmmDepositEvent,
31
- RaydiumCpmmWithdrawEvent, OrcaWhirlpoolSwapEvent, OrcaWhirlpoolLiquidityIncreasedEvent,
31
+ RaydiumClmmCollectFeeEvent, RaydiumClmmLiquidityChangeEvent,
32
+ RaydiumClmmConfigChangeEvent, RaydiumClmmCreatePersonalPositionEvent,
33
+ RaydiumClmmLiquidityCalculateEvent, RaydiumClmmOpenLimitOrderEvent,
34
+ RaydiumClmmIncreaseLimitOrderEvent, RaydiumClmmDecreaseLimitOrderEvent,
35
+ RaydiumClmmSettleLimitOrderEvent, RaydiumClmmUpdateRewardInfosEvent,
36
+ RaydiumCpmmSwapEvent, RaydiumCpmmDepositEvent,
37
+ RaydiumCpmmWithdrawEvent, RaydiumCpmmInitializeEvent,
38
+ OrcaWhirlpoolSwapEvent, OrcaWhirlpoolLiquidityIncreasedEvent,
32
39
  OrcaWhirlpoolLiquidityDecreasedEvent, OrcaWhirlpoolPoolInitializedEvent,
33
40
  MeteoraDlmmSwapEvent, MeteoraDlmmAddLiquidityEvent, MeteoraDlmmRemoveLiquidityEvent,
34
41
  MeteoraDlmmInitializePoolEvent, MeteoraDlmmInitializeBinArrayEvent,
@@ -39,6 +46,11 @@ from .event_types import (
39
46
  MeteoraDammV2CreatePositionEvent, MeteoraDammV2ClosePositionEvent,
40
47
  MeteoraDammV2AddLiquidityEvent, MeteoraDammV2RemoveLiquidityEvent,
41
48
  MeteoraDammV2InitializePoolEvent,
49
+ MeteoraDammV2DynamicFeeParameters,
50
+ MeteoraDammV2UpdateDelegatePermissionEvent,
51
+ MeteoraDammV2WithdrawDeadLiquidityRewardEvent,
52
+ MeteoraDammV2CreateConfigEvent,
53
+ MeteoraDammV2CreateDynamicConfigEvent,
42
54
  MeteoraDbcCurveCompleteEvent, MeteoraDbcInitializePoolEvent, MeteoraDbcSwapEvent,
43
55
  RaydiumLaunchlabTradeEvent, RaydiumLaunchlabPoolCreateEvent,
44
56
  )
@@ -246,6 +258,8 @@ def parse_trade_from_data(data: bytes, meta: dict, is_created_buy: bool) -> DexE
246
258
  quote_amount = _optional_u64(data, tail)
247
259
  virtual_quote_reserves = _optional_u64(data, tail)
248
260
  real_quote_reserves = _optional_u64(data, tail)
261
+ holder_rewards_bps = _optional_u64(data, tail)
262
+ holder_rewards = _optional_u64(data, tail)
249
263
 
250
264
  event_data = PumpFunTradeEvent(
251
265
  metadata=_make_meta(meta),
@@ -282,6 +296,8 @@ def parse_trade_from_data(data: bytes, meta: dict, is_created_buy: bool) -> DexE
282
296
  quote_amount=quote_amount,
283
297
  virtual_quote_reserves=virtual_quote_reserves,
284
298
  real_quote_reserves=real_quote_reserves,
299
+ holder_rewards_bps=holder_rewards_bps,
300
+ holder_rewards=holder_rewards,
285
301
  is_cashback_coin=cb_bps > 0,
286
302
  bonding_curve=Z,
287
303
  associated_bonding_curve=Z,
@@ -337,6 +353,10 @@ def parse_create_from_data(data: bytes, meta: dict) -> DexEvent:
337
353
  quote_mint = _pub(data, o) if o + 32 <= len(data) else Z
338
354
  o += 32
339
355
  virtual_quote_reserves = _u64le(data, o) if o + 8 <= len(data) else 0
356
+ o += 8
357
+ creator_fee_bps = _u64le(data, o) if o + 8 <= len(data) else 0
358
+ o += 8
359
+ is_holder_reward = _bool(data, o) if o < len(data) else False
340
360
 
341
361
  return DexEvent(
342
362
  type=EventType.PUMP_FUN_CREATE,
@@ -359,6 +379,8 @@ def parse_create_from_data(data: bytes, meta: dict) -> DexEvent:
359
379
  is_cashback_enabled=ice,
360
380
  quote_mint=quote_mint,
361
381
  virtual_quote_reserves=virtual_quote_reserves,
382
+ creator_fee_bps=creator_fee_bps,
383
+ is_holder_reward=is_holder_reward,
362
384
  ),
363
385
  )
364
386
 
@@ -752,129 +774,179 @@ def parse_pump_fees_upsert_fee_tiers_from_data(data: bytes, meta: dict) -> DexEv
752
774
 
753
775
 
754
776
  def parse_clmm_swap_from_data(data: bytes, meta: dict) -> DexEvent:
755
- if len(data) < 32 + 32 + 8 + 8 + 16 + 1:
777
+ if len(data) < 32 + 32 + 32 + 32 + 8 + 8 + 8 + 8 + 1 + 16 + 16 + 4:
756
778
  return DexEvent()
757
779
  o = 0
758
780
  ps = _pub(data, o)
759
781
  o += 32
760
- user = _pub(data, o)
761
- o += 32 + 8 + 8
782
+ sender = _pub(data, o)
783
+ o += 32
784
+ token_account_0 = _pub(data, o)
785
+ o += 32
786
+ token_account_1 = _pub(data, o)
787
+ o += 32
788
+ amount_0 = _u64le(data, o)
789
+ o += 8
790
+ transfer_fee_0 = _u64le(data, o)
791
+ o += 8
792
+ amount_1 = _u64le(data, o)
793
+ o += 8
794
+ transfer_fee_1 = _u64le(data, o)
795
+ o += 8
796
+ zfo = _bool(data, o)
797
+ o += 1
762
798
  sqrt = str(_u128le_int(data, o))
763
799
  o += 16
764
- zfo = _bool(data, o)
800
+ liq = str(_u128le_int(data, o))
801
+ o += 16
802
+ tick = _i32le(data, o)
765
803
 
766
804
  return DexEvent(
767
805
  type=EventType.RAYDIUM_CLMM_SWAP,
768
806
  data=RaydiumClmmSwapEvent(
769
807
  metadata=_make_meta(meta),
770
808
  pool_state=ps,
771
- sender=user,
772
- token_account_0=Z,
773
- token_account_1=Z,
774
- amount_0=0,
775
- amount_1=0,
809
+ sender=sender,
810
+ token_account_0=token_account_0,
811
+ token_account_1=token_account_1,
812
+ amount_0=amount_0,
813
+ amount_1=amount_1,
776
814
  zero_for_one=zfo,
777
815
  sqrt_price_x64=sqrt,
778
- liquidity="0",
779
- transfer_fee_0=0,
780
- transfer_fee_1=0,
781
- tick=0,
816
+ liquidity=liq,
817
+ transfer_fee_0=transfer_fee_0,
818
+ transfer_fee_1=transfer_fee_1,
819
+ tick=tick,
782
820
  ),
783
821
  )
784
822
 
785
823
 
786
824
  def parse_clmm_inc_from_data(data: bytes, meta: dict) -> DexEvent:
787
- if len(data) < 32 + 32 + 16 + 8 + 8:
825
+ if len(data) < 32 + 16 + 8 + 8 + 8 + 8:
788
826
  return DexEvent()
789
827
  o = 0
790
- pool = _pub(data, o)
791
- o += 32
792
- user = _pub(data, o)
828
+ position_nft_mint = _pub(data, o)
793
829
  o += 32
794
830
  liq = str(_u128le_int(data, o))
795
831
  o += 16
796
- a0 = _u64le(data, o)
832
+ amount_0 = _u64le(data, o)
797
833
  o += 8
798
- a1 = _u64le(data, o)
834
+ amount_1 = _u64le(data, o)
835
+ o += 8
836
+ amount_0_transfer_fee = _u64le(data, o)
837
+ o += 8
838
+ amount_1_transfer_fee = _u64le(data, o)
799
839
 
800
840
  return DexEvent(
801
841
  type=EventType.RAYDIUM_CLMM_INCREASE_LIQUIDITY,
802
842
  data=RaydiumClmmIncreaseLiquidityEvent(
803
843
  metadata=_make_meta(meta),
804
- pool=pool,
805
- position_nft_mint=Z,
806
- user=user,
844
+ pool=Z,
845
+ position_nft_mint=position_nft_mint,
846
+ user=Z,
807
847
  liquidity=liq,
808
- amount0_max=a0,
809
- amount1_max=a1,
848
+ amount_0=amount_0,
849
+ amount_1=amount_1,
850
+ amount_0_transfer_fee=amount_0_transfer_fee,
851
+ amount_1_transfer_fee=amount_1_transfer_fee,
852
+ amount0_max=0,
853
+ amount1_max=0,
810
854
  ),
811
855
  )
812
856
 
813
857
 
814
858
  def parse_clmm_dec_from_data(data: bytes, meta: dict) -> DexEvent:
815
- if len(data) < 32 + 32 + 16 + 8 + 8:
859
+ if len(data) < 32 + 16 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8:
816
860
  return DexEvent()
817
861
  o = 0
818
- pool = _pub(data, o)
819
- o += 32
820
- user = _pub(data, o)
862
+ position_nft_mint = _pub(data, o)
821
863
  o += 32
822
864
  liq = str(_u128le_int(data, o))
823
865
  o += 16
824
- a0 = _u64le(data, o)
866
+ decrease_amount_0 = _u64le(data, o)
825
867
  o += 8
826
- a1 = _u64le(data, o)
868
+ decrease_amount_1 = _u64le(data, o)
869
+ o += 8
870
+ fee_amount_0 = _u64le(data, o)
871
+ o += 8
872
+ fee_amount_1 = _u64le(data, o)
873
+ o += 8
874
+ reward_amounts = [_u64le(data, o), _u64le(data, o + 8), _u64le(data, o + 16)]
875
+ o += 24
876
+ transfer_fee_0 = _u64le(data, o)
877
+ o += 8
878
+ transfer_fee_1 = _u64le(data, o)
827
879
 
828
880
  return DexEvent(
829
881
  type=EventType.RAYDIUM_CLMM_DECREASE_LIQUIDITY,
830
882
  data=RaydiumClmmDecreaseLiquidityEvent(
831
883
  metadata=_make_meta(meta),
832
- pool=pool,
833
- position_nft_mint=Z,
834
- user=user,
884
+ pool=Z,
885
+ position_nft_mint=position_nft_mint,
886
+ user=Z,
835
887
  liquidity=liq,
836
- amount0_min=a0,
837
- amount1_min=a1,
888
+ decrease_amount_0=decrease_amount_0,
889
+ decrease_amount_1=decrease_amount_1,
890
+ fee_amount_0=fee_amount_0,
891
+ fee_amount_1=fee_amount_1,
892
+ reward_amounts=reward_amounts,
893
+ transfer_fee_0=transfer_fee_0,
894
+ transfer_fee_1=transfer_fee_1,
895
+ amount0_min=0,
896
+ amount1_min=0,
838
897
  ),
839
898
  )
840
899
 
841
900
 
842
901
  def parse_clmm_create_from_data(data: bytes, meta: dict) -> DexEvent:
843
- if len(data) < 32 + 32 + 16 + 8:
902
+ if len(data) < 32 + 32 + 2 + 32 + 16 + 4 + 32 + 32:
844
903
  return DexEvent()
845
904
  o = 0
846
- pool = _pub(data, o)
905
+ token_0_mint = _pub(data, o)
906
+ o += 32
907
+ token_1_mint = _pub(data, o)
847
908
  o += 32
848
- cr = _pub(data, o)
909
+ tick_spacing = _u16le(data, o)
910
+ o += 2
911
+ pool = _pub(data, o)
849
912
  o += 32
850
913
  sqrt = str(_u128le_int(data, o))
851
914
  o += 16
852
- ot = _u64le(data, o)
915
+ tick = _i32le(data, o)
916
+ o += 4
917
+ token_vault_0 = _pub(data, o)
918
+ o += 32
919
+ token_vault_1 = _pub(data, o)
853
920
 
854
921
  return DexEvent(
855
922
  type=EventType.RAYDIUM_CLMM_CREATE_POOL,
856
923
  data=RaydiumClmmCreatePoolEvent(
857
924
  metadata=_make_meta(meta),
858
925
  pool=pool,
859
- creator=cr,
860
- token_0_mint=Z,
861
- token_1_mint=Z,
862
- tick_spacing=0,
926
+ creator=Z,
927
+ token_0_mint=token_0_mint,
928
+ token_1_mint=token_1_mint,
929
+ tick_spacing=tick_spacing,
863
930
  fee_rate=0,
864
931
  sqrt_price_x64=sqrt,
865
- open_time=ot,
932
+ tick=tick,
933
+ token_vault_0=token_vault_0,
934
+ token_vault_1=token_vault_1,
935
+ open_time=0,
866
936
  ),
867
937
  )
868
938
 
869
939
 
870
- def parse_clmm_collect_from_data(data: bytes, meta: dict) -> DexEvent:
871
- if len(data) < 32 + 32 + 8 + 8:
940
+ def parse_clmm_collect_personal_from_data(data: bytes, meta: dict) -> DexEvent:
941
+ if len(data) < 32 + 32 + 32 + 8 + 8:
872
942
  return DexEvent()
873
943
  o = 0
874
- ps = _pub(data, o)
875
- o += 32
876
944
  pn = _pub(data, o)
877
945
  o += 32
946
+ recipient_0 = _pub(data, o)
947
+ o += 32
948
+ recipient_1 = _pub(data, o)
949
+ o += 32
878
950
  a0 = _u64le(data, o)
879
951
  o += 8
880
952
  a1 = _u64le(data, o)
@@ -883,14 +955,325 @@ def parse_clmm_collect_from_data(data: bytes, meta: dict) -> DexEvent:
883
955
  type=EventType.RAYDIUM_CLMM_COLLECT_FEE,
884
956
  data=RaydiumClmmCollectFeeEvent(
885
957
  metadata=_make_meta(meta),
886
- pool_state=ps,
958
+ pool_state=Z,
887
959
  position_nft_mint=pn,
960
+ recipient_token_account_0=recipient_0,
961
+ recipient_token_account_1=recipient_1,
962
+ amount_0=a0,
963
+ amount_1=a1,
964
+ ),
965
+ )
966
+
967
+
968
+ def parse_clmm_collect_protocol_from_data(data: bytes, meta: dict) -> DexEvent:
969
+ if len(data) < 32 + 32 + 32 + 8 + 8:
970
+ return DexEvent()
971
+ o = 0
972
+ ps = _pub(data, o)
973
+ o += 32
974
+ recipient_0 = _pub(data, o)
975
+ o += 32
976
+ recipient_1 = _pub(data, o)
977
+ o += 32
978
+ a0 = _u64le(data, o)
979
+ o += 8
980
+ a1 = _u64le(data, o)
981
+
982
+ return DexEvent(
983
+ type=EventType.RAYDIUM_CLMM_COLLECT_FEE,
984
+ data=RaydiumClmmCollectFeeEvent(
985
+ metadata=_make_meta(meta),
986
+ pool_state=ps,
987
+ position_nft_mint=Z,
988
+ recipient_token_account_0=recipient_0,
989
+ recipient_token_account_1=recipient_1,
888
990
  amount_0=a0,
889
991
  amount_1=a1,
890
992
  ),
891
993
  )
892
994
 
893
995
 
996
+ def parse_clmm_liquidity_change_from_data(data: bytes, meta: dict) -> DexEvent:
997
+ if len(data) < 32 + 4 + 4 + 4 + 16 + 16:
998
+ return DexEvent()
999
+ o = 0
1000
+ pool_state = _pub(data, o)
1001
+ o += 32
1002
+ tick = _i32le(data, o)
1003
+ o += 4
1004
+ tick_lower = _i32le(data, o)
1005
+ o += 4
1006
+ tick_upper = _i32le(data, o)
1007
+ o += 4
1008
+ before = str(_u128le_int(data, o))
1009
+ o += 16
1010
+ after = str(_u128le_int(data, o))
1011
+ return DexEvent(
1012
+ type=EventType.RAYDIUM_CLMM_LIQUIDITY_CHANGE,
1013
+ data=RaydiumClmmLiquidityChangeEvent(
1014
+ metadata=_make_meta(meta),
1015
+ pool_state=pool_state,
1016
+ tick=tick,
1017
+ tick_lower=tick_lower,
1018
+ tick_upper=tick_upper,
1019
+ liquidity_before=before,
1020
+ liquidity_after=after,
1021
+ ),
1022
+ )
1023
+
1024
+
1025
+ def parse_clmm_config_change_from_data(data: bytes, meta: dict) -> DexEvent:
1026
+ if len(data) < 2 + 32 + 4 + 4 + 2 + 4 + 32:
1027
+ return DexEvent()
1028
+ o = 0
1029
+ index = _u16le(data, o)
1030
+ o += 2
1031
+ owner = _pub(data, o)
1032
+ o += 32
1033
+ protocol_fee_rate = _u32le(data, o)
1034
+ o += 4
1035
+ trade_fee_rate = _u32le(data, o)
1036
+ o += 4
1037
+ tick_spacing = _u16le(data, o)
1038
+ o += 2
1039
+ fund_fee_rate = _u32le(data, o)
1040
+ o += 4
1041
+ fund_owner = _pub(data, o)
1042
+ return DexEvent(
1043
+ type=EventType.RAYDIUM_CLMM_CONFIG_CHANGE,
1044
+ data=RaydiumClmmConfigChangeEvent(
1045
+ metadata=_make_meta(meta),
1046
+ index=index,
1047
+ owner=owner,
1048
+ protocol_fee_rate=protocol_fee_rate,
1049
+ trade_fee_rate=trade_fee_rate,
1050
+ tick_spacing=tick_spacing,
1051
+ fund_fee_rate=fund_fee_rate,
1052
+ fund_owner=fund_owner,
1053
+ ),
1054
+ )
1055
+
1056
+
1057
+ def parse_clmm_create_personal_position_from_data(data: bytes, meta: dict) -> DexEvent:
1058
+ if len(data) < 32 + 32 + 32 + 4 + 4 + 16 + 8 + 8 + 8 + 8:
1059
+ return DexEvent()
1060
+ o = 0
1061
+ pool_state = _pub(data, o)
1062
+ o += 32
1063
+ minter = _pub(data, o)
1064
+ o += 32
1065
+ nft_owner = _pub(data, o)
1066
+ o += 32
1067
+ tick_lower_index = _i32le(data, o)
1068
+ o += 4
1069
+ tick_upper_index = _i32le(data, o)
1070
+ o += 4
1071
+ liquidity = str(_u128le_int(data, o))
1072
+ o += 16
1073
+ deposit_amount_0 = _u64le(data, o)
1074
+ o += 8
1075
+ deposit_amount_1 = _u64le(data, o)
1076
+ o += 8
1077
+ deposit_amount_0_transfer_fee = _u64le(data, o)
1078
+ o += 8
1079
+ deposit_amount_1_transfer_fee = _u64le(data, o)
1080
+ return DexEvent(
1081
+ type=EventType.RAYDIUM_CLMM_CREATE_PERSONAL_POSITION,
1082
+ data=RaydiumClmmCreatePersonalPositionEvent(
1083
+ metadata=_make_meta(meta),
1084
+ pool_state=pool_state,
1085
+ minter=minter,
1086
+ nft_owner=nft_owner,
1087
+ tick_lower_index=tick_lower_index,
1088
+ tick_upper_index=tick_upper_index,
1089
+ liquidity=liquidity,
1090
+ deposit_amount_0=deposit_amount_0,
1091
+ deposit_amount_1=deposit_amount_1,
1092
+ deposit_amount_0_transfer_fee=deposit_amount_0_transfer_fee,
1093
+ deposit_amount_1_transfer_fee=deposit_amount_1_transfer_fee,
1094
+ ),
1095
+ )
1096
+
1097
+
1098
+ def parse_clmm_liquidity_calculate_from_data(data: bytes, meta: dict) -> DexEvent:
1099
+ if len(data) < 16 + 16 + 4 + 8 + 8 + 8 + 8 + 8 + 8:
1100
+ return DexEvent()
1101
+ o = 0
1102
+ pool_liquidity = str(_u128le_int(data, o))
1103
+ o += 16
1104
+ pool_sqrt_price_x64 = str(_u128le_int(data, o))
1105
+ o += 16
1106
+ pool_tick = _i32le(data, o)
1107
+ o += 4
1108
+ calc_amount_0 = _u64le(data, o)
1109
+ o += 8
1110
+ calc_amount_1 = _u64le(data, o)
1111
+ o += 8
1112
+ trade_fee_owed_0 = _u64le(data, o)
1113
+ o += 8
1114
+ trade_fee_owed_1 = _u64le(data, o)
1115
+ o += 8
1116
+ transfer_fee_0 = _u64le(data, o)
1117
+ o += 8
1118
+ transfer_fee_1 = _u64le(data, o)
1119
+ return DexEvent(
1120
+ type=EventType.RAYDIUM_CLMM_LIQUIDITY_CALCULATE,
1121
+ data=RaydiumClmmLiquidityCalculateEvent(
1122
+ metadata=_make_meta(meta),
1123
+ pool_liquidity=pool_liquidity,
1124
+ pool_sqrt_price_x64=pool_sqrt_price_x64,
1125
+ pool_tick=pool_tick,
1126
+ calc_amount_0=calc_amount_0,
1127
+ calc_amount_1=calc_amount_1,
1128
+ trade_fee_owed_0=trade_fee_owed_0,
1129
+ trade_fee_owed_1=trade_fee_owed_1,
1130
+ transfer_fee_0=transfer_fee_0,
1131
+ transfer_fee_1=transfer_fee_1,
1132
+ ),
1133
+ )
1134
+
1135
+
1136
+ def parse_clmm_open_limit_order_from_data(data: bytes, meta: dict) -> DexEvent:
1137
+ if len(data) < 32 + 32 + 1 + 4 + 8 + 8:
1138
+ return DexEvent()
1139
+ o = 0
1140
+ pool_id = _pub(data, o)
1141
+ o += 32
1142
+ limit_order = _pub(data, o)
1143
+ o += 32
1144
+ zero_for_one = _bool(data, o)
1145
+ o += 1
1146
+ tick_index = _i32le(data, o)
1147
+ o += 4
1148
+ total_amount = _u64le(data, o)
1149
+ o += 8
1150
+ transfer_fee = _u64le(data, o)
1151
+ return DexEvent(
1152
+ type=EventType.RAYDIUM_CLMM_OPEN_LIMIT_ORDER,
1153
+ data=RaydiumClmmOpenLimitOrderEvent(
1154
+ metadata=_make_meta(meta),
1155
+ pool_id=pool_id,
1156
+ limit_order=limit_order,
1157
+ zero_for_one=zero_for_one,
1158
+ tick_index=tick_index,
1159
+ total_amount=total_amount,
1160
+ transfer_fee=transfer_fee,
1161
+ ),
1162
+ )
1163
+
1164
+
1165
+ def parse_clmm_increase_limit_order_from_data(data: bytes, meta: dict) -> DexEvent:
1166
+ if len(data) < 32 + 32 + 1 + 4 + 8 + 8 + 8:
1167
+ return DexEvent()
1168
+ o = 0
1169
+ pool_id = _pub(data, o)
1170
+ o += 32
1171
+ limit_order = _pub(data, o)
1172
+ o += 32
1173
+ zero_for_one = _bool(data, o)
1174
+ o += 1
1175
+ tick_index = _i32le(data, o)
1176
+ o += 4
1177
+ total_amount = _u64le(data, o)
1178
+ o += 8
1179
+ increased_amount = _u64le(data, o)
1180
+ o += 8
1181
+ transfer_fee = _u64le(data, o)
1182
+ return DexEvent(
1183
+ type=EventType.RAYDIUM_CLMM_INCREASE_LIMIT_ORDER,
1184
+ data=RaydiumClmmIncreaseLimitOrderEvent(
1185
+ metadata=_make_meta(meta),
1186
+ pool_id=pool_id,
1187
+ limit_order=limit_order,
1188
+ zero_for_one=zero_for_one,
1189
+ tick_index=tick_index,
1190
+ total_amount=total_amount,
1191
+ increased_amount=increased_amount,
1192
+ transfer_fee=transfer_fee,
1193
+ ),
1194
+ )
1195
+
1196
+
1197
+ def parse_clmm_decrease_limit_order_from_data(data: bytes, meta: dict) -> DexEvent:
1198
+ if len(data) < 32 + 32 + 1 + 4 + 8 + 8 + 8 + 8:
1199
+ return DexEvent()
1200
+ o = 0
1201
+ pool_id = _pub(data, o)
1202
+ o += 32
1203
+ limit_order = _pub(data, o)
1204
+ o += 32
1205
+ zero_for_one = _bool(data, o)
1206
+ o += 1
1207
+ tick_index = _i32le(data, o)
1208
+ o += 4
1209
+ total_amount = _u64le(data, o)
1210
+ o += 8
1211
+ filled_amount = _u64le(data, o)
1212
+ o += 8
1213
+ settled_output_amount = _u64le(data, o)
1214
+ o += 8
1215
+ decreased_amount = _u64le(data, o)
1216
+ return DexEvent(
1217
+ type=EventType.RAYDIUM_CLMM_DECREASE_LIMIT_ORDER,
1218
+ data=RaydiumClmmDecreaseLimitOrderEvent(
1219
+ metadata=_make_meta(meta),
1220
+ pool_id=pool_id,
1221
+ limit_order=limit_order,
1222
+ zero_for_one=zero_for_one,
1223
+ tick_index=tick_index,
1224
+ total_amount=total_amount,
1225
+ filled_amount=filled_amount,
1226
+ settled_output_amount=settled_output_amount,
1227
+ decreased_amount=decreased_amount,
1228
+ ),
1229
+ )
1230
+
1231
+
1232
+ def parse_clmm_settle_limit_order_from_data(data: bytes, meta: dict) -> DexEvent:
1233
+ if len(data) < 32 + 32 + 1 + 4 + 8 + 8 + 8:
1234
+ return DexEvent()
1235
+ o = 0
1236
+ pool_id = _pub(data, o)
1237
+ o += 32
1238
+ limit_order = _pub(data, o)
1239
+ o += 32
1240
+ zero_for_one = _bool(data, o)
1241
+ o += 1
1242
+ tick_index = _i32le(data, o)
1243
+ o += 4
1244
+ total_amount = _u64le(data, o)
1245
+ o += 8
1246
+ filled_amount = _u64le(data, o)
1247
+ o += 8
1248
+ settled_amount_out = _u64le(data, o)
1249
+ return DexEvent(
1250
+ type=EventType.RAYDIUM_CLMM_SETTLE_LIMIT_ORDER,
1251
+ data=RaydiumClmmSettleLimitOrderEvent(
1252
+ metadata=_make_meta(meta),
1253
+ pool_id=pool_id,
1254
+ limit_order=limit_order,
1255
+ zero_for_one=zero_for_one,
1256
+ tick_index=tick_index,
1257
+ total_amount=total_amount,
1258
+ filled_amount=filled_amount,
1259
+ settled_amount_out=settled_amount_out,
1260
+ ),
1261
+ )
1262
+
1263
+
1264
+ def parse_clmm_update_reward_infos_from_data(data: bytes, meta: dict) -> DexEvent:
1265
+ if len(data) < 16 * 3:
1266
+ return DexEvent()
1267
+ rewards = [str(_u128le_int(data, i * 16)) for i in range(3)]
1268
+ return DexEvent(
1269
+ type=EventType.RAYDIUM_CLMM_UPDATE_REWARD_INFOS,
1270
+ data=RaydiumClmmUpdateRewardInfosEvent(
1271
+ metadata=_make_meta(meta),
1272
+ reward_growth_global_x64=rewards,
1273
+ ),
1274
+ )
1275
+
1276
+
894
1277
  # --- Raydium AMM ---
895
1278
 
896
1279
 
@@ -942,6 +1325,27 @@ def parse_amm_swap_out_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
942
1325
  )
943
1326
 
944
1327
 
1328
+ def parse_amm_ray_log_swap(log: str, meta: dict) -> Optional[DexEvent]:
1329
+ prefix = "ray_log: "
1330
+ start = log.find(prefix)
1331
+ if start < 0:
1332
+ return None
1333
+ try:
1334
+ data = base64.b64decode(log[start + len(prefix):].strip(), validate=True)
1335
+ except Exception:
1336
+ return None
1337
+ if len(data) != 57 or data[0] not in (3, 4):
1338
+ return None
1339
+ first = _u64le(data, 1)
1340
+ second = _u64le(data, 9)
1341
+ actual = _u64le(data, 49)
1342
+ if data[0] == 3:
1343
+ event = _amm_swap_event(meta, Z, Z, first, second, 0, actual)
1344
+ else:
1345
+ event = _amm_swap_event(meta, Z, Z, actual, 0, first, second)
1346
+ return DexEvent(type=EventType.RAYDIUM_AMM_V4_SWAP, data=event)
1347
+
1348
+
945
1349
  def parse_amm_deposit_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
946
1350
  if len(data) < 32 + 32 + 8 + 8 + 8:
947
1351
  return None
@@ -1037,6 +1441,41 @@ def parse_amm_init2_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
1037
1441
  # --- Raydium CPMM ---
1038
1442
 
1039
1443
 
1444
+ def parse_cpmm_swap_event_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
1445
+ if len(data) < 32 + 6 * 8 + 1:
1446
+ return None
1447
+ o = 0
1448
+ pool = _pub(data, o)
1449
+ o += 32
1450
+ input_vault_before = _u64le(data, o)
1451
+ o += 8
1452
+ output_vault_before = _u64le(data, o)
1453
+ o += 8
1454
+ input_amount = _u64le(data, o)
1455
+ o += 8
1456
+ output_amount = _u64le(data, o)
1457
+ o += 8
1458
+ input_transfer_fee = _u64le(data, o)
1459
+ o += 8
1460
+ output_transfer_fee = _u64le(data, o)
1461
+ o += 8
1462
+ base_input = _bool(data, o)
1463
+ return DexEvent(
1464
+ type=EventType.RAYDIUM_CPMM_SWAP,
1465
+ data=RaydiumCpmmSwapEvent(
1466
+ metadata=_make_meta(meta),
1467
+ pool_id=pool,
1468
+ input_vault_before=input_vault_before,
1469
+ output_vault_before=output_vault_before,
1470
+ input_amount=input_amount,
1471
+ output_amount=output_amount,
1472
+ input_transfer_fee=input_transfer_fee,
1473
+ output_transfer_fee=output_transfer_fee,
1474
+ base_input=base_input,
1475
+ ),
1476
+ )
1477
+
1478
+
1040
1479
  def parse_cpmm_swap_in_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
1041
1480
  if len(data) < 32 + 32 + 8 + 8 + 8 + 1:
1042
1481
  return None
@@ -1084,6 +1523,31 @@ def parse_cpmm_swap_out_from_data(data: bytes, meta: dict) -> Optional[DexEvent]
1084
1523
  )
1085
1524
 
1086
1525
 
1526
+ def parse_cpmm_create_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
1527
+ if len(data) < 32 + 32 + 32 + 32 + 8 + 8:
1528
+ return None
1529
+ o = 0
1530
+ pool = _pub(data, o)
1531
+ o += 32
1532
+ o += 32
1533
+ o += 32
1534
+ creator = _pub(data, o)
1535
+ o += 32
1536
+ init_amount0 = _u64le(data, o)
1537
+ o += 8
1538
+ init_amount1 = _u64le(data, o)
1539
+ return DexEvent(
1540
+ type=EventType.RAYDIUM_CPMM_INITIALIZE,
1541
+ data=RaydiumCpmmInitializeEvent(
1542
+ metadata=_make_meta(meta),
1543
+ pool=pool,
1544
+ creator=creator,
1545
+ init_amount0=init_amount0,
1546
+ init_amount1=init_amount1,
1547
+ ),
1548
+ )
1549
+
1550
+
1087
1551
  def parse_cpmm_deposit_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
1088
1552
  if len(data) < 32 + 32 + 8 + 8 + 8:
1089
1553
  return None
@@ -1419,7 +1883,7 @@ def parse_meteora_pools_set_pool_fees_from_data(data: bytes, meta: dict) -> Opti
1419
1883
  )
1420
1884
 
1421
1885
 
1422
- # --- Meteora DAMM (Swap / Swap2 only,与 Go/TS 一致) ---
1886
+ # --- Meteora DAMM (对齐 Rust/Node logs/meteora_damm) ---
1423
1887
 
1424
1888
  DAMM_SWAP = _d(27, 60, 21, 213, 138, 170, 187, 147)
1425
1889
  DAMM_SWAP2 = _d(189, 66, 51, 168, 38, 80, 117, 153)
@@ -1427,12 +1891,31 @@ DAMM_CREATE_POSITION = _d(156, 15, 119, 198, 29, 181, 221, 55)
1427
1891
  DAMM_CLOSE_POSITION = _d(20, 145, 144, 68, 143, 142, 214, 178)
1428
1892
  DAMM_ADD_LIQUIDITY = _d(175, 242, 8, 157, 30, 247, 185, 169)
1429
1893
  DAMM_REMOVE_LIQUIDITY = _d(87, 46, 88, 98, 175, 96, 34, 91)
1894
+ DAMM_LIQUIDITY_CHANGE = _d(197, 171, 78, 127, 224, 211, 87, 13)
1430
1895
  DAMM_INIT_POOL = _d(228, 50, 246, 85, 203, 66, 134, 37)
1896
+ DAMM_UPDATE_DELEGATE_PERMISSION = _d(66, 188, 75, 151, 150, 232, 87, 93)
1897
+ DAMM_WITHDRAW_DEAD_LIQUIDITY_REWARD = _d(228, 66, 150, 195, 42, 62, 163, 13)
1898
+ DAMM_CREATE_CONFIG = _d(131, 207, 180, 174, 180, 73, 165, 54)
1899
+ DAMM_CREATE_DYNAMIC_CONFIG = _d(231, 197, 13, 164, 248, 213, 133, 152)
1900
+ # Mainnet upgrade: trading_fee/partner_fee → claiming_fee/compounding_fee in EvtSwap2
1901
+ COMPOUNDING_FEE_LAYOUT_ACTIVATION_SLOT = 406_048_752
1431
1902
  DBC_SWAP = DAMM_SWAP
1432
1903
  DBC_INIT_POOL = DAMM_INIT_POOL
1433
1904
  DBC_CURVE_COMPLETE = _d(229, 231, 86, 84, 156, 134, 75, 24)
1434
1905
 
1435
1906
 
1907
+ def _uses_compounding_fee_layout(slot: int) -> bool:
1908
+ return slot == 0 or slot >= COMPOUNDING_FEE_LAYOUT_ACTIVATION_SLOT
1909
+
1910
+
1911
+ def _meta_slot(meta: dict) -> int:
1912
+ if isinstance(meta, EventMetadata):
1913
+ return int(meta.slot or 0)
1914
+ if isinstance(meta, dict):
1915
+ return int(meta.get("slot", 0) or 0)
1916
+ return 0
1917
+
1918
+
1436
1919
  def parse_meteora_damm_from_buf(buf: bytes, meta: dict) -> Optional[DexEvent]:
1437
1920
  if len(buf) < 8:
1438
1921
  return None
@@ -1450,8 +1933,18 @@ def parse_meteora_damm_from_buf(buf: bytes, meta: dict) -> Optional[DexEvent]:
1450
1933
  return _parse_damm_add_liquidity(data, meta)
1451
1934
  if d == DAMM_REMOVE_LIQUIDITY:
1452
1935
  return _parse_damm_remove_liquidity(data, meta)
1936
+ if d == DAMM_LIQUIDITY_CHANGE:
1937
+ return _parse_damm_liquidity_change(data, meta)
1453
1938
  if d == DAMM_INIT_POOL:
1454
1939
  return _parse_damm_initialize_pool(data, meta)
1940
+ if d == DAMM_UPDATE_DELEGATE_PERMISSION:
1941
+ return _parse_damm_update_delegate_permission(data, meta)
1942
+ if d == DAMM_WITHDRAW_DEAD_LIQUIDITY_REWARD:
1943
+ return _parse_damm_withdraw_dead_liquidity_reward(data, meta)
1944
+ if d == DAMM_CREATE_CONFIG:
1945
+ return _parse_damm_create_config(data, meta)
1946
+ if d == DAMM_CREATE_DYNAMIC_CONFIG:
1947
+ return _parse_damm_create_dynamic_config(data, meta)
1455
1948
  return None
1456
1949
 
1457
1950
 
@@ -1625,13 +2118,15 @@ def _parse_damm_swap(data: bytes, meta: dict) -> Optional[DexEvent]:
1625
2118
 
1626
2119
 
1627
2120
  def _parse_damm_swap2(data: bytes, meta: dict) -> Optional[DexEvent]:
1628
- if len(data) < 32 + 1 + 1 + 1 + 8 * 2 + 1 + 8 * 6 + 16 + 8 * 4 + 8 * 3:
2121
+ # Full 180-byte EvtSwap2 layout (Rust/Node parity)
2122
+ if len(data) < 180:
1629
2123
  return None
1630
2124
  o = 0
1631
2125
  pool = _pub(data, o)
1632
2126
  o += 32
1633
2127
  td = _u8(data, o)
1634
2128
  o += 1
2129
+ collect_fee_mode = _u8(data, o)
1635
2130
  o += 1
1636
2131
  hr = _bool(data, o)
1637
2132
  o += 1
@@ -1643,38 +2138,82 @@ def _parse_damm_swap2(data: bytes, meta: dict) -> Optional[DexEvent]:
1643
2138
  o += 1
1644
2139
  ifi = _u64le(data, o)
1645
2140
  o += 8
1646
- o += 16
2141
+ efi = _u64le(data, o)
2142
+ o += 8
2143
+ amount_left = _u64le(data, o)
2144
+ o += 8
1647
2145
  oa = _u64le(data, o)
1648
2146
  o += 8
1649
2147
  nsp = str(_u128le_int(data, o))
1650
2148
  o += 16
1651
- lpf = _u64le(data, o)
2149
+ claiming_or_trading = _u64le(data, o)
1652
2150
  o += 8
1653
2151
  pf = _u64le(data, o)
1654
2152
  o += 8
2153
+ compounding_or_partner = _u64le(data, o)
2154
+ o += 8
1655
2155
  rf = _u64le(data, o)
1656
2156
  o += 8
2157
+ itf_in = _u64le(data, o)
2158
+ o += 8
2159
+ itf_out = _u64le(data, o)
1657
2160
  o += 8
2161
+ etf_out = _u64le(data, o)
1658
2162
  o += 8
1659
2163
  ct = _u64le(data, o)
1660
- ai, mo = (a0, a1) if sm == 0 else (a1, a0)
2164
+ o += 8
2165
+ reserve_a = _u64le(data, o)
2166
+ o += 8
2167
+ reserve_b = _u64le(data, o)
2168
+
2169
+ if sm in (0, 1):
2170
+ ai, mo = a0, a1
2171
+ elif sm == 2:
2172
+ ai, mo = a1, a0
2173
+ else:
2174
+ return None
2175
+
2176
+ if _uses_compounding_fee_layout(_meta_slot(meta)):
2177
+ lpf = claiming_or_trading + compounding_or_partner
2178
+ partner_fee = compounding_or_partner
2179
+ claiming_fee = claiming_or_trading
2180
+ compounding_fee = compounding_or_partner
2181
+ else:
2182
+ lpf = claiming_or_trading
2183
+ partner_fee = compounding_or_partner
2184
+ claiming_fee = 0
2185
+ compounding_fee = 0
2186
+
1661
2187
  return DexEvent(
1662
2188
  type=EventType.METEORA_DAMM_V2_SWAP,
1663
2189
  data=MeteoraDammV2SwapEvent(
1664
2190
  metadata=_make_meta(meta),
1665
2191
  pool=pool,
1666
2192
  trade_direction=td,
2193
+ collect_fee_mode=collect_fee_mode,
1667
2194
  has_referral=hr,
2195
+ amount_0=a0,
2196
+ amount_1=a1,
2197
+ swap_mode=sm,
1668
2198
  amount_in=ai,
1669
2199
  minimum_amount_out=mo,
1670
2200
  output_amount=oa,
1671
2201
  next_sqrt_price=nsp,
1672
2202
  lp_fee=lpf,
1673
2203
  protocol_fee=pf,
1674
- partner_fee=0,
2204
+ partner_fee=partner_fee,
1675
2205
  referral_fee=rf,
1676
2206
  actual_amount_in=ifi,
2207
+ excluded_fee_input_amount=efi,
2208
+ amount_left=amount_left,
2209
+ claiming_fee=claiming_fee,
2210
+ compounding_fee=compounding_fee,
2211
+ included_transfer_fee_amount_in=itf_in,
2212
+ included_transfer_fee_amount_out=itf_out,
2213
+ excluded_transfer_fee_amount_out=etf_out,
1677
2214
  current_timestamp=ct,
2215
+ reserve_a_amount=reserve_a,
2216
+ reserve_b_amount=reserve_b,
1678
2217
  token_a_vault=Z,
1679
2218
  token_b_vault=Z,
1680
2219
  token_a_mint=Z,
@@ -1948,6 +2487,231 @@ def _parse_damm_remove_liquidity(data: bytes, meta: dict) -> Optional[DexEvent]:
1948
2487
  )
1949
2488
 
1950
2489
 
2490
+ def _parse_damm_liquidity_change(data: bytes, meta: dict) -> Optional[DexEvent]:
2491
+ """EvtLiquidityChange; change_type 0=add, 1=remove."""
2492
+ if len(data) < 177:
2493
+ return None
2494
+ pool = _pub(data, 0)
2495
+ position = _pub(data, 32)
2496
+ owner = _pub(data, 64)
2497
+ ta = _u64le(data, 96)
2498
+ tb = _u64le(data, 104)
2499
+ tota = _u64le(data, 112)
2500
+ totb = _u64le(data, 120)
2501
+ ra = _u64le(data, 128)
2502
+ rb = _u64le(data, 136)
2503
+ ld = str(_u128le_int(data, 144))
2504
+ tat = _u64le(data, 160)
2505
+ tbt = _u64le(data, 168)
2506
+ change_type = _u8(data, 176)
2507
+ md = _make_meta(meta)
2508
+ if change_type == 0:
2509
+ return DexEvent(
2510
+ type=EventType.METEORA_DAMM_V2_ADD_LIQUIDITY,
2511
+ data=MeteoraDammV2AddLiquidityEvent(
2512
+ metadata=md,
2513
+ pool=pool,
2514
+ position=position,
2515
+ owner=owner,
2516
+ liquidity_delta=ld,
2517
+ token_a_amount_threshold=tat,
2518
+ token_b_amount_threshold=tbt,
2519
+ token_a_amount=ta,
2520
+ token_b_amount=tb,
2521
+ total_amount_a=tota,
2522
+ total_amount_b=totb,
2523
+ reserve_a_amount=ra,
2524
+ reserve_b_amount=rb,
2525
+ ),
2526
+ )
2527
+ if change_type == 1:
2528
+ return DexEvent(
2529
+ type=EventType.METEORA_DAMM_V2_REMOVE_LIQUIDITY,
2530
+ data=MeteoraDammV2RemoveLiquidityEvent(
2531
+ metadata=md,
2532
+ pool=pool,
2533
+ position=position,
2534
+ owner=owner,
2535
+ liquidity_delta=ld,
2536
+ token_a_amount_threshold=tat,
2537
+ token_b_amount_threshold=tbt,
2538
+ token_a_amount=ta,
2539
+ token_b_amount=tb,
2540
+ total_amount_a=tota,
2541
+ total_amount_b=totb,
2542
+ reserve_a_amount=ra,
2543
+ reserve_b_amount=rb,
2544
+ ),
2545
+ )
2546
+ return None
2547
+
2548
+
2549
+ def _parse_damm_update_delegate_permission(data: bytes, meta: dict) -> Optional[DexEvent]:
2550
+ if len(data) < 32 + 32 + 4 + 1:
2551
+ return None
2552
+ o = 0
2553
+ position = _pub(data, o)
2554
+ o += 32
2555
+ owner = _pub(data, o)
2556
+ o += 32
2557
+ permission = _u32le(data, o)
2558
+ o += 4
2559
+ has_delegate = _bool(data, o)
2560
+ o += 1
2561
+ delegate = None
2562
+ if has_delegate:
2563
+ if o + 32 > len(data):
2564
+ return None
2565
+ delegate = _pub(data, o)
2566
+ return DexEvent(
2567
+ type=EventType.METEORA_DAMM_V2_UPDATE_DELEGATE_PERMISSION,
2568
+ data=MeteoraDammV2UpdateDelegatePermissionEvent(
2569
+ metadata=_make_meta(meta),
2570
+ position=position,
2571
+ owner=owner,
2572
+ permission=permission,
2573
+ delegate=delegate,
2574
+ ),
2575
+ )
2576
+
2577
+
2578
+ def _parse_damm_withdraw_dead_liquidity_reward(data: bytes, meta: dict) -> Optional[DexEvent]:
2579
+ if len(data) < 32 + 32 + 8:
2580
+ return None
2581
+ o = 0
2582
+ pool = _pub(data, o)
2583
+ o += 32
2584
+ reward_mint = _pub(data, o)
2585
+ o += 32
2586
+ amount = _u64le(data, o)
2587
+ return DexEvent(
2588
+ type=EventType.METEORA_DAMM_V2_WITHDRAW_DEAD_LIQUIDITY_REWARD,
2589
+ data=MeteoraDammV2WithdrawDeadLiquidityRewardEvent(
2590
+ metadata=_make_meta(meta),
2591
+ pool=pool,
2592
+ reward_mint=reward_mint,
2593
+ amount=amount,
2594
+ ),
2595
+ )
2596
+
2597
+
2598
+ def _parse_damm_create_config_dynamic_fee(
2599
+ data: bytes, o: int
2600
+ ) -> Optional[tuple[MeteoraDammV2DynamicFeeParameters, int]]:
2601
+ if o + 32 > len(data):
2602
+ return None
2603
+ bs = _u16le(data, o)
2604
+ o += 2
2605
+ bu = str(_u128le_int(data, o))
2606
+ o += 16
2607
+ fp = _u16le(data, o)
2608
+ o += 2
2609
+ dp = _u16le(data, o)
2610
+ o += 2
2611
+ rf = _u16le(data, o)
2612
+ o += 2
2613
+ mva = _u32le(data, o)
2614
+ o += 4
2615
+ vfc = _u32le(data, o)
2616
+ o += 4
2617
+ return (
2618
+ MeteoraDammV2DynamicFeeParameters(
2619
+ bin_step=bs,
2620
+ bin_step_u128=bu,
2621
+ filter_period=fp,
2622
+ decay_period=dp,
2623
+ reduction_factor=rf,
2624
+ max_volatility_accumulator=mva,
2625
+ variable_fee_control=vfc,
2626
+ ),
2627
+ o,
2628
+ )
2629
+
2630
+
2631
+ def _parse_damm_create_config(data: bytes, meta: dict) -> Optional[DexEvent]:
2632
+ o = 0
2633
+ if len(data) < 27:
2634
+ return None
2635
+ base_fee_data = bytes(data[o : o + 27])
2636
+ o += 27
2637
+ if o + 2 + 1 + 1 > len(data):
2638
+ return None
2639
+ cfb = _u16le(data, o)
2640
+ o += 2
2641
+ pad = _u8(data, o)
2642
+ o += 1
2643
+ has_dyn = _bool(data, o)
2644
+ o += 1
2645
+ dyn = None
2646
+ if has_dyn:
2647
+ parsed = _parse_damm_create_config_dynamic_fee(data, o)
2648
+ if not parsed:
2649
+ return None
2650
+ dyn, o = parsed
2651
+ need = 32 + 32 + 1 + 16 + 16 + 1 + 8 + 32 + 16
2652
+ if o + need > len(data):
2653
+ return None
2654
+ vault = _pub(data, o)
2655
+ o += 32
2656
+ pca = _pub(data, o)
2657
+ o += 32
2658
+ act = _u8(data, o)
2659
+ o += 1
2660
+ smin = str(_u128le_int(data, o))
2661
+ o += 16
2662
+ smax = str(_u128le_int(data, o))
2663
+ o += 16
2664
+ cfm = _u8(data, o)
2665
+ o += 1
2666
+ index = _u64le(data, o)
2667
+ o += 8
2668
+ config = _pub(data, o)
2669
+ o += 32
2670
+ permission = str(_u128le_int(data, o))
2671
+ return DexEvent(
2672
+ type=EventType.METEORA_DAMM_V2_CREATE_CONFIG,
2673
+ data=MeteoraDammV2CreateConfigEvent(
2674
+ metadata=_make_meta(meta),
2675
+ base_fee_data=base_fee_data,
2676
+ compounding_fee_bps=cfb,
2677
+ padding=pad,
2678
+ dynamic_fee=dyn,
2679
+ vault_config_key=vault,
2680
+ pool_creator_authority=pca,
2681
+ activation_type=act,
2682
+ sqrt_min_price=smin,
2683
+ sqrt_max_price=smax,
2684
+ collect_fee_mode=cfm,
2685
+ index=index,
2686
+ config=config,
2687
+ permission=permission,
2688
+ ),
2689
+ )
2690
+
2691
+
2692
+ def _parse_damm_create_dynamic_config(data: bytes, meta: dict) -> Optional[DexEvent]:
2693
+ if len(data) < 32 + 32 + 8 + 16:
2694
+ return None
2695
+ o = 0
2696
+ config = _pub(data, o)
2697
+ o += 32
2698
+ pca = _pub(data, o)
2699
+ o += 32
2700
+ index = _u64le(data, o)
2701
+ o += 8
2702
+ permission = str(_u128le_int(data, o))
2703
+ return DexEvent(
2704
+ type=EventType.METEORA_DAMM_V2_CREATE_DYNAMIC_CONFIG,
2705
+ data=MeteoraDammV2CreateDynamicConfigEvent(
2706
+ metadata=_make_meta(meta),
2707
+ config=config,
2708
+ pool_creator_authority=pca,
2709
+ index=index,
2710
+ permission=permission,
2711
+ ),
2712
+ )
2713
+
2714
+
1951
2715
  # --- RaydiumLaunchlab ---
1952
2716
 
1953
2717
  DISC_RAYDIUM_LAUNCHLAB_TRADE = _d(189, 219, 127, 211, 78, 230, 97, 238)
@@ -2014,9 +2778,56 @@ def _parse_raydium_launchlab_pool_create(data: bytes, meta: dict) -> Optional[De
2014
2778
  # --- PumpSwap ---
2015
2779
 
2016
2780
 
2781
+ def _parse_pumpswap_trade_tail(data: bytes) -> Optional[Dict[str, Any]]:
2782
+ tail: Dict[str, Any] = {
2783
+ "cashback_fee_basis_points": 0,
2784
+ "cashback": 0,
2785
+ "buyback_fee_basis_points": 0,
2786
+ "buyback_fee": 0,
2787
+ "virtual_quote_reserves": 0,
2788
+ "can_boost": False,
2789
+ "base_supply": 0,
2790
+ "holder_rewards_bps": 0,
2791
+ "holder_rewards": 0,
2792
+ }
2793
+ if not data:
2794
+ return tail
2795
+ if len(data) < 16:
2796
+ return None
2797
+
2798
+ tail["cashback_fee_basis_points"] = _u64le(data, 0)
2799
+ tail["cashback"] = _u64le(data, 8)
2800
+ if len(data) == 16:
2801
+ return tail
2802
+ if len(data) < 32:
2803
+ return None
2804
+
2805
+ tail["buyback_fee_basis_points"] = _u64le(data, 16)
2806
+ tail["buyback_fee"] = _u64le(data, 24)
2807
+ if len(data) == 32:
2808
+ return tail
2809
+ if len(data) < 57:
2810
+ return None
2811
+
2812
+ tail["virtual_quote_reserves"] = int.from_bytes(data[32:48], "little", signed=True)
2813
+ if data[48] not in (0, 1):
2814
+ return None
2815
+ tail["can_boost"] = data[48] == 1
2816
+ tail["base_supply"] = _u64le(data, 49)
2817
+ if len(data) != 57 and len(data) < 73:
2818
+ return None
2819
+ if len(data) >= 73:
2820
+ tail["holder_rewards_bps"] = _u64le(data, 57)
2821
+ tail["holder_rewards"] = _u64le(data, 65)
2822
+ return tail
2823
+
2824
+
2017
2825
  def parse_ps_buy_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2018
- min_len = 16 * 8 + 7 * 32 + 1 + 5 * 8 + 4
2019
- if len(data) < min_len:
2826
+ legacy_len = 16 * 8 + 7 * 32 + 1 + 4 * 8
2827
+ min_required_len = legacy_len + 8 + 4
2828
+ if len(data) != legacy_len and len(data) < min_required_len:
2829
+ return None
2830
+ if data[352] not in (0, 1):
2020
2831
  return None
2021
2832
  o = 0
2022
2833
 
@@ -2065,36 +2876,36 @@ def parse_ps_buy_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2065
2876
  "coin_creator_fee_basis_points": rd(),
2066
2877
  "coin_creator_fee": rd(),
2067
2878
  }
2068
- tv = _bool(data, o)
2879
+ tv = data[o] == 1
2069
2880
  o += 1
2070
2881
  ev["track_volume"] = tv
2071
2882
  ev["total_unclaimed_tokens"] = rd()
2072
2883
  ev["total_claimed_tokens"] = rd()
2073
2884
  ev["current_sol_volume"] = rd()
2074
2885
  ev["last_update_timestamp"] = ri()
2075
- ev["min_base_amount_out"] = rd()
2076
- ix = ""
2077
- if o + 4 <= len(data):
2078
- ln = _u32le(data, o)
2886
+ ev["min_base_amount_out"] = 0
2887
+ ev["ix_name"] = ""
2888
+ tail = _parse_pumpswap_trade_tail(b"")
2889
+ if len(data) != legacy_len:
2890
+ ev["min_base_amount_out"] = rd()
2891
+ if o + 4 > len(data):
2892
+ return None
2893
+ name_len = _u32le(data, o)
2079
2894
  o += 4
2080
- if o + ln <= len(data):
2081
- ix = data[o : o + ln].decode("utf-8", errors="replace")
2082
- ev["ix_name"] = ix
2083
- # Mayhem mode and cashback fields
2084
- mm = False
2085
- if o < len(data):
2086
- mm = _bool(data, o)
2087
- o += 1
2088
- cb_bps = 0
2089
- cb = 0
2090
- if o + 16 <= len(data):
2091
- cb_bps = _u64le(data, o)
2092
- o += 8
2093
- cb = _u64le(data, o)
2094
- ev["mayhem_mode"] = mm
2095
- ev["cashback_fee_basis_points"] = cb_bps
2096
- ev["cashback"] = cb
2097
- ev["is_cashback_coin"] = cb_bps > 0
2895
+ name_end = o + name_len
2896
+ if name_end > len(data):
2897
+ return None
2898
+ try:
2899
+ ev["ix_name"] = data[o:name_end].decode("utf-8")
2900
+ except UnicodeDecodeError:
2901
+ return None
2902
+ o = name_end
2903
+ tail = _parse_pumpswap_trade_tail(data[o:])
2904
+ if tail is None:
2905
+ return None
2906
+ assert tail is not None
2907
+ ev.update(tail)
2908
+ ev["is_cashback_coin"] = tail["cashback_fee_basis_points"] > 0
2098
2909
  md = ev.pop("metadata", meta)
2099
2910
  return DexEvent(
2100
2911
  type=EventType.PUMP_SWAP_BUY,
@@ -2103,9 +2914,12 @@ def parse_ps_buy_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2103
2914
 
2104
2915
 
2105
2916
  def parse_ps_sell_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2106
- req = 13 * 8 + 7 * 32
2917
+ req = 14 * 8 + 7 * 32 + 2 * 8
2107
2918
  if len(data) < req:
2108
2919
  return None
2920
+ tail = _parse_pumpswap_trade_tail(data[req:])
2921
+ if tail is None:
2922
+ return None
2109
2923
  o = 0
2110
2924
 
2111
2925
  def rd() -> int:
@@ -2152,12 +2966,7 @@ def parse_ps_sell_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2152
2966
  "coin_creator_fee_basis_points": rd(),
2153
2967
  "coin_creator_fee": rd(),
2154
2968
  }
2155
- cash_bps, cash = 0, 0
2156
- if len(data) >= 368:
2157
- cash_bps = _u64le(data, 352)
2158
- cash = _u64le(data, 360)
2159
- ev["cashback_fee_basis_points"] = cash_bps
2160
- ev["cashback"] = cash
2969
+ ev.update(tail)
2161
2970
  md = ev.pop("metadata", meta)
2162
2971
  return DexEvent(
2163
2972
  type=EventType.PUMP_SWAP_SELL,
@@ -2166,9 +2975,11 @@ def parse_ps_sell_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2166
2975
 
2167
2976
 
2168
2977
  def parse_ps_create_pool_from_data(data: bytes, meta: dict) -> Optional[DexEvent]:
2169
- req = 8 + 2 + 32 * 6 + 2 + 8 * 7 + 1
2978
+ req = 326
2170
2979
  if len(data) < req:
2171
2980
  return None
2981
+ if len(data) != req and len(data) < 335:
2982
+ return None
2172
2983
  o = 0
2173
2984
  ts = _i64le(data, o)
2174
2985
  o += 8
@@ -2226,6 +3037,9 @@ def parse_ps_create_pool_from_data(data: bytes, meta: dict) -> Optional[DexEvent
2226
3037
  ev["user_quote_token_account"] = uqa
2227
3038
  ev["coin_creator"] = cc
2228
3039
  ev["is_mayhem_mode"] = len(data) > 325 and _bool(data, 325)
3040
+ ev["creator_fee_bps"] = _u64le(data, 326) if len(data) >= 334 else 0
3041
+ ev["can_edit_creator_fee"] = len(data) > 334 and _bool(data, 334)
3042
+ ev["is_holder_reward"] = len(data) > 335 and _bool(data, 335)
2229
3043
  md = ev.pop("metadata", meta)
2230
3044
  return DexEvent(
2231
3045
  type=EventType.PUMP_SWAP_CREATE_POOL,
@@ -2329,14 +3143,24 @@ def parse_ps_remove_liq_from_data(data: bytes, meta: dict) -> Optional[DexEvent]
2329
3143
 
2330
3144
  # --- Meteora DLMM ---
2331
3145
 
2332
- DLMM_SWAP = _d(143, 190, 90, 218, 196, 30, 51, 222)
2333
- DLMM_ADD_LIQ = _d(181, 157, 89, 67, 143, 182, 52, 72)
2334
- DLMM_REMOVE_LIQ = _d(80, 85, 209, 72, 24, 206, 35, 178)
2335
- DLMM_INIT_POOL = _d(95, 180, 10, 172, 84, 174, 232, 40)
3146
+ DLMM_SWAP = _d(81, 108, 227, 190, 205, 208, 10, 196)
3147
+ DLMM_SWAP2 = _d(46, 116, 82, 215, 148, 27, 84, 77)
3148
+ DLMM_ADD_LIQ = _d(31, 94, 125, 90, 227, 52, 61, 186)
3149
+ DLMM_REMOVE_LIQ = _d(116, 244, 97, 232, 103, 31, 152, 58)
3150
+ DLMM_INIT_POOL = _d(185, 74, 252, 125, 27, 215, 188, 111)
2336
3151
  DLMM_INIT_BIN = _d(11, 18, 155, 194, 33, 115, 238, 119)
2337
- DLMM_CREATE_POS = _d(123, 233, 11, 43, 146, 180, 97, 119)
2338
- DLMM_CLOSE_POS = _d(94, 168, 102, 45, 59, 122, 137, 54)
2339
- DLMM_CLAIM_FEE = _d(152, 70, 208, 111, 104, 91, 44, 1)
3152
+ DLMM_CREATE_POS = _d(144, 142, 252, 84, 157, 53, 37, 121)
3153
+ DLMM_CLOSE_POS = _d(255, 196, 16, 107, 28, 202, 53, 128)
3154
+ DLMM_CLAIM_FEE = _d(75, 122, 154, 48, 140, 74, 123, 163)
3155
+ DLMM_CLAIM_FEE2 = _d(232, 171, 242, 97, 58, 77, 35, 45)
3156
+
3157
+ DLMM_LEGACY_SWAP = _d(143, 190, 90, 218, 196, 30, 51, 222)
3158
+ DLMM_LEGACY_ADD_LIQ = _d(181, 157, 89, 67, 143, 182, 52, 72)
3159
+ DLMM_LEGACY_REMOVE_LIQ = _d(80, 85, 209, 72, 24, 206, 35, 178)
3160
+ DLMM_LEGACY_INIT_POOL = _d(95, 180, 10, 172, 84, 174, 232, 40)
3161
+ DLMM_LEGACY_CREATE_POS = _d(123, 233, 11, 43, 146, 180, 97, 119)
3162
+ DLMM_LEGACY_CLOSE_POS = _d(94, 168, 102, 45, 59, 122, 137, 54)
3163
+ DLMM_LEGACY_CLAIM_FEE = _d(152, 70, 208, 111, 104, 91, 44, 1)
2340
3164
 
2341
3165
 
2342
3166
  def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
@@ -2344,7 +3168,11 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2344
3168
  return None
2345
3169
  d = _disc8(buf[:8])
2346
3170
  data = buf[8:]
2347
- if d == DLMM_SWAP:
3171
+ return parse_dlmm_event_from_data(d, data, meta)
3172
+
3173
+
3174
+ def parse_dlmm_event_from_data(d: int, data: bytes, meta: dict) -> Optional[DexEvent]:
3175
+ if d in (DLMM_SWAP, DLMM_LEGACY_SWAP):
2348
3176
  if len(data) < 32 + 32 + 4 + 4 + 8 + 8 + 1 + 8 + 8 + 16 + 8:
2349
3177
  return None
2350
3178
  o = 0
@@ -2386,7 +3214,51 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2386
3214
  host_fee=hf,
2387
3215
  ),
2388
3216
  )
2389
- if d == DLMM_ADD_LIQ:
3217
+ if d == DLMM_SWAP2:
3218
+ if len(data) < 32 + 32 + 4 + 4 + 1 + 16 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 1 + 1:
3219
+ return None
3220
+ o = 0
3221
+ pool = _pub(data, o)
3222
+ o += 32
3223
+ frm = _pub(data, o)
3224
+ o += 32
3225
+ sb = _i32le(data, o)
3226
+ o += 4
3227
+ eb = _i32le(data, o)
3228
+ o += 4
3229
+ sy = _bool(data, o)
3230
+ o += 1
3231
+ fbps = str(_u128le_int(data, o))
3232
+ o += 16
3233
+ ai = _u64le(data, o)
3234
+ o += 8
3235
+ o += 8
3236
+ ao = _u64le(data, o)
3237
+ o += 8
3238
+ fee = _u64le(data, o)
3239
+ o += 8
3240
+ pf = _u64le(data, o)
3241
+ o += 8
3242
+ o += 8
3243
+ hf = _u64le(data, o)
3244
+ return DexEvent(
3245
+ type=EventType.METEORA_DLMM_SWAP,
3246
+ data=MeteoraDlmmSwapEvent(
3247
+ metadata=_make_meta(meta),
3248
+ pool=pool,
3249
+ from_addr=frm,
3250
+ start_bin_id=sb,
3251
+ end_bin_id=eb,
3252
+ amount_in=ai,
3253
+ amount_out=ao,
3254
+ swap_for_y=sy,
3255
+ fee=fee,
3256
+ protocol_fee=pf,
3257
+ fee_bps=fbps,
3258
+ host_fee=hf,
3259
+ ),
3260
+ )
3261
+ if d in (DLMM_ADD_LIQ, DLMM_LEGACY_ADD_LIQ):
2390
3262
  if len(data) < 32 + 32 + 32 + 8 + 8 + 4:
2391
3263
  return None
2392
3264
  o = 0
@@ -2412,7 +3284,7 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2412
3284
  active_bin_id=ab,
2413
3285
  ),
2414
3286
  )
2415
- if d == DLMM_REMOVE_LIQ:
3287
+ if d in (DLMM_REMOVE_LIQ, DLMM_LEGACY_REMOVE_LIQ):
2416
3288
  if len(data) < 32 + 32 + 32 + 8 + 8 + 4:
2417
3289
  return None
2418
3290
  o = 0
@@ -2439,6 +3311,23 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2439
3311
  ),
2440
3312
  )
2441
3313
  if d == DLMM_INIT_POOL:
3314
+ if len(data) < 32 + 2 + 32 + 32:
3315
+ return None
3316
+ o = 0
3317
+ pool = _pub(data, o)
3318
+ o += 32
3319
+ bs = _u16le(data, o)
3320
+ return DexEvent(
3321
+ type=EventType.METEORA_DLMM_INITIALIZE_POOL,
3322
+ data=MeteoraDlmmInitializePoolEvent(
3323
+ metadata=_make_meta(meta),
3324
+ pool=pool,
3325
+ creator=Z,
3326
+ active_bin_id=0,
3327
+ bin_step=bs,
3328
+ ),
3329
+ )
3330
+ if d == DLMM_LEGACY_INIT_POOL:
2442
3331
  if len(data) < 32 + 32 + 4 + 2:
2443
3332
  return None
2444
3333
  o = 0
@@ -2478,6 +3367,26 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2478
3367
  ),
2479
3368
  )
2480
3369
  if d == DLMM_CREATE_POS:
3370
+ if len(data) < 32 + 32 + 32:
3371
+ return None
3372
+ o = 0
3373
+ pool = _pub(data, o)
3374
+ o += 32
3375
+ pos = _pub(data, o)
3376
+ o += 32
3377
+ owner = _pub(data, o)
3378
+ return DexEvent(
3379
+ type=EventType.METEORA_DLMM_CREATE_POSITION,
3380
+ data=MeteoraDlmmCreatePositionEvent(
3381
+ metadata=_make_meta(meta),
3382
+ pool=pool,
3383
+ position=pos,
3384
+ owner=owner,
3385
+ lower_bin_id=0,
3386
+ width=0,
3387
+ ),
3388
+ )
3389
+ if d == DLMM_LEGACY_CREATE_POS:
2481
3390
  if len(data) < 32 + 32 + 32 + 4 + 4:
2482
3391
  return None
2483
3392
  o = 0
@@ -2502,6 +3411,22 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2502
3411
  ),
2503
3412
  )
2504
3413
  if d == DLMM_CLOSE_POS:
3414
+ if len(data) < 32 + 32:
3415
+ return None
3416
+ o = 0
3417
+ pos = _pub(data, o)
3418
+ o += 32
3419
+ owner = _pub(data, o)
3420
+ return DexEvent(
3421
+ type=EventType.METEORA_DLMM_CLOSE_POSITION,
3422
+ data=MeteoraDlmmClosePositionEvent(
3423
+ metadata=_make_meta(meta),
3424
+ pool=Z,
3425
+ position=pos,
3426
+ owner=owner,
3427
+ ),
3428
+ )
3429
+ if d == DLMM_LEGACY_CLOSE_POS:
2505
3430
  if len(data) < 32 + 32 + 32:
2506
3431
  return None
2507
3432
  o = 0
@@ -2519,7 +3444,7 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2519
3444
  owner=owner,
2520
3445
  ),
2521
3446
  )
2522
- if d == DLMM_CLAIM_FEE:
3447
+ if d in (DLMM_CLAIM_FEE, DLMM_LEGACY_CLAIM_FEE):
2523
3448
  if len(data) < 32 + 32 + 32 + 8 + 8:
2524
3449
  return None
2525
3450
  o = 0
@@ -2543,6 +3468,30 @@ def parse_dlmm_from_program_data(buf: bytes, meta: dict) -> Optional[DexEvent]:
2543
3468
  fee_y=fy,
2544
3469
  ),
2545
3470
  )
3471
+ if d == DLMM_CLAIM_FEE2:
3472
+ if len(data) < 32 + 32 + 32 + 8 + 8 + 4:
3473
+ return None
3474
+ o = 0
3475
+ pool = _pub(data, o)
3476
+ o += 32
3477
+ pos = _pub(data, o)
3478
+ o += 32
3479
+ owner = _pub(data, o)
3480
+ o += 32
3481
+ fx = _u64le(data, o)
3482
+ o += 8
3483
+ fy = _u64le(data, o)
3484
+ return DexEvent(
3485
+ type=EventType.METEORA_DLMM_CLAIM_FEE,
3486
+ data=MeteoraDlmmClaimFeeEvent(
3487
+ metadata=_make_meta(meta),
3488
+ pool=pool,
3489
+ position=pos,
3490
+ owner=owner,
3491
+ fee_x=fx,
3492
+ fee_y=fy,
3493
+ ),
3494
+ )
2546
3495
  return None
2547
3496
 
2548
3497
 
@@ -2567,13 +3516,24 @@ _LOG_DISCRIMINATOR_EVENT_TYPES = {
2567
3516
  _d(177, 49, 12, 210, 160, 118, 167, 116): EventType.PUMP_SWAP_CREATE_POOL,
2568
3517
  _d(120, 248, 61, 83, 31, 142, 107, 144): EventType.PUMP_SWAP_LIQUIDITY_ADDED,
2569
3518
  _d(22, 9, 133, 26, 160, 44, 71, 192): EventType.PUMP_SWAP_LIQUIDITY_REMOVED,
2570
- _d(248, 198, 158, 145, 225, 117, 135, 200): EventType.RAYDIUM_CLMM_SWAP,
2571
- _d(133, 29, 89, 223, 69, 238, 176, 10): EventType.RAYDIUM_CLMM_INCREASE_LIQUIDITY,
2572
- _d(160, 38, 208, 111, 104, 91, 44, 1): EventType.RAYDIUM_CLMM_DECREASE_LIQUIDITY,
2573
- _d(233, 146, 209, 142, 207, 104, 64, 188): EventType.RAYDIUM_CLMM_CREATE_POOL,
2574
- _d(164, 152, 207, 99, 187, 104, 171, 119): EventType.RAYDIUM_CLMM_COLLECT_FEE,
3519
+ _d(64, 198, 205, 232, 38, 8, 113, 226): EventType.RAYDIUM_CLMM_SWAP,
3520
+ _d(49, 79, 105, 212, 32, 34, 30, 84): EventType.RAYDIUM_CLMM_INCREASE_LIQUIDITY,
3521
+ _d(58, 222, 86, 58, 68, 50, 85, 56): EventType.RAYDIUM_CLMM_DECREASE_LIQUIDITY,
3522
+ _d(126, 240, 175, 206, 158, 88, 153, 107): EventType.RAYDIUM_CLMM_LIQUIDITY_CHANGE,
3523
+ _d(247, 189, 7, 119, 106, 112, 95, 151): EventType.RAYDIUM_CLMM_CONFIG_CHANGE,
3524
+ _d(100, 30, 87, 249, 196, 223, 154, 206): EventType.RAYDIUM_CLMM_CREATE_PERSONAL_POSITION,
3525
+ _d(237, 112, 148, 230, 57, 84, 180, 162): EventType.RAYDIUM_CLMM_LIQUIDITY_CALCULATE,
3526
+ _d(106, 24, 71, 85, 57, 169, 158, 216): EventType.RAYDIUM_CLMM_OPEN_LIMIT_ORDER,
3527
+ _d(11, 120, 13, 204, 199, 87, 19, 200): EventType.RAYDIUM_CLMM_INCREASE_LIMIT_ORDER,
3528
+ _d(70, 48, 40, 221, 219, 237, 212, 163): EventType.RAYDIUM_CLMM_DECREASE_LIMIT_ORDER,
3529
+ _d(88, 119, 77, 164, 125, 124, 10, 194): EventType.RAYDIUM_CLMM_SETTLE_LIMIT_ORDER,
3530
+ _d(109, 127, 186, 78, 114, 65, 37, 236): EventType.RAYDIUM_CLMM_UPDATE_REWARD_INFOS,
3531
+ _d(25, 94, 75, 47, 112, 99, 53, 63): EventType.RAYDIUM_CLMM_CREATE_POOL,
3532
+ _d(166, 174, 105, 192, 81, 161, 83, 105): EventType.RAYDIUM_CLMM_COLLECT_FEE,
3533
+ _d(206, 87, 17, 79, 45, 41, 213, 61): EventType.RAYDIUM_CLMM_COLLECT_FEE,
2575
3534
  _d(143, 190, 90, 218, 196, 30, 51, 222): EventType.RAYDIUM_CPMM_SWAP,
2576
3535
  _d(55, 217, 98, 86, 163, 74, 180, 173): EventType.RAYDIUM_CPMM_SWAP,
3536
+ _d(233, 146, 209, 142, 207, 104, 64, 188): EventType.RAYDIUM_CPMM_INITIALIZE,
2577
3537
  _d(242, 35, 198, 137, 82, 225, 242, 182): EventType.RAYDIUM_CPMM_DEPOSIT,
2578
3538
  _d(183, 18, 70, 156, 148, 109, 161, 34): EventType.RAYDIUM_CPMM_WITHDRAW,
2579
3539
  _d(0, 0, 0, 0, 0, 0, 0, 9): EventType.RAYDIUM_AMM_V4_SWAP,
@@ -2594,11 +3554,16 @@ _LOG_DISCRIMINATOR_EVENT_TYPES = {
2594
3554
  _d(245, 26, 198, 164, 88, 18, 75, 9): EventType.METEORA_POOLS_SET_POOL_FEES,
2595
3555
  DAMM_SWAP: EventType.METEORA_DAMM_V2_SWAP,
2596
3556
  DAMM_SWAP2: EventType.METEORA_DAMM_V2_SWAP,
2597
- _d(175, 242, 8, 157, 30, 247, 185, 169): EventType.METEORA_DAMM_V2_ADD_LIQUIDITY,
2598
- _d(87, 46, 88, 98, 175, 96, 34, 91): EventType.METEORA_DAMM_V2_REMOVE_LIQUIDITY,
2599
- _d(228, 50, 246, 85, 203, 66, 134, 37): EventType.METEORA_DAMM_V2_INITIALIZE_POOL,
2600
- _d(156, 15, 119, 198, 29, 181, 221, 55): EventType.METEORA_DAMM_V2_CREATE_POSITION,
2601
- _d(20, 145, 144, 68, 143, 142, 214, 178): EventType.METEORA_DAMM_V2_CLOSE_POSITION,
3557
+ DAMM_ADD_LIQUIDITY: EventType.METEORA_DAMM_V2_ADD_LIQUIDITY,
3558
+ DAMM_REMOVE_LIQUIDITY: EventType.METEORA_DAMM_V2_REMOVE_LIQUIDITY,
3559
+ DAMM_LIQUIDITY_CHANGE: EventType.METEORA_DAMM_V2_ADD_LIQUIDITY, # routed by change_type in parser
3560
+ DAMM_INIT_POOL: EventType.METEORA_DAMM_V2_INITIALIZE_POOL,
3561
+ DAMM_CREATE_POSITION: EventType.METEORA_DAMM_V2_CREATE_POSITION,
3562
+ DAMM_CLOSE_POSITION: EventType.METEORA_DAMM_V2_CLOSE_POSITION,
3563
+ DAMM_UPDATE_DELEGATE_PERMISSION: EventType.METEORA_DAMM_V2_UPDATE_DELEGATE_PERMISSION,
3564
+ DAMM_WITHDRAW_DEAD_LIQUIDITY_REWARD: EventType.METEORA_DAMM_V2_WITHDRAW_DEAD_LIQUIDITY_REWARD,
3565
+ DAMM_CREATE_CONFIG: EventType.METEORA_DAMM_V2_CREATE_CONFIG,
3566
+ DAMM_CREATE_DYNAMIC_CONFIG: EventType.METEORA_DAMM_V2_CREATE_DYNAMIC_CONFIG,
2602
3567
  DISC_RAYDIUM_LAUNCHLAB_POOL_CREATE: EventType.RAYDIUM_LAUNCHLAB_POOL_CREATE,
2603
3568
  DLMM_ADD_LIQ: EventType.METEORA_DLMM_ADD_LIQUIDITY,
2604
3569
  DLMM_REMOVE_LIQ: EventType.METEORA_DLMM_REMOVE_LIQUIDITY,
@@ -2615,18 +3580,115 @@ def event_type_for_discriminator(disc: int) -> Optional[EventType]:
2615
3580
 
2616
3581
 
2617
3582
  RAYDIUM_LAUNCHLAB_PROGRAM_ID = "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj"
3583
+ PUMPFUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
3584
+ PUMP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
3585
+ PUMPSWAP_PROGRAM_ID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
3586
+ RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK"
3587
+ RAYDIUM_CPMM_PROGRAM_ID = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"
3588
+ RAYDIUM_AMM_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
3589
+ ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
3590
+ METEORA_POOLS_PROGRAM_ID = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB"
2618
3591
  METEORA_DAMM_V2_PROGRAM_ID = "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
2619
3592
  METEORA_DBC_PROGRAM_ID = "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN"
2620
3593
  METEORA_DLMM_PROGRAM_ID = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"
2621
3594
 
2622
3595
 
2623
3596
  def event_type_for_program_discriminator(program_id: Optional[str], disc: int) -> Optional[EventType]:
3597
+ if program_id == PUMPFUN_PROGRAM_ID:
3598
+ if disc == PUMP_CREATE:
3599
+ return EventType.PUMP_FUN_CREATE
3600
+ if disc == PUMP_TRADE:
3601
+ return EventType.PUMP_FUN_TRADE
3602
+ if disc == PUMP_MIGRATE:
3603
+ return EventType.PUMP_FUN_MIGRATE
3604
+ if disc == PUMP_MIGRATE_BONDING_CURVE_CREATOR:
3605
+ return EventType.PUMP_FUN_MIGRATE_BONDING_CURVE_CREATOR
3606
+ return None
3607
+ if program_id == PUMP_FEES_PROGRAM_ID:
3608
+ mapping = {
3609
+ PUMP_FEES_CREATE_FEE_SHARING_CONFIG: EventType.PUMP_FEES_CREATE_FEE_SHARING_CONFIG,
3610
+ PUMP_FEES_INITIALIZE_FEE_CONFIG: EventType.PUMP_FEES_INITIALIZE_FEE_CONFIG,
3611
+ PUMP_FEES_RESET_FEE_SHARING_CONFIG: EventType.PUMP_FEES_RESET_FEE_SHARING_CONFIG,
3612
+ PUMP_FEES_REVOKE_FEE_SHARING_AUTHORITY: EventType.PUMP_FEES_REVOKE_FEE_SHARING_AUTHORITY,
3613
+ PUMP_FEES_TRANSFER_FEE_SHARING_AUTHORITY: EventType.PUMP_FEES_TRANSFER_FEE_SHARING_AUTHORITY,
3614
+ PUMP_FEES_UPDATE_ADMIN: EventType.PUMP_FEES_UPDATE_ADMIN,
3615
+ PUMP_FEES_UPDATE_FEE_CONFIG: EventType.PUMP_FEES_UPDATE_FEE_CONFIG,
3616
+ PUMP_FEES_UPDATE_FEE_SHARES: EventType.PUMP_FEES_UPDATE_FEE_SHARES,
3617
+ PUMP_FEES_UPSERT_FEE_TIERS: EventType.PUMP_FEES_UPSERT_FEE_TIERS,
3618
+ }
3619
+ return mapping.get(disc)
3620
+ if program_id == PUMPSWAP_PROGRAM_ID:
3621
+ mapping = {
3622
+ _d(103, 244, 82, 31, 44, 245, 119, 119): EventType.PUMP_SWAP_BUY,
3623
+ _d(62, 47, 55, 10, 165, 3, 220, 42): EventType.PUMP_SWAP_SELL,
3624
+ _d(177, 49, 12, 210, 160, 118, 167, 116): EventType.PUMP_SWAP_CREATE_POOL,
3625
+ _d(120, 248, 61, 83, 31, 142, 107, 144): EventType.PUMP_SWAP_LIQUIDITY_ADDED,
3626
+ _d(22, 9, 133, 26, 160, 44, 71, 192): EventType.PUMP_SWAP_LIQUIDITY_REMOVED,
3627
+ }
3628
+ return mapping.get(disc)
2624
3629
  if program_id == RAYDIUM_LAUNCHLAB_PROGRAM_ID:
2625
3630
  if disc == DISC_RAYDIUM_LAUNCHLAB_TRADE:
2626
3631
  return EventType.RAYDIUM_LAUNCHLAB_TRADE
2627
3632
  if disc == DISC_RAYDIUM_LAUNCHLAB_POOL_CREATE:
2628
3633
  return EventType.RAYDIUM_LAUNCHLAB_POOL_CREATE
2629
3634
  return None
3635
+ if program_id == RAYDIUM_CLMM_PROGRAM_ID:
3636
+ mapping = {
3637
+ _d(64, 198, 205, 232, 38, 8, 113, 226): EventType.RAYDIUM_CLMM_SWAP,
3638
+ _d(49, 79, 105, 212, 32, 34, 30, 84): EventType.RAYDIUM_CLMM_INCREASE_LIQUIDITY,
3639
+ _d(58, 222, 86, 58, 68, 50, 85, 56): EventType.RAYDIUM_CLMM_DECREASE_LIQUIDITY,
3640
+ _d(126, 240, 175, 206, 158, 88, 153, 107): EventType.RAYDIUM_CLMM_LIQUIDITY_CHANGE,
3641
+ _d(247, 189, 7, 119, 106, 112, 95, 151): EventType.RAYDIUM_CLMM_CONFIG_CHANGE,
3642
+ _d(100, 30, 87, 249, 196, 223, 154, 206): EventType.RAYDIUM_CLMM_CREATE_PERSONAL_POSITION,
3643
+ _d(237, 112, 148, 230, 57, 84, 180, 162): EventType.RAYDIUM_CLMM_LIQUIDITY_CALCULATE,
3644
+ _d(106, 24, 71, 85, 57, 169, 158, 216): EventType.RAYDIUM_CLMM_OPEN_LIMIT_ORDER,
3645
+ _d(11, 120, 13, 204, 199, 87, 19, 200): EventType.RAYDIUM_CLMM_INCREASE_LIMIT_ORDER,
3646
+ _d(70, 48, 40, 221, 219, 237, 212, 163): EventType.RAYDIUM_CLMM_DECREASE_LIMIT_ORDER,
3647
+ _d(88, 119, 77, 164, 125, 124, 10, 194): EventType.RAYDIUM_CLMM_SETTLE_LIMIT_ORDER,
3648
+ _d(109, 127, 186, 78, 114, 65, 37, 236): EventType.RAYDIUM_CLMM_UPDATE_REWARD_INFOS,
3649
+ _d(25, 94, 75, 47, 112, 99, 53, 63): EventType.RAYDIUM_CLMM_CREATE_POOL,
3650
+ _d(166, 174, 105, 192, 81, 161, 83, 105): EventType.RAYDIUM_CLMM_COLLECT_FEE,
3651
+ _d(206, 87, 17, 79, 45, 41, 213, 61): EventType.RAYDIUM_CLMM_COLLECT_FEE,
3652
+ }
3653
+ return mapping.get(disc)
3654
+ if program_id == RAYDIUM_CPMM_PROGRAM_ID:
3655
+ mapping = {
3656
+ _d(64, 198, 205, 232, 38, 8, 113, 226): EventType.RAYDIUM_CPMM_SWAP,
3657
+ _d(143, 190, 90, 218, 196, 30, 51, 222): EventType.RAYDIUM_CPMM_SWAP,
3658
+ _d(55, 217, 98, 86, 163, 74, 180, 173): EventType.RAYDIUM_CPMM_SWAP,
3659
+ _d(233, 146, 209, 142, 207, 104, 64, 188): EventType.RAYDIUM_CPMM_INITIALIZE,
3660
+ _d(242, 35, 198, 137, 82, 225, 242, 182): EventType.RAYDIUM_CPMM_DEPOSIT,
3661
+ _d(183, 18, 70, 156, 148, 109, 161, 34): EventType.RAYDIUM_CPMM_WITHDRAW,
3662
+ }
3663
+ return mapping.get(disc)
3664
+ if program_id == RAYDIUM_AMM_V4_PROGRAM_ID:
3665
+ mapping = {
3666
+ _d(0, 0, 0, 0, 0, 0, 0, 9): EventType.RAYDIUM_AMM_V4_SWAP,
3667
+ _d(0, 0, 0, 0, 0, 0, 0, 11): EventType.RAYDIUM_AMM_V4_SWAP,
3668
+ _d(0, 0, 0, 0, 0, 0, 0, 3): EventType.RAYDIUM_AMM_V4_DEPOSIT,
3669
+ _d(0, 0, 0, 0, 0, 0, 0, 4): EventType.RAYDIUM_AMM_V4_WITHDRAW,
3670
+ _d(0, 0, 0, 0, 0, 0, 0, 1): EventType.RAYDIUM_AMM_V4_INITIALIZE2,
3671
+ _d(0, 0, 0, 0, 0, 0, 0, 7): EventType.RAYDIUM_AMM_V4_WITHDRAW_PNL,
3672
+ }
3673
+ return mapping.get(disc)
3674
+ if program_id == ORCA_WHIRLPOOL_PROGRAM_ID:
3675
+ mapping = {
3676
+ _d(225, 202, 73, 175, 147, 43, 160, 150): EventType.ORCA_WHIRLPOOL_SWAP,
3677
+ _d(30, 7, 144, 181, 102, 254, 155, 161): EventType.ORCA_WHIRLPOOL_LIQUIDITY_INCREASED,
3678
+ _d(166, 1, 36, 71, 112, 202, 181, 171): EventType.ORCA_WHIRLPOOL_LIQUIDITY_DECREASED,
3679
+ _d(100, 118, 173, 87, 12, 198, 254, 229): EventType.ORCA_WHIRLPOOL_POOL_INITIALIZED,
3680
+ }
3681
+ return mapping.get(disc)
3682
+ if program_id == METEORA_POOLS_PROGRAM_ID:
3683
+ mapping = {
3684
+ _d(81, 108, 227, 190, 205, 208, 10, 196): EventType.METEORA_POOLS_SWAP,
3685
+ _d(31, 94, 125, 90, 227, 52, 61, 186): EventType.METEORA_POOLS_ADD_LIQUIDITY,
3686
+ _d(116, 244, 97, 232, 103, 31, 152, 58): EventType.METEORA_POOLS_REMOVE_LIQUIDITY,
3687
+ _d(121, 127, 38, 136, 92, 55, 14, 247): EventType.METEORA_POOLS_BOOTSTRAP_LIQUIDITY,
3688
+ _d(202, 44, 41, 88, 104, 220, 157, 82): EventType.METEORA_POOLS_POOL_CREATED,
3689
+ _d(245, 26, 198, 164, 88, 18, 75, 9): EventType.METEORA_POOLS_SET_POOL_FEES,
3690
+ }
3691
+ return mapping.get(disc)
2630
3692
  if program_id == METEORA_DAMM_V2_PROGRAM_ID:
2631
3693
  if disc in (DAMM_SWAP, DAMM_SWAP2):
2632
3694
  return EventType.METEORA_DAMM_V2_SWAP
@@ -2634,12 +3696,22 @@ def event_type_for_program_discriminator(program_id: Optional[str], disc: int) -
2634
3696
  return EventType.METEORA_DAMM_V2_ADD_LIQUIDITY
2635
3697
  if disc == DAMM_REMOVE_LIQUIDITY:
2636
3698
  return EventType.METEORA_DAMM_V2_REMOVE_LIQUIDITY
3699
+ if disc == DAMM_LIQUIDITY_CHANGE:
3700
+ return EventType.METEORA_DAMM_V2_ADD_LIQUIDITY
2637
3701
  if disc == DAMM_INIT_POOL:
2638
3702
  return EventType.METEORA_DAMM_V2_INITIALIZE_POOL
2639
3703
  if disc == DAMM_CREATE_POSITION:
2640
3704
  return EventType.METEORA_DAMM_V2_CREATE_POSITION
2641
3705
  if disc == DAMM_CLOSE_POSITION:
2642
3706
  return EventType.METEORA_DAMM_V2_CLOSE_POSITION
3707
+ if disc == DAMM_UPDATE_DELEGATE_PERMISSION:
3708
+ return EventType.METEORA_DAMM_V2_UPDATE_DELEGATE_PERMISSION
3709
+ if disc == DAMM_WITHDRAW_DEAD_LIQUIDITY_REWARD:
3710
+ return EventType.METEORA_DAMM_V2_WITHDRAW_DEAD_LIQUIDITY_REWARD
3711
+ if disc == DAMM_CREATE_CONFIG:
3712
+ return EventType.METEORA_DAMM_V2_CREATE_CONFIG
3713
+ if disc == DAMM_CREATE_DYNAMIC_CONFIG:
3714
+ return EventType.METEORA_DAMM_V2_CREATE_DYNAMIC_CONFIG
2643
3715
  return None
2644
3716
  if program_id == METEORA_DBC_PROGRAM_ID:
2645
3717
  if disc == DBC_SWAP:
@@ -2649,19 +3721,221 @@ def event_type_for_program_discriminator(program_id: Optional[str], disc: int) -
2649
3721
  if disc == DBC_CURVE_COMPLETE:
2650
3722
  return EventType.METEORA_DBC_CURVE_COMPLETE
2651
3723
  return None
3724
+ if program_id == METEORA_DLMM_PROGRAM_ID:
3725
+ if disc in (DLMM_SWAP, DLMM_SWAP2, DLMM_LEGACY_SWAP):
3726
+ return EventType.METEORA_DLMM_SWAP
3727
+ if disc in (DLMM_ADD_LIQ, DLMM_LEGACY_ADD_LIQ):
3728
+ return EventType.METEORA_DLMM_ADD_LIQUIDITY
3729
+ if disc in (DLMM_REMOVE_LIQ, DLMM_LEGACY_REMOVE_LIQ):
3730
+ return EventType.METEORA_DLMM_REMOVE_LIQUIDITY
3731
+ if disc in (DLMM_INIT_POOL, DLMM_LEGACY_INIT_POOL):
3732
+ return EventType.METEORA_DLMM_INITIALIZE_POOL
3733
+ if disc == DLMM_INIT_BIN:
3734
+ return EventType.METEORA_DLMM_INITIALIZE_BIN_ARRAY
3735
+ if disc in (DLMM_CREATE_POS, DLMM_LEGACY_CREATE_POS):
3736
+ return EventType.METEORA_DLMM_CREATE_POSITION
3737
+ if disc in (DLMM_CLOSE_POS, DLMM_LEGACY_CLOSE_POS):
3738
+ return EventType.METEORA_DLMM_CLOSE_POSITION
3739
+ if disc in (DLMM_CLAIM_FEE, DLMM_CLAIM_FEE2, DLMM_LEGACY_CLAIM_FEE):
3740
+ return EventType.METEORA_DLMM_CLAIM_FEE
3741
+ return None
2652
3742
  return event_type_for_discriminator(disc)
2653
3743
 
2654
3744
 
3745
+ def filter_wants_pumpfun_trade(event_type_filter: Any) -> bool:
3746
+ return event_type_filter is None or any(
3747
+ event_type_filter.should_include(t)
3748
+ for t in (
3749
+ EventType.PUMP_FUN_TRADE,
3750
+ EventType.PUMP_FUN_BUY,
3751
+ EventType.PUMP_FUN_SELL,
3752
+ EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
3753
+ )
3754
+ )
3755
+
3756
+
3757
+ def filter_wants_raydium_launchlab_trade(event_type_filter: Any) -> bool:
3758
+ return event_type_filter is None or event_type_filter.should_include(
3759
+ EventType.RAYDIUM_LAUNCHLAB_TRADE
3760
+ )
3761
+
3762
+
3763
+ def filter_allows_unscoped_discriminator(event_type_filter: Any, disc: int) -> bool:
3764
+ if event_type_filter is None:
3765
+ return True
3766
+ if disc == PUMP_TRADE:
3767
+ return filter_wants_pumpfun_trade(event_type_filter) or filter_wants_raydium_launchlab_trade(
3768
+ event_type_filter
3769
+ )
3770
+ if disc in (DLMM_SWAP, DLMM_SWAP2, DLMM_LEGACY_SWAP):
3771
+ return event_type_filter.should_include(EventType.RAYDIUM_CPMM_SWAP) or event_type_filter.should_include(
3772
+ EventType.METEORA_DLMM_SWAP
3773
+ )
3774
+ event_type = event_type_for_discriminator(disc)
3775
+ if event_type is not None:
3776
+ return event_type_filter.should_include(event_type)
3777
+ return filter_wants_supported_logs(event_type_filter)
3778
+
3779
+
3780
+ def filter_wants_supported_logs(event_type_filter: Any) -> bool:
3781
+ return any(
3782
+ filter_includes_program(event_type_filter, program_id)
3783
+ for program_id in (
3784
+ PUMPFUN_PROGRAM_ID,
3785
+ PUMP_FEES_PROGRAM_ID,
3786
+ PUMPSWAP_PROGRAM_ID,
3787
+ RAYDIUM_LAUNCHLAB_PROGRAM_ID,
3788
+ RAYDIUM_CLMM_PROGRAM_ID,
3789
+ RAYDIUM_CPMM_PROGRAM_ID,
3790
+ RAYDIUM_AMM_V4_PROGRAM_ID,
3791
+ ORCA_WHIRLPOOL_PROGRAM_ID,
3792
+ METEORA_POOLS_PROGRAM_ID,
3793
+ METEORA_DAMM_V2_PROGRAM_ID,
3794
+ METEORA_DLMM_PROGRAM_ID,
3795
+ METEORA_DBC_PROGRAM_ID,
3796
+ )
3797
+ )
3798
+
3799
+
3800
+ def dispatch_unscoped_pumpfun_launchlab_trade(
3801
+ data: bytes,
3802
+ meta: dict,
3803
+ is_created_buy: bool,
3804
+ event_type_filter: Any = None,
3805
+ ) -> Optional[DexEvent]:
3806
+ if filter_wants_pumpfun_trade(event_type_filter):
3807
+ pumpfun = apply_event_type_filter(
3808
+ parse_trade_from_data(data, meta, is_created_buy),
3809
+ event_type_filter,
3810
+ )
3811
+ if pumpfun is not None:
3812
+ return pumpfun
3813
+ if filter_wants_raydium_launchlab_trade(event_type_filter):
3814
+ return apply_event_type_filter(
3815
+ parse_raydium_launchlab_from_discriminator(PUMP_TRADE, data, meta),
3816
+ event_type_filter,
3817
+ )
3818
+ return None
3819
+
3820
+
3821
+ def _pumpfun_trade_matches_include_only(ev: DexEvent, include_only: List[EventType]) -> bool:
3822
+ if ev.type == EventType.PUMP_FUN_BUY:
3823
+ return EventType.PUMP_FUN_BUY in include_only or EventType.PUMP_FUN_BUY_EXACT_SOL_IN in include_only
3824
+ if ev.type == EventType.PUMP_FUN_SELL:
3825
+ return EventType.PUMP_FUN_SELL in include_only
3826
+ if ev.type == EventType.PUMP_FUN_BUY_EXACT_SOL_IN:
3827
+ return EventType.PUMP_FUN_BUY in include_only or EventType.PUMP_FUN_BUY_EXACT_SOL_IN in include_only
3828
+ if ev.type == EventType.PUMP_FUN_TRADE:
3829
+ return EventType.PUMP_FUN_TRADE in include_only
3830
+ if ev.type in (EventType.PUMP_FUN_CREATE, EventType.PUMP_FUN_CREATE_V2):
3831
+ return EventType.PUMP_FUN_CREATE in include_only or EventType.PUMP_FUN_CREATE_V2 in include_only
3832
+ return False
3833
+
3834
+
3835
+ def apply_pumpfun_secondary_filter(ev: Optional[DexEvent], event_type_filter: Any) -> Optional[DexEvent]:
3836
+ if ev is None or not ev.is_valid():
3837
+ return None
3838
+ include_only = getattr(event_type_filter, "include_only", None)
3839
+ if include_only:
3840
+ has_specific = any(
3841
+ t
3842
+ in (
3843
+ EventType.PUMP_FUN_BUY,
3844
+ EventType.PUMP_FUN_SELL,
3845
+ EventType.PUMP_FUN_BUY_EXACT_SOL_IN,
3846
+ EventType.PUMP_FUN_CREATE,
3847
+ EventType.PUMP_FUN_CREATE_V2,
3848
+ )
3849
+ for t in include_only
3850
+ )
3851
+ if has_specific and not _pumpfun_trade_matches_include_only(ev, include_only):
3852
+ return None
3853
+ return apply_event_type_filter(ev, event_type_filter)
3854
+
3855
+
3856
+ def dispatch_scoped_pumpfun_data(
3857
+ disc: int,
3858
+ data: bytes,
3859
+ meta: dict,
3860
+ is_created_buy: bool,
3861
+ event_type_filter: Any = None,
3862
+ ) -> Optional[DexEvent]:
3863
+ if disc == PUMP_TRADE:
3864
+ return apply_pumpfun_secondary_filter(
3865
+ parse_trade_from_data(data, meta, is_created_buy),
3866
+ event_type_filter,
3867
+ )
3868
+ if disc == PUMP_CREATE:
3869
+ return parse_create_from_data(data, meta)
3870
+ if disc == PUMP_MIGRATE:
3871
+ return parse_migrate_from_data(data, meta)
3872
+ if disc == PUMP_MIGRATE_BONDING_CURVE_CREATOR:
3873
+ return parse_migrate_bonding_curve_creator_from_data(data, meta)
3874
+ return None
3875
+
3876
+
3877
+ def dispatch_scoped_pump_fees_data(disc: int, data: bytes, meta: dict) -> Optional[DexEvent]:
3878
+ if disc == PUMP_FEES_CREATE_FEE_SHARING_CONFIG:
3879
+ return parse_pump_fees_create_fee_sharing_config_from_data(data, meta)
3880
+ if disc == PUMP_FEES_INITIALIZE_FEE_CONFIG:
3881
+ return parse_pump_fees_initialize_fee_config_from_data(data, meta)
3882
+ if disc == PUMP_FEES_RESET_FEE_SHARING_CONFIG:
3883
+ return parse_pump_fees_reset_fee_sharing_config_from_data(data, meta)
3884
+ if disc == PUMP_FEES_REVOKE_FEE_SHARING_AUTHORITY:
3885
+ return parse_pump_fees_revoke_fee_sharing_authority_from_data(data, meta)
3886
+ if disc == PUMP_FEES_TRANSFER_FEE_SHARING_AUTHORITY:
3887
+ return parse_pump_fees_transfer_fee_sharing_authority_from_data(data, meta)
3888
+ if disc == PUMP_FEES_UPDATE_ADMIN:
3889
+ return parse_pump_fees_update_admin_from_data(data, meta)
3890
+ if disc == PUMP_FEES_UPDATE_FEE_CONFIG:
3891
+ return parse_pump_fees_update_fee_config_from_data(data, meta)
3892
+ if disc == PUMP_FEES_UPDATE_FEE_SHARES:
3893
+ return parse_pump_fees_update_fee_shares_from_data(data, meta)
3894
+ if disc == PUMP_FEES_UPSERT_FEE_TIERS:
3895
+ return parse_pump_fees_upsert_fee_tiers_from_data(data, meta)
3896
+ return None
3897
+
3898
+
3899
+ def dispatch_scoped_pumpswap_data(disc: int, data: bytes, meta: dict) -> Optional[DexEvent]:
3900
+ if disc == _d(103, 244, 82, 31, 44, 245, 119, 119):
3901
+ return parse_ps_buy_from_data(data, meta)
3902
+ if disc == _d(62, 47, 55, 10, 165, 3, 220, 42):
3903
+ return parse_ps_sell_from_data(data, meta)
3904
+ if disc == _d(177, 49, 12, 210, 160, 118, 167, 116):
3905
+ return parse_ps_create_pool_from_data(data, meta)
3906
+ if disc == _d(120, 248, 61, 83, 31, 142, 107, 144):
3907
+ return parse_ps_add_liq_from_data(data, meta)
3908
+ if disc == _d(22, 9, 133, 26, 160, 44, 71, 192):
3909
+ return parse_ps_remove_liq_from_data(data, meta)
3910
+ return None
3911
+
3912
+
2655
3913
  def filter_includes_program(event_type_filter: Any, program_id: Optional[str]) -> bool:
2656
3914
  from .grpc_types import (
2657
3915
  METEORA_DAMM_V2_FILTER_TYPES,
2658
3916
  METEORA_DBC_FILTER_TYPES,
2659
3917
  METEORA_DLMM_FILTER_TYPES,
3918
+ METEORA_POOLS_FILTER_TYPES,
3919
+ ORCA_WHIRLPOOL_FILTER_TYPES,
3920
+ PUMP_FEES_EVENT_TYPES,
3921
+ PUMPFUN_FILTER_TYPES,
3922
+ PUMPSWAP_FILTER_TYPES,
3923
+ RAYDIUM_AMM_V4_FILTER_TYPES,
3924
+ RAYDIUM_CLMM_FILTER_TYPES,
3925
+ RAYDIUM_CPMM_FILTER_TYPES,
2660
3926
  RAYDIUM_LAUNCHLAB_FILTER_TYPES,
2661
3927
  )
2662
3928
 
2663
3929
  groups = {
3930
+ PUMPFUN_PROGRAM_ID: PUMPFUN_FILTER_TYPES,
3931
+ PUMP_FEES_PROGRAM_ID: PUMP_FEES_EVENT_TYPES,
3932
+ PUMPSWAP_PROGRAM_ID: PUMPSWAP_FILTER_TYPES,
2664
3933
  RAYDIUM_LAUNCHLAB_PROGRAM_ID: RAYDIUM_LAUNCHLAB_FILTER_TYPES,
3934
+ RAYDIUM_CLMM_PROGRAM_ID: RAYDIUM_CLMM_FILTER_TYPES,
3935
+ RAYDIUM_CPMM_PROGRAM_ID: RAYDIUM_CPMM_FILTER_TYPES,
3936
+ RAYDIUM_AMM_V4_PROGRAM_ID: RAYDIUM_AMM_V4_FILTER_TYPES,
3937
+ ORCA_WHIRLPOOL_PROGRAM_ID: ORCA_WHIRLPOOL_FILTER_TYPES,
3938
+ METEORA_POOLS_PROGRAM_ID: METEORA_POOLS_FILTER_TYPES,
2665
3939
  METEORA_DAMM_V2_PROGRAM_ID: METEORA_DAMM_V2_FILTER_TYPES,
2666
3940
  METEORA_DBC_PROGRAM_ID: METEORA_DBC_FILTER_TYPES,
2667
3941
  METEORA_DLMM_PROGRAM_ID: METEORA_DLMM_FILTER_TYPES,
@@ -2697,16 +3971,114 @@ def dispatch_program_data(
2697
3971
  meta: dict,
2698
3972
  is_created_buy: bool,
2699
3973
  program_id: Optional[str] = None,
3974
+ event_type_filter: Any = None,
2700
3975
  ) -> Optional[DexEvent]:
3976
+ if program_id == PUMPFUN_PROGRAM_ID:
3977
+ return dispatch_scoped_pumpfun_data(disc, data, meta, is_created_buy, event_type_filter)
3978
+ if program_id == PUMP_FEES_PROGRAM_ID:
3979
+ return dispatch_scoped_pump_fees_data(disc, data, meta)
3980
+ if program_id == PUMPSWAP_PROGRAM_ID:
3981
+ return dispatch_scoped_pumpswap_data(disc, data, meta)
2701
3982
  if program_id == RAYDIUM_LAUNCHLAB_PROGRAM_ID:
2702
3983
  return parse_raydium_launchlab_from_discriminator(disc, data, meta)
3984
+ if program_id == RAYDIUM_CLMM_PROGRAM_ID:
3985
+ if disc == _d(64, 198, 205, 232, 38, 8, 113, 226):
3986
+ return parse_clmm_swap_from_data(data, meta)
3987
+ if disc == _d(49, 79, 105, 212, 32, 34, 30, 84):
3988
+ return parse_clmm_inc_from_data(data, meta)
3989
+ if disc == _d(58, 222, 86, 58, 68, 50, 85, 56):
3990
+ return parse_clmm_dec_from_data(data, meta)
3991
+ if disc == _d(126, 240, 175, 206, 158, 88, 153, 107):
3992
+ return parse_clmm_liquidity_change_from_data(data, meta)
3993
+ if disc == _d(247, 189, 7, 119, 106, 112, 95, 151):
3994
+ return parse_clmm_config_change_from_data(data, meta)
3995
+ if disc == _d(100, 30, 87, 249, 196, 223, 154, 206):
3996
+ return parse_clmm_create_personal_position_from_data(data, meta)
3997
+ if disc == _d(237, 112, 148, 230, 57, 84, 180, 162):
3998
+ return parse_clmm_liquidity_calculate_from_data(data, meta)
3999
+ if disc == _d(106, 24, 71, 85, 57, 169, 158, 216):
4000
+ return parse_clmm_open_limit_order_from_data(data, meta)
4001
+ if disc == _d(11, 120, 13, 204, 199, 87, 19, 200):
4002
+ return parse_clmm_increase_limit_order_from_data(data, meta)
4003
+ if disc == _d(70, 48, 40, 221, 219, 237, 212, 163):
4004
+ return parse_clmm_decrease_limit_order_from_data(data, meta)
4005
+ if disc == _d(88, 119, 77, 164, 125, 124, 10, 194):
4006
+ return parse_clmm_settle_limit_order_from_data(data, meta)
4007
+ if disc == _d(109, 127, 186, 78, 114, 65, 37, 236):
4008
+ return parse_clmm_update_reward_infos_from_data(data, meta)
4009
+ if disc == _d(25, 94, 75, 47, 112, 99, 53, 63):
4010
+ return parse_clmm_create_from_data(data, meta)
4011
+ if disc == _d(166, 174, 105, 192, 81, 161, 83, 105):
4012
+ return parse_clmm_collect_personal_from_data(data, meta)
4013
+ if disc == _d(206, 87, 17, 79, 45, 41, 213, 61):
4014
+ return parse_clmm_collect_protocol_from_data(data, meta)
4015
+ return None
4016
+ if program_id == RAYDIUM_CPMM_PROGRAM_ID:
4017
+ if disc == _d(64, 198, 205, 232, 38, 8, 113, 226):
4018
+ return parse_cpmm_swap_event_from_data(data, meta)
4019
+ if disc == _d(143, 190, 90, 218, 196, 30, 51, 222):
4020
+ return parse_cpmm_swap_in_from_data(data, meta)
4021
+ if disc == _d(55, 217, 98, 86, 163, 74, 180, 173):
4022
+ return parse_cpmm_swap_out_from_data(data, meta)
4023
+ if disc == _d(233, 146, 209, 142, 207, 104, 64, 188):
4024
+ return parse_cpmm_create_from_data(data, meta)
4025
+ if disc == _d(242, 35, 198, 137, 82, 225, 242, 182):
4026
+ return parse_cpmm_deposit_from_data(data, meta)
4027
+ if disc == _d(183, 18, 70, 156, 148, 109, 161, 34):
4028
+ return parse_cpmm_withdraw_from_data(data, meta)
4029
+ return None
4030
+ if program_id == RAYDIUM_AMM_V4_PROGRAM_ID:
4031
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 9):
4032
+ return parse_amm_swap_in_from_data(data, meta)
4033
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 11):
4034
+ return parse_amm_swap_out_from_data(data, meta)
4035
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 3):
4036
+ return parse_amm_deposit_from_data(data, meta)
4037
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 4):
4038
+ return parse_amm_withdraw_from_data(data, meta)
4039
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 1):
4040
+ return parse_amm_init2_from_data(data, meta)
4041
+ if disc == _d(0, 0, 0, 0, 0, 0, 0, 7):
4042
+ return parse_amm_withdraw_pnl_from_data(data, meta)
4043
+ return None
4044
+ if program_id == ORCA_WHIRLPOOL_PROGRAM_ID:
4045
+ if disc == _d(225, 202, 73, 175, 147, 43, 160, 150):
4046
+ return parse_orca_traded_from_data(data, meta)
4047
+ if disc == _d(30, 7, 144, 181, 102, 254, 155, 161):
4048
+ return parse_orca_liq_inc_from_data(data, meta)
4049
+ if disc == _d(166, 1, 36, 71, 112, 202, 181, 171):
4050
+ return parse_orca_liq_dec_from_data(data, meta)
4051
+ if disc == _d(100, 118, 173, 87, 12, 198, 254, 229):
4052
+ return parse_orca_pool_init_from_data(data, meta)
4053
+ return None
4054
+ if program_id == METEORA_POOLS_PROGRAM_ID:
4055
+ if disc == _d(81, 108, 227, 190, 205, 208, 10, 196):
4056
+ return parse_meteora_swap_from_data(data, meta)
4057
+ if disc == _d(31, 94, 125, 90, 227, 52, 61, 186):
4058
+ return parse_meteora_add_from_data(data, meta)
4059
+ if disc == _d(116, 244, 97, 232, 103, 31, 152, 58):
4060
+ return parse_meteora_remove_from_data(data, meta)
4061
+ if disc == _d(121, 127, 38, 136, 92, 55, 14, 247):
4062
+ return parse_meteora_bootstrap_from_data(data, meta)
4063
+ if disc == _d(202, 44, 41, 88, 104, 220, 157, 82):
4064
+ return parse_meteora_pool_created_from_data(data, meta)
4065
+ if disc == _d(245, 26, 198, 164, 88, 18, 75, 9):
4066
+ return parse_meteora_pools_set_pool_fees_from_data(data, meta)
4067
+ return None
4068
+ if program_id == METEORA_DAMM_V2_PROGRAM_ID:
4069
+ return parse_meteora_damm_from_buf(buf, meta)
2703
4070
  if program_id == METEORA_DBC_PROGRAM_ID:
2704
4071
  return parse_meteora_dbc_from_discriminator(disc, data, meta)
2705
4072
  if program_id == METEORA_DLMM_PROGRAM_ID:
2706
4073
  return parse_dlmm_from_program_data(buf, meta)
2707
4074
  if disc == PUMP_TRADE:
2708
- return parse_trade_from_data(data, meta, is_created_buy)
2709
- if disc == _d(248, 198, 158, 145, 225, 117, 135, 200):
4075
+ return dispatch_unscoped_pumpfun_launchlab_trade(
4076
+ data,
4077
+ meta,
4078
+ is_created_buy,
4079
+ event_type_filter,
4080
+ )
4081
+ if disc == _d(64, 198, 205, 232, 38, 8, 113, 226):
2710
4082
  return parse_clmm_swap_from_data(data, meta)
2711
4083
  if disc == _d(0, 0, 0, 0, 0, 0, 0, 9):
2712
4084
  return parse_amm_swap_in_from_data(data, meta)
@@ -2744,16 +4116,36 @@ def dispatch_program_data(
2744
4116
  return parse_ps_add_liq_from_data(data, meta)
2745
4117
  if disc == _d(22, 9, 133, 26, 160, 44, 71, 192):
2746
4118
  return parse_ps_remove_liq_from_data(data, meta)
2747
- if disc == _d(133, 29, 89, 223, 69, 238, 176, 10):
4119
+ if disc == _d(49, 79, 105, 212, 32, 34, 30, 84):
2748
4120
  return parse_clmm_inc_from_data(data, meta)
2749
- if disc == _d(160, 38, 208, 111, 104, 91, 44, 1):
4121
+ if disc == _d(58, 222, 86, 58, 68, 50, 85, 56):
2750
4122
  return parse_clmm_dec_from_data(data, meta)
2751
- if disc == _d(233, 146, 209, 142, 207, 104, 64, 188):
4123
+ if disc == _d(126, 240, 175, 206, 158, 88, 153, 107):
4124
+ return parse_clmm_liquidity_change_from_data(data, meta)
4125
+ if disc == _d(247, 189, 7, 119, 106, 112, 95, 151):
4126
+ return parse_clmm_config_change_from_data(data, meta)
4127
+ if disc == _d(100, 30, 87, 249, 196, 223, 154, 206):
4128
+ return parse_clmm_create_personal_position_from_data(data, meta)
4129
+ if disc == _d(237, 112, 148, 230, 57, 84, 180, 162):
4130
+ return parse_clmm_liquidity_calculate_from_data(data, meta)
4131
+ if disc == _d(106, 24, 71, 85, 57, 169, 158, 216):
4132
+ return parse_clmm_open_limit_order_from_data(data, meta)
4133
+ if disc == _d(11, 120, 13, 204, 199, 87, 19, 200):
4134
+ return parse_clmm_increase_limit_order_from_data(data, meta)
4135
+ if disc == _d(70, 48, 40, 221, 219, 237, 212, 163):
4136
+ return parse_clmm_decrease_limit_order_from_data(data, meta)
4137
+ if disc == _d(88, 119, 77, 164, 125, 124, 10, 194):
4138
+ return parse_clmm_settle_limit_order_from_data(data, meta)
4139
+ if disc == _d(109, 127, 186, 78, 114, 65, 37, 236):
4140
+ return parse_clmm_update_reward_infos_from_data(data, meta)
4141
+ if disc == _d(25, 94, 75, 47, 112, 99, 53, 63):
2752
4142
  return parse_clmm_create_from_data(data, meta)
2753
- if disc == _d(164, 152, 207, 99, 187, 104, 171, 119):
2754
- return parse_clmm_collect_from_data(data, meta)
4143
+ if disc == _d(166, 174, 105, 192, 81, 161, 83, 105):
4144
+ return parse_clmm_collect_personal_from_data(data, meta)
4145
+ if disc == _d(206, 87, 17, 79, 45, 41, 213, 61):
4146
+ return parse_clmm_collect_protocol_from_data(data, meta)
2755
4147
  if disc == _d(143, 190, 90, 218, 196, 30, 51, 222):
2756
- return parse_cpmm_swap_in_from_data(data, meta)
4148
+ return apply_event_type_filter(parse_cpmm_swap_in_from_data(data, meta), event_type_filter)
2757
4149
  if disc == _d(55, 217, 98, 86, 163, 74, 180, 173):
2758
4150
  return parse_cpmm_swap_out_from_data(data, meta)
2759
4151
  if disc == _d(242, 35, 198, 137, 82, 225, 242, 182):
@@ -2793,11 +4185,16 @@ def dispatch_program_data(
2793
4185
  if disc in (
2794
4186
  DAMM_SWAP,
2795
4187
  DAMM_SWAP2,
2796
- _d(175, 242, 8, 157, 30, 247, 185, 169),
2797
- _d(87, 46, 88, 98, 175, 96, 34, 91),
2798
- _d(228, 50, 246, 85, 203, 66, 134, 37),
2799
- _d(156, 15, 119, 198, 29, 181, 221, 55),
2800
- _d(20, 145, 144, 68, 143, 142, 214, 178),
4188
+ DAMM_ADD_LIQUIDITY,
4189
+ DAMM_REMOVE_LIQUIDITY,
4190
+ DAMM_LIQUIDITY_CHANGE,
4191
+ DAMM_INIT_POOL,
4192
+ DAMM_CREATE_POSITION,
4193
+ DAMM_CLOSE_POSITION,
4194
+ DAMM_UPDATE_DELEGATE_PERMISSION,
4195
+ DAMM_WITHDRAW_DEAD_LIQUIDITY_REWARD,
4196
+ DAMM_CREATE_CONFIG,
4197
+ DAMM_CREATE_DYNAMIC_CONFIG,
2801
4198
  ):
2802
4199
  return parse_meteora_damm_from_buf(buf, meta)
2803
4200
  raydium_launchlab = parse_raydium_launchlab_from_discriminator(disc, data, meta)