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.
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/CHANGELOG +21 -0
- {bitcoinlib-0.7.2/bitcoinlib.egg-info → bitcoinlib-0.7.4}/PKG-INFO +10 -6
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/README.rst +4 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/__init__.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/__init__.py +1 -1
- bitcoinlib-0.7.4/bitcoinlib/config/VERSION +1 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/providers.examples.json +21 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/providers.json +47 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/keys.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/networks.py +2 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/authproxy.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bcoin.py +5 -5
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitcoind.py +8 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockbook.py +2 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockchaininfo.py +2 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockcypher.py +9 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blocksmurfer.py +10 -4
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/electrumx.py +2 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/mempool.py +1 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/services.py +3 -3
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/transactions.py +8 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wallets.py +22 -14
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4/bitcoinlib.egg-info}/PKG-INFO +10 -6
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/requires.txt +7 -2
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/setup.cfg +4 -3
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_db.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_keys.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_networks.py +1 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_services.py +41 -36
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_wallets.py +2 -2
- bitcoinlib-0.7.2/bitcoinlib/config/VERSION +0 -1
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/LICENSE +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/MANIFEST.in +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/blocks.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__init__.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/__init__.cpython-310.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/__init__.cpython-38.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/config.cpython-310.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/config.cpython-38.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/opcodes.cpython-310.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/opcodes.cpython-38.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-310.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-38.pyc +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/config.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/opcodes.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/secp256k1.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/config.ini +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/data/networks.json +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/db.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/db_cache.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/encoding.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/main.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/mnemonic.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/scripts.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/__init__.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/baseclient.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitaps.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitcoinlibtest.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitflyer.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/bitgo.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockchair.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/blockstream.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/chainso.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/cryptoid.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/dogecoind.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoinblockexplorer.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoind.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/services/litecoreio.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/__init__.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/benchmark.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/clw.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/import_database.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/mnemonic_key_create.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/sign_raw.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/tools/wallet_multisig_2of3.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/values.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/chinese_simplified.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/chinese_traditional.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/dutch.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/english.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/french.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/italian.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/japanese.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/portuguese.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/wordlist/spanish.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/SOURCES.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/dependency_links.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/entry_points.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/top_level.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib.egg-info/zip-safe +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/pyproject.toml +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/requirements.txt +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/__init__.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/bip38_protected_key_tests.json +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block250000.pickle +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block330000.pickle +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block625007.pickle +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block629999.pickle +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/block722010.pickle +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/electrum_keys.json +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/mnemonics_tests.json +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_blocks.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_custom.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_encoding.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_mnemonic.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_script.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_security.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_tools.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_transactions.py +0 -0
- {bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/tests/test_values.py +0 -0
- {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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: bitcoinlib
|
|
3
|
-
Version: 0.7.
|
|
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
|
|
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
|
-
-
|
|
62
|
-
-
|
|
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
|
-
-
|
|
15
|
-
-
|
|
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
|
|
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 -
|
|
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":
|
|
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":
|
|
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 -
|
|
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 -
|
|
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
|
|
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=
|
|
94
|
+
txs = self.gettransactions(address, limit=200)
|
|
95
95
|
|
|
96
96
|
# Fail if large number of transactions are found
|
|
97
|
-
if len(txs)
|
|
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':
|
|
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) ==
|
|
140
|
-
after_txid = res[
|
|
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
|
-
#
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
|
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(
|
|
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=
|
|
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
|
-
|
|
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
|
|
@@ -141,8 +141,7 @@ class MempoolClient(BaseClient):
|
|
|
141
141
|
if len(prtxs) > 100:
|
|
142
142
|
break
|
|
143
143
|
txs = []
|
|
144
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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)
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: bitcoinlib
|
|
3
|
-
Version: 0.7.
|
|
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
|
|
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
|
-
-
|
|
62
|
-
-
|
|
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
|
|
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.
|
|
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.
|
|
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=['
|
|
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)
|
|
@@ -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
|
|
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'
|
|
630
|
-
srv = ServiceTest(min_providers=3, cache_uri='', network=nw
|
|
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 =
|
|
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
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
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
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
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
|
|
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
|
-
#
|
|
2397
|
-
self.assertAlmostEqual(t.locktime, block_height+1, delta=
|
|
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
|
{bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/__init__.cpython-310.pyc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-310.pyc
RENAMED
|
File without changes
|
{bitcoinlib-0.7.2 → bitcoinlib-0.7.4}/bitcoinlib/config/__pycache__/secp256k1.cpython-38.pyc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|