Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bibajz/bitcoin-python-async-rpc
Minimal Bitcoin JSON-RPC Python asynchronous client
https://github.com/bibajz/bitcoin-python-async-rpc
async bitcoin cryptocurrency python python3
Last synced: about 1 month ago
JSON representation
Minimal Bitcoin JSON-RPC Python asynchronous client
- Host: GitHub
- URL: https://github.com/bibajz/bitcoin-python-async-rpc
- Owner: bibajz
- License: mit
- Created: 2020-04-14T18:08:07.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-02-11T23:35:41.000Z (9 months ago)
- Last Synced: 2024-09-29T04:03:11.897Z (about 2 months ago)
- Topics: async, bitcoin, cryptocurrency, python, python3
- Language: Python
- Homepage:
- Size: 37.1 KB
- Stars: 31
- Watchers: 4
- Forks: 12
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# bitcoin-python-async-rpc
Lightweight Bitcoin async JSON-RPC Python client.Serves as a tiny layer between an application and a Bitcoin daemon, its primary usage
is querying the current state of Bitcoin blockchain, network stats, transactions...If you want complete Bitcoin experience in Python, consult
[python-bitcoinlib](https://github.com/petertodd/python-bitcoinlib).## Installation
```bash
$ pip install bitcoinrpc
```## Supported methods
Here is a list of supported methods, divided by their categories. Should you need
method not implemented, wrap the call in `BitcoinRPC.acall(, ...)` coroutine.### Blockchain
| Method | Supported? |
|------------|:----------------:|
| `getbestblockhash` | ✔ |
| `getblock` | ✔ |
| `getblockchaininfo` | ✔ |
| `getblockcount` | ✔ |
| `getblockhash` | ✔ |
| `getblockheader` | ✔ |
| `getblockstats` | ✔ |
| `getchaintips` | ✔ |
| `getdifficulty` | ✔ |
| `getmempoolinfo` | ✔ |
| `getnetworkhashps` | ✔ |### Mining
| Method | Supported? |
|------------|:----------------:|
| `getmininginfo` | ✔ |### Network
| Method | Supported? |
|------------|:----------------:|
| `getconnectioncount` | ✔ |
| `getnetworkinfo` | ✔ |### Raw transactions
| Method | Supported? |
|------------|:----------------:|
| `analyzepsbt` | ✔ |
| `combinepsbt` | ✔ |
| `decodepsbt` | ✔ |
| `finalizepsbt` | ✔ |
| `getrawtransaction` | ✔ |
| `joinpsbts` | ✔ |
| `utxoupdatepsbt` | ✔ |### Wallet
| Method | Supported? |
|------------|:----------------:|
| `walletprocesspsbt` | ✔ |## Usage
Minimal illustration (assuming Python 3.8+, where you can run `async` code in console)```
$ python -m asyncio
>>> import asyncio
>>>
>>> from bitcoinrpc import BitcoinRPC
>>> rpc = BitcoinRPC.from_config("http://localhost:18443", ("rpc_user", "rpc_passwd"))
>>> await rpc.getconnectioncount()
10
>>> await rpc.aclose() # Clean-up resource
```You can also use the `BitcoinRPC` as an asynchronous context manager, which does
all the resource clean-up automatically, as the following example shows:```python
$ cat btc_rpc_minimal.py
import asynciofrom bitcoinrpc import BitcoinRPC
async def main():
async with BitcoinRPC.from_config("http://localhost:18443", ("rpc_user", "rpc_password")) as rpc:
print(await rpc.getconnectioncount())if __name__ == "__main__":
asyncio.run(main())
```Running this script yields:
```
$ python btc_rpc_minimal.py
10
```If you want customize the underlying `httpx.AsyncClient`, you can instantiate the `BitcoinRPC` with one.
Consider the following script, where the client is configured to log every HTTP request before it is sent
out over the wire:```python
$ cat btc_custom_client.py
import asyncioimport httpx
from bitcoinrpc import BitcoinRPC
async def log_request(request: httpx.Request) -> None:
print(request.content)async def main() -> None:
client = httpx.AsyncClient(auth=("rpc_user", "rpc_password"), event_hooks={"request": [log_request]})
async with BitcoinRPC(url="http://localhost:18443", client=client) as rpc:
print(await rpc.getconnectioncount())if __name__ == "__main__":
asyncio.run(main())
```Running this script yields:
```
$ python btc_custom_client.py
b'{"jsonrpc":"2.0","id":1,"method":"getconnectioncount","params":[]}'
0
```## Testing
A `Containerfile` is provided as a means to build an OCI image of a Bitcoin `regtest` node.
Build the image (`podman` is used, but `docker` should be fine too):```
$ podman build \
-f Containerfile \
--build-arg BTC_VERSION=v24.1 \
-t bitcoin-regtest:v24.1 \
-t bitcoin-regtest:latest \
.
```and run it afterwards:
```
$ podman run \
--rm \
-it \
--mount=type=bind,src=./tests/bitcoin-regtest.conf,target=/home/rpc/.bitcoin/bitcoin.conf \
-p 127.0.0.1:18443:18443 \
--name bitcoin-regtest \
localhost/bitcoin-regtest:v24.1
```which will expose the Bitcoin `regtest` node on port 18443, accesible from localhost only, with RPC user/password `rpc_user/rpc_password`.
After you are done testing, stop the container via:
```
$ podman stop bitcoin-regtest
```---
If you want to test against a different version of Bitcoin node, pass a different [tag](https://github.com/bitcoin/bitcoin/tags) in the build stage:
```
$ podman build \
-f Containerfile \
--build-arg BTC_VERSION=v25.0 \
-t bitcoin-regtest:v25.0 \
-t bitcoin-regtest:latest \
.
```---
Different settings of the Bitcoin node may be passed via mounting your custom configuration file, or optionally as "arguments" to `podman run`:
```
$ podman run \
--rm \
-it \
--mount=type=bind,src=,target=/home/rpc/.bitcoin/bitcoin.conf \
-p 127.0.0.1:18443:18443 \
--name bitcoin-regtest \
localhost/bitcoin-regtest:v24.1 ...
```---
Please, keep in mind that Bitcoin node compiled in the image is intended for testing & debugging purposes only! It may serve you as an inspiration for building
your own, production-ready Bitcoin node, but its intended usage is testing!---
For testing this library, install `tox` (preferably, in a fresh virtual environment).
Afterwards, coding-style is enforced by running:
```
(your-venv-with-tox) $ tox run -e linters
```and tests corresponding are run (this example uses Python3.11)
```
(your-venv-with-tox) $ tox run -e py311
```If you do not want to run tests marked as `"integration"`, which denote those requiring the bitcoin regtest node to run, you can filter them out by:
```
(your-venv-with-tox) $ tox run -e py311 -- -m 'not integration'
```## Changelog
- **2024/02/12 - 0.7.0**: More robust handling of JSON-RPC 2.0 specification (thanks https://github.com/joxerx !)
* **Breaking change**: change the handling of responses with non-2xx status codes in 'BitcoinRPC.acall'.
Previously, said errors would be raised directly via the `httpx.Response.raise_for_status` method.
Now, `httpx.Response.raise_for_status` is used only when the server
returns an empty response, which may happen due to for example bad
authentication. In all other cases, defer the decision whether RPC
call was a success or a failure to the inspection of return JSON.
- **2023/06/04 - 0.6.1**: Add RPC methods, mainly concerned with PSBTs
- **2023/06/01 - 0.6.0**:
* `BitcoinRPC` is now instantiated with a `httpx.AsyncClient` directly and an optional `counter` argument, which is a callable that may be used for distinguishing
the JSON-RPC requests. Old-style instantiation, with `url` and optional user/password tuple, is kept within `BitcoinRPC.from_config` method.- **2021/12/28 - 0.5.0** change the signature of `BitcoinRPC` from `host, port, ...` to `url, ...`, delegating the creation of the node url to the caller.
## License
MIT