bitcoinlib 0.7.2__tar.gz → 0.7.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/CHANGELOG +21 -0
  2. {bitcoinlib-0.7.2/bitcoinlib.egg-info → bitcoinlib-0.7.4}/PKG-INFO +10 -6
  3. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/README.rst +4 -2
  4. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/__init__.py +1 -1
  5. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/__init__.py +1 -1
  6. bitcoinlib-0.7.4/bitcoinlib/config/VERSION +1 -0
  7. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/providers.examples.json +21 -0
  8. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/providers.json +47 -2
  9. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/keys.py +1 -1
  10. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/networks.py +2 -2
  11. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/authproxy.py +1 -1
  12. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bcoin.py +5 -5
  13. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitcoind.py +8 -0
  14. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockbook.py +2 -1
  15. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockchaininfo.py +2 -1
  16. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockcypher.py +9 -1
  17. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blocksmurfer.py +10 -4
  18. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/electrumx.py +2 -0
  19. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/mempool.py +1 -2
  20. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/services.py +3 -3
  21. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/transactions.py +8 -2
  22. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wallets.py +22 -14
  23. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4/bitcoinlib.egg-info}/PKG-INFO +10 -6
  24. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/requires.txt +7 -2
  25. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/setup.cfg +4 -3
  26. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_db.py +1 -1
  27. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_keys.py +1 -1
  28. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_networks.py +1 -1
  29. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_services.py +41 -36
  30. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_wallets.py +2 -2
  31. bitcoinlib-0.7.2/bitcoinlib/config/VERSION +0 -1
  32. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/LICENSE +0 -0
  33. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/MANIFEST.in +0 -0
  34. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/blocks.py +0 -0
  35. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__init__.py +0 -0
  36. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/__init__.cpython-310.pyc +0 -0
  37. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/__init__.cpython-38.pyc +0 -0
  38. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/config.cpython-310.pyc +0 -0
  39. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/config.cpython-38.pyc +0 -0
  40. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/opcodes.cpython-310.pyc +0 -0
  41. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/opcodes.cpython-38.pyc +0 -0
  42. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-310.pyc +0 -0
  43. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-38.pyc +0 -0
  44. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/config.py +0 -0
  45. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/opcodes.py +0 -0
  46. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/secp256k1.py +0 -0
  47. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/config.ini +0 -0
  48. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/networks.json +0 -0
  49. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/db.py +0 -0
  50. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/db_cache.py +0 -0
  51. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/encoding.py +0 -0
  52. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/main.py +0 -0
  53. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/mnemonic.py +0 -0
  54. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/scripts.py +0 -0
  55. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/__init__.py +0 -0
  56. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/baseclient.py +0 -0
  57. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitaps.py +0 -0
  58. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitcoinlibtest.py +0 -0
  59. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitflyer.py +0 -0
  60. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitgo.py +0 -0
  61. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockchair.py +0 -0
  62. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockstream.py +0 -0
  63. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/chainso.py +0 -0
  64. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/cryptoid.py +0 -0
  65. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/dogecoind.py +0 -0
  66. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoinblockexplorer.py +0 -0
  67. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoind.py +0 -0
  68. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoreio.py +0 -0
  69. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/__init__.py +0 -0
  70. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/benchmark.py +0 -0
  71. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/clw.py +0 -0
  72. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/import_database.py +0 -0
  73. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/mnemonic_key_create.py +0 -0
  74. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/sign_raw.py +0 -0
  75. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/wallet_multisig_2of3.py +0 -0
  76. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/values.py +0 -0
  77. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/chinese_simplified.txt +0 -0
  78. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/chinese_traditional.txt +0 -0
  79. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/dutch.txt +0 -0
  80. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/english.txt +0 -0
  81. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/french.txt +0 -0
  82. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/italian.txt +0 -0
  83. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/japanese.txt +0 -0
  84. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/portuguese.txt +0 -0
  85. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/spanish.txt +0 -0
  86. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/SOURCES.txt +0 -0
  87. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/dependency_links.txt +0 -0
  88. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/entry_points.txt +0 -0
  89. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/top_level.txt +0 -0
  90. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/zip-safe +0 -0
  91. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/pyproject.toml +0 -0
  92. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/requirements.txt +0 -0
  93. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/__init__.py +0 -0
  94. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/bip38_protected_key_tests.json +0 -0
  95. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block250000.pickle +0 -0
  96. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block330000.pickle +0 -0
  97. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block625007.pickle +0 -0
  98. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block629999.pickle +0 -0
  99. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block722010.pickle +0 -0
  100. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/electrum_keys.json +0 -0
  101. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/mnemonics_tests.json +0 -0
  102. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_blocks.py +0 -0
  103. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_custom.py +0 -0
  104. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_encoding.py +0 -0
  105. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_mnemonic.py +0 -0
  106. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_script.py +0 -0
  107. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_security.py +0 -0
  108. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_tools.py +0 -0
  109. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_transactions.py +0 -0
  110. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_values.py +0 -0
  111. {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/transactions_raw.json +0 -0
@@ -1,3 +1,24 @@
1
+ RELEASE 0.7.4 - Add and updates providers, improve blockchain parsing
2
+ =====================================================================
3
+ * Add testnet4, signet Blockbook provider
4
+ * Allow to manage unrecognised keys and transactions for blockchain parsing
5
+ * Fix issue with uncompressed wallet keys
6
+ * Fix Blocksmurfer provider issues
7
+ * Various provider updates and fixes
8
+ * Update FAQ page and documentation
9
+ * Avoid litecoin unittest issues
10
+
11
+ RELEASE 0.7.3 - Fix provider issues, increase performance
12
+ =========================================================
13
+ * ElectrumX and Blockbook examples and documentation
14
+ * Add mempool Signet provider
15
+ * Fix documentation build
16
+ * Enable unittest for Bitaps
17
+ * Fix Mempool provider transaction order
18
+ * Fix incorrect txid's when parsing blocks
19
+ * Fix other provider issues
20
+ * Improve provider performance
21
+
1
22
  RELEASE 0.7.2 - ElectrumX, Signet, Blocksmurfer API
2
23
  ===================================================
3
24
  * ElectrumX server support
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: bitcoinlib
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Bitcoin cryptocurrency Library
5
5
  Home-page: http://github.com/1200wd/bitcoinlib
6
6
  Author: 1200wd
@@ -33,10 +33,11 @@ Requires-Dist: ecdsa>=0.18; platform_system == "Windows"
33
33
  Requires-Dist: pycryptodome>=3.19.0
34
34
  Requires-Dist: SQLAlchemy>=2.0.20
35
35
  Requires-Dist: numpy==1.24.4; python_version < "3.9"
36
- Requires-Dist: numpy>=1.22.0; python_version >= "3.9"
36
+ Requires-Dist: numpy<2,>=1.24.4; python_version >= "3.9"
37
37
  Provides-Extra: dev
38
38
  Requires-Dist: scrypt>=0.8.20; platform_system != "Windows" and extra == "dev"
39
- Requires-Dist: sphinx>=7.1.0; extra == "dev"
39
+ Requires-Dist: sphinx>=7.1.0; python_version < "3.9" and extra == "dev"
40
+ Requires-Dist: sphinx>=7.2.0; python_version >= "3.9" and extra == "dev"
40
41
  Requires-Dist: coveralls>=4.0.1; extra == "dev"
41
42
  Requires-Dist: psycopg>=3.1.16; extra == "dev"
42
43
  Requires-Dist: mysql-connector-python>=8.4.0; extra == "dev"
@@ -44,6 +45,7 @@ Requires-Dist: mysqlclient>=2.2.0; extra == "dev"
44
45
  Requires-Dist: sphinx_rtd_theme>=2.0.0; extra == "dev"
45
46
  Requires-Dist: Cython>=3.0.8; extra == "dev"
46
47
  Requires-Dist: win-unicode-console; platform_system == "Windows" and extra == "dev"
48
+ Dynamic: license-file
47
49
 
48
50
  Python Bitcoin Library
49
51
  ======================
@@ -58,8 +60,10 @@ With BitcoinLib you can:
58
60
  - Create, analyse and run Bitcoin scripts
59
61
  - Generate Bitcoin addresses and represent them in different address formats like P2PKH, P2SH, Bech32, etc
60
62
  - Create private keys and work with Mnemonic password phrases
61
- - Uses external Service providers to fetch address, transaction, utxo and blockchain data. Or connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_ or `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ node.
62
- - Can be extended to support other cryptocurrencies by configuring custom parameters. At the moment Litecoin and Dogecoin are also supported.
63
+ - Use external Service providers to fetch address, transaction, utxo and blockchain data.
64
+ - Connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_, `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ or `ElectrumX <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-electrumx.html>`_ node.
65
+ - Can be extended to support other cryptocurrencies by configuring custom parameters.
66
+ - At the moment Litecoin, Dogecoin and various test networks are supported out-of-the-box.
63
67
 
64
68
 
65
69
  .. image:: https://github.com/1200wd/bitcoinlib/actions/workflows/unittests.yaml/badge.svg
@@ -11,8 +11,10 @@ With BitcoinLib you can:
11
11
  - Create, analyse and run Bitcoin scripts
12
12
  - Generate Bitcoin addresses and represent them in different address formats like P2PKH, P2SH, Bech32, etc
13
13
  - Create private keys and work with Mnemonic password phrases
14
- - Uses external Service providers to fetch address, transaction, utxo and blockchain data. Or connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_ or `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ node.
15
- - Can be extended to support other cryptocurrencies by configuring custom parameters. At the moment Litecoin and Dogecoin are also supported.
14
+ - Use external Service providers to fetch address, transaction, utxo and blockchain data.
15
+ - Connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_, `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ or `ElectrumX <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-electrumx.html>`_ node.
16
+ - Can be extended to support other cryptocurrencies by configuring custom parameters.
17
+ - At the moment Litecoin, Dogecoin and various test networks are supported out-of-the-box.
16
18
 
17
19
 
18
20
  .. image:: https://github.com/1200wd/bitcoinlib/actions/workflows/unittests.yaml/badge.svg
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
- # © 2016 November - 1200 Web Development <http://1200wd.com/>
4
+ # © 2016 - 2025 May - 1200 Web Development <http://1200wd.com/>
5
5
  #
6
6
  # This program is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU Affero General Public License as
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
- # © 2018 - 2019 March - 1200 Web Development <http://1200wd.com/>
4
+ # © 2018 - 2025 May - 1200 Web Development <http://1200wd.com/>
5
5
  #
6
6
  # This program is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU Affero General Public License as
@@ -0,0 +1 @@
1
+ 0.7.4
@@ -438,5 +438,26 @@
438
438
  "priority": 10,
439
439
  "denominator": 100000000,
440
440
  "network_overrides": null
441
+ },
442
+ "localhost.electrumx": {
443
+ "provider": "electrumx",
444
+ "network": "bitcoin",
445
+ "client_class": "ElectrumxClient",
446
+ "provider_coin_id": "",
447
+ "url": "localhost:50001",
448
+ "api_key": "",
449
+ "priority": 10,
450
+ "denominator": 1,
451
+ "network_overrides": null
452
+ },
453
+ "blockbook.localhost": {
454
+ "provider": "blockbook",
455
+ "network": "bitcoin",
456
+ "client_class": "BlockbookClient",
457
+ "provider_coin_id": "",
458
+ "url": "http://localhost:9130/api/v2/",
459
+ "priority": 10,
460
+ "denominator": 100000000,
461
+ "network_overrides": null
441
462
  }
