0
# RPC Functionality
1
2
Comprehensive RPC client support with request/response handling, configuration options, and subscription capabilities for interacting with Solana networks. This provides type-safe access to all Solana JSON-RPC methods with proper serialization and error handling.
3
4
## Capabilities
5
6
### RPC Requests
7
8
Type-safe request classes for all Solana JSON-RPC methods with parameter validation and serialization.
9
10
#### Account Information
11
12
```python { .api }
13
class GetAccountInfo:
14
"""
15
Request account information including balance, data, and metadata.
16
"""
17
def __init__(self, pubkey: Pubkey, config: Optional[RpcAccountInfoConfig] = None):
18
"""
19
Create get account info request.
20
21
Parameters:
22
- pubkey: Pubkey, account to query
23
- config: Optional[RpcAccountInfoConfig], request configuration
24
"""
25
26
class RpcAccountInfoConfig:
27
"""Configuration for account info requests."""
28
def __init__(
29
self,
30
encoding: Optional[UiAccountEncoding] = None,
31
data_slice: Optional[UiDataSliceConfig] = None,
32
commitment: Optional[CommitmentConfig] = None,
33
min_context_slot: Optional[int] = None
34
):
35
"""
36
Configure account info request.
37
38
Parameters:
39
- encoding: Optional[UiAccountEncoding], data encoding format
40
- data_slice: Optional[UiDataSliceConfig], slice of account data to return
41
- commitment: Optional[CommitmentConfig], confirmation level
42
- min_context_slot: Optional[int], minimum slot for response
43
"""
44
45
class GetBalance:
46
"""
47
Request account balance in lamports.
48
"""
49
def __init__(self, pubkey: Pubkey, config: Optional[CommitmentConfig] = None):
50
"""
51
Create get balance request.
52
53
Parameters:
54
- pubkey: Pubkey, account to query
55
- config: Optional[CommitmentConfig], confirmation level
56
"""
57
58
class GetMultipleAccounts:
59
"""
60
Request information for multiple accounts in single call.
61
"""
62
def __init__(self, pubkeys: List[Pubkey], config: Optional[RpcAccountInfoConfig] = None):
63
"""
64
Create multiple accounts request.
65
66
Parameters:
67
- pubkeys: List[Pubkey], accounts to query (max 100)
68
- config: Optional[RpcAccountInfoConfig], request configuration
69
"""
70
71
class GetProgramAccounts:
72
"""
73
Request all accounts owned by specified program.
74
"""
75
def __init__(self, program_id: Pubkey, config: Optional[RpcProgramAccountsConfig] = None):
76
"""
77
Create program accounts request.
78
79
Parameters:
80
- program_id: Pubkey, program that owns accounts
81
- config: Optional[RpcProgramAccountsConfig], filtering and encoding options
82
"""
83
84
class RpcProgramAccountsConfig:
85
"""Configuration for program accounts requests."""
86
def __init__(
87
self,
88
encoding: Optional[UiAccountEncoding] = None,
89
data_slice: Optional[UiDataSliceConfig] = None,
90
filters: Optional[List[RpcFilterType]] = None,
91
commitment: Optional[CommitmentConfig] = None,
92
min_context_slot: Optional[int] = None,
93
with_context: Optional[bool] = None
94
):
95
"""Configure program accounts filtering and encoding."""
96
```
97
98
#### Blockchain Information
99
100
```python { .api }
101
class GetBlock:
102
"""
103
Request block information and transactions.
104
"""
105
def __init__(self, slot: int, config: Optional[RpcBlockConfig] = None):
106
"""
107
Create get block request.
108
109
Parameters:
110
- slot: int, block slot number
111
- config: Optional[RpcBlockConfig], block encoding and detail level
112
"""
113
114
class RpcBlockConfig:
115
"""Configuration for block requests."""
116
def __init__(
117
self,
118
encoding: Optional[UiTransactionEncoding] = None,
119
transaction_details: Optional[TransactionDetails] = None,
120
rewards: Optional[bool] = None,
121
commitment: Optional[CommitmentConfig] = None,
122
max_supported_transaction_version: Optional[int] = None
123
):
124
"""Configure block response format and detail level."""
125
126
class GetBlockHeight:
127
"""Request current block height."""
128
def __init__(self, config: Optional[CommitmentConfig] = None):
129
"""Create block height request."""
130
131
class GetBlockTime:
132
"""Request estimated production time of a block."""
133
def __init__(self, slot: int):
134
"""
135
Create block time request.
136
137
Parameters:
138
- slot: int, block slot number
139
"""
140
141
class GetBlocks:
142
"""Request list of confirmed blocks."""
143
def __init__(self, start_slot: int, end_slot: Optional[int] = None, config: Optional[CommitmentConfig] = None):
144
"""
145
Create blocks request.
146
147
Parameters:
148
- start_slot: int, first slot to return
149
- end_slot: Optional[int], last slot to return (default: latest)
150
- config: Optional[CommitmentConfig], confirmation level
151
"""
152
153
class GetBlocksWithLimit:
154
"""Request limited number of confirmed blocks."""
155
def __init__(self, start_slot: int, limit: int, config: Optional[CommitmentConfig] = None):
156
"""
157
Create blocks with limit request.
158
159
Parameters:
160
- start_slot: int, first slot to return
161
- limit: int, maximum number of blocks to return
162
- config: Optional[CommitmentConfig], confirmation level
163
"""
164
165
class GetLatestBlockhash:
166
"""Request most recent blockhash."""
167
def __init__(self, config: Optional[CommitmentConfig] = None):
168
"""Create latest blockhash request."""
169
```
170
171
#### Transaction Operations
172
173
```python { .api }
174
class GetTransaction:
175
"""
176
Request transaction details by signature.
177
"""
178
def __init__(self, signature: Signature, config: Optional[RpcTransactionConfig] = None):
179
"""
180
Create get transaction request.
181
182
Parameters:
183
- signature: Signature, transaction signature to look up
184
- config: Optional[RpcTransactionConfig], encoding and detail options
185
"""
186
187
class RpcTransactionConfig:
188
"""Configuration for transaction requests."""
189
def __init__(
190
self,
191
encoding: Optional[UiTransactionEncoding] = None,
192
commitment: Optional[CommitmentConfig] = None,
193
max_supported_transaction_version: Optional[int] = None
194
):
195
"""Configure transaction response format."""
196
197
class GetSignatureStatuses:
198
"""
199
Request confirmation status of multiple transaction signatures.
200
"""
201
def __init__(self, signatures: List[Signature], config: Optional[RpcSignatureStatusConfig] = None):
202
"""
203
Create signature statuses request.
204
205
Parameters:
206
- signatures: List[Signature], transaction signatures to check (max 256)
207
- config: Optional[RpcSignatureStatusConfig], status search options
208
"""
209
210
class GetSignaturesForAddress:
211
"""
212
Request transaction signatures for an address.
213
"""
214
def __init__(self, address: Pubkey, config: Optional[RpcSignaturesForAddressConfig] = None):
215
"""
216
Create signatures for address request.
217
218
Parameters:
219
- address: Pubkey, account address to search
220
- config: Optional[RpcSignaturesForAddressConfig], search parameters
221
"""
222
223
class RpcSignaturesForAddressConfig:
224
"""Configuration for signature history requests."""
225
def __init__(
226
self,
227
limit: Optional[int] = None,
228
before: Optional[Signature] = None,
229
until: Optional[Signature] = None,
230
commitment: Optional[CommitmentConfig] = None,
231
min_context_slot: Optional[int] = None
232
):
233
"""
234
Configure signature search parameters.
235
236
Parameters:
237
- limit: Optional[int], maximum signatures to return (default 1000, max 1000)
238
- before: Optional[Signature], start search before this signature
239
- until: Optional[Signature], stop search at this signature
240
- commitment: Optional[CommitmentConfig], confirmation level
241
- min_context_slot: Optional[int], minimum context slot
242
"""
243
244
class GetFeeForMessage:
245
"""Request transaction fee for a message."""
246
def __init__(self, message: VersionedMessage, config: Optional[CommitmentConfig] = None):
247
"""
248
Create fee calculation request.
249
250
Parameters:
251
- message: VersionedMessage, transaction message to estimate
252
- config: Optional[CommitmentConfig], confirmation level
253
"""
254
```
255
256
#### Network and Validator Information
257
258
```python { .api }
259
class GetEpochInfo:
260
"""Request current epoch information."""
261
def __init__(self, config: Optional[CommitmentConfig] = None):
262
"""Create epoch info request."""
263
264
class GetEpochSchedule:
265
"""Request epoch schedule configuration."""
266
def __init__(self):
267
"""Create epoch schedule request."""
268
269
class GetSlot:
270
"""Request current slot number."""
271
def __init__(self, config: Optional[CommitmentConfig] = None):
272
"""Create slot request."""
273
274
class GetSlotLeader:
275
"""Request current slot leader."""
276
def __init__(self, config: Optional[CommitmentConfig] = None):
277
"""Create slot leader request."""
278
279
class GetSlotLeaders:
280
"""Request slot leaders for range of slots."""
281
def __init__(self, start_slot: int, limit: int):
282
"""
283
Create slot leaders request.
284
285
Parameters:
286
- start_slot: int, first slot to query
287
- limit: int, number of slots to query
288
"""
289
290
class GetLeaderSchedule:
291
"""Request leader schedule for an epoch."""
292
def __init__(self, slot: Optional[int] = None, config: Optional[RpcLeaderScheduleConfig] = None):
293
"""
294
Create leader schedule request.
295
296
Parameters:
297
- slot: Optional[int], slot to get schedule for (default: current epoch)
298
- config: Optional[RpcLeaderScheduleConfig], identity filter
299
"""
300
301
class GetVoteAccounts:
302
"""Request current vote accounts."""
303
def __init__(self, config: Optional[RpcGetVoteAccountsConfig] = None):
304
"""Create vote accounts request."""
305
306
class GetClusterNodes:
307
"""Request information about cluster nodes."""
308
def __init__(self):
309
"""Create cluster nodes request."""
310
```
311
312
#### Token-Specific Requests
313
314
```python { .api }
315
class GetTokenAccountBalance:
316
"""Request SPL token account balance."""
317
def __init__(self, account: Pubkey, config: Optional[CommitmentConfig] = None):
318
"""
319
Create token balance request.
320
321
Parameters:
322
- account: Pubkey, token account to query
323
- config: Optional[CommitmentConfig], confirmation level
324
"""
325
326
class GetTokenSupply:
327
"""Request total supply of SPL token."""
328
def __init__(self, mint: Pubkey, config: Optional[CommitmentConfig] = None):
329
"""
330
Create token supply request.
331
332
Parameters:
333
- mint: Pubkey, token mint to query
334
- config: Optional[CommitmentConfig], confirmation level
335
"""
336
337
class GetTokenAccountsByOwner:
338
"""Request all token accounts owned by address."""
339
def __init__(
340
self,
341
owner: Pubkey,
342
filter: Union[RpcTokenAccountsFilterMint, RpcTokenAccountsFilterProgramId],
343
config: Optional[RpcAccountInfoConfig] = None
344
):
345
"""
346
Create token accounts by owner request.
347
348
Parameters:
349
- owner: Pubkey, token account owner
350
- filter: Union filter by mint or program ID
351
- config: Optional[RpcAccountInfoConfig], encoding options
352
"""
353
354
class RpcTokenAccountsFilterMint:
355
"""Filter token accounts by mint."""
356
def __init__(self, mint: Pubkey):
357
"""Filter by specific token mint."""
358
359
class RpcTokenAccountsFilterProgramId:
360
"""Filter token accounts by program ID."""
361
def __init__(self, program_id: Pubkey):
362
"""Filter by token program (SPL Token vs Token-2022)."""
363
364
class GetTokenAccountsByDelegate:
365
"""Request all token accounts with specific delegate."""
366
def __init__(
367
self,
368
delegate: Pubkey,
369
filter: Union[RpcTokenAccountsFilterMint, RpcTokenAccountsFilterProgramId],
370
config: Optional[RpcAccountInfoConfig] = None
371
):
372
"""Create token accounts by delegate request."""
373
374
class GetTokenLargestAccounts:
375
"""Request largest token accounts for mint."""
376
def __init__(self, mint: Pubkey, config: Optional[CommitmentConfig] = None):
377
"""
378
Create largest token accounts request.
379
380
Parameters:
381
- mint: Pubkey, token mint to query
382
- config: Optional[CommitmentConfig], confirmation level
383
"""
384
```
385
386
### RPC Subscriptions
387
388
Real-time data streaming through WebSocket subscriptions.
389
390
```python { .api }
391
class AccountSubscribe:
392
"""
393
Subscribe to account changes.
394
"""
395
def __init__(self, account: Pubkey, config: Optional[RpcAccountInfoConfig] = None):
396
"""
397
Create account subscription.
398
399
Parameters:
400
- account: Pubkey, account to monitor
401
- config: Optional[RpcAccountInfoConfig], encoding and commitment options
402
"""
403
404
class AccountUnsubscribe:
405
"""
406
Unsubscribe from account changes.
407
"""
408
def __init__(self, subscription_id: int):
409
"""
410
Create account unsubscription.
411
412
Parameters:
413
- subscription_id: int, subscription ID to cancel
414
"""
415
416
class BlockSubscribe:
417
"""
418
Subscribe to block updates.
419
"""
420
def __init__(self, config: Optional[RpcBlockSubscribeConfig] = None):
421
"""
422
Create block subscription.
423
424
Parameters:
425
- config: Optional[RpcBlockSubscribeConfig], block filter and encoding
426
"""
427
428
class RpcBlockSubscribeConfig:
429
"""Configuration for block subscriptions."""
430
def __init__(
431
self,
432
filter: Optional[RpcBlockSubscribeFilter] = None,
433
encoding: Optional[UiTransactionEncoding] = None,
434
transaction_details: Optional[TransactionDetails] = None,
435
show_rewards: Optional[bool] = None,
436
commitment: Optional[CommitmentConfig] = None,
437
max_supported_transaction_version: Optional[int] = None
438
):
439
"""Configure block subscription parameters."""
440
441
class BlockUnsubscribe:
442
"""
443
Unsubscribe from block updates.
444
"""
445
def __init__(self, subscription_id: int):
446
"""Cancel block subscription."""
447
448
class ProgramSubscribe:
449
"""
450
Subscribe to program account changes.
451
"""
452
def __init__(self, program_id: Pubkey, config: Optional[RpcProgramAccountsConfig] = None):
453
"""
454
Create program subscription.
455
456
Parameters:
457
- program_id: Pubkey, program to monitor
458
- config: Optional[RpcProgramAccountsConfig], filtering options
459
"""
460
461
class SignatureSubscribe:
462
"""
463
Subscribe to signature confirmations.
464
"""
465
def __init__(self, signature: Signature, config: Optional[RpcSignatureSubscribeConfig] = None):
466
"""
467
Create signature subscription.
468
469
Parameters:
470
- signature: Signature, transaction signature to monitor
471
- config: Optional[RpcSignatureSubscribeConfig], commitment level
472
"""
473
```
474
475
### Transaction Simulation
476
477
```python { .api }
478
class SimulateTransaction:
479
"""
480
Simulate transaction execution without committing.
481
"""
482
def __init__(
483
self,
484
transaction: Union[Transaction, VersionedTransaction],
485
config: Optional[RpcSimulateTransactionConfig] = None
486
):
487
"""
488
Create transaction simulation request.
489
490
Parameters:
491
- transaction: Union transaction to simulate
492
- config: Optional[RpcSimulateTransactionConfig], simulation options
493
"""
494
495
class RpcSimulateTransactionConfig:
496
"""Configuration for transaction simulation."""
497
def __init__(
498
self,
499
sig_verify: Optional[bool] = None,
500
replace_recent_blockhash: Optional[bool] = None,
501
commitment: Optional[CommitmentConfig] = None,
502
encoding: Optional[UiTransactionEncoding] = None,
503
accounts: Optional[RpcSimulateTransactionAccountsConfig] = None,
504
min_context_slot: Optional[int] = None,
505
inner_instructions: Optional[bool] = None
506
):
507
"""
508
Configure simulation parameters.
509
510
Parameters:
511
- sig_verify: Optional[bool], whether to verify signatures (default: false)
512
- replace_recent_blockhash: Optional[bool], replace with latest blockhash
513
- commitment: Optional[CommitmentConfig], confirmation level for simulation
514
- encoding: Optional[UiTransactionEncoding], response encoding
515
- accounts: Optional config for returning account states
516
- min_context_slot: Optional[int], minimum context slot
517
- inner_instructions: Optional[bool], include inner instructions in response
518
"""
519
520
class RpcSimulateTransactionAccountsConfig:
521
"""Configuration for simulation account returns."""
522
def __init__(
523
self,
524
encoding: UiAccountEncoding,
525
addresses: List[Pubkey]
526
):
527
"""
528
Configure which accounts to return after simulation.
529
530
Parameters:
531
- encoding: UiAccountEncoding, account data encoding
532
- addresses: List[Pubkey], accounts to return
533
"""
534
```
535
536
### Network Configuration
537
538
```python { .api }
539
class RpcSendTransactionConfig:
540
"""Configuration for sending transactions."""
541
def __init__(
542
self,
543
skip_preflight: Optional[bool] = None,
544
preflight_commitment: Optional[CommitmentLevel] = None,
545
encoding: Optional[UiTransactionEncoding] = None,
546
max_retries: Optional[int] = None,
547
min_context_slot: Optional[int] = None
548
):
549
"""
550
Configure transaction sending.
551
552
Parameters:
553
- skip_preflight: Optional[bool], skip preflight validation
554
- preflight_commitment: Optional[CommitmentLevel], commitment for preflight
555
- encoding: Optional[UiTransactionEncoding], transaction encoding
556
- max_retries: Optional[int], maximum retry attempts
557
- min_context_slot: Optional[int], minimum context slot
558
"""
559
```
560
561
## Usage Examples
562
563
### Basic Account Queries
564
565
```python
566
from solders.rpc.requests import GetAccountInfo, GetBalance, GetMultipleAccounts
567
from solders.rpc.config import RpcAccountInfoConfig
568
from solders.account_decoder import UiAccountEncoding
569
from solders.commitment_config import CommitmentConfig
570
from solders.pubkey import Pubkey
571
572
# Single account info
573
account = Pubkey.from_string("7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj")
574
575
# Basic account info request
576
account_info_request = GetAccountInfo(account)
577
578
# Account info with configuration
579
config = RpcAccountInfoConfig(
580
encoding=UiAccountEncoding.Base64,
581
commitment=CommitmentConfig.confirmed()
582
)
583
configured_request = GetAccountInfo(account, config)
584
585
# Account balance
586
balance_request = GetBalance(account, CommitmentConfig.finalized())
587
588
# Multiple accounts at once
589
accounts = [
590
Pubkey.from_string("7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj"),
591
Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
592
Pubkey.from_string("11111111111111111111111111111112")
593
]
594
multi_account_request = GetMultipleAccounts(accounts, config)
595
```
596
597
### Program Account Filtering
598
599
```python
600
from solders.rpc.requests import GetProgramAccounts
601
from solders.rpc.config import RpcProgramAccountsConfig
602
from solders.rpc.filter import RpcFilterType, MemcmpFilter
603
604
# Get all token accounts (SPL Token program)
605
token_program = Pubkey.from_string("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
606
607
# Basic program accounts request
608
program_accounts_request = GetProgramAccounts(token_program)
609
610
# Filter for specific mint (offset 0, 32 bytes)
611
mint_filter = MemcmpFilter(
612
offset=0,
613
bytes=bytes(Pubkey.from_string("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")) # USDC mint
614
)
615
616
# Filter for specific owner (offset 32, 32 bytes)
617
owner_filter = MemcmpFilter(
618
offset=32,
619
bytes=bytes(Pubkey.from_string("7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj"))
620
)
621
622
filtered_config = RpcProgramAccountsConfig(
623
encoding=UiAccountEncoding.JsonParsed,
624
filters=[mint_filter, owner_filter],
625
commitment=CommitmentConfig.confirmed()
626
)
627
628
filtered_request = GetProgramAccounts(token_program, filtered_config)
629
```
630
631
### Transaction Operations
632
633
```python
634
from solders.rpc.requests import GetTransaction, GetSignatureStatuses, SimulateTransaction
635
from solders.rpc.config import RpcTransactionConfig, RpcSimulateTransactionConfig
636
from solders.transaction_status import UiTransactionEncoding
637
from solders.signature import Signature
638
639
# Get transaction details
640
tx_signature = Signature.from_string("signature_string_here")
641
642
tx_config = RpcTransactionConfig(
643
encoding=UiTransactionEncoding.Json,
644
commitment=CommitmentConfig.confirmed(),
645
max_supported_transaction_version=0
646
)
647
648
tx_request = GetTransaction(tx_signature, tx_config)
649
650
# Check multiple signature statuses
651
signatures = [
652
Signature.from_string("sig1"),
653
Signature.from_string("sig2"),
654
Signature.from_string("sig3")
655
]
656
657
status_request = GetSignatureStatuses(signatures)
658
659
# Simulate transaction before sending
660
simulation_config = RpcSimulateTransactionConfig(
661
sig_verify=False, # Skip signature verification for speed
662
replace_recent_blockhash=True,
663
commitment=CommitmentConfig.processed(),
664
inner_instructions=True
665
)
666
667
simulate_request = SimulateTransaction(transaction, simulation_config)
668
```
669
670
### Block and Network Queries
671
672
```python
673
from solders.rpc.requests import (
674
GetBlock, GetBlockHeight, GetLatestBlockhash, GetEpochInfo, GetSlotLeaders
675
)
676
from solders.rpc.config import RpcBlockConfig
677
from solders.transaction_status import TransactionDetails
678
679
# Get current block height
680
block_height_request = GetBlockHeight(CommitmentConfig.finalized())
681
682
# Get latest blockhash for transactions
683
blockhash_request = GetLatestBlockhash(CommitmentConfig.finalized())
684
685
# Get block with full transaction details
686
block_config = RpcBlockConfig(
687
encoding=UiTransactionEncoding.Json,
688
transaction_details=TransactionDetails.Full,
689
rewards=True,
690
max_supported_transaction_version=0
691
)
692
693
block_request = GetBlock(slot_number, block_config)
694
695
# Get current epoch information
696
epoch_request = GetEpochInfo(CommitmentConfig.confirmed())
697
698
# Get slot leaders for next 100 slots
699
current_slot = 100000000 # Would get from GetSlot request
700
leaders_request = GetSlotLeaders(current_slot, 100)
701
```
702
703
### Token-Specific Queries
704
705
```python
706
from solders.rpc.requests import (
707
GetTokenAccountBalance, GetTokenSupply, GetTokenAccountsByOwner,
708
GetTokenLargestAccounts
709
)
710
from solders.rpc.config import RpcTokenAccountsFilterMint
711
712
# Token account balance
713
token_account = Pubkey.from_string("token_account_address")
714
balance_request = GetTokenAccountBalance(token_account, CommitmentConfig.confirmed())
715
716
# Token total supply
717
usdc_mint = Pubkey.from_string("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
718
supply_request = GetTokenSupply(usdc_mint, CommitmentConfig.finalized())
719
720
# All USDC accounts for a user
721
owner = Pubkey.from_string("user_wallet_address")
722
mint_filter = RpcTokenAccountsFilterMint(usdc_mint)
723
724
accounts_config = RpcAccountInfoConfig(
725
encoding=UiAccountEncoding.JsonParsed,
726
commitment=CommitmentConfig.confirmed()
727
)
728
729
owner_accounts_request = GetTokenAccountsByOwner(owner, mint_filter, accounts_config)
730
731
# Largest USDC holders
732
largest_request = GetTokenLargestAccounts(usdc_mint, CommitmentConfig.confirmed())
733
```
734
735
### Real-Time Subscriptions
736
737
```python
738
from solders.rpc.requests import AccountSubscribe, BlockSubscribe, SignatureSubscribe
739
from solders.rpc.config import RpcBlockSubscribeConfig
740
741
# Subscribe to account changes
742
account_to_watch = Pubkey.from_string("account_address")
743
sub_config = RpcAccountInfoConfig(
744
encoding=UiAccountEncoding.Base64,
745
commitment=CommitmentConfig.confirmed()
746
)
747
748
account_subscription = AccountSubscribe(account_to_watch, sub_config)
749
750
# Subscribe to new blocks
751
block_config = RpcBlockSubscribeConfig(
752
encoding=UiTransactionEncoding.Json,
753
transaction_details=TransactionDetails.Full,
754
show_rewards=True,
755
commitment=CommitmentConfig.confirmed()
756
)
757
758
block_subscription = BlockSubscribe(block_config)
759
760
# Subscribe to signature confirmation
761
pending_signature = Signature.from_string("pending_tx_signature")
762
signature_subscription = SignatureSubscribe(
763
pending_signature,
764
RpcSignatureSubscribeConfig(commitment=CommitmentConfig.confirmed())
765
)
766
767
# Note: Actual subscription handling would require WebSocket client implementation
768
# These request objects define the subscription parameters
769
```
770
771
### Transaction Sending and Monitoring
772
773
```python
774
from solders.rpc.requests import SendTransaction
775
from solders.rpc.config import RpcSendTransactionConfig
776
777
# Configure transaction sending
778
send_config = RpcSendTransactionConfig(
779
skip_preflight=False, # Run preflight checks
780
preflight_commitment=CommitmentLevel.Processed,
781
encoding=UiTransactionEncoding.Base64,
782
max_retries=3,
783
min_context_slot=None
784
)
785
786
# Send transaction (this would be handled by RPC client)
787
# send_request = SendTransaction(signed_transaction, send_config)
788
789
# Monitor confirmation with signature subscription
790
confirmation_subscription = SignatureSubscribe(
791
transaction.signatures[0], # First signature is transaction ID
792
RpcSignatureSubscribeConfig(commitment=CommitmentConfig.finalized())
793
)
794
```
795
796
## Error Handling
797
798
### RPC Request Validation
799
800
```python
801
from solders.rpc.errors import RpcError
802
803
def validate_rpc_request(request) -> bool:
804
"""Validate RPC request before sending."""
805
try:
806
if isinstance(request, GetMultipleAccounts):
807
if len(request.pubkeys) > 100:
808
raise ValueError("Too many accounts requested (max 100)")
809
810
elif isinstance(request, GetSignatureStatuses):
811
if len(request.signatures) > 256:
812
raise ValueError("Too many signatures requested (max 256)")
813
814
elif isinstance(request, GetBlocks):
815
if request.end_slot and (request.end_slot - request.start_slot) > 500000:
816
raise ValueError("Slot range too large (max 500,000)")
817
818
return True
819
except Exception as e:
820
print(f"Request validation failed: {e}")
821
return False
822
```
823
824
### Commitment Level Handling
825
826
```python
827
from solders.commitment_config import CommitmentLevel, CommitmentConfig
828
829
def choose_commitment_level(use_case: str) -> CommitmentConfig:
830
"""Choose appropriate commitment level based on use case."""
831
if use_case == "realtime_trading":
832
return CommitmentConfig(CommitmentLevel.Processed) # Fastest, least secure
833
elif use_case == "user_interface":
834
return CommitmentConfig(CommitmentLevel.Confirmed) # Balance of speed and security
835
elif use_case == "settlement":
836
return CommitmentConfig(CommitmentLevel.Finalized) # Slowest, most secure
837
else:
838
return CommitmentConfig(CommitmentLevel.Confirmed) # Safe default
839
```
840
841
## Response Processing
842
843
### Handling RPC Responses
844
845
```python
846
def process_account_info_response(response_data: dict) -> Optional[Account]:
847
"""Process GetAccountInfo response."""
848
try:
849
if response_data.get("value") is None:
850
return None # Account doesn't exist
851
852
account_data = response_data["value"]
853
854
# Parse account from RPC response
855
account = Account(
856
lamports=account_data["lamports"],
857
data=base64.b64decode(account_data["data"][0]), # Assuming base64 encoding
858
owner=Pubkey.from_string(account_data["owner"]),
859
executable=account_data["executable"],
860
rent_epoch=account_data["rentEpoch"]
861
)
862
863
return account
864
except Exception as e:
865
print(f"Failed to process account info response: {e}")
866
return None
867
868
def process_transaction_response(response_data: dict) -> Optional[dict]:
869
"""Process GetTransaction response."""
870
try:
871
if response_data.get("value") is None:
872
return None # Transaction not found
873
874
tx_data = response_data["value"]
875
876
# Extract useful information
877
return {
878
"slot": tx_data["slot"],
879
"block_time": tx_data.get("blockTime"),
880
"fee": tx_data["meta"]["fee"],
881
"status": "success" if tx_data["meta"]["err"] is None else "failed",
882
"error": tx_data["meta"]["err"],
883
"log_messages": tx_data["meta"]["logMessages"]
884
}
885
except Exception as e:
886
print(f"Failed to process transaction response: {e}")
887
return None
888
```
889
890
## Configuration Best Practices
891
892
### Optimal Request Configuration
893
894
```python
895
# For user interfaces - balance responsiveness and reliability
896
UI_CONFIG = RpcAccountInfoConfig(
897
encoding=UiAccountEncoding.Base64,
898
commitment=CommitmentConfig.confirmed()
899
)
900
901
# For token operations - parse token data automatically
902
TOKEN_CONFIG = RpcAccountInfoConfig(
903
encoding=UiAccountEncoding.JsonParsed,
904
commitment=CommitmentConfig.confirmed()
905
)
906
907
# For trading applications - prioritize speed
908
TRADING_CONFIG = RpcAccountInfoConfig(
909
encoding=UiAccountEncoding.Base64,
910
commitment=CommitmentConfig.processed()
911
)
912
913
# For settlement - prioritize finality
914
SETTLEMENT_CONFIG = RpcAccountInfoConfig(
915
encoding=UiAccountEncoding.Base64,
916
commitment=CommitmentConfig.finalized()
917
)
918
```