├── .gitignore ├── README.md └── src ├── bitmonerod_basic_rpc_call_01.py ├── bitmonerod_basic_rpc_call_02.py ├── bitmonerod_basic_rpc_call_03.py ├── bitmonerod_basic_rpc_call_04.py ├── simplewallet_basic_rpc_call_01.py ├── simplewallet_basic_rpc_call_02.py ├── simplewallet_basic_rpc_call_03.py ├── simplewallet_basic_rpc_call_04.py └── simplewallet_rpc_examples.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .sass-cache 3 | *.*~ 4 | .idea/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Example usage of json-rpc in Python for Monero 2 | 3 | Monero is a secure, private, untraceable cryptocurrency. For more information or questions, 4 | please go to [getmonero.org](https://getmonero.org) and 5 | [r/Monero](https://www.reddit.com/r/Monero), respectively. 6 | 7 | The two main components of monero are `simplewallet` and `bitmonerod`. The first one 8 | is the wallet, as the name suggest. The second one is monero deamon, which is responsbile 9 | for interacting with monero blockchain. 10 | 11 | Most important functions of Monero's `simplewallet` and 12 | `bitmonreod` can be executed by means of JavaScript Object Notation Remote Procedure Calls ([json-rpc](https://en.wikipedia.org/wiki/JSON-RPC)). 13 | 14 | Using these procedures, other applications can be developed 15 | on top of the `simplewallet` and `bitmonerod`. For examples, a GUI wallet, 16 | an web applications allowing for accessing wallet balance 17 | online, and block explorer. 18 | 19 | Since there seem to be no tutorials and/or examples of how 20 | to use json-rpc to interact with both `bitmonerod` and `simplewallet`, 21 | the following examples in Python were created. Hopefully, they will allow others to start developing some python 22 | programs on top of Monero. 23 | 24 | ## simplewallet 25 | The examples demonstrate how to call the most popular procedures 26 | that `simplewallet` exposes for other applications to use, such as: 27 | 28 | - getbalance 29 | - query_key 30 | - get_payments 31 | - getaddress 32 | - incoming_transfers 33 | - transfer 34 | 35 | The basic documentaion of the procedures can be found 36 | [here](https://getmonero.org/knowledge-base/developer-guides/wallet-rpc). 37 | 38 | **Prerequsits** 39 | 40 | Before executing this code make sure that `simplewallet` is 41 | running and listening for the incoming rpc calls. For example, you can run the `simplewallet `in rpc mode as follows: 42 | ``` 43 | /opt/bitmonero/simplewallet --wallet-file ~/wallet.bin --password --rpc-bind-port 18082 44 | ``` 45 | 46 | The code was written, tested and executed on Ubuntu 15.10 with 47 | Python 3.4.3 and requires the [Requests package](https://pypi.python.org/pypi/requests). 48 | 49 | **Basic example 1: get wallet balance** 50 | ```python 51 | import requests 52 | import json 53 | 54 | def main(): 55 | 56 | # simple wallet is running on the localhost and port of 18082 57 | url = "http://localhost:18082/json_rpc" 58 | 59 | # standard json header 60 | headers = {'content-type': 'application/json'} 61 | 62 | # simplewallet' procedure/method to call 63 | rpc_input = { 64 | "method": "getbalance" 65 | } 66 | 67 | # add standard rpc values 68 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 69 | 70 | # execute the rpc request 71 | response = requests.post( 72 | url, 73 | data=json.dumps(rpc_input), 74 | headers=headers) 75 | 76 | # amounts in cryptonote are encoded in a way which is convenient 77 | # for a computer, not a user. Thus, its better need to recode them 78 | # to something user friendly, before displaying them. 79 | # 80 | # For examples: 81 | # 4760000000000 is 4.76 82 | # 80000000000 is 0.08 83 | # 84 | # In example 3 "Basic example 3: get incoming transfers" it is 85 | # shown how to convert cryptonote values to user friendly format. 86 | 87 | # pretty print json output 88 | print(json.dumps(response.json(), indent=4)) 89 | 90 | if __name__ == "__main__": 91 | main() 92 | ``` 93 | 94 | Generated output: 95 | ```python 96 | { 97 | "jsonrpc": "2.0", 98 | "id": "0", 99 | "result": { 100 | "unlocked_balance": 4760000000000, 101 | "balance": 4760000000000 102 | } 103 | } 104 | ``` 105 | 106 | 107 | 108 | **Basic example 2: get a payment information having payment id** 109 | ```python 110 | import requests 111 | import json 112 | 113 | def main(): 114 | 115 | # simple wallet is running on the localhost and port of 18082 116 | url = "http://localhost:18082/json_rpc" 117 | 118 | # standard json header 119 | headers = {'content-type': 'application/json'} 120 | 121 | # an example of a payment id 122 | payment_id = "426870cb29c598e191184fa87003ca562d9e25f761ee9e520a888aec95195912" 123 | 124 | # simplewallet' procedure/method to call 125 | rpc_input = { 126 | "method": "get_payments", 127 | "params": {"payment_id": payment_id} 128 | } 129 | 130 | # add standard rpc values 131 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 132 | 133 | # execute the rpc request 134 | response = requests.post( 135 | url, 136 | data=json.dumps(rpc_input), 137 | headers=headers) 138 | 139 | # pretty print json output 140 | print(json.dumps(response.json(), indent=4)) 141 | 142 | if __name__ == "__main__": 143 | main() 144 | ``` 145 | 146 | Generated output: 147 | ```python 148 | { 149 | "result": { 150 | "payments": [ 151 | { 152 | "tx_hash": "66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577", 153 | "amount": 4800000000000, 154 | "block_height": 795523, 155 | "payment_id": "426870cb29c598e191184fa87003ca562d9e25f761ee9e520a888aec95195912", 156 | "unlock_time": 0 157 | } 158 | ] 159 | }, 160 | "jsonrpc": "2.0", 161 | "id": "0" 162 | } 163 | ``` 164 | 165 | 166 | 167 | **Basic example 3: get incoming transfers** 168 | 169 | ```python 170 | import requests 171 | import json 172 | 173 | def main(): 174 | 175 | # simple wallet is running on the localhost and port of 18082 176 | url = "http://localhost:18082/json_rpc" 177 | 178 | # standard json header 179 | headers = {'content-type': 'application/json'} 180 | 181 | # simplewallet' procedure/method to call 182 | rpc_input = { 183 | "method": "incoming_transfers", 184 | "params": {"transfer_type": "all"} 185 | } 186 | 187 | # add standard rpc values 188 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 189 | 190 | # execute the rpc request 191 | response = requests.post( 192 | url, 193 | data=json.dumps(rpc_input), 194 | headers=headers) 195 | 196 | # make json dict with response 197 | response_json = response.json() 198 | 199 | # amounts in cryptonote are encoded in a way which is convenient 200 | # for a computer, not a user. Thus, its better need to recode them 201 | # to something user friendly, before displaying them. 202 | # 203 | # For examples: 204 | # 4760000000000 is 4.76 205 | # 80000000000 is 0.08 206 | # 207 | if "result" in response_json: 208 | if "transfers" in response_json["result"]: 209 | for transfer in response_json["result"]["transfers"]: 210 | transfer["amount"] = float(get_money(str(transfer["amount"]))) 211 | 212 | 213 | # pretty print json output 214 | print(json.dumps(response_json, indent=4)) 215 | 216 | def get_money(amount): 217 | """decode cryptonote amount format to user friendly format. Hope its correct. 218 | 219 | Based on C++ code: 220 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L751 221 | """ 222 | 223 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 224 | 225 | s = amount 226 | 227 | if len(s) < CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1: 228 | # add some trailing zeros, if needed, to have constant width 229 | s = '0' * (CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1 - len(s)) + s 230 | 231 | idx = len(s) - CRYPTONOTE_DISPLAY_DECIMAL_POINT 232 | 233 | s = s[0:idx] + "." + s[idx:] 234 | 235 | return s 236 | 237 | if __name__ == "__main__": 238 | main() 239 | ``` 240 | 241 | Generated output: 242 | ```python 243 | { 244 | "jsonrpc": "2.0", 245 | "result": { 246 | "transfers": [ 247 | { 248 | "tx_hash": "<66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577>", 249 | "tx_size": 521, 250 | "spent": true, 251 | "global_index": 346865, 252 | "amount": 0.8 253 | }, 254 | { 255 | "tx_hash": "<66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577>", 256 | "tx_size": 521, 257 | "spent": true, 258 | "global_index": 177947, 259 | "amount": 4.0 260 | }, 261 | { 262 | "tx_hash": "<79e7eb67b7022a21505fa034388b5e3b29e1ce639d6dec37347fefa612117ce9>", 263 | "tx_size": 562, 264 | "spent": false, 265 | "global_index": 165782, 266 | "amount": 0.08 267 | }, 268 | { 269 | "tx_hash": "<79e7eb67b7022a21505fa034388b5e3b29e1ce639d6dec37347fefa612117ce9>", 270 | "tx_size": 562, 271 | "spent": false, 272 | "global_index": 300597, 273 | "amount": 0.9 274 | }, 275 | { 276 | "tx_hash": "<79e7eb67b7022a21505fa034388b5e3b29e1ce639d6dec37347fefa612117ce9>", 277 | "tx_size": 562, 278 | "spent": false, 279 | "global_index": 214803, 280 | "amount": 3.0 281 | }, 282 | { 283 | "tx_hash": "", 284 | "tx_size": 525, 285 | "spent": false, 286 | "global_index": 165783, 287 | "amount": 0.08 288 | }, 289 | { 290 | "tx_hash": "", 291 | "tx_size": 525, 292 | "spent": false, 293 | "global_index": 375952, 294 | "amount": 0.7 295 | } 296 | ] 297 | }, 298 | "id": "0" 299 | } 300 | ``` 301 | 302 | **Basic example 4: make a transaction** 303 | ```python 304 | import requests 305 | import json 306 | import os 307 | import binascii 308 | 309 | 310 | def main(): 311 | """DONT RUN IT without changing the destination address!!!""" 312 | 313 | # simple wallet is running on the localhost and port of 18082 314 | url = "http://localhost:18082/json_rpc" 315 | 316 | # standard json header 317 | headers = {'content-type': 'application/json'} 318 | 319 | destination_address = "489MAxaT7xXP3Etjk2suJT1uDYZU6cqFycsau2ynCTBacncWVEwe9eYFrAD6BqTn4Y2KMs7maX75iX1UFwnJNG5G88wxKoj" 320 | 321 | 322 | # amount of xmr to send 323 | amount = 0.54321 324 | 325 | # cryptonote amount format is different then 326 | # that normally used by people. 327 | # thus the float amount must be changed to 328 | # something that cryptonote understands 329 | int_amount = int(get_amount(amount)) 330 | 331 | # just to make sure that amount->coversion->back 332 | # gives the same amount as in the initial number 333 | assert amount == float(get_money(str(int_amount))), "Amount conversion failed" 334 | 335 | # send specified xmr amount to the given destination_address 336 | recipents = [{"address": destination_address, 337 | "amount": int_amount}] 338 | 339 | # using given mixin 340 | mixin = 4 341 | 342 | # get some random payment_id 343 | payment_id = get_payment_id() 344 | 345 | # simplewallet' procedure/method to call 346 | rpc_input = { 347 | "method": "transfer", 348 | "params": {"destinations": recipents, 349 | "mixin": mixin, 350 | "payment_id" : payment_id} 351 | } 352 | 353 | # add standard rpc values 354 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 355 | 356 | # execute the rpc request 357 | response = requests.post( 358 | url, 359 | data=json.dumps(rpc_input), 360 | headers=headers) 361 | 362 | # print the payment_id 363 | print("#payment_id: ", payment_id) 364 | 365 | # pretty print json output 366 | print(json.dumps(response.json(), indent=4)) 367 | 368 | 369 | def get_amount(amount): 370 | """encode amount (float number) to the cryptonote format. Hope its correct. 371 | 372 | Based on C++ code: 373 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L211 374 | """ 375 | 376 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 377 | 378 | str_amount = str(amount) 379 | 380 | fraction_size = 0 381 | 382 | if '.' in str_amount: 383 | 384 | point_index = str_amount.index('.') 385 | 386 | fraction_size = len(str_amount) - point_index - 1 387 | 388 | while fraction_size < CRYPTONOTE_DISPLAY_DECIMAL_POINT and '0' == str_amount[-1]: 389 | print(44) 390 | str_amount = str_amount[:-1] 391 | fraction_size = fraction_size - 1 392 | 393 | if CRYPTONOTE_DISPLAY_DECIMAL_POINT < fraction_size: 394 | return False 395 | 396 | str_amount = str_amount[:point_index] + str_amount[point_index+1:] 397 | 398 | if not str_amount: 399 | return False 400 | 401 | if fraction_size < CRYPTONOTE_DISPLAY_DECIMAL_POINT: 402 | str_amount = str_amount + '0'*(CRYPTONOTE_DISPLAY_DECIMAL_POINT - fraction_size) 403 | 404 | return str_amount 405 | 406 | 407 | def get_money(amount): 408 | """decode cryptonote amount format to user friendly format. Hope its correct. 409 | 410 | Based on C++ code: 411 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L751 412 | """ 413 | 414 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 415 | 416 | s = amount 417 | 418 | if len(s) < CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1: 419 | # add some trailing zeros, if needed, to have constant width 420 | s = '0' * (CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1 - len(s)) + s 421 | 422 | idx = len(s) - CRYPTONOTE_DISPLAY_DECIMAL_POINT 423 | 424 | s = s[0:idx] + "." + s[idx:] 425 | 426 | return s 427 | 428 | def get_payment_id(): 429 | """generate random payment_id 430 | 431 | generate some random payment_id for the 432 | transactions 433 | 434 | payment_id is 32 bytes (64 hexadecimal characters) 435 | thus we first generate 32 random byte array 436 | which is then change to string representation, since 437 | json will not not what to do with the byte array. 438 | """ 439 | 440 | random_32_bytes = os.urandom(32) 441 | payment_id = "".join(map(chr, binascii.hexlify(random_32_bytes))) 442 | 443 | return payment_id 444 | 445 | 446 | if __name__ == "__main__": 447 | main() 448 | ``` 449 | 450 | Generated output: 451 | 452 | ```python 453 | #payment_id: 4926869b6b5d50b24cb59f08fd76826cacdf76201b2d4648578fe610af7f786e 454 | { 455 | "id": "0", 456 | "jsonrpc": "2.0", 457 | "result": { 458 | "tx_key": "", 459 | "tx_hash": "<04764ab4855b8a9f9c42d99e19e1c40956a502260123521ca3f6488dd809797a>" 460 | } 461 | } 462 | ``` 463 | 464 | Other examples are [here](https://github.com/moneroexamples/python-json-rpc/blob/master/src/simplewallet_rpc_examples.py) 465 | 466 | ## bitmonreod 467 | 468 | The baisc `bitmonerod` rpc calls are as follows: 469 | 470 | - getheight 471 | - query_key 472 | - mining_status 473 | - getlastblockheader 474 | - getblockheaderbyhash 475 | - getblockheaderbyheight 476 | - getblock 477 | - get_info 478 | - get_connections 479 | 480 | **Prerequsits** 481 | Before executing this code make sure that `bitmonerod` is running. 482 | Just like before, the code was written, tested and executed on Ubuntu 15.10 with 483 | Python 3.4.3 and it requires the [Requests package](https://pypi.python.org/pypi/requests). 484 | 485 | 486 | **Basic example 1: get a mining status** 487 | ```python 488 | import requests 489 | import json 490 | 491 | def main(): 492 | 493 | # bitmonerod' is running on the localhost and port of 18081 494 | url = "http://localhost:18081/mining_status" 495 | 496 | # standard json header 497 | headers = {'content-type': 'application/json'} 498 | 499 | # execute the rpc request 500 | response = requests.post( 501 | url, 502 | headers=headers) 503 | 504 | # pretty print json output 505 | print(json.dumps(response.json(), indent=4)) 506 | 507 | if __name__ == "__main__": 508 | main() 509 | ``` 510 | Generated output: 511 | 512 | ```python 513 | { 514 | "status": "OK", 515 | "threads_count": 2, 516 | "speed": 117, 517 | "active": true, 518 | "address": "48daf1rG3hE1Txapcsxh6WXNe9MLNKtu7W7tKTivtSoVLHErYzvdcpea2nSTgGkz66RFP4GKVAsTV14v6G3oddBTHfxP6tU" 519 | } 520 | ``` 521 | 522 | 523 | **Basic example 2: get block header having a block hash** 524 | ```python 525 | import requests 526 | import json 527 | 528 | def main(): 529 | 530 | # bitmonerod is running on the localhost and port of 18081 531 | url = "http://localhost:18081/json_rpc" 532 | 533 | # standard json header 534 | headers = {'content-type': 'application/json'} 535 | 536 | # the block to get 537 | block_hash = 'd78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6' 538 | 539 | # bitmonerod' procedure/method to call 540 | rpc_input = { 541 | "method": "getblockheaderbyhash", 542 | "params": {"hash": block_hash} 543 | } 544 | 545 | # add standard rpc values 546 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 547 | 548 | # execute the rpc request 549 | response = requests.post( 550 | url, 551 | data=json.dumps(rpc_input), 552 | headers=headers) 553 | 554 | # pretty print json output 555 | print(json.dumps(response.json(), indent=4)) 556 | 557 | if __name__ == "__main__": 558 | main() 559 | ``` 560 | 561 | Generated output: 562 | ```python 563 | { 564 | "result": { 565 | "status": "OK", 566 | "block_header": { 567 | "difficulty": 756932534, 568 | "height": 796743, 569 | "nonce": 8389, 570 | "depth": 46, 571 | "orphan_status": false, 572 | "hash": "d78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6", 573 | "timestamp": 1445741816, 574 | "major_version": 1, 575 | "minor_version": 0, 576 | "prev_hash": "dff9c6299c84f945fabde9e96afa5d44f3c8fa88835fb87a965259c46694a2cd", 577 | "reward": 8349972377827 578 | } 579 | }, 580 | "jsonrpc": "2.0", 581 | "id": "0" 582 | } 583 | ``` 584 | 585 | 586 | **Basic example 3: get full block information** 587 | 588 | ```python 589 | import requests 590 | import json 591 | 592 | def main(): 593 | 594 | # bitmonerod is running on the localhost and port of 18082 595 | url = "http://localhost:18081/json_rpc" 596 | 597 | # standard json header 598 | headers = {'content-type': 'application/json'} 599 | 600 | # the block to get 601 | block_hash = 'd78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6' 602 | 603 | # bitmonerod' procedure/method to call 604 | rpc_input = { 605 | "method": "getblock", 606 | "params": {"hash": block_hash} 607 | } 608 | 609 | # add standard rpc values 610 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 611 | 612 | # execute the rpc request 613 | response = requests.post( 614 | url, 615 | data=json.dumps(rpc_input), 616 | headers=headers) 617 | 618 | # the response will contain binary blob. For some reason 619 | # python's json encoder will crash trying to parse such 620 | # response. Thus, its better to remove it from the response. 621 | response_json_clean = json.loads( 622 | "\n".join(filter( 623 | lambda l: "blob" not in l, response.text.split("\n") 624 | ))) 625 | 626 | # pretty print json output 627 | print(json.dumps(response_json_clean, indent=4)) 628 | 629 | if __name__ == "__main__": 630 | main() 631 | ``` 632 | 633 | Generated output: 634 | ```python 635 | { 636 | "jsonrpc": "2.0", 637 | "result": { 638 | "block_header": { 639 | "difficulty": 756932534, 640 | "major_version": 1, 641 | "height": 796743, 642 | "prev_hash": "dff9c6299c84f945fabde9e96afa5d44f3c8fa88835fb87a965259c46694a2cd", 643 | "depth": 166, 644 | "reward": 8349972377827, 645 | "minor_version": 0, 646 | "timestamp": 1445741816, 647 | "nonce": 8389, 648 | "orphan_status": false, 649 | "hash": "d78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6" 650 | }, 651 | "json": "{\n \"major_version\": 1, \n \"minor_version\": 0, \n \"timestamp\": 1445741816, \n \"prev_id\": \"dff9c6299c84f945fabde9e96afa5d44f3c8fa88835fb87a965259c46694a2cd\", \n \"nonce\": 8389, \n \"miner_tx\": {\n \"version\": 1, \n \"unlock_time\": 796803, \n \"vin\": [ {\n \"gen\": {\n \"height\": 796743\n }\n }\n ], \n \"vout\": [ {\n \"amount\": 9972377827, \n \"target\": {\n \"key\": \"aecebf2757be84a2d986052607ec3114969f7c9e128a051f5e13f2304287733d\"\n }\n }, {\n \"amount\": 40000000000, \n \"target\": {\n \"key\": \"c3a6d449f3fa837edbbc6beac8bc0405c6340c4e39418164b4aa1fa2202573f2\"\n }\n }, {\n \"amount\": 300000000000, \n \"target\": {\n \"key\": \"cfce614b779ab2705fc5f94a022eb983a2960ba9da02d61f430e988128236b0a\"\n }\n }, {\n \"amount\": 8000000000000, \n \"target\": {\n \"key\": \"b445b474d19ae555e048762e12ac8c406a4a6d7b0f37993dc8dabe7a31ef65b8\"\n }\n }\n ], \n \"extra\": [ 1, 243, 56, 214, 120, 176, 255, 133, 1, 251, 134, 27, 135, 49, 198, 55, 249, 146, 222, 116, 48, 103, 249, 229, 195, 120, 162, 127, 62, 35, 57, 231, 51, 2, 8, 0, 0, 0, 0, 25, 79, 41, 47\n ], \n \"signatures\": [ ]\n }, \n \"tx_hashes\": [ \"cc283dcae267c622d685b3e5f8e72aaba807dad0bb2d4170521af57c50be8165\", \"d2873b1c1800ce04434c663893a16417e8717015e9686914166f7957c5eabd68\"\n ]\n}", 652 | "tx_hashes": [ 653 | "cc283dcae267c622d685b3e5f8e72aaba807dad0bb2d4170521af57c50be8165", 654 | "d2873b1c1800ce04434c663893a16417e8717015e9686914166f7957c5eabd68" 655 | ], 656 | "status": "OK" 657 | }, 658 | "id": "0" 659 | } 660 | ``` 661 | 662 | **Basic example 4: get blockchain information** 663 | ```python 664 | import requests 665 | import json 666 | 667 | def main(): 668 | 669 | # bitmonerod is running on the localhost and port of 18082 670 | url = "http://localhost:18081/json_rpc" 671 | 672 | # standard json header 673 | headers = {'content-type': 'application/json'} 674 | 675 | # bitmonerod' procedure/method to call 676 | rpc_input = { 677 | "method": "get_info" 678 | } 679 | 680 | # add standard rpc values 681 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 682 | 683 | # execute the rpc request 684 | response = requests.post( 685 | url, 686 | data=json.dumps(rpc_input), 687 | headers=headers) 688 | 689 | # pretty print json output 690 | print(json.dumps(response.json(), indent=4)) 691 | 692 | if __name__ == "__main__": 693 | main() 694 | ``` 695 | 696 | 697 | Generated output: 698 | ```python 699 | { 700 | "jsonrpc": "2.0", 701 | "result": { 702 | "status": "OK", 703 | "alt_blocks_count": 0, 704 | "difficulty": 692400878, 705 | "height": 797031, 706 | "tx_pool_size": 1, 707 | "grey_peerlist_size": 3447, 708 | "outgoing_connections_count": 12, 709 | "tx_count": 492488, 710 | "white_peerlist_size": 253, 711 | "target_height": 796995, 712 | "incoming_connections_count": 0 713 | }, 714 | "id": "0" 715 | } 716 | ``` 717 | 718 | More examples hopefully coming soon. 719 | 720 | ## How can you help? 721 | 722 | Constructive criticism, code and website edits, and new examples are always welcome. 723 | They can be made through gihub. 724 | 725 | Some Monero are also welcome: 726 | ``` 727 | 48daf1rG3hE1Txapcsxh6WXNe9MLNKtu7W7tKTivtSoVLHErYzvdcpea2nSTgGkz66RFP4GKVAsTV14v6G3oddBTHfxP6tU 728 | ``` 729 | -------------------------------------------------------------------------------- /src/bitmonerod_basic_rpc_call_01.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's bitmonerod. 2 | # 3 | # The example gets a header a mining status 4 | # 5 | # The bitmonerod RPC docs are here: not avaliable 6 | 7 | 8 | import requests 9 | import json 10 | 11 | def main(): 12 | 13 | # bitmonerod' is running on the localhost and port of 18081 14 | url = "http://localhost:18081/mining_status" 15 | 16 | # standard json header 17 | headers = {'content-type': 'application/json'} 18 | 19 | # execute the rpc request 20 | response = requests.post( 21 | url, 22 | headers=headers) 23 | 24 | # pretty print json output 25 | print(json.dumps(response.json(), indent=4)) 26 | 27 | if __name__ == "__main__": 28 | main() -------------------------------------------------------------------------------- /src/bitmonerod_basic_rpc_call_02.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's bitmonerod. 2 | # 3 | # The example gets a header of a block with 4 | # the following hash: 5 | # d78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6 6 | # 7 | # The bitmonerod RPC docs are here: not avaliable 8 | 9 | 10 | import requests 11 | import json 12 | 13 | def main(): 14 | 15 | # bitmonerod is running on the localhost and port of 18082 16 | url = "http://localhost:18081/json_rpc" 17 | 18 | # standard json header 19 | headers = {'content-type': 'application/json'} 20 | 21 | # the block to get 22 | block_hash = 'd78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6' 23 | 24 | # bitmonerod' procedure/method to call 25 | rpc_input = { 26 | "method": "getblockheaderbyhash", 27 | "params": {"hash": block_hash} 28 | } 29 | 30 | # add standard rpc values 31 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 32 | 33 | # execute the rpc request 34 | response = requests.post( 35 | url, 36 | data=json.dumps(rpc_input), 37 | headers=headers) 38 | 39 | # pretty print json output 40 | print(json.dumps(response.json(), indent=4)) 41 | 42 | if __name__ == "__main__": 43 | main() -------------------------------------------------------------------------------- /src/bitmonerod_basic_rpc_call_03.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's bitmonerod. 2 | # 3 | # The example gets full block info 4 | # the following hash: 5 | # d78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6 6 | # 7 | # The bitmonerod RPC docs are here: not avaliable 8 | 9 | 10 | import requests 11 | import json 12 | 13 | def main(): 14 | 15 | # bitmonerod is running on the localhost and port of 18082 16 | url = "http://localhost:18081/json_rpc" 17 | 18 | # standard json header 19 | headers = {'content-type': 'application/json'} 20 | 21 | # the block to get 22 | block_hash = 'd78e2d024532d8d8f9c777e2572623fd0f229d72d9c9c9da3e7cb841a3cb73c6' 23 | 24 | # bitmonerod' procedure/method to call 25 | rpc_input = { 26 | "method": "getblock", 27 | "params": {"hash": block_hash} 28 | } 29 | 30 | # add standard rpc values 31 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 32 | 33 | # execute the rpc request 34 | response = requests.post( 35 | url, 36 | data=json.dumps(rpc_input), 37 | headers=headers) 38 | 39 | # the response will contain binary blob. For some reason 40 | # python's json encoder will crash trying to parse such 41 | # response. Thus, its better to remove it from the response. 42 | response_json_clean = json.loads( 43 | "\n".join(filter( 44 | lambda l: "blob" not in l, response.text.split("\n") 45 | ))) 46 | 47 | # pretty print json output 48 | print(json.dumps(response_json_clean, indent=4)) 49 | 50 | if __name__ == "__main__": 51 | main() -------------------------------------------------------------------------------- /src/bitmonerod_basic_rpc_call_04.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's bitmonerod. 2 | # 3 | # The example gets blockchain information 4 | # 5 | # The bitmonerod RPC docs are here: not avaliable 6 | 7 | 8 | import requests 9 | import json 10 | 11 | def main(): 12 | 13 | # bitmonerod is running on the localhost and port of 18082 14 | url = "http://localhost:18081/json_rpc" 15 | 16 | # standard json header 17 | headers = {'content-type': 'application/json'} 18 | 19 | # bitmonerod' procedure/method to call 20 | rpc_input = { 21 | "method": "get_info" 22 | } 23 | 24 | # add standard rpc values 25 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 26 | 27 | # execute the rpc request 28 | response = requests.post( 29 | url, 30 | data=json.dumps(rpc_input), 31 | headers=headers) 32 | 33 | # pretty print json output 34 | print(json.dumps(response.json(), indent=4)) 35 | 36 | if __name__ == "__main__": 37 | main() -------------------------------------------------------------------------------- /src/simplewallet_basic_rpc_call_01.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's simplewallet. 2 | # 3 | # The example gets the wallet's balance 4 | # 5 | # The simplewallet RPC docs are here: 6 | # https://getmonero.org/knowledge-base/developer-guides/wallet-rpc 7 | # 8 | 9 | import requests 10 | import json 11 | 12 | def main(): 13 | 14 | # simple wallet is running on the localhost and port of 18082 15 | url = "http://localhost:18082/json_rpc" 16 | 17 | # standard json header 18 | headers = {'content-type': 'application/json'} 19 | 20 | # simplewallet' procedure/method to call 21 | rpc_input = { 22 | "method": "getbalance" 23 | } 24 | 25 | # add standard rpc values 26 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 27 | 28 | # execute the rpc request 29 | response = requests.post( 30 | url, 31 | data=json.dumps(rpc_input), 32 | headers=headers) 33 | 34 | # amounts in cryptonote are encoded in a way which is convenient 35 | # for a computer, not a user. Thus, its better need to recode them 36 | # to something user friendly, before displaying them. 37 | # 38 | # For examples: 39 | # 4760000000000 is 4.76 40 | # 80000000000 is 0.08 41 | # 42 | # In example 3 "Basic example 3: get incoming transfers" it is 43 | # shown how to convert cryptonote values to user friendly format. 44 | 45 | # pretty print json output 46 | print(json.dumps(response.json(), indent=4)) 47 | 48 | if __name__ == "__main__": 49 | main() -------------------------------------------------------------------------------- /src/simplewallet_basic_rpc_call_02.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's simplewallet. 2 | # 3 | # The example gets payment information based on given 4 | # payment id: 426870cb29c598e191184fa87003ca562d9e25f761ee9e520a888aec95195912 5 | # 6 | # The simplewallet RPC docs are here: 7 | # https://getmonero.org/knowledge-base/developer-guides/wallet-rpc 8 | # 9 | 10 | import requests 11 | import json 12 | 13 | def main(): 14 | 15 | # simple wallet is running on the localhost and port of 18082 16 | url = "http://localhost:18082/json_rpc" 17 | 18 | # standard json header 19 | headers = {'content-type': 'application/json'} 20 | 21 | # an example of a payment id 22 | payment_id = "426870cb29c598e191184fa87003ca562d9e25f761ee9e520a888aec95195912" 23 | 24 | # simplewallet' procedure/method to call 25 | rpc_input = { 26 | "method": "get_payments", 27 | "params": {"payment_id": payment_id} 28 | } 29 | 30 | # add standard rpc values 31 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 32 | 33 | # execute the rpc request 34 | response = requests.post( 35 | url, 36 | data=json.dumps(rpc_input), 37 | headers=headers) 38 | 39 | # pretty print json output 40 | print(json.dumps(response.json(), indent=4)) 41 | 42 | if __name__ == "__main__": 43 | main() -------------------------------------------------------------------------------- /src/simplewallet_basic_rpc_call_03.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's simplewallet. 2 | # 3 | # Get list of incoming transfers 4 | # 5 | # The simplewallet RPC docs are here: 6 | # https://getmonero.org/knowledge-base/developer-guides/wallet-rpc 7 | # 8 | # The bitmonerod RPC docs are here: not avaliable 9 | 10 | 11 | import requests 12 | import json 13 | 14 | def main(): 15 | 16 | # simple wallet is running on the localhost and port of 18082 17 | url = "http://localhost:18082/json_rpc" 18 | 19 | # standard json header 20 | headers = {'content-type': 'application/json'} 21 | 22 | # simplewallet' procedure/method to call 23 | rpc_input = { 24 | "method": "incoming_transfers", 25 | "params": {"transfer_type": "all"} 26 | } 27 | 28 | # add standard rpc values 29 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 30 | 31 | # execute the rpc request 32 | response = requests.post( 33 | url, 34 | data=json.dumps(rpc_input), 35 | headers=headers) 36 | 37 | # make json dict with response 38 | response_json = response.json() 39 | 40 | # amounts in cryptonote are encoded in a way which is convenient 41 | # for a computer, not a user. Thus, its better need to recode them 42 | # to something user friendly, before displaying them. 43 | # 44 | # For examples: 45 | # 4760000000000 is 4.76 46 | # 80000000000 is 0.08 47 | # 48 | if "result" in response_json: 49 | if "transfers" in response_json["result"]: 50 | for transfer in response_json["result"]["transfers"]: 51 | transfer["amount"] = float(get_money(str(transfer["amount"]))) 52 | 53 | 54 | # pretty print json output 55 | print(json.dumps(response_json, indent=4)) 56 | 57 | def get_money(amount): 58 | """decode cryptonote amount format to user friendly format. Hope its correct. 59 | 60 | Based on C++ code: 61 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L751 62 | """ 63 | 64 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 65 | 66 | s = amount 67 | 68 | if len(s) < CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1: 69 | # add some trailing zeros, if needed, to have constant width 70 | s = '0' * (CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1 - len(s)) + s 71 | 72 | idx = len(s) - CRYPTONOTE_DISPLAY_DECIMAL_POINT 73 | 74 | s = s[0:idx] + "." + s[idx:] 75 | 76 | return s 77 | 78 | if __name__ == "__main__": 79 | main() -------------------------------------------------------------------------------- /src/simplewallet_basic_rpc_call_04.py: -------------------------------------------------------------------------------- 1 | # Basic example of json-rpc calls to Monero's simplewallet. 2 | # 3 | # Transfer given xmr amount to some address 4 | # 5 | # The simplewallet RPC docs are here: 6 | # https://getmonero.org/knowledge-base/developer-guides/wallet-rpc 7 | # 8 | # The bitmonerod RPC docs are here: not avaliable 9 | 10 | 11 | import requests 12 | import json 13 | import os 14 | import binascii 15 | 16 | 17 | def main(): 18 | """DONT RUN IT without changing the destination address!!!""" 19 | 20 | # simple wallet is running on the localhost and port of 18082 21 | url = "http://localhost:18082/json_rpc" 22 | 23 | # standard json header 24 | headers = {'content-type': 'application/json'} 25 | 26 | destination_address = "489MAxaT7xXP3Etjk2suJT1uDYZU6cqFycsau2ynCTBacncWVEwe9eYFrAD6BqTn4Y2KMs7maX75iX1UFwnJNG5G88wxKoj" 27 | 28 | 29 | # amount of xmr to send 30 | amount = 0.54321 31 | 32 | # cryptonote amount format is different then 33 | # that normally used by people. 34 | # thus the float amount must be changed to 35 | # something that cryptonote understands 36 | int_amount = int(get_amount(amount)) 37 | 38 | # just to make sure that amount->coversion->back 39 | # gives the same amount as in the initial number 40 | assert amount == float(get_money(str(int_amount))), "Amount conversion failed" 41 | 42 | # send specified xmr amount to the given destination_address 43 | recipents = [{"address": destination_address, 44 | "amount": int_amount}] 45 | 46 | # using given mixin 47 | mixin = 4 48 | 49 | # get some random payment_id 50 | payment_id = get_payment_id() 51 | 52 | # simplewallet' procedure/method to call 53 | rpc_input = { 54 | "method": "transfer", 55 | "params": {"destinations": recipents, 56 | "mixin": mixin, 57 | "payment_id" : payment_id} 58 | } 59 | 60 | # add standard rpc values 61 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 62 | 63 | # execute the rpc request 64 | response = requests.post( 65 | url, 66 | data=json.dumps(rpc_input), 67 | headers=headers) 68 | 69 | # print the payment_id 70 | print("#payment_id: ", payment_id) 71 | 72 | # pretty print json output 73 | print(json.dumps(response.json(), indent=4)) 74 | 75 | 76 | def get_amount(amount): 77 | """encode amount (float number) to the cryptonote format. Hope its correct. 78 | 79 | Based on C++ code: 80 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L211 81 | """ 82 | 83 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 84 | 85 | str_amount = str(amount) 86 | 87 | fraction_size = 0 88 | 89 | if '.' in str_amount: 90 | 91 | point_index = str_amount.index('.') 92 | 93 | fraction_size = len(str_amount) - point_index - 1 94 | 95 | while fraction_size < CRYPTONOTE_DISPLAY_DECIMAL_POINT and '0' == str_amount[-1]: 96 | print(44) 97 | str_amount = str_amount[:-1] 98 | fraction_size = fraction_size - 1 99 | 100 | if CRYPTONOTE_DISPLAY_DECIMAL_POINT < fraction_size: 101 | return False 102 | 103 | str_amount = str_amount[:point_index] + str_amount[point_index+1:] 104 | 105 | if not str_amount: 106 | return False 107 | 108 | if fraction_size < CRYPTONOTE_DISPLAY_DECIMAL_POINT: 109 | str_amount = str_amount + '0'*(CRYPTONOTE_DISPLAY_DECIMAL_POINT - fraction_size) 110 | 111 | return str_amount 112 | 113 | 114 | def get_money(amount): 115 | """decode cryptonote amount format to user friendly format. Hope its correct. 116 | 117 | Based on C++ code: 118 | https://github.com/monero-project/bitmonero/blob/master/src/cryptonote_core/cryptonote_format_utils.cpp#L751 119 | """ 120 | 121 | CRYPTONOTE_DISPLAY_DECIMAL_POINT = 12 122 | 123 | s = amount 124 | 125 | if len(s) < CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1: 126 | # add some trailing zeros, if needed, to have constant width 127 | s = '0' * (CRYPTONOTE_DISPLAY_DECIMAL_POINT + 1 - len(s)) + s 128 | 129 | idx = len(s) - CRYPTONOTE_DISPLAY_DECIMAL_POINT 130 | 131 | s = s[0:idx] + "." + s[idx:] 132 | 133 | return s 134 | 135 | def get_payment_id(): 136 | """generate random payment_id 137 | 138 | generate some random payment_id for the 139 | transactions 140 | 141 | payment_id is 32 bytes (64 hexadecimal characters) 142 | thus we first generate 32 random byte array 143 | which is then change to string representation, since 144 | json will not not what to do with the byte array. 145 | """ 146 | 147 | payment_id = os.urandom(32).encode('hex') 148 | 149 | return payment_id 150 | 151 | 152 | if __name__ == "__main__": 153 | main() 154 | -------------------------------------------------------------------------------- /src/simplewallet_rpc_examples.py: -------------------------------------------------------------------------------- 1 | # Examples of json-rpc calls for Monero's simplewallet. 2 | # 3 | # The simplewallet RPC docs are here: 4 | # https://getmonero.org/knowledge-base/developer-guides/wallet-rpc 5 | # 6 | # The examples demonstrate how to call the most popular procedures 7 | # that simplewallet exposes for other applications to use. 8 | # 9 | # Using these procedures, other applications can be developed 10 | # on that ese monero's simplewallet. For example, a GUI, 11 | # or an web applications allowing for accessing wallets online. 12 | # 13 | # Before executing this code make sure that simplewallet is 14 | # running and listening for the incoming rpc calls. 15 | # 16 | # For example, you can run the simplewallet in rpc mode as follows: 17 | # /opt/bitmonero/simplewallet --wallet-file ~/wallet.bin --password --rpc-bind-port 18082 18 | # 19 | # 20 | # The code was written, tested and executed on Ubuntu 15.10 with 21 | # Python 3.4.3. It uses Requests package (https://pypi.python.org/pypi/requests). 22 | # 23 | # 24 | # Example output: 25 | # 26 | # get_balance(): 27 | # return the wallet's balance 28 | # {'jsonrpc': '2.0', 'id': '0', 'result': {'unlocked_balance': 4800000000000, 'balance': 4800000000000}} 29 | # 30 | # get_address(): 31 | # return the wallet's address 32 | # {'jsonrpc': '2.0', 'id': '0', 'result': {'address': '48daf1rG3hE1Txapcsxh6WXNe9MLNKtu7W7tKTivtSoVLHErYzvdcpea2nSTgGkz66RFP4GKVAsTV14v6G3oddBTHfxP6tU'}} 33 | # 34 | # get_view_key(): 35 | # return the wallet's the view key 36 | # {'jsonrpc': '2.0', 'id': '0', 'result': {'key': '1ddabaa51cea5f6d9068728dc08c7ffaefe39a7a4b5f39fa8a976ecbe2cb520a'}} 37 | # 38 | # get_mnemonic_key(): 39 | # return the wallet's mnemonic key 40 | # {'jsonrpc': '2.0', 'error': {'code': 0, 'message': 'The wallet is non-deterministic. Cannot display seed.'}, 'id': '0'} 41 | # 42 | # get_payments(): 43 | # get a list of incoming payments using a given payment id 44 | # {'jsonrpc': '2.0', 'id': '0', 'result': {'payments': [{'amount': 4800000000000, 'payment_id': '426870cb29c598e191184fa87003ca562d9e25f761ee9e520a888aec95195912', 'unlock_time': 0, 'tx_hash': '66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577', 'block_height': 795523}]}} 45 | # 46 | # incoming_transfers(): 47 | # return a list of incoming transfers to the wallet 48 | # {'jsonrpc': '2.0', 'id': '0', 'result': {'transfers': [{'global_index': 346865, 'amount': 800000000000, 'tx_hash': '<66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577>', 'tx_size': 521, 'spent': False}, {'global_index': 177947, 'amount': 4000000000000, 'tx_hash': '<66040ad29f0d780b4d47641a67f410c28cce575b5324c43b784bb376f4e30577>', 'tx_size': 521, 'spent': False}]}} 49 | # 50 | # transfer(): 51 | # send monero to a number of recipients 52 | # 53 | # Transfer 1 xmr to: 489MAxaT7xXP3Etjk2suJT1uDYZU6cqFycsau2ynCTBacncWVEwe9eYFrAD6BqTn4Y2KMs7maX75iX1UFwnJNG5G88wxKoj 54 | # {'id': '0', 'jsonrpc': '2.0', 'result': {'tx_key': '', 'tx_hash': ''}} 55 | # 56 | # 57 | # Last update: 25 Oct 2015 58 | 59 | import requests 60 | import json 61 | 62 | 63 | class SimplewalletRpcExamples(): 64 | 65 | def __init__(self): 66 | # simple wallet is running on the localhost and port of 18082 67 | self.url = "http://localhost:18082/json_rpc" 68 | 69 | # standard json header 70 | self.headers = {'content-type': 'application/json'} 71 | 72 | def get_balance(self): 73 | """return the wallet's balance""" 74 | 75 | rpc_input = { 76 | "method": "getbalance" 77 | } 78 | 79 | response = self.__do_rpc(rpc_input) 80 | 81 | return response.json() 82 | 83 | def get_view_key(self): 84 | """return the wallet's the view key""" 85 | 86 | rpc_input = { 87 | "method": "query_key", 88 | "params": {"key_type": "view_key"} 89 | } 90 | 91 | response = self.__do_rpc(rpc_input) 92 | 93 | return response.json() 94 | 95 | def get_mnemonic_key(self): 96 | """return the wallet's mnemonic key""" 97 | 98 | rpc_input = { 99 | "method": "query_key", 100 | "params": {"key_type": "mnemonic"} 101 | } 102 | 103 | response = self.__do_rpc(rpc_input) 104 | 105 | return response.json() 106 | 107 | def get_address(self): 108 | """return the wallet's address""" 109 | 110 | rpc_input = { 111 | "method": "getaddress" 112 | } 113 | 114 | response = self.__do_rpc(rpc_input) 115 | 116 | return response.json() 117 | 118 | def get_payments(self): 119 | """get a list of incoming payments using a given payment id""" 120 | 121 | # en example of a payment id 122 | payment_id = "4926869b6b5d50b24cb59f08fd76826cacdf76201b2d4648578fe610af7f786e" 123 | 124 | rpc_input = { 125 | "method": "get_payments", 126 | "params": {"payment_id": payment_id} 127 | } 128 | 129 | response = self.__do_rpc(rpc_input) 130 | 131 | return response.json() 132 | 133 | def incoming_transfers(self): 134 | """return a list of incoming transfers to the wallet""" 135 | 136 | rpc_input = { 137 | "method": "incoming_transfers", 138 | "params": {"transfer_type": "all"} 139 | } 140 | 141 | response = self.__do_rpc(rpc_input) 142 | 143 | return response.json() 144 | 145 | 146 | def execute(self): 147 | """run read-only examples""" 148 | 149 | example_functions = [self.get_balance, 150 | self.get_address, 151 | self.get_view_key, 152 | self.get_mnemonic_key, 153 | self.get_payments, 154 | self.incoming_transfers] 155 | 156 | for fun_obj in example_functions: 157 | print(fun_obj.__name__ + "():\n" + fun_obj.__doc__) 158 | json_result = fun_obj() 159 | print(json_result, "\n") 160 | 161 | def __do_rpc(self, rpc_input): 162 | """does the rpc calls""" 163 | 164 | # add standard rpc values 165 | rpc_input.update({"jsonrpc": "2.0", "id": "0"}) 166 | 167 | # execute the rpc requrest 168 | response = requests.post( 169 | self.url, 170 | data=json.dumps(rpc_input), 171 | headers=self.headers) 172 | 173 | return response 174 | 175 | 176 | if __name__ == "__main__": 177 | sw = SimplewalletRpcExamples() 178 | sw.execute() 179 | --------------------------------------------------------------------------------