Get balance
FREE2Z

Python Zcash RPC Client

Python Zcash RPC Client: A Python library to interact with the Zcash blockchain, providing tools to communicate with a Zcash node and make RPC calls.

March 5, 2022· 3 min read
2K score

The Reason

I want to be able to interact with the Zcash blockchain using one of my favorite languages, Python. How to communicate with the Zcash blockchain was not obvious to me for a few years! So, hopefully this will help someone else get started!

The Result

In [1]: from free2z.client import Client In [2]: z = Client() In [3]: z.get_balance?Signature: z.get_balance(addr: str) -> decimal.DecimalDocstring: Calls z_getbalance on the addr argument and returns a Decimal.File:      free2z/client.pyType:      method In [4]: z.get_balance("zs1uxr6n9zrqxzh3pzppfl0enf9x3q4wcszsp06ke8w4uc8rsan5pds7uhzqv75qdcqp96zgxh6l6g")Out[4]: 0.01

The Dependencies

  • zcashd:
    To talk to the Zcash blockchain with Python,
    I will be running a full node.

  • slick-bitcoinrpc:
    I'll be starting with a cool little library called slick-bitcoinrpc. This
    tidy little thing can talk to a bitcoin node or a Zcash node right out of the box. It's very flexible; but, perhaps
    as a side-effect, it doesn't give tools any type information or even an idea of what is available in the API. So, we'll
    be making a wrapper client with type hints that will make it
    more fun and productive to use from an editor or an interactive session.

Running a full node

Refer to the docs for how to run a full node. This can take a day or two to sync. Perhaps a follow-up to this post might show how to use a
light client.
If you're serious about integrating Zcash into your product, you can spin up a permanent node on a VM with >= 4GB of RAM for not too much $$. Note that you'll have to set rpcuser and rpcpassword in your .zcash/zcash.conf to turn on the
RPC
API

Making RPC calls with Python

Once the node is up and running, we can easily make basic calls to the RPC interface with the help of slick-bitcoinrpc. To figure out what we can do with this interface, these are my favorite docs: https://zcash.github.io/rpc/. With these in hand we can easily implement a wrapper client with fancy type hints.

to be continued ...

Please fund this page if you would like to see this post completed and a pip-installable package put on PyPI. Even a modest donation of 0.001 ZEC would lift the spirits while providing raw material for the soul.

import osimport randomimport decimalfrom typing import List  class Client(object):     def __init__(self) -> None:        # show special mock stuff        self._get_rpc()     def _get_rpc(self):        from slickrpc import Proxy        user = os.environ["ZCASH_USER"]        password = os.environ["ZCASH_PASSWORD"]        host = os.environ.get("ZCASH_HOST", "127.0.0.1")        port = os.environ.get("ZCASH_PORT", "8232")        proto = os.environ.get("ZCASH_PROTO", "http")        self.rpc = Proxy(f"{proto}://{user}:{password}@{host}:{port}")        # self.dummy = False     def new_addr(self) -> str:        return self.rpc.z_getnewaddress()     def is_valid(self, addr: str) -> bool:        return self.rpc.z_validateaddress(addr)     def get_balance(self, addr: str) -> decimal.Decimal:        """        Calls z_getbalance on the addr argument and returns a float.        """        return self.rpc.z_getbalance(addr)     def list(self) -> List[str]:        return self.rpc.z_listaddresses() 

Example Usage:

"""Look in local node to find the latest payments and flip those pages to funded"""from django.core.management.base import BaseCommand from free2z.client import Clientfrom g12f.models import zPage  class Command(BaseCommand):    help = 'Checks if zPages are funded'     def handle(self, *args, **kwargs):        z = Client()        unfunded_pages = zPage.objects.filter(is_funded=False)         funded = 0        for page in unfunded_pages:            print(f"checking {page}")            if z.get_balance(page.free2zaddr) >= 0.01:                print(f"{page} is funded")                page.is_funded = True                page.save()                funded += 1        print(f"{funded} pages were funded. Exiting ..")

Tags

Related Articles