442
463
  }
@@ -58,6 +58,18 @@
58
58
  "denominator": 1,
59
59
  "network_overrides": null,
60
60
  "timeout": 0
61
+ },
62
+ "blockcypher": {
63
+ "provider": "blockcypher",
64
+ "network": "bitcoin",
65
+ "client_class": "BlockCypher",
66
+ "provider_coin_id": "",
67
+ "url": "https://api.blockcypher.com/v1/btc/main/",
68
+ "api_key": "",
69
+ "priority": 10,
70
+ "denominator": 1,
71
+ "network_overrides": null,
72
+ "timeout": 0
61
73
  },
62
74
  "cryptoid.litecoin": {
63
75
  "provider": "cryptoid",
@@ -342,7 +354,7 @@
342
354
  "provider_coin_id": "",
343
355
  "url": "https://mempool.space/api/",
344
356
  "api_key": "",
345
- "priority": 0,
357
+ "priority": 10,
346
358
  "denominator": 1,
347
359
  "network_overrides": null,
348
360
  "timeout": 0
@@ -354,7 +366,7 @@
354
366
  "provider_coin_id": "",
355
367
  "url": "https://mempool.space/testnet/api/",
356
368
  "api_key": "",
357
- "priority": 0,
369
+ "priority": 10,
358
370
  "denominator": 1,
359
371
  "network_overrides": null,
360
372
  "timeout": 0
@@ -370,6 +382,17 @@
370
382
  "denominator": 1,
371
383
  "network_overrides": null
372
384
  },
