sol-parser-sdk-python 0.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. sol_parser/__init__.py +400 -0
  2. sol_parser/account_dispatcher.py +209 -0
  3. sol_parser/account_fillers/__init__.py +5 -0
  4. sol_parser/account_fillers/bonk.py +30 -0
  5. sol_parser/account_fillers/meteora.py +51 -0
  6. sol_parser/account_fillers/orca.py +40 -0
  7. sol_parser/account_fillers/pumpfun.py +97 -0
  8. sol_parser/account_fillers/pumpswap.py +93 -0
  9. sol_parser/account_fillers/raydium.py +119 -0
  10. sol_parser/accounts/__init__.py +461 -0
  11. sol_parser/accounts/rpc_wallet.py +64 -0
  12. sol_parser/accounts/utils.py +71 -0
  13. sol_parser/check_migration.py +18 -0
  14. sol_parser/clock.py +10 -0
  15. sol_parser/common/__init__.py +27 -0
  16. sol_parser/dex_parsers.py +2576 -0
  17. sol_parser/entries_decode.py +186 -0
  18. sol_parser/env_config.py +215 -0
  19. sol_parser/event_types.py +1750 -0
  20. sol_parser/geyser_pb2.py +148 -0
  21. sol_parser/geyser_pb2_grpc.py +398 -0
  22. sol_parser/grpc/__init__.py +61 -0
  23. sol_parser/grpc/geyser_connect.py +42 -0
  24. sol_parser/grpc/subscribe_builder.py +133 -0
  25. sol_parser/grpc/transaction_meta.py +183 -0
  26. sol_parser/grpc_client.py +870 -0
  27. sol_parser/grpc_instruction_parser.py +318 -0
  28. sol_parser/grpc_types.py +919 -0
  29. sol_parser/inner_instruction_parser.py +281 -0
  30. sol_parser/instr/__init__.py +15 -0
  31. sol_parser/instr_account_utils.py +58 -0
  32. sol_parser/instructions.py +1026 -0
  33. sol_parser/json_util.py +41 -0
  34. sol_parser/log_instr_dedup.py +284 -0
  35. sol_parser/logs/__init__.py +15 -0
  36. sol_parser/merger.py +233 -0
  37. sol_parser/order_buffer.py +171 -0
  38. sol_parser/parser.py +300 -0
  39. sol_parser/pumpfun_fee_enrich.py +75 -0
  40. sol_parser/rpc_parser.py +655 -0
  41. sol_parser/rust_api_inventory.py +42 -0
  42. sol_parser/rust_event_json.py +50 -0
  43. sol_parser/shredstream_client.py +191 -0
  44. sol_parser/shredstream_pb2.py +40 -0
  45. sol_parser/shredstream_pb2_grpc.py +81 -0
  46. sol_parser/shredstream_pumpfun.py +296 -0
  47. sol_parser/solana_storage_pb2.py +75 -0
  48. sol_parser/solana_storage_pb2_grpc.py +24 -0
  49. sol_parser/u128_parity.py +115 -0
  50. sol_parser/verify_discriminators.py +85 -0
  51. sol_parser_sdk_python-0.4.4.dist-info/METADATA +14 -0
  52. sol_parser_sdk_python-0.4.4.dist-info/RECORD +54 -0
  53. sol_parser_sdk_python-0.4.4.dist-info/WHEEL +4 -0
  54. sol_parser_sdk_python-0.4.4.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,75 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: solana-storage.proto
