nerva-py 1.0.0__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.
nerva/daemon.py ADDED
@@ -0,0 +1,1326 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ import aiohttp
6
+
7
+ __all__ = ["DaemonJSONRPC", "DaemonOther"]
8
+
9
+
10
+ class DaemonJSONRPC:
11
+ """
12
+ A class to interact with the Nerva daemon's JSON-RPC interface.
13
+
14
+ Parameters
15
+ ----------
16
+ host : str, optional
17
+ The host of the daemon.
18
+ port : int, optional
19
+ The port of the daemon.
20
+ ssl : bool, optional
21
+ Whether to use SSL.
22
+ timeout : float, optional
23
+ The timeout for the request.
24
+
25
+ Attributes
26
+ ----------
27
+ url : str
28
+ The URL of the daemon.
29
+ timeout : float
30
+ The timeout for the request.
31
+ headers : Dict[str, str]
32
+ The headers for the request.
33
+ """
34
+
35
+ __slots__ = ["url", "timeout", "headers"]
36
+
37
+ def __init__(
38
+ self,
39
+ host: Optional[str] = "localhost",
40
+ port: Optional[int] = 17566,
41
+ ssl: Optional[bool] = False,
42
+ timeout: Optional[float] = 10.0,
43
+ ) -> None:
44
+ self.url: str = f"{'https' if ssl else 'http'}://{host}:{port}"
45
+ self.timeout: float = timeout
46
+ self.headers: Dict[str, str] = {"Content-Type": "application/json"}
47
+
48
+ async def _request(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
49
+ async with aiohttp.ClientSession() as session:
50
+ async with session.post(
51
+ f"{self.url}/json_rpc",
52
+ json={"jsonrpc": "2.0", "id": 0, "method": method, "params": params},
53
+ headers=self.headers,
54
+ timeout=self.timeout,
55
+ ) as response:
56
+ return await response.json(content_type=None)
57
+
58
+ async def get_block_count(self) -> Dict[str, Any]:
59
+ """
60
+ Get the current block count.
61
+
62
+ Returns
63
+ -------
64
+ dict
65
+ The response from the daemon.
66
+ """
67
+ return await self._request("get_block_count", {})
68
+
69
+ async def on_get_block_hash(self, height: int) -> Dict[str, Any]:
70
+ """
71
+ Get the block hash at a certain height.
72
+
73
+ Parameters
74
+ ----------
75
+ height : int
76
+ The height of the block.
77
+
78
+ Returns
79
+ -------
80
+ dict
81
+ The response from the daemon.
82
+
83
+ """
84
+ return await self._request("on_get_block_hash", {"height": height})
85
+
86
+ async def get_block_template(
87
+ self, wallet_address: str, reserve_size: int
88
+ ) -> Dict[str, Any]:
89
+ """
90
+ Get a block template for mining.
91
+
92
+ Parameters
93
+ ----------
94
+ wallet_address : str
95
+ The wallet address to mine to.
96
+
97
+ reserve_size : int
98
+ The reserve size.
99
+
100
+ Returns
101
+ -------
102
+ dict
103
+ The response from the daemon.
104
+
105
+ """
106
+ return await self._request(
107
+ "get_block_template",
108
+ {"wallet_address": wallet_address, "reserve_size": reserve_size},
109
+ )
110
+
111
+ async def submit_block(self, block_blob: List[str]) -> Dict[str, Any]:
112
+ """
113
+ Submit a block to the network.
114
+
115
+ Parameters
116
+ ----------
117
+ block_blob : List[str]
118
+ The block blob to submit.
119
+
120
+ Returns
121
+ -------
122
+ Dict[str, Any]
123
+ The response from the daemon.
124
+
125
+ """
126
+ return await self._request("submit_block", {"blob": block_blob})
127
+
128
+ async def get_last_block_header(self) -> Dict[str, Any]:
129
+ """
130
+ Get the last block header.
131
+
132
+ Returns
133
+ -------
134
+ Dict[str, Any]
135
+ The response from the daemon.
136
+
137
+ """
138
+ return await self._request("get_last_block_header", {})
139
+
140
+ async def get_block_header_by_hash(self, block_hash: str) -> Dict[str, Any]:
141
+ """
142
+ Get the block header by hash.
143
+
144
+ Parameters
145
+ ----------
146
+ block_hash : str
147
+ The hash of the block.
148
+
149
+ Returns
150
+ -------
151
+ Dict[str, Any]
152
+ The response from the daemon.
153
+
154
+ """
155
+ return await self._request("get_block_header_by_hash", {"hash": block_hash})
156
+
157
+ async def get_block_header_by_height(self, height: int) -> Dict[str, Any]:
158
+ """
159
+ Get the block header by height.
160
+
161
+ Parameters
162
+ ----------
163
+ height : int
164
+ The height of the block.
165
+
166
+ Returns
167
+ -------
168
+ Dict[str, Any]
169
+ The response from the daemon.
170
+
171
+ """
172
+ return await self._request("get_block_header_by_height", {"height": height})
173
+
174
+ async def get_block_headers_range(
175
+ self, start_height: int, end_height: int
176
+ ) -> Dict[str, Any]:
177
+ """
178
+ Get a range of block headers.
179
+
180
+ Parameters
181
+ ----------
182
+ start_height : int
183
+ The start height.
184
+ end_height : int
185
+ The end height.
186
+
187
+ Returns
188
+ -------
189
+ Dict[str, Any]
190
+ The response from the daemon.
191
+
192
+ """
193
+ return await self._request(
194
+ "get_block_headers_range",
195
+ {"start_height": start_height, "end_height": end_height},
196
+ )
197
+
198
+ async def get_block(
199
+ self, block_hash: Optional[str] = None, height: Optional[int] = None
200
+ ) -> Dict[str, Any]:
201
+ """
202
+ Get a block by hash or height.
203
+
204
+ Parameters
205
+ ----------
206
+ block_hash : str, optional
207
+ The hash of the block.
208
+ height : int, optional
209
+ The height of the block.
210
+
211
+ Returns
212
+ -------
213
+ Dict[str, Any]
214
+ The response from the daemon.
215
+
216
+ """
217
+ if block_hash and not height:
218
+ return await self._request("get_block", {"hash": block_hash})
219
+
220
+ elif height and not block_hash:
221
+ return await self._request("get_block", {"height": height})
222
+
223
+ else:
224
+ raise ValueError("Either block_hash OR height must be provided.")
225
+
226
+ async def get_connections(self) -> Dict[str, Any]:
227
+ """
228
+ Get the connections to the daemon.
229
+
230
+ Returns
231
+ -------
232
+ Dict[str, Any]
233
+ The response from the daemon.
234
+
235
+ """
236
+ return await self._request("get_connections", {})
237
+
238
+ async def get_info(self) -> Dict[str, Any]:
239
+ """
240
+ Get the information about the daemon.
241
+
242
+ Returns
243
+ -------
244
+ Dict[str, Any]
245
+ The response from the daemon.
246
+
247
+ """
248
+ return await self._request("get_info", {})
249
+
250
+ async def hard_fork_info(self) -> Dict[str, Any]:
251
+ """
252
+ Get the hard fork information.
253
+
254
+ Returns
255
+ -------
256
+ Dict[str, Any]
257
+ The response from the daemon.
258
+
259
+ """
260
+ return await self._request("hard_fork_info", {})
261
+
262
+ async def set_bans(self, bans: List[Dict[str, Any]]) -> Dict[str, Any]:
263
+ """
264
+ Set bans for the daemon.
265
+
266
+ Parameters
267
+ ----------
268
+ bans : List[Dict[str, Any]]
269
+ The bans to set. Each ban should be a dictionary with the following keys:
270
+ - host : str
271
+ Host to ban (IP in A.B.C.D format).
272
+ - ip : int, optional
273
+ IP to ban (int format).
274
+ - ban : bool
275
+ Set `true` to ban, `false` to unban.
276
+ - seconds : int
277
+ Time to ban in seconds.
278
+
279
+ Returns
280
+ -------
281
+ Dict[str, Any]
282
+ The response from the daemon.
283
+
284
+ """
285
+ return await self._request("set_bans", {"bans": bans})
286
+
287
+ async def get_bans(self) -> Dict[str, Any]:
288
+ """
289
+ Get the bans of the daemon.
290
+
291
+ Returns
292
+ -------
293
+ Dict[str, Any]
294
+ The response from the daemon.
295
+
296
+ """
297
+ return await self._request("get_bans", {})
298
+
299
+ async def flush_txpool(self, txids: Optional[list] = None) -> Dict[str, Any]:
300
+ """
301
+ Flush the transaction pool.
302
+
303
+ Parameters
304
+ ----------
305
+ txids : list, optional
306
+ The transaction IDs to flush. If not provided, all transactions will be flushed.
307
+
308
+ Returns
309
+ -------
310
+ Dict[str, Any]
311
+ The response from the daemon.
312
+
313
+ """
314
+ return await self._request("flush_txpool", {"txids": txids or []})
315
+
316
+ async def get_output_histogram(
317
+ self,
318
+ amounts: list,
319
+ min_count: int,
320
+ max_count: int,
321
+ unlocked: bool,
322
+ recent_cutoff: int,
323
+ ) -> Dict[str, Any]:
324
+ """
325
+ Get the output histogram.
326
+
327
+ Parameters
328
+ ----------
329
+ amounts : list
330
+ The amounts to get the histogram for.
331
+ min_count : int
332
+ The minimum count.
333
+ max_count : int
334
+ The maximum count.
335
+ unlocked : bool
336
+ Whether to get the unlocked outputs.
337
+ recent_cutoff : int
338
+ The recent cutoff.
339
+
340
+ Returns
341
+ -------
342
+ Dict[str, Any]
343
+ The response from the daemon.
344
+
345
+ """
346
+ return await self._request(
347
+ "get_output_histogram",
348
+ {
349
+ "amounts": amounts,
350
+ "min_count": min_count,
351
+ "max_count": max_count,
352
+ "unlocked": unlocked,
353
+ "recent_cutoff": recent_cutoff,
354
+ },
355
+ )
356
+
357
+ async def get_version(self) -> Dict[str, Any]:
358
+ """
359
+ Get the version of the daemon.
360
+
361
+ Returns
362
+ -------
363
+ Dict[str, Any]
364
+ The response from the daemon.
365
+
366
+ """
367
+ return await self._request("get_version", {})
368
+
369
+ async def get_coinbase_tx_sum(self, height: int, count: int) -> Dict[str, Any]:
370
+ """
371
+ Get the coinbase transaction sum.
372
+
373
+ Parameters
374
+ ----------
375
+ height : int
376
+ The height of the block.
377
+ count : int
378
+ The count of blocks.
379
+
380
+ Returns
381
+ -------
382
+ Dict[str, Any]
383
+ The response from the daemon.
384
+
385
+ """
386
+ return await self._request(
387
+ "get_coinbase_tx_sum", {"height": height, "count": count}
388
+ )
389
+
390
+ async def get_fee_estimate(
391
+ self, grace_blocks: Optional[int] = None
392
+ ) -> Dict[str, Any]:
393
+ """
394
+ Get the fee estimate.
395
+
396
+ Parameters
397
+ ----------
398
+ grace_blocks : int, optional
399
+ The number of grace blocks.
400
+
401
+ Returns
402
+ -------
403
+ Dict[str, Any]
404
+ The response from the daemon.
405
+
406
+ """
407
+ return await self._request(
408
+ "get_fee_estimate",
409
+ {"grace_blocks": grace_blocks} if grace_blocks else {},
410
+ )
411
+
412
+ async def get_alternate_chains(self) -> Dict[str, Any]:
413
+ """
414
+ Get the alternate chains.
415
+
416
+ Returns
417
+ -------
418
+ Dict[str, Any]
419
+ The response from the daemon.
420
+
421
+ """
422
+ return await self._request("get_alternate_chains", {})
423
+
424
+ async def relay_tx(self, txids: list) -> Dict[str, Any]:
425
+ """
426
+ Relay transactions to the network.
427
+
428
+ Parameters
429
+ ----------
430
+ txids : list
431
+ The transaction IDs to relay.
432
+
433
+ Returns
434
+ -------
435
+ Dict[str, Any]
436
+ The response from the daemon.
437
+
438
+ """
439
+ return await self._request("relay_tx", {"txids": txids})
440
+
441
+ async def sync_info(self) -> Dict[str, Any]:
442
+ """
443
+ Get the sync information of the daemon.
444
+
445
+ Returns
446
+ -------
447
+ Dict[str, Any]
448
+ The response from the daemon.
449
+
450
+ """
451
+ return await self._request("sync_info", {})
452
+
453
+ async def get_txpool_backlog(self) -> Dict[str, Any]:
454
+ """
455
+ Get the transaction pool backlog.
456
+
457
+ Returns
458
+ -------
459
+ Dict[str, Any]
460
+ The response from the daemon.
461
+
462
+ """
463
+ return await self._request("get_txpool_backlog", {})
464
+
465
+ async def get_output_distribution(
466
+ self,
467
+ amounts: list[int],
468
+ from_height: Optional[int] = 0,
469
+ to_height: Optional[int] = 0,
470
+ cumulative: Optional[bool] = False,
471
+ binary: Optional[bool] = True,
472
+ compress: Optional[bool] = False,
473
+ ) -> Dict[str, Any]:
474
+ """
475
+ Get the output distribution.
476
+
477
+ Parameters
478
+ ----------
479
+ amounts : list[int]
480
+ The amounts to get the distribution for.
481
+ from_height : int, optional
482
+ The height to start from.
483
+ to_height : int, optional
484
+ The height to end at.
485
+ cumulative : bool, optional
486
+ Whether to get the cumulative distribution.
487
+ binary : bool, optional
488
+ Whether to get the binary distribution.
489
+ compress : bool, optional
490
+ Whether to compress the distribution.
491
+
492
+ Returns
493
+ -------
494
+ Dict[str, Any]
495
+ The response from the daemon.
496
+
497
+ """
498
+ return await self._request(
499
+ "get_output_distribution",
500
+ {
501
+ "amounts": amounts,
502
+ "from_height": from_height,
503
+ "to_height": to_height,
504
+ "cumulative": cumulative,
505
+ "binary": binary,
506
+ "compress": compress,
507
+ },
508
+ )
509
+
510
+ async def prune_blockchain(self) -> Dict[str, Any]:
511
+ """
512
+ Prune the blockchain.
513
+
514
+ Returns
515
+ -------
516
+ Dict[str, Any]
517
+ The response from the daemon.
518
+
519
+ """
520
+ return await self._request("prune_blockchain", {})
521
+
522
+ async def flush_cache(self, bad_txs: Optional[bool] = False) -> Dict[str, Any]:
523
+ """
524
+ Flush the cache.
525
+
526
+ Parameters
527
+ ----------
528
+ bad_txs : bool, optional
529
+ Whether to flush the bad transactions.
530
+
531
+ Returns
532
+ -------
533
+ Dict[str, Any]
534
+ The response from the daemon.
535
+
536
+ """
537
+ return await self._request("flush_cache", {"bad_txs": bad_txs})
538
+
539
+ async def get_generated_coins(
540
+ self, height: Optional[int] = None
541
+ ) -> Dict[str, Any]:
542
+ """
543
+ Get the generated coins.
544
+
545
+ Parameters
546
+ ----------
547
+ height : int, optional
548
+ The height.
549
+
550
+ Returns
551
+ -------
552
+ Dict[str, Any]
553
+ The response from the daemon.
554
+
555
+ """
556
+ return await self._request(
557
+ "get_generated_coins", {"height": height} if height else {}
558
+ )
559
+
560
+ async def get_min_version(self) -> Dict[str, Any]:
561
+ """
562
+ Get the minimum version of the daemon.
563
+
564
+ Returns
565
+ -------
566
+ Dict[str, Any]
567
+ The response from the daemon.
568
+
569
+ """
570
+ return await self._request("get_min_version", {})
571
+
572
+ async def get_tx_pubkey(self, extra: str) -> Dict[str, Any]:
573
+ """
574
+ Get the transaction public key.
575
+
576
+ Parameters
577
+ ----------
578
+ extra : str
579
+ The extra data.
580
+
581
+ Returns
582
+ -------
583
+ Dict[str, Any]
584
+ The response from the daemon.
585
+
586
+ """
587
+ return await self._request("get_tx_pubkey", {"extra": extra})
588
+
589
+ async def decode_outputs(
590
+ self, tx_hashes: list, sec_view_key: str, address: str
591
+ ) -> Dict[str, Any]:
592
+ """
593
+ Decode the outputs of transactions.
594
+
595
+ Parameters
596
+ ----------
597
+ tx_hashes : list
598
+ The transaction hashes.
599
+ sec_view_key : str
600
+ The secret view key.
601
+ address : str
602
+ The address to decode.
603
+
604
+ Returns
605
+ -------
606
+ Dict[str, Any]
607
+ The response from the daemon.
608
+
609
+ """
610
+ return await self._request(
611
+ "decode_outputs",
612
+ {
613
+ "tx_hashes": tx_hashes,
614
+ "sec_view_key": sec_view_key,
615
+ "address": address,
616
+ },
617
+ )
618
+
619
+ async def add_peer(self, host: str) -> Dict[str, Any]:
620
+ """
621
+ Add a peer to the daemon.
622
+
623
+ Parameters
624
+ ----------
625
+ host : str
626
+ The host of the peer.
627
+
628
+ Returns
629
+ -------
630
+ Dict[str, Any]
631
+ The response from the daemon.
632
+
633
+ """
634
+ return await self._request("add_peer", {"host": host})
635
+
636
+
637
+ class DaemonOther:
638
+ """
639
+ A class to interact with the Nerva daemon's independent endpoint methods.
640
+
641
+ Parameters
642
+ ----------
643
+ host : str, optional
644
+ The host of the daemon.
645
+ port : int, optional
646
+ The port of the daemon.
647
+ ssl : bool, optional
648
+ Whether to use SSL.
649
+ timeout : float, optional
650
+ The timeout for the request.
651
+
652
+ Attributes
653
+ ----------
654
+ url : str
655
+ The URL of the daemon.
656
+ timeout : float
657
+ The timeout for the request.
658
+ headers : dict
659
+ The headers for the request.
660
+
661
+ """
662
+
663
+ __slots__ = ["url", "timeout", "headers"]
664
+
665
+ def __init__(
666
+ self,
667
+ host: Optional[str] = "localhost",
668
+ port: Optional[int] = 17566,
669
+ ssl: Optional[bool] = False,
670
+ timeout: Optional[float] = 10.0,
671
+ ):
672
+ self.url = f"{'https' if ssl else 'http'}://{host}:{port}"
673
+ self.timeout = timeout
674
+
675
+ self.headers = {"Content-Type": "application/json"}
676
+
677
+ async def _request(
678
+ self, endpoint: str, params: Dict[str, Any]
679
+ ) -> Dict[str, Any]:
680
+ async with aiohttp.ClientSession() as session:
681
+ async with session.post(
682
+ f"{self.url}/{endpoint}",
683
+ json=params,
684
+ headers=self.headers,
685
+ timeout=self.timeout,
686
+ ) as response:
687
+ return await response.json(content_type=None)
688
+
689
+ async def get_height(self) -> Dict[str, Any]:
690
+ """
691
+ Get the current block height.
692
+
693
+ Returns
694
+ -------
695
+ Dict[str, Any]
696
+ The response from the daemon.
697
+
698
+ """
699
+ return await self._request("get_height", {})
700
+
701
+ async def get_blocks_bin(
702
+ self, block_ids: list[str], start_height: int, prune: bool
703
+ ) -> Dict[str, Any]:
704
+ """
705
+ Get a list of blocks.
706
+
707
+ Parameters
708
+ ----------
709
+ block_ids : list[str]
710
+ Binary list of block IDs.
711
+ start_height : int
712
+ The start height.
713
+ prune : bool
714
+ Whether to prune the blocks.
715
+
716
+ Returns
717
+ -------
718
+ Dict[str, Any]
719
+ The response from the daemon.
720
+
721
+ """
722
+ return await self._request(
723
+ "get_blocks.bin",
724
+ {"block_ids": block_ids, "start_height": start_height, "prune": prune},
725
+ )
726
+
727
+ async def get_blocks_by_height_bin(self, heights: List[int]) -> Dict[str, Any]:
728
+ """
729
+ Get a list of blocks by height.
730
+
731
+ Parameters
732
+ ----------
733
+ heights : List[int]
734
+ The block heights to get.
735
+
736
+ Returns
737
+ -------
738
+ Dict[str, Any]
739
+ The response from the daemon.
740
+
741
+ """
742
+ return await self._request("get_blocks_by_height.bin", {"heights": heights})
743
+
744
+ async def get_hashes_bin(
745
+ self, block_ids: List[str], start_height: int
746
+ ) -> Dict[str, Any]:
747
+ """
748
+ Get the hashes of blocks.
749
+
750
+ Parameters
751
+ ----------
752
+ block_ids : list[str]
753
+ Binary list of block IDs.
754
+ start_height : int
755
+ The start height.
756
+
757
+ Returns
758
+ -------
759
+ Dict[str, Any]
760
+ The response from the daemon.
761
+
762
+ """
763
+ return await self._request(
764
+ "get_hashes.bin", {"block_ids": block_ids, "start_height": start_height}
765
+ )
766
+
767
+ async def get_o_indexes_bin(self, txid: str) -> Dict[str, Any]:
768
+ """
769
+ Get the output indexes of a transaction.
770
+
771
+ Parameters
772
+ ----------
773
+ txid : str
774
+ Binary transaction ID.
775
+
776
+ Returns
777
+ -------
778
+ Dict[str, Any]
779
+ The response from the daemon.
780
+
781
+ """
782
+ return await self._request("get_o_indexes.bin", {"txid": txid})
783
+
784
+ async def get_outs_bin(self, outputs: List[Dict[str, Any]]) -> Dict[str, Any]:
785
+ """
786
+ Get the outputs.
787
+
788
+ Parameters
789
+ ----------
790
+ outputs : List[Dict[str, Any]]
791
+ List of outputs as dictionaries with the following keys:
792
+ - amount : int
793
+ The amount.
794
+ - index : int
795
+ The index.
796
+
797
+ Returns
798
+ -------
799
+ Dict[str, Any]
800
+ The response from the daemon.
801
+
802
+ """
803
+ return await self._request("get_outs.bin", {"outputs": outputs})
804
+
805
+ async def get_transactions(
806
+ self,
807
+ txs_hashes: list[str],
808
+ decode_as_json: Optional[bool] = False,
809
+ prune: Optional[bool] = False,
810
+ split: Optional[bool] = False,
811
+ ) -> Dict[str, Any]:
812
+ """
813
+ Get a list of transactions.
814
+
815
+ Parameters
816
+ ----------
817
+ txs_hashes : list[str]
818
+ List of transaction hashes.
819
+ decode_as_json : bool, optional
820
+ Whether to decode as JSON.
821
+ prune : bool, optional
822
+ Whether to prune the transactions.
823
+ split : bool, optional
824
+ Whether to split the transactions.
825
+
826
+ Returns
827
+ -------
828
+ Dict[str, Any]
829
+ The response from the daemon.
830
+
831
+ """
832
+ return await self._request(
833
+ "get_transactions",
834
+ {
835
+ "txs_hashes": txs_hashes,
836
+ "decode_as_json": decode_as_json,
837
+ "prune": prune,
838
+ "split": split,
839
+ },
840
+ )
841
+
842
+ async def get_alt_blocks_hashes(self) -> Dict[str, Any]:
843
+ """
844
+ Get the hashes of alternate blocks.
845
+
846
+ Returns
847
+ -------
848
+ Dict[str, Any]
849
+ The response from the daemon.
850
+
851
+ """
852
+ return await self._request("get_alt_blocks_hashes", {})
853
+
854
+ async def is_key_image_spent(self, key_images: List[str]) -> Dict[str, Any]:
855
+ """
856
+ Check if key images are spent.
857
+
858
+ Parameters
859
+ ----------
860
+ key_images : List[str]
861
+ List of key images.
862
+
863
+ Returns
864
+ -------
865
+ Dict[str, Any]
866
+ The response from the daemon.
867
+
868
+ """
869
+ return await self._request("is_key_image_spent", {"key_images": key_images})
870
+
871
+ async def send_raw_transaction(
872
+ self, tx_as_hex: str, do_not_relay: Optional[bool] = False
873
+ ) -> Dict[str, Any]:
874
+ """
875
+ Send a raw transaction.
876
+
877
+ Parameters
878
+ ----------
879
+ tx_as_hex : str
880
+ The transaction as hex.
881
+ do_not_relay : bool, optional
882
+ Whether to relay the transaction.
883
+
884
+ Returns
885
+ -------
886
+ Dict[str, Any]
887
+ The response from the daemon.
888
+
889
+ """
890
+ return await self._request(
891
+ "send_raw_transaction",
892
+ {"tx_as_hex": tx_as_hex, "do_not_relay": do_not_relay},
893
+ )
894
+
895
+ async def start_mining(
896
+ self,
897
+ address: str,
898
+ threads_count: int,
899
+ do_background_mining: bool,
900
+ ignore_battery: bool,
901
+ ) -> Dict[str, Any]:
902
+ """
903
+ Start mining.
904
+
905
+ Parameters
906
+ ----------
907
+ address : str
908
+ The address to mine to.
909
+ threads_count : int
910
+ The number of threads.
911
+ do_background_mining : bool
912
+ Whether to mine in the background.
913
+ ignore_battery : bool
914
+ Whether to ignore the battery.
915
+
916
+ Returns
917
+ -------
918
+ Dict[str, Any]
919
+ The response from the daemon.
920
+
921
+ """
922
+ return await self._request(
923
+ "start_mining",
924
+ {
925
+ "address": address,
926
+ "threads_count": threads_count,
927
+ "do_background_mining": do_background_mining,
928
+ "ignore_battery": ignore_battery,
929
+ },
930
+ )
931
+
932
+ async def set_donate_level(self, blocks: int) -> Dict[str, Any]:
933
+ """
934
+ Set the donate level.
935
+
936
+ Parameters
937
+ ----------
938
+ blocks : int
939
+ The number of blocks to donate.
940
+
941
+ Returns
942
+ -------
943
+ Dict[str, Any]
944
+ The response from the daemon.
945
+
946
+ """
947
+ return await self._request("set_donate_level", {"blocks": blocks})
948
+
949
+ async def stop_mining(self) -> Dict[str, Any]:
950
+ """
951
+ Stop mining.
952
+
953
+ Returns
954
+ -------
955
+ Dict[str, Any]
956
+ The response from the daemon.
957
+
958
+ """
959
+ return await self._request("stop_mining", {})
960
+
961
+ async def mining_status(self) -> Dict[str, Any]:
962
+ """
963
+ Get the mining status.
964
+
965
+ Returns
966
+ -------
967
+ Dict[str, Any]
968
+ The response from the daemon.
969
+
970
+ """
971
+ return await self._request("mining_status", {})
972
+
973
+ async def save_bc(self) -> Dict[str, Any]:
974
+ """
975
+ Save the blockchain.
976
+
977
+ Returns
978
+ -------
979
+ Dict[str, Any]
980
+ The response from the daemon.
981
+
982
+ """
983
+ return await self._request("save_bc", {})
984
+
985
+ async def get_peer_list(self) -> Dict[str, Any]:
986
+ """
987
+ Get the peer list.
988
+
989
+ Returns
990
+ -------
991
+ Dict[str, Any]
992
+ The response from the daemon.
993
+
994
+ """
995
+ return await self._request("get_peer_list", {})
996
+
997
+ async def get_public_nodes(self) -> Dict[str, Any]:
998
+ """
999
+ Get the public nodes.
1000
+
1001
+ Returns
1002
+ -------
1003
+ Dict[str, Any]
1004
+ The response from the daemon.
1005
+
1006
+ """
1007
+ return await self._request("get_public_nodes", {})
1008
+
1009
+ async def set_log_hash_rate(self, visible: bool) -> Dict[str, Any]:
1010
+ """
1011
+ Set the log hash rate.
1012
+
1013
+ Parameters
1014
+ ----------
1015
+ visible : bool
1016
+ Whether to make the hash rate visible.
1017
+
1018
+ Returns
1019
+ -------
1020
+ Dict[str, Any]
1021
+ The response from the daemon.
1022
+
1023
+ """
1024
+ return await self._request("set_log_hash_rate", {"visible": visible})
1025
+
1026
+ async def set_log_level(self, level: int) -> Dict[str, Any]:
1027
+ """
1028
+ Set the log level.
1029
+
1030
+ Parameters
1031
+ ----------
1032
+ level : int
1033
+ The log level.
1034
+
1035
+ Returns
1036
+ -------
1037
+ Dict[str, Any]
1038
+ The response from the daemon.
1039
+
1040
+ """
1041
+ return await self._request("set_log_level", {"level": level})
1042
+
1043
+ async def set_log_categories(self, categories: str) -> Dict[str, Any]:
1044
+ """
1045
+ Set the log categories.
1046
+
1047
+ Parameters
1048
+ ----------
1049
+ categories : str
1050
+ The log categories.
1051
+
1052
+ Returns
1053
+ -------
1054
+ Dict[str, Any]
1055
+ The response from the daemon.
1056
+
1057
+ """
1058
+ return await self._request("set_log_categories", {"categories": categories})
1059
+
1060
+ async def get_transaction_pool(self) -> Dict[str, Any]:
1061
+ """
1062
+ Get the transaction pool.
1063
+
1064
+ Returns
1065
+ -------
1066
+ Dict[str, Any]
1067
+ The response from the daemon.
1068
+
1069
+ """
1070
+ return await self._request("get_transaction_pool", {})
1071
+
1072
+ async def get_transaction_pool_hashes_bin(self) -> Dict[str, Any]:
1073
+ """
1074
+ Get the transaction pool hashes.
1075
+
1076
+ Returns
1077
+ -------
1078
+ Dict[str, Any]
1079
+ The response from the daemon.
1080
+
1081
+ """
1082
+ return await self._request("get_transaction_pool_hashes.bin", {})
1083
+
1084
+ async def get_transaction_pool_hashes(self) -> Dict[str, Any]:
1085
+ """
1086
+ Get the transaction pool hashes.
1087
+
1088
+ Returns
1089
+ -------
1090
+ Dict[str, Any]
1091
+ The response from the daemon.
1092
+
1093
+ """
1094
+ return await self._request("get_transaction_pool_hashes", {})
1095
+
1096
+ async def get_transaction_pool_stats(self) -> Dict[str, Any]:
1097
+ """
1098
+ Get the transaction pool stats.
1099
+
1100
+ Returns
1101
+ -------
1102
+ Dict[str, Any]
1103
+ The response from the daemon.
1104
+
1105
+ """
1106
+ return await self._request("get_transaction_pool_stats", {})
1107
+
1108
+ async def set_bootstrap_daemon(
1109
+ self, address: str, username: str, password: str
1110
+ ) -> Dict[str, Any]:
1111
+ """
1112
+ Set the bootstrap daemon.
1113
+
1114
+ Parameters
1115
+ ----------
1116
+ address : str
1117
+ The address of the daemon.
1118
+ username : str
1119
+ The username.
1120
+ password : str
1121
+ The password.
1122
+
1123
+ Returns
1124
+ -------
1125
+ Dict[str, Any]
1126
+ The response from the daemon.
1127
+
1128
+ """
1129
+ return await self._request(
1130
+ "set_bootstrap_daemon",
1131
+ {"address": address, "username": username, "password": password},
1132
+ )
1133
+
1134
+ async def stop_daemon(self) -> Dict[str, Any]:
1135
+ """
1136
+ Stop the daemon.
1137
+
1138
+ Returns
1139
+ -------
1140
+ Dict[str, Any]
1141
+ The response from the daemon.
1142
+
1143
+ """
1144
+ return await self._request("stop_daemon", {})
1145
+
1146
+ async def get_info(self) -> Dict[str, Any]:
1147
+ """
1148
+ Get the information of the daemon.
1149
+
1150
+ Returns
1151
+ -------
1152
+ Dict[str, Any]
1153
+ The response from the daemon.
1154
+
1155
+ """
1156
+ return await self._request("get_info", {})
1157
+
1158
+ async def get_net_stats(self) -> Dict[str, Any]:
1159
+ """
1160
+ Get the network stats.
1161
+
1162
+ Returns
1163
+ -------
1164
+ Dict[str, Any]
1165
+ The response from the daemon.
1166
+
1167
+ """
1168
+ return await self._request("get_net_stats", {})
1169
+
1170
+ async def get_limit(self) -> Dict[str, Any]:
1171
+ """
1172
+ Get daemon bandwidth limits.
1173
+
1174
+ Returns
1175
+ -------
1176
+ Dict[str, Any]
1177
+ The response from the daemon.
1178
+
1179
+ """
1180
+ return await self._request("get_limit", {})
1181
+
1182
+ async def set_limit(self, limit_down: int, limit_up: int) -> Dict[str, Any]:
1183
+ """
1184
+ Set daemon bandwidth limits.
1185
+
1186
+ Parameters
1187
+ ----------
1188
+ limit_down : int
1189
+ The download limit. (-1 to change to default; 0 for no change)
1190
+ limit_up : int
1191
+ The upload limit. (-1 to change to default; 0 for no change)
1192
+
1193
+ Returns
1194
+ -------
1195
+ Dict[str, Any]
1196
+ The response from the daemon.
1197
+
1198
+ """
1199
+ return await self._request(
1200
+ "set_limit", {"limit_down": limit_down, "limit_up": limit_up}
1201
+ )
1202
+
1203
+ async def out_peers(self) -> Dict[str, Any]:
1204
+ """
1205
+ Get the outgoing peers.
1206
+
1207
+ Returns
1208
+ -------
1209
+ Dict[str, Any]
1210
+ The response from the daemon.
1211
+
1212
+ """
1213
+ return await self._request("out_peers", {})
1214
+
1215
+ async def in_peers(self) -> Dict[str, Any]:
1216
+ """
1217
+ Get the incoming peers.
1218
+
1219
+ Returns
1220
+ -------
1221
+ Dict[str, Any]
1222
+ The response from the daemon.
1223
+
1224
+ """
1225
+ return await self._request("in_peers", {})
1226
+
1227
+ async def get_outs(
1228
+ self, outputs: List[Dict[str, Any]], get_txid: bool
1229
+ ) -> Dict[str, Any]:
1230
+ """
1231
+ Get outputs.
1232
+
1233
+ Parameters
1234
+ ----------
1235
+ outputs : List[Dict[str, Any]]
1236
+ List of outputs as dictionaries with the following keys:
1237
+ - amount : int
1238
+ The amount.
1239
+ - index : int
1240
+ The index.
1241
+ get_txid : bool
1242
+ Whether to get the transaction ID.
1243
+
1244
+ Returns
1245
+ -------
1246
+ Dict[str, Any]
1247
+ The response from the daemon.
1248
+
1249
+ """
1250
+ return await self._request(
1251
+ "get_outs", {"outputs": outputs, "get_txid": get_txid}
1252
+ )
1253
+
1254
+ async def update(self) -> Dict[str, Any]:
1255
+ """
1256
+ Update the daemon.
1257
+
1258
+ Returns
1259
+ -------
1260
+ Dict[str, Any]
1261
+ The response from the daemon.
1262
+
1263
+ """
1264
+ return await self._request("update", {})
1265
+
1266
+ async def get_output_distribution_bin(
1267
+ self,
1268
+ amounts: list[int],
1269
+ from_height: Optional[int] = 0,
1270
+ to_height: Optional[int] = 0,
1271
+ cumulative: Optional[bool] = False,
1272
+ binary: Optional[bool] = True,
1273
+ compress: Optional[bool] = False,
1274
+ ) -> Dict[str, Any]:
1275
+ """
1276
+ Get the output distribution.
1277
+
1278
+ Parameters
1279
+ ----------
1280
+ amounts : list[int]
1281
+ The amounts to get the distribution for.
1282
+ from_height : int, optional
1283
+ The height to start from.
1284
+ to_height : int, optional
1285
+ The height to end at.
1286
+ cumulative : bool, optional
1287
+ Whether to get the cumulative distribution.
1288
+ binary : bool, optional
1289
+ Whether to get the binary distribution.
1290
+ compress : bool, optional
1291
+ Whether to compress the distribution.
1292
+
1293
+ Returns
1294
+ -------
1295
+ Dict[str, Any]
1296
+ The response from the daemon.
1297
+
1298
+ """
1299
+ return await self._request(
1300
+ "get_output_distribution.bin",
1301
+ {
1302
+ "amounts": amounts,
1303
+ "from_height": from_height,
1304
+ "to_height": to_height,
1305
+ "cumulative": cumulative,
1306
+ "binary": binary,
1307
+ "compress": compress,
1308
+ },
1309
+ )
1310
+
1311
+ async def pop_blocks(self, nblocks: int) -> Dict[str, Any]:
1312
+ """
1313
+ Pop blocks from the blockchain.
1314
+
1315
+ Parameters
1316
+ ----------
1317
+ nblocks : int
1318
+ The number of blocks to pop.
1319
+
1320
+ Returns
1321
+ -------
1322
+ Dict[str, Any]
1323
+ The response from the daemon.
1324
+
1325
+ """
1326
+ return await self._request("pop_blocks", {"nblocks": nblocks})