385
+ "blockbook.testnet4": {
386
+ "provider": "blockbook",
387
+ "network": "testnet4",
388
+ "client_class": "BlockbookClient",
389
+ "provider_coin_id": "",
390
+ "url": "https://blockbook.tbtc-1.zelcore.io/api/v2/",
391
+ "api_key": "",
392
+ "priority": 10,
393
+ "denominator": 1,
394
+ "network_overrides": null
395
+ },
373
396
  "mempool.litecoin": {
374
397
  "provider": "mempool",
375
398
  "network": "litecoin",
@@ -393,5 +416,27 @@
393
416
  "denominator": 1,
394
417
  "network_overrides": null,
395
418
  "timeout": 0
419
+ },
420
+ "mempool.signet": {
421
+ "provider": "mempool",
422
+ "network": "signet",
423
+ "client_class": "MempoolClient",
424
+ "provider_coin_id": "",
425
+ "url": "https://mempool.space/signet/api/",
426
+ "api_key": "",
427
+ "priority": 10,
428
+ "denominator": 1,
429
+ "network_overrides": null
430
+ },
431
+ "blockbook.signet": {
432
+ "provider": "blockbook",
433
+ "network": "signet",
434
+ "client_class": "BlockbookClient",
435
+ "provider_coin_id": "",
436
+ "url": "https://signet-explorer.wakiyamap.dev/api/v2/",
437
+ "api_key": "",
438
+ "priority": 10,
439
+ "denominator": 1,
440
+ "network_overrides": null
396
441
  }
397
442
  }
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # Public key cryptography and Hierarchical Deterministic Key Management
5
- # © 2016 - 2024 June - 1200 Web Development <http://1200wd.com/>
5
+ # © 2016 - 2025 May - 1200 Web Development <http://1200wd.com/>
6
6
  #
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Affero General Public License as
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # NETWORK class reads network definitions and with helper methods
5
- # © 2017 - 2022 October - 1200 Web Development <http://1200wd.com/>
5
+ # © 2017 - 2025 May - 1200 Web Development <http://1200wd.com/>
6
6
  #
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Affero General Public License as
@@ -93,7 +93,7 @@ def network_by_value(field, value):
93
93
  >>> network_by_value('prefix_wif', 'B0')
94
94
  ['litecoin', 'litecoin_legacy']
95
95
  >>> network_by_value('prefix_address', '6f')
96
- ['testnet', 'litecoin_testnet']
96
+ ['testnet', 'testnet4', 'signet', 'litecoin_testnet']
97
97
 
98
98
  This method does not work for HD prefixes, use 'wif_prefix_search' instead
99
99
 
@@ -168,7 +168,7 @@ class AuthServiceProxy(object):
168
168
  results = []
169
169
  responses = self._get_response()
170
170
  for response in responses:
171
- if response['error'] is not None:
171
+ if response.get('error') is not None:
172
172
  raise JSONRPCException(response['error'])
173
173
  elif 'result' not in response:
174
174
  raise JSONRPCException({
@@ -91,10 +91,10 @@ class BcoinClient(BaseClient):
91
91
 
92
92
  def getutxos(self, address, after_txid='', limit=MAX_TRANSACTIONS):
93
93
  # First get all transactions for this address from the blockchain
94
- txs = self.gettransactions(address, limit=50)
94
+ txs = self.gettransactions(address, limit=200)
95
95
 
96
96
  # Fail if large number of transactions are found
97
- if len(txs) > 50:
97
+ if len(txs) >= 200:
98
98
  raise ClientError("If not all transactions are known, we cannot determine utxo's")
99
99
 
100
100
  utxos = []
@@ -130,14 +130,14 @@ class BcoinClient(BaseClient):
130
130
  assert(limit > 0)
131
131
  txs = []
132
132
  while True:
133
- variables = {'limit': limit, 'after': after_txid}
133
+ variables = {'limit': 100, 'after': after_txid}
134
134
  res = self.compose_request('tx', 'address', address, variables)
135
135
  for tx in res:
136
136
  txs.append(self._parse_transaction(tx))
137
137
  if not txs or len(txs) >= limit:
138
138
  break
139
- if len(res) == limit:
140
- after_txid = res[limit-1]['hash']
139
+ if len(res) == 100:
140
+ after_txid = res[99]['hash']
141
141
  else:
142
142
  break
143
143
 
@@ -195,6 +195,14 @@ class BitcoindClient(BaseClient):
195
195
  if get_input_values:
196
196
  txi = self.proxy.getrawtransaction(i.prev_txid.hex(), 1)
197
197
  i.value = int(round(float(txi['vout'][i.output_n_int]['value']) / self.network.denominator))
198
+ # This doesn't seem to save any time:
199
+ # if get_input_values:
200
+ # batchreq = []
201
+ # for i in t.inputs:
202
+ # batchreq.append(['getrawtransaction', i.prev_txid.hex(), 1])
203
+ # res = self.proxy.batch_(batchreq)
204
+ # for n, txi in enumerate(res):
205
+ # t.inputs[n].value = int(round(float(txi['vout'][t.inputs[n].output_n_int]['value']) / self.network.denominator))
198
206
  for o in t.outputs:
199
207
  o.spent = None
200
208
 
@@ -2,7 +2,8 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # Blockbook Client api/v2 - available on various servers or run on your own see https://github.com/trezor/blockbook
5
- # © 2023 - 1200 Web Development <http://1200wd.com/>
5
+ # 1200 Web Development <http://1200wd.com/>
6
+ # © 2023 - 2025 May
6
7
  #
7
8
  # This program is free software: you can redistribute it and/or modify
8
9
  # it under the terms of the GNU Affero General Public License as
@@ -2,7 +2,8 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # blockchain_info client
5
- # © 2017-2019 July - 1200 Web Development <http://1200wd.com/>
5
+ # 1200 Web Development <http://1200wd.com/>
6
+ # © 2017 - 2025 May
6
7
  #
7
8
  # This program is free software: you can redistribute it and/or modify
8
9
  # it under the terms of the GNU Affero General Public License as
@@ -216,4 +216,12 @@ class BlockCypher(BaseClient):
216
216
  t = self.gettransaction(txid)
217
217
  return 1 if t.outputs[output_n].spent else 0
218
218
 
219
- # def getinfo(self):
219
+ def getinfo(self):
220
+ info = self.compose_request('', '')
221
+ return {
222
+ 'blockcount': info['height'],
223
+ 'chain': info['name'],
224
+ 'difficulty': 0,
225
+ 'hashrate': 0,
226
+ 'mempool_size': info['unconfirmed_count'],
227
+ }
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # Blocksmurfer client
5
- # © 2020 Januari - 1200 Web Development <http://1200wd.com/>
5
+ # © 2020 - 2025 May - 1200 Web Development <http://1200wd.com/>
6
6
  #
7
7
  # This program is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU Affero General Public License as
@@ -21,6 +21,7 @@
21
21
  import logging
22
22
  from datetime import datetime, timezone
23
23
  from bitcoinlib.main import MAX_TRANSACTIONS
24
+ from bitcoinlib.keys import Address
24
25
  from bitcoinlib.services.baseclient import BaseClient, ClientError
25
26
  from bitcoinlib.transactions import Transaction
26
27
 
@@ -75,7 +76,8 @@ class BlocksmurferClient(BaseClient):
75
76
  'size': u['size'],
76
77
  'value': u['value'],
77
78
  'script': u['script'],
78
- 'date': datetime.strptime(u['date'][:19], "%Y-%m-%dT%H:%M:%S").replace(tzinfo=timezone.utc)
79
+ 'date': None if not u['date'] else datetime.strptime(u['date'][:19], "%Y-%m-%dT%H:%M:%S").replace(
80
+ tzinfo=timezone.utc)
79
81
  })