5
+ # Protobuf Python Version: 6.31.0
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 6,
15
+ 31,
16
+ 0,
17
+ '',
18
+ 'solana-storage.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14solana-storage.proto\x12\x1dsolana.storage.ConfirmedBlock\"\xa1\x03\n\x0e\x43onfirmedBlock\x12\x1a\n\x12previous_blockhash\x18\x01 \x01(\t\x12\x11\n\tblockhash\x18\x02 \x01(\t\x12\x13\n\x0bparent_slot\x18\x03 \x01(\x04\x12I\n\x0ctransactions\x18\x04 \x03(\x0b\x32\x33.solana.storage.ConfirmedBlock.ConfirmedTransaction\x12\x36\n\x07rewards\x18\x05 \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12@\n\nblock_time\x18\x06 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UnixTimestamp\x12@\n\x0c\x62lock_height\x18\x07 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.BlockHeight\x12\x44\n\x0enum_partitions\x18\x08 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.NumPartitions\"\x9b\x01\n\x14\x43onfirmedTransaction\x12?\n\x0btransaction\x18\x01 \x01(\x0b\x32*.solana.storage.ConfirmedBlock.Transaction\x12\x42\n\x04meta\x18\x02 \x01(\x0b\x32\x34.solana.storage.ConfirmedBlock.TransactionStatusMeta\"Z\n\x0bTransaction\x12\x12\n\nsignatures\x18\x01 \x03(\x0c\x12\x37\n\x07message\x18\x02 \x01(\x0b\x32&.solana.storage.ConfirmedBlock.Message\"\xad\x02\n\x07Message\x12<\n\x06header\x18\x01 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.MessageHeader\x12\x14\n\x0c\x61\x63\x63ount_keys\x18\x02 \x03(\x0c\x12\x18\n\x10recent_blockhash\x18\x03 \x01(\x0c\x12H\n\x0cinstructions\x18\x04 \x03(\x0b\x32\x32.solana.storage.ConfirmedBlock.CompiledInstruction\x12\x11\n\tversioned\x18\x05 \x01(\x08\x12W\n\x15\x61\x64\x64ress_table_lookups\x18\x06 \x03(\x0b\x32\x38.solana.storage.ConfirmedBlock.MessageAddressTableLookup\"~\n\rMessageHeader\x12\x1f\n\x17num_required_signatures\x18\x01 \x01(\r\x12$\n\x1cnum_readonly_signed_accounts\x18\x02 \x01(\r\x12&\n\x1enum_readonly_unsigned_accounts\x18\x03 \x01(\r\"d\n\x19MessageAddressTableLookup\x12\x13\n\x0b\x61\x63\x63ount_key\x18\x01 \x01(\x0c\x12\x18\n\x10writable_indexes\x18\x02 \x01(\x0c\x12\x18\n\x10readonly_indexes\x18\x03 \x01(\x0c\"\x82\x06\n\x15TransactionStatusMeta\x12<\n\x03\x65rr\x18\x01 \x01(\x0b\x32/.solana.storage.ConfirmedBlock.TransactionError\x12\x0b\n\x03\x66\x65\x65\x18\x02 \x01(\x04\x12\x14\n\x0cpre_balances\x18\x03 \x03(\x04\x12\x15\n\rpost_balances\x18\x04 \x03(\x04\x12L\n\x12inner_instructions\x18\x05 \x03(\x0b\x32\x30.solana.storage.ConfirmedBlock.InnerInstructions\x12\x1f\n\x17inner_instructions_none\x18\n \x01(\x08\x12\x14\n\x0clog_messages\x18\x06 \x03(\t\x12\x19\n\x11log_messages_none\x18\x0b \x01(\x08\x12G\n\x12pre_token_balances\x18\x07 \x03(\x0b\x32+.solana.storage.ConfirmedBlock.TokenBalance\x12H\n\x13post_token_balances\x18\x08 \x03(\x0b\x32+.solana.storage.ConfirmedBlock.TokenBalance\x12\x36\n\x07rewards\x18\t \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12!\n\x19loaded_writable_addresses\x18\x0c \x03(\x0c\x12!\n\x19loaded_readonly_addresses\x18\r \x03(\x0c\x12>\n\x0breturn_data\x18\x0e \x01(\x0b\x32).solana.storage.ConfirmedBlock.ReturnData\x12\x18\n\x10return_data_none\x18\x0f \x01(\x08\x12#\n\x16\x63ompute_units_consumed\x18\x10 \x01(\x04H\x00\x88\x01\x01\x12\x17\n\ncost_units\x18\x11 \x01(\x04H\x01\x88\x01\x01\x42\x19\n\x17_compute_units_consumedB\r\n\x0b_cost_units\"\x1f\n\x10TransactionError\x12\x0b\n\x03\x65rr\x18\x01 \x01(\x0c\"i\n\x11InnerInstructions\x12\r\n\x05index\x18\x01 \x01(\r\x12\x45\n\x0cinstructions\x18\x02 \x03(\x0b\x32/.solana.storage.ConfirmedBlock.InnerInstruction\"x\n\x10InnerInstruction\x12\x18\n\x10program_id_index\x18\x01 \x01(\r\x12\x10\n\x08\x61\x63\x63ounts\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\x12\x19\n\x0cstack_height\x18\x04 \x01(\rH\x00\x88\x01\x01\x42\x0f\n\r_stack_height\"O\n\x13\x43ompiledInstruction\x12\x18\n\x10program_id_index\x18\x01 \x01(\r\x12\x10\n\x08\x61\x63\x63ounts\x18\x02 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\x9d\x01\n\x0cTokenBalance\x12\x15\n\raccount_index\x18\x01 \x01(\r\x12\x0c\n\x04mint\x18\x02 \x01(\t\x12\x45\n\x0fui_token_amount\x18\x03 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.UiTokenAmount\x12\r\n\x05owner\x18\x04 \x01(\t\x12\x12\n\nprogram_id\x18\x05 \x01(\t\"^\n\rUiTokenAmount\x12\x11\n\tui_amount\x18\x01 \x01(\x01\x12\x10\n\x08\x64\x65\x63imals\x18\x02 \x01(\r\x12\x0e\n\x06\x61mount\x18\x03 \x01(\t\x12\x18\n\x10ui_amount_string\x18\x04 \x01(\t\".\n\nReturnData\x12\x12\n\nprogram_id\x18\x01 \x01(\x0c\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x94\x01\n\x06Reward\x12\x0e\n\x06pubkey\x18\x01 \x01(\t\x12\x10\n\x08lamports\x18\x02 \x01(\x03\x12\x14\n\x0cpost_balance\x18\x03 \x01(\x04\x12>\n\x0breward_type\x18\x04 \x01(\x0e\x32).solana.storage.ConfirmedBlock.RewardType\x12\x12\n\ncommission\x18\x05 \x01(\t\"\x87\x01\n\x07Rewards\x12\x36\n\x07rewards\x18\x01 \x03(\x0b\x32%.solana.storage.ConfirmedBlock.Reward\x12\x44\n\x0enum_partitions\x18\x02 \x01(\x0b\x32,.solana.storage.ConfirmedBlock.NumPartitions\"\"\n\rUnixTimestamp\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\"#\n\x0b\x42lockHeight\x12\x14\n\x0c\x62lock_height\x18\x01 \x01(\x04\"\'\n\rNumPartitions\x12\x16\n\x0enum_partitions\x18\x01 \x01(\x04*I\n\nRewardType\x12\x0f\n\x0bUnspecified\x10\x00\x12\x07\n\x03\x46\x65\x65\x10\x01\x12\x08\n\x04Rent\x10\x02\x12\x0b\n\x07Staking\x10\x03\x12\n\n\x06Voting\x10\x04\x42;Z9github.com/rpcpool/yellowstone-grpc/examples/golang/protob\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'solana_storage_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ _globals['DESCRIPTOR']._loaded_options = None
34
+ _globals['DESCRIPTOR']._serialized_options = b'Z9github.com/rpcpool/yellowstone-grpc/examples/golang/proto'
35
+ _globals['_REWARDTYPE']._serialized_start=3082
36
+ _globals['_REWARDTYPE']._serialized_end=3155
37
+ _globals['_CONFIRMEDBLOCK']._serialized_start=56
38
+ _globals['_CONFIRMEDBLOCK']._serialized_end=473
39
+ _globals['_CONFIRMEDTRANSACTION']._serialized_start=476
40
+ _globals['_CONFIRMEDTRANSACTION']._serialized_end=631
41
+ _globals['_TRANSACTION']._serialized_start=633
42
+ _globals['_TRANSACTION']._serialized_end=723
43
+ _globals['_MESSAGE']._serialized_start=726
44
+ _globals['_MESSAGE']._serialized_end=1027
45
+ _globals['_MESSAGEHEADER']._serialized_start=1029
46
+ _globals['_MESSAGEHEADER']._serialized_end=1155
47
+ _globals['_MESSAGEADDRESSTABLELOOKUP']._serialized_start=1157
48
+ _globals['_MESSAGEADDRESSTABLELOOKUP']._serialized_end=1257
49
+ _globals['_TRANSACTIONSTATUSMETA']._serialized_start=1260
50
+ _globals['_TRANSACTIONSTATUSMETA']._serialized_end=2030
51
+ _globals['_TRANSACTIONERROR']._serialized_start=2032
52
+ _globals['_TRANSACTIONERROR']._serialized_end=2063
53
+ _globals['_INNERINSTRUCTIONS']._serialized_start=2065
54
+ _globals['_INNERINSTRUCTIONS']._serialized_end=2170
55
+ _globals['_INNERINSTRUCTION']._serialized_start=2172
56
+ _globals['_INNERINSTRUCTION']._serialized_end=2292
57
+ _globals['_COMPILEDINSTRUCTION']._serialized_start=2294
58
+ _globals['_COMPILEDINSTRUCTION']._serialized_end=2373
59
+ _globals['_TOKENBALANCE']._serialized_start=2376
60
+ _globals['_TOKENBALANCE']._serialized_end=2533
61
+ _globals['_UITOKENAMOUNT']._serialized_start=2535
62
+ _globals['_UITOKENAMOUNT']._serialized_end=2629
63
+ _globals['_RETURNDATA']._serialized_start=2631
64
+ _globals['_RETURNDATA']._serialized_end=2677
65
+ _globals['_REWARD']._serialized_start=2680
66
+ _globals['_REWARD']._serialized_end=2828
67
+ _globals['_REWARDS']._serialized_start=2831
68
+ _globals['_REWARDS']._serialized_end=2966
69
+ _globals['_UNIXTIMESTAMP']._serialized_start=2968
70
+ _globals['_UNIXTIMESTAMP']._serialized_end=3002
71
+ _globals['_BLOCKHEIGHT']._serialized_start=3004
72
+ _globals['_BLOCKHEIGHT']._serialized_end=3039
73
+ _globals['_NUMPARTITIONS']._serialized_start=3041
74
+ _globals['_NUMPARTITIONS']._serialized_end=3080
75
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,24 @@
1
+ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2
+ """Client and server classes corresponding to protobuf-defined services."""
3
+ import grpc
4
+ import warnings
5
+
6
+
7
+ GRPC_GENERATED_VERSION = '1.73.1'
8
+ GRPC_VERSION = grpc.__version__
9
+ _version_not_supported = False
10
+
11
+ try:
12
+ from grpc._utilities import first_version_is_lower
13
+ _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
14
+ except ImportError:
15
+ _version_not_supported = True
16
+
17
+ if _version_not_supported:
18
+ raise RuntimeError(
19
+ f'The grpc package installed is at version {GRPC_VERSION},'
20
+ + f' but the generated code in solana_storage_pb2_grpc.py depends on'
21
+ + f' grpcio>={GRPC_GENERATED_VERSION}.'
22
+ + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
23
+ + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
24
+ )
@@ -0,0 +1,115 @@
1
+ """u128 小端十进制字符串与 Go `u128LEDecimalString` 语义一致性的自检(不依赖 Go 运行时)。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import struct
6
+ import sys
7
+
8
+ from .dex_parsers import (
9
+ DLMM_SWAP,
10
+ _u128le_int,
11
+ parse_dlmm_from_program_data,
12
+ parse_orca_traded_from_data,
13
+ )
14
+ from .event_types import MeteoraDlmmSwapEvent, OrcaWhirlpoolSwapEvent
15
+
16
+
17
+ def verify_u128_le_decimal() -> int:
18
+ """断言 `_u128le_int` → `str` 与无符号 128 位小端整数值一致。"""
19
+ cases = [
20
+ 0,
21
+ 1,
22
+ 255,
23
+ 256,
24
+ 10**18,
25
+ 2**64 - 1,
26
+ 2**127 - 1,
27
+ 2**128 - 1,
28
+ ]
29
+ buf = bytearray(32)
30
+ for n in cases:
31
+ le = n.to_bytes(16, "little")
32
+ buf[:16] = le
33
+ got = str(_u128le_int(bytes(buf), 0))
34
+ if got != str(n):
35
+ print(
36
+ f"[u128-parity] 失败: 期望十进制 {n!s}, 得到 {got!s}",
37
+ file=sys.stderr,
38
+ )
39
+ return 1
40
+ print("[u128-parity] OK:小端 u128 十进制与 Go u128LEDecimalString 一致")
41
+ return 0
42
+
43
+
44
+ def verify_orca_swap_sqrt_decimal_strings() -> int:
45
+ """合成 OrcaWhirlpoolSwap 载荷,确认 `pre_sqrt_price` / `post_sqrt_price` 为十进制字符串。"""
46
+ meta = {
47
+ "signature": "",
48
+ "slot": 0,
49
+ "tx_index": 0,
50
+ "block_time_us": 0,
51
+ "grpc_recv_us": 0,
52
+ }
53
+ whirlpool = bytes(32)
54
+ pre = (1000).to_bytes(16, "little")
55
+ post = (2000).to_bytes(16, "little")
56
+ tail = b"".join((0).to_bytes(8, "little") for _ in range(6))
57
+ data = whirlpool + b"\x00" + pre + post + tail
58
+ ev = parse_orca_traded_from_data(data, meta)
59
+ if ev is None or not isinstance(ev.data, OrcaWhirlpoolSwapEvent):
60
+ print("[u128-parity] Orca 合成载荷解析失败", file=sys.stderr)
61
+ return 1
62
+ inner = ev.data
63
+ if inner.pre_sqrt_price != "1000" or inner.post_sqrt_price != "2000":
64
+ print(f"[u128-parity] Orca sqrt 字段不符: {inner!r}", file=sys.stderr)
65
+ return 1
66
+ print("[u128-parity] OK:OrcaWhirlpoolSwap u128 字段为十进制字符串")
67
+ return 0
68
+
69
+
70
+ def verify_dlmm_swap_fee_bps_decimal_string() -> int:
71
+ """合成 MeteoraDlmmSwap 载荷,确认 `fee_bps` 为十进制字符串。"""
72
+ meta = {
73
+ "signature": "",
74
+ "slot": 0,
75
+ "tx_index": 0,
76
+ "block_time_us": 0,
77
+ "grpc_recv_us": 0,
78
+ }
79
+ fee_bps_val = 4242
80
+ data = (
81
+ bytes(64)
82
+ + struct.pack("<ii", 0, 0)
83
+ + struct.pack("<QQ", 0, 0)
84
+ + b"\x00"
85
+ + struct.pack("<QQ", 0, 0)
86
+ + fee_bps_val.to_bytes(16, "little")
87
+ + struct.pack("<Q", 0)
88
+ )
89
+ buf = struct.pack("<Q", DLMM_SWAP) + data
90
+ ev = parse_dlmm_from_program_data(buf, meta)
91
+ if ev is None or not isinstance(ev.data, MeteoraDlmmSwapEvent):
92
+ print("[u128-parity] DLMM 合成载荷解析失败", file=sys.stderr)
93
+ return 1
94
+ inner = ev.data
95
+ if inner.fee_bps != str(fee_bps_val):
96
+ print(f"[u128-parity] DLMM fee_bps 不符: {inner!r}", file=sys.stderr)
97
+ return 1
98
+ print("[u128-parity] OK:MeteoraDlmmSwap fee_bps 为十进制字符串")
99
+ return 0
100
+
101
+
102
+ def run_all_u128_checks() -> int:
103
+ if verify_u128_le_decimal() != 0:
104
+ return 1
105
+ if verify_orca_swap_sqrt_decimal_strings() != 0:
106
+ return 1
107
+ return verify_dlmm_swap_fee_bps_decimal_string()
108
+
109
+
110
+ def main() -> None:
111
+ sys.exit(run_all_u128_checks())
112
+
113
+
114
+ if __name__ == "__main__":
115
+ main()
@@ -0,0 +1,85 @@
1
+ """
2
+ 校验本包 `dex_parsers.dispatch_program_data` 与 Go matcher 是否覆盖
3
+ Node/TS 快照 `scripts/program-log-discriminators.json` 中的字节序列。
4
+
5
+ 用法(在仓库内任意目录均可,依赖 `__file__` 定位)::
6
+
7
+ python3 -m sol_parser.verify_discriminators
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ import sys
14
+ from pathlib import Path
15
+
16
+
17
+ def _repo_root() -> Path:
18
+ # sol-parser-sdk-python/sol_parser/verify_discriminators.py -> parents[2] = monorepo root
19
+ return Path(__file__).resolve().parents[2]
20
+
21
+
22
+ def _comma_seq(arr: list[int]) -> str:
23
+ return ", ".join(str(b) for b in arr)
24
+
25
+
26
+ def main() -> int:
27
+ root = _repo_root()
28
+ snap_candidates = [
29
+ root / "sol-parser-sdk-nodejs/scripts/program-log-discriminators.json",
30
+ root / "sol-parser-sdk-ts/scripts/program-log-discriminators.json",
31
+ ]
32
+ snap_path = next((p for p in snap_candidates if p.is_file()), None)
33
+ py_path = root / "sol-parser-sdk-python/sol_parser/dex_parsers.py"
34
+ go_dir = root / "sol-parser-sdk-golang/solparser"
35
+
36
+ if snap_path is None:
37
+ joined = ", ".join(str(p) for p in snap_candidates)
38
+ print(f"[verify-discriminators] 缺少快照,已检查: {joined}", file=sys.stderr)
39
+ return 1
40
+ if not py_path.is_file():
41
+ print(f"[verify-discriminators] 缺少: {py_path}", file=sys.stderr)
42
+ return 1
43
+ if not go_dir.is_dir():
44
+ print(f"[verify-discriminators] 缺少: {go_dir}", file=sys.stderr)
45
+ return 1
46
+
47
+ snap = json.loads(snap_path.read_text(encoding="utf-8"))
48
+ py_text = py_path.read_text(encoding="utf-8")
49
+ go_parts = [p.read_text(encoding="utf-8") for p in sorted(go_dir.glob("*.go"))]
50
+ go_text = "\n".join(go_parts)
51
+
52
+ entries: dict[str, list[int]] = {}
53
+ for block in ("PROGRAM_LOG_DISC", "PUMPSWAP_DISC"):
54
+ for k, arr in snap[block].items():
55
+ if not isinstance(arr, list) or len(arr) != 8:
56
+ print(f"[verify-discriminators] {block}.{k} 须为长度 8 的数组", file=sys.stderr)
57
+ return 1
58
+ entries[f"{block}.{k}"] = [int(x) for x in arr]
59
+
60
+ failed = False
61
+ for label, arr in sorted(entries.items()):
62
+ seq = _comma_seq(arr)
63
+ if seq not in py_text:
64
+ print(f"[verify-discriminators] Python dex_parsers 未出现字节序列: {label} [{seq}]", file=sys.stderr)
65
+ failed = True
66
+ if seq not in go_text:
67
+ print(f"[verify-discriminators] Go solparser 未出现字节序列: {label} [{seq}]", file=sys.stderr)
68
+ failed = True
69
+
70
+ if failed:
71
+ print(
72
+ "[verify-discriminators] 请同步 Node/TS scripts/program-log-discriminators.json、"
73
+ "Go matcher 与 Python dex_parsers。",
74
+ file=sys.stderr,
75
+ )
76
+ return 1
77
+
78
+ print(
79
+ f"[verify-discriminators] OK:{len(entries)} 条字节序列在 Python dex_parsers 与 Go solparser 中均可找到"
80
+ )
81
+ return 0
82
+
83
+
84
+ if __name__ == "__main__":
85
+ raise SystemExit(main())
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: sol-parser-sdk-python
3
+ Version: 0.4.4
4
+ Summary: Solana DEX program log parsing (pure Python, API aligned with sol-parser-sdk)
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: base58>=2.0
7
+ Requires-Dist: grpcio-tools>=1.64.0
8
+ Requires-Dist: grpcio>=1.64.0
9
+ Requires-Dist: python-dotenv>=1.0.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest-benchmark>=4.0; extra == 'dev'
12
+ Requires-Dist: pytest>=8.0; extra == 'dev'
13
+ Provides-Extra: shredstream
14
+ Requires-Dist: solders>=0.21.0; extra == 'shredstream'
@@ -0,0 +1,54 @@
1
+ sol_parser/__init__.py,sha256=eJ7E4UG5ImAkLFQWRwyYl2BxiEsH5N_7k4cJj_yP078,12209
2
+ sol_parser/account_dispatcher.py,sha256=QnsCRb0IH3qn-c_Zm9sMVv5rCnaouVNgjpG40UZNXcc,9678
3
+ sol_parser/check_migration.py,sha256=hW2qb-EVVoqBUTH3ARhEkSvP9aHcNEkg3ket7lfMVzQ,415
4
+ sol_parser/clock.py,sha256=RHF99qMerKvEsT55krkftIh-uqy_uTzpgdKCqKBMDmA,278
5
+ sol_parser/dex_parsers.py,sha256=xHrkrq4L7rYH8XEX_2p1WMGO8upzZFL3rtQgweAWGuU,74314
6
+ sol_parser/entries_decode.py,sha256=-eooIYrXOcpNtrSgSEVehY8NkBhwUMnziAR5Wx8S0Nk,5620
7
+ sol_parser/env_config.py,sha256=Lw0SdZuy_MvUaVkyFxS0qPBgMzR9UBbxbN0CVz8nxg4,7296
8
+ sol_parser/event_types.py,sha256=UmEaZ_w2PM3FvHTK4vIhAgGM-shKSp4wFU80mdxY7yk,60872
9
+ sol_parser/geyser_pb2.py,sha256=Hq66wmWxXD2jSbSVQW7vmBRB7nWmR1DuYDMQ6nKgl3o,20123
10
+ sol_parser/geyser_pb2_grpc.py,sha256=ASPmZsCNvyCzt_j4IrhKjSacWUNLVuAiLfpjmyd-2Qc,15322
11
+ sol_parser/grpc_client.py,sha256=eVa_R3jnqOSA-yp9LCkjXFHboDDV2Yyc8p3WhPkmZdo,31215
12
+ sol_parser/grpc_instruction_parser.py,sha256=Fz01WbHbfAMFSpfIu935qgJBg-dmHX2RLBaTM-67svo,11016
13
+ sol_parser/grpc_types.py,sha256=6EKVJHnGPrVQrIPVPVLN7FWiqWbRpqNKGlmEe7wNePI,29975
14
+ sol_parser/inner_instruction_parser.py,sha256=M6Rh6S2IIphyn1_GiTEKYCTnxVQPonk_q_4hwZOwy74,11161
15
+ sol_parser/instr_account_utils.py,sha256=MY8bgoIDiv2yJKeWxqhpfKc3pV4xUFTcYKnSXtnQMWc,1990
16
+ sol_parser/instructions.py,sha256=jiG81vaKgVYYLHr2fDSl6lgoNiSDZK4KZf3Lejw4sKo,37697
17
+ sol_parser/json_util.py,sha256=qq0A5bs-HxxQH6vgg1Kja4tQ8cPaop9uItBcW7Ajox4,1458
18
+ sol_parser/log_instr_dedup.py,sha256=g9nqcMFw8eGjib3eHSOsBlRUu6LszOisJiBfq4j0cdc,10216
19
+ sol_parser/merger.py,sha256=xe-ohG-UBwByIGr-Dr8HRbJRSysvV_UHls13RZoyW2k,9102
20
+ sol_parser/order_buffer.py,sha256=xW-Okii8a9t9tCqbBKtxFh1moTEi7RqycMFO2kwp-d4,6447
21
+ sol_parser/parser.py,sha256=aueK1XF6BMcxhXiw2aPQn_9ohWpVhXaimh9t9AMzq0A,8215
22
+ sol_parser/pumpfun_fee_enrich.py,sha256=rVP5INqafa7u9Z7bM9VbHo0XALuASkIS1FEwn9kniOk,2619
23
+ sol_parser/rpc_parser.py,sha256=cFtMH2DD2ZZVPbq2j4SpCK3cV6_ZdxwFUlht6Zg4tB0,21229
24
+ sol_parser/rust_api_inventory.py,sha256=V5Bx1M3GT-ku_vj_kD6lnbqWExv1K_A00PrmhCFfRec,2257
25
+ sol_parser/rust_event_json.py,sha256=7hho9TGfSOQjHev_8uRa4YHU1hrEsW1RfwcU9qHYz1o,1649
26
+ sol_parser/shredstream_client.py,sha256=xU7MoKzGRSlNPtRbKgGkVWIUMR-xR52KtSe61Un6kqo,6949
27
+ sol_parser/shredstream_pb2.py,sha256=BMrgCTcvRu5sY_QG1nj5AhWK9RL1fqF9Ga0xYihQfio,1703
28
+ sol_parser/shredstream_pb2_grpc.py,sha256=zfRJaDj-76Gbr6tC3x4gFOz6Xpu2fmJFWWcTOTmyIXs,3013
29
+ sol_parser/shredstream_pumpfun.py,sha256=0QsEUqBqKSpM-yiTZYNxCypiFU25l-6XXzYZVid5N4I,9934
30
+ sol_parser/solana_storage_pb2.py,sha256=_mi8CkHCzIc85DZKjI4dApJdEGmLsoNemSrGY2f9m8k,8443
31
+ sol_parser/solana_storage_pb2_grpc.py,sha256=-Gys-K2Kw5Uy3JjtgIXmaYE6YKnXd5ZfBaMHTYQeycA,895
32
+ sol_parser/u128_parity.py,sha256=D8PYuy1l-1QwkIEeGCLvrGfzAfTzpBDcGINxRIJAEPs,3487
33
+ sol_parser/verify_discriminators.py,sha256=oqCBWL065ixBIjhHW255nk4S-F1F0x4zfTzs68nXMqA,3011
34
+ sol_parser/account_fillers/__init__.py,sha256=XNS5Yu-YId17qVPcwHnvg92JuwwDZIfUs_iVEtlC8XM,209
35
+ sol_parser/account_fillers/bonk.py,sha256=HSl2UHn0GH7EymCNgylRqd0zISdTqv9_ZxoVL-hcVBY,708
36
+ sol_parser/account_fillers/meteora.py,sha256=seS80dMIeFE-E0Kd2U50p09w69wDi4sf4UxWFl-WP8U,1159
37
+ sol_parser/account_fillers/orca.py,sha256=2s-hfi20fa5sy6p1rGc7_7NxzkpaleJdqn3YD41aBAw,895
38
+ sol_parser/account_fillers/pumpfun.py,sha256=bB89cWs6ZJlMECyIsjc9I3BTPPPN3_wMfz4SCmznT0E,2881
39
+ sol_parser/account_fillers/pumpswap.py,sha256=76KVjXI7hsOqZazJnB-ytqMq38e63gp0-3IiwvC_LAc,2722
40
+ sol_parser/account_fillers/raydium.py,sha256=j5vNSKAV-8bJuakG2dicc8ao5I-ZD2TEthLM6ooZqQ4,3350
41
+ sol_parser/accounts/__init__.py,sha256=BU2mQgF6IqL56KTob31XZmjAYMAaTDRWIOFptLFihCc,15387
42
+ sol_parser/accounts/rpc_wallet.py,sha256=IT0WEzna9phG7AzhJR8o4GA_BlB4ZvhuDWfCHQcMXwg,1944
43
+ sol_parser/accounts/utils.py,sha256=BAACAIvA2Uz0U26BpYPTalTqiuarXYhkbS-i2o1uJUY,2140
44
+ sol_parser/common/__init__.py,sha256=bAdNd5lDj8CBXKuoIUHzdqUw0zmhBeCGCEH7fZuj_1w,761
45
+ sol_parser/grpc/__init__.py,sha256=1tyV7rLRVs-o_3SKaT1tbdUu5JByJKW0t8bievC6guQ,1796
46
+ sol_parser/grpc/geyser_connect.py,sha256=vgrY-UI75Y7U-Ei6vpwAYkCvKXRfmHN5FQtZSlF8RvA,1474
47
+ sol_parser/grpc/subscribe_builder.py,sha256=fv6_jQAR6Q0seUhXjgcDPnPsG03Bxs59lHGetExBRLI,4383
48
+ sol_parser/grpc/transaction_meta.py,sha256=NmIffIQ1_OIfWGjy6JY-f8pIK5ucjDZXXJryjnlgoQs,5894
49
+ sol_parser/instr/__init__.py,sha256=i4HlMIWmEZu60rDcJnzWxHu30W2M3fGWorHgv-MOpEg,353
50
+ sol_parser/logs/__init__.py,sha256=e1cbhbCNeXy-NZvVsYCpGksBpZf4NJBLmdlky06og-U,349
51
+ sol_parser_sdk_python-0.4.4.dist-info/METADATA,sha256=HNqsrb7yHHaf2m7uEOpgXYbfI-3efwCxJgePTJEsqhg,504
52
+ sol_parser_sdk_python-0.4.4.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
53
+ sol_parser_sdk_python-0.4.4.dist-info/entry_points.txt,sha256=ZGXRb-2jBdc56d8PCAZFiJBLTAzUKFeHPohysJnKVbA,206
54
+ sol_parser_sdk_python-0.4.4.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ sol-parser-check-migration = sol_parser.check_migration:main
3
+ sol-parser-verify-u128 = sol_parser.u128_parity:main
4
+ verify-program-log-discriminators = sol_parser.verify_discriminators:main