helius-python 0.3.2__tar.gz → 0.3.4__tar.gz

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 (46) hide show
  1. {helius_python-0.3.2 → helius_python-0.3.4}/AGENTS.md +1 -12
  2. {helius_python-0.3.2 → helius_python-0.3.4}/PKG-INFO +4 -1
  3. {helius_python-0.3.2 → helius_python-0.3.4}/README.md +2 -0
  4. helius_python-0.3.4/TODO.md +4 -0
  5. helius_python-0.3.4/examples/README.md +4 -0
  6. helius_python-0.3.4/examples/laserstream/websocket_logs.py +76 -0
  7. helius_python-0.3.4/examples/solana_rpc/address_transactions.py +125 -0
  8. helius_python-0.3.4/examples/solana_rpc/address_transfers.py +118 -0
  9. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/block_explorer.py +4 -3
  10. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/devnet_airdrop.py +26 -4
  11. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/network_status.py +1 -1
  12. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/priority_fees.py +2 -2
  13. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/stake_overview.py +5 -2
  14. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/token_inspector.py +12 -5
  15. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/transaction_inspector.py +2 -2
  16. {helius_python-0.3.2/examples → helius_python-0.3.4/examples/solana_rpc}/wallet_tracker.py +4 -4
  17. {helius_python-0.3.2 → helius_python-0.3.4}/pyproject.toml +2 -1
  18. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/laserstream/websockets.py +2 -1
  19. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/solana_rpc/client.py +85 -0
  20. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/solana_rpc/models.py +98 -0
  21. helius_python-0.3.4/test_examples.py +216 -0
  22. {helius_python-0.3.2 → helius_python-0.3.4}/tests/unit/solana_rpc/test_client.py +333 -0
  23. helius_python-0.3.2/TODO.md +0 -3
  24. {helius_python-0.3.2 → helius_python-0.3.4}/.editorconfig +0 -0
  25. {helius_python-0.3.2 → helius_python-0.3.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  26. {helius_python-0.3.2 → helius_python-0.3.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {helius_python-0.3.2 → helius_python-0.3.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  28. {helius_python-0.3.2 → helius_python-0.3.4}/.github/workflows/python-package.yml +0 -0
  29. {helius_python-0.3.2 → helius_python-0.3.4}/.github/workflows/python-publish.yml +0 -0
  30. {helius_python-0.3.2 → helius_python-0.3.4}/.gitignore +0 -0
  31. {helius_python-0.3.2 → helius_python-0.3.4}/CLAUDE.md +0 -0
  32. {helius_python-0.3.2 → helius_python-0.3.4}/CONTRIBUTING.md +0 -0
  33. {helius_python-0.3.2 → helius_python-0.3.4}/LICENSE +0 -0
  34. {helius_python-0.3.2 → helius_python-0.3.4}/requirements.txt +0 -0
  35. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/__init__.py +0 -0
  36. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/admin/__init__.py +0 -0
  37. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/admin/admin.py +0 -0
  38. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/rpc/__init__.py +0 -0
  39. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/rpc/json_rpc_request.py +0 -0
  40. {helius_python-0.3.2 → helius_python-0.3.4}/src/helius/solana_rpc/__init__.py +0 -0
  41. {helius_python-0.3.2 → helius_python-0.3.4}/tests/fixtures/account.json +0 -0
  42. {helius_python-0.3.2 → helius_python-0.3.4}/tests/fixtures/supply.json +0 -0
  43. {helius_python-0.3.2 → helius_python-0.3.4}/tests/unit/admin/test_admin.py +0 -0
  44. {helius_python-0.3.2 → helius_python-0.3.4}/tests/unit/lasterstream/test_websockets.py +0 -0
  45. {helius_python-0.3.2 → helius_python-0.3.4}/tests/unit/rpc/test_json_rpc_request.py +0 -0
  46. {helius_python-0.3.2 → helius_python-0.3.4}/tests/unit/solana_rpc/test_models.py +0 -0
@@ -1,14 +1,3 @@
1
-
2
- ## Conventions
3
-
4
- - Use **double-quoted triple strings** (`"""..."""`).
5
- - Wrap docstring lines at 88 columns.
6
- - Refer to parameters in backticks: `` `commitment` ``, `` `min_context_slot` ``.
7
- - Refer to other client methods with their snake_case name in backticks: `` `get_balance` ``.
8
- - Do NOT include the upstream JSON-RPC method name in the summary — that's already in the See Also URLs.
9
- - Do NOT copy-paste large chunks from the Helius docs. Summarize and link.
10
- - Examples (`Example:` section) are encouraged for methods with non-trivial argument combinations (e.g. `get_block_production`, `get_token_accounts_by_owner`), optional for everything else.
11
-
12
1
  ## Implementation conventions
13
2
 
14
3
  - **If the RPC returns an `RpcResponse` wrapper (`{context, value}`), the Python method MUST return `(context, value)`** — never silently drop `context`. For methods whose `value` is itself a small composite, flatten the tuple (e.g. `get_latest_blockhash` returns `tuple[dict, str, int]`, not `tuple[dict, tuple[str, int]]`). Check the upstream Helius API reference page to see whether the response is wrapped.
@@ -124,7 +113,7 @@ For methods with branching logic (e.g. `get_block_production`, `get_token_accoun
124
113
  ## Running
125
114
 
126
115
  ```bash
127
- pytest
116
+ .venv/bin/pytest
128
117
  ```
129
118
 
130
119
  All tests must pass and there must be no real network traffic. If a test fails because it tried to hit the network, that's a bug in the test — add the missing `@respx.mock` or `respx` route.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: helius-python
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Typed Python client for the Helius API
5
5
  Project-URL: Homepage, https://github.com/markosnarinian/helius-python
6
6
  Project-URL: Issues, https://github.com/markosnarinian/helius-python/issues
@@ -13,6 +13,7 @@ Requires-Python: >=3.10
13
13
  Requires-Dist: httpx
14
14
  Requires-Dist: pydantic
15
15
  Requires-Dist: python-dotenv
16
+ Requires-Dist: typing-extensions
16
17
  Requires-Dist: websockets
17
18
  Provides-Extra: dev
18
19
  Requires-Dist: pytest; extra == 'dev'
@@ -322,6 +323,8 @@ continuously.
322
323
  | `minimumLedgerSlot` | `minimum_ledger_slot()` | [guide](https://www.helius.dev/docs/rpc/guides/minimumledgerslot), [reference](https://www.helius.dev/docs/api-reference/rpc/http/minimumledgerslot) |
323
324
  | `requestAirdrop` | `request_airdrop(...)` | [guide](https://www.helius.dev/docs/rpc/guides/requestairdrop), [reference](https://www.helius.dev/docs/api-reference/rpc/http/requestairdrop) |
324
325
  | `sendTransaction` | `send_transaction(...)` | [guide](https://www.helius.dev/docs/rpc/guides/sendtransaction), [reference](https://www.helius.dev/docs/api-reference/rpc/http/sendtransaction) |
326
+ | `getTransactionsForAddress` | `get_transactions_for_address(...)` | [reference](https://www.helius.dev/docs/api-reference/rpc/http/gettransactionsforaddress) |
327
+ | `getTransfersByAddress` | `get_transfers_by_address(...)` | [guide](https://www.helius.dev/docs/rpc/gettransfersbyaddress), [reference](https://www.helius.dev/docs/api-reference/rpc/http/gettransfersbyaddress) |
325
328
 
326
329
  ## WebSocket subscriptions
327
330
 
@@ -301,6 +301,8 @@ continuously.
301
301
  | `minimumLedgerSlot` | `minimum_ledger_slot()` | [guide](https://www.helius.dev/docs/rpc/guides/minimumledgerslot), [reference](https://www.helius.dev/docs/api-reference/rpc/http/minimumledgerslot) |
302
302
  | `requestAirdrop` | `request_airdrop(...)` | [guide](https://www.helius.dev/docs/rpc/guides/requestairdrop), [reference](https://www.helius.dev/docs/api-reference/rpc/http/requestairdrop) |
303
303
  | `sendTransaction` | `send_transaction(...)` | [guide](https://www.helius.dev/docs/rpc/guides/sendtransaction), [reference](https://www.helius.dev/docs/api-reference/rpc/http/sendtransaction) |
304
+ | `getTransactionsForAddress` | `get_transactions_for_address(...)` | [reference](https://www.helius.dev/docs/api-reference/rpc/http/gettransactionsforaddress) |
305
+ | `getTransfersByAddress` | `get_transfers_by_address(...)` | [guide](https://www.helius.dev/docs/rpc/gettransfersbyaddress), [reference](https://www.helius.dev/docs/api-reference/rpc/http/gettransfersbyaddress) |
304
306
 
305
307
  ## WebSocket subscriptions
306
308
 
@@ -0,0 +1,4 @@
1
+ - Mangling __
2
+ - WebSocket subscription manager
3
+ - Use typeddicts where useful
4
+ - When Python 3.10 and 3.11 go out of support we should use TypedDict from typing instead of typing_extensions
@@ -0,0 +1,4 @@
1
+ # Examples
2
+
3
+ Examples can be found under the `examples` directory
4
+ Please note that all examples are AI-generated and not thoroughly reviewed.
@@ -0,0 +1,76 @@
1
+ """Listen for Solana log notifications over Helius WebSockets.
2
+
3
+ Subscribes with `logsSubscribe`, prints a small number of notifications,
4
+ then unsubscribes cleanly. Use `--mentions <ADDRESS>` to filter logs to a
5
+ single account or program; otherwise the example listens to all logs.
6
+
7
+ Usage:
8
+
9
+ export HELIUS_API_KEY=your_helius_api_key
10
+ python examples/laserstream/websocket_logs.py --mentions <ADDRESS>
11
+ python examples/laserstream/websocket_logs.py --count 3
12
+
13
+ Docs:
14
+ https://www.helius.dev/docs/api-reference/rpc/websocket/logssubscribe
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import argparse
20
+ from contextlib import suppress
21
+ import sys
22
+
23
+ from helius.laserstream.websockets import WebSocketClient
24
+
25
+
26
+ def main() -> int:
27
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
28
+ parser.add_argument(
29
+ "--mentions",
30
+ help="Only receive logs mentioning this account or program address",
31
+ )
32
+ parser.add_argument(
33
+ "--count",
34
+ type=int,
35
+ default=5,
36
+ help="Number of notifications to print before exiting (default 5)",
37
+ )
38
+ args = parser.parse_args()
39
+
40
+ log_filter = {"mentions": [args.mentions]} if args.mentions else "all"
41
+
42
+ with WebSocketClient() as client:
43
+ subscription = client.logs_subscribe(
44
+ filter=log_filter,
45
+ commitment="confirmed",
46
+ )
47
+ print(f"Subscribed to logs with id {subscription}. Waiting...\n")
48
+
49
+ try:
50
+ for index, (context, notification, _subscription) in enumerate(
51
+ client.listen(), start=1
52
+ ):
53
+ slot = context.get("slot") if context else "unknown"
54
+ status = "ERR" if notification.err else "OK "
55
+ print(f"[{index}/{args.count}] slot={slot} {status} {notification.signature}")
56
+ for line in notification.logs[:5]:
57
+ print(f" {line}")
58
+ if len(notification.logs) > 5:
59
+ print(f" ... {len(notification.logs) - 5} more log lines")
60
+ print()
61
+ if index >= args.count:
62
+ break
63
+ finally:
64
+ # A busy `logsSubscribe` stream can deliver another notification
65
+ # between our unsubscribe request and the unsubscribe response. The
66
+ # client helper currently expects the very next frame to be the RPC
67
+ # response, so ignore that race here and let the context manager
68
+ # close the socket cleanly.
69
+ with suppress(KeyError):
70
+ client.logs_unsubscribe(subscription)
71
+
72
+ return 0
73
+
74
+
75
+ if __name__ == "__main__":
76
+ sys.exit(main())
@@ -0,0 +1,125 @@
1
+ """List Helius enhanced transactions for an address.
2
+
3
+ Uses Helius's `getTransactionsForAddress` RPC method, which can return
4
+ either compact signature rows or full transaction payloads with pagination.
5
+
6
+ Usage:
7
+
8
+ export HELIUS_API_KEY=your_helius_api_key
9
+ python examples/solana_rpc/address_transactions.py <ADDRESS> [--limit 10]
10
+ python examples/solana_rpc/address_transactions.py <ADDRESS> --full --limit 5
11
+
12
+ Docs:
13
+ https://www.helius.dev/docs/getting-data/get-transactions-for-address
14
+
15
+ Note:
16
+ Helius documents this exclusive RPC method as requiring a Developer plan
17
+ or higher.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import datetime as dt
24
+ import sys
25
+
26
+ import httpx
27
+
28
+ from helius.solana_rpc import SolanaRpcClient
29
+
30
+
31
+ def format_time(block_time: int | None) -> str:
32
+ if block_time is None:
33
+ return "(no time)"
34
+ return dt.datetime.fromtimestamp(block_time, tz=dt.timezone.utc).strftime(
35
+ "%Y-%m-%d %H:%M:%SZ"
36
+ )
37
+
38
+
39
+ def main() -> int:
40
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
41
+ parser.add_argument("address", help="Wallet, account, or program address")
42
+ parser.add_argument(
43
+ "--limit",
44
+ type=int,
45
+ default=10,
46
+ help="Number of rows to fetch (1-1000, default 10)",
47
+ )
48
+ parser.add_argument(
49
+ "--pagination-token",
50
+ help="Token returned by a previous page of results",
51
+ )
52
+ parser.add_argument(
53
+ "--full",
54
+ action="store_true",
55
+ help="Fetch full transaction details instead of signature rows",
56
+ )
57
+ parser.add_argument(
58
+ "--dry-run",
59
+ action="store_true",
60
+ help="Validate arguments and print the planned request without sending it",
61
+ )
62
+ args = parser.parse_args()
63
+
64
+ details = "full" if args.full else "signatures"
65
+ if args.dry_run:
66
+ print("Would call get_transactions_for_address with:")
67
+ print(f" address={args.address}")
68
+ print(f" transaction_details={details}")
69
+ print(f" limit={args.limit}")
70
+ print(f" pagination_token={args.pagination_token}")
71
+ print(f" encoding={'jsonParsed' if args.full else None}")
72
+ return 0
73
+
74
+ try:
75
+ with SolanaRpcClient() as client:
76
+ transactions, next_token = client.get_transactions_for_address(
77
+ address=args.address,
78
+ transaction_details=details,
79
+ sort_order="desc",
80
+ commitment="finalized",
81
+ limit=args.limit,
82
+ pagination_token=args.pagination_token,
83
+ encoding="jsonParsed" if args.full else None,
84
+ max_supported_transaction_version=0 if args.full else None,
85
+ )
86
+ except httpx.HTTPStatusError as exc:
87
+ print(
88
+ f"HTTP {exc.response.status_code}: getTransactionsForAddress was rejected. "
89
+ "This Helius-exclusive method may require a Developer plan or higher.",
90
+ file=sys.stderr,
91
+ )
92
+ return 2
93
+
94
+ print(f"\n=== Transactions for {args.address} ===\n")
95
+ if not transactions:
96
+ print("No transactions returned.")
97
+ return 0
98
+
99
+ for tx in transactions:
100
+ if details == "signatures":
101
+ status = "ERR" if tx.err else "OK "
102
+ print(
103
+ f"{format_time(tx.block_time)} slot={tx.slot:<12} "
104
+ f"idx={tx.transaction_index:<4} {status} {tx.signature}"
105
+ )
106
+ else:
107
+ signature = "(signature unavailable)"
108
+ signatures = tx.transaction.get("signatures")
109
+ if isinstance(signatures, list) and signatures:
110
+ signature = signatures[0]
111
+ err = tx.meta.get("err") if isinstance(tx.meta, dict) else None
112
+ status = "ERR" if err else "OK "
113
+ print(
114
+ f"{format_time(tx.block_time)} slot={tx.slot:<12} "
115
+ f"idx={tx.transaction_index:<4} {status} {signature}"
116
+ )
117
+
118
+ if next_token:
119
+ print(f"\nNext page token: {next_token}")
120
+
121
+ return 0
122
+
123
+
124
+ if __name__ == "__main__":
125
+ sys.exit(main())
@@ -0,0 +1,118 @@
1
+ """List token and SOL transfers for an address.
2
+
3
+ Uses Helius's `getTransfersByAddress` RPC method exposed by this client as
4
+ `get_transfers_by_address`.
5
+
6
+ Usage:
7
+
8
+ export HELIUS_API_KEY=your_helius_api_key
9
+ python examples/solana_rpc/address_transfers.py <ADDRESS> [--limit 20]
10
+ python examples/solana_rpc/address_transfers.py <ADDRESS> --direction in --mint <MINT>
11
+
12
+ Docs:
13
+ https://www.helius.dev/docs/getting-data/get-transfers-by-address
14
+
15
+ Note:
16
+ Helius documents this exclusive RPC method as requiring a Developer plan
17
+ or higher.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import datetime as dt
24
+ import sys
25
+
26
+ import httpx
27
+
28
+ from helius.solana_rpc import SolanaRpcClient
29
+
30
+
31
+ def format_time(block_time: int) -> str:
32
+ return dt.datetime.fromtimestamp(block_time, tz=dt.timezone.utc).strftime(
33
+ "%Y-%m-%d %H:%M:%SZ"
34
+ )
35
+
36
+
37
+ def main() -> int:
38
+ parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
39
+ parser.add_argument("address", help="Wallet, token account, or owner address")
40
+ parser.add_argument(
41
+ "--limit",
42
+ type=int,
43
+ default=20,
44
+ help="Number of transfers to fetch (1-100, default 20)",
45
+ )
46
+ parser.add_argument(
47
+ "--direction",
48
+ choices=("in", "out", "any"),
49
+ default="any",
50
+ help="Transfer direction relative to address (default any)",
51
+ )
52
+ parser.add_argument("--with-address", help="Counterparty address filter")
53
+ parser.add_argument("--mint", help="Mint address filter")
54
+ parser.add_argument(
55
+ "--pagination-token",
56
+ help="Token returned by a previous page of results",
57
+ )
58
+ parser.add_argument(
59
+ "--dry-run",
60
+ action="store_true",
61
+ help="Validate arguments and print the planned request without sending it",
62
+ )
63
+ args = parser.parse_args()
64
+
65
+ if args.dry_run:
66
+ print("Would call get_transfers_by_address with:")
67
+ print(f" address={args.address}")
68
+ print(f" with_address={args.with_address}")
69
+ print(f" direction={args.direction}")
70
+ print(f" mint={args.mint}")
71
+ print(f" limit={args.limit}")
72
+ print(f" pagination_token={args.pagination_token}")
73
+ return 0
74
+
75
+ try:
76
+ with SolanaRpcClient() as client:
77
+ transfers, next_token = client.get_transfers_by_address(
78
+ address=args.address,
79
+ with_address=args.with_address,
80
+ direction=args.direction,
81
+ mint=args.mint,
82
+ limit=args.limit,
83
+ pagination_token=args.pagination_token,
84
+ commitment="finalized",
85
+ sort_order="desc",
86
+ )
87
+ except httpx.HTTPStatusError as exc:
88
+ print(
89
+ f"HTTP {exc.response.status_code}: getTransfersByAddress was rejected. "
90
+ "This Helius-exclusive method may require a Developer plan or higher.",
91
+ file=sys.stderr,
92
+ )
93
+ return 2
94
+
95
+ print(f"\n=== Transfers for {args.address} ===\n")
96
+ if not transfers:
97
+ print("No transfers returned.")
98
+ return 0
99
+
100
+ for transfer in transfers:
101
+ from_acct = transfer.from_user_account or transfer.from_token_account or "-"
102
+ to_acct = transfer.to_user_account or transfer.to_token_account or "-"
103
+ print(
104
+ f"{format_time(transfer.block_time)} slot={transfer.slot:<12} "
105
+ f"{transfer.type:<11} {transfer.ui_amount:>18} mint={transfer.mint}"
106
+ )
107
+ print(f" from={from_acct}")
108
+ print(f" to ={to_acct}")
109
+ print(f" sig ={transfer.signature}")
110
+
111
+ if next_token:
112
+ print(f"\nNext page token: {next_token}")
113
+
114
+ return 0
115
+
116
+
117
+ if __name__ == "__main__":
118
+ sys.exit(main())
@@ -8,8 +8,8 @@ breakdown of successful vs. failed transactions plus total fees paid.
8
8
  Usage:
9
9
 
10
10
  export HELIUS_API_KEY=your_helius_api_key
11
- python examples/block_explorer.py
12
- python examples/block_explorer.py --slot 250000000
11
+ python examples/solana_rpc/block_explorer.py
12
+ python examples/solana_rpc/block_explorer.py --slot 250000000
13
13
 
14
14
  Uses (with `with`):
15
15
  get_slot, get_block.
@@ -43,9 +43,10 @@ def main() -> int:
43
43
  else helius.get_slot(commitment="finalized")
44
44
  )
45
45
  block = helius.get_block(
46
- slot,
46
+ slot=slot,
47
47
  commitment="finalized",
48
48
  encoding="jsonParsed",
49
+ rewards=False,
49
50
  max_supported_transcation_version=0,
50
51
  )
51
52
 
@@ -7,7 +7,7 @@ polls `getSignatureStatuses` until the airdrop transaction reaches a
7
7
  Usage:
8
8
 
9
9
  export HELIUS_API_KEY=your_helius_api_key
10
- python examples/devnet_airdrop.py <WALLET_ADDRESS> [--sol 1.0]
10
+ python examples/solana_rpc/devnet_airdrop.py <WALLET_ADDRESS> [--sol 1.0]
11
11
 
12
12
  Note:
13
13
  `requestAirdrop` is only available on Devnet and Testnet — never on
@@ -24,6 +24,8 @@ import argparse
24
24
  import sys
25
25
  import time
26
26
 
27
+ import httpx
28
+
27
29
  from helius.solana_rpc import SolanaRpcClient
28
30
 
29
31
  LAMPORTS_PER_SOL = 1_000_000_000
@@ -45,20 +47,40 @@ def main() -> int:
45
47
  default=30.0,
46
48
  help="Seconds to wait for confirmation (default: 30)",
47
49
  )
50
+ parser.add_argument(
51
+ "--dry-run",
52
+ action="store_true",
53
+ help="Validate arguments and print the planned airdrop without sending it",
54
+ )
48
55
  args = parser.parse_args()
49
56
  lamports = int(args.sol * LAMPORTS_PER_SOL)
50
57
 
58
+ if args.dry_run:
59
+ print("Would request devnet airdrop with:")
60
+ print(f" address={args.address}")
61
+ print(f" sol={args.sol}")
62
+ print(f" lamports={lamports}")
63
+ print(f" timeout={args.timeout}")
64
+ return 0
65
+
51
66
  client = SolanaRpcClient(base_url=DEVNET_URL)
52
67
  try:
53
68
  print(f"Requesting {args.sol} SOL airdrop to {args.address} on devnet...")
54
- signature = client.request_airdrop(args.address, lamports)
69
+ try:
70
+ signature = client.request_airdrop(public_key=args.address, lamports=lamports)
71
+ except httpx.HTTPStatusError as exc:
72
+ print(
73
+ f"HTTP {exc.response.status_code}: devnet airdrop request was rejected.",
74
+ file=sys.stderr,
75
+ )
76
+ return 2
55
77
  print(f" signature: {signature}")
56
78
 
57
79
  deadline = time.monotonic() + args.timeout
58
80
  status = None
59
81
  while time.monotonic() < deadline:
60
82
  _ctx, statuses = client.get_signature_statuses(
61
- [signature], search_transaction_history=True
83
+ signatures=[signature], search_transaction_history=True
62
84
  )
63
85
  status = statuses[0]
64
86
  if status is not None and status.confirmation_status in (
@@ -79,7 +101,7 @@ def main() -> int:
79
101
  return 1
80
102
  print(f" status: {status.confirmation_status} at slot {status.slot}")
81
103
 
82
- _ctx, balance = client.get_balance(args.address)
104
+ _ctx, balance = client.get_balance(public_key=args.address)
83
105
  print(f"Post-airdrop balance: {balance / LAMPORTS_PER_SOL:.9f} SOL")
84
106
  finally:
85
107
  client.close()
@@ -7,7 +7,7 @@ recent-performance summary (avg TPS over the last samples).
7
7
  Usage:
8
8
 
9
9
  export HELIUS_API_KEY=your_helius_api_key
10
- python examples/network_status.py
10
+ python examples/solana_rpc/network_status.py
11
11
 
12
12
  Uses (with `with`):
13
13
  get_health, get_version, get_slot, get_block_height, get_epoch_info,
@@ -12,8 +12,8 @@ sample only counts transactions that locked those accounts as writable
12
12
  Usage:
13
13
 
14
14
  export HELIUS_API_KEY=your_helius_api_key
15
- python examples/priority_fees.py
16
- python examples/priority_fees.py --account <PUBKEY> --account <PUBKEY>
15
+ python examples/solana_rpc/priority_fees.py
16
+ python examples/solana_rpc/priority_fees.py --account <PUBKEY> --account <PUBKEY>
17
17
 
18
18
  Uses (with `with`):
19
19
  get_recent_prioritization_fees.
@@ -7,7 +7,7 @@ validator set (top 10 by stake).
7
7
  Usage:
8
8
 
9
9
  export HELIUS_API_KEY=your_helius_api_key
10
- python examples/stake_overview.py
10
+ python examples/solana_rpc/stake_overview.py
11
11
 
12
12
  Uses (with `try/finally`):
13
13
  get_inflation_rate, get_inflation_governor, get_supply,
@@ -18,6 +18,8 @@ from __future__ import annotations
18
18
 
19
19
  import sys
20
20
 
21
+ import httpx
22
+
21
23
  from helius.solana_rpc import SolanaRpcClient
22
24
 
23
25
  LAMPORTS_PER_SOL = 1_000_000_000
@@ -25,10 +27,11 @@ LAMPORTS_PER_SOL = 1_000_000_000
25
27
 
26
28
  def main() -> int:
27
29
  client = SolanaRpcClient()
30
+ client._client.timeout = httpx.Timeout(30.0)
28
31
  try:
29
32
  rate = client.get_inflation_rate()
30
33
  gov = client.get_inflation_governor()
31
- _ctx, supply = client.get_supply(exclude_non_circulating_accounts_list=True)
34
+ _ctx, supply = client.get_supply(exclude_non_circulating_accounts_list=False)
32
35
  _ctx, min_stake = client.get_stake_minimum_delegation()
33
36
  current, delinquent = client.get_vote_accounts()
34
37
  finally:
@@ -7,11 +7,15 @@ Given a mint address, prints:
7
7
  Usage:
8
8
 
9
9
  export HELIUS_API_KEY=your_helius_api_key
10
- python examples/token_inspector.py <MINT_ADDRESS>
10
+ python examples/solana_rpc/token_inspector.py <MINT_ADDRESS>
11
11
 
12
- Example with USDC:
12
+ Example with a small-holder-count mint:
13
13
 
14
- python examples/token_inspector.py EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
14
+ python examples/solana_rpc/token_inspector.py J5iyNuTa6zqqA62Xe4h1VBvcBW5CTSNNva3QPh8DU5RV
15
+
16
+ Note:
17
+ Very large mints may be rejected by `getTokenLargestAccounts` if the
18
+ upstream RPC would need to scan too many accounts.
15
19
 
16
20
  Uses (with `try/finally`):
17
21
  get_token_supply, get_token_largest_accounts.
@@ -22,6 +26,8 @@ from __future__ import annotations
22
26
  import argparse
23
27
  import sys
24
28
 
29
+ import httpx
30
+
25
31
  from helius.solana_rpc import SolanaRpcClient
26
32
 
27
33
 
@@ -31,9 +37,10 @@ def main() -> int:
31
37
  args = parser.parse_args()
32
38
 
33
39
  client = SolanaRpcClient()
40
+ client._client.timeout = httpx.Timeout(30.0)
34
41
  try:
35
- _ctx, supply = client.get_token_supply(args.mint)
36
- _ctx, holders = client.get_token_largest_accounts(args.mint)
42
+ _ctx, supply = client.get_token_supply(mint_address=args.mint)
43
+ _ctx, holders = client.get_token_largest_accounts(mint=args.mint)
37
44
  finally:
38
45
  client.close()
39
46
 
@@ -7,7 +7,7 @@ involved, and any log messages emitted by the on-chain programs.
7
7
  Usage:
8
8
 
9
9
  export HELIUS_API_KEY=your_helius_api_key
10
- python examples/transaction_inspector.py <SIGNATURE>
10
+ python examples/solana_rpc/transaction_inspector.py <SIGNATURE>
11
11
 
12
12
  Uses (with `with`):
13
13
  get_transaction.
@@ -31,7 +31,7 @@ def main() -> int:
31
31
 
32
32
  with SolanaRpcClient() as helius:
33
33
  tx = helius.get_transaction(
34
- args.signature,
34
+ transaction_signature=args.signature,
35
35
  encoding="jsonParsed",
36
36
  max_supported_transaction_version=0,
37
37
  )
@@ -3,11 +3,11 @@
3
3
  Usage:
4
4
 
5
5
  export HELIUS_API_KEY=your_helius_api_key
6
- python examples/wallet_tracker.py <WALLET_ADDRESS> [--limit 20]
6
+ python examples/solana_rpc/wallet_tracker.py <WALLET_ADDRESS> [--limit 20]
7
7
 
8
8
  Example (Helius's own treasury-ish address, replace with any):
9
9
 
10
- python examples/wallet_tracker.py 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
10
+ python examples/solana_rpc/wallet_tracker.py 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
11
11
 
12
12
  It prints:
13
13
  - SOL balance (in SOL, not lamports)
@@ -43,7 +43,7 @@ def main() -> int:
43
43
 
44
44
  with SolanaRpcClient() as client: # reads HELIUS_API_KEY from env / .env
45
45
  # --- SOL balance ---------------------------------------------------
46
- _ctx, lamports = client.get_balance(args.address)
46
+ _ctx, lamports = client.get_balance(public_key=args.address)
47
47
  print(f"\n=== {args.address} ===\n")
48
48
  print(
49
49
  f"SOL balance: {lamports / LAMPORTS_PER_SOL:.9f} SOL "
@@ -75,7 +75,7 @@ def main() -> int:
75
75
  print("SPL token accounts: none with non-zero balance.\n")
76
76
 
77
77
  # --- Recent activity ----------------------------------------------
78
- sigs = client.get_signatures_for_address(args.address, limit=args.limit)
78
+ sigs = client.get_signatures_for_address(address=args.address, limit=args.limit)
79
79
  print(f"Last {len(sigs)} signatures:")
80
80
  for sig in sigs:
81
81
  ts = (
@@ -10,7 +10,7 @@ build-backend = "hatchling.build"
10
10
 
11
11
  [project]
12
12
  name = "helius-python"
13
- version = "0.3.2"
13
+ version = "0.3.4"
14
14
  authors = [
15
15
  { name="Markos Narinian", email="manarinian@gmail.com" },
16
16
  ]
@@ -21,6 +21,7 @@ dependencies = [
21
21
  "httpx",
22
22
  "pydantic",
23
23
  "python-dotenv",
24
+ "typing-extensions",
24
25
  "websockets",
25
26
  ]
26
27
  classifiers = [
@@ -1,11 +1,12 @@
1
1
  import json
2
2
  from os import environ
3
- from typing import Annotated, Literal, TypedDict
3
+ from typing import Annotated, Literal
4
4
 
5
5
  import httpx
6
6
  from dotenv import dotenv_values
7
7
  from pydantic import AliasGenerator, BaseModel, ConfigDict, Field, model_validator
8
8
  from pydantic.alias_generators import to_camel
9
+ from typing_extensions import TypedDict
9
10
  from websockets.sync.client import connect
10
11
 
11
12
  from helius.rpc import JsonRpcRequest