80
82
  return utxos[:limit]
81
83
 
@@ -93,16 +95,20 @@ class BlocksmurferClient(BaseClient):
93
95
  status=tx['status'], coinbase=tx['coinbase'], rawtx=bytes.fromhex(tx['raw_hex']),
94
96
  witness_type=tx['witness_type'])
95
97
  for ti in tx['inputs']:
98
+ address = ti['address'] if not self.network_overrides else (
99
+ Address.parse(ti['address'], network_overrides=self.network_overrides).address)
96
100
  t.add_input(prev_txid=ti['prev_txid'], output_n=ti['output_n'], keys=ti.get('keys', []),
97
101
  index_n=ti['index_n'], unlocking_script=ti['script'], value=ti['value'],
98
- public_hash=bytes.fromhex(ti['public_hash']), address=ti['address'],
102
+ public_hash=bytes.fromhex(ti['public_hash']), address=address,
99
103
  witness_type=ti['witness_type'], locktime_cltv=ti['locktime_cltv'],
100
104
  locktime_csv=ti['locktime_csv'], signatures=ti['signatures'], compressed=ti['compressed'],
101
105
  locking_script=ti['locking_script'], sigs_required=ti['sigs_required'], sequence=ti['sequence'],
102
106
  witnesses=[bytes.fromhex(w) for w in ti['witnesses']], script_type=ti['script_type'],
103
107
  strict=self.strict)
104
108
  for to in tx['outputs']:
