sol-parser-sdk-python 0.5.7__py3-none-any.whl → 0.5.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sol_parser/__init__.py +10 -0
- sol_parser/account_dispatcher.py +79 -0
- sol_parser/account_fillers/meteora.py +10 -2
- sol_parser/account_fillers/raydium.py +3 -2
- sol_parser/account_fillers/raydium_launchlab.py +50 -0
- sol_parser/accounts/__init__.py +47 -2
- sol_parser/dex_parsers.py +648 -68
- sol_parser/event_type_parity.py +4 -0
- sol_parser/event_types.py +221 -3
- sol_parser/grpc_instruction_parser.py +85 -26
- sol_parser/grpc_types.py +12 -0
- sol_parser/inner_instruction_parser.py +5 -7
- sol_parser/instructions.py +213 -49
- sol_parser/log_instr_dedup.py +56 -12
- sol_parser/merger.py +73 -85
- sol_parser/parser.py +11 -0
- sol_parser/pumpfun_fee_enrich.py +2 -0
- sol_parser/rpc_parser.py +30 -4
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/METADATA +26 -9
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/RECORD +22 -22
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/WHEEL +1 -1
- {sol_parser_sdk_python-0.5.7.dist-info → sol_parser_sdk_python-0.5.8.dist-info}/entry_points.txt +0 -0
sol_parser/instructions.py
CHANGED
|
@@ -43,6 +43,7 @@ from .event_types import (
|
|
|
43
43
|
PumpFunCreateV2TokenEvent,
|
|
44
44
|
PumpFunTradeEvent,
|
|
45
45
|
PumpSwapBuyEvent,
|
|
46
|
+
PumpSwapCreatePoolEvent,
|
|
46
47
|
PumpSwapSellEvent,
|
|
47
48
|
MeteoraDlmmAddLiquidityEvent,
|
|
48
49
|
MeteoraDlmmClaimFeeEvent,
|
|
@@ -83,6 +84,7 @@ def _d(*xs: int) -> int:
|
|
|
83
84
|
_DISC_PUMPSWAP_BUY = _d(102, 6, 61, 18, 1, 218, 235, 234)
|
|
84
85
|
_DISC_PUMPSWAP_SELL = _d(51, 230, 133, 164, 1, 127, 131, 173)
|
|
85
86
|
_DISC_PUMPSWAP_BUY_EXACT_QUOTE_IN = _d(198, 46, 21, 82, 180, 217, 232, 112)
|
|
87
|
+
_DISC_PUMPSWAP_CREATE_POOL = _d(233, 146, 209, 142, 207, 104, 64, 188)
|
|
86
88
|
|
|
87
89
|
_DISC_DAMM_SWAP = _d(27, 60, 21, 213, 138, 170, 187, 147)
|
|
88
90
|
_DISC_DAMM_SWAP2 = _d(189, 66, 51, 168, 38, 80, 117, 153)
|
|
@@ -97,6 +99,50 @@ _DISC_METEORA_POOLS_ADD_LIQUIDITY = _d(181, 157, 89, 67, 143, 182, 52, 72)
|
|
|
97
99
|
_DISC_METEORA_POOLS_REMOVE_LIQUIDITY = _d(80, 85, 209, 72, 24, 206, 177, 108)
|
|
98
100
|
_DISC_METEORA_POOLS_CREATE_POOL = _d(95, 180, 10, 172, 84, 174, 232, 40)
|
|
99
101
|
|
|
102
|
+
_DISC_DLMM_ADD_LIQUIDITY = _d(181, 157, 89, 67, 143, 182, 52, 72)
|
|
103
|
+
_DISC_DLMM_ADD_LIQUIDITY2 = _d(228, 162, 78, 28, 70, 219, 116, 115)
|
|
104
|
+
_DISC_DLMM_CLAIM_FEE = _d(169, 32, 79, 137, 136, 232, 70, 137)
|
|
105
|
+
_DISC_DLMM_CLAIM_FEE2 = _d(112, 191, 101, 171, 28, 144, 127, 187)
|
|
106
|
+
_DISC_DLMM_CLOSE_POSITION = _d(123, 134, 81, 0, 49, 68, 98, 98)
|
|
107
|
+
_DISC_DLMM_CLOSE_POSITION2 = _d(174, 90, 35, 115, 186, 40, 147, 226)
|
|
108
|
+
_DISC_DLMM_INITIALIZE_BIN_ARRAY = _d(35, 86, 19, 185, 78, 212, 75, 211)
|
|
109
|
+
_DISC_DLMM_INITIALIZE_LB_PAIR = _d(45, 154, 237, 210, 221, 15, 166, 92)
|
|
110
|
+
_DISC_DLMM_INITIALIZE_LB_PAIR2 = _d(73, 59, 36, 120, 237, 83, 108, 198)
|
|
111
|
+
_DISC_DLMM_INITIALIZE_POSITION = _d(219, 192, 234, 71, 190, 191, 102, 80)
|
|
112
|
+
_DISC_DLMM_INITIALIZE_POSITION2 = _d(143, 19, 242, 145, 213, 15, 104, 115)
|
|
113
|
+
_DISC_DLMM_INITIALIZE_POSITION_PDA = _d(46, 82, 125, 146, 85, 141, 228, 153)
|
|
114
|
+
_DISC_DLMM_REMOVE_LIQUIDITY = _d(80, 85, 209, 72, 24, 206, 177, 108)
|
|
115
|
+
_DISC_DLMM_REMOVE_LIQUIDITY2 = _d(230, 215, 82, 127, 241, 101, 227, 146)
|
|
116
|
+
_DISC_DLMM_SWAP = _d(248, 198, 158, 145, 225, 117, 135, 200)
|
|
117
|
+
_DISC_DLMM_SWAP2 = _d(65, 75, 63, 76, 235, 91, 91, 136)
|
|
118
|
+
_DISC_DLMM_SWAP_EXACT_OUT = _d(250, 73, 101, 33, 38, 207, 75, 184)
|
|
119
|
+
_DISC_DLMM_SWAP_EXACT_OUT2 = _d(43, 215, 247, 132, 137, 60, 243, 81)
|
|
120
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT = _d(56, 173, 230, 208, 173, 228, 156, 205)
|
|
121
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT2 = _d(74, 98, 192, 214, 177, 51, 75, 51)
|
|
122
|
+
|
|
123
|
+
_DLMM_INSTRUCTION_DISCS = (
|
|
124
|
+
_DISC_DLMM_INITIALIZE_LB_PAIR,
|
|
125
|
+
_DISC_DLMM_INITIALIZE_LB_PAIR2,
|
|
126
|
+
_DISC_DLMM_INITIALIZE_BIN_ARRAY,
|
|
127
|
+
_DISC_DLMM_ADD_LIQUIDITY,
|
|
128
|
+
_DISC_DLMM_ADD_LIQUIDITY2,
|
|
129
|
+
_DISC_DLMM_REMOVE_LIQUIDITY,
|
|
130
|
+
_DISC_DLMM_REMOVE_LIQUIDITY2,
|
|
131
|
+
_DISC_DLMM_INITIALIZE_POSITION,
|
|
132
|
+
_DISC_DLMM_INITIALIZE_POSITION2,
|
|
133
|
+
_DISC_DLMM_INITIALIZE_POSITION_PDA,
|
|
134
|
+
_DISC_DLMM_SWAP,
|
|
135
|
+
_DISC_DLMM_SWAP2,
|
|
136
|
+
_DISC_DLMM_SWAP_EXACT_OUT,
|
|
137
|
+
_DISC_DLMM_SWAP_EXACT_OUT2,
|
|
138
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT,
|
|
139
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT2,
|
|
140
|
+
_DISC_DLMM_CLAIM_FEE,
|
|
141
|
+
_DISC_DLMM_CLAIM_FEE2,
|
|
142
|
+
_DISC_DLMM_CLOSE_POSITION,
|
|
143
|
+
_DISC_DLMM_CLOSE_POSITION2,
|
|
144
|
+
)
|
|
145
|
+
|
|
100
146
|
_DISC_CLMM_SWAP = _d(248, 198, 158, 145, 225, 117, 135, 200)
|
|
101
147
|
_DISC_CLMM_SWAP_V2 = _d(43, 4, 237, 11, 26, 201, 30, 98)
|
|
102
148
|
_DISC_CLMM_INC_LIQ = _d(133, 29, 89, 223, 69, 238, 176, 10)
|
|
@@ -324,7 +370,8 @@ def normal_instruction_data_may_parse(program_id: str, instruction_data: bytes)
|
|
|
324
370
|
if program_id == RAYDIUM_AMM_V4_PROGRAM_ID:
|
|
325
371
|
return instruction_data[0] in (1, 3, 4, 7, 9, 11)
|
|
326
372
|
if program_id == METEORA_DLMM_PROGRAM_ID:
|
|
327
|
-
|
|
373
|
+
disc = _disc8(instruction_data)
|
|
374
|
+
return disc in _DLMM_INSTRUCTION_DISCS if disc is not None else False
|
|
328
375
|
disc = _disc8(instruction_data)
|
|
329
376
|
if disc is None:
|
|
330
377
|
return False
|
|
@@ -345,7 +392,7 @@ def normal_instruction_data_may_parse(program_id: str, instruction_data: bytes)
|
|
|
345
392
|
return disc in (
|
|
346
393
|
_DISC_PUMPSWAP_BUY,
|
|
347
394
|
_DISC_PUMPSWAP_SELL,
|
|
348
|
-
|
|
395
|
+
_DISC_PUMPSWAP_CREATE_POOL,
|
|
349
396
|
_DISC_PUMPSWAP_BUY_EXACT_QUOTE_IN,
|
|
350
397
|
_d(242, 35, 198, 137, 82, 225, 242, 182),
|
|
351
398
|
_d(183, 18, 70, 156, 148, 109, 161, 34),
|
|
@@ -764,6 +811,12 @@ def _parse_pumpfun_create_v2(data: bytes, accounts: List[str], meta: EventMetada
|
|
|
764
811
|
is_mayhem_mode = data[offset] == 1
|
|
765
812
|
offset += 1
|
|
766
813
|
is_cashback_enabled = data[offset] == 1 if offset < len(data) else False
|
|
814
|
+
if offset < len(data):
|
|
815
|
+
offset += 1
|
|
816
|
+
creator_fee_bps = struct.unpack_from("<Q", data, offset)[0] if offset + 8 <= len(data) else 0
|
|
817
|
+
if offset + 8 <= len(data):
|
|
818
|
+
offset += 8
|
|
819
|
+
is_holder_reward = data[offset] == 1 if offset < len(data) else False
|
|
767
820
|
|
|
768
821
|
return DexEvent(
|
|
769
822
|
type=EventType.PUMP_FUN_CREATE_V2,
|
|
@@ -796,6 +849,8 @@ def _parse_pumpfun_create_v2(data: bytes, accounts: List[str], meta: EventMetada
|
|
|
796
849
|
token_total_supply=0,
|
|
797
850
|
is_mayhem_mode=is_mayhem_mode,
|
|
798
851
|
is_cashback_enabled=is_cashback_enabled,
|
|
852
|
+
creator_fee_bps=creator_fee_bps,
|
|
853
|
+
is_holder_reward=is_holder_reward,
|
|
799
854
|
quote_mint=_get_account_safe(accounts, 16) or Z,
|
|
800
855
|
quote_vault=_get_account_safe(accounts, 17),
|
|
801
856
|
quote_token_program=_get_account_safe(accounts, 18),
|
|
@@ -906,6 +961,38 @@ def parse_pumpswap_instruction(
|
|
|
906
961
|
fill_sell_tail(ev)
|
|
907
962
|
return DexEvent(type=EventType.PUMP_SWAP_SELL, data=ev)
|
|
908
963
|
|
|
964
|
+
if discriminator == _DISC_PUMPSWAP_CREATE_POOL:
|
|
965
|
+
if len(accounts) < 8:
|
|
966
|
+
return None
|
|
967
|
+
return DexEvent(
|
|
968
|
+
type=EventType.PUMP_SWAP_CREATE_POOL,
|
|
969
|
+
data=PumpSwapCreatePoolEvent(
|
|
970
|
+
metadata=meta,
|
|
971
|
+
index=struct.unpack_from("<H", payload, 0)[0] if len(payload) >= 2 else 0,
|
|
972
|
+
pool=_get_account_safe(accounts, 0),
|
|
973
|
+
creator=_get_account_safe(accounts, 2),
|
|
974
|
+
base_mint=_get_account_safe(accounts, 3),
|
|
975
|
+
quote_mint=_get_account_safe(accounts, 4),
|
|
976
|
+
base_amount_in=struct.unpack_from("<Q", payload, 2)[0] if len(payload) >= 10 else 0,
|
|
977
|
+
quote_amount_in=struct.unpack_from("<Q", payload, 10)[0] if len(payload) >= 18 else 0,
|
|
978
|
+
lp_mint=_get_account_safe(accounts, 5),
|
|
979
|
+
user_base_token_account=_get_account_safe(accounts, 6),
|
|
980
|
+
user_quote_token_account=_get_account_safe(accounts, 7),
|
|
981
|
+
coin_creator=(
|
|
982
|
+
base58.b58encode(payload[18:50]).decode("ascii")
|
|
983
|
+
if len(payload) >= 50
|
|
984
|
+
else Z
|
|
985
|
+
),
|
|
986
|
+
is_mayhem_mode=len(payload) > 50 and payload[50] == 1,
|
|
987
|
+
is_cashback_coin=len(payload) > 51 and payload[51] == 1,
|
|
988
|
+
creator_fee_bps=(
|
|
989
|
+
struct.unpack_from("<Q", payload, 52)[0] if len(payload) >= 60 else 0
|
|
990
|
+
),
|
|
991
|
+
can_edit_creator_fee=len(payload) > 60 and payload[60] == 1,
|
|
992
|
+
is_holder_reward=len(payload) > 61 and payload[61] == 1,
|
|
993
|
+
),
|
|
994
|
+
)
|
|
995
|
+
|
|
909
996
|
return None
|
|
910
997
|
|
|
911
998
|
|
|
@@ -1024,94 +1111,124 @@ def parse_meteora_dlmm_instruction(
|
|
|
1024
1111
|
block_time_us: Optional[int],
|
|
1025
1112
|
grpc_recv_us: int,
|
|
1026
1113
|
) -> Optional[DexEvent]:
|
|
1027
|
-
if
|
|
1114
|
+
if len(data) < 8 or not accounts:
|
|
1028
1115
|
return None
|
|
1029
|
-
|
|
1030
|
-
payload = data[
|
|
1116
|
+
discriminator = struct.unpack_from("<Q", data, 0)[0]
|
|
1117
|
+
payload = data[8:]
|
|
1031
1118
|
meta = _make_meta(signature, slot, tx_index, block_time_us, grpc_recv_us)
|
|
1032
|
-
pool = accounts[0]
|
|
1033
1119
|
|
|
1034
|
-
if
|
|
1120
|
+
if discriminator == _DISC_DLMM_INITIALIZE_LB_PAIR:
|
|
1035
1121
|
if len(payload) < 6:
|
|
1036
1122
|
return None
|
|
1123
|
+
pool = _get_account_safe(accounts, 0)
|
|
1037
1124
|
return DexEvent(
|
|
1038
1125
|
type=EventType.METEORA_DLMM_INITIALIZE_POOL,
|
|
1039
1126
|
data=MeteoraDlmmInitializePoolEvent(
|
|
1040
1127
|
metadata=meta,
|
|
1041
1128
|
pool=pool,
|
|
1042
|
-
creator=_get_account_safe(accounts,
|
|
1129
|
+
creator=_get_account_safe(accounts, 8),
|
|
1043
1130
|
active_bin_id=struct.unpack_from("<i", payload, 0)[0],
|
|
1044
1131
|
bin_step=struct.unpack_from("<H", payload, 4)[0],
|
|
1045
1132
|
),
|
|
1046
1133
|
)
|
|
1047
1134
|
|
|
1048
|
-
if
|
|
1135
|
+
if discriminator == _DISC_DLMM_INITIALIZE_LB_PAIR2:
|
|
1136
|
+
if len(payload) < 4:
|
|
1137
|
+
return None
|
|
1138
|
+
pool = _get_account_safe(accounts, 0)
|
|
1139
|
+
return DexEvent(
|
|
1140
|
+
type=EventType.METEORA_DLMM_INITIALIZE_POOL,
|
|
1141
|
+
data=MeteoraDlmmInitializePoolEvent(
|
|
1142
|
+
metadata=meta,
|
|
1143
|
+
pool=pool,
|
|
1144
|
+
creator=_get_account_safe(accounts, 8),
|
|
1145
|
+
active_bin_id=struct.unpack_from("<i", payload, 0)[0],
|
|
1146
|
+
bin_step=0,
|
|
1147
|
+
),
|
|
1148
|
+
)
|
|
1149
|
+
|
|
1150
|
+
if discriminator == _DISC_DLMM_INITIALIZE_BIN_ARRAY:
|
|
1049
1151
|
if len(payload) < 8:
|
|
1050
1152
|
return None
|
|
1153
|
+
pool = _get_account_safe(accounts, 0)
|
|
1051
1154
|
return DexEvent(
|
|
1052
1155
|
type=EventType.METEORA_DLMM_INITIALIZE_BIN_ARRAY,
|
|
1053
1156
|
data=MeteoraDlmmInitializeBinArrayEvent(
|
|
1054
1157
|
metadata=meta,
|
|
1055
1158
|
pool=pool,
|
|
1056
1159
|
bin_array=_get_account_safe(accounts, 1),
|
|
1057
|
-
index=struct.unpack_from("<
|
|
1160
|
+
index=struct.unpack_from("<q", payload, 0)[0],
|
|
1058
1161
|
),
|
|
1059
1162
|
)
|
|
1060
1163
|
|
|
1061
|
-
if
|
|
1062
|
-
|
|
1063
|
-
|
|
1164
|
+
if discriminator in (_DISC_DLMM_ADD_LIQUIDITY, _DISC_DLMM_ADD_LIQUIDITY2):
|
|
1165
|
+
pool = _get_account_safe(accounts, 1)
|
|
1166
|
+
sender_index = 9 if discriminator == _DISC_DLMM_ADD_LIQUIDITY2 else 11
|
|
1064
1167
|
return DexEvent(
|
|
1065
1168
|
type=EventType.METEORA_DLMM_ADD_LIQUIDITY,
|
|
1066
1169
|
data=MeteoraDlmmAddLiquidityEvent(
|
|
1067
1170
|
metadata=meta,
|
|
1068
1171
|
pool=pool,
|
|
1069
|
-
from_addr=_get_account_safe(accounts,
|
|
1070
|
-
position=_get_account_safe(accounts,
|
|
1172
|
+
from_addr=_get_account_safe(accounts, sender_index),
|
|
1173
|
+
position=_get_account_safe(accounts, 0),
|
|
1071
1174
|
amounts=[0, 0],
|
|
1072
1175
|
active_bin_id=0,
|
|
1073
1176
|
),
|
|
1074
1177
|
)
|
|
1075
1178
|
|
|
1076
|
-
if
|
|
1077
|
-
|
|
1078
|
-
|
|
1179
|
+
if discriminator in (_DISC_DLMM_REMOVE_LIQUIDITY, _DISC_DLMM_REMOVE_LIQUIDITY2):
|
|
1180
|
+
pool = _get_account_safe(accounts, 1)
|
|
1181
|
+
sender_index = 9 if discriminator == _DISC_DLMM_REMOVE_LIQUIDITY2 else 11
|
|
1079
1182
|
return DexEvent(
|
|
1080
1183
|
type=EventType.METEORA_DLMM_REMOVE_LIQUIDITY,
|
|
1081
1184
|
data=MeteoraDlmmRemoveLiquidityEvent(
|
|
1082
1185
|
metadata=meta,
|
|
1083
1186
|
pool=pool,
|
|
1084
|
-
from_addr=_get_account_safe(accounts,
|
|
1085
|
-
position=_get_account_safe(accounts,
|
|
1187
|
+
from_addr=_get_account_safe(accounts, sender_index),
|
|
1188
|
+
position=_get_account_safe(accounts, 0),
|
|
1086
1189
|
amounts=[0, 0],
|
|
1087
1190
|
active_bin_id=0,
|
|
1088
1191
|
),
|
|
1089
1192
|
)
|
|
1090
1193
|
|
|
1091
|
-
if
|
|
1194
|
+
if discriminator in (
|
|
1195
|
+
_DISC_DLMM_INITIALIZE_POSITION,
|
|
1196
|
+
_DISC_DLMM_INITIALIZE_POSITION2,
|
|
1197
|
+
_DISC_DLMM_INITIALIZE_POSITION_PDA,
|
|
1198
|
+
):
|
|
1092
1199
|
if len(payload) < 8:
|
|
1093
1200
|
return None
|
|
1201
|
+
lower_bin_id, width = struct.unpack_from("<ii", payload, 0)
|
|
1202
|
+
if width < 0:
|
|
1203
|
+
return None
|
|
1204
|
+
pda = discriminator == _DISC_DLMM_INITIALIZE_POSITION_PDA
|
|
1205
|
+
position_index, pool_index, owner_index = (2, 3, 4) if pda else (1, 2, 3)
|
|
1094
1206
|
return DexEvent(
|
|
1095
1207
|
type=EventType.METEORA_DLMM_CREATE_POSITION,
|
|
1096
1208
|
data=MeteoraDlmmCreatePositionEvent(
|
|
1097
1209
|
metadata=meta,
|
|
1098
|
-
pool=
|
|
1099
|
-
position=_get_account_safe(accounts,
|
|
1100
|
-
owner=_get_account_safe(accounts,
|
|
1101
|
-
lower_bin_id=
|
|
1102
|
-
width=
|
|
1210
|
+
pool=_get_account_safe(accounts, pool_index),
|
|
1211
|
+
position=_get_account_safe(accounts, position_index),
|
|
1212
|
+
owner=_get_account_safe(accounts, owner_index),
|
|
1213
|
+
lower_bin_id=lower_bin_id,
|
|
1214
|
+
width=width,
|
|
1103
1215
|
),
|
|
1104
1216
|
)
|
|
1105
1217
|
|
|
1106
|
-
if
|
|
1107
|
-
if len(payload) <
|
|
1218
|
+
if discriminator in (_DISC_DLMM_SWAP, _DISC_DLMM_SWAP2):
|
|
1219
|
+
if len(payload) < 8:
|
|
1108
1220
|
return None
|
|
1221
|
+
min_out = struct.unpack_from("<Q", payload, 8)[0] if len(payload) >= 16 else 0
|
|
1222
|
+
pool = _get_account_safe(accounts, 0)
|
|
1109
1223
|
return DexEvent(
|
|
1110
1224
|
type=EventType.METEORA_DLMM_SWAP,
|
|
1111
1225
|
data=MeteoraDlmmSwapEvent(
|
|
1112
1226
|
metadata=meta,
|
|
1113
1227
|
pool=pool,
|
|
1114
|
-
from_addr=_get_account_safe(accounts,
|
|
1228
|
+
from_addr=_get_account_safe(accounts, 10),
|
|
1229
|
+
user_token_in=_get_account_safe(accounts, 4),
|
|
1230
|
+
user_token_out=_get_account_safe(accounts, 5),
|
|
1231
|
+
min_amount_out=min_out,
|
|
1115
1232
|
start_bin_id=0,
|
|
1116
1233
|
end_bin_id=0,
|
|
1117
1234
|
amount_in=struct.unpack_from("<Q", payload, 0)[0],
|
|
@@ -1124,27 +1241,65 @@ def parse_meteora_dlmm_instruction(
|
|
|
1124
1241
|
),
|
|
1125
1242
|
)
|
|
1126
1243
|
|
|
1127
|
-
if
|
|
1244
|
+
if discriminator in (
|
|
1245
|
+
_DISC_DLMM_SWAP_EXACT_OUT,
|
|
1246
|
+
_DISC_DLMM_SWAP_EXACT_OUT2,
|
|
1247
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT,
|
|
1248
|
+
_DISC_DLMM_SWAP_WITH_PRICE_IMPACT2,
|
|
1249
|
+
):
|
|
1250
|
+
exact_out = discriminator in (_DISC_DLMM_SWAP_EXACT_OUT, _DISC_DLMM_SWAP_EXACT_OUT2)
|
|
1251
|
+
if len(payload) < (16 if exact_out else 8):
|
|
1252
|
+
return None
|
|
1253
|
+
amount_out = 0
|
|
1254
|
+
if exact_out:
|
|
1255
|
+
amount_out = struct.unpack_from("<Q", payload, 8)[0]
|
|
1256
|
+
pool = _get_account_safe(accounts, 0)
|
|
1257
|
+
return DexEvent(
|
|
1258
|
+
type=EventType.METEORA_DLMM_SWAP,
|
|
1259
|
+
data=MeteoraDlmmSwapEvent(
|
|
1260
|
+
metadata=meta,
|
|
1261
|
+
pool=pool,
|
|
1262
|
+
from_addr=_get_account_safe(accounts, 10),
|
|
1263
|
+
user_token_in=_get_account_safe(accounts, 4),
|
|
1264
|
+
user_token_out=_get_account_safe(accounts, 5),
|
|
1265
|
+
min_amount_out=0,
|
|
1266
|
+
start_bin_id=0,
|
|
1267
|
+
end_bin_id=0,
|
|
1268
|
+
amount_in=struct.unpack_from("<Q", payload, 0)[0],
|
|
1269
|
+
amount_out=amount_out,
|
|
1270
|
+
swap_for_y=False,
|
|
1271
|
+
fee=0,
|
|
1272
|
+
protocol_fee=0,
|
|
1273
|
+
fee_bps="0",
|
|
1274
|
+
host_fee=0,
|
|
1275
|
+
),
|
|
1276
|
+
)
|
|
1277
|
+
|
|
1278
|
+
if discriminator in (_DISC_DLMM_CLAIM_FEE, _DISC_DLMM_CLAIM_FEE2):
|
|
1279
|
+
pool = _get_account_safe(accounts, 0)
|
|
1280
|
+
owner_index = 2 if discriminator == _DISC_DLMM_CLAIM_FEE2 else 4
|
|
1128
1281
|
return DexEvent(
|
|
1129
1282
|
type=EventType.METEORA_DLMM_CLAIM_FEE,
|
|
1130
1283
|
data=MeteoraDlmmClaimFeeEvent(
|
|
1131
1284
|
metadata=meta,
|
|
1132
1285
|
pool=pool,
|
|
1133
1286
|
position=_get_account_safe(accounts, 1),
|
|
1134
|
-
owner=_get_account_safe(accounts,
|
|
1287
|
+
owner=_get_account_safe(accounts, owner_index),
|
|
1135
1288
|
fee_x=0,
|
|
1136
1289
|
fee_y=0,
|
|
1137
1290
|
),
|
|
1138
1291
|
)
|
|
1139
1292
|
|
|
1140
|
-
if
|
|
1293
|
+
if discriminator in (_DISC_DLMM_CLOSE_POSITION, _DISC_DLMM_CLOSE_POSITION2):
|
|
1294
|
+
position = _get_account_safe(accounts, 0)
|
|
1295
|
+
v2 = discriminator == _DISC_DLMM_CLOSE_POSITION2
|
|
1141
1296
|
return DexEvent(
|
|
1142
1297
|
type=EventType.METEORA_DLMM_CLOSE_POSITION,
|
|
1143
1298
|
data=MeteoraDlmmClosePositionEvent(
|
|
1144
1299
|
metadata=meta,
|
|
1145
|
-
pool=
|
|
1146
|
-
position=
|
|
1147
|
-
owner=_get_account_safe(accounts,
|
|
1300
|
+
pool=Z if v2 else _get_account_safe(accounts, 1),
|
|
1301
|
+
position=position,
|
|
1302
|
+
owner=_get_account_safe(accounts, 1 if v2 else 4),
|
|
1148
1303
|
),
|
|
1149
1304
|
)
|
|
1150
1305
|
|
|
@@ -1486,7 +1641,7 @@ def parse_raydium_cpmm_instruction(
|
|
|
1486
1641
|
return None
|
|
1487
1642
|
return legacy_dict_to_dex_event({"RaydiumCpmmSwap": {
|
|
1488
1643
|
"metadata": meta,
|
|
1489
|
-
"pool_id":
|
|
1644
|
+
"pool_id": _get_account_safe(accounts, 3),
|
|
1490
1645
|
"input_amount": 0, "output_amount": 0,
|
|
1491
1646
|
"input_vault_before": 0, "output_vault_before": 0,
|
|
1492
1647
|
"input_transfer_fee": 0, "output_transfer_fee": 0,
|
|
@@ -1497,7 +1652,7 @@ def parse_raydium_cpmm_instruction(
|
|
|
1497
1652
|
return None
|
|
1498
1653
|
return legacy_dict_to_dex_event({"RaydiumCpmmSwap": {
|
|
1499
1654
|
"metadata": meta,
|
|
1500
|
-
"pool_id":
|
|
1655
|
+
"pool_id": _get_account_safe(accounts, 3),
|
|
1501
1656
|
"input_amount": 0, "output_amount": 0,
|
|
1502
1657
|
"input_vault_before": 0, "output_vault_before": 0,
|
|
1503
1658
|
"input_transfer_fee": 0, "output_transfer_fee": 0,
|
|
@@ -1556,20 +1711,28 @@ def parse_raydium_amm_v4_instruction(
|
|
|
1556
1711
|
meta = _make_meta(signature, slot, tx_index, block_time_us, grpc_recv_us)
|
|
1557
1712
|
|
|
1558
1713
|
if instr_type in (9, 11): # SwapBaseIn / SwapBaseOut
|
|
1714
|
+
if len(data) < 17:
|
|
1715
|
+
return None
|
|
1716
|
+
first, second = struct.unpack_from("<QQ", data, 1)
|
|
1717
|
+
shift = 1 if len(accounts) == 17 else 0
|
|
1718
|
+
def g(index: int) -> str:
|
|
1719
|
+
return _get_account_safe(accounts, index - shift if index >= 5 else index)
|
|
1559
1720
|
return legacy_dict_to_dex_event({"RaydiumAmmV4Swap": {
|
|
1560
1721
|
"metadata": meta,
|
|
1561
1722
|
"amm": _get_account_safe(accounts, 1),
|
|
1562
|
-
"user_source_owner":
|
|
1563
|
-
"amount_in":
|
|
1564
|
-
"
|
|
1565
|
-
"
|
|
1566
|
-
"
|
|
1567
|
-
"
|
|
1568
|
-
"
|
|
1569
|
-
"
|
|
1570
|
-
"
|
|
1571
|
-
"
|
|
1572
|
-
"
|
|
1723
|
+
"user_source_owner": g(17),
|
|
1724
|
+
"amount_in": first if instr_type == 9 else 0,
|
|
1725
|
+
"minimum_amount_out": second if instr_type == 9 else 0,
|
|
1726
|
+
"max_amount_in": first if instr_type == 11 else 0,
|
|
1727
|
+
"amount_out": second if instr_type == 11 else 0,
|
|
1728
|
+
"token_program": g(0), "amm_authority": g(2), "amm_open_orders": g(3),
|
|
1729
|
+
"pool_coin_token_account": g(5), "pool_pc_token_account": g(6),
|
|
1730
|
+
"serum_program": g(7), "serum_market": g(8), "serum_bids": g(9),
|
|
1731
|
+
"serum_asks": g(10), "serum_event_queue": g(11),
|
|
1732
|
+
"serum_coin_vault_account": g(12), "serum_pc_vault_account": g(13),
|
|
1733
|
+
"serum_vault_signer": g(14),
|
|
1734
|
+
"user_source_token_account": g(15),
|
|
1735
|
+
"user_destination_token_account": g(16),
|
|
1573
1736
|
}})
|
|
1574
1737
|
|
|
1575
1738
|
return None
|
|
@@ -1599,9 +1762,10 @@ def parse_orca_whirlpool_instruction(
|
|
|
1599
1762
|
sqrt_price_limit = int.from_bytes(data[24:40], "little")
|
|
1600
1763
|
amount_specified_is_input = data[40] != 0
|
|
1601
1764
|
a_to_b = data[41] != 0
|
|
1765
|
+
whirlpool_index = 4 if discriminator == _DISC_ORCA_SWAP_V2 else 2
|
|
1602
1766
|
return legacy_dict_to_dex_event({"OrcaWhirlpoolSwap": {
|
|
1603
1767
|
"metadata": meta,
|
|
1604
|
-
"whirlpool": _get_account_safe(accounts,
|
|
1768
|
+
"whirlpool": _get_account_safe(accounts, whirlpool_index),
|
|
1605
1769
|
"a_to_b": a_to_b,
|
|
1606
1770
|
"pre_sqrt_price": str(sqrt_price_limit), "post_sqrt_price": "0",
|
|
1607
1771
|
"input_amount": amount if amount_specified_is_input else 0,
|
sol_parser/log_instr_dedup.py
CHANGED
|
@@ -49,16 +49,19 @@ def _ix_lane(ix_name: Any) -> int:
|
|
|
49
49
|
return 0
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
OccurrenceBase = Tuple[Any, ...]
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
def _next_occurrence(base:
|
|
55
|
+
def _next_occurrence(base: OccurrenceBase, counts: Dict[OccurrenceBase, int]) -> int:
|
|
56
56
|
current = counts.get(base, 0)
|
|
57
57
|
counts[base] = current + 1
|
|
58
58
|
return current
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
def _dedupe_key(
|
|
61
|
+
def _dedupe_key(
|
|
62
|
+
ev: DexEvent,
|
|
63
|
+
occurrence_counts: Dict[OccurrenceBase, int],
|
|
64
|
+
) -> Optional[str]:
|
|
62
65
|
data = ev.data
|
|
63
66
|
if data is None:
|
|
64
67
|
return None
|
|
@@ -71,7 +74,7 @@ def _dedupe_key(ev: DexEvent, pumpfun_lane_counts: Dict[PumpfunLaneBase, int]) -
|
|
|
71
74
|
bool(getattr(data, "is_buy", False)),
|
|
72
75
|
lane,
|
|
73
76
|
)
|
|
74
|
-
occ = _next_occurrence(base,
|
|
77
|
+
occ = _next_occurrence(("PumpFun", *base), occurrence_counts)
|
|
75
78
|
return f"PumpFunTrade|{base[0]}|{base[1]}|{base[2]}|{base[3]}|{occ}"
|
|
76
79
|
|
|
77
80
|
t = ev.type
|
|
@@ -110,13 +113,32 @@ def _dedupe_key(ev: DexEvent, pumpfun_lane_counts: Dict[PumpfunLaneBase, int]) -
|
|
|
110
113
|
if t == EventType.PUMP_SWAP_LIQUIDITY_REMOVED:
|
|
111
114
|
return f"PumpSwapLiquidityRemoved|{getattr(data, 'pool', '')}|{getattr(data, 'user', '')}"
|
|
112
115
|
if t == EventType.RAYDIUM_CLMM_SWAP:
|
|
113
|
-
|
|
116
|
+
pool = getattr(data, "pool_state", "")
|
|
117
|
+
occurrence = _next_occurrence(("RaydiumClmm", pool), occurrence_counts)
|
|
118
|
+
return f"RaydiumClmmSwap|{pool}|{occurrence}"
|
|
119
|
+
if t == EventType.RAYDIUM_CPMM_SWAP:
|
|
120
|
+
pool = getattr(data, "pool_id", "")
|
|
121
|
+
occurrence = _next_occurrence(("RaydiumCpmm", pool), occurrence_counts)
|
|
122
|
+
return f"RaydiumCpmmSwap|{pool}|{occurrence}"
|
|
114
123
|
if t == EventType.RAYDIUM_AMM_V4_SWAP:
|
|
115
|
-
|
|
124
|
+
base_out = getattr(data, "max_amount_in", 0) != 0
|
|
125
|
+
amount = getattr(data, "amount_out" if base_out else "amount_in", 0)
|
|
126
|
+
base = (base_out, amount)
|
|
127
|
+
occurrence = _next_occurrence(("RaydiumAmmV4", *base), occurrence_counts)
|
|
128
|
+
return f"RaydiumAmmV4Swap|{base_out}|{amount}|{occurrence}"
|
|
129
|
+
if t == EventType.ORCA_WHIRLPOOL_SWAP:
|
|
130
|
+
whirlpool = getattr(data, "whirlpool", "")
|
|
131
|
+
occurrence = _next_occurrence(("OrcaWhirlpool", whirlpool), occurrence_counts)
|
|
132
|
+
return f"OrcaWhirlpoolSwap|{whirlpool}|{occurrence}"
|
|
116
133
|
if t == EventType.METEORA_DLMM_SWAP:
|
|
134
|
+
base = (
|
|
135
|
+
getattr(data, "pool", ""),
|
|
136
|
+
getattr(data, "from_addr", ""),
|
|
137
|
+
bool(getattr(data, "swap_for_y", False)),
|
|
138
|
+
)
|
|
139
|
+
occurrence = _next_occurrence(("MeteoraDlmm", *base), occurrence_counts)
|
|
117
140
|
return (
|
|
118
|
-
f"MeteoraDlmmSwap|{
|
|
119
|
-
f"{getattr(data, 'from_addr', '')}|{bool(getattr(data, 'swap_for_y', False))}"
|
|
141
|
+
f"MeteoraDlmmSwap|{base[0]}|{base[1]}|{base[2]}|{occurrence}"
|
|
120
142
|
)
|
|
121
143
|
return None
|
|
122
144
|
|
|
@@ -163,6 +185,8 @@ def _merge_pumpfun_trade(log: Any, ix: Any) -> None:
|
|
|
163
185
|
"quote_amount",
|
|
164
186
|
"virtual_quote_reserves",
|
|
165
187
|
"real_quote_reserves",
|
|
188
|
+
"holder_rewards_bps",
|
|
189
|
+
"holder_rewards",
|
|
166
190
|
):
|
|
167
191
|
if getattr(log, attr, 0) == 0 and getattr(ix, attr, 0) != 0:
|
|
168
192
|
setattr(log, attr, getattr(ix, attr))
|
|
@@ -195,6 +219,7 @@ def _merge_pumpfun_create(log: Any, ix: Any) -> None:
|
|
|
195
219
|
"real_token_reserves",
|
|
196
220
|
"token_total_supply",
|
|
197
221
|
"virtual_quote_reserves",
|
|
222
|
+
"creator_fee_bps",
|
|
198
223
|
):
|
|
199
224
|
if getattr(log, attr, 0) == 0 and getattr(ix, attr, 0) != 0:
|
|
200
225
|
setattr(log, attr, getattr(ix, attr))
|
|
@@ -204,6 +229,9 @@ def _merge_pumpfun_create(log: Any, ix: Any) -> None:
|
|
|
204
229
|
log.is_cashback_enabled = bool(getattr(log, "is_cashback_enabled", False)) or bool(
|
|
205
230
|
getattr(ix, "is_cashback_enabled", False)
|
|
206
231
|
)
|
|
232
|
+
log.is_holder_reward = bool(getattr(log, "is_holder_reward", False)) or bool(
|
|
233
|
+
getattr(ix, "is_holder_reward", False)
|
|
234
|
+
)
|
|
207
235
|
|
|
208
236
|
|
|
209
237
|
def _merge_pumpfun_create_v2(log: Any, ix: Any) -> None:
|
|
@@ -283,6 +311,20 @@ def _merge_grpc_instruction_into_log(log_ev: DexEvent, ix_ev: DexEvent) -> None:
|
|
|
283
311
|
"coin_creator",
|
|
284
312
|
):
|
|
285
313
|
_fill_attr(log, attr, ix)
|
|
314
|
+
if getattr(log, "creator_fee_bps", 0) == 0 and getattr(ix, "creator_fee_bps", 0) != 0:
|
|
315
|
+
log.creator_fee_bps = ix.creator_fee_bps
|
|
316
|
+
log.is_mayhem_mode = bool(getattr(log, "is_mayhem_mode", False)) or bool(
|
|
317
|
+
getattr(ix, "is_mayhem_mode", False)
|
|
318
|
+
)
|
|
319
|
+
log.is_cashback_coin = bool(getattr(log, "is_cashback_coin", False)) or bool(
|
|
320
|
+
getattr(ix, "is_cashback_coin", False)
|
|
321
|
+
)
|
|
322
|
+
log.can_edit_creator_fee = bool(getattr(log, "can_edit_creator_fee", False)) or bool(
|
|
323
|
+
getattr(ix, "can_edit_creator_fee", False)
|
|
324
|
+
)
|
|
325
|
+
log.is_holder_reward = bool(getattr(log, "is_holder_reward", False)) or bool(
|
|
326
|
+
getattr(ix, "is_holder_reward", False)
|
|
327
|
+
)
|
|
286
328
|
elif (
|
|
287
329
|
log_ev.type == EventType.PUMP_SWAP_LIQUIDITY_ADDED
|
|
288
330
|
and ix_ev.type == EventType.PUMP_SWAP_LIQUIDITY_ADDED
|
|
@@ -312,6 +354,8 @@ def _merge_grpc_instruction_into_log(log_ev: DexEvent, ix_ev: DexEvent) -> None:
|
|
|
312
354
|
"serum_vault_signer",
|
|
313
355
|
"user_source_token_account",
|
|
314
356
|
"user_destination_token_account",
|
|
357
|
+
"user_source_owner",
|
|
358
|
+
"amm",
|
|
315
359
|
):
|
|
316
360
|
_fill_attr(log, attr, ix)
|
|
317
361
|
elif log_ev.type == EventType.RAYDIUM_LAUNCHLAB_POOL_CREATE and ix_ev.type == EventType.RAYDIUM_LAUNCHLAB_POOL_CREATE:
|
|
@@ -329,17 +373,17 @@ def dedupe_log_instruction_events(
|
|
|
329
373
|
) -> List[DexEvent]:
|
|
330
374
|
out: List[DexEvent] = []
|
|
331
375
|
index_by_key: Dict[str, int] = {}
|
|
332
|
-
|
|
333
|
-
|
|
376
|
+
log_occurrences: Dict[OccurrenceBase, int] = {}
|
|
377
|
+
ix_occurrences: Dict[OccurrenceBase, int] = {}
|
|
334
378
|
|
|
335
379
|
for ev in log_events:
|
|
336
|
-
key = _dedupe_key(ev,
|
|
380
|
+
key = _dedupe_key(ev, log_occurrences)
|
|
337
381
|
if key is not None:
|
|
338
382
|
index_by_key[key] = len(out)
|
|
339
383
|
out.append(ev)
|
|
340
384
|
|
|
341
385
|
for ev in instruction_events:
|
|
342
|
-
key = _dedupe_key(ev,
|
|
386
|
+
key = _dedupe_key(ev, ix_occurrences)
|
|
343
387
|
if key is None:
|
|
344
388
|
out.append(ev)
|
|
345
389
|
continue
|