105
- t.add_output(value=to['value'], address=to['address'], public_hash=to['public_hash'],
109
+ address = to['address'] if not self.network_overrides else (
110
+ Address.parse(to['address'], network_overrides=self.network_overrides).address)
111
+ t.add_output(value=to['value'], address=address, public_hash=to['public_hash'],
106
112
  lock_script=to['script'], spent=to['spent'], strict=self.strict)
107
113
  t.update_totals()
108
114
  return t
@@ -168,6 +168,8 @@ class ElectrumxClient(BaseClient):
168
168
  except:
169
169
  pass
170
170
  t.input_total += i.value
171
+ for o in t.outputs:
172
+ o.spent = None
171
173
  t.update_totals()
172
174
  return t
173
175
 
@@ -141,8 +141,7 @@ class MempoolClient(BaseClient):
141
141
  if len(prtxs) > 100:
142
142
  break
143
143
  txs = []
144
- # FIXME: Mempool return transactions in incorrect order, this tries to fix it, but does not always work...
145
- for tx in sorted(prtxs, key=lambda x: x['status']['block_height']):
144
+ for tx in prtxs[::-1]:
146
145
  t = self._parse_transaction(tx)
147
146
  if t:
148
147
  txs.append(t)
@@ -101,7 +101,7 @@ class Service(object):
101
101
  raise ServiceError(errstr)
102
102
  f.close()
103
103
 
104
- provider_list = list(set([self.providers_defined[x]['provider'] for x in self.providers_defined]))
104
+ provider_set = {self.providers_defined[x]['provider'] for x in self.providers_defined}
105
105
  if providers is None:
106
106
  providers = []
107
107
  if exclude_providers is None:
@@ -109,7 +109,7 @@ class Service(object):
109
109
  if not isinstance(providers, list):
110
110
  providers = [providers]
111
111
  for p in providers:
112
- if p not in provider_list:
112
+ if p not in provider_set:
113
113
  raise ServiceError("Provider '%s' not found in provider definitions" % p)
114
114
 
115
115
  self.providers = {}
@@ -344,7 +344,7 @@ class Service(object):
344
344
  """
345
345
  Get all transactions for specified address.
346
346
 
347
- Sorted from old to new, so transactions with highest number of confirmations first.
347
+ Sorted from old to new, so transactions with the highest number of confirmations first.
348
348
 
349
349
  :param address: Address string
350
350
  :type address: str
@@ -745,7 +745,10 @@ class Output(object):
745
745
  @property
746
746
  def address(self):
747
747
  if not self._address:
748
- address_obj = self.address_obj
748
+ try:
749
+ address_obj = self.address_obj
750
+ except Exception:
751
+ return ''
749
752
  if not address_obj:
750
753
  return ''
751
754
  self._address = address_obj.address
@@ -1006,8 +1009,11 @@ class Transaction(object):
1006
1009
  rawtx.seek(pos_start)
1007
1010
  raw_bytes = rawtx.read(raw_len)
1008
1011
 
1012
+ txid = '' if witness_type == 'segwit' else double_sha256(raw_bytes)[::-1].hex()
1013
+
1009
1014
  return Transaction(inputs, outputs, locktime, version, network, size=raw_len, output_total=output_total,
1010
- coinbase=coinbase, flag=flag, witness_type=witness_type, rawtx=raw_bytes, index=index)
1015
+ coinbase=coinbase, flag=flag, witness_type=witness_type, rawtx=raw_bytes, index=index,
1016
+ txid=txid)
1011
1017
 
1012
1018
  @classmethod
1013
1019
  def parse_hex(cls, rawtx, strict=True, network=DEFAULT_NETWORK):
@@ -838,7 +838,7 @@ class WalletTransaction(Transaction):
838
838
  return None
839
839
 
840
840
  srv = Service(network=self.network.name, wallet_name=self.hdwallet.name, providers=self.hdwallet.providers,
841
- cache_uri=self.hdwallet.db_cache_uri)
841
+ cache_uri=self.hdwallet.db_cache_uri, strict=self.hdwallet.strict)
842
842
  res = srv.sendrawtransaction(self.raw_hex())
843
843
  if not res:
844
844
  self.error = "Cannot send transaction. %s" % srv.errors
@@ -1235,9 +1235,9 @@ class Wallet(object):
1235
1235
  def _commit(self):
1236
1236
  try:
1237
1237
  self.session.commit()
1238
- except Exception:
1238
+ except Exception as e:
1239
1239
  self.session.rollback()
1240
- raise WalletError("Could not commit to database, rollback performed!")
1240
+ raise WalletError("Could not commit to database, rollback performed! Database error: %s" % str(e))
1241
1241
 
1242
1242
  @classmethod
1243
1243
  def create(cls, name, keys=None, owner='', network=None, account_id=0, purpose=0, scheme='bip32',
@@ -1546,6 +1546,7 @@ class Wallet(object):
1546
1546
  self.key_depth = len(self.key_path) - 1
1547
1547
  self.last_updated = None
1548
1548
  self.anti_fee_sniping = db_wlt.anti_fee_sniping
1549
+ self.strict = True
1549
1550
  else:
1550
1551
  raise WalletError("Wallet '%s' not found, please specify correct wallet ID or name." % wallet)
1551
1552
 
@@ -2965,7 +2966,8 @@ class Wallet(object):
2965
2966
  """
2966
2967
 
2967
2968
  network, account_id, acckey = self._get_account_defaults(network, account_id)
2968
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
2969
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri,
2970
+ strict=self.strict)
2969
2971
  balance = srv.getbalance(self.addresslist(account_id=account_id, network=network))
2970
2972
  if srv.results:
2971
2973
  new_balance = {
@@ -3189,7 +3191,8 @@ class Wallet(object):
3189
3191
  addresslist = self.addresslist(account_id=account_id, used=used, network=network, key_id=key_id,
3190
3192
  change=change, depth=depth)
3191
3193
  random.shuffle(addresslist)
3192
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
3194
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers,
3195
+ cache_uri=self.db_cache_uri, strict=self.strict)
3193
3196
  utxos = []
3194
3197
  for address in addresslist:
3195
3198
  if rescan_all:
@@ -3390,7 +3393,8 @@ class Wallet(object):
3390
3393
  :return:
3391
3394
  """
3392
3395
  network = self.network.name
3393
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
3396
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri,
3397
+ strict=self.strict)
3394
3398
  blockcount = srv.blockcount()
3395
3399
  self.session.query(DbTransaction).\
3396
3400
  filter(DbTransaction.wallet_id == self.wallet_id,
@@ -3413,7 +3417,8 @@ class Wallet(object):
3413
3417
  txids = list(dict.fromkeys(txids))
3414
3418
 
3415
3419
  txs = []
3416
- srv = Service(network=self.network.name, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
3420
+ srv = Service(network=self.network.name, wallet_name=self.name, providers=self.providers,
3421
+ cache_uri=self.db_cache_uri, strict=self.strict)
3417
3422
  for txid in txids:
3418
3423
  tx = srv.gettransaction(to_hexstring(txid))
3419
3424
  if tx:
@@ -3468,7 +3473,8 @@ class Wallet(object):
3468
3473
  # Update number of confirmations and status for already known transactions
3469
3474
  self.transactions_update_confirmations()
3470
3475
 
3471
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
3476
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri,
3477
+ strict=self.strict)
3472
3478
 
3473
3479
  # Get transactions for wallet's addresses
3474
3480
  txs = []
@@ -3752,12 +3758,12 @@ class Wallet(object):
3752
3758
  if not key:
3753
3759
  raise WalletError("Key '%s' not found in this wallet" % key_id)
3754
3760
  if key.key_type == 'multisig':
3755
- inp_keys = [HDKey.from_wif(ck.child_key.wif, network=ck.child_key.network_name) for ck in
3756
- key.multisig_children]
3761
+ inp_keys = [HDKey.from_wif(ck.child_key.wif, network=ck.child_key.network_name, compressed=key.compressed)
3762
+ for ck in key.multisig_children]
3757
3763
  elif key.key_type in ['bip32', 'single']:
3758
3764
  if not key.wif:
3759
3765
  raise WalletError("WIF of key is empty cannot create HDKey")
3760
- inp_keys = [HDKey.from_wif(key.wif, network=key.network_name)]
3766
+ inp_keys = [HDKey.from_wif(key.wif, network=key.network_name, compressed=key.compressed)]
3761
3767
  else:
3762
3768
  raise WalletError("Input key type %s not supported" % key.key_type)
3763
3769
  return inp_keys, key
@@ -3946,10 +3952,11 @@ class Wallet(object):
3946
3952
  addr = addr.key()
3947
3953
  transaction.add_output(value, addr, change=False)
3948
3954
 
3949
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
3955
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri,
3956
+ strict=self.strict)
3950
3957
 
3951
3958
  if not locktime and self.anti_fee_sniping:
3952
- srv = Service(network=network, providers=self.providers, cache_uri=self.db_cache_uri)
3959
+ srv = Service(network=network, providers=self.providers, cache_uri=self.db_cache_uri, strict=self.strict)
3953
3960
  blockcount = srv.blockcount()
3954
3961
  if blockcount:
3955
3962
  transaction.locktime = blockcount
@@ -4451,7 +4458,8 @@ class Wallet(object):
4451
4458
  continue
4452
4459
  input_arr.append((utxo['txid'], utxo['output_n'], utxo['key_id'], utxo['value']))
4453
4460
  total_amount += utxo['value']
4454
- srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri)
4461
+ srv = Service(network=network, wallet_name=self.name, providers=self.providers, cache_uri=self.db_cache_uri,
4462
+ strict=self.strict)
4455
4463
 
4456
4464
  fee_modifier = 1 if self.witness_type == 'legacy' else 0.6
4457
4465
  if isinstance(fee, str):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: bitcoinlib
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Bitcoin cryptocurrency Library
5
5
  Home-page: http://github.com/1200wd/bitcoinlib
6
6
  Author: 1200wd
@@ -33,10 +33,11 @@ Requires-Dist: ecdsa>=0.18; platform_system == "Windows"
33
33
  Requires-Dist: pycryptodome>=3.19.0
34
34
  Requires-Dist: SQLAlchemy>=2.0.20
35
35
  Requires-Dist: numpy==1.24.4; python_version < "3.9"
36
- Requires-Dist: numpy>=1.22.0; python_version >= "3.9"
36
+ Requires-Dist: numpy<2,>=1.24.4; python_version >= "3.9"
37
37
  Provides-Extra: dev
38
38
  Requires-Dist: scrypt>=0.8.20; platform_system != "Windows" and extra == "dev"
39
- Requires-Dist: sphinx>=7.1.0; extra == "dev"
39
+ Requires-Dist: sphinx>=7.1.0; python_version < "3.9" and extra == "dev"
40
+ Requires-Dist: sphinx>=7.2.0; python_version >= "3.9" and extra == "dev"
40
41
  Requires-Dist: coveralls>=4.0.1; extra == "dev"
41
42
  Requires-Dist: psycopg>=3.1.16; extra == "dev"
42
43
  Requires-Dist: mysql-connector-python>=8.4.0; extra == "dev"
@@ -44,6 +45,7 @@ Requires-Dist: mysqlclient>=2.2.0; extra == "dev"
44
45
  Requires-Dist: sphinx_rtd_theme>=2.0.0; extra == "dev"
45
46
  Requires-Dist: Cython>=3.0.8; extra == "dev"
46
47
  Requires-Dist: win-unicode-console; platform_system == "Windows" and extra == "dev"
48
+ Dynamic: license-file
47
49
 
48
50
  Python Bitcoin Library
49
51
  ======================
@@ -58,8 +60,10 @@ With BitcoinLib you can:
58
60
  - Create, analyse and run Bitcoin scripts
59
61
  - Generate Bitcoin addresses and represent them in different address formats like P2PKH, P2SH, Bech32, etc
60
62
  - Create private keys and work with Mnemonic password phrases
61
- - Uses external Service providers to fetch address, transaction, utxo and blockchain data. Or connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_ or `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ node.
62
- - Can be extended to support other cryptocurrencies by configuring custom parameters. At the moment Litecoin and Dogecoin are also supported.
63
+ - Use external Service providers to fetch address, transaction, utxo and blockchain data.
64
+ - Connect to you local `Bitcoin core <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bitcoind-connection.html>`_, `Bcoin <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-bcoin.html>`_, `Blockbook <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-blockbook.html>`_ or `ElectrumX <https://bitcoinlib.readthedocs.io/en/latest/source/_static/manuals.setup-electrumx.html>`_ node.
65
+ - Can be extended to support other cryptocurrencies by configuring custom parameters.
66
+ - At the moment Litecoin, Dogecoin and various test networks are supported out-of-the-box.
63
67
 
64
68
 
65
69
  .. image:: https://github.com/1200wd/bitcoinlib/actions/workflows/unittests.yaml/badge.svg
@@ -12,10 +12,9 @@ ecdsa>=0.18
12
12
  numpy==1.24.4
13
13
 
14
14
  [:python_version >= "3.9"]
15
- numpy>=1.22.0
15
+ numpy<2,>=1.24.4
16
16
 
17
17
  [dev]
18
- sphinx>=7.1.0
19
18
  coveralls>=4.0.1
20
19
  psycopg>=3.1.16
21
20
  mysql-connector-python>=8.4.0
@@ -28,3 +27,9 @@ scrypt>=0.8.20
28
27
 
29
28
  [dev:platform_system == "Windows"]
30
29
  win-unicode-console
30
+
31
+ [dev:python_version < "3.9"]
32
+ sphinx>=7.1.0
33
+
34
+ [dev:python_version >= "3.9"]
35
+ sphinx>=7.2.0
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = bitcoinlib
3
- version = 0.7.2
3
+ version = 0.7.4
4
4
  url = http://github.com/1200wd/bitcoinlib
5
5
  author = 1200wd
6
6
  author_email = info@1200wd.com
@@ -40,12 +40,13 @@ install_requires =
40
40
  pycryptodome >= 3.19.0
41
41
  SQLAlchemy >= 2.0.20
42
42
  numpy == 1.24.4;python_version<"3.9"
43
- numpy >= 1.22.0;python_version>="3.9"
43
+ numpy >= 1.24.4, <2;python_version>="3.9"
44
44
 
45
45
  [options.extras_require]
46
46
  dev =
47
47
  scrypt >= 0.8.20;platform_system!="Windows"
48
- sphinx >= 7.1.0
48
+ sphinx >= 7.1.0;python_version<"3.9"
49
+ sphinx >= 7.2.0;python_version>="3.9"
49
50
  coveralls >= 4.0.1
50
51
  psycopg >= 3.1.16
51
52
  mysql-connector-python >= 8.4.0
@@ -89,7 +89,7 @@ class TestDb(unittest.TestCase):
89
89
  if os.getenv('UNITTEST_DATABASE') == 'mysql':
90
90
  self.skipTest('MySQL does not allow indexing on LargeBinary fields, so caching is not possible')
91
91
  dbtmp = DbCache(self.database_cache_uri)
92
- srv = Service(cache_uri=self.database_cache_uri, exclude_providers=['bitaps', 'bitgo'])
92
+ srv = Service(cache_uri=self.database_cache_uri, exclude_providers=['bitgo'])
93
93
  t = srv.gettransaction('68104dbd6819375e7bdf96562f89290b41598df7b002089ecdd3c8d999025b13')
94
94
  if t:
95
95
  self.assertGreaterEqual(srv.results_cache_n, 0)
@@ -609,7 +609,7 @@ class TestHDKeys(unittest.TestCase):
609
609
  k = HDKey(network=network)
610
610
  for witness_type in ['legacy', 'p2sh-segwit', 'segwit']:
611
611
  for multisig in [False, True]:
612
- if (network[:4] == 'doge') and witness_type != 'legacy':
612
+ if (network[:4] == 'doge' or network[:4] == 'dash') and witness_type != 'legacy':
613
613
  break
614
614
  kwif = k.wif_private(witness_type=witness_type, multisig=multisig)
615
615
  hdkey = wif_prefix_search(kwif, witness_type=witness_type, multisig=multisig, network=network)
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # BitcoinLib - Python Cryptocurrency Library
4
4
  # Unit Tests for Bitcoinlib Network Class
5
- # © 2018 - 2020 November - 1200 Web Development <http://1200wd.com/>
5
+ # © 2018 - 2025 May - 1200 Web Development <http://1200wd.com/>
6
6
  #
7
7
 
8
8
  import unittest
@@ -310,7 +310,7 @@ class TestService(unittest.TestCase, CustomAssertions):
310
310
  self.assertEqual(res[0].txid, '8b8a8f1de23f70b2bdaa74488d97dc64728c2d99d2d486945c71e258fdef6ca1')
311
311
 
312
312
  def test_service_gettransactions_after_txid_segwit(self):
313
- res = ServiceTest(timeout=TIMEOUT_TEST, exclude_providers=['blockcypher']).\
313
+ res = ServiceTest(timeout=TIMEOUT_TEST).\
314
314
  gettransactions('bc1qj9hlju59t0m4389033r2x8mlxwc86qgqm9flm626sd22cdhfs9jsyrrp6q',
315
315
  after_txid='bd430d52f35166a7dd6251c73a48559ad8b5f41b6c5bc4a6c4c1a3e3702f4287')
316
316
  self.assertEqual(res[0].txid, 'cab75da6d7fe1531c881d4efdb4826410a2604aa9e6442ab12a08363f34fb408')
@@ -626,13 +626,13 @@ class TestService(unittest.TestCase, CustomAssertions):
626
626
  self.assertIn(txid, [utxo['txid'] for utxo in utxos])
627
627
 
628
628
  def test_service_blockcount(self):
629
- for nw in ['bitcoin', 'litecoin', 'testnet']: # ToDo: add testnet4 when more providers are available
630
- srv = ServiceTest(min_providers=3, cache_uri='', network=nw, exclude_providers=['bitgo', 'bitaps'])
629
+ for nw in ['bitcoin']:
630
+ srv = ServiceTest(min_providers=3, cache_uri='', network=nw)
631
631
  srv.blockcount()
632
632
  n_blocks = None
633
633
  delta = 200
634
- if nw == 'testnet':
635
- delta = 2500
634
+ if nw == 'testnet': # Testnet 3 has frequent blockstorms causing delay in processing for various providers
635
+ delta = 25000
636
636
  for provider in srv.results:
637
637
  if n_blocks is not None:
638
638
  self.assertAlmostEqual(srv.results[provider], n_blocks, delta=delta,
@@ -785,11 +785,14 @@ class TestService(unittest.TestCase, CustomAssertions):
785
785
  fields = [k for k, _ in res.items()]
786
786
  self.assertListEqual(sorted(fields), ['blockcount', 'chain', 'difficulty', 'hashrate', 'mempool_size'])
787
787
 
788
- def test_service_getinfo_litecoin(self):
789
- srv = ServiceTest(network='litecoin')
790
- res = srv.getinfo()
791
- fields = [k for k, _ in res.items()]
792
- self.assertListEqual(sorted(fields), ['blockcount', 'chain', 'difficulty', 'hashrate', 'mempool_size'])
788
+ # Temporary disable unittest - all service provider have issues
789
+ # def test_service_getinfo_litecoin(self):
790
+ # srv = ServiceTest(network='litecoin')
791
+ # res = srv.getinfo()
792
+ # if not res:
793
+ # print(srv.errors)
794
+ # fields = [k for k, _ in res.items()]
795
+ # self.assertListEqual(sorted(fields), ['blockcount', 'chain', 'difficulty', 'hashrate', 'mempool_size'])
793
796
 
794
797
  def test_service_getinputvalues(self):
795
798
  rawtx = '02000000000101cb5f7b25dbf8106c6df0083d97e36690ba95c6477bdae2b9fa487115f259b3b60000000000ffffffff' \
@@ -861,11 +864,14 @@ class TestServiceCache(unittest.TestCase):
861
864
  if os.path.isfile(DATABASE_CACHE_UNITTESTS):
862
865
  try:
863
866
  os.remove(DATABASE_CACHE_UNITTESTS)
867
+ except:
868
+ pass
869
+ if os.path.isfile(DATABASE_CACHE_UNITTESTS2):
870
+ try:
864
871
  os.remove(DATABASE_CACHE_UNITTESTS2)
865
872
  except:
866
873
  pass
867
874
 
868
-
869
875
  def test_service_cache_transactions(self):
870
876
  srv = ServiceTest(cache_uri=DATABASE_CACHE_UNITTESTS2)
871
877
  address = '1JQ7ybfFBoWhPJpjoihezpeAjd2xv9nXaN'
@@ -889,30 +895,29 @@ class TestServiceCache(unittest.TestCase):
889
895
  ca = srv.getcacheaddressinfo(address)
890
896
  self.assertEqual(ca['address'], address)
891
897
 
892
- # FIXME: Disabled, lack of providers
893
- # def test_service_cache_gettransaction(self):
894
- # srv = ServiceTest(network='litecoin_testnet', cache_uri=DATABASE_CACHE_UNITTESTS2)
895
- # txid = 'b6533d361daac291f64fff32a5c157a4785b423ce36e2eac27117879f93973da'
896
- #
897
- # t = srv.gettransaction(txid)
898
- # self.assertEqual(srv.results_cache_n, 0)
899
- # self.assertEqual(t.fee, 6680)
900
- #
901
- # t = srv.gettransaction(txid)
902
- # self.assertEqual(srv.results_cache_n, 1)
903
- # self.assertEqual(t.fee, 6680)
904
- #
905
- # rawtx = srv.getrawtransaction(txid)
906
- # self.assertEqual(srv.results_cache_n, 1)
907
- # self.assertEqual(rawtx, '0100000001ce18990b7a14afaf00eef179852daf07a7eb0eaaf90ae92393220fcd6fd899a101000000'
908
- # 'db00483045022100bdcd0f4713b35872154c94e65fe65946abf60ef9b6b307479981dbec546b22ce02'
909
- # '20156d537a93b174392e23360c4336785362de1028c9400ef298252c9006cdb01501483045022100b5'
910
- # 'f876fdd2a6200bed1f15b9eba213e24fb3b9707b07ba8f24ef06bf8e774018022002165eeb777463a6'
911
- # 'e1bceb0d2c29c2ad3aa46b639b744520020e1a028c66bc3c0147522102a6126cabab675799a7f8022d'
912
- # 'c756b40fd5226c8ebe3c279e4f5aebc034b6d48d21039b904498e7702692b72b265dfb0221994bb850'
913
- # '5ee50837aba768083b3a25aba952aeffffffff0240787d010000000017a914d9f17035fdd2180e4e67'
914
- # 'de2c17d63c218948780a875022d64ead01000017a91494d0071ed66b6584650440fdc6dfc2916a119b'
915
- # '068700000000')
898
+ def test_service_cache_gettransaction(self):
899
+ srv = ServiceTest(network='litecoin_testnet', cache_uri=DATABASE_CACHE_UNITTESTS2)
900
+ txid = 'b6533d361daac291f64fff32a5c157a4785b423ce36e2eac27117879f93973da'
901
+
902
+ t = srv.gettransaction(txid)
903
+ self.assertEqual(srv.results_cache_n, 0)
904
+ self.assertEqual(t.fee, 6680)
905
+
906
+ t = srv.gettransaction(txid)
907
+ self.assertEqual(srv.results_cache_n, 1)
908
+ self.assertEqual(t.fee, 6680)
909
+
910
+ rawtx = srv.getrawtransaction(txid)
911
+ self.assertEqual(srv.results_cache_n, 1)
912
+ self.assertEqual(rawtx, '0100000001ce18990b7a14afaf00eef179852daf07a7eb0eaaf90ae92393220fcd6fd899a101000000'
913
+ 'db00483045022100bdcd0f4713b35872154c94e65fe65946abf60ef9b6b307479981dbec546b22ce02'
914
+ '20156d537a93b174392e23360c4336785362de1028c9400ef298252c9006cdb01501483045022100b5'
915
+ 'f876fdd2a6200bed1f15b9eba213e24fb3b9707b07ba8f24ef06bf8e774018022002165eeb777463a6'
916
+ 'e1bceb0d2c29c2ad3aa46b639b744520020e1a028c66bc3c0147522102a6126cabab675799a7f8022d'
917
+ 'c756b40fd5226c8ebe3c279e4f5aebc034b6d48d21039b904498e7702692b72b265dfb0221994bb850'
918
+ '5ee50837aba768083b3a25aba952aeffffffff0240787d010000000017a914d9f17035fdd2180e4e67'
919
+ 'de2c17d63c218948780a875022d64ead01000017a91494d0071ed66b6584650440fdc6dfc2916a119b'
920
+ '068700000000')
916
921
 
917
922
  def test_service_cache_transactions_after_txid(self):
918
923
  # Do not store anything in cache if after_txid is used
@@ -936,7 +941,7 @@ class TestServiceCache(unittest.TestCase):
936
941
  self.assertGreaterEqual(srv.results_cache_n, 1)
937
942
 
938
943
  def test_service_cache_transaction_coinbase(self):
939
- srv = ServiceTest(cache_uri=DATABASE_CACHE_UNITTESTS2, exclude_providers=['bitaps', 'bitgo'])
944
+ srv = ServiceTest(cache_uri=DATABASE_CACHE_UNITTESTS2)
940
945
  t = srv.gettransaction('68104dbd6819375e7bdf96562f89290b41598df7b002089ecdd3c8d999025b13')
941
946
  if t:
942
947
  self.assertGreaterEqual(srv.results_cache_n, 0)
@@ -2393,8 +2393,8 @@ class TestWalletTransactions(unittest.TestCase, CustomAssertions):
2393
2393
  w.utxo_add(w.get_key().address, 1234567, os.urandom(32).hex(), 1)
2394
2394
  t = w.send_to('tb1qrjtz22q59e76mhumy0p586cqukatw5vcd0xvvz', 123456)
2395
2395
  block_height = Service(network='testnet', cache_uri='').blockcount()
2396
- # FIXME: remove delta when testnet network is stable again
2397
- self.assertAlmostEqual(t.locktime, block_height+1, delta=500)
2396
+ # TODO: Replace with testnet4 / bitcoin test to avoid issues with testnet3 blockstorms
2397
+ self.assertAlmostEqual(t.locktime, block_height+1, delta=25000)
2398
2398
 
2399
2399
  w2 = wallet_create_or_open('antifeesnipingtestwallet2', network='testnet', anti_fee_sniping=True,
2400
2400
  db_uri=self.database_uri)
@@ -1 +0,0 @@
1
- 0.7.2
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes